three.js
three.js copied to clipboard
Add envMapIntensityNode for node materials in WebGLRenderer
Related issue: #27141
Description
ThreeJS already supports scaling the effect of the environment map by the envMapIntensity property of a material.
For the node materials, it would be very handy to also have a envMapIntensityNode property available to setup more complex intensity values rather than just a single float value.
While a similar effect can already be achieved by material.envNode = cubeTexture( myCubeTexture ).mul( intensity ); for the WebGPURenderer, the WebGLRenderer currently only supports setting the environment via scene.environment = texture;, i.e. all materials share one common environment map.
For some use-cases it is desirable to scale the intensity of the environment map for each material individually.
It is already possible to do this via material.envMapIntensity = 0.5;. However, this allows to only set static values. For the node materials, it would be really good to have a envMapIntensityNode parameter which allows more sophisticated node based settings. For example material.envMapIntensityNode = THREENodes.pow(material.roughnessNode, THREENodes.float(4.0)); to let the environment map only contribute to the really mirroring parts of a surface.
@sunag: I tried to also add the functionality in a meaningful way to WebGPU using a multiplication of the envMap. Happy to get some feedback.
P.S: I understand that WebGPU is the "new" thing and ultimately everything will shift towards it. But it would be really appreciated if we could still have the overall WebGL functionality kept more or less on par until this happens wherever this is possible. 👍
📦 Bundle size
Full ESM build, minified and gzipped.
Filesize dev |
Filesize PR | Diff |
|---|---|---|
| 668.7 kB (166 kB) | 668.8 kB (166 kB) | +161 B |
🌳 Bundle size after tree-shaking
Minimal build including a renderer, camera, empty scene, and dependencies.
Filesize dev |
Filesize PR | Diff |
|---|---|---|
| 449.8 kB (108.9 kB) | 449.9 kB (108.9 kB) | +161 B |
@sunag @Mugen87 @WestLangley After the extended discussions above and adaptions to the code, is there any chance this gets merged?
It should be mentioned that also with the classical materials it is already possible to do this by setting material1.envMapIntensity = 0.5 and material2.envMapIntensity = 2.0 (i.e. different scaling factors per material).
That seems to me to be the natural solution for your use case. I am curious as to why that is not acceptable to you.
That seems to me to be the natural solution for your use case. I am curious as to why that is not acceptable to you.
I want to scale the material.envMapIntensity according to the roughness of the material. However, the roughness is not a single scalar value but a map itself (i.e. an arbitrary material.roughnessNode).
Thus I'd need something like:
material.envMapIntensityNode = THREENodes.pow(material.roughnessNode, THREENodes.float(4.0));
I think your use case is too specific that it justifies a modification of WebGLRenderer.
Fortunately, you can achieve your requirements with WebGPURenderer. It will be normal that certain features will only be available with the new renderer and its node material. Also keep in mind that renderers/webgl-legacy/nodes/ is already deprecated as the name implies.
@sunag I feel the time is right to remove renderers/webgl-legacy now. Are you okay with that step?
That's fine, I don't have any particular interest of this being merged anymore because I already forked Three.
Is there some documentation how node materials can be used with the WebGPURenderer?
To me as a user it is a bit unclear what is the future proof way how Three should be used, which methodology is currently replaced by which and why 😄
A migration guide from WebGL to WebGPU would be a prerequisite IMO before stuff is removed. Also there are devices that still do not support WebGPU and require WebGL, so Three will stop working on these?
WebGPURenderer has a WebGL backend so if WebGPU isn't available on a device, it will fallback to WebGL 2.
Regarding the documentation, expect more to see in this regard during this year. WebGPURenderer gradually matures and at a certain point we will add documentation and migrating more examples to WebGPURenderer.
@sunag I feel the time is right to remove renderers/webgl-legacy now. Are you okay with that step?
@Mugen87 For me ok, I will take care of this removal.
@Mugen87 to clarify – are we removing support for node-based materials in WebGL? or is the idea that we can use node-based materials with WebGPURenderer, and WebGPURenderer will fall back to WebGL2 while still supporting those node-based materials (with some limitations).
or is the idea that we can use node-based materials with WebGPURenderer, and WebGPURenderer will fall back to WebGL2 while still supporting those node-based materials (with some limitations).
Yes, that is the plan.
Part of the discussion above mentioned the legacy node support for WebGLRenderer which has been removed with r164 in the meanwhile.