Signed Distance Fields in Real-time Rendering

ref: https://zhuanlan.zhihu.com/p/35098986

题图: UE4 Distance Field Ambient Occlusion

Shadow

最基本的制作阴影的方法就是从光源发射射线, 然后判断着色的点和光源之间是否被物体遮挡, 有遮挡是阴影内, 无遮挡是阴影外. 但是这么做的结果投射出来的阴影边缘比较硬. 现实中我们见到的阴影都会有柔和的半影区, 如下面两个图所示:

Signed Distance Fields in Real-time Rendering_第1张图片

HardShadow

Signed Distance Fields in Real-time Rendering_第2张图片

SoftShadow

使用SDF做柔和阴影具有先天优势, 因为场景内的距离信息全都有. 上图的做法就是计算每个着色点距离本影的距离, 如果接近, 那么就计算一个跟距离有关的衰减作为半影的值去模拟柔和阴影. 现在回头看看利用SDF计算阴影的方法, 我们很容易联想到, 这方法类似计算环境遮蔽啊, 所以, SDF当然可以用来计算AO.

Ambient Occlusion

AO是Crytek[1]发扬光大的. 我们可以在碰撞点周围随机采样位置信息, 距离碰撞点在一定范围内, 算作AO的权重加权:

Signed Distance Fields in Real-time Rendering_第3张图片

AO Only

目前为止, 我们的渲染对象都是简单的几何体, 可以使用公式描述, 但是如果想要更进一步使用SDF的话, 比如在游戏内, 我们需要面对更复杂的几何体, 可能无法用公式描述, 怎么办呢? 因此我们需要把这些复杂物体映射成SDF.

Create SDF

Evans[2]提出一种方法: 使用立体贴图存储SDF. 后来UE4的Mesh Distance Field[3]也使用了类似的方法. 但是两者的都有一个主要的缺点就是比较耗内存. 后者把这个技术限制在DX11或更高的API特性才能使用, 并且只能用在等比缩放的静态物体上.

Evans的方法是用OBB分多个切片, 然后切片和物体相交算SDF.

Signed Distance Fields in Real-time Rendering_第4张图片

Evans, 2006.

如果是简单的物体, 可以实时算, 复杂的话可以离线算好实时渲染时使用. 另外一种变通方法是使用立体网格每一个网格去采样目标物体的三角面, 寻找距离最近的三角面做SDF. 这种方法首先需要存储立体贴图比较耗内存, 其次是目标物体越复杂这个算法就越耗时, 目前我还没有去看UE4的实现, 但是根据使用方式猜测是这种方法.

作为测试和演示, 我采用的方法是把3d信息平铺到2d贴图上:

Signed Distance Fields in Real-time Rendering_第5张图片

采用2D平铺模拟3D texture

Signed Distance Fields in Real-time Rendering_第6张图片

SDF Visualization

SSS

这里使用的方法基于Simon Green[4]使用depth map快速模拟SSS。

Signed Distance Fields in Real-time Rendering_第7张图片

截图来自 Real-Time Approximations to Subsurface Scattering

Signed Distance Fields in Real-time Rendering_第8张图片

利用SDF进行简单的SSS

Signed Distance Fields in Real-time Rendering_第9张图片

可以使用魔参调整通透度


[1] Mittring, M., Finding Next Gen CryENGINE2, 2007.

[2] Alex Evans, Fast Approximations for Global Illumination on Dynamic Scenes, 2006.

[3] Daniel Wright, Dynamic Occlusion With Signed Distance Field, 2015.

[4] Simon Green, Real-Time Approximations to Subsurface Scattering, 2004.

编辑于 2018-04-09

你可能感兴趣的:(Signed Distance Fields in Real-time Rendering)