关于Unity Transform缩放负数的问题

先从最开始就一直萦绕在心里的困惑说起,在Unity Documentation中降到Draw call batching( https://docs.unity3d.com/Manual/DrawCallBatching.html )时,对Dynamic batching的限制有这样一段描述:

GameObjects are not batched if they contain mirroring on the transform (for example GameObject A with +1 scale and GameObject B with –1 scale cannot be batched together).

这里其实我一直不解,为什么mirroring了会打断Dynamic batching,因为Dynamic batching和Static batching本质上是一样的,都是把各自模型的顶点转换到世界空间,再合并成一个Mesh,跟Mirroring有什么关系(mirroring的信息都在worldTransformMatrix里面,顶点转换到世界空间后,这个信息就在顶点自身上了)。不过也一直没有去深究其中的原因。

直到自己做模型静态合并的时候,美术在场景中将一个模型Transform的ScaleY设置成了负数,我将其顶点转到世界空间后合并成新的模型,发现模型正反面跟Unity中的不一样,从图形学角度来看,我这个正反面才是正确的。


满怀期待地用Frame Debugger抓了一下,Cull都是Back啊,这就有点颠覆我的认知了。如果没有改CullMode的话,难不成Unity还把顶点索引顺序变掉了,那样的话我就要鄙视他了。总感觉Frame Debugger抓的不靠谱,有些信息没有完全显示出来(后话,看完后面才知道它显示的根本就不是最终GPU真正渲染管线的状态)。于是打成exe包,用NSight抓DX的渲染设置:


果然,Unity偷偷地将CullMode换掉了,这就能说明之前的现象了。经过测试,当有一个轴缩放为负时,CullMode会设置为相反,当有两个轴缩放为负时,CullMode不会改变,当三个轴都为负时,又会设置为相反。可见,Unity处理的原则是,只要缩放导致坐标系从左手(Unity世界坐标系)变到了右手,就会将CullMode设置为相反,无论你缩放怎么变,只要坐标系左右手没变,就不用做改变。这也能解释最上面说到的Mirroring为什么会导致Dynamic batching打断了,虽然材质都是一样的,但是渲染状态发生了变化,就无法合批了。然后也告诉了我们,Frame Debugger中显示的不是GPU的渲染状态,而是Shader里设置的渲染状态。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我是一个偏爱冷漠,执着悲观的人。 其实我们的悲观都是因为我们生活中并没有悲伤的事情存在,所以我们才有着悲观的思维和...
    枕下有那么多个春秋大梦阅读 232评论 0 0
  • 简述 关于android消息机制我也看了不少文章,但是没有自己真的翻看源码,因为要尝试read the fucki...
    kidz阅读 251评论 0 1
  • “你跟别的女孩不一样,你很特别”这是我大多数的追求者说过的话。 而后呢?他们的行为和做法就是把我变成他们...
    真李里阅读 258评论 1 1
  • 一个白日 一杯白茶 山围着城 城锁着人 我看着太阳 从一个墙角 移到另一个墙角 又偷走了我的一点青春 想到这里 我...
    今天也要好好学习yoursel阅读 296评论 0 2