Rendering 3D models with translucent textures

550 views
Skip to first unread message

Arne Schilling

unread,
Mar 1, 2016, 4:15:27 AM3/1/16
to cesium-dev
Hi,

I am creating B3DM/GLTF 3D models of buildings with PNG textures that are partly translucent. The window parts in the texture have a low alpha/transparency value but they are not fully transparent. the other parts should be rendered opaque. I was experimenting with BLEND rendering mode and functions for blending alpha values of textures. But I cannot get the example in the attached screenshot right. The opaque parts are also blended making the building appear like a ghost.

What is the best way to render such kind of objects?

cheers,
Arne


My technique is defined as:

"ID154": {
            "attributes": {
                "a_batchId": "batchId",
                "a_texcoord0": "texcoord0",
                "a_position": "position"
            },
            "parameters": {
                "projectionMatrix": {
                    "semantic": "PROJECTION",
                    "type": 35676
                },
                "texcoord0": {
                    "semantic": "TEXCOORD_0",
                    "type": 35664
                },
                "position": {
                    "semantic": "POSITION",
                    "type": 35665
                },
                "diffuse": {
                    "type": 35678
                },
                "batchId": {
                    "semantic": "BATCHID",
                    "type": 5126
                },
                "modelViewMatrix": {
                    "semantic": "CESIUM_RTC_MODELVIEW",
                    "type": 35676
                }
            },
            "program": "ID159",
            "states": {
                "enable": [2929, 3042],
                "functions": {
                    "blendColor": [0.0, 0.0, 0.0, 0.0],
                    "blendEquationSeparate": [32774, 32774],
                    "blendFuncSeparate": [1, 771, 1, 771],
                    "colorMask": [true, true, true, true],
                    "cullFace": [1029],
                    "depthFunc": [513],
                    "depthMask": [true],
                    "depthRange": [0.0, 1.0],
                    "frontFace": [2305],
                    "lineWidth": [1.0],
                    "polygonOffset": [0.0, 0.0],
                    "scissor": [0.0, 0.0, 0.0, 0.0]
                }
            },
            "uniforms": {
                "u_modelViewMatrix": "modelViewMatrix",
                "u_projectionMatrix": "projectionMatrix",
                "u_diffuse": "diffuse"
            }
        }


Meaning of the numbers in  blending functions:

       "enable": [2929, 3042], ->   DEPTH_TEST ,BLEND
       "blendEquationSeparate": [32774, 32774],  ->   FUNC_ADD,FUNC_ADD
       "blendFuncSeparate": [1, 771, 1, 771],   ->  ONE, ONE_MINUS_SRC_ALPHA, ONE, ONE_MINUS_SRC_ALPHA


The fragment shader is very simple:

precision highp float;
varying vec2 v_texcoord0;
uniform sampler2D u_diffuse;

void main(void) {
        vec4 color = texture2D(u_diffuse, v_texcoord0);
        gl_FragColor = color;
}


cesium-translucent-tex.jpg

Patrick Cozzi

unread,
Mar 2, 2016, 10:36:35 AM3/2/16
to cesium-dev
Hi Arne,

In most cases, we don't use additive blending in Cesium (FUNC_ADD) because it often saturates.  Instead we use alpha blending like this:


For b3dm, make sure you are using the Cesium 3d-tiles branch, not 3d-tiles-style, which may temporarily have an issue with this.

Also, I'm giving a talk about 3D Tiles next week and would be happy to include your work with the b3dm format.  See this thread for details and let me know.

Patrick

Arne Schilling

unread,
Mar 2, 2016, 11:44:21 AM3/2/16
to cesium-dev
I still don't understand what is happening.
No matter what functions and equations i use, the result is more or less the same. I am using the 3d-tiles branch.

My settings above are the same in
PRE_MULTIPLIED_ALPHA_BLEND in BlendingState.js from your link

ALPHA_BLEND and ADDITIVE_BLEND isn't much of an improvement either.

What do you mean by "we don't use additive blending" ?

Should I remove BLEND mode altogether? I thought that's the way to go...

In BlendingState.js i see:
            equationRgb : BlendEquation.ADD,
            equationAlpha : BlendEquation.ADD,

isn't that the same as
FUNC_ADD in  "blendEquationSeparate"?

The GLTF spec says that
FUNC_ADD is the default value for blendEquationSeparate
see https://github.com/KhronosGroup/glTF/blob/master/specification/schema/technique.states.functions.schema.json#L19-L32

alternatives are
"FUNC_SUBTRACT", "FUNC_REVERSE_SUBTRACT"

In other CG threads I often read that depth sorting of primitives is mandatory in order to get rendering of translucent textures right.


We are very happy about the opportunity to have our work included in your presentation at the next OGC TC meeting, since nobody from us will be in Washington. Claus should have gotten in touch with you already.

Arne






Patrick Cozzi

unread,
Mar 2, 2016, 1:40:08 PM3/2/16
to cesiu...@googlegroups.com
Hi Arne,

Ah, I didn't realize that you are working with Claus.  We are already in touch, thanks!


You won't have to worry about sorting geometry; Cesium uses a technique that does not require sorting explained here: https://cesiumjs.org/2014/03/14/Weighted-Blended-Order-Independent-Transparency/

