Install
$ agentstack add skill-bbeierle12-skill-mcp-claude-particles-gpu ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
GPU Particles
Render massive particle counts (10k-1M+) efficiently using GPU instancing and custom shaders.
Quick Start
import { useRef, useMemo } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
function Particles({ count = 10000 }) {
const points = useRef(null!);
const positions = useMemo(() => {
const pos = new Float32Array(count * 3);
for (let i = 0; i
);
}
Rendering Approaches
| Approach | Particle Count | Complexity | Use Case | |----------|---------------|------------|----------| | Points | 10k - 500k | Low | Simple particles, stars | | Instanced Mesh | 1k - 100k | Medium | 3D geometry particles | | Custom Shader | 100k - 10M | High | Maximum control |
Points Geometry
Simplest approach—each particle is a screen-facing point sprite.
Basic Points
function BasicPoints({ count = 5000 }) {
const positions = useMemo(() => {
const pos = new Float32Array(count * 3);
for (let i = 0; i
);
}
Points with Texture
function TexturedPoints({ count = 5000 }) {
const texture = useTexture('/particle.png');
return (
{/* ... positions ... */}
);
}
Custom Attributes
Add per-particle data like color, size, velocity:
function ColoredParticles({ count = 10000 }) {
const { positions, colors, sizes } = useMemo(() => {
const pos = new Float32Array(count * 3);
const col = new Float32Array(count * 3);
const siz = new Float32Array(count);
for (let i = 0; i
);
}
Custom Shader Particles
Maximum control over particle appearance and animation:
const vertexShader = `
attribute float aSize;
attribute vec3 aColor;
attribute float aAlpha;
uniform float uTime;
uniform float uPixelRatio;
varying vec3 vColor;
varying float vAlpha;
void main() {
vColor = aColor;
vAlpha = aAlpha;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
// Size attenuation
gl_PointSize = aSize * uPixelRatio * (300.0 / -mvPosition.z);
gl_Position = projectionMatrix * mvPosition;
}
`;
const fragmentShader = `
varying vec3 vColor;
varying float vAlpha;
void main() {
// Circular particle
float dist = length(gl_PointCoord - 0.5);
if (dist > 0.5) discard;
// Soft edge
float alpha = 1.0 - smoothstep(0.4, 0.5, dist);
gl_FragColor = vec4(vColor, alpha * vAlpha);
}
`;
function ShaderParticles({ count = 50000 }) {
const points = useRef(null!);
const { positions, sizes, colors, alphas } = useMemo(() => {
const pos = new Float32Array(count * 3);
const siz = new Float32Array(count);
const col = new Float32Array(count * 3);
const alp = new Float32Array(count);
for (let i = 0; i {
points.current.material.uniforms.uTime.value = clock.elapsedTime;
});
return (
);
}
Animated Particles
Position Animation in Shader
// Vertex shader with animation
attribute vec3 aVelocity;
attribute float aPhase;
uniform float uTime;
void main() {
vec3 pos = position;
// Simple oscillation
pos.y += sin(uTime * 2.0 + aPhase) * 0.5;
// Velocity-based movement
pos += aVelocity * uTime;
// Wrap around bounds
pos = mod(pos + 10.0, 20.0) - 10.0;
vec4 mvPosition = modelViewMatrix * vec4(pos, 1.0);
gl_PointSize = 10.0 * (300.0 / -mvPosition.z);
gl_Position = projectionMatrix * mvPosition;
}
CPU Animation (for dynamic systems)
function AnimatedParticles({ count = 10000 }) {
const points = useRef(null!);
const velocities = useMemo(() => {
const vel = new Float32Array(count * 3);
for (let i = 0; i {
const positions = points.current.geometry.attributes.position.array as Float32Array;
for (let i = 0; i 5) positions[i * 3 + j] = -5;
if (positions[i * 3 + j] (null!);
const dummy = useMemo(() => new THREE.Object3D(), []);
useEffect(() => {
for (let i = 0; i {
for (let i = 0; i
);
}
Buffer Geometry Patterns
Sphere Distribution
function spherePositions(count: number, radius: number) {
const positions = new Float32Array(count * 3);
for (let i = 0; i
File Structure
particles-gpu/
├── SKILL.md
├── references/
│ ├── buffer-patterns.md # Distribution patterns
│ └── shader-examples.md # Complete shader examples
└── scripts/
├── particles/
│ ├── basic-points.tsx # Simple points setup
│ ├── shader-points.tsx # Custom shader particles
│ └── instanced.tsx # Instanced mesh particles
└── distributions/
├── sphere.ts # Sphere distribution
├── galaxy.ts # Galaxy spiral
└── grid.ts # Grid distribution
Reference
references/buffer-patterns.md— Position distribution patternsreferences/shader-examples.md— Complete particle shaders
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Bbeierle12
- Source: Bbeierle12/Skill-MCP-Claude
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.