Skip to content

Conversation

Mugen87
Copy link
Collaborator

@Mugen87 Mugen87 commented Aug 1, 2025

Related issue: -

Description

The PR introduces a new implementation for DepthOfFieldNode in order to fix open issues with the previous implementation. The approach is based on the id-Tech 6 DoF used in Doom (2016) and described in the linked articles (see JSDoc).

The new DepthOfFieldNode has a new parametrization that allows to configure a DOF effect more easily and correct. Besides, DepthOfFieldNode also uses a Bokeh blur now which produces a more correct optical lens blur which was not true with the previous approach.

I've looked at different techniques but decided for the Doom approach because it was manageable to implement with good results. The code lies the foundation (separate near and far field computation via MRT) for more complex approaches like "Circular Separable Convolution Depth of Field" from the Frostbite engine which could be added in the future.

There is one open issue that I marked as a TODO in the code: Compared to the original version, DepthOfFieldNode does not use the (artistic) Bokeh scale factor to modulate the blend factors for the final composite. During my tests, I have noticed this can cause very noticable blending artifacts when blurred foreground objects are blended with the background. I did not find a solution for mitigating these artifacts so I have not adapted this scaling which means fragments within the CoC range [0,1] are slightly less blurred like in the original. The effect still looks great imo.

For testing and comparison:

https://rawcdn.githack.com/Mugen87/three.js/305a70530ece85721966fee966b408d5d24cfb85/examples/webgpu_postprocessing_dof.html
https://threejs.org/examples/webgpu_postprocessing_dof

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Aug 1, 2025

Also note that DepthOfFieldNode is now a multi-pass approach producing a more correct lens blur quality. That means the effect is more taxing so mobile devices or performance restricted use cases should potentially go with the approach in webgpu_postprocessing_dof_basic.

On my macMini with M2Pro, webgpu_postprocessing_dof still runs at 60 FPS in 5k but on my Pixel 8a the frame rate drops to 48 FPS. So depending on the use case you want to pick a different DoF approach (similar situation like with AA techniques).

That said, more advanced DoF techniques like "Circular Separable Convolution Depth of Field" allow to implement the blur with a separable approach which could help to optimize the performance.

@sunag sunag added this to the r180 milestone Aug 1, 2025
@WestLangley
Copy link
Collaborator

Respectfully, I think the example scene obfuscates both your contribution and the feature you are trying to demonstrate.

How about a static scene with OrbitControls and no render loop?

Use the same scene in both your basic and advanced DOF examples. That way a user can clearly see the trade-offs.

If you prefer a performance metric as part of the example, add a GUI for controls.autoRotate, defaulting to false.

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Aug 1, 2025

The existing scene with the reflective spheres is actually very good for detecting artifacts when blending foreground objects into the background. I would not detect them with the scene from the basic example which I also modified locally (among others) to test the new effect. That's why I'd prefer to keep webgpu_postprocessing_dof as it is.

Although I agree introducing OrbitControls is an improvement. For debugging purposes, I would prefer an animation loop though. Updating the scene on-demand is a bit tedious, tbh.

It's also a good idea to enhance webgpu_postprocessing_dof_basic so you an switch between both techniques. However, I would like to implement this separately (the example should also be renamed then).

@WestLangley
Copy link
Collaborator

Introduction of OrbitControls helps a lot. Thanks.

And my comments are not to distract from your contribution, but can you stop the animation?

How can a user be expected to adjust the parameters via the GUI, while the animation continues to auto-adjust?

Plus the scene appears too dark to see the effect clearly. Is this done on purpose for some reason?

@mrdoob
Copy link
Owner

mrdoob commented Aug 1, 2025

Let's not worry about these details. I'll look for a better scene to demonstrate the effect next week 🙏

@Mugen87 Mugen87 merged commit 82b03f5 into mrdoob:dev Aug 2, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants