WebGL利用FBO完成立方体贴图效果完整实例(附demo源(3)

在上面不知是gl-matrix提供的矩阵算法有问题,还是本来应该这样,在上下面的时候生成的纹理图不对,需要偏转摄像机的向上矢量。因为这是摄像机位置与目标的生成的Z轴和设定的UP轴平行了,这样导致不能正确计算X轴,然后对应的UP轴也计算不出来,相应视图矩阵出现错误。

最后是球体的绘画,代码主要和立方体的差不多,注意球体的顶点算法。

球体:

function InitSphereShader() { //WebGLShader var shader_vertex = GetShader("sphereshader-vs"); var shader_fragment = GetShader("sphereshader-fs"); //WebglCubeProgram glSphereProgram = gl.createProgram(); gl.attachShader(glSphereProgram, shader_vertex); gl.attachShader(glSphereProgram, shader_fragment); gl.linkProgram(glSphereProgram); if (!gl.getProgramParameter(glSphereProgram, gl.LINK_STATUS)) { alert("Shader hava error."); } glSphereProgram.positionAttribute = gl.getAttribLocation(glSphereProgram, "a_position"); glSphereProgram.normalAttribute = gl.getAttribLocation(glSphereProgram, "a_normal"); glSphereProgram.eye = gl.getUniformLocation(glSphereProgram, "eye"); glSphereProgram.mapCube = gl.getUniformLocation(glSphereProgram, "mapCube"); glSphereProgram.model = gl.getUniformLocation(glSphereProgram, "model"); glSphereProgram.view = gl.getUniformLocation(glSphereProgram, "view"); glSphereProgram.perspective = gl.getUniformLocation(glSphereProgram, "perspective"); } function InitSphereBuffer() { var radius = 1; var segments = 16; var rings = 16; var length = segments * rings * 6; var sphereData = new Array(); var sphereIndex = new Array(); for (var y = 0; y < rings; y++) { var phi = (y / (rings - 1)) * Math.PI; for (var x = 0; x < segments; x++) { var theta = (x / (segments - 1)) * 2 * Math.PI; sphereData.push(radius * Math.sin(phi) * Math.cos(theta)); sphereData.push(radius * Math.cos(phi)); sphereData.push(radius * Math.sin(phi) * Math.sin(theta)); sphereData.push(Math.sin(phi) * Math.cos(theta)); sphereData.push(radius * Math.cos(phi)) sphereData.push(Math.sin(phi) * Math.sin(theta)); } } for (var y = 0; y < rings - 1; y++) { for (var x = 0; x < segments - 1; x++) { sphereIndex.push((y + 0) * segments + x); sphereIndex.push((y + 1) * segments + x); sphereIndex.push((y + 1) * segments + x + 1); sphereIndex.push((y + 1) * segments + x + 1); sphereIndex.push((y + 0) * segments + x + 1) sphereIndex.push((y + 0) * segments + x); } } sphereVBO = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVBO); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereData), gl.STATIC_DRAW); sphereVBO.numItems = segments * rings; sphereEBO = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereEBO); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(sphereIndex), gl.STATIC_DRAW); sphereEBO.numItems = sphereIndex.length; } function RenderSphere() { gl.useProgram(glSphereProgram); gl.bindBuffer(gl.ARRAY_BUFFER, sphereVBO); gl.vertexAttribPointer(glSphereProgram.positionAttribute, 3, gl.FLOAT, false, 24, 0); gl.enableVertexAttribArray(glSphereProgram.positionAttribute); gl.vertexAttribPointer(glSphereProgram.normalAttribute, 3, gl.FLOAT, false, 24, 12); gl.enableVertexAttribArray(glSphereProgram.normalAttribute); var mMatrix = mat4.create(); mat4.translate(mMatrix, mMatrix, spherePos); gl.uniform3f(glSphereProgram.eye, eyePos[0],eyePos[1],eyePos[2]); gl.uniformMatrix4fv(glSphereProgram.model, false, mMatrix); gl.uniformMatrix4fv(glSphereProgram.view, false, vMatrix); gl.uniformMatrix4fv(glSphereProgram.perspective, false, pMatrix); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTexID); //gl.uniformMatrix4fv(glSphereProgram.mapCube, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereEBO); gl.drawElements(gl.TRIANGLES, sphereEBO.numItems, gl.UNSIGNED_SHORT, 0); gl.bindTexture(gl.TEXTURE_2D, null); }

可以看到,也是和立方体一样的三步,初始化着色器,初始化顶点与法线,绘画。下面给出着色器代码:

球体着色器:

<script type="x-shader/x-fragment"> precision mediump float; varying vec3 normal; varying vec3 eyevec; uniform samplerCube mapCube; void main( void ) { gl_FragColor = textureCube(mapCube, reflect(normalize(-eyevec), normalize(normal))); } </script> <script type="x-shader/x-vertex"> attribute vec3 a_position; attribute vec3 a_normal; uniform mat4 model; uniform mat4 view; uniform mat4 perspective; uniform vec3 eye; varying vec3 normal; varying vec3 eyevec; void main( void ) { gl_Position = perspective * view * model * vec4(a_position,1.0); eyevec = -eye;// a_position.xyz; normal = a_normal; } </script>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgwzfp.html