three.js icon indicating copy to clipboard operation
three.js copied to clipboard

Add envMapIntensityNode for node materials in WebGLRenderer

Open TobiasNoell opened this issue 2 years ago • 5 comments

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.

TobiasNoell avatar Nov 09 '23 08:11 TobiasNoell

@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. 👍

TobiasNoell avatar Nov 09 '23 08:11 TobiasNoell

📦 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

github-actions[bot] avatar Nov 09 '23 08:11 github-actions[bot]

@sunag @Mugen87 @WestLangley After the extended discussions above and adaptions to the code, is there any chance this gets merged?

TobiasNoell avatar Jan 02 '24 07:01 TobiasNoell

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.

WestLangley avatar Jan 04 '24 03:01 WestLangley

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));

TobiasNoell avatar Jan 04 '24 08:01 TobiasNoell

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?

Mugen87 avatar Apr 17 '24 09:04 Mugen87

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?

TobiasNoell avatar Apr 17 '24 09:04 TobiasNoell

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.

Mugen87 avatar Apr 17 '24 10:04 Mugen87

@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.

sunag avatar Apr 18 '24 14:04 sunag

@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).

donmccurdy avatar May 04 '24 01:05 donmccurdy

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.

Mugen87 avatar May 04 '24 08:05 Mugen87