Feature: Add transmissionFactor to Materials

When rendering a transparent object in THREE the specular highlight fades along with the diffuse surface of the material. I’d expect it retain the same brightness considering specular is supposed to be more of a mirror like reflection. Here’s a picture of a sphere with the Standard material in THREE:


metalness: 0, roughness: 0.3, opacity: 0.15

And here’s what a similar sphere looks like in Unity, which is more what I’d expect:


metallic: 0, smoothness: 0.8, opacity: 11 / 255

As an aside I’m a bit surprised by the difference in darkness of the transparent objects between THREE and Unity. The THREE material has an opacity of 0.15 while the Unity material has an opacity of 0.043 (11 / 255) and yet they look the same. Switching Unity’s color space from Linear to Gamma makes the results look more similar with the same with the same opacity. Is this a limitation of blending in the current WebGL APIs?


Author: Fantashit

3 thoughts on “Feature: Add transmissionFactor to Materials

  1. Sorry for jumping around a bit — I think I understand a bit more of what’s going on now and I see that setting premultipliedAlpha to true does make things look more correct. However it’s still surprising to me that the opacity of the material affects the specular highlight instead of just the diffuse color. This means that even when premultipliedAlpha is true if the material has an opacity of 0 then nothing will render.

    In Unity, though, the specular highlight is unaffected by the opacity. See a comparison here of a material with 0 and 100%% opacity:


    I see that the alpha multiplication happens as the very last step of the shader, meaning the specular (and every other effect) is already included in the color that is multiplied by the alpha. Instead shouldn’t only the diffuse component be multiplied by the opacity? For example, the phong shader might look like this with no further alpha multiplication.

    vec3 outgoingLight =
        reflectedLight.directDiffuse * diffuseColor.a +
        reflectedLight.indirectDiffuse * diffuseColor.a +
        reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
    // ...
    gl_FragColor = vec4( outgoingLight, diffuseColor.a );

    Additionally it looks like the emissive value is also getting diluted by the materials opacity which doesn’t feel right, either.

  2. I do not take game engines as good material models, they are usually hacked in. I would look at Disney’s Physical Model from Burley, or V-Ray or Arnold — the guys who specialize in rendering and correctness.

    V-Ray defines opacity as “Opacity – Specifies how opaque or transparent the material is. A texture map can be assigned to this channel.” https://docs.chaosgroup.com/display/VRAYRHINO/VRay+Material+%%7C+VRayBRDF#VRayMaterial|VRayBRDF-Reflection

    The reason is that if you want to fade out an object, you want to fade out all aspects of an object. To do that you modify opacity. In V-Ray if you want to make the base layer transparent you modify “refraction” or if you want light to leak into the diffuse layer you set “translucency.”

    In Arnold they use the term “transmission” and this refers to the base layer transparency: https://docs.arnoldrenderer.com/display/A5AFMUG/Transmission

    Arnold discusses “Opacity” and “Transmission” in a way that I also think of it: “Opacity will also cut out the shape completely whereas Transmission will leave the reflections/speculars visible even on areas that are completely transparent.”


    So both V-Ray and Arnold view opacity as affecting both specular and diffuse layers and use other terms to refer to diffuse layer specific opacity (refraction for V-Ray, transmission for Arnold.)

  3. Regardless of whether glTF alpha affects specular, its alpha is not meant to approximate physical transparency.

    There’s a fair chance physical transparency will come in a more advanced PBR extension in the future, and if so I would expect transmission to be included separately from alpha – Adobe’s extension for their own web viewer is doing the same: https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Vendor/ADOBE_materials_thin_transparency/README.md

    I think adding transmission as a distinct thing from opacity, perhaps just on MeshPhysicalMaterial, would be reasonable.

Comments are closed.