I'm implementing a simple 3D-paint and want to implement an erasing. In order to do it I decided to use two layers of canvas: one for texture image and another one (transparent) for drawing to erase only canvas for drawing. Can you please advice how to have one meshStandardMaterial with the image texture (which shouldn't be modified while painting/erasing) and one ore more transparent meshStandardMaterial just for painting Here is the component code:
<Canvas
onCreated={({ gl }) => {
gl.physicallyCorrectLights = true;
}}
camera=
>
{isControlsAllowed && <Controls />}
<mesh
onPointerLeave={handleDrawStop}
onPointerDown={() => {
setIsControlsAllowed(false);
}}
onPointerUp={() => {
setIsControlsAllowed(true);
}}
onPointerMove={(ev) => {
handleBrushPointerMove(ev, previousPoint.current);
}}
geometry={geometry}
>
<meshStandardMaterial
attach="material"
metalness={0}
roughness={1}
>
<canvasTexture
ref={currentTextureRef}
attach="map"
image={currentCanvasRef.current}
/>
</meshStandardMaterial>
<meshStandardMaterial attach="material" metalness={0} roughness={1}>
<canvasTexture
ref={currentDrawingTextureRef}
attach="map"
image={currentDrawingCanvasRef.current}
/>
</meshStandardMaterial>
</mesh>
<ambientLight intensity={1} />
<spotLight position={[0, 0, 10]} intensity={10} />
<spotLight position={[-10, 0, -5]} intensity={10} />
<spotLight position={[10, 0, -5]} intensity={10} />
</Canvas>
My hook code:
const currentCanvasRef = useRef(document.createElement("canvas"));
const currentTextureRef = useRef<CanvasTexture>(null);
const currentDrawingCanvasRef = useRef(document.createElement("canvas"));
const currentDrawingTextureRef = useRef<CanvasTexture>(null);
useLayoutEffect(() => {
const context = currentDrawingCanvasRef.current.getContext("2d");
context?.clearRect(
0,
0,
currentDrawingCanvasRef.current.width,
currentDrawingCanvasRef.current.height
);
createCanvasTextureFromImage("/Stool.jpg");
}, []);
const createCanvasTextureFromImage = (
imageUrl: string,
) => {
const canvas = currentCanvasRef.current;
new ImageLoader().load(imageUrl, (image) => {
const ctx = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
if (ctx) {
ctx.clearRect(0.0, 0.0, canvas.width, canvas.height);
ctx.drawImage(image, 0.0, 0.0, image.width, image.height);
}
});
};
const handleBrushPointerMove = (
currentPoint: ThreeEvent<PointerEvent>,
prevPoint?: ThreeEvent<PointerEvent>
) => {
// Some drawing logic
};
What I'm expecting to see:
And what I'm actually see:
UPDATE: I just checked that array of materials doesn't work for mesh. Although each of the materials works separately, when using an array, the 3D model is not displayed at all
from Transparent layer of meshStandardMaterial three js React
No comments:
Post a Comment