Unity3D PBR光照计算公式推导详解
前言
在Unity3D中,PBR(Physically Based Rendering,基于物理的渲染)光照模型是一种高级光照模型,它模拟了真实世界中光的传播和反射过程,从而提供了更加逼真的渲染效果。PBR光照模型的计算公式涉及多个物理参数和函数,包括反射率(Albedo)、法线分布函数(D)、菲涅尔项(F)、几何衰减项(G)等。以下是对这些参数的详细推导以及代码实现。
对惹,这里有一个游戏开发交流小组,大家可以点击进来一起交流一下开发经验呀!
技术详解
- 反射率(Albedo)
- 反射率表示物体表面的基本颜色,通常通过反射率贴图获取。
- 在Unity3D中,反射率贴图通常是一个RGB贴图,表示物体表面的颜色。
- 法线分布函数(D)
- 法线分布函数描述了组成表面一点的所有微表面的法线分布概率。
- 常用的GGX函数公式为:
DGGX(h,n,α)=π((n⋅h)2(α2−1)+1)2α2
复制代码
其中,$h$是半角向量,$n$是表面法线,$\alpha$是粗糙度参数,取值范围为0到1。 |
3. 菲涅尔项(F)
- 菲涅尔项描述了反射率随入射角度的变化。
- 使用Schlick近似公式计算:
F(θ,F0)=F0+(1−F0)(1−cosθ)5
复制代码
其中,$F_0$是基础反射率,$\theta$是入射角。 |
4. 几何衰减项(G)
- 几何衰减项描述了由于微表面自遮挡造成的光线衰减。
- 常用的Smith函数公式为:
G(l,v,n,k)=(1+(l⋅n)(1−k))2(1+(v⋅n)(1−k))21
复制代码
其中,$l$是光照方向,$v$是观察方向,$n$是表面法线,$k$是与粗糙度相关的参数。 |
公式推导
PBR光照模型的最终颜色由漫反射和镜面反射组成。
- 漫反射
- 漫反射的强度与光照方向和表面法线的点积成正比。
- 漫反射颜色 = 反射率 * (1 - 菲涅尔项)。
- 镜面反射
- 镜面反射的强度由法线分布函数、菲涅尔项和几何衰减项共同决定。
- 镜面反射颜色 = 菲涅尔项 * 法线分布函数 * 几何衰减项。
代码实现
以下是Unity3D中PBR光照模型的代码实现,使用HLSL(High-Level Shader Language)编写:
// 反射率贴图 | |
float3 albedo = texture2D(albedoMap, uv).rgb; | |
// 法线贴图 | |
float3 normal = UnpackNormal(texture2D(normalMap, uv)); | |
// 观察方向 | |
float3 viewDir = normalize(viewPosition - surfacePosition); | |
// 光照方向 | |
float3 lightDir = normalize(lightPosition - surfacePosition); | |
// 半角向量 | |
float3 halfDir = normalize(lightDir + viewDir); | |
// 镜面反射率 | |
float3 F0 = mix(F0NonMetal, F0Metal, metallic); // F0NonMetal和F0Metal为金属和非金属的基础反射率 | |
float3 F = FresnelSchlick(dot(halfDir, viewDir), F0); | |
// 漫反射 | |
float3 diffuse = albedo * (1 - F); | |
// 粗糙度贴图 | |
float roughness = texture2D(roughnessMap, uv).r; | |
// 镜面反射 | |
float3 specular = F * D_GGX(normal, halfDir, roughness) * G_Smith(normal, viewDir, lightDir, roughness) | |
/ (4 * dot(normal, viewDir) * dot(normal, lightDir)); | |
// 最终颜色 | |
float3 finalColor = (diffuse + specular) * lightColor; |
在上述代码中:
albedoMap
、normalMap
和roughnessMap
分别为反射率、法线和粗糙度贴图。F0NonMetal
和F0Metal
分别为非金属和金属的基础反射率。FresnelSchlick
函数用于计算菲涅尔项。D_GGX
函数用于计算GGX法线分布函数。G_Smith
函数用于计算Smith几何衰减项。lightColor
为光源颜色。
总结
PBR光照模型通过模拟真实世界中光的传播和反射过程,提供了更加逼真的渲染效果。在Unity3D中,通过Standard Shader可以方便地实现PBR光照模型,而理解其背后的物理原理和公式推导对于优化渲染效果至关重要。希望本文的详细推导和代码实现能够对读者有所帮助。
更多教学视频
Unity3Dwww.bycwedu.com/promotion_channels/2146264125