Patrick

--
You received this message because you are subscribed to a topic in the Google Groups "cesium-dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cesium-dev/ApjKyLX3QYU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cesium-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Arne Schilling

unread,
Mar 3, 2016, 9:30:04 AM3/3/16
to cesium-dev
I am working now on a solution that involves a second mesh primitive, which is rendered differntly in order to mimic multi pass rendering.

Inspired by https://groups.google.com/forum/#!topic/cesium-dev/wIxwpak4ft8, I also define a second primitive in my meshes, which have a translucent texture.
The second primitive shares the same attributes and indices as the first one, but has a different material with different rendering modes and fragment shader.

The idea is to first draw the mesh with blending mode on in order to render the window panes correctly represented by the translucent parts of the texture.
The technique for the first draw uses BLEND mode and PRE_MULTIPLIED_ALPHA_BLEND functions.

The second draw is with blending mode off in order to render the parts of the texture representing building walls as fully opaque areas.
The fragment shader used for this pass is configured to discard fragments with alpha values < 0.9 so that the window parts will not be rendered at all (color and depth buffer)


This way my buildings are rendered very nicely. However, I limit this approach to meshes which have PNG or TIFF textures that actually have transparent or translucent pixels (alpha < 255).
Otherwise the default approach with only one pass is used.

I hope that the overhead introduced by a second mesh primitive is kept within a reasonable limit. However, I would prefer actual two pass rendering defined within the GLTF Technique.

Parts of my GLTF below

Arne






ID106 fragment shader:


precision highp float;
varying vec2 v_texcoord0;
uniform sampler2D u_diffuse;

void main(void) {
        vec4 color = texture2D(u_diffuse, v_texcoord0);
        gl_FragColor = color;
}





ID116 Fragment shader:


precision highp float;
varying vec2 v_texcoord0;
uniform sampler2D u_diffuse;

void main(void) {
        vec4 color = texture2D(u_diffuse, v_texcoord0);
      if(color.a < 0.9)
           discard;
        gl_FragColor = color;
}



{
    "programs": {
        "ID120": {
            "attributes": ["a_texcoord0"],
            "fragmentShader": "ID116",
            "vertexShader": "ID118"
        },
        "ID110": {
            "attributes": ["a_texcoord0"],
            "fragmentShader": "ID106",
            "vertexShader": "ID108"
        }
    },



    "techniques": {
        "ID105": {
            "program": "ID110",

            "states": {
                "enable": [2929, 3042],
                "functions": {
                    "blendColor": [0.0, 0.0, 0.0, 0.0],
                    "blendEquationSeparate": [32774, 32774],
                    "blendFuncSeparate": [1, 771, 1, 771],
                    "colorMask": [true, true, true, true],
                    "cullFace": [1029],
                    "depthFunc": [513],
                    "depthMask": [true],
                    "depthRange": [0.0, 1.0],
                    "frontFace": [2305],
                    "lineWidth": [1.0],
                    "polygonOffset": [0.0, 0.0],
                    "scissor": [0.0, 0.0, 0.0, 0.0]
                }
            },
            "uniforms": {
                "u_modelViewMatrix": "modelViewMatrix",
                "u_projectionMatrix": "projectionMatrix",
                "u_diffuse": "diffuse"
            }
        },


        "ID115": {
            "program": "ID120",
            "states": {
                "enable": [2929],

                "functions": {
                    "blendColor": [0.0, 0.0, 0.0, 0.0],
                    "blendEquationSeparate": [32774, 32774],
                    "blendFuncSeparate": [1, 1, 0, 0],

                    "colorMask": [true, true, true, true],
                    "cullFace": [1029],
                    "depthFunc": [513],
                    "depthMask": [true],
                    "depthRange": [0.0, 1.0],
                    "frontFace": [2305],
                    "lineWidth": [1.0],
                    "polygonOffset": [0.0, 0.0],
                    "scissor": [0.0, 0.0, 0.0, 0.0]
                }
            },
            "uniforms": {
                "u_modelViewMatrix": "modelViewMatrix",
                "u_projectionMatrix": "projectionMatrix",
                "u_diffuse": "diffuse"
            }
        }

    },




    "materials": {
        "ID142": {
            "name": "M_ID142",
            "technique": "ID105",
            "values": {
                "diffuse": "ID143"
            }
        },
        "ID146": {
            "name": "M_ID142_opaque",
            "technique": "ID115",
            "values": {
                "diffuse": "ID143"
            }
        }

    },



    "meshes": {
        "ID147": {
            "name": "TA_ID147",
            "primitives": [{
                "attributes": {
                    "BATCHID": "ID150",
                    "POSITION": "ID149",
                    "TEXCOORD_0": "ID148"
                },
                "indices": "ID151",
                "material": "ID142",
                "mode": 4
            }, {
                "attributes": {
                    "BATCHID": "ID150",
                    "POSITION": "ID149",
                    "TEXCOORD_0": "ID148"
                },
                "indices": "ID151",
                "material": "ID146",
                "mode": 4
            }]
        }

    }

}
corr_translucent_textures.jpg
corr_translucent_textures2.jpg
Reply all
Reply to author
Forward
0 new messages