【光照】[各向異性]在UnityURP中的實現
【從UnityURP開始探索游戲渲染】專欄-直達
Kajiya-Kay模型在Unity URP中的BRDF實現
模型原理與特點
Kajiya-Kay模型是一種專門用于模擬頭發、毛發等纖維狀材質各向異性高光的光照模型,其核心特點是用切線方向替代傳統法線方向計算高光反射。該模型具有以下特性:
- ?切線空間計算?:使用切線向量(Tangent)或副切線(Bitangent)替代法線向量,通過
TdotH = dot(tangent, halfVector)計算高光強度,再轉換為TsinH = sqrt(1 - TdotH2)實現條狀高光效果。 - ?雙層高光特性?:主高光(Primary Specular)靠近發梢,次高光(Secondary Specular)靠近發根且帶有彩色偏移,模擬Marschner模型的散射特性。
- ?切線偏移技術?:通過噪聲貼圖擾動切線方向(ShiftTangent函數),增強高光的動態變化和真實感。
URP中的BRDF結構
在Unity URP中,BRDF通常基于Cook-Torrance微表面模型,包含
三個核心組件:
- ?D項 法線分布函數?:描述微表面法線的分布,常用GGX模型。
- ?F項 菲涅爾項?:使用Schlick近似計算反射光強。
- ?G項 幾何遮蔽項?:采用Smith聯合陰影函數,結合光方向和視線方向的遮蔽效果。
URP中的BRDF數據通常包含以下字段:
csharp
struct BRDF {
float3 diffuse;// 材料身顏色
float3 specular;// 材料本身的高光顏色
float roughness;// 粗糙度
float perceptualRoughness;// 感知粗糙度
float fresnel;// 材料本身菲涅爾反射顏色
}
Kajiya-Kay與BRDF的整合方法
要將Kajiya-Kay模型融入URP的BRDF框架,需要進行以下
關鍵處理:
- ?切線空間轉換?:
- 使用TBN矩陣(切線-副切線-法線矩陣)將標準BRDF計算轉換到切線空間
- 在頂點著色器中計算并傳遞切線空間向量
- ?高光項替換?:
- 用Kajiya-Kay的
D_KajiyaKay函數替換標準BRDF中的D項 - 保持F項和G項不變,或根據需要進行調整
- 用Kajiya-Kay的
- ?雙層高光實現?:
- 主高光使用原始切線方向計算
- 次高光使用偏移后的切線方向計算,并賦予不同顏色
完整實現代碼
以下是Kajiya-Kay BRDF在URP Shader中的完整實現框架:
hlsl
// 1. 計算偏移后的切線方向
float3 ShiftTangent(float3 T, float3 N, float shift) {
return normalize(T + N * shift);
}
// 2. Kajiya-Kay高光計算
float D_KajiyaKay(float3 T, float3 H, float shininess) {
float TdotH = dot(T, H);
float sinTH = sqrt(1.0 - TdotH * TdotH);
return pow(sinTH, shininess);
}
// 3. BRDF整合計算
void Lighting_KajiyaKay(
SurfaceData surface,
inout Light light,
inout BRDFData brdf,
inout float3 specular)
{
// 切線空間轉換
float3 T = surface.tangent;
float3 B = cross(surface.normal, T) * surface.tangent.w;
float3 N = surface.normal;
// 計算主高光
float3 H = normalize(light.dir + viewDir);
float3 T_shifted = ShiftTangent(T, N, _ShiftAmount1);
float3 H_shifted = normalize(light.dir + viewDir);
// 計算次高光
float3 T_shifted2 = ShiftTangent(T, N, _ShiftAmount2);
float3 H_shifted2 = normalize(light.dir + viewDir);
// 計算高光項
float specular1 = D_KajiyaKay(T_shifted, H_shifted, _Shininess1);
float specular2 = D_KajiyaKay(T_shifted2, H_shifted2, _Shininess2);
// 組合結果
specular = _SpecColor1 * specular1 + _SpecColor2 * specular2;
// 標準BRDF漫反射部分
brdf.diffuse = surface.color * (1.0 - _Metallic);
brdf.specular = lerp(0.04, surface.color, _Metallic);
brdf.roughness = _Roughness;
}
實現要點說明
?紋理需求?:
- 基礎色貼圖(Albedo)
- 各向異性噪聲貼圖(控制高光擾動)
- 半透明通道(Alpha貼圖)
?優化技巧?:
- 利用URP內置函數
SafeNormalize和NormalizeNormalPerPixel提升計算穩定性 - 副切線(Bitangent)通過
cross(N, T) * tangent.w正確生成,避免UV方向錯誤
?參數設置?:
_ShiftAmount1/2:控制主次高光的切線偏移量_Shininess1/2:控制主次高光的銳利程度_SpecColor1/2:設置主次高光的顏色
該實現通過將Kajiya-Kay模型的核心計算融入URP的標準BRDF框架,既保持了PBR工作流的兼容性,又實現了纖維材質特有的各向異性高光效果
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,??)

《Unity URP中實現Kajiya-Kay頭發渲染模型》摘要 本文詳細介紹了如何在Unity URP渲染管線中實現Kajiya-Kay各向異性光照模型。該模型專為模擬頭發、毛發等纖維材質設計,通過切線空間計算替代傳統法線,產生條狀高光效果。文章剖析了模型的雙層高光特性(主高光靠近發梢、次高光帶彩色偏移)和切線偏移技術,并展示了如何將其整合到URP的Cook-Torrance BRDF框架中。實現關鍵包括切線空間轉換、高光項替換和雙層高光計算,提供了完整的Shader代碼框架及紋理需求、參數設置等實用細節
浙公網安備 33010602011771號