美文网首页
OpenGL ES 光照计算

OpenGL ES 光照计算

作者: 紫水依 | 来源:发表于2019-07-15 18:38 被阅读0次
  • 光照计算在片元着色器执行,计算每一个像素点的颜色

一、光照计算

1、环境光计算

环境光 = 光源的环境光颜色 * 物体的材质颜色

  • 环境光 = 光的颜色 * 材质颜色;
    光是有颜色的,比如红光、绿光等;
    材质颜色也就是纹理颜色。

2、发射光的计算

发射颜色 = 物体的反射材质颜色

  • 物体本身是有颜色的,比如手电筒,其本身能发光,发出的光的颜色就是发射颜色。

3、漫反射光照计算

  • 光照有阴面和阳面,由法线计算光与物体之间的夹角,这个夹角分为入射角和反射角

漫反射颜色 = 光源的漫反射颜色 * 物体的漫反射材质颜色 * DiffuseFactor

DiffuseFactor = max(0, dot(N, L));

  • 漫反射因子DiffuseFactor 是光线与顶点法线向量的点积,是光线与法线之间的夹角,其值不能小于0

4、镜面光计算

镜面反射颜色 = 光源的镜面光颜色 * 物体的镜面材质颜色 * SpecularFactor

SpecularFactor = power(max(0, dot(N, H)), shininess);
H:视线向量E 与光线向量L 的半向量
dot(N, H):H,N的点积几何意义,平方线与法线夹角的cos值
shininess:高光的反光度

  • 镜面因子SpecularFactor,shininess反光度越小光照越集中

5、普通光照计算

光照颜色 = (环境颜色 + 漫反射颜色 + 镜面反射颜色) * 衰减因子

衰减因子计算

衰减因子 = 1.0 / (距离衰减常量 + 线性衰减常量 * 距离 + 二次衰减常量 * 距离的平方)
距离衰减常量、线性衰减常量和二次衰减常量均为常量值

tips:环境光、漫反射光和镜面光的强度都会受距离的增大而衰减,只有发射光和全局环境光的强度不会受影响

6、聚光灯因子

聚光灯夹角cos值 = power(max(0, dot(单位光源位置, 单位光线向量)), 聚光灯指数);

单位光线向量:是从光源指向顶点的单位向量
聚光灯指数:表示聚光灯的亮度程度
公式解读:单位光源位置 * 单位光线向量 点积 的 聚光灯指数次方

  • 增加过渡计算
    聚光灯因子 = clamp((外环的聚光灯角度cos值 - 当前顶点的聚光灯角度cos值) / (外环的聚光灯角度cos值 - 内环聚光灯的角度cos值), 0.1);

7、光照计算终极公式

光照颜色 = 发射颜色 + 全局环境颜色 + (环境颜色 + 漫反射颜色 + 镜面颜色) * 聚光灯效果 * 衰减因子

平面光终极公式

  • 平面光也就是平行光,没有具体的方向

点光源终极公式

  • 比如灯泡光源,点光源是有方向的

二、光照的GLSL实现

1、环境光的GLSL实现

varying vec3 objectColor;
void main() {

    //至少有10%的光照到物体所有面
    float ambientStrength = 0.1;

    //环境光颜色 = 环境光比率 * 环境光颜色
    vec3 ambient = ambientStrength * lightColor;

    //最终颜色 = 环境光颜色 * 物体颜色
    vec3 result = ambient * objectColor;
    //vec3转化成vec4
    gl_FragColor = vec4(result, 1.0);

}

2、漫反射光的GLSL实现

uniform vec3 lightColor;     //光源颜色
uniform vec3 lightPo;         //光源位置
uniform vec3 objectColor; //物体颜色
uniform vec3 viewPo;        //物体位置
varying vec3 outNormal;  //传入当前顶点平面的法向量

//确保法线为单位向量,normalize为内建函数,把法向量转换成单位向量
vec3 norm = normalize(outNormal);
//顶点指向光源的单位向量
vec3 lightDir = normalize(lightPo -   FragPo);
//得到两向量的cos值,小于0则为0
float diff = max(dot(norm, lightDir), 0.0);
//夹角乘以光照颜色得到漫反射的光源向量
vec3 diffuse = diff * lightColor;

