-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
Examples: webgl_loader_gltf_transmission issues #22009
Comments
I think that displaying transmissive materials (as defined by Similarly, I believe I'm seeing (1) in https://sandbox.babylonjs.com/ and https://github.khronos.org/glTF-Sample-Viewer-Release/, with reflections only from the nearest transmission material. Adding (2) and (3) requires techniques like depth peeling; see comment by @MiiBond in #16977 (comment). This would certainly be a welcome addition, but we'd want the flexibility to configure the number of layers, or disable that entirely for performance. |
Fixed ac6d30a |
Worth noting that this would only work in WebGL2 as we do need mipmaps. |
Another problem with the current transmission code is that it "breaks" in transparent contexts. Here I'm setting /cc @elalish |
I consider this pretty important. The DOM uses transparency pretty extensively which is why model-viewer uses alpha: true. This way DOM backgrounds and gradients and such fit nicely into the scene and the 3D doesn't have to look like a rectangle. Of course this is non-physical, so we'll need some kind of simple approximation. I'm hoping we can just get the shader to set the alpha to whatever the transmission % of the pixel was, though we'll have to be careful to keep it opaque if it was already drawn to by something opaque. It won't blur the DOM background, but I think that's fine, and more or less in line with not seeing transparent objects through each other. |
Hello @takahirox, Thanks for the PR! I found that current example has gaps if look from a side view or back view: |
@takahirox Any ideas? |
Unfortunately I currently have lack of time to tackle this problem.
This guess sounds right to me. The ray is calculated in src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js I'm happy if anyone can help the investigation in the details. Update: The model looks fine if |
I've made a model that shows the issue: TransmissionThickness.gltf.zip
|
@UX3D-eckerlein Any ideas of what we got wrong? |
@whatisor Is this something you dealt with in your implementation? |
Thank you for fixing the shader. I tried again with the latest version of the library. Looks good.
|
Hi @mrdoob @donmccurdy, Would it be possible to get an idea or pointer in the right direction with regards to getting the alpha blend materials to show through transmission / volume? I am pretty much new to three js and would appreciate some help. |
@rohan-percept sorry, I don't have pointers to get things started on (2) or (3). |
Related: #23448 |
I'm not sure if (3) "transmission through transmission" necessarily requires depth peeling. Another approach would be to copy render contents to a secondary transmission target sources while rendering the transmission material meshes back to front. This would be a bit more limiting (transmission from the same mesh couldn't be seen through the other) but it should work on the above glasses model if the side pieces are separate meshes and I'd think be more performant than depth peeling. The down side is that it would require another render target and render target copies. Consider the following case with three transmissive meshes sorted back to front A, B, C:
This is is a rough algorithm, at least. Not sure how how intensive a full target copy would be but maybe it's a starting point. Do we know what Babylon is doing? Depth peeling is definitely a nice option but definitely expensive and I think a big first step would be getting the ability to use custom and change depth textures on render targets would be a big first step for that (#19554) |
I think we could achieve something decent by doing:
Hmm, now that we're moving into WebGL2... Sooner or later we'll have to investigate rendering everything into a multisampled RT in linear and copying the RT into the framebuffer while applying gamma and tonemapping. Although I think @Mugen87 tried this recently and it was slower than the current setup. |
I don't know if this is going to have all that great of an effect and probably wouldn't work well on the sun glasses example above. If backfaces are rendered first and used for transmission when rendering front faces then every frontface transmission fragment is effectively going to have the transmission tint doubly applied (once for backside, once for frontside). And with refraction you'll probably get artifacts at the edges of the mesh when the refracted sample doesn't line up with the back face mesh edges. And if only backfaces are used in the transmission then continuity of things like the top highlight caused by the front ridge of glasses side piece will be lost: Might be worth trying out I just expect there to be more issues than you might expect. |
Correct. Applying gamma and tone mapping in an additional render pass was noticeably slower than doing it inline. In certain examples, performance dropped from 60 to 40 FPS when using a FP32 render target, see #23019 (comment). |
Most of the issues raised in the original post have been addressed, so I think it is OK to close this now. |
Reposting #21000 (comment) so as to consolidate some remaining issues.
webgl_loader_gltf_transmission
has thetransparent
property of each sphere to set tofalse
. Is that what the loader should be doing? What shouldtransparent
be set to whentransmission
is non-zero?After setting
transparent
totrue
, only front-faces show the hot-spot. (This may be a known limitation, but @mrdoob just added support for properly rendering back-faces of double-sided meshes.) There should be two hot-spots.FIXED: This is caused by issue 7. below.FIXED Also, in Chrome and Firefox (not Safari)Transmission always sets theUSE_UV
flag.FIXED: If performant, I think the dimensions of the "transmission render target" should match the dimensions of the "current render target".Doing so will prevent artifacts like the following:FIXED In the following code snippet,transmissionFactor
is applied togetIBLVolumeRefraction()
twice. I expect that is a physical modeling error.three.js/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js
Lines 23 to 28 in dd6ab3c
FIXED Also in the above snippet,totalSpecular
has units of radiance, and therefore cannot be the correct argument because the function expects a unit-less quantity. A reasonable guess would bematerial.specularColor
, instead./ping @takahirox @donmccurdy
The text was updated successfully, but these errors were encountered: