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

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.dtcms.com/a/274308.html

相关文章:

  • 【网络安全】理解安全事件的“三分法”流程:应对警报的第一道防线
  • leaflet【十二】自定义图层——海量数据加载
  • 安全监测预警平台的应用场景
  • 机器学习数据集加载全攻略:从本地到网络
  • Git Submodule 介绍和使用指南
  • FS820R08A6P2LB——英飞凌高性能IGBT模块,驱动高效能源未来!
  • Vscode 下载远程服务器失败解决方法
  • Jenkins 版本升级与插件问题深度复盘:从 2.443 到 2.504.3 及功能恢复全解析
  • 和鲸社区深度学习基础训练营2025年关卡2(3)pytorch
  • 限流算法
  • GT IP核仿真测试
  • 关于大模型引用特定网页或文章的思考
  • 稳石氢能受邀参加亚洲氢能与燃料电池技术应用论坛,荣获2025中国制氢装备技术创新企业。
  • P1484 种树,特殊情形下的 WQS 二分转化。
  • 【leetcode】1486. 数组异或操作
  • 国际学术期刊IJCAST发布最新一期论文
  • 声明式 vs 编程式:Spring事务管理全对比
  • windows exe爬虫:exe抓包
  • Redis的高级特性与应用实战指南
  • Kubernetes高级调度1
  • 用鼠标点击终端窗口的时候出现:0;61;50M0;61;50M0;62;50M0
  • Typecho图片自动Webp转换插件开发指南
  • Pycharm测试连接neoj4
  • LeetCode 148 排序链表解析:高效归并排序实现
  • 【AI大模型】BERT微调文本分类任务实战
  • Python PDFplumber详解:从入门到精通的PDF处理指南
  • 扫描文件 PDF / 图片 纠斜 | 图片去黑边 / 裁剪 / 压缩
  • 力扣-142.环形链表 II
  • 力扣热门算法题 204.计数质数,207.课程表,213.打家劫舍II
  • 运行ssh -T git@github.com报错