Splat with 256 Texture – Review on MegaSplat | 256套贴图混合地形-MegaSplat回顾

最近看到MegaSplat这个插件感觉很有意思,在这里做一介绍。作者Jason Booth是有二十多年经验的程序员,现在是Disruptor Beam工作室的客户端和图形架构师,最近unity官方博客还推了行尸走肉:行军作战移动端优化经验,便是这位大神所写

MegaSplat是一套地形的shader,支持很多的feature,另外有写的很好的顶点色绘制工具,shader编译代码,以及最重要的,用顶点混合256张贴图的方法。

雪的混合,代码在DoSnow函数中,基本思路是用height和ao来生成一个snowAmount,这个snowAmount来lerp颜色法线等等

比如还有岩浆,下图是unity截图,在DoLava函数中

比如还有小溪, 在DoPuddle里,会有泡沫和水波涟漪的计算,另外还会用法线重采样原有地形贴图造成折射效果

另外还有tessellation,triplar,parallax, macromap等等很多特性。

另外一点有意思的是它的所有shader都是预先写好片段,修改feature后组装编译出来的。 基本思路是会有一个feature类,不同的shader启用不同feature,按feature来组装写好的片段,需要的property和define写进去。当然函数主体是一样的,只是不同的define控制的分支。

看代码感觉最精巧的是用顶点色支持到256张贴图的操作了。以往的方法会使用一张IDMap,比如在Ghost Recon Wildland中,就是一个texel有一个id,混合的时候去采样周边texel的id,然后再做bilinear插值。

在顶点上存ID的主要问题是,v2f会插值计算,这样像素上抓不到需要使用的ID。MegaSplat巧妙用了一个mask的方式.

每个顶点上存两个index,分别是这里混合的两层贴图的id,还会存一个顶点色,这个顶点色就是通道mask。对于某一个三角形,三个vertex存的颜色分别是(1,0,0), (0,1,0), (0,0,1).
之后vertex shader里来做插值。这里假设顶点色存的是上图的颜色,UV3的x是第一层id,UV3的y是第二层id,UV3的z是两层的混合强度

之后再surf/frag里面这样就可以了,用Input的index0除以vertexWeights,就得到了这个pixel所在的三角形,三个顶点处的ID,就可以来用它采样texturearray

神奇的事情发生在顶点插值计算的时候,vertexWeights的通道特性决定了index0的xyz分别是该pixel所在的三角面上三个vertex的id,于是用这个id正好和vertexWeights进行混合
上面示例代码中,用了顶点色和UV3来存储mask和id,但其实可以pack起来,一套顶点色就能装下

以下就是一个用houdini procedural生成的地形,采用了这种splat的方式

发表评论

电子邮件地址不会被公开。 必填项已用*标注