2016-03-19 47 views
0

我有一个应用程序,当你按下屏幕时,应用程序会在该位置创建一个圆圈并开始增长,直到达到最大尺寸并被删除。
如何优化我的代码以绘制大量圈子?绘制很多圈子 - 优化

Iterator<CircleShape> it = mCircles.iterator(); 
    while (it.hasNext()) { 
     CircleShape shape = it.next(); 
     if (shape.getScale().x <= shape.getMaxScale()) { 
      shape.setScale(shape.getScale().x + mGrowSpeed * smoothedDeltaRealTime_ms); 
      draw(shape); 
     } else { 
      it.remove(); 
     } 
    } 

的圆圈在片段着色器通过丢弃像素创建我不需要:

void main() 
{ 
    float d = distance(v_texCoord, vec2(0.5, 0.5)); 

    if (d > 0.5f) 
      discard; 

    gl_FragColor = uColor; 
} 

这里是我的应用程序的图片:

enter image description here

回答

1

第一你应该尝试分析瓶颈在哪里。我认为片段着色器仍然很重,但可以进行一些优化。

您正在比较使用通常较慢的根部平方的距离。尝试做

vec2 vector = v_texCoord - vec2(0.5, 0.5); 
if(vector.x*vector.x + vector.y*vector.y > 0.5*0.5) // or 0.25 

如果您不使用深度缓冲区,在这种情况下可能会使您受益。如果你不使用它,我假设你按照从最老的(最宽的)到最新的顺序绘制圆圈。这意味着它会为每个圆圈实际绘制所有的碎片,然后新的碎片将重新绘制在旧的碎片上。您可以启用深度缓冲区,并且当您增加圆圈大小时,您可能还会进一步将其放在z坐标中。现在将绘图的顺序从最新更改为最旧,以便后面的圆圈不会绘制出前一个圆圈已经显示的位置。不要忘记清除深度缓冲区。

还有一些其他潜在的优化,比如在你的情况下,你可能只是绘制围绕圆圈的描边,这代表了尺寸的增加并且不清除颜色缓冲区。但是这意味着实际上创建顶点以绘制具有定义宽度的笔画圆,这将至少增加顶点部分上的负载,但会严重降低栅格化和绘制的片段数量。在这种方法中,您需要一个深度缓冲区,但是一旦有新的圆圈出现,您还需要推回当前的深度缓冲区......可以通过单个屏幕重绘来完成,但这是完成正确任务的相当重要的任务。

我能想到的另一种方法实际上是为圆形中心,颜色和半径提供一个统一的数组,以便将其送入片段着色器。然后在片段着色器中遍历数组,并检查哪个圆形表示实际上是应在该特定像素处绘制的那个,并使用其颜色(如果非有效,则简单地丢弃以保留当前背景颜色)。这意味着在整个视图中只绘制一个矩形。没有深度缓冲区,不需要清除颜色缓冲区。这可能会对片段着色器造成很大影响,但是一些片段会严重减少,因此可能会提高性能(或不会)。