Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README: "Passing custom shader" guide #6

Merged
merged 6 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 36 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,38 @@ If everything is set up correctly, you should see this picture (which is the def

<img alt="Default fragment shader" src="./README.shader-default.png" width="250" height="250" />

### Passing custom shader

To pass your custom shader, define it as a string of WGSL code.

```ts
const shaderFragment = /* wgsl */`
struct FragmentOutput {
@location(0) color: vec4<f32>,
}

@fragment
fn fragment_main() -> FragmentOutput {
var output: FragmentOutput;
output.color = vec4<f32>(0.1, 0.2, 0.25, 1.0);
return output;
}
`;
```

And then pass it to `WGSLCanvas` instance via `shaderFragment` property:

```ts
wgslCanvas.shaderFragment = shaderFragment;
```

> [!TIP]
> If you want to store your WGSL code under `.wgsl` files, you should configure your bundler to be able to resolve them as strings. The easiest way is to start with Vite, which can do this out of the box via [`?raw` suffix](https://vite.dev/guide/assets#importing-asset-as-string).

See full example here:
- [apps/examples/src/examples/Example01Color.ts](./apps/examples/src/examples/Example01Color.ts)
- [apps/examples/src/examples/Example01Color.wgsl](./apps/examples/src/examples/Example01Color.wgsl)

### Passing uniforms

To pass uniforms to your shader, you should first define them in `uniformsKeys` array in your `WGSLCanvas` instance:
Expand Down Expand Up @@ -95,8 +127,8 @@ struct Uniforms {
> The order of keys in `struct Uniforms` must be the same as defined in `uniformsKeys` array!

See full example here:
- [apps/examples/src/examples/Example01Uniforms.ts](./apps/examples/src/examples/Example01Uniforms.ts)
- [apps/examples/src/examples/Example01Uniforms.wgsl](./apps/examples/src/examples/Example01Uniforms.wgsl)
- [apps/examples/src/examples/Example02Uniforms.ts](./apps/examples/src/examples/Example02Uniforms.ts)
- [apps/examples/src/examples/Example02Uniforms.wgsl](./apps/examples/src/examples/Example02Uniforms.wgsl)

### Passing textures

Expand Down Expand Up @@ -126,8 +158,8 @@ In WGSL shader, it'll appear under the following vars:
> If you have uniforms, they'll appear at `@binding(0)`, but `sampler` and `textures` will appear under their bindings incremented by 1.

See full example here:
- [apps/examples/src/examples/Example02Texture.ts](./apps/examples/src/examples/Example02Texture.ts)
- [apps/examples/src/examples/Example02Texture.wgsl](./apps/examples/src/examples/Example02Texture.ts)
- [apps/examples/src/examples/Example03Texture.ts](./apps/examples/src/examples/Example03Texture.ts)
- [apps/examples/src/examples/Example03Texture.wgsl](./apps/examples/src/examples/Example03Texture.ts)

## Examples

Expand Down
9 changes: 9 additions & 0 deletions apps/examples/src/examples/Example01Color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { WGSLCanvas } from "@wgsl-canvas/core";
import shaderFragment from "./Example01Color.wgsl?raw";

export const Example01Color = async (canvas: HTMLCanvasElement) => {
const wgslCanvas = new WGSLCanvas({ canvas });
await wgslCanvas.init();
wgslCanvas.shaderFragment = shaderFragment;
wgslCanvas.render();
};
10 changes: 10 additions & 0 deletions apps/examples/src/examples/Example01Color.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct FragmentOutput {
@location(0) color: vec4<f32>,
}

@fragment
fn fragment_main() -> FragmentOutput {
var output: FragmentOutput;
output.color = vec4<f32>(0.1, 0.2, 0.25, 1.0);
return output;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WGSLCanvas } from "@wgsl-canvas/core";
import shaderFragment from "./Example01Uniforms.wgsl?raw";
import shaderFragment from "./Example02Uniforms.wgsl?raw";

export const Example01Uniforms = async (canvas: HTMLCanvasElement) => {
export const Example02Uniforms = async (canvas: HTMLCanvasElement) => {
const wgslCanvas = new WGSLCanvas({ canvas });
await wgslCanvas.init();
wgslCanvas.shaderFragment = shaderFragment;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WGSLCanvas } from "@wgsl-canvas/core";
import shaderFragment from "./Example02Texture.wgsl?raw";
import shaderFragment from "./Example03Texture.wgsl?raw";

export const Example02Texture = async (canvas: HTMLCanvasElement) => {
export const Example03Texture = async (canvas: HTMLCanvasElement) => {
const wgslCanvas = new WGSLCanvas({ canvas });
await wgslCanvas.init();
const textureUrl = "/assets/textures/uv_grid/uv_grid_webgpu.jpg";
Expand Down
12 changes: 9 additions & 3 deletions apps/examples/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { WGSLCanvas } from "@wgsl-canvas/core";
import { Example00Default } from "./examples/Example00Default";
import { Example01Uniforms } from "./examples/Example01Uniforms";
import { Example02Texture } from "./examples/Example02Texture";
import { Example01Color } from "./examples/Example01Color";
import { Example02Uniforms } from "./examples/Example02Uniforms";
import { Example03Texture } from "./examples/Example03Texture";

const main = async () => {
if (!WGSLCanvas.isSupported()) {
Expand All @@ -12,7 +13,12 @@ const main = async () => {
const container = document.getElementById("examples");
if (!container) return;

const examples = [Example00Default, Example01Uniforms, Example02Texture];
const examples = [
Example00Default,
Example01Color,
Example02Uniforms,
Example03Texture,
];
for (const example of examples) {
const canvas = document.createElement("canvas");
canvas.width = 250;
Expand Down