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

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

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

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

 1 var gl;//WebGLRenderingContext
 2 var cubeVBO;//Cube buffer ID
 3 var sphereVBO;//球体VBO
 4 var sphereEBO;//球体EBO
 5 var cubeTexID;//立方体纹理ID
 6 var fboBuffer;//桢缓存对象
 7 var glCubeProgram;//立方体着色器应用
 8 var glSphereProgram;//球体着色器应用
 9
10 var fboWidth = 512;//桢缓存绑定纹理宽度
11 var fboHeight = 512;//桢缓存绑定纹理高度
12 var targets;//立方体贴图六个方向
13
14 var pMatrix = mat4.create();//透视矩阵
15 var vMatrix = mat4.create();//视图矩阵
16 var eyePos = vec3.fromValues(0.0, 1.0, 0.0);//眼睛位置
17 var eyeLookat = vec3.fromValues(0.0, -0.0, 0.0);//眼睛方向
18 var spherePos = vec3.fromValues(0.0, -0.0, 0.0);//球体位置
19 var canvanName;
20
21 function webGLStart(cName) {
22     canvanName = cName;
23     InitWebGL();
24     InitCubeShader();
25     InitSphereShader();
26     InitCubeBuffer();
27     InitSphereBuffer();
28     InitFBOCube();
29     //RenderFBO();
30     gl.clearColor(0.0, 0.0, 0.0, 1.0);
31     gl.enable(gl.DEPTH_TEST);
32     tick();
33 }
34
35 function InitWebGL() {
36     //var canvas = document.getElementById(canvanName);
37     InitGL(canvanName);
38 }
39
40 function InitGL(canvas) {
41     try {
42         //WebGLRenderingContext
43         gl = canvas.getContext("experimental-webgl");
44         gl.viewportWidth = canvas.width;
45         gl.viewportHeight = canvas.height;
46
47         targets = [gl.TEXTURE_CUBE_MAP_POSITIVE_X,
48                      gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
49                      gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
50                      gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
51                      gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
52                      gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
53     } catch (e) { }
54     if (!gl) { alert("你的浏览器不支持WebGL"); }
55 }

初始化

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

 1 function InitCubeShader() {
 2     //WebGLShader
 3     var shader_vertex = GetShader("cubeshader-vs");
 4     var shader_fragment = GetShader("cubeshader-fs");
 5     //WebglCubeProgram
 6     glCubeProgram = gl.createProgram();
 7     gl.attachShader(glCubeProgram, shader_vertex);
 8     gl.attachShader(glCubeProgram, shader_fragment);
 9     gl.linkProgram(glCubeProgram);
10     if (!gl.getProgramParameter(glCubeProgram, gl.LINK_STATUS)) {
11         alert("Shader hava error.");
12     }
13     gl.useProgram(glCubeProgram);
14     glCubeProgram.positionAttribute = gl.getAttribLocation(glCubeProgram, "a_position");
15     glCubeProgram.normalAttribute = gl.getAttribLocation(glCubeProgram, "a_normal");
16     glCubeProgram.texCoordAttribute = gl.getAttribLocation(glCubeProgram, "a_texCoord");
17
18     glCubeProgram.view = gl.getUniformLocation(glCubeProgram, "view");
19     glCubeProgram.perspective = gl.getUniformLocation(glCubeProgram, "perspective");
20 }
21
22 function InitCubeBuffer() {
23     var cubeData = [
24             -10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 0.0,
25             -10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 1.0,
26             10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 1.0,
27
28             10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 1.0,
29             10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 0.0,
30             -10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 0.0,
31
32             -10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 0.0,
33             10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 0.0,
34             10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 1.0,
35
36             10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 1.0,
37             -10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 1.0,
38             -10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 0.0,
39
40             -10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 0.0, 0.0,
41             10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 1.0, 0.0,
42             10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 1.0, 1.0,
43
44             10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 1.0, 1.0,
45             -10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 0.0, 1.0,
46             -10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 0.0, 0.0,
47
48             10.0, -10.0, -10.0, 10.0, 0.0, 0.0, 0.0, 0.0,
49             10.0, 10.0, -10.0, 10.0, 0.0, 0.0, 1.0, 0.0,
50             10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 1.0, 1.0,
51
52             10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 1.0, 1.0,
53             10.0, -10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 1.0,
54             10.0, -10.0, -10.0, 10.0, 0.0, 0.0, 0.0, 0.0,
55
56             10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0,
57             -10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 1.0, 0.0,
58             -10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 1.0, 1.0,
59
60             -10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 1.0, 1.0,
61             10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 0.0, 1.0,
62             10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0,
63
64             -10.0, 10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0,
65             -10.0, -10.0, -10.0, -10.0, 0.0, 0.0, 1.0, 0.0,
66             -10.0, -10.0, 10.0, -10.0, 0.0, 0.0, 1.0, 1.0,
67
68             -10.0, -10.0, 10.0, -10.0, 0.0, 0.0, 1.0, 1.0,
69             -10.0, 10.0, 10.0, -10.0, 0.0, 0.0, 0.0, 1.0,
70             -10.0, 10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0,
71     ];
72     cubeVBO = gl.createBuffer();
73     gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO);
74     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeData), gl.STATIC_DRAW);
75 }
76
77 function RenderCube() {
78     gl.useProgram(glCubeProgram);
79     gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO);
80
81     gl.vertexAttribPointer(glCubeProgram.positionAttribute, 3, gl.FLOAT, false, 32, 0);
82     gl.enableVertexAttribArray(glCubeProgram.positionAttribute);
83
84     gl.vertexAttribPointer(glCubeProgram.normalAttribute, 3, gl.FLOAT, false, 32, 12);
85     gl.enableVertexAttribArray(glCubeProgram.normalAttribute);
86
87     gl.vertexAttribPointer(glCubeProgram.texCoordAttribute, 2, gl.FLOAT, false, 32, 24);
88     gl.enableVertexAttribArray(glCubeProgram.texCoordAttribute);
89
90     gl.uniformMatrix4fv(glCubeProgram.view, false, vMatrix);
91     gl.uniformMatrix4fv(glCubeProgram.perspective, false, pMatrix);
92
93     gl.drawArrays(gl.TRIANGLES, 0, 36);
94 }

