美文网首页
OpenGL ES on iOS --- 基础光照

OpenGL ES on iOS --- 基础光照

作者: miku酱啦 | 来源:发表于2017-12-05 09:24 被阅读0次

    简述

    本文记录我记录我学习 坐标体系和矩阵转换的过程,加深学习便于后续查询,可能有些描述不够准确,或者内容不够充实,还请多多指正,共同学习.

    颜色

    一个没有Alpha通道的颜色可以用一个3维向量来表示 例如 glm::vec3(1.0,1.0,1.0); 表示白色.

    在现实世界中,一个物体的颜色是它反射的颜色导致的, 例如我们将纯红光 照射在纯绿物体上, 因为红光都被吸收,所以显示为黑色.

    将吸收反射的过程用向量表示出来

    glm::vec3 lightColor(0.0f, 1.0f, 0.0f); //绿色光源向量
    glm::vec3 objColor(1.0f, 0.5f, 0.31f);  //物体色
    glm::vec3 result = lightColor * objColor; // 光源下颜色(0.0f, 0.5f, 0.0f);
    

    冯氏光照模型

    冯氏光照模型的主要结构由3个分量组成 环境(Ambient) 漫反射(Diffuse) 镜面(Specular)


    冯氏光照模型

    环境光照

    在现实环境下 即使在黑暗的情况下,世界上通常也会有一些光亮(如 月光), 而且即使物体不朝光源的,也会因为 其他物体的反射,使阴面有光,这种情况下 就要使用 全局照明算法 这种算法开销大而且复杂,以后在研究 先实现简单的 环境光照

    所以给物体一个环境光照量,让物体始终有一点颜色. 在着色器中表现如下

    void main()
    {
        float ambientStrength = 0.1;        //至少有%10的光找到物体所有面
        vec3 ambient = ambientStrength * lightColor;
    
        vec3 result = ambient * objectColor;
        FragColor = vec4(result, 1.0);
    }
    

    漫反射光照

    模拟光源对物体的方向性影响(Directional Impact)。它是冯氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源,它就会越亮. 也就是光线物体表面法线的夹角越小,光线对物体的影响就越大.

    漫反射效果

    这样就可以利用夹角的cos值作为参考,来修改光线对物体的影响.

    片段着色器重相关实现

    uniform vec3 lightColor;        //光源色
    uniform vec3 lightPo;           //光源位置
    uniform vec3 objectColor;       //物体色
    uniform vec3 viewPo;            //物体位置
    
    in vec3 outNormal;              //传入当前顶点平面的法向量
    
    vec3 norm = normalize(outNormal);   //确保法线为单位向量
    vec3 lightDir = normalize(lightPo - FragPo);  //顶点指向光源 单位向量  
    
    float diff = max(dot(norm,lightDir),0.0);   //得到两向量的cos值 小于0则则为0
    vec3 diffuse = diff * lightColor;           //得到漫反射收的光源向量
    

    法向量变换

    对于法向量,它是一个方向向量,不会因为物体的移动而发生变化,所以在对法向量 进行矩阵处理时,要消除矩阵中位移部分对其造成的影响. 因此位移使用3x3矩阵 或者 将 法向量的w分量设置为0.0;

    另外,若矩阵对物体进行里不等比缩放时候,会导致法向量不在垂直于物体表面.


    不等比缩放对法向量的影响

    这种情况 则需要使用法线矩阵 来移除对法向量错误缩放的影响. 法线矩阵由逆矩阵转置矩阵 组成.

        glm::transpose(glm::inverse(model));    //法线矩阵的计算
        
        mat3(transpose(inverse(model))) * aNormal;  //着色器语言的使用 使用3x3矩阵 能够与 vec3法向量计算
    

    镜面光照

    模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。镜面光照的计算依赖于 观察的视角, 若视线与光源在物体的反射线的夹角越小 则镜面光照效果越好.

    计算他 我们需要 观察者位置.镜面强度(镜面效果强弱)

    float specularStrength = 0.5;   //镜面强度
    vec3 viewDir = normalize(viewPo - FragPo);  //顶点指向观察点的单位向量
    vec3 reflectDir = reflect(-lightDir,outNormal); //求得光线 在 顶点的反射线(传入光源指向顶点的向量)
    
    float spec = pow(max(dot(viewDir, reflectDir),0.0),256.0);
    // 求得夹角cos值 取256次幂 注意 pow(float,float)函数参数类型
    
    vec3 specular = specularStrength * spec * lightColor;
    

    256 表示高光的反光度, 反光度越高,发射光的能力越强,散射越少 高光点越小


    反光度影响

    最后综合

     vec3 res =(ambientStrength + diffuse + specular) * objectColor;
    

    效果图: 白色方块为白色光源


    效果图.gif

    相关文章

      网友评论

          本文标题:OpenGL ES on iOS --- 基础光照

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