vec3 result = diffuse * objectColor;
gl_FragColor = vec4(result, 1.0);

3、镜面光的GLSL实现

//镜面强度
float specularStrength = 0.5;

//顶点指向观察点的单位向量
vec3 viewDir = normalize(viewPo - FragPo);

//光线在顶点的反射线(传入光源指向顶点的向量),镜面光是反方向的光线
vec3 reflectDir = reflect(-lightDir, outNormal);

//夹角cos值,取256次幂,镜面因子
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 256.0);

vec3 specular = specularStrength * spec * lightColor;

4、衰减因子计算

//距离衰减常量
float constantPara = 1.0;
//线性衰减常量
float linearPara = 0.09;
//二次衰减因子
float quadraticPara = 0.032;
//距离
float lightWeakPara = 1.0/(constantPara + linearPara * LFDistance + quadraticPara * (LFDistance * LFDistance));

5、聚光灯过渡计算

//一些复杂的计算操作应该让CPU做以提高效率,不变的量也建议外部传输,避免重复计算
//内锥角cos值
float inCutoff = cos(radians(10.0));
//外锥角cos值
float outCutoff = cos(radians(15.0));
//聚光朝向
vec3 spotDir = vec3(-1.2, -1.0, -2.0);

//光源指向物体的向量和聚光朝向的cos值
float theta = dot(lightDir, normalize(-spotDir));
//内外锥角cos差值
float epsilon = inCutoff - outCutoff;

//clamp(a, b, c);若b<a<c则函数返回a,若不是则返回最小b,最大c
/*(theta - outCutoff)/epsilon 若theta的角度小于内锥角则其值>=1,
若theta的角度大于外锥角则其值<=0,这样光线就在内外锥角之间平滑变化*/
float intensity = clamp((theta - outCutoff) / epsilon, 0.0, 1.0);

相关文章

  • OpenGL ES光照计算

    光照是OpenGL ES里很重要的一部分,下面我们来学习总结一下如何计算不同的光照效果。 光照基础1、环境光照2、...

  • OpenGL ES 􏳆􏰤􏷐􏶾􏲗􏵘光照计算

    光照基础 环境光 漫反射光 镜面光 光照特性 发射光:由物体自身发光 环境光:环境中充分散射的光,而且无法分辨它的...

  • OpenGL ES光照计算

    光照基础 环境光照:利用环境光可以描述一块区域的亮度,通常在场景中,环境光的颜色是一个常量 漫反射光照:光线向所有...

  • OpenGL ES 光照计算

    冯氏光照模型:主要结构由3个元素组成:环境(Ambient)光照、漫反射(Diffuse)光照和镜面(Specul...

  • OPenGL ES光照计算

    现实世界的光照是极其复杂的,而且会受到诸多因素的影响,这是以目前我们所拥有的处理能力无法模拟的。因此OpenGL的...

  • OpenGL ES 光照计算

    光照计算在片元着色器执行,计算每一个像素点的颜色 一、光照计算 1、环境光计算 环境光 = 光源的环境光颜色 * ...

  • OpenGL ES 光照计算

    光照基础 1.环境光照(ambient) 2.漫反射光照(diffuse) 3.镜面光照(specular) 光照...

  • OpenGL ES之旅(四)-- OpenGL ES 光照计算

    光照是个很复杂的话题,尤其是多光源,阴影的计算。在这篇文章中,我会详细介绍不同类型光的性质以及物体的材质属性,以及...

  • OpenGL ES(八)-光照计算

    光照基础 从生理学的角度上讲,眼睛之所以看见各种物体,是因为光线直接或间接的从它们那里到达了眼睛。人类对于光线强弱...

  • OpenGL ES 关于光照计算

    有关光照的代码公式, 在此用CC老师已经写好的代码做一个记录, 方便以后使用的时候查询. 记录一个函数-->根据你...

网友评论

      本文标题:OpenGL ES 光照计算

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