【从UnityURP开始探索游戏渲染】专栏-直达

高光反射的基本流程

经验光照模型中的高光反射通常遵循以下流程:

  • 入射光计算‌:确定光源方向和强度
  • 视角向量计算‌:确定观察者方向
  • 反射向量计算‌:根据表面法线计算理想反射方向
  • 高光强度计算‌:使用特定模型计算高光反射强度
  • 最终合成‌:将高光反射与漫反射和环境光结合

主要高光反射模型及实现

Phong模型 (1975) -经验模型

1975 裴祥风(Bui Tuong Phong)剔除了标准光照模型背后的基本理念。标准光照只关心直接光照direct light。

  • Phong模型计算高光反射:

    • 反射方向:$r=2(n·I)n-I$
    • $C_{specular}=(C_{light}·M_{specular})max(0,v·r)^{M_{gloss}}$
    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);
    • Mgloss 材质光泽度,也称为反光度shininess。控制高光区域亮点有多宽,Mgloss越大,亮点越小。

特点‌:

  • 计算反射向量需要额外步骤
  • 高光边缘过渡较硬
  • 计算成本中等

Unity URP应用‌:

  • 早期移动端简化着色器中使用
  • 现在主要用于教学演示目的

Blinn-Phong模型 (1977) -经验模型

  • Blinn提出简单方法得出类似效果(Blinn-Phong高光反射光照)

    • $h=\frac{(v+I)}{|v+I|}$
    • $C_{specular}=(C_{light}·M_{specular})max(0,n·h)^{M_{gloss}}$
    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);
    • 摄像机和光源距离物体足够远时,可认为v和I是定值,Blinn模型会快于Phong模型。
    • 当v和I不定时,Phong可能更快。

特点‌:

  • 比Phong模型计算效率更高
  • 高光过渡更柔和自然
  • 成为游戏行业长期标准

Unity URP选用方案‌:

  • URP内置的SimpleLit着色器使用此模型
  • 移动端默认高光方案

Ward各向异性模型 (1992)

实现原理‌:

$高光 = 光源强度 × 特殊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));

Cook-Torrance模型 (1982)

实现原理‌:

$高光 = (D × F × G) / (4 × (N·V) × (N·L))$

包含三个函数:

  • D (微表面分布):Beckmann/GGX
  • F (菲涅尔反射):Schlick近似
  • G (几何遮蔽):Smith函数

特点‌:

  • 物理基础渲染(PBR)核心模型
  • 计算成本最高
  • 需要更多材质参数

Unity URP选用方案‌:

  • URP的Lit着色器使用简化版
  • 主要采用GGX分布+Schlick菲涅尔
  • 实现核心:
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));

Unity URP的高光实现策略

多级高光系统

URP采用分层的高光处理方案:

质量等级 使用模型 目标平台 特性
Low Blinn-Phong 低端移动 单光源简化
Medium 改进Blinn-Phong 主流移动 多光源支持
High Cook-Torrance PC/主机 PBR工作流
Ultra 完整PBR 高端设备 多散射支持

URP核心实现

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);
}

移动端优化技巧

  • 近似计算‌:

    • 使用半精度浮点(half)
    • 预计算菲涅尔项
    • 简化几何函数
  • 纹理烘焙‌:
    • 粗糙度映射使用LUT
    • 环境反射使用立方体贴图
  • 着色频率控制‌:
    • 顶点着色器计算低频高光
    • 像素着色器处理细节

方案选型原因分析

为什么URP选择混合方案?

  • 性能与质量平衡‌:

    • 低端设备:Blinn-Phong (60%性能提升)
    • 高端设备:PBR (100%物理准确)
  • 美术工作流统一‌:
    • 统一的光滑度参数(0-1)
    • 自动模型切换无感知
  • 平台适应性‌:
    • 根据GPU能力动态调整
    • 保留核心视觉一致性

技术对比数据

模型 计算周期 内存访问 视觉保真度
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开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,)

