You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:35:32