当前位置: 首页 > java >正文

PBR渲染

参考Shader学习 (18)PBR光照模型效果分析手动复现 - 九猫的文章 - 知乎
https://zhuanlan.zhihu.com/p/364932774

PBR效果可以拆为两大部分,直接光照间接光照。在直接光照和间接光照的效果中,都能再分为漫反射镜面反射两种计算。

直接光照计算的是灯光在第一次接触到物体的时候产生的计算结果。而间接光照计算的就是光线从物体上被反射出去之后的效果。

直接光照

漫反射部分单独拿出来就是很常见的Lambert模型,一个简单的从亮到暗的过渡。

再说直接光照的镜面反射,拆分为几个更基础的效果:镜面高光、几何遮蔽、菲涅尔。

间接光照

漫反射的间接光使用球谐光照来实现,而镜面反射的间接光照由CubeMap来实现。

漫反射间接光照:(环境中其他物体表面反射的光线照射到当前物体上产生的漫反射效果"

球谐光照的的作用是为非金属的材质添加间接光照,它只受到金属度这一个参数的影响,当物体是金属时,不受到漫反射间接光照(球谐光照)的影响。

镜面反射间接光照:

CubeMap就是一张全景HDR图,CubeMap在制作或者说拍摄的时候,有球面映射的(较多)和立方体映射的。

镜面反射的显示收到两个参数的影响:Metallic和Roughness 。

金属物体反射的光线会带有金属本身的颜色,而非金属物体不论本身是什么颜色,它们反射的光线都是光线原本的颜色。金属物体的镜面反射的强度更高

 粗糙度控制CubeMap的Mip等级,Mip等级越高,贴图就越模糊。越粗糙的物体反射的光线越少,而越光滑的物体镜面反射就越强。(贴图的MipMap技术在各个游戏和影视中的应用非常广泛,简单来说就是把一张贴图缩小为多个等级的更小分辨率的图片保存下来,游戏运行时根据物体和摄像机的距离读取不同分辨率的图片。)

 在相同粗糙度的时候,金属材质颜色更暗一些,金属吸收的能量更多

  1. 能量守恒​:在PBR中,光线照射到物体表面时,会被分为两部分:一部分被反射(镜面反射),另一部分进入物体内部发生散射(漫反射)。总反射光不能超过入射光,即满足能量守恒。

  2. 金属与非金属的区别​:

    • 非金属(电介质)​​:光线进入物体内部,经过多次散射后部分光线重新射出表面形成漫反射,只有少部分光线在表面直接反射(镜面反射)。因此,非金属的漫反射较强,镜面反射较弱。
    • 金属(导体)​​:光线进入金属表面后,由于金属内部的自由电子会迅速吸收光线(转化为热能),所以几乎没有光线能够重新射出表面(即没有漫反射),大部分光线被反射(镜面反射)。因此,金属的镜面反射很强,漫反射几乎没有。
  3. 颜色与明暗​:

    • 非金属​:漫反射的颜色由物体表面的色素(即Albedo颜色)决定,所以看起来颜色较亮(有漫反射贡献)。
    • 金属​:由于没有漫反射,只有镜面反射,而镜面反射的颜色通常由入射光颜色和金属本身的颜色共同决定(即Fresnel项中的F0是金属的颜色)。但是,金属会吸收大部分进入内部的光线,导致其整体看起来更暗(因为只有反射部分可见,而反射只发生在特定方向,其他方向则较暗)。

代码解读

Li(p,ωi)代表的是物体表面某一点p的位置上在ωi方向上观察到的所有光线的总和。也可以理解为光源的颜色。

base_color:点云的“固有色”。

Lo​:出射光(最终pbr颜色:这个点在当前光照、视角、材质等条件下,真实应该呈现出来的颜色。)
fdiffuse​:直接光照漫反射 BRDF
fspecular​:直接光照镜面反射 BRDF
n⋅ωi​:​余弦项​(法线与入射光方向的点积),光线入射角θi​的余弦值

直接光照镜面反射D/G/F三项完整实现f_s=GGX_specular函数
直接光照漫反射Lambert + 能量守恒f_d = base_color/π
间接光照镜面反射环境贴图采样global_incident_lights
间接光照漫反射球谐函数

local_incident_lights

几何遮蔽(间接光)预计算可见性incident_visibility

间接光照

物体接收的总入射光,公式中的Li(p,wi)

incident_lights = local_incident_lights + global_incident_lights* incident_visibility

 ​​

def rendering_equation(base_color, roughness, normals, viewdirs,incidents, direct_light_env_light=None,visibility_precompute=None, incident_dirs_precompute=None, incident_areas_precompute=None):#brdf_color, extra_results = rendering_equation(# base_color, roughness, normal.detach(), viewdirs, incidents,# direct_light_env_light, visibility_precompute=pc._visibility_tracing, # incident_dirs_precompute=pc._incident_dirs, incident_areas_precompute=pc._incident_areas)incident_dirs, incident_areas = incident_dirs_precompute, incident_areas_precompute#之前计算的采样方向和面积权重,# (num_pts, num_sample, 3), (num_pts, num_sample, 1)deg = int(np.sqrt(incidents.shape[1]) - 1)global_incident_lights = direct_light_env_light.direct_light(incident_dirs)#间接光照镜面反射,对应方向的环境光辐射亮度(RGB值:包含颜色和光强)local_incident_lights = eval_sh(deg, incidents.transpose(1, 2).view(-1, 1, 3, (deg + 1) ** 2), incident_dirs).clamp_min(0)#间接光照漫反射(球谐函数计算)incident_visibility = visibility_precompute#每个高斯体、每个采样方向的高斯的可见性global_incident_lights = global_incident_lights * incident_visibilityincident_lights = local_incident_lights + global_incident_lights#间接光照,物体接收的总入射光,(num_pts, num_sample, 3)n_d_i = (normals[:, None] * incident_dirs).sum(-1, keepdim=True).clamp(min=0)#法向量与采样方向的点积,(num_pts, num_sample, 1)f_d = base_color[:, None] / np.pif_s = GGX_specular(normals, viewdirs, incident_dirs, roughness, fresnel=0.04)transport = incident_lights * incident_areas * n_d_i  # (num_pts, num_sample, 3)specular = ((f_s) * transport).mean(dim=-2)#镜面反射分量pbr = ((f_d + f_s) * transport).mean(dim=-2)diffuse_light = transport.mean(dim=-2) #入射辐照度(Irradiance):描述表面接收的总光能量,尚未考虑材质如何反射或散射这部分能量。

张量与维度

见张量与维度-CSDN博客

http://www.xdnf.cn/news/15129.html

相关文章:

  • 软件开发那些基础事儿:需求、模型与生命周期
  • 大模型在卵巢癌预测及诊疗方案制定中的应用研究
  • 河南专升本2026年练习题、真题和2000题每日一节
  • 分割网络Segformer
  • 【B题解题思路】2025APMCM亚太杯中文赛B题解题思路+可运行代码参考(无偿分享)
  • 设计模式(结构型)-适配器模式
  • c++——浅拷贝和深拷贝、浅赋值和深赋值
  • 基于强化学习的智能推荐系统优化实践
  • c/c++拷贝函数
  • 字节豆包又一个新功能,超级实用,4 种玩法,你肯定用得上!(建议收藏)
  • 力扣_二叉搜索树_python版本
  • 聚焦数据资源建设与应用,浙江省质科院赴景联文科技调研交流
  • 【龙泽科技】新能源汽车维护与动力蓄电池检测仿真教学软件【吉利几何G6】
  • Elasticsearch 滚动(Scroll)用法、使用场景及与扫描(Scan)的区别
  • DIDCTF-蓝帽杯
  • 【经典面经】C++新特性 TCP完整收发数据 TLS1.2 TLS1.3
  • 【C++】全套数据结构算法-线性表讲解(1)
  • Anaconda及Conda介绍及使用
  • 注意力机制十问
  • 简单记录一下Debug的折磨历程
  • 汽车级MCU选型新方向:eVTOL垂桨控制监控芯片的替代选型技术分析
  • 巨人网络持续加强AI工业化管线,Lovart国内版有望协同互补
  • UI前端大数据可视化实战技巧:如何利用数据故事化提升用户参与度?
  • 云暴露面分析完整指南
  • Qt:布局管理器Layout
  • [Meetily后端框架] 多模型-Pydantic AI 代理-统一抽象 | SQLite管理
  • React 核心知识点速览:从基础到关键概念
  • 7.12 卷积 | 最小生成树 prim
  • 手把手一起使用Miniforge3+mamba平替Anaconda(Win10)
  • mac电脑的usr/libexec目录是干什么的?