美文网首页
OpenGL ES 光照模型(一)

OpenGL ES 光照模型(一)

作者: ZerLon51 | 来源:发表于2017-05-10 23:27 被阅读0次

关于光照模型的总结,我就不一一细谈了,一是自己记不住那么多,二呢,我觉得知识还是要实践为主。所以以下的东西主要针对编程而言的,不会涉及很综合深刻的讲解。照例最后可以猛戳下载代码。
1.漫反射
漫反射光大概就是从光源照射到物体表面,不考虑人的观察视角与反射的角度形成的光源强弱差别,而只考虑光源入射角和顶点法线的夹角,在各个方向上均等的反射光线的一种光。
假设Ld表示光源强度,Kd表示某个物体的反射系数,那么漫反射公式就是
Ia = Ld * Kd * cos(b)
如下图


漫反射

那么s和n的点乘就表示夹角的cos了(有疑惑的翻翻几何课本),于是就有公式如下


漫反射公式

有了这个公式,我们愉快的开始写代码吧!

attribute vec3 vertPosition; // Vertex position
attribute vec3 vertNorm; // Vertex normal

varying vec3 lightIntensity; // Light intensity

uniform vec3 lightPosition; // Light position in eye - coordinate
uniform vec3 Kd; // Reflect of diffuse light
uniform vec3 Ld; // Intensity of light

uniform mat3 normMat; // matrix of normal
uniform mat4 modelview; // matrix of modelview
uniform mat4 projection; // matrix of projection

void main() {
    // Convert normal and position to eye coord
    vec3 tnorm = normalize(normMat * vertNorm);
    vec3 eyecoord = vec3(modelview * vec4(vertPosition, 1.0));
    vec3 s = normalize(lightPosition - eyecoord);
    
    // The diffuse shading equation
    lightIntensity = Ld * Kd * max(dot(s, tnorm), 0.0);
    
    gl_Position = projection * modelview * vec4(vertPosition, 1.0);
}

接下来,说代码吧。
前两行的attribute变量用于定义顶点坐标和顶点法线,也就是我们届时要输入的值。这里一定要注意,这个shader文件里的处理流程是逐顶点的,就是每次处理一个顶点变换。
然后定义一个varying输出变量,一会儿在fragment shader中要用到的。
之后是光源坐标Position,这里已经转换为观察坐标了,你也可以在shader里面转换。然后就是光照强度La,反射系数Kd。
接着定义了法线变换矩阵。这个东西简单讲一下。


我扣的图
类似于图中的法线,在图被拉伸(还有旋转什么的,法线要跟着顶点动才对)了之后,法线的方向就错了,因此需要法线矩阵来变换一下。法线矩阵的推导公式就不列出来了,线性代数我还在复习,也讲不太好,网上有不少资料,能看懂就好了。刚体变换就用观察矩阵modelview的左上角3x3就可以了。
然后定义了观察变换矩阵和投影变换矩阵。
然后,鸡冻人心的时刻就到了。
首先我们用法线矩阵变换顶点法向量,观察矩阵变换顶点坐标

    vec3 tnorm = normalize(normMat * vertNorm);
    vec3 eyecoord = vec3(modelview * vec4(vertPosition, 1.0));

然后计算指向光源坐标的向量,并且归一化

    vec3 s = normalize(lightPosition - eyecoord);

接着,就要用到我们上面的公式了

    lightIntensity = Ld * Kd * max(dot(s, tnorm), 0.0);

这个lightIntensity一会儿就是我们计算出来的顶点颜色。
接下来,使用gl_Position输出最终经过观察->投影变换后的顶点坐标

    gl_Position = projection * modelview * vec4(vertPosition, 1.0);

至此,顶点shader的工作就完成了。

然后开始处理片段shader了。
上代码

precision mediump float;

varying vec3 lightIntensity;

void main() {
    gl_FragColor = vec4(lightIntensity, 1.0);
}

其中定义的varying vec3 lightIntensity就是我们在vertex shader中计算出来的光照后的顶点颜色值。最终赋值给gl_FragColor,就是顶点的最后颜色了。
然后让程序跑起来,最终结果如下

渲染结果

另外代码中的ToyMater/ToyTest目录下是测试用的,可以很方便的修修改改的来测试。

猛戳代码

相关文章

  • OpenGL ES 光照模型(一)

    关于光照模型的总结,我就不一一细谈了,一是自己记不住那么多,二呢,我觉得知识还是要实践为主。所以以下的东西主要针对...

  • OpenGL ES(五) 光照

    在OpenGL ES中光照模型主要结构由3个元素组成:环境(Ambient)光照、漫反射(Diffuse)光照和镜...

  • OpenGL ES 光照模型(二)

    OpenGL固定管线中默认的光照类似于将三种光照分量组合起来:环境光+漫反射+镜面反射。其中漫反射之前就说过了。环...

  • OpenGL ES 光照

    冯氏光照 冯氏光照模型(Phong Lighting Model))的主要结构由3个分量组成:环境(Ambient...

  • OpenGL/OpenGL ES (九) —— 光照

    OpenGL/OpenGL ES (一) —— 专业名词快速了解OpenGL/OpenGL ES (二) —— 渲...

  • shader光照和阴影

    一.标准光照模型OpenGL与Direct3D提供了几乎相同的固定功能光照模型。什么是固定功能光照模型?在过去只有...

  • OpenGL学习9——基本光照

    OpenGL的一种光照模型:冯氏光照模型(Phong lighting model),主要包含3个分量:环境光(a...

  • 理解 RGB & YUV 颜色编码

    OpenGL + OpenGL ES +Metal 系列文章汇总 RGB 和 YUV 都是色彩空间模型,下面来分别...

  • OpenGL光照(冯氏光照模型)

    1、OpenGL最容易理解和实现的就是冯氏光照模型了。冯氏光照模型的主要结构由3个元素组成:环境(Ambient)...

  • 02总结--014--OpenGL ES 初识

    OpenGL ES 初识 OpenGL ES 简介 OpenGL ES (OpenGL for Embedded ...

网友评论

      本文标题:OpenGL ES 光照模型(一)

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