Hi guys!
I’ve got a question about normalMap
and (I suppose) normalScale
too.
They gave me a render and they told me I should be able to decrease the size and repeat the normalMap
.
The texture applied to the normalMap
is a 1024x1024 jpg (it’s embed in the exported glb).
The result without changes:
I want to ask to you if it is possibile to reach this result working with the normalMap
parameters (the image below is same render but with a detailed texture embed in the glb file):
Any advice are precious!
Thanks in advance and kind regards,
Davide
I tried to add a new texture to the nomral map (2048x2048) and it works.
My question now is: how can I add a small image (521x512) as texture and repeat it to obtain the result above?
Look at repeat in the docs, is this what you’re after? three.js docs
Ps. I think normalScale is the amount of implied displacement above and below the surface that the material is on…
Hi!
Thanks I tried repeating the texture (form an image 256x256) but it doesn’t works as aspected, the texture looks zoomed in:
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 1, 1 );
mesh.material.normalMap = texture;
mesh.material.needsUpdate = true
and the results:
instead of
Thanks in advance and kind regards,
Davide
Have, you tried changing the repeat value size such as texture.repeat.set( 2, 2 );
@Lawrence3DPK hi yes I’ve tried with big values too.
If I do the same with the material map it works.
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 1, 1 );
mesh.material.map = texture; // material map
mesh.material.needsUpdate = true
Seems normalMap
works differently
read here… UV offset / repeat should be part of materials rather than textures · Issue #5876 · mrdoob/three.js · GitHub
an option may be to use a custom vertex shader with the required uv repeat on your normal uniform
texture.repeat.set( 1, 1 ); change map, aoMap, lightMap etc. Not separately.
Need to use “onbeforecompile” for changing fragment shader
1 Like
@Chaser_Code @Lawrence3DPK thanks for the suggestions! I check!
gave a nice day and kind regards,
Davide
Not good
mesh.material.onBeforeCompile=(shader)=>{
//console.log(shader.fragmentShader);
shader.fragmentShader=shader.fragmentShader.replace("#include <normal_fragment_maps>",
`#include <normal_fragment_maps>
normal=texture2D(normalMap,vUv*vec2(6.0,2.0)).xyz*2.0-1.0;`
)
};
1 Like
@Chaser_Code thanks! It works!
Better solution for default normal:
mesh.material.onBeforeCompile=(shader)=>{
//console.log(shader.fragmentShader);
shader.fragmentShader=shader.fragmentShader.replace("#include <normal_fragment_maps>",
`vec3 mapN=texture2D( normalMap, vUv*vec2(6.0,2.0) ).xyz * 2.0 - 1.0;
mapN.xy *= normalScale;
normal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );
`)
};
What does one need to do to enable perturbNormal2Arb
in THREE.js? When I try to use your code (@Chase_Code) I get an error:
ERROR: 0:…: ‘perturbNormal2Arb’ : no matching overloaded function found
Googled but found nothing about this.
Thank you!
perturbNormal2Arb into MeshPhongMaterial, MeshStandardMaterial, MeshPhicsicalMaterial
Compiled shader
Source here: three\src\renderers\shaders\ShaderChunk\normalmap_pars_fragment.glsl.js
Thanks very much, @Chaser_Code – I should have checked in three.js but thought that was a standard function (since it ends with ‘Arb’).
I reviewed the code in three.js and had trouble figuring out why it wasn’t compiling (I’d get an error about perturbNormal2Arb() not existing), and I discovered that the shader will only include the normal code is there is a normalMap present, and I had not yet assigned one. When no normalMap is present, the code is compiled out of the shader w/ #defines, which makes sense.
Long story short, it works now.
Thanks again!
1 Like