Bent Normal (环境法线?)

前段时间读论文看到了Bent Normal这个概念,找了些相关的资料学习了一下。Bent Normal常见于离线的Ambient Occlusion渲染中(中文翻译过来应该叫做环境法线?网上搜索看有些地方是这么叫的),从它的字面意思中即可以看出其同样是一种Normal,只不过是做了修改变形(Bent)。这个Bent是如何计算而来的呢?这个Bent Normal又有什么用外呢?这里做个简单的介绍。

什么是Bent Normal?

首先我们知道,对于不管什么反射模型的渲染方程来说,几何模型的表面法向量是必需的一个信息元素。而Bent Normal就是对原始的Normal做修改之后的新向量,它指向了当前像素一个不被其它物体(或几何体元)遮挡的平均方向,也即光线传入的主要方向。由些可知其与Ambient Occlusion是相关的。其公式化后的形式如下所示【式一】:

 

其中的即为当前点xw方向上的可见性,也即是否被遮挡。该式与普通的AO计算公式基本上相同,使用蒙特卡罗积分将其离散化即可得到一个有限采样下可行的Bent Normal计算公式。

Bent Normal的采样示意图(从图中可以看出,Bent Normal(黄色)与原始Normal(蓝色)相比,其在考虑周围几何体元分布的情况下向右侧做了修整)

Bent Normal有什么用处?

Bent Normal一般来说可以有两种用途:

  • 用来改变原始的Normal,并记录光线的主要通过方向,这样在做环境贴图的采样时可以从更优化的方向来计算采样的光线。
  • 用来代替原始的Normal做正常的Shading,这样可以在尽管只有Normal的情况下一定程度上得到类似于Ambient Occlusion的Soft Shadow效果。

如何计算Bent Normal?

Bent Normal的计算方式一般来说也有两种方法;

  • 第一种方法就是传统的离线采样方法,这里的操作就跟传统offline的Ambient Occlusion计算方法一样,在场景的表面上的每个点处做采样,并计算【式一】的蒙特卡罗积分即可统计得到考虑场景遮挡情况下的Bent Normal。
  • 第二种方法就是当前各种图形算法很流行的基于Screen Space的方法,其优点就是快、缺点就是不太精确。为了在游戏中得到实时的AO计算,众多基于屏幕空间的SSAO算法被提出来,而AO 的计算又与Bent Normal的计算是相关的,因而就可以使用通常的SSAO post pass来将Bent Normal无过多额外代价的快速计算出来(但是会多出一个Normal buffer的采样,或以合适的方法避免之)。具体的操作也跟AO的计算类似,只不过在每个屏幕采样点处将相应的AO 值转化为对Normal 的偏移即可。

下述为原始Normal与Bent Normal的对比图(Bent Normal的生成采用了离线的蒙特卡罗算法来计算,木有优化采样方式,因而存在噪点痕迹):

 

 

从上述Normal对比图中可以看出,对于普通表面曲率大于等于0的表面,其Bent Normal与原始Normal并没有什么区别,表现在场景上的情况即是其没有被其它几何体元所遮挡;而对于那些表面凹处,则Bent Normal会对原始的Normal产生相应的修改,而这些地方在做SSAO操作时则同样会产生相应的AO。

这两张为使用Normal&Bent Normal的渲染效果:

 

阅读更多
想对作者说点什么? 我来说一句
相关热词

没有更多推荐了,返回首页