Skip to content

Commit

Permalink
docs: add an example of simple particules (ping pong FBO)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsulpis committed Mar 3, 2025
1 parent babad94 commit 8547e22
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 17 deletions.
25 changes: 17 additions & 8 deletions docs/.vitepress/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@ export const examplesSidebar = sections.map((section) => {

return {
text: upperFirst(section),
items: pages.map((page) => {
const indexPath = path.join(sectionPath, page, "index.md");
const { data } = matter(fs.readFileSync(indexPath, "utf8"));
return {
text: data.title || page,
link: `/examples/${section}/${page}/`,
};
}),
items: pages
.map((page) => {
const indexPath = path.join(sectionPath, page, "index.md");
const { data } = matter(fs.readFileSync(indexPath, "utf8"));
return {
title: data.title || page,
slug: page,
position: data.position || 0,
};
})
.sort((a, b) => a.position - b.position)
.map((data) => {
return {
text: data.title,
link: `/examples/${section}/${data.slug}/`,
};
}),
};
});

Expand Down
3 changes: 2 additions & 1 deletion docs/examples/gpgpu/boids/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: ping pong FBO (Boids)
title: Boids
position: 2
---

::: example-editor {deps=tweakpane@^4.0.5}
Expand Down
17 changes: 9 additions & 8 deletions docs/examples/gpgpu/boids/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const velocities = usePingPongFBO(gl, {
dataTexture: {
name: "tVelocities",
initialData: Array.from({ length: count }).flatMap(() => [
Math.random() * 0.2 - 0.1,
Math.random() * 0.2 - 0.1,
0,
0,
/* R */ Math.random() * 0.2 - 0.1,
/* G */ Math.random() * 0.2 - 0.1,
/* B */ 0,
/* A */ 0,
]),
},
});
Expand All @@ -45,10 +45,10 @@ const positions = usePingPongFBO(gl, {
dataTexture: {
name: "tPositions",
initialData: Array.from({ length: count }).flatMap(() => [
Math.random() * 2 - 1,
Math.random() * 2 - 1,
0,
0,
/* R */ Math.random() * 2 - 1,
/* G */ Math.random() * 2 - 1,
/* B */ 0,
/* A */ 0,
]),
},
});
Expand All @@ -67,6 +67,7 @@ const renderPass = useWebGLCanvas({
transparent: true,
});

// Wait for the canvas to be resized to avoid a flash at the first renders
renderPass.onCanvasReady(() => {
useLoop(({ deltaTime }) => {
velocities.uniforms.uDeltaTime = deltaTime / 500;
Expand Down
12 changes: 12 additions & 0 deletions docs/examples/gpgpu/particles/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: Particles
position: 1
---

::: example-editor

<<< ./index.ts
<<< @/snippets/canvas-full/styles.css
<<< @/snippets/default/index.html

:::
96 changes: 96 additions & 0 deletions docs/examples/gpgpu/particles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
useWebGLContext,
useLoop,
usePingPongFBO,
useWebGLCanvas,
createFloatDataTexture,
} from "usegl";
import "./styles.css";

const { gl, canvas } = useWebGLContext("#glCanvas");

const positionsFragment = /* glsl */ `
uniform float uDeltaTime;
uniform sampler2D tPositions;
uniform sampler2D tVelocities;
in vec2 uv;
out vec4 fragColor;
vec2 wrapToRange(vec2 value) {
vec2 shifted = value + 1.0;
vec2 wrapped = mod(mod(shifted, 2.0) + 2.0, 2.0);
return wrapped - 1.0;
}
void main() {
vec2 position = texture(tPositions, uv).xy;
vec2 velocity = texture(tVelocities, uv).xy;
fragColor = vec4(wrapToRange(position + velocity * uDeltaTime), 0.0, 0.0);
}
`;

const count = 100;

const positions = usePingPongFBO(gl, {
fragment: positionsFragment,
uniforms: {
uDeltaTime: 0,
tVelocities: createFloatDataTexture(
Array.from({ length: count }).flatMap(() => [
/* R */ Math.random() * 0.2 - 0.1,
/* G */ Math.random() * 0.2 - 0.1,
/* B */ 0,
/* A */ 0,
]),
),
},
dataTexture: {
name: "tPositions",
initialData: Array.from({ length: count }).flatMap(() => [
/* R */ Math.random() * 2 - 1,
/* G */ Math.random() * 2 - 1,
/* B */ 0,
/* A */ 0,
]),
},
});

const renderPass = useWebGLCanvas({
canvas,
vertex: `
uniform sampler2D uPositions;
in vec2 aCoords;
void main() {
gl_Position = vec4(texture2D(uPositions, aCoords).xy, 0, 1);
gl_PointSize = 20.0;
}
`,
fragment: `
in vec2 uv;
out vec4 outColor;
void main() {
vec2 uv = gl_PointCoord.xy;
outColor = vec4(0, 1, .5, smoothstep(0.5, 0.4, length(uv - 0.5)));
}
`,
uniforms: {
uPositions: () => positions.texture,
},
attributes: {
aCoords: positions.coords,
},
transparent: true,
});

// Wait for the canvas to be resized to avoid a flash at the first renders
renderPass.onCanvasReady(() => {
useLoop(({ deltaTime }) => {
positions.uniforms.uDeltaTime = deltaTime / 500;
positions.render();
renderPass.render();
});
});
1 change: 1 addition & 0 deletions docs/snippets/canvas-full/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ canvas {
width: 100svw;
height: 100svh;
display: block;
background: #000;
}

0 comments on commit 8547e22

Please sign in to comment.