PBR个人学习总结

本文是作者关于PBR的学习总结,涵盖了漫反射和镜面反射的原理、公式、效果展示及代码实现,涉及Unity的Disney Diffuse函数、法线分布函数(NDF)、菲涅尔方程和几何遮蔽函数。通过示例模型展示了各参数对最终效果的影响,适合技术美术和游戏引擎开发者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要是把个人学习的PBR经验做个小总结,便于理清思路与复习,如果能帮助到您的话那也是荣幸之至,如果发现有不对的地方,请大佬们加以指正。

所涉及到的PBR知识主要是BXDF中最简单也是最为常用的双向反射分布函数(Bidrectional Beflectance Distribution Function,BRDF)类型,BRDF搞明白之后,其它的如BTDF、BSDF、BSSRDF也就有了基础。

本文有关各种原理不做详细的赘述,可以自行找各位大佬们的精彩文章或视频去深入,在此只做简要的阐述,请见谅。

一、 PBR知识体系架构图

认识PBR前,还是一定要多熟悉这个架构图,对于理清各分支细节有很大的好处,特别是刚接触容易迷惑之时。

 

上图是自己绘制的比较简版的架构图,详细的PBR架构图请可以去下载查看[1]

 

清晰了上图的架构之后 ,就可以按各分支详细分解了。

几个分支组合之后的效果如下:

 二、资源列表

示例模型为网上下载的一个复古电脑,仅1920个三角面的低模,等有时间了再自己做一个高模的示例模型吧。

贴图有5张: Albedo基本色贴图、自发光贴图、金属度贴图、粗糙度贴图、法线贴图、以及AO遮挡贴图。

示例模型及布线
示例模型及布线
示例模型使用到的贴图
示例模型使用到的贴图

 Properties属性内容

最后Option项是调试时使用部分
最后Option项是调试时使用部分

 在面板中Option添加了几大分支的开关与选择项,在编写时便于调试使用。

Shader代码片段:

Properties
    {
        _DiffuseColor("DiffuseColor",Color)=(1,1,1,1)
        [Space(10)]_MainTex ("BaseTexture", 2D) = "white" {}
        [NoScaleOffset]_BumpMap("BumpMap",2D)="white"{}
        _BumpScale("BumpScale",Range(0,1))=1

        [Space(20)]
        [NoScaleOffset]_MetallicTex("MetallicTex",2D)="white"{}
        _MetallicScale("MetallicScale",Range(0.0,1.0))=0.0
        [NoScaleOffset]_RoughnessTex("RoughnessTex",2D)="white"{}
        _RoughnessScale("RoughnessScale",Range(0,1))=0.5

        [Space(20)] [NoScaleOffset]_OcclusionTex("OcclusionTex",2D)="white"{}
        _OcclusionScale("OcclusionScale",Range(0,1))=1

        [Space(10)] [NoScaleOffset]_EmssionTex("EmssionTex",2D)="white"{}
        [HDR]_EmissionColor("EmissionColor",Color)=(1,1,1)

        [Header(Aniso)]
        [Space(10)]
        [KeywordEnum(None,GTR2,GGX)] _ANISO("AnisoType",float)=0

        _Aniso("Aniso",Range(0,1))=0
        _AnisoOffset("AnisoOffset",Range(-10,10))=0
        _AnisoRoat("AnisoRoat",Range(-10,10))=0
        // [Space(10)] _ClearCoat("ClearCoat",Range(0,1))=0
        [Header(Option)]
        [Space(10)]
        [Toggle] _IS_AMBIENT("自发光",float)=1
        [Toggle] _IS_DIFFUSE("漫反射",float)=1
        [Toggle] _IsSpecular("镜面反射",float)=1
        [KeywordEnum(None,GGXTerm,GTR1,GTR2,GND)] _UIDNF("法线分布 D项",float)=0
        [KeywordEnum(None,Unity,Schlick,SG)] _UIF("菲涅尔 F项",float)=0
        [KeywordEnum(None,Filament,GGX,GSF,Beckman)] _UIG("几何遮蔽 G项",float)=0
        [Toggle] _ISIBL("环境光照",float)=1
    }

Pass中需要引入与Shader文件同目录的自定义的文件: #include "Pbr_Function.cginc"

三、漫反射项

3.1漫反射和镜面反射

先从漫反射和镜面反射开始,当灯光照射一个标准的BRDF材质时可以拆分成两部分:漫反射+镜面反射,如下图可以有一个很直观的了解。

在BRDF模型下,L为灯光照射时表面的漫反射(绿色)和镜面反射(蓝色)的示意图
在BRDF模型下,L为灯光照射时表面的漫反射(绿色)和镜面反射(蓝色)的示意图(图来源网络)

 

 3.2公式

漫反射项使用的是Unity内置的Disney Diffuse函数。

f_d=\frac{baseColor}{\pi}(1+(F_{D90}-1)(1-cos\theta_l)^5)(1+F_{D90}-1)(1-cos\theta_v)^5)

F_{90}=0.5+2\times roughtness \times cos^2 \theta_d

3.3效果展示

只贴上基础纹理贴图时的效果
只贴上基础纹理贴图时的效果

 3.4 相关代码

以下为UnityShader中内置的Disney Diffuse代码部分。

inline half Diffuse_Disney(half NdotV, half NdotL, half LdotH, half perceptualRoughness)
{
    half fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
    // Two schlick fresnel term
    half lightScatter   = (1 + (fd90 - 1) * Pows5(1 - NdotL));
    half viewScatter    = (1 + (fd90 - 1) * Pows5(1 - NdotV));
    return lightScatter * viewScatter;
}
inline half Pow5 (half x){
    return x*x * x*x * x;
}

Pow5这个方法,有一维到四维,但为什么不直接用pow函数,而是使用相同的量相乘5次,其在文中也有说到其两个好处:

  1. 更好的优化渲染管线
  2. 不用担心出现异常

四、镜面反射项

整个镜面反射的公式结构如下:

\large f_r(v,l)=\frac{D(h,\alpha)G(v,l,\alpha)F(v,h,f0)}{4(n\cdot{v})(n\cdot{l})}

分母 4(n·l)(n·v:校正因子(correctionfactor),作为微观几何的局部空间和整个宏观表面的局部空间之间变换的微平面量的校正。

4.1 D项 法线分布函数

D(h):法线分布函数(Normal Distribution Function),描述微面元法线分布的概率,即正确朝向的法线的浓度,即具有正确朝向,能够将来自L的光反射到V的表面点的相对于表面面积的浓度。

4.11 大致原理

         把一个平面哪怕是镜子放大到微观层面,会发现表面会是凸凹不平的表面,以此来理解就容易懂了,看下面的示意图。

微平面粗糙度对材质外观的影响(图片来自Moving Frostbite to PBR,SIGGRAPH 2014)
微平面粗糙度对材质外观的影响(图片来自Moving Frostbite to PBR,SIGGRAPH 2014)

4.12 公式 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值