基于shader着色器实现三维下雨特效

67 阅读1分钟

1.png

 1.绘制一条直线,并修改材质shader

drawLine(start, end, color,index) {

            let that = this

            let geometry = new THREE.BufferGeometry().setFromPoints([start, end]);

            let material = new THREE.LineBasicMaterial({ color: color });

            let line = new THREE.Line(geometry, material);

            line.name = 'line'+index

            let startRandom = this.getRandomIntInclusive(0, 99)

            material.onBeforeCompile = function (shader) {

                shader.uniforms.startY = { value: startRandom };

                shader.uniforms.height = { value: 1 };

                 // 修改顶点着色器

                shader.vertexShader = shader.vertexShader.replace(

                    'void main() {',

                    `varying vec3 vPosition;

                    void main() {

                        vPosition = position;`

                )

                shader.fragmentShader = shader.fragmentShader.replace(

                'void main() {',

                `varying vec3 vPosition;

                float w = 0.5;

                uniform float startY;

                uniform float height;

                void main() {`

                )

                shader.fragmentShader = shader.fragmentShader.replace(

                '#include <dithering_fragment>',

                //多行代码字符串,用模板字符串``更方便

                `

                #include <dithering_fragment>

                if(vPosition.y > startY && vPosition.y < (startY+height)){

                        float per = (vPosition.y - startY) / 1.0;

                        gl_FragColor.rgb = mix(gl_FragColor.rgb,vec3(188/255,25/255,194/255),per);

                    }else{

                        discard;

                    }

                `

                )

                line.shader = shader;

                that.lineShaderMap.set(line.name,shader)

            }

            scene.add(line);

        },

2.随机绘制多条 

randomline() {

            let that = this

            for (let i = 0; i < 900; i++) {

                let x = that.getRandomFloat(-100, 100);

                let z = that.getRandomFloat(-100, 100);

                this.drawLine(new THREE.Vector3(x,0,z),new THREE.Vector3(x-100,200,z-100),0xffffff,i)

            }

        },

3.动态修改着色器传入参数

modelAction(){
            this.render()
            for(let [key,shader] of this.lineShaderMap){
                shader.uniforms.startY.value -= 1;
                if (shader.uniforms.startY.value <= 0) {
                    shader.uniforms.startY.value = 99.0;
                }
            }
          
            requestAnimationFrame(this.modelAction)
        },