Skip to content

Commit

Permalink
Merge 9f2131c into bc5c11c
Browse files Browse the repository at this point in the history
  • Loading branch information
ibgreen committed Apr 25, 2024
2 parents bc5c11c + 9f2131c commit 367770e
Show file tree
Hide file tree
Showing 78 changed files with 851 additions and 699 deletions.
2 changes: 1 addition & 1 deletion docs/README.mdx
Expand Up @@ -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:
Expand Down
106 changes: 11 additions & 95 deletions 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
Expand Down Expand Up @@ -42,112 +42,28 @@ 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: '...',
inject: {},
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 <type>` 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.
29 changes: 0 additions & 29 deletions docs/api-guide/shaders/shader-transpilation.md

This file was deleted.

18 changes: 9 additions & 9 deletions docs/api-reference/README.md
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/core/resources/shader.md
Expand Up @@ -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 |
Expand Down
1 change: 0 additions & 1 deletion docs/api-reference/engine/computation.md
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion docs/api-reference/engine/model.md
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion docs/api-reference/shadertools/README.md
Expand Up @@ -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

Expand Down
9 changes: 1 addition & 8 deletions docs/api-reference/shadertools/shader-assembler.md
Expand Up @@ -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:

Expand Down Expand Up @@ -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.

@@ -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.
Expand All @@ -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.
2 changes: 1 addition & 1 deletion docs/api-reference/shadertools/shader-info.md
Expand Up @@ -19,4 +19,4 @@ function getShaderInfo(shaderSource: string): {
Returns:
- `name`
- `language`: `'glsl'`
- `version`: GLSL version e.g. 130 or 300
- `version`: WGLS version (100) or GLSL version (300)

0 comments on commit 367770e

Please sign in to comment.