@codexo/exojs 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +14 -14
  3. package/dist/esm/core/Application.d.ts +25 -6
  4. package/dist/esm/core/Application.js +42 -8
  5. package/dist/esm/core/Application.js.map +1 -1
  6. package/dist/esm/core/Perf.d.ts +23 -0
  7. package/dist/esm/core/Perf.js +49 -0
  8. package/dist/esm/core/Perf.js.map +1 -0
  9. package/dist/esm/core/Scene.d.ts +8 -8
  10. package/dist/esm/core/Scene.js +7 -7
  11. package/dist/esm/core/Scene.js.map +1 -1
  12. package/dist/esm/core/SceneManager.js +2 -2
  13. package/dist/esm/core/SceneManager.js.map +1 -1
  14. package/dist/esm/core/SceneNode.d.ts +0 -3
  15. package/dist/esm/core/SceneNode.js +0 -9
  16. package/dist/esm/core/SceneNode.js.map +1 -1
  17. package/dist/esm/core/capabilities.d.ts +2 -0
  18. package/dist/esm/core/capabilities.js +15 -0
  19. package/dist/esm/core/capabilities.js.map +1 -1
  20. package/dist/esm/core/index.d.ts +1 -0
  21. package/dist/esm/core/types.d.ts +1 -1
  22. package/dist/esm/core/utils.d.ts +12 -0
  23. package/dist/esm/core/utils.js +18 -1
  24. package/dist/esm/core/utils.js.map +1 -1
  25. package/dist/esm/index.js +14 -3
  26. package/dist/esm/index.js.map +1 -1
  27. package/dist/esm/particles/ParticleSystem.d.ts +8 -5
  28. package/dist/esm/particles/ParticleSystem.js +9 -5
  29. package/dist/esm/particles/ParticleSystem.js.map +1 -1
  30. package/dist/esm/particles/distributions/{Gradient.d.ts → ColorGradient.d.ts} +5 -5
  31. package/dist/esm/particles/distributions/{Gradient.js → ColorGradient.js} +5 -5
  32. package/dist/esm/particles/distributions/ColorGradient.js.map +1 -0
  33. package/dist/esm/particles/distributions/Distribution.d.ts +2 -2
  34. package/dist/esm/particles/distributions/index.d.ts +2 -2
  35. package/dist/esm/particles/gpu/ParticleGpuState.js +1 -1
  36. package/dist/esm/particles/modules/ColorOverLifetime.d.ts +3 -3
  37. package/dist/esm/particles/modules/ColorOverLifetime.js.map +1 -1
  38. package/dist/esm/particles/modules/ColorOverSpeed.d.ts +3 -3
  39. package/dist/esm/particles/modules/ColorOverSpeed.js.map +1 -1
  40. package/dist/esm/particles/modules/UpdateModule.d.ts +2 -2
  41. package/dist/esm/particles/modules/UpdateModule.js +1 -1
  42. package/dist/esm/particles/modules/WgslContribution.d.ts +2 -2
  43. package/dist/esm/rendering/Camera.d.ts +33 -0
  44. package/dist/esm/rendering/Camera.js +38 -0
  45. package/dist/esm/rendering/Camera.js.map +1 -0
  46. package/dist/esm/rendering/Container.d.ts +5 -24
  47. package/dist/esm/rendering/Container.js +8 -71
  48. package/dist/esm/rendering/Container.js.map +1 -1
  49. package/dist/esm/rendering/Drawable.d.ts +8 -10
  50. package/dist/esm/rendering/Drawable.js +12 -20
  51. package/dist/esm/rendering/Drawable.js.map +1 -1
  52. package/dist/esm/rendering/RenderBackend.d.ts +18 -0
  53. package/dist/esm/rendering/RenderNode.d.ts +81 -8
  54. package/dist/esm/rendering/RenderNode.js +121 -144
  55. package/dist/esm/rendering/RenderNode.js.map +1 -1
  56. package/dist/esm/rendering/RenderTarget.d.ts +13 -0
  57. package/dist/esm/rendering/RenderTarget.js +13 -0
  58. package/dist/esm/rendering/RenderTarget.js.map +1 -1
  59. package/dist/esm/rendering/RenderTargetPass.js +17 -0
  60. package/dist/esm/rendering/RenderTargetPass.js.map +1 -1
  61. package/dist/esm/rendering/RenderingContext.d.ts +87 -0
  62. package/dist/esm/rendering/RenderingContext.js +157 -0
  63. package/dist/esm/rendering/RenderingContext.js.map +1 -0
  64. package/dist/esm/rendering/TransformBuffer.d.ts +38 -0
  65. package/dist/esm/rendering/TransformBuffer.js +116 -0
  66. package/dist/esm/rendering/TransformBuffer.js.map +1 -0
  67. package/dist/esm/rendering/filters/WebGpuShaderFilter.js +5 -12
  68. package/dist/esm/rendering/filters/WebGpuShaderFilter.js.map +1 -1
  69. package/dist/esm/rendering/geometry/Geometry.d.ts +40 -0
  70. package/dist/esm/rendering/geometry/Geometry.js +228 -0
  71. package/dist/esm/rendering/geometry/Geometry.js.map +1 -0
  72. package/dist/esm/rendering/geometry/GeometryAttribute.d.ts +32 -0
  73. package/dist/esm/rendering/geometry/QuadGeometry.d.ts +5 -0
  74. package/dist/esm/rendering/gradient/Gradient.d.ts +34 -0
  75. package/dist/esm/rendering/gradient/Gradient.js +114 -0
  76. package/dist/esm/rendering/gradient/Gradient.js.map +1 -0
  77. package/dist/esm/rendering/gradient/LinearGradient.d.ts +10 -0
  78. package/dist/esm/rendering/gradient/LinearGradient.js +26 -0
  79. package/dist/esm/rendering/gradient/LinearGradient.js.map +1 -0
  80. package/dist/esm/rendering/gradient/RadialGradient.d.ts +10 -0
  81. package/dist/esm/rendering/gradient/RadialGradient.js +25 -0
  82. package/dist/esm/rendering/gradient/RadialGradient.js.map +1 -0
  83. package/dist/esm/rendering/index.d.ts +16 -2
  84. package/dist/esm/rendering/material/Material.d.ts +114 -0
  85. package/dist/esm/rendering/material/Material.js +111 -0
  86. package/dist/esm/rendering/material/Material.js.map +1 -0
  87. package/dist/esm/rendering/material/MaterialKey.d.ts +18 -0
  88. package/dist/esm/rendering/material/MaterialKey.js +82 -0
  89. package/dist/esm/rendering/material/MaterialKey.js.map +1 -0
  90. package/dist/esm/rendering/material/MeshMaterial.d.ts +16 -0
  91. package/dist/esm/rendering/material/MeshMaterial.js +21 -0
  92. package/dist/esm/rendering/material/MeshMaterial.js.map +1 -0
  93. package/dist/esm/rendering/{mesh/MeshShader.d.ts → material/ShaderSource.d.ts} +29 -62
  94. package/dist/esm/rendering/{mesh/MeshShader.js → material/ShaderSource.js} +35 -62
  95. package/dist/esm/rendering/material/ShaderSource.js.map +1 -0
  96. package/dist/esm/rendering/material/SpriteMaterial.d.ts +15 -0
  97. package/dist/esm/rendering/material/SpriteMaterial.js +20 -0
  98. package/dist/esm/rendering/material/SpriteMaterial.js.map +1 -0
  99. package/dist/esm/rendering/mesh/Mesh.d.ts +29 -12
  100. package/dist/esm/rendering/mesh/Mesh.js +122 -3
  101. package/dist/esm/rendering/mesh/Mesh.js.map +1 -1
  102. package/dist/esm/rendering/pass/RenderPassCoordinator.d.ts +63 -0
  103. package/dist/esm/rendering/pass/RenderPassDescriptor.d.ts +48 -0
  104. package/dist/esm/rendering/pass/RenderPassDescriptor.js +16 -0
  105. package/dist/esm/rendering/pass/RenderPassDescriptor.js.map +1 -0
  106. package/dist/esm/rendering/plan/RenderCommand.d.ts +67 -0
  107. package/dist/esm/rendering/plan/RenderCommand.js +94 -0
  108. package/dist/esm/rendering/plan/RenderCommand.js.map +1 -0
  109. package/dist/esm/rendering/plan/RenderEffectExecutor.d.ts +10 -0
  110. package/dist/esm/rendering/plan/RenderEffectExecutor.js +159 -0
  111. package/dist/esm/rendering/plan/RenderEffectExecutor.js.map +1 -0
  112. package/dist/esm/rendering/plan/RenderPlan.d.ts +23 -0
  113. package/dist/esm/rendering/plan/RenderPlan.js +12 -0
  114. package/dist/esm/rendering/plan/RenderPlan.js.map +1 -0
  115. package/dist/esm/rendering/plan/RenderPlanBuilder.d.ts +31 -0
  116. package/dist/esm/rendering/plan/RenderPlanBuilder.js +242 -0
  117. package/dist/esm/rendering/plan/RenderPlanBuilder.js.map +1 -0
  118. package/dist/esm/rendering/plan/RenderPlanOptimizer.d.ts +10 -0
  119. package/dist/esm/rendering/plan/RenderPlanOptimizer.js +180 -0
  120. package/dist/esm/rendering/plan/RenderPlanOptimizer.js.map +1 -0
  121. package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts +9 -0
  122. package/dist/esm/rendering/plan/RenderPlanPlayer.js +56 -0
  123. package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -0
  124. package/dist/esm/rendering/plan/RenderScope.d.ts +70 -0
  125. package/dist/esm/rendering/plan/RenderScope.js +16 -0
  126. package/dist/esm/rendering/plan/RenderScope.js.map +1 -0
  127. package/dist/esm/rendering/plan/playRenderTree.d.ts +4 -0
  128. package/dist/esm/rendering/plan/playRenderTree.js +19 -0
  129. package/dist/esm/rendering/plan/playRenderTree.js.map +1 -0
  130. package/dist/esm/rendering/sprite/Sprite.d.ts +22 -1
  131. package/dist/esm/rendering/sprite/Sprite.js +33 -2
  132. package/dist/esm/rendering/sprite/Sprite.js.map +1 -1
  133. package/dist/esm/rendering/sprite/spriteMaterialSources.d.ts +36 -0
  134. package/dist/esm/rendering/sprite/spriteMaterialSources.js +128 -0
  135. package/dist/esm/rendering/sprite/spriteMaterialSources.js.map +1 -0
  136. package/dist/esm/rendering/text/TextStyle.d.ts +1 -1
  137. package/dist/esm/rendering/texture/DataTexture.d.ts +5 -0
  138. package/dist/esm/rendering/texture/DataTexture.js +7 -0
  139. package/dist/esm/rendering/texture/DataTexture.js.map +1 -1
  140. package/dist/esm/rendering/video/Video.d.ts +3 -7
  141. package/dist/esm/rendering/video/Video.js +3 -8
  142. package/dist/esm/rendering/video/Video.js.map +1 -1
  143. package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +40 -0
  144. package/dist/esm/rendering/webgl2/WebGl2Backend.js +303 -22
  145. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
  146. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.d.ts +22 -2
  147. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +404 -112
  148. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -1
  149. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.d.ts +57 -0
  150. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.js +79 -0
  151. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.js.map +1 -0
  152. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +12 -0
  153. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +214 -58
  154. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
  155. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.d.ts +34 -0
  156. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.js +169 -0
  157. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.js.map +1 -0
  158. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js +4 -0
  159. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js.map +1 -1
  160. package/dist/esm/rendering/webgl2/glsl/mesh.frag.js +1 -1
  161. package/dist/esm/rendering/webgl2/glsl/mesh.vert.js +1 -1
  162. package/dist/esm/rendering/webgl2/glsl/stencil-clip.frag.js +4 -0
  163. package/dist/esm/rendering/webgl2/glsl/stencil-clip.frag.js.map +1 -0
  164. package/dist/esm/rendering/webgl2/glsl/stencil-clip.vert.js +4 -0
  165. package/dist/esm/rendering/webgl2/glsl/stencil-clip.vert.js.map +1 -0
  166. package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +50 -0
  167. package/dist/esm/rendering/webgpu/WebGpuBackend.js +135 -19
  168. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
  169. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js +22 -17
  170. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js.map +1 -1
  171. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.d.ts +24 -0
  172. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +488 -74
  173. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -1
  174. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +13 -17
  175. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
  176. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.d.ts +141 -0
  177. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js +270 -0
  178. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js.map +1 -0
  179. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +16 -0
  180. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +335 -26
  181. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  182. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.d.ts +57 -0
  183. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.js +257 -0
  184. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.js.map +1 -0
  185. package/dist/esm/rendering/webgpu/WebGpuStencilState.d.ts +14 -0
  186. package/dist/esm/rendering/webgpu/WebGpuStencilState.js +36 -0
  187. package/dist/esm/rendering/webgpu/WebGpuStencilState.js.map +1 -0
  188. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js +14 -12
  189. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js.map +1 -1
  190. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +16 -0
  191. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +57 -0
  192. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -0
  193. package/dist/esm/resources/JsonStore.d.ts +18 -0
  194. package/dist/esm/resources/JsonStore.js +62 -0
  195. package/dist/esm/resources/JsonStore.js.map +1 -0
  196. package/dist/esm/resources/factories/ImageFactory.d.ts +14 -8
  197. package/dist/esm/resources/factories/ImageFactory.js +13 -6
  198. package/dist/esm/resources/factories/ImageFactory.js.map +1 -1
  199. package/dist/esm/resources/factories/TextureFactory.d.ts +4 -4
  200. package/dist/esm/resources/factories/TextureFactory.js +8 -4
  201. package/dist/esm/resources/factories/TextureFactory.js.map +1 -1
  202. package/dist/esm/resources/index.d.ts +1 -0
  203. package/dist/exo.esm.js +5424 -2205
  204. package/dist/exo.esm.js.map +1 -1
  205. package/package.json +30 -24
  206. package/dist/esm/particles/distributions/Gradient.js.map +0 -1
  207. package/dist/esm/rendering/mesh/MeshShader.js.map +0 -1
  208. package/dist/esm/vendor/webgl-debug.js +0 -1160
  209. package/dist/esm/vendor/webgl-debug.js.map +0 -1