立方体

  上面的代码主要分为初始化立方体的着色器对象,初始化相关缓存,然后绘制立方体,可以说在Opengl中,如果用着色器来画,过程也是差不多的,在Opengl里,已经没有固定管线的一些功能如InterleavedArrays来指定是顶点还是法线或是纹理了,统一用vertexAttribPointer来传递应用程序与着色器之间的数据。在前面 MD2桢动画实现里面后面的参数传递改进版也有相关应用。

  相应着立方体着色器主要代码如下.

 1     <script id="cubeshader-fs" type="x-shader/x-fragment">
 2         precision mediump float;
 3
 4         varying vec3 normal;
 5         varying vec3 tex1;
 6         varying vec3 tex2;
 7         void main( void )
 8         {
 9         float x = tex1.x * 6.28 * 8.0; //2兀 * 8
10         float y = tex1.y * 6.28 * 8.0; //2兀 * 8
11         //cos(x)= 8个 (1 -1 1)
12         gl_FragColor = vec4(tex2,1.0) * vec4(sign(cos(x)+cos(y))); //
13         //gl_FragColor = vec4(normal*vec3(0.5)+vec3(0.5), 1);
14         }
15     </script>
16
17     <script id="cubeshader-vs" type="x-shader/x-vertex">
18         attribute vec3 a_position;
19         attribute vec3 a_normal;
20         attribute vec2 a_texCoord;
21
22         uniform mat4 view;
23         uniform mat4 perspective;
24         varying vec3 normal;
25         varying vec3 tex1;
26         varying vec3 tex2;
27         void main( void )
28         {
29         gl_Position = perspective * view * vec4(a_position,1.0);
30         normal = a_normal;
31         tex1 = vec3(a_texCoord,0.0);
32         tex2 = normalize(a_position)*0.5+0.5;
33         }
34     </script>

