【光照】[漫反射]UnityURP兰伯特能量守恒吗?

news/2025/9/19 11:20:44/文章来源:https://www.cnblogs.com/SmalBox/p/19100428

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

兰伯特漫反射的能量守恒性

‌能量守恒基本原理‌

在物理正确的渲染中,能量守恒要求:

  1. 表面反射的光能总量 ≤ 入射光能
  2. 漫反射+高光反射 ≤ 1.0
  3. 没有能量凭空产生或消失

‌经典兰伯特模型的能量守恒问题‌

传统兰伯特漫反射公式:

$漫反射 = 表面反照率 × max(0, N·L)$

不守恒的原因‌:

  • 缺乏归一化因子‌:
    • 半球积分结果应为π,但兰伯特模型直接使用N·L
    • 正确公式应为:$漫反射 = 表面反照率 / π × max(0, N·L)$
  • 反射率超标‌:
    • 当反照率(albedo)设为1.0时,反射率可能超过100%
    • 例如:N·L=1时反射率为100%,但实际应有吸收损失
  • 恒定反射率‌:
    • 对所有入射角使用相同反射率
    • 现实中菲涅尔效应导致掠射角反射率增加

‌URP中的修正方案‌

Unity URP采用改进的兰伯特模型:

hlsl
// URP实际实现(Lighting.hlsl)
half diffuseTerm = saturate(dot(normal, lightDir));
half3 diffuse = albedo * lightColor * diffuseTerm * INV_PI;

其中:

  • INV_PI ≈ 0.31831 (1/π)
  • 通过除以π实现能量归一化

PBR工作流兼容性分析

‌兼容性类型‌

兼容维度 支持情况 说明
数据输入 ✅ 完全兼容 使用相同的albedo贴图输入
光照计算 ⚠️ 部分兼容 缺乏物理反射特性
材质工作流 ✅ 完全兼容 支持标准材质参数
后期处理 ✅ 完全兼容 兼容HDR/Bloom等效果
全局光照 ⚠️ 有限兼容 需要特殊处理

‌完全兼容的方面‌

  • 材质参数统一‌:
    • 使用相同的albedo纹理和颜色参数
    • 支持相同的法线贴图格式
  • HDR管线整合‌:
    • 支持线性颜色空间
    • 兼容HDR渲染和自动曝光
  • 后期处理协同‌:
    • 与Bloom效果无缝配合
    • 支持屏幕空间环境光遮蔽(SSAO)

‌有限兼容的方面‌

  • 能量守恒缺口‌:

    graph LR A[入射光能量] --> B[经验模型] B --> C[漫反射输出] C --> D{能量总和} D --> |100%| E[违反守恒] D --> |物理模型<90%| F[正确守恒]
  • 金属度工作流问题‌:

    • 金属表面应无漫反射,但兰伯特模型无法正确处理
    • 需要额外代码屏蔽金属表面的漫反射
  • 菲涅尔效应缺失‌:

    • 掠射角反射率无增强
    • 影响边缘光照的真实性
  • 全局光照不一致‌:

    • 与基于物理的GI系统配合时可能出现能量不匹配
    • 需要手动调整间接光照强度

‌URP中的兼容性实现‌

  • URP采用混合方案实现兼容:
hlsl
// URP的BRDF处理(BRDF.hlsl)
half3 BRDF_lambert(half3 albedo)
{return albedo * INV_PI;
}#if defined(_PBR_ENABLED)// 物理正确的漫反射计算half3 diffuse = BRDF_lambert(albedo) * saturate(NdotL);
#else// 传统兰伯特计算half3 diffuse = albedo * saturate(NdotL);
#endif

结论与建议

‌能量守恒结论‌

  • 原始兰伯特模型不守恒‌:缺乏归一化因子,反射率可能超标
  • 修正版可基本守恒‌:通过添加1/π因子实现能量平衡
  • URP实现部分守恒‌:在标准着色器中已包含修正因子

‌PBR兼容性结论‌

  • ✅ ‌美术工作流兼容‌:可使用相同材质和纹理
  • ️ ‌物理精度局限‌:无法完全匹配物理反射特性
  • ️ ‌工程实用方案‌:适合风格化/性能优先项目

‌实际开发建议‌

  • 移动端项目‌:

    hlsl
    // 使用优化版兰伯特(包含能量修正)
    half3 diffuse = albedo * saturate(NdotL) * 0.31831;
    
  • PC/主机项目‌:

    hlsl
    // 使用完整PBR漫反射(Disney模型)
    half3 diffuse = albedo * (1 / PI) * (1 - metallic) * saturate(NdotL);
    
  • 风格化渲染‌:

    hlsl
    // 艺术导向的增强版
    half3 diffuse = albedo * pow(saturate(NdotL), _RampPower) * _Intensity;
    

在URP中,经验模型与PBR工作流可通过条件编译实现无缝切换,开发者可根据目标平台和艺术需求选择最适合的模型,在物理准确性和性能之间取得最佳平衡。


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

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

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/907719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft AI Genius 限时挑战赛:实战开启,等你应战!

通过 Microsoft AI Genius 系列 2.0 的实战专题课程,相信各位开发者对智能 GitHub Copilot 副驾驶 Agent Mode、Azure AI Foundry Agent Service(国际版)及 Copilot Studio 的理解与掌握达到了新高度。现在,是时候…

DevSecOps革命:测试工具如何重塑企业数字化转型的质量防线

