From 0e9d7381fdf2f79d22003c9cf07c742e2a3d2a07 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Thu, 13 Jun 2024 15:57:46 +0200 Subject: [PATCH 1/2] feat(engine): ShaderModule.getBindings() --- modules/engine/src/model/model.ts | 1 + modules/engine/src/shader-inputs.ts | 6 ++-- modules/engine/test/shader-inputs.spec.ts | 30 +++++++++++++++++++ .../src/lib/shader-module/shader-module.ts | 4 ++- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/modules/engine/src/model/model.ts b/modules/engine/src/model/model.ts index eca6b9e573..9b2eed3d7d 100644 --- a/modules/engine/src/model/model.ts +++ b/modules/engine/src/model/model.ts @@ -505,6 +505,7 @@ export class Model { /** Update uniform buffers from the model's shader inputs */ updateShaderInputs(): void { this._uniformStore.setUniforms(this.shaderInputs.getUniformValues()); + this.setBindings(this.shaderInputs.getBindings()); // TODO - this is already tracked through buffer/texture update times? this.setNeedsRedraw('shaderInputs'); } diff --git a/modules/engine/src/shader-inputs.ts b/modules/engine/src/shader-inputs.ts index 6298fde90a..0e4c91cf2e 100644 --- a/modules/engine/src/shader-inputs.ts +++ b/modules/engine/src/shader-inputs.ts @@ -26,6 +26,7 @@ export type ShaderModuleInputs< type: 'texture' | 'sampler' | 'uniforms'; } >; + getBindings?: (settings: Partial, prevBindings?: BindingsT) => BindingsT; uniformTypes?: any; }; @@ -112,9 +113,8 @@ export class ShaderInputs< // console.log(`setProps(${String(moduleName)}`, moduleName, this.moduleUniforms[moduleName]) - // TODO - Get Module bindings - // const bindings = module.getBindings?.(moduleProps); - // this.moduleUniforms[moduleName] = bindings; + const bindings = module.getBindings?.(moduleProps); + this.moduleBindings[moduleName] = bindings; } } diff --git a/modules/engine/test/shader-inputs.spec.ts b/modules/engine/test/shader-inputs.spec.ts index 21a8cdebda..6c6af5f881 100644 --- a/modules/engine/test/shader-inputs.spec.ts +++ b/modules/engine/test/shader-inputs.spec.ts @@ -7,6 +7,7 @@ import {picking} from '../../shadertools/src/index'; // import {_ShaderInputs as ShaderInputs} from '@luma.gl/engine'; import {ShaderInputs} from '../src/shader-inputs'; import {ShaderModule} from '@luma.gl/shadertools'; +import {Texture} from '@luma.gl/core'; test('ShaderInputs#picking', t => { const shaderInputsUntyped = new ShaderInputs({picking}); @@ -92,3 +93,32 @@ test('ShaderInputs#dependencies', t => { t.end(); }); + +test('ShaderInputs#bindings', t => { + type CustomProps = {color: number[]; colorTexture: Texture}; + const custom: ShaderModule = { + name: 'custom', + uniformTypes: {color: 'vec3'}, + uniformPropTypes: {color: {value: [0, 0, 0]}}, + getUniforms: ({color}) => ({color}), + getBindings: ({colorTexture}) => ({colorTexture}) + }; + + const shaderInputs = new ShaderInputs<{ + custom: CustomProps; + }>({custom}); + + const MOCK_TEXTURE = 'MOCK_TEXTURE' as unknown as Texture; + shaderInputs.setProps({ + custom: {color: [255, 0, 0], colorTexture: MOCK_TEXTURE} + }); + t.deepEqual(shaderInputs.moduleUniforms.custom.color, [255, 0, 0], 'custom color updated'); + t.equal(shaderInputs.moduleBindings.custom.colorTexture, MOCK_TEXTURE, 'colorTexture updated'); + + const uniformValues = shaderInputs.getUniformValues(); + const bindings = shaderInputs.getBindings(); + t.deepEqual(uniformValues, {custom: {color: [255, 0, 0]}}, 'uniformValues correct'); + t.deepEqual(bindings, {colorTexture: 'MOCK_TEXTURE'}, 'bindings correct'); + + t.end(); +}); diff --git a/modules/shadertools/src/lib/shader-module/shader-module.ts b/modules/shadertools/src/lib/shader-module/shader-module.ts index 77ea2ff7c6..1f1167238c 100644 --- a/modules/shadertools/src/lib/shader-module/shader-module.ts +++ b/modules/shadertools/src/lib/shader-module/shader-module.ts @@ -5,6 +5,7 @@ import {NumberArray} from '@math.gl/types'; import {UniformFormat} from '../../types'; import {PropType} from '../filters/prop-types'; +import {Sampler, Texture} from '@luma.gl/core'; export type UniformValue = number | boolean | Readonly; // Float32Array> | Readonly | Readonly | Readonly; @@ -19,7 +20,7 @@ export type UniformInfo = { export type ShaderModule< PropsT extends Record = Record, UniformsT extends Record = Record, - BindingsT extends Record = {} + BindingsT extends Record = {} > = { /** Used for type inference not for values */ props?: Required; @@ -43,6 +44,7 @@ export type ShaderModule< /** uniform buffers, textures, samplers, storage, ... */ bindings?: Record; + getBindings?: (settings?: any, prevBindings?: any) => Record; defines?: Record; /** Injections */ From 320c12a4e60a7d3f23fa19a06f84813643c608f2 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Wed, 19 Jun 2024 17:25:30 +0200 Subject: [PATCH 2/2] splitUniformsAndBindings --- modules/engine/src/shader-inputs.ts | 12 ++++++------ modules/engine/test/shader-inputs.spec.ts | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/engine/src/shader-inputs.ts b/modules/engine/src/shader-inputs.ts index 0e4c91cf2e..b8ab5bbb16 100644 --- a/modules/engine/src/shader-inputs.ts +++ b/modules/engine/src/shader-inputs.ts @@ -3,7 +3,7 @@ // Copyright (c) vis.gl contributors import type {UniformValue, Texture, Sampler} from '@luma.gl/core'; -import {log} from '@luma.gl/core'; +import {log, splitUniformsAndBindings} from '@luma.gl/core'; // import type {ShaderUniformType, UniformValue, UniformFormat, UniformInfoDevice, Texture, Sampler} from '@luma.gl/core'; import {_resolveModules, ShaderModuleInstance} from '@luma.gl/shadertools'; @@ -26,7 +26,6 @@ export type ShaderModuleInputs< type: 'texture' | 'sampler' | 'uniforms'; } >; - getBindings?: (settings: Partial, prevBindings?: BindingsT) => BindingsT; uniformTypes?: any; }; @@ -105,16 +104,17 @@ export class ShaderInputs< } const oldUniforms = this.moduleUniforms[moduleName]; - const uniforms = + const oldBindings = this.moduleBindings[moduleName]; + const uniformsAndBindings = module.getUniforms?.(moduleProps, this.moduleUniforms[moduleName]) || (moduleProps as any); + + const {uniforms, bindings} = splitUniformsAndBindings(uniformsAndBindings); // console.error(uniforms) this.moduleUniforms[moduleName] = {...oldUniforms, ...uniforms}; + this.moduleBindings[moduleName] = {...oldBindings, ...bindings}; // this.moduleUniformsChanged ||= moduleName; // console.log(`setProps(${String(moduleName)}`, moduleName, this.moduleUniforms[moduleName]) - - const bindings = module.getBindings?.(moduleProps); - this.moduleBindings[moduleName] = bindings; } } diff --git a/modules/engine/test/shader-inputs.spec.ts b/modules/engine/test/shader-inputs.spec.ts index 6c6af5f881..84de79f1aa 100644 --- a/modules/engine/test/shader-inputs.spec.ts +++ b/modules/engine/test/shader-inputs.spec.ts @@ -100,8 +100,7 @@ test('ShaderInputs#bindings', t => { name: 'custom', uniformTypes: {color: 'vec3'}, uniformPropTypes: {color: {value: [0, 0, 0]}}, - getUniforms: ({color}) => ({color}), - getBindings: ({colorTexture}) => ({colorTexture}) + getUniforms: ({color, colorTexture}) => ({color, colorTexture}) }; const shaderInputs = new ShaderInputs<{