立方体着色器实现

  着色器中,已经没有ftransform()功能可供调用,要自己传递如模型,视图,透视矩阵,在这里,模型是以原点为中心来绘画,意思模型视图矩阵也就是视图矩阵,所以屏幕位置的计算只需要视图和透视矩阵。在片断着色器中,x,y是从顶点着色器中的纹理坐标传递过来,相应过程6.28*8.0,相当于8个360度,用于控制立方体上的方块显示,而tex2是着色器中的顶点映射[0,1]的值,分别给立方体的六面分别设置不同的意思,然后用二个矢量的乘积来混合这二种颜色显示,gl_FragColor = vec4(tex2,1.0) * vec4(sign(cos(x)+cos(y)))。

  在显示球体之前,应该先生成当前环境的立方体绘图,在这里使用FBO,先生成桢缓存和立方体绘理,并关联,然后以原点为中心,分别向上下左右前右绘图,然后利用桢缓冲分别输出到立方体上的六个面,主要代码如下:

 1 function InitFBOCube() {
 2     // WebGLFramebuffer
 3     fboBuffer = gl.createFramebuffer();
 4     gl.bindFramebuffer(gl.FRAMEBUFFER, fboBuffer);
 5     fboBuffer.width = 512;
 6     fboBuffer.height = 512;
 7
 8     cubeTexID = gl.createTexture();
 9     gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTexID);
10     gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
11     gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
12     gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
13     gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
14
15     for (var i = 0; i < targets.length; i++) {
16         gl.texImage2D(targets[i], 0, gl.RGBA, fboBuffer.width, fboBuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
17     }
18     gl.bindFramebuffer(gl.FRAMEBUFFER, null);
19 }
20
21 function RenderFBO() {
22     gl.disable(gl.DEPTH_TEST);
23     gl.viewport(0, 0, fboBuffer.width, fboBuffer.height);
24     gl.clearColor(0.0, 0.0, 0.0, 1.0);
25     gl.bindFramebuffer(gl.FRAMEBUFFER, fboBuffer);
26     for (var i = 0; i < targets.length; i++) {
27         gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, targets[i], cubeTexID, null);
28         gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
29     }
30
31     mat4.perspective(pMatrix, 45, fboBuffer.width / fboBuffer.height, 0.1, 100.0);
32     for (var i = 0; i < targets.length; i++) {
33         gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, targets[i], cubeTexID, null);
34         var lookat = vec3.create();
35         var up = vec3.create();
36         up[1] = 1.0;
37         if (i == 0) {
38             lookat[0] = -1.0;
39         } else if (i == 1) {
40             lookat[0] = 1.0;
41         } else if (i == 2) {
42             lookat[1] = -1.0;
43             up[0] = 1.0;
44         } else if (i == 3) {
45             lookat[1] = 1.0;
46             up[0] = 1.0;
47         } else if (i == 4) {
48             lookat[2] == -1.0;
49         } else if (i == 5) {
50             lookat[2] = 1.0;
51         } else {
52         }
53         //vec3.fromValues(0.0, 0.0, 0.0)
54         vMatrix = mat4.create();
55         mat4.lookAt(vMatrix, vec3.fromValues(0.0, 0.0, 0.0), lookat, up);
56         //mat4.scale(vMatrix, vMatrix, vec3.fromValues(-1.0, -1.0, -1.0));
57         //mat4.translate(vMatrix, vMatrix, spherePos);
58         RenderCube();
59     }
60     gl.bindFramebuffer(gl.FRAMEBUFFER, null);
61     gl.enable(gl.DEPTH_TEST);
62 }

