1 | import { Matrix } from "@pixi/math";
|
2 | import { Program } from "../shader/Program.mjs";
|
3 | import { Shader } from "../shader/Shader.mjs";
|
4 | import { UniformGroup } from "../shader/UniformGroup.mjs";
|
5 | class BatchShaderGenerator {
|
6 | |
7 |
|
8 |
|
9 |
|
10 | constructor(vertexSrc, fragTemplate) {
|
11 | if (this.vertexSrc = vertexSrc, this.fragTemplate = fragTemplate, this.programCache = {}, this.defaultGroupCache = {}, !fragTemplate.includes("%count%"))
|
12 | throw new Error('Fragment template must contain "%count%".');
|
13 | if (!fragTemplate.includes("%forloop%"))
|
14 | throw new Error('Fragment template must contain "%forloop%".');
|
15 | }
|
16 | generateShader(maxTextures) {
|
17 | if (!this.programCache[maxTextures]) {
|
18 | const sampleValues = new Int32Array(maxTextures);
|
19 | for (let i = 0; i < maxTextures; i++)
|
20 | sampleValues[i] = i;
|
21 | this.defaultGroupCache[maxTextures] = UniformGroup.from({ uSamplers: sampleValues }, !0);
|
22 | let fragmentSrc = this.fragTemplate;
|
23 | fragmentSrc = fragmentSrc.replace(/%count%/gi, `${maxTextures}`), fragmentSrc = fragmentSrc.replace(/%forloop%/gi, this.generateSampleSrc(maxTextures)), this.programCache[maxTextures] = new Program(this.vertexSrc, fragmentSrc);
|
24 | }
|
25 | const uniforms = {
|
26 | tint: new Float32Array([1, 1, 1, 1]),
|
27 | translationMatrix: new Matrix(),
|
28 | default: this.defaultGroupCache[maxTextures]
|
29 | };
|
30 | return new Shader(this.programCache[maxTextures], uniforms);
|
31 | }
|
32 | generateSampleSrc(maxTextures) {
|
33 | let src = "";
|
34 | src += `
|
35 | `, src += `
|
36 | `;
|
37 | for (let i = 0; i < maxTextures; i++)
|
38 | i > 0 && (src += `
|
39 | else `), i < maxTextures - 1 && (src += `if(vTextureId < ${i}.5)`), src += `
|
40 | {`, src += `
|
41 | color = texture2D(uSamplers[${i}], vTextureCoord);`, src += `
|
42 | }`;
|
43 | return src += `
|
44 | `, src += `
|
45 | `, src;
|
46 | }
|
47 | }
|
48 | export {
|
49 | BatchShaderGenerator
|
50 | };
|
51 |
|