美文网首页
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 关于光照计算

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