FBO与立方体纹理

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

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

 1 function InitSphereShader() {
 2     //WebGLShader
 3     var shader_vertex = GetShader("sphereshader-vs");
 4     var shader_fragment = GetShader("sphereshader-fs");
 5     //WebglCubeProgram
 6     glSphereProgram = gl.createProgram();
 7     gl.attachShader(glSphereProgram, shader_vertex);
 8     gl.attachShader(glSphereProgram, shader_fragment);
 9     gl.linkProgram(glSphereProgram);
10     if (!gl.getProgramParameter(glSphereProgram, gl.LINK_STATUS)) {
11         alert("Shader hava error.");
12     }
13     glSphereProgram.positionAttribute = gl.getAttribLocation(glSphereProgram, "a_position");
14     glSphereProgram.normalAttribute = gl.getAttribLocation(glSphereProgram, "a_normal");
15
16     glSphereProgram.eye = gl.getUniformLocation(glSphereProgram, "eye");
17     glSphereProgram.mapCube = gl.getUniformLocation(glSphereProgram, "mapCube");
18
19     glSphereProgram.model = gl.getUniformLocation(glSphereProgram, "model");
20     glSphereProgram.view = gl.getUniformLocation(glSphereProgram, "view");
21     glSphereProgram.perspective = gl.getUniformLocation(glSphereProgram, "perspective");
22 }
23
24 function InitSphereBuffer() {
25     var radius = 1;
26     var segments = 16;
27     var rings = 16;
28     var length = segments * rings * 6;
29     var sphereData = new Array();
30     var sphereIndex = new Array();
31     for (var y = 0; y < rings; y++) {
32         var phi = (y / (rings - 1)) * Math.PI;
33         for (var x = 0; x < segments; x++) {
34             var theta = (x / (segments - 1)) * 2 * Math.PI;
35             sphereData.push(radius * Math.sin(phi) * Math.cos(theta));
36             sphereData.push(radius * Math.cos(phi));
37             sphereData.push(radius * Math.sin(phi) * Math.sin(theta));
38             sphereData.push(Math.sin(phi) * Math.cos(theta));
39             sphereData.push(radius * Math.cos(phi))
40             sphereData.push(Math.sin(phi) * Math.sin(theta));
41         }
42     }
43     for (var y = 0; y < rings - 1; y++) {
44         for (var x = 0; x < segments - 1; x++) {
45             sphereIndex.push((y + 0) * segments + x);
46             sphereIndex.push((y + 1) * segments + x);
47             sphereIndex.push((y + 1) * segments + x + 1);
48
49             sphereIndex.push((y + 1) * segments + x + 1);
50             sphereIndex.push((y + 0) * segments + x + 1)
51             sphereIndex.push((y + 0) * segments + x);
52         }
53     }
54     sphereVBO = gl.createBuffer();
55     gl.bindBuffer(gl.ARRAY_BUFFER, sphereVBO);
56     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereData), gl.STATIC_DRAW);
57     sphereVBO.numItems = segments * rings;
58     sphereEBO = gl.createBuffer();
59     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereEBO);
60     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(sphereIndex), gl.STATIC_DRAW);
61     sphereEBO.numItems = sphereIndex.length;
62 }
63
64 function RenderSphere() {
65     gl.useProgram(glSphereProgram);
66     gl.bindBuffer(gl.ARRAY_BUFFER, sphereVBO);
67
68     gl.vertexAttribPointer(glSphereProgram.positionAttribute, 3, gl.FLOAT, false, 24, 0);
69     gl.enableVertexAttribArray(glSphereProgram.positionAttribute);
70
71     gl.vertexAttribPointer(glSphereProgram.normalAttribute, 3, gl.FLOAT, false, 24, 12);
72     gl.enableVertexAttribArray(glSphereProgram.normalAttribute);
73
74     var mMatrix = mat4.create();
75     mat4.translate(mMatrix, mMatrix, spherePos);
76     gl.uniform3f(glSphereProgram.eye, eyePos[0],eyePos[1],eyePos[2]);
77     gl.uniformMatrix4fv(glSphereProgram.model, false, mMatrix);
78     gl.uniformMatrix4fv(glSphereProgram.view, false, vMatrix);
79     gl.uniformMatrix4fv(glSphereProgram.perspective, false, pMatrix);
80
81     gl.activeTexture(gl.TEXTURE0);
82     gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTexID);
83     //gl.uniformMatrix4fv(glSphereProgram.mapCube, 0);
84
85     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereEBO);
86     gl.drawElements(gl.TRIANGLES, sphereEBO.numItems, gl.UNSIGNED_SHORT, 0);
87     gl.bindTexture(gl.TEXTURE_2D, null);
88 }