【光照】[高光反射specular]以UnityURP为例的更多相关文章

  1. 【Unity Shader】四、高光反射Specular Shader例子

    http://www.cnblogs.com/guxin/p/unity-diffuse-shader-demo.html 在上文中已经学习了漫反射Diffuse Shader和环境光,现在再在此基础 ...

  2. 【Unity Shader学习笔记】Unity光照基础-高光反射

    1.原理 1.1.Phong模型 计算高光反射需要表面法线.视角方向.光源方向.反射方向等. 在这四个矢量中,我们实际上只需要知道其中3个矢量即可,而第4个矢量(反射方向r)可以通过其他信息计算得到: ...

  3. 游戏引擎中三大及时光照渲染方法介绍(以unity3d为例)

    (转)游戏引擎中三大及时光照渲染方法介绍(以unity3d为例)   重要:在目前市面上常见的游戏引擎中,主要采用以下三种灯光实现方式: 顶点照明渲染路径细节 Vertex Lit Rendering ...

  4. 【Unity Shader】(三) ------ 光照模型原理及漫反射和高光反射的实现

    [Unity Shader](三) ---------------- 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 ...

  5. TWaver3D特效之高光反射

    前篇我们介绍了TWaver 3D的环境映射特效,下面我们接着给大家分享高光反射特效.高光反射定义了物体上的某一区域比其他地方更反光.在高光反射的贴图中,黑色区域的反射率为0(完全不反光),白色区域的反 ...

  6. Unity shader学习之高光反射光照模型

    高光反射光照模型的公式如下: Cspecular = Clight * mspecular * max(0, dot(v, r))gloss 要计算高光反射需要知道4个参数:入射光线颜色Cspecul ...

  7. (转)游戏引擎中三大及时光照渲染方法介绍(以unity3d为例)

    重要:在目前市面上常见的游戏引擎中,主要采用以下三种灯光实现方式: 顶点照明渲染路径细节 Vertex Lit Rendering Path Details 正向渲染路径细节 Forward Rend ...

  8. Java中反射和Unsafe破坏单例设计模式

    有如下单例模式设计代码: class Singleton { private String info = "HELLO SHIT"; private static Singleto ...

  9. Java 反射经常用法演示样例

    <pre name="code" class="java">import java.lang.reflect.Constructor; import ...

  10. 【Unity Shader】---基础光照

    一.[标准光照模型]1.自发光emissve:描述一个表面本身会发散多少光.在没有使用全局光照时,这些自发光是不会真正照亮周围物体. 自发光就是直接由发光体发射进入摄像机,不经过任何反射,在标准光照模 ...

随机推荐

  1. SQL Server 清除表TRUNCATE TABLE 提示: 因为该表正由 FOREIGN KEY 约束引用

    https://blog.csdn.net/dengguawei0519/article/details/101315699 1.找到引用这个表外键名称 SELECT * FROM sys.forei ...

  2. java基础--List

    List基本属性和方法移步官方文档: List (Java Platform SE 8 ) 1.处理最简单的List<String>: (1)并集.交集.差集 并集: 如果只用List.a ...

  3. 工作中常见的OOM?你了解JVM调优吗?

    工作中常见的6种OOM问题 堆内存OOM 堆内存OOM是最常见的OOM了. 出现堆内存OOM问题的异常信息如下: java.lang.OutOfMemoryError: Java heap space ...

  4. iPaaS 集成究竟是什么?深度解析集成平台即服务的核心价值

    一.iPaaS 的定义与核心功能 iPaaS(Integration Platform as a Service,集成平台即服务) 是一种基于云计算的集成解决方案,通过预构建的连接器.API和自动化工 ...

  5. SciTech-Docs.-RFC2119-Key words for use in RFCs to Indicate Requirement Levels@NetworkWorkingGroup:S.Bradner@HarvardUniversity

    R.F.C. : Request For Comments https://www.rfc-editor.org/rfc/rfc2119 ,Key words for use in RFCs to I ...

  6. unity判断点是否在长方体内部

    using UnityEngine; public class CubeCheck : MonoBehaviour { // 长方体的位置.旋转和尺寸 public Vector3 position ...

  7. Notes of Effective CMake

    Notes of Effective CMake 目录 Notes of Effective CMake 1. The Philosophy of Modern CMake Why "Eff ...

  8. NewStar CTF[pwn] overwrite WriteUp

    IDA打开,查看func()函数,得到以下代码 点击查看代码 unsigned __int64 func() { size_t input1[6]; // [rsp+Ch] [rbp-84h] BYR ...

  9. tcpdump linux 抓包 - 三次握手 四次挥手

    前提: 1. linux环境 2. 可正常使用tcpdump 使用(node)serve -p 10005 启动一个前端 前端存放一个静态1.txt文件,内容为test 模拟:在linux环境中启动一 ...

  10. Mac OS键盘常用快捷键

    图形 按键 ⌘ Command 键 ⌃ Control 键 ⌥ Option 键 ⇧ Shift 键 ⇪ Caps Lock fn 功能键 常用快捷键 剪切.拷贝和粘贴 您可以在大多数 app 中使用 ...