I have a Floor
component in my React Three Fiber project that currently loads a texture using useKTX2
. Each texture set consists of a diffuse map, normal map, and an ARM (Ambient Occlusion, Roughness, Metalness) map. I want to implement an effect where, upon clicking the floor mesh, it smoothly transitions (animates) to a new random texture from a set of 11 available textures. The transition should be gradual rather than an instant switch. What would be the best approach to achieve this texture blending effect?
import { useKTX2 } from “@react-three/drei”;
import { useThree } from “@react-three/fiber”;
import { useEffect, useMemo, useRef } from “react”;
import * as THREE from “three”;
import { generateFloor } from “../../../utils/generateWallsUtils”;
const Floor = ({ innerWallsPoints, windingOrder }) => {
const floorTexture = 1;
const { scene } = useThree();
const meshRef = useRef();
const geometry = useMemo(() => {
const { floorVertices, floorIndices, floorUVs } = generateFloor(
innerWallsPoints,
windingOrder,
100
);
// Create the combined geometry
const bufferGeometry = new THREE.BufferGeometry();
// Set vertex positions
bufferGeometry.setAttribute(
"position",
new THREE.BufferAttribute(new Float32Array(floorVertices), 3)
);
// Set UVs
bufferGeometry.setAttribute(
"uv",
new THREE.BufferAttribute(new Float32Array(floorUVs), 2)
);
// Set indices
bufferGeometry.setIndex(floorIndices);
// Generate normals
bufferGeometry.computeVertexNormals();
return bufferGeometry;
}, [innerWallsPoints, windingOrder]);
useEffect(() => {
const currentMesh = meshRef.current;
return () => {
if (currentMesh) {
// Get access to the material
const material = currentMesh.material;
// Dispose of geometry and material
geometry.dispose();
if (material) material.dispose();
// Remove mesh from scene
scene.remove(currentMesh);
}
};
}, [geometry, scene]);
const floorTextures = useKTX2({
map: `/floorTextures/${floorTexture}/diffuse.ktx2`,
normalMap: `/floorTextures/${floorTexture}/normal.ktx2`,
aoMap: `/floorTextures/${floorTexture}/ambientOcclusionRoughnessMetalness.ktx2`,
roughnessMap: `/floorTextures/${floorTexture}/ambientOcclusionRoughnessMetalness.ktx2`,
metalnessMap: `/floorTextures/${floorTexture}/ambientOcclusionRoughnessMetalness.ktx2`,
});
Object.values(floorTextures).forEach((texture, i) => {
// if (i === 0) texture.colorSpace = THREE.SRGBColorSpace;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
});
return (
<mesh ref={meshRef} geometry={geometry}>
<meshStandardMaterial {...floorTextures} />
</mesh>
);
};
export default Floor;