球体

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

 1     <script id="sphereshader-fs" type="x-shader/x-fragment">
 2         precision mediump float;
 3
 4         varying vec3 normal;
 5         varying vec3 eyevec;
 6         uniform samplerCube mapCube;
 7         void main( void )
 8         {
 9         gl_FragColor = textureCube(mapCube, reflect(normalize(-eyevec), normalize(normal)));
10         }
11     </script>
12
13     <script id="sphereshader-vs" type="x-shader/x-vertex">
14         attribute vec3 a_position;
15         attribute vec3 a_normal;
16
17         uniform mat4 model;
18         uniform mat4 view;
19         uniform mat4 perspective;
20         uniform vec3 eye;
21
22         varying vec3 normal;
23         varying vec3 eyevec;
24
25         void main( void )
26         {
27         gl_Position = perspective * view * model * vec4(a_position,1.0);
28         eyevec = -eye;// a_position.xyz;
29         normal = a_normal;
30         }
31     </script>

球体着色器

  和前面立方体有点不同的是,球体有自己的模型矩阵,这也是一般正常的用法,然后传递眼睛对应球体顶点矢量与法线传递在片断着色器中,在片断着色器中,就有用到前面所生成的立方体纹理,我们根据眼睛经过顶点通过对应法向量反射到立体体纹理上的点来获取当前球体所对应的环境颜色,在这里,我们可以直接调用textureCube来完成上面所说的过程,不需要我们手动来计算。

其中GetShader函数的使用,参照了http://msdn.microsoft.com/zh-TW/library/ie/dn302360(v=vs.85) 这里的讲解。

  可以说,上面主要的绘制函数已经完成,但是我们这个是能动的,所以需要模拟如客户端环境每隔多久绘制一次,主要代码如下:

 1 function tick() {
 2     Update();
 3     OnDraw();
 4     setTimeout(function () { tick() }, 15);
 5 }
 6 function OnDraw() {
 7     //fbo rander CUBE_MAP
 8     RenderFBO();
 9     //element rander
10     gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
11     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
12     mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 200.0);
13     mat4.lookAt(vMatrix, eyePos, eyeLookat, vec3.fromValues(0.0, 1.0, 0.0));
14     RenderCube();
15     RenderSphere();
16 }
17
18 var lastTime = new Date().getTime();
19 function Update() {
20     var timeNow = new Date().getTime();
21     if (lastTime != 0) {
22         var elapsed = timeNow - lastTime;
23         //3000控制人眼的旋转速度。8控制人眼的远近
24         eyePos[0] = Math.cos(elapsed / 3000) * 8;
25         eyePos[2] = Math.sin(elapsed / 2000) * 8;
26
27         spherePos[0] = Math.cos(elapsed / 4000) * 3;
28         spherePos[2] = Math.cos(elapsed / 4000) * 3;
29     }
30
31 }

动画

  在上面,每隔15毫秒调用一次Update与Draw函数,其中Update用于更新眼睛与球体位置,Draw绘画。

  有二年没做网页上的开发,可能其中javascript的用法让大家见笑了,动态语言实在太自由了,反而不好写。

  源代码

  在新的一年的第一天,祝大家事事如意。

  

转载于:https://www.cnblogs.com/zhouxin/p/3500926.html

