美文网首页
OpenGL ES 关于光照计算

OpenGL ES 关于光照计算

作者: 为了自由的白菜 | 来源:发表于2020-08-28 16:27 被阅读0次

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

记录一个函数-->根据你的设置返回一个4x4矩阵变换的世界坐标系坐标。

//获取世界坐标系去模型矩阵中.  
    /*  
     LKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,  
     float centerX, float centerY, float centerZ,  
     float upX, float upY, float upZ)  
     等价于 OpenGL 中  
     void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);  
     
     目的:根据你的设置返回一个4x4矩阵变换的世界坐标系坐标。  
     参数1:眼睛位置的x坐标  
     参数2:眼睛位置的y坐标  
     参数3:眼睛位置的z坐标  
     第一组:就是脑袋的位置  
     
     参数4:正在观察的点的X坐标  
     参数5:正在观察的点的Y坐标  
     参数6:正在观察的点的Z坐标  
     第二组:就是眼睛所看物体的位置  
     
     参数7:摄像机上向量的x坐标  
     参数8:摄像机上向量的y坐标  
     参数9:摄像机上向量的z坐标  
     第三组:就是头顶朝向的方向(因为你可以头歪着的状态看物体)  
     */  
    
    GLKMatrix4 view1 = GLKMatrix4MakeLookAt(camX,camX,camZ,0,0,0,0,1,0);  

其中注意 in out 相对应的输入输入属性写法, 其实与attribute varying的意思是一样的, 注意此处的写法
以及在外部的使用与attribute varying的区别

    glEnableVertexAttribArray(0);  
    glEnableVertexAttribArray(1);  
    glEnableVertexAttribArray(2);  
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)NULL);  
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(3*sizeof(float)));  
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float)));  
  • 顶点着色器相应代码 (在此的作用 主要用来相应解释片元着色器代码)
#version 300 es  

layout(location = 0) in vec3 position;  //顶点  
layout(location = 1) in vec3 normal;    //法向量  
layout(location = 2) in vec2 texCoord;  //纹理坐标  

uniform mat4 view;  
uniform mat4 projection;  

out vec3 outNormal; //法向量  
out vec3 FragPo;    //顶点在世界坐标位置  
out vec2 outTexCoord;//纹理坐标  

void main()  
{  

    FragPo = position;  
    outNormal = normal;  
    outTexCoord = texCoord;  
    gl_Position = projection * view * vec4(position,1.0);  
    
}  
  • 重点查看片元着色器中 光线的计算公式
#version 300 es  

precision mediump float;  
out vec4 FragColor;  

uniform vec3 lightColor;    //光源颜色  
uniform vec3 lightPo;       //光源位置  
uniform vec3 viewPo;        //视角位置  
uniform sampler2D Texture;          //物体纹理  
uniform sampler2D specularTexture;  //镜面纹理  

in vec2 outTexCoord;    //纹理坐标  
in vec3 outNormal;      //顶点法向量  
in vec3 FragPo;         //顶点坐标  

//点光源版本
void pointLight(){
    
    float ambientStrength = 0.3;    //环境因子  
    float specularStrength = 2.0;   //镜面强度  
    float reflectance = 256.0;      //反射率  

    float constantPara = 1.0f;     //距离衰减常量  
    float linearPara = 0.09f;      //线性衰减常量  
    float quadraticPara = 0.032f;  //二次衰减常量  

    //环境光 = 环境因子 * 物体的材质颜色  
    vec3 ambient = ambientStrength * texture(Texture,outTexCoord).rgb;  

    //漫反射
    vec3 norm = normalize(outNormal);  
    //当前顶点 至 光源的的单位向量  
    vec3 lightDir = normalize(lightPo - FragPo);  
    //DiffuseFactor=光源与法线夹角 max(0,dot(N,L))  
    float diff = max(dot(norm,lightDir),0.0);  
    //漫反射光颜色计算 = 光源的漫反射颜色 * 物体的漫发射材质颜色 * DiffuseFactor  
    vec3 diffuse = diff * lightColor*texture(Texture,outTexCoord).rgb;  

    //镜面反射  
    vec3 viewDir = normalize(viewPo - FragPo);  
    // reflect (genType I, genType N),返回反射向量  
    vec3 reflectDir = reflect(-lightDir,outNormal);  
    //SpecularFactor = power(max(0,dot(N,H)),shininess)  
    float spec = pow(max(dot(viewDir, reflectDir),0.0),reflectance);  
    //镜面反射颜色 = 光源的镜面光的颜色 * 物体的镜面材质颜色 * SpecularFactor  
    vec3 specular = specularStrength * spec * texture(specularTexture,outTexCoord).rgb;  

    //衰减因子计算  
    float LFDistance = length(lightPo - FragPo);  
    //衰减因子 =  1.0/(距离衰减常量 + 线性衰减常量 * 距离 + 二次衰减常量 * 距离的平方)  
    float lightWeakPara = 1.0/(constantPara + linearPara * LFDistance + quadraticPara * (LFDistance*LFDistance));  
    
    //光照颜色 =(环境颜色 + 漫反射颜色 + 镜面反射颜色)* 衰减因子  
    vec3 res = (ambient + diffuse + specular)*lightWeakPara;  

    //最终输出的颜色  
    FragColor = vec4(res,1.0);  

}

// 平行光版本  
void parallelLight(){  
  
    float ambientStrength = 0.3;    //环境因子  
    float specularStrength = 2.0;   //镜面强度  
    float reflectance = 256.0;      //反射率  

    //平行光方向
    //vec3 paraLightDir = normalize(vec3(-0.2,-1.0,-0.3));  
    vec3 paraLightDir =normalize(vec3(-1,-1,1));  

    //环境光 = 环境因子 * 物体的材质颜色  
    vec3 ambient = ambientStrength * texture(Texture,outTexCoord).rgb;  

    //漫反射  
    vec3 norm = normalize(outNormal);  
    //当前顶点至光源的的单位向量  
    vec3 lightDir = normalize(lightPo - FragPo);  
    //DiffuseFactor=光源与paraLightDir 平行光夹角 max(0,dot(N,L))  
    float diff = max(dot(norm,paraLightDir),0.0);  
    //漫反射光颜色计算 = 光源的漫反射颜色 * 物体的漫发射材质颜色 * DiffuseFactor  
    vec3 diffuse = diff * lightColor * texture(Texture,outTexCoord).rgb;  

    //镜面反射  
    vec3 viewDir = normalize(viewPo - FragPo);  
    // reflect (genType I, genType N),返回反射向量 -paraLightDir平行光  
    vec3 reflectDir = reflect(-paraLightDir,outNormal);  
    //SpecularFactor = power(max(0,dot(N,H)),shininess)  
    float spec = pow(max(dot(viewDir, reflectDir),0.0),reflectance);  
    //镜面反射颜色 = 光源的镜面光的颜色 * 物体的镜面材质颜色 * SpecularFactor  
    vec3 specular = specularStrength * spec * texture(specularTexture,outTexCoord).rgb;  

    //距离衰减常量  
    float constantPara = 1.0f;  
    //线性衰减常量  
    float linearPara = 0.09f;  
    //二次衰减常量  
    float quadraticPara = 0.032f;  
    //衰减因子计算  
    float LFDistance = length(lightPo - FragPo);  
    //衰减因子 =  1.0/(距离衰减常量 + 线性衰减常量 * 距离 + 二次衰减常量 * 距离的平方)  
    float lightWeakPara = 1.0/(constantPara + linearPara * LFDistance + quadraticPara * (LFDistance*LFDistance));  

    //光照颜色 =(环境颜色 + 漫反射颜色 + 镜面反射颜色)* 衰减因子  
    vec3 res = (ambient + diffuse + specular)*lightWeakPara;  
    
    //最终输出的颜色  
    FragColor = vec4(res,1.0);  
}  

