Writing ESSL programs
让我们回头来看看全景图。ESSL使得我们可以在有着着色方式和光线反射模型的前提下实现照明策略。 在朗博反射模型下的高洛德着色。在这一部分,我们将一个球体作为我们想要照亮的对象,我们将会看到 灯光策略的选择如何改变场景。
我们将看到Goraud插值方式下的两种情况:Lambertian反射和Phong反射;以及一种情况下的Phong插值方式:在phone着色下的Lambertian反射模型与Phong反射模型没有什么不同,因为环境和镜面分量被设置为零。
Goraud shading with Lambertian reflections
Lambertian反射模型只考虑了漫反射物质的相互作用漫射光属性。简而言之,我们将final color赋值为:
Final Vertex Color = Id
其中值如下所示:
Id = Light Diffuse Property * Material Diffuse Property * Lambert coefficient
在Goraud着色下,通过计算顶点向量和光方向向量的逆向量的点积得到的Lambert系数。在在求点积之前两个向量都经过标准化的。
现在让我们来看看ch3_Sphere_Goraud_Lambert.html文件中顶点着色器和片元着色器代码:
顶点着色器:
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uNMatrix;
uniform vec3 uLightDirection;
uniform vec4 uLightDiffuse;
uniform vec4 uMaterialDiffuse;
varying vec4 vFinalColor;
void main(void) {
vec3 N = normalize(vec3(uNMatrix * vec4(aVertexNormal, 1.0)));
vec3 L = normalize(uLightDirection);
float lambertTerm = dot(N,-L);
vec4 Id = uMaterialDiffuse * uLightDiffuse * lambertTerm;
vFinalColor = Id;
vFinalColor.a = 1.0;
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
}
片元着色器:
#ifdef GL_ES
precision highp float;
#endif
varying vec4 vFinalColor;
void main(void) {
gl_FragColor = vFinalColor;
}
我们可以看到,我们在顶点着色器中处理的最终顶点颜色通过varying变量被传递进片元(像素)着色器。但是,请记住这个到达片元着色器的值不是我们在顶点着色器中计算的原始值。片元着色器插入vFinalColor变量来生成对应片元的最终颜色。这个插值考虑到了靠近当前片元的顶点如我们在第二章中所示。
Time for action – updating uniforms in real time
- 打开ch3_Sphere_Goraud_Lambert.html文件
- 您将看到这个示例在页面底部有一些小部件。这些小部件是使用JQuery UI创建的。你可以在HTML文件中的
<body>部分查看这些代码
- X,Y,Z: 控制光线的方向。滑动滑块控制uniform变量 uLightDirection.
- 球体颜色:改变代表着球体漫反射颜色的uniform变量uMaterialDiffuse。这里我们使用颜色选择器来控制,这样你可以尝试不同的颜色。updateObjectColor函数接收从颜色选择器传来的数据并更新uMaterialDiffuse变量。
- Light diffuse term:改变代表着光源的漫反射光的uLightDiffuse变量。