什么是 HDR?
HDR(High Dynamic Range,高动态范围)是一种图像技术,它允许像素值超过传统的 [0, 1] 范围。在现实世界中,阳光直射与阴影处的亮度差异可达 1,000,000:1,而普通显示器只能显示约 2,500:1 的对比度。

核心区别
LDR 管线下,所有计算都在 [0, 1] 范围内完成;而 HDR 管线下,中间结果可以超过 1.0,最终由 Tonemapper 压缩到可显示范围。
URP 中的 HDR 配置
在 Universal Render Pipeline Asset 中启用 HDR 是第一步。以下是关键设置位置:

| 设置项 | 说明 | 推荐值 |
|---|---|---|
| HDR | 启用高动态范围渲染 | ☑ 开启 |
| Antialiasing | 抗锯齿方法 | MSAA 4x / None |
| Tonemapping | 色调映射算法 | ACES |
| Bloom | 泛光效果(在 Volume 中) | Intensity 1.0+ |
Emission 与 HDR 的关系
Emission(自发光)是 HDR 管线中最常见的 >1.0 值来源。当材质启用 Emission 后,其输出可以超过 1.0,这些"过曝"的像素会储存在 HDR Buffer 中,等待 Tonemapper 的处理。
为什么 Emission 需要 HDR?
想象一个发光的霓虹灯牌:如果限制在 [0, 1],灯光只能呈现"较亮"的程度;但在 HDR 下,Emission 3.5 的灯牌会明显比 Emission 1.0 的灯牌更亮更真实,Bloom 效果也会相应增强。
Emission Intensity 的典型值
低强度 (0.5 - 1.0)
微弱发光、屏幕UI元素、次要指示灯。不会产生明显 Bloom,但参与光照计算。
中强度 (1.0 - 3.0)
标准发光材质、霓虹灯、显示器屏幕。开始产生可感知的 Bloom 光晕。
高强度 (3.0 - 10.0+)
太阳表面、爆炸核心、激光束。需要 Tonemapping 才能正常显示,否则会完全过曝。
Tonemapping 的作用
Tonemapping(色调映射)是 HDR 到 LDR 的桥梁。它将 HDR Buffer 中任意范围的像素值压缩到 [0, 1],同时尽可能保留人眼感知的亮度对比。

ACES Filmic
行业标准曲线,源自美国电影艺术与科学学院。完美平衡高光与阴影,是 URP 默认推荐选项。
Neutral
中性色调映射,保持色彩平衡。适合写实风格,对饱和度控制更好。
None
不进行色调映射,超出 1.0 的值会直接被截断。视觉效果通常较差。
为什么不能 clamp?
这是 HDR 渲染中最常见的错误之一。当开发者在 Shader 中直接写 clamp(color, 0.0, 1.0) 时,看似在"修正"输出,实际上是在破坏 HDR 管线。

关键认知
Blooms 是基于 HDR 缓冲区中像素值的相对差异 来工作的。如果你在 Shader 中提前 clamp,差异消失,Bloom 效果随之消失。
正确的 Shader 写法
错误写法
cs
// ❌ 错误:在 Shader 中截断 HDR 值
float3 CalculateEmission(float3 emissionColor, float intensity) {
float3 emission = emissionColor * intensity;
// 🚫 这里破坏了 HDR 信息!
return clamp(emission, 0.0, 1.0);
正确写法
cs
// ✅ 正确:保留 HDR 值,让 Tonemapper 处理
float3 CalculateEmission(float3 emissionColor, float intensity) {
// 直接返回 HDR 值,不需要 clamp
// Tonemapping 会自动压缩到 [0, 1]
return emissionColor * intensity;
}
标准 Surface Shader 片段
cs
struct SurfaceData {
float3 albedo;
float3 emission; // HDR,可以 > 1.0
float metallic;
float smoothness;
float alpha;
};
void InitializeSurfaceData(float3 emissionColor, float intensity,
out SurfaceData surfaceData) {
// ✅ 保留 HDR emission 值
surfaceData.emission = emissionColor * intensity;
// ⚠️ 注意:仅对 alpha 做 clamp,这是合理的
surfaceData.alpha = clamp(surfaceData.alpha, 0.0, 1.0);
}
全链路示例:从 Emission 到输出
cs
// ===== 管线各阶段的 clamp 策略 =====
// ✅ Phase 1: 材质计算 - 不 clamp emission
float3 CalcMaterialEmission(float3 baseColor, float intensity) {
return baseColor * intensity; // HDR, 可 > 1.0
}
// ✅ Phase 2: 光照计算 - 不 clamp 最终颜色
float3 CalcLighting(float3 albedo, float3 emission,
float metallic, float smoothness,
float3 lightColor, float3 normal, float3 viewDir) {
float3 diffuse = albedo * saturate(dot(normal, viewDir));
float3 finalColor = diffuse + emission; // HDR
return finalColor; // 🚫 不要 clamp!
}
// ✅ Phase 3: 后处理 - 由 Tonemapper 统一处理
float3 ApplyTonemapping(float3 hdrColor) {
// ACES 近似实现
float3 a = 2.51;
float3 b = 0.03;
float3 c = 2.43;
float3 d = 0.59;
float3 e = 0.14;
return (hdrColor * (a * hdrColor + b)) /
(hdrColor * (c * hdrColor + d) + e);
}
实际应用检查清单
在 URP 项目中实施 HDR 时,遵循以下检查清单确保效果正确:
-
URP Pipeline Asset 中启用 HDR
Project Settings → Graphics → Quality → 当前使用的 Asset → HDR = On
-
配置 Tonemapping 模式为 ACES
在 Pipeline Asset 中设置 Tonemapping = ACES Filmic
-
Bloom Volume 组件激活
Post-process Volume → 勾选 Bloom,Intensity 建议 1.0-2.0
-
Emission 材质使用 HDR 强度值
材质 Emission Intensity > 1.0 以触发 Bloom
-
Shader 中不截断 Emission 和最终颜色
仅 clamp alpha 值,保留 HDR 信息给 Tonemapper
-
在支持 HDR 的显示器上验证效果
SDR 显示器无法完全展示 HDR 效果,但 Tonemapping 使其仍可接受
总结
HDR 与 Tonemapping 是现代游戏渲染的基石技术。理解它们之间的关系,需要建立一种"管道意识":

核心原则
在 Shader 中 保留 HDR 值,让 Tonemapper 在渲染管线的正确阶段完成色调映射。不要在中间步骤截断,只有输出到屏幕前才需要 Tonemapping 的压缩。