React+Three.js中MeshStandardMaterial透明图层实现3D擦除问询
3D绘画工具双材质配置问题
我正在实现一个简易3D绘画工具,需要添加擦除功能。计划采用双Canvas图层:一个承载图片纹理(绘画/擦除时不修改),另一个透明图层用于绘画擦除。想咨询如何为一个mesh配置一个带图片纹理的MeshStandardMaterial,以及一个或多个用于绘画的透明MeshStandardMaterial。
组件代码
<Canvas onCreated={({ gl }) => { gl.physicallyCorrectLights = true; }} camera={{ position: [0, 0, 10] }} > {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>
Hook代码
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 };
效果对比
预期效果

实际效果

更新说明
经测试,材质数组对mesh无效。单独使用每个材质均正常,但使用数组时3D模型完全不显示。
内容的提问来源于stack exchange,提问作者Lev Kostychenko
相关产品推荐
相关产品推荐

