我有一个应用程序,当你按下屏幕时,应用程序在该位置创建一个圆圈并开始增长,直到达到最大尺寸并将其删除。
如何优化我的代码以吸引很多圈子?
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;
}
这是我的应用的图片:
答案 0 :(得分: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
坐标中。现在将绘图的顺序从最新更改为最旧,以便不会在前一个圆已经显示的位置绘制背景中的圆。不要忘记清除深度缓冲区。
还有一些其他潜在的优化,例如在你的情况下,你可能只是在圆圈周围绘制笔划,这表示尺寸的增加,而不是清除颜色缓冲区。但这意味着实际创建顶点以绘制具有定义宽度的笔划圆,这至少会增加顶点部分的负荷,但会严重降低光栅化和绘制的碎片数量。在这种方法中你需要一个深度缓冲区,但是一旦有一个新的圆圈,你还需要推回当前的深度缓冲区...可以通过单个屏幕重绘来完成,但这是一项非常正确的任务。
我能想到的另一种方法实际上是为圆心,颜色和半径提供了一个统一的数组,可以将其提供给片段着色器。然后在片段着色器中迭代遍历数组并检查哪个圆形表示实际上是您应该在该特定像素处绘制的那个并使用其颜色(如果非有效则简单地丢弃以保持当前背景颜色)。这意味着在整个视图中仅绘制一个矩形。无深度缓冲,无需清除颜色缓冲区。对于片段着色器来说,这可能很重,但是大量片段会严重减少,因此它可能会提高性能(或不提高)。