Most of the information about how semi-opaque (or semi-transparent) objects should be rendered is encoded directly in the glTF asset. This information is contained in the technique.states
and technique.states.functions
. For example, the technique.states
contains information about whether GL_BLEND
is enabled or not. And technique.sates.functions
contains information about the blend equation and blend functions.
At the bottom of this issue, there is a glTF asset intended for testing the opacity handling.
The materials are ordered from upper left to lower right. So the upper left blue triangle is supposed to be fully transparent. Obviously, the result is utterly wrong.
Because the pixels should be written with the source alpha, and the existing background pixels should be "blended out" or "overwritten" depending on the source alpha. The result looks correct for me:
The glTF asset used for testing. The buffer data is embedded. The shaders are given below.
{
"scenes" : {
"scene0" : {
"nodes" : [ "node0", "node1", "node2", "node3", "node4", "node5" ]
}
},
"nodes" : {
"node0" : {
"translation" : [ -0.5, -0.5, -1.0 ],
"meshes" : [ "meshWithOpaqueMaterial" ]
},
"node1" : {
"translation" : [ -0.5, -0.1, -0.99 ],
"meshes" : [ "meshWithSemiOpaqueMaterial0" ]
},
"node2" : {
"translation" : [ -0.4, -0.2, -0.98 ],
"meshes" : [ "meshWithSemiOpaqueMaterial25" ]
},
"node3" : {
"translation" : [ -0.3, -0.3, -0.97 ],
"meshes" : [ "meshWithSemiOpaqueMaterial50" ]
},
"node4" : {
"translation" : [ -0.2, -0.4, -0.96 ],
"meshes" : [ "meshWithSemiOpaqueMaterial75" ]
},
"node5" : {
"translation" : [ -0.1, -0.5, -0.95 ],
"meshes" : [ "meshWithSemiOpaqueMaterial100" ]
}
},
"meshes" : {
"meshWithOpaqueMaterial" : {
"primitives" : [ {
"attributes" : {
"POSITION" : "positionsAccessor",
"NORMAL" : "normalsAccessor",
"TEXCOORD_0" : "texCoordsAccessor"
},
"indices" : "indicesAccessor",
"material" : "opaqueMaterial"
} ]
},
"meshWithSemiOpaqueMaterial0" : {
"primitives" : [ {
"attributes" : {
"POSITION" : "positionsAccessor",
"NORMAL" : "normalsAccessor",
"TEXCOORD_0" : "texCoordsAccessor"
},
"indices" : "indicesAccessor",
"material" : "semiOpaqueMaterial0"
} ]
},
"meshWithSemiOpaqueMaterial25" : {
"primitives" : [ {
"attributes" : {
"POSITION" : "positionsAccessor",
"NORMAL" : "normalsAccessor",
"TEXCOORD_0" : "texCoordsAccessor"
},
"indices" : "indicesAccessor",
"material" : "semiOpaqueMaterial25"
} ]
},
"meshWithSemiOpaqueMaterial50" : {
"primitives" : [ {
"attributes" : {
"POSITION" : "positionsAccessor",
"NORMAL" : "normalsAccessor",
"TEXCOORD_0" : "texCoordsAccessor"
},
"indices" : "indicesAccessor",
"material" : "semiOpaqueMaterial50"
} ]
},
"meshWithSemiOpaqueMaterial75" : {
"primitives" : [ {
"attributes" : {
"POSITION" : "positionsAccessor",
"NORMAL" : "normalsAccessor",
"TEXCOORD_0" : "texCoordsAccessor"
},
"indices" : "indicesAccessor",
"material" : "semiOpaqueMaterial75"
} ]
},
"meshWithSemiOpaqueMaterial100" : {
"primitives" : [ {
"attributes" : {
"POSITION" : "positionsAccessor",
"NORMAL" : "normalsAccessor",
"TEXCOORD_0" : "texCoordsAccessor"
},
"indices" : "indicesAccessor",
"material" : "semiOpaqueMaterial100"
} ]
}
},
"materials" : {
"opaqueMaterial" : {
"technique" : "opaqueTechnique",
"values": {
"diffuseParameter": [ 1.0, 0.0, 0.0, 1.0 ]
}
},
"semiOpaqueMaterial0" : {
"technique" : "semiOpaqueTechnique",
"values": {
"opacityParameter" : [ 0.0 ],
"diffuseParameter": [ 0.0, 0.0, 1.0, 1.0 ]
}
},
"semiOpaqueMaterial25" : {
"technique" : "semiOpaqueTechnique",
"values": {
"opacityParameter" : [ 0.25 ],
"diffuseParameter": [ 0.0, 0.0, 1.0, 1.0 ]
}
},
"semiOpaqueMaterial50" : {
"technique" : "semiOpaqueTechnique",
"values": {
"opacityParameter" : [ 0.50 ],
"diffuseParameter": [ 0.0, 0.0, 1.0, 1.0 ]
}
},
"semiOpaqueMaterial75" : {
"technique" : "semiOpaqueTechnique",
"values": {
"opacityParameter" : [ 0.75 ],
"diffuseParameter": [ 0.0, 0.0, 1.0, 1.0 ]
}
},
"semiOpaqueMaterial100" : {
"technique" : "semiOpaqueTechnique",
"values": {
"opacityParameter" : [ 1.0 ],
"diffuseParameter": [ 0.0, 0.0, 1.0, 1.0 ]
}
}
},
"techniques": {
"opaqueTechnique": {
"program": "opacityProgram",
"attributes": {
"a_position": "positionParameter",
"a_normal": "normalParameter"
},
"uniforms": {
"u_modelViewMatrix": "modelViewMatrixParameter",
"u_normalMatrix": "normalMatrixParameter",
"u_projectionMatrix": "projectionMatrixParameter",
"u_ambient": "ambientParameter",
"u_diffuse": "diffuseParameter",
"u_specular": "specularParameter",
"u_shininess": "shininessParameter",
"u_opacity": "opacityParameter"
},
"parameters": {
"positionParameter" : {
"type": 35665,
"semantic": "POSITION"
},
"normalParameter" : {
"type": 35665,
"semantic": "NORMAL"
},
"modelViewMatrixParameter": {
"type": 35676,
"semantic": "MODELVIEW"
},
"normalMatrixParameter": {
"type": 35675,
"semantic": "MODELVIEWINVERSETRANSPOSE"
},
"projectionMatrixParameter": {
"type": 35676,
"semantic": "PROJECTION"
},
"ambientParameter": {
"type": 35666,
"value": [ 0.1, 0.1, 0.1, 1.0 ]
},
"diffuseParameter": {
"type": 35666,
"value": [ 1.0, 1.0, 1.0, 1.0 ]
},
"specularParameter": {
"type": 35666,
"value": [ 1.0, 1.0, 1.0, 1.0 ]
},
"shininessParameter": {
"type": 5126,
"value": [ 100.0 ]
},
"opacityParameter": {
"type": 5126,
"value": [ 1.0 ]
}
},
"states": {
"enable": [ 2929 ]
}
},
"semiOpaqueTechnique": {
"program": "opacityProgram",
"attributes": {
"a_position": "positionParameter",
"a_normal": "normalParameter"
},
"uniforms": {
"u_modelViewMatrix": "modelViewMatrixParameter",
"u_normalMatrix": "normalMatrixParameter",
"u_projectionMatrix": "projectionMatrixParameter",
"u_ambient": "ambientParameter",
"u_diffuse": "diffuseParameter",
"u_specular": "specularParameter",
"u_shininess": "shininessParameter",
"u_opacity": "opacityParameter"
},
"parameters": {
"positionParameter" : {
"type": 35665,
"semantic": "POSITION"
},
"normalParameter" : {
"type": 35665,
"semantic": "NORMAL"
},
"modelViewMatrixParameter": {
"type": 35676,
"semantic": "MODELVIEW"
},
"normalMatrixParameter": {
"type": 35675,
"semantic": "MODELVIEWINVERSETRANSPOSE"
},
"projectionMatrixParameter": {
"type": 35676,
"semantic": "PROJECTION"
},
"ambientParameter": {
"type": 35666,
"value": [ 0.1, 0.1, 0.1, 1.0 ]
},
"diffuseParameter": {
"type": 35666,
"value": [ 1.0, 1.0, 1.0, 1.0 ]
},
"specularParameter": {
"type": 35666,
"value": [ 1.0, 1.0, 1.0, 1.0 ]
},
"shininessParameter": {
"type": 5126,
"value": [ 100.0 ]
},
"opacityParameter": {
"type": 5126,
"value": [ 0.5 ]
}
},
"states": {
"enable": [ 2929, 3042 ],
"functions": {
"blendEquationSeparate": [ 32774, 32774 ],
"blendFuncSeparate": [ 1, 771, 1, 771],
"depthMask": [false]
}
}
}
},
"programs": {
"opacityProgram": {
"vertexShader": "opacityVertexShader",
"fragmentShader": "opacityFragmentShader",
"attributes": [
"a_position",
"a_normal"
]
}
},
"shaders": {
"opacityVertexShader": {
"type": 35633,
"uri": "opacity.vert"
},
"opacityFragmentShader": {
"type": 35632,
"uri": "opacity.frag"
}
},
"buffers" : {
"buffer0" : {
"uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/",
"byteLength" : 108
}
},
"bufferViews" : {
"indicesBufferView" : {
"buffer" : "buffer0",
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
"attributesBufferView" : {
"buffer" : "buffer0",
"byteOffset" : 6,
"byteLength" : 96,
"target" : 34962
}
},
"accessors" : {
"indicesAccessor" : {
"bufferView" : "indicesBufferView",
"byteOffset" : 0,
"componentType" : 5123,
"count" : 3,
"type" : "SCALAR",
"max" : [ 2.0 ],
"min" : [ 0.0 ]
},
"positionsAccessor" : {
"bufferView" : "attributesBufferView",
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
},
"normalsAccessor" : {
"bufferView" : "attributesBufferView",
"byteOffset" : 36,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 0.0, 0.0, 1.0 ],
"min" : [ 0.0, 0.0, 1.0 ]
},
"texCoordsAccessor" : {
"bufferView" : "attributesBufferView",
"byteOffset" : 72,
"componentType" : 5126,
"count" : 3,
"type" : "VEC2",
"max" : [ 1.0, 1.0 ],
"min" : [ 0.0, 0.0 ]
}
},
"asset" : {
"version" : "1.1"
}
}