threejs[练习] 获取鼠标在模型上的位置,并传递到GLSL控制顶点着色器和片元着色器

172 阅读1分钟

yvzri-o3ic8.gif

本次实验是验证鼠标与模型上的顶点着色器和片元着色如何获取模型上鼠标坐标。并验证其可行性。

首先创建一个平面,并使用着色器纹理渲染,

  getBox() {
    const group = new THREE.Group();
    const geometry = new THREE.PlaneGeometry(50, 50, 50, 50);
    const material = new THREE.ShaderMaterial({
      uniforms: {
        u_point: {
          value: new THREE.Vector3(0.5, 0.5, 0.5),
        },
        height: { value: 0.5 },
      },
      fragmentShader: fs,
      vertexShader: vs,
      side: THREE.DoubleSide,
    });
    this.shader = material;
    const mesh = new THREE.Mesh(geometry, material);
    group.add(mesh);
    return group;
  }

监听window的mousemove事件,并通过Raycaster获取鼠标落在的模型,并获取point点传递给 uniforms的u_point


  handleClick(event: MouseEvent) {
    // 将坐标转化为 [-1,1]的元矩阵
    const mouse = new THREE.Vector2(
      (event.clientX / window.innerWidth) * 2 - 1,
      -(event.clientY / window.innerHeight) * 2 + 1
    );

    const raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, this.camera);

    const instanceObj = raycaster.intersectObjects(this.scene.children, true);
    if (instanceObj[0]) {
      this.point = instanceObj[0].point;
      this.shader.uniforms.u_point.value = this.point;
      // console.log(this.point);
    }
  }

顶点着色器

uniform vec3 u_point;
varying vec3 v_position;
void main() {
    const float scope = 10.0;
    v_position = position;
    v_uv = uv;
    vec3 pos = position;
    if(abs(length(v_position.xy - u_point.xy)) <= scope) {
        pos.z = pos.z + 10.;
    }
    v_position = pos;

vec4 modelViewPosition = modelViewMatrix * vec4(pos, 1.0);
    vec4 projectPosition = projectionMatrix * modelViewPosition;
    gl_Position = projectPosition;
}

片元着色器

uniform vec3 u_point;
varying vec3 v_position;
void main() {
    const float scope = 10.0;
    float height_opc = ((v_position.x + .5) / 1.5);
    vec3 point3 = u_point / 25.0;
    vec2 pos = vec2(2., 2.);
    if(abs(length(v_position.xy - u_point.xy)) <= scope) {
        gl_FragColor = vec4(vec3(0.8039, 0.0824, 0.5765), v_position.z);
        return;
    }
    gl_FragColor = vec4(vec3(1.), 1.0);
}