这是一篇OpenGlES 系统学习教程,记录自己的学习过程。
环境: Xcode10.2.1 + OpenGL ES 3.0
目标: 基础光照
代码已上传github
,Tutorial-07-光照,你的star和fork是对我最好的支持和动力。
概述
现实世界的光照是极其复杂的,OpenGlES也只是使用简单的光照模型。其中一个模型被称为冯氏光照。冯氏光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子:
-
环境光照
(Ambient Lighting):即使在黑暗的情况下,世界上通常也仍然有一些光亮(月亮、远处的光),所以物体几乎永远不会是完全黑暗的。为了模拟这个,我们会使用一个环境光照常量,它永远会给物体一些颜色。 -
漫反射光照
(Diffuse Lighting):模拟光源对物体的方向性影响(Directional Impact)。它是冯氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源,它就会越亮。 -
镜面光照
(Specular Lighting):模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。
环境光照
环境光照场景相对比较简单。我们用光的颜色乘以一个常量环境因子,再跟乘以物体本身颜色,最终效果就是环境光照。片段如下:
void main(void) {
lowp vec4 AmbientColor = vec4(u_Light.Color, 1.0) * u_Light.AmbientIntensity;
gl_FragColor = texture2D(u_Texture, frag_TexCoord) * AmbientColor;
}
效果
漫反射光照
顶点:
void main(void) {
frag_TexCoord = a_TexCoord;
frag_Normal = vec3(u_modelMatrix * vec4(a_Normal, 0.0));
frag_Pos = vec3(u_modelMatrix * vec4(a_Position, 1.0));
gl_Position = u_modelMatrix * vec4(a_Position, 1.0);
}
片段:
void main(void) {
// Ambient
lowp vec3 AmbientColor = u_Light.Color * u_Light.AmbientIntensity;
// Diffuse
lowp vec3 Normal = normalize(frag_Normal);
lowp vec3 lightDir = normalize(u_Light.LightPos - frag_Pos);
lowp float DiffuseFactor = max(-dot(Normal, lightDir), 0.0);
lowp vec3 DiffuseColor = u_Light.Color * u_Light.DiffuseIntensity * DiffuseFactor;
gl_FragColor = texture2D(u_Texture, frag_TexCoord) * vec4((AmbientColor + DiffuseColor), 1.0);
}
注意:法向量需要转换到世界坐标。
镜面光照
片段:
void main(void) {
// Ambient
lowp vec3 AmbientColor = u_Light.Color * u_Light.AmbientIntensity;
// Diffuse
lowp vec3 Normal = normalize(frag_Normal);
lowp vec3 lightDir = normalize(u_Light.LightPos - frag_Pos);
lowp float DiffuseFactor = max(-dot(Normal, lightDir), 0.0);
lowp vec3 DiffuseColor = u_Light.Color * u_Light.DiffuseIntensity * DiffuseFactor;
// Specular
lowp vec3 Eye = normalize(frag_Pos);
lowp vec3 Reflection = reflect(-lightDir, Normal);
lowp float SpecularFactor = pow(max(0.0, dot(Reflection, Eye)), u_Light.Shininess);
lowp vec3 SpecularColor = u_Light.Color * u_Light.SpecularIntensity * SpecularFactor;
gl_FragColor = texture2D(u_Texture, frag_TexCoord) * vec4((AmbientColor + DiffuseColor + SpecularColor), 1.0);
}
效果
注:更多细节和理论知识可以去这里查看,结合
demo
应该比较好理解。