代码之家  ›  专栏  ›  技术社区  ›  Felastine

着色的精灵真的是在新版本的Unity中批量生产的吗?

  •  2
  • Felastine  · 技术社区  · 8 年前

    从我第一天在统一发展,我看到了一些提示和东西说,我们不应该着色精灵。如果我们想要不同颜色的精灵,创建它们并将它们放置在相同的纹理中,然后交换不同颜色的精灵。

    原因是着色精灵会破坏批处理。

    我已经创建了一个小演示。


    情况1

    Situation 1

    同样的正方形精灵被用于6个游戏对象。没什么好惊讶的。在统计中,有一批。5通过批处理保存。


    情况2

    Situation 2

    同样的正方形精灵再次用于6个游戏对象,但这一次,所有对象都用相同的颜色值染成红色。

    这不应该已经打破分批吗?


    情况3

    Situation 3

    为了完整起见,我给正方形的精灵涂上了不同的颜色。不过,我们还有一批货,还有五批。什么都没变。


    附加信息

    1. 我在一次重播中捕获了情景1和2,在另一次重播中捕获了情景3。
    2. 我试着给雪碧上色 直接在编辑器中 通过更改的“颜色”字段 SpriteRenderer 通过脚本 通过改变 SpriteRenderer.color 是的。结果是一样的。
    2 回复  |  直到 8 年前
        1
  •  4
  •   Programmer    8 年前

    更改上的精灵颜色 SpriteRenderer 组件不应中断批处理。中断批处理的是当您更改spritender的sprite、材质,甚至尝试使用 SpriteRenderer.material 财产。

    例如,

    这个 打破 配料:

    SpriteRenderer sr = GetComponent<SpriteRenderer>();
    sr.material.color = Color.red;
    

    因为你正在访问材料。当您第一次访问material属性时,它将创建新的material实例。


    这个 不会的 间歇配料:

    SpriteRenderer sr = GetComponent<SpriteRenderer>();
    sr.color = Color.red;
    

    它不会,因为它没有访问 material 财产。尽管它不会中断批处理,但它的一个问题是性能。这样做会影响性能。

        2
  •  3
  •   KYL3R    8 年前

    首先,着色基本上是设置顶点颜色。对于粒子,可以在其中设置随机开始颜色,并且所有粒子都在一次绘制调用中渲染。顶点颜色不会更改/创建新材质。

    不确定在早期的unity版本中是如何处理的,但是sprite应该是简单的四边形,因此支持顶点颜色。sprite着色器在着色方面的工作方式可能相同。

    总的来说,你是对的。更改材质球属性将创建该材质的副本,或者更改材质本身并影响使用该材质的所有实例。你是在雪碧材料上使用了这种颜色,还是在雪碧粉刷机上使用了这种颜色?

    用手,我可以想到使用材料属性块,但也许Unity确实为精灵做到了这一点。


    需要澄清的更多细节:

    一个 你有“material01.mat”-是绿色的。你把这个材料复制到10个精灵身上。你想要10种颜色吗?你必须创建10种材质,每种材质都包含所需的颜色-10个绘制调用。

    通过脚本也可以这样做,只需更改material.color。但团结会为你复制材料。还有10个电话。有些人不明白为什么它会中断批处理,直到他们听说这件事。

    你改变了渲染器的颜色。这个sprite渲染器将把颜色写入sprites顶点(可能是4?)-使用顶点颜色属性。基本上是免费的,因为它们无论如何都会被传送到gpu(afaik)

    如上所述,粒子系统中也使用了相同的方法,允许彩虹粒子使用1个drawcall。

    因此,任何粒子明暗器、自写明暗器或精灵明暗器都应该与此配合使用。你只需要 a.albedo = c.rgb * IN.vert.color (这里有点伪代码)

    这意味着,相同的材质和材质可以用于具有不同顶点颜色的多个对象。这不会中断批处理。

    你甚至可以有任何形状和顶点数的不同对象,给它们不同的顶点颜色(每个顶点,像梯度等),它仍然会成批。

    尽可能检查静态,将信息输入顶点颜色,对于移动的对象,尝试将其保持在300个顶点以下,以便动态批处理可以工作。

    但是对于精灵,Unity为您自动执行此操作,您只需要使用Spriterender-这就是为什么您不使用具有纹理的四边形,而是使用“Sprite”和Spriterender。

    同样,我可能错了,喷溅器实际上使用了材料属性块,但它的工作原理几乎相同。可以为每个对象设置这些变量,而不创建新的drawcall。变量值在着色器中使用,因此对于多个对象,材质/着色器是相同的。