Skip to content

Commit

Permalink
Add information about shaders on web
Browse files Browse the repository at this point in the history
  • Loading branch information
noituri committed Mar 5, 2025
1 parent b1c9fbc commit be03216
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 6 deletions.
29 changes: 28 additions & 1 deletion src/content/docs/fundamentals/concepts/shaders.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
title: Shaders
---
import { Code } from '@astrojs/starlight/components';
import { Code, Aside } from '@astrojs/starlight/components';
import { Image } from 'astro:assets';
import CollapsibleDetails from '../../../../components/CollapsibleDetails.astro';
import vertexShader from '../../../../assets/docs/vertex-shader.png';

Shaders are small programs that we send to a GPU to perform computations. Shaders are extensively used in Smelter, in fact all built-in transformations rely on them.
Expand Down Expand Up @@ -93,6 +94,32 @@ struct BaseShaderParameters {
var<push_constant> base_params: BaseShaderParameters;
`} lang='wgsl' />

<Aside type="caution">
When `@swmansion/smelter-web-wasm` is used, shaders can accept only one texture (use `texture_2d<f32>` instead of `binding_array<texture_2d<f32>, 16>`).
</Aside>

<CollapsibleDetails summaryTitle="@swmansion/smelter-web-wasm">
<Code code={`
struct VertexInput {
@location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>,
}
struct BaseShaderParameters {
plane_id: i32,
time: f32,
output_resolution: vec2<u32>,
texture_count: u32,
}
@group(0) @binding(0) var texture: texture_2d<f32>;
@group(2) @binding(0) var sampler_: sampler;
var<push_constant> base_params: BaseShaderParameters;
`} lang='wgsl' mark={13} />
</CollapsibleDetails>


### Custom parameters
You can define a custom WGSL struct and bind a value of this type:

Expand Down
12 changes: 9 additions & 3 deletions src/content/docs/ts-sdk/components/Shader.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
---
title: Shader
---
import { Aside, Code, Badge } from '@astrojs/starlight/components';
import { Aside, Code } from '@astrojs/starlight/components';
import shaderExample from './examples/Shader.tsx?raw';
import shaderExampleWasm from './examples/ShaderWasm.tsx?raw';
import CollapsibleDetails from '../../../../components/CollapsibleDetails.astro';
import ExampleImage from '../../../../assets/guides/component-shader-example.mp4';

<Badge text="Node.js" variant="tip" size="large" />

<br />
<br />

Expand All @@ -19,6 +18,13 @@ For more information on using shaders in Smelter, please visit [Shaders document
## Usage

<Code code={shaderExample} title='ShaderExample.tsx' lang='tsx' collapse={["7-54", "77-98"]} />
<Aside type="caution">
When `@swmansion/smelter-web-wasm` is used, shaders can accept only one texture (use `texture_2d<f32>` instead of `binding_array<texture_2d<f32>, 16>`).
</Aside>

<CollapsibleDetails summaryTitle='@swmansion/smelter-web-wasm'>
<Code code={shaderExampleWasm} title='ShaderExample.tsx' lang='tsx' collapse={["5-30", "58-100"]} mark={[32, 55]} />
</CollapsibleDetails>

<CollapsibleDetails summaryTitle='Example output'>
<video autoplay loop muted src={ExampleImage} alt="example output" />
Expand Down
100 changes: 100 additions & 0 deletions src/content/docs/ts-sdk/components/examples/ShaderWasm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Mp4, Shader } from "@swmansion/smelter";
import Smelter from "@swmansion/smelter-node";

const EXAMPLE_SHADER = `
struct VertexInput {
@location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>,
}
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,
}
@vertex
fn vs_main(input: VertexInput) -> VertexOutput {
var output: VertexOutput;
output.position = vec4(input.position, 1.0);
output.tex_coords = input.tex_coords;
return output;
}
struct BaseShaderParameters {
plane_id: i32,
time: f32,
output_resolution: vec2<u32>,
texture_count: u32,
}
@group(0) @binding(0) var texture: texture_2d<f32>;
@group(2) @binding(0) var sampler_: sampler;
var<push_constant> base_params: BaseShaderParameters;
@fragment
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
// Return transparent frame in case of different input video count
if (base_params.texture_count != 1u) {
return vec4(0.0, 0.0, 0.0, 0.0);
}
let pi = 3.14159;
let effect_radius = abs(sin(base_params.time) / 2.0);
let effect_angle = 2.0 * pi * abs(sin(base_params.time) / 2.0);
let center = vec2(0.5, 0.5);
let uv = input.tex_coords - center;
let len = length(uv);
let angle = atan2(uv.y, uv.x) + effect_angle * smoothstep(effect_radius, 0.0, len);
let coords = vec2(len * cos(angle), len * sin(angle)) + center;
return textureSample(texture, sampler_, coords);
}
`;

function ExampleApp() {
return (
<Shader
shaderId="example_shader"
resolution={{ width: 1280, height: 720 }}>
<Mp4 source="https://example.com/video.mp4" />
</Shader>
);
}

async function run() {
const smelter = new Smelter();
await smelter.init();

await smelter.registerShader("example_shader", {
source: EXAMPLE_SHADER,
});

await smelter.registerOutput("output", <ExampleApp />, {
type: "mp4",
serverPath: "./output.mp4",
video: {
encoder: {
type: "ffmpeg_h264",
preset: "ultrafast",
},
resolution: {
width: 1920,
height: 1080,
},
},
audio: {
encoder: {
type: "aac",
channels: "stereo",
},
},
});

await smelter.start();
}
void run();
5 changes: 3 additions & 2 deletions src/content/docs/ts-sdk/resources/shader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ title: Shader
import { Aside, Code, Badge } from '@astrojs/starlight/components';
import CollapsibleDetails from '../../../../components/CollapsibleDetails.astro';

<Badge text="Node.js" variant="tip" size="large" />

<br />
<br />

Expand All @@ -28,3 +26,6 @@ Shader source code. To learn more visit [Shaders documentation](/fundamentals/co

- **Type**: `string`

<Aside type="caution">
Shader header is different on `@swmansion/smelter-web-wasm`. Visit [Shader header documentation](/fundamentals/concepts/shaders#header).
</Aside>

0 comments on commit be03216

Please sign in to comment.