冯氏光照模型的使用尝试

冯氏光照模型

示例Fragment Shader

#version 330 core

//光源位置
uniform vec3 lightPos;    
//光源颜色
uniform vec3 lightColor;
//环境光强度
uniform float ambientStrength;
//相机位置
uniform vec3 viewPos;
//镜面反射高光强度因子
uniform uint powValue;

uniform sampler2D borderSampler2D;
uniform sampler2D containerSampler2D;

in vec3 FragPos;
in vec3 Normal;
in vec2 texCoord;
out vec4 FragColor;

void main()
{
    float ambient;

    //环境光强度乘以光源的颜色 得到一个 环境光照强度
    if( ambientStrength < 0.0f ){
        ambient = 0.0f;
    }else if( ambientStrength > 1.0f ){
        ambient = 1.0f;
    }else{
        ambient = ambientStrength;
    }

    //计算漫反射光照,基本算法如下:
    //  光源到当前顶点的方向向量 点乘以  顶点法线向量 == 光线方向与顶点发现向量的角度
    //  这个角度就可以当成漫反射光照强度 diff
    //  需要注意的是,由于在真是环境中,如果光线方向和顶点法线向量的夹角超过 90 度的时候
    //  光线是看不见的,所以要排除掉 大于 90度 的情况(暂时不考虑特别的情况)
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(lightDir, norm), 0.0);


    //计算镜面光照,基本算法如下:
    //  1. 通过入射光线的方向向量 和 顶点法线向量 计算出反射光线的方向
    //  2. 通过观察者的位置 和 当前顶点的位置 计算出 观察者观察当前顶点的 方向向量
    //  3. 通过 反射光线方向向量 和 观察视线方向向量 计算出两者的夹角, 这个夹角用来
    //      计算镜面反射光照强度的因子 specFactor
    //  4. 我们知道 在 镜面反射中,反射光强度 随着 视线和反射光线的角度 的增大而极具下降
    //      这个强度衰减的过程是非线性的,而是类似指数级的的衰减,那么 我们就可以利用 指数
    //      来模拟这个衰减的过程:
    //          float spec = pow(specFactor, 幂值)
    //      此处求出的 spec 称为镜面反射的高光强度
    //      上述的 幂值 可以用来表示衰减的急剧程度, 幂指越大,spec的值变化越急剧,衰减就越剧烈
    //      在现实中,镜面光照感越强,这样让人觉得 物体表面越平滑有光泽
    vec3 reflectDir = normalize(reflect(-lightDir, norm));
    vec3 viewDir = normalize(viewPos - FragPos);
    float specFactor = max(dot(reflectDir, viewDir), 0.0);
    float spec = pow(specFactor, powValue);

    //我们此处要接受光照的对象是 带有金属边框的木头箱子
    //可以知道,能够镜面反射光线的只有金属边框,木头部分基本无法做镜面反射,所以我们忽略
    //判断 当前顶点是 金属边框 还是 木头 是 通过一张 灰度图 纹理 来指明
    //当前的纹理中,灰度值为 0 的部分是木头, 不为0 的部分是金属
    vec3 result;
    vec4 borderTexFrag = texture2D(borderSampler2D, texCoord);
    vec4 containerTexFrag = texture2D(containerSampler2D, texCoord);

    //环境光照 加上 光源光照 等于总的光照
    //总的光照 乘以 物体的颜色 就计算出了 物体在光照下 呈现出的颜色
    if( borderTexFrag.x == 0.0f ){
        result = ((ambient + diff) * lightColor)  * containerTexFrag.xyz;
    }else{
        result = ((ambient + diff + spec) * lightColor)  * containerTexFrag.xyz;
    }

    FragColor = vec4(result, 1.0f);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。