环境光的漫反射

环境光经过多长反射后形成,从四面八方射来。用什么颜色的环境光照射到白色物体上,跟用白光照射到什么颜色的物体,是等效的。 在 Vertex Shader 中声明一个类型是 vec3uniform 变量,存入光的颜色,它跟顶点颜色相乘,就可以了。

环境反射颜色 = 入射光颜色 × 表面基底色

<script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; attribute vec4 a_Color; uniform mat4 u_mvpMatrix; uniform vec3 u_AmbientLight; varying vec4 v_Color; void main(){ gl_Position = u_mvpMatrix * a_Position; vec3 ambient = u_AmbientLight * a_Color.rgb; v_Color = vec4( ambient, a_Color.a ); } </script> <script id="fragmentShader" type="x-shader/x-fragment"> precision mediump float; varying vec4 v_Color; void main(){ gl_FragColor = v_Color; } </script> function init(){ var canvas = document.getElementById('canvas'), gl = canvas.getContext('webgl'); if(!gl){ console.log('Failed to get WebGL.'); return; } if(!initShaders(gl, "vertexShader", "fragmentShader")){ console.log('Failed to initShaders.'); return; } gl.clearColor( 0.0, 0.0, 0.0, 1.0 ); gl.enable( gl.DEPTH_TEST ); var viewProjMatrix = new Matrix4(); viewProjMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100); viewProjMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0); var u_mvpMatrix = gl.getUniformLocation(gl.program, 'u_mvpMatrix'); gl.uniformMatrix4fv(u_mvpMatrix, false, viewProjMatrix.elements); var ambientLight = new Vector3([ 0.2, 0.2, 0.2 ]); var u_AmbientLight = gl.getUniformLocation( gl.program, "u_AmbientLight" ); gl.uniform3fv( u_AmbientLight, ambientLight.elements ); // 立方体 gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT ); var n = initVertexBuffers(gl); gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); } function initVertexBuffers(gl){ var vertices = new Float32Array([ 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0 ]), colors = new Float32Array([ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ]), indices = new Uint8Array([ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23 ]); initArrayBuffer(gl, 'a_Position', vertices, 3, gl.FLOAT); initArrayBuffer(gl, 'a_Color', colors, 3, gl.FLOAT); var indicesBuffer = gl.createBuffer(); gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, indicesBuffer ); gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW ); return indices.length; } function initArrayBuffer(gl, attribute, data, num, type){ var buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); var a_location = gl.getAttribLocation(gl.program, attribute); gl.vertexAttribPointer(a_location, num, type, false, 0, 0); gl.enableVertexAttribArray(a_location); return true; }