Hey, anyone here can help me with the code?
So the problem I am facing right now, is to how can I implment the shader to a merged instance from drei. I’ll tell you what’s happening right now. I think when I am using merged from drei, what it does is, that it picks the default material from the glb and applies that, and it ignores the shader. Is there a way out of this?
Code is below:
import * as THREE from 'three';
import { createContext, useMemo, useContext, useRef, useEffect } from 'react';
import { Merged, useGLTF } from '@react-three/drei';
import { GLTF } from 'three-stdlib';
import { useLoader } from '@react-three/fiber';
import InfinitePlaneShaderMaterial from './InfinitePlaneShader';
import fabricWhiteTex from '../assets/knitted_seamless_white.jpg';
import fabricBlackTex from '../assets/knitted_seamless_black.jpg';
type GLTFResult = GLTF & {
nodes: {
Plane005001: THREE.Mesh
}
materials: {
['01 - Default.002']: THREE.MeshStandardMaterial
}
}
type ContextType = Record<string, React.ForwardRefExoticComponent<JSX.IntrinsicElements['mesh']>>;
const context = createContext({} as ContextType);
export function Instances({ children, ...props }: JSX.IntrinsicElements['group']) {
const { nodes } = useGLTF('/ClothNewSeamless-transformed.glb') as GLTFResult
const instances = useMemo(
() => ({
Plane: nodes.Plane005001,
}),
[nodes],
)
return (
<Merged meshes={instances} {...props}>
{(instances: ContextType) => <context.Provider value={instances} children={children} />}
</Merged>
)
}
export function Cloth({ ...props }: JSX.IntrinsicElements['group']) {
const instances = useContext(context);
const materialRef = useRef<THREE.ShaderMaterial>(null);
const fabricTextureLeft = useLoader(THREE.TextureLoader, fabricBlackTex);
const fabricTextureRight = useLoader(THREE.TextureLoader, fabricWhiteTex);
useEffect(() => {
if (materialRef.current) {
materialRef.current.uniforms.fabricTextureLeft.value = fabricTextureLeft;
materialRef.current.uniforms.fabricTextureRight.value = fabricTextureRight;
fabricTextureLeft.wrapS = fabricTextureLeft.wrapT = THREE.RepeatWrapping;
fabricTextureRight.wrapS = fabricTextureRight.wrapT = THREE.RepeatWrapping;
materialRef.current.needsUpdate = true; // Ensure the material updates
}
}, [fabricTextureLeft, fabricTextureRight]);
return (
<group dispose={null} {...props}>
<instances.Plane castShadow receiveShadow scale={10}>
<shaderMaterial
ref={materialRef}
attach="material"
uniforms={InfinitePlaneShaderMaterial.uniforms}
vertexShader={InfinitePlaneShaderMaterial.vertexShader}
fragmentShader={InfinitePlaneShaderMaterial.fragmentShader}
side={THREE.DoubleSide}
/>
</instances.Plane>
</group>
);
}
useGLTF.preload('/ClothNewSeamless-transformed.glb');