所以我有一个程序。而且我正在尝试模拟大量具有错综复杂的时刻逻辑的移动粒子,我不希望因为多种原因而进入CGP。当然,我将在GPU上绘制这一切。
现在最初我认为在模拟TONS粒子时,GPU延迟会成为问题,而不是CPU。不幸的是,我以高达6fps的速度运行500个粒子:(。
我已经跟踪了如何将顶点发送到粒子模拟器的延迟。甚至不是缓冲区创建,只是我如何构建数组。基本上我有数组我清除每一帧,然后遍历粒子数组中的每个粒子并为每个粒子创建数组。这导致大约17500个附加调用(具有500个粒子)。所以我需要一种不同的方法来实现这一点,因为如果不构建这些数组,它将以60fps运行,无cpu延迟。大多数这些追加调用都是一个结构的成员。
目前,每个粒子都是基于类对象制作的。并且它具有存储在结构中的位置和颜色等。将结构切换到数组会不会发生什么事?或许我应该将所有内容切换到数组?显然,做任何这些都会让事情变得更难。但它值得吗?
一个很大的问题是我需要将每个粒子绘制成一个胶囊。我用两个点和一条粗线做出来。不幸的是,OpenGL es 2.0不支持粗线,所以我必须用两个点和两个三角形绘制它们:(。你可以看到函数“calculateSquare”使得这两个三角形基于两点。它也非常迟钝但是,这不是唯一的问题,我会在以后尝试找到一种不同的方式。
你有什么想法?
注意:根据xcode ram的使用量仅为10 mb。但是cpu帧时间是141毫秒。
这是代码BTW:
func buildParticleArrays()
{
lineStrip = []
lineStripColors = []
lineStripsize = []
s_vertes = []
s_color = []
s_size = []
for cparticle in particles
{
let pp = cparticle.lastPosition
let np = cparticle.position
if (cparticle.frozen == true)
{
addPoint(cparticle.position, color: cparticle.color, size: cparticle.size)
}
else
{
let s = cparticle.size / 2.0
//Add point merely adds the data in array format
addPoint(cparticle.position, color: cparticle.color, size: cparticle.size)
addPoint(cparticle.lastPosition, color: cparticle.color, size: cparticle.size)
lineStrip += calculateSquare(pp, pp2: np, size: s)
for var i = 0; i < 6; i++
{
let rgb = hsvtorgb(cparticle.color)
lineStripColors.append(GLfloat(rgb.r))
lineStripColors.append(GLfloat(rgb.g))
lineStripColors.append(GLfloat(rgb.b))
lineStripColors.append(GLfloat(rgb.a))
lineStripsize.append(GLfloat(cparticle.size))
}
}
}
}
func addPoint(theObject: point, color: colorhsv, size: CGFloat)
{
let rgb = hsvtorgb(color)
s_vertes += [GLfloat(theObject.x), GLfloat(theObject.y), GLfloat(theObject.z)]
s_color += [GLfloat(rgb.r), GLfloat(rgb.g), GLfloat(rgb.b), GLfloat(rgb.a)]
s_size.append(GLfloat(size))
}
func calculateSquare(pp1: point, pp2: point, size: CGFloat) -> [GLfloat]
{
let p1 = pp1
var p2 = pp2
var s1 = point()
var s2 = point()
let center = CGPointMake((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0)
var angle:CGFloat = 0
if ((p1.x == p2.x) && (p1.y == p2.y))
{
//They are ontop of eachother
angle = CGFloat(M_PI) / 2.0
p2.x += 0.0001
p2.y += 0.0001
}
else
{
if(p1.x == p2.x)
{
//UH OH x axis is equal
if (p1.y < p2.y)
{
//RESULT: p1 is lower so should be first
s1 = p1
s2 = p2
}
else
{
//RESULT: p2 is lower and should be first
s1 = p2
s2 = p1
}
}
else
{
//We could be all good
if (p1.y == p2.y)
{
//Uh oh y axis is equal
if (p1.x < p2.x)
{
//RESULT: p1 is left so should be first
s1 = p1
s2 = p2
}
else
{
//RESULT: p2 is to the right so should be first
s1 = p2
s2 = p1
}
}
else
{
//Feuf everything is ok
if ((p1.x < p2.x) && (p1.y < p2.y)) //First point is left and below
{
//P1 should be first
s1 = p1
s2 = p2
}
else //First point is right and top
{
//P2 should be first
s1 = p2
s2 = p1
}
}
}
angle = angle2p(s1, p2: s2)
}
if (angle < 0)
{
angle += CGFloat(M_PI) * 2.0
}
let yh = size / 2.0
let distance = dist(p1, p2: p2)
let xh = distance / 2.0
let tl = rotateVector(CGPointMake(-xh, yh), angle: angle) + center
let tr = rotateVector(CGPointMake(xh, yh), angle: angle) + center
let bl = rotateVector(CGPointMake(-xh, -yh), angle: angle) + center
let br = rotateVector(CGPointMake(xh, -yh), angle: angle) + center
let c1:[GLfloat] = [GLfloat(bl.x), GLfloat(bl.y), 0]
let c2:[GLfloat] = [GLfloat(tl.x), GLfloat(tl.y), 0]
let c3:[GLfloat] = [GLfloat(br.x), GLfloat(br.y), 0]
let c4:[GLfloat] = [GLfloat(tr.x), GLfloat(tr.y), 0]
let part1 = c1 + c2 + c3
let part2 = c2 + c3 + c4
return part1 + part2
}
答案 0 :(得分:0)
你真的需要系统RAM中的所有粒子吗?例如对于与场景中其他对象相关的一些物理碰撞计算?否则,您可以创建一个粒子,将其发送到GPU并在GPU着色器中进行计算。
答案 1 :(得分:0)
好的,经过几个小时的调整效率小代码的代码后,我得到它运行500粒子,fps为28,看起来非常流畅!我还有一些方法可以去。最好的建议与分配内存而不是附加内存有关。这节省了大量的问题。
特别感谢@Darko,@ Marcelo_Cantos提出了最终优化我的代码的想法!