@@ -0,0 +1,114 @@
1
+ import type { RenderTexture } from '@/rendering/texture/RenderTexture';
2
+ import type { SamplerOptions } from '@/rendering/texture/Sampler';
3
+ import type { Texture } from '@/rendering/texture/Texture';
4
+ import { BlendModes } from '@/rendering/types';
5
+ import type { ShaderSource } from './ShaderSource';
6
+ /**
7
+ * Value accepted by a material uniform. Scalars and small tuples
8
+ * auto-marshal to the appropriate `Float32Array`/`Int32Array` for the
9
+ * backend's uniform call. `Texture`/`RenderTexture` values are bound to
10
+ * texture slots starting at slot 1 — slot 0 is reserved for the drawable's
11
+ * own `texture`.
12
+ */
13
+ export type UniformValue = number | readonly [number, number] | readonly [number, number, number] | readonly [number, number, number, number] | Float32Array | Int32Array | Texture | RenderTexture;
14
+ /**
15
+ * Construction options shared by every {@link Material}.
16
+ *
17
+ * Only `shader` is required. Textures may be supplied either through the
18
+ * dedicated `textures` map or as texture-valued entries in `uniforms`;
19
+ * both are honoured by the bind-key derivation.
20
+ */
21
+ export interface MaterialOptions {
22
+ /** GLSL/WGSL source pair backing this material. */
23
+ readonly shader: ShaderSource;
24
+ /** Initial uniform values; mutate per frame via {@link Material.uniforms}. */
25
+ readonly uniforms?: Record<string, UniformValue>;
26
+ /** Named texture bindings claimed in addition to the drawable's own texture. */
27
+ readonly textures?: Record<string, Texture | RenderTexture>;
28
+ /** Compositing blend mode; defaults to {@link BlendModes.Normal}. */
29
+ readonly blendMode?: BlendModes;
30
+ /**
31
+ * Backend-agnostic sampling state descriptor, or `null` to inherit the
32
+ * backend/texture default. Defaults to `null`.
33
+ */
34
+ readonly sampler?: SamplerOptions | null;
35
+ }
36
+ /**
37
+ * Describes the look of a renderable — shader, uniforms, textures, blend
38
+ * mode, and sampling state — independent of its geometry.
39
+ *
40
+ * A `Material` can be shared across many drawables; renderers cache
41
+ * compiled programs/pipelines keyed on {@link pipelineKey} and reuse
42
+ * bindings keyed on {@link bindKey}. Subclasses fix the {@link target}
43
+ * drawable class. Call {@link destroy} when the material is no longer
44
+ * needed to release the GPU resources cached on every backend it was used
45
+ * on.
46
+ *
47
+ * Both keys are derived live from the current material state, so they stay
48
+ * stable across repeated reads and change exactly when the relevant state
49
+ * changes — even when {@link uniforms}, {@link textures}, {@link blendMode},
50
+ * or {@link sampler} are mutated in place.
51
+ * @advanced
52
+ */
53
+ export declare abstract class Material {
54
+ /** GLSL/WGSL source pair backing this material. */
55
+ readonly shader: ShaderSource;
56
+ /**
57
+ * Mutable user uniform values. Mutate between frames to drive animated
58
+ * effects; the renderer reads from this map every draw.
59
+ *
60
+ * material.uniforms.u_time = performance.now() / 1000;
61
+ * material.uniforms.u_color = [1, 0.5, 0, 1];
62
+ */
63
+ uniforms: Record<string, UniformValue>;
64
+ /** Named texture bindings claimed in addition to the drawable's own texture. */
65
+ textures: Record<string, Texture | RenderTexture>;
66
+ /** Compositing blend mode applied when drawing with this material. */
67
+ blendMode: BlendModes;
68
+ /** Backend-agnostic sampling state descriptor, or `null` for the default. */
69
+ sampler: SamplerOptions | null;
70
+ /** Which drawable class this material can serve; renderers check compatibility. */
71
+ abstract readonly target: 'mesh' | 'sprite';
72
+ private readonly _id;
73
+ private readonly _disposeCallbacks;
74
+ protected constructor(options: MaterialOptions);
75
+ /**
76
+ * Stable pipeline key: identical ⇒ same GPU pipeline/program can be used.
77
+ * Derived from shader identity, blend mode, and sampler state, and is
78
+ * independent of the owning material instance so identically configured
79
+ * materials share a pipeline. Drives grouping and the pipeline cache.
80
+ */
81
+ get pipelineKey(): number;
82
+ /**
83
+ * Stable bind key: identical ⇒ same bindings (textures unchanged). Derived
84
+ * from this material's identity and the identities of its bound textures.
85
+ * Changes when a texture is swapped; drives bind-group/slot reuse.
86
+ */
87
+ get bindKey(): number;
88
+ /**
89
+ * Set a uniform value. Equivalent to `material.uniforms[name] = value`,
90
+ * returned `this` for chaining.
91
+ */
92
+ setUniform(name: string, value: UniformValue): this;
93
+ /**
94
+ * Bind a named texture. Equivalent to `material.textures[name] = texture`,
95
+ * returned `this` for chaining.
96
+ */
97
+ setTexture(name: string, texture: Texture | RenderTexture): this;
98
+ /**
99
+ * Release GPU resources cached against this material on every backend
100
+ * that has compiled it. Safe to call multiple times. After destroy, the
101
+ * material can still be re-used — renderers recompile on next draw — but
102
+ * typical usage is to drop the reference.
103
+ */
104
+ destroy(): void;
105
+ /**
106
+ * Internal hook for renderers to register a per-material-instance cleanup
107
+ * callback (release compiled program, pipeline, or bind groups). The
108
+ * callback fires on {@link destroy}; renderers MUST also tolerate the
109
+ * material being garbage-collected without destroy ever being called.
110
+ *
111
+ * @internal
112
+ */
113
+ _onDispose(callback: () => void): void;
114
+ }
@@ -0,0 +1,111 @@
1
+ import { BlendModes } from '../types.js';
2
+ import { derivePipelineKey, deriveBindKey } from './MaterialKey.js';
3
+
4
+ let nextMaterialId = 1;
5
+ /**
6
+ * Describes the look of a renderable — shader, uniforms, textures, blend
7
+ * mode, and sampling state — independent of its geometry.
8
+ *
9
+ * A `Material` can be shared across many drawables; renderers cache
10
+ * compiled programs/pipelines keyed on {@link pipelineKey} and reuse
11
+ * bindings keyed on {@link bindKey}. Subclasses fix the {@link target}
12
+ * drawable class. Call {@link destroy} when the material is no longer
13
+ * needed to release the GPU resources cached on every backend it was used
14
+ * on.
15
+ *
16
+ * Both keys are derived live from the current material state, so they stay
17
+ * stable across repeated reads and change exactly when the relevant state
18
+ * changes — even when {@link uniforms}, {@link textures}, {@link blendMode},
19
+ * or {@link sampler} are mutated in place.
20
+ * @advanced
21
+ */
22
+ class Material {
23
+ /** GLSL/WGSL source pair backing this material. */
24
+ shader;
25
+ /**
26
+ * Mutable user uniform values. Mutate between frames to drive animated
27
+ * effects; the renderer reads from this map every draw.
28
+ *
29
+ * material.uniforms.u_time = performance.now() / 1000;
30
+ * material.uniforms.u_color = [1, 0.5, 0, 1];
31
+ */
32
+ uniforms;
33
+ /** Named texture bindings claimed in addition to the drawable's own texture. */
34
+ textures;
35
+ /** Compositing blend mode applied when drawing with this material. */
36
+ blendMode;
37
+ /** Backend-agnostic sampling state descriptor, or `null` for the default. */
38
+ sampler;
39
+ _id;
40
+ _disposeCallbacks = new Set();
41
+ constructor(options) {
42
+ if (options.shader === undefined || options.shader === null) {
43
+ throw new Error('Material requires a `shader` ShaderSource.');
44
+ }
45
+ this.shader = options.shader;
46
+ this.uniforms = { ...(options.uniforms ?? {}) };
47
+ this.textures = { ...(options.textures ?? {}) };
48
+ this.blendMode = options.blendMode ?? BlendModes.Normal;
49
+ this.sampler = options.sampler ?? null;
50
+ this._id = nextMaterialId++;
51
+ }
52
+ /**
53
+ * Stable pipeline key: identical ⇒ same GPU pipeline/program can be used.
54
+ * Derived from shader identity, blend mode, and sampler state, and is
55
+ * independent of the owning material instance so identically configured
56
+ * materials share a pipeline. Drives grouping and the pipeline cache.
57
+ */
58
+ get pipelineKey() {
59
+ return derivePipelineKey(this.shader.id, this.blendMode, this.sampler);
60
+ }
61
+ /**
62
+ * Stable bind key: identical ⇒ same bindings (textures unchanged). Derived
63
+ * from this material's identity and the identities of its bound textures.
64
+ * Changes when a texture is swapped; drives bind-group/slot reuse.
65
+ */
66
+ get bindKey() {
67
+ return deriveBindKey(this._id, this.uniforms, this.textures);
68
+ }
69
+ /**
70
+ * Set a uniform value. Equivalent to `material.uniforms[name] = value`,
71
+ * returned `this` for chaining.
72
+ */
73
+ setUniform(name, value) {
74
+ this.uniforms[name] = value;
75
+ return this;
76
+ }
77
+ /**
78
+ * Bind a named texture. Equivalent to `material.textures[name] = texture`,
79
+ * returned `this` for chaining.
80
+ */
81
+ setTexture(name, texture) {
82
+ this.textures[name] = texture;
83
+ return this;
84
+ }
85
+ /**
86
+ * Release GPU resources cached against this material on every backend
87
+ * that has compiled it. Safe to call multiple times. After destroy, the
88
+ * material can still be re-used — renderers recompile on next draw — but
89
+ * typical usage is to drop the reference.
90
+ */
91
+ destroy() {
92
+ for (const callback of this._disposeCallbacks) {
93
+ callback();
94
+ }
95
+ this._disposeCallbacks.clear();
96
+ }
97
+ /**
98
+ * Internal hook for renderers to register a per-material-instance cleanup
99
+ * callback (release compiled program, pipeline, or bind groups). The
100
+ * callback fires on {@link destroy}; renderers MUST also tolerate the
101
+ * material being garbage-collected without destroy ever being called.
102
+ *
103
+ * @internal
104
+ */
105
+ _onDispose(callback) {
106
+ this._disposeCallbacks.add(callback);
107
+ }
108
+ }
109
+
110
+ export { Material };
111
+ //# sourceMappingURL=Material.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Material.js","sources":["../../../../../src/rendering/material/Material.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAoDA,IAAI,cAAc,GAAG,CAAC;AAEtB;;;;;;;;;;;;;;;;AAgBG;MACmB,QAAQ,CAAA;;AAEZ,IAAA,MAAM;AAEtB;;;;;;AAMG;AACI,IAAA,QAAQ;;AAGR,IAAA,QAAQ;;AAGR,IAAA,SAAS;;AAGT,IAAA,OAAO;AAKG,IAAA,GAAG;AACH,IAAA,iBAAiB,GAAG,IAAI,GAAG,EAAc;AAE1D,IAAA,WAAA,CAAsB,OAAwB,EAAA;AAC5C,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE;AAC3D,YAAA,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC;QAC/D;AAEA,QAAA,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;AAC5B,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE;AAC/C,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE;QAC/C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,MAAM;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI;AACtC,QAAA,IAAI,CAAC,GAAG,GAAG,cAAc,EAAE;IAC7B;AAEA;;;;;AAKG;AACH,IAAA,IAAW,WAAW,GAAA;AACpB,QAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;IACxE;AAEA;;;;AAIG;AACH,IAAA,IAAW,OAAO,GAAA;AAChB,QAAA,OAAO,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC;IAC9D;AAEA;;;AAGG;IACI,UAAU,CAAC,IAAY,EAAE,KAAmB,EAAA;AACjD,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK;AAE3B,QAAA,OAAO,IAAI;IACb;AAEA;;;AAGG;IACI,UAAU,CAAC,IAAY,EAAE,OAAgC,EAAA;AAC9D,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO;AAE7B,QAAA,OAAO,IAAI;IACb;AAEA;;;;;AAKG;IACI,OAAO,GAAA;AACZ,QAAA,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC7C,YAAA,QAAQ,EAAE;QACZ;AAEA,QAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE;IAChC;AAEA;;;;;;;AAOG;AACI,IAAA,UAAU,CAAC,QAAoB,EAAA;AACpC,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC;IACtC;AACD;;;;"}
@@ -0,0 +1,18 @@
1
+ import type { RenderTexture } from '@/rendering/texture/RenderTexture';
2
+ import type { SamplerOptions } from '@/rendering/texture/Sampler';
3
+ import type { Texture } from '@/rendering/texture/Texture';
4
+ import type { BlendModes } from '@/rendering/types';
5
+ import type { UniformValue } from './Material';
6
+ /**
7
+ * Pipeline key from shader identity, blend mode, and sampler state.
8
+ * @internal
9
+ */
10
+ export declare const derivePipelineKey: (shaderId: number, blendMode: BlendModes, sampler: SamplerOptions | null) => number;
11
+ /**
12
+ * Bind key from material identity and the identities of every bound
13
+ * texture, whether declared in the `textures` map or carried as a
14
+ * texture-valued uniform. Texture entries are sorted before joining so the
15
+ * descriptor is independent of insertion order.
16
+ * @internal
17
+ */
18
+ export declare const deriveBindKey: (materialId: number, uniforms: Record<string, UniformValue>, textures: Record<string, Texture | RenderTexture>) => number;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @internal
3
+ *
4
+ * Stable key derivation for {@link Material}. Keys are interned from a
5
+ * normalized string descriptor, so identical material state always maps to
6
+ * the exact same integer (no hashing, no collisions), and distinct state
7
+ * maps to distinct integers. Descriptors are built from scalar fields in a
8
+ * fixed order and from sorted texture-binding entries — never from
9
+ * `JSON.stringify` over objects with unstable key order.
10
+ *
11
+ * Two key spaces:
12
+ * - {@link derivePipelineKey}: shader identity + blend + sampler state.
13
+ * Drives GPU pipeline/program reuse and material grouping. Independent of
14
+ * the owning material instance, so identically configured materials share
15
+ * a pipeline key.
16
+ * - {@link deriveBindKey}: material identity + bound texture identities.
17
+ * Drives bind-group/slot reuse; changes when a material swaps a texture.
18
+ */
19
+ const textureIds = new WeakMap();
20
+ let nextTextureId = 1;
21
+ const getTextureId = (texture) => {
22
+ const cached = textureIds.get(texture);
23
+ if (cached !== undefined) {
24
+ return cached;
25
+ }
26
+ const id = nextTextureId++;
27
+ textureIds.set(texture, id);
28
+ return id;
29
+ };
30
+ const pipelineKeyRegistry = new Map();
31
+ let nextPipelineKey = 1;
32
+ const bindKeyRegistry = new Map();
33
+ let nextBindKey = 1;
34
+ const intern = (registry, descriptor, allocate) => {
35
+ const cached = registry.get(descriptor);
36
+ if (cached !== undefined) {
37
+ return cached;
38
+ }
39
+ const key = allocate();
40
+ registry.set(descriptor, key);
41
+ return key;
42
+ };
43
+ const samplerDescriptor = (sampler) => {
44
+ if (sampler === null) {
45
+ return '-';
46
+ }
47
+ return [sampler.scaleMode, sampler.wrapMode, sampler.premultiplyAlpha ? 1 : 0, sampler.generateMipMap ? 1 : 0, sampler.flipY ? 1 : 0].join(':');
48
+ };
49
+ const isTextureBinding = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && !ArrayBuffer.isView(value);
50
+ /**
51
+ * Pipeline key from shader identity, blend mode, and sampler state.
52
+ * @internal
53
+ */
54
+ const derivePipelineKey = (shaderId, blendMode, sampler) => {
55
+ const descriptor = `${shaderId}|${blendMode}|${samplerDescriptor(sampler)}`;
56
+ return intern(pipelineKeyRegistry, descriptor, () => nextPipelineKey++);
57
+ };
58
+ /**
59
+ * Bind key from material identity and the identities of every bound
60
+ * texture, whether declared in the `textures` map or carried as a
61
+ * texture-valued uniform. Texture entries are sorted before joining so the
62
+ * descriptor is independent of insertion order.
63
+ * @internal
64
+ */
65
+ const deriveBindKey = (materialId, uniforms, textures) => {
66
+ const entries = [];
67
+ for (const name of Object.keys(textures)) {
68
+ entries.push(`t:${name}=${getTextureId(textures[name])}`);
69
+ }
70
+ for (const name of Object.keys(uniforms)) {
71
+ const value = uniforms[name];
72
+ if (isTextureBinding(value)) {
73
+ entries.push(`u:${name}=${getTextureId(value)}`);
74
+ }
75
+ }
76
+ entries.sort();
77
+ const descriptor = `${materialId}|${entries.join(',')}`;
78
+ return intern(bindKeyRegistry, descriptor, () => nextBindKey++);
79
+ };
80
+
81
+ export { deriveBindKey, derivePipelineKey };
82
+ //# sourceMappingURL=MaterialKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MaterialKey.js","sources":["../../../../../src/rendering/material/MaterialKey.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { MaterialOptions } from './Material';
2
+ import { Material } from './Material';
3
+ /**
4
+ * Material specialization for {@link Mesh} drawables.
5
+ *
6
+ * Carries the mesh contract conceptually: fixed vertex attribute locations
7
+ * (0 = position, 1 = texcoord, 2 = color), the auto-bound uniforms
8
+ * `u_projection`/`u_translation`/`u_tint`/`u_texture`, and the WGSL
9
+ * group(0)=mesh-uniforms / group(1)=texture / group(2)=user binding scheme.
10
+ * Renderer wiring is added in a later phase.
11
+ * @advanced
12
+ */
13
+ export declare class MeshMaterial extends Material {
14
+ readonly target = "mesh";
15
+ constructor(options: MaterialOptions);
16
+ }
@@ -0,0 +1,21 @@
1
+ import { Material } from './Material.js';
2
+
3
+ /**
4
+ * Material specialization for {@link Mesh} drawables.
5
+ *
6
+ * Carries the mesh contract conceptually: fixed vertex attribute locations
7
+ * (0 = position, 1 = texcoord, 2 = color), the auto-bound uniforms
8
+ * `u_projection`/`u_translation`/`u_tint`/`u_texture`, and the WGSL
9
+ * group(0)=mesh-uniforms / group(1)=texture / group(2)=user binding scheme.
10
+ * Renderer wiring is added in a later phase.
11
+ * @advanced
12
+ */
13
+ class MeshMaterial extends Material {
14
+ target = 'mesh';
15
+ constructor(options) {
16
+ super(options);
17
+ }
18
+ }
19
+
20
+ export { MeshMaterial };
21
+ //# sourceMappingURL=MeshMaterial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MeshMaterial.js","sources":["../../../../../src/rendering/material/MeshMaterial.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAGA;;;;;;;;;AASG;AACG,MAAO,YAAa,SAAQ,QAAQ,CAAA;IACxB,MAAM,GAAG,MAAM;AAE/B,IAAA,WAAA,CAAmB,OAAwB,EAAA;QACzC,KAAK,CAAC,OAAO,CAAC;IAChB;AACD;;;;"}
@@ -1,22 +1,12 @@
1
- import type { RenderTexture } from '@/rendering/texture/RenderTexture';
2
- import type { Texture } from '@/rendering/texture/Texture';
3
1
  /**
4
- * Uniform value passed to a custom mesh shader. Scalars and small tuples
5
- * auto-marshal to the appropriate `Float32Array`/`Int32Array` for the
6
- * backend's uniform call. `Texture`/`RenderTexture` values are bound to
7
- * texture slots starting at slot 1 — slot 0 is reserved for the mesh's
8
- * own `texture`.
9
- */
10
- export type MeshShaderUniformValue = number | readonly [number, number] | readonly [number, number, number] | readonly [number, number, number, number] | Float32Array | Int32Array | Texture | RenderTexture;
11
- /**
12
- * Construction options for {@link MeshShader}.
2
+ * Construction options for {@link ShaderSource}.
13
3
  *
14
4
  * At least one language must be supplied. Provide `glsl` for WebGL2,
15
- * `wgsl` for WebGPU, or both for backend-portable meshes. The shader
5
+ * `wgsl` for WebGPU, or both for backend-portable materials. The source
16
6
  * is compiled lazily on first use against the active backend; an
17
7
  * unsupported backend at draw time throws with a clear error.
18
8
  */
