webgl的shader系列(4)——(利用Three.js)顶点着色器与片元着色器中计算的区别

首先看一下光照颜色在顶点着色器中的效果:

1、颜色计算放在顶点着色器中

const VSHADER=`
        uniform vec3 u_LightColor;
        uniform vec3 u_LightDirction;
        uniform vec3 u_AmbientLight;
        uniform vec3 u_Color;
        varying vec4 v_Color;
        void main(){
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
            //计算变换后的法向量并归一化
            vec3 newnormal=normalize(vec3(normalMatrix*normal));
            //计算光线方向和法向量的点积
            float nDotL=max(dot(u_LightDirction,newnormal),0.0);
            //计算漫反射光的颜色
            vec3 diffuse=u_LightColor*u_Color.rgb*nDotL;
            //计算环境光产生的反射光的颜色
            vec3 ambient=u_AmbientLight*u_Color.rgb;
            //将以上两者相加作为最终的颜色
            v_Color=vec4(diffuse+ambient,1.0);
        }
        `
        const FSHADER=`        
        precision mediump float;
        varying vec4 v_Color;
        void main(){
            gl_FragColor=v_Color;
        }
        `

2、颜色计算放在片元着色器中

const VSHADER=`
        varying vec3 v_Normal;
        void main(){
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
            //计算变换后的法向量并归一化
            v_Normal=normalize(vec3(normalMatrix*normal));
        }
        `
        const FSHADER=`        
        precision mediump float;
        uniform vec3 u_LightColor;
        uniform vec3 u_LightDirction;
        uniform vec3 u_AmbientLight;
        varying vec3 v_Normal;
        uniform vec3 u_Color;
        void main(){
            //计算光线方向和法向量的点积
            float nDotL=max(dot(u_LightDirction,v_Normal),0.0);
            //计算漫反射光的颜色
            vec3 diffuse=u_LightColor*u_Color.rgb*nDotL;
            //计算环境光产生的反射光的颜色
            vec3 ambient=u_AmbientLight*u_Color.rgb;
            //将以上两者相加作为最终的颜色
            gl_FragColor=vec4(diffuse+ambient,1.0);
        }
        `

从二者的结果来看,把计算放在片元着色器中,效果会更好,颜色界限处会更平滑。

在three.js中使用的代码

let geometry = new THREE.SphereBufferGeometry( 2, 64, 64 );
        geometry.computeVertexNormals ()
        let geometryMat = new THREE.ShaderMaterial( {
            uniforms:{
                u_Color:{value:new THREE.Color(0xff0000)},
                u_LightColor:{value:this.dirLight.color},
                u_LightDirction:{value:this.dirLight.position},
                u_AmbientLight:{value:this.ambientLight.color}                
            },
            vertexShader:VSHADER,
            fragmentShader:FSHADER,
            vertexColors: true
            } );
        let cube = new THREE.Mesh( geometry, geometryMat );
        cube.castShadow=true        
        cube.position.set(0,0,2)
        this.scene.add( cube );

源码地址:

https://gitee.com/niuge8905/webglsample

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值