美文网首页OpenGL
iOS-OpenGLES-进阶-基础光照

iOS-OpenGLES-进阶-基础光照

作者: 夜半敲门话不语 | 来源:发表于2019-05-20 19:19 被阅读0次

这是一篇OpenGlES 系统学习教程,记录自己的学习过程。
环境: Xcode10.2.1 + OpenGL ES 3.0
目标: 基础光照
代码已上传githubTutorial-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应该比较好理解。

相关文章

网友评论

    本文标题:iOS-OpenGLES-进阶-基础光照

    本文链接:https://www.haomeiwen.com/subject/cvmhzqtx.html