Skip to content
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

Pluggable Tone Mapping Operators (their own class that injects GLSL) #26661

Closed
bhouston opened this issue Aug 28, 2023 · 9 comments
Closed

Pluggable Tone Mapping Operators (their own class that injects GLSL) #26661

bhouston opened this issue Aug 28, 2023 · 9 comments

Comments

@bhouston
Copy link
Contributor

Description

Since we introduced tone mapping, we have usually done it via a set of enums which triggered fixed function tone map operators in the core Three.js code.

As tone mapping matures there are more and more tone mapping operators. This hard coding of our "preferred tone mapping" methods is getting a bit cumbersome.

Solution

Instead, why don't we refactor the tone mapping operators to be their own classes. And you can then allow others to define their own tone mappers how ever they want. In the end, the tone map operator just gives a chunk of GLSL code that can be inserted into a shader.

We can still keep the old hard coded interface, we can just add one more type called "Pluggable" or "custom" and then you can plug in your own. the underlying code behind the hard coded enums can still use the new pluggable system as well, thus avoiding duplicated code.

Alternatives

The alternative is just to add more hard coded tone mappers, but at some point that stops scaling well.

Additional context

I was suggesting this as we look to add AgX to Three.js.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Aug 28, 2023

+1. It would be great to be able to import a tone mapper from three/addons and tree-shake the rest, even if the current tone mappers are quite small. Making it easier for users to define custom tone mapping would be a good thing. And this should give us more flexibility to work on tone mapping in wide gamut or HDR color spaces.

@sunag
Copy link
Collaborator

sunag commented Aug 28, 2023

I imagine this is not related to the new architecture that is under development, there we added this feature:

renderer.toneMappingNode = toneMapping( THREE.LinearToneMapping, 1 );

@bhouston
Copy link
Contributor Author

@sunag nice! That is exactly the same solution. Great minds thing alike! So WebGPU has support for it.

Maybe we should try to back port it to WebGL? WebGPU isn't going to be feasible for some time as is still hovering around 50% support: https://web3dsurvey.com/webgpu

@sunag
Copy link
Collaborator

sunag commented Aug 28, 2023

We are creating a fallback - WebGLBackend #26581, the new architecture can work on both backend, our goal is to preserve backwards compatibility, this may still take a while to get fully ready.

@WestLangley
Copy link
Collaborator

three.js already supports Custom Tonemapping via code injection. See https://threejs.org/examples/webgl_tonemapping.html.

Granted, a plug-in API would be better.

In fact we could use it it now -- independent of WebGPU support -- as we investigate supporting wide-gamut and/or HDR displays.

@bhouston
Copy link
Contributor Author

The current solutions are good enough.

@hybridherbst
Copy link
Contributor

@bhouston did you end up implementing AgX somewhere? I've done a pass too but not too happy with the resulting colors so would be great to see if your implementation is closer.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Oct 26, 2023

@hybridherbst I have an early implementation here:

https://glitch.com/edit/#!/three-sb2383

Wait a moment and it will load, showing an OpenEXR image with AgX tone mapping applied. The file selection input will let you choose a .glb model to preview.

My implementation could be improved (1) for performance by using a piece-wise linear function to approximate the sigmoid contrast curve instead of a LUT, and (2) visually by adding support for the 'punchy' and 'golden' looks. Both are implemented in Filament, for example:

@donmccurdy
Copy link
Collaborator

Continuing AgX discussion in a new thread:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants