PBR渲染方程简单总结和实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PBR渲染方程简单总结和实现相关的知识,希望对你有一定的参考价值。
参考技术A 看了很多PBR相关的文章了,虽然复杂,但似乎使用起来很简单的样子。
这儿写个简单版的PBR实现,留下点学习痕迹。
1975年Phong提出Phong反射模型(Phong Reflection Model):
1977年Blinn对Phong模型做出修改,这就是后来广泛使用的Blinn-Phong反射模型:
一个简单的基于物理的Blinn-Phong:
物理上辐射度量学的基本量及其关系( 符号被我简化了,比如立体角和偏导 ):
辐射率被用来量化单一方向上发射来的光线的大小或者强度,不随距离变化,人眼看到的颜色强度的度量单位就是这个。
PBR的渲染方程(反射方程)一般长这样:
v是观察方向,l是光照方向, 。
有些文章使用 , 表示按向量的分量相乘,因为 和 都包含RGB三个分量。
辐射率与辐照度按定义有这样的关系:
双向反射分布函数BRDF的定义是: 。
积分方程一般用蒙特卡洛方法近似计算,即便如此,也是 不能实时计算 ,一般都是先离线预处理。知道的几个方法
对于理想光源(点光源、方向光等), 是没有意义的,比如平行光,只有一个方向有值,且值是无限大。
对于理想光源照射的物体来说,有意义的是辐照度 ,渲染方程退化成:
这个方程可以在shader里实时算。
下面这个模型大概是叫Cook-Torrance BRDF模型吧。
首先BRDF分为漫反射和镜面反射两部分:
系数用来控制能量守恒的。
n是表面法线
h就是前面提到的半角向量,在这儿它多了一个含义,微表面法线
α是表面的粗糙度( UE的文章定义 ,导致有些文章写错了,这儿直接就是roughness ),n是表面法线。这个方程是大佬特地研究出来的。
菲涅尔现象是掠角越大,镜面反射越强,表现出边缘高光现象。
表示的是表面基础反射率,这个值区分了金属和非金属。金属大于0.5,非金属小于0.2,并且常见的非金属小于0.04。
这个值输入的方式一般是:金属的通过贴图输入,非金属的直接设置为0.04。
前面提到的系数 与 有关系。
令 ,就能达到能量守恒了:镜面反射+漫反射<=1,同时还减弱金属的漫反射。
其中 有各种不同的方案,disney、unity、unreal的渲染方程就有差别。
这儿只是列一个可行的方案。
分两种情况
PBR的渲染需要综合间接光才能效果不错。
PBR需要在线性空间里计算,不同光源是可以线性相加的。当结果>1时,有专门的算法归一。
exposure 默认是1,可以设置,也可以根据上一帧的图像平均亮度平滑过渡。
可以看 LearnOpenGL 的评论区。
只实现了一个,只支持一个平行光。
额外利用了Unity内置的一些功能:Shadow,SH环境光,SkyBox。
标准胶囊体的渲染接近Standard了,有那么个感觉了。
获取环境间接光的部分真是~~~下次搞懂吧。
以上是关于PBR渲染方程简单总结和实现的主要内容,如果未能解决你的问题,请参考以下文章
基于物理的渲染(PBR)白皮书 PBR核心理论与渲染光学原理总结