19
- export interface MeshShaderOptions {
9
+ export interface ShaderSourceOptions {
20
10
  /**
21
11
  * GLSL ES 3.00 sources for the WebGL2 backend. Both `vertex` and
22
12
  * `fragment` are required when `glsl` is supplied.
@@ -30,21 +20,21 @@ export interface MeshShaderOptions {
30
20
  * points live in the same source file (WGSL convention).
31
21
  */
32
22
  readonly wgsl?: string;
33
- /** Initial uniform values; mutate per frame via {@link MeshShader.uniforms}. */
34
- readonly uniforms?: Record<string, MeshShaderUniformValue>;
35
23
  }
36
24
  /**
37
- * Custom shader pair attached to a {@link Mesh}.
25
+ * Immutable shader source pair shared by {@link Material} instances.
38
26
  *
39
- * One `MeshShader` instance can be shared across many meshes; renderers
40
- * cache compiled programs/pipelines on the instance reference. Call
41
- * {@link destroy} when the shader is no longer needed to release the
42
- * cached GPU resources on every backend the shader was used on.
27
+ * `ShaderSource` owns only the GLSL/WGSL text and its stable identity;
28
+ * it carries no uniform/texture state (that lives on the {@link Material}).
29
+ * One `ShaderSource` can back many materials, and renderers key their
30
+ * compiled program/pipeline caches on the source identity exposed via
31
+ * {@link id}.
43
32
  *
44
33
  * # Vertex layout
45
34
  *
46
- * The vertex layout is fixed and shared with the default mesh shader,
47
- * so custom vertex shaders MUST pin the standard attribute locations:
35
+ * The vertex layout for the mesh path is fixed and shared with the default
36
+ * mesh material, so custom vertex shaders MUST pin the standard attribute
37
+ * locations:
48
38
  *
49
39
  * ## GLSL (location-qualified)
50
40
  *
@@ -66,16 +56,16 @@ export interface MeshShaderOptions {
66
56
  *
67
57
  * # Auto-bound uniforms
68
58
  *
69
- * The renderer auto-binds these when the shader declares them. Declared
70
- * but unused is fine; absent is fine too. Both backends carry the same
71
- * logical uniforms, only the binding scheme differs.
59
+ * Renderers auto-bind these when the source declares them. Declared but
60
+ * unused is fine; absent is fine too. Both backends carry the same logical
61
+ * uniforms, only the binding scheme differs.
72
62
  *
73
63
  * ## GLSL
74
64
  *
75
65
  * ```glsl
76
66
  * uniform mat3 u_projection; // active view's projection
77
- * uniform mat3 u_translation; // mesh's global transform
78
- * uniform vec4 u_tint; // mesh.tint as RGBA in 0..1
67
+ * uniform mat3 u_translation; // drawable's global transform
68
+ * uniform vec4 u_tint; // tint as RGBA in 0..1
79
69
  * uniform sampler2D u_texture; // bound to texture slot 0
80
70
  * ```
81
71
  *
@@ -96,8 +86,9 @@ export interface MeshShaderOptions {
96
86
  *
97
87
  * # User uniforms
98
88
  *
99
- * Anything in {@link uniforms} is set after the auto-binds. `Texture`/
100
- * `RenderTexture` values claim slots 1..N (slot 0 belongs to the mesh).
89
+ * Anything in {@link Material.uniforms} is set after the auto-binds.
90
+ * `Texture`/`RenderTexture` values claim slots 1..N (slot 0 belongs to the
91
+ * drawable's own texture).
101
92
  *
102
93
  * ## WGSL user-uniform contract
103
94
  *
@@ -109,15 +100,7 @@ export interface MeshShaderOptions {
109
100
  * in declaration order, alongside its sampler at `@binding(N+1)`.
110
101
  * @advanced
111
102
  */
112
- export declare class MeshShader {
113
- /**
114
- * Mutable user uniform values. Mutate between frames to drive animated
115
- * effects; the renderer reads from this map every draw.
116
- *
117
- * shader.uniforms.uTime = performance.now() / 1000;
118
- * shader.uniforms.uColor = [1, 0.5, 0, 1];
119
- */
120
- uniforms: Record<string, MeshShaderUniformValue>;
103
+ export declare class ShaderSource {
121
104
  /** GLSL source pair for the WebGL2 backend, or `null` if not provided. */
122
105
  readonly glsl: {
123
106
  readonly vertex: string;
@@ -125,14 +108,13 @@ export declare class MeshShader {
125
108
  } | null;
126
109
  /** WGSL source for the WebGPU backend, or `null` if not provided. */
127
110
  readonly wgsl: string | null;
128
- private readonly _disposeCallbacks;
129
- constructor(options: MeshShaderOptions);
111
+ private readonly _id;
112
+ constructor(options: ShaderSourceOptions);
130
113
  /**
131
- * Convenience setter equivalent to `shader.uniforms[name] = value`.
132
- * Provided for symmetry with engine APIs that prefer explicit methods
133
- * over property mutation.
114
+ * Stable per-instance identity. Identical `id` same compiled program/
115
+ * pipeline can be reused. Monotonic across the session; never reused.
134
116
  */
135
- setUniform(name: string, value: MeshShaderUniformValue): void;
117
+ get id(): number;
136
118
  /**
137
119
  * Reflect declared uniforms from each language's source. Returns a per-
138
120
  * language map of uniform-name → declared type, parsed from the shader
@@ -142,8 +124,9 @@ export declare class MeshShader {
142
124
  *
143
125
  * Reflection is best-effort and intended for CI drift-checks and editor
144
126
  * tooling, not for runtime uniform binding decisions. The renderers do
145
- * NOT consult this map; they bind uniforms by name from {@link uniforms}
146
- * and let the underlying API resolve declared-but-unused entries.
127
+ * NOT consult this map; they bind uniforms by name from
128
+ * {@link Material.uniforms} and let the underlying API resolve declared-
129
+ * but-unused entries.
147
130
  */
148
131
  getDeclaredUniforms(): {
149
132
  glsl: Record<string, string>;
@@ -165,20 +148,4 @@ export declare class MeshShader {
165
148
  onlyInGlsl: readonly string[];
166
149
  onlyInWgsl: readonly string[];
167
150
  };
168
- /**
169
- * Release GPU resources cached against this `MeshShader` on every
170
- * backend that has compiled it. Safe to call multiple times. After
171
- * destroy, the shader can still be re-used — renderers will recompile
172
- * on next draw — but typical usage is to drop the reference.
173
- */
174
- destroy(): void;
175
- /**
176
- * Internal hook for renderers to register a per-shader-instance cleanup
177
- * callback (release compiled program, pipeline, or bind groups). The
178
- * callback fires on {@link destroy}; renderers MUST also tolerate the
179
- * shader being garbage-collected without destroy ever being called.
180
- *
181
- * @internal
182
- */
183
- _onDispose(callback: () => void): void;
184
151
  }