perf(web): share card texture via shader UV transform
Move the card sprite repeat/offset out of per-card texture clones and into a uniform injected into the material shader. Cards now share the deck sheet (one GPU upload), the shader, and the geometry, with only per-card material uniforms differing, so navigating a deck no longer re-uploads the sheet on every step.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import * as THREE from 'three';
|
||||
import { applyMapTransform } from './cardMaterial';
|
||||
|
||||
describe('applyMapTransform', () => {
|
||||
it('injects the repeat/offset uniforms and UV transform into the shader', () => {
|
||||
const mat = new THREE.MeshStandardMaterial();
|
||||
applyMapTransform(mat, new THREE.Vector2(0.5, 0.25), new THREE.Vector2(0.1, 0.2));
|
||||
|
||||
expect(mat.onBeforeCompile).toBeTypeOf('function');
|
||||
|
||||
const shader = {
|
||||
uniforms: {} as Record<string, { value: unknown }>,
|
||||
vertexShader: '#include <uv_vertex>\nvoid main() {}',
|
||||
};
|
||||
mat.onBeforeCompile!(shader as never, {} as never);
|
||||
|
||||
// Uniforms are copied, so the caller's vectors stay reusable.
|
||||
expect(shader.uniforms.uMapRepeat!.value).toEqual(new THREE.Vector2(0.5, 0.25));
|
||||
expect(shader.uniforms.uMapOffset!.value).toEqual(new THREE.Vector2(0.1, 0.2));
|
||||
// The override is injected right after the chunk include, which stays in
|
||||
// place (it declares `vMapUv`/`uv`).
|
||||
expect(shader.vertexShader).toContain('#include <uv_vertex>\n\tvMapUv = uv * uMapRepeat + uMapOffset;');
|
||||
});
|
||||
|
||||
it('copies the vectors so later mutation of the inputs has no effect', () => {
|
||||
const mat = new THREE.MeshStandardMaterial();
|
||||
const repeat = new THREE.Vector2(1, 1);
|
||||
const offset = new THREE.Vector2(0, 0);
|
||||
applyMapTransform(mat, repeat, offset);
|
||||
|
||||
repeat.set(9, 9);
|
||||
offset.set(9, 9);
|
||||
|
||||
const shader = { uniforms: {} as Record<string, { value: unknown }>, vertexShader: '' };
|
||||
mat.onBeforeCompile!(shader as never, {} as never);
|
||||
expect(shader.uniforms.uMapRepeat!.value).toEqual(new THREE.Vector2(1, 1));
|
||||
expect(shader.uniforms.uMapOffset!.value).toEqual(new THREE.Vector2(0, 0));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user