iOS-OpenGLES-进阶-基础光照

这是一篇OpenGlES 系统学习教程,记录自己的学习过程。
环境: Xcode10.2.1 + OpenGL ES 3.0
目标: 基础光照
代码已上传github,Tutorial-07-光照,你的star和fork是对我最好的支持和动力。

概述

现实世界的光照是极其复杂的,OpenGlES也只是使用简单的光照模型。其中一个模型被称为冯氏光照。冯氏光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子:


iOS-OpenGLES-进阶-基础光照_第1张图片
  • 环境光照(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;
}

效果

iOS-OpenGLES-进阶-基础光照_第2张图片

漫反射光照

顶点:

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);
}

效果

iOS-OpenGLES-进阶-基础光照_第3张图片

注:更多细节和理论知识可以去 这里查看,结合 demo应该比较好理解。

你可能感兴趣的:(iOS-OpenGLES-进阶-基础光照)