//聚光版本  
void Spotlight(){  
   
    float ambientStrength = 0.3;    //环境因子  
    float specularStrength = 2.0;   //镜面强度  
    float reflectance = 256.0;      //反射率  

    //环境光 = 环境因子 * 物体的材质颜色  
    vec3 ambient = ambientStrength * texture(Texture,outTexCoord).rgb;  

    //漫反射  
    vec3 norm = normalize(outNormal);  
    vec3 lightDir = normalize(lightPo - FragPo);    //当前顶点 至 光源的的单位向量  
    //DiffuseFactor=光源与paraLightDir lightDir夹角 max(0,dot(N,L))  
    float diff = max(dot(norm,lightDir),0.0);   //光源与法线夹角  
    //漫反射光颜色计算 = 光源的漫反射颜色 * 物体的漫发射材质颜色 * DiffuseFactor  
    vec3 diffuse = diff * lightColor*texture(Texture,outTexCoord).rgb;  

    //镜面反射  
    vec3 viewDir = normalize(viewPo - FragPo);  
     // reflect (genType I, genType N),返回反射向量    
    vec3 reflectDir = reflect(-lightDir,outNormal);  
    //SpecularFactor = power(max(0,dot(N,H)),shininess)  
    float spec = pow(max(dot(viewDir, reflectDir),0.0),reflectance);  
    //镜面反射颜色 = 光源的镜面光的颜色 * 物体的镜面材质颜色 * SpecularFactor  
    vec3 specular = specularStrength * spec * texture(specularTexture,outTexCoord).rgb;  

    float constantPara = 1.0f;    //距离衰减常量  
    float linearPara = 0.09f;     //线性衰减常量  
    float quadraticPara = 0.032f; //二次衰减常量  
    
    //衰减因子计算  
    float LFDistance = length(lightPo - FragPo);  
    //衰减因子 =  1.0/(距离衰减常量 + 线性衰减常量 * 距离 + 二次衰减常量 * 距离的平方)  
    float lightWeakPara = 1.0/(constantPara + linearPara * LFDistance + quadraticPara * (LFDistance*LFDistance));  

    //聚光灯切角 (一些复杂的计算操作 应该让CPU做,提高效率,不变的量也建议外部传输,避免重复计算)  
    float inCutOff = cos(radians(10.0f));  
    float outCutOff = cos(radians(15.0f));  
    vec3 spotDir = vec3(-1.2f,-1.0f,-2.0f);  
    
    //聚光灯因子 = clamp((外环的聚光灯角度cos值 - 当前顶点的聚光灯角度cos值)/(外环的聚光灯角度cos值- 内环聚光灯的角度的cos值),0,1);  
    float theta = dot(lightDir,normalize(-spotDir));  
    //(外环的聚光灯角度cos值- 内环聚光灯的角度的cos值)  
    float epsilon  = inCutOff - outCutOff;  
    //(外环的聚光灯角度cos值 - 当前顶点的聚光灯角度cos值) / (外环的聚光灯角度cos值- 内环聚光灯的角度的cos值)  
    float intensity = clamp((theta - outCutOff)/epsilon,0.0,1.0);  
    vec3 res = (ambient + diffuse + specular)*intensity*lightWeakPara;  

    FragColor = vec4(res,1.0);  
}  

void DiffultLight(){  
    
    float ambientStrength = 0.3;    //环境因子  
    //环境光 = 环境因子 * 物体的材质颜色  
    vec3 ambient = ambientStrength * texture(Texture,outTexCoord).rgb;  
    
    //光源方向  
    //vec3 paraLightDir =normalize(vec3(0,1,0));  

    //漫反射  
    vec3 norm = normalize(outNormal);  
    vec3 lightDir = normalize(lightPo - FragPo);    //当前顶点 至 光源的的单位向量  
    //DiffuseFactor=光源与paraLightDir lightDir夹角 max(0,dot(N,L))  
    float diff = max(dot(norm,lightDir),0.0);   //光源与法线夹角  
    //漫反射光颜色计算 = 光源的漫反射颜色 * 物体的漫发射材质颜色 * DiffuseFactor  
    vec3 diffuse = diff * lightColor * texture(Texture,outTexCoord).rgb;  
    
     vec3 res = ambient + diffuse;  
     FragColor = vec4(res,1.0);  
}


void main()  
{
    //聚光版本  
    //Spotlight();  
    //点光源版本  
    //pointLight();  
    //平行光版本  
    //parallelLight();  
     DiffultLight();  
    
}  

相关文章

  • OpenGL ES 关于光照计算

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

  • OpenGL ES--关于光照计算

    光照基础 环境光照 漫反射光照 镜面光照 image.png 光照特性 发射光:由物体自身发光。 环境光:就是在环...

  • 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 关于光照计算

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