When I enable OIT through scene.useOrderIndependentTransparency = true;, the edges of translucent triangles are visible.
They are not visible if OIT is disabled.
Any idea?
Hi, thanks for the answer and sorry for the delay. Indeed, at the exact location of the edges bug, there are two meshes at the exact same depth.
But in the playground and in my Babylon.js v5.0.0 locally, I do not reproduce the issue (even without moving the meshes to have different depthâŚ) So I donât really know what happened here.
However, I found what it looks like a bug when using OIT : in my code I :
Activate OIT
append a glTF file as a file containing semi-transparent textures
Clear the mesh using mesh.dispose()
Add another mesh using Append
Then, if OIT is activated, all the textures that are semi-transparent are not cleared and remains in the scene. Even if I clear all the scene by iterating over scene.meshes, the semi-transparent textures are not cleared. This issue is not here if I disable OIT. Do you have any ideas ?
I am trying to reproduce the issue in the playground
Sorry for ugly code, but the issue is here. If you disable oit it works, but if you enable it, you notice that the transparent textures stay at the same location on the screen. It looks like we are not flushing the dual-depth peeling framebuffers or something like that !
I managed to run Spectorjs on this one, showing that even the first draw call is showing these black edge artifacts, so I donât think itâs related to two meshes at the same location:
@CraigFeldspar My guess on the issue: my glTF doesnât have tangents attribute, so the TBN matrix is computed using dFdx and dFdy. However, the derivatives must be called unconditionally, and it seems that the shader can return before cotangent_frame which uses the derivatives.
@sebavan@CraigFeldspar any update?
I was able to confirm that the bug isnât visible when my glTF file includes tangents, so itâs definitely related to cotangent_frame being called after the potential return resulting in undefined derivatives.
The expression inside the inverse square root can be sometimes 0, so the inverse op breaks the shading of the pixel.
I was able to have a correct shading by safeguarding the value : float invmax = inversesqrt(max(0.00001, max(dot(tangent, tangent), dot(bitangent, bitangent))));
I really donât like this solution though.
@sebavan@Evgeni_Popov would you happen to know in what case dFdx(p) would return 0 ? This op is related to the neighbouring fragments, so something may happen there.
Btw I tried to move the OIT part that was returning before the use of derivatives, as @Michael suggested, and it has no effect Maybe we need to find a way to avoid this branching at all ?