Revision control

Copy as Markdown

// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#if defined(QSSG_PARTICLES_ENABLE_ANIMATED) || defined(QSSG_PARTICLES_ENABLE_LINE_PARTICLE)
const uint particleSize = 4;
#else
const uint particleSize = 3;
#endif
#ifdef QSSG_PARTICLES_ENABLE_LINE_PARTICLE
struct Particle
{
vec3 position;
float size;
vec4 color;
vec3 binormal;
float animationFrame;
float age;
float segmentLength;
vec2 unusedPadding;
};
#else
struct Particle
{
vec3 position;
float size;
vec3 rotation;
float age;
vec4 color;
#ifdef QSSG_PARTICLES_ENABLE_ANIMATED
float animationFrame;
vec3 unusedPadding;
#endif
};
#endif
vec2 qt_indexToUV(in uint index)
{
uint v = index / qt_countPerSlice;
uint u = index - qt_countPerSlice * v;
return (vec2(u * particleSize, v) + vec2(0.5)) * qt_oneOverParticleImageSize;
}
#ifdef QSSG_PARTICLES_ENABLE_LINE_PARTICLE
Particle qt_loadParticle(in uint index)
{
Particle p;
vec2 offset = qt_indexToUV(index);
vec4 p0 = texture(qt_particleTexture, offset);
vec4 p1 = texture(qt_particleTexture, vec2(offset.x + qt_oneOverParticleImageSize.x, offset.y));
vec4 p2 = texture(qt_particleTexture, vec2(offset.x + 2.0 * qt_oneOverParticleImageSize.x, offset.y));
vec4 p3 = texture(qt_particleTexture, vec2(offset.x + 3.0 * qt_oneOverParticleImageSize.x, offset.y));
p.position = p0.xyz;
p.size = p0.w;
p.color = p1;
p.binormal = p2.xyz;
p.animationFrame = p2.w;
p.age = p3.x;
p.segmentLength = p3.y;
return p;
}
#else
Particle qt_loadParticle(in uint index)
{
Particle p;
vec2 offset = qt_indexToUV(index);
vec4 p0 = texture(qt_particleTexture, offset);
vec4 p1 = texture(qt_particleTexture, vec2(offset.x + qt_oneOverParticleImageSize.x, offset.y));
vec4 p2 = texture(qt_particleTexture, vec2(offset.x + 2.0 * qt_oneOverParticleImageSize.x, offset.y));
#ifdef QSSG_PARTICLES_ENABLE_ANIMATED
vec4 p3 = texture(qt_particleTexture, vec2(offset.x + 3.0 * qt_oneOverParticleImageSize.x, offset.y));
#endif
p.position = p0.xyz;
p.size = p0.w;
p.rotation = p1.xyz;
p.age = p1.w;
p.color = p2;
#ifdef QSSG_PARTICLES_ENABLE_ANIMATED
p.animationFrame = p3.x;
#endif
return p;
}
#endif
mat3 qt_fromEulerRotation(in vec3 rotation)
{
float a = cos(rotation.x);
float b = sin(rotation.x);
float c = cos(rotation.y);
float d = sin(rotation.y);
float e = cos(rotation.z);
float f = sin(rotation.z);
mat3 ret;
float bd = b*d;
float ad = a*d;
ret[0][0] = c * e;
ret[0][1] = -c * f;
ret[0][2] = d;
ret[1][0] = bd*e + a*f;
ret[1][1] = a*e - bd*f;
ret[1][2] = -b*c;
ret[2][0] = b*f - ad*e;
ret[2][1] = ad*f + b*e;
ret[2][2] = a*c;
return ret;
}
float qt_ageToSpriteFactor(in float age)
{
// Age should be [0, 1], but just in case take the fraction
return fract(age);
}
#ifdef QSSG_PARTICLES_ENABLE_LINE_PARTICLE
float qt_calcAlphaFade(in uint segmentIndex)
{
return pow(qt_alphaFade, float(segmentIndex));
}
float qt_calcSizeFactor(in uint segmentIndex)
{
return pow(qt_sizeModifier, float(segmentIndex));
}
#endif