From ebe36705223d00bfe92c7b8fc391e97895ba1155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaj=20Gr=C3=B6nholm?= Date: Fri, 6 Nov 2020 12:56:36 +0200 Subject: Optimize particles vertex data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use uchar instead of float for vertex data that doesn't need float. Continue using floats in shaders. Also remove animY2, which is same as animY1. These changes reduce memory usage especially when the amount of particles increases. Testing on windows, memory reductions with emitters/trailemitter example were: - OpenGL: 82.7 MB -> 76.5 MB - Vulkan: 130.8 MB -> 126.3 MB - D3D11: 143.7 MB -> 135.8 MB Task-number: QTBUG-88124 Change-Id: I8f8dcb3845323b0e69fb99b5bff830cd0f151a47 Reviewed-by: Laszlo Agocs Reviewed-by: Tomi Korpipää --- src/particles/qquickimageparticle.cpp | 43 ++++++++++----------- src/particles/qquickimageparticle_p.h | 32 ++++++++------- src/particles/qquickparticlesystem_p.h | 2 +- src/particles/shaders_ng/imageparticle.vert | 24 ++++++------ .../shaders_ng/imageparticle_colored.frag.qsb | Bin 1634 -> 1638 bytes .../shaders_ng/imageparticle_colored.vert.qsb | Bin 3451 -> 3438 bytes .../shaders_ng/imageparticle_deformed.frag.qsb | Bin 1654 -> 1653 bytes .../shaders_ng/imageparticle_deformed.vert.qsb | Bin 5352 -> 5356 bytes .../shaders_ng/imageparticle_simple.frag.qsb | Bin 1639 -> 1644 bytes .../shaders_ng/imageparticle_simple.vert.qsb | Bin 3449 -> 3448 bytes .../shaders_ng/imageparticle_sprite.frag.qsb | Bin 1964 -> 1974 bytes .../shaders_ng/imageparticle_sprite.vert.qsb | Bin 5997 -> 5995 bytes .../shaders_ng/imageparticle_tabled.frag.qsb | Bin 1833 -> 1841 bytes .../shaders_ng/imageparticle_tabled.vert.qsb | Bin 5673 -> 5652 bytes 14 files changed, 51 insertions(+), 50 deletions(-) (limited to 'src/particles') diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 7ba26c4e54..1331032e7a 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -1067,8 +1067,8 @@ void QQuickImageParticle::createEngine() } static QSGGeometry::Attribute SimpleParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), // Position - QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data + QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), // Position + QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType) // Vectors }; @@ -1080,9 +1080,9 @@ static QSGGeometry::AttributeSet SimpleParticle_AttributeSet = }; static QSGGeometry::Attribute ColoredParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), // Position - QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data - QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType), // Vectors + QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), // Position + QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data + QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType), // Vectors QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType), // Colors }; @@ -1094,36 +1094,36 @@ static QSGGeometry::AttributeSet ColoredParticle_AttributeSet = }; static QSGGeometry::Attribute DeformableParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType), // Position & TexCoord - QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data - QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType), // Vectors + QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType), // Position & Rotation + QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data + QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType), // Vectors QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType), // Colors - QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType), // DeformationVectors - QSGGeometry::Attribute::create(5, 3, QSGGeometry::FloatType), // Rotation + QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType), // DeformationVectors + QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType), // TexCoord & autoRotate }; static QSGGeometry::AttributeSet DeformableParticle_AttributeSet = { 6, // Attribute Count - (4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar), + (4 + 4 + 4 + 4) * sizeof(float) + (4 + 4) * sizeof(uchar), DeformableParticle_Attributes }; static QSGGeometry::Attribute SpriteParticle_Attributes[] = { - QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType), // Position & TexCoord - QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data - QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType), // Vectors + QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType), // Position & Rotation + QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType), // Data + QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType), // Vectors QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType), // Colors - QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType), // DeformationVectors - QSGGeometry::Attribute::create(5, 3, QSGGeometry::FloatType), // Rotation - QSGGeometry::Attribute::create(6, 3, QSGGeometry::FloatType), // Anim Data - QSGGeometry::Attribute::create(7, 4, QSGGeometry::FloatType) // Anim Pos + QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType), // DeformationVectors + QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType), // TexCoord & autoRotate + QSGGeometry::Attribute::create(6, 3, QSGGeometry::FloatType), // Anim Data + QSGGeometry::Attribute::create(7, 3, QSGGeometry::FloatType) // Anim Pos }; static QSGGeometry::AttributeSet SpriteParticle_AttributeSet = { 8, // Attribute Count - (4 + 4 + 4 + 4 + 3 + 3 + 4) * sizeof(float) + 4 * sizeof(uchar), + (4 + 4 + 4 + 4 + 3 + 3) * sizeof(float) + (4 + 4) * sizeof(uchar), SpriteParticle_Attributes }; @@ -1622,7 +1622,6 @@ void QQuickImageParticle::spritesUpdate(qreal time) spriteVertices[i].animX1 = x1; spriteVertices[i].animY1 = y; spriteVertices[i].animX2 = x2; - spriteVertices[i].animY2 = y; spriteVertices[i].animW = w; spriteVertices[i].animH = h; spriteVertices[i].animProgress = progress; @@ -1677,7 +1676,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx) float rotation; float rotationVelocity; - float autoRotate; + uchar autoRotate; switch (perfLevel){//Fall-through is intended on all of them case Sprites: // Initial Sprite State @@ -1749,7 +1748,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx) (m_rotation + (m_rotationVariation - 2*QRandomGenerator::global()->bounded(m_rotationVariation)) ) * CONV; rotationVelocity = (m_rotationVelocity + (m_rotationVelocityVariation - 2*QRandomGenerator::global()->bounded(m_rotationVelocityVariation)) ) * CONV; - autoRotate = m_autoRotation?1.0:0.0; + autoRotate = m_autoRotation ? 1 : 0; if (datum->rotationOwner == this) { datum->rotation = rotation; datum->rotationVelocity = rotationVelocity; diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h index 5399bc068c..894d31c300 100644 --- a/src/particles/qquickimageparticle_p.h +++ b/src/particles/qquickimageparticle_p.h @@ -99,8 +99,8 @@ struct ColoredVertex { struct DeformableVertex { float x; float y; - float tx; - float ty; + float rotation; + float rotationVelocity; float t; float lifeSpan; float size; @@ -114,16 +114,17 @@ struct DeformableVertex { float xy; float yx; float yy; - float rotation; - float rotationVelocity; - float autoRotate;//Assumed that GPUs prefer floats to bools + uchar tx; + uchar ty; + uchar autoRotate; + uchar _padding; // feel free to use }; struct SpriteVertex { float x; float y; - float tx; - float ty; + float rotation; + float rotationVelocity; float t; float lifeSpan; float size; @@ -137,16 +138,16 @@ struct SpriteVertex { float xy; float yx; float yy; - float rotation; - float rotationVelocity; - float autoRotate;//Assumed that GPUs prefer floats to bools + uchar tx; + uchar ty; + uchar autoRotate; + uchar _padding; // feel free to use float animW; float animH; float animProgress; float animX1; float animY1; float animX2; - float animY2; }; template @@ -433,18 +434,19 @@ private: template void initTexCoords(Vertex* v, int count){ Vertex* end = v + count; + // Vertex coords between (0.0, 0.0) and (1.0, 1.0) while (v < end){ v[0].tx = 0; v[0].ty = 0; - v[1].tx = 1; + v[1].tx = 255; v[1].ty = 0; v[2].tx = 0; - v[2].ty = 1; + v[2].ty = 255; - v[3].tx = 1; - v[3].ty = 1; + v[3].tx = 255; + v[3].ty = 255; v += 4; } diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h index 8b14b74131..d991257452 100644 --- a/src/particles/qquickparticlesystem_p.h +++ b/src/particles/qquickparticlesystem_p.h @@ -301,7 +301,7 @@ public: float yy; float rotation; float rotationVelocity; - float autoRotate;//Assume that GPUs prefer floats to bools + uchar autoRotate; // Basically a bool //Used by ImageParticle Sprite mode float animIdx; float frameDuration; diff --git a/src/particles/shaders_ng/imageparticle.vert b/src/particles/shaders_ng/imageparticle.vert index 870139452b..124071e48e 100644 --- a/src/particles/shaders_ng/imageparticle.vert +++ b/src/particles/shaders_ng/imageparticle.vert @@ -4,7 +4,7 @@ layout(location = 1) in vec4 vData; // x = time, y = lifeSpan, z = size, w = end layout(location = 2) in vec4 vVec; // x,y = constant velocity, z,w = acceleration #if defined(DEFORM) -layout(location = 0) in vec4 vPosTex; +layout(location = 0) in vec4 vPosRot; //x = x, y = y, z = radians of rotation, w = rotation velocity #else layout(location = 0) in vec2 vPos; #endif @@ -15,12 +15,12 @@ layout(location = 3) in vec4 vColor; #if defined(DEFORM) layout(location = 4) in vec4 vDeformVec; // x,y x unit vector; z,w = y unit vector -layout(location = 5) in vec3 vRotation; // x = radians of rotation, y = rotation velocity, z = bool autoRotate +layout(location = 5) in vec3 vTex; // x = tx, y = ty, z = bool autoRotate #endif #if defined(SPRITE) layout(location = 6) in vec3 vAnimData; // w,h(premultiplied of anim), interpolation progress -layout(location = 7) in vec4 vAnimPos; // x,y, x,y (two frames for interpolation) +layout(location = 7) in vec3 vAnimPos; // x, y, x2 (two frames for interpolation) #endif #if defined(TABLE) @@ -55,7 +55,7 @@ void main() float t = (ubuf.timestamp - vData.x) / vData.y; if (t < 0. || t > 1.) { #if defined(DEFORM) - gl_Position = ubuf.matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.); + gl_Position = ubuf.matrix * vec4(vPosRot.x, vPosRot.y, 0., 1.); #else gl_PointSize = 0.; #endif @@ -64,13 +64,13 @@ void main() tt.y = vAnimData.z; // Calculate frame location in texture - fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy; + fTexS.xy = vAnimPos.xy + vTex.xy * vAnimData.xy; // Next frame is also passed, for interpolation - fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy; + fTexS.zw = vAnimPos.zy + vTex.xy * vAnimData.xy; #elif defined(DEFORM) - fTex = vPosTex.zw; + fTex = vTex.xy; #endif float currentSize = mix(vData.z, vData.w, t * t); float fade = 1.; @@ -89,7 +89,7 @@ void main() if (currentSize <= 0.) { #if defined(DEFORM) - gl_Position = ubuf.matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.); + gl_Position = ubuf.matrix * vec4(vPosRot.x, vPosRot.y, 0., 1.); #else gl_PointSize = 0.; #endif @@ -99,14 +99,14 @@ void main() vec2 pos; #if defined(DEFORM) - float rotation = vRotation.x + vRotation.y * t * vData.y; - if (vRotation.z == 1.0) { + float rotation = vPosRot.z + vPosRot.w * t * vData.y; + if (vTex.z > 0.) { vec2 curVel = vVec.zw * t * vData.y + vVec.xy; if (length(curVel) > 0.) rotation += atan(curVel.y, curVel.x); } vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); - vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5); + vec4 deform = vDeformVec * currentSize * (vTex.xxyy - 0.5); vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy; rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.)); /* The readable version: @@ -119,7 +119,7 @@ void main() yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; */ - pos = vPosTex.xy + pos = vPosRot.xy + rotatedDeform.xy + rotatedDeform.zw + vVec.xy * t * vData.y // apply velocity diff --git a/src/particles/shaders_ng/imageparticle_colored.frag.qsb b/src/particles/shaders_ng/imageparticle_colored.frag.qsb index 72e517c0ee..84ba3262eb 100644 Binary files a/src/particles/shaders_ng/imageparticle_colored.frag.qsb and b/src/particles/shaders_ng/imageparticle_colored.frag.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_colored.vert.qsb b/src/particles/shaders_ng/imageparticle_colored.vert.qsb index a18b222b61..293cc7ea4e 100644 Binary files a/src/particles/shaders_ng/imageparticle_colored.vert.qsb and b/src/particles/shaders_ng/imageparticle_colored.vert.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_deformed.frag.qsb b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb index 3107cfeddd..02179080fa 100644 Binary files a/src/particles/shaders_ng/imageparticle_deformed.frag.qsb and b/src/particles/shaders_ng/imageparticle_deformed.frag.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_deformed.vert.qsb b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb index b4a701e9fb..d67cb043bb 100644 Binary files a/src/particles/shaders_ng/imageparticle_deformed.vert.qsb and b/src/particles/shaders_ng/imageparticle_deformed.vert.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_simple.frag.qsb b/src/particles/shaders_ng/imageparticle_simple.frag.qsb index 79e81fa479..e781a1d7a8 100644 Binary files a/src/particles/shaders_ng/imageparticle_simple.frag.qsb and b/src/particles/shaders_ng/imageparticle_simple.frag.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_simple.vert.qsb b/src/particles/shaders_ng/imageparticle_simple.vert.qsb index 4e1d4c0423..a2e0df027b 100644 Binary files a/src/particles/shaders_ng/imageparticle_simple.vert.qsb and b/src/particles/shaders_ng/imageparticle_simple.vert.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_sprite.frag.qsb b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb index 05858b1e1e..b720360a1b 100644 Binary files a/src/particles/shaders_ng/imageparticle_sprite.frag.qsb and b/src/particles/shaders_ng/imageparticle_sprite.frag.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_sprite.vert.qsb b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb index 4054a0268e..284f610f51 100644 Binary files a/src/particles/shaders_ng/imageparticle_sprite.vert.qsb and b/src/particles/shaders_ng/imageparticle_sprite.vert.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_tabled.frag.qsb b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb index 35da4df2f4..c4ca41814b 100644 Binary files a/src/particles/shaders_ng/imageparticle_tabled.frag.qsb and b/src/particles/shaders_ng/imageparticle_tabled.frag.qsb differ diff --git a/src/particles/shaders_ng/imageparticle_tabled.vert.qsb b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb index c8be30f414..91955cb521 100644 Binary files a/src/particles/shaders_ng/imageparticle_tabled.vert.qsb and b/src/particles/shaders_ng/imageparticle_tabled.vert.qsb differ -- cgit v1.2.3