Can anyone tell me if this well known transparency stacking issue is solved when using the web GPU renderer?
I hate to generalize from a single example, but maybe so.
I have upgraded to WebGPU version r167 and am trying to add the excellent WebGPU smoke generator (from the three.js examples) and am having a serious case of deja vu. Sometimes the island is in front of the smoke and other times the smoke is (properly) emitting from the island. I re-ordered the smoke generator to the front of the object list and it helped a bit. Otherwise, it seems that this problem probably still exists in WebGPU.
I will see if I can create a small demo to illustrate.
There arenāt really any silver bullets for transparency afaik.
Alpha hash is great on higher res displays where the pixels are small enough that the hashing falls below a visual threshhold, and its great at reducing overdraw on High DPI, low power GPUs. (retina)
Itās also really great mixed with TAA where the TAA makes it work better at a lower cost than forward blending.
But the vast majority of threejs apps donāt use taa, and have to run on all devices⦠including chonky pixel devices.
The āidealā transparency depends on too many factors to declare one The Best.
-
forward transparency (aka the default): reasonably fast, suffers from overdraw/blending, basically requires sorting hacks to get ordering that looks good or disabling depthwrite and pretending transparent things donāt intersect each other. but fast and well understood. used everywhere.
-
hash - Fast⦠looks good on high dpi⦠on regular dpi displays, can look hashed.
-
hash+taa - fast transparency + overhead of TAA + taa artifacts/control
can look fantastic with the right setup -
depth peeling ā higher complexity⦠designed for accuracy⦠higher overdraw+blending ⦠only one full implementation for threejs that I am aware of @dubois
none of the above support ior/transmission except for:
-
MeshPhysicalMaterial+transmission⦠similar caveats to forward But additional overhead since it does multiple rendering passes, but can look amazing.
-
path tracing ā accurate but slow, super complex⦠a complete rendering pipeline probably mostly useful for high quality offline rendering imo
Damn, I was hoping that with webGPU, those issues would belong to the past.
Iāve never experienced the transparency bug in Sketchfab, do they have their own 3d engine, not based on webGL ?
Ima leave this implementation (live demo) and this discussion here.
If it wasnāt based on webGL I doubt it would run in a browser, at least without plugins of some sort, like flash used to be. Is the product you are referring to online? Like, on a webpage?
Let me leave a few links too,
Thread with demos:
Discussion for sharing stencil buffers, this is from 2018 (wow still open!!) not sure if things changed but thereās mention of depth textures. @gkjohnson is a collaborator I believe, maybe he can push it.
This was also proposed as an example, was stuck for a few years so I closed it:
I think that my demo is still the oldest, if any credit can be thrown my way it would be very much appreciated. I am having a really hard time proving that I know anything about threejs, and itās hard to put food on the table.
I was reffering to https://sketchfab.com , a popular 3D model viewer
Yeah, since no unity player, flash and such is needed to run sketchfab we can assume that they run on webGL, there simply isnāt another way to do this in the browser.
Iām facing issues with transparency and overlapping meshes similar to whatās being discussed here. But I didnāt find any solution which suits my case.
Iām gathering all the resources I found here for future reference and also for other users:
- wboit - three.js webgl - order independent transparency
- GanguLabs/three-wboit: Weighted, blended order independent transparency pass for use with three.js.
- three.js webgl - wboit - weighted, blended order-independent transparency
- Source code Repo: three.js-wboit/examples/webgl_transparency_wboit.html at wboit Ā· GanguLabs/three.js-wboit
- Source Code/PR - Examples: Add weighted, blended order-independent transparency pass / demo by stevinz Ā· Pull Request #24903 Ā· mrdoob/three.js (github.com)
- depth peel - three.js webgl - materials - depth peel (githack.com)
- alpha hashed transparency - three.js examples
- 40M cubes with individual opacity and color - Questions - three.js forum
- Need help making transparency show correctly in point cloud - Questions - three.js forum
- ios - How to avoid transparency overlap using OpenGL? - Stack Overflow
- darker intersects on transparent objects : r/threejs (reddit.com)
- Another solution is to render the object solid (no transparency) in a framebuffer and compose it into the final render with transparency. Youāll have to manage the scene differently for solid objects and for transparent objects
- InstancedMesh overlapping transparent ShaderMaterial issues - Questions - three.js forum (threejs.org)
- DoubleSide, transparent material produces artefacts between overlapping front and back faces Ā· Issue #2476 Ā· mrdoob/three.js (github.com)
- 3d - Whatās the simplest way to render overlapping transparent meshes in THREE.js? - Stack Overflow
- This post talks about a technique called Screen-Door Transparency (reference)
- transparency - artifacts when rendering both sides of a transparent object with three.js - Stack Overflow
- this posts suggests using 2 meshes with opposite sides -
material.side = THREE.BackSide
, andmaterial.side = THREE.FrontSide
- this posts suggests using 2 meshes with opposite sides -
- Overlapping, off-centred translucent objects? - Questions - three.js forum (threejs.org)
- three.js - Overlapping layers flickering
- Add alphas channel for instanced meshes. Update example. by Displee Ā· Pull Request #25211 Ā· mrdoob/three.js
after going through a lot of references and scratching my head for weeks, I was able to fix my issue with the method suggested here with a small change.
First of all, this solution is specific to my case where I have 3d grid of adjacent boxes.
Note that the faces exactly adjacent, the boxes donāt intersect/overlap with each other.
In my case with the default settings, the following screenshot is how it looks like without default souble-sided material & transparency.
And with below change this screenshot is how it looks like
Scale the mesh ever-so slightly to solve the z-fighting issue so that the faces donāt exactly overlap
const scale = boxDimensionVec.clone().multiplyScalar(0.99);
mesh.scale(scale)
use shader definitions to conditionally apply colors to only front-side of the mesh (as mentioned in the following github discussion)
void main() {
#ifdef FLIP_SIDED
gl_FragColor = vec4( 0, 0, 0, 0.0 );
#elif defined( DOUBLE_SIDED )
gl_FragColor = ( gl_FrontFacing ) ? vec4( 1, 0, 0, 0.5 ) : vec4( 0, 0, 0, 0.0 );
#else
gl_FragColor = vec4( 1, 0, 0, 0.5 );
#endif
}