这里新的东西就是 包围盒,就是把物体用盒子装起来,这样只需要计算面到这个是否相交,在外边,减少了很多计算量;
这个其实就是计算问题,
视锥体求的那个几个面的公式,自己用就可以了,不要问为什么,推导很麻烦;能用就行
相机的旋转,使用相机的up,lookat 两个向量的叉积 的到第三个向量 所形成的坐标系,旋转就通过第三向量的移动完成,就这么简单;
代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>第三人称</title> <script src="glMatrix-0.9.6.min.js"></script> <script src="../lib/my-webgl-utils.js"></script> <script id="vs" type="x-shader/x-vertex"> attribute vec3 a_Position; attribute vec4 a_Color; attribute vec2 a_TexCoord; uniform mat4 u_Proj; varying vec4 v_Color; varying vec2 v_texCoord; void main(){ gl_Position = u_Proj * vec4(a_Position,1.0); v_Color = a_Color; v_texCoord = a_TexCoord; } </script> <script id="fs" type="x-shader/x-fragment"> precision mediump float; varying vec4 v_Color; varying vec2 v_texCoord; uniform sampler2D u_Texture; void main(void){ gl_FragColor = texture2D(u_Texture,v_texCoord); } </script> </head> <body> <canvas id="webgl" width="500px" height="500px"></canvas> <script> var gl; var viewPortW; var viewPortH; var triangleBuffer = null; var textureHandle;//纹理对象 var textureGround; var projectMat = mat4.create();//投影矩阵 var viewMat = mat4.create();//视图矩阵 var cameraEye = new Float32Array(3);//相机位置 var cameraTrag = new Float32Array(3);//观看目标位置 var cameraLookAt = new Float32Array(3); var cameraUp = new Float32Array(3); var fbo; var textureDynamic; var times = (new Date()).valueOf(); var role = {};//角色对象 role._position = new Float32Array(3); role._target = new Float32Array(3); role._speed = 5;//速度 var varRotFBOX = 0; var varRotFBOY = 0; var mouseDown = false; var rButtonDown = false; var lastMouseX = 0; var lastMouseY = 0; var radius = 40; var loadTextureNum = 0; onload = function () { var canvas = document.getElementById("webgl"); gl = canvas.getContext("webgl"); viewPortW = canvas.clientWidth; viewPortH = canvas.clientHeight; gl.viewport(0, 0, canvas.clientWidth, viewPortH); if (!initShaders(gl, "vs", "fs")) { console.log('Failed to intialize shaders.'); return; } initLocation();//初始化,获取着色器中的变量地址 initCamera(); initModelData(); canvas.onmousedown = handleMouseDown; canvas.onmouseup = handleMouseUp; canvas.onmousemove = handleMouseMove; canvas.onmousewheel = handleMouseWheel; document.onkeydown = handleKeyDown; document.onkeyup = handleKeyup; tick(); } function tick() { requestAnimFrame(tick); renderScene(); } function renderScene() { renderToFBO(); var elspsed = (new Date()).valueOf() - times; times = (new Date()).valueOf(); updateTarget(elspsed); cameraTrag = role._position; updateCamera();//更新相机位置 varRotFBOX += 1; //使用fbo gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.viewport(0, 0, viewPortW, viewPortH); //! 设置重绘背景的颜色 gl.clearColor(0.0, 0.0, 0.0, 1.0); //! 执行绘制,即将背景清空成制定的颜色(clearColor) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.enable(gl.DEPTH_TEST); //! 指定绘制所使用的顶点数据 从 该缓冲区中获取 gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer); var mvp = mat4.create(); var matTrans = mat4.create(); var matModel = mat4.create(); var matRotX = mat4.create(); var matROtY = mat4.create(); var matRot = mat4.create(); var matTemp = mat4.create(); mat4.identity(matRot); mat4.identity(matRotX); mat4.identity(matROtY); mat4.identity(matTrans); mat4.identity(matModel); mat4.identity(mvp); mat4.identity(matTemp); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, textureDynamic); gl.uniform1i(gl.uniformTexture, 0); mat4.translate(matTrans, [role._position[0], 0.0, role._position[2]]); //varRot += 1; mat4.rotate(matROtY, degToRad(varRotFBOY), [0.0, 1.0, 0.0]); mat4.rotate(matRotX, degToRad(varRotFBOX), [1.0, 0.0, 0.0]); mat4.multiply(matROtY, matRotX, matRot); mat4.multiply(matTrans, matRot, matModel); mat4.multiply(projectMat, viewMat, matTemp); mat4.multiply(matTemp, matTrans, mvp); gl.uniformMatrix4fv(gl.uniformProj, false, mvp); gl.enableVertexAttribArray(gl.a_Position); gl.enableVertexAttribArray(gl.a_TexCoord); gl.enableVertexAttribArray(gl.a_Color); gl.vertexAttribPointer(gl.a_Position, 3, gl.FLOAT, false, 4 * 9, 0); gl.vertexAttribPointer(gl.a_TexCoord, 2, gl.FLOAT, false, 4 * 9, 4 * 3); gl.vertexAttribPointer(gl.a_Color, 4, gl.FLOAT, false, 4 * 9, 4 * 5); gl.drawArrays(gl.TRIANGLES, 0, 36); mat4.multiply(projectMat, viewMat, mvp); gl.uniformMatrix4fv(gl.uniformProj, false, mvp); gl.bindTexture(gl.TEXTURE_2D, textureGround); gl.drawArrays(gl.TRIANGLES, 36, 6); } //计算相机位置 function updateCamera() { //反向推导,知道目标位置,和相机与目标位置的距离,求相机位置 //camerD 是 目标位置减去相机位置的向量,并归一化,没归一化前,其实就相当于camerD * radius //camerD归一化,类似于单位向量,乘以 长,就是它们相减得到的向量 cameraEye[0] = cameraTrag[0] - cameraLookAt[0] * radius; cameraEye[1] = cameraTrag[1] - cameraLookAt[1] * radius; cameraEye[2] = cameraTrag[2] - cameraLookAt[2] * radius; //规格化up坐标 var upDir = vec3.normalize(cameraUp); mat4.lookAt(cameraEye, cameraTrag, upDir, viewMat); } //更新目标 function updateTarget(elapsed) { if (role._target[0] == role._position[0] && role._target[1] == role._position[1] && role._target[2] == role._position[2]) { return; } var offset = new Float32Array(3); var dir = new Float32Array(3); offset[0] = role._target[0] - role._position[0]; offset[1] = role._target[1] - role._position[1]; offset[2] = role._target[2] - role._position[2]; vec3.normalize(offset, dir); var dist = vec3.length(offset); if (dist > role._speed * elapsed / 1000.0 * 2) { var dist = role._speed * elapsed / 1000.0; role._position[0] += dir[0] * dist; role._position[2] += dir[2] * dist; } else { role._position[0] = role._target[0]; role._position[1] = role._target[1]; role._position[2] = role._target[2]; } } function renderToFBO() { //使用fbo gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); gl.viewport(0, 0, viewPortW, viewPortH); //设置重绘背景的颜色 gl.clearColor(1.0, 1.0, 1.0, 1.0); //执行绘制,即将背景清空成制定的颜色 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.enable(gl.DEPTH_TEST); //指定绘制使用的顶点数据 gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer); var mvp = mat4.create();//MVP矩阵 var matTrans = mat4.create();//移动矩阵 var matModel = mat4.create();//模型矩阵 var matRotX = mat4.create();//X旋转矩阵 var matRotY = mat4.create();//Y 旋转矩阵 var matRot = mat4.create();//旋转矩阵 //初始化成单位向量 mat4.identity(matRot); mat4.identity(matRotX); mat4.identity(matRotY); mat4.identity(matTrans); mat4.identity(matModel); mat4.identity(mvp); gl.activeTexture(gl.TEXTURE0);//开启纹理 gl.bindTexture(gl.TEXTURE_2D, textureHandle); gl.uniform1i(gl.uniformTexture, 0); mat4.translate(matTrans, [0, 0.0, -4]); mat4.rotate(matRotY, degToRad(varRotFBOY), [0.0, 1.0, 0.0]); mat4.rotate(matRotX, degToRad(varRotFBOX), [1.0, 0.0, 0.0]); mat4.multiply(matRotY, matRotX, matRot); mat4.multiply(matTrans, matRot, matModel); mat4.multiply(projectMat, matModel, mvp);//得到mvp 矩阵 gl.uniformMatrix4fv(gl.uniformProj, false, mvp); gl.enableVertexAttribArray(gl.a_Position); gl.enableVertexAttribArray(gl.a_Color); gl.enableVertexAttribArray(gl.a_TexCoord); gl.vertexAttribPointer(gl.a_Position, 3, gl.FLOAT, false, 4 * 9, 0); gl.vertexAttribPointer(gl.a_TexCoord, 2, gl.FLOAT, false, 4 * 9, 4 * 3); gl.vertexAttribPointer(gl.a_Color, 4, gl.FLOAT, false, 4 * 9, 4 * 5); gl.drawArrays(gl.TRIANGLES, 0, 36); } function degToRad(degrees) { return degrees * Math.PI / 180; } function handleKeyup(event) { } function handleKeyDown(event) { } /** * 将屏幕坐标转化成世界坐标 * @param screen * @returns {*} */ function screenToWorld(screen) { var v = new Float32Array(4); var world = new Float32Array(4); v[0] = screen[0]; v[1] = screen[1]; v[2] = screen[2]; v[3] = 1.0;//w分量 //转换成 0 - 1 的坐标 v[0] = (v[0])/viewPortW; v[1] = (viewPortH - v[1])/viewPortH; //转换成 -1 到 1 之间的坐标 v[0] = v[0] * 2.0 - 1.0; v[1] = v[1] * 2.0 - 1.0; v[2] = v[2] * 2.0 - 1.0; var mvp = mat4.create(); var mvpInvert = mat4.create(); //计算MVP矩阵 mat4.multiply(projectMat,viewMat,mvp); //求mvp的逆矩阵 inverseEx(mvp,mvpInvert); world[0] = v[0]; world[1] = v[1]; world[2] = v[2]; world[3] = v[3]; multiply(mvpInvert,v,world);//得到世界坐标 if (world[3] == 0.0) { return world; } world[0] /= world[3]; world[1] /= world[3]; world[2] /= world[3]; return world; } function multiply(mat,v,outv) { outv[0] = mat[0] * v[0] + mat[1] * v[1] + mat[2] * v[2] + mat[3] * v[3]; outv[1] = mat[4] * v[0] + mat[5] * v[1] + mat[6] * v[2] + mat[7] * v[3]; outv[2] = mat[8] * v[0] + mat[9] * v[1] + mat[10] * v[2] + mat[11] * v[3]; outv[3] = mat[12] * v[0] + mat[13] * v[1] + mat[14] * v[2] + mat[15] * v[3]; } //逆矩阵 function inverseEx(pData,resData) { var subFactor00 = pData[10] * pData[15] - pData[14] * pData[11]; var subFactor01 = pData[9] * pData[15] - pData[13] * pData[11]; var subFactor02 = pData[9] * pData[14] - pData[13] * pData[10]; var subFactor03 = pData[8] * pData[15] - pData[12] * pData[11]; var subFactor04 = pData[8] * pData[14] - pData[12] * pData[10]; var subFactor05 = pData[8] * pData[13] - pData[12] * pData[9]; var subFactor06 = pData[6] * pData[15] - pData[14] * pData[7]; var subFactor07 = pData[5] * pData[15] - pData[13] * pData[7]; var subFactor08 = pData[5] * pData[14] - pData[13] * pData[6]; var subFactor09 = pData[4] * pData[15] - pData[12] * pData[7]; var subFactor10 = pData[4] * pData[14] - pData[12] * pData[6]; var subFactor11 = pData[5] * pData[15] - pData[13] * pData[7]; var SubFactor12 = pData[4] * pData[13] - pData[12] * pData[5]; var subFactor13 = pData[6] * pData[11] - pData[10] * pData[7]; var subFactor14 = pData[5] * pData[11] - pData[9] * pData[7]; var subFactor15 = pData[5] * pData[10] - pData[9] * pData[6]; var subFactor16 = pData[4] * pData[11] - pData[8] * pData[7]; var subFactor17 = pData[4] * pData[10] - pData[8] * pData[6]; var subFactor18 = pData[4] * pData[9] - pData[8] * pData[5]; resData[0] = + pData[5] * subFactor00 - pData[6] * subFactor01 + pData[7] * subFactor02; resData[1] = - pData[4] * subFactor00 + pData[6] * subFactor03 - pData[7] * subFactor04; resData[2] = + pData[4] * subFactor01 - pData[5] * subFactor03 + pData[7] * subFactor05; resData[3] = - pData[4] * subFactor02 + pData[5] * subFactor04 - pData[6] * subFactor05; resData[4] = - pData[1] * subFactor00 + pData[2] * subFactor01 - pData[3] * subFactor02; resData[5] = + pData[0] * subFactor00 - pData[2] * subFactor03 + pData[3] * subFactor04; resData[6] = - pData[0] * subFactor01 + pData[1] * subFactor03 - pData[3] * subFactor05; resData[7] = + pData[0] * subFactor02 - pData[1] * subFactor04 + pData[2] * subFactor05; resData[8] = + pData[1] * subFactor06 - pData[2] * subFactor07 + pData[3] * subFactor08; resData[9] = - pData[0] * subFactor06 + pData[2] * subFactor09 - pData[3] * subFactor10; resData[10] = + pData[0] * subFactor11 - pData[1] * subFactor09 + pData[3] * SubFactor12; resData[11] = - pData[0] * subFactor08 + pData[1] * subFactor10 - pData[2] * SubFactor12; resData[12] = - pData[1] * subFactor13 + pData[2] * subFactor14 - pData[3] * subFactor15; resData[13] = + pData[0] * subFactor13 - pData[2] * subFactor16 + pData[3] * subFactor17; resData[14] = - pData[0] * subFactor14 + pData[1] * subFactor16 - pData[3] * subFactor18; resData[15] = + pData[0] * subFactor15 - pData[1] * subFactor17 + pData[2] * subFactor18; var determinant = + pData[0] * resData[0] + pData[1] * resData[4] + pData[2] * resData[8] + pData[3] * resData[12]; for( var i = 0 ;i < 16 ; ++ i) resData[i] /= determinant; } function handleMouseDown(event) { if (event.button == 0){ //计算射线 var minWorld = new Float32Array(3); var maxWorld = new Float32Array(3); var screen = new Float32Array(3); screen[0] = event.offsetX; screen[1] = event.offsetY; screen[2] = 0.0; var screen1 = new Float32Array(3); screen[0] = event.offsetX; screen[1] = event.offsetY; screen[2] = 1.0; var minWorld = screenToWorld(screen); var maxWorld = screenToWorld(screen1); //射线向量 var dir = new Float32Array(3); dir[0] = maxWorld[0] - minWorld[0]; dir[1] = maxWorld[1] - minWorld[1]; dir[2] = maxWorld[2] - minWorld[2]; vec3.normalize(dir); //计算交点: //计算方式:因为地面的y=0;射线的起点y轴减去地面的y轴得到高,然后用射线的单位向量除以高,minWorld[1]/dir[1],得到速度(步长,) //射线的起点位置 加上 tm(步长,相当于时间,走了多长,)乘以 射线的单位向量,得到交点 //计算时间 var tm = Math.abs(minWorld[1]/dir[1]); var target = new Float32Array(3); target[0] = minWorld[0] + tm * dir[0]; target[1] = minWorld[1] + tm * dir[1]; target[2] = minWorld[2] + tm * dir[2]; moveTo(target); }else { rButtonDown = true; lastMouseX = event.offsetX; console.log("rButtonDown = true;"); } } function moveTo(targetPos) { role._target = targetPos; role._target[1] = 0;//没有高度 } function handleMouseUp(event) { } function handleMouseMove(event) { } function handleMouseWheel(event) { } function initModelData() { var gSize = 100;//大小 var gPos = -10;//高度 var rept = 20;//重复 var boxVertex = [ //x y z u v r g b a -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.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, 0.0, 0.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, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, -gSize, gPos, -gSize, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, gSize, gPos, -gSize, rept, 0.0, 1.0, 1.0, 1.0, 1.0, gSize, gPos, gSize, rept, rept, 1.0, 1.0, 1.0, 1.0, -gSize, gPos, -gSize, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, gSize, gPos, gSize, rept, rept, 1.0, 1.0, 1.0, 1.0, -gSize, gPos, gSize, 0.0, rept, 1.0, 1.0, 1.0, 1.0, ] triangleBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxVertex), gl.STATIC_DRAW); textureHandle = initTextures("test.gif"); textureGround = initTextures("1.jpg"); fbo = createFOB(viewPortW, viewPortH); } //离屏渲染,创建帧缓冲区 function createFOB(width, height) { var obj = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, obj); //创建深度缓冲区 var depthObj = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, depthObj); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthObj);//把深度缓冲区绑定到帧缓冲区 textureDynamic = createDynamicTexture(width, height);//动态纹理 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureDynamic, 0); gl.bindRenderbuffer(gl.RENDERBUFFER, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.bindTexture(gl.TEXTURE_2D, null); return obj; } function createDynamicTexture(width, height) { var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); return texture; } function initTextures(imageFile) { var texture; //创建一个纹理 texture = gl.createTexture(); //创建一个图片 texture.image = new Image(); //指定图片的路径 texture.image.src = imageFile; texture.image.onload = function () { handleLoadedTexture(texture); } return texture; } function handleLoadedTexture(texture) { 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); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); gl.bindTexture(gl.TEXTURE_2D, null); loadTextureNum++; } function initCamera() { cameraEye[0] = 28.017817; cameraEye[1] = 29.867514; cameraEye[2] = 29.429590; cameraTrag[0] = -0.84969789; cameraTrag[1] = 1; cameraTrag[2] = 0.56207591; cameraUp[0] = 0; cameraUp[1] = 1; cameraUp[2] = 0; role._position[0] = 0; role._position[1] = 0; role._position[2] = 0; role._target[0] = 0; role._target[1] = 1; role._target[2] = 2; calcDir(); mat4.perspective(45, viewPortW / viewPortH, 0.1, 10000.0, projectMat);//设置投影矩阵 mat4.lookAt(cameraEye, cameraTrag, cameraUp, viewMat);//设置视图矩阵 } //求的lookAt方向 单位向量 function calcDir() { //相机看向位置 减 去 眼睛位置,得到 一个向量, D坐标 vec3.subtract(cameraTrag, cameraEye, cameraLookAt); var d = new Float32Array(3); d[0] = cameraTrag[0] - cameraEye[0]; d[1] = cameraTrag[1] - cameraEye[1]; d[2] = cameraTrag[2] - cameraEye[2]; vec3.normalize(d, cameraLookAt); } function initLocation() { gl.uniformProj = gl.getUniformLocation(gl.program, "u_Proj"); gl.uniformTexture = gl.getUniformLocation(gl.program, "u_Texture"); gl.a_Position = gl.getAttribLocation(gl.program, "a_Position"); gl.a_Color = gl.getAttribLocation(gl.program, "a_Color"); gl.a_TexCoord = gl.getAttribLocation(gl.program, "a_TexCoord"); if (!gl.uniformProj && !gl.uniformTexture) { console.log("err 001:获取地址变量错误!"); } if (gl.a_Position < 0 || gl.a_TexCoord < 0 || gl.a_Color < 0) { console.log("err 002:获取地址变量错误!"); } } window.requestAnimFrame = (function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback, element) { window.setTimeout(callback, 10); }; })(); function inverseEx(pData,resData) { var subFactor00 = pData[10] * pData[15] - pData[14] * pData[11]; var subFactor01 = pData[9] * pData[15] - pData[13] * pData[11]; var subFactor02 = pData[9] * pData[14] - pData[13] * pData[10]; var subFactor03 = pData[8] * pData[15] - pData[12] * pData[11]; var subFactor04 = pData[8] * pData[14] - pData[12] * pData[10]; var subFactor05 = pData[8] * pData[13] - pData[12] * pData[9]; var subFactor06 = pData[6] * pData[15] - pData[14] * pData[7]; var subFactor07 = pData[5] * pData[15] - pData[13] * pData[7]; var subFactor08 = pData[5] * pData[14] - pData[13] * pData[6]; var subFactor09 = pData[4] * pData[15] - pData[12] * pData[7]; var subFactor10 = pData[4] * pData[14] - pData[12] * pData[6]; var subFactor11 = pData[5] * pData[15] - pData[13] * pData[7]; var SubFactor12 = pData[4] * pData[13] - pData[12] * pData[5]; var subFactor13 = pData[6] * pData[11] - pData[10] * pData[7]; var subFactor14 = pData[5] * pData[11] - pData[9] * pData[7]; var subFactor15 = pData[5] * pData[10] - pData[9] * pData[6]; var subFactor16 = pData[4] * pData[11] - pData[8] * pData[7]; var subFactor17 = pData[4] * pData[10] - pData[8] * pData[6]; var subFactor18 = pData[4] * pData[9] - pData[8] * pData[5]; resData[0] = + pData[5] * subFactor00 - pData[6] * subFactor01 + pData[7] * subFactor02; resData[1] = - pData[4] * subFactor00 + pData[6] * subFactor03 - pData[7] * subFactor04; resData[2] = + pData[4] * subFactor01 - pData[5] * subFactor03 + pData[7] * subFactor05; resData[3] = - pData[4] * subFactor02 + pData[5] * subFactor04 - pData[6] * subFactor05; resData[4] = - pData[1] * subFactor00 + pData[2] * subFactor01 - pData[3] * subFactor02; resData[5] = + pData[0] * subFactor00 - pData[2] * subFactor03 + pData[3] * subFactor04; resData[6] = - pData[0] * subFactor01 + pData[1] * subFactor03 - pData[3] * subFactor05; resData[7] = + pData[0] * subFactor02 - pData[1] * subFactor04 + pData[2] * subFactor05; resData[8] = + pData[1] * subFactor06 - pData[2] * subFactor07 + pData[3] * subFactor08; resData[9] = - pData[0] * subFactor06 + pData[2] * subFactor09 - pData[3] * subFactor10; resData[10] = + pData[0] * subFactor11 - pData[1] * subFactor09 + pData[3] * SubFactor12; resData[11] = - pData[0] * subFactor08 + pData[1] * subFactor10 - pData[2] * SubFactor12; resData[12] = - pData[1] * subFactor13 + pData[2] * subFactor14 - pData[3] * subFactor15; resData[13] = + pData[0] * subFactor13 - pData[2] * subFactor16 + pData[3] * subFactor17; resData[14] = - pData[0] * subFactor14 + pData[1] * subFactor16 - pData[3] * subFactor18; resData[15] = + pData[0] * subFactor15 - pData[1] * subFactor17 + pData[2] * subFactor18; var determinant = + pData[0] * resData[0] + pData[1] * resData[4] + pData[2] * resData[8] + pData[3] * resData[12]; for( var i = 0 ;i < 16 ; ++ i) resData[i] /= determinant; } function multiply(mat,v,outv) { outv[0] = mat[0] * v[0] + mat[1] * v[1] + mat[2] * v[2] + mat[3] * v[3]; outv[1] = mat[4] * v[0] + mat[5] * v[1] + mat[6] * v[2] + mat[7] * v[3]; outv[2] = mat[8] * v[0] + mat[9] * v[1] + mat[10] * v[2] + mat[11] * v[3]; outv[3] = mat[12] * v[0] + mat[13] * v[1] + mat[14] * v[2] + mat[15] * v[3]; } </script> </body> </html>