悬停时变换顶点位置(Three.js/Shaders GLSL)

问题描述 投票:0回答:0

我正在学习着色器,并且有一个正在构建的小项目。该项目基于将鼠标悬停在粒子上时将粒子转换为纹理。现在我有大约 85% 的逻辑下降,但我想要在鼠标悬停时进行更多的完整转换,但似乎无法正确处理。比如,当鼠标没有悬停在网格上时,我应该只看到网格,当它悬停在上面时,我应该看到 100% 的纹理和它的新位置。

这是我目前得到的示例.

我能够更新我原来的东西,它更接近我的视觉,但是当我刷新页面时,首先显示纹理而不是粒子。那就是我需要帮助弄清楚我需要修复的地方。

顶点着色器

varying vec2 vUv;
varying vec3 vPos;
varying vec2 vCoordinates;

attribute vec3 aCoordinates;
attribute vec3 aPosition;

uniform float uTime;
uniform vec2 uMouse;
uniform float uRadius;

mat3 rotation3dY(float angle) {
    float s = sin(angle);
    float c = cos(angle);
    return mat3(c, 0.0, -s, 0.0, 1.0, 0.0, s, 0.0, c);
}

void main() {
    vUv = uv;

    // START
    float distanceFactor = uRadius - distance(aPosition, vec3(0.0));
    vec3 start = aPosition * rotation3dY(uTime * 0.2 * distanceFactor);

    // TRANSITION
    vec3 plane = position;
    float moveDist = distance(start.xy, uMouse * 2.0);
    float moveArea = smoothstep(0.0, 1024.0, moveDist);

    vec3 finalPos = abs(moveDist/ 8.0) > 32.0 ? start : plane;

    // END
    vec4 mvPosition = modelViewMatrix * vec4(finalPos, 1.0);
    vec4 viewPosition = viewMatrix * mvPosition;

    gl_PointSize = 3000.0;
    gl_PointSize *= (1.0 / -viewPosition.z);
    gl_Position = projectionMatrix * mvPosition;

    vCoordinates = aCoordinates.xy;

    vPos = start;
}

片段

varying vec2 vCoordinates;
varying vec3 vPos;
uniform sampler2D ish;
uniform sampler2D mask;
uniform float uMove;

void main() {
    vec4 maskTexture = texture2D(mask, gl_PointCoord);
    vec2 myUV = vec2(vCoordinates.x / 512.0, vCoordinates.y / 512.0);
    vec4 image = texture2D(ish, myUV);


    float alpha = 1.0 - clamp(0.0, 1.0, abs(vPos.z / 900.0));

    gl_FragColor = image;
    gl_FragColor.a *= maskTexture.r * alpha;

}

相关Three.js代码

mouseEffects() {

        this.test = new THREE.Mesh(
            new THREE.PlaneGeometry(512, 512),
            new THREE.MeshBasicMaterial()
        )

        window.addEventListener('mousemove', (evt) => {
            this.move += evt.clientY / 100;
            this.mouse.x = (evt.clientX / window.innerWidth) * 2 - 1;
            this.mouse.y = -(evt.clientY / window.innerHeight) * 2 + 1;
            this.raycaster.setFromCamera(this.mouse, this.camera);


            let intersects = this.raycaster.intersectObjects([this.test]);
            console.log(intersects[0].point);

            this.point.x = intersects[0].point.x;
            this.point.y = intersects[0].point.y;
        }, false);
    }

    addMesh() {
        const number = 512 * 512;

        this.material = new THREE.ShaderMaterial({
            vertexShader,
            fragmentShader,
            uniforms: {
                progress: { type: "f", value: 0.0 },
                ish: { type: "t", value: this.textures[0] },
                logo: { type: "t", value: this.textures[1] },
                mask: { type: "t", value: this.mask },
                uMouse: { type: "v2", value: null },
                uTime: { type: "f", value: 0.0 },
                uRadius: {
                    type: "f", value: 2
                }
            },
            side: THREE.DoubleSide,
            depthTest: false,
            depthWrite: false,
            transparent: true,
        })

        this.geometry = new THREE.BufferGeometry();
        this.positions = new THREE.BufferAttribute(new Float32Array(number * 3), 3);
        this.startPos = new THREE.BufferAttribute(new Float32Array(number * 3), 3)
        this.coordinates = new THREE.BufferAttribute(new Float32Array(number * 3), 3);
        this.speeds = new THREE.BufferAttribute(new Float32Array(number), 1);
        this.offset = new THREE.BufferAttribute(new Float32Array(number), 1);
        this.directions = new THREE.BufferAttribute(new Float32Array(number), 1);
        this.press = new THREE.BufferAttribute(new Float32Array(number), 1);


        function rand(a, b) {
            return a + (b - a) * Math.random();
        }

        let index = 0;
        for (let i = 0; i < 512; i++) {
            let posX = i - 256;
            for (let j = 0; j < 512; j++) {
                this.positions.setXYZ(index, posX * 2, (j - 256) * 2, 0);
                this.coordinates.setXYZ(index, i, j, 0);
                this.offset.setX(index, rand(-1000, 1000));
                this.speeds.setX(index, rand(0.4, 1));
                this.directions.setX(index, Math.random() > 0.5 ? 1 : -1);
                this.press.setX(index, rand(0.4, 1));

                const phi = Math.random() * Math.PI * 2;
                let r = 0.2 + (Math.random() < 0.6 ? Math.pow(Math.random(), 1 / 6) + 0.001 : Math.pow((1 + 200 * Math.random()) * Math.random(), 3 / 6));
                this.startPos.setXYZ(index, (r * 16) * Math.cos(phi), (r * 16) * Math.sin(phi), 0)
                index++;
            }
        }
        this.geometry.setAttribute("position", this.positions);
        this.geometry.setAttribute("aPosition", this.startPos);
        this.geometry.setAttribute("aCoordinates", this.coordinates);
        this.geometry.setAttribute("aOffset", this.offset);
        this.geometry.setAttribute("aSpeed", this.speeds);
        this.geometry.setAttribute("aDirection", this.directions);
        this.geometry.setAttribute("aPress", this.press);
        this.mesh = new THREE.Points(this.geometry, this.material);
        this.scene.add(this.mesh);
    }
three.js hover glsl shader mousehover
© www.soinside.com 2019 - 2024. All rights reserved.