找回密码
 立即注册
查看: 504|回复: 0

优化unity地形的曲面细分

[复制链接]
发表于 2021-11-19 09:09 | 显示全部楼层 |阅读模式
内置算法的问题
unity的曲面细分,特别是surface shader下开发自由度很低,能做的特殊修改手段较少。但是自带的2种细分方式都有各自的问题。
先看看按UnityDistanceBasedTess
    有接缝(必须解决)从最终的屏幕空间看远处比近处细分的更多(算是有性能浪费 一般来说远处的细节不需要超过近处)



UnityDistanceBasedTess 曲面细分的问题

再看下 UnityEdgeLengthBasedTess
    没做距离裁剪,性能不行(因为地形一般都会覆盖很长一段距离)



UnityEdgeLengthBasedTess 曲面细分问题

修改思路
经过观察2个算法问题,那么思路就比较明确了,就是要实现一版支持距离剔除的 EdgeLength 算法。
首先找到 buildin的这部分函数 (Tessellation.cginc 文件内)


我们先做一步按距离衰减,临时凑几个参数关系,关键点是让 分母变大的快些 也就是按dist的 x次发,x>1 来计算比如 取1.2。


为什么又要 外面*8 内部/8呢?这是因为直接的pow让远处变的比原来小很多 没有细分的效果.我们只想要变化下降的更快,不是有效距离更近,对比以下的3个函数曲线图可以看到,f2在黄箭头处确实实现了更快下降,但红箭头处值比原来小太多.而f3 就同时满足保持远处有效距离与中部快速下降细分参数.





过小f值 剔除前效果

这样就得到了上图效果,可以发现当f 又远又小的时候,那点细分都几乎是平行线了,这种划分方式对曲面细分效果没帮助。因为中间的区域没得到更多顶点。所以需要再加一句这部分剔除  if (f/ dist <0.06)f = 1;这样就得到下图效果了。



过小f值 剔除后效果



本方案 细分效果

性能对比
原版算法是支持无穷远的,而本方案是支持有限距离,所以计算量和效果本就不同,这个对比数据没多少意义。但是一般项目都不会选择无限距离开启细分,所以调了一版尽量接近原版效果的对比下帧数。



原版UnityEdgeLengthBasedTess 性能



本方案 UnityEdgeLengthBasedTess 性能

法线修正
根据日常经验,任何修改顶点坐标的算法,都会引起normalmap计算的错误. 这是因为离线烘焙normalmap的时候 预想的切线空间是固定的低模.而不是 现在修改后的样子.所以严谨的说,植被的顶点摇摆动画,曲面细分的高度修改,树的半球法线方案.都修改了 切线空间.都应该做法线的修复计算.只是多数情况下这个计算需要额外开销,且小幅度运动下误差不明显,所以很少提及而已.对比下 quixel mixer里 正确的法线输出 与unity的对比.因为他们yz轴定义不同,我用ps交换了gb通道.



quixel mixer里正确的法线效果(交换gb通道后)



unity里 曲面细分+高度置换后 错误的法线数据

这是因为顶点修改后 xz平面变成了 一个斜面,normalmap里 一个蓝色 原本应该往y方向突起方向 ,现在需要改成沿着新法线方向突起的部分.
常见的解决方案是2种
    多采样:2次计算出顶点所在的斜面的 斜率,根据这个计算出新的切线方向.多存储:把1的斜率离线存起来,或直接存切线方向.
这2种方法我都不太喜欢,所以就不想动手写这部分代码,下午就开始了技术型划水.划着划着发现了第三种方法.quixel mixer里发现了这个选项,这不就是我需要的吗?不修改切线空间直接修改置换后新空间的法线.不用多采样 也不用额外存储.正是我想要的.验证下效果确实基本正确了.





unity里 曲面细分+高度置换后 用上修正后法线贴图



普通法线(左)与置换贴图产生的法线(右)



法线修复效果对比



开启本方案效果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-23 03:17 , Processed in 0.090080 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表