时间:2025-09-23 11:52
人气:
作者:admin
【从UnityURP开始探索游戏渲染】专栏-直达
经验光照模型中的高光反射通常遵循以下流程:
1975 裴祥风(Bui Tuong Phong)剔除了标准光照模型背后的基本理念。标准光照只关心直接光照direct light。
Phong模型计算高光反射:

fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
特点:
Unity URP应用:
Blinn提出简单方法得出类似效果(Blinn-Phong高光反射光照)

fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);
特点:
Unity URP选用方案:
实现原理:
$高光 = 光源强度 × 特殊BRDF × exp(-tan²θ/(α²))$
其中:
特点:
Unity URP应用:
hlsl
float3 T = i.tangent;
float3 B = cross(N, T);
float dotTH = dot(T, H);
float dotBH = dot(B, H);
float spec = exp(-2.0*(dotTH*dotTH + dotBH*dotBH)/(1.0 + dotNH));
实现原理:
$高光 = (D × F × G) / (4 × (N·V) × (N·L))$
包含三个函数:
特点:
Unity URP选用方案:
hlsl
float D = GGXDistribution(N, H, roughness);
float F = SchlickFresnel(dot(H, V));
float G = SmithGeometry(N, V, L, roughness);
float spec = (D * F * G) / (4 * max(dot(N,V), 0.01) * max(dot(N,L), 0.01));
URP采用分层的高光处理方案:
| 质量等级 | 使用模型 | 目标平台 | 特性 |
|---|---|---|---|
| Low | Blinn-Phong | 低端移动 | 单光源简化 |
| Medium | 改进Blinn-Phong | 主流移动 | 多光源支持 |
| High | Cook-Torrance | PC/主机 | PBR工作流 |
| Ultra | 完整PBR | 高端设备 | 多散射支持 |
Shader架构:
graph TD A[URP输入] --> B{质量设置} B -->|Low| C[Blinn-Phong] B -->|Medium| D[优化Cook-Torrance] B -->|High| E[完整PBR] C --> F[光照累加] D --> F E --> F F --> G[输出合成]关键代码片段:
hlsl
// URP的BRDF处理 (BRDF.hlsl)
half3 BRDF_Simple(
half3 albedo, half3 specular,
half smoothness, half3 normal,
half3 lightDir, half3 viewDir)
{
half3 halfVec = SafeNormalize(lightDir + viewDir);
half NdotH = saturate(dot(normal, halfVec));
half modifier = pow(NdotH, smoothness * smoothness * 50.0);
return specular * modifier;
}
// URP的PBR BRDF (BRDF_PBR.hlsl)
half3 BRDF_PBR(
half3 albedo, half metallic,
half smoothness, half3 normal,
half3 lightDir, half3 viewDir)
{
half perceptualRoughness = 1.0 - smoothness;
half roughness = perceptualRoughness * perceptualRoughness;
half3 halfVec = SafeNormalize(lightDir + viewDir);
half NdotV = saturate(dot(normal, viewDir));
half NdotL = saturate(dot(normal, lightDir));
// GGX分布
half D = DistributionGGX(normal, halfVec, roughness);
// 菲涅尔Schlick近似
half3 F = FresnelSchlick(halfVec, viewDir, metallic);
// 几何遮蔽
half G = GeometrySmith(normal, viewDir, lightDir, roughness);
return (D * F * G) / (4.0 * NdotV * NdotL + 0.0001);
}
| 模型 | 计算周期 | 内存访问 | 视觉保真度 |
|---|---|---|---|
| Phong | 18 | 5 | 70% |
| Blinn-Phong | 15 | 4 | 75% |
| Cook-Torrance | 35 | 8 | 95% |
| URP优化版 | 22 | 6 | 88% |
移动游戏:
hlsl
// 使用SimpleLit着色器
Shader "Universal Render Pipeline/Simple Lit"
AAA级项目:
hlsl
// 使用完整PBR管线
Shader "Universal Render Pipeline/Lit"
风格化渲染:
hlsl
// 自定义高光形状
float spec = pow(dotNH, _Glossiness) * step(0.9, dotNH);
Unity URP的高光反射实现体现了现代渲染引擎的设计哲学:在物理精确性与实时性能之间寻找最佳平衡点,通过分层架构满足不同项目需求,同时保持美术工作流的一致性。这种灵活而高效的设计使URP成为跨平台开发的理想选择。
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,????)