reactjs 如何在鼠标移动时更新统一的VEC2,

nhaq1z21  于 2023-01-08  发布在  React
关注(0)|答案(1)|浏览(96)

我试图更新一个统一的vec2当鼠标移动,但我得到一个错误:类型错误:未能在“WebGL2RenderingContext”上执行“统一2fv”:重载解析失败。
为此我设计了一套裁判制服

const uniformRef = useRef({
    uAlpha: 0,
    uOffset: { x: 0.0, y: 0.0 },
    uTexture: imageTexture,
  });

然后我创建了一个useEffect来监听"mousemove"事件

useEffect(() => {
    document.addEventListener("mousemove", onMouseMove);

    return () => document.removeEventListener("mousemove", onMouseMove);
  }, [onMouseMove]);

最后我创建了对"mousemove"的函数调用

const onMouseMove = useCallback((e: MouseEvent) => {
    if (!planeRef.current || planeRef.current === undefined) return;
    // mouse coordinate
    let x = (e.clientX / window.innerWidth) * 2 - 1;
    let y = -(e.clientY / window.innerHeight) * 2 + 1;

    const position = new THREE.Vector3(x, y, 0);
    // change position of the mesh
    gsap.to(planeRef.current?.position, {
      duration: 1,
      x,
      y,
      ease: Power4.easeOut,
      onUpdate: () => onPositionUpdate(position),
    });
  }, []);

  // update the offset
  const onPositionUpdate = (position: THREE.Vector3) => {
    if (planeRef.current) {
      let offset = planeRef.current.position
        .clone()
        .sub(position)
        .multiplyScalar(-0.25);

      gsap.to(uniformRef.current, {
        uOffset: { x: offset.x, y: offset.y },
        duration: 1,
        ease: Power4.easeOut,
      });
    }
  };

这是着色器的初始化

const ColorShiftMaterial = shaderMaterial(
  {
    uTexture: new THREE.Texture(),
    uOffset: new THREE.Vector2(0.0, 0.0),
    uAlpha: 0,
  },
...)

如果你能在这方面帮助我或者只是给点提示,这会帮我很大的忙!谢谢
我尝试了很多方法,但是每次我尝试新的方法,我仍然会得到错误,我想这可能是因为我给了uOffset一个vec3,所以我换了一个vec2,但是即使这样我仍然会得到错误。

kq4fsx7k

kq4fsx7k1#

首先,你应该使用react-three纤维处理3JS和React。
按照命名约定,您应该将制服命名为u_mouse(带下划线)。
在three fiber中,有一个onPointerMove,您可以使用它来获取鼠标移动。
例如:

<mesh onPointerMove={(e) => handleMove(e)}>

若要将值传递到着色器,需要具有制服。

const uniforms = {
    u_time: { value: 0.0 },
    u_mouse: { value: { x: 0.0, y: 0.0 } },
    u_resolution: { value: { x: 0, y: 0 } },
  };

你可以使用useEffect来获取屏幕大小的值,并在你的分辨率统一中使用这些值。然后你可以在你的着色器中使用这些值来计算鼠标的移动,而不管屏幕大小如何。
我不知道你是如何编写着色器的,但是你可以为鼠标创建一个vec2,为分辨率创建一个vec2,并执行如下操作

vec2 v = u_mouse/u_resolution; // mouseposition / screensize
vec3 color = vec3(v.x, (v.y/v.x+0.2), v.y); // use the v-value for the x- and y-axis
gl_FragColor = vec4(color, 1.0); // add the new colors to your output

这完全取决于你想发生什么,你想它看起来如何。

相关问题