OpenGL

iOS-OpenGLES-进阶-基础光照

2019-05-20  本文已影响0人  夜半敲门话不语

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

概述

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


环境光照

环境光照场景相对比较简单。我们用光的颜色乘以一个常量环境因子,再跟乘以物体本身颜色,最终效果就是环境光照。片段如下:

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应该比较好理解。
上一篇 下一篇

猜你喜欢

热点阅读