版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78503759
<html> <!--开始实现一个三维街景的渲染效果--> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>NeHeWebGL----环境光(光照模型)</title> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> <script type="text/javascript" src="Oak3D_v_0_5.js"></script> <script id="shader-fs" type="x-shader/x-fragment"> precision mediump float; varying vec2 vTextureCoord; varying vec3 vLightWeighting; uniform sampler2D uSampler; void main(void) { vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a); } </script> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aVertexPosition; attribute vec3 aVertexNormal; attribute vec2 aTextureCoord; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; uniform mat4 uNMatrix; uniform vec3 uAmbientColor; uniform vec3 uLightingDirection; uniform vec3 uDirectionalColor; uniform bool uUseLighting; varying vec2 vTextureCoord; varying vec3 vLightWeighting; void main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); vTextureCoord = aTextureCoord; if (!uUseLighting) { vLightWeighting = vec3(1.0, 1.0, 1.0); } else { vec3 transformedNormal = (uNMatrix * vec4(aVertexNormal, 1.0)).xyz; float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0); vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting; } } </script> <script type="text/javascript"> var gl; //初始化WEBGL上下文 function initGL(canvas) { try { gl = canvas.getContext("experimental-webgl"); gl.viewportWidth = canvas.width; gl.viewportHeight = canvas.height; } catch (e) { } if (!gl) { alert("Could not initialise WebGL, sorry :-("); } } //获取着色器 function getShader(gl, id) { var shaderScript = document.getElementById(id); if (!shaderScript) { return null; } var str = ""; var k = shaderScript.firstChild; while (k) { if (k.nodeType == 3) { str += k.textContent; } k = k.nextSibling; } var shader; if (shaderScript.type == "x-shader/x-fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } else if (shaderScript.type == "x-shader/x-vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else { return null; } gl.shaderSource(shader, str); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } //初始化着色器 var shaderProgram; function initShaders() { var fragmentShader = getShader(gl, "shader-fs"); var vertexShader = getShader(gl, "shader-vs"); shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Could not initialise shaders"); } gl.useProgram(shaderProgram); //获取顶点着色器中的aVertexPosition变量,并开启 shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); //获取顶点着色器中的aVertexNormal法向量变量,并开启 shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute); //获取顶点着色器中的aTextureCoord纹理坐标的存储位置,并且开启 shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); //获取模型居住,取样器,光照等参数信息的存储位置 shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix"); shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting"); shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor"); shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection"); shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor"); } //处理已经加载的纹理图片 /*function handleLoadedTexture(texture) { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D); gl.bindTexture(gl.TEXTURE_2D, null); }*/ //从本地文件中加载一张纹理图片并且初始化 /* var crateTexture; function initTexture() { crateTexture = gl.createTexture(); crateTexture.image = new Image(); crateTexture.image.onload = function () { handleLoadedTexture(crateTexture) } //设置我的纹理图片 crateTexture.image.src = "./resources/woodbox.bmp"; }*/ //创建我的模型视图矩阵 var mvMatrix; var mvMatrixStack = []; var pMatrix; //矩阵入栈 function mvPushMatrix() { var copy = new okMat4(); mvMatrix.clone(copy); mvMatrixStack.push(copy); } //矩阵出栈 function mvPopMatrix() { if (mvMatrixStack.length == 0) { throw "Invalid popMatrix!"; } mvMatrix = mvMatrixStack.pop(); } //该函数主要是吧我当前的模型视图投影矩阵及时更新到顶点着色器 function setMatrixUniforms() { gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray()); gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray()); //计算模型视图矩阵的逆转置矩阵(运动物体的法向量不断在改变) var normalMatrix = mvMatrix.inverse().transpose(); gl.uniformMatrix4fv(shaderProgram.nMatrixUniform, false, normalMatrix.toArray()); } //处理物体运动的一些基本参数 var xRot = 0; var xSpeed = 3; var yRot = 0; var ySpeed = -3; var z = -5.0; //可以处理多个按键同时按下的情形 var currentlyPressedKeys = {}; function handleKeyDown(event) { currentlyPressedKeys[event.keyCode] = true; } function handleKeyUp(event) { currentlyPressedKeys[event.keyCode] = false; } //根据不同的按键做出不同的反应 function handleKeys() { if (currentlyPressedKeys[33]) { // Page Up z -= 0.05; } if (currentlyPressedKeys[34]) { // Page Down z += 0.05; } if (currentlyPressedKeys[37]) { // Left cursor key ySpeed -= 1; } if (currentlyPressedKeys[39]) { // Right cursor key ySpeed += 1; } if (currentlyPressedKeys[38]) { // Up cursor key xSpeed -= 1; } if (currentlyPressedKeys[40]) { // Down cursor key xSpeed += 1; } } //初始化我的顶点缓冲区参数(包括位置、法向量、纹理坐标、位置索引) var cubeVertexPositionBuffer; var cubeVertexNormalBuffer; var cubeVertexTextureCoordBuffer; var cubeVertexIndexBuffer; //立方体的索引 var cubeVertexTextureIndex0; var cubeVertexTextureIndex1; var cubeVertexTextureIndex2; var cubeVertexTextureIndex3; var cubeVertexTextureIndex4; var cubeVertexTextureIndex5; //利用这个全局变量来保存所有的属性信息 var pwgl = {}; // Keep track of ongoing image loads to be able to handle lost context pwgl.ongoingImageLoads = []; function initBuffers() { cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); var vertices = [ // Front face -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // Back face -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // Top face -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, // Bottom face -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, // Right face 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, // Left face -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); cubeVertexPositionBuffer.itemSize = 3; cubeVertexPositionBuffer.numItems = 24; //设置我的立方体各个方向的法向量 cubeVertexNormalBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); var vertexNormals = [ // Front face 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // Back face 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, // Top face 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // Bottom face 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, // Right face 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // Left face -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW); cubeVertexNormalBuffer.itemSize = 3; cubeVertexNormalBuffer.numItems = 24; //纹理坐标的创建 cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = [ // Front face 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, // Back face 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // Top face 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, // Bottom face 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // Right face 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // Left face 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); cubeVertexTextureCoordBuffer.itemSize = 2; cubeVertexTextureCoordBuffer.numItems = 24; //顶点索引坐标的初始化 /*cubeVertexIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); var cubeVertexIndices = [ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face ]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); cubeVertexIndexBuffer.itemSize = 1; cubeVertexIndexBuffer.numItems = 36;*/ //对立方体的六个面建立索引,为后面的渲染做准备 //对立方体的每一个面分别建立缓冲区,以实现对不同的面实现不同的纹理 //前面 cubeVertexTextureIndex0 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex0); var Indices0 = [0, 1, 2, 0, 2, 3]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices0), gl.STATIC_DRAW); cubeVertexTextureIndex0.itemSize = 1; cubeVertexTextureIndex0.numItems = 6; //后面 cubeVertexTextureIndex1 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex1); var Indices1 = [4, 5, 6, 4, 6, 7]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices1), gl.STATIC_DRAW); cubeVertexTextureIndex1.itemSize = 1; cubeVertexTextureIndex1.numItems = 6; //上面 cubeVertexTextureIndex2 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex2); var Indices2 = [8, 9, 10, 8, 10, 11]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices2), gl.STATIC_DRAW); cubeVertexTextureIndex2.itemSize = 1; cubeVertexTextureIndex2.numItems = 6; //下面 cubeVertexTextureIndex3 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex3); var Indices3 = [12, 13, 14, 12, 14, 15]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices3), gl.STATIC_DRAW); cubeVertexTextureIndex3.itemSize = 1; cubeVertexTextureIndex3.numItems = 6; //右边 cubeVertexTextureIndex4 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex4); var Indices4 = [16, 17, 18, 16, 18, 19]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices4), gl.STATIC_DRAW); cubeVertexTextureIndex4.itemSize = 1; cubeVertexTextureIndex4.numItems = 6; //左边 cubeVertexTextureIndex5 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex5); var Indices5 = [20, 21, 22, 20, 22, 23]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices5), gl.STATIC_DRAW); cubeVertexTextureIndex5.itemSize = 1; cubeVertexTextureIndex5.numItems = 6; } //纹理加载完成之后的处理 function textureFinishedLoading(image, texture) { gl.bindTexture(gl.TEXTURE_2D, texture); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); //把纹理对象载入到顶点着色器 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); //Mip映射纹理(会自动生成Mip映射纹理链)---会提高纹理的分辨率 gl.generateMipmap(gl.TEXTURE_2D); //设置我的纹理滤波方式 //拉伸纹理 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); //纹理收缩 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); //对于所有的纹理坐标的S,T方向应用镜面映射 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT); gl.bindTexture(gl.TEXTURE_2D, null); } //开始从本地加载图片作为纹理图片 function loadImageForTexture(url, texture) { //创建一个类似javascript的DOM对象的图片对象【< img src="" id=""/>】 var image = new Image(); //图片在如完成之后 image.onload = function() { //删除当前数组中的这张图片 pwgl.ongoingImageLoads.splice(pwgl.ongoingImageLoads.indexOf(image), 1); textureFinishedLoading(image, texture); } pwgl.ongoingImageLoads.push(image); image.crossOrigin = "anonymous"; image.src = url; } //在这里我设置了三张纹理图片 function setupTextures() { // Texture for the table pwgl.woodTexture = gl.createTexture(); loadImageForTexture("./resources/wood_128x128.jpg", pwgl.woodTexture); // Texture for the floor pwgl.groundTexture = gl.createTexture(); loadImageForTexture("./resources/wood_floor_256.jpg", pwgl.groundTexture); // Texture for the box on the table pwgl.boxTexture = gl.createTexture(); loadImageForTexture("./resources/xiuxiuba.bmp", pwgl.boxTexture); //这里会出现错误的跨域请求 //has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource //loadImageForTexture("127.0.0.1:8080/webgl/images/xiuxiu.bmp", pwgl.boxTexture); pwgl.mofangTexture = gl.createTexture(); loadImageForTexture("./resources/xiuxiu.bmp", pwgl.mofangTexture); //再次循环创建六个立方体纹理图片 pwgl.cube1 = gl.createTexture(); pwgl.cube2 = gl.createTexture(); pwgl.cube3 = gl.createTexture(); pwgl.cube4 = gl.createTexture(); pwgl.cube5 = gl.createTexture(); pwgl.cube6 = gl.createTexture(); loadImageForTexture("./resources/cube/01.bmp", pwgl.cube1); loadImageForTexture("./resources/cube/02.bmp", pwgl.cube2); loadImageForTexture("./resources/cube/03.bmp", pwgl.cube3); loadImageForTexture("./resources/cube/04.bmp", pwgl.cube4); loadImageForTexture("./resources/cube/05.bmp", pwgl.cube5); loadImageForTexture("./resources/cube/06.bmp", pwgl.cube6); } //绘制场景 function drawScene() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //设置我的投影矩阵 pMatrix = okMat4Proj(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0); //模型视图矩阵 mvMatrix = okMat4Trans(0.0, 0.0, z); mvMatrix.rotX(OAK.SPACE_LOCAL, xRot, true); mvMatrix.rotY(OAK.SPACE_LOCAL, yRot, true); //开始向顶点着色器中的相应参数传值 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer); gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, cubeVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); /* gl.activeTexture(gl.TEXTURE0); //绑定纹理坐标到目标对象 gl.bindTexture(gl.TEXTURE_2D, crateTexture); gl.uniform1i(shaderProgram.samplerUniform, 0); var lighting = document.getElementById("lighting").checked; //console.log(lighting); //这里就只是把光照是否勾选的状态传给顶点着色器 gl.uniform1i(shaderProgram.useLightingUniform, lighting);*/ var lighting = document.getElementById("lighting").checked; //console.log(lighting); //这里就只是把光照是否勾选的状态传给顶点着色器 gl.uniform1i(shaderProgram.useLightingUniform, lighting); //在这里重复执行六次赋值纹理的操作 gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, pwgl.cube1); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex0); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, pwgl.cube2); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex1); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, pwgl.cube3); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex2); // gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, pwgl.cube4); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex3); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, pwgl.cube5); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex4); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, pwgl.cube6); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex5); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); setMatrixUniforms(); //判断光照选项框是否被选中 if (lighting) { //读出用户在输入框中键入的环境光的红、绿、蓝的颜色值,并传递给着色器 gl.uniform3f( shaderProgram.ambientColorUniform, parseFloat(document.getElementById("ambientR").value), parseFloat(document.getElementById("ambientG").value), parseFloat(document.getElementById("ambientB").value) ); //传递光线方向给着色器 var lightingDirection = new okVec3( parseFloat(document.getElementById("lightDirectionX").value), parseFloat(document.getElementById("lightDirectionY").value), parseFloat(document.getElementById("lightDirectionZ").value) ); //光线方向的归一化(实时胴体地在物体运动的每一个时刻,把环境光的相应参数传给顶点着色器) var adjustedLD = lightingDirection.normalize(false); //将光线方向向量乘以一个标量-1,用于调转向量的方向 adjustedLD = okVec3MulVal(adjustedLD, -1.0); gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD.toArray()); gl.uniform3f( shaderProgram.directionalColorUniform, parseFloat(document.getElementById("directionalR").value), parseFloat(document.getElementById("directionalG").value), parseFloat(document.getElementById("directionalB").value) ); } //开始把顶点位置 传给顶点着色器(通过索引方式绘图) /*gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); setMatrixUniforms(); //gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);*/ } var lastTime = 0; //实时更新旋转角度 function animate() { var timeNow = new Date().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; xRot += (xSpeed * elapsed) / 1000.0; yRot += (ySpeed * elapsed) / 1000.0; } lastTime = timeNow; } //不断重绘场景 function tick() { okRequestAnimationFrame(tick); handleKeys(); drawScene(); animate(); } //主函数 function webGLStart() { var canvas = document.getElementById("lesson07-canvas"); initGL(canvas); initShaders(); initBuffers(); //initTexture(); //设置纹理 setupTextures(); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.enable(gl.DEPTH_TEST); document.onkeydown = handleKeyDown; document.onkeyup = handleKeyUp; tick(); } </script> </head> <body onload="webGLStart();"> <br> <canvas id="lesson07-canvas" style="border: none;" width="500" height="500"></canvas> <br/> <input type="checkbox" id="lighting" checked/> 开启光照<br/> (使用<code>Page Up</code>和<code>Page Down</code>键来进行缩放) <br/> <h2>平行光:</h2> <table style="border: 0; padding: 10px;"> <tr> <td><b>方向:</b> <td>X: <input type="text" id="lightDirectionX" value="-0.25"/> <td>Y: <input type="text" id="lightDirectionY" value="-0.25"/> <td>Z: <input type="text" id="lightDirectionZ" value="-1.0"/> </tr> <tr> <td><b>颜色:</b> <td>R: <input type="text" id="directionalR" value="0.8"/> <td>G: <input type="text" id="directionalG" value="0.8"/> <td>B: <input type="text" id="directionalB" value="0.8"/> </tr> </table> <h2>环境光:</h2> <table style="border: 0; padding: 10px;"> <tr> <td><b>颜色:</b> <td>R: <input type="text" id="ambientR" value="0.2"/> <td>G: <input type="text" id="ambientG" value="0.2"/> <td>B: <input type="text" id="ambientB" value="0.2"/> </tr> </table> </body> <!-- 注释:简单记录一下吧,经过前期的百般尝试;终于实现了在立方体的六个面贴上不同的纹理图片的功能; 但是使用的额仍然是2D纹理贴图方式,虽然功能实现了, 但是代码中仍然有待进一步改善哈@@@webmaster@xiuxiu.space 2017 11/9/ --></html>