-
-
Notifications
You must be signed in to change notification settings - Fork 35.3k
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 WebGLDepthPrepass #8676
added WebGLDepthPrepass #8676
Conversation
Hmm... I'm not sure this should be part of the renderer. Currently this can be done at the app level, right? |
As far as I understand if the one decides to try it from app level using renderer.render() he has to do the following before depth pass:
and the following before main pass:
After doing that you still get potentially major overhead from updating camera matrix and doing frustum culling twice. I've noticed there is an object.frustumCulled property but couldn't find an obvious way to set it only for objects, culled in a first pass. From my perspective doing this from app is not user friendly (even if there were no overheads). Having complex scene the one could want to check if depth prepass would give him performance boost without spending time in renderer code. And it is probably not worth trying due to extra frustum culling cost. Sorry if I missed something. |
Hmm, I think I didn't understood exactly how this works. As far as I understand, you're pre-rendering the opaque objects using the depth material (similar code to How does this improve performance? |
Right, it was something like that. Now I'm not sure that this optimization should be in core since it complicates code base and is very situational, that is why I closed PR. If someone needs this optimization he indeed could tinker it in renderer or at app level (with some overhead). However, performance boost from depth prepass comes in case of "complex per-fragment computations in a scene, where effective objects sorting couldn't be performed". It makes sure that unneeded computations in fragment shader wouldn't be performed for opaque objects (like with early z-test, which is not guaranteed) at cost of extra render pass with depth materials. |
@WestLangley @mrdoob This was actually a really good idea. Depth-prepasses are used by all modern games, such as Doom, Metal Gear Solid V, etc. |
I think we just need more context. What would be a use case for a core material to use this? |
The idea is that before you render your opaque beauty pass (which is costly on a per-pixel basis) , you render the depth pre-pass, which is a fast to run material and it just fills the z-buffer. Then when you run the opaque beauty pass, no pixels that are hidden are every written because you have pre-populated the z-buffer. You need to render the beauty pass with EQUAL rather than LESS THAN, but given you are just re-rendering the same faces with the same values, it will not produce artifacts/z-fighting. This is useful when there is lots of complex geometry that leads to costly overdraw. If you just have a single sphere, this doesn't help. But if you have lots of complex large shapes that hide each other (think indoors with walls, etc), this can save between 30% to 50% of beauty pixel computations. |
I think this can be implemented as a DepthPrePass in the composer maybe. Rather than the way it was in this specific PR. |
Ah, I see. Yeah, for objects with a lot of "self overdraw".
Indeed. It seems simple enough though. I think it's more of a matter of repurposing the ShadowMap code instead of duplicating. |
Related #13858 |
There was a post on the forum related to selectively performing a depth prepass for helping to alleviate transparent object artifacts here which would be nice to support with a material flag: It also occurred to me that a simple version of a scene depth prepass could be achieved by rendering all opaque objects beforehand with Basically this would boil down to reusing the vertex shader that's already on the object material so even custom user shaders that manipulate a materials vertices would work with it. It would be possible to create more optimal prepass materials that don't calculate things like normals in the vertex shader but I believe depth prepass is most useful for fragment-bound cases anyway? |
@mlknz Can you please update this PR? |
@LeviPesin I think with also these years passed it should be easier to write new PR from scratch. |
Seems like #20673 is a good working alternative. |
THREE.WebGLDepthPrepass renders opaque objects depth before main render pass.
It could speed up rendering in certain scenarios ( complex per-fragment computations in a scene, where effective objects sorting couldn't be performed ). Here is a simple example scene to demonstrate speed-up: https://jsfiddle.net/mlkn/fd6mg4kr ( might have to resize a canvas until FPS drops ).
Currently interface is: renderer.depthPrepass.enable() / renderer.depthPrepass.disable() .
Notes: object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ) is performed twice (in depth pass and in main pass).
renderer.info now just doubles its values with DepthPrepass enabled. If this feature is going to be merged, I suppose it makes sense to extend renderer.info.