gpt4 book ai didi

java - OpenGL ES 3.0 中的粒子系统优化

转载 作者:行者123 更新时间:2023-12-01 17:59:12 27 4
gpt4 key购买 nike

有一个爆炸的粒子系统,类似于烟花:

enter image description here

顶点着色器代码:

#version 300 es
uniform float u_lastTimeExplosion; // time elapsed since the explosion
// explosion center (particle coordinates are set relative to this center
uniform vec3 u_centerPosition;
uniform float u_sizeSprite;
// particle lifetime in seconds
layout(location = 0) in float a_lifeTime;
// initial position of the particle at the time of the explosion
layout(location = 1) in vec3 a_startPosition;
layout(location = 2) in vec3 a_endPosition; // final position of the particle
out float v_lifeTime; // remaining particle lifetime
void main()
{
// calculate particle position (algorithm from the book of D.Ginsburg, B.Purnomo)
gl_Position.xyz = a_startPosition + (u_lastTimeExplosion * a_endPosition);
gl_Position.xyz += u_centerPosition;
gl_Position.w = 1.0;
// calculate the remaining particle lifetime
v_lifeTime = 1.0 - (u_lastTimeExplosion / a_lifeTime);
v_lifeTime = clamp(v_lifeTime, 0.0, 1.0);
// calculate sprite size based on remaining life time
gl_PointSize = pow(v_lifeTime, 5.0) * u_sizeSprite;
}

fragment 着色器代码:

#version 300 es
precision lowp float;
in float v_lifeTime;
uniform vec4 u_color;
out vec4 fragColor;
uniform sampler2D s_texture;
void main()
{
vec4 texColor = texture(s_texture, gl_PointCoord);
fragColor = u_color * texColor;
// increase sprite transparency
fragColor.a *= v_lifeTime;
}

使用三个顶点缓冲区:用于具有粒子生命周期的数组;粒子初始坐标数组;最终粒子坐标数组:

lifeTimeAsFloatBuffer.position(0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBO[0]);
GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,
FLOAT_SIZE * numberParticles, lifeTimeAsFloatBuffer,
GLES30.GL_STATIC_DRAW);

startPositionAsFloatBuffer.position(0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBO[1]);
GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,
FLOAT_SIZE * NUM_COORDINATES * numberParticles,
startPositionAsFloatBuffer, GLES30.GL_STATIC_DRAW);

endPositionAsFloatBuffer.position(0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBO[2]);
GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,
FLOAT_SIZE * NUM_COORDINATES * numberParticles,
endPositionAsFloatBuffer, GLES30.GL_STATIC_DRAW);

生成顶点数据:

private final float[] lifeTimeData; // life time of particles
private final float[] startPositionData; // start coordinates of particles
private final float[] endPositionData; // end coordinates of particles
...
public void createDataVertex() {
float maxLifeTime = 3.0f;
for (int i = 0; i < numberParticles; i ++) {
// life time of particle, random value 0-3 second
lifeTimeData[i] = random.nextFloat() * maxLifeTime;
}
float[] xyz;
for (int i = 0; i < numberParticles * NUM_COORDINATES; i += NUM_COORDINATES) {
xyz = getPointForSphere(startRadius); // start position particle
startPositionData[i] = xyz[0] * aspect;
startPositionData[i + 1] = xyz[1];
startPositionData[i + 2] = xyz[2];
xyz = getPointForSphere(endRadius); // end position particle
endPositionData[i] = xyz[0] * aspect;
endPositionData[i + 1] = xyz[1];
endPositionData[i + 2] = xyz[2];
}
lifeTimeAsFloatBuffer = floatBuffer(lifeTimeData);
startPositionAsFloatBuffer = floatBuffer(startPositionData);
endPositionAsFloatBuffer = floatBuffer(endPositionData);
}

将数据传递给着色器:

public void onDrawFrame(GL10 glUnused) {
...
GLES30.glEnableVertexAttribArray(startPositionLink);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBO[1]);
GLES30.glVertexAttribPointer(startPositionLink, NUM_COORDINATES,
GLES30.GL_FLOAT, false, FLOAT_SIZE * NUM_COORDINATES, 0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
...
}

问题:在某些物理设备上,渲染速度会变慢(FPS 降低)。哪怕有几百个粒子。观看了一个帖子:Improve Particle system OpenGL 。但这里的问题似乎有所不同。

问题:有没有办法进一步优化这个粒子系统?任何答案/评论都非常有值(value)。

最佳答案

事实证明, Sprite 的大小对性能影响很大。如果 Sprite 的初始大小是从 1 到 10,那么一切都很好:

GLES20.glUniform1f(sizeSpriteLink, 10f);

如果 Sprite 的大小增加,则渲染速度会变慢(FPS 降低)。不确定,但似乎增加 Sprite 的大小会极大地影响图形内存资源的消耗。也许有人知道这个?

根据 Columbo 的建议,添加了用于粒子纹理的 mipmap。 Sprite 的大小最好不要超过纹理的大小。

GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D)

最好使用这种类型的过滤来提高性能:

// one value is taken from the nearest pyramid level
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST_MIPMAP_NEAREST);

关于java - OpenGL ES 3.0 中的粒子系统优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60664551/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com