React-Fiber Three.js如何避免Plane组件点击穿透问题
问题根因
你遇到的点击穿透是两个原因共同导致的:
- 你给Plane的材质设置了
DoubleSide双面渲染,Three.js的射线检测会同时识别平面的正面和背面,当射线穿过立方体外侧的平面后,会继续命中立方体内侧的其他平面 - @react-three/fiber的交互事件默认会触发所有射线命中的对象的绑定事件,不会自动只触发最近的对象
解决方案
方案一(推荐):修改材质渲染面
把材质的DoubleSide改为默认的FrontSide即可,你用来构建立方体的每个Plane的法线本身就是朝向立方体外部的,从相机视角出发的射线只会命中朝向自己的外侧平面,不会检测到内侧的其他面,从根源避免穿透。
修改代码如下:
首先从three中导入FrontSide:
import { DoubleSide, FrontSide } from "three";
然后替换meshPhongMaterial的side属性:
<meshPhongMaterial side={FrontSide} color={colorStyle()} />
方案二:阻止事件冒泡
如果你确实需要保留双面渲染的配置,可以在每个交互事件中调用stopPropagation(),@react-three/fiber的交互事件会按射线命中的距离由近到远触发,最近的平面先触发事件,阻止冒泡后就不会触发更远位置的平面的事件,代码修改如下:
<Plane scale={1} onClick={(e) => { e.stopPropagation(); setChecked(!checked); }} onPointerEnter={(e) => { e.stopPropagation(); hover(true); }} onPointerLeave={(e) => { e.stopPropagation(); hover(false); }} position={props.position} rotation={props.rotation} > <meshPhongMaterial side={DoubleSide} color={colorStyle()} /> </Plane>
内容的提问来源于stack exchange,提问作者pythonNovice
相关产品推荐
相关产品推荐

