-
-
Notifications
You must be signed in to change notification settings - Fork 35.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added transparency to StandardNodeMaterial #16996
Conversation
# Conflicts: # examples/webgl_materials_transparency.html # src/materials/MeshPhysicalMaterial.js # src/renderers/WebGLRenderer.js # src/renderers/shaders/ShaderLib.js
Thank you for contributing this! ❤️ I’m traveling this week, but would be happy to review it next week. |
src/renderers/shaders/ShaderChunk/transparency_pars_fragment.glsl.js
Outdated
Show resolved
Hide resolved
Agreed. The rendering is pretty, but I am unable to comprehend the model on which your changes are based. Do you have a reference for your modeling approach? |
Babylon has another solution. Live demo: https://www.babylonjs-playground.com/#19JGPR#13 Instead of having both |
Perhaps a better approach would be to create Related reading ADOBE_materials_thin_transparency. |
|
I appreciate the glTF paper you linked. This part happens to describes what I'm actually trying to do, which is mix the diffuse/specular based on the fresnel. This may have not been obvious, so I went back and cleaned up my code
|
Although I appreciate the elegance of Babylon's method, I support the Enterprise PBR model (see #16977), which allows for separate transparency/opacity values. |
@DanielSturk Thank you for the link to the Arnold doc. I think it explains quite well the justification for both transparency and opacity. The fact that such a detailed explanation is required leads me to believe the API was confusing to users, but I think the API is OK. I also support adding the feature you are trying to implement. I do not understand your physical modeling, however. Am I correct in guessing that this is something you developed on you own? If that is the case, I suggest you use This is my attempt to reverse-engineer your code. Is it accurate? vec3 fresnel = BRDF_Specular_GGX_Environment( ... );
float F = luminance( fresnel );
vec4 fragColor = ( 1 - F ) * vec4( diffuseRGB * ( 1 - T ), 1 - T ) + F * vec4( specularRGB, F );
fragColor.rgb /= fragColor.a;
return fragColor; |
@WestLangley Thanks for the help. I knew there was multiple ways of calculating luminescence but I didn't know we had a standard one in Three.JS, I'll add that in. As far as I can tell your code is correct (multiply diffuse by transparency, mix diffuse/specular using fresnel). Also your are correct that I "developed" it myself, in relation to the luminescence thing. After some sleuthing I found that Babylon does something similar, but it seems less physical/accurate than our method, because it looks like they are calculating specular alpha from the specular light (wouldn't this mean brighter highlights are more opaque? seems wrong) |
Just to clarify, it is not my code, it is a representation of your code. Unfortunately, I cannot understand any mathematical or physical justification for your equation. You are also dividing by Like I said, I support your efforts, but as of now, not the implementation. I do not have an alternate solution, however.
Yes, that is what they claim. I think their claim is an accurate one. Their solution is to increase the opacity of the specular highlights using some heuristic. |
The API surface related to alpha and transparency is becoming complex:
In particular, Note the distinct "alpha" and "transmission" sockets. My first, and simplest, suggestion would be that perhaps we should implement this only on NodeMaterial first, to buy some time to experiment with techniques and API. I'm nervous about the suggestion of a separate material type for physically-based transparency — Blender and glTF are both using a single ubermaterial. We've also discussed having an equivalent of dither temporal AA or alpha hashing, which would throw another complication into the existing material API but is easier with NodeMaterial's |
…erial # Conflicts: # src/renderers/shaders/ShaderChunk/transparency_pars_fragment.glsl.js
# Conflicts: # examples/jsm/nodes/materials/nodes/StandardNode.js # examples/webgl_materials_transparency.html
I'm totally satisfied with implementing this in the I don't have a solution for the names. It's already convoluted enough. That's one nice thing about node materials is having significantly less attributes (eg. alpha and transparency, but no .alphaMap, no .transparent (at the user level)) Also I don't see the point of adding yet another material, specifically for transparency. I think fewer materials is better |
@DanielSturk I found these changes great, this is exactly what I suggest here #16971 (comment), you can do this in To isolate this change completely of the Removing this of |
The model makes no mathematical sense and produces bizarre results. Here is what happens when the It should be clear. Please do not try to develop your own PBR shading models. Implement models you can reference elsewhere -- models that, at a minimum, are physically plausible. |
@WestLangley I didn't think that was the desired behavior, since currently (including with opacity), |
@DanielSturk Sorry, I do support your efforts, but I cannot support your model. Perhaps you can have a look at #17114 and try to break it. That is the only way I think we will be able to arrive at a model that is reasonably acceptable. |
Enhancing the node material should based on #17114 now. It's probably better to create a new PR for this. Closing. |
In an effort to align more with the Enterprise PBR model (#16977) I've implemented transparency (#15941).

Transparency differs from opacity in that transparency only hides the diffuse lighting (more physically accurate), whereas opacity completely fades the material (non-physical).
(taken from https://dassaultsystemes-technology.github.io/EnterprisePBRShadingModel/spec.md.html)
Admittedly, this is somewhat hacked in, and mostly serves as a proof of concept for accelerating the changes towards Enterprise PBR. I'll spend the remainder of this post explaining what should be changed.
The blending is straight forward: at the end of the fragment shader, opacity still affects the final alpha, but an additional 'transparency' term is added which only affects the opacity of the diffuse lighting. For example, when transparency=1, the only visible light is coming from the specular (see the above Enterprise PBR chart). Unfortunately, there is no alpha value pertaining to the specular stored at this point, so I must infer one by re-calculating the fresnel term, and dividing it out of the specular light.
The obvious change that must be made is that the F term of the DFG should never be included in the
directSpecular
orindirectSpecular
values, and it should only be calculated once at the end of the shader, where it is treated as the alpha term of the specular light.Unfortunately I am struggling to seperate the fresnel term, mainly due to the opaque environment BRDF (#7489). F can easily be factored out of
BRDF_Specular_GGX()
, but notBRDF_Specular_GGX_Environment()
orBRDF_Specular_Multiscattering_Environment()
.