[Help] How to change size of normalMap

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

Screenshot 2022-01-28 at 09.05.06

Thanks in advance and kind regards,

Davide

Have, you tried changing the repeat value size such as texture.repeat.set( 2, 2 );

@forerunrun 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 @forerunrun 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
image

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