1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
const uint particleSize = 4;
struct Particle
{
vec3 position;
float size;
vec3 rotation;
float age;
vec4 color;
vec3 center;
};
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;
}
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.rotation = p1.xyz;
p.age = p1.w;
p.color = p2;
p.center = p3.xyz;
return p;
}
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;
}
vec3 qt_applyParticle(in vec3 position, in vec3 normal, in vec4 color, out vec3 outNormal, out vec4 outColor, in mat4 particleMatrix)
{
uint index = (gl_VertexIndex + qt_particleIndexOffset) / 3;
Particle p = qt_loadParticle(index);
mat3 rotMat = qt_fromEulerRotation(p.rotation);
vec3 particlePos = p.size * rotMat * (position - p.center);
vec3 pos = particlePos + (particleMatrix * vec4(p.position, 1.0)).xyz;
outNormal = normalize(rotMat * normal);
outColor = color * p.color;
return pos;
}
|