Skip to content

Commit 968c4d2

Browse files
author
Martin Valigursky
committed
Convert JS based particle shader generator to define based
1 parent 4cde8c4 commit 968c4d2

File tree

6 files changed

+223
-90
lines changed

6 files changed

+223
-90
lines changed

src/scene/particle-system/particle-material.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class ParticleMaterial extends Material {
5858
// in Editor, screen space particles (children of 2D Screen) are still rendered in 3d space
5959
screenSpace: emitter.inTools ? false : this.emitter.screenSpace,
6060

61-
blend: this.blendType,
61+
blend: this.emitter.blendType,
6262
animTex: this.emitter._isAnimated(),
6363
animTexLoop: this.emitter.animLoop,
6464
pack8: this.emitter.pack8,

src/scene/shader-lib/chunks-wgsl/chunks-wgsl.js

+4
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ import morphVS from './internal/morph/vert/morph.js';
135135
// import particle_normalVS from './particle/vert/particle_normal.js';
136136
// import particle_normalMapPS from './particle/frag/particle_normalMap.js';
137137
// import particle_pointAlongVS from './particle/vert/particle_pointAlong.js';
138+
// import particle_shaderPS from './particle/frag/particle-shader.js';
139+
// import particle_shaderVS from './particle/vert/particle-shader.js';
138140
// import particle_softPS from './particle/frag/particle_soft.js';
139141
// import particle_softVS from './particle/vert/particle_soft.js';
140142
// import particle_stretchVS from './particle/vert/particle_stretch.js';
@@ -344,6 +346,8 @@ const shaderChunksWGSL = {
344346
// particle_normalVS,
345347
// particle_normalMapPS,
346348
// particle_pointAlongVS,
349+
// particle_shaderPS,
350+
// particle_shaderVS,
347351
// particle_softPS,
348352
// particle_softVS,
349353
// particle_stretchVS,

src/scene/shader-lib/chunks/chunks.js

+4
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ import particle_meshVS from './particle/vert/particle_mesh.js';
138138
import particle_normalVS from './particle/vert/particle_normal.js';
139139
import particle_normalMapPS from './particle/frag/particle_normalMap.js';
140140
import particle_pointAlongVS from './particle/vert/particle_pointAlong.js';
141+
import particle_shaderPS from './particle/frag/particle-shader.js';
142+
import particle_shaderVS from './particle/vert/particle-shader.js';
141143
import particle_softPS from './particle/frag/particle_soft.js';
142144
import particle_softVS from './particle/vert/particle_soft.js';
143145
import particle_stretchVS from './particle/vert/particle_stretch.js';
@@ -349,6 +351,8 @@ const shaderChunks = {
349351
particle_normalVS,
350352
particle_normalMapPS,
351353
particle_pointAlongVS,
354+
particle_shaderPS,
355+
particle_shaderVS,
352356
particle_softPS,
353357
particle_softVS,
354358
particle_stretchVS,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// The main code of particle system fragment shader
2+
export default /* glsl */`
3+
#if NORMAL != NONE
4+
#if NORMAL == VERTEX
5+
varying vec3 Normal;
6+
#endif
7+
8+
#if NORMAL == MAP
9+
varying mat3 ParticleMat;
10+
#endif
11+
12+
uniform vec3 lightCube[6];
13+
#endif
14+
15+
#ifdef SOFT
16+
varying float vDepth;
17+
#include "screenDepthPS"
18+
#endif
19+
20+
#include "gammaPS"
21+
#include "tonemappingPS"
22+
#include "fogPS"
23+
24+
#if NORMAL == MAP
25+
uniform sampler2D normalMap;
26+
#endif
27+
28+
#include "particlePS"
29+
30+
#ifdef SOFT
31+
#include "particle_softPS"
32+
#endif
33+
34+
#if NORMAL == VERTEX
35+
vec3 normal = Normal;
36+
#endif
37+
38+
#if NORMAL == MAP
39+
#include "particle_normalMapPS"
40+
#endif
41+
42+
#if NORMAL != NONE
43+
#ifdef HALF_LAMBERT
44+
#include "particle_halflambertPS"
45+
#else
46+
#include "particle_lambertPS"
47+
#endif
48+
49+
#include "particle_lightingPS"
50+
#endif
51+
52+
#if BLEND == NORMAL
53+
#include "particle_blendNormalPS"
54+
#elif BLEND == ADDITIVE
55+
#include "particle_blendAddPS"
56+
#elif BLEND == MULTIPLICATIVE
57+
#include "particle_blendMultiplyPS"
58+
#endif
59+
60+
#include "particle_endPS"
61+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// The main code of particle system vertex shader
2+
export default /* glsl */`
3+
#ifdef ANIMTEX
4+
uniform vec2 animTexTilesParams;
5+
uniform vec4 animTexParams;
6+
uniform vec2 animTexIndexParams;
7+
#endif
8+
9+
#if NORMAL == MAP
10+
varying mat3 ParticleMat;
11+
#endif
12+
13+
#if NORMAL == VERTEX
14+
varying vec3 Normal;
15+
#endif
16+
17+
#ifdef SOFT
18+
varying float vDepth;
19+
#endif
20+
21+
#ifdef PARTICLE_GPU
22+
23+
#include "particle_initVS"
24+
25+
#ifdef PACK8
26+
#include "particleInputRgba8PS" // why are these PS and not VS?
27+
#else
28+
#include "particleInputFloatPS" // why are these PS and not VS?
29+
#endif
30+
31+
#ifdef SOFT
32+
#include "screenDepthPS"
33+
#endif
34+
35+
#include "particleVS"
36+
37+
#else // PARTICLE_CPU
38+
39+
#ifdef SOFT
40+
#include "screenDepthPS"
41+
#endif
42+
43+
#include "particle_cpuVS"
44+
45+
#endif
46+
47+
#ifdef LOCAL_SPACE
48+
#include "particle_localShiftVS"
49+
#endif
50+
51+
#ifdef ANIMTEX
52+
#ifdef ANIMTEX_LOOP
53+
#include "particleAnimFrameLoopVS"
54+
#else
55+
#include "particleAnimFrameClampVS"
56+
#endif
57+
#include "particleAnimTexVS"
58+
#endif
59+
60+
// wrap is not used on CPU, it was commented out. TODO: investigate why
61+
#ifdef PARTICLE_GPU
62+
#ifdef WRAP
63+
#include "particle_wrapVS"
64+
#endif
65+
#endif
66+
67+
#ifdef ALIGN_TO_MOTION
68+
#include "particle_pointAlongVS"
69+
#endif
70+
71+
#ifdef USE_MESH
72+
#include "particle_meshVS"
73+
#else
74+
#ifdef CUSTOM_FACE
75+
#include "particle_customFaceVS"
76+
#else
77+
#include "particle_billboardVS"
78+
#endif
79+
#endif
80+
81+
#if NORMAL == VERTEX
82+
#include "particle_normalVS"
83+
#endif
84+
85+
#if NORMAL == MAP
86+
#include "particle_TBNVS"
87+
#endif
88+
89+
#ifdef STRETCH
90+
#include "particle_stretchVS"
91+
#endif
92+
93+
94+
#ifdef PARTICLE_GPU
95+
#include "particle_endVS"
96+
#else // PARTICLE_CPU
97+
#include "particle_cpu_endVS"
98+
#endif
99+
100+
#ifdef SOFT
101+
#include "particle_softVS"
102+
#endif
103+
104+
}
105+
`;

src/scene/shader-lib/programs/particle.js

+48-89
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { ShaderUtils } from '../../../platform/graphics/shader-utils.js';
2-
import { BLEND_ADDITIVE, BLEND_MULTIPLICATIVE, BLEND_NORMAL } from '../../constants.js';
2+
import { blendNames } from '../../constants.js';
33
import { shaderChunks } from '../chunks/chunks.js';
44
import { ShaderGenerator } from './shader-generator.js';
55

6+
const normalTypeNames = [
7+
'NONE',
8+
'VERTEX',
9+
'MAP'
10+
];
11+
612
class ShaderGeneratorParticle extends ShaderGenerator {
713
generateKey(options) {
814
const definesHash = ShaderGenerator.definesHash(options.defines);
@@ -15,95 +21,47 @@ class ShaderGeneratorParticle extends ShaderGenerator {
1521
return key;
1622
}
1723

18-
_animTex(options) {
19-
let vshader = '';
20-
vshader += options.animTexLoop ? shaderChunks.particleAnimFrameLoopVS : shaderChunks.particleAnimFrameClampVS;
21-
vshader += shaderChunks.particleAnimTexVS;
22-
return vshader;
24+
createVertexDefines(options) {
25+
const vDefines = new Map(options.defines);
26+
27+
if (options.mesh) vDefines.set('USE_MESH', '');
28+
if (options.localSpace) vDefines.set('LOCAL_SPACE', '');
29+
if (options.screenSpace) vDefines.set('SCREEN_SPACE', '');
30+
if (options.animTex) vDefines.set('ANIMTEX', '');
31+
if (options.soft > 0) vDefines.set('SOFT', '');
32+
if (options.stretch > 0.0) vDefines.set('STRETCH', '');
33+
if (options.customFace) vDefines.set('CUSTOM_FACE', '');
34+
if (options.pack8) vDefines.set('PACK8', '');
35+
if (options.localSpace) vDefines.set('LOCAL_SPACE', '');
36+
if (options.animTexLoop) vDefines.set('ANIMTEX_LOOP', '');
37+
if (options.wrap) vDefines.set('WRAP', '');
38+
if (options.alignToMotion) vDefines.set('ALIGN_TO_MOTION', '');
39+
40+
vDefines.set('NORMAL', normalTypeNames[options.normal]);
41+
42+
return vDefines;
43+
}
44+
45+
createFragmentDefines(options) {
46+
const fDefines = new Map(options.defines);
47+
48+
if (options.soft > 0) fDefines.set('SOFT', '');
49+
if (options.halflambert) fDefines.set('HALF_LAMBERT', '');
50+
51+
fDefines.set('NORMAL', normalTypeNames[options.normal]);
52+
fDefines.set('BLEND', blendNames[options.blend]);
53+
54+
return fDefines;
2355
}
2456

2557
createShaderDefinition(device, options) {
2658

27-
const executionDefine = `#define PARTICLE_${options.useCpu ? 'CPU' : 'GPU'}\n`;
28-
29-
let fshader = `#define PARTICLE\n${executionDefine}`;
30-
let vshader = `#define VERTEXSHADER\n${executionDefine}`;
31-
32-
if (options.mesh) vshader += '#define USE_MESH\n';
33-
if (options.localSpace) vshader += '#define LOCAL_SPACE\n';
34-
if (options.screenSpace) vshader += '#define SCREEN_SPACE\n';
35-
36-
if (options.animTex) vshader += '\nuniform vec2 animTexTilesParams;\n';
37-
if (options.animTex) vshader += '\nuniform vec4 animTexParams;\n';
38-
if (options.animTex) vshader += '\nuniform vec2 animTexIndexParams;\n';
39-
if (options.normal === 2) vshader += '\nvarying mat3 ParticleMat;\n';
40-
if (options.normal === 1) vshader += '\nvarying vec3 Normal;\n';
41-
if (options.soft) vshader += '\nvarying float vDepth;\n';
42-
43-
const faceVS = options.customFace ? shaderChunks.particle_customFaceVS : shaderChunks.particle_billboardVS;
44-
45-
if (!options.useCpu) {
46-
vshader += shaderChunks.particle_initVS;
47-
vshader += (options.pack8 ? shaderChunks.particleInputRgba8PS : shaderChunks.particleInputFloatPS);
48-
if (options.soft > 0) vshader += shaderChunks.screenDepthPS;
49-
vshader += shaderChunks.particleVS;
50-
if (options.localSpace) vshader += shaderChunks.particle_localShiftVS;
51-
if (options.animTex) vshader += this._animTex(options);
52-
if (options.wrap) vshader += shaderChunks.particle_wrapVS;
53-
if (options.alignToMotion) vshader += shaderChunks.particle_pointAlongVS;
54-
vshader += options.mesh ? shaderChunks.particle_meshVS : faceVS;
55-
if (options.normal === 1) vshader += shaderChunks.particle_normalVS;
56-
if (options.normal === 2) vshader += shaderChunks.particle_TBNVS;
57-
if (options.stretch > 0.0) vshader += shaderChunks.particle_stretchVS;
58-
vshader += shaderChunks.particle_endVS;
59-
if (options.soft > 0) vshader += shaderChunks.particle_softVS;
60-
} else {
61-
if (options.soft > 0) vshader += shaderChunks.screenDepthPS;
62-
vshader += shaderChunks.particle_cpuVS;
63-
if (options.localSpace) vshader += shaderChunks.particle_localShiftVS;
64-
if (options.animTex) vshader += this._animTex(options);
65-
// if (options.wrap) vshader += shaderChunks.particle_wrapVS;
66-
if (options.alignToMotion) vshader += shaderChunks.particle_pointAlongVS;
67-
vshader += options.mesh ? shaderChunks.particle_meshVS : faceVS;
68-
if (options.normal === 1) vshader += shaderChunks.particle_normalVS;
69-
if (options.normal === 2) vshader += shaderChunks.particle_TBNVS;
70-
if (options.stretch > 0.0) vshader += shaderChunks.particle_stretchVS;
71-
vshader += shaderChunks.particle_cpu_endVS;
72-
if (options.soft > 0) vshader += shaderChunks.particle_softVS;
73-
}
74-
vshader += '}\n';
59+
const vDefines = this.createVertexDefines(options);
60+
const fDefines = this.createFragmentDefines(options);
7561

76-
if (options.normal > 0) {
77-
if (options.normal === 1) {
78-
fshader += '\nvarying vec3 Normal;\n';
79-
} else if (options.normal === 2) {
80-
fshader += '\nvarying mat3 ParticleMat;\n';
81-
}
82-
fshader += '\nuniform vec3 lightCube[6];\n';
83-
}
84-
if (options.soft) fshader += '\nvarying float vDepth;\n';
85-
86-
fshader += shaderChunks.decodePS;
87-
fshader += '#include "gammaPS"\n';
88-
fshader += '#include "tonemappingPS"\n';
89-
fshader += '#include "fogPS"\n';
90-
91-
if (options.normal === 2) fshader += '\nuniform sampler2D normalMap;\n';
92-
if (options.soft > 0) fshader += shaderChunks.screenDepthPS;
93-
fshader += shaderChunks.particlePS;
94-
if (options.soft > 0) fshader += shaderChunks.particle_softPS;
95-
if (options.normal === 1) fshader += '\nvec3 normal = Normal;\n';
96-
if (options.normal === 2) fshader += shaderChunks.particle_normalMapPS;
97-
if (options.normal > 0) fshader += options.halflambert ? shaderChunks.particle_halflambertPS : shaderChunks.particle_lambertPS;
98-
if (options.normal > 0) fshader += shaderChunks.particle_lightingPS;
99-
if (options.blend === BLEND_NORMAL) {
100-
fshader += shaderChunks.particle_blendNormalPS;
101-
} else if (options.blend === BLEND_ADDITIVE) {
102-
fshader += shaderChunks.particle_blendAddPS;
103-
} else if (options.blend === BLEND_MULTIPLICATIVE) {
104-
fshader += shaderChunks.particle_blendMultiplyPS;
105-
}
106-
fshader += shaderChunks.particle_endPS;
62+
const executionDefine = `PARTICLE_${options.useCpu ? 'CPU' : 'GPU'}\n`;
63+
vDefines.set(executionDefine, '');
64+
fDefines.set(executionDefine, '');
10765

10866
const includes = new Map(Object.entries({
10967
...shaderChunks,
@@ -112,11 +70,12 @@ class ShaderGeneratorParticle extends ShaderGenerator {
11270

11371
return ShaderUtils.createDefinition(device, {
11472
name: 'ParticleShader',
115-
vertexCode: vshader,
116-
fragmentCode: fshader,
117-
fragmentDefines: options.defines,
73+
vertexCode: shaderChunks.particle_shaderVS,
74+
fragmentCode: shaderChunks.particle_shaderPS,
75+
fragmentDefines: fDefines,
11876
fragmentIncludes: includes,
119-
vertexDefines: options.defines
77+
vertexIncludes: includes,
78+
vertexDefines: vDefines
12079
});
12180
}
12281
}

0 commit comments

Comments
 (0)