0
点赞
收藏
分享

微信扫一扫

《WebGL编程指南》笔记

三维控件研究 2022-01-27 阅读 35

这里首先贴出其第三章绘制正方形代码的简化版本(为了阅读流畅性,去除了一些错误判断):

var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '}\n';

var FSHADER_SOURCE =
  'void main() {\n' +
  '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
  '}\n';

function main() {
  var canvas = document.getElementById('webgl');
  var gl = getWebGLContext(canvas);
  initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);
  var n = initVertexBuffers(gl);

  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}

function initVertexBuffers(gl) {
  var vertices = new Float32Array([-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,-0.5]);
  var n = 4;
  var vertexBuffer = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(a_Position);
  return n;
}

下面对代码中的一些关键点做个解释:

//-------------------------------------------------------------------------------------------------------------------------------

gl.clear(gl.COLOR_BUFFER_BIT);

这行代码的意思是清除缓冲区,参数可以是一下三种

        gl.COLOR_BUFFER_BIT        指定颜色缓存

        gl.DEPTH_BUFFER_BIT        指定深度缓冲区

        gl.STENCIL_BUFFER_BIT        指定模板缓冲区

使用位操作符or(|)可用来清空多个缓冲区。

//-------------------------------------------------------------------------------------------------------------------------------

 var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

这行代码的意思是获取字符串'a_Position'参数指定的gl.program着色器对象中的attribute变量存储地址。与此类似的是下面这行代码:

var u_FragColor=gl.getUniformLocation(gl.program,'u_FragColor');

它的意思是获取字符串'au_FragColor参数指定的gl.program着色器对象中的uniform变量存储地址。

需要说明的是在shader中有三种变量类型,分别是attribute、uniform和varying。分别介绍如下:

 1.attribute变量是只能在vertex着色器中使用的变量。(它不能在fragment着色器中声明attribute变量,也不能被fragment着色器中使用),一般用attribute变量来表示一些顶点的数据,如:顶点坐标,法线,纹理坐标,顶点颜色等。在application中,一般用函数glBindAttribLocation()来绑定每个attribute变量的位置,然后用函数glVertexAttribPointer()为每个attribute变量赋值。使用参考如下:

uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
void main(void)
{
    gl_Position = u_matViewProjection * a_position;
    v_texCoord = a_texCoord0;
}

2.uniform变量在vertex着色器和fragment着色器两者之间声明方式完全一样,则它可以在vertex着色器和fragment着色器共享使用(相当于一个被vertex着色器和fragment着色器共享的全局变量),uniform变量一般用来表示:变换矩阵,材质,光照参数和颜色等信息。使用参考如下: 

uniform mat4 viewProjMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

3.varying变量
varying变量是vertex和fragment shader之间做数据传递用的。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。其在Vertex着色器中使用参考如下:

uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
void main(void)
{
    gl_Position = u_matViewProjection * a_position;
    v_texCoord = a_texCoord0;
}

其在Fragment着色器中使用参考如下:

precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_baseMap;
uniform sampler2D s_lightMap;
void main()
{
    vec4 baseColor;
    vec4 lightColor;
    baseColor = texture2D(s_baseMap, v_texCoord);
    lightColor = texture2D(s_lightMap, v_texCoord);
    gl_FragColor = baseColor * (lightColor + 0.25);
}

//-------------------------------------------------------------------------------------------------------------------------------

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

这行代码的意思是绑定缓冲区,函数原型是gl.bindBuffer(target,buffer)。

其中target可以是下面两种:

        gl.ARRAY_BUFFER  表示缓冲区对象包含了顶点的数据。

        gl.ELEMENT_ARRAY_BUFFER   表示缓冲区对象中包含顶点的索引值。

buffer指定之前由gl.creareBuffer返回的待绑定的缓冲区对象,如果指定为null,则禁用对target的绑定。

//-------------------------------------------------------------------------------------------------------------------------------

 gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

举报

相关推荐

0 条评论