【光照】[PBR][漫反射]实现方法对比
【从UnityURP开始探索游戏渲染】专栏-直达
URP BRDF漫反射方法对比
方法名称 | 数学公式 | 特点 | 性能消耗 | 适用场景 |
---|---|---|---|---|
Lambert | $L_d = k_d * max(0, N·L)$ | 经典模型,能量不守恒 | ★☆☆ | 移动端低配 |
Half-Lambert | $L_d = k_d * (0.5*(N·L)+0.5)^2$ | 增强暗部细节 | ★★☆ | 卡通渲染 |
Disney Diffuse | 复杂能量守恒公式 | 物理准确,计算复杂 | ★★★ | PC/主机高品质 |
Burley Diffuse | 基于微表面理论 | PBR标准,次表面散射近似 | ★★★ | 金属/粗糙度工作流 |
具体实现方法及示例
Lambert模型(URP默认)
hlsl
// Lighting.hlsl 中的实现
half3 DiffuseLambert(half3 diffuseColor)
{
return diffuseColor / PI; // 能量归一化
}
// 实际调用示例
half NdotL = saturate(dot(normalWS, light.direction));
half3 lambert = DiffuseLambert(_BaseColor.rgb) * NdotL;
Half-Lambert(Valve改进版)
hlsl
half3 DiffuseHalfLambert(half3 diffuseColor, half NdotL)
{
half wrap = 0.5 * (NdotL + 1.0);
return diffuseColor * wrap * wrap;
}
// 调用示例
half3 halfLambert = DiffuseHalfLambert(_BaseColor.rgb, NdotL);
Disney Diffuse(URP Lit.shader使用)
hlsl
// BRDF.hlsl 中的实现
half3 DiffuseDisney(half3 baseColor, half NdotV, half NdotL, half LdotH, half roughness)
{
half fd90 = 0.5 + 2 * LdotH * LdotH * roughness;
half lightScatter = (1 + (fd90 - 1) * pow(1 - NdotL, 5));
half viewScatter = (1 + (fd90 - 1) * pow(1 - NdotV, 5));
return baseColor * lightScatter * viewScatter / PI;
}
URP实际使用情况
默认采用方案:
- Simple Lit管线:Lambert模型(简化版)
- Lit管线:Disney Diffuse + Burley改进(见
BRDF.hlsl
)
核心代码路径:
Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl
→ DirectBDRF()函数
→ DisneyDiffuse()分支
性能优化策略:
csharp
// URP Asset中可关闭高质量漫反射
UniversalRenderPipelineAsset.asset →
Lighting → UseRoughnessRefraction = false
方法对比
- 视觉差异:
- Lambert:明暗对比强烈
- Half-Lambert:暗部提亮约30%
- Disney:边缘光更自然(菲涅尔效应)
- 推荐选择:
- 移动端:Lambert(Simple Lit)
- 主机/PC:Disney(Lit Shader)
- 风格化:Half-Lambert(需自定义Shader)
URP 2022 LTS版本中,主流的Lit.shader默认使用改进版Disney模型,通过#define _BRDF_BURLEY
宏启用。开发者可通过修改BRDF.hlsl
中的#define
语句切换不同模型。
除了以上Unity URP中涉及到的基于物理光照模型的漫反射实现方式,还有Oren-Nayar模型来实现漫反射
Oren-Nayar模型原理
核心思想:
由Michael Oren和Shree Nayar于1994年提出,基于微表面自阴影理论,适用于粗糙表面(如布料、砂石)。其公式为:
$L = k_d * max(0, N·L) * (A + B * max(0, cos(φ_v-φ_l)) * sin(α) * tan(β))$
$A = 1 - 0.5*(σ²)/(σ²+0.33)$
$B = 0.45*(σ²)/(σ²+0.09)$
$α = max(θ_v, θ_l)$
$β = min(θ_v, θ_l)$
- σ:表面粗糙度参数(0°-90°)
- φ:方位角
视觉特性:
- 粗糙表面边缘亮度增强
- 逆向光时出现"后向散射"效果
- 相比Lambert更符合真实布料观测
Unity URP中的使用情况
- 默认未采用原因:
- 性能考量:需要额外计算角度和粗糙度(比Lambert多30%指令数)
- 艺术控制:参数物理意义不如PBR直观
- 光照一致性:URP优先保证移动端性能
- 替代方案:
- 简单场景:使用
SimpleLit
的Lambert - 复杂材质:通过
Lit
Shader的Smoothness
参数间接控制
- 简单场景:使用
手动实现方案
若需在URP中使用Oren-Nayar,可修改BRDF.hlsl
:
hlsl
// 在BRDF.hlsl中添加
half3 DiffuseOrenNayar(half3 albedo, half roughness, half NdotV, half NdotL, half LdotV)
{
half sigma2 = roughness * roughness;
half A = 1.0 - 0.5 * sigma2 / (sigma2 + 0.33);
half B = 0.45 * sigma2 / (sigma2 + 0.09);
half s = LdotV - NdotL * NdotV;
half t = s > 0 ? 1.0 / max(NdotL, NdotV) : 1.0;
return albedo * (A + B * s * t) * NdotL;
}
适用场景建议
推荐使用情况:
- 风格化渲染(如手绘布料)
- 考古/地质仿真项目
- 需要特殊边缘光效果的场景
性能对比:
模型 指令数(移动端) 内存访问 Lambert 12 3 Oren-Nayar 38 5 Disney 45 6
当前URP 2022 LTS版本中,可通过自定义Shader Graph节点实现Oren-Nayar,但官方未内置因其不符合URP的"性能优先"设计原则。实际项目中建议通过法线贴图+Lambert近似替代。
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,)
【光照】[PBR][漫反射]实现方法对比的更多相关文章
- Linux和Windows下查看环境变量方法对比
摘自:Linux和Windows下查看环境变量方法对比 一.查看所有环境变量的名称和值 Linux下:export Windows下:set 二.根据名称查该环境变量的值 Linux下:echo $环 ...
- C语言清空输入缓冲区的N种方法对比
转自C语言清空输入缓冲区的N种方法对比 C语言中有几个基本输入函数: //获取字符系列 int fgetc(FILE *stream); int getc(FILE *stream); int get ...
- iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比
iPhone开发 数据持久化总结(终结篇)—5种数据持久化方法对比 iphoneiPhoneIPhoneIPHONEIphone数据持久化 对比总结 本篇对IOS中常用的5种数据持久化方法进行简单 ...
- interrupt interrupted isInterrupted 方法对比、区别与联系 多线程中篇(八)
interrupt interrupted isInterrupted 是三个“长相”非常类似的方法. 本文将对这三个方法简单的对比下,首先了解下线程停止的方式 线程停止方式 在Java中如果想停止一 ...
- JavaScript中易混淆的DOM属性及方法对比
JavaScript中易混淆的DOM属性及方法对比 ParentNode.children VS Node.prototype.childNodes ParentNode.children:该属性继承 ...
- vue-cli 项目优化之3种方法对比:本地静态库资源(推荐)、cdn、DllPlugin
vue-cli 项目优化之3种方法对比:本地静态库资源(推荐).cdn.DllPlugin 事项 本地静态库资源 cdn DllPlugin 依赖 依赖cdn网站资源(有种完善方法:如果cdn引入不成 ...
- vue 和 react 组件间通信方法对比
vue 和 react 组件间通信方法对比: 通信路径 vue的方法 react的方法 父组件 => 子组件 props(推荐).slot(推荐).this.$refs.this.$childr ...
- js与jQuery方法对比
javascript与jQuery方法对比jquery对象转dom对象 // 方式一(推荐使用) $("input")[0] // 方式二 $("input" ...
- 【Unity Shader学习笔记】Unity光照基础-漫反射光照
本代码只适用于平行光. 1.逐顶点漫反射光照 1.1漫反射光照原理 1.2代码实现 在Properties语义块中声明一个漫反射颜色属性 Properties { //漫反射参数,用于调整漫反射效果 ...
- Unity3D 开发之shader教程(浅谈光照之漫反射diffuse)
在游戏开发过程中,光照应该是必不可少部分,当然,这是指大多数的稍微大型一些的3D游戏会需要,给模型或者山山水水加上光照,会看上去更加的真实,获得更好的体验.一个本身不发光物体显示什么颜色,在于本身反射 ...
随机推荐
- react发布一个组件库 系列篇(二)
前言 在上篇说到,不是特殊情况,我们尽量还是把源码打包编译成es5之后再发布到npm,这样用户使用的时候就很方便. 接下来我们就还拿上章的代码,使用rollup+babel编译.打包后再发版,来举个例 ...
- ETL快速同步 用友u8数据方式
在企业信息化进程中,用友U8作为一款广泛应用的ERP系统,承载着企业核心业务数据.为了实现这些数据的有效利用与深度分析,往往需要通过ETL(Extract, Transform, Load)工具进行快 ...
- H3C华三路由器抓包并显示会话
相信大家都遇到过这么样的情况,客户说他的包已经发出来了,但是没有收到对方的回包,对方说我这里网络一切正常,就这么僵持着.其实有些厂商设备是可以通过ACL匹配流量,然后通过debug输出在CLI终端上, ...
- 管理心理学 Management Psychology
管理心理学 Management Psychology 作者: 浏览量:4046 [课程编号][所属模块]专业方向课 [学分数]3学分 [适用专业]心理学 [学时数]52学时 [开设学期]秋季 [已开 ...
- SciTech-Python-编译Python的C/C++扩展的setup.py使用pybind映射C/C++到Python库
pybind:pybind11 - Seamless operability between C++11 and Python header-only library exposes C++ type ...
- SciTech-Mathmatics-Probability+Statistics-IV-Population:Parameter<->Sample:Statistics : Confidence Interval(置信区间)
SciTech-Mathmatics-Probability+Statistics-IV- Population:Parameter<->Sample:Statistics : CI(Co ...
- SciTech-Mathematics-Probability+Statistics-Causation vs. Correlation: From Correlation to Causation: Deep Dive into Data Interpretation
https://www.statology.org/from-correlation-to-causation-deep-dive-into-data-interpretation/ From Cor ...
- 标准结构篇:10)合理收集和理解标准standards
本章目标:合理收集.理解.使用标准. 1.前言 没有比标准更好的设计依据了. 如果说哪种设计更可靠.更能经得起验证.更能说服别人,那就是按照国家标准的设计(有明确标准编号的那种). 依据标准来设计,总 ...
- uni-app支付宝小程序样式穿透失效
前情 uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验也挺棒的,公司项目就是主推uni-app,对于一些组件我觉得可 ...
- .NET 10 中的新增功能系列文章3—— .NET MAUI 中的新增功能
.NET 10 预览版 6 中的 .NET MAUI .NET 10 预览版 5 中的.NET MAUI .NET 10 预览版 4 中的 .NET MAUI .NET 10 预览版 3 中的 .NE ...