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

这篇主要记录WebGL的一些基本要点,顺便也学习下如何使用FBO与环境贴图。先看下效果图(需要支持WebGL,Chrome,火狐,IE11)。

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

主要实现过程如下,先用FBO输出当前环境在立方体纹理中,再画出当前立方体,最后画球,并且把FBO关联的纹理贴在这个球面上。

开始WebGL时,最好有些OpenGL基础,在前面讲Obj完善与MD2时,大家可能已经发现了,因为着色器的添加使用,原来一些Opengl大部分API已经没有使用。WebGL就和这差不多,大部分功能是着色器完成主要功能,记录下主要过程,大家可以比较下前面的,看看是不是很像,为了熟悉WebGL基本功能,本文没有利用比较完善的框架,只是用到一个帮助计算矩阵的框架(gl-matrix.js).

和使用OpenGL一样,我们要初始化使用环境,提取一些全局使用量。相关代码如下:

初始化:

var gl;//WebGLRenderingContext var cubeVBO;//Cube buffer ID var sphereVBO;//球体VBO var sphereEBO;//球体EBO var cubeTexID;//立方体纹理ID var fboBuffer;//桢缓存对象 var glCubeProgram;//立方体着色器应用 var glSphereProgram;//球体着色器应用 var fboWidth = 512;//桢缓存绑定纹理宽度 var fboHeight = 512;//桢缓存绑定纹理高度 var targets;//立方体贴图六个方向 var pMatrix = mat4.create();//透视矩阵 var vMatrix = mat4.create();//视图矩阵 var eyePos = vec3.fromValues(0.0, 1.0, 0.0);//眼睛位置 var eyeLookat = vec3.fromValues(0.0, -0.0, 0.0);//眼睛方向 var spherePos = vec3.fromValues(0.0, -0.0, 0.0);//球体位置 var canvanName; function webGLStart(cName) { canvanName = cName; InitWebGL(); InitCubeShader(); InitSphereShader(); InitCubeBuffer(); InitSphereBuffer(); InitFBOCube(); //RenderFBO(); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.enable(gl.DEPTH_TEST); tick(); } function InitWebGL() { //var canvas = document.getElementById(canvanName); InitGL(canvanName); } function InitGL(canvas) { try { //WebGLRenderingContext gl = canvas.getContext("experimental-webgl"); gl.viewportWidth = canvas.width; gl.viewportHeight = canvas.height; targets = [gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]; } catch (e) { } if (!gl) { alert("你的浏览器不支持WebGL"); } }

在这里,我们初始化在网页中WebGL的上下方环境,并给出一系列初始化过程。下面先给出房间,也就是其中立方体的相关代码。

立方体:

function InitCubeShader() { //WebGLShader var shader_vertex = GetShader("cubeshader-vs"); var shader_fragment = GetShader("cubeshader-fs"); //WebglCubeProgram glCubeProgram = gl.createProgram(); gl.attachShader(glCubeProgram, shader_vertex); gl.attachShader(glCubeProgram, shader_fragment); gl.linkProgram(glCubeProgram); if (!gl.getProgramParameter(glCubeProgram, gl.LINK_STATUS)) { alert("Shader hava error."); } gl.useProgram(glCubeProgram); glCubeProgram.positionAttribute = gl.getAttribLocation(glCubeProgram, "a_position"); glCubeProgram.normalAttribute = gl.getAttribLocation(glCubeProgram, "a_normal"); glCubeProgram.texCoordAttribute = gl.getAttribLocation(glCubeProgram, "a_texCoord"); glCubeProgram.view = gl.getUniformLocation(glCubeProgram, "view"); glCubeProgram.perspective = gl.getUniformLocation(glCubeProgram, "perspective"); } function InitCubeBuffer() { var cubeData = [ -10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 0.0, -10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 1.0, 10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 1.0, 10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 1.0, 10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 0.0, -10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 0.0, -10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 0.0, 10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 1.0, 10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 1.0, -10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 1.0, -10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 0.0, -10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 0.0, 0.0, 10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 1.0, 0.0, 10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 1.0, 1.0, 10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 1.0, 1.0, -10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 0.0, 1.0, -10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 0.0, 0.0, 10.0, -10.0, -10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, -10.0, 10.0, 0.0, 0.0, 1.0, 0.0, 10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 1.0, 1.0, 10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 1.0, 1.0, 10.0, -10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 1.0, 10.0, -10.0, -10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0, -10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 1.0, 0.0, -10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 1.0, 1.0, -10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 1.0, 1.0, 10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 0.0, 1.0, 10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0, -10.0, 10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0, -10.0, -10.0, -10.0, -10.0, 0.0, 0.0, 1.0, 0.0, -10.0, -10.0, 10.0, -10.0, 0.0, 0.0, 1.0, 1.0, -10.0, -10.0, 10.0, -10.0, 0.0, 0.0, 1.0, 1.0, -10.0, 10.0, 10.0, -10.0, 0.0, 0.0, 0.0, 1.0, -10.0, 10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0, ]; cubeVBO = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeData), gl.STATIC_DRAW); } function RenderCube() { gl.useProgram(glCubeProgram); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO); gl.vertexAttribPointer(glCubeProgram.positionAttribute, 3, gl.FLOAT, false, 32, 0); gl.enableVertexAttribArray(glCubeProgram.positionAttribute); gl.vertexAttribPointer(glCubeProgram.normalAttribute, 3, gl.FLOAT, false, 32, 12); gl.enableVertexAttribArray(glCubeProgram.normalAttribute); gl.vertexAttribPointer(glCubeProgram.texCoordAttribute, 2, gl.FLOAT, false, 32, 24); gl.enableVertexAttribArray(glCubeProgram.texCoordAttribute); gl.uniformMatrix4fv(glCubeProgram.view, false, vMatrix); gl.uniformMatrix4fv(glCubeProgram.perspective, false, pMatrix); gl.drawArrays(gl.TRIANGLES, 0, 36); }

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

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