第三部分:立体感与深度
我们需要找到一个办法让我们的地图呈现出高低起伏的效果。
- 寻找一个呈现立体感的办法
立体感的来源
立体感
现在仔细思考一个问题,到底立体感是怎么来的?在什么情况下,我们会说一个东西是立体的呢?
我会这样简单的概括:
如果一个物体有长宽高,它给人的感觉就是立体的。
或者
当一个物体在 X, Y, Z 三个方向上的大小都不是 0,它给人的感觉就是立体的
如果这样的话,我们只需要找到一个办法,让那张平面地图根据情况,一部分变高,一部分变低,它就有立体感了。
一部分变高,一部分变低
你了解顶点的概念,你知道顶点在3D建模软件中被移动和链接来构成网格,变换形状。
Blender 3D视口,展示一个被拉起一角的平面
如果能够在 Unity 和 VRChat 像建模软件那样,将一个平面的顶点进行上下移动,那么就可以让一个平面的物体呈现出立体感。虽然你不能在 Unity 和 VRChat 中直接拖动顶点,但是着色器可以实现这个效果。
一些功能强大的着色器,或者为此(顶点位置变换)专门设计的着色器会提供通过 Height Map 变换顶点位置的功能。在本书中,将使用 Poiyomi Toon 作为示例着色器。
Height Map 是一张用灰度表示高度信息的图片,白色代表高处,黑色代表低处。它常用于3D建模中生成地形、凹凸效果或形状变化。
本书使用 Poiyomi Pro 9.2.1
Vertex Option -> Height Map
VOB3DM 所需的功能在 Poiyomi Toon 免费版本中同样提供
如果我手动准备一张纹理图,作为 Height Map 输入到着色器,结果看起来像这样
白色代表高处,黑色代表低处
哪里应该变高,哪里应该变低
你是一个人类如果你不是的话,说明VRCD的技术部门需要加班了 ;(
,分辨距离对你来说不是一件难事。虽然你不能精确的测算出某一个物体或者某一点与你的距离,但是你可以清晰的感觉到哪个更近,哪个更更远。
一张正交视角下的图片
我们是否有一种办法,可以测算两点之间的距离呢?如果我们能知道地图摄像机与地面或某个物体上任意一点的距离,我们就可以根据这个距离,将它以黑色与白色记录下来,然后这个信息就能作为 Height Map 输入到着色器中,使得地图变得立体。
感谢图形开发工程师(Graphics Programmers)在过去数个世纪来不断对图形渲染做出的改进和发明的方法,今天的我们有一个十分简单的办法可以得到距离信息。
Z-Buffer
Z-Buffer 是一种用于存储每个像素距离摄像机的深度值的数据结构。在3D渲染中,Z-Buffer记录了从摄像机到场景中各个物体表面的距离信息,它帮助确定哪些物体在前,哪些物体在后。当渲染一个场景时,Z-Buffer会被用来判断每个像素是否被当前的物体遮挡,确保最终图像中只显示最前面的物体,
而其中正包含我们需要的深度信息(Depth Map),它记录了物体表面到摄像机的距离,它看起来像这样:
一张深度信息图
这正是我们需要的东西。
Depth Map 是一张用灰度表示距离信息的图片,白色代表远处,黑色代表近处。
Height Map 是一张用灰度表示高度信息的图片,白色代表高处,黑色代表低处。
获取深度信息
在 Unity 中,Render Texture 可以被设定仅储存深度信息,这样我们就可以得到摄像机摄录画面的物体与摄像机的距离了。
左:新的摄像机;右:一张被设定为不保存颜色,仅保存深度信息的 Render Texture
随后将这块 Render Texture 作为 Height Map 分配给着色器,这块地图现在就立体了... 吗?
Render Texture 可以同时储存颜色与深度信息,理论上可以直接使用同一个Render Texture来减少性能和显存消耗,但是着色器可能会使用颜色信息而非深度信息,故在此依然分为2个不同的 Render Texture 处理,你可以根据喜好决定如何处理。
不要忘记将 Clear Flags 设定为 Depth Only 或 Solid 黑色,如此一来,当摄像机没有拍摄到任何物体时就会清空内容。
No Comments