I am trying to convert a MeshStandardMaterial to a MeshStandardNodeMaterial. I have loaded an envMap using THREE.CubeTextureLoader and saved the result as scene.background = envMap.
Here is the original material:
Mat = new THREE.MeshStandardMaterial({
color: difCol,
metalness: 1.0,
roughness: 0.7,
normalMap: nrmMap,
normalScale: new THREE.Vector2(2.5,2.5),
envMap: envMap,
envMapIntensity: 4,
premultipliedAlpha: true,
});
Here is the NodeTexture, so far:
Mat = new MeshStandardNodeMaterial({
colorNode: color(difCol),
metalnessNode: float(1.0),
roughnessNode: float(0.7),
normalNode: normalMap(texture(nrmMap),vec2(2.5,2.5)),
});
Is there a Node equivalent for the envMap and envMapIntensity properties?
This example, indicates that you can make the material reflect the envMap by adding scene.environment = envMap;
However, it would seem that there should be a NodeMaterial definition - otherwise all materials would reflect. Also the resulting texture is darker, likely because something like the envMapIntensity is needed to make the lighter environment color mix more with the darker material color.
ALMOST THERE (30 Mar 2024)
A method for creating a Skybox reflection was apparently in the example program:
webgl_nodes_materials_instance_uniform
This program contains a little Class-type extender called InstanceUniformNode, which you should add to your program.
Before defining the material, add these lines:
let instanceUniform = nodeObject(new InstanceUniformNode());
let cubeTextureNode = cubeTexture(cubeMap);
where cubeMap is the address of your Skybox
Within your material definitions, add this line:
colorNode: instanceUniform.add(cubeTextureNode),
Finally, after using the material to create your mesh, add:
mesh.color = new THREE.Color(color);
(This last step is important since that is the color that is mixed with the reflection.)
The example program also contains material definitions for the emissiveNode, but these are apparently not necessary and might prevent your material from reflecting lights.
Another option is to simply ignore all of the above and use this colorNode definition:
colorNode: cubeTexture(cubeMap),
However, with this method, you can’t change the base color of the material.
The only remaining problem is that, while the InstanceUniformNode solution creates a mirror reflection of the Skybox, I cannot figure out how to mix the base color (or a colored texture) with the reflection. There is apparently no Node-equivalent command for envMapIntensity.
[Edit} Or perhaps there is a command that allows you to control the “mix” of the reflection and the color or texture. The color definition indicates that it is adding the reflection to the color.
EDIT - AN UNEXPECTED TWIST (31 Mar 2024)
In searching for something that would allow me to mix colors, I ran across this example program:
webgpu_cubemap_dynamic.html
Although it is a webgpu program, it provided some interesting information about nodes and shows how to change the intensity of the reflection. However, in doing so, it took me right back to where I started by showing that there is an envMap node and an envMapIntensity node - which took me back to where I had started.
One of the material definitions was:
const material2 = new Nodes.MeshStandardNodeMaterial( {
map: uvTexture,
roughness: 0.1,
metalness: 0,
envMap: texture,
} );
where uvTexture is a texture and texture is the cubeMap texture.
This was a bit surprising in that it did not use the same variable definitions, such as float and texture(). Nor are there references to Nodes, such as roughnessNode, metalnessNode and envMapNode. Through trial and error, I was able to get the following combination of commands to work:
Mat = new MeshStandardNodeMaterial( {
colorNode: color(color2),
map: grd_.Dif, // Diffuse map
metalness: 0.5,
roughness: 0.1,
roughnessMap: grd_.Ruf, // Roughness map
normalMap: wav_.Nrm, // Animated normal map
positionNode: positionLocal.add(texture(wav_.Dsp)), // Animated displacement map
envMap: cubeMap,
envMapIntensity: 1,
} );
Note that this uses normalMap, rather than normalNode. And for some reason, the envMap and envMapIntensity which did not seem to work before are now working fine. It uses different inputs than my original version, but I think the result is looks better than the original.
One problem is that there are visible seams between adjoining displacement maps, but that is a problem for another post.
I realize that this has turned into a long post, but it does show a couple of ways to add cubeMap reflections to your texture, so I will leave it as is until I find out which answer is best.