Unity教程|立体渲染
本文将介绍在Unity中实现简单的立体渲染(Volumetric Rendering)效果,立体渲染可以实现逼真的材质与灯光进行复杂的交互,例如:雾、烟、水和玻璃。
立体渲染的基本概念可以查看下图了解:
为了突破这种强大的限制,大量技术顺势而出。尽管传统着色器最终都会止于物体表面,但这并不意味着无法更深入。立体渲染技术可以在材质内部模拟光线的传送,从而实现更震撼也更真实的视觉效果。
无光照纹理的片段着色器如下:
不严格地说,上述代码会为最终渲染图像每一个可能的像素(片段)调用。GPU会在有三角形与相机视锥体相交时,调用该片段着色器。换句话说,就是相机“看见了”该对象。Unity需要知道该对象的实际颜色,以便将其分配到渲染图像的各个像素。
如果想模拟前面的效果,就要更精确地进行描述。假设主物体是一个立方体,要在其内部立体渲染一个球体,实际上并不存在这个球体,因为我们将完全通过着色器代码来渲染。球体中心点位于_Centre,半径是_Radius,均为世界坐标。移动立方体不会影响球体位置,因为它是完全以世界坐标系来表述的。外部的几何体也不会对该球体造成任何影响。立方体表面的三角形就是通向几何体内部的窗口。虽然可以使用四边形(Quad)减少三角形数量,但要能从立方体的任意角度观看该球体。
在片段着色器函数中添加剩下的代码:
首先,片段的世界坐标就是从相机生成的射线投射到几何体上的点。在片段着色器中获取世界坐标的代码如下:
立体光线追踪会缓慢地将射线投射到立方体内,每一步都会检测当前是否已投射到红色球体。
每条射线均从片段坐标worldPosition开始,然后迭代沿着viewDirection的方向投射STEP_SIZE单位长度。这可以通过每次迭代为worldPosition加上STEP_SIZE * viewDirection 来实现。
用下面的raymarchHit函数代替之前的raycastHit:
本文介绍了基本的立体渲染概念。尽管传统着色器只能渲染材质的外壳,但还是有办法让光线穿透到材质内部的几何体,创造画面的深度。光线追踪就是最常用的技术,本文用该技术在立方体内绘制了一个红色球体。后面的教程将分享如何逼真地着色(第三篇表面着色)以及如何做出一些有趣的形状(第四篇 有向距离场)。最终将能够使用简单几行代码和一个立体渲染着色器实现如下效果:
本系列共有四篇教程,立体渲染是第一篇,后面将继续更新,请保持关注。
本文来源于:alanzucconi.com
原作者:Alan Zucconi
更多实用Unity技术小文章:
备受行业瞩目的VR/AR行业大会Vision VR/AR Summit Asia 2016即将在北京召开(轻触图片了解详情)!