Hi all!
I have two normal maps, one texture, and one material that I test. When I apply one of the normal maps to a material, I get a weird grainy distorted look on the material. If I replace the normal map with another one, the problem seems to fix itself (although I am not entirely sure whether it is solved or just not pronounced as much). The light dispersion is also weird.
I tried setting receiveShadow
and castShadow
to false, tried playing with shadow biases, but to no result. Also, I tried setting the minFilter
and magFilter
, as well as generating mipmaps - no effect.
React-three-fiber code below:
const ruberoid1 = useMemo(() => {
ruberoidTexture.colorSpace = SRGBColorSpace;
// ruberoidTexture.minFilter = NearestMipMapNearestFilter;
// ruberoidTexture.magFilter = LinearFilter;
// ruberoidTexture.wrapS = ruberoidTexture.wrapT = RepeatWrapping;
// ruberoidTexture.generateMipmaps = true;
// ruberoidNormalMap1.minFilter = NearestMipMapNearestFilter;
// ruberoidNormalMap1.magFilter = LinearFilter;
// ruberoidNormalMap1.wrapS = ruberoidNormalMap1.wrapT = RepeatWrapping;
// ruberoidNormalMap1.generateMipmaps = true;
// ruberoidNormalMap1.needsUpdate = true;
const material = new MeshStandardMaterial({
map: ruberoidTexture,
normalMap: ruberoidNormalMap2,
normalScale: new Vector2(2, 2),
metalness: 1.7,
roughness: 0.7,
});
// ruberoidTexture.needsUpdate = true;
// ruberoidNormalMap1.needsUpdate = true;
return material;
}, [ruberoidNormalMap2, ruberoidTexture]);
The consumer component:
interface RuberoidRoofProps {
width: number;
depth: number;
geometry?: BufferGeometry;
material?: Material;
overhangOuter: number;
}
export function RuberoidRoof({
width,
depth,
geometry,
material,
overhangOuter,
}: RuberoidRoofProps) {
const scale = new Vector3(
width + overhangOuter * 2,
1,
depth + overhangOuter * 2
);
const adjustedGeometry = useUvAdjustedGeometry({ geometry, scale });
const offset = 0.012;
return (
<mesh
scale={scale}
position={new Vector3(0, 2.2 + 0.32 + offset, 0)}
geometry={adjustedGeometry}
material={material}
/>
);
}
useUvAdjustedGeometry:
interface AdjustGeometryProps {
geometry?: BufferGeometry;
scale: Vector3;
scaleFactor?: number;
}
export function useUvAdjustedGeometry({
geometry,
scale,
scaleFactor = 1,
}: AdjustGeometryProps) {
return useMemo(() => {
if (!geometry) return;
const clonedGeometry = geometry.clone();
const uvAttribute = clonedGeometry.attributes.uv;
const uvs = uvAttribute.array;
for (let i = 0; i < uvs.length; i += 2) {
uvs[i] *= scale.z * scaleFactor;
uvs[i + 1] *= scale.x * scaleFactor;
}
uvAttribute.needsUpdate = true;
return clonedGeometry;
}, [geometry, scale.x, scale.z, scaleFactor]);
}
You can find the texture and normal maps attached.
Links to some videos to visualise the problem:
Link 1
Link 2
Link 3
Link 4
P.S.
Forgot to add info about my lighting.
This is the only lighting I have in the scene:
function Skybox() {
return (
<>
<Environment
preset="sunset"
environmentIntensity={0.9}
background
backgroundBlurriness={1}
/>
</>
);
}