【光照】Unity中的[物理模型]PBR

news/2025/9/25 16:17:35/文章来源:https://www.cnblogs.com/SmalBox/p/19111418

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

PBR(Physically Based Rendendering)的核心内容与BRDF应用‌

PBR是一种基于物理光学原理的渲染框架,其核心是通过‌物理可测量的材质属性‌和‌真实的光照计算规则‌实现跨环境一致的真实感渲染。


‌PBR四大核心支柱‌

模块 作用 关键参数
材质参数系统 定义物体固有光学属性 金属度(Metallic)粗糙度(Roughness)基础反射率(Albedo)
微表面理论 描述微观几何对光的影响 法线分布(NDF)几何遮蔽(G)菲涅尔(F)
能量守恒约束 确保物理正确性 漫反射+镜面反射≤入射光能
线性工作流 模拟真实光强度 HDR环境光照伽马校正

BRDF和PBR的关系

BRDF(双向反射分布函数)与PBR(基于物理的渲染)是计算机图形学中紧密关联的两个概念.

理论层级关系

  • BRDF是PBR的数学基础

    BRDF通过微表面理论(Microfacet Theory)描述光线与物体表面的交互,定义了入射光方向(ωi)与出射光方向(ωo)的反射比例关系‌。

    PBR则基于BRDF构建完整的渲染流程,通过物理参数(如粗糙度、金属度)实现真实材质模拟‌。

  • PBR的三大核心条件

    • 微表面理论(BRDF的物理基础)
    • 能量守恒(BRDF需满足反射率≤1)
    • 基于物理的BRDF(如Cook-Torrance模型)‌

技术实现差异

特性 BRDF PBR
作用范围 局部反射计算(单点光照) 全局渲染流程(含IBL、阴影等)
参数化 数学函数(如GGX、Schlick) 材质系统(URP/Standard Shader)
物理准确性 高(需满足能量守恒) 更高(整合多物理效应)

Unity中的实际应用

  • BRDF实现
    • URP的BRDF.hlsl文件包含GGX法线分布、菲涅尔项等核心计算‌。
    • 示例:BRDF_Unity_PBS函数组合漫反射与镜面反射‌。
  • PBR流程
    • 通过Lighting.hlsl整合BRDF与IBL(环境光遮蔽)‌。
    • 材质参数(如_Metallic)直接控制BRDF行为‌。

演进与扩展

  • 从BRDF到PBR‌:BRDF解决了Phong模型非物理问题,PBR进一步扩展至全局光照(如IBL)和材质系统‌。
  • 现代应用‌:URP/Standard Shader均采用PBR流程,但底层仍依赖BRDF的数学实现‌

BRDF(PBR)实现

核心脚本

  • BRDF.hlsl(路径:Packages/com.unity.render-pipelines.universal/ShaderLibrary/
  • 关键类:BRDFData(存储粗糙度、金属度等参数)和Lighting.hlsl(处理光照计算)

实现方法

  • GGX法线分布函数‌:

    hlsl
    float D_GGX(float NdotH, float roughness) {float a = roughness * roughness;return a / (PI * pow((NdotH * NdotH * (a - 1.0) + 1.0), 2.0));
    }
    
  • 菲涅尔项 Schlick近似‌:其中F0为基础反射率(金属材质为0.9,非金属为0.04)

    hlsl
    float3 F_Schlick(float3 F0, float VdotH) {return F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);
    }
    

调用流程

  • 在Shader中通过#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"引入
  • 最终调用BRDF_Unity_PBS函数组合漫反射和镜面反射

