We use cookies to improve user experience, analytics and to provide personalised content. With your approval we use cookies for marketing as well.
Together with our partners, such as Google, Meta and Klaviyo, we collect information about the use of our site, which we use for analytics and, with your consent, also for marketing targeting. The information collected includes:
- clicked links and viewed products
- products added to and removed from the shopping cart
- product information of orders placed
This information helps us improve our service and offer you more interesting products and better offers.
You can change your cookie settings at any time. You can find more information about the use of cookies in our privacy statement.
Lees meer
Gratis levering naar Polen voor bestellingen boven 549,97 zł!
// ------------------------------------------------- // 2️⃣ Post‑processing (the “affect” part) // ------------------------------------------------- const composer = new EffectComposer(renderer); composer.addPass(new RenderPass(scene, camera));
const scene = new THREE.Scene(); scene.background = new THREE.Color(0x0a0a0a); affect3d gif
| Step | Description | |------|-------------| | | A rotating torus‑knot with a metallic‑red material. | | Lighting | Directional + ambient light for depth. | | Post‑processing | UnrealBloomPass adds a soft glow that gives the animation its “affective” feel. | | Capture | Every 1/30 second we pull the raw pixel buffer from the canvas and push it into gif.js . | | Export | Once 2 seconds of animation are recorded, the GIF is assembled and automatically downloaded. | Tip: Swap UnrealBloomPass for FilmPass , GlitchPass , or a custom shader to change the mood instantly. 4️⃣ Common Gotchas & How to Fix Them | Issue | Why it Happens | Fix | |-------|----------------|-----| | GIF appears jerky | Frame‑capture isn’t synchronized with the render loop. | Use requestAnimationFrame and a fixed‑time accumulator ( delta ) to guarantee exactly FPS captures per second. | | Colors look washed out | The canvas is using sRGB but gif.js expects linear RGB. | Add renderer.outputEncoding = THREE.sRGBEncoding; before recording, and call renderer.toneMapping = THREE.ACESFilmicToneMapping; for better contrast. | | File size > 5 MB | Too many frames or high resolution. | Reduce width/height ( renderer.setSize(480, 270) ), lower quality in GIF options, or use a palette‑reduction step ( gif.js does this automatically if quality ≤ 10). | | Loop doesn’t close perfectly | The first and last frames aren’t identical. | Make the animation mathematically periodic (e.g., use Math.sin(t) / Math.cos(t) ) or duplicate the first frame at the end. | | Browser freezes during encoding | Large GIFs block the main thread. | Increase workers in the GIF constructor (e.g., workers: 4 ) or off‑load the process to a Web Worker manually. | 5️⃣ Extending the Example | Feature | How to add it | |---------|---------------| | UI controls | Use a lightweight UI library like Tweakpane to expose bloom strength, rotation speed, or GIF length. | | Export to APNG | Replace gif.js with apngjs (same API, lossless transparency). | | Batch render | Wrap the code in a function that accepts a JSON description of multiple scenes, then loops over them, concatenating the resulting GIFs into a zip (use JSZip ). | | Server‑side rendering | For high‑resolution outputs (≥ 1080p) run the same Three.js code in Node + headless‑gl and pipe the frames into ffmpeg → MP4 → GIF. | | Interactive GIF | Record a short “preview” with the UI, then embed the GIF in a <canvas> that restores interactivity when the user clicks (swap the static GIF for the live Three.js canvas). | 6️⃣ Where to Learn More | Resource | Type | Highlights | |----------|------|------------| | Official Affect3D repo | GitHub (open‑source) | Boilerplates, docs, and a built‑in GIF recorder example. | | Three.js Journey (by Bruno Simon) | Paid video course | Deep dive into post‑processing pipelines, which translate directly to Affect3D. | | “Creating GIFs with WebGL” (MDN blog) | Article | Discusses pitfalls of pixel‑capture and cross‑browser considerations. | | “Animating with Bloom & Film Grain” (Medium) | Tutorial | Shows how to combine multiple passes for cinematic moods. | | gif.js documentation | API reference | Options for quality, worker count, and palette control. | Quick link: https://github.com/affect3d/affect3d (clone, npm i , npm start → you’ll see a live editor that already includes a “Export GIF” button.) 7️⃣ TL;DR – One‑Liner Cheat Sheet // After setting up your Three.js scene: const gif = new GIF(workers:2, quality:10); gif.addFrame(canvasCtx.getImageData(0,0,w,h), delay:1000/30); gif.on('finished',blob=>download(blob,'my‑loop.gif')); gif.render(); That’s all you need to turn any Affect3D animation into a sharable GIF. Enjoy creating mood‑rich loops! If you hit a snag or want ideas for a specific visual style (neon cyber‑punk, moody noir, pastel dreamscape), just let me know and I can walk you through a custom shader or post‑process chain. Happy animating! | | Capture | Every 1/30 second we
// Capture the current canvas as a frame every 1/FPS second if (frameCount % Math.round(60 / FPS) === 0) // Grab the raw pixel data const ctx = renderer.domElement.getContext('2d'); const imgData = ctx.getImageData(0, 0, renderer.domElement.width, renderer.domElement.height); gif.addFrame(imgData, delay: 1000 / FPS ); 4️⃣ Common Gotchas & How to Fix Them
// Simple geometry const geometry = new THREE.TorusKnotGeometry(0.8, 0.2, 150, 20); const material = new THREE.MeshStandardMaterial( color: 0xff4e50, metalness: 0.7, roughness: 0.2 ); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh);
// ------------------------------------------------- // 2️⃣ Post‑processing (the “affect” part) // ------------------------------------------------- const composer = new EffectComposer(renderer); composer.addPass(new RenderPass(scene, camera));
const scene = new THREE.Scene(); scene.background = new THREE.Color(0x0a0a0a);
| Step | Description | |------|-------------| | | A rotating torus‑knot with a metallic‑red material. | | Lighting | Directional + ambient light for depth. | | Post‑processing | UnrealBloomPass adds a soft glow that gives the animation its “affective” feel. | | Capture | Every 1/30 second we pull the raw pixel buffer from the canvas and push it into gif.js . | | Export | Once 2 seconds of animation are recorded, the GIF is assembled and automatically downloaded. | Tip: Swap UnrealBloomPass for FilmPass , GlitchPass , or a custom shader to change the mood instantly. 4️⃣ Common Gotchas & How to Fix Them | Issue | Why it Happens | Fix | |-------|----------------|-----| | GIF appears jerky | Frame‑capture isn’t synchronized with the render loop. | Use requestAnimationFrame and a fixed‑time accumulator ( delta ) to guarantee exactly FPS captures per second. | | Colors look washed out | The canvas is using sRGB but gif.js expects linear RGB. | Add renderer.outputEncoding = THREE.sRGBEncoding; before recording, and call renderer.toneMapping = THREE.ACESFilmicToneMapping; for better contrast. | | File size > 5 MB | Too many frames or high resolution. | Reduce width/height ( renderer.setSize(480, 270) ), lower quality in GIF options, or use a palette‑reduction step ( gif.js does this automatically if quality ≤ 10). | | Loop doesn’t close perfectly | The first and last frames aren’t identical. | Make the animation mathematically periodic (e.g., use Math.sin(t) / Math.cos(t) ) or duplicate the first frame at the end. | | Browser freezes during encoding | Large GIFs block the main thread. | Increase workers in the GIF constructor (e.g., workers: 4 ) or off‑load the process to a Web Worker manually. | 5️⃣ Extending the Example | Feature | How to add it | |---------|---------------| | UI controls | Use a lightweight UI library like Tweakpane to expose bloom strength, rotation speed, or GIF length. | | Export to APNG | Replace gif.js with apngjs (same API, lossless transparency). | | Batch render | Wrap the code in a function that accepts a JSON description of multiple scenes, then loops over them, concatenating the resulting GIFs into a zip (use JSZip ). | | Server‑side rendering | For high‑resolution outputs (≥ 1080p) run the same Three.js code in Node + headless‑gl and pipe the frames into ffmpeg → MP4 → GIF. | | Interactive GIF | Record a short “preview” with the UI, then embed the GIF in a <canvas> that restores interactivity when the user clicks (swap the static GIF for the live Three.js canvas). | 6️⃣ Where to Learn More | Resource | Type | Highlights | |----------|------|------------| | Official Affect3D repo | GitHub (open‑source) | Boilerplates, docs, and a built‑in GIF recorder example. | | Three.js Journey (by Bruno Simon) | Paid video course | Deep dive into post‑processing pipelines, which translate directly to Affect3D. | | “Creating GIFs with WebGL” (MDN blog) | Article | Discusses pitfalls of pixel‑capture and cross‑browser considerations. | | “Animating with Bloom & Film Grain” (Medium) | Tutorial | Shows how to combine multiple passes for cinematic moods. | | gif.js documentation | API reference | Options for quality, worker count, and palette control. | Quick link: https://github.com/affect3d/affect3d (clone, npm i , npm start → you’ll see a live editor that already includes a “Export GIF” button.) 7️⃣ TL;DR – One‑Liner Cheat Sheet // After setting up your Three.js scene: const gif = new GIF(workers:2, quality:10); gif.addFrame(canvasCtx.getImageData(0,0,w,h), delay:1000/30); gif.on('finished',blob=>download(blob,'my‑loop.gif')); gif.render(); That’s all you need to turn any Affect3D animation into a sharable GIF. Enjoy creating mood‑rich loops! If you hit a snag or want ideas for a specific visual style (neon cyber‑punk, moody noir, pastel dreamscape), just let me know and I can walk you through a custom shader or post‑process chain. Happy animating!
// Capture the current canvas as a frame every 1/FPS second if (frameCount % Math.round(60 / FPS) === 0) // Grab the raw pixel data const ctx = renderer.domElement.getContext('2d'); const imgData = ctx.getImageData(0, 0, renderer.domElement.width, renderer.domElement.height); gif.addFrame(imgData, delay: 1000 / FPS );
// Simple geometry const geometry = new THREE.TorusKnotGeometry(0.8, 0.2, 150, 20); const material = new THREE.MeshStandardMaterial( color: 0xff4e50, metalness: 0.7, roughness: 0.2 ); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh);