@flighthq/displayobject-wgpu 0.1.0 → 0.2.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 (55) hide show
  1. package/dist/enableWgpuColorAdjustmentGuards.d.ts +4 -0
  2. package/dist/enableWgpuColorAdjustmentGuards.d.ts.map +1 -0
  3. package/dist/enableWgpuColorAdjustmentGuards.js +21 -0
  4. package/dist/enableWgpuColorAdjustmentGuards.js.map +1 -0
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/wgpuBitmap.d.ts.map +1 -1
  10. package/dist/wgpuBitmap.js +2 -1
  11. package/dist/wgpuBitmap.js.map +1 -1
  12. package/dist/wgpuCache.d.ts.map +1 -1
  13. package/dist/wgpuCache.js +4 -1
  14. package/dist/wgpuCache.js.map +1 -1
  15. package/dist/wgpuColorAdjustment.d.ts +3 -0
  16. package/dist/wgpuColorAdjustment.d.ts.map +1 -0
  17. package/dist/wgpuColorAdjustment.js +198 -0
  18. package/dist/wgpuColorAdjustment.js.map +1 -0
  19. package/dist/wgpuQuadBatch.d.ts.map +1 -1
  20. package/dist/wgpuQuadBatch.js +8 -4
  21. package/dist/wgpuQuadBatch.js.map +1 -1
  22. package/dist/wgpuRichText.js +1 -0
  23. package/dist/wgpuRichText.js.map +1 -1
  24. package/dist/wgpuShape.d.ts.map +1 -1
  25. package/dist/wgpuShape.js +2 -1
  26. package/dist/wgpuShape.js.map +1 -1
  27. package/dist/wgpuSpriteBatch.d.ts +2 -1
  28. package/dist/wgpuSpriteBatch.d.ts.map +1 -1
  29. package/dist/wgpuSpriteBatch.js +31 -9
  30. package/dist/wgpuSpriteBatch.js.map +1 -1
  31. package/dist/wgpuSpriteRenderer.d.ts.map +1 -1
  32. package/dist/wgpuSpriteRenderer.js +2 -1
  33. package/dist/wgpuSpriteRenderer.js.map +1 -1
  34. package/dist/wgpuTextLabel.d.ts.map +1 -1
  35. package/dist/wgpuTextLabel.js +3 -1
  36. package/dist/wgpuTextLabel.js.map +1 -1
  37. package/dist/wgpuTilemap.d.ts.map +1 -1
  38. package/dist/wgpuTilemap.js +8 -4
  39. package/dist/wgpuTilemap.js.map +1 -1
  40. package/package.json +22 -15
  41. package/src/enableWgpuColorAdjustmentGuards.test.ts +82 -0
  42. package/src/wgpuColorAdjustment.test.ts +119 -0
  43. package/src/wgpuParticleEmitter.test.ts +1 -1
  44. package/src/wgpuSpriteBatch.test.ts +65 -1
  45. package/src/wgpuVelocity.test.ts +2 -1
  46. package/dist/wgpuColorTransformMaterial.d.ts +0 -5
  47. package/dist/wgpuColorTransformMaterial.d.ts.map +0 -1
  48. package/dist/wgpuColorTransformMaterial.js +0 -97
  49. package/dist/wgpuColorTransformMaterial.js.map +0 -1
  50. package/dist/wgpuMaterials.d.ts +0 -15
  51. package/dist/wgpuMaterials.d.ts.map +0 -1
  52. package/dist/wgpuMaterials.js +0 -34
  53. package/dist/wgpuMaterials.js.map +0 -1
  54. package/src/wgpuColorTransformMaterial.test.ts +0 -62
  55. package/src/wgpuMaterials.test.ts +0 -44
@@ -1,8 +1,9 @@
1
1
  import { renderWgpuBackground, submitWgpuRenderPass } from '@flighthq/render-wgpu';
2
2
  import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
3
3
  import { createWgpuRenderStateForTest, installWgpuMock } from '@flighthq/render-wgpu';
4
- import type { Material } from '@flighthq/types';
4
+ import type { ColorTransform, Material } from '@flighthq/types';
5
5
 
6
+ import { enableWgpuColorAdjustment } from './wgpuColorAdjustment';
6
7
  import { defaultWgpuMaterialRenderer } from './wgpuDefaultMaterial';
7
8
  import {
8
9
  ensureWgpuQuadBatchResources,
@@ -11,6 +12,7 @@ import {
11
12
  getWgpuQuadBatchPreludeWGSL,
12
13
  packWgpuSpriteBatchMaterialInstance,
13
14
  prepareWgpuSpriteBatchWrite,
15
+ recordWgpuSpriteBatchColorTransform,
14
16
  resetWgpuSpriteBatchBufferPool,
15
17
  } from './wgpuSpriteBatch';
16
18
 
@@ -22,6 +24,31 @@ function makeMaterial(): Material {
22
24
  return { kind: 'TestMaterial' } as Material;
23
25
  }
24
26
 
27
+ function ct(
28
+ redMultiplier = 1,
29
+ greenMultiplier = 1,
30
+ blueMultiplier = 1,
31
+ alphaMultiplier = 1,
32
+ redOffset = 0,
33
+ greenOffset = 0,
34
+ blueOffset = 0,
35
+ alphaOffset = 0,
36
+ ): ColorTransform {
37
+ return {
38
+ redMultiplier,
39
+ greenMultiplier,
40
+ blueMultiplier,
41
+ alphaMultiplier,
42
+ redOffset,
43
+ greenOffset,
44
+ blueOffset,
45
+ alphaOffset,
46
+ } as ColorTransform;
47
+ }
48
+
49
+ const CT_MODE_NONE = 0;
50
+ const CT_MODE_UNIFORM = 1;
51
+
25
52
  describe('ensureWgpuQuadBatchResources', () => {
26
53
  it('returns resources with bind group layouts and a pipelines WeakMap', async () => {
27
54
  const state = await createWgpuRenderStateForTest();
@@ -161,6 +188,43 @@ describe('prepareWgpuSpriteBatchWrite', () => {
161
188
  });
162
189
  });
163
190
 
191
+ describe('recordWgpuSpriteBatchColorTransform', () => {
192
+ it('skips the tint and records no fold state when color adjustment is not enabled', async () => {
193
+ const state = await createWgpuRenderStateForTest();
194
+ const runtime = getWgpuRenderStateRuntime(state);
195
+ recordWgpuSpriteBatchColorTransform(state, ct(0.5), 0);
196
+ expect(runtime.spriteBatchColorTransformMode ?? CT_MODE_NONE).toBe(CT_MODE_NONE);
197
+ });
198
+
199
+ it('is a no-op for an untinted instance whether or not the fold is enabled', async () => {
200
+ const state = await createWgpuRenderStateForTest();
201
+ const runtime = getWgpuRenderStateRuntime(state);
202
+ expect(() => recordWgpuSpriteBatchColorTransform(state, null, 0)).not.toThrow();
203
+ expect(runtime.spriteBatchColorTransformMode ?? CT_MODE_NONE).toBe(CT_MODE_NONE);
204
+ });
205
+
206
+ it('delegates to the installed fold when color adjustment is enabled', async () => {
207
+ const state = await createWgpuRenderStateForTest();
208
+ const runtime = getWgpuRenderStateRuntime(state);
209
+ enableWgpuColorAdjustment(state);
210
+ recordWgpuSpriteBatchColorTransform(state, ct(0.5), 0);
211
+ expect(runtime.spriteBatchColorTransformMode).toBe(CT_MODE_UNIFORM);
212
+ });
213
+
214
+ it('an untinted batch on flush uses the lean material module (no fold)', async () => {
215
+ const state = await createWgpuRenderStateForTest();
216
+ enableWgpuColorAdjustment(state);
217
+ renderWgpuBackground(state);
218
+ const runtime = getWgpuRenderStateRuntime(state);
219
+ const tex = document.createElement('img');
220
+ prepareWgpuSpriteBatchWrite(state, tex, null, null, defaultWgpuMaterialRenderer, 1);
221
+ recordWgpuSpriteBatchColorTransform(state, null, 0);
222
+ runtime.spriteBatchCount = 1;
223
+ expect(() => flushWgpuSpriteBatch(state)).not.toThrow();
224
+ submitWgpuRenderPass(state);
225
+ });
226
+ });
227
+
164
228
  describe('resetWgpuSpriteBatchBufferPool', () => {
165
229
  it('rewinds the pool cursor so slots are reclaimed next frame', async () => {
166
230
  const state = await createWgpuRenderStateForTest();
@@ -1,7 +1,8 @@
1
1
  import { createDisplayObject } from '@flighthq/displayobject';
2
+ import { createParticleEmitter, reserveParticleEmitter } from '@flighthq/particleemitter';
2
3
  import { renderWgpuBackground } from '@flighthq/render-wgpu';
3
4
  import { createWgpuRenderStateForTest, installWgpuMock } from '@flighthq/render-wgpu';
4
- import { createParticleEmitter, createQuadBatch, getQuadBatchRuntime, reserveParticleEmitter } from '@flighthq/sprite';
5
+ import { createQuadBatch, getQuadBatchRuntime } from '@flighthq/sprite';
5
6
  import type { QuadBatchRuntime, TextureAtlas, TextureAtlasRegion } from '@flighthq/types';
6
7
  import { QuadBatchKind } from '@flighthq/types';
7
8
  import { beginVelocityFrame, contributeVelocity, createVelocityField } from '@flighthq/velocity';
@@ -1,5 +0,0 @@
1
- import type { WgpuMaterialRenderer, WgpuRenderState } from '@flighthq/types';
2
- export declare function registerWgpuColorTransformMaterials(state: WgpuRenderState): void;
3
- export declare const colorTransformWgpuMaterialRenderer: WgpuMaterialRenderer;
4
- export declare const uniformColorTransformWgpuMaterialRenderer: WgpuMaterialRenderer;
5
- //# sourceMappingURL=wgpuColorTransformMaterial.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wgpuColorTransformMaterial.d.ts","sourceRoot":"","sources":["../src/wgpuColorTransformMaterial.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,oBAAoB,EACpB,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAOzB,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAGhF;AAGD,eAAO,MAAM,kCAAkC,EAAE,oBAMhD,CAAC;AAKF,eAAO,MAAM,yCAAyC,EAAE,oBAOvD,CAAC"}
@@ -1,97 +0,0 @@
1
- import { registerWgpuMaterialRenderer } from '@flighthq/render-wgpu';
2
- import { ColorTransformMaterialKind, UniformColorTransformMaterialKind } from '@flighthq/types';
3
- import { getWgpuQuadBatchPreludeWGSL } from './wgpuSpriteBatch';
4
- const COLOR_TRANSFORM_INSTANCE_FLOATS = 8;
5
- export function registerWgpuColorTransformMaterials(state) {
6
- registerWgpuMaterialRenderer(state, UniformColorTransformMaterialKind, uniformColorTransformWgpuMaterialRenderer);
7
- registerWgpuMaterialRenderer(state, ColorTransformMaterialKind, colorTransformWgpuMaterialRenderer);
8
- }
9
- // Per-instance color transform: packs each node's materialData color transform into the instance.
10
- export const colorTransformWgpuMaterialRenderer = {
11
- instanceFloatCount: COLOR_TRANSFORM_INSTANCE_FLOATS,
12
- getShaderModule: getColorTransformShaderModule,
13
- packInstance(_state, _material, materialData, out, offset) {
14
- packWgpuColorTransform(out, offset, materialData);
15
- },
16
- };
17
- // Per-batch color transform: packs the material's own color transform into every instance. Wgpu
18
- // carries color transform per-instance, so a "uniform" color transform is the same value on each
19
- // instance of the batch — it shares the per-instance shader module.
20
- export const uniformColorTransformWgpuMaterialRenderer = {
21
- instanceFloatCount: COLOR_TRANSFORM_INSTANCE_FLOATS,
22
- getShaderModule: getColorTransformShaderModule,
23
- packInstance(_state, material, _materialData, out, offset) {
24
- const ct = material !== null ? material.colorTransform : null;
25
- packWgpuColorTransform(out, offset, ct);
26
- },
27
- };
28
- function getColorTransformShaderModule(state) {
29
- const cached = _modules.get(state.device);
30
- if (cached !== undefined)
31
- return cached;
32
- const module = state.device.createShaderModule({
33
- code: getWgpuQuadBatchPreludeWGSL() + COLOR_TRANSFORM_MATERIAL_WGSL,
34
- });
35
- _modules.set(state.device, module);
36
- return module;
37
- }
38
- function packWgpuColorTransform(out, offset, ct) {
39
- if (ct !== null) {
40
- out[offset] = ct.redMultiplier;
41
- out[offset + 1] = ct.greenMultiplier;
42
- out[offset + 2] = ct.blueMultiplier;
43
- out[offset + 3] = ct.alphaMultiplier;
44
- out[offset + 4] = ct.redOffset / 255;
45
- out[offset + 5] = ct.greenOffset / 255;
46
- out[offset + 6] = ct.blueOffset / 255;
47
- out[offset + 7] = ct.alphaOffset / 255;
48
- }
49
- else {
50
- out[offset] = 1;
51
- out[offset + 1] = 1;
52
- out[offset + 2] = 1;
53
- out[offset + 3] = 1;
54
- out[offset + 4] = 0;
55
- out[offset + 5] = 0;
56
- out[offset + 6] = 0;
57
- out[offset + 7] = 0;
58
- }
59
- }
60
- // Reads 8 per-instance floats (color multiplier rgba, color offset rgba) from the material storage
61
- // buffer at @group(3), applies them in unpremultiplied space. The base path never sees these — color
62
- // transform is contained entirely in this module and its packInstance.
63
- const COLOR_TRANSFORM_MATERIAL_WGSL = /* wgsl */ `
64
- @group(3) @binding(0) var<storage, read> ctData : array<f32>;
65
-
66
- struct VertexOut {
67
- @builtin(position) position : vec4f,
68
- @location(0) uv : vec2f,
69
- @location(1) alpha : f32,
70
- @location(2) ctMult : vec4f,
71
- @location(3) ctOff : vec4f,
72
- }
73
-
74
- @vertex
75
- fn vs_main(@builtin(vertex_index) vi : u32, @builtin(instance_index) ii : u32) -> VertexOut {
76
- let bv = quadBaseVertex(vi, ii);
77
- let b = ii * 8u;
78
- let ctMult = vec4f(ctData[b + 0u], ctData[b + 1u], ctData[b + 2u], ctData[b + 3u]);
79
- let ctOff = vec4f(ctData[b + 4u], ctData[b + 5u], ctData[b + 6u], ctData[b + 7u]);
80
- return VertexOut(bv.position, bv.uv, bv.alpha, ctMult, ctOff);
81
- }
82
-
83
- @fragment
84
- fn fs_main(in : VertexOut) -> @location(0) vec4f {
85
- var color = textureSample(tex, smp, in.uv);
86
- if (color.a <= 0.0) { discard; }
87
- color = color * clamp(in.alpha, 0.0, 1.0);
88
- if (color.a > 0.0) {
89
- color = vec4f(color.rgb / color.a, color.a);
90
- color = clamp(color * in.ctMult + in.ctOff, vec4f(0.0), vec4f(1.0));
91
- color = vec4f(color.rgb * color.a, color.a);
92
- }
93
- return color;
94
- }
95
- `;
96
- const _modules = new WeakMap();
97
- //# sourceMappingURL=wgpuColorTransformMaterial.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wgpuColorTransformMaterial.js","sourceRoot":"","sources":["../src/wgpuColorTransformMaterial.ts"],"names":[],"mappings":"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"}
@@ -1,15 +0,0 @@
1
- import type { BlendMode, WgpuRenderState } from '@flighthq/types';
2
- export declare function drawWgpuColorTransformBitmap(state: WgpuRenderState, renderProxy: {
3
- alpha: number;
4
- transform2D: {
5
- a: number;
6
- b: number;
7
- c: number;
8
- d: number;
9
- tx: number;
10
- ty: number;
11
- };
12
- blendMode: BlendMode | null;
13
- }, imageSource: CanvasImageSource, x0: number, y0: number, x1: number, y1: number, u0: number, v0: number, u1: number, v1: number): void;
14
- export declare function registerWgpuColorTransformShader(state: WgpuRenderState): void;
15
- //# sourceMappingURL=wgpuMaterials.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wgpuMaterials.d.ts","sourceRoot":"","sources":["../src/wgpuMaterials.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAoB,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAOpF,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACpF,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CAC7B,EACD,WAAW,EAAE,iBAAiB,EAC9B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CASN;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAkB7E"}
@@ -1,34 +0,0 @@
1
- import { bindWgpuTexture, getWgpuRenderStateRuntime, submitWgpuQuadDraw, writeWgpuQuadUniforms, } from '@flighthq/render-wgpu';
2
- // The color transform shader is the same WGSL as the bitmap shader since color transform
3
- // support is built directly into the standard WGSL uniform struct (hasColorTransform flag).
4
- // Registering a color transform "shader" simply sets the useColorTransform flag on nodes
5
- // that have a color transform, which the existing uniform upload already handles.
6
- export function drawWgpuColorTransformBitmap(state, renderProxy, imageSource, x0, y0, x1, y1, u0, v0, u1, v1) {
7
- const runtime = getWgpuRenderStateRuntime(state);
8
- const pass = runtime.renderPass;
9
- if (pass === null)
10
- return;
11
- state.applyBlendMode?.(state, renderProxy.blendMode);
12
- const textureEntry = bindWgpuTexture(state, imageSource);
13
- const uniformOffset = writeWgpuQuadUniforms(state, renderProxy, null, x0, y0, x1, y1, u0, v0, u1, v1);
14
- submitWgpuQuadDraw(state, uniformOffset, textureEntry.bindGroup);
15
- }
16
- export function registerWgpuColorTransformShader(state) {
17
- const runtime = getWgpuRenderStateRuntime(state);
18
- if (runtime.colorTransformBitmapShader !== undefined)
19
- return;
20
- // The color transform shader is the default pipeline — color transform data is
21
- // already baked into the uniform buffer and handled by the WGSL fragment shader.
22
- // This function exists for API symmetry with registerGlColorTransformShader.
23
- const shader = {
24
- pipeline: null, // pipeline is resolved dynamically via getActiveWgpuPipeline
25
- bind(bindState, renderProxy) {
26
- // bind() is called by the user when customising draw; for color transform the default
27
- // pipeline handles everything automatically via the uniform buffer.
28
- void bindState;
29
- void renderProxy;
30
- },
31
- };
32
- runtime.colorTransformBitmapShader = shader;
33
- }
34
- //# sourceMappingURL=wgpuMaterials.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wgpuMaterials.js","sourceRoot":"","sources":["../src/wgpuMaterials.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAG/B,yFAAyF;AACzF,4FAA4F;AAC5F,yFAAyF;AACzF,kFAAkF;AAElF,MAAM,UAAU,4BAA4B,CAC1C,KAAsB,EACtB,WAIC,EACD,WAA8B,EAC9B,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU;IAEV,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;IAChC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAE1B,KAAK,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACtG,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,KAAsB;IACrE,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,0BAA0B,KAAK,SAAS;QAAE,OAAO;IAE7D,+EAA+E;IAC/E,iFAAiF;IACjF,6EAA6E;IAC7E,MAAM,MAAM,GAAqB;QAC/B,QAAQ,EAAE,IAAa,EAAE,6DAA6D;QACtF,IAAI,CAAC,SAA0B,EAAE,WAA8B;YAC7D,sFAAsF;YACtF,oEAAoE;YACpE,KAAK,SAAS,CAAC;YACf,KAAK,WAAW,CAAC;QACnB,CAAC;KACF,CAAC;IAEF,OAAO,CAAC,0BAA0B,GAAG,MAAM,CAAC;AAC9C,CAAC"}
@@ -1,62 +0,0 @@
1
- import { getWgpuMaterialRenderer } from '@flighthq/render-wgpu';
2
- import { createWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
3
- import type { WgpuRenderState } from '@flighthq/types';
4
- import { ColorTransformMaterialKind, EntityRuntimeKey, UniformColorTransformMaterialKind } from '@flighthq/types';
5
-
6
- import {
7
- colorTransformWgpuMaterialRenderer,
8
- registerWgpuColorTransformMaterials,
9
- uniformColorTransformWgpuMaterialRenderer,
10
- } from './wgpuColorTransformMaterial';
11
-
12
- function makeColorTransform(redMultiplier: number) {
13
- return {
14
- redMultiplier,
15
- greenMultiplier: 1,
16
- blueMultiplier: 1,
17
- alphaMultiplier: 1,
18
- redOffset: 0,
19
- greenOffset: 0,
20
- blueOffset: 0,
21
- alphaOffset: 0,
22
- };
23
- }
24
-
25
- describe('colorTransformWgpuMaterialRenderer', () => {
26
- it('declares 8 per-instance floats', () => {
27
- expect(colorTransformWgpuMaterialRenderer.instanceFloatCount).toBe(8);
28
- });
29
-
30
- it('packs the materialData color transform', () => {
31
- const out = new Float32Array(8);
32
- colorTransformWgpuMaterialRenderer.packInstance!(null as never, null, makeColorTransform(0.5) as never, out, 0);
33
- expect(out[0]).toBe(0.5);
34
- });
35
-
36
- it('packs identity when materialData is null', () => {
37
- const out = new Float32Array(8);
38
- colorTransformWgpuMaterialRenderer.packInstance!(null as never, null, null, out, 0);
39
- expect(Array.from(out)).toEqual([1, 1, 1, 1, 0, 0, 0, 0]);
40
- });
41
- });
42
-
43
- describe('registerWgpuColorTransformMaterials', () => {
44
- it('registers both color transform material renderers', () => {
45
- const state = {} as WgpuRenderState;
46
- state[EntityRuntimeKey] = createWgpuRenderStateRuntime();
47
- registerWgpuColorTransformMaterials(state);
48
- expect(getWgpuMaterialRenderer(state, UniformColorTransformMaterialKind)).toBe(
49
- uniformColorTransformWgpuMaterialRenderer,
50
- );
51
- expect(getWgpuMaterialRenderer(state, ColorTransformMaterialKind)).toBe(colorTransformWgpuMaterialRenderer);
52
- });
53
- });
54
-
55
- describe('uniformColorTransformWgpuMaterialRenderer', () => {
56
- it('packs the material color transform onto the instance', () => {
57
- const out = new Float32Array(8);
58
- const material = { kind: UniformColorTransformMaterialKind, colorTransform: makeColorTransform(0.5) } as never;
59
- uniformColorTransformWgpuMaterialRenderer.packInstance!(null as never, material, null, out, 0);
60
- expect(out[0]).toBe(0.5);
61
- });
62
- });
@@ -1,44 +0,0 @@
1
- import { createBitmap } from '@flighthq/displayobject';
2
- import { getOrCreateRenderProxy2D, prepareDisplayObjectRender } from '@flighthq/render';
3
- import { renderWgpuBackground, submitWgpuRenderPass } from '@flighthq/render-wgpu';
4
- import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
5
- import { createWgpuRenderStateForTest, installWgpuMock } from '@flighthq/render-wgpu';
6
-
7
- import { drawWgpuColorTransformBitmap, registerWgpuColorTransformShader } from './wgpuMaterials';
8
-
9
- beforeAll(() => {
10
- installWgpuMock();
11
- });
12
-
13
- describe('drawWgpuColorTransformBitmap', () => {
14
- it('does not throw when render pass is open', async () => {
15
- const state = await createWgpuRenderStateForTest();
16
- renderWgpuBackground(state);
17
- const canvas = document.createElement('canvas');
18
- canvas.width = 4;
19
- canvas.height = 4;
20
- const fakeRenderProxy = {
21
- alpha: 1,
22
- useColorTransform: false,
23
- colorTransform: null,
24
- transform2D: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 },
25
- blendMode: null,
26
- };
27
- expect(() => drawWgpuColorTransformBitmap(state, fakeRenderProxy, canvas, 0, 0, 4, 4, 0, 0, 1, 1)).not.toThrow();
28
- submitWgpuRenderPass(state);
29
- });
30
- });
31
-
32
- describe('registerWgpuColorTransformShader', () => {
33
- it('registers the color transform shader on the state', async () => {
34
- const state = await createWgpuRenderStateForTest();
35
- registerWgpuColorTransformShader(state);
36
- expect(getWgpuRenderStateRuntime(state).colorTransformBitmapShader).toBeDefined();
37
- });
38
-
39
- it('is idempotent — calling twice does not throw', async () => {
40
- const state = await createWgpuRenderStateForTest();
41
- registerWgpuColorTransformShader(state);
42
- expect(() => registerWgpuColorTransformShader(state)).not.toThrow();
43
- });
44
- });