自定义扩展

  • 新增光照模型
    • 修改StencilUsage.cs定义新的Stencil值(如MaterialCustom
    • GBufferPass.cs中添加对应Shader Tag和Stencil写入逻辑
  • 参数调整
    • 标准光照模型:通过Material面板调整_Specular_Glossiness
    • BRDF模型:调整_Metallic_Smoothness参数

对比总结

特性 标准光照模型 BRDF模型
实现文件 SimpleLit.shader BRDF.hlsl + Lighting.hlsl
核心函数 UniversalFragmentBlinnPhong BRDF_Unity_PBS
物理准确性 低(经验模型) 高(微表面理论)

如需深度定制,建议参考URP官方Shader库中的Lighting.hlslBRDF.hlsl实现

‌BRDF在PBR中的具体应用‌

PBR通过分解BRDF实现光照计算,以下是各部分的实现原理:

‌镜面反射计算(Cook-Torrance BRDF)

PBR直接调用BRDF的微表面模型:

$f_{spec}=\frac{F⋅D⋅G}{4(n⋅ω_i)(n⋅ω_o)}$

  • 🔴 菲涅尔项 F

    基于Schlick近似:

    $F = F_0 + (1 - F_0)(1 - \cos\theta)^5$

    PBR应用‌:

    • $F_0$由金属度控制(金属=Albedo,非金属=0.04)
    • 掠射角反射增强自动实现(如水面倒影随视角变化)
  • 🔵 法线分布 D

    GGX模型‌(主流选择):

    $D = \frac{\alpha_g2}{\pi[(n·h)2(\alpha_g2-1)+1]2}$

    PBR应用‌:

    • 粗糙度参数α = roughness²控制高光扩散
    • 粗糙度高→微表面法线分散→宽泛柔和高光
  • 🟢 几何遮蔽 G

    Smith联合遮蔽函数:

    $G = \frac{n·\omega_i}{n·\omega_i + k} · \frac{n·\omega_o}{n·\omega_o + k}$

    PBR应用‌:

    • $k = (roughness + 1)^2 / 8$ 控制自阴影
    • 防止粗糙表面边缘过亮(如磨损金属棱角)

漫反射计算

采用‌能量守恒型Lambert模型‌:

$f_{diff}=\frac{albedo}{π}⋅(1−F)⋅(1−metallic)$

PBR优化‌:

  • 金属度metallic=1时漫反射归零(纯金属无漫反射)
  • (1-F)确保未被镜面反射的光才参与漫反射

‌环境光照(IBL)

PBR将BRDF扩展到环境光:

技术 作用 BRDF整合方式
辐照度图 漫反射环境光 对BRDF的cos项半球积分
预滤波环境图 镜面反射环境光 按粗糙度预过滤GGX分布
BRDF LUT 菲涅尔补偿 存储∫fspecdωi∫fspecdωi预积分结果

‌PBR渲染流程中的BRDF调用‌

典型PBR着色器代码结构(Unity URP示例):

hlsl
// 输入参数
float3 albedo = baseColor.rgb;
float metallic = params.x;
float roughness = params.y;// 1. 计算直接光照BRDF
float3 F0 = lerp(0.04, albedo, metallic); // 基础反射率
float3 directLight = 0;
foreach (Light light in sceneLights) {float3 H = normalize(V + L);float NdotV = dot(N, V);float NdotL = dot(N, L);// BRDF计算float3 F = FresnelSchlick(max(dot(H, V), 0.0), F0);float D = NDF_GGX(roughness, N, H);float G = GeometrySmith(roughness, NdotV, NdotL);float3 kS = F; // 镜面反射比例float3 kD = (1 - F) * (1 - metallic); // 漫反射比例// Cook-Torrance BRDFfloat3 specularBRDF = (F * D * G) / max(4.0 * NdotV * NdotL, 0.001);float3 diffuseBRDF = kD * albedo / PI;directLight += (diffuseBRDF + specularBRDF) * lightColor;
}// 2. 应用IBL环境BRDF
float3 envDiffuse = texture(irradianceMap, N).rgb * albedo;
float3 R = reflect(-V, N);
float3 envSpecular = textureLod(prefilterMap, R, roughness * MAX_LOD).rgb;
float2 envBRDF = texture(BRDF_LUT, float2(NdotV, roughness)).rg;
float3 iblSpecular = envSpecular * (F0 * envBRDF.x + envBRDF.y);// 3. 组合结果(能量守恒)
float3 result = (directLight + envDiffuse + iblSpecular) * aoMap;

‌PBR与传统渲染的本质区别‌

特性 传统光照模型 PBR+BRDF
参数意义 人工经验值 物理可测量属性
高光控制 独立高光强度参数 粗糙度+金属度推导
环境响应 环境贴图简单叠加 IBL精确匹配BRDF
一致性 不同光照需重调参数 一次校准全场景适用

‌案例说明:金属铜材质‌

  • 材质参数‌:

    albedo = (0.95, 0.64, 0.54)(铜色)

    metallic = 0.98

    roughness = 0.3

  • BRDF作用‌:

    • 菲涅尔项F:掠射角反射增强至金色
    • GGX分布D:中等粗糙度产生柔化高光边缘
    • 几何遮蔽G:表面微小凹痕产生阴影细节
    • IBL:环境中的暖色光自然融入反射

🔍 ‌效果对比‌:传统Phong模型会显示均匀橙色+圆形高光,而PBR+BRDF呈现真实的金属渐变反射和表面微结构细节。

PBR通过系统化应用BRDF的物理光学模型,实现了材质表达的客观性和光照响应的真实性,成为现代3A游戏与影视渲染的工业标准。


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

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

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

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

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

相关文章

详细介绍:传输层————TCP

详细介绍:传输层————TCPpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

c++内建函数

builtin 是内建的意思。下面函数的时间复杂度都是 \(O(1)\) 的。 __builtin_ctz(x) 返回末尾的 0 的个数(__builtin_ctz(0) 未定义)。 __builtin_popcount(x) 返回二进制下的 popcount。

门户网站开发解决方案福田公司门口

标题线性位置不变退化估计退化函数采用观察法估计退化函数采用试验法估计退化函数采用建模法估计退化函数运动模糊函数OpenCV Motion Blur在这一节中,得到的结果,有些不是很好,我需要再努力多找资料,重新完成学习,如果…

鹤山市城乡住房建设部网站照着别人网站做

题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 解题思路 剑指offer的解法 看到这个题目&#xff0…

comfyui-数字人

comfyui-数字人sonic。 1、安装sonic相关插件 模型 2-1 、 图 +音频 生成数字人口播 正面的清晰的照片 , sonic 会按音频的内容 识别 生成对应的视频 2-2 ,只有一张图, +文字的话。 先文字 生成音频 。 音频+图片…

我天,前端岗要消亡了吗?

大家好,我是R哥。 之前分享过一篇文章:前端岗、测试岗即将消亡!阿里菜鸟国际后端研发全员转全栈有的大厂靠成熟的低代码、测试平台,逐渐把前端、测试边缘化了,比如阿里菜鸟国际后端研发全员转全栈这个事,说明前端…

java8的集合新API - --

https://blog.csdn.net/m0_37989980/article/details/126091233

基于MATLAB/Simulink的500kW三相光伏逆变器仿真

一、系统架构设计 1.1 主电路拓扑 graph LR A[光伏阵列] -->|直流母线| B(DC-DC转换器) B -->|800V DC| C[三电平NPC逆变桥] C -->|LCL滤波器| D[380V电网] 1.2 核心模块组成DC-DC模块:Boost电路+MPPT控制 逆…

重庆seo整站优化设置网页游戏破解版

前言 在我们日常工作中,经常会遇到一些异常,比如:NullPointerException、NumberFormatException、ClassCastException等等。 那么问题来了,我们该如何处理异常,让代码变得更优雅呢? 1 不要忽略异常 不知…

做cps需要什么样的网站asp建站软件

跟数据类型是有关的。当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。但是不是所有的变动都可以通过set/get捕捉到,比如一个数组l…

Docker Compose启动多个镜像实例

1. Docker Compose 基础概念Docker Compose 是一个工具,用 YAML 文件定义和运行 多容器 Docker 应用。核心文件:docker-compose.yml通过一个命令可以启动、停止、管理整个应用,而不必一个一个容器操作。Compose 文件…

深入解析:⸢ 伍-Ⅱ⸥ ⤳ 默认安全治理实践:水平越权检测 前端安全防控

深入解析:⸢ 伍-Ⅱ⸥ ⤳ 默认安全治理实践:水平越权检测 & 前端安全防控pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fa…

实用指南:在 CentOS 中安装 MySQL

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

卫星时间同步平台:助力分布式测控系统同步工作

卫星时间同步平台:助力分布式测控系统同步工作pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

mkfx 对磁盘设置标签

mkfs.xfs -i size=512 -n ftype=1 -L RUSTFS0 /dev/sdb -L <label>: 为文件系统设置一个标签(label),方便后续识别和挂载。-i size=512: RustFS官方推荐将inode大小设置为512字节,这对于存储大量小对象(元…

河南网站设计价格阿里云服务器学生

1. 为什么要使用框架 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。 几乎当下所有企业级JavaEE开发都离不开SSM&#xff08;Spring SpringMVC MyBatis&#xff09;Spring B…

C# Avalonia 15- Animation- Easing

C# Avalonia 15- Animation- EasingEasing.axaml代码<Window xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.m…

安卓编译重点记录

Ubuntu18.04编译安卓11详细步骤 在 Ubuntu 18.04 上编译 Android 11 的详细步骤 以下是为 ​Ubuntu 18.04 环境编译 ​Android 11(AOSP)​ 的完整指南,涵盖环境配置、源码下载、编译及常见问题解决。 ​1. 系统要求…

kubelet源码阅读(二)——device plugin 的ListAndWatch过程

从kubelet运行到plugin注册过程 kubernetes-master/pkg/kubelet/kubelet.go1 func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {2 // ...3 go wait.Until(kl.updateRuntimeUp, 5*time.Second,…

最新网站制作公司哪个好各大网站搜索引擎提交入口

同事电话询问Linux下一个集群内2个主机前后2天相继无响应&#xff0c;表现状况为ping都没响应。因为没任何监控或其他性能数据&#xff0c;故需要获取历史OS性能数据。我们知道rhel5,6下默认可以通过sar命令查看OS历史信息&#xff0c;故执行sar即可看到当天的数据。[rootora11…