DevSecOps革命:测试工具如何重塑企业数字化转型的质量防线 在数字化转型浪潮席卷全球的当下,软件质量保障体系正经历着前所未有的范式转变。DevSecOps作为这场变革的核心方法论,正在重新定义测试工具在企业技术栈中…

3.sysaux tablesace 清理

select min(snap_id),max(snap_id) from dba_hist_snapshot; 查完后,记录min和max的值 select dbid from v$database; 18701与18953分别为min与max的snap_id的值,387090299为dbid的值,将这些值代入下面的语句执行 b…

2.LOCK session

select * from v$session_blockers; 或者 select * from gv$session_blockers; (在rac情况下) 通过 select count(1) from v$locked_object; 可以查出内容 首先询问客户能否提供lock table的session sid和serial#,如…

php本地搭建知识库实现rag遇到的一些问题解决方式

1、向量化的问题,中文的话,使用尽量使用国内的嵌入模型,国外的虽然支持中文,但是还是比不上国内专门针对中文的优化 本地使用ollama 搭建的话 ,我使用的是 quentinz/bge-large-zh-v1.5:latest2、不规则的pdf文件…

2025 ~ 2026 游击 - gfoi

2025/09/19 试了试 CSP-S 的历年题目,2019 年有 84.5 分。

【初赛】第二类斯特林数意义 - Slayer

第二类斯特林数(斯特林子集数) \(\begin{Bmatrix}n\\ k\end{Bmatrix}\),也可记做 \(S(n,k)\),表示将 \(n\) 个两两不同的元素,划分为 \(k\) 个互不区分的非空子集的方案数。 通项公式 \(\begin{Bmatrix}n\\m\end{…

在AI技术快速实现功能的时代,挖掘新需求成为核心竞争力——某知名Android面试题库需求洞察

该篇文章无摘要a.内容描述 该项目是一个专注于Android开发领域的技术面试题库,核心功能定位为提供全面的Android面试问题与答案集合,帮助开发者准备技术面试。关键应用场景包括Android开发者求职准备、技术知识查漏补…

php本地搭建知识库实现rag遇到的各种问题解决方式

1、向量化的问题,中文的话,使用尽量使用国内的嵌入模型,国外的虽然支持中文,但是还是比不上国内专门针对中文的优化 本地使用ollama 搭建的话 ,我使用的是 quentinz/bge-large-zh-v1.5:latest2、不规则的pdf文件…

docker操作包括使用docker制作为接口

Docker 化 Flask OCR 应用指南 1. 创建必要的文件 在你的 Flask 应用项目根目录下,你需要创建以下文件: 1.1 Dockerfile 这是一个文本文件,包含了构建 Docker 镜像所需的所有指令1 # 使用官方 Python 3.10 (Python…

BuildingSystemPlugin使用指南

使用自定义碰撞 1.启用Use Custom Overlay:2.修改Overlapping Box的BoxExtent来设置大小(不能设置Scale来设置大小):

openEuler 24.03 (LTS-SP2)安装mysql5.7.42

环境:OS:openEuler 24.03 (LTS-SP2)(安装时候没有图形界面的选择项可选)mysql:5.7.42 glib.2.17 操作系统下载https://www.openeuler.org/en/download/#openEuler%2024.03%20LTS%20SP2 查看系统glibc版本[root@localho…

Trae AI IDE与Gitee MCP深度整合:开启智能协作开发新时代

Trae AI IDE与Gitee MCP深度整合:开启智能协作开发新时代 在AI技术快速渗透软件开发领域的当下,字节跳动推出的Trae AI IDE凭借其创新的智能编码能力,正在重塑开发者的工作流程。这款国产AI编程工具通过深度整合Git…

【字节跳动】LLM大模型算法面试题:大模型 LLM的架构介绍? - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

LangChain 入门:从 0 到 1 搞懂 LLM 应用开发框架​

LangChain 入门:从 0 到 1 搞懂 LLM 应用开发框架​如果你常逛技术社区,大概率听过 “大语言模型(LLM)能做很多事”—— 写文案、答问题、编代码,但真要把它放进实际业务里,比如给公司做个智能客服、给团队搭个文…

cpu wa

cpu wa👌 我明白了,你需要的是把 两个文档合并:逐指标展开分析逻辑(cycles/instructions、context-switches、page-faults、syscalls 等 → 如何推导分支)。典型 %wa 场景说明(本地块设备、NFS/iSCSI、Swap、虚…

解码C语言指针

一、指针的定义与本质 1. 指针是什么? 指针是一种 存储变量内存地址 的特殊变量。所有数据存储在内存中,每个内存单元都有唯一地址(编号),指针通过记录地址实现对数据的间接访问。 2. 指针的核心作用直接操作内存…

windows下Qt调用fftw库

环境:Windows 11 Qt:6.8.3 程序中需要用到fftw库来进行傅里叶变换,通过网上的资料,配置了很久一直没成功,后来发下还是没有配置正确,最后终于成功,顺便记录一下 1.下载fftw3.3.5 http://www.fftw.org/install/…

Gitee崛起:国产代码托管平台如何接棒CODING成为开发者新宠

Gitee崛起:国产代码托管平台如何接棒CODING成为开发者新宠 随着腾讯云宣布CODING DevOps系列产品逐步停止服务,中国开发者生态正在经历一次重要的基础设施迁移。在这场变革中,开源中国旗下Gitee平台凭借其十年本土化…

flask下的MySQL增查配置

flask下的MySQL增删配置 添加数据 @app.route(/add) def add_data():u = UserInfo()new_user1 = UserInfo(nickname=flask_test1, mobile=13888888888, signature=理想, create_time=datetime.now(), role_id=1)new_us…