Unity中的BRDF实现(双向反射分布函数)
以下是一个简化的Cook-Torrance BRDF实现框架:glsl// 菲涅尔项// 几何遮蔽项(Smith联合模型)// GGX法线分布// BRDF计算此代码结合了菲涅尔、几何遮蔽与法线分布项,适用于逐像素光照计算6910。Unity的BRDF实现结合了理论模型(如Cook-Torrance)与工程优化(如Schlick近似),开发者可通过自定义Shader调整各参数(金属度、粗糙度等)实
在Unity中实现基于物理的渲染(PBR)时,BRDF(Bidirectional Reflectance Distribution Function,双向反射分布函数) 是核心模型,用于描述光线与物体表面的交互方式。以下是Unity中BRDF的关键实现要点及参考示例:
一、BRDF的核心组件
BRDF通常基于Cook-Torrance微表面模型,包含三个核心项:
-
D项(法线分布函数)
D(h)=α2π((n⋅h)2(α2−1)+1)2D(h)=π((n⋅h)2(α2−1)+1)2α2
描述微表面法线的分布,常用**GGX(Trowbridge-Reitz)**模型,其数学形式为:其中,α=roughness2α=roughness2,用于控制表面粗糙度61017。
-
F项(菲涅尔项)
FSchlick(F0,v,h)=F0+(1−F0)(1−(v⋅h))5FSchlick(F0,v,h)=F0+(1−F0)(1−(v⋅h))5
使用Schlick近似计算反射光强,公式为:F0F0为基础反射率,金属材质通常设为高值(如0.9),非金属材质设为低值(如0.04)910。
-
G项(几何遮蔽项)
G(l,v,h)=G1(l)⋅G1(v)G(l,v,h)=G1(l)⋅G1(v)
采用Smith联合阴影函数,结合光方向和视线方向的遮蔽效果,公式为:其中G1(x)G1(x)通过粗糙度参数计算光的可见性61017。
二、Unity中的BRDF实现
1. 内置BRDF函数
Unity的Standard Shader
内置了BRDF模型,通过BRDF2_Unity_PBS
函数实现。该函数参数包括:
-
diffColor
:漫反射颜色(Albedo贴图提取) -
specColor
:镜面反射颜色(金属度或高光贴图控制) -
smoothness
:光滑度(转换为粗糙度α=roughness2α=roughness2) -
normal
和viewDir
:法线与视线方向向量17。
2. 自定义BRDF Shader示例
以下是一个简化的Cook-Torrance BRDF实现框架:
glsl
// 菲涅尔项 float3 FresnelSchlick(float3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } // 几何遮蔽项(Smith联合模型) float GeometrySmith(float NdotV, float NdotL, float roughness) { float k = (roughness + 1.0) * (roughness + 1.0) / 8.0; float GGXV = NdotV / (NdotV * (1.0 - k) + k); float GGXL = NdotL / (NdotL * (1.0 - k) + k); return GGXV * GGXL; } // GGX法线分布 float DistributionGGX(float NdotH, float roughness) { float a = roughness * roughness; float a2 = a * a; float denom = (NdotH * NdotH * (a2 - 1.0) + 1.0); return a2 / (PI * denom * denom); } // BRDF计算 float3 BRDF(float3 F0, float3 N, float3 L, float3 V, float roughness) { float3 H = normalize(V + L); float NdotL = saturate(dot(N, L)); float NdotV = saturate(dot(N, V)); float NdotH = saturate(dot(N, H)); float LdotH = saturate(dot(L, H)); float3 F = FresnelSchlick(F0, LdotH); float G = GeometrySmith(NdotV, NdotL, roughness); float D = DistributionGGX(NdotH, roughness); float3 specular = (F * G * D) / (4.0 * NdotV * NdotL + 0.001); return specular; }
此代码结合了菲涅尔、几何遮蔽与法线分布项,适用于逐像素光照计算6910。
三、进阶应用与优化
-
漫反射模型
-
Disney漫反射模型:考虑粗糙度对菲涅尔效应的影响,公式为:
fd=baseColorπ(1+(FD90−1)(1−cosθl)5)(1+(FD90−1)(1−cosθv)5)fd=πbaseColor(1+(FD90−1)(1−cosθl)5)(1+(FD90−1)(1−cosθv)5)其中FD90=0.5+2×roughness×cos2θdFD90=0.5+2×roughness×cos2θd,适用于更自然的表面散射1017。
-
-
性能优化
-
预计算与近似:例如将菲涅尔项简化为F0+(1−F0)(1−v⋅h)5F0+(1−F0)(1−v⋅h)5,减少实时计算量910。
-
移动端适配:使用低复杂度的NDF(如Blinn-Phong)或简化几何项17。
-
四、实际案例参考
-
雪景效果扩展
通过修改Unity的Standard Shader
,在FragmentSetup
函数中添加雪覆盖逻辑,调整Albedo和法线信息以模拟积雪,同时保持BRDF的物理正确性16。 -
粗糙折射(BTDF)
最终颜色=fr(BRDF)+ft(BTDF)最终颜色=fr(BRDF)+ft(BTDF)
结合BRDF与BTDF(双向透射分布函数),通过环境贴图模拟半透明材质的折射效果,公式为:适用于玻璃、液体等材质8。
五、总结
Unity的BRDF实现结合了理论模型(如Cook-Torrance)与工程优化(如Schlick近似),开发者可通过自定义Shader调整各参数(金属度、粗糙度等)实现多样化材质效果。
更多推荐
所有评论(0)