使用shaderMaterial实现环境光与漫反射光

来源:互联网 发布:零基础学python 老齐 编辑:程序博客网 时间:2024/04/28 07:28

上次咱们使用shaderMaterial实现纹理贴图,之后进一步拓展,在之前的基础上加上平行光与漫反射光的效果。
代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>无标题文档</title><script src="libs/three.js"></script><script src="libs/OrbitControls.js"></script><script src="libs/stats.min.js"></script><script src="js/stats.js"></script><script src="js/windowResize.js"></script>    <script id="vertexShader" type="x-shader/x-vertex">        varying vec2 vUv;        varying vec3 vNormal;        void main(){                vUv = uv;                vNormal = normal;                vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );                //projectionMatrix * mvPosition; 最终得到MVP矩阵                gl_Position = projectionMatrix * mvPosition;            }    </script>    <script type="x-shader/x-fragment" id="fragmentShader">        //获取纹理        uniform sampler2D texture1;        //加载的时间        uniform float u_time;        vec3 u_lightColor = vec3(1.0, 1.0, 1.0);//光线的颜色        //光的入射方向        uniform vec3 u_lightDirection;        //纹理坐标        varying vec2 vUv;        //法线        varying vec3 vNormal;        void main(void){            vec3 faceNormal = normalize(vNormal);//表面的法向量            //获取入射光线与法向量的夹角            float nDotL = max(dot(u_lightDirection, faceNormal), 0.0);            //vec4 a_color = texture2D(texture1, vUv) * vec4(abs(sin(u_time)), abs(cos(u_time)), 0.0, 1.0);            vec4 a_color = texture2D(texture1, vUv);            vec4 AmbientColor = vec4(u_lightColor, 1.0) * a_color;//环境光            vec4 diffuseColor = a_color * vec4(u_lightColor, 1.0) * nDotL;//漫反射光的颜色            gl_FragColor = a_color * (AmbientColor + diffuseColor) ;        }    </script><style>*{ margin:0; padding:0}</style></head><body style="overflow: hidden"><div id="Stats-output"></div></body><script>    var stats = initStats();    var scene = new THREE.Scene();    var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 10000);    camera.position.set(0, 0, 10);    camera.lookAt(scene.position);    var renderer = new THREE.WebGLRenderer({antialias:true});    renderer.setClearColor(0xffffff);    renderer.setSize(window.innerWidth, window.innerHeight);    document.body.appendChild(renderer.domElement);    var textureLoader = new THREE.TextureLoader();    var uniforms = {        //所用到的纹理        texture1 : {value : textureLoader.load('img/img-1.png')},        //加载时间先初始化为1.0        u_time : {value : 1.0},        //光线方向,先进行归一化        u_lightDirection : {value : new THREE.Vector3(0.5, 3.0, 4.0).normalize()}    };    uniforms.texture1.value.warpS = uniforms.texture1.value.warpT = THREE.RepeatWrapping;    var boxGeometry = new THREE.BoxGeometry(3, 3, 3);    //计算box的顶点法线,之后threejs会给出一个默认值normal,这个就是顶点法线    boxGeometry.computeVertexNormals();    var boxMaterial = new THREE.ShaderMaterial({        uniforms : uniforms,        vertexShader: document.getElementById( 'vertexShader' ).textContent,        fragmentShader: document.getElementById( 'fragmentShader' ).textContent,        color:0x00BBFF    });    var box = new THREE.Mesh(boxGeometry, boxMaterial);    scene.add(box);    var orbitControls = new THREE.OrbitControls(camera);    var clock = new THREE.Clock();    function render() {        stats.update();        var delta = clock.getDelta();        uniforms.u_time.value += 0.6 * delta;        requestAnimationFrame(render);        renderer.render(scene, camera);    }    render();</script></html>

最终结果如下:

0 0