From 0af201f960ebd9feddfacb7700db2c7b90b8e7f0 Mon Sep 17 00:00:00 2001 From: Ib Green Date: Thu, 25 Apr 2024 09:02:35 -0400 Subject: [PATCH] chore(shadertools): Remove ShaderModuleInstance class (#2074) --- docs/README.mdx | 2 +- docs/api-guide/shaders/shader-modules.md | 106 ++--------- .../api-guide/shaders/shader-transpilation.md | 29 --- docs/api-reference/README.md | 18 +- docs/api-reference/core/resources/shader.md | 2 +- docs/api-reference/engine/computation.md | 1 - docs/api-reference/engine/model.md | 1 - docs/api-reference/shadertools/README.md | 1 - .../shadertools/shader-assembler.md | 9 +- ...hader-modules.md => shader-conventions.md} | 7 +- docs/api-reference/shadertools/shader-info.md | 2 +- .../shadertools/shader-module.md | 135 ++++++++++++++ docs/developer-guide/installing.md | 2 +- docs/sidebar.json | 5 +- docs/tutorials/hello-instancing.mdx | 2 +- docs/tutorials/transform-feedback.mdx | 4 +- docs/tutorials/transform.mdx | 4 +- docs/upgrade-guide.md | 7 + modules/engine/src/shader-inputs.ts | 6 +- modules/shadertools/src/index.ts | 108 +++++++---- .../shadertools/src/lib/shader-assembler.ts | 15 +- .../lib/shader-assembly/assemble-shaders.ts | 63 +++++-- .../lib/shader-assembly/resolve-modules.ts | 81 --------- .../shader-module/normalize-shader-module.ts | 17 -- .../shader-module-dependencies.ts | 112 ++++++++++++ .../shader-module/shader-module-instance.ts | 167 ------------------ .../src/lib/shader-module/shader-module.ts | 137 ++++++++++++-- .../src/lib/shader-module/shader-pass.ts | 5 +- .../src/modules/engine/picking/picking.ts | 7 +- .../gouraud-material/gouraud-material.ts | 4 + .../src/modules/lighting/lights/lighting.ts | 6 +- .../modules/lighting/no-material/dirlight.ts | 6 +- .../lighting/pbr-material/pbr-material.ts | 82 +++++---- .../lighting/phong-material/phong-material.ts | 7 +- .../brightnesscontrast.ts | 5 + .../image-adjust-filters/denoise.ts | 7 +- .../image-adjust-filters/huesaturation.ts | 10 +- .../image-adjust-filters/noise.ts | 5 + .../image-adjust-filters/sepia.ts | 5 + .../image-adjust-filters/vibrance.ts | 4 + .../image-adjust-filters/vignette.ts | 12 +- .../image-blur-filters/tiltshift.ts | 5 + .../image-blur-filters/triangleblur.ts | 5 + .../image-blur-filters/zoomblur.ts | 5 + .../image-fun-filters/colorhalftone.ts | 5 + .../image-fun-filters/dotscreen.ts | 5 + .../image-fun-filters/edgework.ts | 11 +- .../image-fun-filters/hexagonalpixelate.ts | 5 + .../postprocessing/image-fun-filters/ink.ts | 8 +- .../image-fun-filters/magnify.ts | 2 + .../image-warp-filters/bulgepinch.ts | 5 + .../image-warp-filters/swirl.ts | 7 + .../postprocessing/image-warp-filters/warp.ts | 2 + modules/shadertools/test/index.ts | 17 +- .../test/lib/shader-assembler.spec.ts | 21 ++- .../shader-assembly/assemble-shaders.spec.ts | 29 +-- .../shader-module-dependencies.spec.ts} | 21 +-- .../lib/shader-module/shader-module.spec.ts | 85 +++++---- .../test/modules/engine/picking.spec.ts | 8 +- .../modules/lighting/pbr-material.spec.ts | 5 +- .../shadertools/test/modules/modules.spec.ts | 6 +- .../brightnesscontrast.spec.ts | 5 +- .../image-adjust-filters/denoise.spec.ts | 5 +- .../huesaturation.spec.ts | 5 +- .../image-adjust-filters/noise.spec.ts | 5 +- .../image-adjust-filters/sepia.spec.ts | 5 +- .../image-adjust-filters/vibrance.spec.ts | 5 +- .../image-adjust-filters/vignette.spec.ts | 5 +- .../image-blur-filters/tiltshift.spec.ts | 5 +- .../image-blur-filters/triangleblur.spec.ts | 5 +- .../image-blur-filters/zoomblur.spec.ts | 5 +- .../image-fun-filters/colorhalftone.spec.ts | 5 +- .../image-fun-filters/dotscreen.spec.ts | 5 +- .../image-fun-filters/edgework.spec.ts | 5 +- .../hexagonalpixelate.spec.ts | 5 +- .../image-fun-filters/ink.spec.ts | 5 +- .../image-warp-filters/bulgepinch.spec.ts | 5 +- .../image-warp-filters/swirl.spec.ts | 5 +- 78 files changed, 851 insertions(+), 699 deletions(-) delete mode 100644 docs/api-guide/shaders/shader-transpilation.md rename docs/api-reference/shadertools/{shader-modules.md => shader-conventions.md} (88%) create mode 100644 docs/api-reference/shadertools/shader-module.md delete mode 100644 modules/shadertools/src/lib/shader-assembly/resolve-modules.ts delete mode 100644 modules/shadertools/src/lib/shader-module/normalize-shader-module.ts create mode 100644 modules/shadertools/src/lib/shader-module/shader-module-dependencies.ts delete mode 100644 modules/shadertools/src/lib/shader-module/shader-module-instance.ts rename modules/shadertools/test/lib/{shader-assembly/resolve-modules.spec.ts => shader-module/shader-module-dependencies.spec.ts} (70%) diff --git a/docs/README.mdx b/docs/README.mdx index 30f6d9b536..e658c4b125 100644 --- a/docs/README.mdx +++ b/docs/README.mdx @@ -57,7 +57,7 @@ luma.gl is a modern GPU toolkit for the Web, created to facilitate processing an - **Pluggable backends** - for WebGPU and WebGL . - **Engine-level classes** - `Model`, `Transform` and `AnimationLoop`, as well as scenegraph support. - **glTF** support. -- **Shader management system** - supports shader modules, dependencies, injection, transpilation etc. +- **Shader management system** - supports shader modules, dependencies, injection etc. - **Shader module library** - Pre-optimized moduls for compute, visual effects and post processing. For 3D math and data loading, luma.gl uses companion framworks: diff --git a/docs/api-guide/shaders/shader-modules.md b/docs/api-guide/shaders/shader-modules.md index 3dab2d4085..52d2ddee8c 100644 --- a/docs/api-guide/shaders/shader-modules.md +++ b/docs/api-guide/shaders/shader-modules.md @@ -1,9 +1,9 @@ # Shader Modules -luma.device provides a GLSL shader module system (through the `@luma.device/shadertools` module) that allows you build modular shaders. The system is built around a GLSL "assembler", and addresses the lack of a module/import system in the GLSL language. The shader assembler allows you to import chunks of reusable shader code from separately defined shader fragments into your shader program source code, which allows you to organize your shader code in reusable modules. +luma.device provides a shader module system (through the `@luma.device/shadertools` module) that allows you build modular shaders. The system is built around a shader "assembler", and addresses the lack of a module/import system in the GLSL and WGSL languages. The shader assembler allows you to import chunks of reusable shader code from separately defined shader fragments into your shader program source code, which allows you to organize your shader code in reusable modules. - Enables you to import and "inject" prepackaged modules of shader code into your shaders. -- Allows you to package up reusable GLSL code as shader modules. +- Allows you to package up reusable GLSL and/or WGSL code as shader modules. - Adds GPU detection and a measure of portability your shaders. ## Usage @@ -42,19 +42,18 @@ assembleShaders(device, {..., modules: [MY_SHADER_MODULE]}); ## Structure of a Shader Module -### Shader Module Type +The simplest shader modules just contain one or more reusable generic global GLSL / WGLS functions that can be included either in fragment or vertex shaders (or both). The shader assembles just adds the functions to the top of the assembled shader. The `fp64` module is an example of this type of module. -A shader module is either: +More complex shader modules contain specific vertex and/or fragment shader "chunks". In this case the shader module defines vertex shader inputs and outputs requiring more sophisticated shader generation to wire up the inputs and outputs between shader stages. -- **Generic** - a set of generic GLSL functions that can be included either in a fragment shader or a vertex shader (or both). The `fp64` module is a good example of this type of module. -- **Functional** - Contains specific vertex and/or fragment shader "chunks", often set up so that the vertex shader part sets up a `varying` used by the fragment shader part. - -### Shader Module Descriptor +### Shader Module Descriptors To define a new shader module, you create a descriptor object that brings together all the necessary pieces: ```typescript -export const MY_SHADER_MODULE = { +import type {ShaderModule} from '@luma.gl/shadertools'; + +export const myShaderModule = { name: 'my-shader-module', vs: '...', fs: '...', @@ -62,92 +61,9 @@ export const MY_SHADER_MODULE = { dependencies: [], deprecations: [], getUniforms -}; -``` - -Descriptor objects can define the following fields: - -- `name` (_String_, Required) - The name of the shader module. -- `vs` - (String | null) -- `fs` - (String | null) -- `getUniforms` JavaScript function that maps JavaScript parameter keys to uniforms used by this module -- `uniforms` (_Object_) - a light alternative to `getUniforms`, see below -- `inject` (_Object_) - injections the module will make into shader hooks, see below -- `dependencies` (_Array_) - a list of other shader modules that this module is dependent on -- `deprecations` (_Array_) - a list of deprecated APIs. - -If `deprecations` is supplied, `assembleShaders` will scan GLSL source code for the deprecated constructs and issue a console warning if found. Each API is described in the following format: - -- `type`: `uniform ` or `function` -- `old`: name of the deprecated uniform/function -- `new`: name of the new uniform/function -- `deprecated`: whether the old API is still supported. - -### GLSL Code - -The GLSL code for a shader module typically contains: - -- a mix of uniform and varying declarations -- one or more GLSL function definitions - -### getUniforms - -Each shader module provides a method to get a map of uniforms for the shader. This function will be called with two arguments: - -- `opts` - the module settings to update. This argument may not be provided when `getUniforms` is called to generate a set of default uniform values. -- `context` - the uniforms generated by this module's dependencies. - -The function should return a JavaScript object with keys representing uniform names and values representing uniform values. - -The function should expect the shape of the dependency uniforms to vary based on what's passed in `opts`. This behavior is intended because we only want to recalculate a uniform if the uniforms that it depends on are changed. An example is the `project` and `project64` modules in deck.device. When `opts.viewport` is provided, `project64` will receive the updated projection matrix generated by the `project` module. If `opts.viewport` is empty, then the `project` module generates nothing and so should `project64`. - -### uniforms - -If the uniforms of this module can be directly pulled from user settings, they may declaratively defined by a `uniforms` object: - -```typescript -{ - name: 'my-shader-module', - uniforms: { - strength: {type: 'number', value: 1, min: 0, max: 1}, - center: [0.5, 0.5] - } -} -``` - -At runtime, this map will be used to generate the uniforms needed by the shaders. If either `strength` or `center` is present in the user's module settings, then the user's value will be used; otherwise, the default value in the original definition will be used. - -Each uniform definition may contain the following fields: - -- `type` (_String_) - one of `number`, `boolean`, `array` or `object` -- `value` - the default value of this uniform - -With `type: 'number'`, the following additional fields may be added for validation: - -- `min` (_Number_) -- `max` (_Number_) - -Note: `uniforms` is ignored if `getUniforms` is provided. - -## inject - -A map of hook function signatures to either the injection code string, or an object containing the injection code and an `order` option indicating ordering within the hook function. See [assembleShaders]( /docs/api-reference/shadertools/shader-assembler) documentation for more information on shader hooks. - -For example: - -```typescript -{ - picking: { - 'vs:VERTEX_HOOK_FUNCTION': 'picking_setPickingColor(color.rgb);', - 'fs:FRAGMENT_HOOK_FUNCTION': { - injection: 'color = picking_filterColor(color);', - order: Number.POSITIVE_INFINITY - }, - 'fs:#main-end': 'gl_FragColor = picking_filterColor(gl_FragColor);' - } -} +} as const satisfies ShaderModule; ``` -## GLSL Versions +For details see the [`ShaderModule`](/docs/api-reference/shadertools/shader-module) type reference page. -Shader modules will undergo some basic text transformations in order to match the GLSL version of the shaders they are injected into. These transformations are generally limited to the naming of input variables, output variables and texture sampling functions. See [assembleShaders]( /docs/api-reference/shadertools/shader-assembler) documentation for more information. +Several functions are also available to initialize and use shader modules. diff --git a/docs/api-guide/shaders/shader-transpilation.md b/docs/api-guide/shaders/shader-transpilation.md deleted file mode 100644 index a9a112d3cb..0000000000 --- a/docs/api-guide/shaders/shader-transpilation.md +++ /dev/null @@ -1,29 +0,0 @@ -# Shader Transpilation - -> From v9 luma.gl requires GLSL shaders to be written in GLSL 3.00 ES syntax. - -If `platformInfo` specifies that GLSL 1.0 is required by the `Device`, `assembleShaders` will attempt to transpile GLSL 3.0 shaders to GLSL ES 1.0. - -This transpilation is a limited text replacement and requires that certain conventions be followed: - -- Statements are written one per line. -- Only one fragment shader output is supported. -- GLSL 3.0-only features, such as 3D textures are not supported. - -Text transformations are performed according to the following tables: - -Vertex Shaders - -| 3.00 ES | 1.00 ES | Comment | -| ------- | ----------- | ------- | -| `in` | `attribute` | | -| `out` | `varying` | | - -Fragment Shaders - -| 3.00 ES | 1.00 ES | Comment | -| -------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `in` | `varying` | | -| `out vec4 ` | `gl_FragColor` | `` declaration is removed and usage in the code are replaced with `gl_FragColor` | -| `texture` | `texture2D` | `texture` will be replaced with `texture2D` to ensure 1.00 code is correct. See note on `textureCube` below. | -| `textureCube` \* | `textureCube` | `textureCube` is not valid 3.00 syntax, but must be used to ensure 1.00 code is correct, because `texture` will be substituted with `texture2D` when transpiled to 100. Also `textureCube` will be replaced with correct `texture` syntax when transpiled to 300. | diff --git a/docs/api-reference/README.md b/docs/api-reference/README.md index d7df6fab94..dd6bf2682a 100644 --- a/docs/api-reference/README.md +++ b/docs/api-reference/README.md @@ -2,15 +2,15 @@ luma.gl is packaged and published as a suite of composable npm modules, so that applications can choose what functionality they need. -| Module | Usage | Description | -| ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | -| [`@luma.gl/core`][core] | Required | The "Abstract" `Device` API (implemented by both the `webgpu` and `webgl` modules). | -| [`@luma.gl/webgl`][webgl] | Required \* | `Device` adapter implemented using the WebGPU API. Enables creation of WebGPU resources | -| [`@luma.gl/webgpu`][webgpu] | Required \* | `Device` adapter implemented using the WebGL API. Enables creation of WebGL resources. | -| [`@luma.gl/engine`][engine] | Recommended | A set of WebGPU/WebGL independent core 3D engine style classes built on top of `@luma.gl/core`. | -| [`@luma.gl/shadertools`][shadertools] | Recommended | System for modularizing and composing shader code, shader module system, transpiler, shader modules. | -| [`@luma.gl/gltf`][gltf] | Optional | glTF scenegraph loading and instantiation etc. | -| [`@luma.gl/test-utils`][test-utils] | Optional | Test setups, in particular support for rendering and comparing images. | +| Module | Usage | Description | +| ------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------- | +| [`@luma.gl/core`][core] | Required | The "Abstract" `Device` API (implemented by both the `webgpu` and `webgl` modules). | +| [`@luma.gl/webgl`][webgl] | Required \* | `Device` adapter implemented using the WebGPU API. Enables creation of WebGPU resources | +| [`@luma.gl/webgpu`][webgpu] | Required \* | `Device` adapter implemented using the WebGL API. Enables creation of WebGL resources. | +| [`@luma.gl/engine`][engine] | Recommended | A set of WebGPU/WebGL independent core 3D engine style classes built on top of `@luma.gl/core`. | +| [`@luma.gl/shadertools`][shadertools] | Recommended | System for modularizing and composing shader code, shader module system,, shader modules. | +| [`@luma.gl/gltf`][gltf] | Optional | glTF scenegraph loading and instantiation etc. | +| [`@luma.gl/test-utils`][test-utils] | Optional | Test setups, in particular support for rendering and comparing images. | \* At least one backend, either WebGL or WebGPU, must be installed to enable GPU resource creation. diff --git a/docs/api-reference/core/resources/shader.md b/docs/api-reference/core/resources/shader.md index e252e6814d..8ff3d480c1 100644 --- a/docs/api-reference/core/resources/shader.md +++ b/docs/api-reference/core/resources/shader.md @@ -23,7 +23,7 @@ Properties for a Shader | Field | Type | Description | | ------------- | ------------------------------------------------------ | ---------------------------------------------- | | `id` | `string` | name/identifier (for debugging) | -| `stage` | 'vertex' \| 'fragment' \| 'compute' | Required by WebGL and GLSL transpiler | +| `stage` | 'vertex' \| 'fragment' \| 'compute' | Required by WebGL | | `source` | `string` | Shader source code | | `sourceMap?` | `string` | WebGPU only | | `language?` | 'glsl' \| 'wgsl' | wgsl in WebGPU only | diff --git a/docs/api-reference/engine/computation.md b/docs/api-reference/engine/computation.md index a2b78dc530..02948aa9b0 100644 --- a/docs/api-reference/engine/computation.md +++ b/docs/api-reference/engine/computation.md @@ -5,7 +5,6 @@ The `Computation` class is a high-level class in the luma.gl API. It brings toge `Computation` manages the following responsibilities: - **bindings** these can reference textures and uniform buffers - **shader module injection** -- **shader transpilation**** - **debugging** - Detailed debug logging of draw calls The `Computation` class integrates with diff --git a/docs/api-reference/engine/model.md b/docs/api-reference/engine/model.md index b5bd7893be..62d6587047 100644 --- a/docs/api-reference/engine/model.md +++ b/docs/api-reference/engine/model.md @@ -8,7 +8,6 @@ The `Model` class is the centerpiece of the luma.gl API. It brings together all - **bindings** these can reference textures and uniform buffers - **uniforms** WebGL only uniforms - **shader module injection** -- **shader transpilation**** - **debugging** - Detailed debug logging of draw calls The `Model` class integrates with diff --git a/docs/api-reference/shadertools/README.md b/docs/api-reference/shadertools/README.md index 152516866d..076e5c2204 100644 --- a/docs/api-reference/shadertools/README.md +++ b/docs/api-reference/shadertools/README.md @@ -15,7 +15,6 @@ Shader Modules - A Shader Pass system allowing simple description and chaining of post processing effects. - A props to uniforms mapping system - A selection of shader modules and shader passes -- A GLSL Version Transpiler (transpiles between GLSL ES 3.00, GLSL ES 1.00). ### Shader Injections diff --git a/docs/api-reference/shadertools/shader-assembler.md b/docs/api-reference/shadertools/shader-assembler.md index 712fc04d82..b6fd9c7695 100644 --- a/docs/api-reference/shadertools/shader-assembler.md +++ b/docs/api-reference/shadertools/shader-assembler.md @@ -86,7 +86,7 @@ Generate the final vertex and fragment shader source that can be compiled to cre - composes base vertex and fragment shader source with source from shader modules - resolves hook functions and injections -Takes the source code of a vertex shader and a fragment shader, and a list of modules, defines, etc. Outputs resolved source code for both shaders, after adding prologue, adding defines, importing and transpiling modules, and injecting any shader fragments). +Takes the source code of a vertex shader and a fragment shader, and a list of modules, defines, etc. Outputs resolved source code for both shaders, after adding prologue, adding defines, and importing modules, and injecting any shader fragments). Returns: @@ -189,10 +189,3 @@ new Model(gl, { } }); ``` - -## Transpilation - -If the platformInfo specifies that GLSL 1.0 is required, `assembleShaders` will attempt to transpile GLSL 3.0 shaders to GLSL ES 1.0. - -See the user guide for more details. - diff --git a/docs/api-reference/shadertools/shader-modules.md b/docs/api-reference/shadertools/shader-conventions.md similarity index 88% rename from docs/api-reference/shadertools/shader-modules.md rename to docs/api-reference/shadertools/shader-conventions.md index c2526230ba..59b5eaa675 100644 --- a/docs/api-reference/shadertools/shader-modules.md +++ b/docs/api-reference/shadertools/shader-conventions.md @@ -1,5 +1,10 @@ # Shader Modules +:::caution +This describes informal conventions that luma.gl applies to its shaders. +It is still a work in progress/ +::: + ## Uniform Blocks Shader modules are built around a set of well-defined uniform interface blocks. @@ -22,4 +27,4 @@ by adding the `passes` field to a shader module. ### Defining your own Shader Modules -It is critical that the order and types of declarations of uniforms match those in the shader. +It is important that the order and types of declarations of uniforms match those in the shader. diff --git a/docs/api-reference/shadertools/shader-info.md b/docs/api-reference/shadertools/shader-info.md index eb7bc08816..9e8c32a69a 100644 --- a/docs/api-reference/shadertools/shader-info.md +++ b/docs/api-reference/shadertools/shader-info.md @@ -19,4 +19,4 @@ function getShaderInfo(shaderSource: string): { Returns: - `name` - `language`: `'glsl'` -- `version`: GLSL version e.g. 130 or 300 \ No newline at end of file +- `version`: WGLS version (100) or GLSL version (300) \ No newline at end of file diff --git a/docs/api-reference/shadertools/shader-module.md b/docs/api-reference/shadertools/shader-module.md new file mode 100644 index 0000000000..fd17531d11 --- /dev/null +++ b/docs/api-reference/shadertools/shader-module.md @@ -0,0 +1,135 @@ +# ShaderModule + +In luma.gl, reusable shader modules are defined by objects that conform to the `ShaderModule` type. +For more information see [Shader Module System Guide](/docs/api-guide/shaders/shader-modules). + +`ShaderModule`s are used by the luma.gl [shader assembler](.shader-module). The shader assembler imports chunks of reusable shader code from the module into your shader program source code. + +## Usage + +To define a new shader module, you create a descriptor object that brings together all the necessary pieces: + +```typescript +export const MY_SHADER_MODULE = { + name: 'my-shader-module', + vs: '...', + fs: '...', + inject: {}, + dependencies: [], + deprecations: [], + getUniforms +}; +``` + +## Fields + + +#### `name` + +- `name` (string) - The name of the shader module. + +#### `vs` + +- `vs?` - (string | null) + +#### `fs` + +- `fs` - (string | null) + +#### `uniforms` (_Object_) + +#### `inject` (_Object_) - injections the module will make into shader hooks, see below + +#### `dependencies` (_Array_) - a list of other shader modules that this module is dependent on + +#### `deprecations` (_Array_) - a list of deprecated APIs. + +If `deprecations` is supplied, `assembleShaders` will scan shader source code for the deprecated constructs and issue a console warning if found. Each API is described in the following format: + +- `type`: `uniform ` or `function` +- `old`: name of the deprecated uniform/function +- `new`: name of the new uniform/function +- `deprecated`: whether the old API is still supported. + + +### Defining Uniforms + +If the uniforms of this module can be directly pulled from user settings, they may declaratively defined by a `uniforms` object: + +```typescript +{ + name: 'my-shader-module', + uniforms: { + strength: {type: 'number', value: 1, min: 0, max: 1}, + center: [0.5, 0.5] + } +} +``` + +At runtime, this map will be used to generate the uniforms needed by the shaders. If either `strength` or `center` is present in the user's module settings, then the user's value will be used; otherwise, the default value in the original definition will be used. + +Each uniform definition may contain the following fields: + +- `type` (string `number`, `boolean`, `array` or `object` +- `value` - the default value of this uniform + +With `type: 'number'`, the following additional fields may be added for validation: + +- `min` (_Number_) +- `max` (_Number_) + +Note: `uniforms` is ignored if `getUniforms` is provided. + +## Defining Injections + +A map of hook function signatures to either the injection code string, or an object containing the injection code and an `order` option indicating ordering within the hook function. See [assembleShaders]( /docs/api-reference/shadertools/shader-assembler) documentation for more information on shader hooks. + +For example: + +```typescript +{ + picking: { + 'vs:VERTEX_HOOK_FUNCTION': 'picking_setPickingColor(color.rgb);', + 'fs:FRAGMENT_HOOK_FUNCTION': { + injection: 'color = picking_filterColor(color);', + order: Number.POSITIVE_INFINITY + }, + 'fs:#main-end': 'gl_FragColor = picking_filterColor(gl_FragColor);' + } +} +``` + +## Functions + +#### `getShaderModuleUniforms()` + +```ts +getShaderModuleUniforms(module: ShaderModule) +``` +- +- JavaScript function that maps JavaScript parameter keys to uniforms used by this module + +Each shader module provides a method to get a map of uniforms for the shader. This function will be called with two arguments: + +- `opts` - the module settings to update. This argument may not be provided when `getUniforms` is called to generate a set of default uniform values. +- `context` - the uniforms generated by this module's dependencies. + +The function should return a JavaScript object with keys representing uniform names and values representing uniform values. + +The function should expect the shape of the dependency uniforms to vary based on what's passed in `opts`. This behavior is intended because we only want to recalculate a uniform if the uniforms that it depends on are changed. An example is the `project` and `project64` modules in deck.device. When `opts.viewport` is provided, `project64` will receive the updated projection matrix generated by the `project` module. If `opts.viewport` is empty, then the `project` module generates nothing and so should `project64` + +#### `getShaderModuleDependencies()` + +```ts +getShaderModuleDependencies(module: ShaderModule): ShaderModule[] +``` + +## TODO + +:::caution +This page is not complete: +- Describe props to uniforms mapping system +- Better documentation of getShaderModuleUniforms +- Describe all functions working on shader modules +- Better reference information for injections +::: diff --git a/docs/developer-guide/installing.md b/docs/developer-guide/installing.md index b6328645d2..ff985a48a0 100644 --- a/docs/developer-guide/installing.md +++ b/docs/developer-guide/installing.md @@ -42,7 +42,7 @@ const webgpuDevice = luma.createDevice({type: 'best-available', canvas: ...}); - `engine`: High-level constructs such as `Model`, `AnimationLoop` and `Geometry` that allow a developer to work without worrying about rendering pipeline details. - `webgl`: Wrapper classes around WebGL objects such as `Program`, `Buffer`, `VertexArray` that allow a developer to manager the rendering pipeline directly but with a more convenient API. -- `shadertools`: A system for modularizing and composing GLSL shader code. +- `shadertools`: A system for modularizing and composing shader code. - `debug`: Tooling to aid in debugging. diff --git a/docs/sidebar.json b/docs/sidebar.json index 6e5e4e50e2..6c6cd5f024 100644 --- a/docs/sidebar.json +++ b/docs/sidebar.json @@ -54,8 +54,7 @@ "type": "category", "label": "Shader Programming", "items": [ - "api-guide/shaders/shader-modules", - "api-guide/shaders/shader-transpilation" + "api-guide/shaders/shader-modules" ] }, { @@ -137,7 +136,6 @@ "type": "category", "label": "Shader Modules", "items": [ - "api-reference/shadertools/shader-modules", "api-reference/shadertools/shader-modules/fp32", "api-reference/shadertools/shader-modules/fp64", "api-reference/shadertools/shader-modules/pbr-material", @@ -153,6 +151,7 @@ "items": ["api-reference/shadertools/shader-passes/image-processing"] }, "api-reference/shadertools/README", + "api-reference/shadertools/shader-module", "api-reference/shadertools/shader-assembler", "api-reference/shadertools/shader-info" ] diff --git a/docs/tutorials/hello-instancing.mdx b/docs/tutorials/hello-instancing.mdx index 9302bd2726..997144bd49 100644 --- a/docs/tutorials/hello-instancing.mdx +++ b/docs/tutorials/hello-instancing.mdx @@ -36,7 +36,7 @@ const colorShaderModule = { }; ``` -A shader module is essentially just some GLSL code that will be inserted into our vertex and fragment shaders. They're usually used to define functions that implement generic functionality that can be reused in different programs. In this case, we're defining one to simply pass a color from the vertex shader to the fragment shader. This module also demonstrates a common convention in luma.gl to prefix function and variable names in a shader module with the name of the module to avoid name collisions. +A shader module essentially just contains some shader code fragments that will be inserted into our vertex and fragment shaders. They're usually used to define functions that implement generic functionality that can be reused in different programs. In this case, we're defining one to simply pass a color from the vertex shader to the fragment shader. This module also demonstrates a common convention in luma.gl to prefix function and variable names in a shader module with the name of the module to avoid name collisions. Now let's update our vertex and fragment shaders to use the module functions: diff --git a/docs/tutorials/transform-feedback.mdx b/docs/tutorials/transform-feedback.mdx index 0780548192..433c02ee1a 100644 --- a/docs/tutorials/transform-feedback.mdx +++ b/docs/tutorials/transform-feedback.mdx @@ -23,7 +23,7 @@ import {AnimationLoop, Transform, Model} from '@luma.gl/engine'; import {Buffer, clear} from '@luma.gl/webgl'; ``` -Then we'll define our shaders, which we'll write in GLSL ES 3.0 since we're using WebGL 2: +Then we'll define our shaders: ```typescript const transformVs = `\ @@ -69,7 +69,7 @@ void main() { `; ``` -Internally, we'll be using two separate programs, one for transform feedback and the other for rendering, so we define shaders for both. By default, the `Transform` class will skip rasterization and doesn't require a fragment shader since transform feedback is an operation on vertex data. We define a vertex shader for a transform feedback pass that simply rotates each vertex by 2 degrees in the xy-plane. The rendering vertex and fragment shaders are identical to the ones used in the [Hello Triangle](/docs/tutorials/hello-triangle) tutorial aside from being written in GLSL ES 3.0. +Internally, we'll be using two separate programs, one for transform feedback and the other for rendering, so we define shaders for both. By default, the `Transform` class will skip rasterization and doesn't require a fragment shader since transform feedback is an operation on vertex data. We define a vertex shader for a transform feedback pass that simply rotates each vertex by 2 degrees in the xy-plane. The rendering vertex and fragment shaders are identical to the ones used in the [Hello Triangle](/docs/tutorials/hello-triangle) tutorial. In `onInitialize`, we create our `Transform` instance: diff --git a/docs/tutorials/transform.mdx b/docs/tutorials/transform.mdx index 394b98cf1c..fe39796380 100644 --- a/docs/tutorials/transform.mdx +++ b/docs/tutorials/transform.mdx @@ -27,7 +27,7 @@ import {AnimationLoop, Transform, Model} from '@luma.gl/engine'; import {Buffer, clear} from '@luma.gl/webgl'; ``` -Then we'll define our shaders, which we'll write in GLSL ES 3.0 since we're using WebGL 2: +Then we'll define our shaders: ```typescript const transformVs = `\ @@ -73,7 +73,7 @@ void main() { `; ``` -Internally, we'll be using two separate programs, one for transform feedback and the other for rendering, so we define shaders for both. By default, the `Transform` class will skip rasterization and doesn't require a fragment shader since transform feedback is an operation on vertex data. We define a vertex shader for a transform feedback pass that simply rotates each vertex by 2 degrees in the xy-plane. The rendering vertex and fragment shaders are identical to the ones used in the [Hello Triangle](/docs/tutorials/hello-triangle) tutorial aside from being written in GLSL ES 3.0. +Internally, we'll be using two separate programs, one for transform feedback and the other for rendering, so we define shaders for both. By default, the `Transform` class will skip rasterization and doesn't require a fragment shader since transform feedback is an operation on vertex data. We define a vertex shader for a transform feedback pass that simply rotates each vertex by 2 degrees in the xy-plane. The rendering vertex and fragment shaders are identical to the ones used in the [Hello Triangle](/docs/tutorials/hello-triangle) tutorial. In `onInitialize`, we create our `Transform` instance: diff --git a/docs/upgrade-guide.md b/docs/upgrade-guide.md index dfeeebc5e9..067f9ceb4b 100644 --- a/docs/upgrade-guide.md +++ b/docs/upgrade-guide.md @@ -16,6 +16,13 @@ luma.gl largely follows [SEMVER](https://semver.org) conventions. Breaking chang - `RenderPipeline.topology`: `line-loop-webgl` and `triangle-fan-webgl` topologies are no longer supported. Rebuild your geometries using `triangle-strip` and `line-list`. +**@luma.gl/shadertools** + +- `ShaderModuleInstance` type has been removed. Use `ShaderModule` instead. + - `initializeShaderModule()` now store initialized information on the original shader module structure, and can be called multiple times. + - `moduleInstance.getUniforms()` is removed. Use `getShaderModuleUniforms(module, ...)` instead. + - `getDependencyGraph()` is private. Use `getShaderModuleDependencies(module)` instead. + ## Upgrading to v9.0 luma.gl v9 is a major modernization of the luma.gl API, with many breaking changes, so the upgrade notes for this release are unusually long. To facilitate porting to the v9 release we have also provided a diff --git a/modules/engine/src/shader-inputs.ts b/modules/engine/src/shader-inputs.ts index 6d832e3d95..18cb4869a6 100644 --- a/modules/engine/src/shader-inputs.ts +++ b/modules/engine/src/shader-inputs.ts @@ -5,7 +5,7 @@ import type {UniformValue, Texture, Sampler} from '@luma.gl/core'; import {log} from '@luma.gl/core'; // import type {ShaderUniformType, UniformValue, UniformFormat, UniformInfoDevice, Texture, Sampler} from '@luma.gl/core'; -import {_resolveModules, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {getShaderModuleDependencies, ShaderModule} from '@luma.gl/shadertools'; /** Minimal ShaderModule subset, we don't need shader code etc */ export type ShaderModuleInputs< @@ -63,7 +63,7 @@ export class ShaderInputs< // @ts-expect-error Fix typings constructor(modules: {[P in keyof ShaderPropsT]: ShaderModuleInputs}) { // TODO - get all dependencies from modules - const allModules = _resolveModules(Object.values(modules)); + const allModules = getShaderModuleDependencies(Object.values(modules)); log.log( 1, 'Creating ShaderInputs with modules', @@ -126,7 +126,7 @@ export class ShaderInputs< * Return the map of modules * @todo should should this include the resolved dependencies? */ - getModules(): ShaderModuleInstance[] { + getModules(): ShaderModule[] { return Object.values(this.modules); } diff --git a/modules/shadertools/src/index.ts b/modules/shadertools/src/index.ts index 359b461065..ec7f613b79 100644 --- a/modules/shadertools/src/index.ts +++ b/modules/shadertools/src/index.ts @@ -12,16 +12,25 @@ export {glsl} from './lib/glsl-utils/highlight'; export type {PlatformInfo} from './lib/shader-assembly/platform-info'; +// ShaderModules + export type {ShaderModule} from './lib/shader-module/shader-module'; export type {ShaderPass} from './lib/shader-module/shader-pass'; -export type {ShaderHook} from './lib/shader-assembly/shader-hooks'; -export type {ShaderInjection} from './lib/shader-assembly/shader-injections'; -export {ShaderModuleInstance} from './lib/shader-module/shader-module-instance'; + +export {initializeShaderModule, initializeShaderModules} from './lib/shader-module/shader-module'; +export {getShaderModuleUniforms} from './lib/shader-module/shader-module'; +export {getShaderModuleDependencies} from './lib/shader-module/shader-module-dependencies'; +export {checkShaderModuleDeprecations} from './lib/shader-module/shader-module'; + +export {getShaderModuleSource} from './lib/shader-assembly/assemble-shaders'; + +export {resolveModules as _resolveModules} from './lib/shader-module/shader-module-dependencies'; +export {getDependencyGraph as _getDependencyGraph} from './lib/shader-module/shader-module-dependencies'; // ShaderAssembler export {ShaderAssembler} from './lib/shader-assembler'; - -export {normalizeShaderModule} from './lib/shader-module/normalize-shader-module'; +export type {ShaderHook} from './lib/shader-assembly/shader-hooks'; +export type {ShaderInjection} from './lib/shader-assembly/shader-injections'; // SHADER HELPERS @@ -43,10 +52,7 @@ export {capitalize} from './lib/shader-generator/utils/capitalize'; // TEST EXPORTS - Do not use in production applications export {preprocess} from './lib/preprocessor/preprocessor'; export {assembleGLSLShaderPair} from './lib/shader-assembly/assemble-shaders'; -export {ShaderModuleInstance as _ShaderModuleInstance} from './lib/shader-module/shader-module-instance'; export {combineInjects} from './lib/shader-assembly/shader-injections'; -export {resolveModules as _resolveModules} from './lib/shader-assembly/resolve-modules'; -export {getDependencyGraph as _getDependencyGraph} from './lib/shader-assembly/resolve-modules'; // EXPERIMENTAL WGSL export {getShaderLayoutFromWGSL} from './lib/wgsl/get-shader-layout-wgsl'; @@ -66,11 +72,11 @@ export {fp32} from './modules/math/fp32/fp32'; // // projection // export type {ProjectionUniforms} from './modules/engine/project/project'; // export {projection} from './modules/engine/project/project'; -export type {PickingProps} from './modules/engine/picking/picking'; +export type {PickingProps, PickingUniforms} from './modules/engine/picking/picking'; export {picking} from './modules/engine/picking/picking'; // // lighting -export type {LightingProps} from './modules/lighting/lights/lighting'; +export type {LightingProps, LightingUniforms} from './modules/lighting/lights/lighting'; export {lighting} from './modules/lighting/lights/lighting'; export {dirlight} from './modules/lighting/no-material/dirlight'; export type {PhongMaterialUniforms as GouraudMaterialUniforms} from './modules/lighting/phong-material/phong-material'; @@ -83,55 +89,97 @@ export {pbrMaterial} from './modules/lighting/pbr-material/pbr-material'; // POST PROCESSING / SHADER PASS MODULES // glfx image adjustment shader modules -export type {BrightnessContrastProps} from './modules/postprocessing/image-adjust-filters/brightnesscontrast'; +export type { + BrightnessContrastProps, + BrightnessContrastUniforms +} from './modules/postprocessing/image-adjust-filters/brightnesscontrast'; export {brightnessContrast} from './modules/postprocessing/image-adjust-filters/brightnesscontrast'; -export type {DenoiseProps} from './modules/postprocessing/image-adjust-filters/denoise'; +export type { + DenoiseProps, + DenoiseUniforms +} from './modules/postprocessing/image-adjust-filters/denoise'; export {denoise} from './modules/postprocessing/image-adjust-filters/denoise'; -export type {HueSaturationProps} from './modules/postprocessing/image-adjust-filters/huesaturation'; +export type { + HueSaturationProps, + HueSaturationUniforms +} from './modules/postprocessing/image-adjust-filters/huesaturation'; export {hueSaturation} from './modules/postprocessing/image-adjust-filters/huesaturation'; -export type {NoiseProps} from './modules/postprocessing/image-adjust-filters/noise'; +export type {NoiseProps, NoiseUniforms} from './modules/postprocessing/image-adjust-filters/noise'; export {noise} from './modules/postprocessing/image-adjust-filters/noise'; -export type {SepiaProps} from './modules/postprocessing/image-adjust-filters/sepia'; +export type {SepiaProps, SepiaUniforms} from './modules/postprocessing/image-adjust-filters/sepia'; export {sepia} from './modules/postprocessing/image-adjust-filters/sepia'; -export type {VibranceProps} from './modules/postprocessing/image-adjust-filters/vibrance'; +export type { + VibranceProps, + VibranceUniforms +} from './modules/postprocessing/image-adjust-filters/vibrance'; export {vibrance} from './modules/postprocessing/image-adjust-filters/vibrance'; -export type {VignetteProps} from './modules/postprocessing/image-adjust-filters/vignette'; +export type { + VignetteProps, + VignetteUniforms +} from './modules/postprocessing/image-adjust-filters/vignette'; export {vignette} from './modules/postprocessing/image-adjust-filters/vignette'; // glfx BLUR shader modules -export type {TiltShiftProps} from './modules/postprocessing/image-blur-filters/tiltshift'; +export type { + TiltShiftProps, + TiltShiftUniforms +} from './modules/postprocessing/image-blur-filters/tiltshift'; export {tiltShift} from './modules/postprocessing/image-blur-filters/tiltshift'; -export type {TriangleBlurProps} from './modules/postprocessing/image-blur-filters/triangleblur'; +export type { + TriangleBlurProps, + TriangleBlurUniforms +} from './modules/postprocessing/image-blur-filters/triangleblur'; export {triangleBlur} from './modules/postprocessing/image-blur-filters/triangleblur'; -export type {ZoomBlurProps} from './modules/postprocessing/image-blur-filters/zoomblur'; +export type { + ZoomBlurProps, + ZoomBlurUniforms +} from './modules/postprocessing/image-blur-filters/zoomblur'; export {zoomBlur} from './modules/postprocessing/image-blur-filters/zoomblur'; // glfx FUN shader modules -export type {ColorHalftoneProps} from './modules/postprocessing/image-fun-filters/colorhalftone'; +export type { + ColorHalftoneProps, + ColorHalftoneUniforms +} from './modules/postprocessing/image-fun-filters/colorhalftone'; export {colorHalftone} from './modules/postprocessing/image-fun-filters/colorhalftone'; -export type {DotScreenProps} from './modules/postprocessing/image-fun-filters/dotscreen'; +export type { + DotScreenProps, + DotScreenUniforms +} from './modules/postprocessing/image-fun-filters/dotscreen'; export {dotScreen} from './modules/postprocessing/image-fun-filters/dotscreen'; -export type {EdgeWorkProps} from './modules/postprocessing/image-fun-filters/edgework'; +export type { + EdgeWorkProps, + EdgeWorkUniforms +} from './modules/postprocessing/image-fun-filters/edgework'; export {edgeWork} from './modules/postprocessing/image-fun-filters/edgework'; -export type {HexagonalPixelateProps} from './modules/postprocessing/image-fun-filters/hexagonalpixelate'; +export type { + HexagonalPixelateProps, + HexagonalPixelateUniforms +} from './modules/postprocessing/image-fun-filters/hexagonalpixelate'; export {hexagonalPixelate} from './modules/postprocessing/image-fun-filters/hexagonalpixelate'; -export type {InkProps} from './modules/postprocessing/image-fun-filters/ink'; +export type {InkProps, InkUniforms} from './modules/postprocessing/image-fun-filters/ink'; export {ink} from './modules/postprocessing/image-fun-filters/ink'; -export type {MagnifyProps} from './modules/postprocessing/image-fun-filters/magnify'; +export type { + MagnifyProps, + MagnifyUniforms +} from './modules/postprocessing/image-fun-filters/magnify'; export {magnify} from './modules/postprocessing/image-fun-filters/magnify'; // glfx WARP shader modules -export type {BulgePinchProps} from './modules/postprocessing/image-warp-filters/bulgepinch'; +export type { + BulgePinchProps, + BulgePinchUniforms +} from './modules/postprocessing/image-warp-filters/bulgepinch'; export {bulgePinch} from './modules/postprocessing/image-warp-filters/bulgepinch'; -export type {SwirlProps} from './modules/postprocessing/image-warp-filters/swirl'; +export type {SwirlProps, SwirlUniforms} from './modules/postprocessing/image-warp-filters/swirl'; export {swirl} from './modules/postprocessing/image-warp-filters/swirl'; // Postprocessing modules -// export type {FXAAProps} from './modules/postprocessing/fxaa/fxaa'; +// export type {FXAAProps, FXAAUniforms} from './modules/postprocessing/fxaa/fxaa'; export {fxaa} from './modules/postprocessing/fxaa/fxaa'; // experimental modules -export type {WarpProps} from './modules/postprocessing/image-warp-filters/warp'; +export type {WarpProps, WarpUniforms} from './modules/postprocessing/image-warp-filters/warp'; export {warp as _warp} from './modules/postprocessing/image-warp-filters/warp'; // DEPRECATED - v8 legacy shader modules (non-uniform buffer) diff --git a/modules/shadertools/src/lib/shader-assembler.ts b/modules/shadertools/src/lib/shader-assembler.ts index 2a5ea417c7..3f9f44f50e 100644 --- a/modules/shadertools/src/lib/shader-assembler.ts +++ b/modules/shadertools/src/lib/shader-assembler.ts @@ -3,7 +3,7 @@ // Copyright (c) vis.gl contributors import type {ShaderModule} from './shader-module/shader-module'; -import {ShaderModuleInstance} from './shader-module/shader-module-instance'; +import {initializeShaderModules} from './shader-module/shader-module'; import { AssembleShaderProps, GetUniformsFunc, @@ -76,7 +76,7 @@ export class ShaderAssembler { assembleWGSLShader(props: AssembleShaderProps): { source: string; getUniforms: GetUniformsFunc; - modules: ShaderModuleInstance[]; + modules: ShaderModule[]; } { const modules = this._getModuleList(props.modules); // Combine with default modules const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions @@ -103,7 +103,7 @@ export class ShaderAssembler { vs: string; fs: string; getUniforms: GetUniformsFunc; - modules: ShaderModuleInstance[]; + modules: ShaderModule[]; } { const modules = this._getModuleList(props.modules); // Combine with default modules const hookFunctions = this._hookFunctions; // TODO - combine with default hook functions @@ -123,10 +123,8 @@ export class ShaderAssembler { /** * Dedupe and combine with default modules */ - _getModuleList(appModules: (ShaderModule | ShaderModuleInstance)[] = []): ShaderModuleInstance[] { - const modules = new Array( - this._defaultModules.length + appModules.length - ); + _getModuleList(appModules: ShaderModule[] = []): ShaderModule[] { + const modules = new Array(this._defaultModules.length + appModules.length); const seen: Record = {}; let count = 0; @@ -148,6 +146,7 @@ export class ShaderAssembler { modules.length = count; - return ShaderModuleInstance.instantiateModules(modules); + initializeShaderModules(modules); + return modules; } } diff --git a/modules/shadertools/src/lib/shader-assembly/assemble-shaders.ts b/modules/shadertools/src/lib/shader-assembly/assemble-shaders.ts index a4f29f9c29..448636c95f 100644 --- a/modules/shadertools/src/lib/shader-assembly/assemble-shaders.ts +++ b/modules/shadertools/src/lib/shader-assembly/assemble-shaders.ts @@ -3,12 +3,12 @@ // Copyright (c) vis.gl contributors import {glsl} from '../glsl-utils/highlight'; -import {resolveModules} from './resolve-modules'; +import {getShaderModuleDependencies} from '../shader-module/shader-module-dependencies'; import {PlatformInfo} from './platform-info'; import {getPlatformShaderDefines} from './platform-defines'; import {injectShader, DECLARATION_INJECT_MARKER} from './shader-injections'; import {transpileGLSLShader} from '../shader-transpiler/transpile-glsl-shader'; -import {ShaderModuleInstance} from '../shader-module/shader-module-instance'; +import {checkShaderModuleDeprecations} from '../shader-module/shader-module'; import type {ShaderInjection} from './shader-injections'; import type {ShaderModule} from '../shader-module/shader-module'; import {ShaderHook, normalizeShaderHooks, getShaderHooks} from './shader-hooks'; @@ -47,7 +47,7 @@ export type AssembleShaderOptions = { /** Inject shader id #defines */ id?: string; /** Modules to be injected */ - modules?: (ShaderModule | ShaderModuleInstance)[]; + modules?: ShaderModule[]; /** Defines to be injected */ defines?: Record; /** Hook functions */ @@ -99,7 +99,8 @@ export function assembleWGSLShader( source: string; getUniforms: GetUniformsFunc; } { - const modules = resolveModules(options.modules || []); + const modules = getShaderModuleDependencies(options.modules || []); + return { source: assembleShaderWGSL(options.platformInfo, { ...options, @@ -127,7 +128,7 @@ export function assembleGLSLShaderPair( getUniforms: GetUniformsFunc; } { const {vs, fs} = options; - const modules = resolveModules(options.modules || []); + const modules = getShaderModuleDependencies(options.modules || []); return { vs: assembleShaderGLSL(options.platformInfo, { @@ -228,9 +229,9 @@ export function assembleShaderWGSL(platformInfo: PlatformInfo, options: Assemble for (const module of modulesToInject) { if (log) { - module.checkDeprecations(coreSource, log); + checkShaderModuleDeprecations(module, coreSource, log); } - const moduleSource = module.getModuleSource(stage, 'wgsl'); + const moduleSource = getShaderModuleSource(module, stage); // Add the module source, and a #define that declares it presence assembledSource += moduleSource; @@ -279,7 +280,7 @@ function assembleShaderGLSL( source: string; language?: 'glsl' | 'wgsl'; stage: 'vertex' | 'fragment'; - modules: ShaderModuleInstance[]; + modules: ShaderModule[]; defines?: Record; hookFunctions?: any[]; inject?: Record; @@ -314,7 +315,7 @@ function assembleShaderGLSL( // Combine Module and Application Defines const allDefines = {}; modules.forEach(module => { - Object.assign(allDefines, module.getDefines()); + Object.assign(allDefines, module.defines); }); Object.assign(allDefines, defines); @@ -378,13 +379,13 @@ ${getApplicationDefines(allDefines)} for (const module of modules) { if (log) { - module.checkDeprecations(coreSource, log); + checkShaderModuleDeprecations(module, coreSource, log); } - const moduleSource = module.getModuleSource(stage); + const moduleSource = getShaderModuleSource(module, stage); // Add the module source, and a #define that declares it presence assembledSource += moduleSource; - const injections = module.injections[stage]; + const injections = module.instance?.normalizedInjections[stage] || {}; for (const key in injections) { const match = /^(v|f)s:#([\w-]+)$/.exec(key); if (match) { @@ -429,13 +430,13 @@ ${getApplicationDefines(allDefines)} * @param modules * @returns */ -export function assembleGetUniforms(modules: ShaderModuleInstance[]) { +export function assembleGetUniforms(modules: ShaderModule[]) { return function getUniforms(opts: Record): Record { const uniforms = {}; for (const module of modules) { // `modules` is already sorted by dependency level. This guarantees that // modules have access to the uniforms that are generated by their dependencies. - const moduleUniforms = module.getUniforms(opts, uniforms); + const moduleUniforms = module.getUniforms?.(opts, uniforms); Object.assign(uniforms, moduleUniforms); } return uniforms; @@ -474,6 +475,40 @@ function getApplicationDefines(defines: Record = {}): stri return sourceText; } +/** Extracts the source code chunk for the specified shader type from the named shader module */ +export function getShaderModuleSource( + module: ShaderModule, + stage: 'vertex' | 'fragment' | 'wgsl' +): string { + let moduleSource; + switch (stage) { + case 'vertex': + moduleSource = module.vs || ''; + break; + case 'fragment': + moduleSource = module.fs || ''; + break; + case 'wgsl': + moduleSource = module.source || ''; + break; + default: + assert(false); + } + + if (!module.name) { + throw new Error('Shader module must have a name'); + } + const moduleName = module.name.toUpperCase().replace(/[^0-9a-z]/gi, '_'); + return `\ +// ----- MODULE ${module.name} --------------- + +#define MODULE_${moduleName} +${moduleSource}\ + + +`; +} + /* function getHookFunctions( hookFunctions: Record, diff --git a/modules/shadertools/src/lib/shader-assembly/resolve-modules.ts b/modules/shadertools/src/lib/shader-assembly/resolve-modules.ts deleted file mode 100644 index 1c33261aeb..0000000000 --- a/modules/shadertools/src/lib/shader-assembly/resolve-modules.ts +++ /dev/null @@ -1,81 +0,0 @@ -// luma.gl -// SPDX-License-Identifier: MIT -// Copyright (c) vis.gl contributors - -import type {ShaderModule} from '../shader-module/shader-module'; -import {ShaderModuleInstance} from '../shader-module/shader-module-instance'; - -/** - * Instantiate shader modules and esolve any dependencies - */ -export function resolveModules( - modules: (ShaderModule | ShaderModuleInstance)[] -): ShaderModuleInstance[] { - const instances = ShaderModuleInstance.instantiateModules(modules); - return getShaderDependencies(instances); -} - -/** - * Takes a list of shader module names and returns a new list of - * shader module names that includes all dependencies, sorted so - * that modules that are dependencies of other modules come first. - * - * If the shader glsl code from the returned modules is concatenated - * in the reverse order, it is guaranteed that all functions be resolved and - * that all function and variable definitions come before use. - * - * @param modules - Array of modules (inline modules or module names) - * @return - Array of modules - */ -function getShaderDependencies(modules: ShaderModuleInstance[]): ShaderModuleInstance[] { - const moduleMap: Record = {}; - const moduleDepth: Record = {}; - getDependencyGraph({modules, level: 0, moduleMap, moduleDepth}); - - // Return a reverse sort so that dependencies come before the modules that use them - return Object.keys(moduleDepth) - .sort((a, b) => moduleDepth[b] - moduleDepth[a]) - .map(name => moduleMap[name]); -} - -/** - * Recursively checks module dependencies to calculate dependency level of each module. - * - * @param options.modules - Array of modules - * @param options.level - Current level - * @param options.moduleMap - - * @param options.moduleDepth - Current level - * @return - Map of module name to its level - */ -// Adds another level of dependencies to the result map -export function getDependencyGraph(options: { - modules: ShaderModuleInstance[]; - level: number; - moduleMap: Record; - moduleDepth: Record; -}) { - const {modules, level, moduleMap, moduleDepth} = options; - if (level >= 5) { - throw new Error('Possible loop in shader dependency graph'); - } - - // Update level on all current modules - for (const module of modules) { - moduleMap[module.name] = module; - if (moduleDepth[module.name] === undefined || moduleDepth[module.name] < level) { - moduleDepth[module.name] = level; - } - } - - // Recurse - for (const module of modules) { - if (module.dependencies) { - getDependencyGraph({modules: module.dependencies, level: level + 1, moduleMap, moduleDepth}); - } - } -} - -export const TEST_EXPORTS = { - getShaderDependencies, - getDependencyGraph -}; diff --git a/modules/shadertools/src/lib/shader-module/normalize-shader-module.ts b/modules/shadertools/src/lib/shader-module/normalize-shader-module.ts deleted file mode 100644 index 48fa7fca04..0000000000 --- a/modules/shadertools/src/lib/shader-module/normalize-shader-module.ts +++ /dev/null @@ -1,17 +0,0 @@ -// luma.gl -// SPDX-License-Identifier: MIT -// Copyright (c) vis.gl contributors - -import {ShaderModule} from './shader-module'; -import {ShaderModuleInstance} from './shader-module-instance'; - -export function normalizeShaderModule(module: ShaderModule): ShaderModule { - if (!module.normalized) { - module.normalized = true; - if (module.uniformPropTypes && !module.getUniforms) { - const shaderModule = new ShaderModuleInstance(module); - module.getUniforms = shaderModule.getUniforms.bind(shaderModule); - } - } - return module; -} diff --git a/modules/shadertools/src/lib/shader-module/shader-module-dependencies.ts b/modules/shadertools/src/lib/shader-module/shader-module-dependencies.ts new file mode 100644 index 0000000000..e68f4b2431 --- /dev/null +++ b/modules/shadertools/src/lib/shader-module/shader-module-dependencies.ts @@ -0,0 +1,112 @@ +// luma.gl +// SPDX-License-Identifier: MIT +// Copyright (c) vis.gl contributors + +import {ShaderModule} from './shader-module'; +import {initializeShaderModules} from '../shader-module/shader-module'; + +// import type {ShaderModule} from '../shader-module/shader-module'; + +type AbstractModule = { + name: string; + dependencies?: AbstractModule[]; +}; + +/** + * Takes a list of shader module names and returns a new list of + * shader module names that includes all dependencies, sorted so + * that modules that are dependencies of other modules come first. + * + * If the shader glsl code from the returned modules is concatenated + * in the reverse order, it is guaranteed that all functions be resolved and + * that all function and variable definitions come before use. + * + * @param modules - Array of modules (inline modules or module names) + * @return - Array of modules + */ +export function getShaderModuleDependencies(modules: T[]): T[] { + initializeShaderModules(modules); + const moduleMap: Record = {}; + const moduleDepth: Record = {}; + getDependencyGraph({modules, level: 0, moduleMap, moduleDepth}); + + // Return a reverse sort so that dependencies come before the modules that use them + const dependencies = Object.keys(moduleDepth) + .sort((a, b) => moduleDepth[b] - moduleDepth[a]) + .map(name => moduleMap[name]); + initializeShaderModules(dependencies); + return dependencies; +} + +/** + * Recursively checks module dependencies to calculate dependency level of each module. + * + * @param options.modules - Array of modules + * @param options.level - Current level + * @param options.moduleMap - + * @param options.moduleDepth - Current level + * @return - Map of module name to its level + */ +// Adds another level of dependencies to the result map +export function getDependencyGraph(options: { + modules: T[]; + level: number; + moduleMap: Record; + moduleDepth: Record; +}) { + const {modules, level, moduleMap, moduleDepth} = options; + if (level >= 5) { + throw new Error('Possible loop in shader dependency graph'); + } + + // Update level on all current modules + for (const module of modules) { + moduleMap[module.name] = module; + if (moduleDepth[module.name] === undefined || moduleDepth[module.name] < level) { + moduleDepth[module.name] = level; + } + } + + // Recurse + for (const module of modules) { + if (module.dependencies) { + getDependencyGraph({modules: module.dependencies, level: level + 1, moduleMap, moduleDepth}); + } + } +} + +/** + * Takes a list of shader module names and returns a new list of + * shader module names that includes all dependencies, sorted so + * that modules that are dependencies of other modules come first. + * + * If the shader glsl code from the returned modules is concatenated + * in the reverse order, it is guaranteed that all functions be resolved and + * that all function and variable definitions come before use. + * + * @param modules - Array of modules (inline modules or module names) + * @return - Array of modules + */ +export function getShaderDependencies(modules: ShaderModule[]): ShaderModule[] { + initializeShaderModules(modules); + const moduleMap: Record = {}; + const moduleDepth: Record = {}; + getDependencyGraph({modules, level: 0, moduleMap, moduleDepth}); + + // Return a reverse sort so that dependencies come before the modules that use them + modules = Object.keys(moduleDepth) + .sort((a, b) => moduleDepth[b] - moduleDepth[a]) + .map(name => moduleMap[name]); + initializeShaderModules(modules); + return modules; +} + +// DEPRECATED + +/** + * Instantiate shader modules and resolve any dependencies + * @deprecated Use getShaderDpendencies + */ +export function resolveModules(modules: ShaderModule[]): ShaderModule[] { + return getShaderDependencies(modules); +} diff --git a/modules/shadertools/src/lib/shader-module/shader-module-instance.ts b/modules/shadertools/src/lib/shader-module/shader-module-instance.ts deleted file mode 100644 index 92de80a300..0000000000 --- a/modules/shadertools/src/lib/shader-module/shader-module-instance.ts +++ /dev/null @@ -1,167 +0,0 @@ -// luma.gl -// SPDX-License-Identifier: MIT -// Copyright (c) vis.gl contributors - -import {assert} from '../utils/assert'; -import {makePropValidators, getValidatedProperties, PropValidator} from '../filters/prop-types'; -import {ShaderModule, ShaderModuleDeprecation} from './shader-module'; -import {ShaderInjection, normalizeInjections} from '../shader-assembly/shader-injections'; - -let index = 1; - -/** An initialized ShaderModule, ready to use with `assembleShaders()` */ -export class ShaderModuleInstance { - name: string; - vs?: string; - fs?: string; - getModuleUniforms: Function; - dependencies: ShaderModuleInstance[]; - deprecations: ShaderModuleDeprecation[]; - defines: Record; - injections: { - vertex: Record; - fragment: Record; - }; - uniforms: Record = {}; - uniformTypes: Record = {}; - - static instantiateModules( - modules: (ShaderModule | ShaderModuleInstance)[] - ): ShaderModuleInstance[] { - return modules.map((module: ShaderModule | ShaderModuleInstance) => { - if (module instanceof ShaderModuleInstance) { - return module; - } - - assert( - typeof module !== 'string', - `Shader module use by name is deprecated. Import shader module '${JSON.stringify( - module - )}' and use it directly.` - ); - if (!module.name) { - // eslint-disable-next-line no-console - console.warn('shader module has no name'); - module.name = `shader-module-${index++}`; - } - - const moduleObject = new ShaderModuleInstance(module); - moduleObject.dependencies = ShaderModuleInstance.instantiateModules( - module.dependencies || [] - ); - - return moduleObject; - }); - } - - constructor(props: ShaderModule) { - const { - name, - vs, - fs, - dependencies = [], - uniformPropTypes = {}, - getUniforms, - deprecations = [], - defines = {}, - inject = {} - } = props; - - assert(typeof name === 'string'); - this.name = name; - this.vs = vs; - this.fs = fs; - this.getModuleUniforms = getUniforms!; - this.dependencies = ShaderModuleInstance.instantiateModules(dependencies); - this.deprecations = this._parseDeprecationDefinitions(deprecations); - this.defines = defines; - this.injections = normalizeInjections(inject); - - if (uniformPropTypes) { - this.uniforms = makePropValidators(uniformPropTypes); - } - } - - // Extracts the source code chunk for the specified shader type from the named shader module - getModuleSource(stage: 'vertex' | 'fragment'): string { - let moduleSource; - switch (stage) { - case 'vertex': - moduleSource = this.vs || ''; - break; - case 'fragment': - moduleSource = this.fs || ''; - break; - default: - assert(false); - } - - const moduleName = this.name.toUpperCase().replace(/[^0-9a-z]/gi, '_'); - return `\ -// ----- MODULE ${this.name} --------------- - -#define MODULE_${moduleName} -${moduleSource}\ - - -`; - } - - getUniforms(userProps: Record, uniforms: Record): Record { - if (this.getModuleUniforms) { - return this.getModuleUniforms(userProps, uniforms); - } - // Build uniforms from the uniforms array - return getValidatedProperties(userProps, this.uniforms, this.name); - } - - getDefines(): Record { - return this.defines; - } - - // Warn about deprecated uniforms or functions - checkDeprecations(shaderSource: string, log: any): void { - this.deprecations.forEach(def => { - if (def.regex?.test(shaderSource)) { - if (def.deprecated) { - log.deprecated(def.old, def.new)(); - } else { - log.removed(def.old, def.new)(); - } - } - }); - } - - _parseDeprecationDefinitions(deprecations: ShaderModuleDeprecation[]) { - deprecations.forEach(def => { - switch (def.type) { - case 'function': - def.regex = new RegExp(`\\b${def.old}\\(`); - break; - default: - def.regex = new RegExp(`${def.type} ${def.old};`); - } - }); - - return deprecations; - } - - _defaultGetUniforms(opts: Record = {}): Record { - const uniforms: Record = {}; - const propTypes = this.uniforms; - - for (const key in propTypes) { - const propDef = propTypes[key]; - if (key in opts && !propDef.private) { - if (propDef.validate) { - assert(propDef.validate(opts[key], propDef), `${this.name}: invalid ${key}`); - } - uniforms[key] = opts[key]; - } else { - uniforms[key] = propDef.value; - } - } - - return uniforms; - } -} diff --git a/modules/shadertools/src/lib/shader-module/shader-module.ts b/modules/shadertools/src/lib/shader-module/shader-module.ts index 679d0313ce..f361417ad7 100644 --- a/modules/shadertools/src/lib/shader-module/shader-module.ts +++ b/modules/shadertools/src/lib/shader-module/shader-module.ts @@ -2,9 +2,12 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {NumberArray} from '@math.gl/types'; -import {UniformFormat} from '../../types'; -import {PropType} from '../filters/prop-types'; +import type {NumberArray} from '@math.gl/types'; +import type {UniformFormat} from '../../types'; +import {PropType, PropValidator} from '../filters/prop-types'; +import {ShaderInjection} from '../shader-assembly/shader-injections'; +import {makePropValidators, getValidatedProperties} from '../filters/prop-types'; +import {normalizeInjections} from '../shader-assembly/shader-injections'; export type UniformValue = number | boolean | Readonly; // Float32Array> | Readonly | Readonly | Readonly; @@ -14,7 +17,7 @@ export type UniformInfo = { /** * A shader module definition object - * @note Can be viewed as the ShaderModuleProps for a ShaderModuleInstance + * @note Needs to be initialized with `initializeShaderModules` */ export type ShaderModule< PropsT extends Record = Record, @@ -22,12 +25,17 @@ export type ShaderModule< BindingsT extends Record = {} > = { /** Used for type inference not for values */ - props?: Required; + props?: PropsT; /** Used for type inference, not currently used for values */ uniforms?: UniformsT; name: string; + + /** WGSL code */ + source?: string; + /** GLSL fragment shader code */ fs?: string; + /** GLSL vertex shader code */ vs?: string; /** Uniform shader types @note: Both order and types MUST match uniform block declarations in shader */ @@ -51,8 +59,16 @@ export type ShaderModule< /** Information on deprecated properties */ deprecations?: ShaderModuleDeprecation[]; - /** Internal */ - normalized?: boolean; + /** The instance field contains information that is generated at run-time */ + instance?: { + propValidators?: Record; + parsedDeprecations: ShaderModuleDeprecation[]; + + normalizedInjections: { + vertex: Record; + fragment: Record; + }; + }; }; /** Use to generate deprecations when shader module is used */ @@ -64,16 +80,109 @@ export type ShaderModuleDeprecation = { deprecated?: boolean; }; +// SHNDER MODULE API + +export function initializeShaderModules(modules: ShaderModule[]): void { + modules.map((module: ShaderModule) => initializeShaderModule(module)); +} + +export function initializeShaderModule(module: ShaderModule): void { + if (module.instance) { + return; + } + + initializeShaderModules(module.dependencies || []); + + const { + uniformPropTypes = {}, + deprecations = [], + // defines = {}, + inject = {} + } = module; + + const instance: Required['instance'] = { + normalizedInjections: normalizeInjections(inject), + parsedDeprecations: parseDeprecationDefinitions(deprecations) + }; + + if (uniformPropTypes) { + instance.propValidators = makePropValidators(uniformPropTypes); + } + + module.instance = instance; +} + /** Convert module props to uniforms */ export function getShaderModuleUniforms< ShaderModuleT extends ShaderModule, Record> ->(module: ShaderModuleT, props: ShaderModuleT['props']): ShaderModuleT['uniforms'] { - const uniforms = {...module.defaultUniforms}; +>( + module: ShaderModuleT, + props: ShaderModuleT['props'], + oldUniforms?: ShaderModuleT['uniforms'] +): ShaderModuleT['uniforms'] { + initializeShaderModule(module); + + const uniforms = oldUniforms || {...module.defaultUniforms}; + // If module has a getUniforms function, use it if (module.getUniforms) { - // @ts-expect-error - Object.assign(props, module.getUniforms(props)); - } else { - Object.assign(uniforms, props); + return module.getUniforms(props, uniforms); } - return uniforms; + + // Build uniforms from the uniforms array + // @ts-expect-error + return getValidatedProperties(props, module.instance?.propValidators, module.name); +} + +/* TODO this looks like it was unused code + _defaultGetUniforms(opts: Record = {}): Record { + const uniforms: Record = {}; + const propTypes = this.uniforms; + + for (const key in propTypes) { + const propDef = propTypes[key]; + if (key in opts && !propDef.private) { + if (propDef.validate) { + assert(propDef.validate(opts[key], propDef), `${this.name}: invalid ${key}`); + } + uniforms[key] = opts[key]; + } else { + uniforms[key] = propDef.value; + } + } + + return uniforms; + } +} +*/ +// Warn about deprecated uniforms or functions +export function checkShaderModuleDeprecations( + shaderModule: ShaderModule, + shaderSource: string, + log: any +): void { + shaderModule.deprecations?.forEach(def => { + if (def.regex?.test(shaderSource)) { + if (def.deprecated) { + log.deprecated(def.old, def.new)(); + } else { + log.removed(def.old, def.new)(); + } + } + }); +} + +// HELPERS + +function parseDeprecationDefinitions(deprecations: ShaderModuleDeprecation[]) { + deprecations.forEach(def => { + switch (def.type) { + case 'function': + def.regex = new RegExp(`\\b${def.old}\\(`); + break; + default: + def.regex = new RegExp(`${def.type} ${def.old};`); + } + }); + + return deprecations; } diff --git a/modules/shadertools/src/lib/shader-module/shader-pass.ts b/modules/shadertools/src/lib/shader-module/shader-pass.ts index 92bfadc03a..f45bd55503 100644 --- a/modules/shadertools/src/lib/shader-module/shader-pass.ts +++ b/modules/shadertools/src/lib/shader-module/shader-pass.ts @@ -5,8 +5,8 @@ import type {ShaderModule, UniformValue} from './shader-module'; /** - * A shaderpass is a shader module with additional information - * on how to run + * A ShaderPass is a ShaderModule that can be run "standalone" (e.g. post processing effects) + * It adds additional information on how to run the module in one or more passes. */ export type ShaderPass< PropsT extends Record = Record, @@ -15,6 +15,7 @@ export type ShaderPass< passes: ShaderPassData[]; }; +/** Information on how to run a specific pass */ type ShaderPassData = { sampler?: boolean; filter?: boolean; diff --git a/modules/shadertools/src/modules/engine/picking/picking.ts b/modules/shadertools/src/modules/engine/picking/picking.ts index 0e8fba1a2b..212dc6c4bf 100644 --- a/modules/shadertools/src/modules/engine/picking/picking.ts +++ b/modules/shadertools/src/modules/engine/picking/picking.ts @@ -191,7 +191,11 @@ vec4 picking_filterColor(vec4 color) { * primitives with the same picking color in non-instanced draw-calls */ export const picking = { + props: {} as PickingProps, + uniforms: {} as PickingUniforms, + name: 'picking', + uniformTypes: { isActive: 'f32', isAttribute: 'f32', @@ -208,10 +212,9 @@ export const picking = { highlightedObjectColor: new Float32Array([0, 0, 0]), highlightColor: DEFAULT_HIGHLIGHT_COLOR }, + vs, fs, - props: {} as Required, - uniforms: {} as PickingUniforms, getUniforms } as const satisfies ShaderModule; diff --git a/modules/shadertools/src/modules/lighting/gouraud-material/gouraud-material.ts b/modules/shadertools/src/modules/lighting/gouraud-material/gouraud-material.ts index 7dd8cb692f..6efcb34023 100644 --- a/modules/shadertools/src/modules/lighting/gouraud-material/gouraud-material.ts +++ b/modules/shadertools/src/modules/lighting/gouraud-material/gouraud-material.ts @@ -18,6 +18,9 @@ export type GouraudMaterialUniforms = { /** In Gouraud shading, color is calculated for each triangle vertex normal, and then color is interpolated colors across the triangle */ export const gouraudMaterial = { + props: {} as GouraudMaterialProps, + uniforms: {} as GouraudMaterialUniforms, + name: 'gouraud-lighting', // Note these are switched between phong and gouraud vs: GOURAUD_VS, @@ -38,6 +41,7 @@ export const gouraudMaterial = { shininess: 32, specularColor: [0.15, 0.15, 0.15] }, + getUniforms(props: GouraudMaterialProps): GouraudMaterialUniforms { return {...gouraudMaterial.defaultUniforms, ...props}; } diff --git a/modules/shadertools/src/modules/lighting/lights/lighting.ts b/modules/shadertools/src/modules/lighting/lights/lighting.ts index 0256ac74e3..aa3ef54103 100644 --- a/modules/shadertools/src/modules/lighting/lights/lighting.ts +++ b/modules/shadertools/src/modules/lighting/lights/lighting.ts @@ -68,7 +68,11 @@ export type LightingUniforms = { /** UBO ready lighting module */ export const lighting = { + props: {} as LightingProps, + uniforms: {} as LightingUniforms, + name: 'lighting', + defines: { MAX_LIGHTS }, @@ -99,8 +103,6 @@ export const lighting = { vs: lightingUniforms, fs: lightingUniforms, - props: {} as Required, - uniforms: {} as LightingUniforms, getUniforms } as const satisfies ShaderModule; diff --git a/modules/shadertools/src/modules/lighting/no-material/dirlight.ts b/modules/shadertools/src/modules/lighting/no-material/dirlight.ts index 414da6bddc..615b050992 100644 --- a/modules/shadertools/src/modules/lighting/no-material/dirlight.ts +++ b/modules/shadertools/src/modules/lighting/no-material/dirlight.ts @@ -58,10 +58,14 @@ vec4 dirlight_filterColor(vec4 color) { * Cheap lighting - single directional light, single dot product, one uniform */ export const dirlight = { + props: {} as DirlightProps, + uniforms: {} as DirlightUniforms, + name: 'dirlight', dependencies: [], vs: VS_GLSL, fs: FS_GLSL, + // fragmentInputs: [ // { // name: 'dirlight_vNormal', @@ -74,8 +78,6 @@ export const dirlight = { defaultUniforms: { lightDirection: new Float32Array([1, 1, 2]) }, - props: {} as Required, - uniforms: {} as DirlightUniforms, getUniforms } as const satisfies ShaderModule; diff --git a/modules/shadertools/src/modules/lighting/pbr-material/pbr-material.ts b/modules/shadertools/src/modules/lighting/pbr-material/pbr-material.ts index f71ec6c24e..18301d2d11 100644 --- a/modules/shadertools/src/modules/lighting/pbr-material/pbr-material.ts +++ b/modules/shadertools/src/modules/lighting/pbr-material/pbr-material.ts @@ -15,35 +15,35 @@ import {vs} from './pbr-vertex-glsl'; import {fs} from './pbr-fragment-glsl'; export type PBRMaterialProps = PBRMaterialBindings & { - unlit: boolean; + unlit?: boolean; // Base color map - baseColorMapEnabled: boolean; - baseColorFactor: Readonly; + baseColorMapEnabled?: boolean; + baseColorFactor?: Readonly; - normalMapEnabled: boolean; - normalScale: number; // #ifdef HAS_NORMALMAP + normalMapEnabled?: boolean; + normalScale?: number; // #ifdef HAS_NORMALMAP - emissiveMapEnabled: boolean; - emissiveFactor: Readonly; // #ifdef HAS_EMISSIVEMAP + emissiveMapEnabled?: boolean; + emissiveFactor?: Readonly; // #ifdef HAS_EMISSIVEMAP - metallicRoughnessValues: Readonly; - metallicRoughnessMapEnabled: boolean; + metallicRoughnessValues?: Readonly; + metallicRoughnessMapEnabled?: boolean; - occlusionMapEnabled: boolean; - occlusionStrength: number; // #ifdef HAS_OCCLUSIONMAP + occlusionMapEnabled?: boolean; + occlusionStrength?: number; // #ifdef HAS_OCCLUSIONMAP - alphaCutoffEnabled: boolean; - alphaCutoff: number; // #ifdef ALPHA_CUTOFF + alphaCutoffEnabled?: boolean; + alphaCutoff?: number; // #ifdef ALPHA_CUTOFF // IBL - IBLenabled: boolean; - scaleIBLAmbient: Readonly; // #ifdef USE_IBL + IBLenabled?: boolean; + scaleIBLAmbient?: Readonly; // #ifdef USE_IBL // debugging flags used for shader output of intermediate PBR variables // #ifdef PBR_DEBUG - scaleDiffBaseMR: Readonly; - scaleFGDSpec: Readonly; + scaleDiffBaseMR?: Readonly; + scaleFGDSpec?: Readonly; }; /** Non-uniform block bindings for pbr module */ @@ -56,41 +56,41 @@ type PBRMaterialBindings = { occlusionSampler?: Texture | null; // #ifdef HAS_OCCLUSIONMAP // IBL Samplers - diffuseEnvSampler: Texture | null; // #ifdef USE_IBL (samplerCube) - specularEnvSampler: Texture | null; // #ifdef USE_IBL (samplerCube) + diffuseEnvSampler?: Texture | null; // #ifdef USE_IBL (samplerCube) + specularEnvSampler?: Texture | null; // #ifdef USE_IBL (samplerCube) brdfLUT?: Texture | null; // #ifdef USE_IBL }; export type PBRMaterialUniforms = { - unlit: boolean; + unlit?: boolean; // Base color map - baseColorMapEnabled: boolean; - baseColorFactor: Readonly; + baseColorMapEnabled?: boolean; + baseColorFactor?: Readonly; - normalMapEnabled: boolean; - normalScale: number; // #ifdef HAS_NORMALMAP + normalMapEnabled?: boolean; + normalScale?: number; // #ifdef HAS_NORMALMAP - emissiveMapEnabled: boolean; - emissiveFactor: Readonly; // #ifdef HAS_EMISSIVEMAP + emissiveMapEnabled?: boolean; + emissiveFactor?: Readonly; // #ifdef HAS_EMISSIVEMAP - metallicRoughnessValues: Readonly; - metallicRoughnessMapEnabled: boolean; + metallicRoughnessValues?: Readonly; + metallicRoughnessMapEnabled?: boolean; - occlusionMapEnabled: boolean; - occlusionStrength: number; // #ifdef HAS_OCCLUSIONMAP + occlusionMapEnabled?: boolean; + occlusionStrength?: number; // #ifdef HAS_OCCLUSIONMAP - alphaCutoffEnabled: boolean; - alphaCutoff: number; // #ifdef ALPHA_CUTOFF + alphaCutoffEnabled?: boolean; + alphaCutoff?: number; // #ifdef ALPHA_CUTOFF // IBL - IBLenabled: boolean; - scaleIBLAmbient: Readonly; // #ifdef USE_IBL + IBLenabled?: boolean; + scaleIBLAmbient?: Readonly; // #ifdef USE_IBL // debugging flags used for shader output of intermediate PBR variables // #ifdef PBR_DEBUG - scaleDiffBaseMR: Readonly; - scaleFGDSpec: Readonly; + scaleDiffBaseMR?: Readonly; + scaleFGDSpec?: Readonly; }; /** @@ -98,9 +98,14 @@ export type PBRMaterialUniforms = { * Physically Based Shading of a microfacet surface defined by a glTF material. */ export const pbrMaterial = { + props: {} as PBRMaterialProps, + uniforms: {} as PBRMaterialUniforms, + name: 'pbr', + dependencies: [lighting], vs, fs, + defines: { LIGHTING_FRAGMENT: 1, HAS_NORMALMAP: 0, @@ -112,6 +117,7 @@ export const pbrMaterial = { USE_IBL: 0, PBR_DEBUG: 0 }, + uniformTypes: { // Material is unlit unlit: 'i32', @@ -144,6 +150,7 @@ export const pbrMaterial = { scaleDiffBaseMR: 'vec4', scaleFGDSpec: 'vec4' }, + bindings: { baseColorSampler: {type: 'texture', location: 8}, // #ifdef HAS_BASECOLORMAP normalSampler: {type: 'texture', location: 9}, // #ifdef HAS_NORMALMAP @@ -154,6 +161,5 @@ export const pbrMaterial = { diffuseEnvSampler: {type: 'texture', location: 13}, // #ifdef USE_IBL (samplerCube) specularEnvSampler: {type: 'texture', location: 14}, // #ifdef USE_IBL (samplerCube) brdfLUT: {type: 'texture', location: 15} // #ifdef USE_IBL - }, - dependencies: [lighting] + } } as const satisfies ShaderModule; diff --git a/modules/shadertools/src/modules/lighting/phong-material/phong-material.ts b/modules/shadertools/src/modules/lighting/phong-material/phong-material.ts index 22e9549ac5..899f4cc269 100644 --- a/modules/shadertools/src/modules/lighting/phong-material/phong-material.ts +++ b/modules/shadertools/src/modules/lighting/phong-material/phong-material.ts @@ -18,14 +18,17 @@ export type PhongMaterialUniforms = { /** In Phong shading, the normal vector is linearly interpolated across the surface of the polygon from the polygon's vertex normals. */ export const phongMaterial = { + props: {} as PhongMaterialProps, + uniforms: {} as PhongMaterialUniforms, + name: 'phong-lighting', + dependencies: [lighting], // Note these are switched between phong and gouraud vs: PHONG_VS, fs: PHONG_FS, defines: { LIGHTING_FRAGMENT: 1 }, - dependencies: [lighting], uniformTypes: { ambient: 'f32', diffuse: 'f32', @@ -38,8 +41,6 @@ export const phongMaterial = { shininess: 32, specularColor: [0.15, 0.15, 0.15] }, - props: {} as Required, - uniforms: {} as PhongMaterialUniforms, getUniforms(props?: PhongMaterialProps): PhongMaterialUniforms { return {...phongMaterial.defaultUniforms, ...props}; } diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/brightnesscontrast.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/brightnesscontrast.ts index 3db956014d..80316d32d2 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/brightnesscontrast.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/brightnesscontrast.ts @@ -32,6 +32,8 @@ export type BrightnessContrastProps = { contrast?: number; }; +export type BrightnessContrastUniforms = BrightnessContrastProps; + /** * Brightness / Contrast - * Provides additive brightness and multiplicative contrast control. @@ -39,6 +41,9 @@ export type BrightnessContrastProps = { * @param contrast -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) */ export const brightnessContrast = { + props: {} as BrightnessContrastProps, + uniforms: {} as BrightnessContrastUniforms, + name: 'brightnessContrast', uniformTypes: { brightness: 'f32', diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/denoise.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/denoise.ts index 341cfbbdc9..ef36581175 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/denoise.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/denoise.ts @@ -45,12 +45,17 @@ export type DenoiseProps = { strength?: number; }; +export type DenoiseUniforms = DenoiseProps; + /** * Denoise - * Smooths over grainy noise in dark images using an 9x9 box filter * weighted by color intensity, similar to a bilateral filter. */ export const denoise = { + props: {} as DenoiseProps, + uniforms: {} as DenoiseUniforms, + name: 'denoise', uniformTypes: { strength: 'f32' @@ -61,4 +66,4 @@ export const denoise = { }, fs, passes: [{sampler: true}, {sampler: true}] -} as const satisfies ShaderPass; +} as const satisfies ShaderPass; diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/huesaturation.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/huesaturation.ts index d80e228cc2..12e050bc07 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/huesaturation.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/huesaturation.ts @@ -46,10 +46,12 @@ export type HueSaturationProps = { /** -1 to 1 (-1 is 180 degree rotation in the negative direction, 0 is no change, * and 1 is 180 degree rotation in the positive direction) */ hue?: number; - /** @param saturation -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) */ + /** -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) */ saturation?: number; }; +export type HueSaturationUniforms = HueSaturationProps; + /** * Hue / Saturation * Provides rotational hue and multiplicative saturation control. RGB color space @@ -60,7 +62,12 @@ export type HueSaturationProps = { * or away from the average color channel value. */ export const hueSaturation = { + props: {} as HueSaturationProps, + uniforms: {} as HueSaturationUniforms, + name: 'hueSaturation', + fs, + uniformTypes: { hue: 'f32', saturation: 'f32' @@ -69,6 +76,5 @@ export const hueSaturation = { hue: {value: 0, min: -1, max: 1}, saturation: {value: 0, min: -1, max: 1} }, - fs, passes: [{filter: true}] } as const satisfies ShaderPass; diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/noise.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/noise.ts index 8af1753b73..0a8c33b1df 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/noise.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/noise.ts @@ -35,11 +35,16 @@ export type NoiseProps = { amount?: number; }; +export type NoiseUniforms = NoiseProps; + /** * Noise * Adds black and white noise to the image. */ export const noise = { + props: {} as NoiseProps, + uniforms: {} as NoiseUniforms, + name: 'noise', uniformTypes: { amount: 'f32' diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/sepia.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/sepia.ts index 5779dd0517..da8a0946c7 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/sepia.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/sepia.ts @@ -32,12 +32,17 @@ export type SepiaProps = { amount?: number; }; +export type SepiaUniforms = SepiaProps; + /** * @filter Sepia * @description Gives the image a reddish-brown monochrome tint that imitates an old photograph. * @param amount 0 to 1 (0 for no effect, 1 for full sepia coloring) */ export const sepia = { + props: {} as SepiaProps, + uniforms: {} as SepiaUniforms, + name: 'sepia', uniformTypes: { amount: 'f32' diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vibrance.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vibrance.ts index a9195eb7ef..e7831bd822 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vibrance.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vibrance.ts @@ -31,8 +31,12 @@ export type VibranceProps = { amount?: number; }; +export type VibranceUniforms = VibranceProps; + /** Vibrance - Modifies the saturation of desaturated colors, leaving saturated colors unmodified. */ export const vibrance = { + props: {} as VibranceProps, + uniforms: {} as VibranceUniforms, name: 'vibrance', uniformPropTypes: { amount: {value: 0, min: -1, max: 1} diff --git a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vignette.ts b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vignette.ts index ced3bbdae1..e7a37b40e0 100644 --- a/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vignette.ts +++ b/modules/shadertools/src/modules/postprocessing/image-adjust-filters/vignette.ts @@ -32,13 +32,18 @@ export type VignetteProps = { amount?: number; }; +export type VignetteUniforms = VignetteProps; + /** * Vignette - * Adds a simulated lens edge darkening effect. */ export const vignette = { + props: {} as VignetteProps, + uniforms: {} as VignetteUniforms, + name: 'vignette', - fs, + uniformTypes: { radius: 'f32', amount: 'f32' @@ -47,5 +52,8 @@ export const vignette = { radius: {value: 0.5, min: 0, max: 1}, amount: {value: 0.5, min: 0, max: 1} }, - passes: [{filter: true}] + + passes: [{filter: true}], + + fs } as const satisfies ShaderPass; diff --git a/modules/shadertools/src/modules/postprocessing/image-blur-filters/tiltshift.ts b/modules/shadertools/src/modules/postprocessing/image-blur-filters/tiltshift.ts index 40a1dff757..6c74326016 100644 --- a/modules/shadertools/src/modules/postprocessing/image-blur-filters/tiltshift.ts +++ b/modules/shadertools/src/modules/postprocessing/image-blur-filters/tiltshift.ts @@ -69,6 +69,8 @@ export type TiltShiftProps = { invert?: number; }; +export type TiltShiftUniforms = TiltShiftProps; + /** * Tilt Shift * Simulates the shallow depth of field normally encountered in close-up @@ -81,6 +83,9 @@ export type TiltShiftProps = { * on the line and increases further from the line. */ export const tiltShift = { + props: {} as TiltShiftProps, + uniforms: {} as TiltShiftUniforms, + name: 'tiltShift', dependencies: [random], uniformTypes: { diff --git a/modules/shadertools/src/modules/postprocessing/image-blur-filters/triangleblur.ts b/modules/shadertools/src/modules/postprocessing/image-blur-filters/triangleblur.ts index 8393068a8a..3359c5a914 100644 --- a/modules/shadertools/src/modules/postprocessing/image-blur-filters/triangleblur.ts +++ b/modules/shadertools/src/modules/postprocessing/image-blur-filters/triangleblur.ts @@ -55,6 +55,8 @@ export type TriangleBlurProps = { delta?: number[]; }; +export type TriangleBlurUniforms = TriangleBlurProps; + /** * @filter Triangle Blur * @description This is the most basic blur filter, which convolves the image with a @@ -62,6 +64,9 @@ export type TriangleBlurProps = { * perpendicular triangle filters. */ export const triangleBlur = { + props: {} as TriangleBlurProps, + uniforms: {} as TriangleBlurUniforms, + name: 'triangleBlur', uniformTypes: { radius: 'f32', diff --git a/modules/shadertools/src/modules/postprocessing/image-blur-filters/zoomblur.ts b/modules/shadertools/src/modules/postprocessing/image-blur-filters/zoomblur.ts index 71fc75af9c..07a2803b7a 100644 --- a/modules/shadertools/src/modules/postprocessing/image-blur-filters/zoomblur.ts +++ b/modules/shadertools/src/modules/postprocessing/image-blur-filters/zoomblur.ts @@ -50,11 +50,16 @@ export type ZoomBlurProps = { strength?: number; }; +export type ZoomBlurUniforms = ZoomBlurProps; + /** * Zoom Blur * Blurs the image away from a certain point, which looks like radial motion blur. */ export const zoomBlur = { + props: {} as ZoomBlurProps, + uniforms: {} as ZoomBlurUniforms, + name: 'zoomBlur', uniformTypes: { center: 'vec2', diff --git a/modules/shadertools/src/modules/postprocessing/image-fun-filters/colorhalftone.ts b/modules/shadertools/src/modules/postprocessing/image-fun-filters/colorhalftone.ts index 7678328141..e8e1109410 100644 --- a/modules/shadertools/src/modules/postprocessing/image-fun-filters/colorhalftone.ts +++ b/modules/shadertools/src/modules/postprocessing/image-fun-filters/colorhalftone.ts @@ -58,6 +58,8 @@ export type ColorHalftoneProps = { size?: number; }; +export type ColorHalftoneUniforms = ColorHalftoneProps; + /** * Color Halftone - * Simulates a CMYK halftone rendering of the image by multiplying pixel values @@ -65,6 +67,9 @@ export type ColorHalftoneProps = { * and black. */ export const colorHalftone = { + props: {} as ColorHalftoneProps, + uniforms: {} as ColorHalftoneUniforms, + name: 'colorHalftone', uniformTypes: { center: 'vec2', diff --git a/modules/shadertools/src/modules/postprocessing/image-fun-filters/dotscreen.ts b/modules/shadertools/src/modules/postprocessing/image-fun-filters/dotscreen.ts index 65287e7214..1d74bb8f7a 100644 --- a/modules/shadertools/src/modules/postprocessing/image-fun-filters/dotscreen.ts +++ b/modules/shadertools/src/modules/postprocessing/image-fun-filters/dotscreen.ts @@ -44,12 +44,17 @@ export type DotScreenProps = { size?: number; }; +export type DotScreenUniforms = DotScreenProps; + /** * Dot Screen - * Simulates a black and white halftone rendering of the image by multiplying * pixel values with a rotated 2D sine wave pattern. */ export const dotScreen = { + props: {} as DotScreenProps, + uniforms: {} as DotScreenUniforms, + name: 'dotScreen', uniformTypes: { center: 'vec2', diff --git a/modules/shadertools/src/modules/postprocessing/image-fun-filters/edgework.ts b/modules/shadertools/src/modules/postprocessing/image-fun-filters/edgework.ts index 3c8637966d..733e96071d 100644 --- a/modules/shadertools/src/modules/postprocessing/image-fun-filters/edgework.ts +++ b/modules/shadertools/src/modules/postprocessing/image-fun-filters/edgework.ts @@ -75,19 +75,26 @@ export type EdgeWorkProps = { delta?: number; }; +export type EdgeWorkUniforms = EdgeWorkProps; + /** * Edge Work - * Picks out different frequencies in the image by subtracting two * copies of the image blurred with different radii. */ export const edgeWork = { + props: {} as EdgeWorkProps, + uniforms: {} as EdgeWorkProps, + name: 'edgeWork', + dependencies: [random], + fs, + uniformPropTypes: { radius: {value: 2, min: 1, softMax: 50}, delta: {value: [1, 0], private: true} }, - fs, - dependencies: [random], + passes: [ { // @ts-expect-error diff --git a/modules/shadertools/src/modules/postprocessing/image-fun-filters/hexagonalpixelate.ts b/modules/shadertools/src/modules/postprocessing/image-fun-filters/hexagonalpixelate.ts index 46e6b65fbd..7858c85981 100644 --- a/modules/shadertools/src/modules/postprocessing/image-fun-filters/hexagonalpixelate.ts +++ b/modules/shadertools/src/modules/postprocessing/image-fun-filters/hexagonalpixelate.ts @@ -62,12 +62,17 @@ export type HexagonalPixelateProps = { scale?: number; }; +export type HexagonalPixelateUniforms = HexagonalPixelateProps; + /** * Hexagonal Pixelate * Renders the image using a pattern of hexagonal tiles. Tile colors * are nearest-neighbor sampled from the centers of the tiles. */ export const hexagonalPixelate = { + props: {} as HexagonalPixelateProps, + uniforms: {} as HexagonalPixelateUniforms, + name: 'hexagonalPixelate', uniformTypes: { center: 'vec2', diff --git a/modules/shadertools/src/modules/postprocessing/image-fun-filters/ink.ts b/modules/shadertools/src/modules/postprocessing/image-fun-filters/ink.ts index 1d2c25f232..3293488511 100644 --- a/modules/shadertools/src/modules/postprocessing/image-fun-filters/ink.ts +++ b/modules/shadertools/src/modules/postprocessing/image-fun-filters/ink.ts @@ -49,6 +49,8 @@ export type InkProps = { strength?: number; }; +export type InkUniforms = InkProps; + /** * Ink - * Simulates outlining the image in ink by darkening edges stronger than a @@ -56,13 +58,17 @@ export type InkProps = { * copies of the image, each blurred using a blur of a different radius. */ export const ink = { + props: {} as InkProps, + uniforms: {} as InkUniforms, + name: 'ink', + fs, + uniformTypes: { strength: 'f32' }, uniformPropTypes: { strength: {value: 0.25, min: 0, softMax: 1} }, - fs, passes: [{sampler: true}] } as const satisfies ShaderPass; diff --git a/modules/shadertools/src/modules/postprocessing/image-fun-filters/magnify.ts b/modules/shadertools/src/modules/postprocessing/image-fun-filters/magnify.ts index 32b002de76..f8242bbf94 100644 --- a/modules/shadertools/src/modules/postprocessing/image-fun-filters/magnify.ts +++ b/modules/shadertools/src/modules/postprocessing/image-fun-filters/magnify.ts @@ -44,6 +44,8 @@ export type MagnifyProps = { borderColor?: number[]; }; +export type MagnifyUniforms = MagnifyProps; + /** * Magnify - display a circle with magnify effect applied to surrounding the pixels given position */ diff --git a/modules/shadertools/src/modules/postprocessing/image-warp-filters/bulgepinch.ts b/modules/shadertools/src/modules/postprocessing/image-warp-filters/bulgepinch.ts index 89182c99cb..7d8608acf0 100644 --- a/modules/shadertools/src/modules/postprocessing/image-warp-filters/bulgepinch.ts +++ b/modules/shadertools/src/modules/postprocessing/image-warp-filters/bulgepinch.ts @@ -46,11 +46,16 @@ export type BulgePinchProps = { strength?: number; }; +export type BulgePinchUniforms = BulgePinchProps; + /** * Bulge / Pinch - * Bulges or pinches the image in a circle. */ export const bulgePinch = { + props: {} as BulgePinchProps, + uniforms: {} as BulgePinchUniforms, + name: 'bulgePinch', dependencies: [warp], fs, diff --git a/modules/shadertools/src/modules/postprocessing/image-warp-filters/swirl.ts b/modules/shadertools/src/modules/postprocessing/image-warp-filters/swirl.ts index 90e304e838..717c53a613 100644 --- a/modules/shadertools/src/modules/postprocessing/image-warp-filters/swirl.ts +++ b/modules/shadertools/src/modules/postprocessing/image-warp-filters/swirl.ts @@ -50,13 +50,19 @@ export type SwirlProps = { angle?: number; }; +export type SwirlUniforms = SwirlProps; + /** * Warps a circular region of the image in a swirl. */ export const swirl = { + props: {} as SwirlProps, + uniforms: {} as SwirlProps, + name: 'swirl', dependencies: [warp], fs, + uniformTypes: { center: 'vec2', radius: 'f32', @@ -67,5 +73,6 @@ export const swirl = { radius: {value: 200, min: 1, softMax: 600}, angle: {value: 3, softMin: -25, softMax: 25} }, + passes: [{sampler: true}] } as const satisfies ShaderPass; diff --git a/modules/shadertools/src/modules/postprocessing/image-warp-filters/warp.ts b/modules/shadertools/src/modules/postprocessing/image-warp-filters/warp.ts index e9d29aa2b9..3fcc0fbae6 100644 --- a/modules/shadertools/src/modules/postprocessing/image-warp-filters/warp.ts +++ b/modules/shadertools/src/modules/postprocessing/image-warp-filters/warp.ts @@ -20,6 +20,8 @@ vec4 warp_sampleColor(sampler2D source, vec2 texSize, vec2 coord) { export type WarpProps = {}; +export type WarpUniforms = WarpProps; + export const warp = { name: 'warp', passes: [], diff --git a/modules/shadertools/test/index.ts b/modules/shadertools/test/index.ts index f554bdffc4..7a770032df 100644 --- a/modules/shadertools/test/index.ts +++ b/modules/shadertools/test/index.ts @@ -2,26 +2,27 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors +// SHADER MODULE API + +import './lib/shader-module/shader-module.spec'; +import './lib/shader-module/shader-module-dependencies.spec'; + // utils import './lib/glsl-utils/get-shader-info.spec'; import './lib/glsl-utils/shader-utils.spec'; -// shader transpilation -import './lib/preprocessor/preprocessor.spec'; +// WGSL parsing +import './lib/wgsl/get-shader-layout-wgsl.spec'; // shader transpilation +import './lib/preprocessor/preprocessor.spec'; import './lib/shader-transpiler/transpile-shader.spec'; // shader generation import './lib/generator/generate-shader.spec'; -// WGSL parsing -import './lib/wgsl/get-shader-layout-wgsl.spec'; +// SHADER ASSEMBLY -// SHADER MODULE API - -import './lib/shader-module/shader-module.spec'; -import './lib/shader-assembly/resolve-modules.spec'; import './lib/shader-assembly/inject-shader.spec'; import './lib/shader-assembly/assemble-shaders.spec'; import './lib/shader-assembler.spec'; diff --git a/modules/shadertools/test/lib/shader-assembler.spec.ts b/modules/shadertools/test/lib/shader-assembler.spec.ts index 39f1127216..9af4ba91e6 100644 --- a/modules/shadertools/test/lib/shader-assembler.spec.ts +++ b/modules/shadertools/test/lib/shader-assembler.spec.ts @@ -75,18 +75,17 @@ test('ShaderAssembler#hooks', t => { t.ok(preHookShaders !== assemblyResults, 'Adding hooks changes hash'); - const pickingInjection = Object.assign( - { - inject: { - 'vs:LUMAGL_pickColor': 'picking_setPickingColor(color.rgb);', - 'fs:LUMAGL_fragmentColor': { - injection: 'color = picking_filterColor(color);', - order: Number.POSITIVE_INFINITY - } + const pickingInjection = { + ...picking, + instance: undefined, + inject: { + 'vs:LUMAGL_pickColor': 'picking_setPickingColor(color.rgb);', + 'fs:LUMAGL_fragmentColor': { + injection: 'color = picking_filterColor(color);', + order: Number.POSITIVE_INFINITY } - }, - picking - ); + } + }; const noModuleProgram = shaderAssembler.assembleGLSLShaderPair({platformInfo, vs, fs}); diff --git a/modules/shadertools/test/lib/shader-assembly/assemble-shaders.spec.ts b/modules/shadertools/test/lib/shader-assembly/assemble-shaders.spec.ts index 489da1fd8c..0251d1fb9e 100644 --- a/modules/shadertools/test/lib/shader-assembly/assemble-shaders.spec.ts +++ b/modules/shadertools/test/lib/shader-assembly/assemble-shaders.spec.ts @@ -345,6 +345,20 @@ test('assembleGLSLShaderPair#defines', t => { t.end(); }); +/** Note that */ +const pickingInject = { + ...picking, + instance: undefined, + inject: { + 'vs:LUMAGL_pickColor': 'picking_setPickingColor(color.rgb);', + 'fs:LUMAGL_fragmentColor': { + injection: 'color = picking_filterColor(color);', + order: Number.POSITIVE_INFINITY + }, + 'fs:#main-end': 'fragmentColor = picking_filterColor(fragmentColor);' + } +}; + test('assembleGLSLShaderPair#shaderhooks', t => { const hookFunctions = [ 'vs:LUMAGL_pickColor(inout vec4 color)', @@ -355,20 +369,6 @@ test('assembleGLSLShaderPair#shaderhooks', t => { } ]; - const pickingInject = Object.assign( - { - inject: { - 'vs:LUMAGL_pickColor': 'picking_setPickingColor(color.rgb);', - 'fs:LUMAGL_fragmentColor': { - injection: 'color = picking_filterColor(color);', - order: Number.POSITIVE_INFINITY - }, - 'fs:#main-end': 'fragmentColor = picking_filterColor(fragmentColor);' - } - }, - picking - ); - const testInject = { name: 'test-injection', inject: { @@ -425,6 +425,7 @@ test('assembleGLSLShaderPair#shaderhooks', t => { assembleResult.fs.indexOf('LUMAGL_fragmentColor') > -1, 'hook function injected into fragment shader' ); + t.ok( assembleResult.vs.indexOf('picking_setPickingColor(color.rgb)') > -1, 'injection code included in vertex shader with module' diff --git a/modules/shadertools/test/lib/shader-assembly/resolve-modules.spec.ts b/modules/shadertools/test/lib/shader-module/shader-module-dependencies.spec.ts similarity index 70% rename from modules/shadertools/test/lib/shader-assembly/resolve-modules.spec.ts rename to modules/shadertools/test/lib/shader-module/shader-module-dependencies.spec.ts index dd3899f529..b32f4337df 100644 --- a/modules/shadertools/test/lib/shader-assembly/resolve-modules.spec.ts +++ b/modules/shadertools/test/lib/shader-module/shader-module-dependencies.spec.ts @@ -4,8 +4,8 @@ import test from 'tape-promise/tape'; import { - _ShaderModuleInstance as ShaderModuleInstance, - _resolveModules as resolveModules, + initializeShaderModules, + _resolveModules, _getDependencyGraph as getDependencyGraph } from '@luma.gl/shadertools'; @@ -30,33 +30,28 @@ const project64 = { }; test('ShaderModules#import', t => { - t.ok(resolveModules !== undefined, 'resolveModules import successful'); + t.ok(_resolveModules !== undefined, '_resolveModules import successful'); t.ok(getDependencyGraph !== undefined, 'getDependencyGraph import successful'); t.end(); }); test('ShaderModules#getShaderDependencies', t => { - const result = resolveModules([project64, project]); + const result = _resolveModules([project64, project]); t.deepEqual( result.map(module => module.name), [fp32.name, project.name, fp64.name, project64.name], 'Module order is correct' ); - t.throws( - // @ts-expect-error - () => resolveModules(['project64']), - /deprecated.+project64/, - 'Useful message for deprecated usage' - ); - t.end(); }); test('ShaderModules#getDependencyGraph', t => { const moduleDepth = {}; + const modules = [project64, project]; + initializeShaderModules(modules); getDependencyGraph({ - modules: ShaderModuleInstance.instantiateModules([project64, project]), + modules, level: 0, moduleMap: {}, moduleDepth @@ -69,7 +64,7 @@ test('ShaderModules#getDependencyGraph', t => { [fp64.name]: 1, [project64.name]: 0 }, - 'Module dependecny is correct' + 'Module dependency is correct' ); t.end(); }); diff --git a/modules/shadertools/test/lib/shader-module/shader-module.spec.ts b/modules/shadertools/test/lib/shader-module/shader-module.spec.ts index 06111e3e8e..7838f63d38 100644 --- a/modules/shadertools/test/lib/shader-module/shader-module.spec.ts +++ b/modules/shadertools/test/lib/shader-module/shader-module.spec.ts @@ -2,19 +2,18 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -// @ts-nocheck - import test from 'tape-promise/tape'; -import {normalizeShaderModule, ShaderModuleInstance} from '@luma.gl/shadertools'; -// import {} from '@luma.gl/shadertools/lib/shader-module/shader-module-instance'; +import type {ShaderModule} from '@luma.gl/shadertools'; +import {initializeShaderModule, checkShaderModuleDeprecations} from '@luma.gl/shadertools'; +import {getShaderModuleUniforms, getShaderModuleSource} from '@luma.gl/shadertools'; -test('ShaderModuleInstance', t => { - let shaderModule = new ShaderModuleInstance({name: 'empty-shader-module', uniformTypes: {}}); +test('ShaderModule', t => { + let shaderModule: ShaderModule = {name: 'empty-shader-module', uniformTypes: {}}; - t.ok(shaderModule.getModuleSource('vertex'), 'returns vertex shader'); - t.ok(shaderModule.getModuleSource('fragment'), 'returns frqgment shader'); + t.ok(getShaderModuleSource(shaderModule, 'vertex'), 'returns vertex shader'); + t.ok(getShaderModuleSource(shaderModule, 'fragment'), 'returns fragment shader'); - shaderModule = new ShaderModuleInstance({ + shaderModule = { name: 'test-shader-module', uniformTypes: {}, vs: ` @@ -25,25 +24,27 @@ varying float vClipped; fs: ` varying float vClipped; ` - }); + }; + initializeShaderModule(shaderModule); - t.ok(shaderModule.getModuleSource('vertex'), 'returns vertex shader'); - t.ok(shaderModule.getModuleSource('fragment'), 'returns fragment shader'); + t.ok(getShaderModuleSource(shaderModule, 'vertex'), 'returns vertex shader'); + t.ok(getShaderModuleSource(shaderModule, 'fragment'), 'returns fragment shader'); // @ts-expect-error - t.throws(() => shaderModule.getModuleSource(''), 'unknown shader type'); + t.throws(() => getShaderModuleSource(shaderModule, ''), 'unknown shader type'); t.end(); }); -test('ShaderModuleInstance#checkDeprecations', t => { - const shaderModule = new ShaderModuleInstance({ +test('checkShader', t => { + const shaderModule = { name: 'test-shader-module', uniformTypes: {}, deprecations: [ {type: 'function', old: 'project', new: 'project_to_clipspace', deprecated: true}, {type: 'vec4', old: 'viewMatrix', new: 'uViewMatrix'} ] - }); + }; + initializeShaderModule(shaderModule); const testShader = ` uniform vec4 viewMatrix; attribute vec3 instancePositions; @@ -67,7 +68,7 @@ void main() { } }; - shaderModule.checkDeprecations(testShader, log); + checkShaderModuleDeprecations(shaderModule, testShader, log); t.deepEqual( log.deprecatedCalled[0], @@ -79,23 +80,25 @@ void main() { t.end(); }); -test('normalizeShaderModule', t => { - const moduleDef = { +test('initializeShaderModule', t => { + const module: ShaderModule = { name: 'test-shader-module', uniformPropTypes: { + // @ts-expect-error center: [0.5, 0.5], strength: {type: 'number', value: 0.3, min: 0, max: 1}, + // @ts-expect-error enabled: false, + // @ts-ignore sampler: null, range: {value: new Float32Array([0, 1]), private: true} } }; - // @ts-expect-error - const module = normalizeShaderModule(moduleDef); + initializeShaderModule(module); - // @ts-expect-error - t.deepEqual(module.getUniforms(), { + let uniforms = getShaderModuleUniforms(module, {}); + t.deepEqual(uniforms, { center: [0.5, 0.5], strength: 0.3, enabled: false, @@ -103,28 +106,22 @@ test('normalizeShaderModule', t => { range: [0, 1] }); - t.deepEqual( - // @ts-expect-error - module.getUniforms({ - center: new Float32Array([0, 0]), - sampler: {}, - range: [0, 2] - }), - { - center: [0, 0], - strength: 0.3, - enabled: false, - sampler: {}, - range: [0, 1] - } - ); + uniforms = getShaderModuleUniforms(module, { + center: new Float32Array([0, 0]), + sampler: {}, + range: [0, 2] + }); + t.deepEqual(uniforms, { + center: [0, 0], + strength: 0.3, + enabled: false, + sampler: {}, + range: [0, 1] + }); - // @ts-expect-error - t.throws(() => module.getUniforms({strength: -1}), 'invalid uniform'); - // @ts-expect-error - t.throws(() => module.getUniforms({strength: 2}), 'invalid uniform'); - // @ts-expect-error - t.throws(() => module.getUniforms({center: 0.5}), 'invalid uniform'); + t.throws(() => getShaderModuleUniforms(module, {strength: -1}), 'invalid uniform'); + t.throws(() => getShaderModuleUniforms(module, {strength: 2}), 'invalid uniform'); + t.throws(() => getShaderModuleUniforms(module, {center: 0.5}), 'invalid uniform'); t.end(); }); diff --git a/modules/shadertools/test/modules/engine/picking.spec.ts b/modules/shadertools/test/modules/engine/picking.spec.ts index 0622f107d8..df5603e4ee 100644 --- a/modules/shadertools/test/modules/engine/picking.spec.ts +++ b/modules/shadertools/test/modules/engine/picking.spec.ts @@ -6,7 +6,7 @@ import test from 'tape-promise/tape'; import {webglDevice} from '@luma.gl/test-utils'; import {BufferTransform} from '@luma.gl/engine'; -import {picking, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {picking, getShaderModuleUniforms} from '@luma.gl/shadertools'; /* eslint-disable camelcase */ @@ -58,7 +58,7 @@ const TEST_CASES = [ ]; test('picking#getUniforms', t => { - t.deepEqual(picking.getUniforms({}), {}, 'Empty input'); + t.deepEqual(getShaderModuleUniforms(picking, {}, {}), {}, 'Empty input'); t.deepEqual( picking.getUniforms({ @@ -212,10 +212,10 @@ test.skip('picking#picking_setPickingColor', async t => { vertexCount }); - const pickingModule = new ShaderModuleInstance(picking); await Promise.all( TEST_CASES.map(async testCase => { - const uniforms = pickingModule.getUniforms( + const uniforms = getShaderModuleUniforms( + picking, { highlightedObjectColor: testCase.highlightedObjectColor, // @ts-expect-error diff --git a/modules/shadertools/test/modules/lighting/pbr-material.spec.ts b/modules/shadertools/test/modules/lighting/pbr-material.spec.ts index e874ca0c62..34648e3344 100644 --- a/modules/shadertools/test/modules/lighting/pbr-material.spec.ts +++ b/modules/shadertools/test/modules/lighting/pbr-material.spec.ts @@ -3,11 +3,10 @@ // Copyright (c) vis.gl contributors import test from 'tape-promise/tape'; -import {pbrMaterial, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {pbrMaterial, getShaderModuleUniforms} from '@luma.gl/shadertools'; test('shadertools#pbrMaterial', t => { - const pbrMaterialModule = new ShaderModuleInstance(pbrMaterial); - const uniforms = pbrMaterialModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(pbrMaterial, {}, {}); t.ok(uniforms, 'Default pbr lighting uniforms ok'); t.end(); }); diff --git a/modules/shadertools/test/modules/modules.spec.ts b/modules/shadertools/test/modules/modules.spec.ts index ea57d11435..070e9262ea 100644 --- a/modules/shadertools/test/modules/modules.spec.ts +++ b/modules/shadertools/test/modules/modules.spec.ts @@ -4,7 +4,7 @@ import test from 'tape-promise/tape'; -import {ShaderModuleInstance} from '@luma.gl/shadertools/lib/shader-module/shader-module-instance'; +import {initializeShaderModule, getShaderModuleUniforms} from '@luma.gl/shadertools'; import * as imports from '@luma.gl/shadertools'; const shaderModules = {}; @@ -25,10 +25,10 @@ test('shadertools#module imports are defined', t => { }); function verifyShaderModule(t, module) { - module = new ShaderModuleInstance(module); + initializeShaderModule(module); t.ok(module, `${module.name} imported`); - const uniforms = module.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(module, {}, {}); let isUniformsVaid = true; for (const key in uniforms) { if (getUniformType(uniforms[key]) === 'unknown') { diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/brightnesscontrast.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/brightnesscontrast.spec.ts index d265fc3862..5f3c3de2d5 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/brightnesscontrast.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/brightnesscontrast.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {brightnessContrast, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {brightnessContrast, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('brightnessContrast#build/uniform', t => { - const brightnessContrastModule = new ShaderModuleInstance(brightnessContrast); - const uniforms = brightnessContrastModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(brightnessContrast, {}, {}); t.ok(uniforms, 'brightnessContrast module build is ok'); t.equal(uniforms.brightness, 0, 'brightnessContrast brightness uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/denoise.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/denoise.spec.ts index 5446b88fe3..7654d340e5 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/denoise.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/denoise.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {denoise, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {denoise, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('denoise#build/uniform', t => { - const denoiseModule = new ShaderModuleInstance(denoise); - const uniforms = denoiseModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(denoise, {}, {}); t.ok(uniforms, 'denoise module build is ok'); t.equal(uniforms.strength, 0.5, 'denoise strength uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/huesaturation.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/huesaturation.spec.ts index f28d6a9f0a..70770f6a8e 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/huesaturation.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/huesaturation.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {hueSaturation, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {hueSaturation, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('hueSaturation#build/uniform', t => { - const hueSaturationModule = new ShaderModuleInstance(hueSaturation); - const uniforms = hueSaturationModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(hueSaturation, {}, {}); t.ok(uniforms, 'hueSaturation module build is ok'); t.equal(uniforms.hue, 0, 'hueSaturation hue uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/noise.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/noise.spec.ts index 5ac616eb20..cd5bc34761 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/noise.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/noise.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {noise, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {noise, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('noise#build/uniform', t => { - const noiseModule = new ShaderModuleInstance(noise); - const uniforms = noiseModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(noise, {}, {}); t.ok(uniforms, 'noise module build is ok'); t.equal(uniforms.amount, 0.5, 'noise amount uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/sepia.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/sepia.spec.ts index 6a0a563bd2..94c9886853 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/sepia.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/sepia.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {sepia, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {sepia, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('sepia#build/uniform', t => { - const sepiaModule = new ShaderModuleInstance(sepia); - const uniforms = sepiaModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(sepia, {}, {}); t.ok(uniforms, 'sepia module build is ok'); t.equal(uniforms.amount, 0.5, 'sepia amount uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vibrance.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vibrance.spec.ts index 69812c387a..7bab5ad394 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vibrance.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vibrance.spec.ts @@ -1,9 +1,8 @@ -import {vibrance, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {vibrance, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('vibrance#build/uniform', t => { - const vibranceModule = new ShaderModuleInstance(vibrance); - const uniforms = vibranceModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(vibrance, {}, {}); t.ok(uniforms, 'vibrance module build is ok'); t.equal(uniforms.amount, 0, 'vibrance amount uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vignette.spec.ts b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vignette.spec.ts index d26aa539f5..b4633b9dca 100644 --- a/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vignette.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-adjust-filters/vignette.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {vignette, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {vignette, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('vignette#build/uniform', t => { - const vignetteModule = new ShaderModuleInstance(vignette); - const uniforms = vignetteModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(vignette, {}, {}); t.ok(uniforms, 'vignette module build is ok'); t.equal(uniforms.radius, 0.5, 'vignette radius uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-blur-filters/tiltshift.spec.ts b/modules/shadertools/test/modules/postprocessing/image-blur-filters/tiltshift.spec.ts index 446031a185..b9a27fad81 100644 --- a/modules/shadertools/test/modules/postprocessing/image-blur-filters/tiltshift.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-blur-filters/tiltshift.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {tiltShift, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {tiltShift, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('tiltShift#build/uniform', t => { - const tiltShiftModule = new ShaderModuleInstance(tiltShift); - const uniforms = tiltShiftModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(tiltShift, {}, {}); t.ok(uniforms, 'tiltShift module build is ok'); t.equal(uniforms.blurRadius, 15, 'tiltShift blurRadius uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-blur-filters/triangleblur.spec.ts b/modules/shadertools/test/modules/postprocessing/image-blur-filters/triangleblur.spec.ts index 2e12ffa06f..70c8a09d0d 100644 --- a/modules/shadertools/test/modules/postprocessing/image-blur-filters/triangleblur.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-blur-filters/triangleblur.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {triangleBlur, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {triangleBlur, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('triangleBlur#build/uniform', t => { - const triangleBlurModule = new ShaderModuleInstance(triangleBlur); - const uniforms = triangleBlurModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(triangleBlur, {}, {}); t.ok(uniforms, 'triangleBlur module build is ok'); t.equal(uniforms.radius, 20, 'triangleBlur radius uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-blur-filters/zoomblur.spec.ts b/modules/shadertools/test/modules/postprocessing/image-blur-filters/zoomblur.spec.ts index 97e9b1dfbb..44905edc7a 100644 --- a/modules/shadertools/test/modules/postprocessing/image-blur-filters/zoomblur.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-blur-filters/zoomblur.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {zoomBlur, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {zoomBlur, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('zoomBlur#build/uniform', t => { - const zoomBlurModule = new ShaderModuleInstance(zoomBlur); - const uniforms = zoomBlurModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(zoomBlur, {}, {}); t.ok(uniforms, 'zoomBlur module build is ok'); t.deepEqual(uniforms.center, [0.5, 0.5], 'zoomBlur center uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-fun-filters/colorhalftone.spec.ts b/modules/shadertools/test/modules/postprocessing/image-fun-filters/colorhalftone.spec.ts index df32fa35e2..8841a7a10d 100644 --- a/modules/shadertools/test/modules/postprocessing/image-fun-filters/colorhalftone.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-fun-filters/colorhalftone.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {colorHalftone, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {colorHalftone, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('colorHalftone#build/uniform', t => { - const colorHalftoneModule = new ShaderModuleInstance(colorHalftone); - const uniforms = colorHalftoneModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(colorHalftone, {}, {}); t.ok(uniforms, 'colorHalftone module build is ok'); t.deepEqual(uniforms.center, [0.5, 0.5], 'colorHalftone center uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-fun-filters/dotscreen.spec.ts b/modules/shadertools/test/modules/postprocessing/image-fun-filters/dotscreen.spec.ts index c44743f380..89dcc553e7 100644 --- a/modules/shadertools/test/modules/postprocessing/image-fun-filters/dotscreen.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-fun-filters/dotscreen.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {dotScreen, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {dotScreen, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('dotScreen#build/uniform', t => { - const dotScreenModule = new ShaderModuleInstance(dotScreen); - const uniforms = dotScreenModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(dotScreen, {}, {}); t.ok(uniforms, 'dotScreen module build is ok'); t.deepEqual(uniforms.center, [0.5, 0.5], 'dotScreen center uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-fun-filters/edgework.spec.ts b/modules/shadertools/test/modules/postprocessing/image-fun-filters/edgework.spec.ts index 5653d92e6f..f47f7b204d 100644 --- a/modules/shadertools/test/modules/postprocessing/image-fun-filters/edgework.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-fun-filters/edgework.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {edgeWork, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {edgeWork, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('edgeWork#build/uniform', t => { - const edgeWorkModule = new ShaderModuleInstance(edgeWork); - const uniforms = edgeWorkModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(edgeWork, {}, {}); t.ok(uniforms, 'edgeWork module build is ok'); t.equal(uniforms.radius, 2, 'edgeWork radius uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-fun-filters/hexagonalpixelate.spec.ts b/modules/shadertools/test/modules/postprocessing/image-fun-filters/hexagonalpixelate.spec.ts index 5b8801b9e2..3c449fb29a 100644 --- a/modules/shadertools/test/modules/postprocessing/image-fun-filters/hexagonalpixelate.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-fun-filters/hexagonalpixelate.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {hexagonalPixelate, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {hexagonalPixelate, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('hexagonalPixelate#build/uniform', t => { - const hexagonalPixelateModule = new ShaderModuleInstance(hexagonalPixelate); - const uniforms = hexagonalPixelateModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(hexagonalPixelate, {}, {}); t.ok(uniforms, 'hexagonalPixelate module build is ok'); t.deepEqual(uniforms.center, [0.5, 0.5], 'hexagonalPixelate center uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-fun-filters/ink.spec.ts b/modules/shadertools/test/modules/postprocessing/image-fun-filters/ink.spec.ts index 9e22bcd771..d52ebf78bb 100644 --- a/modules/shadertools/test/modules/postprocessing/image-fun-filters/ink.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-fun-filters/ink.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {ink, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {ink, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('ink#build/uniform', t => { - const inkModule = new ShaderModuleInstance(ink); - const uniforms = inkModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(ink, {}, {}); t.ok(uniforms, 'ink module build is ok'); t.equal(uniforms.strength, 0.25, 'ink strength uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-warp-filters/bulgepinch.spec.ts b/modules/shadertools/test/modules/postprocessing/image-warp-filters/bulgepinch.spec.ts index 8d8b83e1d2..2baf5bdcff 100644 --- a/modules/shadertools/test/modules/postprocessing/image-warp-filters/bulgepinch.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-warp-filters/bulgepinch.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {bulgePinch, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {bulgePinch, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('bulgePinch#build/uniform', t => { - const bulgePinchModule = new ShaderModuleInstance(bulgePinch); - const uniforms = bulgePinchModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(bulgePinch, {}, {}); t.ok(uniforms, 'bulgePinch module build is ok'); t.deepEqual(uniforms.center, [0.5, 0.5], 'bulgePinch center uniform is ok'); diff --git a/modules/shadertools/test/modules/postprocessing/image-warp-filters/swirl.spec.ts b/modules/shadertools/test/modules/postprocessing/image-warp-filters/swirl.spec.ts index 03eaac4df4..4b06fc0a75 100644 --- a/modules/shadertools/test/modules/postprocessing/image-warp-filters/swirl.spec.ts +++ b/modules/shadertools/test/modules/postprocessing/image-warp-filters/swirl.spec.ts @@ -2,12 +2,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors -import {swirl, ShaderModuleInstance} from '@luma.gl/shadertools'; +import {swirl, getShaderModuleUniforms} from '@luma.gl/shadertools'; import test from 'tape-promise/tape'; test('swirl#build/uniform', t => { - const swirlModule = new ShaderModuleInstance(swirl); - const uniforms = swirlModule.getUniforms({}, {}); + const uniforms = getShaderModuleUniforms(swirl, {}, {}); t.ok(uniforms, 'swirl module build is ok'); t.deepEqual(uniforms.center, [0.5, 0.5], 'swirl center uniform is ok');