WebGL 利用FBO完成立方体贴图。相关推荐

  1. LearnOpenGL->立方体贴图

    立方体贴图 立方体贴图 在本节中,我们将讨论的是将多个纹理组合起来映射到一张纹理上的一种纹理类型:立方体贴图(Cube Map). 简单来说,立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都 ...

  2. OpenGL 核心技术之立方体贴图

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  3. dx12 龙书第十八章学习笔记 -- 立方体贴图

    本章讨论:立方体贴图 cube map,即以特殊的方式来运用这种由6个纹理所构成的基本数组.我们可以利用这项技术方便地映射天空纹理或模拟反射. 1.什么是立方体贴图 -- Cube Map 立方体贴图 ...

  4. QT之OpenG立方体贴图

    QT之OpenGL立方体贴图 1. 概述 2. 绘制天空盒 2.1 demo 3. 环境映射 3.1 反射 3.1.1 demo 3.1.2 3.2 折射 3.2.1 demo 4. 反射纹理 4.1 ...

  5. LearnOpenGL 高级OpenGL—立方体贴图

    文章目录 写在前面 立方体贴图 创建立方体贴图 天空盒 加载天空盒 显示天空盒 优化 环境映射 反射 折射 动态环境贴图 总结 写在前面 原文链接.原文应该是github上的一个项目,本文主要用来记录 ...

  6. LearnOpenGL学习笔记——立方体贴图

    立方体贴图 在本节中,我们将讨论的是将多个纹理组合起来映射到一张纹理上的一种纹理类型:立方体贴图(Cube Map).简单来说,立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的 ...

  7. 立方体贴图 Cubemap

    1. 立方体贴图 Cubemaps 1.1 创建立方体贴图 2. 天空盒 Skybox 2.1 加载天空盒 2.2 显示天空盒 2.3 优化 2.4 整体代码 3. 环境映射 Environment ...

  8. 【OpenGL】笔记二十四、立方体贴图

    1. 流程 之前我们使用了不少2D形式的贴图,那么现在有没有其他类型的贴图呢?当然有,比如立方体贴图,它就是由6个2D贴图组合而成的: 那么为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独的 ...

  9. 基于CUDA实现立方体贴图 (Cubemaps) 转换为全景图 (Equirectangular Panorama)

    在立方体贴图空间内发射光线(视线),计算球面光线(视线)会击中哪个面的哪个像素的像素值,最终生成Equirectangular全景图. InitSceneTexture():先获取Cubemaps并将 ...

最新文章

  1. mybatis there is no getter named forInteger
  2. Easyspy网络检测系统
  3. 推荐一个 Java 接口快速开发框架,超级nice!
  4. Javascript实现页面跳转传值示例Demo
  5. c语言单片机串口通讯,单片机C语言之串口通信协议
  6. 程序员玩连连看的正确姿势
  7. gg修改器ios版下载
  8. python安卓脚本精灵使用教程_按键精灵安卓按键初体验—乱斗西游2自动签到
  9. 新颖的自我介绍_有创意的自我介绍模板(精选6篇)
  10. orbslam2 流程图_一种基于ORBSLAM2的八叉树建图方法与流程
  11. 在RHEL6上针对rm命令做审计
  12. 设计模式之工厂模式(C++)
  13. 怎么给图片添加贴纸?介绍几个简单的方法
  14. 【附源码】计算机毕业设计JAVA中国历史网站
  15. 数据库大表如何优化?
  16. 编写并调用平均值函数
  17. 怎么在b站引流?b站怎么吸粉?b站引流技巧和方法
  18. Java 使用word模板创建word文档报告教程
  19. 微信小程序:更改页面背景颜色
  20. git rebase和git merge使用方法详解

热门文章

  1. nutch开发(二)
  2. hadoop集群swap_性能瓶颈--MEM(swap)
  3. php分布式数据一致性,如何解决分布式系统数据事务一致性问题
  4. md5课程设计java_MD5算法的JAVA实现
  5. 个人博客代码_Solo小众开源博客系统:手把手教你搭建自己的博客系统
  6. dev 居中_div居中 div水平居中代码 | 帮助信息-动天数据
  7. Apache Flink 零基础入门(九)Flink支持哪些数据类型
  8. CentOS6.7安装scala2.11.7
  9. 自然语言处理之循环神经网络(五)
  10. 一个小小指针,竟把Linux内核攻陷了!