Pbr公式结合shader一

         原理方面的东西很难搞明白,越研究疑惑越多,所以先放弃原理,今天结合unity shader来分析下如何套用原理方面的东西很难搞明白,越研究疑惑越多,所以先放弃原理,今天结合unity shader来分析下如何套用,第一次研究,如果有错误的地方欢迎指出。

 

反射率方程

 

将这个公式拆分为两部分 

第一部分:

这是半球积分,表示多光源下光照的叠加,主要是为了环境反射

第二部分:半球积分以内的部分,主要是直射光的结果

第一部分跟第二部分结合过后的结果如下: 

输出颜色 =

 

结果还是两部分组成,漫反射部分 跟 高光部分。

 

 

        下面就开始分别给公式里的每一项来赋值了。

1.漫反射部分:

漫反射比例:Kd  它是用来根据金属度计算漫反射和镜面反射比例,当Metallic为1时,反射率接近1,函数返回的diffColor接近                          0,表示几乎不反射漫反射。下面代码的结果得到的是个float3:albedo x Kd系数 的值

inline half OneMinusReflectivityFromMetallic(half metallic)
{
    half oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.a;
    return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
}

inline half3 DiffuseAndSpecularFromMetallic (half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity)
{
    specColor = lerp (unity_ColorSpaceDielectricSpec.rgb, albedo, metallic);
    oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic);
    return albedo * oneMinusReflectivity;
}

Unity_ColorSpaceDielectricSpec为Unity的内置变量,定义了绝缘体的高光颜色和反射率,不完全为0,是一个经验值。

从第二段函数里:我们可以得到3个变量的结果:

1)specColor:有点不太好理解,只是一个由unity自带的Unity_ColorSpaceDielectricSpec内置变量,比较暗 ,跟 贴图采样              的值根据金属度来lerp,是用来做菲尼尔效果用的

                               

    metallic=0                                    metallic=1

2)oneMinusReflectivity :就是我们想要的Kd系数,及漫反射系数。

3)贴图颜色*oneMinusReflectivity

纹理颜色 

unity分为两部分来做,一个是迪斯尼漫反射,还有一个是兰伯特漫反射,兰伯特漫反射更节省一些,效果并每有太大的差异

迪斯尼漫反射:

half DisneyDiffuse(half NdotV, half NdotL, half LdotH, half perceptualRoughness)
{
    half fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
    half lightScatter   = (1 + (fd90 - 1) * Pow5(1 - NdotL));
    half viewScatter    = (1 + (fd90 - 1) * Pow5(1 - NdotV));
    return lightScatter * viewScatter;
}

那么得出的结果就是:

directDiffuse = lightScatter * viewScatter ;

这个函数计算的结果 还需要 *NdotL*atten*LightColor,而的出来的结果其实就是漫反射系数 ,比lanbert好的一点 ,是随着粗造度的变化,效果稍有变化。

directDiffuse *=  NdotL * attenColor;

环境光照的漫反射部分

 gi.indirect.diffuse:这就是环境光的漫反射部分

GI data:

                 UnityLight light;
                #ifdef LIGHTMAP_OFF
                    light.color = lightColor;
                    light.dir = lightDirection;
                    light.ndotl = LambertTerm (normalDirection, light.dir);
                #else
                    light.color = half3(0.f, 0.f, 0.f);
                    light.ndotl = 0.0f;
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值