Skip to content
Draft
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
31 changes: 31 additions & 0 deletions examples/_shared/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// examples/_shared/setup.js
import * as THREE from "three/webgpu";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

export function setup({ fov = 60 } = {}) {
const canvas = document.getElementById("canvas");
const renderer = new THREE.WebGPURenderer({ canvas, antialias: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(fov, innerWidth / innerHeight, 0.1, 1000);
const controls = new OrbitControls(camera, renderer.domElement);

function resize() {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
}
addEventListener("resize", resize);

function loop(fn) {
renderer.setAnimationLoop((t) => {
controls.update();
fn?.(t / 1000, renderer, scene, camera);
renderer.render(scene, camera);
});
}

return { THREE, renderer, scene, camera, controls, loop };
}
30 changes: 3 additions & 27 deletions examples/anisotropic-fbm-streaks/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { setup } from "../_shared/setup.js";
import { Inspector } from "three/addons/inspector/Inspector.js";
import {
Fn,
Expand All @@ -13,28 +13,13 @@ import {
vec3,
vec4,
} from "three/tsl";
import * as THREE from "three/webgpu";
import { simplexNoise3 } from "../../src/index.js";

// Scene setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const { THREE, renderer, scene, camera, loop } = setup({ fov: 60 });
camera.position.set(0, 0, 2.2);

const renderer = new THREE.WebGPURenderer({
canvas: document.getElementById("canvas"),
antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0x000000);
renderer.inspector = new Inspector();
new OrbitControls(camera, renderer.domElement);

// Controls - define uniforms outside the shader function so Inspector can access them
const scaleX = uniform(0.25);
Expand Down Expand Up @@ -123,13 +108,4 @@ gui.add(fbmLacunarity, "value", 0.1, 4.0, 0.1).name("fbmLacunarity");
gui.add(fbmGain, "value", 0.25, 1.0, 0.01).name("fbmGain");
gui.add(animate, "value", 0, 1, 1).name("animate");

function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener("resize", onResize);

renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
loop();
31 changes: 7 additions & 24 deletions examples/cinematic-gallery/main.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { setup } from "../_shared/setup.js";
import headURL from "@assets/head256x256x109.zip?url";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { unzipSync } from "three/addons/libs/fflate.module.js";
import { texture3D, uniform, pass, color, screenUV } from "three/tsl";
import { knotMorphPosition } from "../../src/knotMorph.js";
import {
buildSphericalWaveCopyKernel,
averageIntensityProjection,
} from "../../src/index.js";
import * as THREE from "three/webgpu";

// Choose cinematic aspect based on viewport orientation: 16:9 (landscape) or 9:16 (portrait)
function getCinematicAspect(w, h) {
Expand All @@ -16,14 +15,11 @@ function getCinematicAspect(w, h) {
let childAspect = getCinematicAspect(window.innerWidth, window.innerHeight);

// Parent (main) scene and camera
const parentScene = new THREE.Scene();
const parentCamera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const { THREE, renderer, camera: parentCamera, controls } = setup({ fov: 60 });
parentCamera.position.set(0, 1.25, 2.5);
controls.update();

const parentScene = new THREE.Scene();

// Child A (offscreen) scene and camera - Raymarch Head
const childScene = new THREE.Scene();
Expand All @@ -37,15 +33,7 @@ const childCamera2 = new THREE.PerspectiveCamera(60, childAspect, 0.05, 1000);
childCamera2.position.set(0, 0, 5);
childCamera2.updateProjectionMatrix();

// Renderer
const renderer = new THREE.WebGPURenderer({
canvas: document.getElementById("canvas"),
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000);

// Parent controls (user controls)
const controls = new OrbitControls(parentCamera, renderer.domElement);
controls.target.set(0, 1.0, 0);
controls.update();

Expand Down Expand Up @@ -469,11 +457,6 @@ new THREE.FileLoader()
childCamera2.lookAt(0, 0, 0);
}

// Resize handling for renderer and parent camera, then update layout
window.addEventListener("resize", () => {
renderer.setSize(window.innerWidth, window.innerHeight);
parentCamera.aspect = window.innerWidth / window.innerHeight;
parentCamera.updateProjectionMatrix();
updateLayout();
});
// Additional resize handling for layout updates
window.addEventListener("resize", updateLayout);
});
27 changes: 4 additions & 23 deletions examples/hello-world/main.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
// examples/main.js
import * as THREE from "three/webgpu";
import { setup } from "../_shared/setup.js";
import { float } from "three/tsl";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { exampleTSLFunction } from "../../src/index.js"; // Import locally from src/ for dev

// Set up scene, camera, renderer...
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGPURenderer({
canvas: document.getElementById("canvas"),
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

new OrbitControls(camera, renderer.domElement);
const { THREE, scene, camera, loop } = setup({ fov: 75 });

// Use your TSL function in a material (uniforms will get auto-GUI)
const material = new THREE.MeshBasicNodeMaterial(); // Or whatever TSL material
Expand All @@ -27,9 +12,5 @@ material.colorNode = exampleTSLFunction(float(1.0));
const mesh = new THREE.Mesh(new THREE.BoxGeometry(), material);
scene.add(mesh);

// Animate/render loop
async function animate() {
requestAnimationFrame(animate);
await renderer.renderAsync(scene, camera);
}
animate();
// Start animation loop
loop();
46 changes: 7 additions & 39 deletions examples/knot-morph/main.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
// examples/knot-morph/main.js
import * as THREE from "three/webgpu";
import { setup } from "../_shared/setup.js";
import { color } from "three/tsl";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { knotMorphPosition } from "../../src/knotMorph.js"; // Import from dedicated module

// Set up scene, camera, renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const { THREE, renderer, scene, camera, loop } = setup({ fov: 75 });
camera.position.z = 5; // Adjusted for better view of knot scale

const canvas = document.getElementById("canvas");
const renderer = new THREE.WebGPURenderer({ canvas, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);

// Controls for interaction
new OrbitControls(camera, renderer.domElement);

// Create starting geometry (p=2, q=3 for trefoil knot)
const startGeo = new THREE.TorusKnotGeometry(1, 0.4, 128, 32, 2, 3);

Expand All @@ -45,21 +31,17 @@ material.colorNode = color(0x00ff00);
const mesh = new THREE.Mesh(startGeo, material);
scene.add(mesh);

// Animation loop
let time = 0;
function animate() {
requestAnimationFrame(animate);
time += 0.01;

// Start animation loop
loop((t) => {
// Ping-pong mix factor for looping morph (0 to 1 and back)
const mixFactor = Math.abs(Math.sin(time * 0.5));
const mixFactor = Math.abs(Math.sin(t * 0.5));
material.positionNode = knotMorphPosition({ mixFactor });

// Dynamic rotation (ported from original)
const quaternion = new THREE.Quaternion();

const slowTime = time * 0.3;
const fastTime = time * 1.2;
const slowTime = t * 0.3;
const fastTime = t * 1.2;

// Y-axis rotation
const ySpeedMultiplier = Math.sin(slowTime) * Math.sin(slowTime * 0.7);
Expand Down Expand Up @@ -92,18 +74,4 @@ function animate() {
// Combine and apply rotations
quaternion.multiply(yQuat).multiply(xQuat).multiply(zQuat);
mesh.quaternion.multiply(quaternion);

renderer.render(scene, camera);
}

// Initialize renderer and start animation
renderer.init().then(() => {
animate();
});

// Handle resize
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
56 changes: 14 additions & 42 deletions examples/portal-door-transition/main.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import * as THREE from "three/webgpu";
import { setup } from "../_shared/setup.js";
import { pass, uniform, mix, Fn } from "three/tsl";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

// ============================================================================
// Scene Setup
// ============================================================================

const { THREE, renderer, camera: mainCamera, controls } = setup({ fov: 60 });
mainCamera.position.set(0, 1.5, 5);
controls.target.set(0, 1, 0);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.update();

// Main gallery scene
const mainScene = new THREE.Scene();
mainScene.background = new THREE.Color(0x222222);
Expand All @@ -18,17 +24,9 @@ const portalSceneB = new THREE.Scene();
portalSceneB.background = new THREE.Color(0x001133); // Cool

// ============================================================================
// Cameras
// Additional Cameras for Portals
// ============================================================================

const mainCamera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
100
);
mainCamera.position.set(0, 1.5, 5);

const portalCameraA = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
Expand All @@ -46,33 +44,16 @@ const portalCameraB = new THREE.PerspectiveCamera(
portalCameraB.position.set(0, 2, 5);

// ============================================================================
// Renderer
// Additional Controls for Portals
// ============================================================================

const renderer = new THREE.WebGPURenderer({
canvas: document.getElementById("canvas"),
antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);

// ============================================================================
// Controls
// ============================================================================

const controls = new OrbitControls(mainCamera, renderer.domElement);
controls.target.set(0, 1, 0);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.update();

const controlsA = new OrbitControls(portalCameraA, renderer.domElement);
const controlsA = new THREE.OrbitControls(portalCameraA, renderer.domElement);
controlsA.target.set(0, 0, 0);
controlsA.enableDamping = true;
controlsA.dampingFactor = 0.05;
controlsA.enabled = false; // Start disabled

const controlsB = new OrbitControls(portalCameraB, renderer.domElement);
const controlsB = new THREE.OrbitControls(portalCameraB, renderer.domElement);
controlsB.target.set(0, 0, 0);
controlsB.enableDamping = true;
controlsB.dampingFactor = 0.05;
Expand Down Expand Up @@ -468,22 +449,13 @@ renderer.setAnimationLoop(() => {
});

// ============================================================================
// Window Resize Handler
// Additional Resize Handler for Portal Cameras
// ============================================================================

window.addEventListener("resize", () => {
const width = window.innerWidth;
const height = window.innerHeight;
const aspect = width / height;

mainCamera.aspect = aspect;
mainCamera.updateProjectionMatrix();

const aspect = window.innerWidth / window.innerHeight;
portalCameraA.aspect = aspect;
portalCameraA.updateProjectionMatrix();

portalCameraB.aspect = aspect;
portalCameraB.updateProjectionMatrix();

renderer.setSize(width, height);
});
Loading