WebGL学习随手记(一)

Shader

varying : vs 的输出, fs 的输入(在光栅化时进行了图元内线性插值)。在 vs,fs 中的声明必须一致。

uniform :应用程序通过通过OpenGL ES 2.0 API 传送给 shader 的只读变量 ;uniform 在 programobject 中是共享的,即一个 programobject 只有一组 uniforms 。如果 uniform 同时在 vs 和 fs 中声明,必须具有相同的类型,并且在这两个 shader 中该 uniform 的值是一样的。在 link 时, linker 会为 program 中的每个 activeuniform 分配一个 uniformlocation 。应用程序使用这个 uniformlocation 作为标识来载入 uniform 的值。

attribute :只在vs中使用,用于指定per-vertex的输入。通常保存位置,法线,纹理坐标,颜色等数据。

WebGL渲染流程

JavaScript定义顶点/颜色等值→绑定到uniform和attribute变量上→提交到vertexShader中→顶点Shader进行差值处理→得到Varying变量→提交到fragmentShader中→最后进行片元处理。

WebGL学习随手记(一)

灯光渲染

疑问1:

shader-vs中

float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
疑问2:

setMatrixUniforms()中

        var normalMatrix = mat3.create();
        mat4.toInverseMat3(mvMatrix, normalMatrix);
        mat3.transpose(normalMatrix);
        gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);

第13章 片元级光照与多program对象

其中片元级光照的实现,是要对法线进行处理,如果法线和光线平行,那应该是最亮的,如果夹角越大,光线会越暗。

WebGL学习随手记(一)

在左边的图中,B点将会相当明亮,因为B点的光线几乎是平行于法线的;而A点则会稍微暗一些,因为光线的入射角更大一些。在A点和B点之间的点,将会有一个从明到暗的渐变。这个效果看起来非常好。

WebGL学习随手记(一)

右图中的那样。A点和C点都会比较暗,因为光线的入射角更大。假设我们仍然使用逐顶点光照,那么B点的明亮程度应该是A点和C点的平均值,所以B点也同样会比较暗。但是,这很明显是错误的!在B点,光线几乎是平行于法线的,所以它应该是其中最明亮的一个点。所以在计算顶点之间的片元光照时,我们必须逐个片元、逐个片元的单独进行计算。

函数回顾:

提交 uniform

a)    

gl.uniform1i(shaderProgram.useLightingUniform, lighting);

b)    

gl.uniform3f(
                shaderProgram.ambientColorUniform,
                parseFloat(document.getElementById("ambientR").value),
                parseFloat(document.getElementById("ambientG").value),
                parseFloat(document.getElementById("ambientB").value)
        );

c)  

gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD);

 

d)   

gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);

f)    

gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);

处理纹理

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, crateTexture);
gl.uniform1i(shaderProgram.samplerUniform, 0);

处理Buffer

gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
 

索引绑定

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,cubeVertexIndexBuffer);
gl.drawElements(gl.TRIANGLES,cubeVertexIndexBuffer.numItems,gl.UNSIGNED_SHORT,0);

美轮美奂的高光效果

相关推荐