diff --git a/examples-testing/changes.patch b/examples-testing/changes.patch index b13bbf8db..e69de29bb 100644 --- a/examples-testing/changes.patch +++ b/examples-testing/changes.patch @@ -1,16216 +0,0 @@ -diff --git a/examples-testing/examples/css2d_label.ts b/examples-testing/examples/css2d_label.ts -index 48a2d1f0..e7260210 100644 ---- a/examples-testing/examples/css2d_label.ts -+++ b/examples-testing/examples/css2d_label.ts -@@ -7,7 +7,7 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - let gui; - --let camera, scene, renderer, labelRenderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, labelRenderer: CSS2DRenderer; - - const layers = { - 'Toggle Name': function () { -@@ -28,7 +28,7 @@ const layers = { - const clock = new THREE.Clock(); - const textureLoader = new THREE.TextureLoader(); - --let moon; -+let moon: THREE.Mesh; - - init(); - animate(); -@@ -63,7 +63,7 @@ function init() { - normalMap: textureLoader.load('textures/planets/earth_normal_2048.jpg'), - normalScale: new THREE.Vector2(0.85, 0.85), - }); -- earthMaterial.map.colorSpace = THREE.SRGBColorSpace; -+ earthMaterial.map!.colorSpace = THREE.SRGBColorSpace; - const earth = new THREE.Mesh(earthGeometry, earthMaterial); - scene.add(earth); - -@@ -72,7 +72,7 @@ function init() { - shininess: 5, - map: textureLoader.load('textures/planets/moon_1024.jpg'), - }); -- moonMaterial.map.colorSpace = THREE.SRGBColorSpace; -+ moonMaterial.map!.colorSpace = THREE.SRGBColorSpace; - moon = new THREE.Mesh(moonGeometry, moonMaterial); - scene.add(moon); - -diff --git a/examples-testing/examples/css3d_molecules.ts b/examples-testing/examples/css3d_molecules.ts -index 53847260..f08bb34a 100644 ---- a/examples-testing/examples/css3d_molecules.ts -+++ b/examples-testing/examples/css3d_molecules.ts -@@ -5,11 +5,11 @@ import { PDBLoader } from 'three/addons/loaders/PDBLoader.js'; - import { CSS3DRenderer, CSS3DObject, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; --let controls; --let root; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: CSS3DRenderer; -+let controls: TrackballControls; -+let root: THREE.Object3D; - --const objects = []; -+const objects: Array = []; - const tmpVec1 = new THREE.Vector3(); - const tmpVec2 = new THREE.Vector3(); - const tmpVec3 = new THREE.Vector3(); -@@ -49,7 +49,7 @@ const params = { - }; - - const loader = new PDBLoader(); --const colorSpriteMap = {}; -+const colorSpriteMap: { [element: string]: string | undefined } = {}; - const baseSprite = document.createElement('img'); - - init(); -@@ -68,7 +68,7 @@ function init() { - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); -- document.getElementById('container').appendChild(renderer.domElement); -+ document.getElementById('container')!.appendChild(renderer.domElement); - - // - -@@ -96,7 +96,7 @@ function init() { - gui.open(); - } - --function changeVizType(value) { -+function changeVizType(value: number) { - if (value === 0) showAtoms(); - else if (value === 1) showBonds(); - else showAtomsBonds(); -@@ -148,7 +148,7 @@ function showAtomsBonds() { - - // - --function colorify(ctx, width, height, color) { -+function colorify(ctx: CanvasRenderingContext2D, width: number, height: number, color: THREE.Color) { - const r = color.r, - g = color.g, - b = color.b; -@@ -165,7 +165,7 @@ function colorify(ctx, width, height, color) { - ctx.putImageData(imageData, 0, 0); - } - --function imageToCanvas(image) { -+function imageToCanvas(image: HTMLImageElement) { - const width = image.width; - const height = image.height; - -@@ -174,7 +174,7 @@ function imageToCanvas(image) { - canvas.width = width; - canvas.height = height; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - context.drawImage(image, 0, 0, width, height); - - return canvas; -@@ -182,12 +182,12 @@ function imageToCanvas(image) { - - // - --function loadMolecule(model) { -+function loadMolecule(model: string) { - const url = 'models/pdb/' + model; - - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; -- object.parent.remove(object); -+ object.parent!.remove(object); - } - - objects.length = 0; -@@ -198,7 +198,7 @@ function loadMolecule(model) { - const json = pdb.json; - - geometryAtoms.computeBoundingBox(); -- geometryAtoms.boundingBox.getCenter(offset).negate(); -+ geometryAtoms.boundingBox!.getCenter(offset).negate(); - - geometryAtoms.translate(offset.x, offset.y, offset.z); - geometryBonds.translate(offset.x, offset.y, offset.z); -@@ -218,7 +218,7 @@ function loadMolecule(model) { - - if (!colorSpriteMap[element]) { - const canvas = imageToCanvas(baseSprite); -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - - colorify(context, canvas.width, canvas.height, color); - -@@ -227,7 +227,7 @@ function loadMolecule(model) { - colorSpriteMap[element] = dataUrl; - } - -- const colorSprite = colorSpriteMap[element]; -+ const colorSprite = colorSpriteMap[element]!; - - const atom = document.createElement('img'); - atom.src = colorSprite; -diff --git a/examples-testing/examples/css3d_orthographic.ts b/examples-testing/examples/css3d_orthographic.ts -index 4aabbed0..67e41fde 100644 ---- a/examples-testing/examples/css3d_orthographic.ts -+++ b/examples-testing/examples/css3d_orthographic.ts -@@ -2,11 +2,11 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; --import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -+import { Controller, GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.OrthographicCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let scene2, renderer2; -+let scene2: THREE.Scene, renderer2: CSS3DRenderer; - - const frustumSize = 500; - -@@ -75,18 +75,18 @@ function init() { - renderer2 = new CSS3DRenderer(); - renderer2.setSize(window.innerWidth, window.innerHeight); - renderer2.domElement.style.position = 'absolute'; -- renderer2.domElement.style.top = 0; -+ renderer2.domElement.style.top = '0'; - document.body.appendChild(renderer2.domElement); - - const controls = new OrbitControls(camera, renderer2.domElement); - controls.minZoom = 0.5; - controls.maxZoom = 2; - -- function createPlane(width, height, cssColor, pos, rot) { -+ function createPlane(width: number, height: number, cssColor: string, pos: THREE.Vector3, rot: THREE.Euler) { - const element = document.createElement('div'); - element.style.width = width + 'px'; - element.style.height = height + 'px'; -- element.style.opacity = 0.75; -+ element.style.opacity = '0.75'; - element.style.background = cssColor; - - const object = new CSS3DObject(element); -@@ -133,12 +133,12 @@ function createPanel() { - - const settings = { - setViewOffset() { -- folder1.children[1].enable().setValue(window.innerWidth); -- folder1.children[2].enable().setValue(window.innerHeight); -- folder1.children[3].enable().setValue(0); -- folder1.children[4].enable().setValue(0); -- folder1.children[5].enable().setValue(window.innerWidth); -- folder1.children[6].enable().setValue(window.innerHeight); -+ (folder1.children[1] as Controller).enable().setValue(window.innerWidth); -+ (folder1.children[2] as Controller).enable().setValue(window.innerHeight); -+ (folder1.children[3] as Controller).enable().setValue(0); -+ (folder1.children[4] as Controller).enable().setValue(0); -+ (folder1.children[5] as Controller).enable().setValue(window.innerWidth); -+ (folder1.children[6] as Controller).enable().setValue(window.innerHeight); - }, - fullWidth: 0, - fullHeight: 0, -@@ -147,12 +147,12 @@ function createPanel() { - width: 0, - height: 0, - clearViewOffset() { -- folder1.children[1].setValue(0).disable(); -- folder1.children[2].setValue(0).disable(); -- folder1.children[3].setValue(0).disable(); -- folder1.children[4].setValue(0).disable(); -- folder1.children[5].setValue(0).disable(); -- folder1.children[6].setValue(0).disable(); -+ (folder1.children[1] as Controller).setValue(0).disable(); -+ (folder1.children[2] as Controller).setValue(0).disable(); -+ (folder1.children[3] as Controller).setValue(0).disable(); -+ (folder1.children[4] as Controller).setValue(0).disable(); -+ (folder1.children[5] as Controller).setValue(0).disable(); -+ (folder1.children[6] as Controller).setValue(0).disable(); - camera.clearViewOffset(); - }, - }; -@@ -185,7 +185,21 @@ function createPanel() { - folder1.add(settings, 'clearViewOffset'); - } - --function updateCameraViewOffset({ fullWidth, fullHeight, x, y, width, height }) { -+function updateCameraViewOffset({ -+ fullWidth, -+ fullHeight, -+ x, -+ y, -+ width, -+ height, -+}: { -+ fullWidth?: number; -+ fullHeight?: number; -+ x?: number; -+ y?: number; -+ width?: number; -+ height?: number; -+}) { - if (!camera.view) { - camera.setViewOffset( - fullWidth || window.innerWidth, -diff --git a/examples-testing/examples/css3d_periodictable.ts b/examples-testing/examples/css3d_periodictable.ts -index e3a33f79..516df464 100644 ---- a/examples-testing/examples/css3d_periodictable.ts -+++ b/examples-testing/examples/css3d_periodictable.ts -@@ -597,11 +597,16 @@ const table = [ - 7, - ]; - --let camera, scene, renderer; --let controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: CSS3DRenderer; -+let controls: TrackballControls; - --const objects = []; --const targets = { table: [], sphere: [], helix: [], grid: [] }; -+const objects: CSS3DObject[] = []; -+const targets: { -+ table: THREE.Object3D[]; -+ sphere: THREE.Object3D[]; -+ helix: THREE.Object3D[]; -+ grid: THREE.Object3D[]; -+} = { table: [], sphere: [], helix: [], grid: [] }; - - init(); - animate(); -@@ -621,12 +626,12 @@ function init() { - - const number = document.createElement('div'); - number.className = 'number'; -- number.textContent = i / 5 + 1; -+ number.textContent = `${i / 5 + 1}`; - element.appendChild(number); - - const symbol = document.createElement('div'); - symbol.className = 'symbol'; -- symbol.textContent = table[i]; -+ symbol.textContent = table[i] as string; - element.appendChild(symbol); - - const details = document.createElement('div'); -@@ -645,8 +650,8 @@ function init() { - // - - const object = new THREE.Object3D(); -- object.position.x = table[i + 3] * 140 - 1330; -- object.position.y = -(table[i + 4] * 180) + 990; -+ object.position.x = (table[i + 3] as number) * 140 - 1330; -+ object.position.y = -((table[i + 4] as number) * 180) + 990; - - targets.table.push(object); - } -@@ -705,7 +710,7 @@ function init() { - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); -- document.getElementById('container').appendChild(renderer.domElement); -+ document.getElementById('container')!.appendChild(renderer.domElement); - - // - -@@ -714,22 +719,22 @@ function init() { - controls.maxDistance = 6000; - controls.addEventListener('change', render); - -- const buttonTable = document.getElementById('table'); -+ const buttonTable = document.getElementById('table')!; - buttonTable.addEventListener('click', function () { - transform(targets.table, 2000); - }); - -- const buttonSphere = document.getElementById('sphere'); -+ const buttonSphere = document.getElementById('sphere')!; - buttonSphere.addEventListener('click', function () { - transform(targets.sphere, 2000); - }); - -- const buttonHelix = document.getElementById('helix'); -+ const buttonHelix = document.getElementById('helix')!; - buttonHelix.addEventListener('click', function () { - transform(targets.helix, 2000); - }); - -- const buttonGrid = document.getElementById('grid'); -+ const buttonGrid = document.getElementById('grid')!; - buttonGrid.addEventListener('click', function () { - transform(targets.grid, 2000); - }); -@@ -741,7 +746,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function transform(targets, duration) { -+function transform(targets: THREE.Object3D[], duration: number) { - TWEEN.removeAll(); - - for (let i = 0; i < objects.length; i++) { -@@ -765,7 +770,7 @@ function transform(targets, duration) { - .start(); - } - -- new TWEEN.Tween(this) -+ new TWEEN.Tween({}) - .to({}, duration * 2) - .onUpdate(render) - .start(); -diff --git a/examples-testing/examples/css3d_sandbox.ts b/examples-testing/examples/css3d_sandbox.ts -index 1088b84b..02f1fa75 100644 ---- a/examples-testing/examples/css3d_sandbox.ts -+++ b/examples-testing/examples/css3d_sandbox.ts -@@ -2,13 +2,13 @@ import * as THREE from 'three'; - - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; --import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -+import { Controller, GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let scene2, renderer2; -+let scene2: THREE.Scene, renderer2: CSS3DRenderer; - --let controls; -+let controls: TrackballControls; - - init(); - animate(); -@@ -35,7 +35,7 @@ function init() { - const element = document.createElement('div'); - element.style.width = '100px'; - element.style.height = '100px'; -- element.style.opacity = i < 5 ? 0.5 : 1; -+ element.style.opacity = `${i < 5 ? 0.5 : 1}`; - element.style.background = new THREE.Color(Math.random() * 0xffffff).getStyle(); - - const object = new CSS3DObject(element); -@@ -67,7 +67,7 @@ function init() { - renderer2 = new CSS3DRenderer(); - renderer2.setSize(window.innerWidth, window.innerHeight); - renderer2.domElement.style.position = 'absolute'; -- renderer2.domElement.style.top = 0; -+ renderer2.domElement.style.top = '0'; - document.body.appendChild(renderer2.domElement); - - controls = new TrackballControls(camera, renderer2.domElement); -@@ -101,12 +101,12 @@ function createPanel() { - - const settings = { - setViewOffset() { -- folder1.children[1].enable().setValue(window.innerWidth); -- folder1.children[2].enable().setValue(window.innerHeight); -- folder1.children[3].enable().setValue(0); -- folder1.children[4].enable().setValue(0); -- folder1.children[5].enable().setValue(window.innerWidth); -- folder1.children[6].enable().setValue(window.innerHeight); -+ (folder1.children[1] as Controller).enable().setValue(window.innerWidth); -+ (folder1.children[2] as Controller).enable().setValue(window.innerHeight); -+ (folder1.children[3] as Controller).enable().setValue(0); -+ (folder1.children[4] as Controller).enable().setValue(0); -+ (folder1.children[5] as Controller).enable().setValue(window.innerWidth); -+ (folder1.children[6] as Controller).enable().setValue(window.innerHeight); - }, - fullWidth: 0, - fullHeight: 0, -@@ -115,12 +115,12 @@ function createPanel() { - width: 0, - height: 0, - clearViewOffset() { -- folder1.children[1].setValue(0).disable(); -- folder1.children[2].setValue(0).disable(); -- folder1.children[3].setValue(0).disable(); -- folder1.children[4].setValue(0).disable(); -- folder1.children[5].setValue(0).disable(); -- folder1.children[6].setValue(0).disable(); -+ (folder1.children[1] as Controller).setValue(0).disable(); -+ (folder1.children[2] as Controller).setValue(0).disable(); -+ (folder1.children[3] as Controller).setValue(0).disable(); -+ (folder1.children[4] as Controller).setValue(0).disable(); -+ (folder1.children[5] as Controller).setValue(0).disable(); -+ (folder1.children[6] as Controller).setValue(0).disable(); - camera.clearViewOffset(); - }, - }; -@@ -153,7 +153,21 @@ function createPanel() { - folder1.add(settings, 'clearViewOffset'); - } - --function updateCameraViewOffset({ fullWidth, fullHeight, x, y, width, height }) { -+function updateCameraViewOffset({ -+ fullWidth, -+ fullHeight, -+ x, -+ y, -+ width, -+ height, -+}: { -+ fullWidth?: number; -+ fullHeight?: number; -+ x?: number; -+ y?: number; -+ width?: number; -+ height?: number; -+}) { - if (!camera.view) { - camera.setViewOffset( - fullWidth || window.innerWidth, -diff --git a/examples-testing/examples/css3d_sprites.ts b/examples-testing/examples/css3d_sprites.ts -index dfe24e79..93f2c07b 100644 ---- a/examples-testing/examples/css3d_sprites.ts -+++ b/examples-testing/examples/css3d_sprites.ts -@@ -4,12 +4,12 @@ import TWEEN from 'three/addons/libs/tween.module.js'; - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js'; - --let camera, scene, renderer; --let controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: CSS3DRenderer; -+let controls: TrackballControls; - - const particlesTotal = 512; --const positions = []; --const objects = []; -+const positions: number[] = []; -+const objects: CSS3DSprite[] = []; - let current = 0; - - init(); -@@ -25,7 +25,7 @@ function init() { - const image = document.createElement('img'); - image.addEventListener('load', function () { - for (let i = 0; i < particlesTotal; i++) { -- const object = new CSS3DSprite(image.cloneNode()); -+ const object = new CSS3DSprite(image.cloneNode() as typeof image); - (object.position.x = Math.random() * 4000 - 2000), - (object.position.y = Math.random() * 4000 - 2000), - (object.position.z = Math.random() * 4000 - 2000); -@@ -93,7 +93,7 @@ function init() { - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); -- document.getElementById('container').appendChild(renderer.domElement); -+ document.getElementById('container')!.appendChild(renderer.domElement); - - // - -@@ -131,7 +131,7 @@ function transition() { - .start(); - } - -- new TWEEN.Tween(this) -+ new TWEEN.Tween({}) - .to({}, duration * 3) - .onComplete(transition) - .start(); -diff --git a/examples-testing/examples/css3d_youtube.ts b/examples-testing/examples/css3d_youtube.ts -index 62652f87..3dcc2f12 100644 ---- a/examples-testing/examples/css3d_youtube.ts -+++ b/examples-testing/examples/css3d_youtube.ts -@@ -3,10 +3,10 @@ import * as THREE from 'three'; - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; - --let camera, scene, renderer; --let controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: CSS3DRenderer; -+let controls: TrackballControls; - --function Element(id, x, y, z, ry) { -+function Element(id: string, x: number, y: number, z: number, ry: number) { - const div = document.createElement('div'); - div.style.width = '480px'; - div.style.height = '360px'; -@@ -30,7 +30,7 @@ init(); - animate(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.set(500, 350, 750); -@@ -42,10 +42,10 @@ function init() { - container.appendChild(renderer.domElement); - - const group = new THREE.Group(); -- group.add(new Element('SJOz3qjfQXU', 0, 0, 240, 0)); -- group.add(new Element('Y2-xZ-1HE-Q', 240, 0, 0, Math.PI / 2)); -- group.add(new Element('IrydklNpcFI', 0, 0, -240, Math.PI)); -- group.add(new Element('9ubytEsCaS0', -240, 0, 0, -Math.PI / 2)); -+ group.add(Element('SJOz3qjfQXU', 0, 0, 240, 0)); -+ group.add(Element('Y2-xZ-1HE-Q', 240, 0, 0, Math.PI / 2)); -+ group.add(Element('IrydklNpcFI', 0, 0, -240, Math.PI)); -+ group.add(Element('9ubytEsCaS0', -240, 0, 0, -Math.PI / 2)); - scene.add(group); - - controls = new TrackballControls(camera, renderer.domElement); -@@ -55,7 +55,7 @@ function init() { - - // Block iframe events when dragging camera - -- const blocker = document.getElementById('blocker'); -+ const blocker = document.getElementById('blocker')!; - blocker.style.display = 'none'; - - controls.addEventListener('start', function () { -diff --git a/examples-testing/examples/games_fps.ts b/examples-testing/examples/games_fps.ts -index 4c459f9b..b714f591 100644 ---- a/examples-testing/examples/games_fps.ts -+++ b/examples-testing/examples/games_fps.ts -@@ -39,7 +39,7 @@ directionalLight.shadow.radius = 4; - directionalLight.shadow.bias = -0.00006; - scene.add(directionalLight); - --const container = document.getElementById('container'); -+const container = document.getElementById('container')!; - - const renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); -@@ -51,9 +51,9 @@ renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - const stats = new Stats(); --stats.domElement.style.position = 'absolute'; --stats.domElement.style.top = '0px'; --container.appendChild(stats.domElement); -+stats.dom.style.position = 'absolute'; -+stats.dom.style.top = '0px'; -+container.appendChild(stats.dom); - - const GRAVITY = 30; - -@@ -65,7 +65,13 @@ const STEPS_PER_FRAME = 5; - const sphereGeometry = new THREE.IcosahedronGeometry(SPHERE_RADIUS, 5); - const sphereMaterial = new THREE.MeshLambertMaterial({ color: 0xdede8d }); - --const spheres = []; -+interface Sphere { -+ mesh: THREE.Mesh; -+ collider: THREE.Sphere; -+ velocity: THREE.Vector3; -+} -+ -+const spheres: Sphere[] = []; - let sphereIdx = 0; - - for (let i = 0; i < NUM_SPHERES; i++) { -@@ -92,7 +98,7 @@ const playerDirection = new THREE.Vector3(); - let playerOnFloor = false; - let mouseTime = 0; - --const keyStates = {}; -+const keyStates: { [eventCode: string]: boolean | undefined } = {}; - - const vector1 = new THREE.Vector3(); - const vector2 = new THREE.Vector3(); -@@ -167,7 +173,7 @@ function playerCollisions() { - } - } - --function updatePlayer(deltaTime) { -+function updatePlayer(deltaTime: number) { - let damping = Math.exp(-4 * deltaTime) - 1; - - if (!playerOnFloor) { -@@ -187,7 +193,7 @@ function updatePlayer(deltaTime) { - camera.position.copy(playerCollider.end); - } - --function playerSphereCollision(sphere) { -+function playerSphereCollision(sphere: Sphere) { - const center = vector1.addVectors(playerCollider.start, playerCollider.end).multiplyScalar(0.5); - - const sphere_center = sphere.collider.center; -@@ -242,7 +248,7 @@ function spheresCollisions() { - } - } - --function updateSpheres(deltaTime) { -+function updateSpheres(deltaTime: number) { - spheres.forEach(sphere => { - sphere.collider.center.addScaledVector(sphere.velocity, deltaTime); - -@@ -285,7 +291,7 @@ function getSideVector() { - return playerDirection; - } - --function controls(deltaTime) { -+function controls(deltaTime: number) { - // gives a bit of air control - const speedDelta = deltaTime * (playerOnFloor ? 25 : 8); - -@@ -320,12 +326,12 @@ loader.load('collision-world.glb', gltf => { - worldOctree.fromGraphNode(gltf.scene); - - gltf.scene.traverse(child => { -- if (child.isMesh) { -+ if ((child as THREE.Mesh).isMesh) { - child.castShadow = true; - child.receiveShadow = true; - -- if (child.material.map) { -- child.material.map.anisotropy = 4; -+ if (((child as THREE.Mesh).material as THREE.MeshStandardMaterial).map) { -+ ((child as THREE.Mesh).material as THREE.MeshStandardMaterial).map!.anisotropy = 4; - } - } - }); -diff --git a/examples-testing/examples/misc_animation_groups.ts b/examples-testing/examples/misc_animation_groups.ts -index 33fc4199..e5cc63bc 100644 ---- a/examples-testing/examples/misc_animation_groups.ts -+++ b/examples-testing/examples/misc_animation_groups.ts -@@ -2,8 +2,8 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let stats, clock; --let scene, camera, renderer, mixer; -+let stats: Stats, clock: THREE.Clock; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, mixer: THREE.AnimationMixer; - - init(); - -diff --git a/examples-testing/examples/misc_animation_keys.ts b/examples-testing/examples/misc_animation_keys.ts -index e2f141f9..a2e43b58 100644 ---- a/examples-testing/examples/misc_animation_keys.ts -+++ b/examples-testing/examples/misc_animation_keys.ts -@@ -2,8 +2,8 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let stats, clock; --let scene, camera, renderer, mixer; -+let stats: Stats, clock: THREE.Clock; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, mixer: THREE.AnimationMixer; - - init(); - -@@ -24,7 +24,10 @@ function init() { - // - - const geometry = new THREE.BoxGeometry(5, 5, 5); -- const material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }); -+ const material = new THREE.MeshBasicMaterial({ -+ color: 0xffffff, -+ transparent: true, -+ }); - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - -diff --git a/examples-testing/examples/misc_boxselection.ts b/examples-testing/examples/misc_boxselection.ts -index e7079c40..89676cd4 100644 ---- a/examples-testing/examples/misc_boxselection.ts -+++ b/examples-testing/examples/misc_boxselection.ts -@@ -5,8 +5,8 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { SelectionBox } from 'three/addons/interactive/SelectionBox.js'; - import { SelectionHelper } from 'three/addons/interactive/SelectionHelper.js'; - --let container, stats; --let camera, scene, renderer; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -87,12 +87,12 @@ function animate() { - stats.update(); - } - --const selectionBox = new SelectionBox(camera, scene); --const helper = new SelectionHelper(renderer, 'selectBox'); -+const selectionBox = new SelectionBox(camera!, scene!); -+const helper = new SelectionHelper(renderer!, 'selectBox'); - - document.addEventListener('pointerdown', function (event) { - for (const item of selectionBox.collection) { -- item.material.emissive.set(0x000000); -+ (item.material as THREE.MeshLambertMaterial).emissive.set(0x000000); - } - - selectionBox.startPoint.set( -@@ -105,7 +105,7 @@ document.addEventListener('pointerdown', function (event) { - document.addEventListener('pointermove', function (event) { - if (helper.isDown) { - for (let i = 0; i < selectionBox.collection.length; i++) { -- selectionBox.collection[i].material.emissive.set(0x000000); -+ (selectionBox.collection[i].material as THREE.MeshLambertMaterial).emissive.set(0x000000); - } - - selectionBox.endPoint.set( -@@ -117,7 +117,7 @@ document.addEventListener('pointermove', function (event) { - const allSelected = selectionBox.select(); - - for (let i = 0; i < allSelected.length; i++) { -- allSelected[i].material.emissive.set(0xffffff); -+ (allSelected[i].material as THREE.MeshLambertMaterial).emissive.set(0xffffff); - } - } - }); -@@ -132,6 +132,6 @@ document.addEventListener('pointerup', function (event) { - const allSelected = selectionBox.select(); - - for (let i = 0; i < allSelected.length; i++) { -- allSelected[i].material.emissive.set(0xffffff); -+ (allSelected[i].material as THREE.MeshLambertMaterial).emissive.set(0xffffff); - } - }); -diff --git a/examples-testing/examples/misc_controls_arcball.ts b/examples-testing/examples/misc_controls_arcball.ts -index fbef3318..be69ca7b 100644 ---- a/examples-testing/examples/misc_controls_arcball.ts -+++ b/examples-testing/examples/misc_controls_arcball.ts -@@ -12,8 +12,12 @@ const cameraType = { type: 'Perspective' }; - - const perspectiveDistance = 2.5; - const orthographicDistance = 120; --let camera, controls, scene, renderer, gui; --let folderOptions, folderAnimations; -+let camera: THREE.OrthographicCamera | THREE.PerspectiveCamera, -+ controls: ArcballControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ gui: GUI; -+let folderOptions: GUI, folderAnimations: GUI; - - const arcballGui = { - gizmoVisible: true, -@@ -97,8 +101,8 @@ function init() { - material.normalMap.wrapS = THREE.RepeatWrapping; - - group.traverse(function (child) { -- if (child.isMesh) { -- child.material = material; -+ if ((child as THREE.Mesh).isMesh) { -+ (child as THREE.Mesh).material = material; - } - }); - -@@ -164,12 +168,12 @@ function onWindowResize() { - - const halfW = perspectiveDistance * Math.tan(halfFovH); - const halfH = perspectiveDistance * Math.tan(halfFovV); -- camera.left = -halfW; -- camera.right = halfW; -- camera.top = halfH; -- camera.bottom = -halfH; -+ (camera as THREE.OrthographicCamera).left = -halfW; -+ (camera as THREE.OrthographicCamera).right = halfW; -+ (camera as THREE.OrthographicCamera).top = halfH; -+ (camera as THREE.OrthographicCamera).bottom = -halfH; - } else if (camera.type == 'PerspectiveCamera') { -- camera.aspect = window.innerWidth / window.innerHeight; -+ (camera as THREE.PerspectiveCamera).aspect = window.innerWidth / window.innerHeight; - } - - camera.updateProjectionMatrix(); -@@ -183,7 +187,7 @@ function render() { - renderer.render(scene, camera); - } - --function onKeyDown(event) { -+function onKeyDown(event: KeyboardEvent) { - if (event.key === 'c') { - if (event.ctrlKey || event.metaKey) { - controls.copyState(); -@@ -195,7 +199,7 @@ function onKeyDown(event) { - } - } - --function setCamera(type) { -+function setCamera(type: string) { - if (type == 'Orthographic') { - camera = makeOrthographicCamera(); - camera.position.set(0, 0, orthographicDistance); -diff --git a/examples-testing/examples/misc_controls_drag.ts b/examples-testing/examples/misc_controls_drag.ts -index b12b0421..c3b378aa 100644 ---- a/examples-testing/examples/misc_controls_drag.ts -+++ b/examples-testing/examples/misc_controls_drag.ts -@@ -2,12 +2,12 @@ import * as THREE from 'three'; - - import { DragControls } from 'three/addons/controls/DragControls.js'; - --let container; --let camera, scene, renderer; --let controls, group; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controls: DragControls, group: THREE.Group; - let enableSelection = false; - --const objects = []; -+const objects: THREE.Object3D[] = []; - - const mouse = new THREE.Vector2(), - raycaster = new THREE.Raycaster(); -@@ -98,7 +98,7 @@ function onWindowResize() { - render(); - } - --function onKeyDown(event) { -+function onKeyDown(event: KeyboardEvent) { - enableSelection = event.keyCode === 16 ? true : false; - - if (event.keyCode === 77) { -@@ -110,7 +110,7 @@ function onKeyUp() { - enableSelection = false; - } - --function onClick(event) { -+function onClick(event: MouseEvent) { - event.preventDefault(); - - if (enableSelection === true) { -@@ -128,10 +128,10 @@ function onClick(event) { - const object = intersections[0].object; - - if (group.children.includes(object) === true) { -- object.material.emissive.set(0x000000); -+ ((object as THREE.Mesh).material as THREE.MeshLambertMaterial).emissive.set(0x000000); - scene.attach(object); - } else { -- object.material.emissive.set(0xaaaaaa); -+ ((object as THREE.Mesh).material as THREE.MeshLambertMaterial).emissive.set(0xaaaaaa); - group.attach(object); - } - -diff --git a/examples-testing/examples/misc_controls_fly.ts b/examples-testing/examples/misc_controls_fly.ts -index 5b25c489..1210a823 100644 ---- a/examples-testing/examples/misc_controls_fly.ts -+++ b/examples-testing/examples/misc_controls_fly.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, film } from 'three/tsl'; - - import Stats from 'three/addons/libs/stats.module.js'; -@@ -15,11 +15,15 @@ const MARGIN = 0; - let SCREEN_HEIGHT = window.innerHeight - MARGIN * 2; - let SCREEN_WIDTH = window.innerWidth; - --let camera, controls, scene, renderer, stats; --let geometry, meshPlanet, meshClouds, meshMoon; --let dirLight; -+let camera: THREE.PerspectiveCamera, -+ controls: FlyControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ stats: Stats; -+let geometry: THREE.SphereGeometry, meshPlanet: THREE.Mesh, meshClouds: THREE.Mesh, meshMoon: THREE.Mesh; -+let dirLight: THREE.DirectionalLight; - --let postProcessing; -+let postProcessing: THREE.PostProcessing; - - const textureLoader = new THREE.TextureLoader(); - -@@ -51,7 +55,7 @@ function init() { - // y scale is negated to compensate for normal map handedness. - normalScale: new THREE.Vector2(0.85, -0.85), - }); -- materialNormalMap.map.colorSpace = THREE.SRGBColorSpace; -+ materialNormalMap.map!.colorSpace = THREE.SRGBColorSpace; - - // planet - -@@ -68,7 +72,7 @@ function init() { - map: textureLoader.load('textures/planets/earth_clouds_1024.png'), - transparent: true, - }); -- materialClouds.map.colorSpace = THREE.SRGBColorSpace; -+ materialClouds.map!.colorSpace = THREE.SRGBColorSpace; - - meshClouds = new THREE.Mesh(geometry, materialClouds); - meshClouds.scale.set(cloudsScale, cloudsScale, cloudsScale); -@@ -80,7 +84,7 @@ function init() { - const materialMoon = new THREE.MeshPhongMaterial({ - map: textureLoader.load('textures/planets/moon_1024.jpg'), - }); -- materialMoon.map.colorSpace = THREE.SRGBColorSpace; -+ materialMoon.map!.colorSpace = THREE.SRGBColorSpace; - - meshMoon = new THREE.Mesh(geometry, materialMoon); - meshMoon.position.set(radius * 5, 0, 0); -diff --git a/examples-testing/examples/misc_controls_map.ts b/examples-testing/examples/misc_controls_map.ts -index 2f52190c..3a96c544 100644 ---- a/examples-testing/examples/misc_controls_map.ts -+++ b/examples-testing/examples/misc_controls_map.ts -@@ -4,7 +4,7 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { MapControls } from 'three/addons/controls/MapControls.js'; - --let camera, controls, scene, renderer; -+let camera: THREE.PerspectiveCamera, controls: MapControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - //render(); // remove when using animation loop -diff --git a/examples-testing/examples/misc_controls_orbit.ts b/examples-testing/examples/misc_controls_orbit.ts -index 186e216c..0f8b9b11 100644 ---- a/examples-testing/examples/misc_controls_orbit.ts -+++ b/examples-testing/examples/misc_controls_orbit.ts -@@ -2,7 +2,7 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, controls, scene, renderer; -+let camera: THREE.PerspectiveCamera, controls: OrbitControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - //render(); // remove when using animation loop -diff --git a/examples-testing/examples/misc_controls_pointerlock.ts b/examples-testing/examples/misc_controls_pointerlock.ts -index 0b6fcc51..d97bb4c3 100644 ---- a/examples-testing/examples/misc_controls_pointerlock.ts -+++ b/examples-testing/examples/misc_controls_pointerlock.ts -@@ -2,11 +2,11 @@ import * as THREE from 'three'; - - import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js'; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: PointerLockControls; - --const objects = []; -+const objects: THREE.Mesh[] = []; - --let raycaster; -+let raycaster: THREE.Raycaster; - - let moveForward = false; - let moveBackward = false; -@@ -36,8 +36,8 @@ function init() { - - controls = new PointerLockControls(camera, document.body); - -- const blocker = document.getElementById('blocker'); -- const instructions = document.getElementById('instructions'); -+ const blocker = document.getElementById('blocker')!; -+ const instructions = document.getElementById('instructions')!; - - instructions.addEventListener('click', function () { - controls.lock(); -@@ -55,7 +55,7 @@ function init() { - - scene.add(controls.object); - -- const onKeyDown = function (event) { -+ const onKeyDown = function (event: KeyboardEvent) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': -@@ -84,7 +84,7 @@ function init() { - } - }; - -- const onKeyUp = function (event) { -+ const onKeyUp = function (event: KeyboardEvent) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': -@@ -115,7 +115,7 @@ function init() { - - // floor - -- let floorGeometry = new THREE.PlaneGeometry(2000, 2000, 100, 100); -+ let floorGeometry: THREE.BufferGeometry = new THREE.PlaneGeometry(2000, 2000, 100, 100); - floorGeometry.rotateX(-Math.PI / 2); - - // vertex displacement -@@ -164,7 +164,11 @@ function init() { - boxGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colorsBox, 3)); - - for (let i = 0; i < 500; i++) { -- const boxMaterial = new THREE.MeshPhongMaterial({ specular: 0xffffff, flatShading: true, vertexColors: true }); -+ const boxMaterial = new THREE.MeshPhongMaterial({ -+ specular: 0xffffff, -+ flatShading: true, -+ vertexColors: true, -+ }); - boxMaterial.color.setHSL(Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75, THREE.SRGBColorSpace); - - const box = new THREE.Mesh(boxGeometry, boxMaterial); -diff --git a/examples-testing/examples/misc_controls_trackball.ts b/examples-testing/examples/misc_controls_trackball.ts -index b6479e9f..2e8f3dad 100644 ---- a/examples-testing/examples/misc_controls_trackball.ts -+++ b/examples-testing/examples/misc_controls_trackball.ts -@@ -5,7 +5,12 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - --let perspectiveCamera, orthographicCamera, controls, scene, renderer, stats; -+let perspectiveCamera: THREE.PerspectiveCamera, -+ orthographicCamera: THREE.OrthographicCamera, -+ controls: TrackballControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats; - - const params = { - orthographicCamera: false, -@@ -92,7 +97,7 @@ function init() { - createControls(perspectiveCamera); - } - --function createControls(camera) { -+function createControls(camera: THREE.Camera) { - controls = new TrackballControls(camera, renderer.domElement); - - controls.rotateSpeed = 1.0; -diff --git a/examples-testing/examples/misc_controls_transform.ts b/examples-testing/examples/misc_controls_transform.ts -index 6f7793d3..d7d327e9 100644 ---- a/examples-testing/examples/misc_controls_transform.ts -+++ b/examples-testing/examples/misc_controls_transform.ts -@@ -3,8 +3,8 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { TransformControls } from 'three/addons/controls/TransformControls.js'; - --let cameraPersp, cameraOrtho, currentCamera; --let scene, renderer, control, orbit; -+let cameraPersp: THREE.PerspectiveCamera, cameraOrtho: THREE.OrthographicCamera, currentCamera: THREE.Camera; -+let scene: THREE.Scene, renderer: THREE.WebGLRenderer, control: TransformControls, orbit: OrbitControls; - - init(); - render(); -@@ -96,7 +96,9 @@ function init() { - case 'c': - const position = currentCamera.position.clone(); - -- currentCamera = currentCamera.isPerspectiveCamera ? cameraOrtho : cameraPersp; -+ currentCamera = (currentCamera as THREE.PerspectiveCamera).isPerspectiveCamera -+ ? cameraOrtho -+ : cameraPersp; - currentCamera.position.copy(position); - - orbit.object = currentCamera; -diff --git a/examples-testing/examples/misc_exporter_draco.ts b/examples-testing/examples/misc_exporter_draco.ts -index 40a62fb1..cb9d3f59 100644 ---- a/examples-testing/examples/misc_exporter_draco.ts -+++ b/examples-testing/examples/misc_exporter_draco.ts -@@ -4,7 +4,11 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { DRACOExporter } from 'three/addons/exporters/DRACOExporter.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, camera, renderer, exporter, mesh; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ renderer: THREE.WebGLRenderer, -+ exporter: DRACOExporter, -+ mesh: THREE.Mesh; - - const params = { - export: exportFile, -@@ -106,12 +110,12 @@ const link = document.createElement('a'); - link.style.display = 'none'; - document.body.appendChild(link); - --function save(blob, filename) { -+function save(blob: Blob, filename: string) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); - } - --function saveArrayBuffer(buffer, filename) { -+function saveArrayBuffer(buffer: BufferSource, filename: string) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); - } -diff --git a/examples-testing/examples/misc_exporter_exr.ts b/examples-testing/examples/misc_exporter_exr.ts -index f4a189bb..1cd5fb27 100644 ---- a/examples-testing/examples/misc_exporter_exr.ts -+++ b/examples-testing/examples/misc_exporter_exr.ts -@@ -5,7 +5,14 @@ import { EXRExporter, ZIP_COMPRESSION, ZIPS_COMPRESSION, NO_COMPRESSION } from ' - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, camera, renderer, exporter, mesh, controls, renderTarget, dataTexture; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ renderer: THREE.WebGLRenderer, -+ exporter: EXRExporter, -+ mesh: THREE.Mesh, -+ controls: OrbitControls, -+ renderTarget: THREE.WebGLRenderTarget, -+ dataTexture: THREE.DataTexture; - - const params = { - target: 'pmrem', -@@ -148,7 +155,7 @@ async function exportFile() { - saveArrayBuffer(result, params.target + '.exr'); - } - --function saveArrayBuffer(buffer, filename) { -+function saveArrayBuffer(buffer: Uint8Array, filename: string) { - const blob = new Blob([buffer], { type: 'image/x-exr' }); - const link = document.createElement('a'); - -diff --git a/examples-testing/examples/misc_exporter_gltf.ts b/examples-testing/examples/misc_exporter_gltf.ts -index fda0d4df..12e45bf4 100644 ---- a/examples-testing/examples/misc_exporter_gltf.ts -+++ b/examples-testing/examples/misc_exporter_gltf.ts -@@ -6,7 +6,7 @@ import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --function exportGLTF(input) { -+function exportGLTF(input: THREE.Object3D | THREE.Object3D[]) { - const gltfExporter = new GLTFExporter(); - - const options = { -@@ -37,7 +37,7 @@ const link = document.createElement('a'); - link.style.display = 'none'; - document.body.appendChild(link); // Firefox workaround, see #6594 - --function save(blob, filename) { -+function save(blob: Blob, filename: string) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); -@@ -45,18 +45,25 @@ function save(blob, filename) { - // URL.revokeObjectURL( url ); breaks Firefox... - } - --function saveString(text, filename) { -+function saveString(text: string, filename: string) { - save(new Blob([text], { type: 'text/plain' }), filename); - } - --function saveArrayBuffer(buffer, filename) { -+function saveArrayBuffer(buffer: BufferSource, filename: string) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); - } - --let container; -+let container: HTMLDivElement; - --let camera, object, object2, material, geometry, scene1, scene2, renderer; --let gridHelper, sphere, model, coffeemat; -+let camera: THREE.PerspectiveCamera, -+ object: THREE.Object3D, -+ object2: THREE.Mesh, -+ material: THREE.MeshBasicMaterial | THREE.MeshLambertMaterial | THREE.MeshStandardMaterial, -+ geometry: THREE.BufferGeometry, -+ scene1: THREE.Scene, -+ scene2: THREE.Scene, -+ renderer: THREE.WebGLRenderer; -+let gridHelper: THREE.GridHelper, sphere: THREE.Mesh, model: THREE.Group, coffeemat: THREE.Group; - - const params = { - trs: false, -@@ -387,8 +394,8 @@ function init() { - const color = new THREE.Color(); - for (let i = 0; i < 50; i++) { - matrix.setPosition(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50); -- object.setMatrixAt(i, matrix); -- object.setColorAt(i, color.setHSL(i / 50, 1, 0.5)); -+ (object as THREE.InstancedMesh).setMatrixAt(i, matrix); -+ (object as THREE.InstancedMesh).setColorAt(i, color.setHSL(i / 50, 1, 0.5)); - } - - object.position.set(400, 0, 200); -diff --git a/examples-testing/examples/misc_exporter_obj.ts b/examples-testing/examples/misc_exporter_obj.ts -index 025034da..73638fff 100644 ---- a/examples-testing/examples/misc_exporter_obj.ts -+++ b/examples-testing/examples/misc_exporter_obj.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { OBJExporter } from 'three/addons/exporters/OBJExporter.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - const params = { - addTriangle: addTriangle, -@@ -66,12 +66,12 @@ function exportToObj() { - saveString(result, 'object.obj'); - } - --function addGeometry(type) { -+function addGeometry(type: number) { - for (let i = 0; i < scene.children.length; i++) { - const child = scene.children[i]; - -- if (child.isMesh || child.isPoints) { -- child.geometry.dispose(); -+ if ((child as THREE.Mesh).isMesh || (child as THREE.Points).isPoints) { -+ (child as THREE.Mesh | THREE.Points).geometry.dispose(); - scene.remove(child); - i--; - } -@@ -156,13 +156,13 @@ const link = document.createElement('a'); - link.style.display = 'none'; - document.body.appendChild(link); - --function save(blob, filename) { -+function save(blob: Blob, filename: string) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); - } - --function saveString(text, filename) { -+function saveString(text: string, filename: string) { - save(new Blob([text], { type: 'text/plain' }), filename); - } - -diff --git a/examples-testing/examples/misc_exporter_ply.ts b/examples-testing/examples/misc_exporter_ply.ts -index b7e32468..c1682103 100644 ---- a/examples-testing/examples/misc_exporter_ply.ts -+++ b/examples-testing/examples/misc_exporter_ply.ts -@@ -4,7 +4,11 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { PLYExporter } from 'three/addons/exporters/PLYExporter.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, camera, renderer, exporter, mesh; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ renderer: THREE.WebGLRenderer, -+ exporter: PLYExporter, -+ mesh: THREE.Mesh; - - const params = { - exportASCII: exportASCII, -@@ -141,16 +145,16 @@ const link = document.createElement('a'); - link.style.display = 'none'; - document.body.appendChild(link); - --function save(blob, filename) { -+function save(blob: Blob, filename: string) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); - } - --function saveString(text, filename) { -+function saveString(text: string, filename: string) { - save(new Blob([text], { type: 'text/plain' }), filename); - } - --function saveArrayBuffer(buffer, filename) { -+function saveArrayBuffer(buffer: BufferSource, filename: string) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); - } -diff --git a/examples-testing/examples/misc_exporter_stl.ts b/examples-testing/examples/misc_exporter_stl.ts -index ff6d6e2b..105aeb07 100644 ---- a/examples-testing/examples/misc_exporter_stl.ts -+++ b/examples-testing/examples/misc_exporter_stl.ts -@@ -4,7 +4,11 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { STLExporter } from 'three/addons/exporters/STLExporter.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, camera, renderer, exporter, mesh; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ renderer: THREE.WebGLRenderer, -+ exporter: STLExporter, -+ mesh: THREE.Mesh; - - const params = { - exportASCII: exportASCII, -@@ -114,16 +118,16 @@ const link = document.createElement('a'); - link.style.display = 'none'; - document.body.appendChild(link); - --function save(blob, filename) { -+function save(blob: Blob, filename: string) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); - } - --function saveString(text, filename) { -+function saveString(text: string, filename: string) { - save(new Blob([text], { type: 'text/plain' }), filename); - } - --function saveArrayBuffer(buffer, filename) { -+function saveArrayBuffer(buffer: BufferSource, filename: string) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); - } -diff --git a/examples-testing/examples/misc_exporter_usdz.ts b/examples-testing/examples/misc_exporter_usdz.ts -index 9a14919b..2d52e37b 100644 ---- a/examples-testing/examples/misc_exporter_usdz.ts -+++ b/examples-testing/examples/misc_exporter_usdz.ts -@@ -7,7 +7,7 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { USDZExporter } from 'three/addons/exporters/USDZExporter.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - const params = { - exportUSDZ: exportUSDZ, -@@ -50,7 +50,7 @@ function init() { - const arraybuffer = await exporter.parseAsync(gltf.scene); - const blob = new Blob([arraybuffer], { type: 'application/octet-stream' }); - -- const link = document.getElementById('link'); -+ const link = document.getElementById('link') as HTMLAnchorElement; - link.href = URL.createObjectURL(blob); - }); - -@@ -78,7 +78,7 @@ function createSpotShadowMesh() { - canvas.width = 128; - canvas.height = 128; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - const gradient = context.createRadialGradient( - canvas.width / 2, - canvas.height / 2, -@@ -118,7 +118,7 @@ function onWindowResize() { - } - - function exportUSDZ() { -- const link = document.getElementById('link'); -+ const link = document.getElementById('link')!; - link.click(); - } - -diff --git a/examples-testing/examples/misc_lookat.ts b/examples-testing/examples/misc_lookat.ts -index 280b6e2d..be88f897 100644 ---- a/examples-testing/examples/misc_lookat.ts -+++ b/examples-testing/examples/misc_lookat.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - --let sphere; -+let sphere: THREE.Mesh; - - let mouseX = 0, - mouseY = 0; -@@ -64,7 +64,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = (event.clientX - windowHalfX) * 10; - mouseY = (event.clientY - windowHalfY) * 10; - } -diff --git a/examples-testing/examples/misc_uv_tests.ts b/examples-testing/examples/misc_uv_tests.ts -index 4f782d45..0759cfca 100644 ---- a/examples-testing/examples/misc_uv_tests.ts -+++ b/examples-testing/examples/misc_uv_tests.ts -@@ -7,7 +7,7 @@ import { UVsDebug } from 'three/addons/utils/UVsDebug.js'; - * as well as allow a new user to visualize what UVs are about. - */ - --function test(name, geometry) { -+function test(name: string, geometry: THREE.BufferGeometry) { - const d = document.createElement('div'); - - d.innerHTML = '

' + name + '

'; -diff --git a/examples-testing/examples/physics_ammo_instancing.ts b/examples-testing/examples/physics_ammo_instancing.ts -index 265c254c..3a6ae139 100644 ---- a/examples-testing/examples/physics_ammo_instancing.ts -+++ b/examples-testing/examples/physics_ammo_instancing.ts -@@ -1,12 +1,12 @@ - import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { AmmoPhysics } from 'three/addons/physics/AmmoPhysics.js'; -+import { AmmoPhysics, AmmoPhysicsObject } from 'three/addons/physics/AmmoPhysics.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; --let physics, position; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; -+let physics: AmmoPhysicsObject, position: THREE.Vector3; - --let boxes, spheres; -+let boxes: THREE.InstancedMesh, spheres: THREE.InstancedMesh; - - init(); - -diff --git a/examples-testing/examples/physics_jolt_instancing.ts b/examples-testing/examples/physics_jolt_instancing.ts -index 022263c0..3df667b6 100644 ---- a/examples-testing/examples/physics_jolt_instancing.ts -+++ b/examples-testing/examples/physics_jolt_instancing.ts -@@ -1,12 +1,12 @@ - import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { JoltPhysics } from 'three/addons/physics/JoltPhysics.js'; -+import { JoltPhysics, JoltPhysicsObject } from 'three/addons/physics/JoltPhysics.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; --let physics, position; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; -+let physics: JoltPhysicsObject, position: THREE.Vector3; - --let boxes, spheres; -+let boxes: THREE.InstancedMesh, spheres: THREE.InstancedMesh; - - init(); - -diff --git a/examples-testing/examples/physics_rapier_instancing.ts b/examples-testing/examples/physics_rapier_instancing.ts -index f23cf766..859a1d59 100644 ---- a/examples-testing/examples/physics_rapier_instancing.ts -+++ b/examples-testing/examples/physics_rapier_instancing.ts -@@ -1,12 +1,12 @@ - import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { RapierPhysics } from 'three/addons/physics/RapierPhysics.js'; -+import { RapierPhysics, RapierPhysicsObject } from 'three/addons/physics/RapierPhysics.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; --let physics, position; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; -+let physics: RapierPhysicsObject, position: THREE.Vector3; - --let boxes, spheres; -+let boxes: THREE.InstancedMesh, spheres: THREE.InstancedMesh; - - init(); - -diff --git a/examples-testing/examples/svg_lines.ts b/examples-testing/examples/svg_lines.ts -index 99b74c40..65aaf28d 100644 ---- a/examples-testing/examples/svg_lines.ts -+++ b/examples-testing/examples/svg_lines.ts -@@ -4,7 +4,7 @@ import { SVGRenderer } from 'three/addons/renderers/SVGRenderer.js'; - - THREE.ColorManagement.enabled = false; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: SVGRenderer; - - init(); - animate(); -diff --git a/examples-testing/examples/svg_sandbox.ts b/examples-testing/examples/svg_sandbox.ts -index e6be8386..faea9a7a 100644 ---- a/examples-testing/examples/svg_sandbox.ts -+++ b/examples-testing/examples/svg_sandbox.ts -@@ -6,9 +6,9 @@ import { SVGRenderer, SVGObject } from 'three/addons/renderers/SVGRenderer.js'; - - THREE.ColorManagement.enabled = false; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: SVGRenderer, stats: Stats; - --let group; -+let group: THREE.Mesh; - - init(); - animate(); -@@ -33,9 +33,13 @@ function init() { - - const boxGeometry = new THREE.BoxGeometry(100, 100, 100); - -- let mesh = new THREE.Mesh( -+ let mesh: THREE.Mesh = new THREE.Mesh( - boxGeometry, -- new THREE.MeshBasicMaterial({ color: 0x0000ff, opacity: 0.5, transparent: true }), -+ new THREE.MeshBasicMaterial({ -+ color: 0x0000ff, -+ opacity: 0.5, -+ transparent: true, -+ }), - ); - mesh.position.x = 500; - mesh.rotation.x = Math.random(); -@@ -55,7 +59,10 @@ function init() { - - mesh = new THREE.Mesh( - new THREE.PlaneGeometry(100, 100), -- new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, side: THREE.DoubleSide }), -+ new THREE.MeshBasicMaterial({ -+ color: Math.random() * 0xffffff, -+ side: THREE.DoubleSide, -+ }), - ); - mesh.position.y = -500; - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; -@@ -75,7 +82,10 @@ function init() { - // POLYFIELD - - const geometry = new THREE.BufferGeometry(); -- const material = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide }); -+ const material = new THREE.MeshBasicMaterial({ -+ vertexColors: true, -+ side: THREE.DoubleSide, -+ }); - - const v = new THREE.Vector3(); - const v0 = new THREE.Vector3(); -@@ -122,7 +132,9 @@ function init() { - // SPRITES - - for (let i = 0; i < 50; i++) { -- const material = new THREE.SpriteMaterial({ color: Math.random() * 0xffffff }); -+ const material = new THREE.SpriteMaterial({ -+ color: Math.random() * 0xffffff, -+ }); - const sprite = new THREE.Sprite(material); - sprite.position.x = Math.random() * 1000 - 500; - sprite.position.y = Math.random() * 1000 - 500; -@@ -139,7 +151,7 @@ function init() { - node.setAttribute('r', '40'); - - for (let i = 0; i < 50; i++) { -- const object = new SVGObject(node.cloneNode()); -+ const object = new SVGObject(node.cloneNode() as SVGCircleElement); - object.position.x = Math.random() * 1000 - 500; - object.position.y = Math.random() * 1000 - 500; - object.position.z = Math.random() * 1000 - 500; -@@ -152,7 +164,7 @@ function init() { - fileLoader.load('models/svg/hexagon.svg', function (svg) { - const node = document.createElementNS('http://www.w3.org/2000/svg', 'g'); - const parser = new DOMParser(); -- const doc = parser.parseFromString(svg, 'image/svg+xml'); -+ const doc = parser.parseFromString(svg as string, 'image/svg+xml'); - - node.appendChild(doc.documentElement); - -diff --git a/examples-testing/examples/webaudio_orientation.ts b/examples-testing/examples/webaudio_orientation.ts -index 7baaa88a..e133c2cd 100644 ---- a/examples-testing/examples/webaudio_orientation.ts -+++ b/examples-testing/examples/webaudio_orientation.ts -@@ -4,16 +4,16 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { PositionalAudioHelper } from 'three/addons/helpers/PositionalAudioHelper.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let scene, camera, renderer; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer; - --const startButton = document.getElementById('startButton'); -+const startButton = document.getElementById('startButton')!; - startButton.addEventListener('click', init); - - function init() { -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - // - -@@ -65,7 +65,7 @@ function init() { - const listener = new THREE.AudioListener(); - camera.add(listener); - -- const audioElement = document.getElementById('music'); -+ const audioElement = document.getElementById('music') as HTMLAudioElement; - audioElement.play(); - - const positionalAudio = new THREE.PositionalAudio(listener); -@@ -85,10 +85,10 @@ function init() { - boomBox.scale.set(20, 20, 20); - - boomBox.traverse(function (object) { -- if (object.isMesh) { -- object.material.envMap = reflectionCube; -- object.geometry.rotateY(-Math.PI); -- object.castShadow = true; -+ if ((object as THREE.Mesh).isMesh) { -+ ((object as THREE.Mesh).material as THREE.MeshStandardMaterial).envMap = reflectionCube; -+ (object as THREE.Mesh).geometry.rotateY(-Math.PI); -+ (object as THREE.Mesh).castShadow = true; - } - }); - -@@ -101,7 +101,11 @@ function init() { - // sound is damped behind this wall - - const wallGeometry = new THREE.BoxGeometry(2, 1, 0.1); -- const wallMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 }); -+ const wallMaterial = new THREE.MeshBasicMaterial({ -+ color: 0xff0000, -+ transparent: true, -+ opacity: 0.5, -+ }); - - const wall = new THREE.Mesh(wallGeometry, wallMaterial); - wall.position.set(0, 0.5, -0.5); -diff --git a/examples-testing/examples/webaudio_sandbox.ts b/examples-testing/examples/webaudio_sandbox.ts -index d67d0d55..21c7a0bf 100644 ---- a/examples-testing/examples/webaudio_sandbox.ts -+++ b/examples-testing/examples/webaudio_sandbox.ts -@@ -4,19 +4,23 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; - --let camera, controls, scene, renderer, light; -+let camera: THREE.PerspectiveCamera, -+ controls: FirstPersonControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ light: THREE.DirectionalLight; - --let material1, material2, material3; -+let material1: THREE.MeshPhongMaterial, material2: THREE.MeshPhongMaterial, material3: THREE.MeshPhongMaterial; - --let analyser1, analyser2, analyser3; -+let analyser1: THREE.AudioAnalyser, analyser2: THREE.AudioAnalyser, analyser3: THREE.AudioAnalyser; - - const clock = new THREE.Clock(); - --const startButton = document.getElementById('startButton'); -+const startButton = document.getElementById('startButton')!; - startButton.addEventListener('click', init); - - function init() { -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); -@@ -45,7 +49,7 @@ function init() { - scene.add(mesh1); - - const sound1 = new THREE.PositionalAudio(listener); -- const songElement = document.getElementById('song'); -+ const songElement = document.getElementById('song') as HTMLAudioElement; - sound1.setMediaElementSource(songElement); - sound1.setRefDistance(20); - songElement.play(); -@@ -58,7 +62,7 @@ function init() { - scene.add(mesh2); - - const sound2 = new THREE.PositionalAudio(listener); -- const skullbeatzElement = document.getElementById('skullbeatz'); -+ const skullbeatzElement = document.getElementById('skullbeatz') as HTMLAudioElement; - sound2.setMediaElementSource(skullbeatzElement); - sound2.setRefDistance(20); - skullbeatzElement.play(); -@@ -89,7 +93,7 @@ function init() { - // global ambient audio - - const sound4 = new THREE.Audio(listener); -- const utopiaElement = document.getElementById('utopia'); -+ const utopiaElement = document.getElementById('utopia') as HTMLAudioElement; - sound4.setMediaElementSource(utopiaElement); - sound4.setVolume(0.5); - utopiaElement.play(); -@@ -102,18 +106,31 @@ function init() { - - // - -- const SoundControls = function () { -- this.master = listener.getMasterVolume(); -- this.firstSphere = sound1.getVolume(); -- this.secondSphere = sound2.getVolume(); -- this.thirdSphere = sound3.getVolume(); -- this.Ambient = sound4.getVolume(); -- }; -- -- const GeneratorControls = function () { -- this.frequency = oscillator.frequency.value; -- this.wavetype = oscillator.type; -- }; -+ class SoundControls { -+ master: number; -+ firstSphere: number; -+ secondSphere: number; -+ thirdSphere: number; -+ Ambient: number; -+ -+ constructor() { -+ this.master = listener.getMasterVolume(); -+ this.firstSphere = sound1.getVolume(); -+ this.secondSphere = sound2.getVolume(); -+ this.thirdSphere = sound3.getVolume(); -+ this.Ambient = sound4.getVolume(); -+ } -+ } -+ -+ class GeneratorControls { -+ frequency: number; -+ wavetype: OscillatorType; -+ -+ constructor() { -+ this.frequency = oscillator.frequency.value; -+ this.wavetype = oscillator.type; -+ } -+ } - - const gui = new GUI(); - const soundControls = new SoundControls(); -diff --git a/examples-testing/examples/webaudio_timing.ts b/examples-testing/examples/webaudio_timing.ts -index 9e17bcbc..475113b9 100644 ---- a/examples-testing/examples/webaudio_timing.ts -+++ b/examples-testing/examples/webaudio_timing.ts -@@ -2,22 +2,22 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let scene, camera, renderer, clock; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, clock: THREE.Clock; - --const objects = []; -+const objects: THREE.Mesh[] = []; - - const speed = 2.5; - const height = 3; - const offset = 0.5; - --const startButton = document.getElementById('startButton'); -+const startButton = document.getElementById('startButton')!; - startButton.addEventListener('click', init); - - function init() { -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - scene = new THREE.Scene(); - -@@ -141,7 +141,7 @@ function animate() { - if (ball.userData.down === true) { - // ball changed direction from down to up - -- const audio = ball.children[0]; -+ const audio = ball.children[0] as THREE.Audio; - audio.play(); // play audio with perfect timing when ball hits the surface - ball.userData.down = false; - } -diff --git a/examples-testing/examples/webaudio_visualizer.ts b/examples-testing/examples/webaudio_visualizer.ts -index a3f58cb3..0bad866f 100644 ---- a/examples-testing/examples/webaudio_visualizer.ts -+++ b/examples-testing/examples/webaudio_visualizer.ts -@@ -1,8 +1,13 @@ - import * as THREE from 'three'; -+import { IUniform } from 'three'; - --let scene, camera, renderer, analyser, uniforms; -+let scene: THREE.Scene, -+ camera: THREE.Camera, -+ renderer: THREE.WebGLRenderer, -+ analyser: THREE.AudioAnalyser, -+ uniforms: { [uniform: string]: IUniform }; - --const startButton = document.getElementById('startButton'); -+const startButton = document.getElementById('startButton')!; - startButton.addEventListener('click', init); - - function init() { -@@ -10,12 +15,12 @@ function init() { - - // - -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - - // - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - scene = new THREE.Scene(); - -@@ -51,8 +56,8 @@ function init() { - - const material = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - }); - - const geometry = new THREE.PlaneGeometry(1, 1); -diff --git a/examples-testing/examples/webgl_animation_keyframes.ts b/examples-testing/examples/webgl_animation_keyframes.ts -index 88048f24..ffe75d3e 100644 ---- a/examples-testing/examples/webgl_animation_keyframes.ts -+++ b/examples-testing/examples/webgl_animation_keyframes.ts -@@ -8,10 +8,10 @@ import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - --let mixer; -+let mixer: THREE.AnimationMixer; - - const clock = new THREE.Clock(); --const container = document.getElementById('container'); -+const container = document.getElementById('container')!; - - const stats = new Stats(); - container.appendChild(stats.dom); -diff --git a/examples-testing/examples/webgl_animation_multiple.ts b/examples-testing/examples/webgl_animation_multiple.ts -index 152c6506..ce388749 100644 ---- a/examples-testing/examples/webgl_animation_multiple.ts -+++ b/examples-testing/examples/webgl_animation_multiple.ts -@@ -4,11 +4,11 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, clock; --let model, animations; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, clock: THREE.Clock; -+let model: THREE.Group, animations: THREE.AnimationClip[]; - --const mixers = [], -- objects = []; -+const mixers: THREE.AnimationMixer[] = [], -+ objects: THREE.Object3D[] = []; - - const params = { - sharedSkeleton: false, -@@ -60,7 +60,7 @@ function init() { - animations = gltf.animations; - - model.traverse(function (object) { -- if (object.isMesh) object.castShadow = true; -+ if ((object as THREE.Mesh).isMesh) object.castShadow = true; - }); - - setupDefaultScene(); -@@ -102,7 +102,7 @@ function clearScene() { - scene.remove(object); - - scene.traverse(function (child) { -- if (child.isSkinnedMesh) child.skeleton.dispose(); -+ if ((child as THREE.SkinnedMesh).isSkinnedMesh) (child as THREE.SkinnedMesh).skeleton.dispose(); - }); - } - } -@@ -138,9 +138,9 @@ function setupSharedSkeletonScene() { - // all models share the same animation state - - const sharedModel = SkeletonUtils.clone(model); -- const shareSkinnedMesh = sharedModel.getObjectByName('vanguard_Mesh'); -+ const shareSkinnedMesh = sharedModel.getObjectByName('vanguard_Mesh') as THREE.SkinnedMesh; - const sharedSkeleton = shareSkinnedMesh.skeleton; -- const sharedParentBone = sharedModel.getObjectByName('mixamorigHips'); -+ const sharedParentBone = sharedModel.getObjectByName('mixamorigHips')!; - scene.add(sharedParentBone); // the bones need to be in the scene for the animation to work - - const model1 = shareSkinnedMesh.clone(); -diff --git a/examples-testing/examples/webgl_animation_skinning_morph.ts b/examples-testing/examples/webgl_animation_skinning_morph.ts -index f05369aa..5e9ce7d0 100644 ---- a/examples-testing/examples/webgl_animation_skinning_morph.ts -+++ b/examples-testing/examples/webgl_animation_skinning_morph.ts -@@ -5,10 +5,29 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let container, stats, clock, gui, mixer, actions, activeAction, previousAction; --let camera, scene, renderer, model, face; -- --const api = { state: 'Walking' }; -+let container: HTMLDivElement, -+ stats: Stats, -+ clock: THREE.Clock, -+ gui: GUI, -+ mixer: THREE.AnimationMixer, -+ actions: Record, -+ activeAction: THREE.AnimationAction, -+ previousAction: THREE.AnimationAction; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ model: THREE.Group, -+ face: THREE.Mesh; -+ -+const api: { -+ state: string; -+ Jump?: () => void; -+ Yes?: () => void; -+ No?: () => void; -+ Wave?: () => void; -+ Punch?: () => void; -+ ThumbsUp?: () => void; -+} = { state: 'Walking' }; - - init(); - -@@ -80,9 +99,9 @@ function init() { - container.appendChild(stats.dom); - } - --function createGUI(model, animations) { -+function createGUI(model: THREE.Group, animations: THREE.AnimationClip[]) { - const states = ['Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing']; -- const emotes = ['Jump', 'Yes', 'No', 'Wave', 'Punch', 'ThumbsUp']; -+ const emotes = ['Jump', 'Yes', 'No', 'Wave', 'Punch', 'ThumbsUp'] as const; - - gui = new GUI(); - -@@ -95,7 +114,7 @@ function createGUI(model, animations) { - const action = mixer.clipAction(clip); - actions[clip.name] = action; - -- if (emotes.indexOf(clip.name) >= 0 || states.indexOf(clip.name) >= 4) { -+ if (emotes.indexOf(clip.name as (typeof emotes)[number]) >= 0 || states.indexOf(clip.name) >= 4) { - action.clampWhenFinished = true; - action.loop = THREE.LoopOnce; - } -@@ -117,14 +136,14 @@ function createGUI(model, animations) { - - const emoteFolder = gui.addFolder('Emotes'); - -- function createEmoteCallback(name) { -+ function createEmoteCallback(name: (typeof emotes)[number]) { - api[name] = function () { - fadeToAction(name, 0.2); - - mixer.addEventListener('finished', restoreState); - }; - -- emoteFolder.add(api, name); -+ emoteFolder.add(api as Required, name); - } - - function restoreState() { -@@ -141,13 +160,13 @@ function createGUI(model, animations) { - - // expressions - -- face = model.getObjectByName('Head_4'); -+ face = model.getObjectByName('Head_4') as THREE.Mesh; - -- const expressions = Object.keys(face.morphTargetDictionary); -+ const expressions = Object.keys(face.morphTargetDictionary!); - const expressionFolder = gui.addFolder('Expressions'); - - for (let i = 0; i < expressions.length; i++) { -- expressionFolder.add(face.morphTargetInfluences, i, 0, 1, 0.01).name(expressions[i]); -+ expressionFolder.add(face.morphTargetInfluences!, i, 0, 1, 0.01).name(expressions[i]); - } - - activeAction = actions['Walking']; -@@ -156,7 +175,7 @@ function createGUI(model, animations) { - expressionFolder.open(); - } - --function fadeToAction(name, duration) { -+function fadeToAction(name: string, duration: number) { - previousAction = activeAction; - activeAction = actions[name]; - -diff --git a/examples-testing/examples/webgl_buffergeometry.ts b/examples-testing/examples/webgl_buffergeometry.ts -index 28b2c96a..6a802ab6 100644 ---- a/examples-testing/examples/webgl_buffergeometry.ts -+++ b/examples-testing/examples/webgl_buffergeometry.ts -@@ -2,17 +2,17 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let mesh; -+let mesh: THREE.Mesh; - - init(); - animate(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -117,8 +117,8 @@ function init() { - colors.push(color.r, color.g, color.b, alpha); - } - -- function disposeArray() { -- this.array = null; -+ function disposeArray(this: THREE.BufferAttribute) { -+ this.array = null as unknown as THREE.TypedArray; - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3).onUpload(disposeArray)); -diff --git a/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts b/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts -index 96926c2c..76e6c251 100644 ---- a/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts -+++ b/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --let camera, scene, renderer, mesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, mesh: THREE.Mesh; - - init(); - -@@ -65,7 +65,7 @@ function init() { - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2)); - geometry.setAttribute('textureIndex', new THREE.Int16BufferAttribute(textureIndices, 1)); -- geometry.attributes.textureIndex.gpuType = THREE.IntType; -+ (geometry.attributes.textureIndex as THREE.BufferAttribute).gpuType = THREE.IntType; - - geometry.computeBoundingSphere(); - -@@ -83,8 +83,8 @@ function init() { - value: [map1, map2, map3], - }, - }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - side: THREE.DoubleSide, - glslVersion: THREE.GLSL3, - }); -diff --git a/examples-testing/examples/webgl_buffergeometry_attributes_none.ts b/examples-testing/examples/webgl_buffergeometry_attributes_none.ts -index a1424e87..f7fcf29f 100644 ---- a/examples-testing/examples/webgl_buffergeometry_attributes_none.ts -+++ b/examples-testing/examples/webgl_buffergeometry_attributes_none.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --let camera, scene, renderer, mesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, mesh: THREE.Mesh; - - init(); - -@@ -27,8 +27,8 @@ function init() { - uniforms: { - seed: { value: 42 }, - }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - side: THREE.DoubleSide, - glslVersion: THREE.GLSL3, - }); -@@ -48,7 +48,7 @@ function init() { - document.body.appendChild(renderer.domElement); - } - --function animate(time) { -+function animate(time: number) { - mesh.rotation.x = (time / 1000.0) * 0.25; - mesh.rotation.y = (time / 1000.0) * 0.5; - -diff --git a/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts b/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts -index 0dffa65c..96dd8910 100644 ---- a/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts -+++ b/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts -@@ -2,9 +2,11 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let particleSystem, uniforms, geometry; -+let particleSystem: THREE.Points, -+ uniforms: { pointTexture: THREE.IUniform }, -+ geometry: THREE.BufferGeometry; - - const particles = 100000; - -@@ -22,8 +24,8 @@ function init() { - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - - blending: THREE.AdditiveBlending, - depthTest: false, -@@ -66,7 +68,7 @@ function init() { - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - stats = new Stats(); -diff --git a/examples-testing/examples/webgl_buffergeometry_drawrange.ts b/examples-testing/examples/webgl_buffergeometry_drawrange.ts -index 142ff43b..903b59ee 100644 ---- a/examples-testing/examples/webgl_buffergeometry_drawrange.ts -+++ b/examples-testing/examples/webgl_buffergeometry_drawrange.ts -@@ -5,15 +5,15 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let group; --let container, stats; --const particlesData = []; --let camera, scene, renderer; --let positions, colors; --let particles; --let pointCloud; --let particlePositions; --let linesMesh; -+let group: THREE.Group; -+let container: HTMLElement, stats: Stats; -+const particlesData: { velocity: THREE.Vector3; numConnections: number }[] = []; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let positions: Float32Array, colors: Float32Array; -+let particles: THREE.BufferGeometry; -+let pointCloud: THREE.Points; -+let particlePositions: Float32Array; -+let linesMesh: THREE.LineSegments; - - const maxParticleCount = 1000; - let particleCount = 500; -@@ -52,7 +52,7 @@ function initGUI() { - function init() { - initGUI(); - -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 4000); - camera.position.z = 1750; -diff --git a/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts b/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts -index aea462cf..f66207e2 100644 ---- a/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts -+++ b/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts -@@ -2,11 +2,11 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let points; -+let points: THREE.Points, THREE.PointsMaterial>; - - const particles = 300000; - let drawCount = 10000; -@@ -15,7 +15,7 @@ init(); - animate(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -37,7 +37,7 @@ function init() { - - // - -- const geometry = new THREE.BufferGeometry(); -+ const geometry = new THREE.BufferGeometry(); - - const positions = []; - const positions2 = []; -@@ -71,15 +71,15 @@ function init() { - - const gl = renderer.getContext(); - -- const pos = gl.createBuffer(); -+ const pos = gl.createBuffer()!; - gl.bindBuffer(gl.ARRAY_BUFFER, pos); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); - -- const pos2 = gl.createBuffer(); -+ const pos2 = gl.createBuffer()!; - gl.bindBuffer(gl.ARRAY_BUFFER, pos2); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions2), gl.STATIC_DRAW); - -- const rgb = gl.createBuffer(); -+ const rgb = gl.createBuffer()!; - gl.bindBuffer(gl.ARRAY_BUFFER, rgb); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); - -diff --git a/examples-testing/examples/webgl_buffergeometry_indexed.ts b/examples-testing/examples/webgl_buffergeometry_indexed.ts -index a2f9f379..4ad49d3c 100644 ---- a/examples-testing/examples/webgl_buffergeometry_indexed.ts -+++ b/examples-testing/examples/webgl_buffergeometry_indexed.ts -@@ -3,9 +3,9 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - --let mesh; -+let mesh: THREE.Mesh; - - init(); - -diff --git a/examples-testing/examples/webgl_buffergeometry_instancing.ts b/examples-testing/examples/webgl_buffergeometry_instancing.ts -index a5b90ae6..df382735 100644 ---- a/examples-testing/examples/webgl_buffergeometry_instancing.ts -+++ b/examples-testing/examples/webgl_buffergeometry_instancing.ts -@@ -3,14 +3,14 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10); - camera.position.z = 2; -@@ -79,8 +79,8 @@ function init() { - time: { value: 1.0 }, - sineTime: { value: 1.0 }, - }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - side: THREE.DoubleSide, - forceSinglePass: true, - transparent: true, -@@ -126,7 +126,7 @@ function onWindowResize() { - function animate() { - const time = performance.now(); - -- const object = scene.children[0]; -+ const object = scene.children[0] as THREE.Mesh; - - object.rotation.y = time * 0.0005; - object.material.uniforms['time'].value = time * 0.005; -diff --git a/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts b/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts -index 2158dff3..2c97fbd9 100644 ---- a/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts -+++ b/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts -@@ -2,10 +2,10 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; --let geometry, material, mesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let geometry: THREE.InstancedBufferGeometry, material: THREE.RawShaderMaterial, mesh: THREE.Mesh; - - init(); - -@@ -41,8 +41,8 @@ function init() { - map: { value: new THREE.TextureLoader().load('textures/sprites/circle.png') }, - time: { value: 0.0 }, - }, -- vertexShader: document.getElementById('vshader').textContent, -- fragmentShader: document.getElementById('fshader').textContent, -+ vertexShader: document.getElementById('vshader')!.textContent!, -+ fragmentShader: document.getElementById('fshader')!.textContent!, - depthTest: true, - depthWrite: true, - }); -diff --git a/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts b/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts -index bef2c264..c0887a8d 100644 ---- a/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts -+++ b/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts -@@ -2,8 +2,8 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; --let camera, scene, renderer, mesh; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, mesh: THREE.InstancedMesh; - - const instances = 5000; - let lastTime = 0; -@@ -16,7 +16,7 @@ const currentM = new THREE.Matrix4(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - -diff --git a/examples-testing/examples/webgl_buffergeometry_lines.ts b/examples-testing/examples/webgl_buffergeometry_lines.ts -index 1aaa5ca4..9d608594 100644 ---- a/examples-testing/examples/webgl_buffergeometry_lines.ts -+++ b/examples-testing/examples/webgl_buffergeometry_lines.ts -@@ -2,11 +2,11 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats, clock; -+let container: HTMLElement, stats: Stats, clock: THREE.Clock; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let line; -+let line: THREE.Line; - - const segments = 10000; - const r = 800; -@@ -15,7 +15,7 @@ let t = 0; - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -93,14 +93,14 @@ function animate() { - line.rotation.y = time * 0.5; - - t += delta * 0.5; -- line.morphTargetInfluences[0] = Math.abs(Math.sin(t)); -+ line.morphTargetInfluences![0] = Math.abs(Math.sin(t)); - - renderer.render(scene, camera); - - stats.update(); - } - --function generateMorphTargets(geometry) { -+function generateMorphTargets(geometry: THREE.BufferGeometry) { - const data = []; - - for (let i = 0; i < segments; i++) { -diff --git a/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts b/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts -index 58296087..8af0d6e9 100644 ---- a/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts -+++ b/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts -@@ -2,16 +2,16 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let parent_node; -+let parent_node: THREE.Object3D; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 9000; -@@ -21,9 +21,9 @@ function init() { - const geometry = new THREE.BufferGeometry(); - const material = new THREE.LineBasicMaterial({ vertexColors: true }); - -- const indices = []; -- const positions = []; -- const colors = []; -+ const indices: number[] = []; -+ const positions: number[] = []; -+ const colors: number[] = []; - - let next_positions_index = 0; - -@@ -32,7 +32,7 @@ function init() { - const iteration_count = 4; - const rangle = (60 * Math.PI) / 180.0; - -- function add_vertex(v) { -+ function add_vertex(v: THREE.Vector3) { - positions.push(v.x, v.y, v.z); - colors.push(Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1); - -@@ -41,7 +41,7 @@ function init() { - - // simple Koch curve - -- function snowflake_iteration(p0, p4, depth) { -+ function snowflake_iteration(p0: THREE.Vector3, p4: THREE.Vector3, depth: number) { - if (--depth < 0) { - const i = next_positions_index - 1; // p0 already there - add_vertex(p4); -@@ -68,7 +68,7 @@ function init() { - snowflake_iteration(p3, p4, depth); - } - -- function snowflake(points, loop, x_offset) { -+ function snowflake(points: THREE.Vector3[], loop: boolean, x_offset: number) { - for (let iteration = 0; iteration != iteration_count; iteration++) { - add_vertex(points[0]); - -diff --git a/examples-testing/examples/webgl_buffergeometry_points.ts b/examples-testing/examples/webgl_buffergeometry_points.ts -index 4547d9d0..357c3ddd 100644 ---- a/examples-testing/examples/webgl_buffergeometry_points.ts -+++ b/examples-testing/examples/webgl_buffergeometry_points.ts -@@ -2,17 +2,17 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let points; -+let points: THREE.Points; - - init(); - animate(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -diff --git a/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts b/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts -index 93eed992..60e05bc0 100644 ---- a/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts -+++ b/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts -@@ -2,16 +2,16 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let points; -+let points: THREE.Points; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 5, 3500); - camera.position.z = 2750; -diff --git a/examples-testing/examples/webgl_buffergeometry_rawshader.ts b/examples-testing/examples/webgl_buffergeometry_rawshader.ts -index 5bc113dc..225e220a 100644 ---- a/examples-testing/examples/webgl_buffergeometry_rawshader.ts -+++ b/examples-testing/examples/webgl_buffergeometry_rawshader.ts -@@ -2,14 +2,14 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10); - camera.position.z = 2; -@@ -53,8 +53,8 @@ function init() { - uniforms: { - time: { value: 1.0 }, - }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - side: THREE.DoubleSide, - transparent: true, - }); -@@ -86,7 +86,7 @@ function onWindowResize() { - function animate() { - const time = performance.now(); - -- const object = scene.children[0]; -+ const object = scene.children[0] as THREE.Mesh; - - object.rotation.y = time * 0.0005; - object.material.uniforms.time.value = time * 0.005; -diff --git a/examples-testing/examples/webgl_buffergeometry_selective_draw.ts b/examples-testing/examples/webgl_buffergeometry_selective_draw.ts -index d07176c5..ce51386e 100644 ---- a/examples-testing/examples/webgl_buffergeometry_selective_draw.ts -+++ b/examples-testing/examples/webgl_buffergeometry_selective_draw.ts -@@ -2,8 +2,8 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; --let geometry, mesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; -+let geometry: THREE.BufferGeometry, mesh: THREE.LineSegments; - const numLat = 100; - const numLng = 200; - let numLinesCulled = 0; -@@ -23,10 +23,10 @@ function init() { - - addLines(1.0); - -- const hideLinesButton = document.getElementById('hideLines'); -+ const hideLinesButton = document.getElementById('hideLines')!; - hideLinesButton.addEventListener('click', hideLines); - -- const showAllLinesButton = document.getElementById('showAllLines'); -+ const showAllLinesButton = document.getElementById('showAllLines')!; - showAllLinesButton.addEventListener('click', showAllLines); - - renderer = new THREE.WebGLRenderer({ antialias: true }); -@@ -36,7 +36,7 @@ function init() { - document.body.appendChild(renderer.domElement); - } - --function addLines(radius) { -+function addLines(radius: number) { - geometry = new THREE.BufferGeometry(); - const linePositions = new Float32Array(numLat * numLng * 3 * 2); - const lineColors = new Float32Array(numLat * numLng * 3 * 2); -@@ -81,8 +81,8 @@ function addLines(radius) { - geometry.computeBoundingSphere(); - - const shaderMaterial = new THREE.ShaderMaterial({ -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - }); - - mesh = new THREE.LineSegments(geometry, shaderMaterial); -@@ -98,7 +98,7 @@ function updateCount() { - ' lines, ' + - numLinesCulled + - ' culled (author)'; -- document.getElementById('title').innerHTML = str.replace(/\B(?=(\d{3})+(?!\d))/g, ','); -+ document.getElementById('title')!.innerHTML = str.replace(/\B(?=(\d{3})+(?!\d))/g, ','); - } - - function hideLines() { -diff --git a/examples-testing/examples/webgl_buffergeometry_uint.ts b/examples-testing/examples/webgl_buffergeometry_uint.ts -index 0b8df6ec..dbb23e05 100644 ---- a/examples-testing/examples/webgl_buffergeometry_uint.ts -+++ b/examples-testing/examples/webgl_buffergeometry_uint.ts -@@ -2,16 +2,16 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let mesh; -+let mesh: THREE.Mesh; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -diff --git a/examples-testing/examples/webgl_camera.ts b/examples-testing/examples/webgl_camera.ts -index f3d66360..4235f508 100644 ---- a/examples-testing/examples/webgl_camera.ts -+++ b/examples-testing/examples/webgl_camera.ts -@@ -6,11 +6,11 @@ let SCREEN_WIDTH = window.innerWidth; - let SCREEN_HEIGHT = window.innerHeight; - let aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - --let container, stats; --let camera, scene, renderer, mesh; --let cameraRig, activeCamera, activeHelper; --let cameraPerspective, cameraOrtho; --let cameraPerspectiveHelper, cameraOrthoHelper; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, mesh: THREE.Mesh; -+let cameraRig: THREE.Group, activeCamera: THREE.Camera, activeHelper: THREE.CameraHelper; -+let cameraPerspective: THREE.PerspectiveCamera, cameraOrtho: THREE.OrthographicCamera; -+let cameraPerspectiveHelper: THREE.CameraHelper, cameraOrthoHelper: THREE.CameraHelper; - const frustumSize = 600; - - init(); -@@ -122,7 +122,7 @@ function init() { - - // - --function onKeyDown(event) { -+function onKeyDown(event: KeyboardEvent) { - switch (event.keyCode) { - case 79 /*O*/: - activeCamera = cameraOrtho; -diff --git a/examples-testing/examples/webgl_camera_array.ts b/examples-testing/examples/webgl_camera_array.ts -index 8b10e27c..11295c5f 100644 ---- a/examples-testing/examples/webgl_camera_array.ts -+++ b/examples-testing/examples/webgl_camera_array.ts -@@ -1,7 +1,7 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; --let mesh; -+let camera: THREE.ArrayCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let mesh: THREE.Mesh; - const AMOUNT = 6; - - init(); -@@ -86,7 +86,7 @@ function onWindowResize() { - for (let x = 0; x < AMOUNT; x++) { - const subcamera = camera.cameras[AMOUNT * y + x]; - -- subcamera.viewport.set(Math.floor(x * WIDTH), Math.floor(y * HEIGHT), Math.ceil(WIDTH), Math.ceil(HEIGHT)); -+ subcamera.viewport!.set(Math.floor(x * WIDTH), Math.floor(y * HEIGHT), Math.ceil(WIDTH), Math.ceil(HEIGHT)); - - subcamera.aspect = ASPECT_RATIO; - subcamera.updateProjectionMatrix(); -diff --git a/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts b/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts -index f1d44000..7f149db1 100644 ---- a/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts -+++ b/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -+import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - - import Stats from 'three/addons/libs/stats.module.js'; -@@ -17,8 +17,16 @@ let zoompos = -100, - minzoomspeed = 0.015; - let zoomspeed = minzoomspeed; - --let container, border, stats; --const objects = {}; -+let container: HTMLElement, border: HTMLElement, stats: Stats; -+ -+interface ObjectView { -+ container: HTMLElement; -+ renderer: THREE.WebGLRenderer; -+ scene: THREE.Scene; -+ camera: THREE.PerspectiveCamera; -+} -+ -+const objects: { normal?: ObjectView; logzbuf?: ObjectView } = {}; - - // Generate a number of text labels, from 1µm in size up to 100,000,000 light years - // Try to use some descriptive real-world examples of objects at each scale -@@ -44,7 +52,7 @@ const labeldata = [ - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_regular.typeface.json', function (font) { -@@ -61,7 +69,7 @@ function init() { - container.appendChild(stats.dom); - - // Resize border allows the user to easily compare effects of logarithmic depth buffer over the whole scene -- border = document.getElementById('renderer_border'); -+ border = document.getElementById('renderer_border')!; - border.addEventListener('pointerdown', onBorderPointerDown); - - window.addEventListener('mousemove', onMouseMove); -@@ -69,8 +77,8 @@ function init() { - window.addEventListener('wheel', onMouseWheel); - } - --function initView(scene, name, logDepthBuf) { -- const framecontainer = document.getElementById('container_' + name); -+function initView(scene: THREE.Scene, name: string, logDepthBuf: boolean) { -+ const framecontainer = document.getElementById('container_' + name)!; - - const camera = new THREE.PerspectiveCamera(50, (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT, NEAR, FAR); - scene.add(camera); -@@ -85,7 +93,7 @@ function initView(scene, name, logDepthBuf) { - return { container: framecontainer, renderer: renderer, scene: scene, camera: camera }; - } - --function initScene(font) { -+function initScene(font: Font) { - const scene = new THREE.Scene(); - - scene.add(new THREE.AmbientLight(0x777777)); -@@ -94,7 +102,7 @@ function initScene(font) { - light.position.set(100, 100, 100); - scene.add(light); - -- const materialargs = { -+ const materialargs: { color: THREE.ColorRepresentation; specular: number; shininess: number; emissive: number } = { - color: 0xffffff, - specular: 0x050505, - shininess: 50, -@@ -115,7 +123,7 @@ function initScene(font) { - labelgeo.computeBoundingSphere(); - - // center text -- labelgeo.translate(-labelgeo.boundingSphere.radius, 0, 0); -+ labelgeo.translate(-labelgeo.boundingSphere!.radius, 0, 0); - - materialargs.color = new THREE.Color().setHSL(Math.random(), 0.5, 0.5); - -@@ -148,16 +156,16 @@ function updateRendererSizes() { - - screensplit_right = 1 - screensplit; - -- objects.normal.renderer.setSize(screensplit * SCREEN_WIDTH, SCREEN_HEIGHT); -- objects.normal.camera.aspect = (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT; -- objects.normal.camera.updateProjectionMatrix(); -- objects.normal.camera.setViewOffset(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH * screensplit, SCREEN_HEIGHT); -- objects.normal.container.style.width = screensplit * 100 + '%'; -+ objects.normal!.renderer.setSize(screensplit * SCREEN_WIDTH, SCREEN_HEIGHT); -+ objects.normal!.camera.aspect = (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT; -+ objects.normal!.camera.updateProjectionMatrix(); -+ objects.normal!.camera.setViewOffset(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH * screensplit, SCREEN_HEIGHT); -+ objects.normal!.container.style.width = screensplit * 100 + '%'; - -- objects.logzbuf.renderer.setSize(screensplit_right * SCREEN_WIDTH, SCREEN_HEIGHT); -- objects.logzbuf.camera.aspect = (screensplit_right * SCREEN_WIDTH) / SCREEN_HEIGHT; -- objects.logzbuf.camera.updateProjectionMatrix(); -- objects.logzbuf.camera.setViewOffset( -+ objects.logzbuf!.renderer.setSize(screensplit_right * SCREEN_WIDTH, SCREEN_HEIGHT); -+ objects.logzbuf!.camera.aspect = (screensplit_right * SCREEN_WIDTH) / SCREEN_HEIGHT; -+ objects.logzbuf!.camera.updateProjectionMatrix(); -+ objects.logzbuf!.camera.setViewOffset( - SCREEN_WIDTH, - SCREEN_HEIGHT, - SCREEN_WIDTH * screensplit, -@@ -165,7 +173,7 @@ function updateRendererSizes() { - SCREEN_WIDTH * screensplit_right, - SCREEN_HEIGHT, - ); -- objects.logzbuf.container.style.width = screensplit_right * 100 + '%'; -+ objects.logzbuf!.container.style.width = screensplit_right * 100 + '%'; - - border.style.left = screensplit * 100 + '%'; - } -@@ -193,22 +201,22 @@ function render() { - zoompos += zoomspeed; - zoomspeed *= damping; - -- objects.normal.camera.position.x = Math.sin(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -- objects.normal.camera.position.y = Math.sin(0.25 * Math.PI * (mouse[1] - 0.5)) * zoom; -- objects.normal.camera.position.z = Math.cos(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -- objects.normal.camera.lookAt(objects.normal.scene.position); -+ objects.normal!.camera.position.x = Math.sin(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -+ objects.normal!.camera.position.y = Math.sin(0.25 * Math.PI * (mouse[1] - 0.5)) * zoom; -+ objects.normal!.camera.position.z = Math.cos(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -+ objects.normal!.camera.lookAt(objects.normal!.scene.position); - - // Clone camera settings across both scenes -- objects.logzbuf.camera.position.copy(objects.normal.camera.position); -- objects.logzbuf.camera.quaternion.copy(objects.normal.camera.quaternion); -+ objects.logzbuf!.camera.position.copy(objects.normal!.camera.position); -+ objects.logzbuf!.camera.quaternion.copy(objects.normal!.camera.quaternion); - - // Update renderer sizes if the split has changed - if (screensplit_right != 1 - screensplit) { - updateRendererSizes(); - } - -- objects.normal.renderer.render(objects.normal.scene, objects.normal.camera); -- objects.logzbuf.renderer.render(objects.logzbuf.scene, objects.logzbuf.camera); -+ objects.normal!.renderer.render(objects.normal!.scene, objects.normal!.camera); -+ objects.logzbuf!.renderer.render(objects.logzbuf!.scene, objects.logzbuf!.camera); - - stats.update(); - } -@@ -223,7 +231,7 @@ function onBorderPointerDown() { - window.addEventListener('pointerup', onBorderPointerUp); - } - --function onBorderPointerMove(ev) { -+function onBorderPointerMove(ev: PointerEvent) { - screensplit = Math.max(0, Math.min(1, ev.clientX / window.innerWidth)); - } - -@@ -232,12 +240,12 @@ function onBorderPointerUp() { - window.removeEventListener('pointerup', onBorderPointerUp); - } - --function onMouseMove(ev) { -+function onMouseMove(ev: MouseEvent) { - mouse[0] = ev.clientX / window.innerWidth; - mouse[1] = ev.clientY / window.innerHeight; - } - --function onMouseWheel(ev) { -+function onMouseWheel(ev: WheelEvent) { - const amount = ev.deltaY; - if (amount === 0) return; - const dir = amount / Math.abs(amount); -diff --git a/examples-testing/examples/webgl_clipculldistance.ts b/examples-testing/examples/webgl_clipculldistance.ts -index a5fb54d4..0165880a 100644 ---- a/examples-testing/examples/webgl_clipculldistance.ts -+++ b/examples-testing/examples/webgl_clipculldistance.ts -@@ -2,9 +2,14 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, controls, clock, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, -+ controls: OrbitControls, -+ clock: THREE.Clock, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats; - --let material; -+let material: THREE.ShaderMaterial; - - init(); - -@@ -25,7 +30,7 @@ function init() { - document.body.appendChild(renderer.domElement); - - if (renderer.extensions.has('WEBGL_clip_cull_distance') === false) { -- document.getElementById('notSupported').style.display = ''; -+ document.getElementById('notSupported')!.style.display = ''; - return; - } - -@@ -69,8 +74,8 @@ function init() { - uniforms: { - time: { value: 1.0 }, - }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - side: THREE.DoubleSide, - transparent: true, - vertexColors: true, -diff --git a/examples-testing/examples/webgl_clipping.ts b/examples-testing/examples/webgl_clipping.ts -index cde10c7d..6ab3ba65 100644 ---- a/examples-testing/examples/webgl_clipping.ts -+++ b/examples-testing/examples/webgl_clipping.ts -@@ -5,7 +5,12 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, startTime, object, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ startTime: number, -+ object: THREE.Mesh, -+ stats: Stats; - - init(); - -@@ -93,8 +98,8 @@ function init() { - - // ***** Clipping setup (renderer): ***** - const globalPlanes = [globalPlane], -- Empty = Object.freeze([]); -- renderer.clippingPlanes = Empty; // GUI sets it to globalPlanes -+ Empty = Object.freeze([]); -+ renderer.clippingPlanes = Empty as THREE.Plane[]; // GUI sets it to globalPlanes - renderer.localClippingEnabled = true; - - // Stats -@@ -143,7 +148,7 @@ function init() { - return renderer.clippingPlanes !== Empty; - }, - set Enabled(v) { -- renderer.clippingPlanes = v ? globalPlanes : Empty; -+ renderer.clippingPlanes = v ? globalPlanes : (Empty as THREE.Plane[]); - }, - - get Plane() { -diff --git a/examples-testing/examples/webgl_clipping_advanced.ts b/examples-testing/examples/webgl_clipping_advanced.ts -index 614d710d..02b9ad88 100644 ---- a/examples-testing/examples/webgl_clipping_advanced.ts -+++ b/examples-testing/examples/webgl_clipping_advanced.ts -@@ -5,7 +5,7 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --function planesFromMesh(vertices, indices) { -+function planesFromMesh(vertices: THREE.Vector3[], indices: number[]) { - // creates a clipping volume from a convex triangular mesh - // specified by the arrays 'vertices' and 'indices' - -@@ -23,23 +23,23 @@ function planesFromMesh(vertices, indices) { - return result; - } - --function createPlanes(n) { -+function createPlanes(n: number) { - // creates an array of n uninitialized plane objects - -- const result = new Array(n); -+ const result = new Array(n); - - for (let i = 0; i !== n; ++i) result[i] = new THREE.Plane(); - - return result; - } - --function assignTransformedPlanes(planesOut, planesIn, matrix) { -+function assignTransformedPlanes(planesOut: THREE.Plane[], planesIn: THREE.Plane[], matrix: THREE.Matrix4) { - // sets an array of existing planes to transformed 'planesIn' - - for (let i = 0, n = planesIn.length; i !== n; ++i) planesOut[i].copy(planesIn[i]).applyMatrix4(matrix); - } - --function cylindricalPlanes(n, innerRadius) { -+function cylindricalPlanes(n: number, innerRadius: number) { - const result = createPlanes(n); - - for (let i = 0; i !== n; ++i) { -@@ -62,7 +62,7 @@ const planeToMatrix = (function () { - yAxis = new THREE.Vector3(), - trans = new THREE.Vector3(); - -- return function planeToMatrix(plane) { -+ return function planeToMatrix(plane: THREE.Plane) { - const zAxis = plane.normal, - matrix = new THREE.Matrix4(); - -@@ -111,9 +111,17 @@ const Vertices = [ - Planes = planesFromMesh(Vertices, Indices), - PlaneMatrices = Planes.map(planeToMatrix), - GlobalClippingPlanes = cylindricalPlanes(5, 2.5), -- Empty = Object.freeze([]); -- --let camera, scene, renderer, startTime, stats, object, clipMaterial, volumeVisualization, globalClippingPlanes; -+ Empty = Object.freeze([]); -+ -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ startTime: number, -+ stats: Stats, -+ object: THREE.Group, -+ clipMaterial: THREE.MeshPhongMaterial, -+ volumeVisualization: THREE.Group, -+ globalClippingPlanes: THREE.Plane[]; - - function init() { - camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 0.25, 16); -@@ -194,7 +202,7 @@ function init() { - - // clip to the others to show the volume (wildly - // intersecting transparent planes look bad) -- clippingPlanes: clipMaterial.clippingPlanes.filter(function (_, j) { -+ clippingPlanes: clipMaterial.clippingPlanes!.filter(function (_, j) { - return j !== i; - }), - -@@ -234,7 +242,7 @@ function init() { - container.appendChild(renderer.domElement); - // Clipping setup: - globalClippingPlanes = createPlanes(GlobalClippingPlanes.length); -- renderer.clippingPlanes = Empty; -+ renderer.clippingPlanes = Empty as THREE.Plane[]; - renderer.localClippingEnabled = true; - - window.addEventListener('resize', onWindowResize); -@@ -290,7 +298,7 @@ function init() { - return renderer.clippingPlanes !== Empty; - }, - set Enabled(v) { -- renderer.clippingPlanes = v ? globalClippingPlanes : Empty; -+ renderer.clippingPlanes = v ? globalClippingPlanes : (Empty as THREE.Plane[]); - }, - }, - 'Enabled', -@@ -308,12 +316,12 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function setObjectWorldMatrix(object, matrix) { -+function setObjectWorldMatrix(object: THREE.Object3D, matrix: THREE.Matrix4) { - // set the orientation of an object based on a world matrix - - const parent = object.parent; - scene.updateMatrixWorld(); -- object.matrix.copy(parent.matrixWorld).invert(); -+ object.matrix.copy(parent!.matrixWorld).invert(); - object.applyMatrix4(matrix); - } - -@@ -334,7 +342,7 @@ function animate() { - const bouncy = Math.cos(time * 0.5) * 0.5 + 0.7; - transform.multiply(tmpMatrix.makeScale(bouncy, bouncy, bouncy)); - -- assignTransformedPlanes(clipMaterial.clippingPlanes, Planes, transform); -+ assignTransformedPlanes(clipMaterial.clippingPlanes!, Planes, transform); - - const planeMeshes = volumeVisualization.children; - -diff --git a/examples-testing/examples/webgl_clipping_intersection.ts b/examples-testing/examples/webgl_clipping_intersection.ts -index 5f45e45d..cb3cbdf2 100644 ---- a/examples-testing/examples/webgl_clipping_intersection.ts -+++ b/examples-testing/examples/webgl_clipping_intersection.ts -@@ -4,7 +4,7 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - const params = { - clipIntersection: true, -@@ -80,8 +80,8 @@ function init() { - - gui.add(params, 'alphaToCoverage').onChange(function (value) { - group.children.forEach(c => { -- c.material.alphaToCoverage = Boolean(value); -- c.material.needsUpdate = true; -+ (c as THREE.Mesh).material.alphaToCoverage = Boolean(value); -+ (c as THREE.Mesh).material.needsUpdate = true; - }); - - render(); -@@ -93,7 +93,7 @@ function init() { - const children = group.children; - - for (let i = 0; i < children.length; i++) { -- children[i].material.clipIntersection = value; -+ ((children[i] as THREE.Mesh).material as THREE.Material).clipIntersection = value; - } - - render(); -diff --git a/examples-testing/examples/webgl_clipping_stencil.ts b/examples-testing/examples/webgl_clipping_stencil.ts -index ecb6b42b..6efdbf5a 100644 ---- a/examples-testing/examples/webgl_clipping_stencil.ts -+++ b/examples-testing/examples/webgl_clipping_stencil.ts -@@ -3,9 +3,13 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, object, stats; --let planes, planeObjects, planeHelpers; --let clock; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ object: THREE.Group, -+ stats: Stats; -+let planes: THREE.Plane[], planeObjects: THREE.Mesh[], planeHelpers: THREE.PlaneHelper[]; -+let clock: THREE.Clock; - - const params = { - animate: true, -@@ -28,7 +32,7 @@ const params = { - - init(); - --function createPlaneStencilGroup(geometry, plane, renderOrder) { -+function createPlaneStencilGroup(geometry: THREE.TorusKnotGeometry, plane: THREE.Plane, renderOrder: number) { - const group = new THREE.Group(); - const baseMat = new THREE.MeshBasicMaterial(); - baseMat.depthWrite = false; -diff --git a/examples-testing/examples/webgl_custom_attributes.ts b/examples-testing/examples/webgl_custom_attributes.ts -index 0dc89774..8725fd46 100644 ---- a/examples-testing/examples/webgl_custom_attributes.ts -+++ b/examples-testing/examples/webgl_custom_attributes.ts -@@ -2,11 +2,16 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let sphere, uniforms; -+let sphere: THREE.Mesh, -+ uniforms: { -+ amplitude: THREE.IUniform; -+ color: THREE.IUniform; -+ colorTexture: THREE.IUniform; -+ }; - --let displacement, noise; -+let displacement: Float32Array, noise: Float32Array; - - init(); - -@@ -27,8 +32,8 @@ function init() { - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - }); - - const radius = 50, -@@ -54,7 +59,7 @@ function init() { - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - stats = new Stats(); -diff --git a/examples-testing/examples/webgl_custom_attributes_lines.ts b/examples-testing/examples/webgl_custom_attributes_lines.ts -index 3e2454e9..d89a77d5 100644 ---- a/examples-testing/examples/webgl_custom_attributes_lines.ts -+++ b/examples-testing/examples/webgl_custom_attributes_lines.ts -@@ -1,20 +1,25 @@ - import * as THREE from 'three'; - --import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -+import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let line, uniforms; -+let line: THREE.Line, -+ uniforms: { -+ amplitude: THREE.IUniform; -+ opacity: THREE.IUniform; -+ color: THREE.IUniform; -+ }; - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_bold.typeface.json', function (font) { - init(font); - }); - --function init(font) { -+function init(font: Font) { - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 400; - -@@ -29,8 +34,8 @@ function init(font) { - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, -@@ -75,7 +80,7 @@ function init(font) { - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - stats = new Stats(); -diff --git a/examples-testing/examples/webgl_custom_attributes_points.ts b/examples-testing/examples/webgl_custom_attributes_points.ts -index ae112980..9035134c 100644 ---- a/examples-testing/examples/webgl_custom_attributes_points.ts -+++ b/examples-testing/examples/webgl_custom_attributes_points.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let sphere; -+let sphere: THREE.Points; - - const WIDTH = window.innerWidth; - const HEIGHT = window.innerHeight; -@@ -56,8 +56,8 @@ function init() { - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: new THREE.TextureLoader().load('textures/sprites/spark1.png') }, - }, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - - blending: THREE.AdditiveBlending, - depthTest: false, -@@ -76,7 +76,7 @@ function init() { - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - stats = new Stats(); -diff --git a/examples-testing/examples/webgl_custom_attributes_points2.ts b/examples-testing/examples/webgl_custom_attributes_points2.ts -index edd158fa..6f58c70a 100644 ---- a/examples-testing/examples/webgl_custom_attributes_points2.ts -+++ b/examples-testing/examples/webgl_custom_attributes_points2.ts -@@ -4,8 +4,8 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let renderer, scene, camera, stats; --let sphere, length1; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; -+let sphere: THREE.Points, length1: number; - - const WIDTH = window.innerWidth; - const HEIGHT = window.innerHeight; -@@ -22,8 +22,8 @@ function init() { - segments = 68, - rings = 38; - -- let sphereGeometry = new THREE.SphereGeometry(radius, segments, rings); -- let boxGeometry = new THREE.BoxGeometry(0.8 * radius, 0.8 * radius, 0.8 * radius, 10, 10, 10); -+ let sphereGeometry: THREE.BufferGeometry = new THREE.SphereGeometry(radius, segments, rings); -+ let boxGeometry: THREE.BufferGeometry = new THREE.BoxGeometry(0.8 * radius, 0.8 * radius, 0.8 * radius, 10, 10, 10); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate identical vertices with different normal/uv data - -@@ -39,8 +39,8 @@ function init() { - const combinedGeometry = BufferGeometryUtils.mergeGeometries([sphereGeometry, boxGeometry]); - const positionAttribute = combinedGeometry.getAttribute('position'); - -- const colors = []; -- const sizes = []; -+ const colors: number[] = []; -+ const sizes: number[] = []; - - const color = new THREE.Color(); - const vertex = new THREE.Vector3(); -@@ -77,8 +77,8 @@ function init() { - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: texture }, - }, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - transparent: true, - }); - -@@ -94,7 +94,7 @@ function init() { - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - stats = new Stats(); -@@ -150,7 +150,7 @@ function sortPoints() { - sortArray.push([vector.z, i]); - } - -- function numericalSort(a, b) { -+ function numericalSort(a: number[], b: number[]) { - return b[0] - a[0]; - } - -@@ -162,7 +162,7 @@ function sortPoints() { - indices[i] = sortArray[i][1]; - } - -- geometry.index.needsUpdate = true; -+ geometry.index!.needsUpdate = true; - } - - function animate() { -diff --git a/examples-testing/examples/webgl_custom_attributes_points3.ts b/examples-testing/examples/webgl_custom_attributes_points3.ts -index 1b46a805..e5798e30 100644 ---- a/examples-testing/examples/webgl_custom_attributes_points3.ts -+++ b/examples-testing/examples/webgl_custom_attributes_points3.ts -@@ -4,11 +4,11 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let object; -+let object: THREE.Points; - --let vertices1; -+let vertices1: number; - - const WIDTH = window.innerWidth; - const HEIGHT = window.innerHeight; -@@ -47,7 +47,7 @@ function init() { - - radius = 200; - -- let boxGeometry1 = new THREE.BoxGeometry(radius, 0.1 * radius, 0.1 * radius, 50, 5, 5); -+ let boxGeometry1: THREE.BufferGeometry = new THREE.BoxGeometry(radius, 0.1 * radius, 0.1 * radius, 50, 5, 5); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data - -@@ -62,7 +62,7 @@ function init() { - const quaternion = new THREE.Quaternion(); - const scale = new THREE.Vector3(1, 1, 1); - -- function addGeo(geo, x, y, z, ry) { -+ function addGeo(geo: THREE.BufferGeometry, x: number, y: number, z: number, ry: number) { - position.set(x, y, z); - rotation.set(0, ry, 0); - -@@ -93,7 +93,7 @@ function init() { - - // corner edges - -- let boxGeometry2 = new THREE.BoxGeometry(0.1 * radius, radius * 1.2, 0.1 * radius, 5, 60, 5); -+ let boxGeometry2: THREE.BufferGeometry = new THREE.BoxGeometry(0.1 * radius, radius * 1.2, 0.1 * radius, 5, 60, 5); - - boxGeometry2.deleteAttribute('normal'); - boxGeometry2.deleteAttribute('uv'); -@@ -107,8 +107,8 @@ function init() { - - const positionAttribute = new THREE.Float32BufferAttribute(vertices, 3); - -- const colors = []; -- const sizes = []; -+ const colors: number[] = []; -+ const sizes: number[] = []; - - const color = new THREE.Color(); - -@@ -141,8 +141,8 @@ function init() { - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: texture }, - }, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - }); - - // -@@ -157,7 +157,7 @@ function init() { - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - stats = new Stats(); -diff --git a/examples-testing/examples/webgl_decals.ts b/examples-testing/examples/webgl_decals.ts -index 23cdb4da..bbaddccc 100644 ---- a/examples-testing/examples/webgl_decals.ts -+++ b/examples-testing/examples/webgl_decals.ts -@@ -7,12 +7,12 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { DecalGeometry } from 'three/addons/geometries/DecalGeometry.js'; - --const container = document.getElementById('container'); -+const container = document.getElementById('container')!; - --let renderer, scene, camera, stats; --let mesh; --let raycaster; --let line; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; -+let mesh: THREE.Mesh; -+let raycaster: THREE.Raycaster; -+let line: THREE.Line; - - const intersection = { - intersects: false, -@@ -20,7 +20,7 @@ const intersection = { - normal: new THREE.Vector3(), - }; - const mouse = new THREE.Vector2(); --const intersects = []; -+const intersects: THREE.Intersection[] = []; - - const textureLoader = new THREE.TextureLoader(); - const decalDiffuse = textureLoader.load('textures/decal/decal-diffuse.png'); -@@ -41,8 +41,8 @@ const decalMaterial = new THREE.MeshPhongMaterial({ - wireframe: false, - }); - --const decals = []; --let mouseHelper; -+const decals: THREE.Mesh[] = []; -+let mouseHelper: THREE.Mesh; - const position = new THREE.Vector3(); - const orientation = new THREE.Euler(); - const size = new THREE.Vector3(10, 10, 10); -@@ -123,13 +123,13 @@ function init() { - - window.addEventListener('pointermove', onPointerMove); - -- function onPointerMove(event) { -+ function onPointerMove(event: PointerEvent) { - if (event.isPrimary) { - checkIntersection(event.clientX, event.clientY); - } - } - -- function checkIntersection(x, y) { -+ function checkIntersection(x: number, y: number) { - if (mesh === undefined) return; - - mouse.x = (x / window.innerWidth) * 2 - 1; -@@ -143,12 +143,12 @@ function init() { - mouseHelper.position.copy(p); - intersection.point.copy(p); - -- const n = intersects[0].face.normal.clone(); -+ const n = intersects[0].face!.normal.clone(); - n.transformDirection(mesh.matrixWorld); - n.multiplyScalar(10); - n.add(intersects[0].point); - -- intersection.normal.copy(intersects[0].face.normal); -+ intersection.normal.copy(intersects[0].face!.normal); - mouseHelper.lookAt(n); - - const positions = line.geometry.attributes.position; -@@ -182,7 +182,7 @@ function loadLeePerrySmith() { - const loader = new GLTFLoader(); - - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { -- mesh = gltf.scene.children[0]; -+ mesh = gltf.scene.children[0] as THREE.Mesh; - mesh.material = new THREE.MeshPhongMaterial({ - specular: 0x111111, - map: map, -diff --git a/examples-testing/examples/webgl_effects_anaglyph.ts b/examples-testing/examples/webgl_effects_anaglyph.ts -index 8415973d..d6a7d4c5 100644 ---- a/examples-testing/examples/webgl_effects_anaglyph.ts -+++ b/examples-testing/examples/webgl_effects_anaglyph.ts -@@ -2,9 +2,13 @@ import * as THREE from 'three'; - - import { AnaglyphEffect } from 'three/addons/effects/AnaglyphEffect.js'; - --let container, camera, scene, renderer, effect; -+let container: HTMLDivElement, -+ camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ effect: AnaglyphEffect; - --const spheres = []; -+const spheres: THREE.Mesh[] = []; - - let mouseX = 0; - let mouseY = 0; -@@ -84,7 +88,7 @@ function onWindowResize() { - effect.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = (event.clientX - windowHalfX) / 100; - mouseY = (event.clientY - windowHalfY) / 100; - } -diff --git a/examples-testing/examples/webgl_effects_ascii.ts b/examples-testing/examples/webgl_effects_ascii.ts -index a412bb79..751102d7 100644 ---- a/examples-testing/examples/webgl_effects_ascii.ts -+++ b/examples-testing/examples/webgl_effects_ascii.ts -@@ -3,9 +3,13 @@ import * as THREE from 'three'; - import { AsciiEffect } from 'three/addons/effects/AsciiEffect.js'; - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - --let camera, controls, scene, renderer, effect; -+let camera: THREE.PerspectiveCamera, -+ controls: TrackballControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ effect: AsciiEffect; - --let sphere, plane; -+let sphere: THREE.Mesh, plane: THREE.Mesh; - - const start = Date.now(); - -diff --git a/examples-testing/examples/webgl_effects_parallaxbarrier.ts b/examples-testing/examples/webgl_effects_parallaxbarrier.ts -index 90c86797..e03cb5d7 100644 ---- a/examples-testing/examples/webgl_effects_parallaxbarrier.ts -+++ b/examples-testing/examples/webgl_effects_parallaxbarrier.ts -@@ -2,9 +2,13 @@ import * as THREE from 'three'; - - import { ParallaxBarrierEffect } from 'three/addons/effects/ParallaxBarrierEffect.js'; - --let container, camera, scene, renderer, effect; -+let container: HTMLDivElement, -+ camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ effect: ParallaxBarrierEffect; - --const spheres = []; -+const spheres: THREE.Mesh[] = []; - - let mouseX = 0; - let mouseY = 0; -@@ -84,7 +88,7 @@ function onWindowResize() { - effect.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = (event.clientX - windowHalfX) / 100; - mouseY = (event.clientY - windowHalfY) / 100; - } -diff --git a/examples-testing/examples/webgl_effects_peppersghost.ts b/examples-testing/examples/webgl_effects_peppersghost.ts -index 41dfb4b6..54f8aaa5 100644 ---- a/examples-testing/examples/webgl_effects_peppersghost.ts -+++ b/examples-testing/examples/webgl_effects_peppersghost.ts -@@ -2,10 +2,10 @@ import * as THREE from 'three'; - - import { PeppersGhostEffect } from 'three/addons/effects/PeppersGhostEffect.js'; - --let container; -+let container: HTMLDivElement; - --let camera, scene, renderer, effect; --let group; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, effect: PeppersGhostEffect; -+let group: THREE.Group; - - init(); - -diff --git a/examples-testing/examples/webgl_effects_stereo.ts b/examples-testing/examples/webgl_effects_stereo.ts -index dd2f61f9..6dab1b6e 100644 ---- a/examples-testing/examples/webgl_effects_stereo.ts -+++ b/examples-testing/examples/webgl_effects_stereo.ts -@@ -2,9 +2,13 @@ import * as THREE from 'three'; - - import { StereoEffect } from 'three/addons/effects/StereoEffect.js'; - --let container, camera, scene, renderer, effect; -+let container: HTMLDivElement, -+ camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ effect: StereoEffect; - --const spheres = []; -+const spheres: THREE.Mesh[] = []; - - let mouseX = 0, - mouseY = 0; -@@ -73,7 +77,7 @@ function onWindowResize() { - effect.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = (event.clientX - windowHalfX) * 10; - mouseY = (event.clientY - windowHalfY) * 10; - } -diff --git a/examples-testing/examples/webgl_framebuffer_texture.ts b/examples-testing/examples/webgl_framebuffer_texture.ts -index df4acc9d..636f9db9 100644 ---- a/examples-testing/examples/webgl_framebuffer_texture.ts -+++ b/examples-testing/examples/webgl_framebuffer_texture.ts -@@ -3,10 +3,10 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - --let camera, scene, renderer; --let line, sprite, texture; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let line: THREE.Line, sprite: THREE.Sprite, texture: THREE.FramebufferTexture; - --let cameraOrtho, sceneOrtho; -+let cameraOrtho: THREE.OrthographicCamera, sceneOrtho: THREE.Scene; - - let offset = 0; - -@@ -76,7 +76,7 @@ function init() { - - // - -- const selection = document.getElementById('selection'); -+ const selection = document.getElementById('selection')!; - const controls = new OrbitControls(camera, selection); - controls.enablePan = false; - -@@ -133,7 +133,7 @@ function animate() { - renderer.render(sceneOrtho, cameraOrtho); - } - --function updateColors(colorAttribute) { -+function updateColors(colorAttribute: THREE.BufferAttribute | THREE.InterleavedBufferAttribute) { - const l = colorAttribute.count; - - for (let i = 0; i < l; i++) { -diff --git a/examples-testing/examples/webgl_furnace_test.ts b/examples-testing/examples/webgl_furnace_test.ts -index a8195417..46230b4a 100644 ---- a/examples-testing/examples/webgl_furnace_test.ts -+++ b/examples-testing/examples/webgl_furnace_test.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --let scene, camera, renderer, radianceMap; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, radianceMap: THREE.Texture; - - const COLOR = 0xcccccc; - -@@ -20,7 +20,8 @@ function init() { - - document.body.addEventListener('mouseover', function () { - scene.traverse(function (child) { -- if (child.isMesh) child.material.color.setHex(0xffffff); -+ if ((child as THREE.Mesh).isMesh) -+ ((child as THREE.Mesh).material as THREE.MeshStandardMaterial).color.setHex(0xffffff); - }); - - render(); -@@ -28,7 +29,8 @@ function init() { - - document.body.addEventListener('mouseout', function () { - scene.traverse(function (child) { -- if (child.isMesh) child.material.color.setHex(0xccccff); // tinted for visibility -+ if ((child as THREE.Mesh).isMesh) -+ ((child as THREE.Mesh).material as THREE.MeshStandardMaterial).color.setHex(0xccccff); // tinted for visibility - }); - - render(); -diff --git a/examples-testing/examples/webgl_geometries.ts b/examples-testing/examples/webgl_geometries.ts -index 2b2d0261..d5820b37 100644 ---- a/examples-testing/examples/webgl_geometries.ts -+++ b/examples-testing/examples/webgl_geometries.ts -@@ -2,7 +2,7 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - init(); - -@@ -127,7 +127,7 @@ function render() { - camera.lookAt(scene.position); - - scene.traverse(function (object) { -- if (object.isMesh === true) { -+ if ((object as THREE.Mesh).isMesh === true) { - object.rotation.x = timer * 5; - object.rotation.y = timer * 2.5; - } -diff --git a/examples-testing/examples/webgl_geometries_parametric.ts b/examples-testing/examples/webgl_geometries_parametric.ts -index 29bf7ae2..30a6930c 100644 ---- a/examples-testing/examples/webgl_geometries_parametric.ts -+++ b/examples-testing/examples/webgl_geometries_parametric.ts -@@ -6,12 +6,12 @@ import * as Curves from 'three/addons/curves/CurveExtras.js'; - import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; - import { ParametricGeometries } from 'three/addons/geometries/ParametricGeometries.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.y = 400; -@@ -114,7 +114,7 @@ function render() { - camera.lookAt(scene.position); - - scene.traverse(function (object) { -- if (object.isMesh === true) { -+ if ((object as THREE.Mesh).isMesh === true) { - object.rotation.x = timer * 5; - object.rotation.y = timer * 2.5; - } -diff --git a/examples-testing/examples/webgl_geometry_colors.ts b/examples-testing/examples/webgl_geometry_colors.ts -index bc0bf517..68466b5b 100644 ---- a/examples-testing/examples/webgl_geometry_colors.ts -+++ b/examples-testing/examples/webgl_geometry_colors.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mouseX = 0, - mouseY = 0; -@@ -15,7 +15,7 @@ let windowHalfY = window.innerHeight / 2; - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 1800; -@@ -33,7 +33,7 @@ function init() { - canvas.width = 128; - canvas.height = 128; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - const gradient = context.createRadialGradient( - canvas.width / 2, - canvas.height / 2, -@@ -154,7 +154,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_geometry_colors_lookuptable.ts b/examples-testing/examples/webgl_geometry_colors_lookuptable.ts -index 6b013852..382a9b7a 100644 ---- a/examples-testing/examples/webgl_geometry_colors_lookuptable.ts -+++ b/examples-testing/examples/webgl_geometry_colors_lookuptable.ts -@@ -5,19 +5,19 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Lut } from 'three/addons/math/Lut.js'; - --let container; -+let container: HTMLElement; - --let perpCamera, orthoCamera, renderer, lut; -+let perpCamera: THREE.PerspectiveCamera, orthoCamera: THREE.OrthographicCamera, renderer: THREE.WebGLRenderer, lut: Lut; - --let mesh, sprite; --let scene, uiScene; -+let mesh: THREE.Mesh, sprite: THREE.Sprite; -+let scene: THREE.Scene, uiScene: THREE.Scene; - --let params; -+let params: { colorMap: string }; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); -@@ -41,7 +41,7 @@ function init() { - map: new THREE.CanvasTexture(lut.createCanvas()), - }), - ); -- sprite.material.map.colorSpace = THREE.SRGBColorSpace; -+ sprite.material.map!.colorSpace = THREE.SRGBColorSpace; - sprite.scale.x = 0.125; - uiScene.add(sprite); - -@@ -142,7 +142,7 @@ function updateColors() { - - colors.needsUpdate = true; - -- const map = sprite.material.map; -+ const map = sprite.material.map!; - lut.updateCanvas(map.image); - map.needsUpdate = true; - } -diff --git a/examples-testing/examples/webgl_geometry_convex.ts b/examples-testing/examples/webgl_geometry_convex.ts -index ade9cb80..87ea7be3 100644 ---- a/examples-testing/examples/webgl_geometry_convex.ts -+++ b/examples-testing/examples/webgl_geometry_convex.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js'; - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let group, camera, scene, renderer; -+let group: THREE.Group, camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -54,7 +54,7 @@ function init() { - - // points - -- let dodecahedronGeometry = new THREE.DodecahedronGeometry(10); -+ let dodecahedronGeometry: THREE.BufferGeometry = new THREE.DodecahedronGeometry(10); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data - -diff --git a/examples-testing/examples/webgl_geometry_cube.ts b/examples-testing/examples/webgl_geometry_cube.ts -index 572601ac..136a3141 100644 ---- a/examples-testing/examples/webgl_geometry_cube.ts -+++ b/examples-testing/examples/webgl_geometry_cube.ts -@@ -1,7 +1,7 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; --let mesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let mesh: THREE.Mesh; - - init(); - -diff --git a/examples-testing/examples/webgl_geometry_dynamic.ts b/examples-testing/examples/webgl_geometry_dynamic.ts -index 06e858f5..28273563 100644 ---- a/examples-testing/examples/webgl_geometry_dynamic.ts -+++ b/examples-testing/examples/webgl_geometry_dynamic.ts -@@ -4,9 +4,13 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; - --let camera, controls, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, -+ controls: FirstPersonControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats; - --let mesh, geometry, material, clock; -+let mesh: THREE.Mesh, geometry: THREE.PlaneGeometry, material: THREE.MeshBasicMaterial, clock: THREE.Clock; - - const worldWidth = 128, - worldDepth = 128; -@@ -26,7 +30,7 @@ function init() { - geometry = new THREE.PlaneGeometry(20000, 20000, worldWidth - 1, worldDepth - 1); - geometry.rotateX(-Math.PI / 2); - -- const position = geometry.attributes.position; -+ const position = geometry.attributes.position as THREE.BufferAttribute; - position.usage = THREE.DynamicDrawUsage; - - for (let i = 0; i < position.count; i++) { -diff --git a/examples-testing/examples/webgl_geometry_extrude_shapes.ts b/examples-testing/examples/webgl_geometry_extrude_shapes.ts -index 7428aee3..386e8d57 100644 ---- a/examples-testing/examples/webgl_geometry_extrude_shapes.ts -+++ b/examples-testing/examples/webgl_geometry_extrude_shapes.ts -@@ -2,7 +2,7 @@ import * as THREE from 'three'; - - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: TrackballControls; - - init(); - -@@ -13,7 +13,7 @@ function init() { - info.style.width = '100%'; - info.style.textAlign = 'center'; - info.style.color = '#fff'; -- info.style.link = '#f80'; -+ (info.style as any).link = '#f80'; - info.innerHTML = - 'three.js webgl - geometry extrude shapes'; - document.body.appendChild(info); -diff --git a/examples-testing/examples/webgl_geometry_extrude_splines.ts b/examples-testing/examples/webgl_geometry_extrude_splines.ts -index 0741083d..e988b543 100644 ---- a/examples-testing/examples/webgl_geometry_extrude_splines.ts -+++ b/examples-testing/examples/webgl_geometry_extrude_splines.ts -@@ -6,9 +6,14 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import * as Curves from 'three/addons/curves/CurveExtras.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer, splineCamera, cameraHelper, cameraEye; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ splineCamera: THREE.PerspectiveCamera, -+ cameraHelper: THREE.CameraHelper, -+ cameraEye: THREE.Mesh; - - const direction = new THREE.Vector3(); - const binormal = new THREE.Vector3(); -@@ -78,9 +83,18 @@ const splines = { - SampleClosedSpline: sampleClosedSpline, - }; - --let parent, tubeGeometry, mesh; -- --const params = { -+let parent: THREE.Object3D, tubeGeometry: THREE.TubeGeometry, mesh: THREE.Mesh; -+ -+const params: { -+ spline: keyof typeof splines; -+ scale: number; -+ extrusionSegments: number; -+ radiusSegments: number; -+ closed: boolean; -+ animationView: boolean; -+ lookAhead: boolean; -+ cameraHelper: boolean; -+} = { - spline: 'GrannyKnot', - scale: 4, - extrusionSegments: 100, -@@ -125,7 +139,7 @@ function setScale() { - mesh.scale.set(params.scale, params.scale, params.scale); - } - --function addGeometry(geometry) { -+function addGeometry(geometry: THREE.BufferGeometry) { - // 3D shape - - mesh = new THREE.Mesh(geometry, material); -@@ -143,7 +157,7 @@ function animateCamera() { - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // camera - -@@ -202,7 +216,7 @@ function init() { - const gui = new GUI({ width: 285 }); - - const folderGeometry = gui.addFolder('Geometry'); -- folderGeometry.add(params, 'spline', Object.keys(splines)).onChange(function () { -+ folderGeometry.add(params, 'spline', Object.keys(splines) as (keyof typeof splines)[]).onChange(function () { - addTube(); - }); - folderGeometry -diff --git a/examples-testing/examples/webgl_geometry_minecraft.ts b/examples-testing/examples/webgl_geometry_minecraft.ts -index 765aa1e4..b15665d8 100644 ---- a/examples-testing/examples/webgl_geometry_minecraft.ts -+++ b/examples-testing/examples/webgl_geometry_minecraft.ts -@@ -6,9 +6,9 @@ import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.j - import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, controls, scene, renderer; -+let camera: THREE.PerspectiveCamera, controls: FirstPersonControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - const worldWidth = 128, - worldDepth = 128; -@@ -21,7 +21,7 @@ const clock = new THREE.Clock(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 20000); - camera.position.y = getY(worldHalfWidth, worldHalfDepth) * 100 + 100; -@@ -143,7 +143,7 @@ function onWindowResize() { - controls.handleResize(); - } - --function generateHeight(width, height) { -+function generateHeight(width: number, height: number) { - const data = [], - perlin = new ImprovedNoise(), - size = width * height, -@@ -166,7 +166,7 @@ function generateHeight(width, height) { - return data; - } - --function getY(x, z) { -+function getY(x: number, z: number) { - return (data[x + z * worldWidth] * 0.15) | 0; - } - -diff --git a/examples-testing/examples/webgl_geometry_nurbs.ts b/examples-testing/examples/webgl_geometry_nurbs.ts -index a603710b..74676e45 100644 ---- a/examples-testing/examples/webgl_geometry_nurbs.ts -+++ b/examples-testing/examples/webgl_geometry_nurbs.ts -@@ -7,10 +7,10 @@ import { NURBSSurface } from 'three/addons/curves/NURBSSurface.js'; - import { NURBSVolume } from 'three/addons/curves/NURBSVolume.js'; - import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; --let group; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let group: THREE.Group; - - let targetRotation = 0; - let targetRotationOnPointerDown = 0; -@@ -78,7 +78,7 @@ function init() { - group.add(nurbsLine); - - const nurbsControlPointsGeometry = new THREE.BufferGeometry(); -- nurbsControlPointsGeometry.setFromPoints(nurbsCurve.controlPoints); -+ nurbsControlPointsGeometry.setFromPoints(nurbsCurve.controlPoints as THREE.Vector3[]); - - const nurbsControlPointsMaterial = new THREE.LineBasicMaterial({ - color: 0x333333, -@@ -123,7 +123,7 @@ function init() { - map.anisotropy = 16; - map.colorSpace = THREE.SRGBColorSpace; - -- function getSurfacePoint(u, v, target) { -+ function getSurfacePoint(u: number, v: number, target: THREE.Vector3) { - return nurbsSurface.getPoint(u, v, target); - } - -@@ -174,23 +174,23 @@ function init() { - // we create evaluation functions for different surfaces with one of the three - // parameter values (u, v, w) kept constant and create multiple THREE.Mesh - // objects one for each surface -- function getSurfacePointFront(u, v, target) { -+ function getSurfacePointFront(u: number, v: number, target: THREE.Vector3) { - return nurbsVolume.getPoint(u, v, 0, target); - } - -- function getSurfacePointMiddle(u, v, target) { -+ function getSurfacePointMiddle(u: number, v: number, target: THREE.Vector3) { - return nurbsVolume.getPoint(u, v, 0.5, target); - } - -- function getSurfacePointBack(u, v, target) { -+ function getSurfacePointBack(u: number, v: number, target: THREE.Vector3) { - return nurbsVolume.getPoint(u, v, 1, target); - } - -- function getSurfacePointTop(u, w, target) { -+ function getSurfacePointTop(u: number, w: number, target: THREE.Vector3) { - return nurbsVolume.getPoint(u, 1, w, target); - } - -- function getSurfacePointSide(v, w, target) { -+ function getSurfacePointSide(v: number, w: number, target: THREE.Vector3) { - return nurbsVolume.getPoint(0, v, w, target); - } - -@@ -260,7 +260,7 @@ function onWindowResize() { - - // - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; -@@ -270,7 +270,7 @@ function onPointerDown(event) { - document.addEventListener('pointerup', onPointerUp); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; -@@ -278,7 +278,7 @@ function onPointerMove(event) { - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; - } - --function onPointerUp() { -+function onPointerUp(event: PointerEvent) { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); -diff --git a/examples-testing/examples/webgl_geometry_shapes.ts b/examples-testing/examples/webgl_geometry_shapes.ts -index f1d00f01..2042c353 100644 ---- a/examples-testing/examples/webgl_geometry_shapes.ts -+++ b/examples-testing/examples/webgl_geometry_shapes.ts -@@ -2,11 +2,11 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let group; -+let group: THREE.Group; - - let targetRotation = 0; - let targetRotationOnPointerDown = 0; -@@ -45,11 +45,22 @@ function init() { - texture.wrapS = texture.wrapT = THREE.RepeatWrapping; - texture.repeat.set(0.008, 0.008); - -- function addShape(shape, extrudeSettings, color, x, y, z, rx, ry, rz, s) { -+ function addShape( -+ shape: THREE.Shape, -+ extrudeSettings: THREE.ExtrudeGeometryOptions, -+ color: number, -+ x: number, -+ y: number, -+ z: number, -+ rx: number, -+ ry: number, -+ rz: number, -+ s: number, -+ ) { - // flat shape with texture - // note: default UVs generated by THREE.ShapeGeometry are simply the x- and y-coordinates of the vertices - -- let geometry = new THREE.ShapeGeometry(shape); -+ let geometry: THREE.BufferGeometry = new THREE.ShapeGeometry(shape); - - let mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, map: texture })); - mesh.position.set(x, y, z - 175); -@@ -80,7 +91,17 @@ function init() { - addLineShape(shape, color, x, y, z, rx, ry, rz, s); - } - -- function addLineShape(shape, color, x, y, z, rx, ry, rz, s) { -+ function addLineShape( -+ shape: THREE.Path, -+ color: number, -+ x: number, -+ y: number, -+ z: number, -+ rx: number, -+ ry: number, -+ rz: number, -+ s: number, -+ ) { - // lines - - shape.autoClose = true; -@@ -325,7 +346,7 @@ function onWindowResize() { - - // - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; -@@ -335,7 +356,7 @@ function onPointerDown(event) { - document.addEventListener('pointerup', onPointerUp); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; -@@ -343,7 +364,7 @@ function onPointerMove(event) { - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; - } - --function onPointerUp() { -+function onPointerUp(event: PointerEvent) { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); -diff --git a/examples-testing/examples/webgl_geometry_teapot.ts b/examples-testing/examples/webgl_geometry_teapot.ts -index 4c884a55..b94b16db 100644 ---- a/examples-testing/examples/webgl_geometry_teapot.ts -+++ b/examples-testing/examples/webgl_geometry_teapot.ts -@@ -5,22 +5,30 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - let cameraControls; --let effectController; -+let effectController: { -+ newTess: number; -+ bottom: boolean; -+ lid: boolean; -+ body: boolean; -+ fitLid: boolean; -+ nonblinn: boolean; -+ newShading: string; -+}; - const teapotSize = 300; --let ambientLight, light; -+let ambientLight: THREE.AmbientLight, light: THREE.DirectionalLight; - - let tess = -1; // force initialization --let bBottom; --let bLid; --let bBody; --let bFitLid; --let bNonBlinn; --let shading; -- --let teapot, textureCube; --const materials = {}; -+let bBottom: boolean; -+let bLid: boolean; -+let bBody: boolean; -+let bFitLid: boolean; -+let bNonBlinn: boolean; -+let shading: string; -+ -+let teapot: THREE.Mesh, textureCube: THREE.CubeTexture; -+const materials: Record = {}; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_geometry_terrain.ts b/examples-testing/examples/webgl_geometry_terrain.ts -index 8b6ed84e..22ec3f6a 100644 ---- a/examples-testing/examples/webgl_geometry_terrain.ts -+++ b/examples-testing/examples/webgl_geometry_terrain.ts -@@ -5,9 +5,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; - import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - --let container, stats; --let camera, controls, scene, renderer; --let mesh, texture; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, controls: FirstPersonControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let mesh: THREE.Mesh, texture: THREE.CanvasTexture; - - const worldWidth = 256, - worldDepth = 256; -@@ -16,7 +16,7 @@ const clock = new THREE.Clock(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); - -@@ -73,7 +73,7 @@ function onWindowResize() { - controls.handleResize(); - } - --function generateHeight(width, height) { -+function generateHeight(width: number, height: number) { - let seed = Math.PI / 4; - window.Math.random = function () { - const x = Math.sin(seed++) * 10000; -@@ -100,7 +100,7 @@ function generateHeight(width, height) { - return data; - } - --function generateTexture(data, width, height) { -+function generateTexture(data: Uint8Array, width: number, height: number) { - let context, image, imageData, shade; - - const vector3 = new THREE.Vector3(0, 0, 0); -@@ -112,7 +112,7 @@ function generateTexture(data, width, height) { - canvas.width = width; - canvas.height = height; - -- context = canvas.getContext('2d'); -+ context = canvas.getContext('2d')!; - context.fillStyle = '#000'; - context.fillRect(0, 0, width, height); - -@@ -140,7 +140,7 @@ function generateTexture(data, width, height) { - canvasScaled.width = width * 4; - canvasScaled.height = height * 4; - -- context = canvasScaled.getContext('2d'); -+ context = canvasScaled.getContext('2d')!; - context.scale(4, 4); - context.drawImage(canvas, 0, 0); - -diff --git a/examples-testing/examples/webgl_geometry_terrain_raycast.ts b/examples-testing/examples/webgl_geometry_terrain_raycast.ts -index f1383c13..6e9cd025 100644 ---- a/examples-testing/examples/webgl_geometry_terrain_raycast.ts -+++ b/examples-testing/examples/webgl_geometry_terrain_raycast.ts -@@ -5,18 +5,18 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, controls, scene, renderer; -+let camera: THREE.PerspectiveCamera, controls: OrbitControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let mesh, texture; -+let mesh: THREE.Mesh, texture: THREE.CanvasTexture; - - const worldWidth = 256, - worldDepth = 256, - worldHalfWidth = worldWidth / 2, - worldHalfDepth = worldDepth / 2; - --let helper; -+let helper: THREE.Mesh; - - const raycaster = new THREE.Raycaster(); - const pointer = new THREE.Vector2(); -@@ -24,7 +24,7 @@ const pointer = new THREE.Vector2(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - container.innerHTML = ''; - - renderer = new THREE.WebGLRenderer({ antialias: true }); -@@ -94,7 +94,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function generateHeight(width, height) { -+function generateHeight(width: number, height: number) { - const size = width * height, - data = new Uint8Array(size), - perlin = new ImprovedNoise(), -@@ -115,7 +115,7 @@ function generateHeight(width, height) { - return data; - } - --function generateTexture(data, width, height) { -+function generateTexture(data: Uint8Array, width: number, height: number) { - // bake lighting into texture - - let context, image, imageData, shade; -@@ -129,7 +129,7 @@ function generateTexture(data, width, height) { - canvas.width = width; - canvas.height = height; - -- context = canvas.getContext('2d'); -+ context = canvas.getContext('2d')!; - context.fillStyle = '#000'; - context.fillRect(0, 0, width, height); - -@@ -157,7 +157,7 @@ function generateTexture(data, width, height) { - canvasScaled.width = width * 4; - canvasScaled.height = height * 4; - -- context = canvasScaled.getContext('2d'); -+ context = canvasScaled.getContext('2d')!; - context.scale(4, 4); - context.drawImage(canvas, 0, 0); - -@@ -188,7 +188,7 @@ function render() { - renderer.render(scene, camera); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1; - pointer.y = -(event.clientY / renderer.domElement.clientHeight) * 2 + 1; - raycaster.setFromCamera(pointer, camera); -@@ -199,7 +199,7 @@ function onPointerMove(event) { - // Toggle rotation bool for meshes that we clicked - if (intersects.length > 0) { - helper.position.set(0, 0, 0); -- helper.lookAt(intersects[0].face.normal); -+ helper.lookAt(intersects[0].face!.normal); - - helper.position.copy(intersects[0].point); - } -diff --git a/examples-testing/examples/webgl_geometry_text.ts b/examples-testing/examples/webgl_geometry_text.ts -index 831ebcd6..e5947329 100644 ---- a/examples-testing/examples/webgl_geometry_text.ts -+++ b/examples-testing/examples/webgl_geometry_text.ts -@@ -1,23 +1,23 @@ - import * as THREE from 'three'; - --import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -+import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - THREE.Cache.enabled = true; - --let container; -+let container: HTMLDivElement; - --let camera, cameraTarget, scene, renderer; -+let camera: THREE.PerspectiveCamera, cameraTarget: THREE.Vector3, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let group, textMesh1, textMesh2, textGeo, materials; -+let group: THREE.Group, textMesh1: THREE.Mesh, textMesh2: THREE.Mesh, textGeo, materials: THREE.MeshPhongMaterial[]; - - let firstLetter = true; - - let text = 'three.js', - bevelEnabled = true, -- font = undefined, -+ font: Font | undefined = undefined, - fontName = 'optimer', // helvetiker, optimer, gentilis, droid sans, droid serif - fontWeight = 'bold'; // normal bold - -@@ -43,11 +43,11 @@ const weightMap = { - bold: 1, - }; - --const reverseFontMap = []; --const reverseWeightMap = []; -+const reverseFontMap: string[] = []; -+const reverseWeightMap: string[] = []; - --for (const i in fontMap) reverseFontMap[fontMap[i]] = i; --for (const i in weightMap) reverseWeightMap[weightMap[i]] = i; -+for (const i in fontMap) reverseFontMap[fontMap[i as keyof typeof fontMap]] = i; -+for (const i in weightMap) reverseWeightMap[weightMap[i as keyof typeof weightMap]] = i; - - let targetRotation = 0; - let targetRotationOnPointerDown = 0; -@@ -180,7 +180,7 @@ function onWindowResize() { - - // - --function onDocumentKeyDown(event) { -+function onDocumentKeyDown(event: KeyboardEvent) { - if (firstLetter) { - firstLetter = false; - text = ''; -@@ -200,7 +200,7 @@ function onDocumentKeyDown(event) { - } - } - --function onDocumentKeyPress(event) { -+function onDocumentKeyPress(event: KeyboardEvent) { - const keyCode = event.which; - - // backspace -@@ -226,7 +226,7 @@ function loadFont() { - - function createText() { - textGeo = new TextGeometry(text, { -- font: font, -+ font: font!, - - size: size, - depth: depth, -@@ -239,7 +239,7 @@ function createText() { - - textGeo.computeBoundingBox(); - -- const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); -+ const centerOffset = -0.5 * (textGeo.boundingBox!.max.x - textGeo.boundingBox!.min.x); - - textMesh1 = new THREE.Mesh(textGeo, materials); - -@@ -275,7 +275,7 @@ function refreshText() { - createText(); - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; -@@ -285,7 +285,7 @@ function onPointerDown(event) { - document.addEventListener('pointerup', onPointerUp); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; -@@ -293,7 +293,7 @@ function onPointerMove(event) { - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; - } - --function onPointerUp() { -+function onPointerUp(event: PointerEvent) { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); -diff --git a/examples-testing/examples/webgl_geometry_text_shapes.ts b/examples-testing/examples/webgl_geometry_text_shapes.ts -index adfb6008..141b618f 100644 ---- a/examples-testing/examples/webgl_geometry_text_shapes.ts -+++ b/examples-testing/examples/webgl_geometry_text_shapes.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { FontLoader } from 'three/addons/loaders/FontLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -32,13 +32,13 @@ function init() { - - const message = ' Three.js\nSimple text.'; - -- const shapes = font.generateShapes(message, 100); -+ const shapes: THREE.Path[] = font.generateShapes(message, 100); - -- const geometry = new THREE.ShapeGeometry(shapes); -+ const geometry = new THREE.ShapeGeometry(shapes as THREE.Shape[]); - - geometry.computeBoundingBox(); - -- const xMid = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x); -+ const xMid = -0.5 * (geometry.boundingBox!.max.x - geometry.boundingBox!.min.x); - - geometry.translate(xMid, 0, 0); - -@@ -50,10 +50,10 @@ function init() { - - // make line shape ( N.B. edge view remains visible ) - -- const holeShapes = []; -+ const holeShapes: THREE.Path[] = []; - - for (let i = 0; i < shapes.length; i++) { -- const shape = shapes[i]; -+ const shape = shapes[i] as THREE.Shape; - - if (shape.holes && shape.holes.length > 0) { - for (let j = 0; j < shape.holes.length; j++) { -diff --git a/examples-testing/examples/webgl_geometry_text_stroke.ts b/examples-testing/examples/webgl_geometry_text_stroke.ts -index 9a198325..e47d7b66 100644 ---- a/examples-testing/examples/webgl_geometry_text_stroke.ts -+++ b/examples-testing/examples/webgl_geometry_text_stroke.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { SVGLoader } from 'three/addons/loaders/SVGLoader.js'; - import { FontLoader } from 'three/addons/loaders/FontLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -33,13 +33,13 @@ function init() { - - const message = ' Three.js\nStroke text.'; - -- const shapes = font.generateShapes(message, 100); -+ const shapes: THREE.Path[] = font.generateShapes(message, 100); - -- const geometry = new THREE.ShapeGeometry(shapes); -+ const geometry = new THREE.ShapeGeometry(shapes as THREE.Shape[]); - - geometry.computeBoundingBox(); - -- const xMid = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x); -+ const xMid = -0.5 * (geometry.boundingBox!.max.x - geometry.boundingBox!.min.x); - - geometry.translate(xMid, 0, 0); - -@@ -51,10 +51,10 @@ function init() { - - // make line shape ( N.B. edge view remains visible ) - -- const holeShapes = []; -+ const holeShapes: THREE.Path[] = []; - - for (let i = 0; i < shapes.length; i++) { -- const shape = shapes[i]; -+ const shape = shapes[i] as THREE.Shape; - - if (shape.holes && shape.holes.length > 0) { - for (let j = 0; j < shape.holes.length; j++) { -diff --git a/examples-testing/examples/webgl_gpgpu_birds.ts b/examples-testing/examples/webgl_gpgpu_birds.ts -index 20a5e0d9..5bb4ed25 100644 ---- a/examples-testing/examples/webgl_gpgpu_birds.ts -+++ b/examples-testing/examples/webgl_gpgpu_birds.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; -+import { GPUComputationRenderer, Variable } from 'three/addons/misc/GPUComputationRenderer.js'; - - /* TEXTURE WIDTH FOR SIMULATION */ - const WIDTH = 32; -@@ -33,9 +33,9 @@ class BirdGeometry extends THREE.BufferGeometry { - - let v = 0; - -- function verts_push() { -- for (let i = 0; i < arguments.length; i++) { -- vertices.array[v++] = arguments[i]; -+ function verts_push(...args: number[]) { -+ for (let i = 0; i < args.length; i++) { -+ vertices.array[v++] = args[i]; - } - } - -@@ -77,8 +77,8 @@ class BirdGeometry extends THREE.BufferGeometry { - - // - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - let mouseX = 0, - mouseY = 0; - -@@ -90,12 +90,12 @@ const BOUNDS = 800, - - let last = performance.now(); - --let gpuCompute; --let velocityVariable; --let positionVariable; --let positionUniforms; --let velocityUniforms; --let birdUniforms; -+let gpuCompute: GPUComputationRenderer; -+let velocityVariable: Variable; -+let positionVariable: Variable; -+let positionUniforms: Record; -+let velocityUniforms: Record; -+let birdUniforms: Record; - - init(); - -@@ -164,12 +164,12 @@ function initComputeRenderer() { - - velocityVariable = gpuCompute.addVariable( - 'textureVelocity', -- document.getElementById('fragmentShaderVelocity').textContent, -+ document.getElementById('fragmentShaderVelocity')!.textContent!, - dtVelocity, - ); - positionVariable = gpuCompute.addVariable( - 'texturePosition', -- document.getElementById('fragmentShaderPosition').textContent, -+ document.getElementById('fragmentShaderPosition')!.textContent!, - dtPosition, - ); - -@@ -218,8 +218,8 @@ function initBirds() { - // THREE.ShaderMaterial - const material = new THREE.ShaderMaterial({ - uniforms: birdUniforms, -- vertexShader: document.getElementById('birdVS').textContent, -- fragmentShader: document.getElementById('birdFS').textContent, -+ vertexShader: document.getElementById('birdVS')!.textContent!, -+ fragmentShader: document.getElementById('birdFS')!.textContent!, - side: THREE.DoubleSide, - }); - -@@ -231,7 +231,7 @@ function initBirds() { - scene.add(birdMesh); - } - --function fillPositionTexture(texture) { -+function fillPositionTexture(texture: THREE.DataTexture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { -@@ -246,7 +246,7 @@ function fillPositionTexture(texture) { - } - } - --function fillVelocityTexture(texture) { -+function fillVelocityTexture(texture: THREE.DataTexture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { -@@ -271,7 +271,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -diff --git a/examples-testing/examples/webgl_gpgpu_birds_gltf.ts b/examples-testing/examples/webgl_gpgpu_birds_gltf.ts -index 3176b95a..df84fb25 100644 ---- a/examples-testing/examples/webgl_gpgpu_birds_gltf.ts -+++ b/examples-testing/examples/webgl_gpgpu_birds_gltf.ts -@@ -2,7 +2,7 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; --import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; -+import { GPUComputationRenderer, Variable } from 'three/addons/misc/GPUComputationRenderer.js'; - - /* TEXTURE WIDTH FOR SIMULATION */ - const WIDTH = 64; -@@ -10,16 +10,20 @@ const BIRDS = WIDTH * WIDTH; - - /* BAKE ANIMATION INTO TEXTURE and CREATE GEOMETRY FROM BASE MODEL */ - const BirdGeometry = new THREE.BufferGeometry(); --let textureAnimation, durationAnimation, birdMesh, materialShader, indicesPerBird; -+let textureAnimation: THREE.DataTexture, -+ durationAnimation: number, -+ birdMesh: THREE.Mesh, -+ materialShader: THREE.WebGLProgramParametersWithUniforms, -+ indicesPerBird: number; - --function nextPowerOf2(n) { -+function nextPowerOf2(n: number) { - return Math.pow(2, Math.ceil(Math.log(n) / Math.log(2))); - } - --Math.lerp = function (value1, value2, amount) { -+function lerp(value1: number, value2: number, amount: number) { - amount = Math.max(Math.min(amount, 1), 0); - return value1 + (value2 - value1) * amount; --}; -+} - - const gltfs = ['models/gltf/Parrot.glb', 'models/gltf/Flamingo.glb']; - const colors = [0xccffff, 0xffdeff]; -@@ -28,11 +32,11 @@ const selectModel = Math.floor(Math.random() * gltfs.length); - new GLTFLoader().load(gltfs[selectModel], function (gltf) { - const animations = gltf.animations; - durationAnimation = Math.round(animations[0].duration * 60); -- const birdGeo = gltf.scene.children[0].geometry; -+ const birdGeo = (gltf.scene.children[0] as THREE.Mesh).geometry; - const morphAttributes = birdGeo.morphAttributes.position; - const tHeight = nextPowerOf2(durationAnimation); - const tWidth = nextPowerOf2(birdGeo.getAttribute('position').count); -- indicesPerBird = birdGeo.index.count; -+ indicesPerBird = birdGeo.index!.count; - const tData = new Float32Array(4 * tWidth * tHeight); - - for (let i = 0; i < tWidth; i++) { -@@ -50,17 +54,17 @@ new GLTFLoader().load(gltfs[selectModel], function (gltf) { - d0 = morphAttributes[curMorph].array[i * 3]; - d1 = morphAttributes[nextMorph].array[i * 3]; - -- if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4] = Math.lerp(d0, d1, lerpAmount); -+ if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4] = lerp(d0, d1, lerpAmount); - - d0 = morphAttributes[curMorph].array[i * 3 + 1]; - d1 = morphAttributes[nextMorph].array[i * 3 + 1]; - -- if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4 + 1] = Math.lerp(d0, d1, lerpAmount); -+ if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4 + 1] = lerp(d0, d1, lerpAmount); - - d0 = morphAttributes[curMorph].array[i * 3 + 2]; - d1 = morphAttributes[nextMorph].array[i * 3 + 2]; - -- if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4 + 2] = Math.lerp(d0, d1, lerpAmount); -+ if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4 + 2] = lerp(d0, d1, lerpAmount); - - tData[offset + i * 4 + 3] = 1; - } -@@ -94,9 +98,9 @@ new GLTFLoader().load(gltfs[selectModel], function (gltf) { - seeds.push(bird, r, Math.random(), Math.random()); - } - -- for (let i = 0; i < birdGeo.index.array.length * BIRDS; i++) { -- const offset = Math.floor(i / birdGeo.index.array.length) * birdGeo.getAttribute('position').count; -- indices.push(birdGeo.index.array[i % birdGeo.index.array.length] + offset); -+ for (let i = 0; i < birdGeo.index!.array.length * BIRDS; i++) { -+ const offset = Math.floor(i / birdGeo.index!.array.length) * birdGeo.getAttribute('position').count; -+ indices.push(birdGeo.index!.array[i % birdGeo.index!.array.length] + offset); - } - - BirdGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3)); -@@ -110,8 +114,8 @@ new GLTFLoader().load(gltfs[selectModel], function (gltf) { - init(); - }); - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - let mouseX = 0, - mouseY = 0; - -@@ -123,11 +127,20 @@ const BOUNDS = 800, - - let last = performance.now(); - --let gpuCompute; --let velocityVariable; --let positionVariable; --let positionUniforms; --let velocityUniforms; -+let gpuCompute: GPUComputationRenderer; -+let velocityVariable: Variable; -+let positionVariable: Variable; -+let positionUniforms: Record; -+let velocityUniforms: Record; -+ -+interface EffectController { -+ separation: number; -+ alignment: number; -+ cohesion: number; -+ freedom: number; -+ size: number; -+ count: number; -+} - - function init() { - container = document.createElement('div'); -@@ -212,12 +225,12 @@ function initComputeRenderer() { - - velocityVariable = gpuCompute.addVariable( - 'textureVelocity', -- document.getElementById('fragmentShaderVelocity').textContent, -+ document.getElementById('fragmentShaderVelocity')!.textContent!, - dtVelocity, - ); - positionVariable = gpuCompute.addVariable( - 'texturePosition', -- document.getElementById('fragmentShaderPosition').textContent, -+ document.getElementById('fragmentShaderPosition')!.textContent!, - dtPosition, - ); - -@@ -251,7 +264,7 @@ function initComputeRenderer() { - } - } - --function initBirds(effectController) { -+function initBirds(effectController: EffectController) { - const geometry = BirdGeometry; - - const m = new THREE.MeshStandardMaterial({ -@@ -331,7 +344,7 @@ function initBirds(effectController) { - scene.add(birdMesh); - } - --function fillPositionTexture(texture) { -+function fillPositionTexture(texture: THREE.DataTexture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { -@@ -346,7 +359,7 @@ function fillPositionTexture(texture) { - } - } - --function fillVelocityTexture(texture) { -+function fillVelocityTexture(texture: THREE.DataTexture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { -@@ -371,7 +384,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -diff --git a/examples-testing/examples/webgl_gpgpu_protoplanet.ts b/examples-testing/examples/webgl_gpgpu_protoplanet.ts -index 30444ddb..158350b0 100644 ---- a/examples-testing/examples/webgl_gpgpu_protoplanet.ts -+++ b/examples-testing/examples/webgl_gpgpu_protoplanet.ts -@@ -4,22 +4,32 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; -+import { GPUComputationRenderer, Variable } from 'three/addons/misc/GPUComputationRenderer.js'; - - // Texture width for simulation (each texel is a debris particle) - const WIDTH = 64; - --let container, stats; --let camera, scene, renderer, geometry; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, geometry: THREE.BufferGeometry; - - const PARTICLES = WIDTH * WIDTH; - --let gpuCompute; --let velocityVariable; --let positionVariable; --let velocityUniforms; --let particleUniforms; --let effectController; -+let gpuCompute: GPUComputationRenderer; -+let velocityVariable: Variable; -+let positionVariable: Variable; -+let velocityUniforms: Record; -+let particleUniforms: Record; -+let effectController: { -+ gravityConstant: number; -+ density: number; -+ radius: number; -+ height: number; -+ exponent: number; -+ maxMass: number; -+ velocity: number; -+ velocityExponent: number; -+ randVelocity: number; -+}; - - init(); - -@@ -82,12 +92,12 @@ function initComputeRenderer() { - - velocityVariable = gpuCompute.addVariable( - 'textureVelocity', -- document.getElementById('computeShaderVelocity').textContent, -+ document.getElementById('computeShaderVelocity')!.textContent!, - dtVelocity, - ); - positionVariable = gpuCompute.addVariable( - 'texturePosition', -- document.getElementById('computeShaderPosition').textContent, -+ document.getElementById('computeShaderPosition')!.textContent!, - dtPosition, - ); - -@@ -153,8 +163,8 @@ function initProtoplanets() { - // THREE.ShaderMaterial - const material = new THREE.ShaderMaterial({ - uniforms: particleUniforms, -- vertexShader: document.getElementById('particleVertexShader').textContent, -- fragmentShader: document.getElementById('particleFragmentShader').textContent, -+ vertexShader: document.getElementById('particleVertexShader')!.textContent!, -+ fragmentShader: document.getElementById('particleFragmentShader')!.textContent!, - }); - - const particles = new THREE.Points(geometry, material); -@@ -164,7 +174,7 @@ function initProtoplanets() { - scene.add(particles); - } - --function fillTextures(texturePosition, textureVelocity) { -+function fillTextures(texturePosition: THREE.DataTexture, textureVelocity: THREE.DataTexture) { - const posArray = texturePosition.image.data; - const velArray = textureVelocity.image.data; - -@@ -261,7 +271,7 @@ function initGUI() { - folder2.open(); - } - --function getCameraConstant(camera) { -+function getCameraConstant(camera: THREE.PerspectiveCamera) { - return window.innerHeight / (Math.tan(THREE.MathUtils.DEG2RAD * 0.5 * camera.fov) / camera.zoom); - } - -diff --git a/examples-testing/examples/webgl_gpgpu_water.ts b/examples-testing/examples/webgl_gpgpu_water.ts -index 00c32f22..57e7c212 100644 ---- a/examples-testing/examples/webgl_gpgpu_water.ts -+++ b/examples-testing/examples/webgl_gpgpu_water.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; -+import { GPUComputationRenderer, Variable } from 'three/addons/misc/GPUComputationRenderer.js'; - import { SimplexNoise } from 'three/addons/math/SimplexNoise.js'; - - // Texture width for simulation -@@ -13,25 +13,25 @@ const WIDTH = 128; - const BOUNDS = 512; - const BOUNDS_HALF = BOUNDS * 0.5; - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - let mouseMoved = false; - const mouseCoords = new THREE.Vector2(); - const raycaster = new THREE.Raycaster(); - --let waterMesh; --let meshRay; --let gpuCompute; --let heightmapVariable; --let waterUniforms; --let smoothShader; --let readWaterLevelShader; --let readWaterLevelRenderTarget; --let readWaterLevelImage; -+let waterMesh: THREE.Mesh; -+let meshRay: THREE.Mesh; -+let gpuCompute: GPUComputationRenderer; -+let heightmapVariable: Variable; -+let waterUniforms: Record; -+let smoothShader: THREE.ShaderMaterial; -+let readWaterLevelShader: THREE.ShaderMaterial; -+let readWaterLevelRenderTarget: THREE.WebGLRenderTarget; -+let readWaterLevelImage: Uint8Array; - const waterNormal = new THREE.Vector3(); - - const NUM_SPHERES = 5; --const spheres = []; -+const spheres: THREE.Mesh[] = []; - let spheresEnabled = true; - - const simplex = new SimplexNoise(); -@@ -127,7 +127,7 @@ function initWater() { - heightmap: { value: null }, - }, - ]), -- vertexShader: document.getElementById('waterVertexShader').textContent, -+ vertexShader: document.getElementById('waterVertexShader')!.textContent!, - fragmentShader: THREE.ShaderChunk['meshphong_frag'], - }); - -@@ -171,7 +171,7 @@ function initWater() { - - heightmapVariable = gpuCompute.addVariable( - 'heightmap', -- document.getElementById('heightmapFragmentShader').textContent, -+ document.getElementById('heightmapFragmentShader')!.textContent!, - heightmap0, - ); - -@@ -189,13 +189,13 @@ function initWater() { - } - - // Create compute shader to smooth the water surface and velocity -- smoothShader = gpuCompute.createShaderMaterial(document.getElementById('smoothFragmentShader').textContent, { -+ smoothShader = gpuCompute.createShaderMaterial(document.getElementById('smoothFragmentShader')!.textContent!, { - smoothTexture: { value: null }, - }); - - // Create compute shader to read water level - readWaterLevelShader = gpuCompute.createShaderMaterial( -- document.getElementById('readWaterLevelFragmentShader').textContent, -+ document.getElementById('readWaterLevelFragmentShader')!.textContent!, - { - point1: { value: new THREE.Vector2() }, - levelTexture: { value: null }, -@@ -218,10 +218,10 @@ function initWater() { - }); - } - --function fillTexture(texture) { -+function fillTexture(texture: THREE.DataTexture) { - const waterMaxHeight = 10; - -- function noise(x, y) { -+ function noise(x: number, y: number) { - let multR = waterMaxHeight; - let mult = 0.025; - let r = 0; -@@ -346,12 +346,12 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function setMouseCoords(x, y) { -+function setMouseCoords(x: number, y: number) { - mouseCoords.set((x / renderer.domElement.clientWidth) * 2 - 1, -(y / renderer.domElement.clientHeight) * 2 + 1); - mouseMoved = true; - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - setMouseCoords(event.clientX, event.clientY); -diff --git a/examples-testing/examples/webgl_helpers.ts b/examples-testing/examples/webgl_helpers.ts -index a8c3b977..09ad778d 100644 ---- a/examples-testing/examples/webgl_helpers.ts -+++ b/examples-testing/examples/webgl_helpers.ts -@@ -5,10 +5,10 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { VertexNormalsHelper } from 'three/addons/helpers/VertexNormalsHelper.js'; - import { VertexTangentsHelper } from 'three/addons/helpers/VertexTangentsHelper.js'; - --let scene, renderer; --let camera, light; --let vnh; --let vth; -+let scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let camera: THREE.PerspectiveCamera, light: THREE.PointLight; -+let vnh: VertexNormalsHelper; -+let vth: VertexTangentsHelper; - - init(); - -@@ -44,7 +44,7 @@ function init() { - - const loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { -- const mesh = gltf.scene.children[0]; -+ const mesh = gltf.scene.children[0] as THREE.Mesh; - - mesh.geometry.computeTangents(); // generates bad data due to degenerate UVs - -@@ -66,7 +66,7 @@ function init() { - scene.add(new THREE.BoxHelper(mesh)); - - const wireframe = new THREE.WireframeGeometry(mesh.geometry); -- let line = new THREE.LineSegments(wireframe); -+ let line: THREE.LineSegments = new THREE.LineSegments(wireframe); - line.material.depthTest = false; - line.material.opacity = 0.25; - line.material.transparent = true; -diff --git a/examples-testing/examples/webgl_instancing_dynamic.ts b/examples-testing/examples/webgl_instancing_dynamic.ts -index 88562fc5..a8b1e2d0 100644 ---- a/examples-testing/examples/webgl_instancing_dynamic.ts -+++ b/examples-testing/examples/webgl_instancing_dynamic.ts -@@ -3,9 +3,9 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - --let mesh; -+let mesh: THREE.InstancedMesh; - const amount = parseInt(window.location.search.slice(1)) || 10; - const count = Math.pow(amount, 3); - const dummy = new THREE.Object3D(); -diff --git a/examples-testing/examples/webgl_instancing_morph.ts b/examples-testing/examples/webgl_instancing_morph.ts -index 8686a75b..fb76abe3 100644 ---- a/examples-testing/examples/webgl_instancing_morph.ts -+++ b/examples-testing/examples/webgl_instancing_morph.ts -@@ -4,7 +4,13 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats, mesh, mixer, dummy; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ mesh: THREE.InstancedMesh, -+ mixer: THREE.AnimationMixer, -+ dummy: THREE.Mesh; - - const offset = 5000; - -@@ -63,7 +69,7 @@ function init() { - const loader = new GLTFLoader(); - - loader.load('models/gltf/Horse.glb', function (glb) { -- dummy = glb.scene.children[0]; -+ dummy = glb.scene.children[0] as THREE.Mesh; - - mesh = new THREE.InstancedMesh(dummy.geometry, dummy.material, 1024); - -@@ -140,7 +146,7 @@ function render() { - mesh.setMorphAt(i, dummy); - } - -- mesh.morphTexture.needsUpdate = true; -+ mesh.morphTexture!.needsUpdate = true; - } - - renderer.render(scene, camera); -diff --git a/examples-testing/examples/webgl_instancing_performance.ts b/examples-testing/examples/webgl_instancing_performance.ts -index bf1deaba..705d2cf3 100644 ---- a/examples-testing/examples/webgl_instancing_performance.ts -+++ b/examples-testing/examples/webgl_instancing_performance.ts -@@ -6,8 +6,12 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let container, stats, gui, guiStatsEl; --let camera, controls, scene, renderer, material; -+let container: HTMLElement, stats: Stats, gui: GUI, guiStatsEl: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, -+ controls: OrbitControls, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ material: THREE.MeshNormalMaterial; - - // gui - -@@ -30,15 +34,15 @@ initMesh(); - // - - function clean() { -- const meshes = []; -+ const meshes: THREE.Mesh[] = []; - - scene.traverse(function (object) { -- if (object.isMesh) meshes.push(object); -+ if ((object as THREE.Mesh).isMesh) meshes.push(object as THREE.Mesh); - }); - - for (let i = 0; i < meshes.length; i++) { - const mesh = meshes[i]; -- mesh.material.dispose(); -+ (mesh.material as THREE.Material).dispose(); - mesh.geometry.dispose(); - - scene.remove(mesh); -@@ -50,7 +54,7 @@ const randomizeMatrix = (function () { - const quaternion = new THREE.Quaternion(); - const scale = new THREE.Vector3(); - -- return function (matrix) { -+ return function (matrix: THREE.Matrix4) { - position.x = Math.random() * 40 - 20; - position.y = Math.random() * 40 - 20; - position.z = Math.random() * 40 - 20; -@@ -92,7 +96,7 @@ function initMesh() { - }); - } - --function makeInstanced(geometry) { -+function makeInstanced(geometry: THREE.BufferGeometry) { - const matrix = new THREE.Matrix4(); - const mesh = new THREE.InstancedMesh(geometry, material, api.count); - -@@ -113,7 +117,7 @@ function makeInstanced(geometry) { - ].join('
'); - } - --function makeMerged(geometry) { -+function makeMerged(geometry: THREE.BufferGeometry) { - const geometries = []; - const matrix = new THREE.Matrix4(); - -@@ -138,7 +142,7 @@ function makeMerged(geometry) { - ].join('
'); - } - --function makeNaive(geometry) { -+function makeNaive(geometry: THREE.BufferGeometry) { - const matrix = new THREE.Matrix4(); - - for (let i = 0; i < api.count; i++) { -@@ -175,7 +179,7 @@ function init() { - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - // scene -@@ -236,7 +240,7 @@ function animate() { - - // - --function getGeometryByteLength(geometry) { -+function getGeometryByteLength(geometry: THREE.BufferGeometry) { - let total = 0; - - if (geometry.index) total += geometry.index.array.byteLength; -@@ -249,7 +253,7 @@ function getGeometryByteLength(geometry) { - } - - // Source: https://stackoverflow.com/a/18650828/1314762 --function formatBytes(bytes, decimals) { -+function formatBytes(bytes: number, decimals: number) { - if (bytes === 0) return '0 bytes'; - - const k = 1024; -diff --git a/examples-testing/examples/webgl_instancing_raycast.ts b/examples-testing/examples/webgl_instancing_raycast.ts -index 371ea070..861bc9c5 100644 ---- a/examples-testing/examples/webgl_instancing_raycast.ts -+++ b/examples-testing/examples/webgl_instancing_raycast.ts -@@ -4,9 +4,13 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, controls, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ controls: OrbitControls, -+ stats: Stats; - --let mesh; -+let mesh: THREE.InstancedMesh; - const amount = parseInt(window.location.search.slice(1)) || 10; - const count = Math.pow(amount, 3); - -@@ -84,7 +88,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onMouseMove(event) { -+function onMouseMove(event: MouseEvent) { - event.preventDefault(); - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; -@@ -99,14 +103,14 @@ function animate() { - const intersection = raycaster.intersectObject(mesh); - - if (intersection.length > 0) { -- const instanceId = intersection[0].instanceId; -+ const instanceId = intersection[0].instanceId!; - - mesh.getColorAt(instanceId, color); - - if (color.equals(white)) { - mesh.setColorAt(instanceId, color.setHex(Math.random() * 0xffffff)); - -- mesh.instanceColor.needsUpdate = true; -+ mesh.instanceColor!.needsUpdate = true; - } - } - -diff --git a/examples-testing/examples/webgl_instancing_scatter.ts b/examples-testing/examples/webgl_instancing_scatter.ts -index fc3b9cc9..d0904e8e 100644 ---- a/examples-testing/examples/webgl_instancing_scatter.ts -+++ b/examples-testing/examples/webgl_instancing_scatter.ts -@@ -5,7 +5,7 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - const api = { - count: 2000, -@@ -15,11 +15,11 @@ const api = { - backgroundColor: 0xe39469, - }; - --let stemMesh, blossomMesh; --let stemGeometry, blossomGeometry; --let stemMaterial, blossomMaterial; -+let stemMesh: THREE.InstancedMesh, blossomMesh: THREE.InstancedMesh; -+let stemGeometry: THREE.BufferGeometry, blossomGeometry: THREE.BufferGeometry; -+let stemMaterial: THREE.Material | THREE.Material[], blossomMaterial: THREE.Material | THREE.Material[]; - --let sampler; -+let sampler: MeshSurfaceSampler; - const count = api.count; - const ages = new Float32Array(count); - const scales = new Float32Array(count); -@@ -35,21 +35,21 @@ const surfaceMaterial = new THREE.MeshLambertMaterial({ color: api.surfaceColor, - const surface = new THREE.Mesh(surfaceGeometry, surfaceMaterial); - - // Source: https://gist.github.com/gre/1650294 --const easeOutCubic = function (t) { -+const easeOutCubic = function (t: number) { - return --t * t * t + 1; - }; - - // Scaling curve causes particles to grow quickly, ease gradually into full scale, then - // disappear quickly. More of the particle's lifetime is spent around full scale. --const scaleCurve = function (t) { -+const scaleCurve = function (t: number) { - return Math.abs(easeOutCubic((t > 0.5 ? 1 - t : t) * 2)); - }; - - const loader = new GLTFLoader(); - - loader.load('./models/gltf/Flower/Flower.glb', function (gltf) { -- const _stemMesh = gltf.scene.getObjectByName('Stem'); -- const _blossomMesh = gltf.scene.getObjectByName('Blossom'); -+ const _stemMesh = gltf.scene.getObjectByName('Stem') as THREE.Mesh; -+ const _blossomMesh = gltf.scene.getObjectByName('Blossom') as THREE.Mesh; - - stemGeometry = _stemMesh.geometry.clone(); - blossomGeometry = _blossomMesh.geometry.clone(); -@@ -179,7 +179,7 @@ function resample() { - blossomMesh.instanceMatrix.needsUpdate = true; - } - --function resampleParticle(i) { -+function resampleParticle(i: number) { - sampler.sample(_position, _normal); - _normal.add(_position); - -@@ -192,7 +192,7 @@ function resampleParticle(i) { - blossomMesh.setMatrixAt(i, dummy.matrix); - } - --function updateParticle(i) { -+function updateParticle(i: number) { - // Update lifecycle. - - ages[i] += 0.005; -diff --git a/examples-testing/examples/webgl_interactive_buffergeometry.ts b/examples-testing/examples/webgl_interactive_buffergeometry.ts -index 1d6608b1..c6aca942 100644 ---- a/examples-testing/examples/webgl_interactive_buffergeometry.ts -+++ b/examples-testing/examples/webgl_interactive_buffergeometry.ts -@@ -2,18 +2,18 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let raycaster, pointer; -+let raycaster: THREE.Raycaster, pointer: THREE.Vector2; - --let mesh, line; -+let mesh: THREE.Mesh, line: THREE.Line; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -146,7 +146,7 @@ function init() { - - geometry.computeBoundingSphere(); - -- let material = new THREE.MeshPhongMaterial({ -+ let material: THREE.Material = new THREE.MeshPhongMaterial({ - color: 0xaaaaaa, - specular: 0xffffff, - shininess: 250, -@@ -197,7 +197,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -@@ -221,10 +221,10 @@ function render() { - - if (intersects.length > 0) { - const intersect = intersects[0]; -- const face = intersect.face; -+ const face = intersect.face!; - -- const linePosition = line.geometry.attributes.position; -- const meshPosition = mesh.geometry.attributes.position; -+ const linePosition = line.geometry.attributes.position as THREE.BufferAttribute; -+ const meshPosition = mesh.geometry.attributes.position as THREE.BufferAttribute; - - linePosition.copyAt(0, meshPosition, face.a); - linePosition.copyAt(1, meshPosition, face.b); -diff --git a/examples-testing/examples/webgl_interactive_cubes.ts b/examples-testing/examples/webgl_interactive_cubes.ts -index adfcfddf..d26cee37 100644 ---- a/examples-testing/examples/webgl_interactive_cubes.ts -+++ b/examples-testing/examples/webgl_interactive_cubes.ts -@@ -2,10 +2,10 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let stats; --let camera, scene, raycaster, renderer; -+let stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, raycaster: THREE.Raycaster, renderer: THREE.WebGLRenderer; - --let INTERSECTED; -+let INTERSECTED: (THREE.Mesh & { currentHex?: number }) | null; - let theta = 0; - - const pointer = new THREE.Vector2(); -@@ -68,7 +68,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: MouseEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -@@ -98,14 +98,14 @@ function render() { - - if (intersects.length > 0) { - if (INTERSECTED != intersects[0].object) { -- if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); -+ if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex!); - -- INTERSECTED = intersects[0].object; -+ INTERSECTED = intersects[0].object as THREE.Mesh; - INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); - INTERSECTED.material.emissive.setHex(0xff0000); - } - } else { -- if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); -+ if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex!); - - INTERSECTED = null; - } -diff --git a/examples-testing/examples/webgl_interactive_cubes_gpu.ts b/examples-testing/examples/webgl_interactive_cubes_gpu.ts -index 2644469c..d48fa232 100644 ---- a/examples-testing/examples/webgl_interactive_cubes_gpu.ts -+++ b/examples-testing/examples/webgl_interactive_cubes_gpu.ts -@@ -5,12 +5,12 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let container, stats; --let camera, controls, scene, renderer; --let pickingTexture, pickingScene; --let highlightBox; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, controls: TrackballControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let pickingTexture: THREE.WebGLRenderTarget, pickingScene: THREE.Scene; -+let highlightBox: THREE.Mesh; - --const pickingData = []; -+const pickingData: { position: THREE.Vector3; rotation: THREE.Euler; scale: THREE.Vector3 }[] = []; - - const pointer = new THREE.Vector2(); - const offset = new THREE.Vector3(10, 10, 10); -@@ -19,7 +19,7 @@ const clearColor = new THREE.Color(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 1000; -@@ -73,7 +73,7 @@ function init() { - `, - }); - -- function applyId(geometry, id) { -+ function applyId(geometry: THREE.BoxGeometry, id: number) { - const position = geometry.attributes.position; - const array = new Int16Array(position.count); - array.fill(id); -@@ -83,7 +83,7 @@ function init() { - geometry.setAttribute('id', bufferAttribute); - } - -- function applyVertexColors(geometry, color) { -+ function applyVertexColors(geometry: THREE.BoxGeometry, color: THREE.Color) { - const position = geometry.attributes.position; - const colors = []; - -@@ -166,7 +166,7 @@ function init() { - - // - --function onPointerMove(e) { -+function onPointerMove(e: PointerEvent) { - pointer.x = e.clientX; - pointer.y = e.clientY; - } -diff --git a/examples-testing/examples/webgl_interactive_cubes_ortho.ts b/examples-testing/examples/webgl_interactive_cubes_ortho.ts -index 520674b5..4b083ffe 100644 ---- a/examples-testing/examples/webgl_interactive_cubes_ortho.ts -+++ b/examples-testing/examples/webgl_interactive_cubes_ortho.ts -@@ -2,11 +2,11 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let stats; --let camera, scene, raycaster, renderer; -+let stats: Stats; -+let camera: THREE.OrthographicCamera, scene: THREE.Scene, raycaster: THREE.Raycaster, renderer: THREE.WebGLRenderer; - - let theta = 0; --let INTERSECTED; -+let INTERSECTED: (THREE.Mesh & { currentHex?: number }) | null; - - const pointer = new THREE.Vector2(); - const radius = 25; -@@ -83,7 +83,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -@@ -113,14 +113,14 @@ function render() { - - if (intersects.length > 0) { - if (INTERSECTED != intersects[0].object) { -- if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); -+ if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex!); - -- INTERSECTED = intersects[0].object; -+ INTERSECTED = intersects[0].object as THREE.Mesh; - INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); - INTERSECTED.material.emissive.setHex(0xff0000); - } - } else { -- if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); -+ if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex!); - - INTERSECTED = null; - } -diff --git a/examples-testing/examples/webgl_interactive_lines.ts b/examples-testing/examples/webgl_interactive_lines.ts -index b137c550..891e5541 100644 ---- a/examples-testing/examples/webgl_interactive_lines.ts -+++ b/examples-testing/examples/webgl_interactive_lines.ts -@@ -2,8 +2,13 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; --let camera, scene, raycaster, renderer, parentTransform, sphereInter; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ raycaster: THREE.Raycaster, -+ renderer: THREE.WebGLRenderer, -+ parentTransform: THREE.Object3D, -+ sphereInter: THREE.Mesh; - - const pointer = new THREE.Vector2(); - const radius = 100; -@@ -121,7 +126,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -diff --git a/examples-testing/examples/webgl_interactive_points.ts b/examples-testing/examples/webgl_interactive_points.ts -index 93113b86..e090fb6c 100644 ---- a/examples-testing/examples/webgl_interactive_points.ts -+++ b/examples-testing/examples/webgl_interactive_points.ts -@@ -4,19 +4,19 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let particles; -+let particles: THREE.Points; - - const PARTICLE_SIZE = 20; - --let raycaster, intersects; --let pointer, INTERSECTED; -+let raycaster: THREE.Raycaster, intersects: THREE.Intersection[]; -+let pointer: THREE.Vector2, INTERSECTED: number | null; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - scene = new THREE.Scene(); - -@@ -25,7 +25,7 @@ function init() { - - // - -- let boxGeometry = new THREE.BoxGeometry(200, 200, 200, 16, 16, 16); -+ let boxGeometry: THREE.BufferGeometry = new THREE.BoxGeometry(200, 200, 200, 16, 16, 16); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data - -@@ -38,8 +38,8 @@ function init() { - - const positionAttribute = boxGeometry.getAttribute('position'); - -- const colors = []; -- const sizes = []; -+ const colors: number[] = []; -+ const sizes: number[] = []; - - const color = new THREE.Color(); - -@@ -63,8 +63,8 @@ function init() { - pointTexture: { value: new THREE.TextureLoader().load('textures/sprites/disc.png') }, - alphaTest: { value: 0.9 }, - }, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - }); - - // -@@ -96,7 +96,7 @@ function init() { - document.addEventListener('pointermove', onPointerMove); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -@@ -126,9 +126,9 @@ function render() { - - if (intersects.length > 0) { - if (INTERSECTED != intersects[0].index) { -- attributes.size.array[INTERSECTED] = PARTICLE_SIZE; -+ attributes.size.array[INTERSECTED!] = PARTICLE_SIZE; - -- INTERSECTED = intersects[0].index; -+ INTERSECTED = intersects[0].index!; - - attributes.size.array[INTERSECTED] = PARTICLE_SIZE * 1.25; - attributes.size.needsUpdate = true; -diff --git a/examples-testing/examples/webgl_interactive_raycasting_points.ts b/examples-testing/examples/webgl_interactive_raycasting_points.ts -index 41c158a4..bb134818 100644 ---- a/examples-testing/examples/webgl_interactive_raycasting_points.ts -+++ b/examples-testing/examples/webgl_interactive_raycasting_points.ts -@@ -2,16 +2,16 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let renderer, scene, camera, stats; --let pointclouds; --let raycaster; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; -+let pointclouds: THREE.Points[]; -+let raycaster: THREE.Raycaster; - let intersection = null; - let spheresIndex = 0; --let clock; -+let clock: THREE.Clock; - let toggle = 0; - - const pointer = new THREE.Vector2(); --const spheres = []; -+const spheres: THREE.Mesh[] = []; - - const threshold = 0.1; - const pointSize = 0.05; -@@ -21,7 +21,7 @@ const rotateY = new THREE.Matrix4().makeRotationY(0.005); - - init(); - --function generatePointCloudGeometry(color, width, length) { -+function generatePointCloudGeometry(color: THREE.Color, width: number, length: number) { - const geometry = new THREE.BufferGeometry(); - const numPoints = width * length; - -@@ -58,14 +58,14 @@ function generatePointCloudGeometry(color, width, length) { - return geometry; - } - --function generatePointcloud(color, width, length) { -+function generatePointcloud(color: THREE.Color, width: number, length: number) { - const geometry = generatePointCloudGeometry(color, width, length); - const material = new THREE.PointsMaterial({ size: pointSize, vertexColors: true }); - - return new THREE.Points(geometry, material); - } - --function generateIndexedPointcloud(color, width, length) { -+function generateIndexedPointcloud(color: THREE.Color, width: number, length: number) { - const geometry = generatePointCloudGeometry(color, width, length); - const numPoints = width * length; - const indices = new Uint16Array(numPoints); -@@ -86,7 +86,7 @@ function generateIndexedPointcloud(color, width, length) { - return new THREE.Points(geometry, material); - } - --function generateIndexedWithOffsetPointcloud(color, width, length) { -+function generateIndexedWithOffsetPointcloud(color: THREE.Color, width: number, length: number) { - const geometry = generatePointCloudGeometry(color, width, length); - const numPoints = width * length; - const indices = new Uint16Array(numPoints); -@@ -109,7 +109,7 @@ function generateIndexedWithOffsetPointcloud(color, width, length) { - } - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - scene = new THREE.Scene(); - -@@ -174,7 +174,7 @@ function init() { - document.addEventListener('pointermove', onPointerMove); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -diff --git a/examples-testing/examples/webgl_interactive_voxelpainter.ts b/examples-testing/examples/webgl_interactive_voxelpainter.ts -index 48b16f3b..dae1d758 100644 ---- a/examples-testing/examples/webgl_interactive_voxelpainter.ts -+++ b/examples-testing/examples/webgl_interactive_voxelpainter.ts -@@ -1,15 +1,15 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; --let plane; --let pointer, -- raycaster, -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let plane: THREE.Mesh; -+let pointer: THREE.Vector2, -+ raycaster: THREE.Raycaster, - isShiftDown = false; - --let rollOverMesh, rollOverMaterial; --let cubeGeo, cubeMaterial; -+let rollOverMesh: THREE.Mesh, rollOverMaterial: THREE.MeshBasicMaterial; -+let cubeGeo: THREE.BoxGeometry, cubeMaterial: THREE.MeshLambertMaterial; - --const objects = []; -+const objects: THREE.Object3D[] = []; - - init(); - render(); -@@ -87,7 +87,7 @@ function onWindowResize() { - render(); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.set((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1); - - raycaster.setFromCamera(pointer, camera); -@@ -97,14 +97,14 @@ function onPointerMove(event) { - if (intersects.length > 0) { - const intersect = intersects[0]; - -- rollOverMesh.position.copy(intersect.point).add(intersect.face.normal); -+ rollOverMesh.position.copy(intersect.point).add(intersect.face!.normal); - rollOverMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25); - - render(); - } - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - pointer.set((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1); - - raycaster.setFromCamera(pointer, camera); -@@ -126,7 +126,7 @@ function onPointerDown(event) { - // create cube - } else { - const voxel = new THREE.Mesh(cubeGeo, cubeMaterial); -- voxel.position.copy(intersect.point).add(intersect.face.normal); -+ voxel.position.copy(intersect.point).add(intersect.face!.normal); - voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25); - scene.add(voxel); - -@@ -137,7 +137,7 @@ function onPointerDown(event) { - } - } - --function onDocumentKeyDown(event) { -+function onDocumentKeyDown(event: KeyboardEvent) { - switch (event.keyCode) { - case 16: - isShiftDown = true; -@@ -145,7 +145,7 @@ function onDocumentKeyDown(event) { - } - } - --function onDocumentKeyUp(event) { -+function onDocumentKeyUp(event: KeyboardEvent) { - switch (event.keyCode) { - case 16: - isShiftDown = false; -diff --git a/examples-testing/examples/webgl_layers.ts b/examples-testing/examples/webgl_layers.ts -index 8bdcda7f..f24cdc8b 100644 ---- a/examples-testing/examples/webgl_layers.ts -+++ b/examples-testing/examples/webgl_layers.ts -@@ -3,8 +3,8 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let theta = 0; - const radius = 5; -diff --git a/examples-testing/examples/webgl_lensflares.ts b/examples-testing/examples/webgl_lensflares.ts -index 230cebfa..56651e28 100644 ---- a/examples-testing/examples/webgl_lensflares.ts -+++ b/examples-testing/examples/webgl_lensflares.ts -@@ -5,10 +5,10 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { FlyControls } from 'three/addons/controls/FlyControls.js'; - import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; --let controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controls: FlyControls; - - const clock = new THREE.Clock(); - -@@ -70,7 +70,7 @@ function init() { - addLight(0.08, 0.8, 0.5, 0, 0, -1000); - addLight(0.995, 0.5, 0.9, 5000, 5000, -1000); - -- function addLight(h, s, l, x, y, z) { -+ function addLight(h: number, s: number, l: number, x: number, y: number, z: number) { - const light = new THREE.PointLight(0xffffff, 1.5, 2000, 0); - light.color.setHSL(h, s, l); - light.position.set(x, y, z); -diff --git a/examples-testing/examples/webgl_lightprobe.ts b/examples-testing/examples/webgl_lightprobe.ts -index 58f021e6..1427cce4 100644 ---- a/examples-testing/examples/webgl_lightprobe.ts -+++ b/examples-testing/examples/webgl_lightprobe.ts -@@ -8,12 +8,15 @@ import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js' - - import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelper.js'; - --let mesh, renderer, scene, camera; -+let mesh: THREE.Mesh, -+ renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera; - - let gui; - --let lightProbe; --let directionalLight; -+let lightProbe: THREE.LightProbe; -+let directionalLight: THREE.DirectionalLight; - - // linear color space - const API = { -@@ -58,7 +61,7 @@ function init() { - scene.add(directionalLight); - - // envmap -- const genCubeUrls = function (prefix, postfix) { -+ const genCubeUrls = function (prefix: string, postfix: string) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, -diff --git a/examples-testing/examples/webgl_lightprobe_cubecamera.ts b/examples-testing/examples/webgl_lightprobe_cubecamera.ts -index 65425d4e..a9a0533e 100644 ---- a/examples-testing/examples/webgl_lightprobe_cubecamera.ts -+++ b/examples-testing/examples/webgl_lightprobe_cubecamera.ts -@@ -4,9 +4,9 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelper.js'; - import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js'; - --let renderer, scene, camera, cubeCamera; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, cubeCamera: THREE.CubeCamera; - --let lightProbe; -+let lightProbe: THREE.LightProbe; - - init(); - -@@ -40,7 +40,7 @@ function init() { - scene.add(lightProbe); - - // envmap -- const genCubeUrls = function (prefix, postfix) { -+ const genCubeUrls = function (prefix: string, postfix: string) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, -diff --git a/examples-testing/examples/webgl_lights_hemisphere.ts b/examples-testing/examples/webgl_lights_hemisphere.ts -index 15bc7609..ef2538ee 100644 ---- a/examples-testing/examples/webgl_lights_hemisphere.ts -+++ b/examples-testing/examples/webgl_lights_hemisphere.ts -@@ -5,16 +5,16 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, scene, renderer; --const mixers = []; --let stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+const mixers: THREE.AnimationMixer[] = []; -+let stats: Stats; - - const clock = new THREE.Clock(); - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.set(0, 0, 250); -@@ -74,8 +74,8 @@ function init() { - - // SKYDOME - -- const vertexShader = document.getElementById('vertexShader').textContent; -- const fragmentShader = document.getElementById('fragmentShader').textContent; -+ const vertexShader = document.getElementById('vertexShader')!.textContent!; -+ const fragmentShader = document.getElementById('fragmentShader')!.textContent!; - const uniforms = { - topColor: { value: new THREE.Color(0x0077ff) }, - bottomColor: { value: new THREE.Color(0xffffff) }, -diff --git a/examples-testing/examples/webgl_lights_physical.ts b/examples-testing/examples/webgl_lights_physical.ts -index 707ef200..8e4cf0bb 100644 ---- a/examples-testing/examples/webgl_lights_physical.ts -+++ b/examples-testing/examples/webgl_lights_physical.ts -@@ -5,13 +5,19 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, bulbLight, bulbMat, hemiLight, stats; --let ballMat, cubeMat, floorMat; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ bulbLight: THREE.PointLight, -+ bulbMat: THREE.MeshStandardMaterial, -+ hemiLight: THREE.HemisphereLight, -+ stats: Stats; -+let ballMat: THREE.MeshStandardMaterial, cubeMat: THREE.MeshStandardMaterial, floorMat: THREE.MeshStandardMaterial; - - let previousShadowMap = false; - - // ref for lumens: http://www.power-sure.com/lumens.htm --const bulbLuminousPowers = { -+const bulbLuminousPowers: Record = { - '110000 lm (1000W)': 110000, - '3500 lm (300W)': 3500, - '1700 lm (100W)': 1700, -@@ -23,7 +29,7 @@ const bulbLuminousPowers = { - }; - - // ref for solar irradiances: https://en.wikipedia.org/wiki/Lux --const hemiLuminousIrradiances = { -+const hemiLuminousIrradiances: Record = { - '0.0001 lx (Moonless Night)': 0.0001, - '0.002 lx (Night Airglow)': 0.002, - '0.5 lx (Full Moon)': 0.5, -@@ -47,7 +53,7 @@ const params = { - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - stats = new Stats(); - container.appendChild(stats.dom); -diff --git a/examples-testing/examples/webgl_lights_pointlights.ts b/examples-testing/examples/webgl_lights_pointlights.ts -index ea95070c..020d2160 100644 ---- a/examples-testing/examples/webgl_lights_pointlights.ts -+++ b/examples-testing/examples/webgl_lights_pointlights.ts -@@ -4,7 +4,15 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - --let camera, scene, renderer, light1, light2, light3, light4, object, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ light1: THREE.PointLight, -+ light2: THREE.PointLight, -+ light3: THREE.PointLight, -+ light4: THREE.PointLight, -+ object: THREE.Group, -+ stats: Stats; - - const clock = new THREE.Clock(); - -diff --git a/examples-testing/examples/webgl_lights_rectarealight.ts b/examples-testing/examples/webgl_lights_rectarealight.ts -index b841fa6b..f3051618 100644 ---- a/examples-testing/examples/webgl_lights_rectarealight.ts -+++ b/examples-testing/examples/webgl_lights_rectarealight.ts -@@ -6,8 +6,8 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js'; - import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js'; - --let renderer, scene, camera; --let stats, meshKnot; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let stats: Stats, meshKnot: THREE.Mesh; - - init(); - -@@ -70,7 +70,7 @@ function onWindowResize() { - camera.updateProjectionMatrix(); - } - --function animation(time) { -+function animation(time: DOMHighResTimeStamp) { - meshKnot.rotation.y = time / 1000; - - renderer.render(scene, camera); -diff --git a/examples-testing/examples/webgl_lights_spotlight.ts b/examples-testing/examples/webgl_lights_spotlight.ts -index 894abaf6..342a70fb 100644 ---- a/examples-testing/examples/webgl_lights_spotlight.ts -+++ b/examples-testing/examples/webgl_lights_spotlight.ts -@@ -5,9 +5,9 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let renderer, scene, camera; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; - --let spotLight, lightHelper; -+let spotLight: THREE.SpotLight, lightHelper: THREE.SpotLightHelper; - - init(); - -@@ -42,7 +42,7 @@ function init() { - const loader = new THREE.TextureLoader().setPath('textures/'); - const filenames = ['disturb.jpg', 'colors.png', 'uv_grid_opengl.jpg']; - -- const textures = { none: null }; -+ const textures: Record = { none: null }; - - for (let i = 0; i < filenames.length; i++) { - const filename = filenames[i]; -@@ -155,8 +155,8 @@ function init() { - renderer.shadowMap.enabled = val; - - scene.traverse(function (child) { -- if (child.material) { -- child.material.needsUpdate = true; -+ if ((child as THREE.Mesh).material) { -+ (child as THREE.Mesh).material.needsUpdate = true; - } - }); - }); -diff --git a/examples-testing/examples/webgl_lights_spotlights.ts b/examples-testing/examples/webgl_lights_spotlights.ts -index 70caf5a5..fc4817fb 100644 ---- a/examples-testing/examples/webgl_lights_spotlights.ts -+++ b/examples-testing/examples/webgl_lights_spotlights.ts -@@ -29,7 +29,7 @@ const spotLight1 = createSpotlight(0xff7f00); - const spotLight2 = createSpotlight(0x00ff7f); - const spotLight3 = createSpotlight(0x7f00ff); - --let lightHelper1, lightHelper2, lightHelper3; -+let lightHelper1: THREE.SpotLightHelper, lightHelper2: THREE.SpotLightHelper, lightHelper3: THREE.SpotLightHelper; - - function init() { - renderer.shadowMap.enabled = true; -@@ -68,7 +68,7 @@ function init() { - controls.update(); - } - --function createSpotlight(color) { -+function createSpotlight(color: number) { - const newObj = new THREE.SpotLight(color, 10); - - newObj.castShadow = true; -@@ -86,7 +86,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function tween(light) { -+function tween(light: THREE.SpotLight) { - new TWEEN.Tween(light) - .to( - { -diff --git a/examples-testing/examples/webgl_lines_colors.ts b/examples-testing/examples/webgl_lines_colors.ts -index 9da19ee2..68bc979b 100644 ---- a/examples-testing/examples/webgl_lines_colors.ts -+++ b/examples-testing/examples/webgl_lines_colors.ts -@@ -8,7 +8,7 @@ let mouseX = 0, - let windowHalfX = window.innerWidth / 2; - let windowHalfY = window.innerHeight / 2; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -110,7 +110,7 @@ function init() { - const scale = 0.3, - d = 225; - -- const parameters = [ -+ const parameters: [THREE.Material, number, [number, number, number], THREE.BufferGeometry][] = [ - [material, scale * 1.5, [-d, -d / 2, 0], geometry1], - [material, scale * 1.5, [0, -d / 2, 0], geometry2], - [material, scale * 1.5, [d, -d / 2, 0], geometry3], -@@ -152,7 +152,7 @@ function onWindowResize() { - - // - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -@@ -172,7 +172,7 @@ function animate() { - for (let i = 0; i < scene.children.length; i++) { - const object = scene.children[i]; - -- if (object.isLine) { -+ if ((object as THREE.Line).isLine) { - object.rotation.y = time * (i % 2 ? 1 : -1); - } - } -diff --git a/examples-testing/examples/webgl_lines_dashed.ts b/examples-testing/examples/webgl_lines_dashed.ts -index 4849e7c3..4bddc484 100644 ---- a/examples-testing/examples/webgl_lines_dashed.ts -+++ b/examples-testing/examples/webgl_lines_dashed.ts -@@ -4,8 +4,8 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - --let renderer, scene, camera, stats; --const objects = []; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; -+const objects: THREE.Object3D[] = []; - - const WIDTH = window.innerWidth, - HEIGHT = window.innerHeight; -@@ -63,7 +63,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function box(width, height, depth) { -+function box(width: number, height: number, depth: number) { - (width = width * 0.5), (height = height * 0.5), (depth = depth * 0.5); - - const geometry = new THREE.BufferGeometry(); -@@ -176,7 +176,7 @@ function render() { - const time = Date.now() * 0.001; - - scene.traverse(function (object) { -- if (object.isLine) { -+ if ((object as THREE.Line).isLine) { - object.rotation.x = 0.25 * time; - object.rotation.y = 0.25 * time; - } -diff --git a/examples-testing/examples/webgl_lines_fat.ts b/examples-testing/examples/webgl_lines_fat.ts -index 7c7fee65..ba63c722 100644 ---- a/examples-testing/examples/webgl_lines_fat.ts -+++ b/examples-testing/examples/webgl_lines_fat.ts -@@ -9,15 +9,20 @@ import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; - import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; - import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - --let line, renderer, scene, camera, camera2, controls; --let line1; --let matLine, matLineBasic, matLineDashed; --let stats; --let gui; -+let line: Line2, -+ renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ camera2: THREE.PerspectiveCamera, -+ controls: OrbitControls; -+let line1: THREE.Line; -+let matLine: LineMaterial, matLineBasic: THREE.LineBasicMaterial, matLineDashed: THREE.LineDashedMaterial; -+let stats: Stats; -+let gui: GUI; - - // viewport --let insetWidth; --let insetHeight; -+let insetWidth: number; -+let insetHeight: number; - - init(); - -diff --git a/examples-testing/examples/webgl_lines_fat_raycasting.ts b/examples-testing/examples/webgl_lines_fat_raycasting.ts -index 872058e0..fb622394 100644 ---- a/examples-testing/examples/webgl_lines_fat_raycasting.ts -+++ b/examples-testing/examples/webgl_lines_fat_raycasting.ts -@@ -10,12 +10,13 @@ import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js - import { Line2 } from 'three/addons/lines/Line2.js'; - import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; - --let line, thresholdLine, segments, thresholdSegments; --let renderer, scene, camera, controls; --let sphereInter, sphereOnLine; --let stats; --let gui; --let clock; -+let line: Line2, thresholdLine: Line2, segments: LineSegments2, thresholdSegments: LineSegments2; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls; -+let sphereInter: THREE.Mesh, -+ sphereOnLine: THREE.Mesh; -+let stats: Stats; -+let gui: GUI; -+let clock: THREE.Clock; - - const color = new THREE.Color(); - -@@ -23,8 +24,7 @@ const pointer = new THREE.Vector2(Infinity, Infinity); - - const raycaster = new THREE.Raycaster(); - --raycaster.params.Line2 = {}; --raycaster.params.Line2.threshold = 0; -+raycaster.params.Line2 = { threshold: 0 }; - - const matLine = new LineMaterial({ - color: 0xffffff, -@@ -170,7 +170,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - } -@@ -199,9 +199,9 @@ function animate() { - sphereOnLine.visible = true; - - sphereInter.position.copy(intersects[0].point); -- sphereOnLine.position.copy(intersects[0].pointOnLine); -+ sphereOnLine.position.copy(intersects[0].pointOnLine!); - -- const index = intersects[0].faceIndex; -+ const index = intersects[0].faceIndex!; - const colors = obj.geometry.getAttribute('instanceColorStart'); - - color.fromBufferAttribute(colors, index); -@@ -223,7 +223,7 @@ function animate() { - - // - --function switchLine(val) { -+function switchLine(val: number) { - switch (val) { - case 0: - line.visible = true; -@@ -268,7 +268,7 @@ function initGui() { - - gui.add(params, 'width', 1, 10).onChange(function (val) { - matLine.linewidth = val; -- matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2.threshold; -+ matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2!.threshold; - }); - - gui.add(params, 'alphaToCoverage').onChange(function (val) { -@@ -276,8 +276,8 @@ function initGui() { - }); - - gui.add(params, 'threshold', 0, 10).onChange(function (val) { -- raycaster.params.Line2.threshold = val; -- matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2.threshold; -+ raycaster.params.Line2!.threshold = val; -+ matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2!.threshold; - }); - - gui.add(params, 'translation', 0, 10).onChange(function (val) { -diff --git a/examples-testing/examples/webgl_lines_fat_wireframe.ts b/examples-testing/examples/webgl_lines_fat_wireframe.ts -index 59660ad7..9f38fcb6 100644 ---- a/examples-testing/examples/webgl_lines_fat_wireframe.ts -+++ b/examples-testing/examples/webgl_lines_fat_wireframe.ts -@@ -8,15 +8,20 @@ import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; - import { Wireframe } from 'three/addons/lines/Wireframe.js'; - import { WireframeGeometry2 } from 'three/addons/lines/WireframeGeometry2.js'; - --let wireframe, renderer, scene, camera, camera2, controls; --let wireframe1; --let matLine, matLineBasic, matLineDashed; --let stats; --let gui; -+let wireframe: Wireframe, -+ renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ camera2: THREE.PerspectiveCamera, -+ controls: OrbitControls; -+let wireframe1: THREE.LineSegments; -+let matLine: LineMaterial, matLineBasic: THREE.LineBasicMaterial, matLineDashed: THREE.LineDashedMaterial; -+let stats: Stats; -+let gui: GUI; - - // viewport --let insetWidth; --let insetHeight; -+let insetWidth: number; -+let insetHeight: number; - - init(); - -@@ -42,7 +47,7 @@ function init() { - - // Wireframe ( WireframeGeometry2, LineMaterial ) - -- let geo = new THREE.IcosahedronGeometry(20, 1); -+ let geo: THREE.BufferGeometry = new THREE.IcosahedronGeometry(20, 1); - - const geometry = new WireframeGeometry2(geo); - -diff --git a/examples-testing/examples/webgl_loader_3dm.ts b/examples-testing/examples/webgl_loader_3dm.ts -index 7570306f..a363c213 100644 ---- a/examples-testing/examples/webgl_loader_3dm.ts -+++ b/examples-testing/examples/webgl_loader_3dm.ts -@@ -5,8 +5,8 @@ import { Rhino3dmLoader } from 'three/addons/loaders/3DMLoader.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; --let controls, gui; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controls: OrbitControls, gui: GUI; - - init(); - -@@ -38,7 +38,7 @@ function init() { - initGUI(object.userData.layers); - - // hide spinner -- document.getElementById('loader').style.display = 'none'; -+ document.getElementById('loader')!.style.display = 'none'; - }, - function (progress) { - console.log((progress.loaded / progress.total) * 100 + '%'); -@@ -68,7 +68,7 @@ function animate() { - renderer.render(scene, camera); - } - --function initGUI(layers) { -+function initGUI(layers: { name: string; visible: boolean }[]) { - gui = new GUI({ title: 'layers' }); - - for (let i = 0; i < layers.length; i++) { -diff --git a/examples-testing/examples/webgl_loader_3ds.ts b/examples-testing/examples/webgl_loader_3ds.ts -index 10ce3407..ac3a6e23 100644 ---- a/examples-testing/examples/webgl_loader_3ds.ts -+++ b/examples-testing/examples/webgl_loader_3ds.ts -@@ -3,8 +3,8 @@ import * as THREE from 'three'; - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import { TDSLoader } from 'three/addons/loaders/TDSLoader.js'; - --let container, controls; --let camera, scene, renderer; -+let container: HTMLDivElement, controls: TrackballControls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -29,9 +29,9 @@ function init() { - loader.setResourcePath('models/3ds/portalgun/textures/'); - loader.load('models/3ds/portalgun/portalgun.3ds', function (object) { - object.traverse(function (child) { -- if (child.isMesh) { -- child.material.specular.setScalar(0.1); -- child.material.normalMap = normal; -+ if ((child as THREE.Mesh).isMesh) { -+ (child as THREE.Mesh).material.specular.setScalar(0.1); -+ (child as THREE.Mesh).material.normalMap = normal; - } - }); - -diff --git a/examples-testing/examples/webgl_loader_3mf.ts b/examples-testing/examples/webgl_loader_3mf.ts -index c31e3219..eecda516 100644 ---- a/examples-testing/examples/webgl_loader_3mf.ts -+++ b/examples-testing/examples/webgl_loader_3mf.ts -@@ -4,7 +4,12 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, object, loader, controls; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ object: THREE.Group, -+ loader: ThreeMFLoader, -+ controls: OrbitControls; - - const params = { - asset: 'cube_gears', -@@ -73,13 +78,18 @@ function init() { - }); - } - --function loadAsset(asset) { -+function loadAsset(asset: string) { - loader.load('models/3mf/' + asset + '.3mf', function (group) { - if (object) { - object.traverse(function (child) { -- if (child.material) child.material.dispose(); -- if (child.material && child.material.map) child.material.map.dispose(); -- if (child.geometry) child.geometry.dispose(); -+ if ((child as THREE.Mesh).material) -+ (child as THREE.Mesh).material.dispose(); -+ if ( -+ (child as THREE.Mesh).material && -+ (child as THREE.Mesh).material.map -+ ) -+ (child as THREE.Mesh).material.map!.dispose(); -+ if ((child as THREE.Mesh).geometry) (child as THREE.Mesh).geometry.dispose(); - }); - - scene.remove(object); -diff --git a/examples-testing/examples/webgl_loader_3mf_materials.ts b/examples-testing/examples/webgl_loader_3mf_materials.ts -index fcdd7308..3cfb49b4 100644 ---- a/examples-testing/examples/webgl_loader_3mf_materials.ts -+++ b/examples-testing/examples/webgl_loader_3mf_materials.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_amf.ts b/examples-testing/examples/webgl_loader_amf.ts -index ee576e04..7569a044 100644 ---- a/examples-testing/examples/webgl_loader_amf.ts -+++ b/examples-testing/examples/webgl_loader_amf.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { AMFLoader } from 'three/addons/loaders/AMFLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_bvh.ts b/examples-testing/examples/webgl_loader_bvh.ts -index 0be3add4..cfdf0bc7 100644 ---- a/examples-testing/examples/webgl_loader_bvh.ts -+++ b/examples-testing/examples/webgl_loader_bvh.ts -@@ -5,8 +5,8 @@ import { BVHLoader } from 'three/addons/loaders/BVHLoader.js'; - - const clock = new THREE.Clock(); - --let camera, controls, scene, renderer; --let mixer; -+let camera: THREE.PerspectiveCamera, controls: OrbitControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let mixer: THREE.AnimationMixer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_collada.ts b/examples-testing/examples/webgl_loader_collada.ts -index 62588b69..e1e82771 100644 ---- a/examples-testing/examples/webgl_loader_collada.ts -+++ b/examples-testing/examples/webgl_loader_collada.ts -@@ -4,13 +4,13 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; - --let container, stats, clock; --let camera, scene, renderer, elf; -+let container: HTMLElement, stats: Stats, clock: THREE.Clock; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, elf: THREE.Scene; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); - camera.position.set(8, 10, 8); -diff --git a/examples-testing/examples/webgl_loader_collada_skinning.ts b/examples-testing/examples/webgl_loader_collada_skinning.ts -index 5cb808b1..7b2b57bd 100644 ---- a/examples-testing/examples/webgl_loader_collada_skinning.ts -+++ b/examples-testing/examples/webgl_loader_collada_skinning.ts -@@ -5,13 +5,13 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container, stats, clock, controls; --let camera, scene, renderer, mixer; -+let container: HTMLElement, stats: Stats, clock: THREE.Clock, controls: OrbitControls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, mixer: THREE.AnimationMixer; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(15, 10, -15); -diff --git a/examples-testing/examples/webgl_loader_draco.ts b/examples-testing/examples/webgl_loader_draco.ts -index c9947c69..69bf22b4 100644 ---- a/examples-testing/examples/webgl_loader_draco.ts -+++ b/examples-testing/examples/webgl_loader_draco.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --const container = document.querySelector('#container'); -+const container = document.querySelector('#container')!; - - // Configure and create Draco decoder. - const dracoLoader = new DRACOLoader(); -diff --git a/examples-testing/examples/webgl_loader_fbx.ts b/examples-testing/examples/webgl_loader_fbx.ts -index 3b157a22..af4de6ac 100644 ---- a/examples-testing/examples/webgl_loader_fbx.ts -+++ b/examples-testing/examples/webgl_loader_fbx.ts -@@ -8,8 +8,14 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - const manager = new THREE.LoadingManager(); - --let camera, scene, renderer, stats, object, loader, guiMorphsFolder; --let mixer; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ object: THREE.Group, -+ loader: FBXLoader, -+ guiMorphsFolder: GUI; -+let mixer: THREE.AnimationMixer | null; - - const clock = new THREE.Clock(); - -@@ -89,19 +95,22 @@ function init() { - guiMorphsFolder = gui.addFolder('Morphs').hide(); - } - --function loadAsset(asset) { -+function loadAsset(asset: string) { - loader.load('models/fbx/' + asset + '.fbx', function (group) { - if (object) { - object.traverse(function (child) { -- if (child.material) { -- const materials = Array.isArray(child.material) ? child.material : [child.material]; -+ if ((child as THREE.Mesh).material) { -+ const materials = Array.isArray((child as THREE.Mesh).material) -+ ? (child as THREE.Mesh).material -+ : [(child as THREE.Mesh).material]; - materials.forEach(material => { -- if (material.map) material.map.dispose(); -- material.dispose(); -+ if ((material as THREE.MeshPhongMaterial).map) -+ (material as THREE.MeshPhongMaterial).map!.dispose(); -+ (material as THREE.MeshPhongMaterial).dispose(); - }); - } - -- if (child.geometry) child.geometry.dispose(); -+ if ((child as THREE.Mesh).geometry) (child as THREE.Mesh).geometry.dispose(); - }); - - scene.remove(object); -@@ -124,15 +133,21 @@ function loadAsset(asset) { - guiMorphsFolder.hide(); - - object.traverse(function (child) { -- if (child.isMesh) { -+ if ((child as THREE.Mesh).isMesh) { - child.castShadow = true; - child.receiveShadow = true; - -- if (child.morphTargetDictionary) { -+ if ((child as THREE.Mesh).morphTargetDictionary) { - guiMorphsFolder.show(); - const meshFolder = guiMorphsFolder.addFolder(child.name || child.uuid); -- Object.keys(child.morphTargetDictionary).forEach(key => { -- meshFolder.add(child.morphTargetInfluences, child.morphTargetDictionary[key], 0, 1, 0.01); -+ Object.keys((child as THREE.Mesh).morphTargetDictionary!).forEach(key => { -+ meshFolder.add( -+ (child as THREE.Mesh).morphTargetInfluences!, -+ (child as THREE.Mesh).morphTargetDictionary![key], -+ 0, -+ 1, -+ 0.01, -+ ); - }); - } - } -diff --git a/examples-testing/examples/webgl_loader_fbx_nurbs.ts b/examples-testing/examples/webgl_loader_fbx_nurbs.ts -index f2e45bcb..c15264d7 100644 ---- a/examples-testing/examples/webgl_loader_fbx_nurbs.ts -+++ b/examples-testing/examples/webgl_loader_fbx_nurbs.ts -@@ -5,7 +5,7 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_gcode.ts b/examples-testing/examples/webgl_loader_gcode.ts -index 6fd3e149..79c64232 100644 ---- a/examples-testing/examples/webgl_loader_gcode.ts -+++ b/examples-testing/examples/webgl_loader_gcode.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GCodeLoader } from 'three/addons/loaders/GCodeLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_loader_gltf.ts b/examples-testing/examples/webgl_loader_gltf.ts -index e1b0adc5..6fcb3ed5 100644 ---- a/examples-testing/examples/webgl_loader_gltf.ts -+++ b/examples-testing/examples/webgl_loader_gltf.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_gltf_anisotropy.ts b/examples-testing/examples/webgl_loader_gltf_anisotropy.ts -index 6e240a27..96a39391 100644 ---- a/examples-testing/examples/webgl_loader_gltf_anisotropy.ts -+++ b/examples-testing/examples/webgl_loader_gltf_anisotropy.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let renderer, scene, camera, controls; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_gltf_avif.ts b/examples-testing/examples/webgl_loader_gltf_avif.ts -index 37d63859..68dff97f 100644 ---- a/examples-testing/examples/webgl_loader_gltf_avif.ts -+++ b/examples-testing/examples/webgl_loader_gltf_avif.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_loader_gltf_compressed.ts b/examples-testing/examples/webgl_loader_gltf_compressed.ts -index 3bdcea8e..c381c46d 100644 ---- a/examples-testing/examples/webgl_loader_gltf_compressed.ts -+++ b/examples-testing/examples/webgl_loader_gltf_compressed.ts -@@ -7,7 +7,7 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_loader_gltf_dispersion.ts b/examples-testing/examples/webgl_loader_gltf_dispersion.ts -index 100badca..bd16bf3b 100644 ---- a/examples-testing/examples/webgl_loader_gltf_dispersion.ts -+++ b/examples-testing/examples/webgl_loader_gltf_dispersion.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init().then(render); - -diff --git a/examples-testing/examples/webgl_loader_gltf_instancing.ts b/examples-testing/examples/webgl_loader_gltf_instancing.ts -index 5d23e775..b8a6814d 100644 ---- a/examples-testing/examples/webgl_loader_gltf_instancing.ts -+++ b/examples-testing/examples/webgl_loader_gltf_instancing.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_loader_gltf_iridescence.ts b/examples-testing/examples/webgl_loader_gltf_iridescence.ts -index eb0f8d91..9ab15779 100644 ---- a/examples-testing/examples/webgl_loader_gltf_iridescence.ts -+++ b/examples-testing/examples/webgl_loader_gltf_iridescence.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let renderer, scene, camera, controls; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls; - - init().catch(function (err) { - console.error(err); -diff --git a/examples-testing/examples/webgl_loader_gltf_sheen.ts b/examples-testing/examples/webgl_loader_gltf_sheen.ts -index bd258d5c..de946286 100644 ---- a/examples-testing/examples/webgl_loader_gltf_sheen.ts -+++ b/examples-testing/examples/webgl_loader_gltf_sheen.ts -@@ -6,7 +6,7 @@ import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: OrbitControls; - - init(); - -@@ -24,7 +24,10 @@ function init() { - new GLTFLoader().setPath('models/gltf/').load('SheenChair.glb', function (gltf) { - scene.add(gltf.scene); - -- const object = gltf.scene.getObjectByName('SheenChair_fabric'); -+ const object = gltf.scene.getObjectByName('SheenChair_fabric') as THREE.Mesh< -+ THREE.BufferGeometry, -+ THREE.MeshPhysicalMaterial -+ >; - - const gui = new GUI(); - -diff --git a/examples-testing/examples/webgl_loader_gltf_transmission.ts b/examples-testing/examples/webgl_loader_gltf_transmission.ts -index 87a47d2c..c1341d80 100644 ---- a/examples-testing/examples/webgl_loader_gltf_transmission.ts -+++ b/examples-testing/examples/webgl_loader_gltf_transmission.ts -@@ -6,7 +6,12 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - --let camera, scene, renderer, controls, clock, mixer; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ controls: OrbitControls, -+ clock: THREE.Clock, -+ mixer: THREE.AnimationMixer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_imagebitmap.ts b/examples-testing/examples/webgl_loader_imagebitmap.ts -index 1049e985..ae304ad8 100644 ---- a/examples-testing/examples/webgl_loader_imagebitmap.ts -+++ b/examples-testing/examples/webgl_loader_imagebitmap.ts -@@ -1,7 +1,7 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; --let group, cubes; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let group: THREE.Group, cubes: THREE.Group; - - init(); - -@@ -42,7 +42,7 @@ function addImage() { - - const geometry = new THREE.BoxGeometry(); - --function addCube(material) { -+function addCube(material: THREE.MeshBasicMaterial) { - const cube = new THREE.Mesh(geometry, material); - cube.position.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1); - cube.rotation.set(Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI); -diff --git a/examples-testing/examples/webgl_loader_kmz.ts b/examples-testing/examples/webgl_loader_kmz.ts -index f93555e4..8793a351 100644 ---- a/examples-testing/examples/webgl_loader_kmz.ts -+++ b/examples-testing/examples/webgl_loader_kmz.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { KMZLoader } from 'three/addons/loaders/KMZLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_lwo.ts b/examples-testing/examples/webgl_loader_lwo.ts -index fb10c834..df003a04 100644 ---- a/examples-testing/examples/webgl_loader_lwo.ts -+++ b/examples-testing/examples/webgl_loader_lwo.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { LWOLoader } from 'three/addons/loaders/LWOLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_md2_control.ts b/examples-testing/examples/webgl_loader_md2_control.ts -index 683e4c2a..845039ea 100644 ---- a/examples-testing/examples/webgl_loader_md2_control.ts -+++ b/examples-testing/examples/webgl_loader_md2_control.ts -@@ -9,10 +9,10 @@ import { Gyroscope } from 'three/addons/misc/Gyroscope.js'; - let SCREEN_WIDTH = window.innerWidth; - let SCREEN_HEIGHT = window.innerHeight; - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --const characters = []; -+const characters: MD2CharacterComplex[] = []; - let nCharacters = 0; - - let cameraControls; -@@ -76,10 +76,10 @@ function init() { - - const ground = new THREE.Mesh(gg, gm); - ground.rotation.x = -Math.PI / 2; -- ground.material.map.repeat.set(64, 64); -- ground.material.map.wrapS = THREE.RepeatWrapping; -- ground.material.map.wrapT = THREE.RepeatWrapping; -- ground.material.map.colorSpace = THREE.SRGBColorSpace; -+ ground.material.map!.repeat.set(64, 64); -+ ground.material.map!.wrapS = THREE.RepeatWrapping; -+ ground.material.map!.wrapT = THREE.RepeatWrapping; -+ ground.material.map!.colorSpace = THREE.SRGBColorSpace; - // note that because the ground does not cast a shadow, .castShadow is left false - ground.receiveShadow = true; - -@@ -212,7 +212,7 @@ function onWindowResize() { - camera.updateProjectionMatrix(); - } - --function onKeyDown(event) { -+function onKeyDown(event: KeyboardEvent) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': -@@ -241,7 +241,7 @@ function onKeyDown(event) { - } - } - --function onKeyUp(event) { -+function onKeyUp(event: KeyboardEvent) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': -diff --git a/examples-testing/examples/webgl_loader_mdd.ts b/examples-testing/examples/webgl_loader_mdd.ts -index 5b13e8f4..83aad15c 100644 ---- a/examples-testing/examples/webgl_loader_mdd.ts -+++ b/examples-testing/examples/webgl_loader_mdd.ts -@@ -2,7 +2,11 @@ import * as THREE from 'three'; - - import { MDDLoader } from 'three/addons/loaders/MDDLoader.js'; - --let camera, scene, renderer, mixer, clock; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ mixer: THREE.AnimationMixer, -+ clock: THREE.Clock; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_obj.ts b/examples-testing/examples/webgl_loader_obj.ts -index f61eeb75..44b29b66 100644 ---- a/examples-testing/examples/webgl_loader_obj.ts -+++ b/examples-testing/examples/webgl_loader_obj.ts -@@ -3,9 +3,9 @@ import * as THREE from 'three'; - import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let object; -+let object: THREE.Group; - - init(); - -@@ -28,7 +28,8 @@ function init() { - - function loadModel() { - object.traverse(function (child) { -- if (child.isMesh) child.material.map = texture; -+ if ((child as THREE.Mesh).isMesh) -+ (child as THREE.Mesh).material.map = texture; - }); - - object.position.y = -0.95; -@@ -48,7 +49,7 @@ function init() { - - // model - -- function onProgress(xhr) { -+ function onProgress(xhr: ProgressEvent) { - if (xhr.lengthComputable) { - const percentComplete = (xhr.loaded / xhr.total) * 100; - console.log('model ' + percentComplete.toFixed(2) + '% downloaded'); -diff --git a/examples-testing/examples/webgl_loader_obj_mtl.ts b/examples-testing/examples/webgl_loader_obj_mtl.ts -index 4308aee7..f27d82d9 100644 ---- a/examples-testing/examples/webgl_loader_obj_mtl.ts -+++ b/examples-testing/examples/webgl_loader_obj_mtl.ts -@@ -4,7 +4,7 @@ import { MTLLoader } from 'three/addons/loaders/MTLLoader.js'; - import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -25,7 +25,7 @@ function init() { - - // model - -- const onProgress = function (xhr) { -+ const onProgress = function (xhr: ProgressEvent) { - if (xhr.lengthComputable) { - const percentComplete = (xhr.loaded / xhr.total) * 100; - console.log(percentComplete.toFixed(2) + '% downloaded'); -diff --git a/examples-testing/examples/webgl_loader_pcd.ts b/examples-testing/examples/webgl_loader_pcd.ts -index d69e3fa2..312ad67c 100644 ---- a/examples-testing/examples/webgl_loader_pcd.ts -+++ b/examples-testing/examples/webgl_loader_pcd.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { PCDLoader } from 'three/addons/loaders/PCDLoader.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_loader_pdb.ts b/examples-testing/examples/webgl_loader_pdb.ts -index b560efa7..9882dff5 100644 ---- a/examples-testing/examples/webgl_loader_pdb.ts -+++ b/examples-testing/examples/webgl_loader_pdb.ts -@@ -5,10 +5,10 @@ import { PDBLoader } from 'three/addons/loaders/PDBLoader.js'; - import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, labelRenderer; --let controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, labelRenderer: CSS2DRenderer; -+let controls: TrackballControls; - --let root; -+let root: THREE.Group; - - const MOLECULES = { - Ethanol: 'ethanol.pdb', -@@ -64,14 +64,14 @@ function init() { - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); -- document.getElementById('container').appendChild(renderer.domElement); -+ document.getElementById('container')!.appendChild(renderer.domElement); - - labelRenderer = new CSS2DRenderer(); - labelRenderer.setSize(window.innerWidth, window.innerHeight); - labelRenderer.domElement.style.position = 'absolute'; - labelRenderer.domElement.style.top = '0px'; - labelRenderer.domElement.style.pointerEvents = 'none'; -- document.getElementById('container').appendChild(labelRenderer.domElement); -+ document.getElementById('container')!.appendChild(labelRenderer.domElement); - - // - -@@ -97,12 +97,12 @@ function init() { - - // - --function loadMolecule(model) { -+function loadMolecule(model: string) { - const url = 'models/pdb/' + model; - - while (root.children.length > 0) { - const object = root.children[0]; -- object.parent.remove(object); -+ object.parent!.remove(object); - } - - loader.load(url, function (pdb) { -@@ -114,7 +114,7 @@ function loadMolecule(model) { - const sphereGeometry = new THREE.IcosahedronGeometry(1, 3); - - geometryAtoms.computeBoundingBox(); -- geometryAtoms.boundingBox.getCenter(offset).negate(); -+ geometryAtoms.boundingBox!.getCenter(offset).negate(); - - geometryAtoms.translate(offset.x, offset.y, offset.z); - geometryBonds.translate(offset.x, offset.y, offset.z); -diff --git a/examples-testing/examples/webgl_loader_ply.ts b/examples-testing/examples/webgl_loader_ply.ts -index 0f4042b7..dff17d16 100644 ---- a/examples-testing/examples/webgl_loader_ply.ts -+++ b/examples-testing/examples/webgl_loader_ply.ts -@@ -4,9 +4,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, cameraTarget, scene, renderer; -+let camera: THREE.PerspectiveCamera, cameraTarget: THREE.Vector3, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -100,7 +100,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function addShadowedLight(x, y, z, color, intensity) { -+function addShadowedLight(x: number, y: number, z: number, color: number, intensity: number) { - const directionalLight = new THREE.DirectionalLight(color, intensity); - directionalLight.position.set(x, y, z); - scene.add(directionalLight); -diff --git a/examples-testing/examples/webgl_loader_svg.ts b/examples-testing/examples/webgl_loader_svg.ts -index 45361b92..f5d72d3c 100644 ---- a/examples-testing/examples/webgl_loader_svg.ts -+++ b/examples-testing/examples/webgl_loader_svg.ts -@@ -3,14 +3,24 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { SVGLoader } from 'three/addons/loaders/SVGLoader.js'; - --let renderer, scene, camera, gui, guiData; -+let renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ gui: GUI, -+ guiData: { -+ currentURL: string; -+ drawFillShapes: boolean; -+ drawStrokes: boolean; -+ fillShapesWireframe: boolean; -+ strokesWireframe: boolean; -+ }; - - init(); - - // - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - // - -@@ -100,7 +110,7 @@ function createGUI() { - } - } - --function loadSVG(url) { -+function loadSVG(url: string) { - // - - scene = new THREE.Scene(); -@@ -126,12 +136,12 @@ function loadSVG(url) { - let renderOrder = 0; - - for (const path of data.paths) { -- const fillColor = path.userData.style.fill; -+ const fillColor = path.userData!.style.fill; - - if (guiData.drawFillShapes && fillColor !== undefined && fillColor !== 'none') { - const material = new THREE.MeshBasicMaterial({ - color: new THREE.Color().setStyle(fillColor), -- opacity: path.userData.style.fillOpacity, -+ opacity: path.userData!.style.fillOpacity, - transparent: true, - side: THREE.DoubleSide, - depthWrite: false, -@@ -149,12 +159,12 @@ function loadSVG(url) { - } - } - -- const strokeColor = path.userData.style.stroke; -+ const strokeColor = path.userData!.style.stroke; - - if (guiData.drawStrokes && strokeColor !== undefined && strokeColor !== 'none') { - const material = new THREE.MeshBasicMaterial({ - color: new THREE.Color().setStyle(strokeColor), -- opacity: path.userData.style.strokeOpacity, -+ opacity: path.userData!.style.strokeOpacity, - transparent: true, - side: THREE.DoubleSide, - depthWrite: false, -@@ -162,7 +172,7 @@ function loadSVG(url) { - }); - - for (const subPath of path.subPaths) { -- const geometry = SVGLoader.pointsToStroke(subPath.getPoints(), path.userData.style); -+ const geometry = SVGLoader.pointsToStroke(subPath.getPoints(), path.userData!.style); - - if (geometry) { - const mesh = new THREE.Mesh(geometry, material); -diff --git a/examples-testing/examples/webgl_loader_texture_dds.ts b/examples-testing/examples/webgl_loader_texture_dds.ts -index bc4bd057..0bf94def 100644 ---- a/examples-testing/examples/webgl_loader_texture_dds.ts -+++ b/examples-testing/examples/webgl_loader_texture_dds.ts -@@ -2,8 +2,8 @@ import * as THREE from 'three'; - - import { DDSLoader } from 'three/addons/loaders/DDSLoader.js'; - --let camera, scene, renderer; --const meshes = []; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+const meshes: THREE.Mesh[] = []; - - init(); - -@@ -106,7 +106,7 @@ function init() { - const material11 = new THREE.MeshBasicMaterial({ map: map9 }); - const material12 = new THREE.MeshBasicMaterial({ map: map10 }); - -- let mesh = new THREE.Mesh(new THREE.TorusGeometry(), material1); -+ let mesh: THREE.Mesh = new THREE.Mesh(new THREE.TorusGeometry(), material1); - mesh.position.x = -10; - mesh.position.y = -2; - scene.add(mesh); -diff --git a/examples-testing/examples/webgl_loader_texture_ktx.ts b/examples-testing/examples/webgl_loader_texture_ktx.ts -index af66eb81..f7832073 100644 ---- a/examples-testing/examples/webgl_loader_texture_ktx.ts -+++ b/examples-testing/examples/webgl_loader_texture_ktx.ts -@@ -17,8 +17,8 @@ import { KTXLoader } from 'three/addons/loaders/KTXLoader.js'; - ASTC_4x4, ASTC8x8 - transparent textures with full alpha range - */ - --let camera, scene, renderer; --const meshes = []; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+const meshes: THREE.Mesh[] = []; - - init(); - -@@ -51,14 +51,14 @@ function init() { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_PVR2bpp.ktx'), - }); -- material1.map.colorSpace = THREE.SRGBColorSpace; -+ material1.map!.colorSpace = THREE.SRGBColorSpace; - material2 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/lensflare_PVR4bpp.ktx'), - depthTest: false, - transparent: true, - side: THREE.DoubleSide, - }); -- material2.map.colorSpace = THREE.SRGBColorSpace; -+ material2.map!.colorSpace = THREE.SRGBColorSpace; - - meshes.push(new THREE.Mesh(geometry, material1)); - meshes.push(new THREE.Mesh(geometry, material2)); -@@ -68,14 +68,14 @@ function init() { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_BC1.ktx'), - }); -- material1.map.colorSpace = THREE.SRGBColorSpace; -+ material1.map!.colorSpace = THREE.SRGBColorSpace; - material2 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/lensflare_BC3.ktx'), - depthTest: false, - transparent: true, - side: THREE.DoubleSide, - }); -- material2.map.colorSpace = THREE.SRGBColorSpace; -+ material2.map!.colorSpace = THREE.SRGBColorSpace; - - meshes.push(new THREE.Mesh(geometry, material1)); - meshes.push(new THREE.Mesh(geometry, material2)); -@@ -93,14 +93,14 @@ function init() { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_ASTC4x4.ktx'), - }); -- material1.map.colorSpace = THREE.SRGBColorSpace; -+ material1.map!.colorSpace = THREE.SRGBColorSpace; - material2 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/lensflare_ASTC8x8.ktx'), - depthTest: false, - transparent: true, - side: THREE.DoubleSide, - }); -- material2.map.colorSpace = THREE.SRGBColorSpace; -+ material2.map!.colorSpace = THREE.SRGBColorSpace; - - meshes.push(new THREE.Mesh(geometry, material1)); - meshes.push(new THREE.Mesh(geometry, material2)); -diff --git a/examples-testing/examples/webgl_loader_texture_rgbm.ts b/examples-testing/examples/webgl_loader_texture_rgbm.ts -index a882cdbc..a7cbf3e0 100644 ---- a/examples-testing/examples/webgl_loader_texture_rgbm.ts -+++ b/examples-testing/examples/webgl_loader_texture_rgbm.ts -@@ -8,7 +8,7 @@ const params = { - exposure: 2.0, - }; - --let renderer, scene, camera; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.OrthographicCamera; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_texture_tga.ts b/examples-testing/examples/webgl_loader_texture_tga.ts -index c4f65b79..fd6bab07 100644 ---- a/examples-testing/examples/webgl_loader_texture_tga.ts -+++ b/examples-testing/examples/webgl_loader_texture_tga.ts -@@ -5,7 +5,7 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { TGALoader } from 'three/addons/loaders/TGALoader.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_texture_tiff.ts b/examples-testing/examples/webgl_loader_texture_tiff.ts -index f097774a..bb5b9d9d 100644 ---- a/examples-testing/examples/webgl_loader_texture_tiff.ts -+++ b/examples-testing/examples/webgl_loader_texture_tiff.ts -@@ -2,7 +2,7 @@ import * as THREE from 'three'; - - import { TIFFLoader } from 'three/addons/loaders/TIFFLoader.js'; - --let renderer, scene, camera; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_texture_ultrahdr.ts b/examples-testing/examples/webgl_loader_texture_ultrahdr.ts -index c8bce4bf..a28a7f00 100644 ---- a/examples-testing/examples/webgl_loader_texture_ultrahdr.ts -+++ b/examples-testing/examples/webgl_loader_texture_ultrahdr.ts -@@ -5,7 +5,14 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { UltraHDRLoader } from 'three/addons/loaders/UltraHDRLoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --const params = { -+const params: { -+ autoRotate: boolean; -+ metalness: number; -+ roughness: number; -+ exposure: number; -+ resolution: '2k' | '4k'; -+ type: 'HalfFloatType' | 'FloatType'; -+} = { - autoRotate: true, - metalness: 1.0, - roughness: 0.0, -@@ -14,7 +21,12 @@ const params = { - type: 'HalfFloatType', - }; - --let renderer, scene, camera, controls, torusMesh, loader; -+let renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ controls: OrbitControls, -+ torusMesh: THREE.Mesh, -+ loader: UltraHDRLoader; - - init(); - -@@ -45,7 +57,10 @@ function init() { - loader = new UltraHDRLoader(); - loader.setDataType(THREE.FloatType); - -- const loadEnvironment = function (resolution = '2k', type = 'HalfFloatType') { -+ const loadEnvironment = function ( -+ resolution: '2k' | '4k' = '2k', -+ type: 'HalfFloatType' | 'FloatType' = 'HalfFloatType', -+ ) { - loader.setDataType(THREE[type]); - - loader.load(`textures/equirectangular/spruit_sunrise_${resolution}.hdr.jpg`, function (texture) { -diff --git a/examples-testing/examples/webgl_loader_tilt.ts b/examples-testing/examples/webgl_loader_tilt.ts -index 843b3cfd..ea737c79 100644 ---- a/examples-testing/examples/webgl_loader_tilt.ts -+++ b/examples-testing/examples/webgl_loader_tilt.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { TiltLoader } from 'three/addons/loaders/TiltLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_ttf.ts b/examples-testing/examples/webgl_loader_ttf.ts -index 168371a1..073084f7 100644 ---- a/examples-testing/examples/webgl_loader_ttf.ts -+++ b/examples-testing/examples/webgl_loader_ttf.ts -@@ -4,9 +4,9 @@ import { TTFLoader } from 'three/addons/loaders/TTFLoader.js'; - import { Font } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - --let container; --let camera, cameraTarget, scene, renderer; --let group, textMesh1, textMesh2, textGeo, material; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, cameraTarget: THREE.Vector3, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let group: THREE.Group, textMesh1: THREE.Mesh, textMesh2: THREE.Mesh, textGeo, material: THREE.MeshPhongMaterial; - let firstLetter = true; - - let text = 'three.js'; -@@ -17,7 +17,7 @@ const depth = 20, - bevelThickness = 2, - bevelSize = 1.5; - --let font = null; -+let font: Font | null = null; - const mirror = true; - - let targetRotation = 0; -@@ -108,7 +108,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentKeyDown(event) { -+function onDocumentKeyDown(event: KeyboardEvent) { - if (firstLetter) { - firstLetter = false; - text = ''; -@@ -128,7 +128,7 @@ function onDocumentKeyDown(event) { - } - } - --function onDocumentKeyPress(event) { -+function onDocumentKeyPress(event: KeyboardEvent) { - const keyCode = event.which; - - // backspace -@@ -145,7 +145,7 @@ function onDocumentKeyPress(event) { - - function createText() { - textGeo = new TextGeometry(text, { -- font: font, -+ font: font!, - - size: size, - depth: depth, -@@ -159,7 +159,7 @@ function createText() { - textGeo.computeBoundingBox(); - textGeo.computeVertexNormals(); - -- const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); -+ const centerOffset = -0.5 * (textGeo.boundingBox!.max.x - textGeo.boundingBox!.min.x); - - textMesh1 = new THREE.Mesh(textGeo, material); - -@@ -195,7 +195,7 @@ function refreshText() { - createText(); - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; -@@ -205,7 +205,7 @@ function onPointerDown(event) { - document.addEventListener('pointerup', onPointerUp); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; -@@ -214,7 +214,7 @@ function onPointerMove(event) { - } - - function onPointerUp() { -- if (event.isPrimary === false) return; -+ if ((event as PointerEvent).isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); - document.removeEventListener('pointerup', onPointerUp); -diff --git a/examples-testing/examples/webgl_loader_usdz.ts b/examples-testing/examples/webgl_loader_usdz.ts -index d75823d8..cdd7c733 100644 ---- a/examples-testing/examples/webgl_loader_usdz.ts -+++ b/examples-testing/examples/webgl_loader_usdz.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { USDZLoader } from 'three/addons/loaders/USDZLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_vox.ts b/examples-testing/examples/webgl_loader_vox.ts -index 06184801..1f9629e0 100644 ---- a/examples-testing/examples/webgl_loader_vox.ts -+++ b/examples-testing/examples/webgl_loader_vox.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { VOXLoader, VOXMesh } from 'three/addons/loaders/VOXLoader.js'; - --let camera, controls, scene, renderer; -+let camera: THREE.PerspectiveCamera, controls: OrbitControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_vrml.ts b/examples-testing/examples/webgl_loader_vrml.ts -index fecf4bb4..a6093ead 100644 ---- a/examples-testing/examples/webgl_loader_vrml.ts -+++ b/examples-testing/examples/webgl_loader_vrml.ts -@@ -6,7 +6,12 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats, controls, loader; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ controls: OrbitControls, -+ loader: VRMLLoader; - - const params = { - asset: 'house', -@@ -29,7 +34,7 @@ const assets = [ - 'points', - ]; - --let vrmlScene; -+let vrmlScene: THREE.Scene; - - init(); - -@@ -82,9 +87,14 @@ function init() { - gui.add(params, 'asset', assets).onChange(function (value) { - if (vrmlScene) { - vrmlScene.traverse(function (object) { -- if (object.material) object.material.dispose(); -- if (object.material && object.material.map) object.material.map.dispose(); -- if (object.geometry) object.geometry.dispose(); -+ if ((object as THREE.Mesh).material) -+ (object as THREE.Mesh).material.dispose(); -+ if ( -+ (object as THREE.Mesh).material && -+ (object as THREE.Mesh).material.map -+ ) -+ (object as THREE.Mesh).material.map!.dispose(); -+ if ((object as THREE.Mesh).geometry) (object as THREE.Mesh).geometry.dispose(); - }); - - scene.remove(vrmlScene); -@@ -94,7 +104,7 @@ function init() { - }); - } - --function loadAsset(asset) { -+function loadAsset(asset: string) { - loader.load('models/vrml/' + asset + '.wrl', function (object) { - vrmlScene = object; - scene.add(object); -diff --git a/examples-testing/examples/webgl_loader_vtk.ts b/examples-testing/examples/webgl_loader_vtk.ts -index dfc79865..de6983fb 100644 ---- a/examples-testing/examples/webgl_loader_vtk.ts -+++ b/examples-testing/examples/webgl_loader_vtk.ts -@@ -5,9 +5,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import { VTKLoader } from 'three/addons/loaders/VTKLoader.js'; - --let stats; -+let stats: Stats; - --let camera, controls, scene, renderer; -+let camera: THREE.PerspectiveCamera, controls: TrackballControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_loader_xyz.ts b/examples-testing/examples/webgl_loader_xyz.ts -index 90e00984..61ef0cf1 100644 ---- a/examples-testing/examples/webgl_loader_xyz.ts -+++ b/examples-testing/examples/webgl_loader_xyz.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import { XYZLoader } from 'three/addons/loaders/XYZLoader.js'; - --let camera, scene, renderer, clock; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, clock: THREE.Clock; - --let points; -+let points: THREE.Points; - - init(); - -diff --git a/examples-testing/examples/webgl_lod.ts b/examples-testing/examples/webgl_lod.ts -index 0bb9e7be..bd1d0e46 100644 ---- a/examples-testing/examples/webgl_lod.ts -+++ b/examples-testing/examples/webgl_lod.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import { FlyControls } from 'three/addons/controls/FlyControls.js'; - --let container; -+let container: HTMLDivElement; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: FlyControls; - - const clock = new THREE.Clock(); - -@@ -28,7 +28,7 @@ function init() { - dirLight.position.set(0, 0, 1).normalize(); - scene.add(dirLight); - -- const geometry = [ -+ const geometry: [THREE.IcosahedronGeometry, number][] = [ - [new THREE.IcosahedronGeometry(100, 16), 50], - [new THREE.IcosahedronGeometry(100, 8), 300], - [new THREE.IcosahedronGeometry(100, 4), 1000], -diff --git a/examples-testing/examples/webgl_marchingcubes.ts b/examples-testing/examples/webgl_marchingcubes.ts -index d11df56a..ea05a705 100644 ---- a/examples-testing/examples/webgl_marchingcubes.ts -+++ b/examples-testing/examples/webgl_marchingcubes.ts -@@ -7,17 +7,42 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { MarchingCubes } from 'three/addons/objects/MarchingCubes.js'; - import { ToonShader1, ToonShader2, ToonShaderHatching, ToonShaderDotted } from 'three/addons/shaders/ToonShader.js'; - --let container, stats; -- --let camera, scene, renderer; -- --let materials, current_material; -- --let light, pointLight, ambientLight; -- --let effect, resolution; -- --let effectController; -+let container: HTMLElement, stats: Stats; -+ -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+ -+type Material = -+ | 'shiny' -+ | 'chrome' -+ | 'liquid' -+ | 'matte' -+ | 'flat' -+ | 'textured' -+ | 'colors' -+ | 'multiColors' -+ | 'plastic' -+ | 'toon1' -+ | 'toon2' -+ | 'hatching' -+ | 'dotted'; -+ -+let materials: { [M in Material]: THREE.Material }, current_material: Material; -+ -+let light: THREE.DirectionalLight, pointLight: THREE.PointLight, ambientLight: THREE.AmbientLight; -+ -+let effect: MarchingCubes, resolution: number; -+ -+let effectController: { -+ material: Material; -+ speed: number; -+ numBlobs: number; -+ resolution: number; -+ isolation: number; -+ floor: boolean; -+ wallx: boolean; -+ wallz: boolean; -+ dummy: () => void; -+} & { [M in Material]?: () => void }; - - let time = 0; - -@@ -26,7 +51,7 @@ const clock = new THREE.Clock(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // CAMERA - -@@ -164,7 +189,11 @@ function generateMaterials() { - return materials; - } - --function createShaderMaterial(shader, light, ambientLight) { -+function createShaderMaterial( -+ shader: { uniforms: Record; vertexShader: string; fragmentShader: string }, -+ light: THREE.DirectionalLight, -+ ambientLight: THREE.AmbientLight, -+) { - const u = THREE.UniformsUtils.clone(shader.uniforms); - - const vs = shader.vertexShader; -@@ -183,7 +212,7 @@ function createShaderMaterial(shader, light, ambientLight) { - // - - function setupGui() { -- const createHandler = function (id) { -+ const createHandler = function (id: Material) { - return function () { - current_material = id; - -@@ -217,8 +246,8 @@ function setupGui() { - h = gui.addFolder('Materials'); - - for (const m in materials) { -- effectController[m] = createHandler(m); -- h.add(effectController, m).name(m); -+ effectController[m as Material] = createHandler(m as Material); -+ h.add(effectController as Required, m as Material).name(m); - } - - // simulation -@@ -237,7 +266,14 @@ function setupGui() { - - // this controls content of marching cubes voxel field - --function updateCubes(object, time, numblobs, floor, wallx, wallz) { -+function updateCubes( -+ object: MarchingCubes, -+ time: number, -+ numblobs: number, -+ floor: boolean, -+ wallx: boolean, -+ wallz: boolean, -+) { - object.reset(); - - // fill the field with some metaballs -diff --git a/examples-testing/examples/webgl_materials_alphahash.ts b/examples-testing/examples/webgl_materials_alphahash.ts -index 1ecf95f2..2373eb7e 100644 ---- a/examples-testing/examples/webgl_materials_alphahash.ts -+++ b/examples-testing/examples/webgl_materials_alphahash.ts -@@ -10,9 +10,15 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, scene, renderer, controls, stats, mesh, material; -- --let composer, renderPass, taaRenderPass, outputPass; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ controls, -+ stats: Stats, -+ mesh: THREE.InstancedMesh, -+ material: THREE.MeshStandardMaterial; -+ -+let composer: EffectComposer, renderPass: RenderPass, taaRenderPass: TAARenderPass, outputPass: OutputPass; - - let needsUpdate = false; - -diff --git a/examples-testing/examples/webgl_materials_blending.ts b/examples-testing/examples/webgl_materials_blending.ts -index 11cc009b..7f7fd73c 100644 ---- a/examples-testing/examples/webgl_materials_blending.ts -+++ b/examples-testing/examples/webgl_materials_blending.ts -@@ -1,7 +1,7 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; --let mapBg; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let mapBg: THREE.CanvasTexture; - - const textureLoader = new THREE.TextureLoader(); - -@@ -20,7 +20,7 @@ function init() { - // BACKGROUND - - const canvas = document.createElement('canvas'); -- const ctx = canvas.getContext('2d'); -+ const ctx = canvas.getContext('2d')!; - canvas.width = canvas.height = 128; - ctx.fillStyle = '#ddd'; - ctx.fillRect(0, 0, 128, 128); -@@ -50,7 +50,7 @@ function init() { - { name: 'Multiply', constant: THREE.MultiplyBlending }, - ]; - -- const assignSRGB = texture => { -+ const assignSRGB = (texture: THREE.Texture) => { - texture.colorSpace = THREE.SRGBColorSpace; - }; - -@@ -69,7 +69,7 @@ function init() { - addImageRow(map3, -150); - addImageRow(map4, -300); - -- function addImageRow(map, y) { -+ function addImageRow(map: THREE.Texture, y: number) { - for (let i = 0; i < blendings.length; i++) { - const blending = blendings[i]; - -@@ -115,9 +115,9 @@ function onWindowResize() { - camera.updateProjectionMatrix(); - } - --function generateLabelMaterial(text) { -+function generateLabelMaterial(text: string) { - const canvas = document.createElement('canvas'); -- const ctx = canvas.getContext('2d'); -+ const ctx = canvas.getContext('2d')!; - canvas.width = 128; - canvas.height = 32; - -diff --git a/examples-testing/examples/webgl_materials_blending_custom.ts b/examples-testing/examples/webgl_materials_blending_custom.ts -index 07244742..62111971 100644 ---- a/examples-testing/examples/webgl_materials_blending_custom.ts -+++ b/examples-testing/examples/webgl_materials_blending_custom.ts -@@ -2,12 +2,12 @@ import * as THREE from 'three'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let mapBg; --const materials = []; -+let mapBg: THREE.CanvasTexture; -+const materials: THREE.Material[] = []; - --const params = { -+const params: { blendEquation: THREE.BlendingEquation } = { - blendEquation: THREE.AddEquation, - }; - -@@ -34,7 +34,7 @@ function init() { - // BACKGROUND - - const canvas = document.createElement('canvas'); -- const ctx = canvas.getContext('2d'); -+ const ctx = canvas.getContext('2d')!; - canvas.width = canvas.height = 128; - ctx.fillStyle = '#ddd'; - ctx.fillRect(0, 0, 128, 128); -@@ -177,9 +177,9 @@ function onWindowResize() { - - // - --function generateLabelMaterial(text, bg) { -+function generateLabelMaterial(text: string, bg: string) { - const canvas = document.createElement('canvas'); -- const ctx = canvas.getContext('2d'); -+ const ctx = canvas.getContext('2d')!; - canvas.width = 128; - canvas.height = 32; - -@@ -197,7 +197,7 @@ function generateLabelMaterial(text, bg) { - return material; - } - --function updateBlendEquation(value) { -+function updateBlendEquation(value: THREE.BlendingEquation) { - for (const material of materials) { - material.blendEquation = value; - } -diff --git a/examples-testing/examples/webgl_materials_bumpmap.ts b/examples-testing/examples/webgl_materials_bumpmap.ts -index d954fab7..73947a37 100644 ---- a/examples-testing/examples/webgl_materials_bumpmap.ts -+++ b/examples-testing/examples/webgl_materials_bumpmap.ts -@@ -4,13 +4,13 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let container, stats, loader; -+let container: HTMLDivElement, stats: Stats, loader: GLTFLoader; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let mesh; -+let mesh: THREE.Mesh; - --let spotLight; -+let spotLight: THREE.SpotLight; - - let mouseX = 0; - let mouseY = 0; -@@ -71,7 +71,7 @@ function init() { - - loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { -- createScene(gltf.scene.children[0].geometry, 1, material); -+ createScene((gltf.scene.children[0] as THREE.Mesh).geometry, 1, material); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); -@@ -93,7 +93,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function createScene(geometry, scale, material) { -+function createScene(geometry: THREE.BufferGeometry, scale: number, material: THREE.Material) { - mesh = new THREE.Mesh(geometry, material); - - mesh.position.y = -0.5; -@@ -114,7 +114,7 @@ function onWindowResize() { - camera.updateProjectionMatrix(); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_materials_car.ts b/examples-testing/examples/webgl_materials_car.ts -index e810f7b7..5f71ea26 100644 ---- a/examples-testing/examples/webgl_materials_car.ts -+++ b/examples-testing/examples/webgl_materials_car.ts -@@ -8,16 +8,16 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let camera, scene, renderer; --let stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let stats: Stats; - --let grid; --let controls; -+let grid: THREE.GridHelper; -+let controls: OrbitControls; - --const wheels = []; -+const wheels: THREE.Object3D[] = []; - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); -@@ -78,17 +78,17 @@ function init() { - transmission: 1.0, - }); - -- const bodyColorInput = document.getElementById('body-color'); -+ const bodyColorInput = document.getElementById('body-color') as HTMLInputElement; - bodyColorInput.addEventListener('input', function () { - bodyMaterial.color.set(this.value); - }); - -- const detailsColorInput = document.getElementById('details-color'); -+ const detailsColorInput = document.getElementById('details-color') as HTMLInputElement; - detailsColorInput.addEventListener('input', function () { - detailsMaterial.color.set(this.value); - }); - -- const glassColorInput = document.getElementById('glass-color'); -+ const glassColorInput = document.getElementById('glass-color') as HTMLInputElement; - glassColorInput.addEventListener('input', function () { - glassMaterial.color.set(this.value); - }); -@@ -106,21 +106,21 @@ function init() { - loader.load('models/gltf/ferrari.glb', function (gltf) { - const carModel = gltf.scene.children[0]; - -- carModel.getObjectByName('body').material = bodyMaterial; -+ (carModel.getObjectByName('body') as THREE.Mesh).material = bodyMaterial; - -- carModel.getObjectByName('rim_fl').material = detailsMaterial; -- carModel.getObjectByName('rim_fr').material = detailsMaterial; -- carModel.getObjectByName('rim_rr').material = detailsMaterial; -- carModel.getObjectByName('rim_rl').material = detailsMaterial; -- carModel.getObjectByName('trim').material = detailsMaterial; -+ (carModel.getObjectByName('rim_fl') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('rim_fr') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('rim_rr') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('rim_rl') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('trim') as THREE.Mesh).material = detailsMaterial; - -- carModel.getObjectByName('glass').material = glassMaterial; -+ (carModel.getObjectByName('glass') as THREE.Mesh).material = glassMaterial; - - wheels.push( -- carModel.getObjectByName('wheel_fl'), -- carModel.getObjectByName('wheel_fr'), -- carModel.getObjectByName('wheel_rl'), -- carModel.getObjectByName('wheel_rr'), -+ carModel.getObjectByName('wheel_fl')!, -+ carModel.getObjectByName('wheel_fr')!, -+ carModel.getObjectByName('wheel_rl')!, -+ carModel.getObjectByName('wheel_rr')!, - ); - - // shadow -diff --git a/examples-testing/examples/webgl_materials_cubemap.ts b/examples-testing/examples/webgl_materials_cubemap.ts -index 5f269275..87044a87 100644 ---- a/examples-testing/examples/webgl_materials_cubemap.ts -+++ b/examples-testing/examples/webgl_materials_cubemap.ts -@@ -5,9 +5,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let pointLight; - -@@ -65,7 +65,7 @@ function init() { - - objLoader.setPath('models/obj/walt/'); - objLoader.load('WaltHead.obj', function (object) { -- const head = object.children[0]; -+ const head = object.children[0] as THREE.Mesh; - head.scale.setScalar(0.1); - head.position.y = -3; - head.material = cubeMaterial1; -diff --git a/examples-testing/examples/webgl_materials_cubemap_dynamic.ts b/examples-testing/examples/webgl_materials_cubemap_dynamic.ts -index 13a26890..8b84f71a 100644 ---- a/examples-testing/examples/webgl_materials_cubemap_dynamic.ts -+++ b/examples-testing/examples/webgl_materials_cubemap_dynamic.ts -@@ -6,12 +6,12 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats; --let cube, sphere, torus, material; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; -+let cube: THREE.Mesh, sphere: THREE.Mesh, torus: THREE.Mesh, material: THREE.MeshStandardMaterial; - --let cubeCamera, cubeRenderTarget; -+let cubeCamera: THREE.CubeCamera, cubeRenderTarget: THREE.WebGLCubeRenderTarget; - --let controls; -+let controls: OrbitControls; - - init(); - -@@ -88,7 +88,7 @@ function onWindowResized() { - camera.updateProjectionMatrix(); - } - --function animate(msTime) { -+function animate(msTime: DOMHighResTimeStamp) { - const time = msTime / 1000; - - cube.position.x = Math.cos(time) * 30; -diff --git a/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts b/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts -index 944f4c18..21010ffa 100644 ---- a/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts -+++ b/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container; -+let container: HTMLDivElement; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -12,11 +12,11 @@ init(); - async function loadCubeTextureWithMipmaps() { - const path = 'textures/cube/angus/'; - const format = '.jpg'; -- const mipmaps = []; -+ const mipmaps: THREE.CubeTexture[] = []; - const maxLevel = 8; - -- async function loadCubeTexture(urls) { -- return new Promise(function (resolve) { -+ async function loadCubeTexture(urls: string[]) { -+ return new Promise(function (resolve) { - new THREE.CubeTextureLoader().load(urls, function (cubeTexture) { - resolve(cubeTexture); - }); -@@ -44,7 +44,7 @@ async function loadCubeTextureWithMipmaps() { - - await Promise.all(pendings); - -- const customizedCubeTexture = mipmaps.shift(); -+ const customizedCubeTexture = mipmaps.shift()!; - customizedCubeTexture.mipmaps = mipmaps; - customizedCubeTexture.colorSpace = THREE.SRGBColorSpace; - customizedCubeTexture.minFilter = THREE.LinearMipMapLinearFilter; -diff --git a/examples-testing/examples/webgl_materials_cubemap_refraction.ts b/examples-testing/examples/webgl_materials_cubemap_refraction.ts -index 8c025071..a47c4832 100644 ---- a/examples-testing/examples/webgl_materials_cubemap_refraction.ts -+++ b/examples-testing/examples/webgl_materials_cubemap_refraction.ts -@@ -4,9 +4,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mouseX = 0, - mouseY = 0; -@@ -84,7 +84,12 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function createScene(geometry, m1, m2, m3) { -+function createScene( -+ geometry: THREE.BufferGeometry, -+ m1: THREE.MeshPhongMaterial, -+ m2: THREE.MeshPhongMaterial, -+ m3: THREE.MeshPhongMaterial, -+) { - geometry.computeVertexNormals(); - - const s = 1.5; -@@ -104,7 +109,7 @@ function createScene(geometry, m1, m2, m3) { - scene.add(mesh); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = (event.clientX - windowHalfX) * 4; - mouseY = (event.clientY - windowHalfY) * 4; - } -diff --git a/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts b/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts -index 599a1369..a23a0582 100644 ---- a/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts -+++ b/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts -@@ -1,8 +1,8 @@ - import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container; --let camera, scene, renderer; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - const CubemapFilterShader = { - name: 'CubemapFilterShader', -@@ -55,15 +55,15 @@ const CubemapFilterShader = { - - init(); - --async function loadCubeTexture(urls) { -- return new Promise(function (resolve) { -+async function loadCubeTexture(urls: string[]) { -+ return new Promise(function (resolve) { - new THREE.CubeTextureLoader().load(urls, function (cubeTexture) { - resolve(cubeTexture); - }); - }); - } - --function allocateCubemapRenderTarget(cubeMapSize) { -+function allocateCubemapRenderTarget(cubeMapSize: number) { - const params = { - magFilter: THREE.LinearFilter, - minFilter: THREE.LinearMipMapLinearFilter, -@@ -77,13 +77,13 @@ function allocateCubemapRenderTarget(cubeMapSize) { - const rt = new THREE.WebGLCubeRenderTarget(cubeMapSize, params); - - const mipLevels = Math.log(cubeMapSize) * Math.LOG2E + 1.0; -- for (let i = 0; i < mipLevels; i++) rt.texture.mipmaps.push({}); -+ for (let i = 0; i < mipLevels; i++) (rt.texture.mipmaps as THREE.CubeTexture[]).push({} as THREE.CubeTexture); - - rt.texture.mapping = THREE.CubeReflectionMapping; - return rt; - } - --function renderToCubeTexture(cubeMapRenderTarget, sourceCubeTexture) { -+function renderToCubeTexture(cubeMapRenderTarget: THREE.WebGLCubeRenderTarget, sourceCubeTexture: THREE.CubeTexture) { - const geometry = new THREE.BoxGeometry(5, 5, 5); - - const material = new THREE.ShaderMaterial({ -diff --git a/examples-testing/examples/webgl_materials_displacementmap.ts b/examples-testing/examples/webgl_materials_displacementmap.ts -index fd0be9a5..9b08fe73 100644 ---- a/examples-testing/examples/webgl_materials_displacementmap.ts -+++ b/examples-testing/examples/webgl_materials_displacementmap.ts -@@ -6,8 +6,8 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - --let stats; --let camera, scene, renderer, controls; -+let stats: Stats; -+let camera: THREE.OrthographicCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: OrbitControls; - - const settings = { - metalness: 1.0, -@@ -19,9 +19,9 @@ const settings = { - normalScale: 1.0, - }; - --let mesh, material; -+let mesh, material: THREE.MeshStandardMaterial; - --let pointLight, ambientLight; -+let pointLight: THREE.PointLight, ambientLight: THREE.AmbientLight; - - const height = 500; // of camera frustum - -@@ -173,7 +173,7 @@ function init() { - - const loader = new OBJLoader(); - loader.load('models/obj/ninja/ninjaHead_Low.obj', function (group) { -- const geometry = group.children[0].geometry; -+ const geometry = (group.children[0] as THREE.Mesh).geometry; - geometry.center(); - - mesh = new THREE.Mesh(geometry, material); -diff --git a/examples-testing/examples/webgl_materials_envmaps.ts b/examples-testing/examples/webgl_materials_envmaps.ts -index 18a5542e..13fe2efc 100644 ---- a/examples-testing/examples/webgl_materials_envmaps.ts -+++ b/examples-testing/examples/webgl_materials_envmaps.ts -@@ -3,9 +3,19 @@ import * as THREE from 'three'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let controls, camera, scene, renderer; --let textureEquirec, textureCube; --let sphereMesh, sphereMaterial, params; -+let controls: OrbitControls, camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let textureEquirec: THREE.Texture, textureCube: THREE.CubeTexture; -+let sphereMesh: THREE.Mesh, -+ sphereMaterial: THREE.MeshBasicMaterial, -+ params: { -+ Cube: () => void; -+ Equirectangular: () => void; -+ Refraction: boolean; -+ backgroundRotationX: boolean; -+ backgroundRotationY: boolean; -+ backgroundRotationZ: boolean; -+ syncMaterial: boolean; -+ }; - - init(); - -diff --git a/examples-testing/examples/webgl_materials_envmaps_exr.ts b/examples-testing/examples/webgl_materials_envmaps_exr.ts -index c3f3f4f7..4ae4cb95 100644 ---- a/examples-testing/examples/webgl_materials_envmaps_exr.ts -+++ b/examples-testing/examples/webgl_materials_envmaps_exr.ts -@@ -14,11 +14,12 @@ const params = { - debug: false, - }; - --let container, stats; --let camera, scene, renderer, controls; --let torusMesh, planeMesh; --let pngCubeRenderTarget, exrCubeRenderTarget; --let pngBackground, exrBackground; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: OrbitControls; -+let torusMesh: THREE.Mesh, -+ planeMesh: THREE.Mesh; -+let pngCubeRenderTarget: THREE.WebGLRenderTarget, exrCubeRenderTarget: THREE.WebGLRenderTarget; -+let pngBackground: THREE.Texture, exrBackground: THREE.DataTexture; - - init(); - -@@ -42,8 +43,8 @@ function init() { - - // - -- let geometry = new THREE.TorusKnotGeometry(18, 8, 150, 20); -- let material = new THREE.MeshStandardMaterial({ -+ let geometry: THREE.BufferGeometry = new THREE.TorusKnotGeometry(18, 8, 150, 20); -+ let material: THREE.MeshStandardMaterial | THREE.MeshBasicMaterial = new THREE.MeshStandardMaterial({ - metalness: params.metalness, - roughness: params.roughness, - envMapIntensity: 1.0, -diff --git a/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts b/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts -index 48e0077f..09c67188 100644 ---- a/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts -+++ b/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts -@@ -13,7 +13,7 @@ const params = { - enabled: true, - }; - --let camera, scene, renderer, skybox; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, skybox: GroundedSkybox; - - init().then(render); - -@@ -68,15 +68,15 @@ async function init() { - carModel.scale.multiplyScalar(4); - carModel.rotation.y = Math.PI; - -- carModel.getObjectByName('body').material = bodyMaterial; -+ (carModel.getObjectByName('body') as THREE.Mesh).material = bodyMaterial; - -- carModel.getObjectByName('rim_fl').material = detailsMaterial; -- carModel.getObjectByName('rim_fr').material = detailsMaterial; -- carModel.getObjectByName('rim_rr').material = detailsMaterial; -- carModel.getObjectByName('rim_rl').material = detailsMaterial; -- carModel.getObjectByName('trim').material = detailsMaterial; -+ (carModel.getObjectByName('rim_fl') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('rim_fr') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('rim_rr') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('rim_rl') as THREE.Mesh).material = detailsMaterial; -+ (carModel.getObjectByName('trim') as THREE.Mesh).material = detailsMaterial; - -- carModel.getObjectByName('glass').material = glassMaterial; -+ (carModel.getObjectByName('glass') as THREE.Mesh).material = glassMaterial; - - // shadow - const mesh = new THREE.Mesh( -diff --git a/examples-testing/examples/webgl_materials_envmaps_hdr.ts b/examples-testing/examples/webgl_materials_envmaps_hdr.ts -index b4c6f64e..48b6c01c 100644 ---- a/examples-testing/examples/webgl_materials_envmaps_hdr.ts -+++ b/examples-testing/examples/webgl_materials_envmaps_hdr.ts -@@ -8,7 +8,13 @@ import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader. - import { RGBMLoader } from 'three/addons/loaders/RGBMLoader.js'; - import { DebugEnvironment } from 'three/addons/environments/DebugEnvironment.js'; - --const params = { -+const params: { -+ envMap: 'Generated' | 'LDR' | 'HDR' | 'RGBM16'; -+ roughness: number; -+ metalness: number; -+ exposure: number; -+ debug: boolean; -+} = { - envMap: 'HDR', - roughness: 0.0, - metalness: 0.0, -@@ -16,11 +22,15 @@ const params = { - debug: false, - }; - --let container, stats; --let camera, scene, renderer, controls; --let torusMesh, planeMesh; --let generatedCubeRenderTarget, ldrCubeRenderTarget, hdrCubeRenderTarget, rgbmCubeRenderTarget; --let ldrCubeMap, hdrCubeMap, rgbmCubeMap; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: OrbitControls; -+let torusMesh: THREE.Mesh, -+ planeMesh: THREE.Mesh; -+let generatedCubeRenderTarget: THREE.WebGLRenderTarget, -+ ldrCubeRenderTarget: THREE.WebGLRenderTarget, -+ hdrCubeRenderTarget: THREE.WebGLRenderTarget, -+ rgbmCubeRenderTarget: THREE.WebGLRenderTarget; -+let ldrCubeMap: THREE.CubeTexture, hdrCubeMap: THREE.CubeTexture, rgbmCubeMap: THREE.CubeTexture; - - init(); - -@@ -39,9 +49,9 @@ function init() { - - // - -- let geometry = new THREE.TorusKnotGeometry(18, 8, 150, 20); -+ let geometry: THREE.BufferGeometry = new THREE.TorusKnotGeometry(18, 8, 150, 20); - // let geometry = new THREE.SphereGeometry( 26, 64, 32 ); -- let material = new THREE.MeshStandardMaterial({ -+ let material: THREE.MeshStandardMaterial | THREE.MeshBasicMaterial = new THREE.MeshStandardMaterial({ - color: 0xffffff, - metalness: params.metalness, - roughness: params.roughness, -diff --git a/examples-testing/examples/webgl_materials_modified.ts b/examples-testing/examples/webgl_materials_modified.ts -index c6ee5af3..a1a808a7 100644 ---- a/examples-testing/examples/webgl_materials_modified.ts -+++ b/examples-testing/examples/webgl_materials_modified.ts -@@ -5,7 +5,7 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - init(); - -@@ -17,7 +17,7 @@ function init() { - - const loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { -- const geometry = gltf.scene.children[0].geometry; -+ const geometry = (gltf.scene.children[0] as THREE.Mesh).geometry; - - let mesh = new THREE.Mesh(geometry, buildTwistMaterial(2.0)); - mesh.position.x = -3.5; -@@ -50,7 +50,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function buildTwistMaterial(amount) { -+function buildTwistMaterial(amount: number) { - const material = new THREE.MeshNormalMaterial(); - material.onBeforeCompile = function (shader) { - shader.uniforms.time = { value: 0 }; -@@ -102,8 +102,8 @@ function animate() { - - function render() { - scene.traverse(function (child) { -- if (child.isMesh) { -- const shader = child.material.userData.shader; -+ if ((child as THREE.Mesh).isMesh) { -+ const shader = ((child as THREE.Mesh).material as THREE.Material).userData.shader; - - if (shader) { - shader.uniforms.time.value = performance.now() / 1000; -diff --git a/examples-testing/examples/webgl_materials_normalmap_object_space.ts b/examples-testing/examples/webgl_materials_normalmap_object_space.ts -index 1fc6f806..72108134 100644 ---- a/examples-testing/examples/webgl_materials_normalmap_object_space.ts -+++ b/examples-testing/examples/webgl_materials_normalmap_object_space.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let renderer, scene, camera; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; - - init(); - -@@ -38,19 +38,23 @@ function init() { - // model - new GLTFLoader().load('models/gltf/Nefertiti/Nefertiti.glb', function (gltf) { - gltf.scene.traverse(function (child) { -- if (child.isMesh) { -+ if ((child as THREE.Mesh).isMesh) { - // glTF currently supports only tangent-space normal maps. - // this model has been modified to demonstrate the use of an object-space normal map. - -- child.material.normalMapType = THREE.ObjectSpaceNormalMap; -+ (child as THREE.Mesh).material.normalMapType = -+ THREE.ObjectSpaceNormalMap; - - // attribute normals are not required with an object-space normal map. remove them. - -- child.geometry.deleteAttribute('normal'); -+ (child as THREE.Mesh).geometry.deleteAttribute( -+ 'normal', -+ ); - - // - -- child.material.side = THREE.DoubleSide; -+ (child as THREE.Mesh).material.side = -+ THREE.DoubleSide; - - child.scale.multiplyScalar(0.5); - -diff --git a/examples-testing/examples/webgl_materials_physical_clearcoat.ts b/examples-testing/examples/webgl_materials_physical_clearcoat.ts -index 408fd992..dc782ea9 100644 ---- a/examples-testing/examples/webgl_materials_physical_clearcoat.ts -+++ b/examples-testing/examples/webgl_materials_physical_clearcoat.ts -@@ -7,12 +7,12 @@ import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader. - - import { FlakesTexture } from 'three/addons/textures/FlakesTexture.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let particleLight; --let group; -+let particleLight: THREE.Mesh; -+let group: THREE.Group; - - init(); - -diff --git a/examples-testing/examples/webgl_materials_physical_transmission.ts b/examples-testing/examples/webgl_materials_physical_transmission.ts -index d4596797..6464232e 100644 ---- a/examples-testing/examples/webgl_materials_physical_transmission.ts -+++ b/examples-testing/examples/webgl_materials_physical_transmission.ts -@@ -19,7 +19,7 @@ const params = { - exposure: 1, - }; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mesh; - -@@ -170,7 +170,7 @@ function generateTexture() { - canvas.width = 2; - canvas.height = 2; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - context.fillStyle = 'white'; - context.fillRect(0, 1, 2, 1); - -diff --git a/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts b/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts -index d81f59c3..1e194ce8 100644 ---- a/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts -+++ b/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts -@@ -22,17 +22,20 @@ const params = { - exposure: 1, - }; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let mesh, material; -+let mesh: THREE.Mesh, material: THREE.MeshPhysicalMaterial; - - const hdrEquirect = new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function () { - hdrEquirect.mapping = THREE.EquirectangularReflectionMapping; - - new GLTFLoader().setPath('models/gltf/').load('DragonAttenuation.glb', function (gltf) { - gltf.scene.traverse(function (child) { -- if (child.isMesh && child.material.isMeshPhysicalMaterial) { -- mesh = child; -+ if ( -+ (child as THREE.Mesh).isMesh && -+ (child as THREE.Mesh).material.isMeshPhysicalMaterial -+ ) { -+ mesh = child as THREE.Mesh; - material = mesh.material; - - const color = new THREE.Color(); -@@ -74,7 +77,7 @@ function init() { - - // accommodate CSS table - renderer.domElement.style.position = 'absolute'; -- renderer.domElement.style.top = 0; -+ renderer.domElement.style.top = '0'; - - scene = new THREE.Scene(); - -diff --git a/examples-testing/examples/webgl_materials_texture_anisotropy.ts b/examples-testing/examples/webgl_materials_texture_anisotropy.ts -index 1e030d64..65577721 100644 ---- a/examples-testing/examples/webgl_materials_texture_anisotropy.ts -+++ b/examples-testing/examples/webgl_materials_texture_anisotropy.ts -@@ -5,9 +5,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - const SCREEN_WIDTH = window.innerWidth; - const SCREEN_HEIGHT = window.innerHeight; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene1, scene2, renderer; -+let camera: THREE.PerspectiveCamera, scene1: THREE.Scene, scene2: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mouseX = 0, - mouseY = 0; -@@ -70,11 +70,11 @@ function init() { - texture2.repeat.set(512, 512); - - if (maxAnisotropy > 0) { -- document.getElementById('val_left').innerHTML = texture1.anisotropy; -- document.getElementById('val_right').innerHTML = texture2.anisotropy; -+ document.getElementById('val_left')!.innerHTML = texture1.anisotropy.toString(); -+ document.getElementById('val_right')!.innerHTML = texture2.anisotropy.toString(); - } else { -- document.getElementById('val_left').innerHTML = 'not supported'; -- document.getElementById('val_right').innerHTML = 'not supported'; -+ document.getElementById('val_left')!.innerHTML = 'not supported'; -+ document.getElementById('val_right')!.innerHTML = 'not supported'; - } - - // -@@ -110,7 +110,7 @@ function init() { - document.addEventListener('mousemove', onDocumentMouseMove); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_materials_texture_canvas.ts b/examples-testing/examples/webgl_materials_texture_canvas.ts -index d23c6843..5a190fab 100644 ---- a/examples-testing/examples/webgl_materials_texture_canvas.ts -+++ b/examples-testing/examples/webgl_materials_texture_canvas.ts -@@ -1,6 +1,10 @@ - import * as THREE from 'three'; - --let camera, scene, renderer, mesh, material; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ mesh: THREE.Mesh, -+ material: THREE.MeshBasicMaterial; - const drawStartPos = new THREE.Vector2(); - - init(); -@@ -31,8 +35,8 @@ function init() { - function setupCanvasDrawing() { - // get canvas and context - -- const drawingCanvas = document.getElementById('drawing-canvas'); -- const drawingContext = drawingCanvas.getContext('2d'); -+ const drawingCanvas = document.getElementById('drawing-canvas') as HTMLCanvasElement; -+ const drawingContext = drawingCanvas.getContext('2d')!; - - // draw white background - -@@ -66,7 +70,7 @@ function setupCanvasDrawing() { - }); - } - --function draw(drawContext, x, y) { -+function draw(drawContext: CanvasRenderingContext2D, x: number, y: number) { - drawContext.moveTo(drawStartPos.x, drawStartPos.y); - drawContext.strokeStyle = '#000000'; - drawContext.lineTo(x, y); -@@ -74,7 +78,7 @@ function draw(drawContext, x, y) { - // reset drawing start position to current position. - drawStartPos.set(x, y); - // need to flag the map as needing updating. -- material.map.needsUpdate = true; -+ material.map!.needsUpdate = true; - } - - function onWindowResize() { -diff --git a/examples-testing/examples/webgl_materials_texture_filters.ts b/examples-testing/examples/webgl_materials_texture_filters.ts -index 178c2ce4..fb67cabe 100644 ---- a/examples-testing/examples/webgl_materials_texture_filters.ts -+++ b/examples-testing/examples/webgl_materials_texture_filters.ts -@@ -3,9 +3,9 @@ import * as THREE from 'three'; - const SCREEN_WIDTH = window.innerWidth; - const SCREEN_HEIGHT = window.innerHeight; - --let container; -+let container: HTMLDivElement; - --let camera, scene, scene2, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, scene2: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mouseX = 0, - mouseY = 0; -@@ -33,7 +33,7 @@ function init() { - // GROUND - - const imageCanvas = document.createElement('canvas'); -- const context = imageCanvas.getContext('2d'); -+ const context = imageCanvas.getContext('2d')!; - - imageCanvas.width = imageCanvas.height = 128; - -@@ -85,7 +85,7 @@ function init() { - addPainting(scene, mesh); - addPainting(scene2, mesh2); - -- function addPainting(zscene, zmesh) { -+ function addPainting(zscene: THREE.Scene, zmesh: THREE.Mesh) { - zmesh.scale.x = image.width / 100; - zmesh.scale.y = image.height / 100; - -@@ -140,7 +140,7 @@ function init() { - document.addEventListener('mousemove', onDocumentMouseMove); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_materials_texture_manualmipmap.ts b/examples-testing/examples/webgl_materials_texture_manualmipmap.ts -index 24bd4eb9..2dad75e8 100644 ---- a/examples-testing/examples/webgl_materials_texture_manualmipmap.ts -+++ b/examples-testing/examples/webgl_materials_texture_manualmipmap.ts -@@ -3,9 +3,9 @@ import * as THREE from 'three'; - const SCREEN_WIDTH = window.innerWidth; - const SCREEN_HEIGHT = window.innerHeight; - --let container; -+let container: HTMLDivElement; - --let camera, scene1, scene2, renderer; -+let camera: THREE.PerspectiveCamera, scene1: THREE.Scene, scene2: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mouseX = 0, - mouseY = 0; -@@ -32,9 +32,9 @@ function init() { - - // GROUND - -- function mipmap(size, color) { -+ function mipmap(size: number, color: string) { - const imageCanvas = document.createElement('canvas'); -- const context = imageCanvas.getContext('2d'); -+ const context = imageCanvas.getContext('2d')!; - - imageCanvas.width = imageCanvas.height = size; - -@@ -49,14 +49,14 @@ function init() { - - const canvas = mipmap(128, '#f00'); - const textureCanvas1 = new THREE.CanvasTexture(canvas); -- textureCanvas1.mipmaps[0] = canvas; -- textureCanvas1.mipmaps[1] = mipmap(64, '#0f0'); -- textureCanvas1.mipmaps[2] = mipmap(32, '#00f'); -- textureCanvas1.mipmaps[3] = mipmap(16, '#400'); -- textureCanvas1.mipmaps[4] = mipmap(8, '#040'); -- textureCanvas1.mipmaps[5] = mipmap(4, '#004'); -- textureCanvas1.mipmaps[6] = mipmap(2, '#044'); -- textureCanvas1.mipmaps[7] = mipmap(1, '#404'); -+ textureCanvas1.mipmaps![0] = canvas; -+ textureCanvas1.mipmaps![1] = mipmap(64, '#0f0'); -+ textureCanvas1.mipmaps![2] = mipmap(32, '#00f'); -+ textureCanvas1.mipmaps![3] = mipmap(16, '#400'); -+ textureCanvas1.mipmaps![4] = mipmap(8, '#040'); -+ textureCanvas1.mipmaps![5] = mipmap(4, '#004'); -+ textureCanvas1.mipmaps![6] = mipmap(2, '#044'); -+ textureCanvas1.mipmaps![7] = mipmap(1, '#404'); - textureCanvas1.colorSpace = THREE.SRGBColorSpace; - textureCanvas1.repeat.set(1000, 1000); - textureCanvas1.wrapS = THREE.RepeatWrapping; -@@ -97,7 +97,7 @@ function init() { - addPainting(scene1, mesh1); - addPainting(scene2, mesh2); - -- function addPainting(zscene, zmesh) { -+ function addPainting(zscene: THREE.Scene, zmesh: THREE.Mesh) { - zmesh.scale.x = image.width / 100; - zmesh.scale.y = image.height / 100; - -@@ -151,7 +151,7 @@ function init() { - document.addEventListener('mousemove', onDocumentMouseMove); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_materials_texture_partialupdate.ts b/examples-testing/examples/webgl_materials_texture_partialupdate.ts -index 5adfc8e6..55d802e3 100644 ---- a/examples-testing/examples/webgl_materials_texture_partialupdate.ts -+++ b/examples-testing/examples/webgl_materials_texture_partialupdate.ts -@@ -1,6 +1,11 @@ - import * as THREE from 'three'; - --let camera, scene, renderer, clock, dataTexture, diffuseMap; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ clock: THREE.Clock, -+ dataTexture: THREE.DataTexture, -+ diffuseMap: THREE.Texture; - - let last = 0; - const position = new THREE.Vector2(); -@@ -77,7 +82,7 @@ function animate() { - renderer.render(scene, camera); - } - --function updateDataTexture(texture) { -+function updateDataTexture(texture: THREE.DataTexture) { - const size = texture.image.width * texture.image.height; - const data = texture.image.data; - -diff --git a/examples-testing/examples/webgl_materials_texture_rotation.ts b/examples-testing/examples/webgl_materials_texture_rotation.ts -index 2666d09d..b284d9ff 100644 ---- a/examples-testing/examples/webgl_materials_texture_rotation.ts -+++ b/examples-testing/examples/webgl_materials_texture_rotation.ts -@@ -3,7 +3,10 @@ import * as THREE from 'three'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let mesh, renderer, scene, camera; -+let mesh: THREE.Mesh, -+ renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera; - - let gui; - -@@ -76,7 +79,7 @@ function onWindowResize() { - } - - function updateUvTransform() { -- const texture = mesh.material.map; -+ const texture = mesh.material.map!; - - if (texture.matrixAutoUpdate === true) { - texture.offset.set(API.offsetX, API.offsetY); -diff --git a/examples-testing/examples/webgl_materials_toon.ts b/examples-testing/examples/webgl_materials_toon.ts -index 03db286a..883244f5 100644 ---- a/examples-testing/examples/webgl_materials_toon.ts -+++ b/examples-testing/examples/webgl_materials_toon.ts -@@ -4,20 +4,20 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { OutlineEffect } from 'three/addons/effects/OutlineEffect.js'; --import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -+import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer, effect; --let particleLight; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, effect: OutlineEffect; -+let particleLight: THREE.Mesh; - - const loader = new FontLoader(); - loader.load('fonts/gentilis_regular.typeface.json', function (font) { - init(font); - }); - --function init(font) { -+function init(font: Font) { - container = document.createElement('div'); - document.body.appendChild(container); - -@@ -79,7 +79,7 @@ function init(font) { - } - } - -- function addLabel(name, location) { -+ function addLabel(name: string, location: THREE.Vector3) { - const textGeo = new TextGeometry(name, { - font: font, - -diff --git a/examples-testing/examples/webgl_materials_video.ts b/examples-testing/examples/webgl_materials_video.ts -index 4f0d26a1..0bf378c5 100644 ---- a/examples-testing/examples/webgl_materials_video.ts -+++ b/examples-testing/examples/webgl_materials_video.ts -@@ -5,13 +5,16 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let container; -+let container: HTMLDivElement; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let video, texture, material, mesh; -+let video, -+ texture, -+ material: THREE.MeshLambertMaterial & { hue?: number; saturation?: number }, -+ mesh: THREE.Mesh & { dx?: number; dy?: number }; - --let composer; -+let composer: EffectComposer; - - let mouseX = 0; - let mouseY = 0; -@@ -19,20 +22,20 @@ let mouseY = 0; - let windowHalfX = window.innerWidth / 2; - let windowHalfY = window.innerHeight / 2; - --let cube_count; -+let cube_count: number; - --const meshes = [], -- materials = [], -+const meshes: THREE.Mesh[] = [], -+ materials: (THREE.MeshLambertMaterial & { hue?: number; saturation?: number })[] = [], - xgrid = 20, - ygrid = 10; - --const startButton = document.getElementById('startButton'); -+const startButton = document.getElementById('startButton')!; - startButton.addEventListener('click', function () { - init(); - }); - - function init() { -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - - container = document.createElement('div'); -@@ -53,7 +56,7 @@ function init() { - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - -- video = document.getElementById('video'); -+ video = document.getElementById('video') as HTMLVideoElement; - video.play(); - video.addEventListener('play', function () { - this.currentTime = 3; -@@ -145,7 +148,7 @@ function onWindowResize() { - composer.setSize(window.innerWidth, window.innerHeight); - } - --function change_uvs(geometry, unitx, unity, offsetx, offsety) { -+function change_uvs(geometry: THREE.BoxGeometry, unitx: number, unity: number, offsetx: number, offsety: number) { - const uvs = geometry.attributes.uv.array; - - for (let i = 0; i < uvs.length; i += 2) { -@@ -154,7 +157,7 @@ function change_uvs(geometry, unitx, unity, offsetx, offsety) { - } - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = (event.clientY - windowHalfY) * 0.3; - } -@@ -175,20 +178,20 @@ function animate() { - for (let i = 0; i < cube_count; i++) { - material = materials[i]; - -- h = ((360 * (material.hue + time)) % 360) / 360; -- material.color.setHSL(h, material.saturation, 0.5); -+ h = ((360 * (material.hue! + time)) % 360) / 360; -+ material.color.setHSL(h, material.saturation!, 0.5); - } - - if (counter % 1000 > 200) { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - -- mesh.rotation.x += 10 * mesh.dx; -- mesh.rotation.y += 10 * mesh.dy; -+ mesh.rotation.x += 10 * mesh.dx!; -+ mesh.rotation.y += 10 * mesh.dy!; - -- mesh.position.x -= 150 * mesh.dx; -- mesh.position.y += 150 * mesh.dy; -- mesh.position.z += 300 * mesh.dx; -+ mesh.position.x -= 150 * mesh.dx!; -+ mesh.position.y += 150 * mesh.dy!; -+ mesh.position.z += 300 * mesh.dx!; - } - } - -@@ -196,8 +199,8 @@ function animate() { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - -- mesh.dx *= -1; -- mesh.dy *= -1; -+ mesh.dx! *= -1; -+ mesh.dy! *= -1; - } - } - -diff --git a/examples-testing/examples/webgl_materials_video_webcam.ts b/examples-testing/examples/webgl_materials_video_webcam.ts -index cf6f8d50..00b48c16 100644 ---- a/examples-testing/examples/webgl_materials_video_webcam.ts -+++ b/examples-testing/examples/webgl_materials_video_webcam.ts -@@ -2,7 +2,7 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, video; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, video: HTMLVideoElement; - - init(); - -@@ -12,7 +12,7 @@ function init() { - - scene = new THREE.Scene(); - -- video = document.getElementById('video'); -+ video = document.getElementById('video') as HTMLVideoElement; - - const texture = new THREE.VideoTexture(video); - texture.colorSpace = THREE.SRGBColorSpace; -diff --git a/examples-testing/examples/webgl_materials_wireframe.ts b/examples-testing/examples/webgl_materials_wireframe.ts -index 8adbd71d..6424e8cb 100644 ---- a/examples-testing/examples/webgl_materials_wireframe.ts -+++ b/examples-testing/examples/webgl_materials_wireframe.ts -@@ -8,7 +8,10 @@ const API = { - thickness: 1, - }; - --let renderer, scene, camera, mesh2; -+let renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ mesh2: THREE.Mesh; - - init(); - -@@ -50,8 +53,8 @@ function init() { - - const material2 = new THREE.ShaderMaterial({ - uniforms: { thickness: { value: API.thickness } }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - side: THREE.DoubleSide, - alphaToCoverage: true, // only works when WebGLRenderer's "antialias" is set to "true" - }); -@@ -82,7 +85,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function setupAttributes(geometry) { -+function setupAttributes(geometry: THREE.BufferGeometry) { - const vectors = [new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 1)]; - - const position = geometry.attributes.position; -diff --git a/examples-testing/examples/webgl_math_obb.ts b/examples-testing/examples/webgl_math_obb.ts -index 48480d10..97a81a97 100644 ---- a/examples-testing/examples/webgl_math_obb.ts -+++ b/examples-testing/examples/webgl_math_obb.ts -@@ -5,9 +5,16 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, clock, controls, stats, raycaster, hitbox; -- --const objects = [], -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ clock: THREE.Clock, -+ controls: OrbitControls, -+ stats: Stats, -+ raycaster: THREE.Raycaster, -+ hitbox: THREE.Mesh; -+ -+const objects: THREE.Mesh[] = [], - mouse = new THREE.Vector2(); - - init(); -@@ -89,7 +96,7 @@ function init() { - document.addEventListener('click', onClick); - } - --function onClick(event) { -+function onClick(event: MouseEvent) { - event.preventDefault(); - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; -@@ -125,7 +132,10 @@ function onClick(event) { - } - } - --function sortIntersections(a, b) { -+function sortIntersections( -+ a: { distance: number; object: THREE.Mesh }, -+ b: { distance: number; object: THREE.Mesh }, -+) { - return a.distance - b.distance; - } - -diff --git a/examples-testing/examples/webgl_math_orientation_transform.ts b/examples-testing/examples/webgl_math_orientation_transform.ts -index 99be247d..2ff2bca4 100644 ---- a/examples-testing/examples/webgl_math_orientation_transform.ts -+++ b/examples-testing/examples/webgl_math_orientation_transform.ts -@@ -1,6 +1,10 @@ - import * as THREE from 'three'; - --let camera, scene, renderer, mesh, target; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ mesh: THREE.Mesh, -+ target: THREE.Mesh; - - const spherical = new THREE.Spherical(); - const rotationMatrix = new THREE.Matrix4(); -diff --git a/examples-testing/examples/webgl_mesh_batch.ts b/examples-testing/examples/webgl_mesh_batch.ts -index f93e5fb8..ee612f75 100644 ---- a/examples-testing/examples/webgl_mesh_batch.ts -+++ b/examples-testing/examples/webgl_mesh_batch.ts -@@ -4,12 +4,12 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { radixSort } from 'three/addons/utils/SortUtils.js'; -+import { RadixSortOptions, radixSort } from 'three/addons/utils/SortUtils.js'; - --let stats, gui, guiStatsEl; --let camera, controls, scene, renderer; --let geometries, mesh, material; --const ids = []; -+let stats: Stats, gui: GUI, guiStatsEl: HTMLLIElement; -+let camera: THREE.PerspectiveCamera, controls: OrbitControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let geometries: THREE.BufferGeometry[], mesh: THREE.Group | THREE.BatchedMesh, material: THREE.MeshNormalMaterial; -+const ids: number[] = []; - const matrix = new THREE.Matrix4(); - - // -@@ -45,7 +45,7 @@ initMesh(); - - // - --function randomizeMatrix(matrix) { -+function randomizeMatrix(matrix: THREE.Matrix4) { - position.x = Math.random() * 40 - 20; - position.y = Math.random() * 40 - 20; - position.z = Math.random() * 40 - 20; -@@ -61,7 +61,7 @@ function randomizeMatrix(matrix) { - return matrix.compose(position, quaternion, scale); - } - --function randomizeRotationSpeed(rotation) { -+function randomizeRotationSpeed(rotation: THREE.Euler) { - rotation.x = Math.random() * 0.01; - rotation.y = Math.random() * 0.01; - rotation.z = Math.random() * 0.01; -@@ -86,10 +86,10 @@ function createMaterial() { - - function cleanup() { - if (mesh) { -- mesh.parent.remove(mesh); -+ mesh.parent!.remove(mesh); - -- if (mesh.dispose) { -- mesh.dispose(); -+ if ((mesh as THREE.BatchedMesh).dispose) { -+ (mesh as THREE.BatchedMesh).dispose(); - } - } - } -@@ -219,14 +219,18 @@ function init() { - - // - --function sortFunction(list) { -+type BatchedMeshWithOptions = THREE.BatchedMesh & { -+ _options?: RadixSortOptions<{ start: number; count: number; z: number }>; -+}; -+ -+function sortFunction(this: THREE.BatchedMesh, list: { start: number; count: number; z: number }[]) { - // initialize options -- this._options = this._options || { -+ (this as BatchedMeshWithOptions)._options = (this as BatchedMeshWithOptions)._options || { - get: el => el.z, - aux: new Array(this.maxInstanceCount), - }; - -- const options = this._options; -+ const options = (this as BatchedMeshWithOptions)._options!; - options.reversed = this.material.transparent; - - let minZ = Infinity; -@@ -276,9 +280,9 @@ function animateMeshes() { - const rotationMatrix = mesh.userData.rotationSpeeds[i]; - const id = ids[i]; - -- mesh.getMatrixAt(id, matrix); -+ (mesh as THREE.BatchedMesh).getMatrixAt(id, matrix); - matrix.multiply(rotationMatrix); -- mesh.setMatrixAt(id, matrix); -+ (mesh as THREE.BatchedMesh).setMatrixAt(id, matrix); - } - } else { - for (let i = 0; i < loopNum; i++) { -@@ -295,10 +299,10 @@ function animateMeshes() { - } - - function render() { -- if (mesh.isBatchedMesh) { -- mesh.sortObjects = api.sortObjects; -- mesh.perObjectFrustumCulled = api.perObjectFrustumCulled; -- mesh.setCustomSort(api.useCustomSort ? sortFunction : null); -+ if ((mesh as THREE.BatchedMesh).isBatchedMesh) { -+ (mesh as THREE.BatchedMesh).sortObjects = api.sortObjects; -+ (mesh as THREE.BatchedMesh).perObjectFrustumCulled = api.perObjectFrustumCulled; -+ (mesh as THREE.BatchedMesh).setCustomSort(api.useCustomSort ? sortFunction : null); - } - - renderer.render(scene, camera); -diff --git a/examples-testing/examples/webgl_mirror.ts b/examples-testing/examples/webgl_mirror.ts -index 8b27363a..7d0f6cfb 100644 ---- a/examples-testing/examples/webgl_mirror.ts -+++ b/examples-testing/examples/webgl_mirror.ts -@@ -3,18 +3,18 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Reflector } from 'three/addons/objects/Reflector.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let cameraControls; -+let cameraControls: OrbitControls; - --let sphereGroup, smallSphere; -+let sphereGroup: THREE.Object3D, smallSphere: THREE.Mesh; - --let groundMirror, verticalMirror; -+let groundMirror: Reflector, verticalMirror: Reflector; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); -diff --git a/examples-testing/examples/webgl_modifier_edgesplit.ts b/examples-testing/examples/webgl_modifier_edgesplit.ts -index 4725eff6..96620f50 100644 ---- a/examples-testing/examples/webgl_modifier_edgesplit.ts -+++ b/examples-testing/examples/webgl_modifier_edgesplit.ts -@@ -7,9 +7,11 @@ import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js' - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let renderer, scene, camera; --let modifier, mesh, baseGeometry; --let map; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let modifier: EdgeSplitModifier, -+ mesh: THREE.Mesh, -+ baseGeometry: THREE.BufferGeometry; -+let map: THREE.Texture; - - const params = { - smoothShading: true, -@@ -50,7 +52,7 @@ function init() { - scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 3)); - - new OBJLoader().load('./models/obj/cerberus/Cerberus.obj', function (group) { -- const cerberus = group.children[0]; -+ const cerberus = group.children[0] as THREE.Mesh; - const modelGeometry = cerberus.geometry; - - modifier = new EdgeSplitModifier(); -diff --git a/examples-testing/examples/webgl_modifier_simplifier.ts b/examples-testing/examples/webgl_modifier_simplifier.ts -index e6ea453b..f55a6581 100644 ---- a/examples-testing/examples/webgl_modifier_simplifier.ts -+++ b/examples-testing/examples/webgl_modifier_simplifier.ts -@@ -4,7 +4,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { SimplifyModifier } from 'three/addons/modifiers/SimplifyModifier.js'; - --let renderer, scene, camera; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; - - init(); - -@@ -47,7 +47,7 @@ function init() { - - const modifier = new SimplifyModifier(); - -- const simplified = mesh.clone(); -+ const simplified = mesh.clone() as THREE.Mesh; - simplified.material = simplified.material.clone(); - simplified.material.flatShading = true; - const count = Math.floor(simplified.geometry.attributes.position.count * 0.875); // number of vertices to remove -diff --git a/examples-testing/examples/webgl_modifier_tessellation.ts b/examples-testing/examples/webgl_modifier_tessellation.ts -index 4600fc6c..83af66a7 100644 ---- a/examples-testing/examples/webgl_modifier_tessellation.ts -+++ b/examples-testing/examples/webgl_modifier_tessellation.ts -@@ -4,14 +4,14 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - import { TessellateModifier } from 'three/addons/modifiers/TessellateModifier.js'; --import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -+import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - --let renderer, scene, camera, stats; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, stats: Stats; - --let controls; -+let controls: TrackballControls; - --let mesh, uniforms; -+let mesh: THREE.Mesh, uniforms: Record>; - - const WIDTH = window.innerWidth; - const HEIGHT = window.innerHeight; -@@ -21,7 +21,7 @@ loader.load('fonts/helvetiker_bold.typeface.json', function (font) { - init(font); - }); - --function init(font) { -+function init(font: Font) { - camera = new THREE.PerspectiveCamera(40, WIDTH / HEIGHT, 1, 10000); - camera.position.set(-100, 100, 200); - -@@ -90,8 +90,8 @@ function init(font) { - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - }); - - // -@@ -105,7 +105,7 @@ function init(font) { - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.appendChild(renderer.domElement); - - controls = new TrackballControls(camera, renderer.domElement); -diff --git a/examples-testing/examples/webgl_morphtargets.ts b/examples-testing/examples/webgl_morphtargets.ts -index 40d605f8..5965ef35 100644 ---- a/examples-testing/examples/webgl_morphtargets.ts -+++ b/examples-testing/examples/webgl_morphtargets.ts -@@ -3,12 +3,16 @@ import * as THREE from 'three'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container, camera, scene, renderer, mesh; -+let container: HTMLElement, -+ camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ mesh: THREE.Mesh; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x8fbcd4); -@@ -62,7 +66,7 @@ function createGeometry() { - const spherePositions = []; - - // for the second morph target, we'll twist the cubes vertices -- const twistPositions = []; -+ const twistPositions: number[] = []; - const direction = new THREE.Vector3(1, 0, 0); - const vertex = new THREE.Vector3(); - -@@ -103,12 +107,12 @@ function initGUI() { - gui.add(params, 'Spherify', 0, 1) - .step(0.01) - .onChange(function (value) { -- mesh.morphTargetInfluences[0] = value; -+ mesh.morphTargetInfluences![0] = value; - }); - gui.add(params, 'Twist', 0, 1) - .step(0.01) - .onChange(function (value) { -- mesh.morphTargetInfluences[1] = value; -+ mesh.morphTargetInfluences![1] = value; - }); - } - -diff --git a/examples-testing/examples/webgl_morphtargets_face.ts b/examples-testing/examples/webgl_morphtargets_face.ts -index 76179d90..c5b71065 100644 ---- a/examples-testing/examples/webgl_morphtargets_face.ts -+++ b/examples-testing/examples/webgl_morphtargets_face.ts -@@ -12,7 +12,13 @@ import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats, mixer, clock, controls; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ mixer: THREE.AnimationMixer, -+ clock: THREE.Clock, -+ controls: OrbitControls; - - init(); - -@@ -51,13 +57,13 @@ function init() { - - // GUI - -- const head = mesh.getObjectByName('mesh_2'); -- const influences = head.morphTargetInfluences; -+ const head = mesh.getObjectByName('mesh_2') as THREE.Mesh; -+ const influences = head.morphTargetInfluences!; - - const gui = new GUI(); - gui.close(); - -- for (const [key, value] of Object.entries(head.morphTargetDictionary)) { -+ for (const [key, value] of Object.entries(head.morphTargetDictionary!)) { - gui.add(influences, value, 0, 1, 0.01).name(key.replace('blendShape1.', '')).listen(); - } - }); -diff --git a/examples-testing/examples/webgl_morphtargets_horse.ts b/examples-testing/examples/webgl_morphtargets_horse.ts -index 2c29e9c0..5e285283 100644 ---- a/examples-testing/examples/webgl_morphtargets_horse.ts -+++ b/examples-testing/examples/webgl_morphtargets_horse.ts -@@ -4,9 +4,9 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let container, stats; --let camera, scene, renderer; --let mesh, mixer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let mesh: THREE.Object3D, mixer: THREE.AnimationMixer; - - const radius = 600; - let theta = 0; -diff --git a/examples-testing/examples/webgl_morphtargets_sphere.ts b/examples-testing/examples/webgl_morphtargets_sphere.ts -index 2b889911..8ddf9f4a 100644 ---- a/examples-testing/examples/webgl_morphtargets_sphere.ts -+++ b/examples-testing/examples/webgl_morphtargets_sphere.ts -@@ -4,9 +4,9 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { Timer } from 'three/addons/misc/Timer.js'; - --let camera, scene, renderer, timer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, timer: Timer; - --let mesh; -+let mesh: THREE.Mesh; - - let sign = 1; - const speed = 0.5; -@@ -14,7 +14,7 @@ const speed = 0.5; - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.2, 100); - camera.position.set(0, 5, 5); -@@ -35,7 +35,7 @@ function init() { - - const loader = new GLTFLoader(); - loader.load('models/gltf/AnimatedMorphSphere/glTF/AnimatedMorphSphere.gltf', function (gltf) { -- mesh = gltf.scene.getObjectByName('AnimatedMorphSphere'); -+ mesh = gltf.scene.getObjectByName('AnimatedMorphSphere') as THREE.Mesh; - mesh.rotation.z = Math.PI / 2; - scene.add(mesh); - -@@ -94,9 +94,9 @@ function render() { - - mesh.rotation.y += step; - -- mesh.morphTargetInfluences[1] = mesh.morphTargetInfluences[1] + step * sign; -+ mesh.morphTargetInfluences![1] = mesh.morphTargetInfluences![1] + step * sign; - -- if (mesh.morphTargetInfluences[1] <= 0 || mesh.morphTargetInfluences[1] >= 1) { -+ if (mesh.morphTargetInfluences![1] <= 0 || mesh.morphTargetInfluences![1] >= 1) { - sign *= -1; - } - } -diff --git a/examples-testing/examples/webgl_multiple_elements.ts b/examples-testing/examples/webgl_multiple_elements.ts -index 64f8a9c5..8dafa688 100644 ---- a/examples-testing/examples/webgl_multiple_elements.ts -+++ b/examples-testing/examples/webgl_multiple_elements.ts -@@ -2,14 +2,14 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let canvas, renderer; -+let canvas: HTMLCanvasElement, renderer: THREE.WebGLRenderer; - --const scenes = []; -+const scenes: THREE.Scene[] = []; - - init(); - - function init() { -- canvas = document.getElementById('c'); -+ canvas = document.getElementById('c') as HTMLCanvasElement; - - const geometries = [ - new THREE.BoxGeometry(1, 1, 1), -@@ -18,7 +18,7 @@ function init() { - new THREE.CylinderGeometry(0.5, 0.5, 1, 12), - ]; - -- const content = document.getElementById('content'); -+ const content = document.getElementById('content')!; - - for (let i = 0; i < 40; i++) { - const scene = new THREE.Scene(); -diff --git a/examples-testing/examples/webgl_multiple_rendertargets.ts b/examples-testing/examples/webgl_multiple_rendertargets.ts -index 86708082..f63b7de6 100644 ---- a/examples-testing/examples/webgl_multiple_rendertargets.ts -+++ b/examples-testing/examples/webgl_multiple_rendertargets.ts -@@ -3,9 +3,9 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, controls; --let renderTarget; --let postScene, postCamera; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: OrbitControls; -+let renderTarget: THREE.WebGLRenderTarget; -+let postScene: THREE.Scene, postCamera: THREE.OrthographicCamera; - - const parameters = { - samples: 4, -@@ -62,8 +62,8 @@ function init() { - new THREE.TorusKnotGeometry(1, 0.3, 128, 32), - new THREE.RawShaderMaterial({ - name: 'G-Buffer Shader', -- vertexShader: document.querySelector('#gbuffer-vert').textContent.trim(), -- fragmentShader: document.querySelector('#gbuffer-frag').textContent.trim(), -+ vertexShader: document.querySelector('#gbuffer-vert')!.textContent!.trim(), -+ fragmentShader: document.querySelector('#gbuffer-frag')!.textContent!.trim(), - uniforms: { - tDiffuse: { value: diffuse }, - repeat: { value: new THREE.Vector2(5, 0.5) }, -@@ -83,8 +83,8 @@ function init() { - new THREE.PlaneGeometry(2, 2), - new THREE.RawShaderMaterial({ - name: 'Post-FX Shader', -- vertexShader: document.querySelector('#render-vert').textContent.trim(), -- fragmentShader: document.querySelector('#render-frag').textContent.trim(), -+ vertexShader: document.querySelector('#render-vert')!.textContent!.trim(), -+ fragmentShader: document.querySelector('#render-frag')!.textContent!.trim(), - uniforms: { - tDiffuse: { value: renderTarget.textures[0] }, - tNormal: { value: renderTarget.textures[1] }, -@@ -118,8 +118,8 @@ function render() { - renderTarget.samples = parameters.samples; - - scene.traverse(function (child) { -- if (child.material !== undefined) { -- child.material.wireframe = parameters.wireframe; -+ if ((child as THREE.Mesh).material !== undefined) { -+ ((child as THREE.Mesh).material as THREE.RawShaderMaterial).wireframe = parameters.wireframe; - } - }); - -diff --git a/examples-testing/examples/webgl_multiple_scenes_comparison.ts b/examples-testing/examples/webgl_multiple_scenes_comparison.ts -index 41a5130d..66d539a9 100644 ---- a/examples-testing/examples/webgl_multiple_scenes_comparison.ts -+++ b/examples-testing/examples/webgl_multiple_scenes_comparison.ts -@@ -2,15 +2,15 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container, camera, renderer, controls; --let sceneL, sceneR; -+let container: HTMLElement, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, controls: OrbitControls; -+let sceneL: THREE.Scene, sceneR: THREE.Scene; - - let sliderPos = window.innerWidth / 2; - - init(); - - function init() { -- container = document.querySelector('.container'); -+ container = document.querySelector('.container')!; - - sceneL = new THREE.Scene(); - sceneL.background = new THREE.Color(0xbcd48f); -@@ -52,9 +52,9 @@ function initMeshes() { - } - - function initSlider() { -- const slider = document.querySelector('.slider'); -+ const slider = document.querySelector('.slider') as HTMLElement; - -- function onPointerDown() { -+ function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - controls.enabled = false; -@@ -70,10 +70,10 @@ function initSlider() { - window.removeEventListener('pointerup', onPointerUp); - } - -- function onPointerMove(e) { -+ function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - -- sliderPos = Math.max(0, Math.min(window.innerWidth, e.pageX)); -+ sliderPos = Math.max(0, Math.min(window.innerWidth, event.pageX)); - - slider.style.left = sliderPos - slider.offsetWidth / 2 + 'px'; - } -diff --git a/examples-testing/examples/webgl_multiple_views.ts b/examples-testing/examples/webgl_multiple_views.ts -index 29126b01..b418641f 100644 ---- a/examples-testing/examples/webgl_multiple_views.ts -+++ b/examples-testing/examples/webgl_multiple_views.ts -@@ -2,16 +2,27 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let stats; -+let stats: Stats; - --let scene, renderer; -+let scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let mouseX = 0, - mouseY = 0; - --let windowWidth, windowHeight; -- --const views = [ -+let windowWidth: number, windowHeight: number; -+ -+const views: { -+ left: number; -+ bottom: number; -+ width: number; -+ height: number; -+ background: THREE.Color; -+ eye: [number, number, number]; -+ up: [number, number, number]; -+ fov: number; -+ updateCamera: (camera: THREE.PerspectiveCamera, scene: THREE.Scene, mouseX: number, mouseY: number) => void; -+ camera?: THREE.PerspectiveCamera; -+}[] = [ - { - left: 0, - bottom: 0, -@@ -62,7 +73,7 @@ const views = [ - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - for (let ii = 0; ii < views.length; ++ii) { - const view = views[ii]; -@@ -84,7 +95,7 @@ function init() { - canvas.width = 128; - canvas.height = 128; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - const gradient = context.createRadialGradient( - canvas.width / 2, - canvas.height / 2, -@@ -191,7 +202,7 @@ function init() { - document.addEventListener('mousemove', onDocumentMouseMove); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowWidth / 2; - mouseY = event.clientY - windowHeight / 2; - } -@@ -215,7 +226,7 @@ function render() { - - for (let ii = 0; ii < views.length; ++ii) { - const view = views[ii]; -- const camera = view.camera; -+ const camera = view.camera!; - - view.updateCamera(camera, scene, mouseX, mouseY); - -diff --git a/examples-testing/examples/webgl_multisampled_renderbuffers.ts b/examples-testing/examples/webgl_multisampled_renderbuffers.ts -index df84fb14..fc3da7a8 100644 ---- a/examples-testing/examples/webgl_multisampled_renderbuffers.ts -+++ b/examples-testing/examples/webgl_multisampled_renderbuffers.ts -@@ -5,9 +5,9 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, renderer, group, container; -+let camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, group: THREE.Group, container: HTMLElement; - --let composer1, composer2; -+let composer1: EffectComposer, composer2: EffectComposer; - - const params = { - animate: true, -@@ -16,7 +16,7 @@ const params = { - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, container.offsetWidth / container.offsetHeight, 10, 2000); - camera.position.z = 500; -diff --git a/examples-testing/examples/webgl_panorama_cube.ts b/examples-testing/examples/webgl_panorama_cube.ts -index efd09cfc..e4832209 100644 ---- a/examples-testing/examples/webgl_panorama_cube.ts -+++ b/examples-testing/examples/webgl_panorama_cube.ts -@@ -2,14 +2,14 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, controls; --let renderer; --let scene; -+let camera: THREE.PerspectiveCamera, controls: OrbitControls; -+let renderer: THREE.WebGLRenderer; -+let scene: THREE.Scene; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); -@@ -43,8 +43,8 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) { -- const textures = []; -+function getTexturesFromAtlasFile(atlasImgUrl: string, tilesNum: number) { -+ const textures: THREE.Texture[] = []; - - for (let i = 0; i < tilesNum; i++) { - textures[i] = new THREE.Texture(); -@@ -56,7 +56,7 @@ function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) { - - for (let i = 0; i < textures.length; i++) { - canvas = document.createElement('canvas'); -- context = canvas.getContext('2d'); -+ context = canvas.getContext('2d')!; - canvas.height = tileWidth; - canvas.width = tileWidth; - context.drawImage(image, tileWidth * i, 0, tileWidth, tileWidth, 0, 0, tileWidth, tileWidth); -diff --git a/examples-testing/examples/webgl_panorama_equirectangular.ts b/examples-testing/examples/webgl_panorama_equirectangular.ts -index 40796f6e..6d631dee 100644 ---- a/examples-testing/examples/webgl_panorama_equirectangular.ts -+++ b/examples-testing/examples/webgl_panorama_equirectangular.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let isUserInteracting = false, - onPointerDownMouseX = 0, -@@ -15,7 +15,7 @@ let isUserInteracting = false, - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100); - -@@ -54,7 +54,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - isUserInteracting = true; -@@ -69,14 +69,14 @@ function onPointerDown(event) { - document.addEventListener('pointerup', onPointerUp); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - lon = (onPointerDownMouseX - event.clientX) * 0.1 + onPointerDownLon; - lat = (event.clientY - onPointerDownMouseY) * 0.1 + onPointerDownLat; - } - --function onPointerUp() { -+function onPointerUp(event: PointerEvent) { - if (event.isPrimary === false) return; - - isUserInteracting = false; -@@ -85,7 +85,7 @@ function onPointerUp() { - document.removeEventListener('pointerup', onPointerUp); - } - --function onDocumentMouseWheel(event) { -+function onDocumentMouseWheel(event: WheelEvent) { - const fov = camera.fov + event.deltaY * 0.05; - - camera.fov = THREE.MathUtils.clamp(fov, 10, 75); -diff --git a/examples-testing/examples/webgl_performance.ts b/examples-testing/examples/webgl_performance.ts -index 3700386a..6a9cc228 100644 ---- a/examples-testing/examples/webgl_performance.ts -+++ b/examples-testing/examples/webgl_performance.ts -@@ -6,7 +6,7 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; - - init(); - -diff --git a/examples-testing/examples/webgl_pmrem_test.ts b/examples-testing/examples/webgl_pmrem_test.ts -index b33e4e2f..3f0ef819 100644 ---- a/examples-testing/examples/webgl_pmrem_test.ts -+++ b/examples-testing/examples/webgl_pmrem_test.ts -@@ -5,7 +5,7 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, camera, controls, renderer; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls, renderer: THREE.WebGLRenderer; - - function init() { - const width = window.innerWidth; -@@ -68,8 +68,9 @@ function init() { - directionalLight.intensity = value ? 0 : 1; - - scene.traverse(function (child) { -- if (child.isMesh) { -- child.material.envMapIntensity = 1 - directionalLight.intensity; -+ if ((child as THREE.Mesh).isMesh) { -+ ((child as THREE.Mesh).material as THREE.MeshStandardMaterial).envMapIntensity = -+ 1 - directionalLight.intensity; - } - }); - -diff --git a/examples-testing/examples/webgl_points_billboards.ts b/examples-testing/examples/webgl_points_billboards.ts -index 24d4de1a..f1a089bf 100644 ---- a/examples-testing/examples/webgl_points_billboards.ts -+++ b/examples-testing/examples/webgl_points_billboards.ts -@@ -4,7 +4,11 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats, material; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ material: THREE.PointsMaterial; - let mouseX = 0, - mouseY = 0; - -@@ -91,7 +95,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -diff --git a/examples-testing/examples/webgl_points_sprites.ts b/examples-testing/examples/webgl_points_sprites.ts -index 31b9e2ce..d8f24b29 100644 ---- a/examples-testing/examples/webgl_points_sprites.ts -+++ b/examples-testing/examples/webgl_points_sprites.ts -@@ -4,14 +4,18 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, stats, parameters; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ parameters: [[number, number, number], THREE.Texture, number][]; - let mouseX = 0, - mouseY = 0; - - let windowHalfX = window.innerWidth / 2; - let windowHalfY = window.innerHeight / 2; - --const materials = []; -+const materials: THREE.PointsMaterial[] = []; - - init(); - -@@ -27,7 +31,7 @@ function init() { - - const textureLoader = new THREE.TextureLoader(); - -- const assignSRGB = texture => { -+ const assignSRGB = (texture: THREE.Texture) => { - texture.colorSpace = THREE.SRGBColorSpace; - }; - -@@ -126,7 +130,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -diff --git a/examples-testing/examples/webgl_points_waves.ts b/examples-testing/examples/webgl_points_waves.ts -index 91986e9e..cb8e7687 100644 ---- a/examples-testing/examples/webgl_points_waves.ts -+++ b/examples-testing/examples/webgl_points_waves.ts -@@ -6,10 +6,10 @@ const SEPARATION = 100, - AMOUNTX = 50, - AMOUNTY = 50; - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let particles, -+let particles: THREE.Points, - count = 0; - - let mouseX = 0, -@@ -60,8 +60,8 @@ function init() { - uniforms: { - color: { value: new THREE.Color(0xffffff) }, - }, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - }); - - // -@@ -100,7 +100,7 @@ function onWindowResize() { - - // - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -diff --git a/examples-testing/examples/webgl_portal.ts b/examples-testing/examples/webgl_portal.ts -index 4bc59593..e61736c3 100644 ---- a/examples-testing/examples/webgl_portal.ts -+++ b/examples-testing/examples/webgl_portal.ts -@@ -3,26 +3,26 @@ import * as THREE from 'three'; - import * as CameraUtils from 'three/addons/utils/CameraUtils.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let cameraControls; -+let cameraControls: OrbitControls; - --let smallSphereOne, smallSphereTwo; -+let smallSphereOne: THREE.Mesh, smallSphereTwo: THREE.Mesh; - --let portalCamera, -- leftPortal, -- rightPortal, -- leftPortalTexture, -- reflectedPosition, -- rightPortalTexture, -- bottomLeftCorner, -- bottomRightCorner, -- topLeftCorner; -+let portalCamera: THREE.PerspectiveCamera, -+ leftPortal: THREE.Mesh, -+ rightPortal: THREE.Mesh, -+ leftPortalTexture: THREE.WebGLRenderTarget, -+ reflectedPosition: THREE.Vector3, -+ rightPortalTexture: THREE.WebGLRenderTarget, -+ bottomLeftCorner: THREE.Vector3, -+ bottomRightCorner: THREE.Vector3, -+ topLeftCorner: THREE.Vector3; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); -@@ -150,7 +150,11 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function renderPortal(thisPortalMesh, otherPortalMesh, thisPortalTexture) { -+function renderPortal( -+ thisPortalMesh: THREE.Mesh, -+ otherPortalMesh: THREE.Mesh, -+ thisPortalTexture: THREE.WebGLRenderTarget, -+) { - // set the portal camera position to be reflected about the portal plane - thisPortalMesh.worldToLocal(reflectedPosition.copy(camera.position)); - reflectedPosition.x *= -1.0; -diff --git a/examples-testing/examples/webgl_postprocessing.ts b/examples-testing/examples/webgl_postprocessing.ts -index ecc9b28e..2e894236 100644 ---- a/examples-testing/examples/webgl_postprocessing.ts -+++ b/examples-testing/examples/webgl_postprocessing.ts -@@ -8,8 +8,8 @@ import { RGBShiftShader } from 'three/addons/shaders/RGBShiftShader.js'; - import { DotScreenShader } from 'three/addons/shaders/DotScreenShader.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, renderer, composer; --let object; -+let camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, composer: EffectComposer; -+let object: THREE.Object3D; - - init(); - -diff --git a/examples-testing/examples/webgl_postprocessing_advanced.ts b/examples-testing/examples/webgl_postprocessing_advanced.ts -index 82fc39be..1a14c2b9 100644 ---- a/examples-testing/examples/webgl_postprocessing_advanced.ts -+++ b/examples-testing/examples/webgl_postprocessing_advanced.ts -@@ -21,11 +21,21 @@ import { GammaCorrectionShader } from 'three/addons/shaders/GammaCorrectionShade - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let container, stats; -- --let composerScene, composer1, composer2, composer3, composer4; -- --let cameraOrtho, cameraPerspective, sceneModel, sceneBG, renderer, mesh, directionalLight; -+let container: HTMLElement, stats: Stats; -+ -+let composerScene: EffectComposer, -+ composer1: EffectComposer, -+ composer2: EffectComposer, -+ composer3: EffectComposer, -+ composer4: EffectComposer; -+ -+let cameraOrtho: THREE.OrthographicCamera, -+ cameraPerspective: THREE.PerspectiveCamera, -+ sceneModel: THREE.Scene, -+ sceneBG: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ mesh: THREE.Mesh, -+ directionalLight: THREE.DirectionalLight; - - const width = window.innerWidth || 2; - const height = window.innerHeight || 2; -@@ -33,14 +43,14 @@ const height = window.innerHeight || 2; - let halfWidth = width / 2; - let halfHeight = height / 2; - --let quadBG, quadMask, renderScene; -+let quadBG: THREE.Mesh, quadMask: THREE.Mesh, renderScene: TexturePass; - - const delta = 0.01; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -63,7 +73,7 @@ function init() { - - const loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { -- createMesh(gltf.scene.children[0].geometry, sceneModel, 100); -+ createMesh((gltf.scene.children[0] as THREE.Mesh).geometry, sceneModel, 100); - }); - - // -@@ -254,7 +264,7 @@ function onWindowResize() { - quadMask.scale.set(window.innerWidth / 2, window.innerHeight / 2, 1); - } - --function createMesh(geometry, scene, scale) { -+function createMesh(geometry: THREE.BufferGeometry, scene: THREE.Scene, scale: number) { - const diffuseMap = new THREE.TextureLoader().load('models/gltf/LeePerrySmith/Map-COL.jpg'); - diffuseMap.colorSpace = THREE.SRGBColorSpace; - -diff --git a/examples-testing/examples/webgl_postprocessing_afterimage.ts b/examples-testing/examples/webgl_postprocessing_afterimage.ts -index 508f90b8..53e74b77 100644 ---- a/examples-testing/examples/webgl_postprocessing_afterimage.ts -+++ b/examples-testing/examples/webgl_postprocessing_afterimage.ts -@@ -7,10 +7,10 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { AfterimagePass } from 'three/addons/postprocessing/AfterimagePass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, scene, renderer, composer; --let mesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, composer: EffectComposer; -+let mesh: THREE.Mesh; - --let afterimagePass; -+let afterimagePass: AfterimagePass; - - const params = { - enable: true, -diff --git a/examples-testing/examples/webgl_postprocessing_backgrounds.ts b/examples-testing/examples/webgl_postprocessing_backgrounds.ts -index 57a6a2db..f6d4c716 100644 ---- a/examples-testing/examples/webgl_postprocessing_backgrounds.ts -+++ b/examples-testing/examples/webgl_postprocessing_backgrounds.ts -@@ -11,10 +11,10 @@ import { ClearPass } from 'three/addons/postprocessing/ClearPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let scene, renderer, composer; --let clearPass, texturePass, renderPass; --let cameraP, cubeTexturePassP; --let gui, stats; -+let scene: THREE.Scene, renderer: THREE.WebGLRenderer, composer: EffectComposer; -+let clearPass: ClearPass, texturePass: TexturePass, renderPass: RenderPass; -+let cameraP: THREE.PerspectiveCamera, cubeTexturePassP: CubeTexturePass | null; -+let gui: GUI | undefined, stats: Stats; - - const params = { - clearPass: true, -@@ -55,7 +55,7 @@ function clearGui() { - } - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - const width = window.innerWidth || 1; - const height = window.innerHeight || 1; -@@ -111,7 +111,7 @@ function init() { - - // postprocessing - -- const genCubeUrls = function (prefix, postfix) { -+ const genCubeUrls = function (prefix: string, postfix: string) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, -diff --git a/examples-testing/examples/webgl_postprocessing_fxaa.ts b/examples-testing/examples/webgl_postprocessing_fxaa.ts -index 55745f88..78bb4bda 100644 ---- a/examples-testing/examples/webgl_postprocessing_fxaa.ts -+++ b/examples-testing/examples/webgl_postprocessing_fxaa.ts -@@ -6,14 +6,19 @@ import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; - --let camera, scene, renderer, clock, group, container; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ clock: THREE.Clock, -+ group: THREE.Group, -+ container: HTMLElement; - --let composer1, composer2, fxaaPass; -+let composer1: EffectComposer, composer2: EffectComposer, fxaaPass: ShaderPass; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, container.offsetWidth / container.offsetHeight, 1, 2000); - camera.position.z = 500; -diff --git a/examples-testing/examples/webgl_postprocessing_glitch.ts b/examples-testing/examples/webgl_postprocessing_glitch.ts -index f846c0ce..5eaa953f 100644 ---- a/examples-testing/examples/webgl_postprocessing_glitch.ts -+++ b/examples-testing/examples/webgl_postprocessing_glitch.ts -@@ -5,21 +5,21 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, scene, renderer, composer; --let object, light; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, composer: EffectComposer; -+let object: THREE.Object3D, light: THREE.DirectionalLight; - --let glitchPass; -+let glitchPass: GlitchPass; - --const button = document.querySelector('#startButton'); -+const button = document.querySelector('#startButton')!; - button.addEventListener('click', function () { -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - - init(); - }); - - function updateOptions() { -- const wildGlitch = document.getElementById('wildGlitch'); -+ const wildGlitch = document.getElementById('wildGlitch') as HTMLInputElement; - glitchPass.goWild = wildGlitch.checked; - } - -@@ -75,7 +75,7 @@ function init() { - - window.addEventListener('resize', onWindowResize); - -- const wildGlitchOption = document.getElementById('wildGlitch'); -+ const wildGlitchOption = document.getElementById('wildGlitch')!; - wildGlitchOption.addEventListener('change', updateOptions); - - updateOptions(); -diff --git a/examples-testing/examples/webgl_postprocessing_godrays.ts b/examples-testing/examples/webgl_postprocessing_godrays.ts -index fb760441..73c8beb2 100644 ---- a/examples-testing/examples/webgl_postprocessing_godrays.ts -+++ b/examples-testing/examples/webgl_postprocessing_godrays.ts -@@ -11,16 +11,37 @@ import { - GodRaysGenerateShader, - } from 'three/addons/shaders/GodRaysShader.js'; - --let container, stats; --let camera, scene, renderer, materialDepth; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ materialDepth: THREE.MeshDepthMaterial; - --let sphereMesh; -+let sphereMesh: THREE.Mesh; - - const sunPosition = new THREE.Vector3(0, 1000, -1000); - const clipPosition = new THREE.Vector4(); - const screenSpacePosition = new THREE.Vector3(); - --const postprocessing = { enabled: true }; -+const postprocessing: { -+ enabled: boolean; -+ scene?: THREE.Scene; -+ camera?: THREE.OrthographicCamera; -+ rtTextureColors?: THREE.WebGLRenderTarget; -+ rtTextureDepth?: THREE.WebGLRenderTarget; -+ rtTextureDepthMask?: THREE.WebGLRenderTarget; -+ rtTextureGodRays1?: THREE.WebGLRenderTarget; -+ rtTextureGodRays2?: THREE.WebGLRenderTarget; -+ godrayMaskUniforms?: (typeof GodRaysDepthMaskShader)['uniforms']; -+ materialGodraysDepthMask?: THREE.ShaderMaterial; -+ godrayGenUniforms?: (typeof GodRaysGenerateShader)['uniforms']; -+ materialGodraysGenerate?: THREE.ShaderMaterial; -+ godrayCombineUniforms?: (typeof GodRaysCombineShader)['uniforms']; -+ materialGodraysCombine?: THREE.ShaderMaterial; -+ godraysFakeSunUniforms?: (typeof GodRaysFakeSunShader)['uniforms']; -+ materialGodraysFakeSun?: THREE.ShaderMaterial; -+ quad?: THREE.Mesh; -+} = { enabled: true }; - - const orbitRadius = 200; - -@@ -102,17 +123,17 @@ function onWindowResize() { - camera.updateProjectionMatrix(); - - renderer.setSize(renderTargetWidth, renderTargetHeight); -- postprocessing.rtTextureColors.setSize(renderTargetWidth, renderTargetHeight); -- postprocessing.rtTextureDepth.setSize(renderTargetWidth, renderTargetHeight); -- postprocessing.rtTextureDepthMask.setSize(renderTargetWidth, renderTargetHeight); -+ postprocessing.rtTextureColors!.setSize(renderTargetWidth, renderTargetHeight); -+ postprocessing.rtTextureDepth!.setSize(renderTargetWidth, renderTargetHeight); -+ postprocessing.rtTextureDepthMask!.setSize(renderTargetWidth, renderTargetHeight); - - const adjustedWidth = renderTargetWidth * godrayRenderTargetResolutionMultiplier; - const adjustedHeight = renderTargetHeight * godrayRenderTargetResolutionMultiplier; -- postprocessing.rtTextureGodRays1.setSize(adjustedWidth, adjustedHeight); -- postprocessing.rtTextureGodRays2.setSize(adjustedWidth, adjustedHeight); -+ postprocessing.rtTextureGodRays1!.setSize(adjustedWidth, adjustedHeight); -+ postprocessing.rtTextureGodRays2!.setSize(adjustedWidth, adjustedHeight); - } - --function initPostprocessing(renderTargetWidth, renderTargetHeight) { -+function initPostprocessing(renderTargetWidth: number, renderTargetHeight: number) { - postprocessing.scene = new THREE.Scene(); - - postprocessing.camera = new THREE.OrthographicCamera(-0.5, 0.5, 0.5, -0.5, -10000, 10000); -@@ -183,10 +204,10 @@ function initPostprocessing(renderTargetWidth, renderTargetHeight) { - fragmentShader: godraysFakeSunShader.fragmentShader, - }); - -- postprocessing.godraysFakeSunUniforms.bgColor.value.setHex(bgColor); -- postprocessing.godraysFakeSunUniforms.sunColor.value.setHex(sunColor); -+ postprocessing.godraysFakeSunUniforms!.bgColor.value.setHex(bgColor); -+ postprocessing.godraysFakeSunUniforms!.sunColor.value.setHex(sunColor); - -- postprocessing.godrayCombineUniforms.fGodRayIntensity.value = 0.75; -+ postprocessing.godrayCombineUniforms!.fGodRayIntensity.value = 0.75; - - postprocessing.quad = new THREE.Mesh(new THREE.PlaneGeometry(1.0, 1.0), postprocessing.materialGodraysGenerate); - postprocessing.quad.position.z = -9900; -@@ -199,19 +220,19 @@ function animate() { - stats.end(); - } - --function getStepSize(filterLen, tapsPerPass, pass) { -+function getStepSize(filterLen: number, tapsPerPass: number, pass: number) { - return filterLen * Math.pow(tapsPerPass, -pass); - } - --function filterGodRays(inputTex, renderTarget, stepSize) { -- postprocessing.scene.overrideMaterial = postprocessing.materialGodraysGenerate; -+function filterGodRays(inputTex: THREE.Texture, renderTarget: THREE.WebGLRenderTarget, stepSize: number) { -+ postprocessing.scene!.overrideMaterial = postprocessing.materialGodraysGenerate!; - -- postprocessing.godrayGenUniforms['fStepSize'].value = stepSize; -- postprocessing.godrayGenUniforms['tInput'].value = inputTex; -+ postprocessing.godrayGenUniforms!['fStepSize'].value = stepSize; -+ postprocessing.godrayGenUniforms!['tInput'].value = inputTex; - - renderer.setRenderTarget(renderTarget); -- renderer.render(postprocessing.scene, postprocessing.camera); -- postprocessing.scene.overrideMaterial = null; -+ renderer.render(postprocessing.scene!, postprocessing.camera!); -+ postprocessing.scene!.overrideMaterial = null; - } - - function render() { -@@ -239,14 +260,14 @@ function render() { - - // Give it to the god-ray and sun shaders - -- postprocessing.godrayGenUniforms['vSunPositionScreenSpace'].value.copy(screenSpacePosition); -- postprocessing.godraysFakeSunUniforms['vSunPositionScreenSpace'].value.copy(screenSpacePosition); -+ postprocessing.godrayGenUniforms!['vSunPositionScreenSpace'].value.copy(screenSpacePosition); -+ postprocessing.godraysFakeSunUniforms!['vSunPositionScreenSpace'].value.copy(screenSpacePosition); - - // -- Draw sky and sun -- - - // Clear colors and depths, will clear to sky color - -- renderer.setRenderTarget(postprocessing.rtTextureColors); -+ renderer.setRenderTarget(postprocessing.rtTextureColors!); - renderer.clear(true, true, false); - - // Sun render. Runs a shader that gives a brightness based on the screen -@@ -262,11 +283,11 @@ function render() { - renderer.setScissor(screenSpacePosition.x - sunsqW / 2, screenSpacePosition.y - sunsqH / 2, sunsqW, sunsqH); - renderer.setScissorTest(true); - -- postprocessing.godraysFakeSunUniforms['fAspect'].value = window.innerWidth / window.innerHeight; -+ postprocessing.godraysFakeSunUniforms!['fAspect'].value = window.innerWidth / window.innerHeight; - -- postprocessing.scene.overrideMaterial = postprocessing.materialGodraysFakeSun; -- renderer.setRenderTarget(postprocessing.rtTextureColors); -- renderer.render(postprocessing.scene, postprocessing.camera); -+ postprocessing.scene!.overrideMaterial = postprocessing.materialGodraysFakeSun!; -+ renderer.setRenderTarget(postprocessing.rtTextureColors!); -+ renderer.render(postprocessing.scene!, postprocessing.camera!); - - renderer.setScissorTest(false); - -@@ -275,23 +296,23 @@ function render() { - // Colors - - scene.overrideMaterial = null; -- renderer.setRenderTarget(postprocessing.rtTextureColors); -+ renderer.setRenderTarget(postprocessing.rtTextureColors!); - renderer.render(scene, camera); - - // Depth - - scene.overrideMaterial = materialDepth; -- renderer.setRenderTarget(postprocessing.rtTextureDepth); -+ renderer.setRenderTarget(postprocessing.rtTextureDepth!); - renderer.clear(); - renderer.render(scene, camera); - - // - -- postprocessing.godrayMaskUniforms['tInput'].value = postprocessing.rtTextureDepth.texture; -+ postprocessing.godrayMaskUniforms!['tInput'].value = postprocessing.rtTextureDepth!.texture; - -- postprocessing.scene.overrideMaterial = postprocessing.materialGodraysDepthMask; -- renderer.setRenderTarget(postprocessing.rtTextureDepthMask); -- renderer.render(postprocessing.scene, postprocessing.camera); -+ postprocessing.scene!.overrideMaterial = postprocessing.materialGodraysDepthMask!; -+ renderer.setRenderTarget(postprocessing.rtTextureDepthMask!); -+ renderer.render(postprocessing.scene!, postprocessing.camera!); - - // -- Render god-rays -- - -@@ -310,35 +331,35 @@ function render() { - - // pass 1 - render into first ping-pong target - filterGodRays( -- postprocessing.rtTextureDepthMask.texture, -- postprocessing.rtTextureGodRays2, -+ postprocessing.rtTextureDepthMask!.texture, -+ postprocessing.rtTextureGodRays2!, - getStepSize(filterLen, TAPS_PER_PASS, 1.0), - ); - - // pass 2 - render into second ping-pong target - filterGodRays( -- postprocessing.rtTextureGodRays2.texture, -- postprocessing.rtTextureGodRays1, -+ postprocessing.rtTextureGodRays2!.texture, -+ postprocessing.rtTextureGodRays1!, - getStepSize(filterLen, TAPS_PER_PASS, 2.0), - ); - - // pass 3 - 1st RT - filterGodRays( -- postprocessing.rtTextureGodRays1.texture, -- postprocessing.rtTextureGodRays2, -+ postprocessing.rtTextureGodRays1!.texture, -+ postprocessing.rtTextureGodRays2!, - getStepSize(filterLen, TAPS_PER_PASS, 3.0), - ); - - // final pass - composite god-rays onto colors - -- postprocessing.godrayCombineUniforms['tColors'].value = postprocessing.rtTextureColors.texture; -- postprocessing.godrayCombineUniforms['tGodRays'].value = postprocessing.rtTextureGodRays2.texture; -+ postprocessing.godrayCombineUniforms!['tColors'].value = postprocessing.rtTextureColors!.texture; -+ postprocessing.godrayCombineUniforms!['tGodRays'].value = postprocessing.rtTextureGodRays2!.texture; - -- postprocessing.scene.overrideMaterial = postprocessing.materialGodraysCombine; -+ postprocessing.scene!.overrideMaterial = postprocessing.materialGodraysCombine!; - - renderer.setRenderTarget(null); -- renderer.render(postprocessing.scene, postprocessing.camera); -- postprocessing.scene.overrideMaterial = null; -+ renderer.render(postprocessing.scene!, postprocessing.camera!); -+ postprocessing.scene!.overrideMaterial = null; - } else { - renderer.setRenderTarget(null); - renderer.clear(); -diff --git a/examples-testing/examples/webgl_postprocessing_gtao.ts b/examples-testing/examples/webgl_postprocessing_gtao.ts -index 4f16d155..ff12d709 100644 ---- a/examples-testing/examples/webgl_postprocessing_gtao.ts -+++ b/examples-testing/examples/webgl_postprocessing_gtao.ts -@@ -10,7 +10,14 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { GTAOPass } from 'three/addons/postprocessing/GTAOPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, scene, renderer, composer, controls, clock, stats, mixer; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ composer: EffectComposer, -+ controls: OrbitControls, -+ clock: THREE.Clock, -+ stats: Stats, -+ mixer: THREE.AnimationMixer; - - init(); - -diff --git a/examples-testing/examples/webgl_postprocessing_masking.ts b/examples-testing/examples/webgl_postprocessing_masking.ts -index f6e7310b..598a33dc 100644 ---- a/examples-testing/examples/webgl_postprocessing_masking.ts -+++ b/examples-testing/examples/webgl_postprocessing_masking.ts -@@ -6,8 +6,8 @@ import { ClearPass } from 'three/addons/postprocessing/ClearPass.js'; - import { MaskPass, ClearMaskPass } from 'three/addons/postprocessing/MaskPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, composer, renderer; --let box, torus; -+let camera: THREE.PerspectiveCamera, composer: EffectComposer, renderer: THREE.WebGLRenderer; -+let box: THREE.Mesh, torus: THREE.Mesh; - - init(); - -diff --git a/examples-testing/examples/webgl_postprocessing_material_ao.ts b/examples-testing/examples/webgl_postprocessing_material_ao.ts -index 2f17a530..c0374ac4 100644 ---- a/examples-testing/examples/webgl_postprocessing_material_ao.ts -+++ b/examples-testing/examples/webgl_postprocessing_material_ao.ts -@@ -10,7 +10,12 @@ import { GTAOPass } from 'three/addons/postprocessing/GTAOPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - import { MeshPostProcessingMaterial } from 'three/addons/materials/MeshPostProcessingMaterial.js'; - --let renderer, camera, scene, composer, controls, stats; -+let renderer: THREE.WebGLRenderer, -+ camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ composer: EffectComposer, -+ controls: OrbitControls, -+ stats: Stats; - const sceneParameters = { - output: 0, - envMapIntensity: 1.0, -@@ -218,7 +223,7 @@ function init() { - .max(100) - .step(1) - .onChange(() => { -- lightGroup.children.forEach(light => (light.intensity = sceneParameters.lightIntensity)); -+ lightGroup.children.forEach(light => ((light as THREE.Light).intensity = sceneParameters.lightIntensity)); - }); - gui.add(sceneParameters, 'shadow').onChange(value => { - renderer.shadowMap.enabled = value; -diff --git a/examples-testing/examples/webgl_postprocessing_outline.ts b/examples-testing/examples/webgl_postprocessing_outline.ts -index 35657546..fa861b5b 100644 ---- a/examples-testing/examples/webgl_postprocessing_outline.ts -+++ b/examples-testing/examples/webgl_postprocessing_outline.ts -@@ -12,11 +12,11 @@ import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; - --let container, stats; --let camera, scene, renderer, controls; --let composer, effectFXAA, outlinePass; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, controls: OrbitControls; -+let composer: EffectComposer, effectFXAA: ShaderPass, outlinePass: OutlinePass; - --let selectedObjects = []; -+let selectedObjects: THREE.Object3D[] = []; - - const raycaster = new THREE.Raycaster(); - const mouse = new THREE.Vector2(); -@@ -59,9 +59,14 @@ gui.add(params, 'usePatternTexture').onChange(function (value) { - outlinePass.usePatternTexture = value; - }); - --function Configuration() { -- this.visibleEdgeColor = '#ffffff'; -- this.hiddenEdgeColor = '#190a05'; -+class Configuration { -+ visibleEdgeColor: string; -+ hiddenEdgeColor: string; -+ -+ constructor() { -+ this.visibleEdgeColor = '#ffffff'; -+ this.hiddenEdgeColor = '#190a05'; -+ } - } - - const conf = new Configuration(); -@@ -223,7 +228,7 @@ function init() { - renderer.domElement.style.touchAction = 'none'; - renderer.domElement.addEventListener('pointermove', onPointerMove); - -- function onPointerMove(event) { -+ function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; -@@ -232,7 +237,7 @@ function init() { - checkIntersection(); - } - -- function addSelectedObject(object) { -+ function addSelectedObject(object: THREE.Object3D) { - selectedObjects = []; - selectedObjects.push(object); - } -diff --git a/examples-testing/examples/webgl_postprocessing_pixel.ts b/examples-testing/examples/webgl_postprocessing_pixel.ts -index 15b54d07..fdea0e6e 100644 ---- a/examples-testing/examples/webgl_postprocessing_pixel.ts -+++ b/examples-testing/examples/webgl_postprocessing_pixel.ts -@@ -6,8 +6,14 @@ import { RenderPixelatedPass } from 'three/addons/postprocessing/RenderPixelated - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, composer, crystalMesh, clock; --let gui, params; -+let camera: THREE.OrthographicCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ composer: EffectComposer, -+ crystalMesh: THREE.Mesh, -+ clock: THREE.Clock; -+let gui: GUI, -+ params: { pixelSize: number; normalEdgeStrength: number; depthEdgeStrength: number; pixelAlignedPanning: boolean }; - - init(); - -@@ -53,8 +59,14 @@ function init() { - .onChange(() => { - renderPixelatedPass.setPixelSize(params.pixelSize); - }); -- gui.add(renderPixelatedPass, 'normalEdgeStrength').min(0).max(2).step(0.05); -- gui.add(renderPixelatedPass, 'depthEdgeStrength').min(0).max(1).step(0.05); -+ gui.add(renderPixelatedPass as { normalEdgeStrength: number }, 'normalEdgeStrength') -+ .min(0) -+ .max(2) -+ .step(0.05); -+ gui.add(renderPixelatedPass as { depthEdgeStrength: number }, 'depthEdgeStrength') -+ .min(0) -+ .max(1) -+ .step(0.05); - gui.add(params, 'pixelAlignedPanning'); - - // textures -@@ -69,7 +81,7 @@ function init() { - - const boxMaterial = new THREE.MeshPhongMaterial({ map: texChecker2 }); - -- function addBox(boxSideLength, x, z, rotation) { -+ function addBox(boxSideLength: number, x: number, z: number, rotation: number) { - const mesh = new THREE.Mesh(new THREE.BoxGeometry(boxSideLength, boxSideLength, boxSideLength), boxMaterial); - mesh.castShadow = true; - mesh.receiveShadow = true; -@@ -166,7 +178,7 @@ function animate() { - - // Helper functions - --function pixelTexture(texture) { -+function pixelTexture(texture: THREE.Texture) { - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.generateMipmaps = false; -@@ -176,25 +188,30 @@ function pixelTexture(texture) { - return texture; - } - --function easeInOutCubic(x) { -+function easeInOutCubic(x: number) { - return x ** 2 * 3 - x ** 3 * 2; - } - --function linearStep(x, edge0, edge1) { -+function linearStep(x: number, edge0: number, edge1: number) { - const w = edge1 - edge0; - const m = 1 / w; - const y0 = -m * edge0; - return THREE.MathUtils.clamp(y0 + m * x, 0, 1); - } - --function stopGoEased(x, downtime, period) { -+function stopGoEased(x: number, downtime: number, period: number) { - const cycle = (x / period) | 0; - const tween = x - cycle * period; - const linStep = easeInOutCubic(linearStep(tween, downtime, period)); - return cycle + linStep; - } - --function pixelAlignFrustum(camera, aspectRatio, pixelsPerScreenWidth, pixelsPerScreenHeight) { -+function pixelAlignFrustum( -+ camera: THREE.OrthographicCamera, -+ aspectRatio: number, -+ pixelsPerScreenWidth: number, -+ pixelsPerScreenHeight: number, -+) { - // 0. Get Pixel Grid Units - const worldScreenWidth = (camera.right - camera.left) / camera.zoom; - const worldScreenHeight = (camera.top - camera.bottom) / camera.zoom; -diff --git a/examples-testing/examples/webgl_postprocessing_procedural.ts b/examples-testing/examples/webgl_postprocessing_procedural.ts -index 86982427..4533b72b 100644 ---- a/examples-testing/examples/webgl_postprocessing_procedural.ts -+++ b/examples-testing/examples/webgl_postprocessing_procedural.ts -@@ -3,16 +3,20 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let postCamera, postScene, renderer; --let postMaterial, noiseRandom1DMaterial, noiseRandom2DMaterial, noiseRandom3DMaterial, postQuad; --let stats; -+let postCamera: THREE.OrthographicCamera, postScene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let postMaterial: THREE.ShaderMaterial, -+ noiseRandom1DMaterial: THREE.ShaderMaterial, -+ noiseRandom2DMaterial: THREE.ShaderMaterial, -+ noiseRandom3DMaterial: THREE.ShaderMaterial, -+ postQuad: THREE.Mesh; -+let stats: Stats; - - const params = { procedure: 'noiseRandom3D' }; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); -@@ -26,16 +30,16 @@ function init() { - // Setup post processing stage - postCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); - noiseRandom1DMaterial = new THREE.ShaderMaterial({ -- vertexShader: document.querySelector('#procedural-vert').textContent.trim(), -- fragmentShader: document.querySelector('#noiseRandom1D-frag').textContent.trim(), -+ vertexShader: document.querySelector('#procedural-vert')!.textContent!.trim(), -+ fragmentShader: document.querySelector('#noiseRandom1D-frag')!.textContent!.trim(), - }); - noiseRandom2DMaterial = new THREE.ShaderMaterial({ -- vertexShader: document.querySelector('#procedural-vert').textContent.trim(), -- fragmentShader: document.querySelector('#noiseRandom2D-frag').textContent.trim(), -+ vertexShader: document.querySelector('#procedural-vert')!.textContent!.trim(), -+ fragmentShader: document.querySelector('#noiseRandom2D-frag')!.textContent!.trim(), - }); - noiseRandom3DMaterial = new THREE.ShaderMaterial({ -- vertexShader: document.querySelector('#procedural-vert').textContent.trim(), -- fragmentShader: document.querySelector('#noiseRandom3D-frag').textContent.trim(), -+ vertexShader: document.querySelector('#procedural-vert')!.textContent!.trim(), -+ fragmentShader: document.querySelector('#noiseRandom3D-frag')!.textContent!.trim(), - }); - postMaterial = noiseRandom3DMaterial; - const postPlane = new THREE.PlaneGeometry(2, 2); -diff --git a/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts b/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts -index fa46d4c8..2de78ec5 100644 ---- a/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts -+++ b/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts -@@ -8,11 +8,11 @@ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; - import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { HalftonePass } from 'three/addons/postprocessing/HalftonePass.js'; - --let renderer, clock, camera, stats; -+let renderer: THREE.WebGLRenderer, clock: THREE.Clock, camera: THREE.PerspectiveCamera, stats: Stats; - - const rotationSpeed = Math.PI / 64; - --let composer, group; -+let composer: EffectComposer, group: THREE.Group; - - init(); - -diff --git a/examples-testing/examples/webgl_postprocessing_sao.ts b/examples-testing/examples/webgl_postprocessing_sao.ts -index bf40d026..deb21b3f 100644 ---- a/examples-testing/examples/webgl_postprocessing_sao.ts -+++ b/examples-testing/examples/webgl_postprocessing_sao.ts -@@ -8,10 +8,10 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { SAOPass } from 'three/addons/postprocessing/SAOPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let container, stats; --let camera, scene, renderer; --let composer, renderPass, saoPass; --let group; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let composer: EffectComposer, renderPass: RenderPass, saoPass: SAOPass; -+let group: THREE.Object3D; - - init(); - -diff --git a/examples-testing/examples/webgl_postprocessing_smaa.ts b/examples-testing/examples/webgl_postprocessing_smaa.ts -index 6f71f647..44b765c1 100644 ---- a/examples-testing/examples/webgl_postprocessing_smaa.ts -+++ b/examples-testing/examples/webgl_postprocessing_smaa.ts -@@ -8,7 +8,12 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, scene, renderer, composer, stats, smaaPass; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ composer: EffectComposer, -+ stats: Stats, -+ smaaPass: SMAAPass; - - const params = { - enabled: true, -@@ -18,7 +23,7 @@ const params = { - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); -diff --git a/examples-testing/examples/webgl_postprocessing_sobel.ts b/examples-testing/examples/webgl_postprocessing_sobel.ts -index 55d88dc0..1512ed8b 100644 ---- a/examples-testing/examples/webgl_postprocessing_sobel.ts -+++ b/examples-testing/examples/webgl_postprocessing_sobel.ts -@@ -11,9 +11,9 @@ import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; - import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; - import { SobelOperatorShader } from 'three/addons/shaders/SobelOperatorShader.js'; - --let camera, scene, renderer, composer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, composer: EffectComposer; - --let effectSobel; -+let effectSobel: ShaderPass; - - const params = { - enable: true, -diff --git a/examples-testing/examples/webgl_postprocessing_ssaa.ts b/examples-testing/examples/webgl_postprocessing_ssaa.ts -index 429e02de..438d81e7 100644 ---- a/examples-testing/examples/webgl_postprocessing_ssaa.ts -+++ b/examples-testing/examples/webgl_postprocessing_ssaa.ts -@@ -7,10 +7,10 @@ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; - import { SSAARenderPass } from 'three/addons/postprocessing/SSAARenderPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let scene, renderer, composer; --let cameraP, ssaaRenderPassP; --let cameraO, ssaaRenderPassO; --let gui, stats; -+let scene: THREE.Scene, renderer: THREE.WebGLRenderer, composer: EffectComposer; -+let cameraP: THREE.PerspectiveCamera, ssaaRenderPassP: SSAARenderPass; -+let cameraO: THREE.OrthographicCamera, ssaaRenderPassO: SSAARenderPass; -+let gui: GUI, stats: Stats; - - const params = { - sampleLevel: 4, -@@ -50,7 +50,7 @@ function clearGui() { - } - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - const width = window.innerWidth || 1; - const height = window.innerHeight || 1; -@@ -198,7 +198,7 @@ function animate() { - ssaaRenderPassP.enabled = params.camera === 'perspective'; - ssaaRenderPassO.enabled = params.camera === 'orthographic'; - -- cameraP.view.offsetX = params.viewOffsetX; -+ cameraP.view!.offsetX = params.viewOffsetX; - - composer.render(); - -diff --git a/examples-testing/examples/webgl_postprocessing_ssao.ts b/examples-testing/examples/webgl_postprocessing_ssao.ts -index e55ab044..811417b6 100644 ---- a/examples-testing/examples/webgl_postprocessing_ssao.ts -+++ b/examples-testing/examples/webgl_postprocessing_ssao.ts -@@ -8,10 +8,10 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { SSAOPass } from 'three/addons/postprocessing/SSAOPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let container, stats; --let camera, scene, renderer; --let composer; --let group; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let composer: EffectComposer; -+let group: THREE.Group; - - init(); - -diff --git a/examples-testing/examples/webgl_postprocessing_ssr.ts b/examples-testing/examples/webgl_postprocessing_ssr.ts -index 307cfd1d..6b864359 100644 ---- a/examples-testing/examples/webgl_postprocessing_ssr.ts -+++ b/examples-testing/examples/webgl_postprocessing_ssr.ts -@@ -18,17 +18,17 @@ const params = { - otherMeshes: true, - groundReflector: true, - }; --let composer; --let ssrPass; --let gui; --let stats; --let controls; --let camera, scene, renderer; --const otherMeshes = []; --let groundReflector; --const selects = []; -- --const container = document.querySelector('#container'); -+let composer: EffectComposer; -+let ssrPass: SSRPass; -+let gui: GUI; -+let stats: Stats; -+let controls: OrbitControls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+const otherMeshes: THREE.Mesh[] = []; -+let groundReflector: ReflectorForSSRPass; -+const selects: THREE.Mesh[] = []; -+ -+const container = document.querySelector('#container')!; - - // Configure and create Draco decoder. - const dracoLoader = new DRACOLoader(); -@@ -77,7 +77,7 @@ function init() { - dracoLoader.dispose(); - }); - -- let geometry, material, mesh; -+ let geometry: THREE.BufferGeometry, material: THREE.MeshStandardMaterial, mesh: THREE.Mesh; - - geometry = new THREE.BoxGeometry(0.05, 0.05, 0.05); - material = new THREE.MeshStandardMaterial({ color: 'green' }); -diff --git a/examples-testing/examples/webgl_postprocessing_taa.ts b/examples-testing/examples/webgl_postprocessing_taa.ts -index 11a98674..ddb2bcc6 100644 ---- a/examples-testing/examples/webgl_postprocessing_taa.ts -+++ b/examples-testing/examples/webgl_postprocessing_taa.ts -@@ -8,8 +8,13 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, scene, renderer, composer, taaRenderPass, renderPass; --let gui, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ composer: EffectComposer, -+ taaRenderPass: TAARenderPass, -+ renderPass: RenderPass; -+let gui: GUI | undefined, stats: Stats; - let index = 0; - - const param = { TAAEnabled: '1', TAASampleLevel: 0 }; -@@ -50,7 +55,7 @@ function clearGui() { - } - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); -diff --git a/examples-testing/examples/webgl_postprocessing_transition.ts b/examples-testing/examples/webgl_postprocessing_transition.ts -index d0546613..8c5fb871 100644 ---- a/examples-testing/examples/webgl_postprocessing_transition.ts -+++ b/examples-testing/examples/webgl_postprocessing_transition.ts -@@ -7,10 +7,10 @@ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; - import { RenderTransitionPass } from 'three/addons/postprocessing/RenderTransitionPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let stats; --let renderer, composer, renderTransitionPass; -+let stats: Stats; -+let renderer: THREE.WebGLRenderer, composer: EffectComposer, renderTransitionPass: RenderTransitionPass; - --const textures = []; -+const textures: THREE.Texture[] = []; - const clock = new THREE.Clock(); - - const params = { -@@ -23,6 +23,56 @@ const params = { - threshold: 0.1, - }; - -+class FXScene { -+ rotationSpeed: THREE.Vector3; -+ -+ scene: THREE.Scene; -+ camera: THREE.PerspectiveCamera; -+ mesh: THREE.InstancedMesh; -+ -+ update: (delta: number) => void; -+ -+ resize: () => void; -+ -+ constructor(geometry: THREE.BufferGeometry, rotationSpeed: THREE.Vector3, backgroundColor: number) { -+ const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); -+ camera.position.z = 20; -+ -+ // Setup scene -+ const scene = new THREE.Scene(); -+ scene.background = new THREE.Color(backgroundColor); -+ scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); -+ -+ const light = new THREE.DirectionalLight(0xffffff, 3); -+ light.position.set(0, 1, 4); -+ scene.add(light); -+ -+ this.rotationSpeed = rotationSpeed; -+ -+ const color = geometry.type === 'BoxGeometry' ? 0x0000ff : 0xff0000; -+ const material = new THREE.MeshPhongMaterial({ color: color, flatShading: true }); -+ const mesh = generateInstancedMesh(geometry, material, 500); -+ scene.add(mesh); -+ -+ this.scene = scene; -+ this.camera = camera; -+ this.mesh = mesh; -+ -+ this.update = function (delta) { -+ if (params.sceneAnimate) { -+ mesh.rotation.x += this.rotationSpeed.x * delta; -+ mesh.rotation.y += this.rotationSpeed.y * delta; -+ mesh.rotation.z += this.rotationSpeed.z * delta; -+ } -+ }; -+ -+ this.resize = function () { -+ camera.aspect = window.innerWidth / window.innerHeight; -+ camera.updateProjectionMatrix(); -+ }; -+ } -+} -+ - const fxSceneA = new FXScene(new THREE.BoxGeometry(2, 2, 2), new THREE.Vector3(0, -0.4, 0), 0xffffff); - const fxSceneB = new FXScene(new THREE.IcosahedronGeometry(1, 1), new THREE.Vector3(0, 0.2, 0.1), 0x000000); - -@@ -138,45 +188,7 @@ function render() { - } - } - --function FXScene(geometry, rotationSpeed, backgroundColor) { -- const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); -- camera.position.z = 20; -- -- // Setup scene -- const scene = new THREE.Scene(); -- scene.background = new THREE.Color(backgroundColor); -- scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); -- -- const light = new THREE.DirectionalLight(0xffffff, 3); -- light.position.set(0, 1, 4); -- scene.add(light); -- -- this.rotationSpeed = rotationSpeed; -- -- const color = geometry.type === 'BoxGeometry' ? 0x0000ff : 0xff0000; -- const material = new THREE.MeshPhongMaterial({ color: color, flatShading: true }); -- const mesh = generateInstancedMesh(geometry, material, 500); -- scene.add(mesh); -- -- this.scene = scene; -- this.camera = camera; -- this.mesh = mesh; -- -- this.update = function (delta) { -- if (params.sceneAnimate) { -- mesh.rotation.x += this.rotationSpeed.x * delta; -- mesh.rotation.y += this.rotationSpeed.y * delta; -- mesh.rotation.z += this.rotationSpeed.z * delta; -- } -- }; -- -- this.resize = function () { -- camera.aspect = window.innerWidth / window.innerHeight; -- camera.updateProjectionMatrix(); -- }; --} -- --function generateInstancedMesh(geometry, material, count) { -+function generateInstancedMesh(geometry: THREE.BufferGeometry, material: THREE.MeshPhongMaterial, count: number) { - const mesh = new THREE.InstancedMesh(geometry, material, count); - - const dummy = new THREE.Object3D(); -diff --git a/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts b/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts -index 53ec2fe2..b407c23e 100644 ---- a/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts -+++ b/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts -@@ -10,8 +10,8 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, stats; --let composer, renderer, mixer, clock; -+let camera: THREE.PerspectiveCamera, stats: Stats; -+let composer: EffectComposer, renderer: THREE.WebGLRenderer, mixer: THREE.AnimationMixer, clock: THREE.Clock; - - const params = { - threshold: 0, -@@ -23,7 +23,7 @@ const params = { - init(); - - async function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - clock = new THREE.Clock(); - -diff --git a/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts b/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts -index d633806e..a25f53b5 100644 ---- a/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts -+++ b/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts -@@ -22,7 +22,7 @@ const params = { - }; - - const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' }); --const materials = {}; -+const materials: Record = {}; - - const renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); -@@ -60,8 +60,8 @@ const mixPass = new ShaderPass( - baseTexture: { value: null }, - bloomTexture: { value: bloomComposer.renderTarget2.texture }, - }, -- vertexShader: document.getElementById('vertexshader').textContent, -- fragmentShader: document.getElementById('fragmentshader').textContent, -+ vertexShader: document.getElementById('vertexshader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentshader')!.textContent!, - defines: {}, - }), - 'baseTexture', -@@ -112,7 +112,7 @@ toneMappingFolder.add(params, 'exposure', 0.1, 2).onChange(function (value) { - - setupScene(); - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - -@@ -165,9 +165,9 @@ function setupScene() { - render(); - } - --function disposeMaterial(obj) { -- if (obj.material) { -- obj.material.dispose(); -+function disposeMaterial(obj: THREE.Object3D) { -+ if ((obj as THREE.Mesh).material) { -+ ((obj as THREE.Mesh).material as THREE.Material).dispose(); - } - } - -@@ -180,16 +180,16 @@ function render() { - finalComposer.render(); - } - --function darkenNonBloomed(obj) { -- if (obj.isMesh && bloomLayer.test(obj.layers) === false) { -- materials[obj.uuid] = obj.material; -- obj.material = darkMaterial; -+function darkenNonBloomed(obj: THREE.Object3D) { -+ if ((obj as THREE.Mesh).isMesh && bloomLayer.test(obj.layers) === false) { -+ materials[obj.uuid] = (obj as THREE.Mesh).material; -+ (obj as THREE.Mesh).material = darkMaterial; - } - } - --function restoreMaterial(obj) { -+function restoreMaterial(obj: THREE.Object3D) { - if (materials[obj.uuid]) { -- obj.material = materials[obj.uuid]; -+ (obj as THREE.Mesh).material = materials[obj.uuid]; - delete materials[obj.uuid]; - } - } -diff --git a/examples-testing/examples/webgl_raycaster_sprite.ts b/examples-testing/examples/webgl_raycaster_sprite.ts -index f35d5de1..73dd9349 100644 ---- a/examples-testing/examples/webgl_raycaster_sprite.ts -+++ b/examples-testing/examples/webgl_raycaster_sprite.ts -@@ -2,10 +2,10 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let renderer, scene, camera; --let group; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let group: THREE.Group; - --let selectedObject = null; -+let selectedObject: THREE.Mesh | null = null; - const raycaster = new THREE.Raycaster(); - const pointer = new THREE.Vector2(); - -@@ -77,7 +77,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (selectedObject) { - selectedObject.material.color.set('#69f'); - selectedObject = null; -@@ -96,7 +96,7 @@ function onPointerMove(event) { - })[0]; - - if (res && res.object) { -- selectedObject = res.object; -+ selectedObject = res.object as THREE.Mesh; - selectedObject.material.color.set('#f00'); - } - } -diff --git a/examples-testing/examples/webgl_raycaster_texture.ts b/examples-testing/examples/webgl_raycaster_texture.ts -index 72c7054d..0e584dc0 100644 ---- a/examples-testing/examples/webgl_raycaster_texture.ts -+++ b/examples-testing/examples/webgl_raycaster_texture.ts -@@ -8,7 +8,15 @@ const WRAPPING = { - MirroredRepeatWrapping: THREE.MirroredRepeatWrapping, - }; - --const params = { -+const params: { -+ wrapS: THREE.Wrapping; -+ wrapT: THREE.Wrapping; -+ offsetX: number; -+ offsetY: number; -+ repeatX: number; -+ repeatY: number; -+ rotation: number; -+} = { - wrapS: THREE.RepeatWrapping, - wrapT: THREE.RepeatWrapping, - offsetX: 0, -@@ -18,68 +26,68 @@ const params = { - rotation: 0, - }; - --function CanvasTexture(parentTexture) { -- this._canvas = document.createElement('canvas'); -- this._canvas.width = this._canvas.height = 1024; -- this._context2D = this._canvas.getContext('2d'); -+class CanvasTexture { -+ _background: HTMLImageElement; - -- if (parentTexture) { -- this._parentTexture.push(parentTexture); -- parentTexture.image = this._canvas; -- } -+ constructor(parentTexture: THREE.Texture) { -+ this._canvas = document.createElement('canvas'); -+ this._canvas.width = this._canvas.height = 1024; -+ this._context2D = this._canvas.getContext('2d'); - -- const that = this; -- this._background = document.createElement('img'); -- this._background.addEventListener('load', function () { -- that._canvas.width = that._background.naturalWidth; -- that._canvas.height = that._background.naturalHeight; -+ if (parentTexture) { -+ this._parentTexture.push(parentTexture); -+ parentTexture.image = this._canvas; -+ } - -- that._crossRadius = Math.ceil(Math.min(that._canvas.width, that._canvas.height / 30)); -- that._crossMax = Math.ceil(0.70710678 * that._crossRadius); -- that._crossMin = Math.ceil(that._crossMax / 10); -- that._crossThickness = Math.ceil(that._crossMax / 10); -+ const that = this; -+ this._background = document.createElement('img'); -+ this._background.addEventListener('load', function () { -+ that._canvas!.width = that._background.naturalWidth; -+ that._canvas!.height = that._background.naturalHeight; - -- that._draw(); -- }); -- this._background.crossOrigin = ''; -- this._background.src = 'textures/uv_grid_opengl.jpg'; -+ that._crossRadius = Math.ceil(Math.min(that._canvas!.width, that._canvas!.height / 30)); -+ that._crossMax = Math.ceil(0.70710678 * that._crossRadius); -+ that._crossMin = Math.ceil(that._crossMax / 10); -+ that._crossThickness = Math.ceil(that._crossMax / 10); - -- this._draw(); --} -+ that._draw(); -+ }); -+ this._background.crossOrigin = ''; -+ this._background.src = 'textures/uv_grid_opengl.jpg'; - --CanvasTexture.prototype = { -- constructor: CanvasTexture, -+ this._draw(); -+ } - -- _canvas: null, -- _context2D: null, -- _xCross: 0, -- _yCross: 0, -+ _canvas: HTMLCanvasElement | null = null; -+ _context2D: CanvasRenderingContext2D | null = null; -+ _xCross = 0; -+ _yCross = 0; - -- _crossRadius: 57, -- _crossMax: 40, -- _crossMin: 4, -- _crossThickness: 4, -+ _crossRadius = 57; -+ _crossMax = 40; -+ _crossMin = 4; -+ _crossThickness = 4; - -- _parentTexture: [], -+ _parentTexture: THREE.Texture[] = []; - -- addParent: function (parentTexture) { -+ addParent = function (this: CanvasTexture, parentTexture: THREE.Texture) { - if (this._parentTexture.indexOf(parentTexture) === -1) { - this._parentTexture.push(parentTexture); - parentTexture.image = this._canvas; - } -- }, -+ }; - -- setCrossPosition: function (x, y) { -- this._xCross = x * this._canvas.width; -- this._yCross = y * this._canvas.height; -+ setCrossPosition = function (this: CanvasTexture, x: number, y: number) { -+ this._xCross = x * this._canvas!.width; -+ this._yCross = y * this._canvas!.height; - - this._draw(); -- }, -+ }; - -- _draw: function () { -+ _draw = function (this: CanvasTexture) { - if (!this._context2D) return; - -- this._context2D.clearRect(0, 0, this._canvas.width, this._canvas.height); -+ this._context2D.clearRect(0, 0, this._canvas!.width, this._canvas!.height); - - // Background. - this._context2D.drawImage(this._background, 0, 0); -@@ -106,18 +114,18 @@ CanvasTexture.prototype = { - for (let i = 0; i < this._parentTexture.length; i++) { - this._parentTexture[i].needsUpdate = true; - } -- }, --}; -+ }; -+} - - const width = window.innerWidth; - const height = window.innerHeight; - --let canvas; --let planeTexture, cubeTexture, circleTexture; -+let canvas: CanvasTexture; -+let planeTexture: THREE.Texture, cubeTexture: THREE.Texture, circleTexture: THREE.Texture; - --let container; -+let container: HTMLElement; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - const raycaster = new THREE.Raycaster(); - const mouse = new THREE.Vector2(); -@@ -126,7 +134,7 @@ const onClickPosition = new THREE.Vector2(); - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xeeeeee); -@@ -233,7 +241,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onMouseMove(evt) { -+function onMouseMove(evt: MouseEvent) { - evt.preventDefault(); - - const array = getMousePosition(container, evt.clientX, evt.clientY); -@@ -243,17 +251,19 @@ function onMouseMove(evt) { - - if (intersects.length > 0 && intersects[0].uv) { - const uv = intersects[0].uv; -- intersects[0].object.material.map.transformUv(uv); -+ (intersects[0].object as THREE.Mesh).material.map!.transformUv( -+ uv, -+ ); - canvas.setCrossPosition(uv.x, uv.y); - } - } - --function getMousePosition(dom, x, y) { -+function getMousePosition(dom: HTMLElement, x: number, y: number) { - const rect = dom.getBoundingClientRect(); - return [(x - rect.left) / rect.width, (y - rect.top) / rect.height]; - } - --function getIntersects(point, objects) { -+function getIntersects(point: THREE.Vector2, objects: THREE.Object3D[]) { - mouse.set(point.x * 2 - 1, -(point.y * 2) + 1); - - raycaster.setFromCamera(mouse, camera); -@@ -275,12 +285,12 @@ function animate() { - renderer.render(scene, camera); - } - --function setwrapS(value) { -+function setwrapS(value: THREE.Wrapping) { - circleTexture.wrapS = value; - circleTexture.needsUpdate = true; - } - --function setwrapT(value) { -+function setwrapT(value: THREE.Wrapping) { - circleTexture.wrapT = value; - circleTexture.needsUpdate = true; - } -diff --git a/examples-testing/examples/webgl_raymarching_reflect.ts b/examples-testing/examples/webgl_raymarching_reflect.ts -index e5448ebb..58fe2f1c 100644 ---- a/examples-testing/examples/webgl_raymarching_reflect.ts -+++ b/examples-testing/examples/webgl_raymarching_reflect.ts -@@ -5,11 +5,11 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let dolly, camera, scene, renderer; --let geometry, material, mesh; --let stats, clock; -+let dolly: THREE.Group, camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let geometry: THREE.PlaneGeometry, material: THREE.RawShaderMaterial, mesh; -+let stats: Stats, clock: THREE.Clock; - --const canvas = document.querySelector('#canvas'); -+const canvas = document.querySelector('#canvas') as HTMLCanvasElement; - - const config = { - saveImage: function () { -@@ -48,8 +48,8 @@ function init() { - cameraWorldMatrix: { value: camera.matrixWorld }, - cameraProjectionMatrixInverse: { value: camera.projectionMatrixInverse.clone() }, - }, -- vertexShader: document.getElementById('vertex_shader').textContent, -- fragmentShader: document.getElementById('fragment_shader').textContent, -+ vertexShader: document.getElementById('vertex_shader')!.textContent!, -+ fragmentShader: document.getElementById('fragment_shader')!.textContent!, - }); - mesh = new THREE.Mesh(geometry, material); - mesh.frustumCulled = false; -diff --git a/examples-testing/examples/webgl_read_float_buffer.ts b/examples-testing/examples/webgl_read_float_buffer.ts -index 68452a12..51fbce5e 100644 ---- a/examples-testing/examples/webgl_read_float_buffer.ts -+++ b/examples-testing/examples/webgl_read_float_buffer.ts -@@ -2,9 +2,14 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let cameraRTT, sceneRTT, sceneScreen, renderer, zmesh1, zmesh2; -+let cameraRTT: THREE.OrthographicCamera, -+ sceneRTT: THREE.Scene, -+ sceneScreen: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ zmesh1: THREE.Mesh, -+ zmesh2: THREE.Mesh; - - let mouseX = 0, - mouseY = 0; -@@ -12,15 +17,15 @@ let mouseX = 0, - const windowHalfX = window.innerWidth / 2; - const windowHalfY = window.innerHeight / 2; - --let rtTexture, material, quad; -+let rtTexture: THREE.WebGLRenderTarget, material: THREE.ShaderMaterial, quad: THREE.Mesh; - - let delta = 0.01; --let valueNode; -+let valueNode: HTMLElement; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - cameraRTT = new THREE.OrthographicCamera( - window.innerWidth / -2, -@@ -54,14 +59,14 @@ function init() { - - material = new THREE.ShaderMaterial({ - uniforms: { time: { value: 0.0 } }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragment_shader_pass_1').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragment_shader_pass_1')!.textContent!, - }); - - const materialScreen = new THREE.ShaderMaterial({ - uniforms: { tDiffuse: { value: rtTexture.texture } }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragment_shader_screen').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragment_shader_screen')!.textContent!, - - depthWrite: false, - }); -@@ -102,12 +107,12 @@ function init() { - stats = new Stats(); - container.appendChild(stats.dom); - -- valueNode = document.getElementById('values'); -+ valueNode = document.getElementById('values')!; - - document.addEventListener('mousemove', onDocumentMouseMove); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_refraction.ts b/examples-testing/examples/webgl_refraction.ts -index 572575af..169120a1 100644 ---- a/examples-testing/examples/webgl_refraction.ts -+++ b/examples-testing/examples/webgl_refraction.ts -@@ -4,14 +4,14 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Refractor } from 'three/addons/objects/Refractor.js'; - import { WaterRefractionShader } from 'three/addons/shaders/WaterRefractionShader.js'; - --let camera, scene, renderer, clock; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, clock: THREE.Clock; - --let refractor, smallSphere; -+let refractor: Refractor, smallSphere: THREE.Mesh; - - init(); - - async function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - clock = new THREE.Clock(); - -diff --git a/examples-testing/examples/webgl_rtt.ts b/examples-testing/examples/webgl_rtt.ts -index 9f16fdab..9c70a341 100644 ---- a/examples-testing/examples/webgl_rtt.ts -+++ b/examples-testing/examples/webgl_rtt.ts -@@ -2,9 +2,16 @@ import * as THREE from 'three'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLElement, stats: Stats; - --let cameraRTT, camera, sceneRTT, sceneScreen, scene, renderer, zmesh1, zmesh2; -+let cameraRTT: THREE.OrthographicCamera, -+ camera: THREE.PerspectiveCamera, -+ sceneRTT: THREE.Scene, -+ sceneScreen: THREE.Scene, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ zmesh1: THREE.Mesh, -+ zmesh2: THREE.Mesh; - - let mouseX = 0, - mouseY = 0; -@@ -12,14 +19,14 @@ let mouseX = 0, - const windowHalfX = window.innerWidth / 2; - const windowHalfY = window.innerHeight / 2; - --let rtTexture, material, quad; -+let rtTexture: THREE.WebGLRenderTarget, material: THREE.ShaderMaterial, quad: THREE.Mesh; - - let delta = 0.01; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 100; -@@ -52,14 +59,14 @@ function init() { - - material = new THREE.ShaderMaterial({ - uniforms: { time: { value: 0.0 } }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragment_shader_pass_1').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragment_shader_pass_1')!.textContent!, - }); - - const materialScreen = new THREE.ShaderMaterial({ - uniforms: { tDiffuse: { value: rtTexture.texture } }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragment_shader_screen').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragment_shader_screen')!.textContent!, - - depthWrite: false, - }); -@@ -121,7 +128,7 @@ function init() { - document.addEventListener('mousemove', onDocumentMouseMove); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; - } -diff --git a/examples-testing/examples/webgl_shader.ts b/examples-testing/examples/webgl_shader.ts -index 47a6c7ec..7ac1257b 100644 ---- a/examples-testing/examples/webgl_shader.ts -+++ b/examples-testing/examples/webgl_shader.ts -@@ -1,13 +1,13 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; -+let camera: THREE.OrthographicCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let uniforms; -+let uniforms: Record>; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); - -@@ -21,8 +21,8 @@ function init() { - - const material = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - }); - - const mesh = new THREE.Mesh(geometry, material); -diff --git a/examples-testing/examples/webgl_shader_lava.ts b/examples-testing/examples/webgl_shader_lava.ts -index 973a580e..a5d1f1af 100644 ---- a/examples-testing/examples/webgl_shader_lava.ts -+++ b/examples-testing/examples/webgl_shader_lava.ts -@@ -5,14 +5,22 @@ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; - import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; - import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - --let camera, renderer, composer, clock; -- --let uniforms, mesh; -+let camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, composer: EffectComposer, clock: THREE.Clock; -+ -+let uniforms: { -+ fogDensity: THREE.IUniform; -+ fogColor: THREE.IUniform; -+ time: THREE.IUniform; -+ uvScale: THREE.IUniform; -+ texture1: THREE.IUniform; -+ texture2: THREE.IUniform; -+ }, -+ mesh: THREE.Mesh; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 3000); - camera.position.z = 4; -@@ -44,8 +52,8 @@ function init() { - - const material = new THREE.ShaderMaterial({ - uniforms: uniforms, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - }); - - mesh = new THREE.Mesh(new THREE.TorusGeometry(size, 0.3, 30, 30), material); -diff --git a/examples-testing/examples/webgl_shaders_ocean.ts b/examples-testing/examples/webgl_shaders_ocean.ts -index 8b0f9a73..afbdb1da 100644 ---- a/examples-testing/examples/webgl_shaders_ocean.ts -+++ b/examples-testing/examples/webgl_shaders_ocean.ts -@@ -7,14 +7,14 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Water } from 'three/addons/objects/Water.js'; - import { Sky } from 'three/addons/objects/Sky.js'; - --let container, stats; --let camera, scene, renderer; --let controls, water, sun, mesh; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controls: OrbitControls, water: Water, sun: THREE.Vector3, mesh: THREE.Mesh; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -79,7 +79,7 @@ function init() { - const pmremGenerator = new THREE.PMREMGenerator(renderer); - const sceneEnv = new THREE.Scene(); - -- let renderTarget; -+ let renderTarget: THREE.WebGLRenderTarget; - - function updateSun() { - const phi = THREE.MathUtils.degToRad(90 - parameters.elevation); -diff --git a/examples-testing/examples/webgl_shaders_sky.ts b/examples-testing/examples/webgl_shaders_sky.ts -index 18020f78..3b61996d 100644 ---- a/examples-testing/examples/webgl_shaders_sky.ts -+++ b/examples-testing/examples/webgl_shaders_sky.ts -@@ -4,9 +4,9 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Sky } from 'three/addons/objects/Sky.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let sky, sun; -+let sky: Sky, sun: THREE.Vector3; - - init(); - render(); -diff --git a/examples-testing/examples/webgl_shadow_contact.ts b/examples-testing/examples/webgl_shadow_contact.ts -index 9eda35b8..0c262569 100644 ---- a/examples-testing/examples/webgl_shadow_contact.ts -+++ b/examples-testing/examples/webgl_shadow_contact.ts -@@ -5,9 +5,9 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { HorizontalBlurShader } from 'three/addons/shaders/HorizontalBlurShader.js'; - import { VerticalBlurShader } from 'three/addons/shaders/VerticalBlurShader.js'; - --let camera, scene, renderer, stats, gui; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats, gui; - --const meshes = []; -+const meshes: THREE.Mesh[] = []; - - const PLANE_WIDTH = 2.5; - const PLANE_HEIGHT = 2.5; -@@ -26,16 +26,18 @@ const state = { - showWireframe: false, - }; - --let shadowGroup, -- renderTarget, -- renderTargetBlur, -- shadowCamera, -- cameraHelper, -- depthMaterial, -- horizontalBlurMaterial, -- verticalBlurMaterial; -+let shadowGroup: THREE.Group, -+ renderTarget: THREE.WebGLRenderTarget, -+ renderTargetBlur: THREE.WebGLRenderTarget, -+ shadowCamera: THREE.OrthographicCamera, -+ cameraHelper: THREE.CameraHelper, -+ depthMaterial: THREE.MeshDepthMaterial, -+ horizontalBlurMaterial: THREE.ShaderMaterial, -+ verticalBlurMaterial: THREE.ShaderMaterial; - --let plane, blurPlane, fillPlane; -+let plane: THREE.Mesh, -+ blurPlane: THREE.Mesh, -+ fillPlane: THREE.Mesh; - - init(); - -@@ -206,7 +208,7 @@ function onWindowResize() { - } - - // renderTarget --> blurPlane (horizontalBlur) --> renderTargetBlur --> blurPlane (verticalBlur) --> renderTarget --function blurShadow(amount) { -+function blurShadow(amount: number) { - blurPlane.visible = true; - - // blur horizontally and draw in the renderTargetBlur -diff --git a/examples-testing/examples/webgl_shadowmap.ts b/examples-testing/examples/webgl_shadowmap.ts -index 6d0ac3ad..d03a38a3 100644 ---- a/examples-testing/examples/webgl_shadowmap.ts -+++ b/examples-testing/examples/webgl_shadowmap.ts -@@ -15,18 +15,18 @@ let SCREEN_WIDTH = window.innerWidth; - let SCREEN_HEIGHT = window.innerHeight; - const FLOOR = -250; - --let camera, controls, scene, renderer; --let container, stats; -+let camera: THREE.PerspectiveCamera, controls: FirstPersonControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let container: HTMLDivElement, stats: Stats; - - const NEAR = 10, - FAR = 3000; - --let mixer; -+let mixer: THREE.AnimationMixer; - --const morphs = []; -+const morphs: (THREE.Mesh & { speed?: number })[] = []; - --let light; --let lightShadowMapViewer; -+let light: THREE.DirectionalLight; -+let lightShadowMapViewer: ShadowMapViewer; - - const clock = new THREE.Clock(); - -@@ -121,7 +121,7 @@ function onWindowResize() { - controls.handleResize(); - } - --function onKeyDown(event) { -+function onKeyDown(event: KeyboardEvent) { - switch (event.keyCode) { - case 84 /*t*/: - showHUD = !showHUD; -@@ -172,7 +172,7 @@ function createScene() { - }); - - textGeo.computeBoundingBox(); -- const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); -+ const centerOffset = -0.5 * (textGeo.boundingBox!.max.x - textGeo.boundingBox!.min.x); - - const textMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000, specular: 0xffffff }); - -@@ -212,7 +212,16 @@ function createScene() { - - mixer = new THREE.AnimationMixer(scene); - -- function addMorph(mesh, clip, speed, duration, x, y, z, fudgeColor) { -+ function addMorph( -+ mesh: THREE.Mesh & { speed?: number }, -+ clip: THREE.AnimationClip, -+ speed: number, -+ duration: number, -+ x: number, -+ y: number, -+ z: number, -+ fudgeColor?: boolean, -+ ) { - mesh = mesh.clone(); - mesh.material = mesh.material.clone(); - -@@ -243,7 +252,7 @@ function createScene() { - const gltfloader = new GLTFLoader(); - - gltfloader.load('models/gltf/Horse.glb', function (gltf) { -- const mesh = gltf.scene.children[0]; -+ const mesh = gltf.scene.children[0] as THREE.Mesh; - - const clip = gltf.animations[0]; - -@@ -257,21 +266,21 @@ function createScene() { - }); - - gltfloader.load('models/gltf/Flamingo.glb', function (gltf) { -- const mesh = gltf.scene.children[0]; -+ const mesh = gltf.scene.children[0] as THREE.Mesh; - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 500, 1, 500 - Math.random() * 500, FLOOR + 350, 40); - }); - - gltfloader.load('models/gltf/Stork.glb', function (gltf) { -- const mesh = gltf.scene.children[0]; -+ const mesh = gltf.scene.children[0] as THREE.Mesh; - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 350, 1, 500 - Math.random() * 500, FLOOR + 350, 340); - }); - - gltfloader.load('models/gltf/Parrot.glb', function (gltf) { -- const mesh = gltf.scene.children[0]; -+ const mesh = gltf.scene.children[0] as THREE.Mesh; - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 450, 0.5, 500 - Math.random() * 500, FLOOR + 300, 700); -@@ -291,7 +300,7 @@ function render() { - for (let i = 0; i < morphs.length; i++) { - const morph = morphs[i]; - -- morph.position.x += morph.speed * delta; -+ morph.position.x += morph.speed! * delta; - - if (morph.position.x > 2000) { - morph.position.x = -1000 - Math.random() * 500; -diff --git a/examples-testing/examples/webgl_shadowmap_csm.ts b/examples-testing/examples/webgl_shadowmap_csm.ts -index c89bc02d..4da2da35 100644 ---- a/examples-testing/examples/webgl_shadowmap_csm.ts -+++ b/examples-testing/examples/webgl_shadowmap_csm.ts -@@ -2,12 +2,32 @@ import * as THREE from 'three'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; --import { CSM } from 'three/addons/csm/CSM.js'; -+import { CSM, CSMMode } from 'three/addons/csm/CSM.js'; - import { CSMHelper } from 'three/addons/csm/CSMHelper.js'; - --let renderer, scene, camera, orthoCamera, controls, csm, csmHelper; -- --const params = { -+let renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ orthoCamera: THREE.OrthographicCamera, -+ controls: OrbitControls, -+ csm: CSM, -+ csmHelper: CSMHelper; -+ -+const params: { -+ orthographic: boolean; -+ fade: boolean; -+ shadows: boolean; -+ far: number; -+ mode: CSMMode; -+ lightX: number; -+ lightY: number; -+ lightZ: number; -+ margin: number; -+ lightFar: number; -+ lightNear: number; -+ autoUpdateHelper: boolean; -+ updateHelper: () => void; -+} = { - orthographic: false, - fade: false, - shadows: true, -@@ -133,8 +153,8 @@ function init() { - renderer.shadowMap.enabled = value; - - scene.traverse(function (child) { -- if (child.material) { -- child.material.needsUpdate = true; -+ if ((child as THREE.Mesh).material) { -+ (child as THREE.Mesh).material.needsUpdate = true; - } - }); - }); -diff --git a/examples-testing/examples/webgl_shadowmap_pcss.ts b/examples-testing/examples/webgl_shadowmap_pcss.ts -index a47a011f..7e1f5fb3 100644 ---- a/examples-testing/examples/webgl_shadowmap_pcss.ts -+++ b/examples-testing/examples/webgl_shadowmap_pcss.ts -@@ -4,10 +4,10 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let stats; --let camera, scene, renderer; -+let stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let group; -+let group: THREE.Group; - - init(); - -@@ -95,12 +95,12 @@ function init() { - - shader = shader.replace( - '#ifdef USE_SHADOWMAP', -- '#ifdef USE_SHADOWMAP' + document.getElementById('PCSS').textContent, -+ '#ifdef USE_SHADOWMAP' + document.getElementById('PCSS')!.textContent, - ); - - shader = shader.replace( - '#if defined( SHADOWMAP_TYPE_PCF )', -- document.getElementById('PCSSGetShadow').textContent + '#if defined( SHADOWMAP_TYPE_PCF )', -+ document.getElementById('PCSSGetShadow')!.textContent + '#if defined( SHADOWMAP_TYPE_PCF )', - ); - - THREE.ShaderChunk.shadowmap_pars_fragment = shader; -diff --git a/examples-testing/examples/webgl_shadowmap_performance.ts b/examples-testing/examples/webgl_shadowmap_performance.ts -index 0e45b63f..1b61f3db 100644 ---- a/examples-testing/examples/webgl_shadowmap_performance.ts -+++ b/examples-testing/examples/webgl_shadowmap_performance.ts -@@ -16,16 +16,16 @@ const FLOOR = -250; - - const ANIMATION_GROUPS = 25; - --let camera, controls, scene, renderer; --let stats; -+let camera: THREE.PerspectiveCamera, controls: FirstPersonControls, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let stats: Stats; - - const NEAR = 5, - FAR = 3000; - --let morph, mixer; -+let morph, mixer: THREE.AnimationMixer; - --const morphs = [], -- animGroups = []; -+const morphs: (THREE.Mesh & { speed?: number })[] = [], -+ animGroups: THREE.AnimationObjectGroup[] = []; - - const clock = new THREE.Clock(); - -@@ -150,7 +150,7 @@ function createScene() { - }); - - textGeo.computeBoundingBox(); -- const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); -+ const centerOffset = -0.5 * (textGeo.boundingBox!.max.x - textGeo.boundingBox!.min.x); - - const textMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000, specular: 0xffffff }); - -@@ -195,7 +195,17 @@ function createScene() { - - // MORPHS - -- function addMorph(mesh, clip, speed, duration, x, y, z, fudgeColor, massOptimization) { -+ function addMorph( -+ mesh: THREE.Mesh & { speed?: number }, -+ clip: THREE.AnimationClip, -+ speed: number, -+ duration: number, -+ x: number, -+ y: number, -+ z: number, -+ fudgeColor: boolean, -+ massOptimization: boolean, -+ ) { - mesh = mesh.clone(); - mesh.material = mesh.material.clone(); - -@@ -242,7 +252,7 @@ function createScene() { - - const gltfLoader = new GLTFLoader(); - gltfLoader.load('models/gltf/Horse.glb', function (gltf) { -- const mesh = gltf.scene.children[0]; -+ const mesh = gltf.scene.children[0] as THREE.Mesh; - const clip = gltf.animations[0]; - - for (let i = -600; i < 601; i += 2) { -@@ -267,7 +277,7 @@ function render() { - for (let i = 0; i < morphs.length; i++) { - morph = morphs[i]; - -- morph.position.x += morph.speed * delta; -+ morph.position.x += morph.speed! * delta; - - if (morph.position.x > 2000) { - morph.position.x = -1000 - Math.random() * 500; -diff --git a/examples-testing/examples/webgl_shadowmap_pointlight.ts b/examples-testing/examples/webgl_shadowmap_pointlight.ts -index c68d6974..996aedd4 100644 ---- a/examples-testing/examples/webgl_shadowmap_pointlight.ts -+++ b/examples-testing/examples/webgl_shadowmap_pointlight.ts -@@ -4,8 +4,8 @@ import Stats from 'three/addons/libs/stats.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, stats; --let pointLight, pointLight2; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, stats: Stats; -+let pointLight: THREE.PointLight, pointLight2: THREE.PointLight; - - init(); - -@@ -18,7 +18,7 @@ function init() { - - // lights - -- function createLight(color) { -+ function createLight(color: number) { - const intensity = 200; - - const light = new THREE.PointLight(color, intensity, 20); -@@ -26,9 +26,9 @@ function init() { - light.shadow.bias = -0.005; // reduces self-shadowing on double-sided objects - - let geometry = new THREE.SphereGeometry(0.3, 12, 6); -- let material = new THREE.MeshBasicMaterial({ color: color }); -+ let material: THREE.MeshBasicMaterial | THREE.MeshPhongMaterial = new THREE.MeshBasicMaterial({ color: color }); - material.color.multiplyScalar(intensity); -- let sphere = new THREE.Mesh(geometry, material); -+ let sphere = new THREE.Mesh(geometry, material); - light.add(sphere); - - const texture = new THREE.CanvasTexture(generateTexture()); -@@ -107,7 +107,7 @@ function generateTexture() { - canvas.width = 2; - canvas.height = 2; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - context.fillStyle = 'white'; - context.fillRect(0, 1, 2, 1); - -diff --git a/examples-testing/examples/webgl_shadowmap_progressive.ts b/examples-testing/examples/webgl_shadowmap_progressive.ts -index e9f6b5b9..6ad8a650 100644 ---- a/examples-testing/examples/webgl_shadowmap_progressive.ts -+++ b/examples-testing/examples/webgl_shadowmap_progressive.ts -@@ -9,17 +9,17 @@ import { ProgressiveLightMap } from 'three/addons/misc/ProgressiveLightMap.js'; - const shadowMapRes = 512, - lightMapRes = 1024, - lightCount = 8; --let camera, -- scene, -- renderer, -- controls, -- control, -- control2, -- object = new THREE.Mesh(), -- lightOrigin = null, -- progressiveSurfacemap; --const dirLights = [], -- lightmapObjects = []; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ controls: OrbitControls, -+ control: TransformControls, -+ control2: TransformControls, -+ object: THREE.Object3D = new THREE.Mesh(), -+ lightOrigin: THREE.Group | null = null, -+ progressiveSurfacemap: ProgressiveLightMap; -+const dirLights: THREE.DirectionalLight[] = [], -+ lightmapObjects: THREE.Object3D[] = []; - const params = { - Enable: true, - 'Blur Edges': true, -@@ -98,11 +98,11 @@ function init() { - // model - function loadModel() { - object.traverse(function (child) { -- if (child.isMesh) { -+ if ((child as THREE.Mesh).isMesh) { - child.name = 'Loaded Mesh'; - child.castShadow = true; - child.receiveShadow = true; -- child.material = new THREE.MeshPhongMaterial(); -+ (child as THREE.Mesh).material = new THREE.MeshPhongMaterial(); - - // This adds the model to the lightmap - lightmapObjects.push(child); -@@ -183,9 +183,9 @@ function animate() { - // Sometimes they will be uniformly sampled from the upper hemisphere - if (Math.random() > params['Ambient Weight']) { - dirLights[l].position.set( -- lightOrigin.position.x + Math.random() * params['Light Radius'], -- lightOrigin.position.y + Math.random() * params['Light Radius'], -- lightOrigin.position.z + Math.random() * params['Light Radius'], -+ lightOrigin!.position.x + Math.random() * params['Light Radius'], -+ lightOrigin!.position.y + Math.random() * params['Light Radius'], -+ lightOrigin!.position.z + Math.random() * params['Light Radius'], - ); - } else { - // Uniform Hemispherical Surface Distribution for Ambient Occlusion -diff --git a/examples-testing/examples/webgl_shadowmap_viewer.ts b/examples-testing/examples/webgl_shadowmap_viewer.ts -index f974ef03..755278b8 100644 ---- a/examples-testing/examples/webgl_shadowmap_viewer.ts -+++ b/examples-testing/examples/webgl_shadowmap_viewer.ts -@@ -5,10 +5,14 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { ShadowMapViewer } from 'three/addons/utils/ShadowMapViewer.js'; - --let camera, scene, renderer, clock, stats; --let dirLight, spotLight; --let torusKnot, cube; --let dirLightShadowMapViewer, spotLightShadowMapViewer; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ clock: THREE.Clock, -+ stats: Stats; -+let dirLight: THREE.DirectionalLight, spotLight: THREE.SpotLight; -+let torusKnot: THREE.Mesh, cube: THREE.Mesh; -+let dirLightShadowMapViewer: ShadowMapViewer, spotLightShadowMapViewer: ShadowMapViewer; - - init(); - -@@ -62,7 +66,7 @@ function initScene() { - scene.add(new THREE.CameraHelper(dirLight.shadow.camera)); - - // Geometry -- let geometry = new THREE.TorusKnotGeometry(25, 8, 75, 20); -+ let geometry: THREE.BufferGeometry = new THREE.TorusKnotGeometry(25, 8, 75, 20); - let material = new THREE.MeshPhongMaterial({ - color: 0xff0000, - shininess: 150, -diff --git a/examples-testing/examples/webgl_shadowmap_vsm.ts b/examples-testing/examples/webgl_shadowmap_vsm.ts -index 4867c731..2e2ccaa9 100644 ---- a/examples-testing/examples/webgl_shadowmap_vsm.ts -+++ b/examples-testing/examples/webgl_shadowmap_vsm.ts -@@ -5,9 +5,13 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, clock, stats; --let dirLight, spotLight; --let torusKnot, dirGroup; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ clock: THREE.Clock, -+ stats: Stats; -+let dirLight: THREE.DirectionalLight, spotLight: THREE.SpotLight; -+let torusKnot: THREE.Mesh, dirGroup: THREE.Group; - - init(); - -@@ -184,7 +188,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function animate(time) { -+function animate(time: DOMHighResTimeStamp) { - const delta = clock.getDelta(); - - torusKnot.rotation.x += 0.25 * delta; -@@ -192,7 +196,7 @@ function animate(time) { - torusKnot.rotation.z += 1 * delta; - - dirGroup.rotation.y += 0.7 * delta; -- dirLight.position.z = 17 + Math.sin(time * 0.001) * 5; -+ dirLight.position.z = 17 + Math.sin(time! * 0.001) * 5; - - renderer.render(scene, camera); - -diff --git a/examples-testing/examples/webgl_shadowmesh.ts b/examples-testing/examples/webgl_shadowmesh.ts -index 412fc028..6043a477 100644 ---- a/examples-testing/examples/webgl_shadowmesh.ts -+++ b/examples-testing/examples/webgl_shadowmesh.ts -@@ -12,18 +12,18 @@ const renderer = new THREE.WebGLRenderer({ stencil: true }); - - const sunLight = new THREE.DirectionalLight('rgb(255,255,255)', 3); - let useDirectionalLight = true; --let arrowHelper1, arrowHelper2, arrowHelper3; -+let arrowHelper1: THREE.ArrowHelper, arrowHelper2: THREE.ArrowHelper, arrowHelper3: THREE.ArrowHelper; - const arrowDirection = new THREE.Vector3(); - const arrowPosition1 = new THREE.Vector3(); - const arrowPosition2 = new THREE.Vector3(); - const arrowPosition3 = new THREE.Vector3(); --let groundMesh; --let lightSphere, lightHolder; --let pyramid, pyramidShadow; --let sphere, sphereShadow; --let cube, cubeShadow; --let cylinder, cylinderShadow; --let torus, torusShadow; -+let groundMesh: THREE.Mesh; -+let lightSphere: THREE.Mesh, lightHolder: THREE.Mesh; -+let pyramid: THREE.Mesh, pyramidShadow: ShadowMesh; -+let sphere: THREE.Mesh, sphereShadow: ShadowMesh; -+let cube: THREE.Mesh, cubeShadow: ShadowMesh; -+let cylinder: THREE.Mesh, cylinderShadow: ShadowMesh; -+let torus: THREE.Mesh, torusShadow: ShadowMesh; - const normalVector = new THREE.Vector3(0, 1, 0); - const planeConstant = 0.01; // this value must be slightly higher than the groundMesh's y position of 0.0 - const groundPlane = new THREE.Plane(normalVector, planeConstant); -@@ -41,7 +41,7 @@ function init() { - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); -- document.getElementById('container').appendChild(renderer.domElement); -+ document.getElementById('container')!.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - -@@ -150,7 +150,7 @@ function init() { - pyramidShadow = new ShadowMesh(pyramid); - scene.add(pyramidShadow); - -- document.getElementById('lightButton').addEventListener('click', lightButtonHandler); -+ document.getElementById('lightButton')!.addEventListener('click', lightButtonHandler); - } - - function animate() { -@@ -203,7 +203,7 @@ function lightButtonHandler() { - useDirectionalLight = !useDirectionalLight; - - if (useDirectionalLight) { -- scene.background.setHex(0x0096ff); -+ (scene.background as THREE.Color).setHex(0x0096ff); - - groundMesh.material.color.setHex(0x008200); - sunLight.position.set(5, 7, -1); -@@ -221,9 +221,9 @@ function lightButtonHandler() { - lightSphere.visible = false; - lightHolder.visible = false; - -- document.getElementById('lightButton').value = 'Switch to PointLight'; -+ (document.getElementById('lightButton') as HTMLButtonElement).value = 'Switch to PointLight'; - } else { -- scene.background.setHex(0x000000); -+ (scene.background as THREE.Color).setHex(0x000000); - - groundMesh.material.color.setHex(0x969696); - -@@ -245,6 +245,6 @@ function lightButtonHandler() { - lightSphere.visible = true; - lightHolder.visible = true; - -- document.getElementById('lightButton').value = 'Switch to THREE.DirectionalLight'; -+ (document.getElementById('lightButton') as HTMLButtonElement).value = 'Switch to THREE.DirectionalLight'; - } - } -diff --git a/examples-testing/examples/webgl_simple_gi.ts b/examples-testing/examples/webgl_simple_gi.ts -index 4ab6dc89..adea084a 100644 ---- a/examples-testing/examples/webgl_simple_gi.ts -+++ b/examples-testing/examples/webgl_simple_gi.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - - class GIMesh extends THREE.Mesh { -- copy(source) { -+ copy(source: this) { - super.copy(source); - - this.geometry = source.geometry.clone(); -@@ -14,104 +14,109 @@ class GIMesh extends THREE.Mesh { - - // - --const SimpleGI = function (renderer, scene) { -- const SIZE = 32, -- SIZE2 = SIZE * SIZE; -+class SimpleGI { -+ constructor(renderer: THREE.WebGLRenderer, scene: THREE.Scene) { -+ const SIZE = 32, -+ SIZE2 = SIZE * SIZE; - -- const camera = new THREE.PerspectiveCamera(90, 1, 0.01, 100); -+ const camera = new THREE.PerspectiveCamera(90, 1, 0.01, 100); - -- scene.updateMatrixWorld(true); -+ scene.updateMatrixWorld(true); - -- let clone = scene.clone(); -- clone.matrixWorldAutoUpdate = false; -+ let clone = scene.clone(); -+ clone.matrixWorldAutoUpdate = false; - -- const rt = new THREE.WebGLRenderTarget(SIZE, SIZE); -+ const rt = new THREE.WebGLRenderTarget(SIZE, SIZE); - -- const normalMatrix = new THREE.Matrix3(); -+ const normalMatrix = new THREE.Matrix3(); - -- const position = new THREE.Vector3(); -- const normal = new THREE.Vector3(); -+ const position = new THREE.Vector3(); -+ const normal = new THREE.Vector3(); - -- let bounces = 0; -- let currentVertex = 0; -+ let bounces = 0; -+ let currentVertex = 0; - -- const color = new Float32Array(3); -- const buffer = new Uint8Array(SIZE2 * 4); -+ const color = new Float32Array(3); -+ const buffer = new Uint8Array(SIZE2 * 4); - -- function compute() { -- if (bounces === 3) return; -+ function compute() { -+ if (bounces === 3) return; - -- const object = scene.children[0]; // torusKnot -- const geometry = object.geometry; -+ const object = scene.children[0] as GIMesh; // torusKnot -+ const geometry = object.geometry; - -- const attributes = geometry.attributes; -- const positions = attributes.position.array; -- const normals = attributes.normal.array; -+ const attributes = geometry.attributes; -+ const positions = attributes.position.array; -+ const normals = attributes.normal.array; - -- if (attributes.color === undefined) { -- const colors = new Float32Array(positions.length); -- geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3).setUsage(THREE.DynamicDrawUsage)); -- } -+ if (attributes.color === undefined) { -+ const colors = new Float32Array(positions.length); -+ geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3).setUsage(THREE.DynamicDrawUsage)); -+ } - -- const colors = attributes.color.array; -+ const colors = attributes.color.array; - -- const startVertex = currentVertex; -- const totalVertex = positions.length / 3; -+ const startVertex = currentVertex; -+ const totalVertex = positions.length / 3; - -- for (let i = 0; i < 32; i++) { -- if (currentVertex >= totalVertex) break; -+ for (let i = 0; i < 32; i++) { -+ if (currentVertex >= totalVertex) break; - -- position.fromArray(positions, currentVertex * 3); -- position.applyMatrix4(object.matrixWorld); -+ position.fromArray(positions, currentVertex * 3); -+ position.applyMatrix4(object.matrixWorld); - -- normal.fromArray(normals, currentVertex * 3); -- normal.applyMatrix3(normalMatrix.getNormalMatrix(object.matrixWorld)).normalize(); -+ normal.fromArray(normals, currentVertex * 3); -+ normal.applyMatrix3(normalMatrix.getNormalMatrix(object.matrixWorld)).normalize(); - -- camera.position.copy(position); -- camera.lookAt(position.add(normal)); -+ camera.position.copy(position); -+ camera.lookAt(position.add(normal)); - -- renderer.setRenderTarget(rt); -- renderer.render(clone, camera); -+ renderer.setRenderTarget(rt); -+ renderer.render(clone, camera); - -- renderer.readRenderTargetPixels(rt, 0, 0, SIZE, SIZE, buffer); -+ renderer.readRenderTargetPixels(rt, 0, 0, SIZE, SIZE, buffer); - -- color[0] = 0; -- color[1] = 0; -- color[2] = 0; -+ color[0] = 0; -+ color[1] = 0; -+ color[2] = 0; - -- for (let k = 0, kl = buffer.length; k < kl; k += 4) { -- color[0] += buffer[k + 0]; -- color[1] += buffer[k + 1]; -- color[2] += buffer[k + 2]; -- } -+ for (let k = 0, kl = buffer.length; k < kl; k += 4) { -+ color[0] += buffer[k + 0]; -+ color[1] += buffer[k + 1]; -+ color[2] += buffer[k + 2]; -+ } - -- colors[currentVertex * 3 + 0] = color[0] / (SIZE2 * 255); -- colors[currentVertex * 3 + 1] = color[1] / (SIZE2 * 255); -- colors[currentVertex * 3 + 2] = color[2] / (SIZE2 * 255); -+ colors[currentVertex * 3 + 0] = color[0] / (SIZE2 * 255); -+ colors[currentVertex * 3 + 1] = color[1] / (SIZE2 * 255); -+ colors[currentVertex * 3 + 2] = color[2] / (SIZE2 * 255); - -- currentVertex++; -- } -+ currentVertex++; -+ } - -- attributes.color.addUpdateRange(startVertex * 3, (currentVertex - startVertex) * 3); -- attributes.color.needsUpdate = true; -+ (attributes.color as THREE.BufferAttribute).addUpdateRange( -+ startVertex * 3, -+ (currentVertex - startVertex) * 3, -+ ); -+ attributes.color.needsUpdate = true; - -- if (currentVertex >= totalVertex) { -- clone = scene.clone(); -- clone.matrixWorldAutoUpdate = false; -+ if (currentVertex >= totalVertex) { -+ clone = scene.clone(); -+ clone.matrixWorldAutoUpdate = false; - -- bounces++; -- currentVertex = 0; -+ bounces++; -+ currentVertex = 0; -+ } -+ -+ requestAnimationFrame(compute); - } - - requestAnimationFrame(compute); - } -- -- requestAnimationFrame(compute); --}; -+} - - // - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -diff --git a/examples-testing/examples/webgl_sprites.ts b/examples-testing/examples/webgl_sprites.ts -index 2e418934..c9f61690 100644 ---- a/examples-testing/examples/webgl_sprites.ts -+++ b/examples-testing/examples/webgl_sprites.ts -@@ -1,13 +1,17 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; --let cameraOrtho, sceneOrtho; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let cameraOrtho: THREE.OrthographicCamera, sceneOrtho: THREE.Scene; - --let spriteTL, spriteTR, spriteBL, spriteBR, spriteC; -+let spriteTL: THREE.Sprite, -+ spriteTR: THREE.Sprite, -+ spriteBL: THREE.Sprite, -+ spriteBR: THREE.Sprite, -+ spriteC: THREE.Sprite; - --let mapC; -+let mapC: THREE.Texture; - --let group; -+let group: THREE.Group; - - init(); - -@@ -57,8 +61,8 @@ function init() { - } else { - material = materialC.clone(); - material.color.setHSL(0.5 * Math.random(), 0.75, 0.5); -- material.map.offset.set(-0.5, -0.5); -- material.map.repeat.set(2, 2); -+ material.map!.offset.set(-0.5, -0.5); -+ material.map!.repeat.set(2, 2); - } - - const sprite = new THREE.Sprite(material); -@@ -87,13 +91,13 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function createHUDSprites(texture) { -+function createHUDSprites(texture: THREE.Texture) { - texture.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.SpriteMaterial({ map: texture }); - -- const width = material.map.image.width; -- const height = material.map.image.height; -+ const width = material.map!.image.width; -+ const height = material.map!.image.height; - - spriteTL = new THREE.Sprite(material); - spriteTL.center.set(0.0, 1.0); -@@ -156,7 +160,7 @@ function animate() { - const time = Date.now() / 1000; - - for (let i = 0, l = group.children.length; i < l; i++) { -- const sprite = group.children[i]; -+ const sprite = group.children[i] as THREE.Sprite; - const material = sprite.material; - const scale = Math.sin(time + sprite.position.x * 0.01) * 0.3 + 1.0; - -diff --git a/examples-testing/examples/webgl_test_memory.ts b/examples-testing/examples/webgl_test_memory.ts -index f5d0e112..128862a2 100644 ---- a/examples-testing/examples/webgl_test_memory.ts -+++ b/examples-testing/examples/webgl_test_memory.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - -@@ -26,7 +26,7 @@ function createImage() { - canvas.width = 256; - canvas.height = 256; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - context.fillStyle = - 'rgb(' + - Math.floor(Math.random() * 256) + -diff --git a/examples-testing/examples/webgl_test_memory2.ts b/examples-testing/examples/webgl_test_memory2.ts -index 366a2791..74077e99 100644 ---- a/examples-testing/examples/webgl_test_memory2.ts -+++ b/examples-testing/examples/webgl_test_memory2.ts -@@ -2,15 +2,15 @@ import * as THREE from 'three'; - - const N = 100; - --let container; -+let container: HTMLDivElement; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - --let geometry; -+let geometry: THREE.SphereGeometry; - --const meshes = []; -+const meshes: THREE.Mesh[] = []; - --let fragmentShader, vertexShader; -+let fragmentShader: string, vertexShader: string; - - init(); - setInterval(render, 1000 / 60); -@@ -19,8 +19,8 @@ function init() { - container = document.createElement('div'); - document.body.appendChild(container); - -- vertexShader = document.getElementById('vertexShader').textContent; -- fragmentShader = document.getElementById('fragmentShader').textContent; -+ vertexShader = document.getElementById('vertexShader')!.textContent!; -+ fragmentShader = document.getElementById('fragmentShader')!.textContent!; - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 2000; -@@ -70,12 +70,12 @@ function render() { - - renderer.render(scene, camera); - -- console.log('before', renderer.info.programs.length); -+ console.log('before', renderer.info.programs!.length); - - for (let i = 0; i < N; i++) { - const mesh = meshes[i]; - mesh.material.dispose(); - } - -- console.log('after', renderer.info.programs.length); -+ console.log('after', renderer.info.programs!.length); - } -diff --git a/examples-testing/examples/webgl_test_wide_gamut.ts b/examples-testing/examples/webgl_test_wide_gamut.ts -index 693dd459..5e64e184 100644 ---- a/examples-testing/examples/webgl_test_wide_gamut.ts -+++ b/examples-testing/examples/webgl_test_wide_gamut.ts -@@ -2,12 +2,12 @@ import * as THREE from 'three'; - - import WebGL from 'three/addons/capabilities/WebGL.js'; - --let container, camera, renderer, loader; --let sceneL, sceneR, textureL, textureR; -+let container: HTMLElement, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, loader: THREE.TextureLoader; -+let sceneL: THREE.Scene, sceneR: THREE.Scene, textureL: THREE.Texture, textureR: THREE.Texture; - - let sliderPos = window.innerWidth / 2; - --const slider = document.querySelector('.slider'); -+const slider = document.querySelector('.slider') as HTMLElement; - - const isP3Context = WebGL.isColorSpaceAvailable(THREE.DisplayP3ColorSpace); - -@@ -18,7 +18,7 @@ if (isP3Context) { - init(); - - function init() { -- container = document.querySelector('.container'); -+ container = document.querySelector('.container')!; - - sceneL = new THREE.Scene(); - sceneR = new THREE.Scene(); -@@ -60,7 +60,7 @@ async function initTextures() { - } - - function initSlider() { -- function onPointerDown() { -+ function onPointerDown(event: PointerEvent) { - if (event.isPrimary === false) return; - - window.addEventListener('pointermove', onPointerMove); -@@ -72,10 +72,10 @@ function initSlider() { - window.removeEventListener('pointerup', onPointerUp); - } - -- function onPointerMove(e) { -+ function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - -- updateSlider(e.pageX); -+ updateSlider(event.pageX); - } - - updateSlider(sliderPos); -@@ -84,7 +84,7 @@ function initSlider() { - slider.addEventListener('pointerdown', onPointerDown); - } - --function updateSlider(offset) { -+function updateSlider(offset: number) { - sliderPos = Math.max(10, Math.min(window.innerWidth - 10, offset)); - - slider.style.left = sliderPos - slider.offsetWidth / 2 + 'px'; -@@ -96,13 +96,13 @@ function onWindowResize() { - - renderer.setSize(window.innerWidth, window.innerHeight); - -- THREE.TextureUtils.contain(sceneL.background, window.innerWidth / window.innerHeight); -- THREE.TextureUtils.contain(sceneR.background, window.innerWidth / window.innerHeight); -+ THREE.TextureUtils.contain(sceneL.background as THREE.Texture, window.innerWidth / window.innerHeight); -+ THREE.TextureUtils.contain(sceneR.background as THREE.Texture, window.innerWidth / window.innerHeight); - - updateSlider(sliderPos); - } - --function onGamutChange({ matches }) { -+function onGamutChange({ matches }: MediaQueryListEvent) { - renderer.outputColorSpace = isP3Context && matches ? THREE.DisplayP3ColorSpace : THREE.SRGBColorSpace; - - textureL.needsUpdate = true; -diff --git a/examples-testing/examples/webgl_texture2darray_compressed.ts b/examples-testing/examples/webgl_texture2darray_compressed.ts -index f263be70..bc8f8622 100644 ---- a/examples-testing/examples/webgl_texture2darray_compressed.ts -+++ b/examples-testing/examples/webgl_texture2darray_compressed.ts -@@ -3,7 +3,12 @@ import * as THREE from 'three'; - import Stats from 'three/addons/libs/stats.module.js'; - import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - --let camera, scene, mesh, renderer, stats, clock; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ mesh: THREE.Mesh, -+ renderer: THREE.WebGLRenderer, -+ stats: Stats, -+ clock: THREE.Clock; - - const planeWidth = 50; - const planeHeight = 25; -@@ -43,8 +48,8 @@ function init() { - depth: { value: 55 }, - size: { value: new THREE.Vector2(planeWidth, planeHeight) }, - }, -- vertexShader: document.getElementById('vs').textContent.trim(), -- fragmentShader: document.getElementById('fs').textContent.trim(), -+ vertexShader: document.getElementById('vs')!.textContent!.trim(), -+ fragmentShader: document.getElementById('fs')!.textContent!.trim(), - glslVersion: THREE.GLSL3, - }); - -diff --git a/examples-testing/examples/webgl_texture2darray_layerupdate.ts b/examples-testing/examples/webgl_texture2darray_layerupdate.ts -index 0cc136cb..26237259 100644 ---- a/examples-testing/examples/webgl_texture2darray_layerupdate.ts -+++ b/examples-testing/examples/webgl_texture2darray_layerupdate.ts -@@ -3,7 +3,7 @@ import * as THREE from 'three'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - --let camera, scene, mesh, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, mesh: THREE.InstancedMesh, renderer: THREE.WebGLRenderer; - - const planeWidth = 20; - const planeHeight = 10; -@@ -35,7 +35,7 @@ async function init() { - // Load several KTX2 textures which will later be used to modify - // specific texture array layers. - -- const spiritedaway = await ktx2Loader.loadAsync('textures/spiritedaway.ktx2'); -+ const spiritedaway = (await ktx2Loader.loadAsync('textures/spiritedaway.ktx2')) as THREE.CompressedArrayTexture; - - // Create a texture array for rendering. - -@@ -67,9 +67,9 @@ async function init() { - srcLayer: 0, - destLayer: 0, - transfer() { -- const layerElementLength = layerByteLength / spiritedaway.mipmaps[0].data.BYTES_PER_ELEMENT; -- textureArray.mipmaps[0].data.set( -- spiritedaway.mipmaps[0].data.subarray( -+ const layerElementLength = layerByteLength / spiritedaway.mipmaps![0].data.BYTES_PER_ELEMENT; -+ textureArray.mipmaps![0].data.set( -+ spiritedaway.mipmaps![0].data.subarray( - layerElementLength * (formData.srcLayer % spiritedaway.image.depth), - layerElementLength * ((formData.srcLayer % spiritedaway.image.depth) + 1), - ), -@@ -94,13 +94,13 @@ async function init() { - diffuse: { value: textureArray }, - size: { value: new THREE.Vector2(planeWidth, planeHeight) }, - }, -- vertexShader: document.getElementById('vs').textContent.trim(), -- fragmentShader: document.getElementById('fs').textContent.trim(), -+ vertexShader: document.getElementById('vs')!.textContent!.trim(), -+ fragmentShader: document.getElementById('fs')!.textContent!.trim(), - glslVersion: THREE.GLSL3, - }); - - const geometry = new THREE.InstancedBufferGeometry(); -- geometry.copy(new THREE.PlaneGeometry(planeWidth, planeHeight)); -+ geometry.copy(new THREE.PlaneGeometry(planeWidth, planeHeight) as unknown as THREE.InstancedBufferGeometry); - geometry.instanceCount = 3; - - const instancedIndexAttribute = new THREE.InstancedBufferAttribute(new Uint16Array([0, 1, 2]), 1, false, 1); -@@ -116,7 +116,7 @@ async function init() { - // Initialize the texture array by first rendering the spirited away - // frames in order. - -- textureArray.mipmaps[0].data.set(spiritedaway.mipmaps[0].data.subarray(0, textureArray.mipmaps[0].data.length)); -+ textureArray.mipmaps![0].data.set(spiritedaway.mipmaps![0].data.subarray(0, textureArray.mipmaps![0].data.length)); - textureArray.needsUpdate = true; - renderer.render(scene, camera); - } -diff --git a/examples-testing/examples/webgl_texture3d.ts b/examples-testing/examples/webgl_texture3d.ts -index 977dbadb..fb1460ca 100644 ---- a/examples-testing/examples/webgl_texture3d.ts -+++ b/examples-testing/examples/webgl_texture3d.ts -@@ -5,7 +5,15 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { NRRDLoader } from 'three/addons/loaders/NRRDLoader.js'; - import { VolumeRenderShader1 } from 'three/addons/shaders/VolumeShader.js'; - --let renderer, scene, camera, controls, material, volconfig, cmtextures; -+type ColorMap = 'gray' | 'viridis'; -+ -+let renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.OrthographicCamera, -+ controls: OrbitControls, -+ material: THREE.ShaderMaterial, -+ volconfig: { clim1: number; clim2: number; renderstyle: string; isothreshold: number; colormap: ColorMap }, -+ cmtextures: { [K in ColorMap]: THREE.Texture }; - - init(); - -@@ -100,7 +108,7 @@ function init() { - } - - function updateUniforms() { -- material.uniforms['u_clim'].value.set(volconfig.clim1, volconfig.clim2); -+ (material.uniforms['u_clim'].value as THREE.Vector2).set(volconfig.clim1, volconfig.clim2); - material.uniforms['u_renderstyle'].value = volconfig.renderstyle == 'mip' ? 0 : 1; // 0: MIP, 1: ISO - material.uniforms['u_renderthreshold'].value = volconfig.isothreshold; // For ISO renderstyle - material.uniforms['u_cmdata'].value = cmtextures[volconfig.colormap]; -diff --git a/examples-testing/examples/webgl_texture3d_partialupdate.ts b/examples-testing/examples/webgl_texture3d_partialupdate.ts -index 1ad6d264..10b32582 100644 ---- a/examples-testing/examples/webgl_texture3d_partialupdate.ts -+++ b/examples-testing/examples/webgl_texture3d_partialupdate.ts -@@ -6,14 +6,14 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - const INITIAL_CLOUD_SIZE = 128; - --let renderer, scene, camera; --let mesh; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let mesh: THREE.Mesh; - let prevTime = performance.now(); --let cloudTexture = null; -+let cloudTexture: THREE.Data3DTexture | null = null; - - init(); - --function generateCloudTexture(size, scaleFactor = 1.0) { -+function generateCloudTexture(size: number, scaleFactor = 1.0) { - const data = new Uint8Array(size * size * size); - const scale = (scaleFactor * 10.0) / size; - -@@ -60,7 +60,7 @@ function init() { - canvas.width = 1; - canvas.height = 32; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - const gradient = context.createLinearGradient(0, 0, 0, 32); - gradient.addColorStop(0.0, '#014a84'); - gradient.addColorStop(0.5, '#0561a0'); -@@ -310,17 +310,17 @@ function animate() { - const scaleFactor = (Math.random() + 0.5) * 0.5; - const source = generateCloudTexture(perElementPaddedSize, scaleFactor); - -- renderer.copyTextureToTexture3D(source, cloudTexture, box, position); -+ renderer.copyTextureToTexture3D(source, cloudTexture!, box, position); - - prevTime = time; - - curr++; - } - -- mesh.material.uniforms.cameraPos.value.copy(camera.position); -+ (mesh.material.uniforms.cameraPos.value as THREE.Vector3).copy(camera.position); - // mesh.rotation.y = - performance.now() / 7500; - -- mesh.material.uniforms.frame.value++; -+ (mesh.material.uniforms.frame.value as number)++; - - renderer.render(scene, camera); - } -diff --git a/examples-testing/examples/webgl_tonemapping.ts b/examples-testing/examples/webgl_tonemapping.ts -index 9945826c..db817304 100644 ---- a/examples-testing/examples/webgl_tonemapping.ts -+++ b/examples-testing/examples/webgl_tonemapping.ts -@@ -1,22 +1,35 @@ - import * as THREE from 'three'; - --import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -+import { GUI, NumberController } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let mesh, renderer, scene, camera, controls; --let gui, -- guiExposure = null; -+type ToneMapping = 'None' | 'Linear' | 'Reinhard' | 'Cineon' | 'ACESFilmic' | 'AgX' | 'Neutral' | 'Custom'; - --const params = { -+interface Params { -+ exposure: number; -+ toneMapping: ToneMapping; -+ blurriness: number; -+ intensity: number; -+} -+ -+let mesh: THREE.Object3D, -+ renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ controls: OrbitControls; -+let gui: GUI, -+ guiExposure: NumberController | null = null; -+ -+const params: Params = { - exposure: 1.0, - toneMapping: 'AgX', - blurriness: 0.3, - intensity: 1.0, - }; - --const toneMappingOptions = { -+const toneMappingOptions: { [K in ToneMapping]: THREE.ToneMapping } = { - None: THREE.NoToneMapping, - Linear: THREE.LinearToneMapping, - Reinhard: THREE.ReinhardToneMapping, -@@ -88,7 +101,7 @@ async function init() { - - // model - -- mesh = gltf.scene.getObjectByName('node_damagedHelmet_-6514'); -+ mesh = gltf.scene.getObjectByName('node_damagedHelmet_-6514')!; - scene.add(mesh); - - render(); -@@ -99,7 +112,7 @@ async function init() { - const toneMappingFolder = gui.addFolder('Tone Mapping'); - - toneMappingFolder -- .add(params, 'toneMapping', Object.keys(toneMappingOptions)) -+ .add(params, 'toneMapping', Object.keys(toneMappingOptions) as ToneMapping[]) - - .name('type') - .onChange(function () { -@@ -140,11 +153,11 @@ async function init() { - gui.open(); - } - --function updateGUI(folder) { -+function updateGUI(folder: GUI) { - if (params.toneMapping === 'None') { -- guiExposure.hide(); -+ guiExposure!.hide(); - } else { -- guiExposure.show(); -+ guiExposure!.show(); - } - } - -diff --git a/examples-testing/examples/webgl_ubo.ts b/examples-testing/examples/webgl_ubo.ts -index 01064f11..814edd87 100644 ---- a/examples-testing/examples/webgl_ubo.ts -+++ b/examples-testing/examples/webgl_ubo.ts -@@ -1,11 +1,11 @@ - import * as THREE from 'three'; - --let camera, scene, renderer, clock; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer, clock: THREE.Clock; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 25); -@@ -51,8 +51,8 @@ function init() { - normalMatrix: { value: null }, - color: { value: null }, - }, -- vertexShader: document.getElementById('vertexShader1').textContent, -- fragmentShader: document.getElementById('fragmentShader1').textContent, -+ vertexShader: document.getElementById('vertexShader1')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader1')!.textContent!, - glslVersion: THREE.GLSL3, - }); - -@@ -61,8 +61,8 @@ function init() { - modelMatrix: { value: null }, - diffuseMap: { value: null }, - }, -- vertexShader: document.getElementById('vertexShader2').textContent, -- fragmentShader: document.getElementById('fragmentShader2').textContent, -+ vertexShader: document.getElementById('vertexShader2')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader2')!.textContent!, - glslVersion: THREE.GLSL3, - }); - -@@ -127,7 +127,7 @@ function animate() { - const delta = clock.getDelta(); - - scene.traverse(function (child) { -- if (child.isMesh) { -+ if ((child as THREE.Mesh).isMesh) { - child.rotation.x += delta * 0.5; - child.rotation.y += delta * 0.3; - } -diff --git a/examples-testing/examples/webgl_ubo_arrays.ts b/examples-testing/examples/webgl_ubo_arrays.ts -index d846e144..85bcff4c 100644 ---- a/examples-testing/examples/webgl_ubo_arrays.ts -+++ b/examples-testing/examples/webgl_ubo_arrays.ts -@@ -4,11 +4,15 @@ import Stats from 'three/addons/libs/stats.module.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, clock, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ clock: THREE.Clock, -+ stats: Stats; - --let lightingUniformsGroup, lightCenters; -+let lightingUniformsGroup: THREE.UniformsGroup, lightCenters: { x: number; z: number }[]; - --const container = document.getElementById('container'); -+const container = document.getElementById('container')!; - - const pointLightsMax = 300; - -@@ -71,8 +75,8 @@ function init() { - defines: { - POINTLIGHTS_MAX: pointLightsMax, - }, -- vertexShader: document.getElementById('vertexShader').textContent, -- fragmentShader: document.getElementById('fragmentShader').textContent, -+ vertexShader: document.getElementById('vertexShader')!.textContent!, -+ fragmentShader: document.getElementById('fragmentShader')!.textContent!, - glslVersion: THREE.GLSL3, - }); - -@@ -129,7 +133,7 @@ function init() { - gui.add(api, 'count', 1, pointLightsMax) - .step(1) - .onChange(function () { -- lightingUniformsGroup.uniforms[2].value = api.count; -+ (lightingUniformsGroup.uniforms[2] as THREE.Uniform).value = api.count; - }); - } - -@@ -145,7 +149,7 @@ function onWindowResize() { - function animate() { - const elapsedTime = clock.getElapsedTime(); - -- const lights = lightingUniformsGroup.uniforms[0]; -+ const lights = lightingUniformsGroup.uniforms[0] as THREE.Uniform[]; - - // Parameters for circular movement - const radius = 5; // Smaller radius for individual circular movements -diff --git a/examples-testing/examples/webgl_video_kinect.ts b/examples-testing/examples/webgl_video_kinect.ts -index 4f0e2f11..7b4a3fab 100644 ---- a/examples-testing/examples/webgl_video_kinect.ts -+++ b/examples-testing/examples/webgl_video_kinect.ts -@@ -2,9 +2,9 @@ import * as THREE from 'three'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, camera, renderer; --let geometry, mesh, material; --let mouse, center; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer; -+let geometry: THREE.BufferGeometry, mesh: THREE.Points, material: THREE.ShaderMaterial; -+let mouse: THREE.Vector3, center: THREE.Vector3; - - init(); - -@@ -24,7 +24,7 @@ function init() { - center = new THREE.Vector3(); - center.z = -1000; - -- const video = document.getElementById('video'); -+ const video = document.getElementById('video') as HTMLVideoElement; - - const texture = new THREE.VideoTexture(video); - texture.minFilter = THREE.NearestFilter; -@@ -56,8 +56,8 @@ function init() { - pointSize: { value: 2 }, - zOffset: { value: 1000 }, - }, -- vertexShader: document.getElementById('vs').textContent, -- fragmentShader: document.getElementById('fs').textContent, -+ vertexShader: document.getElementById('vs')!.textContent!, -+ fragmentShader: document.getElementById('fs')!.textContent!, - blending: THREE.AdditiveBlending, - depthTest: false, - depthWrite: false, -@@ -99,7 +99,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouse.x = (event.clientX - window.innerWidth / 2) * 8; - mouse.y = (event.clientY - window.innerHeight / 2) * 8; - } -diff --git a/examples-testing/examples/webgl_video_panorama_equirectangular.ts b/examples-testing/examples/webgl_video_panorama_equirectangular.ts -index 866eca16..07301138 100644 ---- a/examples-testing/examples/webgl_video_panorama_equirectangular.ts -+++ b/examples-testing/examples/webgl_video_panorama_equirectangular.ts -@@ -1,6 +1,6 @@ - import * as THREE from 'three'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - let isUserInteracting = false, - lon = 0, -@@ -17,7 +17,7 @@ const distance = 0.5; - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.25, 10); - -@@ -27,7 +27,7 @@ function init() { - // invert the geometry on the x-axis so that all of the faces point inward - geometry.scale(-1, 1, 1); - -- const video = document.getElementById('video'); -+ const video = document.getElementById('video') as HTMLVideoElement; - video.play(); - - const texture = new THREE.VideoTexture(video); -@@ -59,7 +59,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - isUserInteracting = true; - - onPointerDownPointerX = event.clientX; -@@ -69,7 +69,7 @@ function onPointerDown(event) { - onPointerDownLat = lat; - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (isUserInteracting === true) { - lon = (onPointerDownPointerX - event.clientX) * 0.1 + onPointerDownLon; - lat = (onPointerDownPointerY - event.clientY) * 0.1 + onPointerDownLat; -diff --git a/examples-testing/examples/webgl_volume_cloud.ts b/examples-testing/examples/webgl_volume_cloud.ts -index 77dd8de4..6414f1b4 100644 ---- a/examples-testing/examples/webgl_volume_cloud.ts -+++ b/examples-testing/examples/webgl_volume_cloud.ts -@@ -4,8 +4,8 @@ import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let renderer, scene, camera; --let mesh; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let mesh: THREE.Mesh; - - init(); - -@@ -29,7 +29,7 @@ function init() { - canvas.width = 1; - canvas.height = 32; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - const gradient = context.createLinearGradient(0, 0, 0, 32); - gradient.addColorStop(0.0, '#014a84'); - gradient.addColorStop(0.5, '#0561a0'); -@@ -270,10 +270,10 @@ function onWindowResize() { - } - - function animate() { -- mesh.material.uniforms.cameraPos.value.copy(camera.position); -+ (mesh.material.uniforms.cameraPos.value as THREE.Vector3).copy(camera.position); - mesh.rotation.y = -performance.now() / 7500; - -- mesh.material.uniforms.frame.value++; -+ (mesh.material.uniforms.frame.value as number)++; - - renderer.render(scene, camera); - } -diff --git a/examples-testing/examples/webgl_volume_instancing.ts b/examples-testing/examples/webgl_volume_instancing.ts -index bf90eeea..135869e2 100644 ---- a/examples-testing/examples/webgl_volume_instancing.ts -+++ b/examples-testing/examples/webgl_volume_instancing.ts -@@ -2,7 +2,11 @@ import * as THREE from 'three'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { VOXLoader, VOXData3DTexture } from 'three/addons/loaders/VOXLoader.js'; - --let renderer, scene, camera, controls, clock; -+let renderer: THREE.WebGLRenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ controls: OrbitControls, -+ clock: THREE.Clock; - - init(); - -@@ -155,7 +159,7 @@ function init() { - - const mesh = new THREE.InstancedMesh(geometry, material, 50000); - mesh.onBeforeRender = function () { -- this.material.uniforms.cameraPos.value.copy(camera.position); -+ (this.material.uniforms.cameraPos.value as THREE.Vector3).copy(camera.position); - }; - - const transform = new THREE.Object3D(); -diff --git a/examples-testing/examples/webgl_volume_perlin.ts b/examples-testing/examples/webgl_volume_perlin.ts -index a98f9a68..5689cf91 100644 ---- a/examples-testing/examples/webgl_volume_perlin.ts -+++ b/examples-testing/examples/webgl_volume_perlin.ts -@@ -4,8 +4,8 @@ import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let renderer, scene, camera; --let mesh; -+let renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let mesh: THREE.Mesh; - - init(); - -@@ -202,7 +202,7 @@ function onWindowResize() { - } - - function animate() { -- mesh.material.uniforms.cameraPos.value.copy(camera.position); -+ (mesh.material.uniforms.cameraPos.value as THREE.Vector3).copy(camera.position); - - renderer.render(scene, camera); - } -diff --git a/examples-testing/examples/webgl_water.ts b/examples-testing/examples/webgl_water.ts -index 496a5f85..379619a1 100644 ---- a/examples-testing/examples/webgl_water.ts -+++ b/examples-testing/examples/webgl_water.ts -@@ -4,9 +4,13 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Water } from 'three/addons/objects/Water2.js'; - --let scene, camera, clock, renderer, water; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ clock: THREE.Clock, -+ renderer: THREE.WebGLRenderer, -+ water: Water; - --let torusKnot; -+let torusKnot: THREE.Mesh; - - const params = { - color: '#ffffff', -diff --git a/examples-testing/examples/webgl_water_flowmap.ts b/examples-testing/examples/webgl_water_flowmap.ts -index d0255e43..c924d666 100644 ---- a/examples-testing/examples/webgl_water_flowmap.ts -+++ b/examples-testing/examples/webgl_water_flowmap.ts -@@ -4,7 +4,7 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Water } from 'three/addons/objects/Water2.js'; - --let scene, camera, renderer, water; -+let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, water: Water; - - init(); - -diff --git a/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts b/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts -index 565aebb8..f5d6bf42 100644 ---- a/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts -+++ b/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts -@@ -1,20 +1,20 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { screenUV, color, vec2, reflector } from 'three/tsl'; - - import Stats from 'three/addons/libs/stats.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -+import { GLTFLoader, GLTF } from 'three/addons/loaders/GLTFLoader.js'; - import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; - - import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js'; - - const [sourceModel, targetModel] = await Promise.all([ -- new Promise((resolve, reject) => { -+ new Promise((resolve, reject) => { - new FBXLoader().load('./models/fbx/mixamo.fbx', resolve, undefined, reject); - }), - -- new Promise((resolve, reject) => { -+ new Promise((resolve, reject) => { - new GLTFLoader().load('./models/gltf/readyplayer.me.glb', resolve, undefined, reject); - }), - ]); -@@ -100,7 +100,13 @@ scene.add(floor); - - // - --function getSource(sourceModel) { -+interface Source { -+ clip: THREE.AnimationClip; -+ skeleton: THREE.Skeleton; -+ mixer: THREE.AnimationMixer; -+} -+ -+function getSource(sourceModel: THREE.Group): Source { - const clip = sourceModel.animations[0]; - - const helper = new THREE.SkeletonHelper(sourceModel); -@@ -112,10 +118,10 @@ function getSource(sourceModel) { - return { clip, skeleton, mixer }; - } - --function retargetModel(sourceModel, targetModel) { -+function retargetModel(sourceModel: Source, targetModel: GLTF) { - const targetSkin = targetModel.scene.children[0].children[1]; - -- const retargetOptions = { -+ const retargetOptions: SkeletonUtils.RetargetClipOptions = { - // specify the name of the source's hip bone. - hip: 'mixamorigHips', - -diff --git a/examples-testing/examples/webgpu_backdrop_area.ts b/examples-testing/examples/webgpu_backdrop_area.ts -index 5ccf2fa1..72225c8d 100644 ---- a/examples-testing/examples/webgpu_backdrop_area.ts -+++ b/examples-testing/examples/webgpu_backdrop_area.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { - color, - linearDepth, -@@ -18,8 +18,8 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; --let mixer, clock; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let mixer: THREE.AnimationMixer, clock: THREE.Clock; - - init(); - -@@ -137,13 +137,13 @@ function init() { - }; - - const gui = new GUI(); -- const options = { material: 'blurred' }; -+ const options: { material: keyof typeof materials } = { material: 'blurred' }; - - box.material = materials[options.material]; - - gui.add(box.scale, 'x', 0.1, 2, 0.01); - gui.add(box.scale, 'z', 0.1, 2, 0.01); -- gui.add(options, 'material', Object.keys(materials)).onChange(name => { -+ gui.add(options, 'material', Object.keys(materials) as (keyof typeof materials)[]).onChange(name => { - box.material = materials[name]; - }); - } -diff --git a/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts b/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts -index 15527632..58f5cc14 100644 ---- a/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts -+++ b/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts -@@ -1,6 +1,6 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -+import { Font, FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - - import Stats from 'three/addons/libs/stats.module.js'; -@@ -17,8 +17,16 @@ let zoompos = -100, - minzoomspeed = 0.015; - let zoomspeed = minzoomspeed; - --let container, border, stats; --const objects = {}; -+let container: HTMLElement, border: HTMLElement, stats: Stats; -+ -+interface ObjectView { -+ container: HTMLElement; -+ renderer: THREE.WebGPURenderer; -+ scene: THREE.Scene; -+ camera: THREE.PerspectiveCamera; -+} -+ -+const objects: { normal?: ObjectView; logzbuf?: ObjectView } = {}; - - // Generate a number of text labels, from 1µm in size up to 100,000,000 light years - // Try to use some descriptive real-world examples of objects at each scale -@@ -44,7 +52,7 @@ const labeldata = [ - init().then(animate); - - async function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - const loader = new FontLoader(); - const font = await loader.loadAsync('fonts/helvetiker_regular.typeface.json'); -@@ -59,7 +67,7 @@ async function init() { - container.appendChild(stats.dom); - - // Resize border allows the user to easily compare effects of logarithmic depth buffer over the whole scene -- border = document.getElementById('renderer_border'); -+ border = document.getElementById('renderer_border')!; - border.addEventListener('pointerdown', onBorderPointerDown); - - window.addEventListener('mousemove', onMouseMove); -@@ -67,8 +75,8 @@ async function init() { - window.addEventListener('wheel', onMouseWheel); - } - --async function initView(scene, name, logDepthBuf) { -- const framecontainer = document.getElementById('container_' + name); -+async function initView(scene: THREE.Scene, name: string, logDepthBuf: boolean) { -+ const framecontainer = document.getElementById('container_' + name)!; - - const camera = new THREE.PerspectiveCamera(50, (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT, NEAR, FAR); - scene.add(camera); -@@ -85,7 +93,7 @@ async function initView(scene, name, logDepthBuf) { - return { container: framecontainer, renderer: renderer, scene: scene, camera: camera }; - } - --function initScene(font) { -+function initScene(font: Font) { - const scene = new THREE.Scene(); - - scene.add(new THREE.AmbientLight(0x777777)); -@@ -94,7 +102,7 @@ function initScene(font) { - light.position.set(100, 100, 100); - scene.add(light); - -- const materialargs = { -+ const materialargs: { color: THREE.ColorRepresentation; specular: number; shininess: number; emissive: number } = { - color: 0xffffff, - specular: 0x050505, - shininess: 50, -@@ -115,7 +123,7 @@ function initScene(font) { - labelgeo.computeBoundingSphere(); - - // center text -- labelgeo.translate(-labelgeo.boundingSphere.radius, 0, 0); -+ labelgeo.translate(-labelgeo.boundingSphere!.radius, 0, 0); - - materialargs.color = new THREE.Color().setHSL(Math.random(), 0.5, 0.5); - -@@ -148,16 +156,16 @@ function updateRendererSizes() { - - screensplit_right = 1 - screensplit; - -- objects.normal.renderer.setSize(screensplit * SCREEN_WIDTH, SCREEN_HEIGHT); -- objects.normal.camera.aspect = (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT; -- objects.normal.camera.updateProjectionMatrix(); -- objects.normal.camera.setViewOffset(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH * screensplit, SCREEN_HEIGHT); -- objects.normal.container.style.width = screensplit * 100 + '%'; -+ objects.normal!.renderer.setSize(screensplit * SCREEN_WIDTH, SCREEN_HEIGHT); -+ objects.normal!.camera.aspect = (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT; -+ objects.normal!.camera.updateProjectionMatrix(); -+ objects.normal!.camera.setViewOffset(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH * screensplit, SCREEN_HEIGHT); -+ objects.normal!.container.style.width = screensplit * 100 + '%'; - -- objects.logzbuf.renderer.setSize(screensplit_right * SCREEN_WIDTH, SCREEN_HEIGHT); -- objects.logzbuf.camera.aspect = (screensplit_right * SCREEN_WIDTH) / SCREEN_HEIGHT; -- objects.logzbuf.camera.updateProjectionMatrix(); -- objects.logzbuf.camera.setViewOffset( -+ objects.logzbuf!.renderer.setSize(screensplit_right * SCREEN_WIDTH, SCREEN_HEIGHT); -+ objects.logzbuf!.camera.aspect = (screensplit_right * SCREEN_WIDTH) / SCREEN_HEIGHT; -+ objects.logzbuf!.camera.updateProjectionMatrix(); -+ objects.logzbuf!.camera.setViewOffset( - SCREEN_WIDTH, - SCREEN_HEIGHT, - SCREEN_WIDTH * screensplit, -@@ -165,7 +173,7 @@ function updateRendererSizes() { - SCREEN_WIDTH * screensplit_right, - SCREEN_HEIGHT, - ); -- objects.logzbuf.container.style.width = screensplit_right * 100 + '%'; -+ objects.logzbuf!.container.style.width = screensplit_right * 100 + '%'; - - border.style.left = screensplit * 100 + '%'; - } -@@ -190,22 +198,22 @@ function animate() { - zoompos += zoomspeed; - zoomspeed *= damping; - -- objects.normal.camera.position.x = Math.sin(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -- objects.normal.camera.position.y = Math.sin(0.25 * Math.PI * (mouse[1] - 0.5)) * zoom; -- objects.normal.camera.position.z = Math.cos(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -- objects.normal.camera.lookAt(objects.normal.scene.position); -+ objects.normal!.camera.position.x = Math.sin(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -+ objects.normal!.camera.position.y = Math.sin(0.25 * Math.PI * (mouse[1] - 0.5)) * zoom; -+ objects.normal!.camera.position.z = Math.cos(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; -+ objects.normal!.camera.lookAt(objects.normal!.scene.position); - - // Clone camera settings across both scenes -- objects.logzbuf.camera.position.copy(objects.normal.camera.position); -- objects.logzbuf.camera.quaternion.copy(objects.normal.camera.quaternion); -+ objects.logzbuf!.camera.position.copy(objects.normal!.camera.position); -+ objects.logzbuf!.camera.quaternion.copy(objects.normal!.camera.quaternion); - - // Update renderer sizes if the split has changed - if (screensplit_right != 1 - screensplit) { - updateRendererSizes(); - } - -- objects.normal.renderer.render(objects.normal.scene, objects.normal.camera); -- objects.logzbuf.renderer.render(objects.logzbuf.scene, objects.logzbuf.camera); -+ objects.normal!.renderer.render(objects.normal!.scene, objects.normal!.camera); -+ objects.logzbuf!.renderer.render(objects.logzbuf!.scene, objects.logzbuf!.camera); - - stats.update(); - } -@@ -220,7 +228,7 @@ function onBorderPointerDown() { - window.addEventListener('pointerup', onBorderPointerUp); - } - --function onBorderPointerMove(ev) { -+function onBorderPointerMove(ev: PointerEvent) { - screensplit = Math.max(0, Math.min(1, ev.clientX / window.innerWidth)); - } - -@@ -229,12 +237,12 @@ function onBorderPointerUp() { - window.removeEventListener('pointerup', onBorderPointerUp); - } - --function onMouseMove(ev) { -+function onMouseMove(ev: MouseEvent) { - mouse[0] = ev.clientX / window.innerWidth; - mouse[1] = ev.clientY / window.innerHeight; - } - --function onMouseWheel(ev) { -+function onMouseWheel(ev: WheelEvent) { - const amount = ev.deltaY; - if (amount === 0) return; - const dir = amount / Math.abs(amount); -diff --git a/examples-testing/examples/webgpu_clearcoat.ts b/examples-testing/examples/webgpu_clearcoat.ts -index 0d5b70a2..0c147364 100644 ---- a/examples-testing/examples/webgpu_clearcoat.ts -+++ b/examples-testing/examples/webgpu_clearcoat.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -7,12 +7,12 @@ import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader. - - import { FlakesTexture } from 'three/addons/textures/FlakesTexture.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - --let particleLight; --let group; -+let particleLight: THREE.Mesh; -+let group: THREE.Group; - - init(); - -diff --git a/examples-testing/examples/webgpu_clipping.ts b/examples-testing/examples/webgpu_clipping.ts -index e57a7e96..cd6362e3 100644 ---- a/examples-testing/examples/webgpu_clipping.ts -+++ b/examples-testing/examples/webgpu_clipping.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -6,7 +6,12 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, startTime, object, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ startTime: number, -+ object: THREE.Mesh, -+ stats: Stats; - - init(); - -@@ -101,7 +106,7 @@ function init() { - - // ***** Clipping setup (renderer): ***** - const globalPlanes = [globalPlane]; -- const Empty = Object.freeze([]); -+ const Empty: readonly THREE.Plane[] = Object.freeze([]); - - renderer.clippingPlanes = Empty; // GUI sets it to globalPlanes - renderer.localClippingEnabled = true; -@@ -120,7 +125,7 @@ function init() { - folderLocal = gui.addFolder('Local Clipping'), - propsLocal = { - get Enabled() { -- return renderer.localClippingEnabled; -+ return renderer.localClippingEnabled!; - }, - set Enabled(v) { - renderer.localClippingEnabled = v; -@@ -193,7 +198,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function animate(currentTime) { -+function animate(currentTime: DOMHighResTimeStamp) { - const time = (currentTime - startTime) / 1000; - - object.position.y = 0.8; -diff --git a/examples-testing/examples/webgpu_custom_fog_background.ts b/examples-testing/examples/webgpu_custom_fog_background.ts -index 4a2e6c80..22eeb6d0 100644 ---- a/examples-testing/examples/webgpu_custom_fog_background.ts -+++ b/examples-testing/examples/webgpu_custom_fog_background.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, color, rangeFog } from 'three/tsl'; - - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -@@ -6,8 +6,8 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, scene, renderer; --let postProcessing; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let postProcessing: THREE.PostProcessing; - - init(); - -diff --git a/examples-testing/examples/webgpu_display_stereo.ts b/examples-testing/examples/webgpu_display_stereo.ts -index 7eb45fa2..b2af0ebb 100644 ---- a/examples-testing/examples/webgpu_display_stereo.ts -+++ b/examples-testing/examples/webgpu_display_stereo.ts -@@ -1,24 +1,37 @@ --import * as THREE from 'three'; -- --import { stereoPass, anaglyphPass, parallaxBarrierPass } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+ -+import { -+ stereoPass, -+ anaglyphPass, -+ parallaxBarrierPass, -+ ShaderNodeObject, -+ StereoPassNode, -+ AnaglyphPassNode, -+ ParallaxBarrierPassNode, -+} from 'three/tsl'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { Timer } from 'three/addons/misc/Timer.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, postProcessing; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ postProcessing: THREE.PostProcessing; - --let stereo, anaglyph, parallaxBarrier; -+let stereo: ShaderNodeObject, -+ anaglyph: ShaderNodeObject, -+ parallaxBarrier: ShaderNodeObject; - --let mesh, dummy, timer; -+let mesh: THREE.InstancedMesh, dummy: THREE.Mesh, timer: Timer; - - const position = new THREE.Vector3(); - --const params = { -+const params: { effect: 'stereo' | 'anaglyph' | 'parallaxBarrier'; eyeSep: number } = { - effect: 'stereo', - eyeSep: 0.064, - }; - --const effects = { Stereo: 'stereo', Anaglyph: 'anaglyph', ParallaxBarrier: 'parallaxBarrier' }; -+const effects = { Stereo: 'stereo', Anaglyph: 'anaglyph', ParallaxBarrier: 'parallaxBarrier' } as const; - - init(); - -@@ -90,7 +103,7 @@ function init() { - controls.maxDistance = 25; - } - --function update(value) { -+function update(value: 'stereo' | 'anaglyph' | 'parallaxBarrier') { - if (value === 'stereo') { - postProcessing.outputNode = stereo; - } else if (value === 'anaglyph') { -@@ -109,7 +122,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function extractPosition(matrix, position) { -+function extractPosition(matrix: THREE.Matrix4, position: THREE.Vector3) { - position.x = matrix.elements[12]; - position.y = matrix.elements[13]; - position.z = matrix.elements[14]; -diff --git a/examples-testing/examples/webgpu_instancing_morph.ts b/examples-testing/examples/webgpu_instancing_morph.ts -index cfd72172..ae3271f9 100644 ---- a/examples-testing/examples/webgpu_instancing_morph.ts -+++ b/examples-testing/examples/webgpu_instancing_morph.ts -@@ -1,10 +1,16 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer, stats, mesh, mixer, dummy; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ stats: Stats, -+ mesh: THREE.InstancedMesh, -+ mixer: THREE.AnimationMixer, -+ dummy: THREE.Mesh; - - const offset = 5000; - -@@ -70,7 +76,7 @@ function init() { - const loader = new GLTFLoader(); - - loader.load('models/gltf/Horse.glb', function (glb) { -- dummy = glb.scene.children[0]; -+ dummy = glb.scene.children[0] as THREE.Mesh; - - mesh = new THREE.InstancedMesh( - dummy.geometry, -@@ -139,7 +145,7 @@ function animate() { - mesh.setMorphAt(i, dummy); - } - -- mesh.morphTexture.needsUpdate = true; -+ mesh.morphTexture!.needsUpdate = true; - } - - renderer.render(scene, camera); -diff --git a/examples-testing/examples/webgpu_lensflares.ts b/examples-testing/examples/webgpu_lensflares.ts -index 8c157b4b..f297b64e 100644 ---- a/examples-testing/examples/webgpu_lensflares.ts -+++ b/examples-testing/examples/webgpu_lensflares.ts -@@ -1,14 +1,14 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - - import { FlyControls } from 'three/addons/controls/FlyControls.js'; - import { LensflareMesh, LensflareElement } from 'three/addons/objects/LensflareMesh.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; --let controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let controls: FlyControls; - - const clock = new THREE.Clock(); - -@@ -73,7 +73,7 @@ function init() { - addLight(0.1, 0.85, 0.65, 0, 0, -1000); - addLight(0.995, 0.5, 0.95, 5000, 5000, -1000); - -- function addLight(h, s, l, x, y, z) { -+ function addLight(h: number, s: number, l: number, x: number, y: number, z: number) { - const light = new THREE.PointLight(0xffffff, 1.5, 2000, 0); - light.color.setHSL(h, s, l); - light.position.set(x, y, z); -diff --git a/examples-testing/examples/webgpu_lightprobe.ts b/examples-testing/examples/webgpu_lightprobe.ts -index 66f9ffcb..0bcfb599 100644 ---- a/examples-testing/examples/webgpu_lightprobe.ts -+++ b/examples-testing/examples/webgpu_lightprobe.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -@@ -8,12 +8,15 @@ import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js' - - import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelperGPU.js'; - --let mesh, renderer, scene, camera; -+let mesh: THREE.Mesh, -+ renderer: THREE.WebGPURenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera; - --let gui; -+let gui: GUI; - --let lightProbe; --let directionalLight; -+let lightProbe: THREE.LightProbe; -+let directionalLight: THREE.DirectionalLight; - - // linear color space - const API = { -@@ -58,7 +61,7 @@ function init() { - scene.add(directionalLight); - - // envmap -- const genCubeUrls = function (prefix, postfix) { -+ const genCubeUrls = function (prefix: string, postfix: string) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, -diff --git a/examples-testing/examples/webgpu_lights_ies_spotlight.ts b/examples-testing/examples/webgpu_lights_ies_spotlight.ts -index 41b56de8..8f7abe1f 100644 ---- a/examples-testing/examples/webgpu_lights_ies_spotlight.ts -+++ b/examples-testing/examples/webgpu_lights_ies_spotlight.ts -@@ -1,11 +1,11 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --import { OrbitControls } from './jsm/controls/OrbitControls.js'; -+import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - - import { IESLoader } from 'three/addons/loaders/IESLoader.js'; - --let renderer, scene, camera; --let lights; -+let renderer: THREE.WebGPURenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let lights: THREE.IESSpotLight[]; - - async function init() { - const iesLoader = new IESLoader().setPath('./ies/'); -@@ -104,7 +104,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function render(time) { -+function render(time: number) { - time = (time / 1000) * 2.0; - - for (let i = 0; i < lights.length; i++) { -diff --git a/examples-testing/examples/webgpu_lights_rectarealight.ts b/examples-testing/examples/webgpu_lights_rectarealight.ts -index 5638c902..a274a953 100644 ---- a/examples-testing/examples/webgpu_lights_rectarealight.ts -+++ b/examples-testing/examples/webgpu_lights_rectarealight.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -6,8 +6,8 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js'; - import { RectAreaLightTexturesLib } from 'three/addons/lights/RectAreaLightTexturesLib.js'; - --let renderer, scene, camera; --let stats, meshKnot; -+let renderer: THREE.WebGPURenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera; -+let stats: Stats, meshKnot: THREE.Mesh; - - init(); - -@@ -70,7 +70,7 @@ function onWindowResize() { - camera.updateProjectionMatrix(); - } - --function animation(time) { -+function animation(time: number) { - meshKnot.rotation.y = time / 1000; - - renderer.render(scene, camera); -diff --git a/examples-testing/examples/webgpu_loader_gltf.ts b/examples-testing/examples/webgpu_loader_gltf.ts -index 64d1fda4..079b75d7 100644 ---- a/examples-testing/examples/webgpu_loader_gltf.ts -+++ b/examples-testing/examples/webgpu_loader_gltf.ts -@@ -1,11 +1,11 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts b/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts -index d100e8c8..062846a5 100644 ---- a/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts -+++ b/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts -@@ -1,10 +1,10 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let renderer, scene, camera, controls; -+let renderer: THREE.WebGPURenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls; - - init(); - -diff --git a/examples-testing/examples/webgpu_loader_gltf_compressed.ts b/examples-testing/examples/webgpu_loader_gltf_compressed.ts -index 9405b64a..60db096b 100644 ---- a/examples-testing/examples/webgpu_loader_gltf_compressed.ts -+++ b/examples-testing/examples/webgpu_loader_gltf_compressed.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; -@@ -6,7 +6,7 @@ import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - init(); - -diff --git a/examples-testing/examples/webgpu_loader_gltf_dispersion.ts b/examples-testing/examples/webgpu_loader_gltf_dispersion.ts -index c0290b98..c7c8fb59 100644 ---- a/examples-testing/examples/webgpu_loader_gltf_dispersion.ts -+++ b/examples-testing/examples/webgpu_loader_gltf_dispersion.ts -@@ -1,10 +1,10 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - init(); - -diff --git a/examples-testing/examples/webgpu_loader_gltf_iridescence.ts b/examples-testing/examples/webgpu_loader_gltf_iridescence.ts -index f163ea77..3f695e17 100644 ---- a/examples-testing/examples/webgpu_loader_gltf_iridescence.ts -+++ b/examples-testing/examples/webgpu_loader_gltf_iridescence.ts -@@ -1,10 +1,10 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let renderer, scene, camera, controls; -+let renderer: THREE.WebGPURenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls; - - init().catch(function (err) { - console.error(err); -diff --git a/examples-testing/examples/webgpu_loader_gltf_sheen.ts b/examples-testing/examples/webgpu_loader_gltf_sheen.ts -index 788ef2a8..cad87132 100644 ---- a/examples-testing/examples/webgpu_loader_gltf_sheen.ts -+++ b/examples-testing/examples/webgpu_loader_gltf_sheen.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -@@ -6,7 +6,7 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer, controls: OrbitControls; - - init(); - -@@ -25,7 +25,10 @@ function init() { - new GLTFLoader().setPath('models/gltf/').load('SheenChair.glb', function (gltf) { - scene.add(gltf.scene); - -- const object = gltf.scene.getObjectByName('SheenChair_fabric'); -+ const object = gltf.scene.getObjectByName('SheenChair_fabric') as THREE.Mesh< -+ THREE.BufferGeometry, -+ THREE.MeshPhysicalMaterial -+ >; - - const gui = new GUI(); - -diff --git a/examples-testing/examples/webgpu_loader_gltf_transmission.ts b/examples-testing/examples/webgpu_loader_gltf_transmission.ts -index 04023326..05ee79b0 100644 ---- a/examples-testing/examples/webgpu_loader_gltf_transmission.ts -+++ b/examples-testing/examples/webgpu_loader_gltf_transmission.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -@@ -6,7 +6,12 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - --let camera, scene, renderer, controls, clock, mixer; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ controls: OrbitControls, -+ clock: THREE.Clock, -+ mixer: THREE.AnimationMixer; - - init(); - -diff --git a/examples-testing/examples/webgpu_materials_arrays.ts b/examples-testing/examples/webgpu_materials_arrays.ts -index 8db371e6..b893f2c0 100644 ---- a/examples-testing/examples/webgpu_materials_arrays.ts -+++ b/examples-testing/examples/webgpu_materials_arrays.ts -@@ -1,11 +1,11 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let renderer, scene, camera, controls; --let planeMesh, boxMesh, boxMeshWireframe, planeMeshWireframe; --let materials; -+let renderer: THREE.WebGPURenderer, scene: THREE.Scene, camera: THREE.PerspectiveCamera, controls: OrbitControls; -+let planeMesh: THREE.Mesh, boxMesh: THREE.Mesh, boxMeshWireframe: THREE.Mesh, planeMeshWireframe: THREE.Mesh; -+let materials: THREE.MeshBasicMaterial[]; - - const api = { - webgpu: true, -@@ -21,7 +21,7 @@ function init(forceWebGL = false) { - } - - // renderer -- renderer = new THREE.WebGLRenderer({ -+ renderer = new THREE.WebGPURenderer({ - forceWebGL, - antialias: true, - }); -diff --git a/examples-testing/examples/webgpu_materials_basic.ts b/examples-testing/examples/webgpu_materials_basic.ts -index 0161a9c7..590f668d 100644 ---- a/examples-testing/examples/webgpu_materials_basic.ts -+++ b/examples-testing/examples/webgpu_materials_basic.ts -@@ -1,10 +1,10 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - --const spheres = []; -+const spheres: THREE.Mesh[] = []; - - let mouseX = 0; - let mouseY = 0; -@@ -12,7 +12,13 @@ let mouseY = 0; - let windowHalfX = window.innerWidth / 2; - let windowHalfY = window.innerHeight / 2; - --const params = { -+const params: { -+ color: string; -+ mapping: THREE.CubeTextureMapping; -+ refractionRatio: number; -+ transparent: boolean; -+ opacity: number; -+} = { - color: '#ffffff', - mapping: THREE.CubeReflectionMapping, - refractionRatio: 0.98, -@@ -111,7 +117,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = (event.clientX - windowHalfX) / 100; - mouseY = (event.clientY - windowHalfY) / 100; - } -diff --git a/examples-testing/examples/webgpu_materials_displacementmap.ts b/examples-testing/examples/webgpu_materials_displacementmap.ts -index 54d26d65..824c087a 100644 ---- a/examples-testing/examples/webgpu_materials_displacementmap.ts -+++ b/examples-testing/examples/webgpu_materials_displacementmap.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -6,8 +6,8 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - --let stats; --let camera, scene, renderer, controls; -+let stats: Stats; -+let camera: THREE.OrthographicCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer, controls: OrbitControls; - - const settings = { - metalness: 1.0, -@@ -19,9 +19,9 @@ const settings = { - normalScale: 1.0, - }; - --let mesh, material; -+let mesh: THREE.Mesh, material: THREE.MeshStandardNodeMaterial; - --let pointLight, ambientLight; -+let pointLight: THREE.PointLight, ambientLight: THREE.AmbientLight; - - const height = 500; // of camera frustum - -@@ -173,7 +173,7 @@ function init() { - - const loader = new OBJLoader(); - loader.load('models/obj/ninja/ninjaHead_Low.obj', function (group) { -- const geometry = group.children[0].geometry; -+ const geometry = (group.children[0] as THREE.Mesh).geometry; - geometry.center(); - - mesh = new THREE.Mesh(geometry, material); -diff --git a/examples-testing/examples/webgpu_materials_envmaps.ts b/examples-testing/examples/webgpu_materials_envmaps.ts -index f49b4ca1..73c27f5c 100644 ---- a/examples-testing/examples/webgpu_materials_envmaps.ts -+++ b/examples-testing/examples/webgpu_materials_envmaps.ts -@@ -1,11 +1,13 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let controls, camera, scene, renderer; --let textureEquirec, textureCube; --let sphereMesh, sphereMaterial, params; -+let controls, camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let textureEquirec: THREE.Texture, textureCube: THREE.CubeTexture; -+let sphereMesh: THREE.Mesh, -+ sphereMaterial: THREE.MeshBasicMaterial, -+ params: { Cube: () => void; Equirectangular: () => void; Refraction: boolean }; - - init(); - -diff --git a/examples-testing/examples/webgpu_materials_lightmap.ts b/examples-testing/examples/webgpu_materials_lightmap.ts -index 616645aa..288f6e84 100644 ---- a/examples-testing/examples/webgpu_materials_lightmap.ts -+++ b/examples-testing/examples/webgpu_materials_lightmap.ts -@@ -1,12 +1,12 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { vec4, color, positionLocal, mix } from 'three/tsl'; - - import Stats from 'three/addons/libs/stats.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container, stats; --let camera, scene, renderer; -+let container: HTMLDivElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - init(); - -diff --git a/examples-testing/examples/webgpu_materials_toon.ts b/examples-testing/examples/webgpu_materials_toon.ts -index 21746059..060404e7 100644 ---- a/examples-testing/examples/webgpu_materials_toon.ts -+++ b/examples-testing/examples/webgpu_materials_toon.ts -@@ -1,22 +1,23 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { FontLoader } from 'three/addons/loaders/FontLoader.js'; - import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; -+import { Font } from 'three/examples/jsm/loaders/FontLoader.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene, renderer; --let particleLight; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let particleLight: THREE.Mesh; - - const loader = new FontLoader(); - loader.load('fonts/gentilis_regular.typeface.json', function (font) { - init(font); - }); - --function init(font) { -+function init(font: Font) { - container = document.createElement('div'); - document.body.appendChild(container); - -@@ -78,7 +79,7 @@ function init(font) { - } - } - -- function addLabel(name, location) { -+ function addLabel(name: string, location: THREE.Vector3) { - const textGeo = new TextGeometry(name, { - font: font, - -diff --git a/examples-testing/examples/webgpu_materials_transmission.ts b/examples-testing/examples/webgpu_materials_transmission.ts -index 0e04ddad..058172b5 100644 ---- a/examples-testing/examples/webgpu_materials_transmission.ts -+++ b/examples-testing/examples/webgpu_materials_transmission.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -@@ -19,7 +19,7 @@ const params = { - exposure: 1, - }; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - let mesh; - -@@ -156,7 +156,7 @@ function generateTexture() { - canvas.width = 2; - canvas.height = 2; - -- const context = canvas.getContext('2d'); -+ const context = canvas.getContext('2d')!; - context.fillStyle = 'white'; - context.fillRect(0, 1, 2, 1); - -diff --git a/examples-testing/examples/webgpu_materials_video.ts b/examples-testing/examples/webgpu_materials_video.ts -index bd84aba0..f9d188c3 100644 ---- a/examples-testing/examples/webgpu_materials_video.ts -+++ b/examples-testing/examples/webgpu_materials_video.ts -@@ -1,10 +1,13 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --let container; -+let container: HTMLDivElement; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - --let video, texture, material, mesh; -+let video: HTMLVideoElement, -+ texture: THREE.VideoTexture, -+ material: THREE.MeshPhongMaterial & { hue?: number; saturation?: number }, -+ mesh: THREE.Mesh & { dx?: number; dy?: number }; - - let mouseX = 0; - let mouseY = 0; -@@ -12,20 +15,20 @@ let mouseY = 0; - let windowHalfX = window.innerWidth / 2; - let windowHalfY = window.innerHeight / 2; - --let cube_count; -+let cube_count: number; - --const meshes = [], -- materials = [], -+const meshes: THREE.Mesh[] = [], -+ materials: (THREE.MeshPhongMaterial & { hue?: number; saturation?: number })[] = [], - xgrid = 20, - ygrid = 10; - --const startButton = document.getElementById('startButton'); -+const startButton = document.getElementById('startButton')!; - startButton.addEventListener('click', function () { - init(); - }); - - function init() { -- const overlay = document.getElementById('overlay'); -+ const overlay = document.getElementById('overlay')!; - overlay.remove(); - - container = document.createElement('div'); -@@ -46,7 +49,7 @@ function init() { - renderer.setAnimationLoop(render); - container.appendChild(renderer.domElement); - -- video = document.getElementById('video'); -+ video = document.getElementById('video') as HTMLVideoElement; - video.play(); - video.addEventListener('play', function () { - this.currentTime = 3; -@@ -122,7 +125,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function change_uvs(geometry, unitx, unity, offsetx, offsety) { -+function change_uvs(geometry: THREE.BoxGeometry, unitx: number, unity: number, offsetx: number, offsety: number) { - const uvs = geometry.attributes.uv.array; - - for (let i = 0; i < uvs.length; i += 2) { -@@ -131,7 +134,7 @@ function change_uvs(geometry, unitx, unity, offsetx, offsety) { - } - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - mouseX = event.clientX - windowHalfX; - mouseY = (event.clientY - windowHalfY) * 0.3; - } -@@ -152,20 +155,20 @@ function render() { - for (let i = 0; i < cube_count; i++) { - material = materials[i]; - -- h = ((360 * (material.hue + time)) % 360) / 360; -- material.color.setHSL(h, material.saturation, 0.5); -+ h = ((360 * (material.hue! + time)) % 360) / 360; -+ material.color.setHSL(h, material.saturation!, 0.5); - } - - if (counter % 1000 > 200) { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - -- mesh.rotation.x += 10 * mesh.dx; -- mesh.rotation.y += 10 * mesh.dy; -+ mesh.rotation.x += 10 * mesh.dx!; -+ mesh.rotation.y += 10 * mesh.dy!; - -- mesh.position.x -= 150 * mesh.dx; -- mesh.position.y += 150 * mesh.dy; -- mesh.position.z += 300 * mesh.dx; -+ mesh.position.x -= 150 * mesh.dx!; -+ mesh.position.y += 150 * mesh.dy!; -+ mesh.position.z += 300 * mesh.dx!; - } - } - -@@ -173,8 +176,8 @@ function render() { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - -- mesh.dx *= -1; -- mesh.dy *= -1; -+ mesh.dx! *= -1; -+ mesh.dy! *= -1; - } - } - -diff --git a/examples-testing/examples/webgpu_mesh_batch.ts b/examples-testing/examples/webgpu_mesh_batch.ts -index 17bc8440..1f7bc551 100644 ---- a/examples-testing/examples/webgpu_mesh_batch.ts -+++ b/examples-testing/examples/webgpu_mesh_batch.ts -@@ -1,19 +1,19 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { radixSort } from 'three/addons/utils/SortUtils.js'; -+import { radixSort, RadixSortOptions } from 'three/addons/utils/SortUtils.js'; - - import { transformedNormalView, directionToColor, diffuseColor } from 'three/tsl'; - --let camera, scene, renderer; --let controls, stats; --let gui; --let geometries, mesh, material; --const ids = []; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let controls: OrbitControls, stats: Stats; -+let gui: GUI; -+let geometries: THREE.BufferGeometry[], mesh: THREE.BatchedMesh, material: THREE.MeshBasicNodeMaterial; -+const ids: number[] = []; - - const matrix = new THREE.Matrix4(); - -@@ -48,7 +48,7 @@ init(); - - // - --function randomizeMatrix(matrix) { -+function randomizeMatrix(matrix: THREE.Matrix4) { - position.x = Math.random() * 40 - 20; - position.y = Math.random() * 40 - 20; - position.z = Math.random() * 40 - 20; -@@ -64,7 +64,7 @@ function randomizeMatrix(matrix) { - return matrix.compose(position, quaternion, scale); - } - --function randomizeRotationSpeed(rotation) { -+function randomizeRotationSpeed(rotation: THREE.Euler) { - rotation.x = Math.random() * 0.01; - rotation.y = Math.random() * 0.01; - rotation.z = Math.random() * 0.01; -@@ -90,7 +90,7 @@ function createMaterial() { - - function cleanup() { - if (mesh) { -- mesh.parent.remove(mesh); -+ mesh.parent!.remove(mesh); - - if (mesh.dispose) { - mesh.dispose(); -@@ -254,18 +254,26 @@ function init(forceWebGL = false) { - - // - --function sortFunction(list, camera) { -+type BatchedMeshWithOptions = THREE.BatchedMesh & { -+ _options?: RadixSortOptions<{ start: number; count: number; z: number }>; -+}; -+ -+function sortFunction( -+ this: THREE.BatchedMesh, -+ list: { start: number; count: number; z: number }[], -+ camera: THREE.Camera, -+) { - // initialize options -- this._options = this._options || { -+ (this as BatchedMeshWithOptions)._options = (this as BatchedMeshWithOptions)._options || { - get: el => el.z, - aux: new Array(this.maxInstanceCount), - }; - -- const options = this._options; -+ const options = (this as BatchedMeshWithOptions)._options!; - options.reversed = this.material.transparent; - - // convert depth to unsigned 32 bit range -- const factor = (2 ** 32 - 1) / camera.far; // UINT32_MAX / max_depth -+ const factor = (2 ** 32 - 1) / (camera as THREE.PerspectiveCamera).far; // UINT32_MAX / max_depth - for (let i = 0, l = list.length; i < l; i++) { - list[i].z *= factor; - } -diff --git a/examples-testing/examples/webgpu_modifier_curve.ts b/examples-testing/examples/webgpu_modifier_curve.ts -index 4879a9e5..66fee55f 100644 ---- a/examples-testing/examples/webgpu_modifier_curve.ts -+++ b/examples-testing/examples/webgpu_modifier_curve.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { TransformControls } from 'three/addons/controls/TransformControls.js'; - import Stats from 'three/addons/libs/stats.module.js'; - import { Flow } from 'three/addons/modifiers/CurveModifierGPU.js'; -@@ -7,17 +7,17 @@ import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - - const ACTION_SELECT = 1, - ACTION_NONE = 0; --const curveHandles = []; -+const curveHandles: THREE.Object3D[] = []; - const mouse = new THREE.Vector2(); - --let stats; --let scene, -- camera, -- renderer, -- rayCaster, -- control, -- flow, -- action = ACTION_NONE; -+let stats: Stats; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ renderer: THREE.WebGPURenderer, -+ rayCaster: THREE.Raycaster, -+ control: TransformControls, -+ flow: Flow, -+ action: typeof ACTION_SELECT | typeof ACTION_NONE = ACTION_NONE; - - init(); - -@@ -128,7 +128,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - action = ACTION_SELECT; - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; -diff --git a/examples-testing/examples/webgpu_morphtargets.ts b/examples-testing/examples/webgpu_morphtargets.ts -index 9fb7075c..839ff818 100644 ---- a/examples-testing/examples/webgpu_morphtargets.ts -+++ b/examples-testing/examples/webgpu_morphtargets.ts -@@ -1,15 +1,19 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let container, camera, scene, renderer, mesh; -+let container: HTMLElement, -+ camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ mesh: THREE.Mesh; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x8fbcd4); -@@ -63,7 +67,7 @@ function createGeometry() { - const spherePositions = []; - - // for the second morph target, we'll twist the cubes vertices -- const twistPositions = []; -+ const twistPositions: number[] = []; - const direction = new THREE.Vector3(1, 0, 0); - const vertex = new THREE.Vector3(); - -@@ -104,12 +108,12 @@ function initGUI() { - gui.add(params, 'Spherify', 0, 1) - .step(0.01) - .onChange(function (value) { -- mesh.morphTargetInfluences[0] = value; -+ mesh.morphTargetInfluences![0] = value; - }); - gui.add(params, 'Twist', 0, 1) - .step(0.01) - .onChange(function (value) { -- mesh.morphTargetInfluences[1] = value; -+ mesh.morphTargetInfluences![1] = value; - }); - } - -diff --git a/examples-testing/examples/webgpu_morphtargets_face.ts b/examples-testing/examples/webgpu_morphtargets_face.ts -index ea9f8658..b81d7761 100644 ---- a/examples-testing/examples/webgpu_morphtargets_face.ts -+++ b/examples-testing/examples/webgpu_morphtargets_face.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -14,7 +14,7 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - init(); - - async function init() { -- let mixer; -+ let mixer: THREE.AnimationMixer; - - const clock = new THREE.Clock(); - -@@ -54,13 +54,13 @@ async function init() { - - // GUI - -- const head = mesh.getObjectByName('mesh_2'); -- const influences = head.morphTargetInfluences; -+ const head = mesh.getObjectByName('mesh_2') as THREE.Mesh; -+ const influences = head.morphTargetInfluences!; - - const gui = new GUI(); - gui.close(); - -- for (const [key, value] of Object.entries(head.morphTargetDictionary)) { -+ for (const [key, value] of Object.entries(head.morphTargetDictionary!)) { - gui.add(influences, value, 0, 1, 0.01).name(key.replace('blendShape1.', '')).listen(); - } - }); -diff --git a/examples-testing/examples/webgpu_mrt.ts b/examples-testing/examples/webgpu_mrt.ts -index a749bd6d..16bcee89 100644 ---- a/examples-testing/examples/webgpu_mrt.ts -+++ b/examples-testing/examples/webgpu_mrt.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { - output, - transformedNormalView, -@@ -18,8 +18,8 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, scene, renderer; --let postProcessing; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let postProcessing: THREE.PostProcessing; - - init(); - -diff --git a/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts b/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts -index 989361b6..d324a37f 100644 ---- a/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts -+++ b/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts -@@ -1,12 +1,31 @@ --import * as THREE from 'three'; --import { mix, step, texture, screenUV, mrt, output, transformedNormalWorld, uv, vec2 } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { -+ mix, -+ step, -+ texture, -+ screenUV, -+ mrt, -+ output, -+ transformedNormalWorld, -+ uv, -+ vec2, -+ ShaderNodeObject, -+ MRTNode, -+} from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, torus; --let quadMesh, sceneMRT, renderTarget, readbackTarget, material, readbackMaterial, pixelBuffer, pixelBufferTexture; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer, torus: THREE.Mesh; -+let quadMesh: THREE.QuadMesh, -+ sceneMRT: ShaderNodeObject, -+ renderTarget: THREE.RenderTarget, -+ readbackTarget: THREE.RenderTarget, -+ material: THREE.NodeMaterial, -+ readbackMaterial: THREE.MeshBasicNodeMaterial, -+ pixelBuffer: Uint8Array, -+ pixelBufferTexture: THREE.DataTexture; - - const gui = new GUI(); - -@@ -109,7 +128,7 @@ function onWindowResize() { - renderTarget.setSize(window.innerWidth * dpr, window.innerHeight * dpr); - } - --async function render(time) { -+async function render(time: number) { - const selection = options.selection; - - torus.rotation.y = (time / 1000) * 0.4; -@@ -143,12 +162,26 @@ async function readback() { - const selection = options.selection; - - if (selection === 'diffuse') { -- pixelBuffer = await renderer.readRenderTargetPixelsAsync(readbackTarget, 0, 0, width, height, 0); // zero is optional -+ pixelBuffer = (await renderer.readRenderTargetPixelsAsync( -+ readbackTarget, -+ 0, -+ 0, -+ width, -+ height, -+ 0, -+ )) as Uint8Array; // zero is optional - - pixelBufferTexture.image.data = pixelBuffer; - pixelBufferTexture.needsUpdate = true; - } else if (selection === 'normal') { -- pixelBuffer = await renderer.readRenderTargetPixelsAsync(readbackTarget, 0, 0, width, height, 1); -+ pixelBuffer = (await renderer.readRenderTargetPixelsAsync( -+ readbackTarget, -+ 0, -+ 0, -+ width, -+ height, -+ 1, -+ )) as Uint8Array; - - pixelBufferTexture.image.data = pixelBuffer; - pixelBufferTexture.needsUpdate = true; -diff --git a/examples-testing/examples/webgpu_ocean.ts b/examples-testing/examples/webgpu_ocean.ts -index 9eb9922d..b75024ec 100644 ---- a/examples-testing/examples/webgpu_ocean.ts -+++ b/examples-testing/examples/webgpu_ocean.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -7,14 +7,14 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { WaterMesh } from 'three/addons/objects/WaterMesh.js'; - import { SkyMesh } from 'three/addons/objects/SkyMesh.js'; - --let container, stats; --let camera, scene, renderer; --let controls, water, sun, mesh; -+let container: HTMLElement, stats: Stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let controls: OrbitControls, water: WaterMesh, sun: THREE.Vector3, mesh: THREE.Mesh; - - init(); - - function init() { -- container = document.getElementById('container'); -+ container = document.getElementById('container')!; - - // - -@@ -75,7 +75,7 @@ function init() { - const pmremGenerator = new THREE.PMREMGenerator(renderer); - const sceneEnv = new THREE.Scene(); - -- let renderTarget; -+ let renderTarget: THREE.RenderTarget | undefined; - - function updateSun() { - const phi = THREE.MathUtils.degToRad(90 - parameters.elevation); -diff --git a/examples-testing/examples/webgpu_parallax_uv.ts b/examples-testing/examples/webgpu_parallax_uv.ts -index 775399bf..1deb0cb1 100644 ---- a/examples-testing/examples/webgpu_parallax_uv.ts -+++ b/examples-testing/examples/webgpu_parallax_uv.ts -@@ -1,11 +1,11 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { texture, parallaxUV, overlay, uv } from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - --let controls; -+let controls: OrbitControls; - - init(); - -diff --git a/examples-testing/examples/webgpu_performance.ts b/examples-testing/examples/webgpu_performance.ts -index 315eba25..aa01b27a 100644 ---- a/examples-testing/examples/webgpu_performance.ts -+++ b/examples-testing/examples/webgpu_performance.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - -@@ -8,7 +8,7 @@ import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let camera, scene, renderer, stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer, stats: Stats; - - init(); - -diff --git a/examples-testing/examples/webgpu_postprocessing.ts b/examples-testing/examples/webgpu_postprocessing.ts -index 7ae63a39..31397439 100644 ---- a/examples-testing/examples/webgpu_postprocessing.ts -+++ b/examples-testing/examples/webgpu_postprocessing.ts -@@ -1,8 +1,8 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, dotScreen, rgbShift } from 'three/tsl'; - --let camera, renderer, postProcessing; --let object; -+let camera: THREE.PerspectiveCamera, renderer: THREE.WebGPURenderer, postProcessing: THREE.PostProcessing; -+let object: THREE.Object3D; - - init(); - -diff --git a/examples-testing/examples/webgpu_postprocessing_3dlut.ts b/examples-testing/examples/webgpu_postprocessing_3dlut.ts -index 27500a07..2401fa77 100644 ---- a/examples-testing/examples/webgpu_postprocessing_3dlut.ts -+++ b/examples-testing/examples/webgpu_postprocessing_3dlut.ts -@@ -1,20 +1,30 @@ --import * as THREE from 'three'; --import { pass, texture3D, uniform, lut3D, renderOutput } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { pass, texture3D, uniform, lut3D, renderOutput, ShaderNodeObject, Lut3DNode } from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; --import { LUTCubeLoader } from 'three/addons/loaders/LUTCubeLoader.js'; --import { LUT3dlLoader } from 'three/addons/loaders/LUT3dlLoader.js'; --import { LUTImageLoader } from 'three/addons/loaders/LUTImageLoader.js'; -+import { LUTCubeLoader, LUTCubeResult } from 'three/addons/loaders/LUTCubeLoader.js'; -+import { LUT3dlLoader, LUT3dlResult } from 'three/addons/loaders/LUT3dlLoader.js'; -+import { LUTImageLoader, LUTImageResult } from 'three/addons/loaders/LUTImageLoader.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --const params = { -+const params: { lut: keyof typeof lutMap; intensity: number } = { - lut: 'Bourbon 64.CUBE', - intensity: 1, - }; - --const lutMap = { -+const lutMap: { -+ 'Bourbon 64.CUBE': LUTCubeResult | Promise | null; -+ 'Chemical 168.CUBE': LUTCubeResult | Promise | null; -+ 'Clayton 33.CUBE': LUTCubeResult | Promise | null; -+ 'Cubicle 99.CUBE': LUTCubeResult | Promise | null; -+ 'Remy 24.CUBE': LUTCubeResult | Promise | null; -+ 'Presetpro-Cinematic.3dl': LUT3dlResult | Promise | null; -+ NeutralLUT: LUTImageResult | Promise | null; -+ 'B&WLUT': LUTImageResult | Promise | null; -+ NightLUT: LUTImageResult | Promise | null; -+} = { - 'Bourbon 64.CUBE': null, - 'Chemical 168.CUBE': null, - 'Clayton 33.CUBE': null, -@@ -26,9 +36,9 @@ const lutMap = { - NightLUT: null, - }; - --let gui; --let camera, scene, renderer; --let postProcessing, lutPass; -+let gui: GUI; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let postProcessing: THREE.PostProcessing, lutPass: ShaderNodeObject; - - init(); - -@@ -61,11 +71,13 @@ async function init() { - - for (const name in lutMap) { - if (/\.CUBE$/i.test(name)) { -- lutMap[name] = lutCubeLoader.loadAsync('luts/' + name); -+ (lutMap as unknown as Record>)[name] = lutCubeLoader.loadAsync( -+ 'luts/' + name, -+ ); - } else if (/\LUT$/i.test(name)) { -- lutMap[name] = lutImageLoader.loadAsync(`luts/${name}.png`); -+ (lutMap as Record>)[name] = lutImageLoader.loadAsync(`luts/${name}.png`); - } else { -- lutMap[name] = lut3dlLoader.loadAsync('luts/' + name); -+ (lutMap as Record>)[name] = lut3dlLoader.loadAsync('luts/' + name); - } - } - -@@ -73,7 +85,9 @@ async function init() { - await Promise.all(pendings); - - for (const name in lutMap) { -- lutMap[name] = await lutMap[name]; -+ (lutMap as Record)[name] = await ( -+ lutMap as Record> -+ )[name]; - } - - renderer = new THREE.WebGPURenderer(); -@@ -97,7 +111,7 @@ async function init() { - const scenePass = pass(scene, camera); - const outputPass = renderOutput(scenePass); - -- const lut = lutMap[params.lut]; -+ const lut = lutMap[params.lut] as LUTCubeResult | LUT3dlResult | LUTImageResult; - lutPass = lut3D(outputPass, texture3D(lut.texture3D), lut.texture3D.image.width, uniform(1)); - - postProcessing.outputNode = lutPass; -@@ -111,7 +125,7 @@ async function init() { - controls.update(); - - gui = new GUI(); -- gui.add(params, 'lut', Object.keys(lutMap)); -+ gui.add(params, 'lut', Object.keys(lutMap) as (keyof typeof lutMap)[]); - gui.add(params, 'intensity').min(0).max(1); - - window.addEventListener('resize', onWindowResize); -@@ -127,11 +141,11 @@ function onWindowResize() { - // - - function animate() { -- lutPass.intensityNode.value = params.intensity; -+ lutPass.intensityNode!.value = params.intensity; - - if (lutMap[params.lut]) { -- const lut = lutMap[params.lut]; -- lutPass.lutNode.value = lut.texture3D; -+ const lut = lutMap[params.lut] as LUTCubeResult | LUT3dlResult | LUTImageResult; -+ lutPass.lutNode!.value = lut.texture3D; - lutPass.size.value = lut.texture3D.image.width; - } - -diff --git a/examples-testing/examples/webgpu_postprocessing_afterimage.ts b/examples-testing/examples/webgpu_postprocessing_afterimage.ts -index d0775d49..fed02565 100644 ---- a/examples-testing/examples/webgpu_postprocessing_afterimage.ts -+++ b/examples-testing/examples/webgpu_postprocessing_afterimage.ts -@@ -1,10 +1,10 @@ --import * as THREE from 'three'; --import { pass, afterImage } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { pass, afterImage, AfterImageNode, ShaderNodeObject } from 'three/tsl'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; --let mesh, postProcessing, combinedPass; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let mesh: THREE.Mesh, postProcessing: THREE.PostProcessing, combinedPass: ShaderNodeObject; - - const params = { - damp: 0.96, -@@ -38,8 +38,7 @@ function init() { - const scenePass = pass(scene, camera); - const scenePassColor = scenePass.getTextureNode(); - -- combinedPass = scenePassColor; -- combinedPass = afterImage(combinedPass, params.damp); -+ combinedPass = afterImage(scenePassColor, params.damp); - - postProcessing.outputNode = combinedPass; - -diff --git a/examples-testing/examples/webgpu_postprocessing_ao.ts b/examples-testing/examples/webgpu_postprocessing_ao.ts -index 432d641a..801f1f31 100644 ---- a/examples-testing/examples/webgpu_postprocessing_ao.ts -+++ b/examples-testing/examples/webgpu_postprocessing_ao.ts -@@ -1,5 +1,17 @@ --import * as THREE from 'three'; --import { pass, mrt, output, transformedNormalView, texture, ao, denoise } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { -+ pass, -+ mrt, -+ output, -+ transformedNormalView, -+ texture, -+ ao, -+ denoise, -+ ShaderNodeObject, -+ GTAONode, -+ DenoiseNode, -+ Node, -+} from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; -@@ -10,9 +22,20 @@ import { SimplexNoise } from 'three/addons/math/SimplexNoise.js'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer, postProcessing, controls, clock, stats, mixer; -- --let aoPass, denoisePass, blendPassAO, blendPassDenoise, scenePassColor; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ postProcessing: THREE.PostProcessing, -+ controls: OrbitControls, -+ clock: THREE.Clock, -+ stats: Stats, -+ mixer: THREE.AnimationMixer; -+ -+let aoPass: ShaderNodeObject, -+ denoisePass: ShaderNodeObject, -+ blendPassAO: ShaderNodeObject, -+ blendPassDenoise: ShaderNodeObject, -+ scenePassColor: ShaderNodeObject; - - const params = { - distanceExponent: 1, -diff --git a/examples-testing/examples/webgpu_postprocessing_bloom.ts b/examples-testing/examples/webgpu_postprocessing_bloom.ts -index d38a7abb..80478cf8 100644 ---- a/examples-testing/examples/webgpu_postprocessing_bloom.ts -+++ b/examples-testing/examples/webgpu_postprocessing_bloom.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, bloom } from 'three/tsl'; - - import Stats from 'three/addons/libs/stats.module.js'; -@@ -7,8 +7,11 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, stats; --let postProcessing, renderer, mixer, clock; -+let camera: THREE.PerspectiveCamera, stats: Stats; -+let postProcessing: THREE.PostProcessing, -+ renderer: THREE.WebGPURenderer, -+ mixer: THREE.AnimationMixer, -+ clock: THREE.Clock; - - const params = { - threshold: 0, -@@ -20,7 +23,7 @@ const params = { - init(); - - async function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - clock = new THREE.Clock(); - -diff --git a/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts b/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts -index 7a6569f9..71cb1b29 100644 ---- a/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts -+++ b/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, mrt, output, bloom, emissive } from 'three/tsl'; - - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -@@ -8,8 +8,8 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; --let postProcessing; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let postProcessing: THREE.PostProcessing; - - init(); - -diff --git a/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts b/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts -index 55d6b6bb..851d9f30 100644 ---- a/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts -+++ b/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts -@@ -1,5 +1,5 @@ --import * as THREE from 'three'; --import { pass, mrt, output, float, bloom, uniform } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { pass, mrt, output, float, bloom, uniform, UniformNode } from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -@@ -84,9 +84,10 @@ window.addEventListener('pointerdown', event => { - const intersects = raycaster.intersectObjects(scene.children, false); - - if (intersects.length > 0) { -- const material = intersects[0].object.material; -+ const material = (intersects[0].object as THREE.Mesh) -+ .material; - -- const bloomIntensity = material.mrtNode.get('bloomIntensity'); -+ const bloomIntensity = material.mrtNode!.get('bloomIntensity') as UniformNode; - bloomIntensity.value = bloomIntensity.value === 0 ? 1 : 0; - } - }); -diff --git a/examples-testing/examples/webgpu_postprocessing_difference.ts b/examples-testing/examples/webgpu_postprocessing_difference.ts -index dc30eb60..2a156b13 100644 ---- a/examples-testing/examples/webgpu_postprocessing_difference.ts -+++ b/examples-testing/examples/webgpu_postprocessing_difference.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, luminance, saturation } from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -@@ -10,8 +10,8 @@ const params = { - speed: 0, - }; - --let camera, renderer, postProcessing; --let timer, mesh, controls; -+let camera: THREE.PerspectiveCamera, renderer: THREE.WebGPURenderer, postProcessing: THREE.PostProcessing; -+let timer: Timer, mesh: THREE.Mesh, controls: OrbitControls; - - init(); - -diff --git a/examples-testing/examples/webgpu_postprocessing_dof.ts b/examples-testing/examples/webgpu_postprocessing_dof.ts -index 26d034fb..4c351e14 100644 ---- a/examples-testing/examples/webgpu_postprocessing_dof.ts -+++ b/examples-testing/examples/webgpu_postprocessing_dof.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { cubeTexture, positionWorld, oscSine, timerGlobal, pass, dof, uniform } from 'three/tsl'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -@@ -7,7 +7,11 @@ import Stats from 'three/addons/libs/stats.module.js'; - - // - --let camera, scene, renderer, mesh, stats; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ mesh: THREE.InstancedMesh, -+ stats: Stats; - - let mouseX = 0, - mouseY = 0; -@@ -18,7 +22,7 @@ let windowHalfY = window.innerHeight / 2; - let width = window.innerWidth; - let height = window.innerHeight; - --let postProcessing; -+let postProcessing: THREE.PostProcessing; - - init(); - -@@ -125,7 +129,7 @@ function init() { - gui.add(effectController.maxblur, 'value', 0.0, 0.01, 0.001).name('maxblur'); - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; -diff --git a/examples-testing/examples/webgpu_postprocessing_fxaa.ts b/examples-testing/examples/webgpu_postprocessing_fxaa.ts -index 3221614b..ade3e809 100644 ---- a/examples-testing/examples/webgpu_postprocessing_fxaa.ts -+++ b/examples-testing/examples/webgpu_postprocessing_fxaa.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, fxaa, renderOutput } from 'three/tsl'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -@@ -8,8 +8,12 @@ const params = { - animated: false, - }; - --let camera, scene, renderer, clock, group; --let postProcessing; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ clock: THREE.Clock, -+ group: THREE.Group; -+let postProcessing: THREE.PostProcessing; - - init(); - -diff --git a/examples-testing/examples/webgpu_postprocessing_masking.ts b/examples-testing/examples/webgpu_postprocessing_masking.ts -index a4f56b17..ce7e7ad3 100644 ---- a/examples-testing/examples/webgpu_postprocessing_masking.ts -+++ b/examples-testing/examples/webgpu_postprocessing_masking.ts -@@ -1,8 +1,8 @@ --import * as THREE from 'three'; --import { pass, texture } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { Node, pass, texture } from 'three/tsl'; - --let camera, postProcessing, renderer; --let box, torus; -+let camera: THREE.PerspectiveCamera, postProcessing: THREE.PostProcessing, renderer: THREE.WebGPURenderer; -+let box: THREE.Mesh, torus: THREE.Mesh; - - init(); - -@@ -50,7 +50,7 @@ function init() { - const sceneMask1 = pass(maskScene1, camera).a; - const sceneMask2 = pass(maskScene2, camera).a; - -- let compose = base; -+ let compose: Node = base; - compose = sceneMask1.mix(compose, texture(texture1)); - compose = sceneMask2.mix(compose, texture(texture2)); - -diff --git a/examples-testing/examples/webgpu_postprocessing_motion_blur.ts b/examples-testing/examples/webgpu_postprocessing_motion_blur.ts -index 1330953c..4f677d85 100644 ---- a/examples-testing/examples/webgpu_postprocessing_motion_blur.ts -+++ b/examples-testing/examples/webgpu_postprocessing_motion_blur.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, texture, motionBlur, uniform, output, mrt, mix, velocity, uv, screenUV } from 'three/tsl'; - - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -@@ -9,11 +9,11 @@ import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer; --let boxLeft, boxRight, model, mixer, clock; --let postProcessing; --let controls; --let stats; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let boxLeft: THREE.Mesh, boxRight: THREE.Mesh, model: THREE.Group, mixer: THREE.AnimationMixer, clock: THREE.Clock; -+let postProcessing: THREE.PostProcessing; -+let controls: OrbitControls; -+let stats: Stats; - - const params = { - speed: 1.0, -@@ -59,7 +59,7 @@ function init() { - model.rotation.y = Math.PI / 2; - - model.traverse(function (child) { -- if (child.isMesh) { -+ if ((child as THREE.Mesh).isMesh) { - child.castShadow = true; - child.receiveShadow = true; - } -diff --git a/examples-testing/examples/webgpu_postprocessing_pixel.ts b/examples-testing/examples/webgpu_postprocessing_pixel.ts -index d7e51008..a9decd46 100644 ---- a/examples-testing/examples/webgpu_postprocessing_pixel.ts -+++ b/examples-testing/examples/webgpu_postprocessing_pixel.ts -@@ -1,12 +1,23 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --import { uniform, pixelationPass } from 'three/tsl'; -- --let camera, scene, renderer, postProcessing, crystalMesh, clock; --let gui, effectController; -+import { uniform, pixelationPass, UniformNode } from 'three/tsl'; -+ -+let camera: THREE.OrthographicCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ postProcessing: THREE.PostProcessing, -+ crystalMesh: THREE.Mesh, -+ clock: THREE.Clock; -+let gui: GUI, -+ effectController: { -+ pixelSize: UniformNode; -+ normalEdgeStrength: UniformNode; -+ depthEdgeStrength: UniformNode; -+ pixelAlignedPanning: boolean; -+ }; - - init(); - -@@ -34,7 +45,7 @@ function init() { - - const boxMaterial = new THREE.MeshPhongMaterial({ map: texChecker2 }); - -- function addBox(boxSideLength, x, z, rotation) { -+ function addBox(boxSideLength: number, x: number, z: number, rotation: number) { - const mesh = new THREE.Mesh(new THREE.BoxGeometry(boxSideLength, boxSideLength, boxSideLength), boxMaterial); - mesh.castShadow = true; - mesh.receiveShadow = true; -@@ -172,7 +183,7 @@ function animate() { - - // Helper functions - --function pixelTexture(texture) { -+function pixelTexture(texture: THREE.Texture) { - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.generateMipmaps = false; -@@ -182,25 +193,30 @@ function pixelTexture(texture) { - return texture; - } - --function easeInOutCubic(x) { -+function easeInOutCubic(x: number) { - return x ** 2 * 3 - x ** 3 * 2; - } - --function linearStep(x, edge0, edge1) { -+function linearStep(x: number, edge0: number, edge1: number) { - const w = edge1 - edge0; - const m = 1 / w; - const y0 = -m * edge0; - return THREE.MathUtils.clamp(y0 + m * x, 0, 1); - } - --function stopGoEased(x, downtime, period) { -+function stopGoEased(x: number, downtime: number, period: number) { - const cycle = (x / period) | 0; - const tween = x - cycle * period; - const linStep = easeInOutCubic(linearStep(tween, downtime, period)); - return cycle + linStep; - } - --function pixelAlignFrustum(camera, aspectRatio, pixelsPerScreenWidth, pixelsPerScreenHeight) { -+function pixelAlignFrustum( -+ camera: THREE.OrthographicCamera, -+ aspectRatio: number, -+ pixelsPerScreenWidth: number, -+ pixelsPerScreenHeight: number, -+) { - // 0. Get Pixel Grid Units - const worldScreenWidth = (camera.right - camera.left) / camera.zoom; - const worldScreenHeight = (camera.top - camera.bottom) / camera.zoom; -diff --git a/examples-testing/examples/webgpu_postprocessing_sobel.ts b/examples-testing/examples/webgpu_postprocessing_sobel.ts -index 01aa16ec..4f45e231 100644 ---- a/examples-testing/examples/webgpu_postprocessing_sobel.ts -+++ b/examples-testing/examples/webgpu_postprocessing_sobel.ts -@@ -1,12 +1,12 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { pass, sobel } from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; --let postProcessing; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; -+let postProcessing: THREE.PostProcessing; - - const params = { - enable: true, -diff --git a/examples-testing/examples/webgpu_postprocessing_ssaa.ts b/examples-testing/examples/webgpu_postprocessing_ssaa.ts -index 76e3a95c..7748d8f0 100644 ---- a/examples-testing/examples/webgpu_postprocessing_ssaa.ts -+++ b/examples-testing/examples/webgpu_postprocessing_ssaa.ts -@@ -1,13 +1,13 @@ --import * as THREE from 'three'; --import { ssaaPass } from 'three/tsl'; -+import * as THREE from 'three/webgpu'; -+import { ssaaPass, SSAAPassNode, ShaderNodeObject } from 'three/tsl'; - - import { Timer } from 'three/addons/misc/Timer.js'; - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let scene, mesh, renderer, postProcessing; --let camera, ssaaRenderPass; --let gui, stats, timer; -+let scene: THREE.Scene, mesh: THREE.InstancedMesh, renderer: THREE.WebGPURenderer, postProcessing: THREE.PostProcessing; -+let camera: THREE.PerspectiveCamera, ssaaRenderPass: ShaderNodeObject; -+let gui: GUI | undefined, stats: Stats, timer: Timer; - - const params = { - sampleLevel: 3, -@@ -148,7 +148,7 @@ function animate() { - mesh.rotation.y += delta * 0.5; - } - -- let newColor = ssaaRenderPass.clearColor; -+ let newColor: THREE.ColorRepresentation = ssaaRenderPass.clearColor; - - switch (params.clearColor) { - case 'blue': -@@ -173,7 +173,7 @@ function animate() { - - ssaaRenderPass.sampleLevel = params.sampleLevel; - -- camera.view.offsetX = params.viewOffsetX; -+ camera.view!.offsetX = params.viewOffsetX; - - postProcessing.render(); - -diff --git a/examples-testing/examples/webgpu_postprocessing_transition.ts b/examples-testing/examples/webgpu_postprocessing_transition.ts -index b66bad12..babbe1a9 100644 ---- a/examples-testing/examples/webgpu_postprocessing_transition.ts -+++ b/examples-testing/examples/webgpu_postprocessing_transition.ts -@@ -1,15 +1,30 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -+import { GUI, NumberController } from 'three/addons/libs/lil-gui.module.min.js'; - import TWEEN from 'three/addons/libs/tween.module.js'; --import { uniform, transition, pass } from 'three/tsl'; -+import { uniform, transition, pass, ShaderNodeObject, TransitionNode, UniformNode } from 'three/tsl'; - --let renderer, postProcessing, transitionController, transitionPass; -+let renderer: THREE.WebGPURenderer, -+ postProcessing: THREE.PostProcessing, -+ transitionController: NumberController, -+ transitionPass: ShaderNodeObject; - --const textures = []; -+const textures: THREE.Texture[] = []; - const clock = new THREE.Clock(); - --const effectController = { -+interface EffectController { -+ animateScene: boolean; -+ animateTransition: boolean; -+ transition: number; -+ _transition: UniformNode; -+ useTexture: boolean; -+ _useTexture: UniformNode; -+ texture: number; -+ cycle: boolean; -+ threshold: UniformNode; -+} -+ -+const effectController: EffectController = { - animateScene: true, - animateTransition: true, - transition: 0, -@@ -21,7 +36,7 @@ const effectController = { - threshold: uniform(0.1), - }; - --function generateInstancedMesh(geometry, material, count) { -+function generateInstancedMesh(geometry: THREE.BufferGeometry, material: THREE.MeshPhongNodeMaterial, count: number) { - const mesh = new THREE.InstancedMesh(geometry, material, count); - - const dummy = new THREE.Object3D(); -@@ -55,42 +70,54 @@ function generateInstancedMesh(geometry, material, count) { - return mesh; - } - --function FXScene(geometry, rotationSpeed, backgroundColor) { -- const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); -- camera.position.z = 20; -+class FXScene { -+ rotationSpeed: THREE.Vector3; - -- // Setup scene -- const scene = new THREE.Scene(); -- scene.background = new THREE.Color(backgroundColor); -- scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); -+ scene: THREE.Scene; -+ camera: THREE.PerspectiveCamera; -+ mesh: THREE.InstancedMesh; - -- const light = new THREE.DirectionalLight(0xffffff, 3); -- light.position.set(0, 1, 4); -- scene.add(light); -+ update: (delta: number) => void; - -- this.rotationSpeed = rotationSpeed; -+ resize: () => void; - -- const color = geometry.type === 'BoxGeometry' ? 0x0000ff : 0xff0000; -- const material = new THREE.MeshPhongNodeMaterial({ color: color, flatShading: true }); -- const mesh = generateInstancedMesh(geometry, material, 500); -- scene.add(mesh); -+ constructor(geometry: THREE.BufferGeometry, rotationSpeed: THREE.Vector3, backgroundColor: number) { -+ const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); -+ camera.position.z = 20; - -- this.scene = scene; -- this.camera = camera; -- this.mesh = mesh; -+ // Setup scene -+ const scene = new THREE.Scene(); -+ scene.background = new THREE.Color(backgroundColor); -+ scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); - -- this.update = function (delta) { -- if (effectController.animateScene) { -- mesh.rotation.x += this.rotationSpeed.x * delta; -- mesh.rotation.y += this.rotationSpeed.y * delta; -- mesh.rotation.z += this.rotationSpeed.z * delta; -- } -- }; -+ const light = new THREE.DirectionalLight(0xffffff, 3); -+ light.position.set(0, 1, 4); -+ scene.add(light); -+ -+ this.rotationSpeed = rotationSpeed; -+ -+ const color = geometry.type === 'BoxGeometry' ? 0x0000ff : 0xff0000; -+ const material = new THREE.MeshPhongNodeMaterial({ color: color, flatShading: true }); -+ const mesh = generateInstancedMesh(geometry, material, 500); -+ scene.add(mesh); - -- this.resize = function () { -- camera.aspect = window.innerWidth / window.innerHeight; -- camera.updateProjectionMatrix(); -- }; -+ this.scene = scene; -+ this.camera = camera; -+ this.mesh = mesh; -+ -+ this.update = function (delta) { -+ if (effectController.animateScene) { -+ mesh.rotation.x += this.rotationSpeed.x * delta; -+ mesh.rotation.y += this.rotationSpeed.y * delta; -+ mesh.rotation.z += this.rotationSpeed.z * delta; -+ } -+ }; -+ -+ this.resize = function () { -+ camera.aspect = window.innerWidth / window.innerHeight; -+ camera.updateProjectionMatrix(); -+ }; -+ } - } - - const fxSceneA = new FXScene(new THREE.BoxGeometry(2, 2, 2), new THREE.Vector3(0, -0.4, 0), 0xffffff); -diff --git a/examples-testing/examples/webgpu_procedural_texture.ts b/examples-testing/examples/webgpu_procedural_texture.ts -index 84e8ba9e..86560654 100644 ---- a/examples-testing/examples/webgpu_procedural_texture.ts -+++ b/examples-testing/examples/webgpu_procedural_texture.ts -@@ -1,9 +1,9 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { checker, uv, uniform, gaussianBlur, convertToTexture } from 'three/tsl'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - --let camera, scene, renderer; -+let camera: THREE.OrthographicCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - init(); - render(); -diff --git a/examples-testing/examples/webgpu_refraction.ts b/examples-testing/examples/webgpu_refraction.ts -index 4ce8b0a7..d41bc6f4 100644 ---- a/examples-testing/examples/webgpu_refraction.ts -+++ b/examples-testing/examples/webgpu_refraction.ts -@@ -1,13 +1,13 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { viewportSafeUV, viewportSharedTexture, screenUV, texture, uv } from 'three/tsl'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - --let cameraControls; -+let cameraControls: OrbitControls; - --let smallSphere; -+let smallSphere: THREE.Mesh; - - init(); - -diff --git a/examples-testing/examples/webgpu_shadowmap_vsm.ts b/examples-testing/examples/webgpu_shadowmap_vsm.ts -index a9f6f0e5..c68aa5fc 100644 ---- a/examples-testing/examples/webgpu_shadowmap_vsm.ts -+++ b/examples-testing/examples/webgpu_shadowmap_vsm.ts -@@ -1,14 +1,24 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, clock, stats; --let dirLight, spotLight; --let torusKnot, dirGroup; --let config; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ clock: THREE.Clock, -+ stats: Stats; -+let dirLight: THREE.DirectionalLight, spotLight: THREE.SpotLight; -+let torusKnot: THREE.Mesh, dirGroup: THREE.Group; -+let config: { -+ spotlightRadius: number; -+ spotlightSamples: number; -+ dirlightRadius: number; -+ dirlightSamples: number; -+ animate: boolean; -+}; - - init(); - -@@ -188,7 +198,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function animate(time) { -+function animate(time: DOMHighResTimeStamp) { - const delta = clock.getDelta(); - - if (config.animate === true) { -diff --git a/examples-testing/examples/webgpu_sky.ts b/examples-testing/examples/webgpu_sky.ts -index 097d06af..3836e7ee 100644 ---- a/examples-testing/examples/webgpu_sky.ts -+++ b/examples-testing/examples/webgpu_sky.ts -@@ -1,12 +1,12 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { SkyMesh } from 'three/addons/objects/SkyMesh.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - --let sky, sun; -+let sky: SkyMesh, sun: THREE.Vector3; - - init(); - -diff --git a/examples-testing/examples/webgpu_textures_2d-array_compressed.ts b/examples-testing/examples/webgpu_textures_2d-array_compressed.ts -index 3e8bf7ee..56db87fd 100644 ---- a/examples-testing/examples/webgpu_textures_2d-array_compressed.ts -+++ b/examples-testing/examples/webgpu_textures_2d-array_compressed.ts -@@ -1,11 +1,16 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { texture, uniform, uv } from 'three/tsl'; - - import Stats from 'three/addons/libs/stats.module.js'; - import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - --let camera, scene, mesh, renderer, stats, clock; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ mesh: THREE.Mesh, -+ renderer: THREE.WebGPURenderer, -+ stats: Stats, -+ clock: THREE.Clock; - - const depth = uniform(0); - -diff --git a/examples-testing/examples/webgpu_textures_anisotropy.ts b/examples-testing/examples/webgpu_textures_anisotropy.ts -index 7eb0ce1b..7528f59f 100644 ---- a/examples-testing/examples/webgpu_textures_anisotropy.ts -+++ b/examples-testing/examples/webgpu_textures_anisotropy.ts -@@ -1,10 +1,10 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import Stats from 'three/addons/libs/stats.module.js'; - --let container, stats; -+let container: HTMLDivElement, stats: Stats; - --let camera, scene1, scene2, renderer; -+let camera: THREE.PerspectiveCamera, scene1: THREE.Scene, scene2: THREE.Scene, renderer: THREE.WebGPURenderer; - - let mouseX = 0, - mouseY = 0; -@@ -75,11 +75,11 @@ function init() { - texture2.repeat.set(512, 512); - - if (maxAnisotropy > 0) { -- document.getElementById('val_left').innerHTML = texture1.anisotropy; -- document.getElementById('val_right').innerHTML = texture2.anisotropy; -+ document.getElementById('val_left')!.innerHTML = texture1.anisotropy.toString(); -+ document.getElementById('val_right')!.innerHTML = texture2.anisotropy.toString(); - } else { -- document.getElementById('val_left').innerHTML = 'not supported'; -- document.getElementById('val_right').innerHTML = 'not supported'; -+ document.getElementById('val_left')!.innerHTML = 'not supported'; -+ document.getElementById('val_right')!.innerHTML = 'not supported'; - } - - // -@@ -114,7 +114,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onDocumentMouseMove(event) { -+function onDocumentMouseMove(event: MouseEvent) { - const windowHalfX = window.innerWidth / 2; - const windowHalfY = window.innerHeight / 2; - -diff --git a/examples-testing/examples/webgpu_textures_partialupdate.ts b/examples-testing/examples/webgpu_textures_partialupdate.ts -index e8ebe87d..9fae06bd 100644 ---- a/examples-testing/examples/webgpu_textures_partialupdate.ts -+++ b/examples-testing/examples/webgpu_textures_partialupdate.ts -@@ -1,6 +1,11 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --let camera, scene, renderer, clock, dataTexture, diffuseMap; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGPURenderer, -+ clock: THREE.Clock, -+ dataTexture: THREE.DataTexture, -+ diffuseMap: THREE.Texture; - - let last = 0; - const position = new THREE.Vector2(); -@@ -78,7 +83,7 @@ async function animate() { - } - } - --function updateDataTexture(texture) { -+function updateDataTexture(texture: THREE.DataTexture) { - const size = texture.image.width * texture.image.height; - const data = texture.image.data; - -diff --git a/examples-testing/examples/webgpu_tonemapping.ts b/examples-testing/examples/webgpu_tonemapping.ts -index 07fb8d27..ea32b4d6 100644 ---- a/examples-testing/examples/webgpu_tonemapping.ts -+++ b/examples-testing/examples/webgpu_tonemapping.ts -@@ -1,22 +1,35 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -+import { GUI, NumberController } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - --let mesh, renderer, scene, camera, controls; --let gui, -- guiExposure = null; -+let mesh: THREE.Object3D, -+ renderer: THREE.WebGPURenderer, -+ scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ controls: OrbitControls; -+let gui: GUI, -+ guiExposure: NumberController | null = null; -+ -+type ToneMapping = 'None' | 'Linear' | 'Reinhard' | 'Cineon' | 'ACESFilmic' | 'AgX' | 'Neutral'; -+ -+interface Params { -+ exposure: number; -+ toneMapping: ToneMapping; -+ blurriness: number; -+ intensity: number; -+} - --const params = { -+const params: Params = { - exposure: 1.0, - toneMapping: 'AgX', - blurriness: 0.3, - intensity: 1.0, - }; - --const toneMappingOptions = { -+const toneMappingOptions: { [Key in ToneMapping]: THREE.ToneMapping } = { - None: THREE.NoToneMapping, - Linear: THREE.LinearToneMapping, - Reinhard: THREE.ReinhardToneMapping, -@@ -70,7 +83,7 @@ async function init() { - - // model - -- mesh = gltf.scene.getObjectByName('node_damagedHelmet_-6514'); -+ mesh = gltf.scene.getObjectByName('node_damagedHelmet_-6514')!; - scene.add(mesh); - - window.addEventListener('resize', onWindowResize); -@@ -79,7 +92,7 @@ async function init() { - const toneMappingFolder = gui.addFolder('Tone Mapping'); - - toneMappingFolder -- .add(params, 'toneMapping', Object.keys(toneMappingOptions)) -+ .add(params, 'toneMapping', Object.keys(toneMappingOptions) as ToneMapping[]) - - .name('type') - .onChange(function () { -@@ -116,11 +129,11 @@ async function init() { - gui.open(); - } - --function updateGUI(folder) { -+function updateGUI(folder: GUI) { - if (params.toneMapping === 'None') { -- guiExposure.hide(); -+ guiExposure!.hide(); - } else { -- guiExposure.show(); -+ guiExposure!.show(); - } - } - -diff --git a/examples-testing/examples/webgpu_tsl_coffee_smoke.ts b/examples-testing/examples/webgpu_tsl_coffee_smoke.ts -index 9e2404cc..9bd5ef8a 100644 ---- a/examples-testing/examples/webgpu_tsl_coffee_smoke.ts -+++ b/examples-testing/examples/webgpu_tsl_coffee_smoke.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { - mix, - mul, -@@ -18,7 +18,7 @@ import { - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer, controls: OrbitControls; - - init(); - -@@ -36,7 +36,9 @@ function init() { - // baked model - - gltfLoader.load('./models/gltf/coffeeMug.glb', gltf => { -- gltf.scene.getObjectByName('baked').material.map.anisotropy = 8; -+ ( -+ gltf.scene.getObjectByName('baked') as THREE.Mesh -+ ).material.map!.anisotropy = 8; - scene.add(gltf.scene); - }); - -diff --git a/examples-testing/examples/webgpu_tsl_vfx_flames.ts b/examples-testing/examples/webgpu_tsl_vfx_flames.ts -index 6e72392a..b04fdc77 100644 ---- a/examples-testing/examples/webgpu_tsl_vfx_flames.ts -+++ b/examples-testing/examples/webgpu_tsl_vfx_flames.ts -@@ -1,4 +1,4 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - import { - PI2, - oneMinus, -@@ -18,7 +18,15 @@ import { - - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - --let camera, scene, renderer, controls; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer, controls: OrbitControls; -+ -+interface Gradient { -+ element: HTMLCanvasElement; -+ context: CanvasRenderingContext2D; -+ colors: string[]; -+ texture: THREE.CanvasTexture; -+ update: () => void; -+} - - init(); - -@@ -38,11 +46,11 @@ function init() { - - // gradient canvas - -- const gradient = {}; -+ const gradient = {} as Gradient; - gradient.element = document.createElement('canvas'); - gradient.element.width = 128; - gradient.element.height = 1; -- gradient.context = gradient.element.getContext('2d'); -+ gradient.context = gradient.element.getContext('2d')!; - - gradient.colors = ['#090033', '#5f1f93', '#e02e96', '#ffbd80', '#fff0db']; - -diff --git a/examples-testing/examples/webgpu_video_panorama.ts b/examples-testing/examples/webgpu_video_panorama.ts -index e409b3c0..78885bec 100644 ---- a/examples-testing/examples/webgpu_video_panorama.ts -+++ b/examples-testing/examples/webgpu_video_panorama.ts -@@ -1,6 +1,6 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGPURenderer; - - let isUserInteracting = false, - lon = 0, -@@ -17,7 +17,7 @@ const distance = 0.5; - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.25, 10); - -@@ -27,7 +27,7 @@ function init() { - // invert the geometry on the x-axis so that all of the faces point inward - geometry.scale(-1, 1, 1); - -- const video = document.getElementById('video'); -+ const video = document.getElementById('video') as HTMLVideoElement; - video.play(); - - const texture = new THREE.VideoTexture(video); -@@ -59,7 +59,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onPointerDown(event) { -+function onPointerDown(event: PointerEvent) { - isUserInteracting = true; - - onPointerDownPointerX = event.clientX; -@@ -69,7 +69,7 @@ function onPointerDown(event) { - onPointerDownLat = lat; - } - --function onPointerMove(event) { -+function onPointerMove(event: PointerEvent) { - if (isUserInteracting === true) { - lon = (onPointerDownPointerX - event.clientX) * 0.1 + onPointerDownLon; - lat = (onPointerDownPointerY - event.clientY) * 0.1 + onPointerDownLat; -diff --git a/examples-testing/examples/webgpu_water.ts b/examples-testing/examples/webgpu_water.ts -index 76e09f1f..edefce0e 100644 ---- a/examples-testing/examples/webgpu_water.ts -+++ b/examples-testing/examples/webgpu_water.ts -@@ -1,12 +1,16 @@ --import * as THREE from 'three'; -+import * as THREE from 'three/webgpu'; - - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; --import { WaterMesh } from 'three/addons/objects/Water2Mesh.js'; -+import { WaterMesh, WaterNode } from 'three/addons/objects/Water2Mesh.js'; - --let scene, camera, clock, renderer, water; -+let scene: THREE.Scene, -+ camera: THREE.PerspectiveCamera, -+ clock: THREE.Clock, -+ renderer: THREE.WebGPURenderer, -+ water: WaterMesh; - --let torusKnot; -+let torusKnot: THREE.Mesh; - - const params = { - color: '#ffffff', -@@ -121,7 +125,7 @@ function init() { - // gui - - const gui = new GUI(); -- const waterNode = water.material.fragmentNode; -+ const waterNode = water.material.fragmentNode as WaterNode; - - gui.addColor(params, 'color').onChange(function (value) { - waterNode.color.value.set(value); -diff --git a/examples-testing/examples/webxr_ar_cones.ts b/examples-testing/examples/webxr_ar_cones.ts -index 95eb3439..0e641cdb 100644 ---- a/examples-testing/examples/webxr_ar_cones.ts -+++ b/examples-testing/examples/webxr_ar_cones.ts -@@ -1,8 +1,8 @@ - import * as THREE from 'three'; - import { ARButton } from 'three/addons/webxr/ARButton.js'; - --let camera, scene, renderer; --let controller; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controller: THREE.XRTargetRaySpace; - - init(); - -diff --git a/examples-testing/examples/webxr_ar_hittest.ts b/examples-testing/examples/webxr_ar_hittest.ts -index 1867cc47..77acf97e 100644 ---- a/examples-testing/examples/webxr_ar_hittest.ts -+++ b/examples-testing/examples/webxr_ar_hittest.ts -@@ -1,13 +1,13 @@ - import * as THREE from 'three'; - import { ARButton } from 'three/addons/webxr/ARButton.js'; - --let container; --let camera, scene, renderer; --let controller; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controller: THREE.XRTargetRaySpace; - --let reticle; -+let reticle: THREE.Mesh; - --let hitTestSource = null; -+let hitTestSource: XRHitTestSource | null = null; - let hitTestSourceRequested = false; - - init(); -@@ -77,14 +77,14 @@ function onWindowResize() { - - // - --function animate(timestamp, frame) { -+function animate(timestamp: DOMHighResTimeStamp, frame: XRFrame) { - if (frame) { - const referenceSpace = renderer.xr.getReferenceSpace(); -- const session = renderer.xr.getSession(); -+ const session = renderer.xr.getSession()!; - - if (hitTestSourceRequested === false) { - session.requestReferenceSpace('viewer').then(function (referenceSpace) { -- session.requestHitTestSource({ space: referenceSpace }).then(function (source) { -+ session.requestHitTestSource!({ space: referenceSpace })!.then(function (source) { - hitTestSource = source; - }); - }); -@@ -104,7 +104,7 @@ function animate(timestamp, frame) { - const hit = hitTestResults[0]; - - reticle.visible = true; -- reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix); -+ reticle.matrix.fromArray(hit.getPose(referenceSpace!)!.transform.matrix); - } else { - reticle.visible = false; - } -diff --git a/examples-testing/examples/webxr_ar_lighting.ts b/examples-testing/examples/webxr_ar_lighting.ts -index 9de23ad9..df20bb43 100644 ---- a/examples-testing/examples/webxr_ar_lighting.ts -+++ b/examples-testing/examples/webxr_ar_lighting.ts -@@ -3,9 +3,9 @@ import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - import { ARButton } from 'three/addons/webxr/ARButton.js'; - import { XREstimatedLight } from 'three/addons/webxr/XREstimatedLight.js'; - --let camera, scene, renderer; --let controller; --let defaultEnvironment; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controller: THREE.XRTargetRaySpace; -+let defaultEnvironment: THREE.DataTexture; - - init(); - -diff --git a/examples-testing/examples/webxr_vr_handinput.ts b/examples-testing/examples/webxr_vr_handinput.ts -index d746e458..af438f0f 100644 ---- a/examples-testing/examples/webxr_vr_handinput.ts -+++ b/examples-testing/examples/webxr_vr_handinput.ts -@@ -4,13 +4,13 @@ import { VRButton } from 'three/addons/webxr/VRButton.js'; - import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - import { XRHandModelFactory } from 'three/addons/webxr/XRHandModelFactory.js'; - --let container; --let camera, scene, renderer; --let hand1, hand2; --let controller1, controller2; --let controllerGrip1, controllerGrip2; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let hand1: THREE.XRHandSpace, hand2: THREE.XRHandSpace; -+let controller1: THREE.XRTargetRaySpace, controller2: THREE.XRTargetRaySpace; -+let controllerGrip1: THREE.XRGripSpace, controllerGrip2: THREE.XRGripSpace; - --let controls; -+let controls: OrbitControls; - - init(); - -diff --git a/examples-testing/examples/webxr_vr_panorama.ts b/examples-testing/examples/webxr_vr_panorama.ts -index 535e1c93..ab2e4ee0 100644 ---- a/examples-testing/examples/webxr_vr_panorama.ts -+++ b/examples-testing/examples/webxr_vr_panorama.ts -@@ -1,9 +1,9 @@ - import * as THREE from 'three'; - import { VRButton } from 'three/addons/webxr/VRButton.js'; - --let camera; --let renderer; --let scene; -+let camera: THREE.PerspectiveCamera; -+let renderer: THREE.WebGLRenderer; -+let scene: THREE.Scene; - - init(); - -@@ -53,8 +53,8 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) { -- const textures = []; -+function getTexturesFromAtlasFile(atlasImgUrl: string, tilesNum: number) { -+ const textures: THREE.Texture[] = []; - - for (let i = 0; i < tilesNum; i++) { - textures[i] = new THREE.Texture(); -@@ -67,7 +67,7 @@ function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) { - - for (let i = 0; i < textures.length; i++) { - canvas = document.createElement('canvas'); -- context = canvas.getContext('2d'); -+ context = canvas.getContext('2d')!; - canvas.height = tileWidth; - canvas.width = tileWidth; - context.drawImage(imageObj, tileWidth * i, 0, tileWidth, tileWidth, 0, 0, tileWidth, tileWidth); -diff --git a/examples-testing/examples/webxr_vr_panorama_depth.ts b/examples-testing/examples/webxr_vr_panorama_depth.ts -index 66215469..9ad505c4 100644 ---- a/examples-testing/examples/webxr_vr_panorama_depth.ts -+++ b/examples-testing/examples/webxr_vr_panorama_depth.ts -@@ -1,12 +1,16 @@ - import * as THREE from 'three'; - import { VRButton } from 'three/addons/webxr/VRButton.js'; - --let camera, scene, renderer, sphere, clock; -+let camera: THREE.PerspectiveCamera, -+ scene: THREE.Scene, -+ renderer: THREE.WebGLRenderer, -+ sphere: THREE.Mesh, -+ clock: THREE.Clock; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - - clock = new THREE.Clock(); - -diff --git a/examples-testing/examples/webxr_vr_rollercoaster.ts b/examples-testing/examples/webxr_vr_rollercoaster.ts -index b8c35a9e..ee5f02da 100644 ---- a/examples-testing/examples/webxr_vr_rollercoaster.ts -+++ b/examples-testing/examples/webxr_vr_rollercoaster.ts -@@ -9,7 +9,7 @@ import { - } from 'three/addons/misc/RollerCoaster.js'; - import { VRButton } from 'three/addons/webxr/VRButton.js'; - --let mesh, material, geometry; -+let mesh: THREE.Mesh, material: THREE.Material, geometry: SkyGeometry; - - const renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); -@@ -87,7 +87,7 @@ const curve = (function () { - const vector2 = new THREE.Vector3(); - - return { -- getPointAt: function (t) { -+ getPointAt: function (t: number) { - t = t * PI2; - - const x = Math.sin(t * 3) * Math.cos(t * 4) * 50; -@@ -97,7 +97,7 @@ const curve = (function () { - return vector.set(x, y, z).multiplyScalar(2); - }, - -- getTangentAt: function (t) { -+ getTangentAt: function (t: number) { - const delta = 0.0001; - const t1 = Math.max(0, t - delta); - const t2 = Math.min(1, t + delta); -@@ -130,7 +130,7 @@ mesh = new THREE.Mesh(geometry, material); - mesh.position.y = 0.1; - scene.add(mesh); - --const funfairs = []; -+const funfairs: THREE.Mesh[] = []; - - // - -diff --git a/examples-testing/examples/webxr_vr_sandbox.ts b/examples-testing/examples/webxr_vr_sandbox.ts -index 9e8e7590..72aab013 100644 ---- a/examples-testing/examples/webxr_vr_sandbox.ts -+++ b/examples-testing/examples/webxr_vr_sandbox.ts -@@ -11,9 +11,9 @@ import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFa - import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - import Stats from 'three/addons/libs/stats.module.js'; - --let camera, scene, renderer; --let reflector; --let stats, statsMesh; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let reflector: Reflector; -+let stats: Stats, statsMesh: HTMLMesh; - - const parameters = { - radius: 0.6, -@@ -180,7 +180,7 @@ function onWindowResize() { - - function animate() { - const time = performance.now() * 0.0002; -- const torus = scene.getObjectByName('torus'); -+ const torus = scene.getObjectByName('torus')!; - torus.rotation.x = time * 0.4; - torus.rotation.y = time; - -@@ -188,5 +188,9 @@ function animate() { - stats.update(); - - // Canvas elements doesn't trigger DOM updates, so we have to update the texture -- statsMesh.material.map.update(); -+ (statsMesh.material.map as HTMLTexture).update(); -+} -+ -+interface HTMLTexture extends THREE.CanvasTexture { -+ update(): void; - } -diff --git a/examples-testing/examples/webxr_vr_video.ts b/examples-testing/examples/webxr_vr_video.ts -index 50a99041..b5925eb1 100644 ---- a/examples-testing/examples/webxr_vr_video.ts -+++ b/examples-testing/examples/webxr_vr_video.ts -@@ -1,12 +1,12 @@ - import * as THREE from 'three'; - import { VRButton } from 'three/addons/webxr/VRButton.js'; - --let camera, scene, renderer; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; - - init(); - - function init() { -- const container = document.getElementById('container'); -+ const container = document.getElementById('container')!; - container.addEventListener('click', function () { - video.play(); - }); -@@ -16,7 +16,7 @@ function init() { - - // video - -- const video = document.getElementById('video'); -+ const video = document.getElementById('video') as HTMLVideoElement; - video.play(); - - const texture = new THREE.VideoTexture(video); -diff --git a/examples-testing/examples/webxr_xr_controls_transform.ts b/examples-testing/examples/webxr_xr_controls_transform.ts -index 6e690141..ee8cabbd 100644 ---- a/examples-testing/examples/webxr_xr_controls_transform.ts -+++ b/examples-testing/examples/webxr_xr_controls_transform.ts -@@ -3,14 +3,14 @@ import { TransformControls } from 'three/addons/controls/TransformControls.js'; - import { XRButton } from 'three/addons/webxr/XRButton.js'; - import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - --let container; --let camera, scene, renderer; --let controller1, controller2, line; --let controllerGrip1, controllerGrip2; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controller1: THREE.XRTargetRaySpace, controller2: THREE.XRTargetRaySpace, line: THREE.Line; -+let controllerGrip1: THREE.XRGripSpace, controllerGrip2: THREE.XRGripSpace; - --let raycaster; -+let raycaster: THREE.Raycaster; - --let controls, group; -+let controls: TransformControls, group: THREE.Group; - - init(); - -@@ -148,7 +148,7 @@ function init() { - window.addEventListener('resize', onWindowResize); - } - --function onSelect(event) { -+function onSelect(event: THREE.Event<'select', THREE.XRTargetRaySpace>) { - const controller = event.target; - - controller1.userData.active = false; -@@ -173,7 +173,7 @@ function onSelect(event) { - } - } - --function onControllerEvent(event) { -+function onControllerEvent(event: THREE.Event<'selectstart' | 'selectend' | 'move', THREE.XRTargetRaySpace>) { - const controller = event.target; - - if (controller.userData.active === false) return; -diff --git a/examples-testing/examples/webxr_xr_dragging_custom_depth.ts b/examples-testing/examples/webxr_xr_dragging_custom_depth.ts -index 2cd50ba4..b97f3eee 100644 ---- a/examples-testing/examples/webxr_xr_dragging_custom_depth.ts -+++ b/examples-testing/examples/webxr_xr_dragging_custom_depth.ts -@@ -3,18 +3,18 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - import { XRButton } from 'three/addons/webxr/XRButton.js'; - import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - --let container; --let camera, scene, renderer; --let controller1, controller2; --let controllerGrip1, controllerGrip2; -+let container: HTMLDivElement; -+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: THREE.WebGLRenderer; -+let controller1: THREE.XRTargetRaySpace, controller2: THREE.XRTargetRaySpace; -+let controllerGrip1: THREE.XRGripSpace, controllerGrip2: THREE.XRGripSpace; - let isDepthSupplied = false; - --let raycaster; -+let raycaster: THREE.Raycaster; - --const intersected = []; -+const intersected: THREE.Object3D[] = []; - const tempMatrix = new THREE.Matrix4(); - --let controls, group; -+let controls: OrbitControls, group: THREE.Group; - - init(); - animate(); -@@ -289,7 +289,7 @@ function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - } - --function onSelectStart(event) { -+function onSelectStart(event: THREE.Event<'selectstart', THREE.XRTargetRaySpace> & { data: XRInputSource }) { - const controller = event.target; - - const intersections = getIntersections(controller); -@@ -297,7 +297,7 @@ function onSelectStart(event) { - if (intersections.length > 0) { - const intersection = intersections[0]; - -- const object = intersection.object; -+ const object = intersection.object as THREE.Mesh; - object.material.uniforms.emissive.value = 1; - controller.attach(object); - -@@ -307,7 +307,7 @@ function onSelectStart(event) { - controller.userData.targetRayMode = event.data.targetRayMode; - } - --function onSelectEnd(event) { -+function onSelectEnd(event: THREE.Event<'selectend', THREE.XRTargetRaySpace> & { data: XRInputSource }) { - const controller = event.target; - - if (controller.userData.selected !== undefined) { -@@ -319,7 +319,7 @@ function onSelectEnd(event) { - } - } - --function getIntersections(controller) { -+function getIntersections(controller: THREE.XRTargetRaySpace) { - controller.updateMatrixWorld(); - - tempMatrix.identity().extractRotation(controller.matrixWorld); -@@ -330,7 +330,7 @@ function getIntersections(controller) { - return raycaster.intersectObjects(group.children, false); - } - --function intersectObjects(controller) { -+function intersectObjects(controller: THREE.XRTargetRaySpace) { - // Do not highlight in mobile-ar - - if (controller.userData.targetRayMode === 'screen') return; -@@ -345,19 +345,19 @@ function intersectObjects(controller) { - if (intersections.length > 0) { - const intersection = intersections[0]; - -- const object = intersection.object; -+ const object = intersection.object as THREE.Mesh; - object.material.uniforms.emissive.value = 1; - intersected.push(object); - -- line.scale.z = intersection.distance; -+ line!.scale.z = intersection.distance; - } else { -- line.scale.z = 5; -+ line!.scale.z = 5; - } - } - - function cleanIntersected() { - while (intersected.length) { -- const object = intersected.pop(); -+ const object = intersected.pop() as THREE.Mesh; - object.material.uniforms.emissive.value = 0; - } - } -@@ -371,16 +371,18 @@ function animate() { - function render() { - if (renderer.xr.hasDepthSensing() && !isDepthSupplied) { - group.children.forEach(child => { -- child.material.uniforms.depthColor.value = renderer.xr.getDepthTexture(); -- child.material.uniforms.depthWidth.value = 1680; -- child.material.uniforms.depthHeight.value = 1760; -+ (child as THREE.Mesh).material.uniforms.depthColor.value = -+ renderer.xr.getDepthTexture(); -+ (child as THREE.Mesh).material.uniforms.depthWidth.value = 1680; -+ (child as THREE.Mesh).material.uniforms.depthHeight.value = -+ 1760; - - isDepthSupplied = true; - }); - } else if (!renderer.xr.hasDepthSensing() && isDepthSupplied) { - group.children.forEach(child => { -- child.material.uniforms.depthWidth.value = 0; -- child.material.uniforms.depthHeight.value = 0; -+ (child as THREE.Mesh).material.uniforms.depthWidth.value = 0; -+ (child as THREE.Mesh).material.uniforms.depthHeight.value = 0; - - isDepthSupplied = false; - }); diff --git a/examples-testing/examples/css2d_label.ts b/examples-testing/examples/css2d_label.ts deleted file mode 100644 index 48a2d1f05..000000000 --- a/examples-testing/examples/css2d_label.ts +++ /dev/null @@ -1,186 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let gui; - -let camera, scene, renderer, labelRenderer; - -const layers = { - 'Toggle Name': function () { - camera.layers.toggle(0); - }, - 'Toggle Mass': function () { - camera.layers.toggle(1); - }, - 'Enable All': function () { - camera.layers.enableAll(); - }, - - 'Disable All': function () { - camera.layers.disableAll(); - }, -}; - -const clock = new THREE.Clock(); -const textureLoader = new THREE.TextureLoader(); - -let moon; - -init(); -animate(); - -function init() { - const EARTH_RADIUS = 1; - const MOON_RADIUS = 0.27; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); - camera.position.set(10, 5, 20); - camera.layers.enableAll(); - - scene = new THREE.Scene(); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(0, 0, 1); - dirLight.layers.enableAll(); - scene.add(dirLight); - - const axesHelper = new THREE.AxesHelper(5); - axesHelper.layers.enableAll(); - scene.add(axesHelper); - - // - - const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 16, 16); - const earthMaterial = new THREE.MeshPhongMaterial({ - specular: 0x333333, - shininess: 5, - map: textureLoader.load('textures/planets/earth_atmos_2048.jpg'), - specularMap: textureLoader.load('textures/planets/earth_specular_2048.jpg'), - normalMap: textureLoader.load('textures/planets/earth_normal_2048.jpg'), - normalScale: new THREE.Vector2(0.85, 0.85), - }); - earthMaterial.map.colorSpace = THREE.SRGBColorSpace; - const earth = new THREE.Mesh(earthGeometry, earthMaterial); - scene.add(earth); - - const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS, 16, 16); - const moonMaterial = new THREE.MeshPhongMaterial({ - shininess: 5, - map: textureLoader.load('textures/planets/moon_1024.jpg'), - }); - moonMaterial.map.colorSpace = THREE.SRGBColorSpace; - moon = new THREE.Mesh(moonGeometry, moonMaterial); - scene.add(moon); - - // - - earth.layers.enableAll(); - moon.layers.enableAll(); - - const earthDiv = document.createElement('div'); - earthDiv.className = 'label'; - earthDiv.textContent = 'Earth'; - earthDiv.style.backgroundColor = 'transparent'; - - const earthLabel = new CSS2DObject(earthDiv); - earthLabel.position.set(1.5 * EARTH_RADIUS, 0, 0); - earthLabel.center.set(0, 1); - earth.add(earthLabel); - earthLabel.layers.set(0); - - const earthMassDiv = document.createElement('div'); - earthMassDiv.className = 'label'; - earthMassDiv.textContent = '5.97237e24 kg'; - earthMassDiv.style.backgroundColor = 'transparent'; - - const earthMassLabel = new CSS2DObject(earthMassDiv); - earthMassLabel.position.set(1.5 * EARTH_RADIUS, 0, 0); - earthMassLabel.center.set(0, 0); - earth.add(earthMassLabel); - earthMassLabel.layers.set(1); - - const moonDiv = document.createElement('div'); - moonDiv.className = 'label'; - moonDiv.textContent = 'Moon'; - moonDiv.style.backgroundColor = 'transparent'; - - const moonLabel = new CSS2DObject(moonDiv); - moonLabel.position.set(1.5 * MOON_RADIUS, 0, 0); - moonLabel.center.set(0, 1); - moon.add(moonLabel); - moonLabel.layers.set(0); - - const moonMassDiv = document.createElement('div'); - moonMassDiv.className = 'label'; - moonMassDiv.textContent = '7.342e22 kg'; - moonMassDiv.style.backgroundColor = 'transparent'; - - const moonMassLabel = new CSS2DObject(moonMassDiv); - moonMassLabel.position.set(1.5 * MOON_RADIUS, 0, 0); - moonMassLabel.center.set(0, 0); - moon.add(moonMassLabel); - moonMassLabel.layers.set(1); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - labelRenderer = new CSS2DRenderer(); - labelRenderer.setSize(window.innerWidth, window.innerHeight); - labelRenderer.domElement.style.position = 'absolute'; - labelRenderer.domElement.style.top = '0px'; - document.body.appendChild(labelRenderer.domElement); - - const controls = new OrbitControls(camera, labelRenderer.domElement); - controls.minDistance = 5; - controls.maxDistance = 100; - - // - - window.addEventListener('resize', onWindowResize); - - initGui(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - labelRenderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - requestAnimationFrame(animate); - - const elapsed = clock.getElapsedTime(); - - moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5); - - renderer.render(scene, camera); - labelRenderer.render(scene, camera); -} - -// - -function initGui() { - gui = new GUI(); - - gui.title('Camera Layers'); - - gui.add(layers, 'Toggle Name'); - gui.add(layers, 'Toggle Mass'); - gui.add(layers, 'Enable All'); - gui.add(layers, 'Disable All'); - - gui.open(); -} diff --git a/examples-testing/examples/css3d_molecules.ts b/examples-testing/examples/css3d_molecules.ts deleted file mode 100644 index 538472607..000000000 --- a/examples-testing/examples/css3d_molecules.ts +++ /dev/null @@ -1,353 +0,0 @@ -import * as THREE from 'three'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { PDBLoader } from 'three/addons/loaders/PDBLoader.js'; -import { CSS3DRenderer, CSS3DObject, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; -let controls; -let root; - -const objects = []; -const tmpVec1 = new THREE.Vector3(); -const tmpVec2 = new THREE.Vector3(); -const tmpVec3 = new THREE.Vector3(); -const tmpVec4 = new THREE.Vector3(); -const offset = new THREE.Vector3(); - -const VIZ_TYPE = { - Atoms: 0, - Bonds: 1, - 'Atoms + Bonds': 2, -}; - -const MOLECULES = { - Ethanol: 'ethanol.pdb', - Aspirin: 'aspirin.pdb', - Caffeine: 'caffeine.pdb', - Nicotine: 'nicotine.pdb', - LSD: 'lsd.pdb', - Cocaine: 'cocaine.pdb', - Cholesterol: 'cholesterol.pdb', - Lycopene: 'lycopene.pdb', - Glucose: 'glucose.pdb', - 'Aluminium oxide': 'Al2O3.pdb', - Cubane: 'cubane.pdb', - Copper: 'cu.pdb', - Fluorite: 'caf2.pdb', - Salt: 'nacl.pdb', - 'YBCO superconductor': 'ybco.pdb', - Buckyball: 'buckyball.pdb', - // 'Diamond': 'diamond.pdb', - Graphite: 'graphite.pdb', -}; - -const params = { - vizType: 2, - molecule: 'caffeine.pdb', -}; - -const loader = new PDBLoader(); -const colorSpriteMap = {}; -const baseSprite = document.createElement('img'); - -init(); -animate(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - - root = new THREE.Object3D(); - scene.add(root); - - // - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - document.getElementById('container').appendChild(renderer.domElement); - - // - - controls = new TrackballControls(camera, renderer.domElement); - controls.rotateSpeed = 0.5; - - // - - baseSprite.onload = function () { - loadMolecule(params.molecule); - }; - - baseSprite.src = 'textures/sprites/ball.png'; - - // - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - - gui.add(params, 'vizType', VIZ_TYPE).onChange(changeVizType); - gui.add(params, 'molecule', MOLECULES).onChange(loadMolecule); - gui.open(); -} - -function changeVizType(value) { - if (value === 0) showAtoms(); - else if (value === 1) showBonds(); - else showAtomsBonds(); -} - -// - -function showAtoms() { - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; - - if (object instanceof CSS3DSprite) { - object.element.style.display = ''; - object.visible = true; - } else { - object.element.style.display = 'none'; - object.visible = false; - } - } -} - -function showBonds() { - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; - - if (object instanceof CSS3DSprite) { - object.element.style.display = 'none'; - object.visible = false; - } else { - object.element.style.display = ''; - object.element.style.height = object.userData.bondLengthFull; - object.visible = true; - } - } -} - -function showAtomsBonds() { - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; - - object.element.style.display = ''; - object.visible = true; - - if (!(object instanceof CSS3DSprite)) { - object.element.style.height = object.userData.bondLengthShort; - } - } -} - -// - -function colorify(ctx, width, height, color) { - const r = color.r, - g = color.g, - b = color.b; - - const imageData = ctx.getImageData(0, 0, width, height); - const data = imageData.data; - - for (let i = 0, l = data.length; i < l; i += 4) { - data[i + 0] *= r; - data[i + 1] *= g; - data[i + 2] *= b; - } - - ctx.putImageData(imageData, 0, 0); -} - -function imageToCanvas(image) { - const width = image.width; - const height = image.height; - - const canvas = document.createElement('canvas'); - - canvas.width = width; - canvas.height = height; - - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0, width, height); - - return canvas; -} - -// - -function loadMolecule(model) { - const url = 'models/pdb/' + model; - - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; - object.parent.remove(object); - } - - objects.length = 0; - - loader.load(url, function (pdb) { - const geometryAtoms = pdb.geometryAtoms; - const geometryBonds = pdb.geometryBonds; - const json = pdb.json; - - geometryAtoms.computeBoundingBox(); - geometryAtoms.boundingBox.getCenter(offset).negate(); - - geometryAtoms.translate(offset.x, offset.y, offset.z); - geometryBonds.translate(offset.x, offset.y, offset.z); - - const positionAtoms = geometryAtoms.getAttribute('position'); - const colorAtoms = geometryAtoms.getAttribute('color'); - - const position = new THREE.Vector3(); - const color = new THREE.Color(); - - for (let i = 0; i < positionAtoms.count; i++) { - position.fromBufferAttribute(positionAtoms, i); - color.fromBufferAttribute(colorAtoms, i); - - const atomJSON = json.atoms[i]; - const element = atomJSON[4]; - - if (!colorSpriteMap[element]) { - const canvas = imageToCanvas(baseSprite); - const context = canvas.getContext('2d'); - - colorify(context, canvas.width, canvas.height, color); - - const dataUrl = canvas.toDataURL(); - - colorSpriteMap[element] = dataUrl; - } - - const colorSprite = colorSpriteMap[element]; - - const atom = document.createElement('img'); - atom.src = colorSprite; - - const object = new CSS3DSprite(atom); - object.position.copy(position); - object.position.multiplyScalar(75); - - object.matrixAutoUpdate = false; - object.updateMatrix(); - - root.add(object); - - objects.push(object); - } - - const positionBonds = geometryBonds.getAttribute('position'); - - const start = new THREE.Vector3(); - const end = new THREE.Vector3(); - - for (let i = 0; i < positionBonds.count; i += 2) { - start.fromBufferAttribute(positionBonds, i); - end.fromBufferAttribute(positionBonds, i + 1); - - start.multiplyScalar(75); - end.multiplyScalar(75); - - tmpVec1.subVectors(end, start); - const bondLength = tmpVec1.length() - 50; - - // - - let bond = document.createElement('div'); - bond.className = 'bond'; - bond.style.height = bondLength + 'px'; - - let object = new CSS3DObject(bond); - object.position.copy(start); - object.position.lerp(end, 0.5); - - object.userData.bondLengthShort = bondLength + 'px'; - object.userData.bondLengthFull = bondLength + 55 + 'px'; - - // - - const axis = tmpVec2.set(0, 1, 0).cross(tmpVec1); - const radians = Math.acos(tmpVec3.set(0, 1, 0).dot(tmpVec4.copy(tmpVec1).normalize())); - - const objMatrix = new THREE.Matrix4().makeRotationAxis(axis.normalize(), radians); - object.matrix.copy(objMatrix); - object.quaternion.setFromRotationMatrix(object.matrix); - - object.matrixAutoUpdate = false; - object.updateMatrix(); - - root.add(object); - - objects.push(object); - - // - - const joint = new THREE.Object3D(); - joint.position.copy(start); - joint.position.lerp(end, 0.5); - - joint.matrix.copy(objMatrix); - joint.quaternion.setFromRotationMatrix(joint.matrix); - - joint.matrixAutoUpdate = false; - joint.updateMatrix(); - - bond = document.createElement('div'); - bond.className = 'bond'; - bond.style.height = bondLength + 'px'; - - object = new CSS3DObject(bond); - object.rotation.y = Math.PI / 2; - - object.matrixAutoUpdate = false; - object.updateMatrix(); - - object.userData.bondLengthShort = bondLength + 'px'; - object.userData.bondLengthFull = bondLength + 55 + 'px'; - - object.userData.joint = joint; - - joint.add(object); - root.add(joint); - - objects.push(object); - } - - //console.log( "CSS3DObjects:", objects.length ); - - changeVizType(params.vizType); - }); -} - -// - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - requestAnimationFrame(animate); - controls.update(); - - const time = Date.now() * 0.0004; - - root.rotation.x = time; - root.rotation.y = time * 0.7; - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/css3d_orthographic.ts b/examples-testing/examples/css3d_orthographic.ts deleted file mode 100644 index 4aabbed08..000000000 --- a/examples-testing/examples/css3d_orthographic.ts +++ /dev/null @@ -1,208 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -let scene2, renderer2; - -const frustumSize = 500; - -init(); -animate(); - -function init() { - const aspect = window.innerWidth / window.innerHeight; - camera = new THREE.OrthographicCamera( - (frustumSize * aspect) / -2, - (frustumSize * aspect) / 2, - frustumSize / 2, - frustumSize / -2, - 1, - 1000, - ); - - camera.position.set(-200, 200, 200); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - scene2 = new THREE.Scene(); - - const material = new THREE.MeshBasicMaterial({ - color: 0x000000, - wireframe: true, - wireframeLinewidth: 1, - side: THREE.DoubleSide, - }); - - // left - createPlane( - 100, - 100, - 'chocolate', - new THREE.Vector3(-50, 0, 0), - new THREE.Euler(0, -90 * THREE.MathUtils.DEG2RAD, 0), - ); - // right - createPlane(100, 100, 'saddlebrown', new THREE.Vector3(0, 0, 50), new THREE.Euler(0, 0, 0)); - // top - createPlane( - 100, - 100, - 'yellowgreen', - new THREE.Vector3(0, 50, 0), - new THREE.Euler(-90 * THREE.MathUtils.DEG2RAD, 0, 0), - ); - // bottom - createPlane( - 300, - 300, - 'seagreen', - new THREE.Vector3(0, -50, 0), - new THREE.Euler(-90 * THREE.MathUtils.DEG2RAD, 0, 0), - ); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - renderer2 = new CSS3DRenderer(); - renderer2.setSize(window.innerWidth, window.innerHeight); - renderer2.domElement.style.position = 'absolute'; - renderer2.domElement.style.top = 0; - document.body.appendChild(renderer2.domElement); - - const controls = new OrbitControls(camera, renderer2.domElement); - controls.minZoom = 0.5; - controls.maxZoom = 2; - - function createPlane(width, height, cssColor, pos, rot) { - const element = document.createElement('div'); - element.style.width = width + 'px'; - element.style.height = height + 'px'; - element.style.opacity = 0.75; - element.style.background = cssColor; - - const object = new CSS3DObject(element); - object.position.copy(pos); - object.rotation.copy(rot); - scene2.add(object); - - const geometry = new THREE.PlaneGeometry(width, height); - const mesh = new THREE.Mesh(geometry, material); - mesh.position.copy(object.position); - mesh.rotation.copy(object.rotation); - scene.add(mesh); - } - - window.addEventListener('resize', onWindowResize); - createPanel(); -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - camera.left = (-frustumSize * aspect) / 2; - camera.right = (frustumSize * aspect) / 2; - camera.top = frustumSize / 2; - camera.bottom = -frustumSize / 2; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - renderer2.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - requestAnimationFrame(animate); - - renderer.render(scene, camera); - renderer2.render(scene2, camera); -} - -function createPanel() { - const panel = new GUI(); - const folder1 = panel.addFolder('camera setViewOffset').close(); - - const settings = { - setViewOffset() { - folder1.children[1].enable().setValue(window.innerWidth); - folder1.children[2].enable().setValue(window.innerHeight); - folder1.children[3].enable().setValue(0); - folder1.children[4].enable().setValue(0); - folder1.children[5].enable().setValue(window.innerWidth); - folder1.children[6].enable().setValue(window.innerHeight); - }, - fullWidth: 0, - fullHeight: 0, - offsetX: 0, - offsetY: 0, - width: 0, - height: 0, - clearViewOffset() { - folder1.children[1].setValue(0).disable(); - folder1.children[2].setValue(0).disable(); - folder1.children[3].setValue(0).disable(); - folder1.children[4].setValue(0).disable(); - folder1.children[5].setValue(0).disable(); - folder1.children[6].setValue(0).disable(); - camera.clearViewOffset(); - }, - }; - - folder1.add(settings, 'setViewOffset'); - folder1 - .add(settings, 'fullWidth', window.screen.width / 4, window.screen.width * 2, 1) - .onChange(val => updateCameraViewOffset({ fullWidth: val })) - .disable(); - folder1 - .add(settings, 'fullHeight', window.screen.height / 4, window.screen.height * 2, 1) - .onChange(val => updateCameraViewOffset({ fullHeight: val })) - .disable(); - folder1 - .add(settings, 'offsetX', 0, 256, 1) - .onChange(val => updateCameraViewOffset({ x: val })) - .disable(); - folder1 - .add(settings, 'offsetY', 0, 256, 1) - .onChange(val => updateCameraViewOffset({ y: val })) - .disable(); - folder1 - .add(settings, 'width', window.screen.width / 4, window.screen.width * 2, 1) - .onChange(val => updateCameraViewOffset({ width: val })) - .disable(); - folder1 - .add(settings, 'height', window.screen.height / 4, window.screen.height * 2, 1) - .onChange(val => updateCameraViewOffset({ height: val })) - .disable(); - folder1.add(settings, 'clearViewOffset'); -} - -function updateCameraViewOffset({ fullWidth, fullHeight, x, y, width, height }) { - if (!camera.view) { - camera.setViewOffset( - fullWidth || window.innerWidth, - fullHeight || window.innerHeight, - x || 0, - y || 0, - width || window.innerWidth, - height || window.innerHeight, - ); - } else { - camera.setViewOffset( - fullWidth || camera.view.fullWidth, - fullHeight || camera.view.fullHeight, - x || camera.view.offsetX, - y || camera.view.offsetY, - width || camera.view.width, - height || camera.view.height, - ); - } -} diff --git a/examples-testing/examples/css3d_periodictable.ts b/examples-testing/examples/css3d_periodictable.ts deleted file mode 100644 index e3a33f796..000000000 --- a/examples-testing/examples/css3d_periodictable.ts +++ /dev/null @@ -1,793 +0,0 @@ -import * as THREE from 'three'; - -import TWEEN from 'three/addons/libs/tween.module.js'; -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; - -const table = [ - 'H', - 'Hydrogen', - '1.00794', - 1, - 1, - 'He', - 'Helium', - '4.002602', - 18, - 1, - 'Li', - 'Lithium', - '6.941', - 1, - 2, - 'Be', - 'Beryllium', - '9.012182', - 2, - 2, - 'B', - 'Boron', - '10.811', - 13, - 2, - 'C', - 'Carbon', - '12.0107', - 14, - 2, - 'N', - 'Nitrogen', - '14.0067', - 15, - 2, - 'O', - 'Oxygen', - '15.9994', - 16, - 2, - 'F', - 'Fluorine', - '18.9984032', - 17, - 2, - 'Ne', - 'Neon', - '20.1797', - 18, - 2, - 'Na', - 'Sodium', - '22.98976...', - 1, - 3, - 'Mg', - 'Magnesium', - '24.305', - 2, - 3, - 'Al', - 'Aluminium', - '26.9815386', - 13, - 3, - 'Si', - 'Silicon', - '28.0855', - 14, - 3, - 'P', - 'Phosphorus', - '30.973762', - 15, - 3, - 'S', - 'Sulfur', - '32.065', - 16, - 3, - 'Cl', - 'Chlorine', - '35.453', - 17, - 3, - 'Ar', - 'Argon', - '39.948', - 18, - 3, - 'K', - 'Potassium', - '39.948', - 1, - 4, - 'Ca', - 'Calcium', - '40.078', - 2, - 4, - 'Sc', - 'Scandium', - '44.955912', - 3, - 4, - 'Ti', - 'Titanium', - '47.867', - 4, - 4, - 'V', - 'Vanadium', - '50.9415', - 5, - 4, - 'Cr', - 'Chromium', - '51.9961', - 6, - 4, - 'Mn', - 'Manganese', - '54.938045', - 7, - 4, - 'Fe', - 'Iron', - '55.845', - 8, - 4, - 'Co', - 'Cobalt', - '58.933195', - 9, - 4, - 'Ni', - 'Nickel', - '58.6934', - 10, - 4, - 'Cu', - 'Copper', - '63.546', - 11, - 4, - 'Zn', - 'Zinc', - '65.38', - 12, - 4, - 'Ga', - 'Gallium', - '69.723', - 13, - 4, - 'Ge', - 'Germanium', - '72.63', - 14, - 4, - 'As', - 'Arsenic', - '74.9216', - 15, - 4, - 'Se', - 'Selenium', - '78.96', - 16, - 4, - 'Br', - 'Bromine', - '79.904', - 17, - 4, - 'Kr', - 'Krypton', - '83.798', - 18, - 4, - 'Rb', - 'Rubidium', - '85.4678', - 1, - 5, - 'Sr', - 'Strontium', - '87.62', - 2, - 5, - 'Y', - 'Yttrium', - '88.90585', - 3, - 5, - 'Zr', - 'Zirconium', - '91.224', - 4, - 5, - 'Nb', - 'Niobium', - '92.90628', - 5, - 5, - 'Mo', - 'Molybdenum', - '95.96', - 6, - 5, - 'Tc', - 'Technetium', - '(98)', - 7, - 5, - 'Ru', - 'Ruthenium', - '101.07', - 8, - 5, - 'Rh', - 'Rhodium', - '102.9055', - 9, - 5, - 'Pd', - 'Palladium', - '106.42', - 10, - 5, - 'Ag', - 'Silver', - '107.8682', - 11, - 5, - 'Cd', - 'Cadmium', - '112.411', - 12, - 5, - 'In', - 'Indium', - '114.818', - 13, - 5, - 'Sn', - 'Tin', - '118.71', - 14, - 5, - 'Sb', - 'Antimony', - '121.76', - 15, - 5, - 'Te', - 'Tellurium', - '127.6', - 16, - 5, - 'I', - 'Iodine', - '126.90447', - 17, - 5, - 'Xe', - 'Xenon', - '131.293', - 18, - 5, - 'Cs', - 'Caesium', - '132.9054', - 1, - 6, - 'Ba', - 'Barium', - '132.9054', - 2, - 6, - 'La', - 'Lanthanum', - '138.90547', - 4, - 9, - 'Ce', - 'Cerium', - '140.116', - 5, - 9, - 'Pr', - 'Praseodymium', - '140.90765', - 6, - 9, - 'Nd', - 'Neodymium', - '144.242', - 7, - 9, - 'Pm', - 'Promethium', - '(145)', - 8, - 9, - 'Sm', - 'Samarium', - '150.36', - 9, - 9, - 'Eu', - 'Europium', - '151.964', - 10, - 9, - 'Gd', - 'Gadolinium', - '157.25', - 11, - 9, - 'Tb', - 'Terbium', - '158.92535', - 12, - 9, - 'Dy', - 'Dysprosium', - '162.5', - 13, - 9, - 'Ho', - 'Holmium', - '164.93032', - 14, - 9, - 'Er', - 'Erbium', - '167.259', - 15, - 9, - 'Tm', - 'Thulium', - '168.93421', - 16, - 9, - 'Yb', - 'Ytterbium', - '173.054', - 17, - 9, - 'Lu', - 'Lutetium', - '174.9668', - 18, - 9, - 'Hf', - 'Hafnium', - '178.49', - 4, - 6, - 'Ta', - 'Tantalum', - '180.94788', - 5, - 6, - 'W', - 'Tungsten', - '183.84', - 6, - 6, - 'Re', - 'Rhenium', - '186.207', - 7, - 6, - 'Os', - 'Osmium', - '190.23', - 8, - 6, - 'Ir', - 'Iridium', - '192.217', - 9, - 6, - 'Pt', - 'Platinum', - '195.084', - 10, - 6, - 'Au', - 'Gold', - '196.966569', - 11, - 6, - 'Hg', - 'Mercury', - '200.59', - 12, - 6, - 'Tl', - 'Thallium', - '204.3833', - 13, - 6, - 'Pb', - 'Lead', - '207.2', - 14, - 6, - 'Bi', - 'Bismuth', - '208.9804', - 15, - 6, - 'Po', - 'Polonium', - '(209)', - 16, - 6, - 'At', - 'Astatine', - '(210)', - 17, - 6, - 'Rn', - 'Radon', - '(222)', - 18, - 6, - 'Fr', - 'Francium', - '(223)', - 1, - 7, - 'Ra', - 'Radium', - '(226)', - 2, - 7, - 'Ac', - 'Actinium', - '(227)', - 4, - 10, - 'Th', - 'Thorium', - '232.03806', - 5, - 10, - 'Pa', - 'Protactinium', - '231.0588', - 6, - 10, - 'U', - 'Uranium', - '238.02891', - 7, - 10, - 'Np', - 'Neptunium', - '(237)', - 8, - 10, - 'Pu', - 'Plutonium', - '(244)', - 9, - 10, - 'Am', - 'Americium', - '(243)', - 10, - 10, - 'Cm', - 'Curium', - '(247)', - 11, - 10, - 'Bk', - 'Berkelium', - '(247)', - 12, - 10, - 'Cf', - 'Californium', - '(251)', - 13, - 10, - 'Es', - 'Einstenium', - '(252)', - 14, - 10, - 'Fm', - 'Fermium', - '(257)', - 15, - 10, - 'Md', - 'Mendelevium', - '(258)', - 16, - 10, - 'No', - 'Nobelium', - '(259)', - 17, - 10, - 'Lr', - 'Lawrencium', - '(262)', - 18, - 10, - 'Rf', - 'Rutherfordium', - '(267)', - 4, - 7, - 'Db', - 'Dubnium', - '(268)', - 5, - 7, - 'Sg', - 'Seaborgium', - '(271)', - 6, - 7, - 'Bh', - 'Bohrium', - '(272)', - 7, - 7, - 'Hs', - 'Hassium', - '(270)', - 8, - 7, - 'Mt', - 'Meitnerium', - '(276)', - 9, - 7, - 'Ds', - 'Darmstadium', - '(281)', - 10, - 7, - 'Rg', - 'Roentgenium', - '(280)', - 11, - 7, - 'Cn', - 'Copernicium', - '(285)', - 12, - 7, - 'Nh', - 'Nihonium', - '(286)', - 13, - 7, - 'Fl', - 'Flerovium', - '(289)', - 14, - 7, - 'Mc', - 'Moscovium', - '(290)', - 15, - 7, - 'Lv', - 'Livermorium', - '(293)', - 16, - 7, - 'Ts', - 'Tennessine', - '(294)', - 17, - 7, - 'Og', - 'Oganesson', - '(294)', - 18, - 7, -]; - -let camera, scene, renderer; -let controls; - -const objects = []; -const targets = { table: [], sphere: [], helix: [], grid: [] }; - -init(); -animate(); - -function init() { - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 3000; - - scene = new THREE.Scene(); - - // table - - for (let i = 0; i < table.length; i += 5) { - const element = document.createElement('div'); - element.className = 'element'; - element.style.backgroundColor = 'rgba(0,127,127,' + (Math.random() * 0.5 + 0.25) + ')'; - - const number = document.createElement('div'); - number.className = 'number'; - number.textContent = i / 5 + 1; - element.appendChild(number); - - const symbol = document.createElement('div'); - symbol.className = 'symbol'; - symbol.textContent = table[i]; - element.appendChild(symbol); - - const details = document.createElement('div'); - details.className = 'details'; - details.innerHTML = table[i + 1] + '
' + table[i + 2]; - element.appendChild(details); - - const objectCSS = new CSS3DObject(element); - objectCSS.position.x = Math.random() * 4000 - 2000; - objectCSS.position.y = Math.random() * 4000 - 2000; - objectCSS.position.z = Math.random() * 4000 - 2000; - scene.add(objectCSS); - - objects.push(objectCSS); - - // - - const object = new THREE.Object3D(); - object.position.x = table[i + 3] * 140 - 1330; - object.position.y = -(table[i + 4] * 180) + 990; - - targets.table.push(object); - } - - // sphere - - const vector = new THREE.Vector3(); - - for (let i = 0, l = objects.length; i < l; i++) { - const phi = Math.acos(-1 + (2 * i) / l); - const theta = Math.sqrt(l * Math.PI) * phi; - - const object = new THREE.Object3D(); - - object.position.setFromSphericalCoords(800, phi, theta); - - vector.copy(object.position).multiplyScalar(2); - - object.lookAt(vector); - - targets.sphere.push(object); - } - - // helix - - for (let i = 0, l = objects.length; i < l; i++) { - const theta = i * 0.175 + Math.PI; - const y = -(i * 8) + 450; - - const object = new THREE.Object3D(); - - object.position.setFromCylindricalCoords(900, theta, y); - - vector.x = object.position.x * 2; - vector.y = object.position.y; - vector.z = object.position.z * 2; - - object.lookAt(vector); - - targets.helix.push(object); - } - - // grid - - for (let i = 0; i < objects.length; i++) { - const object = new THREE.Object3D(); - - object.position.x = (i % 5) * 400 - 800; - object.position.y = -(Math.floor(i / 5) % 5) * 400 + 800; - object.position.z = Math.floor(i / 25) * 1000 - 2000; - - targets.grid.push(object); - } - - // - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - document.getElementById('container').appendChild(renderer.domElement); - - // - - controls = new TrackballControls(camera, renderer.domElement); - controls.minDistance = 500; - controls.maxDistance = 6000; - controls.addEventListener('change', render); - - const buttonTable = document.getElementById('table'); - buttonTable.addEventListener('click', function () { - transform(targets.table, 2000); - }); - - const buttonSphere = document.getElementById('sphere'); - buttonSphere.addEventListener('click', function () { - transform(targets.sphere, 2000); - }); - - const buttonHelix = document.getElementById('helix'); - buttonHelix.addEventListener('click', function () { - transform(targets.helix, 2000); - }); - - const buttonGrid = document.getElementById('grid'); - buttonGrid.addEventListener('click', function () { - transform(targets.grid, 2000); - }); - - transform(targets.table, 2000); - - // - - window.addEventListener('resize', onWindowResize); -} - -function transform(targets, duration) { - TWEEN.removeAll(); - - for (let i = 0; i < objects.length; i++) { - const object = objects[i]; - const target = targets[i]; - - new TWEEN.Tween(object.position) - .to( - { x: target.position.x, y: target.position.y, z: target.position.z }, - Math.random() * duration + duration, - ) - .easing(TWEEN.Easing.Exponential.InOut) - .start(); - - new TWEEN.Tween(object.rotation) - .to( - { x: target.rotation.x, y: target.rotation.y, z: target.rotation.z }, - Math.random() * duration + duration, - ) - .easing(TWEEN.Easing.Exponential.InOut) - .start(); - } - - new TWEEN.Tween(this) - .to({}, duration * 2) - .onUpdate(render) - .start(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function animate() { - requestAnimationFrame(animate); - - TWEEN.update(); - - controls.update(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/css3d_sandbox.ts b/examples-testing/examples/css3d_sandbox.ts deleted file mode 100644 index 1088b84b1..000000000 --- a/examples-testing/examples/css3d_sandbox.ts +++ /dev/null @@ -1,180 +0,0 @@ -import * as THREE from 'three'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -let scene2, renderer2; - -let controls; - -init(); -animate(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(200, 200, 200); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - scene2 = new THREE.Scene(); - - const material = new THREE.MeshBasicMaterial({ - color: 0x000000, - wireframe: true, - wireframeLinewidth: 1, - side: THREE.DoubleSide, - }); - - // - - for (let i = 0; i < 10; i++) { - const element = document.createElement('div'); - element.style.width = '100px'; - element.style.height = '100px'; - element.style.opacity = i < 5 ? 0.5 : 1; - element.style.background = new THREE.Color(Math.random() * 0xffffff).getStyle(); - - const object = new CSS3DObject(element); - object.position.x = Math.random() * 200 - 100; - object.position.y = Math.random() * 200 - 100; - object.position.z = Math.random() * 200 - 100; - object.rotation.x = Math.random(); - object.rotation.y = Math.random(); - object.rotation.z = Math.random(); - object.scale.x = Math.random() + 0.5; - object.scale.y = Math.random() + 0.5; - scene2.add(object); - - const geometry = new THREE.PlaneGeometry(100, 100); - const mesh = new THREE.Mesh(geometry, material); - mesh.position.copy(object.position); - mesh.rotation.copy(object.rotation); - mesh.scale.copy(object.scale); - scene.add(mesh); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - renderer2 = new CSS3DRenderer(); - renderer2.setSize(window.innerWidth, window.innerHeight); - renderer2.domElement.style.position = 'absolute'; - renderer2.domElement.style.top = 0; - document.body.appendChild(renderer2.domElement); - - controls = new TrackballControls(camera, renderer2.domElement); - - window.addEventListener('resize', onWindowResize); - createPanel(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - renderer2.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - requestAnimationFrame(animate); - - controls.update(); - - renderer.render(scene, camera); - renderer2.render(scene2, camera); -} - -function createPanel() { - const panel = new GUI(); - const folder1 = panel.addFolder('camera setViewOffset').close(); - - const settings = { - setViewOffset() { - folder1.children[1].enable().setValue(window.innerWidth); - folder1.children[2].enable().setValue(window.innerHeight); - folder1.children[3].enable().setValue(0); - folder1.children[4].enable().setValue(0); - folder1.children[5].enable().setValue(window.innerWidth); - folder1.children[6].enable().setValue(window.innerHeight); - }, - fullWidth: 0, - fullHeight: 0, - offsetX: 0, - offsetY: 0, - width: 0, - height: 0, - clearViewOffset() { - folder1.children[1].setValue(0).disable(); - folder1.children[2].setValue(0).disable(); - folder1.children[3].setValue(0).disable(); - folder1.children[4].setValue(0).disable(); - folder1.children[5].setValue(0).disable(); - folder1.children[6].setValue(0).disable(); - camera.clearViewOffset(); - }, - }; - - folder1.add(settings, 'setViewOffset'); - folder1 - .add(settings, 'fullWidth', window.screen.width / 4, window.screen.width * 2, 1) - .onChange(val => updateCameraViewOffset({ fullWidth: val })) - .disable(); - folder1 - .add(settings, 'fullHeight', window.screen.height / 4, window.screen.height * 2, 1) - .onChange(val => updateCameraViewOffset({ fullHeight: val })) - .disable(); - folder1 - .add(settings, 'offsetX', 0, 256, 1) - .onChange(val => updateCameraViewOffset({ x: val })) - .disable(); - folder1 - .add(settings, 'offsetY', 0, 256, 1) - .onChange(val => updateCameraViewOffset({ y: val })) - .disable(); - folder1 - .add(settings, 'width', window.screen.width / 4, window.screen.width * 2, 1) - .onChange(val => updateCameraViewOffset({ width: val })) - .disable(); - folder1 - .add(settings, 'height', window.screen.height / 4, window.screen.height * 2, 1) - .onChange(val => updateCameraViewOffset({ height: val })) - .disable(); - folder1.add(settings, 'clearViewOffset'); -} - -function updateCameraViewOffset({ fullWidth, fullHeight, x, y, width, height }) { - if (!camera.view) { - camera.setViewOffset( - fullWidth || window.innerWidth, - fullHeight || window.innerHeight, - x || 0, - y || 0, - width || window.innerWidth, - height || window.innerHeight, - ); - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - } else { - camera.setViewOffset( - fullWidth || camera.view.fullWidth, - fullHeight || camera.view.fullHeight, - x || camera.view.offsetX, - y || camera.view.offsetY, - width || camera.view.width, - height || camera.view.height, - ); - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - } -} diff --git a/examples-testing/examples/css3d_sprites.ts b/examples-testing/examples/css3d_sprites.ts deleted file mode 100644 index dfe24e79d..000000000 --- a/examples-testing/examples/css3d_sprites.ts +++ /dev/null @@ -1,157 +0,0 @@ -import * as THREE from 'three'; - -import TWEEN from 'three/addons/libs/tween.module.js'; -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { CSS3DRenderer, CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js'; - -let camera, scene, renderer; -let controls; - -const particlesTotal = 512; -const positions = []; -const objects = []; -let current = 0; - -init(); -animate(); - -function init() { - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.set(600, 400, 1500); - camera.lookAt(0, 0, 0); - - scene = new THREE.Scene(); - - const image = document.createElement('img'); - image.addEventListener('load', function () { - for (let i = 0; i < particlesTotal; i++) { - const object = new CSS3DSprite(image.cloneNode()); - (object.position.x = Math.random() * 4000 - 2000), - (object.position.y = Math.random() * 4000 - 2000), - (object.position.z = Math.random() * 4000 - 2000); - scene.add(object); - - objects.push(object); - } - - transition(); - }); - image.src = 'textures/sprite.png'; - - // Plane - - const amountX = 16; - const amountZ = 32; - const separationPlane = 150; - const offsetX = ((amountX - 1) * separationPlane) / 2; - const offsetZ = ((amountZ - 1) * separationPlane) / 2; - - for (let i = 0; i < particlesTotal; i++) { - const x = (i % amountX) * separationPlane; - const z = Math.floor(i / amountX) * separationPlane; - const y = (Math.sin(x * 0.5) + Math.sin(z * 0.5)) * 200; - - positions.push(x - offsetX, y, z - offsetZ); - } - - // Cube - - const amount = 8; - const separationCube = 150; - const offset = ((amount - 1) * separationCube) / 2; - - for (let i = 0; i < particlesTotal; i++) { - const x = (i % amount) * separationCube; - const y = Math.floor((i / amount) % amount) * separationCube; - const z = Math.floor(i / (amount * amount)) * separationCube; - - positions.push(x - offset, y - offset, z - offset); - } - - // Random - - for (let i = 0; i < particlesTotal; i++) { - positions.push(Math.random() * 4000 - 2000, Math.random() * 4000 - 2000, Math.random() * 4000 - 2000); - } - - // Sphere - - const radius = 750; - - for (let i = 0; i < particlesTotal; i++) { - const phi = Math.acos(-1 + (2 * i) / particlesTotal); - const theta = Math.sqrt(particlesTotal * Math.PI) * phi; - - positions.push( - radius * Math.cos(theta) * Math.sin(phi), - radius * Math.sin(theta) * Math.sin(phi), - radius * Math.cos(phi), - ); - } - - // - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - document.getElementById('container').appendChild(renderer.domElement); - - // - - controls = new TrackballControls(camera, renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function transition() { - const offset = current * particlesTotal * 3; - const duration = 2000; - - for (let i = 0, j = offset; i < particlesTotal; i++, j += 3) { - const object = objects[i]; - - new TWEEN.Tween(object.position) - .to( - { - x: positions[j], - y: positions[j + 1], - z: positions[j + 2], - }, - Math.random() * duration + duration, - ) - .easing(TWEEN.Easing.Exponential.InOut) - .start(); - } - - new TWEEN.Tween(this) - .to({}, duration * 3) - .onComplete(transition) - .start(); - - current = (current + 1) % 4; -} - -function animate() { - requestAnimationFrame(animate); - - TWEEN.update(); - controls.update(); - - const time = performance.now(); - - for (let i = 0, l = objects.length; i < l; i++) { - const object = objects[i]; - const scale = Math.sin((Math.floor(object.position.x) + time) * 0.002) * 0.3 + 1; - object.scale.set(scale, scale, scale); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/css3d_youtube.ts b/examples-testing/examples/css3d_youtube.ts deleted file mode 100644 index 62652f87f..000000000 --- a/examples-testing/examples/css3d_youtube.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as THREE from 'three'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; - -let camera, scene, renderer; -let controls; - -function Element(id, x, y, z, ry) { - const div = document.createElement('div'); - div.style.width = '480px'; - div.style.height = '360px'; - div.style.backgroundColor = '#000'; - - const iframe = document.createElement('iframe'); - iframe.style.width = '480px'; - iframe.style.height = '360px'; - iframe.style.border = '0px'; - iframe.src = ['https://www.youtube.com/embed/', id, '?rel=0'].join(''); - div.appendChild(iframe); - - const object = new CSS3DObject(div); - object.position.set(x, y, z); - object.rotation.y = ry; - - return object; -} - -init(); -animate(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.set(500, 350, 750); - - scene = new THREE.Scene(); - - renderer = new CSS3DRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - container.appendChild(renderer.domElement); - - const group = new THREE.Group(); - group.add(new Element('SJOz3qjfQXU', 0, 0, 240, 0)); - group.add(new Element('Y2-xZ-1HE-Q', 240, 0, 0, Math.PI / 2)); - group.add(new Element('IrydklNpcFI', 0, 0, -240, Math.PI)); - group.add(new Element('9ubytEsCaS0', -240, 0, 0, -Math.PI / 2)); - scene.add(group); - - controls = new TrackballControls(camera, renderer.domElement); - controls.rotateSpeed = 4; - - window.addEventListener('resize', onWindowResize); - - // Block iframe events when dragging camera - - const blocker = document.getElementById('blocker'); - blocker.style.display = 'none'; - - controls.addEventListener('start', function () { - blocker.style.display = ''; - }); - controls.addEventListener('end', function () { - blocker.style.display = 'none'; - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - requestAnimationFrame(animate); - controls.update(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/games_fps.ts b/examples-testing/examples/games_fps.ts deleted file mode 100644 index 4c459f9bc..000000000 --- a/examples-testing/examples/games_fps.ts +++ /dev/null @@ -1,372 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import { Octree } from 'three/addons/math/Octree.js'; -import { OctreeHelper } from 'three/addons/helpers/OctreeHelper.js'; - -import { Capsule } from 'three/addons/math/Capsule.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const clock = new THREE.Clock(); - -const scene = new THREE.Scene(); -scene.background = new THREE.Color(0x88ccee); -scene.fog = new THREE.Fog(0x88ccee, 0, 50); - -const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000); -camera.rotation.order = 'YXZ'; - -const fillLight1 = new THREE.HemisphereLight(0x8dc1de, 0x00668d, 1.5); -fillLight1.position.set(2, 1, 1); -scene.add(fillLight1); - -const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5); -directionalLight.position.set(-5, 25, -1); -directionalLight.castShadow = true; -directionalLight.shadow.camera.near = 0.01; -directionalLight.shadow.camera.far = 500; -directionalLight.shadow.camera.right = 30; -directionalLight.shadow.camera.left = -30; -directionalLight.shadow.camera.top = 30; -directionalLight.shadow.camera.bottom = -30; -directionalLight.shadow.mapSize.width = 1024; -directionalLight.shadow.mapSize.height = 1024; -directionalLight.shadow.radius = 4; -directionalLight.shadow.bias = -0.00006; -scene.add(directionalLight); - -const container = document.getElementById('container'); - -const renderer = new THREE.WebGLRenderer({ antialias: true }); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.setAnimationLoop(animate); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.VSMShadowMap; -renderer.toneMapping = THREE.ACESFilmicToneMapping; -container.appendChild(renderer.domElement); - -const stats = new Stats(); -stats.domElement.style.position = 'absolute'; -stats.domElement.style.top = '0px'; -container.appendChild(stats.domElement); - -const GRAVITY = 30; - -const NUM_SPHERES = 100; -const SPHERE_RADIUS = 0.2; - -const STEPS_PER_FRAME = 5; - -const sphereGeometry = new THREE.IcosahedronGeometry(SPHERE_RADIUS, 5); -const sphereMaterial = new THREE.MeshLambertMaterial({ color: 0xdede8d }); - -const spheres = []; -let sphereIdx = 0; - -for (let i = 0; i < NUM_SPHERES; i++) { - const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - sphere.castShadow = true; - sphere.receiveShadow = true; - - scene.add(sphere); - - spheres.push({ - mesh: sphere, - collider: new THREE.Sphere(new THREE.Vector3(0, -100, 0), SPHERE_RADIUS), - velocity: new THREE.Vector3(), - }); -} - -const worldOctree = new Octree(); - -const playerCollider = new Capsule(new THREE.Vector3(0, 0.35, 0), new THREE.Vector3(0, 1, 0), 0.35); - -const playerVelocity = new THREE.Vector3(); -const playerDirection = new THREE.Vector3(); - -let playerOnFloor = false; -let mouseTime = 0; - -const keyStates = {}; - -const vector1 = new THREE.Vector3(); -const vector2 = new THREE.Vector3(); -const vector3 = new THREE.Vector3(); - -document.addEventListener('keydown', event => { - keyStates[event.code] = true; -}); - -document.addEventListener('keyup', event => { - keyStates[event.code] = false; -}); - -container.addEventListener('mousedown', () => { - document.body.requestPointerLock(); - - mouseTime = performance.now(); -}); - -document.addEventListener('mouseup', () => { - if (document.pointerLockElement !== null) throwBall(); -}); - -document.body.addEventListener('mousemove', event => { - if (document.pointerLockElement === document.body) { - camera.rotation.y -= event.movementX / 500; - camera.rotation.x -= event.movementY / 500; - } -}); - -window.addEventListener('resize', onWindowResize); - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function throwBall() { - const sphere = spheres[sphereIdx]; - - camera.getWorldDirection(playerDirection); - - sphere.collider.center.copy(playerCollider.end).addScaledVector(playerDirection, playerCollider.radius * 1.5); - - // throw the ball with more force if we hold the button longer, and if we move forward - - const impulse = 15 + 30 * (1 - Math.exp((mouseTime - performance.now()) * 0.001)); - - sphere.velocity.copy(playerDirection).multiplyScalar(impulse); - sphere.velocity.addScaledVector(playerVelocity, 2); - - sphereIdx = (sphereIdx + 1) % spheres.length; -} - -function playerCollisions() { - const result = worldOctree.capsuleIntersect(playerCollider); - - playerOnFloor = false; - - if (result) { - playerOnFloor = result.normal.y > 0; - - if (!playerOnFloor) { - playerVelocity.addScaledVector(result.normal, -result.normal.dot(playerVelocity)); - } - - if (result.depth >= 1e-10) { - playerCollider.translate(result.normal.multiplyScalar(result.depth)); - } - } -} - -function updatePlayer(deltaTime) { - let damping = Math.exp(-4 * deltaTime) - 1; - - if (!playerOnFloor) { - playerVelocity.y -= GRAVITY * deltaTime; - - // small air resistance - damping *= 0.1; - } - - playerVelocity.addScaledVector(playerVelocity, damping); - - const deltaPosition = playerVelocity.clone().multiplyScalar(deltaTime); - playerCollider.translate(deltaPosition); - - playerCollisions(); - - camera.position.copy(playerCollider.end); -} - -function playerSphereCollision(sphere) { - const center = vector1.addVectors(playerCollider.start, playerCollider.end).multiplyScalar(0.5); - - const sphere_center = sphere.collider.center; - - const r = playerCollider.radius + sphere.collider.radius; - const r2 = r * r; - - // approximation: player = 3 spheres - - for (const point of [playerCollider.start, playerCollider.end, center]) { - const d2 = point.distanceToSquared(sphere_center); - - if (d2 < r2) { - const normal = vector1.subVectors(point, sphere_center).normalize(); - const v1 = vector2.copy(normal).multiplyScalar(normal.dot(playerVelocity)); - const v2 = vector3.copy(normal).multiplyScalar(normal.dot(sphere.velocity)); - - playerVelocity.add(v2).sub(v1); - sphere.velocity.add(v1).sub(v2); - - const d = (r - Math.sqrt(d2)) / 2; - sphere_center.addScaledVector(normal, -d); - } - } -} - -function spheresCollisions() { - for (let i = 0, length = spheres.length; i < length; i++) { - const s1 = spheres[i]; - - for (let j = i + 1; j < length; j++) { - const s2 = spheres[j]; - - const d2 = s1.collider.center.distanceToSquared(s2.collider.center); - const r = s1.collider.radius + s2.collider.radius; - const r2 = r * r; - - if (d2 < r2) { - const normal = vector1.subVectors(s1.collider.center, s2.collider.center).normalize(); - const v1 = vector2.copy(normal).multiplyScalar(normal.dot(s1.velocity)); - const v2 = vector3.copy(normal).multiplyScalar(normal.dot(s2.velocity)); - - s1.velocity.add(v2).sub(v1); - s2.velocity.add(v1).sub(v2); - - const d = (r - Math.sqrt(d2)) / 2; - - s1.collider.center.addScaledVector(normal, d); - s2.collider.center.addScaledVector(normal, -d); - } - } - } -} - -function updateSpheres(deltaTime) { - spheres.forEach(sphere => { - sphere.collider.center.addScaledVector(sphere.velocity, deltaTime); - - const result = worldOctree.sphereIntersect(sphere.collider); - - if (result) { - sphere.velocity.addScaledVector(result.normal, -result.normal.dot(sphere.velocity) * 1.5); - sphere.collider.center.add(result.normal.multiplyScalar(result.depth)); - } else { - sphere.velocity.y -= GRAVITY * deltaTime; - } - - const damping = Math.exp(-1.5 * deltaTime) - 1; - sphere.velocity.addScaledVector(sphere.velocity, damping); - - playerSphereCollision(sphere); - }); - - spheresCollisions(); - - for (const sphere of spheres) { - sphere.mesh.position.copy(sphere.collider.center); - } -} - -function getForwardVector() { - camera.getWorldDirection(playerDirection); - playerDirection.y = 0; - playerDirection.normalize(); - - return playerDirection; -} - -function getSideVector() { - camera.getWorldDirection(playerDirection); - playerDirection.y = 0; - playerDirection.normalize(); - playerDirection.cross(camera.up); - - return playerDirection; -} - -function controls(deltaTime) { - // gives a bit of air control - const speedDelta = deltaTime * (playerOnFloor ? 25 : 8); - - if (keyStates['KeyW']) { - playerVelocity.add(getForwardVector().multiplyScalar(speedDelta)); - } - - if (keyStates['KeyS']) { - playerVelocity.add(getForwardVector().multiplyScalar(-speedDelta)); - } - - if (keyStates['KeyA']) { - playerVelocity.add(getSideVector().multiplyScalar(-speedDelta)); - } - - if (keyStates['KeyD']) { - playerVelocity.add(getSideVector().multiplyScalar(speedDelta)); - } - - if (playerOnFloor) { - if (keyStates['Space']) { - playerVelocity.y = 15; - } - } -} - -const loader = new GLTFLoader().setPath('./models/gltf/'); - -loader.load('collision-world.glb', gltf => { - scene.add(gltf.scene); - - worldOctree.fromGraphNode(gltf.scene); - - gltf.scene.traverse(child => { - if (child.isMesh) { - child.castShadow = true; - child.receiveShadow = true; - - if (child.material.map) { - child.material.map.anisotropy = 4; - } - } - }); - - const helper = new OctreeHelper(worldOctree); - helper.visible = false; - scene.add(helper); - - const gui = new GUI({ width: 200 }); - gui.add({ debug: false }, 'debug').onChange(function (value) { - helper.visible = value; - }); -}); - -function teleportPlayerIfOob() { - if (camera.position.y <= -25) { - playerCollider.start.set(0, 0.35, 0); - playerCollider.end.set(0, 1, 0); - playerCollider.radius = 0.35; - camera.position.copy(playerCollider.end); - camera.rotation.set(0, 0, 0); - } -} - -function animate() { - const deltaTime = Math.min(0.05, clock.getDelta()) / STEPS_PER_FRAME; - - // we look for collisions in substeps to mitigate the risk of - // an object traversing another too quickly for detection. - - for (let i = 0; i < STEPS_PER_FRAME; i++) { - controls(deltaTime); - - updatePlayer(deltaTime); - - updateSpheres(deltaTime); - - teleportPlayerIfOob(); - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/misc_animation_groups.ts b/examples-testing/examples/misc_animation_groups.ts deleted file mode 100644 index 33fc41997..000000000 --- a/examples-testing/examples/misc_animation_groups.ts +++ /dev/null @@ -1,125 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let stats, clock; -let scene, camera, renderer, mixer; - -init(); - -function init() { - scene = new THREE.Scene(); - - // - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(50, 50, 100); - camera.lookAt(scene.position); - - // all objects of this animation group share a common animation state - - const animationGroup = new THREE.AnimationObjectGroup(); - - // - - const geometry = new THREE.BoxGeometry(5, 5, 5); - const material = new THREE.MeshBasicMaterial({ transparent: true }); - - // - - for (let i = 0; i < 5; i++) { - for (let j = 0; j < 5; j++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = 32 - 16 * i; - mesh.position.y = 0; - mesh.position.z = 32 - 16 * j; - - scene.add(mesh); - animationGroup.add(mesh); - } - } - - // create some keyframe tracks - - const xAxis = new THREE.Vector3(1, 0, 0); - const qInitial = new THREE.Quaternion().setFromAxisAngle(xAxis, 0); - const qFinal = new THREE.Quaternion().setFromAxisAngle(xAxis, Math.PI); - const quaternionKF = new THREE.QuaternionKeyframeTrack( - '.quaternion', - [0, 1, 2], - [ - qInitial.x, - qInitial.y, - qInitial.z, - qInitial.w, - qFinal.x, - qFinal.y, - qFinal.z, - qFinal.w, - qInitial.x, - qInitial.y, - qInitial.z, - qInitial.w, - ], - ); - - const colorKF = new THREE.ColorKeyframeTrack( - '.material.color', - [0, 1, 2], - [1, 0, 0, 0, 1, 0, 0, 0, 1], - THREE.InterpolateDiscrete, - ); - const opacityKF = new THREE.NumberKeyframeTrack('.material.opacity', [0, 1, 2], [1, 0, 1]); - - // create clip - - const clip = new THREE.AnimationClip('default', 3, [quaternionKF, colorKF, opacityKF]); - - // apply the animation group to the mixer as the root object - - mixer = new THREE.AnimationMixer(animationGroup); - - const clipAction = mixer.clipAction(clip); - clipAction.play(); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - clock = new THREE.Clock(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) { - mixer.update(delta); - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/misc_animation_keys.ts b/examples-testing/examples/misc_animation_keys.ts deleted file mode 100644 index e2f141f91..000000000 --- a/examples-testing/examples/misc_animation_keys.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let stats, clock; -let scene, camera, renderer, mixer; - -init(); - -function init() { - scene = new THREE.Scene(); - - // - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(25, 25, 50); - camera.lookAt(scene.position); - - // - - const axesHelper = new THREE.AxesHelper(10); - scene.add(axesHelper); - - // - - const geometry = new THREE.BoxGeometry(5, 5, 5); - const material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }); - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // create a keyframe track (i.e. a timed sequence of keyframes) for each animated property - // Note: the keyframe track type should correspond to the type of the property being animated - - // POSITION - const positionKF = new THREE.VectorKeyframeTrack('.position', [0, 1, 2], [0, 0, 0, 30, 0, 0, 0, 0, 0]); - - // SCALE - const scaleKF = new THREE.VectorKeyframeTrack('.scale', [0, 1, 2], [1, 1, 1, 2, 2, 2, 1, 1, 1]); - - // ROTATION - // Rotation should be performed using quaternions, using a THREE.QuaternionKeyframeTrack - // Interpolating Euler angles (.rotation property) can be problematic and is currently not supported - - // set up rotation about x axis - const xAxis = new THREE.Vector3(1, 0, 0); - - const qInitial = new THREE.Quaternion().setFromAxisAngle(xAxis, 0); - const qFinal = new THREE.Quaternion().setFromAxisAngle(xAxis, Math.PI); - const quaternionKF = new THREE.QuaternionKeyframeTrack( - '.quaternion', - [0, 1, 2], - [ - qInitial.x, - qInitial.y, - qInitial.z, - qInitial.w, - qFinal.x, - qFinal.y, - qFinal.z, - qFinal.w, - qInitial.x, - qInitial.y, - qInitial.z, - qInitial.w, - ], - ); - - // COLOR - const colorKF = new THREE.ColorKeyframeTrack( - '.material.color', - [0, 1, 2], - [1, 0, 0, 0, 1, 0, 0, 0, 1], - THREE.InterpolateDiscrete, - ); - - // OPACITY - const opacityKF = new THREE.NumberKeyframeTrack('.material.opacity', [0, 1, 2], [1, 0, 1]); - - // create an animation sequence with the tracks - // If a negative time value is passed, the duration will be calculated from the times of the passed tracks array - const clip = new THREE.AnimationClip('Action', 3, [scaleKF, positionKF, quaternionKF, colorKF, opacityKF]); - - // setup the THREE.AnimationMixer - mixer = new THREE.AnimationMixer(mesh); - - // create a ClipAction and set it to play - const clipAction = mixer.clipAction(clip); - clipAction.play(); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - clock = new THREE.Clock(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) { - mixer.update(delta); - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/misc_boxselection.ts b/examples-testing/examples/misc_boxselection.ts deleted file mode 100644 index e7079c405..000000000 --- a/examples-testing/examples/misc_boxselection.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { SelectionBox } from 'three/addons/interactive/SelectionBox.js'; -import { SelectionHelper } from 'three/addons/interactive/SelectionHelper.js'; - -let container, stats; -let camera, scene, renderer; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 500); - camera.position.z = 50; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - scene.add(new THREE.AmbientLight(0xaaaaaa)); - - const light = new THREE.SpotLight(0xffffff, 10000); - light.position.set(0, 25, 50); - light.angle = Math.PI / 5; - - light.castShadow = true; - light.shadow.camera.near = 10; - light.shadow.camera.far = 100; - light.shadow.mapSize.width = 1024; - light.shadow.mapSize.height = 1024; - - scene.add(light); - - const geometry = new THREE.BoxGeometry(); - - for (let i = 0; i < 200; i++) { - const object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff })); - - object.position.x = Math.random() * 80 - 40; - object.position.y = Math.random() * 45 - 25; - object.position.z = Math.random() * 45 - 25; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() * 2 + 1; - object.scale.y = Math.random() * 2 + 1; - object.scale.z = Math.random() * 2 + 1; - - object.castShadow = true; - object.receiveShadow = true; - - scene.add(object); - } - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFShadowMap; - - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); - - stats.update(); -} - -const selectionBox = new SelectionBox(camera, scene); -const helper = new SelectionHelper(renderer, 'selectBox'); - -document.addEventListener('pointerdown', function (event) { - for (const item of selectionBox.collection) { - item.material.emissive.set(0x000000); - } - - selectionBox.startPoint.set( - (event.clientX / window.innerWidth) * 2 - 1, - -(event.clientY / window.innerHeight) * 2 + 1, - 0.5, - ); -}); - -document.addEventListener('pointermove', function (event) { - if (helper.isDown) { - for (let i = 0; i < selectionBox.collection.length; i++) { - selectionBox.collection[i].material.emissive.set(0x000000); - } - - selectionBox.endPoint.set( - (event.clientX / window.innerWidth) * 2 - 1, - -(event.clientY / window.innerHeight) * 2 + 1, - 0.5, - ); - - const allSelected = selectionBox.select(); - - for (let i = 0; i < allSelected.length; i++) { - allSelected[i].material.emissive.set(0xffffff); - } - } -}); - -document.addEventListener('pointerup', function (event) { - selectionBox.endPoint.set( - (event.clientX / window.innerWidth) * 2 - 1, - -(event.clientY / window.innerHeight) * 2 + 1, - 0.5, - ); - - const allSelected = selectionBox.select(); - - for (let i = 0; i < allSelected.length; i++) { - allSelected[i].material.emissive.set(0xffffff); - } -}); diff --git a/examples-testing/examples/misc_controls_arcball.ts b/examples-testing/examples/misc_controls_arcball.ts deleted file mode 100644 index fbef33189..000000000 --- a/examples-testing/examples/misc_controls_arcball.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { ArcballControls } from 'three/addons/controls/ArcballControls.js'; - -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -const cameras = ['Orthographic', 'Perspective']; -const cameraType = { type: 'Perspective' }; - -const perspectiveDistance = 2.5; -const orthographicDistance = 120; -let camera, controls, scene, renderer, gui; -let folderOptions, folderAnimations; - -const arcballGui = { - gizmoVisible: true, - - setArcballControls: function () { - controls = new ArcballControls(camera, renderer.domElement, scene); - controls.addEventListener('change', render); - - this.gizmoVisible = true; - - this.populateGui(); - }, - - populateGui: function () { - folderOptions.add(controls, 'enabled').name('Enable controls'); - folderOptions.add(controls, 'enableGrid').name('Enable Grid'); - folderOptions.add(controls, 'enableRotate').name('Enable rotate'); - folderOptions.add(controls, 'enablePan').name('Enable pan'); - folderOptions.add(controls, 'enableZoom').name('Enable zoom'); - folderOptions.add(controls, 'cursorZoom').name('Cursor zoom'); - folderOptions.add(controls, 'adjustNearFar').name('adjust near/far'); - folderOptions.add(controls, 'scaleFactor', 1.1, 10, 0.1).name('Scale factor'); - folderOptions.add(controls, 'minDistance', 0, 50, 0.5).name('Min distance'); - folderOptions.add(controls, 'maxDistance', 0, 50, 0.5).name('Max distance'); - folderOptions.add(controls, 'minZoom', 0, 50, 0.5).name('Min zoom'); - folderOptions.add(controls, 'maxZoom', 0, 50, 0.5).name('Max zoom'); - folderOptions - .add(arcballGui, 'gizmoVisible') - .name('Show gizmos') - .onChange(function () { - controls.setGizmosVisible(arcballGui.gizmoVisible); - }); - folderOptions.add(controls, 'copyState').name('Copy state(ctrl+c)'); - folderOptions.add(controls, 'pasteState').name('Paste state(ctrl+v)'); - folderOptions.add(controls, 'reset').name('Reset'); - folderAnimations.add(controls, 'enableAnimations').name('Enable anim.'); - folderAnimations.add(controls, 'dampingFactor', 0, 100, 1).name('Damping'); - folderAnimations.add(controls, 'wMax', 0, 100, 1).name('Angular spd'); - }, -}; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ReinhardToneMapping; - renderer.toneMappingExposure = 3; - renderer.domElement.style.background = 'linear-gradient( 180deg, rgba( 0,0,0,1 ) 0%, rgba( 128,128,255,1 ) 100% )'; - container.appendChild(renderer.domElement); - - // - - scene = new THREE.Scene(); - - camera = makePerspectiveCamera(); - camera.position.set(0, 0, perspectiveDistance); - - const material = new THREE.MeshStandardMaterial(); - - new OBJLoader().setPath('models/obj/cerberus/').load('Cerberus.obj', function (group) { - const textureLoader = new THREE.TextureLoader().setPath('models/obj/cerberus/'); - - material.roughness = 1; - material.metalness = 1; - - const diffuseMap = textureLoader.load('Cerberus_A.jpg', render); - diffuseMap.colorSpace = THREE.SRGBColorSpace; - material.map = diffuseMap; - - material.metalnessMap = material.roughnessMap = textureLoader.load('Cerberus_RM.jpg', render); - material.normalMap = textureLoader.load('Cerberus_N.jpg', render); - - material.map.wrapS = THREE.RepeatWrapping; - material.roughnessMap.wrapS = THREE.RepeatWrapping; - material.metalnessMap.wrapS = THREE.RepeatWrapping; - material.normalMap.wrapS = THREE.RepeatWrapping; - - group.traverse(function (child) { - if (child.isMesh) { - child.material = material; - } - }); - - group.rotation.y = Math.PI / 2; - group.position.x += 0.25; - scene.add(group); - render(); - - new RGBELoader().setPath('textures/equirectangular/').load('venice_sunset_1k.hdr', function (hdrEquirect) { - hdrEquirect.mapping = THREE.EquirectangularReflectionMapping; - - scene.environment = hdrEquirect; - - render(); - }); - - window.addEventListener('keydown', onKeyDown); - window.addEventListener('resize', onWindowResize); - - // - - gui = new GUI(); - gui.add(cameraType, 'type', cameras) - .name('Choose Camera') - .onChange(function () { - setCamera(cameraType.type); - }); - - folderOptions = gui.addFolder('Arcball parameters'); - folderAnimations = folderOptions.addFolder('Animations'); - - arcballGui.setArcballControls(); - - render(); - }); -} - -function makeOrthographicCamera() { - const halfFovV = THREE.MathUtils.DEG2RAD * 45 * 0.5; - const halfFovH = Math.atan((window.innerWidth / window.innerHeight) * Math.tan(halfFovV)); - - const halfW = perspectiveDistance * Math.tan(halfFovH); - const halfH = perspectiveDistance * Math.tan(halfFovV); - const near = 0.01; - const far = 2000; - const newCamera = new THREE.OrthographicCamera(-halfW, halfW, halfH, -halfH, near, far); - return newCamera; -} - -function makePerspectiveCamera() { - const fov = 45; - const aspect = window.innerWidth / window.innerHeight; - const near = 0.01; - const far = 2000; - const newCamera = new THREE.PerspectiveCamera(fov, aspect, near, far); - return newCamera; -} - -function onWindowResize() { - if (camera.type == 'OrthographicCamera') { - const halfFovV = THREE.MathUtils.DEG2RAD * 45 * 0.5; - const halfFovH = Math.atan((window.innerWidth / window.innerHeight) * Math.tan(halfFovV)); - - const halfW = perspectiveDistance * Math.tan(halfFovH); - const halfH = perspectiveDistance * Math.tan(halfFovV); - camera.left = -halfW; - camera.right = halfW; - camera.top = halfH; - camera.bottom = -halfH; - } else if (camera.type == 'PerspectiveCamera') { - camera.aspect = window.innerWidth / window.innerHeight; - } - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} - -function onKeyDown(event) { - if (event.key === 'c') { - if (event.ctrlKey || event.metaKey) { - controls.copyState(); - } - } else if (event.key === 'v') { - if (event.ctrlKey || event.metaKey) { - controls.pasteState(); - } - } -} - -function setCamera(type) { - if (type == 'Orthographic') { - camera = makeOrthographicCamera(); - camera.position.set(0, 0, orthographicDistance); - } else if (type == 'Perspective') { - camera = makePerspectiveCamera(); - camera.position.set(0, 0, perspectiveDistance); - } - - controls.setCamera(camera); - - render(); -} diff --git a/examples-testing/examples/misc_controls_drag.ts b/examples-testing/examples/misc_controls_drag.ts deleted file mode 100644 index b12b0421e..000000000 --- a/examples-testing/examples/misc_controls_drag.ts +++ /dev/null @@ -1,153 +0,0 @@ -import * as THREE from 'three'; - -import { DragControls } from 'three/addons/controls/DragControls.js'; - -let container; -let camera, scene, renderer; -let controls, group; -let enableSelection = false; - -const objects = []; - -const mouse = new THREE.Vector2(), - raycaster = new THREE.Raycaster(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 500); - camera.position.z = 25; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - scene.add(new THREE.AmbientLight(0xaaaaaa)); - - const light = new THREE.SpotLight(0xffffff, 10000); - light.position.set(0, 25, 50); - light.angle = Math.PI / 9; - - light.castShadow = true; - light.shadow.camera.near = 10; - light.shadow.camera.far = 100; - light.shadow.mapSize.width = 1024; - light.shadow.mapSize.height = 1024; - - scene.add(light); - - group = new THREE.Group(); - scene.add(group); - - const geometry = new THREE.BoxGeometry(); - - for (let i = 0; i < 200; i++) { - const object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff })); - - object.position.x = Math.random() * 30 - 15; - object.position.y = Math.random() * 15 - 7.5; - object.position.z = Math.random() * 20 - 10; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() * 2 + 1; - object.scale.y = Math.random() * 2 + 1; - object.scale.z = Math.random() * 2 + 1; - - object.castShadow = true; - object.receiveShadow = true; - - scene.add(object); - - objects.push(object); - } - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFShadowMap; - - container.appendChild(renderer.domElement); - - controls = new DragControls([...objects], camera, renderer.domElement); - controls.rotateSpeed = 2; - controls.addEventListener('drag', render); - - // - - window.addEventListener('resize', onWindowResize); - - document.addEventListener('click', onClick); - window.addEventListener('keydown', onKeyDown); - window.addEventListener('keyup', onKeyUp); - - render(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function onKeyDown(event) { - enableSelection = event.keyCode === 16 ? true : false; - - if (event.keyCode === 77) { - controls.touches.ONE = controls.touches.ONE === THREE.TOUCH.PAN ? THREE.TOUCH.ROTATE : THREE.TOUCH.PAN; - } -} - -function onKeyUp() { - enableSelection = false; -} - -function onClick(event) { - event.preventDefault(); - - if (enableSelection === true) { - const draggableObjects = controls.objects; - draggableObjects.length = 0; - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - raycaster.setFromCamera(mouse, camera); - - const intersections = raycaster.intersectObjects(objects, true); - - if (intersections.length > 0) { - const object = intersections[0].object; - - if (group.children.includes(object) === true) { - object.material.emissive.set(0x000000); - scene.attach(object); - } else { - object.material.emissive.set(0xaaaaaa); - group.attach(object); - } - - controls.transformGroup = true; - draggableObjects.push(group); - } - - if (group.children.length === 0) { - controls.transformGroup = false; - draggableObjects.push(...objects); - } - } - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_controls_fly.ts b/examples-testing/examples/misc_controls_fly.ts deleted file mode 100644 index 5b25c4895..000000000 --- a/examples-testing/examples/misc_controls_fly.ts +++ /dev/null @@ -1,214 +0,0 @@ -import * as THREE from 'three'; -import { pass, film } from 'three/tsl'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { FlyControls } from 'three/addons/controls/FlyControls.js'; - -const radius = 6371; -const tilt = 0.41; -const rotationSpeed = 0.02; - -const cloudsScale = 1.005; -const moonScale = 0.23; - -const MARGIN = 0; -let SCREEN_HEIGHT = window.innerHeight - MARGIN * 2; -let SCREEN_WIDTH = window.innerWidth; - -let camera, controls, scene, renderer, stats; -let geometry, meshPlanet, meshClouds, meshMoon; -let dirLight; - -let postProcessing; - -const textureLoader = new THREE.TextureLoader(); - -let d, dPlanet, dMoon; -const dMoonVec = new THREE.Vector3(); - -const clock = new THREE.Clock(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(25, SCREEN_WIDTH / SCREEN_HEIGHT, 50, 1e7); - camera.position.z = radius * 5; - - scene = new THREE.Scene(); - scene.fog = new THREE.FogExp2(0x000000, 0.00000025); - - dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(-1, 0, 1).normalize(); - scene.add(dirLight); - - const materialNormalMap = new THREE.MeshPhongMaterial({ - specular: 0x7c7c7c, - shininess: 15, - map: textureLoader.load('textures/planets/earth_atmos_2048.jpg'), - specularMap: textureLoader.load('textures/planets/earth_specular_2048.jpg'), - normalMap: textureLoader.load('textures/planets/earth_normal_2048.jpg'), - - // y scale is negated to compensate for normal map handedness. - normalScale: new THREE.Vector2(0.85, -0.85), - }); - materialNormalMap.map.colorSpace = THREE.SRGBColorSpace; - - // planet - - geometry = new THREE.SphereGeometry(radius, 100, 50); - - meshPlanet = new THREE.Mesh(geometry, materialNormalMap); - meshPlanet.rotation.y = 0; - meshPlanet.rotation.z = tilt; - scene.add(meshPlanet); - - // clouds - - const materialClouds = new THREE.MeshLambertMaterial({ - map: textureLoader.load('textures/planets/earth_clouds_1024.png'), - transparent: true, - }); - materialClouds.map.colorSpace = THREE.SRGBColorSpace; - - meshClouds = new THREE.Mesh(geometry, materialClouds); - meshClouds.scale.set(cloudsScale, cloudsScale, cloudsScale); - meshClouds.rotation.z = tilt; - scene.add(meshClouds); - - // moon - - const materialMoon = new THREE.MeshPhongMaterial({ - map: textureLoader.load('textures/planets/moon_1024.jpg'), - }); - materialMoon.map.colorSpace = THREE.SRGBColorSpace; - - meshMoon = new THREE.Mesh(geometry, materialMoon); - meshMoon.position.set(radius * 5, 0, 0); - meshMoon.scale.set(moonScale, moonScale, moonScale); - scene.add(meshMoon); - - // stars - - const r = radius, - starsGeometry = [new THREE.BufferGeometry(), new THREE.BufferGeometry()]; - - const vertices1 = []; - const vertices2 = []; - - const vertex = new THREE.Vector3(); - - for (let i = 0; i < 250; i++) { - vertex.x = Math.random() * 2 - 1; - vertex.y = Math.random() * 2 - 1; - vertex.z = Math.random() * 2 - 1; - vertex.multiplyScalar(r); - - vertices1.push(vertex.x, vertex.y, vertex.z); - } - - for (let i = 0; i < 1500; i++) { - vertex.x = Math.random() * 2 - 1; - vertex.y = Math.random() * 2 - 1; - vertex.z = Math.random() * 2 - 1; - vertex.multiplyScalar(r); - - vertices2.push(vertex.x, vertex.y, vertex.z); - } - - starsGeometry[0].setAttribute('position', new THREE.Float32BufferAttribute(vertices1, 3)); - starsGeometry[1].setAttribute('position', new THREE.Float32BufferAttribute(vertices2, 3)); - - const starsMaterials = [ - new THREE.PointsMaterial({ color: 0x9c9c9c }), - new THREE.PointsMaterial({ color: 0x838383 }), - new THREE.PointsMaterial({ color: 0x5a5a5a }), - ]; - - for (let i = 10; i < 30; i++) { - const stars = new THREE.Points(starsGeometry[i % 2], starsMaterials[i % 3]); - - stars.rotation.x = Math.random() * 6; - stars.rotation.y = Math.random() * 6; - stars.rotation.z = Math.random() * 6; - stars.scale.setScalar(i * 10); - - stars.matrixAutoUpdate = false; - stars.updateMatrix(); - - scene.add(stars); - } - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - controls = new FlyControls(camera, renderer.domElement); - - controls.movementSpeed = 1000; - controls.domElement = renderer.domElement; - controls.rollSpeed = Math.PI / 24; - controls.autoForward = false; - controls.dragToLook = false; - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - - // postprocessing - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - const scenePassColor = scenePass.getTextureNode(); - - postProcessing.outputNode = film(scenePassColor); -} - -function onWindowResize() { - SCREEN_HEIGHT = window.innerHeight; - SCREEN_WIDTH = window.innerWidth; - - camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - // rotate the planet and clouds - - const delta = clock.getDelta(); - - meshPlanet.rotation.y += rotationSpeed * delta; - meshClouds.rotation.y += 1.25 * rotationSpeed * delta; - - // slow down as we approach the surface - - dPlanet = camera.position.length(); - - dMoonVec.subVectors(camera.position, meshMoon.position); - dMoon = dMoonVec.length(); - - if (dMoon < dPlanet) { - d = dMoon - radius * moonScale * 1.01; - } else { - d = dPlanet - radius * 1.01; - } - - controls.movementSpeed = 0.33 * d; - controls.update(delta); - - postProcessing.render(); -} diff --git a/examples-testing/examples/misc_controls_map.ts b/examples-testing/examples/misc_controls_map.ts deleted file mode 100644 index 2f52190cf..000000000 --- a/examples-testing/examples/misc_controls_map.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { MapControls } from 'three/addons/controls/MapControls.js'; - -let camera, controls, scene, renderer; - -init(); -//render(); // remove when using animation loop - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xcccccc); - scene.fog = new THREE.FogExp2(0xcccccc, 0.002); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 200, -400); - - // controls - - controls = new MapControls(camera, renderer.domElement); - - //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop) - - controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled - controls.dampingFactor = 0.05; - - controls.screenSpacePanning = false; - - controls.minDistance = 100; - controls.maxDistance = 500; - - controls.maxPolarAngle = Math.PI / 2; - - // world - - const geometry = new THREE.BoxGeometry(); - geometry.translate(0, 0.5, 0); - const material = new THREE.MeshPhongMaterial({ color: 0xeeeeee, flatShading: true }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 1600 - 800; - mesh.position.y = 0; - mesh.position.z = Math.random() * 1600 - 800; - mesh.scale.x = 20; - mesh.scale.y = Math.random() * 80 + 10; - mesh.scale.z = 20; - mesh.updateMatrix(); - mesh.matrixAutoUpdate = false; - scene.add(mesh); - } - - // lights - - const dirLight1 = new THREE.DirectionalLight(0xffffff, 3); - dirLight1.position.set(1, 1, 1); - scene.add(dirLight1); - - const dirLight2 = new THREE.DirectionalLight(0x002288, 3); - dirLight2.position.set(-1, -1, -1); - scene.add(dirLight2); - - const ambientLight = new THREE.AmbientLight(0x555555); - scene.add(ambientLight); - - // - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - gui.add(controls, 'zoomToCursor'); - gui.add(controls, 'screenSpacePanning'); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_controls_orbit.ts b/examples-testing/examples/misc_controls_orbit.ts deleted file mode 100644 index 186e216cb..000000000 --- a/examples-testing/examples/misc_controls_orbit.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, controls, scene, renderer; - -init(); -//render(); // remove when using animation loop - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xcccccc); - scene.fog = new THREE.FogExp2(0xcccccc, 0.002); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(400, 200, 0); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.listenToKeyEvents(window); // optional - - //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop) - - controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled - controls.dampingFactor = 0.05; - - controls.screenSpacePanning = false; - - controls.minDistance = 100; - controls.maxDistance = 500; - - controls.maxPolarAngle = Math.PI / 2; - - // world - - const geometry = new THREE.ConeGeometry(10, 30, 4, 1); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 1600 - 800; - mesh.position.y = 0; - mesh.position.z = Math.random() * 1600 - 800; - mesh.updateMatrix(); - mesh.matrixAutoUpdate = false; - scene.add(mesh); - } - - // lights - - const dirLight1 = new THREE.DirectionalLight(0xffffff, 3); - dirLight1.position.set(1, 1, 1); - scene.add(dirLight1); - - const dirLight2 = new THREE.DirectionalLight(0x002288, 3); - dirLight2.position.set(-1, -1, -1); - scene.add(dirLight2); - - const ambientLight = new THREE.AmbientLight(0x555555); - scene.add(ambientLight); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_controls_pointerlock.ts b/examples-testing/examples/misc_controls_pointerlock.ts deleted file mode 100644 index 0b6fcc516..000000000 --- a/examples-testing/examples/misc_controls_pointerlock.ts +++ /dev/null @@ -1,245 +0,0 @@ -import * as THREE from 'three'; - -import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js'; - -let camera, scene, renderer, controls; - -const objects = []; - -let raycaster; - -let moveForward = false; -let moveBackward = false; -let moveLeft = false; -let moveRight = false; -let canJump = false; - -let prevTime = performance.now(); -const velocity = new THREE.Vector3(); -const direction = new THREE.Vector3(); -const vertex = new THREE.Vector3(); -const color = new THREE.Color(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.y = 10; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - scene.fog = new THREE.Fog(0xffffff, 0, 750); - - const light = new THREE.HemisphereLight(0xeeeeff, 0x777788, 2.5); - light.position.set(0.5, 1, 0.75); - scene.add(light); - - controls = new PointerLockControls(camera, document.body); - - const blocker = document.getElementById('blocker'); - const instructions = document.getElementById('instructions'); - - instructions.addEventListener('click', function () { - controls.lock(); - }); - - controls.addEventListener('lock', function () { - instructions.style.display = 'none'; - blocker.style.display = 'none'; - }); - - controls.addEventListener('unlock', function () { - blocker.style.display = 'block'; - instructions.style.display = ''; - }); - - scene.add(controls.object); - - const onKeyDown = function (event) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': - moveForward = true; - break; - - case 'ArrowLeft': - case 'KeyA': - moveLeft = true; - break; - - case 'ArrowDown': - case 'KeyS': - moveBackward = true; - break; - - case 'ArrowRight': - case 'KeyD': - moveRight = true; - break; - - case 'Space': - if (canJump === true) velocity.y += 350; - canJump = false; - break; - } - }; - - const onKeyUp = function (event) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': - moveForward = false; - break; - - case 'ArrowLeft': - case 'KeyA': - moveLeft = false; - break; - - case 'ArrowDown': - case 'KeyS': - moveBackward = false; - break; - - case 'ArrowRight': - case 'KeyD': - moveRight = false; - break; - } - }; - - document.addEventListener('keydown', onKeyDown); - document.addEventListener('keyup', onKeyUp); - - raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, -1, 0), 0, 10); - - // floor - - let floorGeometry = new THREE.PlaneGeometry(2000, 2000, 100, 100); - floorGeometry.rotateX(-Math.PI / 2); - - // vertex displacement - - let position = floorGeometry.attributes.position; - - for (let i = 0, l = position.count; i < l; i++) { - vertex.fromBufferAttribute(position, i); - - vertex.x += Math.random() * 20 - 10; - vertex.y += Math.random() * 2; - vertex.z += Math.random() * 20 - 10; - - position.setXYZ(i, vertex.x, vertex.y, vertex.z); - } - - floorGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices - - position = floorGeometry.attributes.position; - const colorsFloor = []; - - for (let i = 0, l = position.count; i < l; i++) { - color.setHSL(Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75, THREE.SRGBColorSpace); - colorsFloor.push(color.r, color.g, color.b); - } - - floorGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colorsFloor, 3)); - - const floorMaterial = new THREE.MeshBasicMaterial({ vertexColors: true }); - - const floor = new THREE.Mesh(floorGeometry, floorMaterial); - scene.add(floor); - - // objects - - const boxGeometry = new THREE.BoxGeometry(20, 20, 20).toNonIndexed(); - - position = boxGeometry.attributes.position; - const colorsBox = []; - - for (let i = 0, l = position.count; i < l; i++) { - color.setHSL(Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75, THREE.SRGBColorSpace); - colorsBox.push(color.r, color.g, color.b); - } - - boxGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colorsBox, 3)); - - for (let i = 0; i < 500; i++) { - const boxMaterial = new THREE.MeshPhongMaterial({ specular: 0xffffff, flatShading: true, vertexColors: true }); - boxMaterial.color.setHSL(Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75, THREE.SRGBColorSpace); - - const box = new THREE.Mesh(boxGeometry, boxMaterial); - box.position.x = Math.floor(Math.random() * 20 - 10) * 20; - box.position.y = Math.floor(Math.random() * 20) * 20 + 10; - box.position.z = Math.floor(Math.random() * 20 - 10) * 20; - - scene.add(box); - objects.push(box); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = performance.now(); - - if (controls.isLocked === true) { - raycaster.ray.origin.copy(controls.object.position); - raycaster.ray.origin.y -= 10; - - const intersections = raycaster.intersectObjects(objects, false); - - const onObject = intersections.length > 0; - - const delta = (time - prevTime) / 1000; - - velocity.x -= velocity.x * 10.0 * delta; - velocity.z -= velocity.z * 10.0 * delta; - - velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass - - direction.z = Number(moveForward) - Number(moveBackward); - direction.x = Number(moveRight) - Number(moveLeft); - direction.normalize(); // this ensures consistent movements in all directions - - if (moveForward || moveBackward) velocity.z -= direction.z * 400.0 * delta; - if (moveLeft || moveRight) velocity.x -= direction.x * 400.0 * delta; - - if (onObject === true) { - velocity.y = Math.max(0, velocity.y); - canJump = true; - } - - controls.moveRight(-velocity.x * delta); - controls.moveForward(-velocity.z * delta); - - controls.object.position.y += velocity.y * delta; // new behavior - - if (controls.object.position.y < 10) { - velocity.y = 0; - controls.object.position.y = 10; - - canJump = true; - } - } - - prevTime = time; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_controls_trackball.ts b/examples-testing/examples/misc_controls_trackball.ts deleted file mode 100644 index b6479e9f6..000000000 --- a/examples-testing/examples/misc_controls_trackball.ts +++ /dev/null @@ -1,134 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - -let perspectiveCamera, orthographicCamera, controls, scene, renderer, stats; - -const params = { - orthographicCamera: false, -}; - -const frustumSize = 400; - -init(); - -function init() { - const aspect = window.innerWidth / window.innerHeight; - - perspectiveCamera = new THREE.PerspectiveCamera(60, aspect, 1, 1000); - perspectiveCamera.position.z = 500; - - orthographicCamera = new THREE.OrthographicCamera( - (frustumSize * aspect) / -2, - (frustumSize * aspect) / 2, - frustumSize / 2, - frustumSize / -2, - 1, - 1000, - ); - orthographicCamera.position.z = 500; - - // world - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xcccccc); - scene.fog = new THREE.FogExp2(0xcccccc, 0.002); - - const geometry = new THREE.ConeGeometry(10, 30, 4, 1); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = (Math.random() - 0.5) * 1000; - mesh.position.y = (Math.random() - 0.5) * 1000; - mesh.position.z = (Math.random() - 0.5) * 1000; - mesh.updateMatrix(); - mesh.matrixAutoUpdate = false; - scene.add(mesh); - } - - // lights - - const dirLight1 = new THREE.DirectionalLight(0xffffff, 3); - dirLight1.position.set(1, 1, 1); - scene.add(dirLight1); - - const dirLight2 = new THREE.DirectionalLight(0x002288, 3); - dirLight2.position.set(-1, -1, -1); - scene.add(dirLight2); - - const ambientLight = new THREE.AmbientLight(0x555555); - scene.add(ambientLight); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const gui = new GUI(); - gui.add(params, 'orthographicCamera') - .name('use orthographic') - .onChange(function (value) { - controls.dispose(); - - createControls(value ? orthographicCamera : perspectiveCamera); - }); - - // - - window.addEventListener('resize', onWindowResize); - - createControls(perspectiveCamera); -} - -function createControls(camera) { - controls = new TrackballControls(camera, renderer.domElement); - - controls.rotateSpeed = 1.0; - controls.zoomSpeed = 1.2; - controls.panSpeed = 0.8; - - controls.keys = ['KeyA', 'KeyS', 'KeyD']; -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - perspectiveCamera.aspect = aspect; - perspectiveCamera.updateProjectionMatrix(); - - orthographicCamera.left = (-frustumSize * aspect) / 2; - orthographicCamera.right = (frustumSize * aspect) / 2; - orthographicCamera.top = frustumSize / 2; - orthographicCamera.bottom = -frustumSize / 2; - orthographicCamera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - controls.handleResize(); -} - -function animate() { - controls.update(); - - render(); - - stats.update(); -} - -function render() { - const camera = params.orthographicCamera ? orthographicCamera : perspectiveCamera; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_controls_transform.ts b/examples-testing/examples/misc_controls_transform.ts deleted file mode 100644 index 6f7793d33..000000000 --- a/examples-testing/examples/misc_controls_transform.ts +++ /dev/null @@ -1,182 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { TransformControls } from 'three/addons/controls/TransformControls.js'; - -let cameraPersp, cameraOrtho, currentCamera; -let scene, renderer, control, orbit; - -init(); -render(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const aspect = window.innerWidth / window.innerHeight; - - const frustumSize = 5; - - cameraPersp = new THREE.PerspectiveCamera(50, aspect, 0.1, 100); - cameraOrtho = new THREE.OrthographicCamera( - -frustumSize * aspect, - frustumSize * aspect, - frustumSize, - -frustumSize, - 0.1, - 100, - ); - currentCamera = cameraPersp; - - currentCamera.position.set(5, 2.5, 5); - - scene = new THREE.Scene(); - scene.add(new THREE.GridHelper(5, 10, 0x888888, 0x444444)); - - const ambientLight = new THREE.AmbientLight(0xffffff); - scene.add(ambientLight); - - const light = new THREE.DirectionalLight(0xffffff, 4); - light.position.set(1, 1, 1); - scene.add(light); - - const texture = new THREE.TextureLoader().load('textures/crate.gif', render); - texture.colorSpace = THREE.SRGBColorSpace; - texture.anisotropy = renderer.capabilities.getMaxAnisotropy(); - - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshLambertMaterial({ map: texture }); - - orbit = new OrbitControls(currentCamera, renderer.domElement); - orbit.update(); - orbit.addEventListener('change', render); - - control = new TransformControls(currentCamera, renderer.domElement); - control.addEventListener('change', render); - control.addEventListener('dragging-changed', function (event) { - orbit.enabled = !event.value; - }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - control.attach(mesh); - - const gizmo = control.getHelper(); - scene.add(gizmo); - - window.addEventListener('resize', onWindowResize); - - window.addEventListener('keydown', function (event) { - switch (event.key) { - case 'q': - control.setSpace(control.space === 'local' ? 'world' : 'local'); - break; - - case 'Shift': - control.setTranslationSnap(1); - control.setRotationSnap(THREE.MathUtils.degToRad(15)); - control.setScaleSnap(0.25); - break; - - case 'w': - control.setMode('translate'); - break; - - case 'e': - control.setMode('rotate'); - break; - - case 'r': - control.setMode('scale'); - break; - - case 'c': - const position = currentCamera.position.clone(); - - currentCamera = currentCamera.isPerspectiveCamera ? cameraOrtho : cameraPersp; - currentCamera.position.copy(position); - - orbit.object = currentCamera; - control.camera = currentCamera; - - currentCamera.lookAt(orbit.target.x, orbit.target.y, orbit.target.z); - onWindowResize(); - break; - - case 'v': - const randomFoV = Math.random() + 0.1; - const randomZoom = Math.random() + 0.1; - - cameraPersp.fov = randomFoV * 160; - cameraOrtho.bottom = -randomFoV * 500; - cameraOrtho.top = randomFoV * 500; - - cameraPersp.zoom = randomZoom * 5; - cameraOrtho.zoom = randomZoom * 5; - onWindowResize(); - break; - - case '+': - case '=': - control.setSize(control.size + 0.1); - break; - - case '-': - case '_': - control.setSize(Math.max(control.size - 0.1, 0.1)); - break; - - case 'x': - control.showX = !control.showX; - break; - - case 'y': - control.showY = !control.showY; - break; - - case 'z': - control.showZ = !control.showZ; - break; - - case ' ': - control.enabled = !control.enabled; - break; - - case 'Escape': - control.reset(); - break; - } - }); - - window.addEventListener('keyup', function (event) { - switch (event.key) { - case 'Shift': - control.setTranslationSnap(null); - control.setRotationSnap(null); - control.setScaleSnap(null); - break; - } - }); -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - cameraPersp.aspect = aspect; - cameraPersp.updateProjectionMatrix(); - - cameraOrtho.left = cameraOrtho.bottom * aspect; - cameraOrtho.right = cameraOrtho.top * aspect; - cameraOrtho.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, currentCamera); -} diff --git a/examples-testing/examples/misc_exporter_draco.ts b/examples-testing/examples/misc_exporter_draco.ts deleted file mode 100644 index 40a62fb18..000000000 --- a/examples-testing/examples/misc_exporter_draco.ts +++ /dev/null @@ -1,117 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { DRACOExporter } from 'three/addons/exporters/DRACOExporter.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, camera, renderer, exporter, mesh; - -const params = { - export: exportFile, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(4, 2, 4); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 4, 20); - - exporter = new DRACOExporter(); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 3); - hemiLight.position.set(0, 20, 0); - scene.add(hemiLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 3); - directionalLight.position.set(0, 20, 10); - directionalLight.castShadow = true; - directionalLight.shadow.camera.top = 2; - directionalLight.shadow.camera.bottom = -2; - directionalLight.shadow.camera.left = -2; - directionalLight.shadow.camera.right = 2; - scene.add(directionalLight); - - // ground - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(40, 40), - new THREE.MeshPhongMaterial({ color: 0xbbbbbb, depthWrite: false }), - ); - ground.rotation.x = -Math.PI / 2; - ground.receiveShadow = true; - scene.add(ground); - - const grid = new THREE.GridHelper(40, 20, 0x000000, 0x000000); - grid.material.opacity = 0.2; - grid.material.transparent = true; - scene.add(grid); - - // export mesh - - const geometry = new THREE.TorusKnotGeometry(0.75, 0.2, 200, 30); - const material = new THREE.MeshPhongMaterial({ color: 0x00ff00 }); - mesh = new THREE.Mesh(geometry, material); - mesh.castShadow = true; - mesh.position.y = 1.5; - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 1.5, 0); - controls.update(); - - // - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'export').name('Export DRC'); - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} - -function exportFile() { - const result = exporter.parse(mesh); - saveArrayBuffer(result, 'file.drc'); -} - -const link = document.createElement('a'); -link.style.display = 'none'; -document.body.appendChild(link); - -function save(blob, filename) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); -} - -function saveArrayBuffer(buffer, filename) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); -} diff --git a/examples-testing/examples/misc_exporter_exr.ts b/examples-testing/examples/misc_exporter_exr.ts deleted file mode 100644 index f4a189bba..000000000 --- a/examples-testing/examples/misc_exporter_exr.ts +++ /dev/null @@ -1,158 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { EXRExporter, ZIP_COMPRESSION, ZIPS_COMPRESSION, NO_COMPRESSION } from 'three/addons/exporters/EXRExporter.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, camera, renderer, exporter, mesh, controls, renderTarget, dataTexture; - -const params = { - target: 'pmrem', - type: 'HalfFloatType', - compression: 'ZIP', - export: exportFile, -}; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(10, 0, 0); - - scene = new THREE.Scene(); - - exporter = new EXRExporter(); - const rgbeloader = new RGBELoader(); - - // - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - pmremGenerator.compileEquirectangularShader(); - - rgbeloader.load('textures/equirectangular/san_giuseppe_bridge_2k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - renderTarget = pmremGenerator.fromEquirectangular(texture); - scene.background = renderTarget.texture; - }); - - createDataTexture(); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.rotateSpeed = -0.25; // negative, to track mouse pointer - - // - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - const input = gui.addFolder('Input'); - input.add(params, 'target').options(['pmrem', 'data-texture']).onChange(swapScene); - - const options = gui.addFolder('Output Options'); - options.add(params, 'type').options(['FloatType', 'HalfFloatType']); - options.add(params, 'compression').options(['ZIP', 'ZIPS', 'NONE']); - - gui.add(params, 'export').name('Export EXR'); - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - renderer.render(scene, camera); -} - -function createDataTexture() { - const normal = new THREE.Vector3(); - const coord = new THREE.Vector2(); - const size = 800, - radius = 320, - factor = (Math.PI * 0.5) / radius; - const data = new Float32Array(4 * size * size); - - for (let i = 0; i < size; i++) { - for (let j = 0; j < size; j++) { - const idx = i * size * 4 + j * 4; - coord.set(j, i).subScalar(size / 2); - - if (coord.length() < radius) - normal.set(Math.sin(coord.x * factor), Math.sin(coord.y * factor), Math.cos(coord.x * factor)); - else normal.set(0, 0, 1); - - data[idx + 0] = 0.5 + 0.5 * normal.x; - data[idx + 1] = 0.5 + 0.5 * normal.y; - data[idx + 2] = 0.5 + 0.5 * normal.z; - data[idx + 3] = 1; - } - } - - dataTexture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.FloatType); - dataTexture.needsUpdate = true; - - const material = new THREE.MeshBasicMaterial({ map: dataTexture }); - const quad = new THREE.PlaneGeometry(50, 50); - mesh = new THREE.Mesh(quad, material); - mesh.visible = false; - - scene.add(mesh); -} - -function swapScene() { - if (params.target == 'pmrem') { - camera.position.set(10, 0, 0); - controls.enabled = true; - scene.background = renderTarget.texture; - mesh.visible = false; - } else { - camera.position.set(0, 0, 70); - controls.enabled = false; - scene.background = new THREE.Color(0, 0, 0); - mesh.visible = true; - } -} - -async function exportFile() { - let result, exportType, exportCompression; - - if (params.type == 'HalfFloatType') exportType = THREE.HalfFloatType; - else exportType = THREE.FloatType; - - if (params.compression == 'ZIP') exportCompression = ZIP_COMPRESSION; - else if (params.compression == 'ZIPS') exportCompression = ZIPS_COMPRESSION; - else exportCompression = NO_COMPRESSION; - - if (params.target == 'pmrem') - result = await exporter.parse(renderer, renderTarget, { type: exportType, compression: exportCompression }); - else result = await exporter.parse(dataTexture, { type: exportType, compression: exportCompression }); - - saveArrayBuffer(result, params.target + '.exr'); -} - -function saveArrayBuffer(buffer, filename) { - const blob = new Blob([buffer], { type: 'image/x-exr' }); - const link = document.createElement('a'); - - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); -} diff --git a/examples-testing/examples/misc_exporter_gltf.ts b/examples-testing/examples/misc_exporter_gltf.ts deleted file mode 100644 index fda0d4df8..000000000 --- a/examples-testing/examples/misc_exporter_gltf.ts +++ /dev/null @@ -1,506 +0,0 @@ -import * as THREE from 'three'; - -import { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; -import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -function exportGLTF(input) { - const gltfExporter = new GLTFExporter(); - - const options = { - trs: params.trs, - onlyVisible: params.onlyVisible, - binary: params.binary, - maxTextureSize: params.maxTextureSize, - }; - gltfExporter.parse( - input, - function (result) { - if (result instanceof ArrayBuffer) { - saveArrayBuffer(result, 'scene.glb'); - } else { - const output = JSON.stringify(result, null, 2); - console.log(output); - saveString(output, 'scene.gltf'); - } - }, - function (error) { - console.log('An error happened during parsing', error); - }, - options, - ); -} - -const link = document.createElement('a'); -link.style.display = 'none'; -document.body.appendChild(link); // Firefox workaround, see #6594 - -function save(blob, filename) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); - - // URL.revokeObjectURL( url ); breaks Firefox... -} - -function saveString(text, filename) { - save(new Blob([text], { type: 'text/plain' }), filename); -} - -function saveArrayBuffer(buffer, filename) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); -} - -let container; - -let camera, object, object2, material, geometry, scene1, scene2, renderer; -let gridHelper, sphere, model, coffeemat; - -const params = { - trs: false, - onlyVisible: true, - binary: false, - maxTextureSize: 4096, - exportScene1: exportScene1, - exportScenes: exportScenes, - exportSphere: exportSphere, - exportModel: exportModel, - exportObjects: exportObjects, - exportSceneObject: exportSceneObject, - exportCompressedObject: exportCompressedObject, -}; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // Make linear gradient texture - - const data = new Uint8ClampedArray(100 * 100 * 4); - - for (let y = 0; y < 100; y++) { - for (let x = 0; x < 100; x++) { - const stride = 4 * (100 * y + x); - - data[stride] = Math.round((255 * y) / 99); - data[stride + 1] = Math.round(255 - (255 * y) / 99); - data[stride + 2] = 0; - data[stride + 3] = 255; - } - } - - const gradientTexture = new THREE.DataTexture(data, 100, 100, THREE.RGBAFormat); - gradientTexture.minFilter = THREE.LinearFilter; - gradientTexture.magFilter = THREE.LinearFilter; - gradientTexture.needsUpdate = true; - - scene1 = new THREE.Scene(); - scene1.name = 'Scene1'; - - // --------------------------------------------------------------------- - // Perspective Camera - // --------------------------------------------------------------------- - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(600, 400, 0); - - camera.name = 'PerspectiveCamera'; - scene1.add(camera); - - // --------------------------------------------------------------------- - // Ambient light - // --------------------------------------------------------------------- - const ambientLight = new THREE.AmbientLight(0xcccccc); - ambientLight.name = 'AmbientLight'; - scene1.add(ambientLight); - - // --------------------------------------------------------------------- - // DirectLight - // --------------------------------------------------------------------- - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.target.position.set(0, 0, -1); - dirLight.add(dirLight.target); - dirLight.lookAt(-1, -1, 0); - dirLight.name = 'DirectionalLight'; - scene1.add(dirLight); - - // --------------------------------------------------------------------- - // Grid - // --------------------------------------------------------------------- - gridHelper = new THREE.GridHelper(2000, 20, 0xc1c1c1, 0x8d8d8d); - gridHelper.position.y = -50; - gridHelper.name = 'Grid'; - scene1.add(gridHelper); - - // --------------------------------------------------------------------- - // Axes - // --------------------------------------------------------------------- - const axes = new THREE.AxesHelper(500); - axes.name = 'AxesHelper'; - scene1.add(axes); - - // --------------------------------------------------------------------- - // Simple geometry with basic material - // --------------------------------------------------------------------- - // Icosahedron - const mapGrid = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - mapGrid.wrapS = mapGrid.wrapT = THREE.RepeatWrapping; - mapGrid.colorSpace = THREE.SRGBColorSpace; - material = new THREE.MeshBasicMaterial({ - color: 0xffffff, - map: mapGrid, - }); - - object = new THREE.Mesh(new THREE.IcosahedronGeometry(75, 0), material); - object.position.set(-200, 0, 200); - object.name = 'Icosahedron'; - scene1.add(object); - - // Octahedron - material = new THREE.MeshBasicMaterial({ - color: 0x0000ff, - wireframe: true, - }); - object = new THREE.Mesh(new THREE.OctahedronGeometry(75, 1), material); - object.position.set(0, 0, 200); - object.name = 'Octahedron'; - scene1.add(object); - - // Tetrahedron - material = new THREE.MeshBasicMaterial({ - color: 0xff0000, - transparent: true, - opacity: 0.5, - }); - - object = new THREE.Mesh(new THREE.TetrahedronGeometry(75, 0), material); - object.position.set(200, 0, 200); - object.name = 'Tetrahedron'; - scene1.add(object); - - // --------------------------------------------------------------------- - // Buffered geometry primitives - // --------------------------------------------------------------------- - // Sphere - material = new THREE.MeshStandardMaterial({ - color: 0xffff00, - metalness: 0.5, - roughness: 1.0, - flatShading: true, - }); - material.map = gradientTexture; - material.bumpMap = mapGrid; - sphere = new THREE.Mesh(new THREE.SphereGeometry(70, 10, 10), material); - sphere.position.set(0, 0, 0); - sphere.name = 'Sphere'; - scene1.add(sphere); - - // Cylinder - material = new THREE.MeshStandardMaterial({ - color: 0xff00ff, - flatShading: true, - }); - object = new THREE.Mesh(new THREE.CylinderGeometry(10, 80, 100), material); - object.position.set(200, 0, 0); - object.name = 'Cylinder'; - scene1.add(object); - - // TorusKnot - material = new THREE.MeshStandardMaterial({ - color: 0xff0000, - roughness: 1, - }); - object = new THREE.Mesh(new THREE.TorusKnotGeometry(50, 15, 40, 10), material); - object.position.set(-200, 0, 0); - object.name = 'Cylinder'; - scene1.add(object); - - // --------------------------------------------------------------------- - // Hierarchy - // --------------------------------------------------------------------- - const mapWood = new THREE.TextureLoader().load('textures/hardwood2_diffuse.jpg'); - material = new THREE.MeshStandardMaterial({ map: mapWood, side: THREE.DoubleSide }); - - object = new THREE.Mesh(new THREE.BoxGeometry(40, 100, 100), material); - object.position.set(-200, 0, 400); - object.name = 'Cube'; - scene1.add(object); - - object2 = new THREE.Mesh(new THREE.BoxGeometry(40, 40, 40, 2, 2, 2), material); - object2.position.set(0, 0, 50); - object2.rotation.set(0, 45, 0); - object2.name = 'SubCube'; - object.add(object2); - - // --------------------------------------------------------------------- - // Groups - // --------------------------------------------------------------------- - const group1 = new THREE.Group(); - group1.name = 'Group'; - scene1.add(group1); - - const group2 = new THREE.Group(); - group2.name = 'subGroup'; - group2.position.set(0, 50, 0); - group1.add(group2); - - object2 = new THREE.Mesh(new THREE.BoxGeometry(30, 30, 30), material); - object2.name = 'Cube in group'; - object2.position.set(0, 0, 400); - group2.add(object2); - - // --------------------------------------------------------------------- - // THREE.Line Strip - // --------------------------------------------------------------------- - geometry = new THREE.BufferGeometry(); - let numPoints = 100; - let positions = new Float32Array(numPoints * 3); - - for (let i = 0; i < numPoints; i++) { - positions[i * 3] = i; - positions[i * 3 + 1] = Math.sin(i / 2) * 20; - positions[i * 3 + 2] = 0; - } - - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - object = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0xffff00 })); - object.position.set(-50, 0, -200); - scene1.add(object); - - // --------------------------------------------------------------------- - // THREE.Line Loop - // --------------------------------------------------------------------- - geometry = new THREE.BufferGeometry(); - numPoints = 5; - const radius = 70; - positions = new Float32Array(numPoints * 3); - - for (let i = 0; i < numPoints; i++) { - const s = (i * Math.PI * 2) / numPoints; - positions[i * 3] = radius * Math.sin(s); - positions[i * 3 + 1] = radius * Math.cos(s); - positions[i * 3 + 2] = 0; - } - - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - object = new THREE.LineLoop(geometry, new THREE.LineBasicMaterial({ color: 0xffff00 })); - object.position.set(0, 0, -200); - - scene1.add(object); - - // --------------------------------------------------------------------- - // THREE.Points - // --------------------------------------------------------------------- - numPoints = 100; - const pointsArray = new Float32Array(numPoints * 3); - for (let i = 0; i < numPoints; i++) { - pointsArray[3 * i] = -50 + Math.random() * 100; - pointsArray[3 * i + 1] = Math.random() * 100; - pointsArray[3 * i + 2] = -50 + Math.random() * 100; - } - - const pointsGeo = new THREE.BufferGeometry(); - pointsGeo.setAttribute('position', new THREE.BufferAttribute(pointsArray, 3)); - - const pointsMaterial = new THREE.PointsMaterial({ color: 0xffff00, size: 5 }); - const pointCloud = new THREE.Points(pointsGeo, pointsMaterial); - pointCloud.name = 'Points'; - pointCloud.position.set(-200, 0, -200); - scene1.add(pointCloud); - - // --------------------------------------------------------------------- - // Ortho camera - // --------------------------------------------------------------------- - - const height = 1000; // frustum height - const aspect = window.innerWidth / window.innerHeight; - - const cameraOrtho = new THREE.OrthographicCamera(-height * aspect, height * aspect, height, -height, 0, 2000); - cameraOrtho.position.set(600, 400, 0); - cameraOrtho.lookAt(0, 0, 0); - scene1.add(cameraOrtho); - cameraOrtho.name = 'OrthographicCamera'; - - material = new THREE.MeshLambertMaterial({ - color: 0xffff00, - side: THREE.DoubleSide, - }); - - object = new THREE.Mesh(new THREE.CircleGeometry(50, 20, 0, Math.PI * 2), material); - object.position.set(200, 0, -400); - scene1.add(object); - - object = new THREE.Mesh(new THREE.RingGeometry(10, 50, 20, 5, 0, Math.PI * 2), material); - object.position.set(0, 0, -400); - scene1.add(object); - - object = new THREE.Mesh(new THREE.CylinderGeometry(25, 75, 100, 40, 5), material); - object.position.set(-200, 0, -400); - scene1.add(object); - - // - const points = []; - - for (let i = 0; i < 50; i++) { - points.push(new THREE.Vector2(Math.sin(i * 0.2) * Math.sin(i * 0.1) * 15 + 50, (i - 5) * 2)); - } - - object = new THREE.Mesh(new THREE.LatheGeometry(points, 20), material); - object.position.set(200, 0, 400); - scene1.add(object); - - // --------------------------------------------------------------------- - // Big red box hidden just for testing `onlyVisible` option - // --------------------------------------------------------------------- - material = new THREE.MeshBasicMaterial({ - color: 0xff0000, - }); - object = new THREE.Mesh(new THREE.BoxGeometry(200, 200, 200), material); - object.position.set(0, 0, 0); - object.name = 'CubeHidden'; - object.visible = false; - scene1.add(object); - - // --------------------------------------------------------------------- - // Model requiring KHR_mesh_quantization - // --------------------------------------------------------------------- - const loader = new GLTFLoader(); - loader.load('models/gltf/ShaderBall.glb', function (gltf) { - model = gltf.scene; - model.scale.setScalar(50); - model.position.set(200, -40, -200); - scene1.add(model); - }); - - // --------------------------------------------------------------------- - // Model requiring KHR_mesh_quantization - // --------------------------------------------------------------------- - - material = new THREE.MeshBasicMaterial({ - color: 0xffffff, - }); - object = new THREE.InstancedMesh(new THREE.BoxGeometry(10, 10, 10, 2, 2, 2), material, 50); - const matrix = new THREE.Matrix4(); - const color = new THREE.Color(); - for (let i = 0; i < 50; i++) { - matrix.setPosition(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50); - object.setMatrixAt(i, matrix); - object.setColorAt(i, color.setHSL(i / 50, 1, 0.5)); - } - - object.position.set(400, 0, 200); - scene1.add(object); - - // --------------------------------------------------------------------- - // 2nd THREE.Scene - // --------------------------------------------------------------------- - scene2 = new THREE.Scene(); - object = new THREE.Mesh(new THREE.BoxGeometry(100, 100, 100), material); - object.position.set(0, 0, 0); - object.name = 'Cube2ndScene'; - scene2.name = 'Scene2'; - scene2.add(object); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - - container.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); - - // --------------------------------------------------------------------- - // Exporting compressed textures and meshes (KTX2 / Draco / Meshopt) - // --------------------------------------------------------------------- - const ktx2Loader = new KTX2Loader().setTranscoderPath('jsm/libs/basis/').detectSupport(renderer); - - const gltfLoader = new GLTFLoader().setPath('models/gltf/'); - gltfLoader.setKTX2Loader(ktx2Loader); - gltfLoader.setMeshoptDecoder(MeshoptDecoder); - gltfLoader.load('coffeemat.glb', function (gltf) { - gltf.scene.position.x = 400; - gltf.scene.position.z = -200; - - scene1.add(gltf.scene); - - coffeemat = gltf.scene; - }); - - // - - const gui = new GUI(); - - let h = gui.addFolder('Settings'); - h.add(params, 'trs').name('Use TRS'); - h.add(params, 'onlyVisible').name('Only Visible Objects'); - h.add(params, 'binary').name('Binary (GLB)'); - h.add(params, 'maxTextureSize', 2, 8192).name('Max Texture Size').step(1); - - h = gui.addFolder('Export'); - h.add(params, 'exportScene1').name('Export Scene 1'); - h.add(params, 'exportScenes').name('Export Scene 1 and 2'); - h.add(params, 'exportSphere').name('Export Sphere'); - h.add(params, 'exportModel').name('Export Model'); - h.add(params, 'exportObjects').name('Export Sphere With Grid'); - h.add(params, 'exportSceneObject').name('Export Scene 1 and Object'); - h.add(params, 'exportCompressedObject').name('Export Coffeemat (from compressed data)'); - - gui.open(); -} - -function exportScene1() { - exportGLTF(scene1); -} - -function exportScenes() { - exportGLTF([scene1, scene2]); -} - -function exportSphere() { - exportGLTF(sphere); -} - -function exportModel() { - exportGLTF(model); -} - -function exportObjects() { - exportGLTF([sphere, gridHelper]); -} - -function exportSceneObject() { - exportGLTF([scene1, gridHelper]); -} - -function exportCompressedObject() { - exportGLTF([coffeemat]); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const timer = Date.now() * 0.0001; - - camera.position.x = Math.cos(timer) * 800; - camera.position.z = Math.sin(timer) * 800; - - camera.lookAt(scene1.position); - renderer.render(scene1, camera); -} diff --git a/examples-testing/examples/misc_exporter_obj.ts b/examples-testing/examples/misc_exporter_obj.ts deleted file mode 100644 index 025034daf..000000000 --- a/examples-testing/examples/misc_exporter_obj.ts +++ /dev/null @@ -1,192 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OBJExporter } from 'three/addons/exporters/OBJExporter.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -const params = { - addTriangle: addTriangle, - addCube: addCube, - addCylinder: addCylinder, - addMultiple: addMultiple, - addTransformed: addTransformed, - addPoints: addPoints, - exportToObj: exportToObj, -}; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 400); - - scene = new THREE.Scene(); - - const ambientLight = new THREE.AmbientLight(0xffffff); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5); - directionalLight.position.set(0, 1, 1); - scene.add(directionalLight); - - const gui = new GUI(); - - let h = gui.addFolder('Geometry Selection'); - h.add(params, 'addTriangle').name('Triangle'); - h.add(params, 'addCube').name('Cube'); - h.add(params, 'addCylinder').name('Cylinder'); - h.add(params, 'addMultiple').name('Multiple objects'); - h.add(params, 'addTransformed').name('Transformed objects'); - h.add(params, 'addPoints').name('Point Cloud'); - - h = gui.addFolder('Export'); - h.add(params, 'exportToObj').name('Export OBJ'); - - gui.open(); - - addGeometry(1); - - window.addEventListener('resize', onWindowResize); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enablePan = false; -} - -function exportToObj() { - const exporter = new OBJExporter(); - const result = exporter.parse(scene); - saveString(result, 'object.obj'); -} - -function addGeometry(type) { - for (let i = 0; i < scene.children.length; i++) { - const child = scene.children[i]; - - if (child.isMesh || child.isPoints) { - child.geometry.dispose(); - scene.remove(child); - i--; - } - } - - if (type === 1) { - const material = new THREE.MeshLambertMaterial({ color: 0x00cc00 }); - const geometry = generateTriangleGeometry(); - - scene.add(new THREE.Mesh(geometry, material)); - } else if (type === 2) { - const material = new THREE.MeshLambertMaterial({ color: 0x00cc00 }); - const geometry = new THREE.BoxGeometry(100, 100, 100); - scene.add(new THREE.Mesh(geometry, material)); - } else if (type === 3) { - const material = new THREE.MeshLambertMaterial({ color: 0x00cc00 }); - const geometry = new THREE.CylinderGeometry(50, 50, 100, 30, 1); - scene.add(new THREE.Mesh(geometry, material)); - } else if (type === 4 || type === 5) { - const material = new THREE.MeshLambertMaterial({ color: 0x00cc00 }); - const geometry = generateTriangleGeometry(); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = -200; - scene.add(mesh); - - const geometry2 = new THREE.BoxGeometry(100, 100, 100); - const mesh2 = new THREE.Mesh(geometry2, material); - scene.add(mesh2); - - const geometry3 = new THREE.CylinderGeometry(50, 50, 100, 30, 1); - const mesh3 = new THREE.Mesh(geometry3, material); - mesh3.position.x = 200; - scene.add(mesh3); - - if (type === 5) { - mesh.rotation.y = Math.PI / 4.0; - mesh2.rotation.y = Math.PI / 4.0; - mesh3.rotation.y = Math.PI / 4.0; - } - } else if (type === 6) { - const points = [0, 0, 0, 100, 0, 0, 100, 100, 0, 0, 100, 0]; - const colors = [0.5, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0.5, 0]; - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', new THREE.Float32BufferAttribute(points, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - const material = new THREE.PointsMaterial({ size: 10, vertexColors: true }); - - const pointCloud = new THREE.Points(geometry, material); - pointCloud.name = 'point cloud'; - scene.add(pointCloud); - } -} - -function addTriangle() { - addGeometry(1); -} - -function addCube() { - addGeometry(2); -} - -function addCylinder() { - addGeometry(3); -} - -function addMultiple() { - addGeometry(4); -} - -function addTransformed() { - addGeometry(5); -} - -function addPoints() { - addGeometry(6); -} - -const link = document.createElement('a'); -link.style.display = 'none'; -document.body.appendChild(link); - -function save(blob, filename) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); -} - -function saveString(text, filename) { - save(new Blob([text], { type: 'text/plain' }), filename); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} - -function generateTriangleGeometry() { - const geometry = new THREE.BufferGeometry(); - const vertices = []; - - vertices.push(-50, -50, 0); - vertices.push(50, -50, 0); - vertices.push(50, 50, 0); - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry.computeVertexNormals(); - - return geometry; -} diff --git a/examples-testing/examples/misc_exporter_ply.ts b/examples-testing/examples/misc_exporter_ply.ts deleted file mode 100644 index b7e324688..000000000 --- a/examples-testing/examples/misc_exporter_ply.ts +++ /dev/null @@ -1,156 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { PLYExporter } from 'three/addons/exporters/PLYExporter.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, camera, renderer, exporter, mesh; - -const params = { - exportASCII: exportASCII, - exportBinaryBigEndian: exportBinaryBigEndian, - exportBinaryLittleEndian: exportBinaryLittleEndian, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(4, 2, 4); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 4, 20); - - exporter = new PLYExporter(); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 3); - hemiLight.position.set(0, 20, 0); - scene.add(hemiLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 3); - directionalLight.position.set(0, 20, 10); - directionalLight.castShadow = true; - directionalLight.shadow.camera.top = 2; - directionalLight.shadow.camera.bottom = -2; - directionalLight.shadow.camera.left = -2; - directionalLight.shadow.camera.right = 2; - scene.add(directionalLight); - - // ground - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(40, 40), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }), - ); - ground.rotation.x = -Math.PI / 2; - ground.receiveShadow = true; - scene.add(ground); - - const grid = new THREE.GridHelper(40, 20, 0x000000, 0x000000); - grid.material.opacity = 0.2; - grid.material.transparent = true; - scene.add(grid); - - // export mesh - - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshPhongMaterial({ vertexColors: true }); - - // color vertices based on vertex positions - const colors = geometry.getAttribute('position').array.slice(); - for (let i = 0, l = colors.length; i < l; i++) { - if (colors[i] > 0) colors[i] = 0.5; - else colors[i] = 0; - } - - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3, false)); - - mesh = new THREE.Mesh(geometry, material); - mesh.castShadow = true; - mesh.position.y = 0.5; - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0.5, 0); - controls.update(); - - // - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'exportASCII').name('Export PLY (ASCII)'); - gui.add(params, 'exportBinaryBigEndian').name('Export PLY (Binary BE)'); - gui.add(params, 'exportBinaryLittleEndian').name('Export PLY (Binary LE)'); - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} - -function exportASCII() { - exporter.parse(mesh, function (result) { - saveString(result, 'box.ply'); - }); -} - -function exportBinaryBigEndian() { - exporter.parse( - mesh, - function (result) { - saveArrayBuffer(result, 'box.ply'); - }, - { binary: true }, - ); -} - -function exportBinaryLittleEndian() { - exporter.parse( - mesh, - function (result) { - saveArrayBuffer(result, 'box.ply'); - }, - { binary: true, littleEndian: true }, - ); -} - -const link = document.createElement('a'); -link.style.display = 'none'; -document.body.appendChild(link); - -function save(blob, filename) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); -} - -function saveString(text, filename) { - save(new Blob([text], { type: 'text/plain' }), filename); -} - -function saveArrayBuffer(buffer, filename) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); -} diff --git a/examples-testing/examples/misc_exporter_stl.ts b/examples-testing/examples/misc_exporter_stl.ts deleted file mode 100644 index ff6d6e2b5..000000000 --- a/examples-testing/examples/misc_exporter_stl.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { STLExporter } from 'three/addons/exporters/STLExporter.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, camera, renderer, exporter, mesh; - -const params = { - exportASCII: exportASCII, - exportBinary: exportBinary, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(4, 2, 4); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 4, 20); - - exporter = new STLExporter(); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 3); - hemiLight.position.set(0, 20, 0); - scene.add(hemiLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 3); - directionalLight.position.set(0, 20, 10); - directionalLight.castShadow = true; - directionalLight.shadow.camera.top = 2; - directionalLight.shadow.camera.bottom = -2; - directionalLight.shadow.camera.left = -2; - directionalLight.shadow.camera.right = 2; - scene.add(directionalLight); - - // ground - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(40, 40), - new THREE.MeshPhongMaterial({ color: 0xbbbbbb, depthWrite: false }), - ); - ground.rotation.x = -Math.PI / 2; - ground.receiveShadow = true; - scene.add(ground); - - const grid = new THREE.GridHelper(40, 20, 0x000000, 0x000000); - grid.material.opacity = 0.2; - grid.material.transparent = true; - scene.add(grid); - - // export mesh - - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshPhongMaterial({ color: 0x00ff00 }); - - mesh = new THREE.Mesh(geometry, material); - mesh.castShadow = true; - mesh.position.y = 0.5; - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0.5, 0); - controls.update(); - - // - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'exportASCII').name('Export STL (ASCII)'); - gui.add(params, 'exportBinary').name('Export STL (Binary)'); - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} - -function exportASCII() { - const result = exporter.parse(mesh); - saveString(result, 'box.stl'); -} - -function exportBinary() { - const result = exporter.parse(mesh, { binary: true }); - saveArrayBuffer(result, 'box.stl'); -} - -const link = document.createElement('a'); -link.style.display = 'none'; -document.body.appendChild(link); - -function save(blob, filename) { - link.href = URL.createObjectURL(blob); - link.download = filename; - link.click(); -} - -function saveString(text, filename) { - save(new Blob([text], { type: 'text/plain' }), filename); -} - -function saveArrayBuffer(buffer, filename) { - save(new Blob([buffer], { type: 'application/octet-stream' }), filename); -} diff --git a/examples-testing/examples/misc_exporter_usdz.ts b/examples-testing/examples/misc_exporter_usdz.ts deleted file mode 100644 index 9a14919ba..000000000 --- a/examples-testing/examples/misc_exporter_usdz.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { USDZExporter } from 'three/addons/exporters/USDZExporter.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -const params = { - exportUSDZ: exportUSDZ, -}; - -init(); -render(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-2.5, 0.6, 3.0); - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture; - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', async function (gltf) { - scene.add(gltf.scene); - - const shadowMesh = createSpotShadowMesh(); - shadowMesh.position.y = -1.1; - shadowMesh.position.z = -0.25; - shadowMesh.scale.setScalar(2); - scene.add(shadowMesh); - - render(); - - // USDZ - - const exporter = new USDZExporter(); - const arraybuffer = await exporter.parseAsync(gltf.scene); - const blob = new Blob([arraybuffer], { type: 'application/octet-stream' }); - - const link = document.getElementById('link'); - link.href = URL.createObjectURL(blob); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 2; - controls.maxDistance = 10; - controls.target.set(0, -0.15, -0.2); - controls.update(); - - window.addEventListener('resize', onWindowResize); - - const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); - - if (isIOS === false) { - const gui = new GUI(); - - gui.add(params, 'exportUSDZ').name('Export USDZ'); - gui.open(); - } -} - -function createSpotShadowMesh() { - const canvas = document.createElement('canvas'); - canvas.width = 128; - canvas.height = 128; - - const context = canvas.getContext('2d'); - const gradient = context.createRadialGradient( - canvas.width / 2, - canvas.height / 2, - 0, - canvas.width / 2, - canvas.height / 2, - canvas.width / 2, - ); - gradient.addColorStop(0.1, 'rgba(130,130,130,1)'); - gradient.addColorStop(1, 'rgba(255,255,255,1)'); - - context.fillStyle = gradient; - context.fillRect(0, 0, canvas.width, canvas.height); - - const shadowTexture = new THREE.CanvasTexture(canvas); - - const geometry = new THREE.PlaneGeometry(); - const material = new THREE.MeshBasicMaterial({ - map: shadowTexture, - blending: THREE.MultiplyBlending, - toneMapped: false, - }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.rotation.x = -Math.PI / 2; - - return mesh; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function exportUSDZ() { - const link = document.getElementById('link'); - link.click(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_lookat.ts b/examples-testing/examples/misc_lookat.ts deleted file mode 100644 index 280b6e2d8..000000000 --- a/examples-testing/examples/misc_lookat.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; - -let sphere; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -document.addEventListener('mousemove', onDocumentMouseMove); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 15000); - camera.position.z = 3200; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - sphere = new THREE.Mesh(new THREE.SphereGeometry(100, 20, 20), new THREE.MeshNormalMaterial()); - scene.add(sphere); - - const geometry = new THREE.CylinderGeometry(0, 10, 100, 12); - geometry.rotateX(Math.PI / 2); - - const material = new THREE.MeshNormalMaterial(); - - for (let i = 0; i < 1000; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 4000 - 2000; - mesh.position.y = Math.random() * 4000 - 2000; - mesh.position.z = Math.random() * 4000 - 2000; - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 4 + 2; - scene.add(mesh); - } - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouseX = (event.clientX - windowHalfX) * 10; - mouseY = (event.clientY - windowHalfY) * 10; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.0005; - - sphere.position.x = Math.sin(time * 0.7) * 2000; - sphere.position.y = Math.cos(time * 0.5) * 2000; - sphere.position.z = Math.cos(time * 0.3) * 2000; - - for (let i = 1, l = scene.children.length; i < l; i++) { - scene.children[i].lookAt(sphere.position); - } - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - camera.lookAt(scene.position); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/misc_uv_tests.ts b/examples-testing/examples/misc_uv_tests.ts deleted file mode 100644 index 4f782d45f..000000000 --- a/examples-testing/examples/misc_uv_tests.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as THREE from 'three'; - -import { UVsDebug } from 'three/addons/utils/UVsDebug.js'; - -/* - * This is to help debug UVs problems in geometry, - * as well as allow a new user to visualize what UVs are about. - */ - -function test(name, geometry) { - const d = document.createElement('div'); - - d.innerHTML = '

' + name + '

'; - - d.appendChild(UVsDebug(geometry)); - - document.body.appendChild(d); -} - -const points = []; - -for (let i = 0; i < 10; i++) { - points.push(new THREE.Vector2(Math.sin(i * 0.2) * 15 + 50, (i - 5) * 2)); -} - -// - -test('new THREE.PlaneGeometry( 100, 100, 4, 4 )', new THREE.PlaneGeometry(100, 100, 4, 4)); - -test('new THREE.SphereGeometry( 75, 12, 6 )', new THREE.SphereGeometry(75, 12, 6)); - -test('new THREE.IcosahedronGeometry( 30, 1 )', new THREE.IcosahedronGeometry(30, 1)); - -test('new THREE.OctahedronGeometry( 30, 2 )', new THREE.OctahedronGeometry(30, 2)); - -test('new THREE.CylinderGeometry( 25, 75, 100, 10, 5 )', new THREE.CylinderGeometry(25, 75, 100, 10, 5)); - -test('new THREE.BoxGeometry( 100, 100, 100, 4, 4, 4 )', new THREE.BoxGeometry(100, 100, 100, 4, 4, 4)); - -test('new THREE.LatheGeometry( points, 8 )', new THREE.LatheGeometry(points, 8)); - -test('new THREE.TorusGeometry( 50, 20, 8, 8 )', new THREE.TorusGeometry(50, 20, 8, 8)); - -test('new THREE.TorusKnotGeometry( 50, 10, 12, 6 )', new THREE.TorusKnotGeometry(50, 10, 12, 6)); diff --git a/examples-testing/examples/physics_ammo_instancing.ts b/examples-testing/examples/physics_ammo_instancing.ts deleted file mode 100644 index 265c254c8..000000000 --- a/examples-testing/examples/physics_ammo_instancing.ts +++ /dev/null @@ -1,119 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { AmmoPhysics } from 'three/addons/physics/AmmoPhysics.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; -let physics, position; - -let boxes, spheres; - -init(); - -async function init() { - physics = await AmmoPhysics(); - position = new THREE.Vector3(); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(-1, 1.5, 2); - camera.lookAt(0, 0.5, 0); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x666666); - - const hemiLight = new THREE.HemisphereLight(); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(5, 5, 5); - dirLight.castShadow = true; - dirLight.shadow.camera.zoom = 2; - scene.add(dirLight); - - const floor = new THREE.Mesh(new THREE.BoxGeometry(10, 5, 10), new THREE.ShadowMaterial({ color: 0x444444 })); - floor.position.y = -2.5; - floor.receiveShadow = true; - floor.userData.physics = { mass: 0 }; - scene.add(floor); - - // - - const material = new THREE.MeshLambertMaterial(); - - const matrix = new THREE.Matrix4(); - const color = new THREE.Color(); - - // Boxes - - const geometryBox = new THREE.BoxGeometry(0.075, 0.075, 0.075); - boxes = new THREE.InstancedMesh(geometryBox, material, 400); - boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - boxes.castShadow = true; - boxes.receiveShadow = true; - boxes.userData.physics = { mass: 1 }; - scene.add(boxes); - - for (let i = 0; i < boxes.count; i++) { - matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); - boxes.setMatrixAt(i, matrix); - boxes.setColorAt(i, color.setHex(0xffffff * Math.random())); - } - - // Spheres - - const geometrySphere = new THREE.IcosahedronGeometry(0.05, 4); - spheres = new THREE.InstancedMesh(geometrySphere, material, 400); - spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - spheres.castShadow = true; - spheres.receiveShadow = true; - spheres.userData.physics = { mass: 1 }; - scene.add(spheres); - - for (let i = 0; i < spheres.count; i++) { - matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); - spheres.setMatrixAt(i, matrix); - spheres.setColorAt(i, color.setHex(0xffffff * Math.random())); - } - - physics.addScene(scene); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.y = 0.5; - controls.update(); - - setInterval(() => { - let index = Math.floor(Math.random() * boxes.count); - - position.set(0, Math.random() + 1, 0); - physics.setMeshPosition(boxes, position, index); - - // - - index = Math.floor(Math.random() * spheres.count); - - position.set(0, Math.random() + 1, 0); - physics.setMeshPosition(spheres, position, index); - }, 1000 / 60); -} - -function animate() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/physics_jolt_instancing.ts b/examples-testing/examples/physics_jolt_instancing.ts deleted file mode 100644 index 022263c0d..000000000 --- a/examples-testing/examples/physics_jolt_instancing.ts +++ /dev/null @@ -1,119 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { JoltPhysics } from 'three/addons/physics/JoltPhysics.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; -let physics, position; - -let boxes, spheres; - -init(); - -async function init() { - physics = await JoltPhysics(); - position = new THREE.Vector3(); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(-1, 1.5, 2); - camera.lookAt(0, 0.5, 0); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x666666); - - const hemiLight = new THREE.HemisphereLight(); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(5, 5, 5); - dirLight.castShadow = true; - dirLight.shadow.camera.zoom = 2; - scene.add(dirLight); - - const floor = new THREE.Mesh(new THREE.BoxGeometry(10, 5, 10), new THREE.ShadowMaterial({ color: 0x444444 })); - floor.position.y = -2.5; - floor.receiveShadow = true; - floor.userData.physics = { mass: 0 }; - scene.add(floor); - - // - - const material = new THREE.MeshLambertMaterial(); - - const matrix = new THREE.Matrix4(); - const color = new THREE.Color(); - - // Boxes - - const geometryBox = new THREE.BoxGeometry(0.075, 0.075, 0.075); - boxes = new THREE.InstancedMesh(geometryBox, material, 400); - boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - boxes.castShadow = true; - boxes.receiveShadow = true; - boxes.userData.physics = { mass: 1 }; - scene.add(boxes); - - for (let i = 0; i < boxes.count; i++) { - matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); - boxes.setMatrixAt(i, matrix); - boxes.setColorAt(i, color.setHex(0xffffff * Math.random())); - } - - // Spheres - - const geometrySphere = new THREE.IcosahedronGeometry(0.05, 4); - spheres = new THREE.InstancedMesh(geometrySphere, material, 400); - spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - spheres.castShadow = true; - spheres.receiveShadow = true; - spheres.userData.physics = { mass: 1 }; - scene.add(spheres); - - for (let i = 0; i < spheres.count; i++) { - matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); - spheres.setMatrixAt(i, matrix); - spheres.setColorAt(i, color.setHex(0xffffff * Math.random())); - } - - physics.addScene(scene); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.y = 0.5; - controls.update(); - - setInterval(() => { - let index = Math.floor(Math.random() * boxes.count); - - position.set(0, Math.random() + 1, 0); - physics.setMeshPosition(boxes, position, index); - - // - - index = Math.floor(Math.random() * spheres.count); - - position.set(0, Math.random() + 1, 0); - physics.setMeshPosition(spheres, position, index); - }, 1000 / 60); -} - -function animate() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/physics_rapier_instancing.ts b/examples-testing/examples/physics_rapier_instancing.ts deleted file mode 100644 index f23cf7667..000000000 --- a/examples-testing/examples/physics_rapier_instancing.ts +++ /dev/null @@ -1,119 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RapierPhysics } from 'three/addons/physics/RapierPhysics.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; -let physics, position; - -let boxes, spheres; - -init(); - -async function init() { - physics = await RapierPhysics(); - position = new THREE.Vector3(); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(-1, 1.5, 2); - camera.lookAt(0, 0.5, 0); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x666666); - - const hemiLight = new THREE.HemisphereLight(); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(5, 5, 5); - dirLight.castShadow = true; - dirLight.shadow.camera.zoom = 2; - scene.add(dirLight); - - const floor = new THREE.Mesh(new THREE.BoxGeometry(10, 5, 10), new THREE.ShadowMaterial({ color: 0x444444 })); - floor.position.y = -2.5; - floor.receiveShadow = true; - floor.userData.physics = { mass: 0 }; - scene.add(floor); - - // - - const material = new THREE.MeshLambertMaterial(); - - const matrix = new THREE.Matrix4(); - const color = new THREE.Color(); - - // Boxes - - const geometryBox = new THREE.BoxGeometry(0.075, 0.075, 0.075); - boxes = new THREE.InstancedMesh(geometryBox, material, 400); - boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - boxes.castShadow = true; - boxes.receiveShadow = true; - boxes.userData.physics = { mass: 1 }; - scene.add(boxes); - - for (let i = 0; i < boxes.count; i++) { - matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); - boxes.setMatrixAt(i, matrix); - boxes.setColorAt(i, color.setHex(0xffffff * Math.random())); - } - - // Spheres - - const geometrySphere = new THREE.IcosahedronGeometry(0.05, 4); - spheres = new THREE.InstancedMesh(geometrySphere, material, 400); - spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - spheres.castShadow = true; - spheres.receiveShadow = true; - spheres.userData.physics = { mass: 1 }; - scene.add(spheres); - - for (let i = 0; i < spheres.count; i++) { - matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5); - spheres.setMatrixAt(i, matrix); - spheres.setColorAt(i, color.setHex(0xffffff * Math.random())); - } - - physics.addScene(scene); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.y = 0.5; - controls.update(); - - setInterval(() => { - let index = Math.floor(Math.random() * boxes.count); - - position.set(0, Math.random() + 1, 0); - physics.setMeshPosition(boxes, position, index); - - // - - index = Math.floor(Math.random() * spheres.count); - - position.set(0, Math.random() + 1, 0); - physics.setMeshPosition(spheres, position, index); - }, 1000 / 60); -} - -function animate() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/svg_lines.ts b/examples-testing/examples/svg_lines.ts deleted file mode 100644 index 99b74c405..000000000 --- a/examples-testing/examples/svg_lines.ts +++ /dev/null @@ -1,87 +0,0 @@ -import * as THREE from 'three'; - -import { SVGRenderer } from 'three/addons/renderers/SVGRenderer.js'; - -THREE.ColorManagement.enabled = false; - -let camera, scene, renderer; - -init(); -animate(); - -function init() { - camera = new THREE.PerspectiveCamera(33, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 10; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0, 0, 0); - - renderer = new SVGRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // - - const vertices = []; - const divisions = 50; - - for (let i = 0; i <= divisions; i++) { - const v = (i / divisions) * (Math.PI * 2); - - const x = Math.sin(v); - const z = Math.cos(v); - - vertices.push(x, 0, z); - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - - // - - for (let i = 1; i <= 3; i++) { - const material = new THREE.LineBasicMaterial({ - color: Math.random() * 0xffffff, - linewidth: 10, - }); - const line = new THREE.Line(geometry, material); - line.scale.setScalar(i / 3); - scene.add(line); - } - - const material = new THREE.LineDashedMaterial({ - color: 'blue', - linewidth: 1, - dashSize: 10, - gapSize: 10, - }); - const line = new THREE.Line(geometry, material); - line.scale.setScalar(2); - scene.add(line); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - let count = 0; - const time = performance.now() / 1000; - - scene.traverse(function (child) { - child.rotation.x = count + time / 3; - child.rotation.z = count + time / 4; - - count++; - }); - - renderer.render(scene, camera); - requestAnimationFrame(animate); -} diff --git a/examples-testing/examples/svg_sandbox.ts b/examples-testing/examples/svg_sandbox.ts deleted file mode 100644 index e6be8386c..000000000 --- a/examples-testing/examples/svg_sandbox.ts +++ /dev/null @@ -1,212 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { SVGRenderer, SVGObject } from 'three/addons/renderers/SVGRenderer.js'; - -THREE.ColorManagement.enabled = false; - -let camera, scene, renderer, stats; - -let group; - -init(); -animate(); - -function init() { - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 500; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - // QRCODE - - const loader = new THREE.BufferGeometryLoader(); - loader.load('models/json/QRCode_buffergeometry.json', function (geometry) { - mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ vertexColors: true })); - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; - scene.add(mesh); - }); - - // CUBES - - const boxGeometry = new THREE.BoxGeometry(100, 100, 100); - - let mesh = new THREE.Mesh( - boxGeometry, - new THREE.MeshBasicMaterial({ color: 0x0000ff, opacity: 0.5, transparent: true }), - ); - mesh.position.x = 500; - mesh.rotation.x = Math.random(); - mesh.rotation.y = Math.random(); - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; - scene.add(mesh); - - mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff })); - mesh.position.x = 500; - mesh.position.y = 500; - mesh.rotation.x = Math.random(); - mesh.rotation.y = Math.random(); - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; - scene.add(mesh); - - // PLANE - - mesh = new THREE.Mesh( - new THREE.PlaneGeometry(100, 100), - new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, side: THREE.DoubleSide }), - ); - mesh.position.y = -500; - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; - scene.add(mesh); - - // CYLINDER - - mesh = new THREE.Mesh( - new THREE.CylinderGeometry(20, 100, 200, 10), - new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff }), - ); - mesh.position.x = -500; - mesh.rotation.x = -Math.PI / 2; - mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; - scene.add(mesh); - - // POLYFIELD - - const geometry = new THREE.BufferGeometry(); - const material = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide }); - - const v = new THREE.Vector3(); - const v0 = new THREE.Vector3(); - const v1 = new THREE.Vector3(); - const v2 = new THREE.Vector3(); - const color = new THREE.Color(); - - const vertices = []; - const colors = []; - - for (let i = 0; i < 100; i++) { - v.set(Math.random() * 1000 - 500, Math.random() * 1000 - 500, Math.random() * 1000 - 500); - - v0.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50); - - v1.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50); - - v2.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50); - - v0.add(v); - v1.add(v); - v2.add(v); - - color.setHex(Math.random() * 0xffffff); - - // create a single triangle - - vertices.push(v0.x, v0.y, v0.z); - vertices.push(v1.x, v1.y, v1.z); - vertices.push(v2.x, v2.y, v2.z); - - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - group = new THREE.Mesh(geometry, material); - group.scale.set(2, 2, 2); - scene.add(group); - - // SPRITES - - for (let i = 0; i < 50; i++) { - const material = new THREE.SpriteMaterial({ color: Math.random() * 0xffffff }); - const sprite = new THREE.Sprite(material); - sprite.position.x = Math.random() * 1000 - 500; - sprite.position.y = Math.random() * 1000 - 500; - sprite.position.z = Math.random() * 1000 - 500; - sprite.scale.set(64, 64, 1); - scene.add(sprite); - } - - // CUSTOM - - const node = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); - node.setAttribute('stroke', 'black'); - node.setAttribute('fill', 'red'); - node.setAttribute('r', '40'); - - for (let i = 0; i < 50; i++) { - const object = new SVGObject(node.cloneNode()); - object.position.x = Math.random() * 1000 - 500; - object.position.y = Math.random() * 1000 - 500; - object.position.z = Math.random() * 1000 - 500; - scene.add(object); - } - - // CUSTOM FROM FILE - - const fileLoader = new THREE.FileLoader(); - fileLoader.load('models/svg/hexagon.svg', function (svg) { - const node = document.createElementNS('http://www.w3.org/2000/svg', 'g'); - const parser = new DOMParser(); - const doc = parser.parseFromString(svg, 'image/svg+xml'); - - node.appendChild(doc.documentElement); - - const object = new SVGObject(node); - object.position.x = 500; - scene.add(object); - }); - - // LIGHTS - - const ambient = new THREE.AmbientLight(0x80ffff); - scene.add(ambient); - - const directional = new THREE.DirectionalLight(0xffff00); - directional.position.set(-1, 0.5, 0); - scene.add(directional); - - renderer = new SVGRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setQuality('low'); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - requestAnimationFrame(animate); - - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.0002; - - camera.position.x = Math.sin(time) * 500; - camera.position.z = Math.cos(time) * 500; - camera.lookAt(scene.position); - - group.rotation.x += 0.01; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webaudio_orientation.ts b/examples-testing/examples/webaudio_orientation.ts deleted file mode 100644 index 7baaa88a0..000000000 --- a/examples-testing/examples/webaudio_orientation.ts +++ /dev/null @@ -1,141 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { PositionalAudioHelper } from 'three/addons/helpers/PositionalAudioHelper.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let scene, camera, renderer; - -const startButton = document.getElementById('startButton'); -startButton.addEventListener('click', init); - -function init() { - const overlay = document.getElementById('overlay'); - overlay.remove(); - - const container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(3, 2, 3); - - const reflectionCube = new THREE.CubeTextureLoader() - .setPath('textures/cube/SwedishRoyalCastle/') - .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 2, 20); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 3); - hemiLight.position.set(0, 20, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(5, 5, 0); - dirLight.castShadow = true; - dirLight.shadow.camera.top = 1; - dirLight.shadow.camera.bottom = -1; - dirLight.shadow.camera.left = -1; - dirLight.shadow.camera.right = 1; - dirLight.shadow.camera.near = 0.1; - dirLight.shadow.camera.far = 20; - scene.add(dirLight); - - // scene.add( new THREE.CameraHelper( dirLight.shadow.camera ) ); - - // - - const mesh = new THREE.Mesh( - new THREE.PlaneGeometry(50, 50), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }), - ); - mesh.rotation.x = -Math.PI / 2; - mesh.receiveShadow = true; - scene.add(mesh); - - const grid = new THREE.GridHelper(50, 50, 0xc1c1c1, 0xc1c1c1); - scene.add(grid); - - // - - const listener = new THREE.AudioListener(); - camera.add(listener); - - const audioElement = document.getElementById('music'); - audioElement.play(); - - const positionalAudio = new THREE.PositionalAudio(listener); - positionalAudio.setMediaElementSource(audioElement); - positionalAudio.setRefDistance(1); - positionalAudio.setDirectionalCone(180, 230, 0.1); - - const helper = new PositionalAudioHelper(positionalAudio, 0.1); - positionalAudio.add(helper); - - // - - const gltfLoader = new GLTFLoader(); - gltfLoader.load('models/gltf/BoomBox.glb', function (gltf) { - const boomBox = gltf.scene; - boomBox.position.set(0, 0.2, 0); - boomBox.scale.set(20, 20, 20); - - boomBox.traverse(function (object) { - if (object.isMesh) { - object.material.envMap = reflectionCube; - object.geometry.rotateY(-Math.PI); - object.castShadow = true; - } - }); - - boomBox.add(positionalAudio); - scene.add(boomBox); - - renderer.setAnimationLoop(animate); - }); - - // sound is damped behind this wall - - const wallGeometry = new THREE.BoxGeometry(2, 1, 0.1); - const wallMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 }); - - const wall = new THREE.Mesh(wallGeometry, wallMaterial); - wall.position.set(0, 0.5, -0.5); - scene.add(wall); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - container.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0.1, 0); - controls.update(); - controls.minDistance = 0.5; - controls.maxDistance = 10; - controls.maxPolarAngle = 0.5 * Math.PI; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webaudio_sandbox.ts b/examples-testing/examples/webaudio_sandbox.ts deleted file mode 100644 index d67d0d552..000000000 --- a/examples-testing/examples/webaudio_sandbox.ts +++ /dev/null @@ -1,222 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; - -let camera, controls, scene, renderer, light; - -let material1, material2, material3; - -let analyser1, analyser2, analyser3; - -const clock = new THREE.Clock(); - -const startButton = document.getElementById('startButton'); -startButton.addEventListener('click', init); - -function init() { - const overlay = document.getElementById('overlay'); - overlay.remove(); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(0, 25, 0); - - const listener = new THREE.AudioListener(); - camera.add(listener); - - scene = new THREE.Scene(); - scene.fog = new THREE.FogExp2(0x000000, 0.0025); - - light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 0.5, 1).normalize(); - scene.add(light); - - const sphere = new THREE.SphereGeometry(20, 32, 16); - - material1 = new THREE.MeshPhongMaterial({ color: 0xffaa00, flatShading: true, shininess: 0 }); - material2 = new THREE.MeshPhongMaterial({ color: 0xff2200, flatShading: true, shininess: 0 }); - material3 = new THREE.MeshPhongMaterial({ color: 0x6622aa, flatShading: true, shininess: 0 }); - - // sound spheres - - const mesh1 = new THREE.Mesh(sphere, material1); - mesh1.position.set(-250, 30, 0); - scene.add(mesh1); - - const sound1 = new THREE.PositionalAudio(listener); - const songElement = document.getElementById('song'); - sound1.setMediaElementSource(songElement); - sound1.setRefDistance(20); - songElement.play(); - mesh1.add(sound1); - - // - - const mesh2 = new THREE.Mesh(sphere, material2); - mesh2.position.set(250, 30, 0); - scene.add(mesh2); - - const sound2 = new THREE.PositionalAudio(listener); - const skullbeatzElement = document.getElementById('skullbeatz'); - sound2.setMediaElementSource(skullbeatzElement); - sound2.setRefDistance(20); - skullbeatzElement.play(); - mesh2.add(sound2); - - // - - const mesh3 = new THREE.Mesh(sphere, material3); - mesh3.position.set(0, 30, -250); - scene.add(mesh3); - - const sound3 = new THREE.PositionalAudio(listener); - const oscillator = listener.context.createOscillator(); - oscillator.type = 'sine'; - oscillator.frequency.setValueAtTime(144, sound3.context.currentTime); - oscillator.start(0); - sound3.setNodeSource(oscillator); - sound3.setRefDistance(20); - sound3.setVolume(0.5); - mesh3.add(sound3); - - // analysers - - analyser1 = new THREE.AudioAnalyser(sound1, 32); - analyser2 = new THREE.AudioAnalyser(sound2, 32); - analyser3 = new THREE.AudioAnalyser(sound3, 32); - - // global ambient audio - - const sound4 = new THREE.Audio(listener); - const utopiaElement = document.getElementById('utopia'); - sound4.setMediaElementSource(utopiaElement); - sound4.setVolume(0.5); - utopiaElement.play(); - - // ground - - const helper = new THREE.GridHelper(1000, 10, 0x444444, 0x444444); - helper.position.y = 0.1; - scene.add(helper); - - // - - const SoundControls = function () { - this.master = listener.getMasterVolume(); - this.firstSphere = sound1.getVolume(); - this.secondSphere = sound2.getVolume(); - this.thirdSphere = sound3.getVolume(); - this.Ambient = sound4.getVolume(); - }; - - const GeneratorControls = function () { - this.frequency = oscillator.frequency.value; - this.wavetype = oscillator.type; - }; - - const gui = new GUI(); - const soundControls = new SoundControls(); - const generatorControls = new GeneratorControls(); - const volumeFolder = gui.addFolder('sound volume'); - const generatorFolder = gui.addFolder('sound generator'); - - volumeFolder - .add(soundControls, 'master') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(function () { - listener.setMasterVolume(soundControls.master); - }); - volumeFolder - .add(soundControls, 'firstSphere') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(function () { - sound1.setVolume(soundControls.firstSphere); - }); - volumeFolder - .add(soundControls, 'secondSphere') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(function () { - sound2.setVolume(soundControls.secondSphere); - }); - - volumeFolder - .add(soundControls, 'thirdSphere') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(function () { - sound3.setVolume(soundControls.thirdSphere); - }); - volumeFolder - .add(soundControls, 'Ambient') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(function () { - sound4.setVolume(soundControls.Ambient); - }); - volumeFolder.open(); - generatorFolder - .add(generatorControls, 'frequency') - .min(50.0) - .max(5000.0) - .step(1.0) - .onChange(function () { - oscillator.frequency.setValueAtTime(generatorControls.frequency, listener.context.currentTime); - }); - generatorFolder - .add(generatorControls, 'wavetype', ['sine', 'square', 'sawtooth', 'triangle']) - .onChange(function () { - oscillator.type = generatorControls.wavetype; - }); - - generatorFolder.open(); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - controls = new FirstPersonControls(camera, renderer.domElement); - - controls.movementSpeed = 70; - controls.lookSpeed = 0.05; - controls.lookVertical = false; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - controls.handleResize(); -} - -function animate() { - const delta = clock.getDelta(); - - controls.update(delta); - - material1.emissive.b = analyser1.getAverageFrequency() / 256; - material2.emissive.b = analyser2.getAverageFrequency() / 256; - material3.emissive.b = analyser3.getAverageFrequency() / 256; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webaudio_timing.ts b/examples-testing/examples/webaudio_timing.ts deleted file mode 100644 index 9e17bcbcd..000000000 --- a/examples-testing/examples/webaudio_timing.ts +++ /dev/null @@ -1,152 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let scene, camera, renderer, clock; - -const objects = []; - -const speed = 2.5; -const height = 3; -const offset = 0.5; - -const startButton = document.getElementById('startButton'); -startButton.addEventListener('click', init); - -function init() { - const overlay = document.getElementById('overlay'); - overlay.remove(); - - const container = document.getElementById('container'); - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - // - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(7, 3, 7); - - // lights - - const ambientLight = new THREE.AmbientLight(0xcccccc); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5); - directionalLight.position.set(0, 5, 5); - scene.add(directionalLight); - - const d = 5; - directionalLight.castShadow = true; - directionalLight.shadow.camera.left = -d; - directionalLight.shadow.camera.right = d; - directionalLight.shadow.camera.top = d; - directionalLight.shadow.camera.bottom = -d; - - directionalLight.shadow.camera.near = 1; - directionalLight.shadow.camera.far = 20; - - directionalLight.shadow.mapSize.x = 1024; - directionalLight.shadow.mapSize.y = 1024; - - // audio - - const audioLoader = new THREE.AudioLoader(); - - const listener = new THREE.AudioListener(); - camera.add(listener); - - // floor - - const floorGeometry = new THREE.PlaneGeometry(10, 10); - const floorMaterial = new THREE.MeshLambertMaterial({ color: 0x4676b6 }); - - const floor = new THREE.Mesh(floorGeometry, floorMaterial); - floor.rotation.x = Math.PI * -0.5; - floor.receiveShadow = true; - scene.add(floor); - - // objects - - const count = 5; - const radius = 3; - - const ballGeometry = new THREE.SphereGeometry(0.3, 32, 16); - ballGeometry.translate(0, 0.3, 0); - const ballMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc }); - - // create objects when audio buffer is loaded - - audioLoader.load('sounds/ping_pong.mp3', function (buffer) { - for (let i = 0; i < count; i++) { - const s = (i / count) * Math.PI * 2; - - const ball = new THREE.Mesh(ballGeometry, ballMaterial); - ball.castShadow = true; - ball.userData.down = false; - - ball.position.x = radius * Math.cos(s); - ball.position.z = radius * Math.sin(s); - - const audio = new THREE.PositionalAudio(listener); - audio.setBuffer(buffer); - ball.add(audio); - - scene.add(ball); - objects.push(ball); - } - - renderer.setAnimationLoop(animate); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - container.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 25; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = clock.getElapsedTime(); - - for (let i = 0; i < objects.length; i++) { - const ball = objects[i]; - - const previousHeight = ball.position.y; - ball.position.y = Math.abs(Math.sin(i * offset + time * speed) * height); - - if (ball.position.y < previousHeight) { - ball.userData.down = true; - } else { - if (ball.userData.down === true) { - // ball changed direction from down to up - - const audio = ball.children[0]; - audio.play(); // play audio with perfect timing when ball hits the surface - ball.userData.down = false; - } - } - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webaudio_visualizer.ts b/examples-testing/examples/webaudio_visualizer.ts deleted file mode 100644 index a3f58cb36..000000000 --- a/examples-testing/examples/webaudio_visualizer.ts +++ /dev/null @@ -1,86 +0,0 @@ -import * as THREE from 'three'; - -let scene, camera, renderer, analyser, uniforms; - -const startButton = document.getElementById('startButton'); -startButton.addEventListener('click', init); - -function init() { - const fftSize = 128; - - // - - const overlay = document.getElementById('overlay'); - overlay.remove(); - - // - - const container = document.getElementById('container'); - - scene = new THREE.Scene(); - - camera = new THREE.Camera(); - - // - - const listener = new THREE.AudioListener(); - - const audio = new THREE.Audio(listener); - const file = './sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3'; - - if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent)) { - const loader = new THREE.AudioLoader(); - loader.load(file, function (buffer) { - audio.setBuffer(buffer); - audio.play(); - }); - } else { - const mediaElement = new Audio(file); - mediaElement.play(); - - audio.setMediaElementSource(mediaElement); - } - - analyser = new THREE.AudioAnalyser(audio, fftSize); - - // - - uniforms = { - tAudioData: { value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, THREE.RedFormat) }, - }; - - const material = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - }); - - const geometry = new THREE.PlaneGeometry(1, 1); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - analyser.getFrequencyData(); - - uniforms.tAudioData.value.needsUpdate = true; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_animation_keyframes.ts b/examples-testing/examples/webgl_animation_keyframes.ts deleted file mode 100644 index 88048f24c..000000000 --- a/examples-testing/examples/webgl_animation_keyframes.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -let mixer; - -const clock = new THREE.Clock(); -const container = document.getElementById('container'); - -const stats = new Stats(); -container.appendChild(stats.dom); - -const renderer = new THREE.WebGLRenderer({ antialias: true }); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -container.appendChild(renderer.domElement); - -const pmremGenerator = new THREE.PMREMGenerator(renderer); - -const scene = new THREE.Scene(); -scene.background = new THREE.Color(0xbfe3dd); -scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture; - -const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100); -camera.position.set(5, 2, 8); - -const controls = new OrbitControls(camera, renderer.domElement); -controls.target.set(0, 0.5, 0); -controls.update(); -controls.enablePan = false; -controls.enableDamping = true; - -const dracoLoader = new DRACOLoader(); -dracoLoader.setDecoderPath('jsm/libs/draco/gltf/'); - -const loader = new GLTFLoader(); -loader.setDRACOLoader(dracoLoader); -loader.load( - 'models/gltf/LittlestTokyo.glb', - function (gltf) { - const model = gltf.scene; - model.position.set(1, 1, 0); - model.scale.set(0.01, 0.01, 0.01); - scene.add(model); - - mixer = new THREE.AnimationMixer(model); - mixer.clipAction(gltf.animations[0]).play(); - - renderer.setAnimationLoop(animate); - }, - undefined, - function (e) { - console.error(e); - }, -); - -window.onresize = function () { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -}; - -function animate() { - const delta = clock.getDelta(); - - mixer.update(delta); - - controls.update(); - - stats.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_animation_multiple.ts b/examples-testing/examples/webgl_animation_multiple.ts deleted file mode 100644 index 152c65067..000000000 --- a/examples-testing/examples/webgl_animation_multiple.ts +++ /dev/null @@ -1,197 +0,0 @@ -import * as THREE from 'three'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, clock; -let model, animations; - -const mixers = [], - objects = []; - -const params = { - sharedSkeleton: false, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(2, 3, -6); - camera.lookAt(0, 1, 0); - - clock = new THREE.Clock(); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 10, 50); - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 3); - hemiLight.position.set(0, 20, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(-3, 10, -10); - dirLight.castShadow = true; - dirLight.shadow.camera.top = 4; - dirLight.shadow.camera.bottom = -4; - dirLight.shadow.camera.left = -4; - dirLight.shadow.camera.right = 4; - dirLight.shadow.camera.near = 0.1; - dirLight.shadow.camera.far = 40; - scene.add(dirLight); - - // scene.add( new THREE.CameraHelper( dirLight.shadow.camera ) ); - - // ground - - const mesh = new THREE.Mesh( - new THREE.PlaneGeometry(200, 200), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }), - ); - mesh.rotation.x = -Math.PI / 2; - mesh.receiveShadow = true; - scene.add(mesh); - - const loader = new GLTFLoader(); - loader.load('models/gltf/Soldier.glb', function (gltf) { - model = gltf.scene; - animations = gltf.animations; - - model.traverse(function (object) { - if (object.isMesh) object.castShadow = true; - }); - - setupDefaultScene(); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'sharedSkeleton').onChange(function () { - clearScene(); - - if (params.sharedSkeleton === true) { - setupSharedSkeletonScene(); - } else { - setupDefaultScene(); - } - }); - gui.open(); -} - -function clearScene() { - for (const mixer of mixers) { - mixer.stopAllAction(); - } - - mixers.length = 0; - - // - - for (const object of objects) { - scene.remove(object); - - scene.traverse(function (child) { - if (child.isSkinnedMesh) child.skeleton.dispose(); - }); - } -} - -function setupDefaultScene() { - // three cloned models with independent skeletons. - // each model can have its own animation state - - const model1 = SkeletonUtils.clone(model); - const model2 = SkeletonUtils.clone(model); - const model3 = SkeletonUtils.clone(model); - - model1.position.x = -2; - model2.position.x = 0; - model3.position.x = 2; - - const mixer1 = new THREE.AnimationMixer(model1); - const mixer2 = new THREE.AnimationMixer(model2); - const mixer3 = new THREE.AnimationMixer(model3); - - mixer1.clipAction(animations[0]).play(); // idle - mixer2.clipAction(animations[1]).play(); // run - mixer3.clipAction(animations[3]).play(); // walk - - scene.add(model1, model2, model3); - - objects.push(model1, model2, model3); - mixers.push(mixer1, mixer2, mixer3); -} - -function setupSharedSkeletonScene() { - // three cloned models with a single shared skeleton. - // all models share the same animation state - - const sharedModel = SkeletonUtils.clone(model); - const shareSkinnedMesh = sharedModel.getObjectByName('vanguard_Mesh'); - const sharedSkeleton = shareSkinnedMesh.skeleton; - const sharedParentBone = sharedModel.getObjectByName('mixamorigHips'); - scene.add(sharedParentBone); // the bones need to be in the scene for the animation to work - - const model1 = shareSkinnedMesh.clone(); - const model2 = shareSkinnedMesh.clone(); - const model3 = shareSkinnedMesh.clone(); - - model1.bindMode = THREE.DetachedBindMode; - model2.bindMode = THREE.DetachedBindMode; - model3.bindMode = THREE.DetachedBindMode; - - const identity = new THREE.Matrix4(); - - model1.bind(sharedSkeleton, identity); - model2.bind(sharedSkeleton, identity); - model3.bind(sharedSkeleton, identity); - - model1.position.x = -2; - model2.position.x = 0; - model3.position.x = 2; - - // apply transformation from the glTF asset - - model1.scale.setScalar(0.01); - model1.rotation.x = -Math.PI * 0.5; - model2.scale.setScalar(0.01); - model2.rotation.x = -Math.PI * 0.5; - model3.scale.setScalar(0.01); - model3.rotation.x = -Math.PI * 0.5; - - // - - const mixer = new THREE.AnimationMixer(sharedParentBone); - mixer.clipAction(animations[1]).play(); - - scene.add(sharedParentBone, model1, model2, model3); - - objects.push(sharedParentBone, model1, model2, model3); - mixers.push(mixer); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - for (const mixer of mixers) mixer.update(delta); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_animation_skinning_morph.ts b/examples-testing/examples/webgl_animation_skinning_morph.ts deleted file mode 100644 index f05369aa9..000000000 --- a/examples-testing/examples/webgl_animation_skinning_morph.ts +++ /dev/null @@ -1,187 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let container, stats, clock, gui, mixer, actions, activeAction, previousAction; -let camera, scene, renderer, model, face; - -const api = { state: 'Walking' }; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 100); - camera.position.set(-5, 3, 10); - camera.lookAt(0, 2, 0); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xe0e0e0); - scene.fog = new THREE.Fog(0xe0e0e0, 20, 100); - - clock = new THREE.Clock(); - - // lights - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 3); - hemiLight.position.set(0, 20, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(0, 20, 10); - scene.add(dirLight); - - // ground - - const mesh = new THREE.Mesh( - new THREE.PlaneGeometry(2000, 2000), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }), - ); - mesh.rotation.x = -Math.PI / 2; - scene.add(mesh); - - const grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000); - grid.material.opacity = 0.2; - grid.material.transparent = true; - scene.add(grid); - - // model - - const loader = new GLTFLoader(); - loader.load( - 'models/gltf/RobotExpressive/RobotExpressive.glb', - function (gltf) { - model = gltf.scene; - scene.add(model); - - createGUI(model, gltf.animations); - }, - undefined, - function (e) { - console.error(e); - }, - ); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - // stats - stats = new Stats(); - container.appendChild(stats.dom); -} - -function createGUI(model, animations) { - const states = ['Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing']; - const emotes = ['Jump', 'Yes', 'No', 'Wave', 'Punch', 'ThumbsUp']; - - gui = new GUI(); - - mixer = new THREE.AnimationMixer(model); - - actions = {}; - - for (let i = 0; i < animations.length; i++) { - const clip = animations[i]; - const action = mixer.clipAction(clip); - actions[clip.name] = action; - - if (emotes.indexOf(clip.name) >= 0 || states.indexOf(clip.name) >= 4) { - action.clampWhenFinished = true; - action.loop = THREE.LoopOnce; - } - } - - // states - - const statesFolder = gui.addFolder('States'); - - const clipCtrl = statesFolder.add(api, 'state').options(states); - - clipCtrl.onChange(function () { - fadeToAction(api.state, 0.5); - }); - - statesFolder.open(); - - // emotes - - const emoteFolder = gui.addFolder('Emotes'); - - function createEmoteCallback(name) { - api[name] = function () { - fadeToAction(name, 0.2); - - mixer.addEventListener('finished', restoreState); - }; - - emoteFolder.add(api, name); - } - - function restoreState() { - mixer.removeEventListener('finished', restoreState); - - fadeToAction(api.state, 0.2); - } - - for (let i = 0; i < emotes.length; i++) { - createEmoteCallback(emotes[i]); - } - - emoteFolder.open(); - - // expressions - - face = model.getObjectByName('Head_4'); - - const expressions = Object.keys(face.morphTargetDictionary); - const expressionFolder = gui.addFolder('Expressions'); - - for (let i = 0; i < expressions.length; i++) { - expressionFolder.add(face.morphTargetInfluences, i, 0, 1, 0.01).name(expressions[i]); - } - - activeAction = actions['Walking']; - activeAction.play(); - - expressionFolder.open(); -} - -function fadeToAction(name, duration) { - previousAction = activeAction; - activeAction = actions[name]; - - if (previousAction !== activeAction) { - previousAction.fadeOut(duration); - } - - activeAction.reset().setEffectiveTimeScale(1).setEffectiveWeight(1).fadeIn(duration).play(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const dt = clock.getDelta(); - - if (mixer) mixer.update(dt); - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry.ts b/examples-testing/examples/webgl_buffergeometry.ts deleted file mode 100644 index 28b2c96a4..000000000 --- a/examples-testing/examples/webgl_buffergeometry.ts +++ /dev/null @@ -1,178 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let mesh; - -init(); -animate(); - -function init() { - container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500); - camera.position.z = 2750; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const light1 = new THREE.DirectionalLight(0xffffff, 1.5); - light1.position.set(1, 1, 1); - scene.add(light1); - - const light2 = new THREE.DirectionalLight(0xffffff, 4.5); - light2.position.set(0, -1, 0); - scene.add(light2); - - // - - const triangles = 160000; - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const normals = []; - const colors = []; - - const color = new THREE.Color(); - - const n = 800, - n2 = n / 2; // triangles spread in the cube - const d = 12, - d2 = d / 2; // individual triangle size - - const pA = new THREE.Vector3(); - const pB = new THREE.Vector3(); - const pC = new THREE.Vector3(); - - const cb = new THREE.Vector3(); - const ab = new THREE.Vector3(); - - for (let i = 0; i < triangles; i++) { - // positions - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - const ax = x + Math.random() * d - d2; - const ay = y + Math.random() * d - d2; - const az = z + Math.random() * d - d2; - - const bx = x + Math.random() * d - d2; - const by = y + Math.random() * d - d2; - const bz = z + Math.random() * d - d2; - - const cx = x + Math.random() * d - d2; - const cy = y + Math.random() * d - d2; - const cz = z + Math.random() * d - d2; - - positions.push(ax, ay, az); - positions.push(bx, by, bz); - positions.push(cx, cy, cz); - - // flat face normals - - pA.set(ax, ay, az); - pB.set(bx, by, bz); - pC.set(cx, cy, cz); - - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - - cb.normalize(); - - const nx = cb.x; - const ny = cb.y; - const nz = cb.z; - - normals.push(nx, ny, nz); - normals.push(nx, ny, nz); - normals.push(nx, ny, nz); - - // colors - - const vx = x / n + 0.5; - const vy = y / n + 0.5; - const vz = z / n + 0.5; - - color.setRGB(vx, vy, vz); - - const alpha = Math.random(); - - colors.push(color.r, color.g, color.b, alpha); - colors.push(color.r, color.g, color.b, alpha); - colors.push(color.r, color.g, color.b, alpha); - } - - function disposeArray() { - this.array = null; - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3).onUpload(disposeArray)); - geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3).onUpload(disposeArray)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4).onUpload(disposeArray)); - - geometry.computeBoundingSphere(); - - const material = new THREE.MeshPhongMaterial({ - color: 0xd5d5d5, - specular: 0xffffff, - shininess: 250, - side: THREE.DoubleSide, - vertexColors: true, - transparent: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = Date.now() * 0.001; - - mesh.rotation.x = time * 0.25; - mesh.rotation.y = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts b/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts deleted file mode 100644 index 96926c2c3..000000000 --- a/examples-testing/examples/webgl_buffergeometry_attributes_integer.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, mesh; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500); - camera.position.z = 2500; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // geometry - - const triangles = 10000; - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const uvs = []; - const textureIndices = []; - - const n = 800, - n2 = n / 2; // triangles spread in the cube - const d = 50, - d2 = d / 2; // individual triangle size - - for (let i = 0; i < triangles; i++) { - // positions - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - const ax = x + Math.random() * d - d2; - const ay = y + Math.random() * d - d2; - const az = z + Math.random() * d - d2; - - const bx = x + Math.random() * d - d2; - const by = y + Math.random() * d - d2; - const bz = z + Math.random() * d - d2; - - const cx = x + Math.random() * d - d2; - const cy = y + Math.random() * d - d2; - const cz = z + Math.random() * d - d2; - - positions.push(ax, ay, az); - positions.push(bx, by, bz); - positions.push(cx, cy, cz); - - // uvs - - uvs.push(0, 0); - uvs.push(0.5, 1); - uvs.push(1, 0); - - // texture indices - - const t = i % 3; - textureIndices.push(t, t, t); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2)); - geometry.setAttribute('textureIndex', new THREE.Int16BufferAttribute(textureIndices, 1)); - geometry.attributes.textureIndex.gpuType = THREE.IntType; - - geometry.computeBoundingSphere(); - - // material - - const loader = new THREE.TextureLoader(); - - const map1 = loader.load('textures/crate.gif'); - const map2 = loader.load('textures/floors/FloorsCheckerboard_S_Diffuse.jpg'); - const map3 = loader.load('textures/terrain/grasslight-big.jpg'); - - const material = new THREE.ShaderMaterial({ - uniforms: { - uTextures: { - value: [map1, map2, map3], - }, - }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - side: THREE.DoubleSide, - glslVersion: THREE.GLSL3, - }); - - // mesh - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); -} - -function animate() { - const time = Date.now() * 0.001; - - mesh.rotation.x = time * 0.25; - mesh.rotation.y = time * 0.5; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_buffergeometry_attributes_none.ts b/examples-testing/examples/webgl_buffergeometry_attributes_none.ts deleted file mode 100644 index a1424e871..000000000 --- a/examples-testing/examples/webgl_buffergeometry_attributes_none.ts +++ /dev/null @@ -1,56 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, mesh; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500); - camera.position.z = 4; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // geometry - - const triangleCount = 10000; - const vertexCountPerTriangle = 3; - const vertexCount = triangleCount * vertexCountPerTriangle; - - const geometry = new THREE.BufferGeometry(); - geometry.setDrawRange(0, vertexCount); - - // material - - const material = new THREE.RawShaderMaterial({ - uniforms: { - seed: { value: 42 }, - }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - side: THREE.DoubleSide, - glslVersion: THREE.GLSL3, - }); - - // mesh - - mesh = new THREE.Mesh(geometry, material); - mesh.frustumCulled = false; - scene.add(mesh); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); -} - -function animate(time) { - mesh.rotation.x = (time / 1000.0) * 0.25; - mesh.rotation.y = (time / 1000.0) * 0.5; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts b/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts deleted file mode 100644 index 0dffa65cc..000000000 --- a/examples-testing/examples/webgl_buffergeometry_custom_attributes_particles.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let renderer, scene, camera, stats; - -let particleSystem, uniforms, geometry; - -const particles = 100000; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 300; - - scene = new THREE.Scene(); - - uniforms = { - pointTexture: { value: new THREE.TextureLoader().load('textures/sprites/spark1.png') }, - }; - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - - blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, - vertexColors: true, - }); - - const radius = 200; - - geometry = new THREE.BufferGeometry(); - - const positions = []; - const colors = []; - const sizes = []; - - const color = new THREE.Color(); - - for (let i = 0; i < particles; i++) { - positions.push((Math.random() * 2 - 1) * radius); - positions.push((Math.random() * 2 - 1) * radius); - positions.push((Math.random() * 2 - 1) * radius); - - color.setHSL(i / particles, 1.0, 0.5); - - colors.push(color.r, color.g, color.b); - - sizes.push(20); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - geometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1).setUsage(THREE.DynamicDrawUsage)); - - particleSystem = new THREE.Points(geometry, shaderMaterial); - - scene.add(particleSystem); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = Date.now() * 0.005; - - particleSystem.rotation.z = 0.01 * time; - - const sizes = geometry.attributes.size.array; - - for (let i = 0; i < particles; i++) { - sizes[i] = 10 * (1 + Math.sin(0.1 * i + time)); - } - - geometry.attributes.size.needsUpdate = true; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_drawrange.ts b/examples-testing/examples/webgl_buffergeometry_drawrange.ts deleted file mode 100644 index 142ff43bf..000000000 --- a/examples-testing/examples/webgl_buffergeometry_drawrange.ts +++ /dev/null @@ -1,239 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let group; -let container, stats; -const particlesData = []; -let camera, scene, renderer; -let positions, colors; -let particles; -let pointCloud; -let particlePositions; -let linesMesh; - -const maxParticleCount = 1000; -let particleCount = 500; -const r = 800; -const rHalf = r / 2; - -const effectController = { - showDots: true, - showLines: true, - minDistance: 150, - limitConnections: false, - maxConnections: 20, - particleCount: 500, -}; - -init(); - -function initGUI() { - const gui = new GUI(); - - gui.add(effectController, 'showDots').onChange(function (value) { - pointCloud.visible = value; - }); - gui.add(effectController, 'showLines').onChange(function (value) { - linesMesh.visible = value; - }); - gui.add(effectController, 'minDistance', 10, 300); - gui.add(effectController, 'limitConnections'); - gui.add(effectController, 'maxConnections', 0, 30, 1); - gui.add(effectController, 'particleCount', 0, maxParticleCount, 1).onChange(function (value) { - particleCount = value; - particles.setDrawRange(0, particleCount); - }); -} - -function init() { - initGUI(); - - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 4000); - camera.position.z = 1750; - - const controls = new OrbitControls(camera, container); - controls.minDistance = 1000; - controls.maxDistance = 3000; - - scene = new THREE.Scene(); - - group = new THREE.Group(); - scene.add(group); - - const helper = new THREE.BoxHelper(new THREE.Mesh(new THREE.BoxGeometry(r, r, r))); - helper.material.color.setHex(0x474747); - helper.material.blending = THREE.AdditiveBlending; - helper.material.transparent = true; - group.add(helper); - - const segments = maxParticleCount * maxParticleCount; - - positions = new Float32Array(segments * 3); - colors = new Float32Array(segments * 3); - - const pMaterial = new THREE.PointsMaterial({ - color: 0xffffff, - size: 3, - blending: THREE.AdditiveBlending, - transparent: true, - sizeAttenuation: false, - }); - - particles = new THREE.BufferGeometry(); - particlePositions = new Float32Array(maxParticleCount * 3); - - for (let i = 0; i < maxParticleCount; i++) { - const x = Math.random() * r - r / 2; - const y = Math.random() * r - r / 2; - const z = Math.random() * r - r / 2; - - particlePositions[i * 3] = x; - particlePositions[i * 3 + 1] = y; - particlePositions[i * 3 + 2] = z; - - // add it to the geometry - particlesData.push({ - velocity: new THREE.Vector3(-1 + Math.random() * 2, -1 + Math.random() * 2, -1 + Math.random() * 2), - numConnections: 0, - }); - } - - particles.setDrawRange(0, particleCount); - particles.setAttribute( - 'position', - new THREE.BufferAttribute(particlePositions, 3).setUsage(THREE.DynamicDrawUsage), - ); - - // create the particle system - pointCloud = new THREE.Points(particles, pMaterial); - group.add(pointCloud); - - const geometry = new THREE.BufferGeometry(); - - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3).setUsage(THREE.DynamicDrawUsage)); - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3).setUsage(THREE.DynamicDrawUsage)); - - geometry.computeBoundingSphere(); - - geometry.setDrawRange(0, 0); - - const material = new THREE.LineBasicMaterial({ - vertexColors: true, - blending: THREE.AdditiveBlending, - transparent: true, - }); - - linesMesh = new THREE.LineSegments(geometry, material); - group.add(linesMesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - let vertexpos = 0; - let colorpos = 0; - let numConnected = 0; - - for (let i = 0; i < particleCount; i++) particlesData[i].numConnections = 0; - - for (let i = 0; i < particleCount; i++) { - // get the particle - const particleData = particlesData[i]; - - particlePositions[i * 3] += particleData.velocity.x; - particlePositions[i * 3 + 1] += particleData.velocity.y; - particlePositions[i * 3 + 2] += particleData.velocity.z; - - if (particlePositions[i * 3 + 1] < -rHalf || particlePositions[i * 3 + 1] > rHalf) - particleData.velocity.y = -particleData.velocity.y; - - if (particlePositions[i * 3] < -rHalf || particlePositions[i * 3] > rHalf) - particleData.velocity.x = -particleData.velocity.x; - - if (particlePositions[i * 3 + 2] < -rHalf || particlePositions[i * 3 + 2] > rHalf) - particleData.velocity.z = -particleData.velocity.z; - - if (effectController.limitConnections && particleData.numConnections >= effectController.maxConnections) - continue; - - // Check collision - for (let j = i + 1; j < particleCount; j++) { - const particleDataB = particlesData[j]; - if (effectController.limitConnections && particleDataB.numConnections >= effectController.maxConnections) - continue; - - const dx = particlePositions[i * 3] - particlePositions[j * 3]; - const dy = particlePositions[i * 3 + 1] - particlePositions[j * 3 + 1]; - const dz = particlePositions[i * 3 + 2] - particlePositions[j * 3 + 2]; - const dist = Math.sqrt(dx * dx + dy * dy + dz * dz); - - if (dist < effectController.minDistance) { - particleData.numConnections++; - particleDataB.numConnections++; - - const alpha = 1.0 - dist / effectController.minDistance; - - positions[vertexpos++] = particlePositions[i * 3]; - positions[vertexpos++] = particlePositions[i * 3 + 1]; - positions[vertexpos++] = particlePositions[i * 3 + 2]; - - positions[vertexpos++] = particlePositions[j * 3]; - positions[vertexpos++] = particlePositions[j * 3 + 1]; - positions[vertexpos++] = particlePositions[j * 3 + 2]; - - colors[colorpos++] = alpha; - colors[colorpos++] = alpha; - colors[colorpos++] = alpha; - - colors[colorpos++] = alpha; - colors[colorpos++] = alpha; - colors[colorpos++] = alpha; - - numConnected++; - } - } - } - - linesMesh.geometry.setDrawRange(0, numConnected * 2); - linesMesh.geometry.attributes.position.needsUpdate = true; - linesMesh.geometry.attributes.color.needsUpdate = true; - - pointCloud.geometry.attributes.position.needsUpdate = true; - - render(); - - stats.update(); -} - -function render() { - const time = Date.now() * 0.001; - - group.rotation.y = time * 0.1; - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts b/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts deleted file mode 100644 index aea462cf4..000000000 --- a/examples-testing/examples/webgl_buffergeometry_glbufferattribute.ts +++ /dev/null @@ -1,139 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let points; - -const particles = 300000; -let drawCount = 10000; - -init(); -animate(); - -function init() { - container = document.getElementById('container'); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 5, 3500); - camera.position.z = 2750; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const positions2 = []; - const colors = []; - - const color = new THREE.Color(); - - const n = 1000, - n2 = n / 2; // particles spread in the cube - - for (let i = 0; i < particles; i++) { - // positions - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - positions.push(x, y, z); - positions2.push(z * 0.3, x * 0.3, y * 0.3); - - // colors - - const vx = x / n + 0.5; - const vy = y / n + 0.5; - const vz = z / n + 0.5; - - color.setRGB(vx, vy, vz, THREE.SRGBColorSpace); - - colors.push(color.r, color.g, color.b); - } - - const gl = renderer.getContext(); - - const pos = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, pos); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); - - const pos2 = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, pos2); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions2), gl.STATIC_DRAW); - - const rgb = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, rgb); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); - - const posAttr1 = new THREE.GLBufferAttribute(pos, gl.FLOAT, 3, 4, particles); - const posAttr2 = new THREE.GLBufferAttribute(pos2, gl.FLOAT, 3, 4, particles); - geometry.setAttribute('position', posAttr1); - - setInterval(function () { - const attr = geometry.getAttribute('position'); - - geometry.setAttribute('position', attr === posAttr1 ? posAttr2 : posAttr1); - }, 2000); - - geometry.setAttribute('color', new THREE.GLBufferAttribute(rgb, gl.FLOAT, 3, 4, particles)); - - // - - const material = new THREE.PointsMaterial({ size: 15, vertexColors: true }); - - points = new THREE.Points(geometry, material); - - geometry.boundingSphere = new THREE.Sphere().set(new THREE.Vector3(), 500); - - scene.add(points); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - drawCount = (Math.max(5000, drawCount) + Math.floor(500 * Math.random())) % particles; - points.geometry.setDrawRange(0, drawCount); - - const time = Date.now() * 0.001; - - points.rotation.x = time * 0.1; - points.rotation.y = time * 0.2; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_indexed.ts b/examples-testing/examples/webgl_buffergeometry_indexed.ts deleted file mode 100644 index a2f9f3795..000000000 --- a/examples-testing/examples/webgl_buffergeometry_indexed.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats; - -let mesh; - -init(); - -function init() { - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500); - camera.position.z = 64; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - - // - - const light = new THREE.HemisphereLight(); - light.intensity = 3; - scene.add(light); - - // - - const geometry = new THREE.BufferGeometry(); - - const indices = []; - - const vertices = []; - const normals = []; - const colors = []; - - const size = 20; - const segments = 10; - - const halfSize = size / 2; - const segmentSize = size / segments; - - const _color = new THREE.Color(); - - // generate vertices, normals and color data for a simple grid geometry - - for (let i = 0; i <= segments; i++) { - const y = i * segmentSize - halfSize; - - for (let j = 0; j <= segments; j++) { - const x = j * segmentSize - halfSize; - - vertices.push(x, -y, 0); - normals.push(0, 0, 1); - - const r = x / size + 0.5; - const g = y / size + 0.5; - - _color.setRGB(r, g, 1, THREE.SRGBColorSpace); - - colors.push(_color.r, _color.g, _color.b); - } - } - - // generate indices (data for element array buffer) - - for (let i = 0; i < segments; i++) { - for (let j = 0; j < segments; j++) { - const a = i * (segments + 1) + (j + 1); - const b = i * (segments + 1) + j; - const c = (i + 1) * (segments + 1) + j; - const d = (i + 1) * (segments + 1) + (j + 1); - - // generate two faces (triangles) per iteration - - indices.push(a, b, d); // face one - indices.push(b, c, d); // face two - } - } - - // - - geometry.setIndex(indices); - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - const material = new THREE.MeshPhongMaterial({ - side: THREE.DoubleSide, - vertexColors: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const gui = new GUI(); - gui.add(material, 'wireframe'); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = Date.now() * 0.001; - - mesh.rotation.x = time * 0.25; - mesh.rotation.y = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_instancing.ts b/examples-testing/examples/webgl_buffergeometry_instancing.ts deleted file mode 100644 index a5b90ae6e..000000000 --- a/examples-testing/examples/webgl_buffergeometry_instancing.ts +++ /dev/null @@ -1,138 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let container, stats; - -let camera, scene, renderer; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10); - camera.position.z = 2; - - scene = new THREE.Scene(); - - // geometry - - const vector = new THREE.Vector4(); - - const instances = 50000; - - const positions = []; - const offsets = []; - const colors = []; - const orientationsStart = []; - const orientationsEnd = []; - - positions.push(0.025, -0.025, 0); - positions.push(-0.025, 0.025, 0); - positions.push(0, 0, 0.025); - - // instanced attributes - - for (let i = 0; i < instances; i++) { - // offsets - - offsets.push(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5); - - // colors - - colors.push(Math.random(), Math.random(), Math.random(), Math.random()); - - // orientation start - - vector.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1); - vector.normalize(); - - orientationsStart.push(vector.x, vector.y, vector.z, vector.w); - - // orientation end - - vector.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1); - vector.normalize(); - - orientationsEnd.push(vector.x, vector.y, vector.z, vector.w); - } - - const geometry = new THREE.InstancedBufferGeometry(); - geometry.instanceCount = instances; // set so its initalized for dat.GUI, will be set in first draw otherwise - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - - geometry.setAttribute('offset', new THREE.InstancedBufferAttribute(new Float32Array(offsets), 3)); - geometry.setAttribute('color', new THREE.InstancedBufferAttribute(new Float32Array(colors), 4)); - geometry.setAttribute( - 'orientationStart', - new THREE.InstancedBufferAttribute(new Float32Array(orientationsStart), 4), - ); - geometry.setAttribute('orientationEnd', new THREE.InstancedBufferAttribute(new Float32Array(orientationsEnd), 4)); - - // material - - const material = new THREE.RawShaderMaterial({ - uniforms: { - time: { value: 1.0 }, - sineTime: { value: 1.0 }, - }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - side: THREE.DoubleSide, - forceSinglePass: true, - transparent: true, - }); - - // - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - const gui = new GUI({ width: 350 }); - gui.add(geometry, 'instanceCount', 0, instances); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = performance.now(); - - const object = scene.children[0]; - - object.rotation.y = time * 0.0005; - object.material.uniforms['time'].value = time * 0.005; - object.material.uniforms['sineTime'].value = Math.sin(object.material.uniforms['time'].value * 0.05); - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts b/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts deleted file mode 100644 index 2158dff39..000000000 --- a/examples-testing/examples/webgl_buffergeometry_instancing_billboards.ts +++ /dev/null @@ -1,86 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; -let geometry, material, mesh; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.z = 1400; - - scene = new THREE.Scene(); - - const circleGeometry = new THREE.CircleGeometry(1, 6); - - geometry = new THREE.InstancedBufferGeometry(); - geometry.index = circleGeometry.index; - geometry.attributes = circleGeometry.attributes; - - const particleCount = 75000; - - const translateArray = new Float32Array(particleCount * 3); - - for (let i = 0, i3 = 0, l = particleCount; i < l; i++, i3 += 3) { - translateArray[i3 + 0] = Math.random() * 2 - 1; - translateArray[i3 + 1] = Math.random() * 2 - 1; - translateArray[i3 + 2] = Math.random() * 2 - 1; - } - - geometry.setAttribute('translate', new THREE.InstancedBufferAttribute(translateArray, 3)); - - material = new THREE.RawShaderMaterial({ - uniforms: { - map: { value: new THREE.TextureLoader().load('textures/sprites/circle.png') }, - time: { value: 0.0 }, - }, - vertexShader: document.getElementById('vshader').textContent, - fragmentShader: document.getElementById('fshader').textContent, - depthTest: true, - depthWrite: true, - }); - - mesh = new THREE.Mesh(geometry, material); - mesh.scale.set(500, 500, 500); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - - return true; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = performance.now() * 0.0005; - - material.uniforms['time'].value = time; - - mesh.rotation.x = time * 0.2; - mesh.rotation.y = time * 0.4; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts b/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts deleted file mode 100644 index bef2c264d..000000000 --- a/examples-testing/examples/webgl_buffergeometry_instancing_interleaved.ts +++ /dev/null @@ -1,152 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; -let camera, scene, renderer, mesh; - -const instances = 5000; -let lastTime = 0; - -const moveQ = new THREE.Quaternion(0.5, 0.5, 0.5, 0.0).normalize(); -const tmpQ = new THREE.Quaternion(); -const tmpM = new THREE.Matrix4(); -const currentM = new THREE.Matrix4(); - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x101010); - - // geometry - - const geometry = new THREE.InstancedBufferGeometry(); - - // per mesh data x,y,z,w,u,v,s,t for 4-element alignment - // only use x,y,z and u,v; but x, y, z, nx, ny, nz, u, v would be a good layout - const vertexBuffer = new THREE.InterleavedBuffer( - new Float32Array([ - // Front - -1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, -1, -1, 1, 0, 0, 1, 0, 0, 1, -1, 1, 0, 1, 1, 0, 0, - // Back - 1, 1, -1, 0, 1, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 1, 0, 0, -1, -1, -1, 0, 0, 1, 0, 0, - // Left - -1, 1, -1, 0, 1, 1, 0, 0, -1, 1, 1, 0, 1, 0, 0, 0, -1, -1, -1, 0, 0, 1, 0, 0, -1, -1, 1, 0, 0, 0, 0, 0, - // Right - 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, -1, 0, 1, 1, 0, 0, 1, -1, 1, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 1, 0, 0, - // Top - -1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, -1, 1, -1, 0, 0, 1, 0, 0, 1, 1, -1, 0, 1, 1, 0, 0, - // Bottom - 1, -1, 1, 0, 1, 0, 0, 0, -1, -1, 1, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 1, 0, 0, -1, -1, -1, 0, 0, 1, 0, 0, - ]), - 8, - ); - - // Use vertexBuffer, starting at offset 0, 3 items in position attribute - const positions = new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0); - geometry.setAttribute('position', positions); - // Use vertexBuffer, starting at offset 4, 2 items in uv attribute - const uvs = new THREE.InterleavedBufferAttribute(vertexBuffer, 2, 4); - geometry.setAttribute('uv', uvs); - - const indices = new Uint16Array([ - 0, 2, 1, 2, 3, 1, 4, 6, 5, 6, 7, 5, 8, 10, 9, 10, 11, 9, 12, 14, 13, 14, 15, 13, 16, 17, 18, 18, 17, 19, 20, 21, - 22, 22, 21, 23, - ]); - - geometry.setIndex(new THREE.BufferAttribute(indices, 1)); - - // material - - const material = new THREE.MeshBasicMaterial(); - material.map = new THREE.TextureLoader().load('textures/crate.gif'); - material.map.colorSpace = THREE.SRGBColorSpace; - material.map.flipY = false; - - // per instance data - - const matrix = new THREE.Matrix4(); - const offset = new THREE.Vector3(); - const orientation = new THREE.Quaternion(); - const scale = new THREE.Vector3(1, 1, 1); - let x, y, z, w; - - mesh = new THREE.InstancedMesh(geometry, material, instances); - - for (let i = 0; i < instances; i++) { - // offsets - - x = Math.random() * 100 - 50; - y = Math.random() * 100 - 50; - z = Math.random() * 100 - 50; - - offset.set(x, y, z).normalize(); - offset.multiplyScalar(5); // move out at least 5 units from center in current direction - offset.set(x + offset.x, y + offset.y, z + offset.z); - - // orientations - - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - z = Math.random() * 2 - 1; - w = Math.random() * 2 - 1; - - orientation.set(x, y, z, w).normalize(); - - matrix.compose(offset, orientation, scale); - - mesh.setMatrixAt(i, matrix); - } - - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = performance.now(); - - mesh.rotation.y = time * 0.00005; - - const delta = (time - lastTime) / 5000; - tmpQ.set(moveQ.x * delta, moveQ.y * delta, moveQ.z * delta, 1).normalize(); - tmpM.makeRotationFromQuaternion(tmpQ); - - for (let i = 0, il = instances; i < il; i++) { - mesh.getMatrixAt(i, currentM); - currentM.multiply(tmpM); - mesh.setMatrixAt(i, currentM); - } - - mesh.instanceMatrix.needsUpdate = true; - mesh.computeBoundingSphere(); - - lastTime = time; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_lines.ts b/examples-testing/examples/webgl_buffergeometry_lines.ts deleted file mode 100644 index 1aaa5ca4a..000000000 --- a/examples-testing/examples/webgl_buffergeometry_lines.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats, clock; - -let camera, scene, renderer; - -let line; - -const segments = 10000; -const r = 800; -let t = 0; - -init(); - -function init() { - container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 4000); - camera.position.z = 2750; - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - const geometry = new THREE.BufferGeometry(); - const material = new THREE.LineBasicMaterial({ vertexColors: true }); - - const positions = []; - const colors = []; - - for (let i = 0; i < segments; i++) { - const x = Math.random() * r - r / 2; - const y = Math.random() * r - r / 2; - const z = Math.random() * r - r / 2; - - // positions - - positions.push(x, y, z); - - // colors - - colors.push(x / r + 0.5); - colors.push(y / r + 0.5); - colors.push(z / r + 0.5); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - generateMorphTargets(geometry); - - geometry.computeBoundingSphere(); - - line = new THREE.Line(geometry, material); - scene.add(line); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const delta = clock.getDelta(); - const time = clock.getElapsedTime(); - - line.rotation.x = time * 0.25; - line.rotation.y = time * 0.5; - - t += delta * 0.5; - line.morphTargetInfluences[0] = Math.abs(Math.sin(t)); - - renderer.render(scene, camera); - - stats.update(); -} - -function generateMorphTargets(geometry) { - const data = []; - - for (let i = 0; i < segments; i++) { - const x = Math.random() * r - r / 2; - const y = Math.random() * r - r / 2; - const z = Math.random() * r - r / 2; - - data.push(x, y, z); - } - - const morphTarget = new THREE.Float32BufferAttribute(data, 3); - morphTarget.name = 'target1'; - - geometry.morphAttributes.position = [morphTarget]; -} diff --git a/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts b/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts deleted file mode 100644 index 58296087e..000000000 --- a/examples-testing/examples/webgl_buffergeometry_lines_indexed.ts +++ /dev/null @@ -1,179 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let parent_node; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 9000; - - scene = new THREE.Scene(); - - const geometry = new THREE.BufferGeometry(); - const material = new THREE.LineBasicMaterial({ vertexColors: true }); - - const indices = []; - const positions = []; - const colors = []; - - let next_positions_index = 0; - - // - - const iteration_count = 4; - const rangle = (60 * Math.PI) / 180.0; - - function add_vertex(v) { - positions.push(v.x, v.y, v.z); - colors.push(Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1); - - return next_positions_index++; - } - - // simple Koch curve - - function snowflake_iteration(p0, p4, depth) { - if (--depth < 0) { - const i = next_positions_index - 1; // p0 already there - add_vertex(p4); - indices.push(i, i + 1); - - return; - } - - const v = p4.clone().sub(p0); - const v_tier = v.clone().multiplyScalar(1 / 3); - const p1 = p0.clone().add(v_tier); - - const angle = Math.atan2(v.y, v.x) + rangle; - const length = v_tier.length(); - const p2 = p1.clone(); - p2.x += Math.cos(angle) * length; - p2.y += Math.sin(angle) * length; - - const p3 = p0.clone().add(v_tier).add(v_tier); - - snowflake_iteration(p0, p1, depth); - snowflake_iteration(p1, p2, depth); - snowflake_iteration(p2, p3, depth); - snowflake_iteration(p3, p4, depth); - } - - function snowflake(points, loop, x_offset) { - for (let iteration = 0; iteration != iteration_count; iteration++) { - add_vertex(points[0]); - - for (let p_index = 0, p_count = points.length - 1; p_index != p_count; p_index++) { - snowflake_iteration(points[p_index], points[p_index + 1], iteration); - } - - if (loop) snowflake_iteration(points[points.length - 1], points[0], iteration); - - // translate input curve for next iteration - - for (let p_index = 0, p_count = points.length; p_index != p_count; p_index++) { - points[p_index].x += x_offset; - } - } - } - - let y = 0; - - snowflake([new THREE.Vector3(0, y, 0), new THREE.Vector3(500, y, 0)], false, 600); - - y += 600; - snowflake( - [new THREE.Vector3(0, y, 0), new THREE.Vector3(250, y + 400, 0), new THREE.Vector3(500, y, 0)], - true, - 600, - ); - - y += 600; - snowflake( - [ - new THREE.Vector3(0, y, 0), - new THREE.Vector3(500, y, 0), - new THREE.Vector3(500, y + 500, 0), - new THREE.Vector3(0, y + 500, 0), - ], - true, - 600, - ); - - y += 1000; - snowflake( - [ - new THREE.Vector3(250, y, 0), - new THREE.Vector3(500, y, 0), - new THREE.Vector3(250, y, 0), - new THREE.Vector3(250, y + 250, 0), - new THREE.Vector3(250, y, 0), - new THREE.Vector3(0, y, 0), - new THREE.Vector3(250, y, 0), - new THREE.Vector3(250, y - 250, 0), - new THREE.Vector3(250, y, 0), - ], - false, - 600, - ); - - // - - geometry.setIndex(indices); - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - geometry.computeBoundingSphere(); - - const lineSegments = new THREE.LineSegments(geometry, material); - lineSegments.position.x -= 1200; - lineSegments.position.y -= 1200; - - parent_node = new THREE.Object3D(); - parent_node.add(lineSegments); - - scene.add(parent_node); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = Date.now() * 0.001; - - parent_node.rotation.z = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_points.ts b/examples-testing/examples/webgl_buffergeometry_points.ts deleted file mode 100644 index 4547d9d08..000000000 --- a/examples-testing/examples/webgl_buffergeometry_points.ts +++ /dev/null @@ -1,109 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let points; - -init(); -animate(); - -function init() { - container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 5, 3500); - camera.position.z = 2750; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // - - const particles = 500000; - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const colors = []; - - const color = new THREE.Color(); - - const n = 1000, - n2 = n / 2; // particles spread in the cube - - for (let i = 0; i < particles; i++) { - // positions - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - positions.push(x, y, z); - - // colors - - const vx = x / n + 0.5; - const vy = y / n + 0.5; - const vz = z / n + 0.5; - - color.setRGB(vx, vy, vz, THREE.SRGBColorSpace); - - colors.push(color.r, color.g, color.b); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - geometry.computeBoundingSphere(); - - // - - const material = new THREE.PointsMaterial({ size: 15, vertexColors: true }); - - points = new THREE.Points(geometry, material); - scene.add(points); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = Date.now() * 0.001; - - points.rotation.x = time * 0.25; - points.rotation.y = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts b/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts deleted file mode 100644 index 93eed992e..000000000 --- a/examples-testing/examples/webgl_buffergeometry_points_interleaved.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let points; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 5, 3500); - camera.position.z = 2750; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // - - const particles = 500000; - - const geometry = new THREE.BufferGeometry(); - - // create a generic buffer of binary data (a single particle has 16 bytes of data) - - const arrayBuffer = new ArrayBuffer(particles * 16); - - // the following typed arrays share the same buffer - - const interleavedFloat32Buffer = new Float32Array(arrayBuffer); - const interleavedUint8Buffer = new Uint8Array(arrayBuffer); - - // - - const color = new THREE.Color(); - - const n = 1000, - n2 = n / 2; // particles spread in the cube - - for (let i = 0; i < interleavedFloat32Buffer.length; i += 4) { - // position (first 12 bytes) - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - interleavedFloat32Buffer[i + 0] = x; - interleavedFloat32Buffer[i + 1] = y; - interleavedFloat32Buffer[i + 2] = z; - - // color (last 4 bytes) - - const vx = x / n + 0.5; - const vy = y / n + 0.5; - const vz = z / n + 0.5; - - color.setRGB(vx, vy, vz, THREE.SRGBColorSpace); - - const j = (i + 3) * 4; - - interleavedUint8Buffer[j + 0] = color.r * 255; - interleavedUint8Buffer[j + 1] = color.g * 255; - interleavedUint8Buffer[j + 2] = color.b * 255; - interleavedUint8Buffer[j + 3] = 0; // not needed - } - - const interleavedBuffer32 = new THREE.InterleavedBuffer(interleavedFloat32Buffer, 4); - const interleavedBuffer8 = new THREE.InterleavedBuffer(interleavedUint8Buffer, 16); - - geometry.setAttribute('position', new THREE.InterleavedBufferAttribute(interleavedBuffer32, 3, 0, false)); - geometry.setAttribute('color', new THREE.InterleavedBufferAttribute(interleavedBuffer8, 3, 12, true)); - - // - - const material = new THREE.PointsMaterial({ size: 15, vertexColors: true }); - - points = new THREE.Points(geometry, material); - scene.add(points); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = Date.now() * 0.001; - - points.rotation.x = time * 0.25; - points.rotation.y = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_rawshader.ts b/examples-testing/examples/webgl_buffergeometry_rawshader.ts deleted file mode 100644 index 5bc113dc3..000000000 --- a/examples-testing/examples/webgl_buffergeometry_rawshader.ts +++ /dev/null @@ -1,97 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10); - camera.position.z = 2; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x101010); - - // geometry - // nr of triangles with 3 vertices per triangle - const vertexCount = 200 * 3; - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const colors = []; - - for (let i = 0; i < vertexCount; i++) { - // adding x,y,z - positions.push(Math.random() - 0.5); - positions.push(Math.random() - 0.5); - positions.push(Math.random() - 0.5); - - // adding r,g,b,a - colors.push(Math.random() * 255); - colors.push(Math.random() * 255); - colors.push(Math.random() * 255); - colors.push(Math.random() * 255); - } - - const positionAttribute = new THREE.Float32BufferAttribute(positions, 3); - const colorAttribute = new THREE.Uint8BufferAttribute(colors, 4); - - colorAttribute.normalized = true; // this will map the buffer values to 0.0f - +1.0f in the shader - - geometry.setAttribute('position', positionAttribute); - geometry.setAttribute('color', colorAttribute); - - // material - - const material = new THREE.RawShaderMaterial({ - uniforms: { - time: { value: 1.0 }, - }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - side: THREE.DoubleSide, - transparent: true, - }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = performance.now(); - - const object = scene.children[0]; - - object.rotation.y = time * 0.0005; - object.material.uniforms.time.value = time * 0.005; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_selective_draw.ts b/examples-testing/examples/webgl_buffergeometry_selective_draw.ts deleted file mode 100644 index d07176c51..000000000 --- a/examples-testing/examples/webgl_buffergeometry_selective_draw.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; -let geometry, mesh; -const numLat = 100; -const numLng = 200; -let numLinesCulled = 0; - -init(); - -function init() { - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.z = 3.5; - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - - addLines(1.0); - - const hideLinesButton = document.getElementById('hideLines'); - hideLinesButton.addEventListener('click', hideLines); - - const showAllLinesButton = document.getElementById('showAllLines'); - showAllLinesButton.addEventListener('click', showAllLines); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); -} - -function addLines(radius) { - geometry = new THREE.BufferGeometry(); - const linePositions = new Float32Array(numLat * numLng * 3 * 2); - const lineColors = new Float32Array(numLat * numLng * 3 * 2); - const visible = new Float32Array(numLat * numLng * 2); - - for (let i = 0; i < numLat; ++i) { - for (let j = 0; j < numLng; ++j) { - const lat = (Math.random() * Math.PI) / 50.0 + (i / numLat) * Math.PI; - const lng = (Math.random() * Math.PI) / 50.0 + (j / numLng) * 2 * Math.PI; - - const index = i * numLng + j; - - linePositions[index * 6 + 0] = 0; - linePositions[index * 6 + 1] = 0; - linePositions[index * 6 + 2] = 0; - linePositions[index * 6 + 3] = radius * Math.sin(lat) * Math.cos(lng); - linePositions[index * 6 + 4] = radius * Math.cos(lat); - linePositions[index * 6 + 5] = radius * Math.sin(lat) * Math.sin(lng); - - const color = new THREE.Color(0xffffff); - - color.setHSL(lat / Math.PI, 1.0, 0.2); - lineColors[index * 6 + 0] = color.r; - lineColors[index * 6 + 1] = color.g; - lineColors[index * 6 + 2] = color.b; - - color.setHSL(lat / Math.PI, 1.0, 0.7); - lineColors[index * 6 + 3] = color.r; - lineColors[index * 6 + 4] = color.g; - lineColors[index * 6 + 5] = color.b; - - // non-0 is visible - visible[index * 2 + 0] = 1.0; - visible[index * 2 + 1] = 1.0; - } - } - - geometry.setAttribute('position', new THREE.BufferAttribute(linePositions, 3)); - geometry.setAttribute('vertColor', new THREE.BufferAttribute(lineColors, 3)); - geometry.setAttribute('visible', new THREE.BufferAttribute(visible, 1)); - - geometry.computeBoundingSphere(); - - const shaderMaterial = new THREE.ShaderMaterial({ - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - }); - - mesh = new THREE.LineSegments(geometry, shaderMaterial); - scene.add(mesh); - - updateCount(); -} - -function updateCount() { - const str = - '1 draw call, ' + - numLat * numLng + - ' lines, ' + - numLinesCulled + - ' culled (author)'; - document.getElementById('title').innerHTML = str.replace(/\B(?=(\d{3})+(?!\d))/g, ','); -} - -function hideLines() { - for (let i = 0; i < geometry.attributes.visible.array.length; i += 2) { - if (Math.random() > 0.75) { - if (geometry.attributes.visible.array[i + 0]) { - ++numLinesCulled; - } - - geometry.attributes.visible.array[i + 0] = 0; - geometry.attributes.visible.array[i + 1] = 0; - } - } - - geometry.attributes.visible.needsUpdate = true; - - updateCount(); -} - -function showAllLines() { - numLinesCulled = 0; - - for (let i = 0; i < geometry.attributes.visible.array.length; i += 2) { - geometry.attributes.visible.array[i + 0] = 1; - geometry.attributes.visible.array[i + 1] = 1; - } - - geometry.attributes.visible.needsUpdate = true; - - updateCount(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = Date.now() * 0.001; - - mesh.rotation.x = time * 0.25; - mesh.rotation.y = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_buffergeometry_uint.ts b/examples-testing/examples/webgl_buffergeometry_uint.ts deleted file mode 100644 index 0b8df6ec7..000000000 --- a/examples-testing/examples/webgl_buffergeometry_uint.ts +++ /dev/null @@ -1,177 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let mesh; - -init(); - -function init() { - container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500); - camera.position.z = 2750; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const light1 = new THREE.DirectionalLight(0xffffff, 1.5); - light1.position.set(1, 1, 1); - scene.add(light1); - - const light2 = new THREE.DirectionalLight(0xffffff, 4.5); - light2.position.set(0, -1, 0); - scene.add(light2); - - // - - const triangles = 500000; - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const normals = []; - const colors = []; - - const color = new THREE.Color(); - - const n = 800, - n2 = n / 2; // triangles spread in the cube - const d = 12, - d2 = d / 2; // individual triangle size - - const pA = new THREE.Vector3(); - const pB = new THREE.Vector3(); - const pC = new THREE.Vector3(); - - const cb = new THREE.Vector3(); - const ab = new THREE.Vector3(); - - for (let i = 0; i < triangles; i++) { - // positions - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - const ax = x + Math.random() * d - d2; - const ay = y + Math.random() * d - d2; - const az = z + Math.random() * d - d2; - - const bx = x + Math.random() * d - d2; - const by = y + Math.random() * d - d2; - const bz = z + Math.random() * d - d2; - - const cx = x + Math.random() * d - d2; - const cy = y + Math.random() * d - d2; - const cz = z + Math.random() * d - d2; - - positions.push(ax, ay, az); - positions.push(bx, by, bz); - positions.push(cx, cy, cz); - - // flat face normals - - pA.set(ax, ay, az); - pB.set(bx, by, bz); - pC.set(cx, cy, cz); - - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - - cb.normalize(); - - const nx = cb.x; - const ny = cb.y; - const nz = cb.z; - - normals.push(nx * 32767, ny * 32767, nz * 32767); - normals.push(nx * 32767, ny * 32767, nz * 32767); - normals.push(nx * 32767, ny * 32767, nz * 32767); - - // colors - - const vx = x / n + 0.5; - const vy = y / n + 0.5; - const vz = z / n + 0.5; - - color.setRGB(vx, vy, vz); - - colors.push(color.r * 255, color.g * 255, color.b * 255); - colors.push(color.r * 255, color.g * 255, color.b * 255); - colors.push(color.r * 255, color.g * 255, color.b * 255); - } - - const positionAttribute = new THREE.Float32BufferAttribute(positions, 3); - const normalAttribute = new THREE.Int16BufferAttribute(normals, 3); - const colorAttribute = new THREE.Uint8BufferAttribute(colors, 3); - - normalAttribute.normalized = true; // this will map the buffer values to 0.0f - +1.0f in the shader - colorAttribute.normalized = true; - - geometry.setAttribute('position', positionAttribute); - geometry.setAttribute('normal', normalAttribute); - geometry.setAttribute('color', colorAttribute); - - geometry.computeBoundingSphere(); - - const material = new THREE.MeshPhongMaterial({ - color: 0xd5d5d5, - specular: 0xffffff, - shininess: 250, - side: THREE.DoubleSide, - vertexColors: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = Date.now() * 0.001; - - mesh.rotation.x = time * 0.25; - mesh.rotation.y = time * 0.5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_camera.ts b/examples-testing/examples/webgl_camera.ts deleted file mode 100644 index f3d663603..000000000 --- a/examples-testing/examples/webgl_camera.ts +++ /dev/null @@ -1,218 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; -let aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - -let container, stats; -let camera, scene, renderer, mesh; -let cameraRig, activeCamera, activeHelper; -let cameraPerspective, cameraOrtho; -let cameraPerspectiveHelper, cameraOrthoHelper; -const frustumSize = 600; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - - // - - camera = new THREE.PerspectiveCamera(50, 0.5 * aspect, 1, 10000); - camera.position.z = 2500; - - cameraPerspective = new THREE.PerspectiveCamera(50, 0.5 * aspect, 150, 1000); - - cameraPerspectiveHelper = new THREE.CameraHelper(cameraPerspective); - scene.add(cameraPerspectiveHelper); - - // - cameraOrtho = new THREE.OrthographicCamera( - (0.5 * frustumSize * aspect) / -2, - (0.5 * frustumSize * aspect) / 2, - frustumSize / 2, - frustumSize / -2, - 150, - 1000, - ); - - cameraOrthoHelper = new THREE.CameraHelper(cameraOrtho); - scene.add(cameraOrthoHelper); - - // - - activeCamera = cameraPerspective; - activeHelper = cameraPerspectiveHelper; - - // counteract different front orientation of cameras vs rig - - cameraOrtho.rotation.y = Math.PI; - cameraPerspective.rotation.y = Math.PI; - - cameraRig = new THREE.Group(); - - cameraRig.add(cameraPerspective); - cameraRig.add(cameraOrtho); - - scene.add(cameraRig); - - // - - mesh = new THREE.Mesh( - new THREE.SphereGeometry(100, 16, 8), - new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }), - ); - scene.add(mesh); - - const mesh2 = new THREE.Mesh( - new THREE.SphereGeometry(50, 16, 8), - new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true }), - ); - mesh2.position.y = 150; - mesh.add(mesh2); - - const mesh3 = new THREE.Mesh( - new THREE.SphereGeometry(5, 16, 8), - new THREE.MeshBasicMaterial({ color: 0x0000ff, wireframe: true }), - ); - mesh3.position.z = 150; - cameraRig.add(mesh3); - - // - - const geometry = new THREE.BufferGeometry(); - const vertices = []; - - for (let i = 0; i < 10000; i++) { - vertices.push(THREE.MathUtils.randFloatSpread(2000)); // x - vertices.push(THREE.MathUtils.randFloatSpread(2000)); // y - vertices.push(THREE.MathUtils.randFloatSpread(2000)); // z - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - - const particles = new THREE.Points(geometry, new THREE.PointsMaterial({ color: 0x888888 })); - scene.add(particles); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - renderer.setScissorTest(true); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - document.addEventListener('keydown', onKeyDown); -} - -// - -function onKeyDown(event) { - switch (event.keyCode) { - case 79 /*O*/: - activeCamera = cameraOrtho; - activeHelper = cameraOrthoHelper; - - break; - - case 80 /*P*/: - activeCamera = cameraPerspective; - activeHelper = cameraPerspectiveHelper; - - break; - } -} - -// - -function onWindowResize() { - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - camera.aspect = 0.5 * aspect; - camera.updateProjectionMatrix(); - - cameraPerspective.aspect = 0.5 * aspect; - cameraPerspective.updateProjectionMatrix(); - - cameraOrtho.left = (-0.5 * frustumSize * aspect) / 2; - cameraOrtho.right = (0.5 * frustumSize * aspect) / 2; - cameraOrtho.top = frustumSize / 2; - cameraOrtho.bottom = -frustumSize / 2; - cameraOrtho.updateProjectionMatrix(); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const r = Date.now() * 0.0005; - - mesh.position.x = 700 * Math.cos(r); - mesh.position.z = 700 * Math.sin(r); - mesh.position.y = 700 * Math.sin(r); - - mesh.children[0].position.x = 70 * Math.cos(2 * r); - mesh.children[0].position.z = 70 * Math.sin(r); - - if (activeCamera === cameraPerspective) { - cameraPerspective.fov = 35 + 30 * Math.sin(0.5 * r); - cameraPerspective.far = mesh.position.length(); - cameraPerspective.updateProjectionMatrix(); - - cameraPerspectiveHelper.update(); - cameraPerspectiveHelper.visible = true; - - cameraOrthoHelper.visible = false; - } else { - cameraOrtho.far = mesh.position.length(); - cameraOrtho.updateProjectionMatrix(); - - cameraOrthoHelper.update(); - cameraOrthoHelper.visible = true; - - cameraPerspectiveHelper.visible = false; - } - - cameraRig.lookAt(mesh.position); - - // - - activeHelper.visible = false; - - renderer.setClearColor(0x000000, 1); - renderer.setScissor(0, 0, SCREEN_WIDTH / 2, SCREEN_HEIGHT); - renderer.setViewport(0, 0, SCREEN_WIDTH / 2, SCREEN_HEIGHT); - renderer.render(scene, activeCamera); - - // - - activeHelper.visible = true; - - renderer.setClearColor(0x111111, 1); - renderer.setScissor(SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2, SCREEN_HEIGHT); - renderer.setViewport(SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2, SCREEN_HEIGHT); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_camera_array.ts b/examples-testing/examples/webgl_camera_array.ts deleted file mode 100644 index 8b10e27cb..000000000 --- a/examples-testing/examples/webgl_camera_array.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; -let mesh; -const AMOUNT = 6; - -init(); - -function init() { - const ASPECT_RATIO = window.innerWidth / window.innerHeight; - - const WIDTH = (window.innerWidth / AMOUNT) * window.devicePixelRatio; - const HEIGHT = (window.innerHeight / AMOUNT) * window.devicePixelRatio; - - const cameras = []; - - for (let y = 0; y < AMOUNT; y++) { - for (let x = 0; x < AMOUNT; x++) { - const subcamera = new THREE.PerspectiveCamera(40, ASPECT_RATIO, 0.1, 10); - subcamera.viewport = new THREE.Vector4( - Math.floor(x * WIDTH), - Math.floor(y * HEIGHT), - Math.ceil(WIDTH), - Math.ceil(HEIGHT), - ); - subcamera.position.x = x / AMOUNT - 0.5; - subcamera.position.y = 0.5 - y / AMOUNT; - subcamera.position.z = 1.5; - subcamera.position.multiplyScalar(2); - subcamera.lookAt(0, 0, 0); - subcamera.updateMatrixWorld(); - cameras.push(subcamera); - } - } - - camera = new THREE.ArrayCamera(cameras); - camera.position.z = 3; - - scene = new THREE.Scene(); - - scene.add(new THREE.AmbientLight(0x999999)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0.5, 0.5, 1); - light.castShadow = true; - light.shadow.camera.zoom = 4; // tighter shadow map - scene.add(light); - - const geometryBackground = new THREE.PlaneGeometry(100, 100); - const materialBackground = new THREE.MeshPhongMaterial({ color: 0x000066 }); - - const background = new THREE.Mesh(geometryBackground, materialBackground); - background.receiveShadow = true; - background.position.set(0, 0, -1); - scene.add(background); - - const geometryCylinder = new THREE.CylinderGeometry(0.5, 0.5, 1, 32); - const materialCylinder = new THREE.MeshPhongMaterial({ color: 0xff0000 }); - - mesh = new THREE.Mesh(geometryCylinder, materialCylinder); - mesh.castShadow = true; - mesh.receiveShadow = true; - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const ASPECT_RATIO = window.innerWidth / window.innerHeight; - const WIDTH = (window.innerWidth / AMOUNT) * window.devicePixelRatio; - const HEIGHT = (window.innerHeight / AMOUNT) * window.devicePixelRatio; - - camera.aspect = ASPECT_RATIO; - camera.updateProjectionMatrix(); - - for (let y = 0; y < AMOUNT; y++) { - for (let x = 0; x < AMOUNT; x++) { - const subcamera = camera.cameras[AMOUNT * y + x]; - - subcamera.viewport.set(Math.floor(x * WIDTH), Math.floor(y * HEIGHT), Math.ceil(WIDTH), Math.ceil(HEIGHT)); - - subcamera.aspect = ASPECT_RATIO; - subcamera.updateProjectionMatrix(); - } - } - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - mesh.rotation.x += 0.005; - mesh.rotation.z += 0.01; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts b/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts deleted file mode 100644 index f1d440004..000000000 --- a/examples-testing/examples/webgl_camera_logarithmicdepthbuffer.ts +++ /dev/null @@ -1,248 +0,0 @@ -import * as THREE from 'three'; - -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -// 1 micrometer to 100 billion light years in one scene, with 1 unit = 1 meter? preposterous! and yet... -const NEAR = 1e-6, - FAR = 1e27; -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; -let screensplit = 0.25, - screensplit_right = 0; -const mouse = [0.5, 0.5]; -let zoompos = -100, - minzoomspeed = 0.015; -let zoomspeed = minzoomspeed; - -let container, border, stats; -const objects = {}; - -// Generate a number of text labels, from 1µm in size up to 100,000,000 light years -// Try to use some descriptive real-world examples of objects at each scale - -const labeldata = [ - { size: 0.01, scale: 0.0001, label: 'microscopic (1µm)' }, // FIXME - triangulating text fails at this size, so we scale instead - { size: 0.01, scale: 0.1, label: 'minuscule (1mm)' }, - { size: 0.01, scale: 1.0, label: 'tiny (1cm)' }, - { size: 1, scale: 1.0, label: 'child-sized (1m)' }, - { size: 10, scale: 1.0, label: 'tree-sized (10m)' }, - { size: 100, scale: 1.0, label: 'building-sized (100m)' }, - { size: 1000, scale: 1.0, label: 'medium (1km)' }, - { size: 10000, scale: 1.0, label: 'city-sized (10km)' }, - { size: 3400000, scale: 1.0, label: 'moon-sized (3,400 Km)' }, - { size: 12000000, scale: 1.0, label: 'planet-sized (12,000 km)' }, - { size: 1400000000, scale: 1.0, label: 'sun-sized (1,400,000 km)' }, - { size: 7.47e12, scale: 1.0, label: 'solar system-sized (50Au)' }, - { size: 9.4605284e15, scale: 1.0, label: 'gargantuan (1 light year)' }, - { size: 3.08567758e16, scale: 1.0, label: 'ludicrous (1 parsec)' }, - { size: 1e19, scale: 1.0, label: 'mind boggling (1000 light years)' }, -]; - -init(); - -function init() { - container = document.getElementById('container'); - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_regular.typeface.json', function (font) { - const scene = initScene(font); - - // Initialize two copies of the same scene, one with normal z-buffer and one with logarithmic z-buffer - objects.normal = initView(scene, 'normal', false); - objects.logzbuf = initView(scene, 'logzbuf', true); - - animate(); - }); - - stats = new Stats(); - container.appendChild(stats.dom); - - // Resize border allows the user to easily compare effects of logarithmic depth buffer over the whole scene - border = document.getElementById('renderer_border'); - border.addEventListener('pointerdown', onBorderPointerDown); - - window.addEventListener('mousemove', onMouseMove); - window.addEventListener('resize', onWindowResize); - window.addEventListener('wheel', onMouseWheel); -} - -function initView(scene, name, logDepthBuf) { - const framecontainer = document.getElementById('container_' + name); - - const camera = new THREE.PerspectiveCamera(50, (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT, NEAR, FAR); - scene.add(camera); - - const renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: logDepthBuf }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH / 2, SCREEN_HEIGHT); - renderer.domElement.style.position = 'relative'; - renderer.domElement.id = 'renderer_' + name; - framecontainer.appendChild(renderer.domElement); - - return { container: framecontainer, renderer: renderer, scene: scene, camera: camera }; -} - -function initScene(font) { - const scene = new THREE.Scene(); - - scene.add(new THREE.AmbientLight(0x777777)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(100, 100, 100); - scene.add(light); - - const materialargs = { - color: 0xffffff, - specular: 0x050505, - shininess: 50, - emissive: 0x000000, - }; - - const geometry = new THREE.SphereGeometry(0.5, 24, 12); - - for (let i = 0; i < labeldata.length; i++) { - const scale = labeldata[i].scale || 1; - - const labelgeo = new TextGeometry(labeldata[i].label, { - font: font, - size: labeldata[i].size, - depth: labeldata[i].size / 2, - }); - - labelgeo.computeBoundingSphere(); - - // center text - labelgeo.translate(-labelgeo.boundingSphere.radius, 0, 0); - - materialargs.color = new THREE.Color().setHSL(Math.random(), 0.5, 0.5); - - const material = new THREE.MeshPhongMaterial(materialargs); - - const group = new THREE.Group(); - group.position.z = -labeldata[i].size * scale; - scene.add(group); - - const textmesh = new THREE.Mesh(labelgeo, material); - textmesh.scale.set(scale, scale, scale); - textmesh.position.z = -labeldata[i].size * scale; - textmesh.position.y = (labeldata[i].size / 4) * scale; - group.add(textmesh); - - const dotmesh = new THREE.Mesh(geometry, material); - dotmesh.position.y = (-labeldata[i].size / 4) * scale; - dotmesh.scale.multiplyScalar(labeldata[i].size * scale); - group.add(dotmesh); - } - - return scene; -} - -function updateRendererSizes() { - // Recalculate size for both renderers when screen size or split location changes - - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - screensplit_right = 1 - screensplit; - - objects.normal.renderer.setSize(screensplit * SCREEN_WIDTH, SCREEN_HEIGHT); - objects.normal.camera.aspect = (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT; - objects.normal.camera.updateProjectionMatrix(); - objects.normal.camera.setViewOffset(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH * screensplit, SCREEN_HEIGHT); - objects.normal.container.style.width = screensplit * 100 + '%'; - - objects.logzbuf.renderer.setSize(screensplit_right * SCREEN_WIDTH, SCREEN_HEIGHT); - objects.logzbuf.camera.aspect = (screensplit_right * SCREEN_WIDTH) / SCREEN_HEIGHT; - objects.logzbuf.camera.updateProjectionMatrix(); - objects.logzbuf.camera.setViewOffset( - SCREEN_WIDTH, - SCREEN_HEIGHT, - SCREEN_WIDTH * screensplit, - 0, - SCREEN_WIDTH * screensplit_right, - SCREEN_HEIGHT, - ); - objects.logzbuf.container.style.width = screensplit_right * 100 + '%'; - - border.style.left = screensplit * 100 + '%'; -} - -function animate() { - requestAnimationFrame(animate); - render(); -} - -function render() { - // Put some limits on zooming - const minzoom = labeldata[0].size * labeldata[0].scale * 1; - const maxzoom = labeldata[labeldata.length - 1].size * labeldata[labeldata.length - 1].scale * 100; - let damping = Math.abs(zoomspeed) > minzoomspeed ? 0.95 : 1.0; - - // Zoom out faster the further out you go - const zoom = THREE.MathUtils.clamp(Math.pow(Math.E, zoompos), minzoom, maxzoom); - zoompos = Math.log(zoom); - - // Slow down quickly at the zoom limits - if ((zoom == minzoom && zoomspeed < 0) || (zoom == maxzoom && zoomspeed > 0)) { - damping = 0.85; - } - - zoompos += zoomspeed; - zoomspeed *= damping; - - objects.normal.camera.position.x = Math.sin(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; - objects.normal.camera.position.y = Math.sin(0.25 * Math.PI * (mouse[1] - 0.5)) * zoom; - objects.normal.camera.position.z = Math.cos(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; - objects.normal.camera.lookAt(objects.normal.scene.position); - - // Clone camera settings across both scenes - objects.logzbuf.camera.position.copy(objects.normal.camera.position); - objects.logzbuf.camera.quaternion.copy(objects.normal.camera.quaternion); - - // Update renderer sizes if the split has changed - if (screensplit_right != 1 - screensplit) { - updateRendererSizes(); - } - - objects.normal.renderer.render(objects.normal.scene, objects.normal.camera); - objects.logzbuf.renderer.render(objects.logzbuf.scene, objects.logzbuf.camera); - - stats.update(); -} - -function onWindowResize() { - updateRendererSizes(); -} - -function onBorderPointerDown() { - // activate draggable window resizing bar - window.addEventListener('pointermove', onBorderPointerMove); - window.addEventListener('pointerup', onBorderPointerUp); -} - -function onBorderPointerMove(ev) { - screensplit = Math.max(0, Math.min(1, ev.clientX / window.innerWidth)); -} - -function onBorderPointerUp() { - window.removeEventListener('pointermove', onBorderPointerMove); - window.removeEventListener('pointerup', onBorderPointerUp); -} - -function onMouseMove(ev) { - mouse[0] = ev.clientX / window.innerWidth; - mouse[1] = ev.clientY / window.innerHeight; -} - -function onMouseWheel(ev) { - const amount = ev.deltaY; - if (amount === 0) return; - const dir = amount / Math.abs(amount); - zoomspeed = dir / 10; - - // Slow down default zoom speed after user starts zooming, to give them more control - minzoomspeed = 0.001; -} diff --git a/examples-testing/examples/webgl_clipculldistance.ts b/examples-testing/examples/webgl_clipculldistance.ts deleted file mode 100644 index a5fb54d47..000000000 --- a/examples-testing/examples/webgl_clipculldistance.ts +++ /dev/null @@ -1,110 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, controls, clock, scene, renderer, stats; - -let material; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10); - camera.position.z = 2; - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - if (renderer.extensions.has('WEBGL_clip_cull_distance') === false) { - document.getElementById('notSupported').style.display = ''; - return; - } - - const ext = renderer.getContext().getExtension('WEBGL_clip_cull_distance'); - const gl = renderer.getContext(); - - gl.enable(ext.CLIP_DISTANCE0_WEBGL); - - // geometry - - const vertexCount = 200 * 3; - - const geometry = new THREE.BufferGeometry(); - - const positions = []; - const colors = []; - - for (let i = 0; i < vertexCount; i++) { - // adding x,y,z - positions.push(Math.random() - 0.5); - positions.push(Math.random() - 0.5); - positions.push(Math.random() - 0.5); - - // adding r,g,b,a - colors.push(Math.random() * 255); - colors.push(Math.random() * 255); - colors.push(Math.random() * 255); - colors.push(Math.random() * 255); - } - - const positionAttribute = new THREE.Float32BufferAttribute(positions, 3); - const colorAttribute = new THREE.Uint8BufferAttribute(colors, 4); - colorAttribute.normalized = true; - - geometry.setAttribute('position', positionAttribute); - geometry.setAttribute('color', colorAttribute); - - // material - - material = new THREE.ShaderMaterial({ - uniforms: { - time: { value: 1.0 }, - }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - side: THREE.DoubleSide, - transparent: true, - vertexColors: true, - }); - - material.extensions.clipCullDistance = true; - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - controls = new OrbitControls(camera, renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - stats.update(); - - material.uniforms.time.value = clock.getElapsedTime(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_clipping.ts b/examples-testing/examples/webgl_clipping.ts deleted file mode 100644 index cde10c7d1..000000000 --- a/examples-testing/examples/webgl_clipping.ts +++ /dev/null @@ -1,195 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, startTime, object, stats; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 0.25, 16); - - camera.position.set(0, 1.3, 3); - - scene = new THREE.Scene(); - - // Lights - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const spotLight = new THREE.SpotLight(0xffffff, 60); - spotLight.angle = Math.PI / 5; - spotLight.penumbra = 0.2; - spotLight.position.set(2, 3, 3); - spotLight.castShadow = true; - spotLight.shadow.camera.near = 3; - spotLight.shadow.camera.far = 10; - spotLight.shadow.mapSize.width = 1024; - spotLight.shadow.mapSize.height = 1024; - scene.add(spotLight); - - const dirLight = new THREE.DirectionalLight(0x55505a, 3); - dirLight.position.set(0, 3, 0); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 1; - dirLight.shadow.camera.far = 10; - - dirLight.shadow.camera.right = 1; - dirLight.shadow.camera.left = -1; - dirLight.shadow.camera.top = 1; - dirLight.shadow.camera.bottom = -1; - - dirLight.shadow.mapSize.width = 1024; - dirLight.shadow.mapSize.height = 1024; - scene.add(dirLight); - - // ***** Clipping planes: ***** - - const localPlane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.8); - const globalPlane = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.1); - - // Geometry - - const material = new THREE.MeshPhongMaterial({ - color: 0x80ee10, - shininess: 100, - side: THREE.DoubleSide, - - // ***** Clipping setup (material): ***** - clippingPlanes: [localPlane], - clipShadows: true, - - alphaToCoverage: true, - }); - - const geometry = new THREE.TorusKnotGeometry(0.4, 0.08, 95, 20); - - object = new THREE.Mesh(geometry, material); - object.castShadow = true; - scene.add(object); - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(9, 9, 1, 1), - new THREE.MeshPhongMaterial({ color: 0xa0adaf, shininess: 150 }), - ); - - ground.rotation.x = -Math.PI / 2; // rotates X/Y to X/Z - ground.receiveShadow = true; - scene.add(ground); - - // Renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - // ***** Clipping setup (renderer): ***** - const globalPlanes = [globalPlane], - Empty = Object.freeze([]); - renderer.clippingPlanes = Empty; // GUI sets it to globalPlanes - renderer.localClippingEnabled = true; - - // Stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // Controls - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 1, 0); - controls.update(); - - // GUI - - const gui = new GUI(), - props = { - alphaToCoverage: true, - }, - folderLocal = gui.addFolder('Local Clipping'), - propsLocal = { - get Enabled() { - return renderer.localClippingEnabled; - }, - set Enabled(v) { - renderer.localClippingEnabled = v; - }, - - get Shadows() { - return material.clipShadows; - }, - set Shadows(v) { - material.clipShadows = v; - }, - - get Plane() { - return localPlane.constant; - }, - set Plane(v) { - localPlane.constant = v; - }, - }, - folderGlobal = gui.addFolder('Global Clipping'), - propsGlobal = { - get Enabled() { - return renderer.clippingPlanes !== Empty; - }, - set Enabled(v) { - renderer.clippingPlanes = v ? globalPlanes : Empty; - }, - - get Plane() { - return globalPlane.constant; - }, - set Plane(v) { - globalPlane.constant = v; - }, - }; - - gui.add(props, 'alphaToCoverage').onChange(function (value) { - ground.material.alphaToCoverage = value; - ground.material.needsUpdate = true; - - material.alphaToCoverage = value; - material.needsUpdate = true; - }); - folderLocal.add(propsLocal, 'Enabled'); - folderLocal.add(propsLocal, 'Shadows'); - folderLocal.add(propsLocal, 'Plane', 0.3, 1.25); - - folderGlobal.add(propsGlobal, 'Enabled'); - folderGlobal.add(propsGlobal, 'Plane', -0.4, 3); - - // Start - - startTime = Date.now(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const currentTime = Date.now(); - const time = (currentTime - startTime) / 1000; - - object.position.y = 0.8; - object.rotation.x = time * 0.5; - object.rotation.y = time * 0.2; - object.scale.setScalar(Math.cos(time) * 0.125 + 0.875); - - stats.begin(); - renderer.render(scene, camera); - stats.end(); -} diff --git a/examples-testing/examples/webgl_clipping_advanced.ts b/examples-testing/examples/webgl_clipping_advanced.ts deleted file mode 100644 index 614d710da..000000000 --- a/examples-testing/examples/webgl_clipping_advanced.ts +++ /dev/null @@ -1,355 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -function planesFromMesh(vertices, indices) { - // creates a clipping volume from a convex triangular mesh - // specified by the arrays 'vertices' and 'indices' - - const n = indices.length / 3, - result = new Array(n); - - for (let i = 0, j = 0; i < n; ++i, j += 3) { - const a = vertices[indices[j]], - b = vertices[indices[j + 1]], - c = vertices[indices[j + 2]]; - - result[i] = new THREE.Plane().setFromCoplanarPoints(a, b, c); - } - - return result; -} - -function createPlanes(n) { - // creates an array of n uninitialized plane objects - - const result = new Array(n); - - for (let i = 0; i !== n; ++i) result[i] = new THREE.Plane(); - - return result; -} - -function assignTransformedPlanes(planesOut, planesIn, matrix) { - // sets an array of existing planes to transformed 'planesIn' - - for (let i = 0, n = planesIn.length; i !== n; ++i) planesOut[i].copy(planesIn[i]).applyMatrix4(matrix); -} - -function cylindricalPlanes(n, innerRadius) { - const result = createPlanes(n); - - for (let i = 0; i !== n; ++i) { - const plane = result[i], - angle = (i * Math.PI * 2) / n; - - plane.normal.set(Math.cos(angle), 0, Math.sin(angle)); - - plane.constant = innerRadius; - } - - return result; -} - -const planeToMatrix = (function () { - // creates a matrix that aligns X/Y to a given plane - - // temporaries: - const xAxis = new THREE.Vector3(), - yAxis = new THREE.Vector3(), - trans = new THREE.Vector3(); - - return function planeToMatrix(plane) { - const zAxis = plane.normal, - matrix = new THREE.Matrix4(); - - // Hughes & Moeller '99 - // "Building an Orthonormal Basis from a Unit Vector." - - if (Math.abs(zAxis.x) > Math.abs(zAxis.z)) { - yAxis.set(-zAxis.y, zAxis.x, 0); - } else { - yAxis.set(0, -zAxis.z, zAxis.y); - } - - xAxis.crossVectors(yAxis.normalize(), zAxis); - - plane.coplanarPoint(trans); - return matrix.set( - xAxis.x, - yAxis.x, - zAxis.x, - trans.x, - xAxis.y, - yAxis.y, - zAxis.y, - trans.y, - xAxis.z, - yAxis.z, - zAxis.z, - trans.z, - 0, - 0, - 0, - 1, - ); - }; -})(); - -// A regular tetrahedron for the clipping volume: - -const Vertices = [ - new THREE.Vector3(+1, 0, +Math.SQRT1_2), - new THREE.Vector3(-1, 0, +Math.SQRT1_2), - new THREE.Vector3(0, +1, -Math.SQRT1_2), - new THREE.Vector3(0, -1, -Math.SQRT1_2), - ], - Indices = [0, 1, 2, 0, 2, 3, 0, 3, 1, 1, 3, 2], - Planes = planesFromMesh(Vertices, Indices), - PlaneMatrices = Planes.map(planeToMatrix), - GlobalClippingPlanes = cylindricalPlanes(5, 2.5), - Empty = Object.freeze([]); - -let camera, scene, renderer, startTime, stats, object, clipMaterial, volumeVisualization, globalClippingPlanes; - -function init() { - camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 0.25, 16); - - camera.position.set(0, 1.5, 3); - - scene = new THREE.Scene(); - - // Lights - - scene.add(new THREE.AmbientLight(0xffffff)); - - const spotLight = new THREE.SpotLight(0xffffff, 60); - spotLight.angle = Math.PI / 5; - spotLight.penumbra = 0.2; - spotLight.position.set(2, 3, 3); - spotLight.castShadow = true; - spotLight.shadow.camera.near = 3; - spotLight.shadow.camera.far = 10; - spotLight.shadow.mapSize.width = 1024; - spotLight.shadow.mapSize.height = 1024; - scene.add(spotLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 1.5); - dirLight.position.set(0, 2, 0); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 1; - dirLight.shadow.camera.far = 10; - - dirLight.shadow.camera.right = 1; - dirLight.shadow.camera.left = -1; - dirLight.shadow.camera.top = 1; - dirLight.shadow.camera.bottom = -1; - - dirLight.shadow.mapSize.width = 1024; - dirLight.shadow.mapSize.height = 1024; - scene.add(dirLight); - - // Geometry - - clipMaterial = new THREE.MeshPhongMaterial({ - color: 0xee0a10, - shininess: 100, - side: THREE.DoubleSide, - // Clipping setup: - clippingPlanes: createPlanes(Planes.length), - clipShadows: true, - }); - - object = new THREE.Group(); - - const geometry = new THREE.BoxGeometry(0.18, 0.18, 0.18); - - for (let z = -2; z <= 2; ++z) - for (let y = -2; y <= 2; ++y) - for (let x = -2; x <= 2; ++x) { - const mesh = new THREE.Mesh(geometry, clipMaterial); - mesh.position.set(x / 5, y / 5, z / 5); - mesh.castShadow = true; - object.add(mesh); - } - - scene.add(object); - - const planeGeometry = new THREE.PlaneGeometry(3, 3, 1, 1), - color = new THREE.Color(); - - volumeVisualization = new THREE.Group(); - volumeVisualization.visible = false; - - for (let i = 0, n = Planes.length; i !== n; ++i) { - const material = new THREE.MeshBasicMaterial({ - color: color.setHSL(i / n, 0.5, 0.5).getHex(), - side: THREE.DoubleSide, - - opacity: 0.2, - transparent: true, - - // clip to the others to show the volume (wildly - // intersecting transparent planes look bad) - clippingPlanes: clipMaterial.clippingPlanes.filter(function (_, j) { - return j !== i; - }), - - // no need to enable shadow clipping - the plane - // visualization does not cast shadows - }); - - const mesh = new THREE.Mesh(planeGeometry, material); - mesh.matrixAutoUpdate = false; - - volumeVisualization.add(mesh); - } - - scene.add(volumeVisualization); - - const ground = new THREE.Mesh( - planeGeometry, - new THREE.MeshPhongMaterial({ - color: 0xa0adaf, - shininess: 10, - }), - ); - ground.rotation.x = -Math.PI / 2; - ground.scale.multiplyScalar(3); - ground.receiveShadow = true; - scene.add(ground); - - // Renderer - - const container = document.body; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - container.appendChild(renderer.domElement); - // Clipping setup: - globalClippingPlanes = createPlanes(GlobalClippingPlanes.length); - renderer.clippingPlanes = Empty; - renderer.localClippingEnabled = true; - - window.addEventListener('resize', onWindowResize); - - // Stats - - stats = new Stats(); - container.appendChild(stats.dom); - - // Controls - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 8; - controls.target.set(0, 1, 0); - controls.update(); - - // GUI - - const gui = new GUI(), - folder = gui.addFolder('Local Clipping'), - props = { - get Enabled() { - return renderer.localClippingEnabled; - }, - set Enabled(v) { - renderer.localClippingEnabled = v; - if (!v) volumeVisualization.visible = false; - }, - - get Shadows() { - return clipMaterial.clipShadows; - }, - set Shadows(v) { - clipMaterial.clipShadows = v; - }, - - get Visualize() { - return volumeVisualization.visible; - }, - set Visualize(v) { - if (renderer.localClippingEnabled) volumeVisualization.visible = v; - }, - }; - - folder.add(props, 'Enabled'); - folder.add(props, 'Shadows'); - folder.add(props, 'Visualize').listen(); - - gui.addFolder('Global Clipping').add( - { - get Enabled() { - return renderer.clippingPlanes !== Empty; - }, - set Enabled(v) { - renderer.clippingPlanes = v ? globalClippingPlanes : Empty; - }, - }, - 'Enabled', - ); - - // Start - - startTime = Date.now(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function setObjectWorldMatrix(object, matrix) { - // set the orientation of an object based on a world matrix - - const parent = object.parent; - scene.updateMatrixWorld(); - object.matrix.copy(parent.matrixWorld).invert(); - object.applyMatrix4(matrix); -} - -const transform = new THREE.Matrix4(), - tmpMatrix = new THREE.Matrix4(); - -function animate() { - const currentTime = Date.now(), - time = (currentTime - startTime) / 1000; - - object.position.y = 1; - object.rotation.x = time * 0.5; - object.rotation.y = time * 0.2; - - object.updateMatrix(); - transform.copy(object.matrix); - - const bouncy = Math.cos(time * 0.5) * 0.5 + 0.7; - transform.multiply(tmpMatrix.makeScale(bouncy, bouncy, bouncy)); - - assignTransformedPlanes(clipMaterial.clippingPlanes, Planes, transform); - - const planeMeshes = volumeVisualization.children; - - for (let i = 0, n = planeMeshes.length; i !== n; ++i) { - tmpMatrix.multiplyMatrices(transform, PlaneMatrices[i]); - setObjectWorldMatrix(planeMeshes[i], tmpMatrix); - } - - transform.makeRotationY(time * 0.1); - - assignTransformedPlanes(globalClippingPlanes, GlobalClippingPlanes, transform); - - stats.begin(); - renderer.render(scene, camera); - stats.end(); -} - -init(); diff --git a/examples-testing/examples/webgl_clipping_intersection.ts b/examples-testing/examples/webgl_clipping_intersection.ts deleted file mode 100644 index 5f45e45df..000000000 --- a/examples-testing/examples/webgl_clipping_intersection.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -const params = { - clipIntersection: true, - planeConstant: 0, - showHelpers: false, - alphaToCoverage: true, -}; - -const clipPlanes = [ - new THREE.Plane(new THREE.Vector3(1, 0, 0), 0), - new THREE.Plane(new THREE.Vector3(0, -1, 0), 0), - new THREE.Plane(new THREE.Vector3(0, 0, -1), 0), -]; - -init(); -render(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.localClippingEnabled = true; - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 200); - - camera.position.set(-1.5, 2.5, 3.0); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use only if there is no animation loop - controls.minDistance = 1; - controls.maxDistance = 10; - controls.enablePan = false; - - const light = new THREE.HemisphereLight(0xffffff, 0x080808, 4.5); - light.position.set(-1.25, 1, 1.25); - scene.add(light); - - // - - const group = new THREE.Group(); - - for (let i = 1; i <= 30; i += 2) { - const geometry = new THREE.SphereGeometry(i / 30, 48, 24); - - const material = new THREE.MeshPhongMaterial({ - color: new THREE.Color().setHSL(Math.random(), 0.5, 0.5, THREE.SRGBColorSpace), - side: THREE.DoubleSide, - clippingPlanes: clipPlanes, - clipIntersection: params.clipIntersection, - alphaToCoverage: true, - }); - - group.add(new THREE.Mesh(geometry, material)); - } - - scene.add(group); - - // helpers - - const helpers = new THREE.Group(); - helpers.add(new THREE.PlaneHelper(clipPlanes[0], 2, 0xff0000)); - helpers.add(new THREE.PlaneHelper(clipPlanes[1], 2, 0x00ff00)); - helpers.add(new THREE.PlaneHelper(clipPlanes[2], 2, 0x0000ff)); - helpers.visible = false; - scene.add(helpers); - - // gui - - const gui = new GUI(); - - gui.add(params, 'alphaToCoverage').onChange(function (value) { - group.children.forEach(c => { - c.material.alphaToCoverage = Boolean(value); - c.material.needsUpdate = true; - }); - - render(); - }); - - gui.add(params, 'clipIntersection') - .name('clip intersection') - .onChange(function (value) { - const children = group.children; - - for (let i = 0; i < children.length; i++) { - children[i].material.clipIntersection = value; - } - - render(); - }); - - gui.add(params, 'planeConstant', -1, 1) - .step(0.01) - .name('plane constant') - .onChange(function (value) { - for (let j = 0; j < clipPlanes.length; j++) { - clipPlanes[j].constant = value; - } - - render(); - }); - - gui.add(params, 'showHelpers') - .name('show helpers') - .onChange(function (value) { - helpers.visible = value; - - render(); - }); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_clipping_stencil.ts b/examples-testing/examples/webgl_clipping_stencil.ts deleted file mode 100644 index ecb6b42b8..000000000 --- a/examples-testing/examples/webgl_clipping_stencil.ts +++ /dev/null @@ -1,260 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, object, stats; -let planes, planeObjects, planeHelpers; -let clock; - -const params = { - animate: true, - planeX: { - constant: 0, - negated: false, - displayHelper: false, - }, - planeY: { - constant: 0, - negated: false, - displayHelper: false, - }, - planeZ: { - constant: 0, - negated: false, - displayHelper: false, - }, -}; - -init(); - -function createPlaneStencilGroup(geometry, plane, renderOrder) { - const group = new THREE.Group(); - const baseMat = new THREE.MeshBasicMaterial(); - baseMat.depthWrite = false; - baseMat.depthTest = false; - baseMat.colorWrite = false; - baseMat.stencilWrite = true; - baseMat.stencilFunc = THREE.AlwaysStencilFunc; - - // back faces - const mat0 = baseMat.clone(); - mat0.side = THREE.BackSide; - mat0.clippingPlanes = [plane]; - mat0.stencilFail = THREE.IncrementWrapStencilOp; - mat0.stencilZFail = THREE.IncrementWrapStencilOp; - mat0.stencilZPass = THREE.IncrementWrapStencilOp; - - const mesh0 = new THREE.Mesh(geometry, mat0); - mesh0.renderOrder = renderOrder; - group.add(mesh0); - - // front faces - const mat1 = baseMat.clone(); - mat1.side = THREE.FrontSide; - mat1.clippingPlanes = [plane]; - mat1.stencilFail = THREE.DecrementWrapStencilOp; - mat1.stencilZFail = THREE.DecrementWrapStencilOp; - mat1.stencilZPass = THREE.DecrementWrapStencilOp; - - const mesh1 = new THREE.Mesh(geometry, mat1); - mesh1.renderOrder = renderOrder; - - group.add(mesh1); - - return group; -} - -function init() { - clock = new THREE.Clock(); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(2, 2, 2); - - scene.add(new THREE.AmbientLight(0xffffff, 1.5)); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(5, 10, 7.5); - dirLight.castShadow = true; - dirLight.shadow.camera.right = 2; - dirLight.shadow.camera.left = -2; - dirLight.shadow.camera.top = 2; - dirLight.shadow.camera.bottom = -2; - - dirLight.shadow.mapSize.width = 1024; - dirLight.shadow.mapSize.height = 1024; - scene.add(dirLight); - - planes = [ - new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0), - new THREE.Plane(new THREE.Vector3(0, -1, 0), 0), - new THREE.Plane(new THREE.Vector3(0, 0, -1), 0), - ]; - - planeHelpers = planes.map(p => new THREE.PlaneHelper(p, 2, 0xffffff)); - planeHelpers.forEach(ph => { - ph.visible = false; - scene.add(ph); - }); - - const geometry = new THREE.TorusKnotGeometry(0.4, 0.15, 220, 60); - object = new THREE.Group(); - scene.add(object); - - // Set up clip plane rendering - planeObjects = []; - const planeGeom = new THREE.PlaneGeometry(4, 4); - - for (let i = 0; i < 3; i++) { - const poGroup = new THREE.Group(); - const plane = planes[i]; - const stencilGroup = createPlaneStencilGroup(geometry, plane, i + 1); - - // plane is clipped by the other clipping planes - const planeMat = new THREE.MeshStandardMaterial({ - color: 0xe91e63, - metalness: 0.1, - roughness: 0.75, - clippingPlanes: planes.filter(p => p !== plane), - - stencilWrite: true, - stencilRef: 0, - stencilFunc: THREE.NotEqualStencilFunc, - stencilFail: THREE.ReplaceStencilOp, - stencilZFail: THREE.ReplaceStencilOp, - stencilZPass: THREE.ReplaceStencilOp, - }); - const po = new THREE.Mesh(planeGeom, planeMat); - po.onAfterRender = function (renderer) { - renderer.clearStencil(); - }; - - po.renderOrder = i + 1.1; - - object.add(stencilGroup); - poGroup.add(po); - planeObjects.push(po); - scene.add(poGroup); - } - - const material = new THREE.MeshStandardMaterial({ - color: 0xffc107, - metalness: 0.1, - roughness: 0.75, - clippingPlanes: planes, - clipShadows: true, - shadowSide: THREE.DoubleSide, - }); - - // add the color - const clippedColorFront = new THREE.Mesh(geometry, material); - clippedColorFront.castShadow = true; - clippedColorFront.renderOrder = 6; - object.add(clippedColorFront); - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(9, 9, 1, 1), - new THREE.ShadowMaterial({ color: 0x000000, opacity: 0.25, side: THREE.DoubleSide }), - ); - - ground.rotation.x = -Math.PI / 2; // rotates X/Y to X/Z - ground.position.y = -1; - ground.receiveShadow = true; - scene.add(ground); - - // Renderer - renderer = new THREE.WebGLRenderer({ antialias: true, stencil: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setClearColor(0x263238); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.localClippingEnabled = true; - document.body.appendChild(renderer.domElement); - - // Stats - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - - // Controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 20; - controls.update(); - - // GUI - const gui = new GUI(); - gui.add(params, 'animate'); - - const planeX = gui.addFolder('planeX'); - planeX.add(params.planeX, 'displayHelper').onChange(v => (planeHelpers[0].visible = v)); - planeX - .add(params.planeX, 'constant') - .min(-1) - .max(1) - .onChange(d => (planes[0].constant = d)); - planeX.add(params.planeX, 'negated').onChange(() => { - planes[0].negate(); - params.planeX.constant = planes[0].constant; - }); - planeX.open(); - - const planeY = gui.addFolder('planeY'); - planeY.add(params.planeY, 'displayHelper').onChange(v => (planeHelpers[1].visible = v)); - planeY - .add(params.planeY, 'constant') - .min(-1) - .max(1) - .onChange(d => (planes[1].constant = d)); - planeY.add(params.planeY, 'negated').onChange(() => { - planes[1].negate(); - params.planeY.constant = planes[1].constant; - }); - planeY.open(); - - const planeZ = gui.addFolder('planeZ'); - planeZ.add(params.planeZ, 'displayHelper').onChange(v => (planeHelpers[2].visible = v)); - planeZ - .add(params.planeZ, 'constant') - .min(-1) - .max(1) - .onChange(d => (planes[2].constant = d)); - planeZ.add(params.planeZ, 'negated').onChange(() => { - planes[2].negate(); - params.planeZ.constant = planes[2].constant; - }); - planeZ.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (params.animate) { - object.rotation.x += delta * 0.5; - object.rotation.y += delta * 0.2; - } - - for (let i = 0; i < planeObjects.length; i++) { - const plane = planes[i]; - const po = planeObjects[i]; - plane.coplanarPoint(po.position); - po.lookAt(po.position.x - plane.normal.x, po.position.y - plane.normal.y, po.position.z - plane.normal.z); - } - - stats.begin(); - renderer.render(scene, camera); - stats.end(); -} diff --git a/examples-testing/examples/webgl_custom_attributes.ts b/examples-testing/examples/webgl_custom_attributes.ts deleted file mode 100644 index 0dc897748..000000000 --- a/examples-testing/examples/webgl_custom_attributes.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let renderer, scene, camera, stats; - -let sphere, uniforms; - -let displacement, noise; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 300; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - - uniforms = { - amplitude: { value: 1.0 }, - color: { value: new THREE.Color(0xff2200) }, - colorTexture: { value: new THREE.TextureLoader().load('textures/water.jpg') }, - }; - - uniforms['colorTexture'].value.wrapS = uniforms['colorTexture'].value.wrapT = THREE.RepeatWrapping; - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - }); - - const radius = 50, - segments = 128, - rings = 64; - - const geometry = new THREE.SphereGeometry(radius, segments, rings); - - displacement = new Float32Array(geometry.attributes.position.count); - noise = new Float32Array(geometry.attributes.position.count); - - for (let i = 0; i < displacement.length; i++) { - noise[i] = Math.random() * 5; - } - - geometry.setAttribute('displacement', new THREE.BufferAttribute(displacement, 1)); - - sphere = new THREE.Mesh(geometry, shaderMaterial); - scene.add(sphere); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.01; - - sphere.rotation.y = sphere.rotation.z = 0.01 * time; - - uniforms['amplitude'].value = 2.5 * Math.sin(sphere.rotation.y * 0.125); - uniforms['color'].value.offsetHSL(0.0005, 0, 0); - - for (let i = 0; i < displacement.length; i++) { - displacement[i] = Math.sin(0.1 * i + time); - - noise[i] += 0.5 * (0.5 - Math.random()); - noise[i] = THREE.MathUtils.clamp(noise[i], -5, 5); - - displacement[i] += noise[i]; - } - - sphere.geometry.attributes.displacement.needsUpdate = true; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_custom_attributes_lines.ts b/examples-testing/examples/webgl_custom_attributes_lines.ts deleted file mode 100644 index 3e2454e92..000000000 --- a/examples-testing/examples/webgl_custom_attributes_lines.ts +++ /dev/null @@ -1,121 +0,0 @@ -import * as THREE from 'three'; - -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let renderer, scene, camera, stats; - -let line, uniforms; - -const loader = new FontLoader(); -loader.load('fonts/helvetiker_bold.typeface.json', function (font) { - init(font); -}); - -function init(font) { - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 400; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - - uniforms = { - amplitude: { value: 5.0 }, - opacity: { value: 0.3 }, - color: { value: new THREE.Color(0xffffff) }, - }; - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, - }); - - const geometry = new TextGeometry('three.js', { - font: font, - - size: 50, - depth: 15, - curveSegments: 10, - - bevelThickness: 5, - bevelSize: 1.5, - bevelEnabled: true, - bevelSegments: 10, - }); - - geometry.center(); - - const count = geometry.attributes.position.count; - - const displacement = new THREE.Float32BufferAttribute(count * 3, 3); - geometry.setAttribute('displacement', displacement); - - const customColor = new THREE.Float32BufferAttribute(count * 3, 3); - geometry.setAttribute('customColor', customColor); - - const color = new THREE.Color(0xffffff); - - for (let i = 0, l = customColor.count; i < l; i++) { - color.setHSL(i / l, 0.5, 0.5); - color.toArray(customColor.array, i * customColor.itemSize); - } - - line = new THREE.Line(geometry, shaderMaterial); - line.rotation.x = 0.2; - scene.add(line); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.001; - - line.rotation.y = 0.25 * time; - - uniforms.amplitude.value = Math.sin(0.5 * time); - uniforms.color.value.offsetHSL(0.0005, 0, 0); - - const attributes = line.geometry.attributes; - const array = attributes.displacement.array; - - for (let i = 0, l = array.length; i < l; i += 3) { - array[i] += 0.3 * (0.5 - Math.random()); - array[i + 1] += 0.3 * (0.5 - Math.random()); - array[i + 2] += 0.3 * (0.5 - Math.random()); - } - - attributes.displacement.needsUpdate = true; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_custom_attributes_points.ts b/examples-testing/examples/webgl_custom_attributes_points.ts deleted file mode 100644 index ae112980a..000000000 --- a/examples-testing/examples/webgl_custom_attributes_points.ts +++ /dev/null @@ -1,117 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let renderer, scene, camera, stats; - -let sphere; - -const WIDTH = window.innerWidth; -const HEIGHT = window.innerHeight; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(40, WIDTH / HEIGHT, 1, 10000); - camera.position.z = 300; - - scene = new THREE.Scene(); - - const amount = 100000; - const radius = 200; - - const positions = new Float32Array(amount * 3); - const colors = new Float32Array(amount * 3); - const sizes = new Float32Array(amount); - - const vertex = new THREE.Vector3(); - const color = new THREE.Color(0xffffff); - - for (let i = 0; i < amount; i++) { - vertex.x = (Math.random() * 2 - 1) * radius; - vertex.y = (Math.random() * 2 - 1) * radius; - vertex.z = (Math.random() * 2 - 1) * radius; - vertex.toArray(positions, i * 3); - - if (vertex.x < 0) { - color.setHSL(0.5 + 0.1 * (i / amount), 0.7, 0.5); - } else { - color.setHSL(0.0 + 0.1 * (i / amount), 0.9, 0.5); - } - - color.toArray(colors, i * 3); - - sizes[i] = 10; - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute('customColor', new THREE.BufferAttribute(colors, 3)); - geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1)); - - // - - const material = new THREE.ShaderMaterial({ - uniforms: { - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: new THREE.TextureLoader().load('textures/sprites/spark1.png') }, - }, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - - blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, - }); - - // - - sphere = new THREE.Points(geometry, material); - scene.add(sphere); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.005; - - sphere.rotation.z = 0.01 * time; - - const geometry = sphere.geometry; - const attributes = geometry.attributes; - - for (let i = 0; i < attributes.size.array.length; i++) { - attributes.size.array[i] = 14 + 13 * Math.sin(0.1 * i + time); - } - - attributes.size.needsUpdate = true; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_custom_attributes_points2.ts b/examples-testing/examples/webgl_custom_attributes_points2.ts deleted file mode 100644 index edd158fa1..000000000 --- a/examples-testing/examples/webgl_custom_attributes_points2.ts +++ /dev/null @@ -1,193 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let renderer, scene, camera, stats; -let sphere, length1; - -const WIDTH = window.innerWidth; -const HEIGHT = window.innerHeight; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 1, 10000); - camera.position.z = 300; - - scene = new THREE.Scene(); - - const radius = 100, - segments = 68, - rings = 38; - - let sphereGeometry = new THREE.SphereGeometry(radius, segments, rings); - let boxGeometry = new THREE.BoxGeometry(0.8 * radius, 0.8 * radius, 0.8 * radius, 10, 10, 10); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate identical vertices with different normal/uv data - - sphereGeometry.deleteAttribute('normal'); - sphereGeometry.deleteAttribute('uv'); - - boxGeometry.deleteAttribute('normal'); - boxGeometry.deleteAttribute('uv'); - - sphereGeometry = BufferGeometryUtils.mergeVertices(sphereGeometry); - boxGeometry = BufferGeometryUtils.mergeVertices(boxGeometry); - - const combinedGeometry = BufferGeometryUtils.mergeGeometries([sphereGeometry, boxGeometry]); - const positionAttribute = combinedGeometry.getAttribute('position'); - - const colors = []; - const sizes = []; - - const color = new THREE.Color(); - const vertex = new THREE.Vector3(); - - length1 = sphereGeometry.getAttribute('position').count; - - for (let i = 0, l = positionAttribute.count; i < l; i++) { - vertex.fromBufferAttribute(positionAttribute, i); - - if (i < length1) { - color.setHSL(0.01 + 0.1 * (i / length1), 0.99, (vertex.y + radius) / (4 * radius)); - } else { - color.setHSL(0.6, 0.75, 0.25 + vertex.y / (2 * radius)); - } - - color.toArray(colors, i * 3); - - sizes[i] = i < length1 ? 10 : 40; - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', positionAttribute); - geometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1)); - geometry.setAttribute('ca', new THREE.Float32BufferAttribute(colors, 3)); - - // - - const texture = new THREE.TextureLoader().load('textures/sprites/disc.png'); - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - - const material = new THREE.ShaderMaterial({ - uniforms: { - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: texture }, - }, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - transparent: true, - }); - - // - - sphere = new THREE.Points(geometry, material); - scene.add(sphere); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function sortPoints() { - const vector = new THREE.Vector3(); - - // Model View Projection matrix - - const matrix = new THREE.Matrix4(); - matrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - matrix.multiply(sphere.matrixWorld); - - // - - const geometry = sphere.geometry; - - let index = geometry.getIndex(); - const positions = geometry.getAttribute('position').array; - const length = positions.length / 3; - - if (index === null) { - const array = new Uint16Array(length); - - for (let i = 0; i < length; i++) { - array[i] = i; - } - - index = new THREE.BufferAttribute(array, 1); - - geometry.setIndex(index); - } - - const sortArray = []; - - for (let i = 0; i < length; i++) { - vector.fromArray(positions, i * 3); - vector.applyMatrix4(matrix); - - sortArray.push([vector.z, i]); - } - - function numericalSort(a, b) { - return b[0] - a[0]; - } - - sortArray.sort(numericalSort); - - const indices = index.array; - - for (let i = 0; i < length; i++) { - indices[i] = sortArray[i][1]; - } - - geometry.index.needsUpdate = true; -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.005; - - sphere.rotation.y = 0.02 * time; - sphere.rotation.z = 0.02 * time; - - const geometry = sphere.geometry; - const attributes = geometry.attributes; - - for (let i = 0; i < attributes.size.array.length; i++) { - if (i < length1) { - attributes.size.array[i] = 16 + 12 * Math.sin(0.1 * i + time); - } - } - - attributes.size.needsUpdate = true; - - sortPoints(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_custom_attributes_points3.ts b/examples-testing/examples/webgl_custom_attributes_points3.ts deleted file mode 100644 index 1b46a805e..000000000 --- a/examples-testing/examples/webgl_custom_attributes_points3.ts +++ /dev/null @@ -1,200 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let renderer, scene, camera, stats; - -let object; - -let vertices1; - -const WIDTH = window.innerWidth; -const HEIGHT = window.innerHeight; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(40, WIDTH / HEIGHT, 1, 1000); - camera.position.z = 500; - - scene = new THREE.Scene(); - - let radius = 100; - const inner = 0.6 * radius; - const vertex = new THREE.Vector3(); - const vertices = []; - - for (let i = 0; i < 100000; i++) { - vertex.x = Math.random() * 2 - 1; - vertex.y = Math.random() * 2 - 1; - vertex.z = Math.random() * 2 - 1; - vertex.multiplyScalar(radius); - - if ( - vertex.x > inner || - vertex.x < -inner || - vertex.y > inner || - vertex.y < -inner || - vertex.z > inner || - vertex.z < -inner - ) - vertices.push(vertex.x, vertex.y, vertex.z); - } - - vertices1 = vertices.length / 3; - - radius = 200; - - let boxGeometry1 = new THREE.BoxGeometry(radius, 0.1 * radius, 0.1 * radius, 50, 5, 5); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data - - boxGeometry1.deleteAttribute('normal'); - boxGeometry1.deleteAttribute('uv'); - - boxGeometry1 = BufferGeometryUtils.mergeVertices(boxGeometry1); - - const matrix = new THREE.Matrix4(); - const position = new THREE.Vector3(); - const rotation = new THREE.Euler(); - const quaternion = new THREE.Quaternion(); - const scale = new THREE.Vector3(1, 1, 1); - - function addGeo(geo, x, y, z, ry) { - position.set(x, y, z); - rotation.set(0, ry, 0); - - matrix.compose(position, quaternion.setFromEuler(rotation), scale); - - const positionAttribute = geo.getAttribute('position'); - - for (let i = 0, l = positionAttribute.count; i < l; i++) { - vertex.fromBufferAttribute(positionAttribute, i); - vertex.applyMatrix4(matrix); - vertices.push(vertex.x, vertex.y, vertex.z); - } - } - - // side 1 - - addGeo(boxGeometry1, 0, 110, 110, 0); - addGeo(boxGeometry1, 0, 110, -110, 0); - addGeo(boxGeometry1, 0, -110, 110, 0); - addGeo(boxGeometry1, 0, -110, -110, 0); - - // side 2 - - addGeo(boxGeometry1, 110, 110, 0, Math.PI / 2); - addGeo(boxGeometry1, 110, -110, 0, Math.PI / 2); - addGeo(boxGeometry1, -110, 110, 0, Math.PI / 2); - addGeo(boxGeometry1, -110, -110, 0, Math.PI / 2); - - // corner edges - - let boxGeometry2 = new THREE.BoxGeometry(0.1 * radius, radius * 1.2, 0.1 * radius, 5, 60, 5); - - boxGeometry2.deleteAttribute('normal'); - boxGeometry2.deleteAttribute('uv'); - - boxGeometry2 = BufferGeometryUtils.mergeVertices(boxGeometry2); - - addGeo(boxGeometry2, 110, 0, 110, 0); - addGeo(boxGeometry2, 110, 0, -110, 0); - addGeo(boxGeometry2, -110, 0, 110, 0); - addGeo(boxGeometry2, -110, 0, -110, 0); - - const positionAttribute = new THREE.Float32BufferAttribute(vertices, 3); - - const colors = []; - const sizes = []; - - const color = new THREE.Color(); - - for (let i = 0; i < positionAttribute.count; i++) { - if (i < vertices1) { - color.setHSL(0.5 + 0.2 * (i / vertices1), 1, 0.5); - } else { - color.setHSL(0.1, 1, 0.5); - } - - color.toArray(colors, i * 3); - - sizes[i] = i < vertices1 ? 10 : 40; - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', positionAttribute); - geometry.setAttribute('ca', new THREE.Float32BufferAttribute(colors, 3)); - geometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1)); - - // - - const texture = new THREE.TextureLoader().load('textures/sprites/ball.png'); - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - - const material = new THREE.ShaderMaterial({ - uniforms: { - amplitude: { value: 1.0 }, - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: texture }, - }, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - }); - - // - - object = new THREE.Points(geometry, material); - scene.add(object); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.01; - - object.rotation.y = object.rotation.z = 0.02 * time; - - const geometry = object.geometry; - const attributes = geometry.attributes; - - for (let i = 0; i < attributes.size.array.length; i++) { - if (i < vertices1) { - attributes.size.array[i] = Math.max(0, 26 + 32 * Math.sin(0.1 * i + 0.6 * time)); - } - } - - attributes.size.needsUpdate = true; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_decals.ts b/examples-testing/examples/webgl_decals.ts deleted file mode 100644 index be3460834..000000000 --- a/examples-testing/examples/webgl_decals.ts +++ /dev/null @@ -1,239 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DecalGeometry } from 'three/addons/geometries/DecalGeometry.js'; - -const container = document.getElementById('container'); - -let renderer, scene, camera, stats; -let mesh; -let raycaster; -let line; - -const intersection = { - intersects: false, - point: new THREE.Vector3(), - normal: new THREE.Vector3(), -}; -const mouse = new THREE.Vector2(); -const intersects = []; - -const textureLoader = new THREE.TextureLoader(); -const decalDiffuse = textureLoader.load('textures/decal/decal-diffuse.png'); -decalDiffuse.colorSpace = THREE.SRGBColorSpace; -const decalNormal = textureLoader.load('textures/decal/decal-normal.jpg'); - -const decalMaterial = new THREE.MeshPhongMaterial({ - specular: 0x444444, - map: decalDiffuse, - normalMap: decalNormal, - normalScale: new THREE.Vector2(1, 1), - shininess: 30, - transparent: true, - depthTest: true, - depthWrite: false, - polygonOffset: true, - polygonOffsetFactor: -4, - wireframe: false, -}); - -const decals = []; -let mouseHelper; -const position = new THREE.Vector3(); -const orientation = new THREE.Euler(); -const size = new THREE.Vector3(10, 10, 10); - -const params = { - minScale: 10, - maxScale: 20, - rotate: true, - clear: function () { - removeDecals(); - }, -}; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 120; - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 50; - controls.maxDistance = 200; - - scene.add(new THREE.AmbientLight(0x666666)); - - const dirLight1 = new THREE.DirectionalLight(0xffddcc, 3); - dirLight1.position.set(1, 0.75, 0.5); - scene.add(dirLight1); - - const dirLight2 = new THREE.DirectionalLight(0xccccff, 3); - dirLight2.position.set(-1, 0.75, -0.5); - scene.add(dirLight2); - - const geometry = new THREE.BufferGeometry(); - geometry.setFromPoints([new THREE.Vector3(), new THREE.Vector3()]); - - line = new THREE.Line(geometry, new THREE.LineBasicMaterial()); - scene.add(line); - - loadLeePerrySmith(); - - raycaster = new THREE.Raycaster(); - - mouseHelper = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 10), new THREE.MeshNormalMaterial()); - mouseHelper.visible = false; - scene.add(mouseHelper); - - window.addEventListener('resize', onWindowResize); - - let moved = false; - - controls.addEventListener('change', function () { - moved = true; - }); - - window.addEventListener('pointerdown', function () { - moved = false; - }); - - window.addEventListener('pointerup', function (event) { - if (moved === false) { - checkIntersection(event.clientX, event.clientY); - - if (intersection.intersects) shoot(); - } - }); - - window.addEventListener('pointermove', onPointerMove); - - function onPointerMove(event) { - if (event.isPrimary) { - checkIntersection(event.clientX, event.clientY); - } - } - - function checkIntersection(x, y) { - if (mesh === undefined) return; - - mouse.x = (x / window.innerWidth) * 2 - 1; - mouse.y = -(y / window.innerHeight) * 2 + 1; - - raycaster.setFromCamera(mouse, camera); - raycaster.intersectObject(mesh, false, intersects); - - if (intersects.length > 0) { - const p = intersects[0].point; - mouseHelper.position.copy(p); - intersection.point.copy(p); - - const normalMatrix = new THREE.Matrix3().getNormalMatrix(mesh.matrixWorld); - - const n = intersects[0].face.normal.clone(); - n.applyNormalMatrix(normalMatrix); - n.multiplyScalar(10); - n.add(intersects[0].point); - - intersection.normal.copy(intersects[0].face.normal); - mouseHelper.lookAt(n); - - const positions = line.geometry.attributes.position; - positions.setXYZ(0, p.x, p.y, p.z); - positions.setXYZ(1, n.x, n.y, n.z); - positions.needsUpdate = true; - - intersection.intersects = true; - - intersects.length = 0; - } else { - intersection.intersects = false; - } - } - - const gui = new GUI(); - - gui.add(params, 'minScale', 1, 30); - gui.add(params, 'maxScale', 1, 30); - gui.add(params, 'rotate'); - gui.add(params, 'clear'); - gui.open(); -} - -function loadLeePerrySmith() { - const map = textureLoader.load('models/gltf/LeePerrySmith/Map-COL.jpg'); - map.colorSpace = THREE.SRGBColorSpace; - const specularMap = textureLoader.load('models/gltf/LeePerrySmith/Map-SPEC.jpg'); - const normalMap = textureLoader.load('models/gltf/LeePerrySmith/Infinite-Level_02_Tangent_SmoothUV.jpg'); - - const loader = new GLTFLoader(); - - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { - mesh = gltf.scene.children[0]; - mesh.material = new THREE.MeshPhongMaterial({ - specular: 0x111111, - map: map, - specularMap: specularMap, - normalMap: normalMap, - shininess: 25, - }); - - scene.add(mesh); - mesh.scale.set(10, 10, 10); - }); -} - -function shoot() { - position.copy(intersection.point); - orientation.copy(mouseHelper.rotation); - - if (params.rotate) orientation.z = Math.random() * 2 * Math.PI; - - const scale = params.minScale + Math.random() * (params.maxScale - params.minScale); - size.set(scale, scale, scale); - - const material = decalMaterial.clone(); - material.color.setHex(Math.random() * 0xffffff); - - const m = new THREE.Mesh(new DecalGeometry(mesh, position, orientation, size), material); - m.renderOrder = decals.length; // give decals a fixed render order - - decals.push(m); - scene.add(m); -} - -function removeDecals() { - decals.forEach(function (d) { - scene.remove(d); - }); - - decals.length = 0; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_effects_anaglyph.ts b/examples-testing/examples/webgl_effects_anaglyph.ts deleted file mode 100644 index 8415973df..000000000 --- a/examples-testing/examples/webgl_effects_anaglyph.ts +++ /dev/null @@ -1,114 +0,0 @@ -import * as THREE from 'three'; - -import { AnaglyphEffect } from 'three/addons/effects/AnaglyphEffect.js'; - -let container, camera, scene, renderer, effect; - -const spheres = []; - -let mouseX = 0; -let mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -document.addEventListener('mousemove', onDocumentMouseMove); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 100); - camera.position.z = 3; - - const path = 'textures/cube/pisa/'; - const format = '.png'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const textureCube = new THREE.CubeTextureLoader().load(urls); - - scene = new THREE.Scene(); - scene.background = textureCube; - - const geometry = new THREE.SphereGeometry(0.1, 32, 16); - const material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: textureCube }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = Math.random() * 10 - 5; - mesh.position.y = Math.random() * 10 - 5; - mesh.position.z = Math.random() * 10 - 5; - - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 3 + 1; - - scene.add(mesh); - - spheres.push(mesh); - } - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - const width = window.innerWidth || 2; - const height = window.innerHeight || 2; - - effect = new AnaglyphEffect(renderer); - effect.setSize(width, height); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - effect.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouseX = (event.clientX - windowHalfX) / 100; - mouseY = (event.clientY - windowHalfY) / 100; -} - -// - -function animate() { - render(); -} - -function render() { - const timer = 0.0001 * Date.now(); - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - for (let i = 0, il = spheres.length; i < il; i++) { - const sphere = spheres[i]; - - sphere.position.x = 5 * Math.cos(timer + i); - sphere.position.y = 5 * Math.sin(timer + i * 1.1); - } - - effect.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_effects_ascii.ts b/examples-testing/examples/webgl_effects_ascii.ts deleted file mode 100644 index a412bb79e..000000000 --- a/examples-testing/examples/webgl_effects_ascii.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as THREE from 'three'; - -import { AsciiEffect } from 'three/addons/effects/AsciiEffect.js'; -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - -let camera, controls, scene, renderer, effect; - -let sphere, plane; - -const start = Date.now(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.y = 150; - camera.position.z = 500; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0, 0, 0); - - const pointLight1 = new THREE.PointLight(0xffffff, 3, 0, 0); - pointLight1.position.set(500, 500, 500); - scene.add(pointLight1); - - const pointLight2 = new THREE.PointLight(0xffffff, 1, 0, 0); - pointLight2.position.set(-500, -500, -500); - scene.add(pointLight2); - - sphere = new THREE.Mesh(new THREE.SphereGeometry(200, 20, 10), new THREE.MeshPhongMaterial({ flatShading: true })); - scene.add(sphere); - - // Plane - - plane = new THREE.Mesh(new THREE.PlaneGeometry(400, 400), new THREE.MeshBasicMaterial({ color: 0xe0e0e0 })); - plane.position.y = -200; - plane.rotation.x = -Math.PI / 2; - scene.add(plane); - - renderer = new THREE.WebGLRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - effect = new AsciiEffect(renderer, ' .:-+*=%@#', { invert: true }); - effect.setSize(window.innerWidth, window.innerHeight); - effect.domElement.style.color = 'white'; - effect.domElement.style.backgroundColor = 'black'; - - // Special case: append effect.domElement, instead of renderer.domElement. - // AsciiEffect creates a custom domElement (a div container) where the ASCII elements are placed. - - document.body.appendChild(effect.domElement); - - controls = new TrackballControls(camera, effect.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - effect.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const timer = Date.now() - start; - - sphere.position.y = Math.abs(Math.sin(timer * 0.002)) * 150; - sphere.rotation.x = timer * 0.0003; - sphere.rotation.z = timer * 0.0002; - - controls.update(); - - effect.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_effects_parallaxbarrier.ts b/examples-testing/examples/webgl_effects_parallaxbarrier.ts deleted file mode 100644 index 90c867973..000000000 --- a/examples-testing/examples/webgl_effects_parallaxbarrier.ts +++ /dev/null @@ -1,110 +0,0 @@ -import * as THREE from 'three'; - -import { ParallaxBarrierEffect } from 'three/addons/effects/ParallaxBarrierEffect.js'; - -let container, camera, scene, renderer, effect; - -const spheres = []; - -let mouseX = 0; -let mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -document.addEventListener('mousemove', onDocumentMouseMove); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 100); - camera.position.z = 3; - - const path = 'textures/cube/pisa/'; - const format = '.png'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const textureCube = new THREE.CubeTextureLoader().load(urls); - - scene = new THREE.Scene(); - scene.background = textureCube; - - const geometry = new THREE.SphereGeometry(0.1, 32, 16); - const material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: textureCube }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = Math.random() * 10 - 5; - mesh.position.y = Math.random() * 10 - 5; - mesh.position.z = Math.random() * 10 - 5; - - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 3 + 1; - - scene.add(mesh); - - spheres.push(mesh); - } - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - const width = window.innerWidth || 2; - const height = window.innerHeight || 2; - - effect = new ParallaxBarrierEffect(renderer); - effect.setSize(width, height); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - effect.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouseX = (event.clientX - windowHalfX) / 100; - mouseY = (event.clientY - windowHalfY) / 100; -} - -// - -function animate() { - const timer = 0.0001 * Date.now(); - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - for (let i = 0, il = spheres.length; i < il; i++) { - const sphere = spheres[i]; - - sphere.position.x = 5 * Math.cos(timer + i); - sphere.position.y = 5 * Math.sin(timer + i * 1.1); - } - - effect.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_effects_peppersghost.ts b/examples-testing/examples/webgl_effects_peppersghost.ts deleted file mode 100644 index 41dfb4b65..000000000 --- a/examples-testing/examples/webgl_effects_peppersghost.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as THREE from 'three'; - -import { PeppersGhostEffect } from 'three/addons/effects/PeppersGhostEffect.js'; - -let container; - -let camera, scene, renderer, effect; -let group; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 100000); - - scene = new THREE.Scene(); - - group = new THREE.Group(); - scene.add(group); - - // Cube - - const geometry = new THREE.BoxGeometry().toNonIndexed(); // ensure unique vertices for each triangle - - const position = geometry.attributes.position; - const colors = []; - const color = new THREE.Color(); - - // generate for each side of the cube a different color - - for (let i = 0; i < position.count; i += 6) { - color.setHex(Math.random() * 0xffffff); - - // first face - - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - - // second face - - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - colors.push(color.r, color.g, color.b); - } - - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - const material = new THREE.MeshBasicMaterial({ vertexColors: true }); - - for (let i = 0; i < 10; i++) { - const cube = new THREE.Mesh(geometry, material); - cube.position.x = Math.random() * 2 - 1; - cube.position.y = Math.random() * 2 - 1; - cube.position.z = Math.random() * 2 - 1; - cube.scale.multiplyScalar(Math.random() + 0.5); - group.add(cube); - } - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - effect = new PeppersGhostEffect(renderer); - effect.setSize(window.innerWidth, window.innerHeight); - effect.cameraDistance = 5; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - effect.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - group.rotation.y += 0.01; - - effect.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_effects_stereo.ts b/examples-testing/examples/webgl_effects_stereo.ts deleted file mode 100644 index dd2f61f91..000000000 --- a/examples-testing/examples/webgl_effects_stereo.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as THREE from 'three'; - -import { StereoEffect } from 'three/addons/effects/StereoEffect.js'; - -let container, camera, scene, renderer, effect; - -const spheres = []; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -document.addEventListener('mousemove', onDocumentMouseMove); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 100000); - camera.position.z = 3200; - - scene = new THREE.Scene(); - scene.background = new THREE.CubeTextureLoader() - .setPath('textures/cube/Park3Med/') - .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']); - - const geometry = new THREE.SphereGeometry(100, 32, 16); - - const textureCube = new THREE.CubeTextureLoader() - .setPath('textures/cube/Park3Med/') - .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']); - textureCube.mapping = THREE.CubeRefractionMapping; - - const material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: textureCube, refractionRatio: 0.95 }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 10000 - 5000; - mesh.position.y = Math.random() * 10000 - 5000; - mesh.position.z = Math.random() * 10000 - 5000; - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 3 + 1; - scene.add(mesh); - - spheres.push(mesh); - } - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - effect = new StereoEffect(renderer); - effect.setSize(window.innerWidth, window.innerHeight); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - effect.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouseX = (event.clientX - windowHalfX) * 10; - mouseY = (event.clientY - windowHalfY) * 10; -} - -// - -function animate() { - const timer = 0.0001 * Date.now(); - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - camera.lookAt(scene.position); - - for (let i = 0, il = spheres.length; i < il; i++) { - const sphere = spheres[i]; - - sphere.position.x = 5000 * Math.cos(timer + i); - sphere.position.y = 5000 * Math.sin(timer + i * 1.1); - } - - effect.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_framebuffer_texture.ts b/examples-testing/examples/webgl_framebuffer_texture.ts deleted file mode 100644 index df4acc9d6..000000000 --- a/examples-testing/examples/webgl_framebuffer_texture.ts +++ /dev/null @@ -1,151 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - -let camera, scene, renderer; -let line, sprite, texture; - -let cameraOrtho, sceneOrtho; - -let offset = 0; - -const dpr = window.devicePixelRatio; - -const textureSize = 128 * dpr; -const vector = new THREE.Vector2(); -const color = new THREE.Color(); - -init(); - -function init() { - // - - const width = window.innerWidth; - const height = window.innerHeight; - - camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000); - camera.position.z = 20; - - cameraOrtho = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 1, 10); - cameraOrtho.position.z = 10; - - scene = new THREE.Scene(); - sceneOrtho = new THREE.Scene(); - - // - - const points = GeometryUtils.gosper(8); - - const geometry = new THREE.BufferGeometry(); - const positionAttribute = new THREE.Float32BufferAttribute(points, 3); - geometry.setAttribute('position', positionAttribute); - geometry.center(); - - const colorAttribute = new THREE.BufferAttribute(new Float32Array(positionAttribute.array.length), 3); - colorAttribute.setUsage(THREE.DynamicDrawUsage); - geometry.setAttribute('color', colorAttribute); - - const material = new THREE.LineBasicMaterial({ vertexColors: true }); - - line = new THREE.Line(geometry, material); - line.scale.setScalar(0.05); - scene.add(line); - - // - - texture = new THREE.FramebufferTexture(textureSize, textureSize); - - // - - const spriteMaterial = new THREE.SpriteMaterial({ map: texture }); - sprite = new THREE.Sprite(spriteMaterial); - sprite.scale.set(textureSize, textureSize, 1); - sceneOrtho.add(sprite); - - updateSpritePosition(); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - document.body.appendChild(renderer.domElement); - - // - - const selection = document.getElementById('selection'); - const controls = new OrbitControls(camera, selection); - controls.enablePan = false; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - cameraOrtho.left = -width / 2; - cameraOrtho.right = width / 2; - cameraOrtho.top = height / 2; - cameraOrtho.bottom = -height / 2; - cameraOrtho.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - updateSpritePosition(); -} - -function updateSpritePosition() { - const halfWidth = window.innerWidth / 2; - const halfHeight = window.innerHeight / 2; - - const halfImageWidth = textureSize / 2; - const halfImageHeight = textureSize / 2; - - sprite.position.set(-halfWidth + halfImageWidth, halfHeight - halfImageHeight, 1); -} - -function animate() { - const colorAttribute = line.geometry.getAttribute('color'); - updateColors(colorAttribute); - - // scene rendering - - renderer.clear(); - renderer.render(scene, camera); - - // calculate start position for copying data - - vector.x = (window.innerWidth * dpr) / 2 - textureSize / 2; - vector.y = (window.innerHeight * dpr) / 2 - textureSize / 2; - - renderer.copyFramebufferToTexture(texture, vector); - - renderer.clearDepth(); - renderer.render(sceneOrtho, cameraOrtho); -} - -function updateColors(colorAttribute) { - const l = colorAttribute.count; - - for (let i = 0; i < l; i++) { - const h = ((offset + i) % l) / l; - - color.setHSL(h, 1, 0.5); - colorAttribute.setX(i, color.r); - colorAttribute.setY(i, color.g); - colorAttribute.setZ(i, color.b); - } - - colorAttribute.needsUpdate = true; - - offset -= 25; -} diff --git a/examples-testing/examples/webgl_furnace_test.ts b/examples-testing/examples/webgl_furnace_test.ts deleted file mode 100644 index a81954176..000000000 --- a/examples-testing/examples/webgl_furnace_test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import * as THREE from 'three'; - -let scene, camera, renderer, radianceMap; - -const COLOR = 0xcccccc; - -function init() { - const width = window.innerWidth; - const height = window.innerHeight; - const aspect = width / height; - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(width, height); - renderer.setPixelRatio(window.devicePixelRatio); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - document.body.addEventListener('mouseover', function () { - scene.traverse(function (child) { - if (child.isMesh) child.material.color.setHex(0xffffff); - }); - - render(); - }); - - document.body.addEventListener('mouseout', function () { - scene.traverse(function (child) { - if (child.isMesh) child.material.color.setHex(0xccccff); // tinted for visibility - }); - - render(); - }); - - // scene - - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(40, aspect, 1, 30); - camera.position.set(0, 0, 18); -} - -function createObjects() { - const geometry = new THREE.SphereGeometry(0.4, 32, 16); - - for (let x = 0; x <= 10; x++) { - for (let y = 0; y <= 10; y++) { - const material = new THREE.MeshPhysicalMaterial({ - roughness: x / 10, - metalness: y / 10, - color: 0xffffff, - envMap: radianceMap, - envMapIntensity: 1, - transmission: 0, - ior: 1.5, - }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = x - 5; - mesh.position.y = 5 - y; - scene.add(mesh); - } - } -} - -function createEnvironment() { - const envScene = new THREE.Scene(); - envScene.background = new THREE.Color(COLOR); - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - radianceMap = pmremGenerator.fromScene(envScene).texture; - pmremGenerator.dispose(); - - scene.background = envScene.background; -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - - render(); -} - -function render() { - renderer.render(scene, camera); -} - -Promise.resolve().then(init).then(createEnvironment).then(createObjects).then(render); diff --git a/examples-testing/examples/webgl_geometries.ts b/examples-testing/examples/webgl_geometries.ts deleted file mode 100644 index 2b2d02613..000000000 --- a/examples-testing/examples/webgl_geometries.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.y = 400; - - scene = new THREE.Scene(); - - let object; - - const ambientLight = new THREE.AmbientLight(0xcccccc, 1.5); - scene.add(ambientLight); - - const pointLight = new THREE.PointLight(0xffffff, 2.5, 0, 0); - camera.add(pointLight); - scene.add(camera); - - const map = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - map.wrapS = map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshPhongMaterial({ map: map, side: THREE.DoubleSide }); - - // - - object = new THREE.Mesh(new THREE.SphereGeometry(75, 20, 10), material); - object.position.set(-300, 0, 200); - scene.add(object); - - object = new THREE.Mesh(new THREE.IcosahedronGeometry(75, 1), material); - object.position.set(-100, 0, 200); - scene.add(object); - - object = new THREE.Mesh(new THREE.OctahedronGeometry(75, 2), material); - object.position.set(100, 0, 200); - scene.add(object); - - object = new THREE.Mesh(new THREE.TetrahedronGeometry(75, 0), material); - object.position.set(300, 0, 200); - scene.add(object); - - // - - object = new THREE.Mesh(new THREE.PlaneGeometry(100, 100, 4, 4), material); - object.position.set(-300, 0, 0); - scene.add(object); - - object = new THREE.Mesh(new THREE.BoxGeometry(100, 100, 100, 4, 4, 4), material); - object.position.set(-100, 0, 0); - scene.add(object); - - object = new THREE.Mesh(new THREE.CircleGeometry(50, 20, 0, Math.PI * 2), material); - object.position.set(100, 0, 0); - scene.add(object); - - object = new THREE.Mesh(new THREE.RingGeometry(10, 50, 20, 5, 0, Math.PI * 2), material); - object.position.set(300, 0, 0); - scene.add(object); - - // - - object = new THREE.Mesh(new THREE.CylinderGeometry(25, 75, 100, 40, 5), material); - object.position.set(-300, 0, -200); - scene.add(object); - - const points = []; - - for (let i = 0; i < 50; i++) { - points.push(new THREE.Vector2(Math.sin(i * 0.2) * Math.sin(i * 0.1) * 15 + 50, (i - 5) * 2)); - } - - object = new THREE.Mesh(new THREE.LatheGeometry(points, 20), material); - object.position.set(-100, 0, -200); - scene.add(object); - - object = new THREE.Mesh(new THREE.TorusGeometry(50, 20, 20, 20), material); - object.position.set(100, 0, -200); - scene.add(object); - - object = new THREE.Mesh(new THREE.TorusKnotGeometry(50, 10, 50, 20), material); - object.position.set(300, 0, -200); - scene.add(object); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const timer = Date.now() * 0.0001; - - camera.position.x = Math.cos(timer) * 800; - camera.position.z = Math.sin(timer) * 800; - - camera.lookAt(scene.position); - - scene.traverse(function (object) { - if (object.isMesh === true) { - object.rotation.x = timer * 5; - object.rotation.y = timer * 2.5; - } - }); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometries_parametric.ts b/examples-testing/examples/webgl_geometries_parametric.ts deleted file mode 100644 index 29bf7ae26..000000000 --- a/examples-testing/examples/webgl_geometries_parametric.ts +++ /dev/null @@ -1,124 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import * as Curves from 'three/addons/curves/CurveExtras.js'; -import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; -import { ParametricGeometries } from 'three/addons/geometries/ParametricGeometries.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.y = 400; - - scene = new THREE.Scene(); - - // - - const ambientLight = new THREE.AmbientLight(0xcccccc, 1.5); - scene.add(ambientLight); - - const pointLight = new THREE.PointLight(0xffffff, 2.5, 0, 0); - camera.add(pointLight); - scene.add(camera); - - // - - const map = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - map.wrapS = map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshPhongMaterial({ map: map, side: THREE.DoubleSide }); - - // - - let geometry, object; - - geometry = new ParametricGeometry(ParametricGeometries.plane(100, 100), 10, 10); - geometry.center(); - object = new THREE.Mesh(geometry, material); - object.position.set(-200, 0, 200); - scene.add(object); - - geometry = new ParametricGeometry(ParametricGeometries.klein, 20, 20); - object = new THREE.Mesh(geometry, material); - object.position.set(0, 0, 200); - object.scale.multiplyScalar(5); - scene.add(object); - - geometry = new ParametricGeometry(ParametricGeometries.mobius, 20, 20); - object = new THREE.Mesh(geometry, material); - object.position.set(200, 0, 200); - object.scale.multiplyScalar(30); - scene.add(object); - - // - - const GrannyKnot = new Curves.GrannyKnot(); - - const torus = new ParametricGeometries.TorusKnotGeometry(50, 10, 50, 20, 2, 3); - const sphere = new ParametricGeometries.SphereGeometry(50, 20, 10); - const tube = new ParametricGeometries.TubeGeometry(GrannyKnot, 100, 3, 8, true); - - object = new THREE.Mesh(torus, material); - object.position.set(-200, 0, -200); - scene.add(object); - - object = new THREE.Mesh(sphere, material); - object.position.set(0, 0, -200); - scene.add(object); - - object = new THREE.Mesh(tube, material); - object.position.set(200, 0, -200); - object.scale.multiplyScalar(2); - scene.add(object); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const timer = Date.now() * 0.0001; - - camera.position.x = Math.cos(timer) * 800; - camera.position.z = Math.sin(timer) * 800; - - camera.lookAt(scene.position); - - scene.traverse(function (object) { - if (object.isMesh === true) { - object.rotation.x = timer * 5; - object.rotation.y = timer * 2.5; - } - }); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_colors.ts b/examples-testing/examples/webgl_geometry_colors.ts deleted file mode 100644 index bc0bf5174..000000000 --- a/examples-testing/examples/webgl_geometry_colors.ts +++ /dev/null @@ -1,176 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 1800; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 0, 1); - scene.add(light); - - // shadow - - const canvas = document.createElement('canvas'); - canvas.width = 128; - canvas.height = 128; - - const context = canvas.getContext('2d'); - const gradient = context.createRadialGradient( - canvas.width / 2, - canvas.height / 2, - 0, - canvas.width / 2, - canvas.height / 2, - canvas.width / 2, - ); - gradient.addColorStop(0.1, 'rgba(210,210,210,1)'); - gradient.addColorStop(1, 'rgba(255,255,255,1)'); - - context.fillStyle = gradient; - context.fillRect(0, 0, canvas.width, canvas.height); - - const shadowTexture = new THREE.CanvasTexture(canvas); - - const shadowMaterial = new THREE.MeshBasicMaterial({ map: shadowTexture }); - const shadowGeo = new THREE.PlaneGeometry(300, 300, 1, 1); - - let shadowMesh; - - shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial); - shadowMesh.position.y = -250; - shadowMesh.rotation.x = -Math.PI / 2; - scene.add(shadowMesh); - - shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial); - shadowMesh.position.y = -250; - shadowMesh.position.x = -400; - shadowMesh.rotation.x = -Math.PI / 2; - scene.add(shadowMesh); - - shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial); - shadowMesh.position.y = -250; - shadowMesh.position.x = 400; - shadowMesh.rotation.x = -Math.PI / 2; - scene.add(shadowMesh); - - const radius = 200; - - const geometry1 = new THREE.IcosahedronGeometry(radius, 1); - - const count = geometry1.attributes.position.count; - geometry1.setAttribute('color', new THREE.BufferAttribute(new Float32Array(count * 3), 3)); - - const geometry2 = geometry1.clone(); - const geometry3 = geometry1.clone(); - - const color = new THREE.Color(); - const positions1 = geometry1.attributes.position; - const positions2 = geometry2.attributes.position; - const positions3 = geometry3.attributes.position; - const colors1 = geometry1.attributes.color; - const colors2 = geometry2.attributes.color; - const colors3 = geometry3.attributes.color; - - for (let i = 0; i < count; i++) { - color.setHSL((positions1.getY(i) / radius + 1) / 2, 1.0, 0.5, THREE.SRGBColorSpace); - colors1.setXYZ(i, color.r, color.g, color.b); - - color.setHSL(0, (positions2.getY(i) / radius + 1) / 2, 0.5, THREE.SRGBColorSpace); - colors2.setXYZ(i, color.r, color.g, color.b); - - color.setRGB(1, 0.8 - (positions3.getY(i) / radius + 1) / 2, 0, THREE.SRGBColorSpace); - colors3.setXYZ(i, color.r, color.g, color.b); - } - - const material = new THREE.MeshPhongMaterial({ - color: 0xffffff, - flatShading: true, - vertexColors: true, - shininess: 0, - }); - - const wireframeMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, wireframe: true, transparent: true }); - - let mesh = new THREE.Mesh(geometry1, material); - let wireframe = new THREE.Mesh(geometry1, wireframeMaterial); - mesh.add(wireframe); - mesh.position.x = -400; - mesh.rotation.x = -1.87; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry2, material); - wireframe = new THREE.Mesh(geometry2, wireframeMaterial); - mesh.add(wireframe); - mesh.position.x = 400; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry3, material); - wireframe = new THREE.Mesh(geometry3, wireframeMaterial); - mesh.add(wireframe); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - document.addEventListener('mousemove', onDocumentMouseMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_colors_lookuptable.ts b/examples-testing/examples/webgl_geometry_colors_lookuptable.ts deleted file mode 100644 index 6b0138529..000000000 --- a/examples-testing/examples/webgl_geometry_colors_lookuptable.ts +++ /dev/null @@ -1,148 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Lut } from 'three/addons/math/Lut.js'; - -let container; - -let perpCamera, orthoCamera, renderer, lut; - -let mesh, sprite; -let scene, uiScene; - -let params; - -init(); - -function init() { - container = document.getElementById('container'); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - uiScene = new THREE.Scene(); - - lut = new Lut(); - - const width = window.innerWidth; - const height = window.innerHeight; - - perpCamera = new THREE.PerspectiveCamera(60, width / height, 1, 100); - perpCamera.position.set(0, 0, 10); - scene.add(perpCamera); - - orthoCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 1, 2); - orthoCamera.position.set(0.5, 0, 1); - - sprite = new THREE.Sprite( - new THREE.SpriteMaterial({ - map: new THREE.CanvasTexture(lut.createCanvas()), - }), - ); - sprite.material.map.colorSpace = THREE.SRGBColorSpace; - sprite.scale.x = 0.125; - uiScene.add(sprite); - - mesh = new THREE.Mesh( - undefined, - new THREE.MeshLambertMaterial({ - side: THREE.DoubleSide, - color: 0xf5f5f5, - vertexColors: true, - }), - ); - scene.add(mesh); - - params = { - colorMap: 'rainbow', - }; - loadModel(); - - const pointLight = new THREE.PointLight(0xffffff, 3, 0, 0); - perpCamera.add(pointLight); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.autoClear = false; - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - const controls = new OrbitControls(perpCamera, renderer.domElement); - controls.addEventListener('change', render); - - const gui = new GUI(); - - gui.add(params, 'colorMap', ['rainbow', 'cooltowarm', 'blackbody', 'grayscale']).onChange(function () { - updateColors(); - render(); - }); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - perpCamera.aspect = width / height; - perpCamera.updateProjectionMatrix(); - - renderer.setSize(width, height); - render(); -} - -function render() { - renderer.clear(); - renderer.render(scene, perpCamera); - renderer.render(uiScene, orthoCamera); -} - -function loadModel() { - const loader = new THREE.BufferGeometryLoader(); - loader.load('models/json/pressure.json', function (geometry) { - geometry.center(); - geometry.computeVertexNormals(); - - // default color attribute - const colors = []; - - for (let i = 0, n = geometry.attributes.position.count; i < n; ++i) { - colors.push(1, 1, 1); - } - - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - mesh.geometry = geometry; - updateColors(); - - render(); - }); -} - -function updateColors() { - lut.setColorMap(params.colorMap); - - lut.setMax(2000); - lut.setMin(0); - - const geometry = mesh.geometry; - const pressures = geometry.attributes.pressure; - const colors = geometry.attributes.color; - const color = new THREE.Color(); - - for (let i = 0; i < pressures.array.length; i++) { - const colorValue = pressures.array[i]; - - color.copy(lut.getColor(colorValue)).convertSRGBToLinear(); - - colors.setXYZ(i, color.r, color.g, color.b); - } - - colors.needsUpdate = true; - - const map = sprite.material.map; - lut.updateCanvas(map.image); - map.needsUpdate = true; -} diff --git a/examples-testing/examples/webgl_geometry_convex.ts b/examples-testing/examples/webgl_geometry_convex.ts deleted file mode 100644 index ade9cb801..000000000 --- a/examples-testing/examples/webgl_geometry_convex.ts +++ /dev/null @@ -1,117 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ConvexGeometry } from 'three/addons/geometries/ConvexGeometry.js'; -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let group, camera, scene, renderer; - -init(); - -function init() { - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // camera - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(15, 20, 30); - scene.add(camera); - - // controls - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 20; - controls.maxDistance = 50; - controls.maxPolarAngle = Math.PI / 2; - - // ambient light - - scene.add(new THREE.AmbientLight(0x666666)); - - // point light - - const light = new THREE.PointLight(0xffffff, 3, 0, 0); - camera.add(light); - - // helper - - scene.add(new THREE.AxesHelper(20)); - - // textures - - const loader = new THREE.TextureLoader(); - const texture = loader.load('textures/sprites/disc.png'); - texture.colorSpace = THREE.SRGBColorSpace; - - group = new THREE.Group(); - scene.add(group); - - // points - - let dodecahedronGeometry = new THREE.DodecahedronGeometry(10); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data - - dodecahedronGeometry.deleteAttribute('normal'); - dodecahedronGeometry.deleteAttribute('uv'); - - dodecahedronGeometry = BufferGeometryUtils.mergeVertices(dodecahedronGeometry); - - const vertices = []; - const positionAttribute = dodecahedronGeometry.getAttribute('position'); - - for (let i = 0; i < positionAttribute.count; i++) { - const vertex = new THREE.Vector3(); - vertex.fromBufferAttribute(positionAttribute, i); - vertices.push(vertex); - } - - const pointsMaterial = new THREE.PointsMaterial({ - color: 0x0080ff, - map: texture, - size: 1, - alphaTest: 0.5, - }); - - const pointsGeometry = new THREE.BufferGeometry().setFromPoints(vertices); - - const points = new THREE.Points(pointsGeometry, pointsMaterial); - group.add(points); - - // convex hull - - const meshMaterial = new THREE.MeshLambertMaterial({ - color: 0xffffff, - opacity: 0.5, - side: THREE.DoubleSide, - transparent: true, - }); - - const meshGeometry = new ConvexGeometry(vertices); - - const mesh = new THREE.Mesh(meshGeometry, meshMaterial); - group.add(mesh); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - group.rotation.y += 0.005; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_cube.ts b/examples-testing/examples/webgl_geometry_cube.ts deleted file mode 100644 index 572601acb..000000000 --- a/examples-testing/examples/webgl_geometry_cube.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; -let mesh; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 2; - - scene = new THREE.Scene(); - - const texture = new THREE.TextureLoader().load('textures/crate.gif'); - texture.colorSpace = THREE.SRGBColorSpace; - - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshBasicMaterial({ map: texture }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - mesh.rotation.x += 0.005; - mesh.rotation.y += 0.01; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_dynamic.ts b/examples-testing/examples/webgl_geometry_dynamic.ts deleted file mode 100644 index 06e858f54..000000000 --- a/examples-testing/examples/webgl_geometry_dynamic.ts +++ /dev/null @@ -1,97 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; - -let camera, controls, scene, renderer, stats; - -let mesh, geometry, material, clock; - -const worldWidth = 128, - worldDepth = 128; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 20000); - camera.position.y = 200; - - clock = new THREE.Clock(); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xaaccff); - scene.fog = new THREE.FogExp2(0xaaccff, 0.0007); - - geometry = new THREE.PlaneGeometry(20000, 20000, worldWidth - 1, worldDepth - 1); - geometry.rotateX(-Math.PI / 2); - - const position = geometry.attributes.position; - position.usage = THREE.DynamicDrawUsage; - - for (let i = 0; i < position.count; i++) { - const y = 35 * Math.sin(i / 2); - position.setY(i, y); - } - - const texture = new THREE.TextureLoader().load('textures/water.jpg'); - texture.wrapS = texture.wrapT = THREE.RepeatWrapping; - texture.repeat.set(5, 5); - texture.colorSpace = THREE.SRGBColorSpace; - - material = new THREE.MeshBasicMaterial({ color: 0x0044ff, map: texture }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - controls = new FirstPersonControls(camera, renderer.domElement); - - controls.movementSpeed = 500; - controls.lookSpeed = 0.1; - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - controls.handleResize(); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - const time = clock.getElapsedTime() * 10; - - const position = geometry.attributes.position; - - for (let i = 0; i < position.count; i++) { - const y = 35 * Math.sin(i / 5 + (time + i) / 7); - position.setY(i, y); - } - - position.needsUpdate = true; - - controls.update(delta); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_extrude_shapes.ts b/examples-testing/examples/webgl_geometry_extrude_shapes.ts deleted file mode 100644 index 7428aee31..000000000 --- a/examples-testing/examples/webgl_geometry_extrude_shapes.ts +++ /dev/null @@ -1,149 +0,0 @@ -import * as THREE from 'three'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; - -let camera, scene, renderer, controls; - -init(); - -function init() { - const info = document.createElement('div'); - info.style.position = 'absolute'; - info.style.top = '10px'; - info.style.width = '100%'; - info.style.textAlign = 'center'; - info.style.color = '#fff'; - info.style.link = '#f80'; - info.innerHTML = - 'three.js webgl - geometry extrude shapes'; - document.body.appendChild(info); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x222222); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 500); - - controls = new TrackballControls(camera, renderer.domElement); - controls.minDistance = 200; - controls.maxDistance = 500; - - scene.add(new THREE.AmbientLight(0x666666)); - - const light = new THREE.PointLight(0xffffff, 3, 0, 0); - light.position.copy(camera.position); - scene.add(light); - - // - - const closedSpline = new THREE.CatmullRomCurve3([ - new THREE.Vector3(-60, -100, 60), - new THREE.Vector3(-60, 20, 60), - new THREE.Vector3(-60, 120, 60), - new THREE.Vector3(60, 20, -60), - new THREE.Vector3(60, -100, -60), - ]); - - closedSpline.curveType = 'catmullrom'; - closedSpline.closed = true; - - const extrudeSettings1 = { - steps: 100, - bevelEnabled: false, - extrudePath: closedSpline, - }; - - const pts1 = [], - count = 3; - - for (let i = 0; i < count; i++) { - const l = 20; - - const a = ((2 * i) / count) * Math.PI; - - pts1.push(new THREE.Vector2(Math.cos(a) * l, Math.sin(a) * l)); - } - - const shape1 = new THREE.Shape(pts1); - - const geometry1 = new THREE.ExtrudeGeometry(shape1, extrudeSettings1); - - const material1 = new THREE.MeshLambertMaterial({ color: 0xb00000, wireframe: false }); - - const mesh1 = new THREE.Mesh(geometry1, material1); - - scene.add(mesh1); - - // - - const randomPoints = []; - - for (let i = 0; i < 10; i++) { - randomPoints.push( - new THREE.Vector3((i - 4.5) * 50, THREE.MathUtils.randFloat(-50, 50), THREE.MathUtils.randFloat(-50, 50)), - ); - } - - const randomSpline = new THREE.CatmullRomCurve3(randomPoints); - - // - - const extrudeSettings2 = { - steps: 200, - bevelEnabled: false, - extrudePath: randomSpline, - }; - - const pts2 = [], - numPts = 5; - - for (let i = 0; i < numPts * 2; i++) { - const l = i % 2 == 1 ? 10 : 20; - - const a = (i / numPts) * Math.PI; - - pts2.push(new THREE.Vector2(Math.cos(a) * l, Math.sin(a) * l)); - } - - const shape2 = new THREE.Shape(pts2); - - const geometry2 = new THREE.ExtrudeGeometry(shape2, extrudeSettings2); - - const material2 = new THREE.MeshLambertMaterial({ color: 0xff8000, wireframe: false }); - - const mesh2 = new THREE.Mesh(geometry2, material2); - - scene.add(mesh2); - - // - - const materials = [material1, material2]; - - const extrudeSettings3 = { - depth: 20, - steps: 1, - bevelEnabled: true, - bevelThickness: 2, - bevelSize: 4, - bevelSegments: 1, - }; - - const geometry3 = new THREE.ExtrudeGeometry(shape2, extrudeSettings3); - - const mesh3 = new THREE.Mesh(geometry3, materials); - - mesh3.position.set(50, 100, 50); - - scene.add(mesh3); -} - -function animate() { - controls.update(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_extrude_splines.ts b/examples-testing/examples/webgl_geometry_extrude_splines.ts deleted file mode 100644 index 0741083da..000000000 --- a/examples-testing/examples/webgl_geometry_extrude_splines.ts +++ /dev/null @@ -1,310 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import * as Curves from 'three/addons/curves/CurveExtras.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container, stats; - -let camera, scene, renderer, splineCamera, cameraHelper, cameraEye; - -const direction = new THREE.Vector3(); -const binormal = new THREE.Vector3(); -const normal = new THREE.Vector3(); -const position = new THREE.Vector3(); -const lookAt = new THREE.Vector3(); - -const pipeSpline = new THREE.CatmullRomCurve3([ - new THREE.Vector3(0, 10, -10), - new THREE.Vector3(10, 0, -10), - new THREE.Vector3(20, 0, 0), - new THREE.Vector3(30, 0, 10), - new THREE.Vector3(30, 0, 20), - new THREE.Vector3(20, 0, 30), - new THREE.Vector3(10, 0, 30), - new THREE.Vector3(0, 0, 30), - new THREE.Vector3(-10, 10, 30), - new THREE.Vector3(-10, 20, 30), - new THREE.Vector3(0, 30, 30), - new THREE.Vector3(10, 30, 30), - new THREE.Vector3(20, 30, 15), - new THREE.Vector3(10, 30, 10), - new THREE.Vector3(0, 30, 10), - new THREE.Vector3(-10, 20, 10), - new THREE.Vector3(-10, 10, 10), - new THREE.Vector3(0, 0, 10), - new THREE.Vector3(10, -10, 10), - new THREE.Vector3(20, -15, 10), - new THREE.Vector3(30, -15, 10), - new THREE.Vector3(40, -15, 10), - new THREE.Vector3(50, -15, 10), - new THREE.Vector3(60, 0, 10), - new THREE.Vector3(70, 0, 0), - new THREE.Vector3(80, 0, 0), - new THREE.Vector3(90, 0, 0), - new THREE.Vector3(100, 0, 0), -]); - -const sampleClosedSpline = new THREE.CatmullRomCurve3([ - new THREE.Vector3(0, -40, -40), - new THREE.Vector3(0, 40, -40), - new THREE.Vector3(0, 140, -40), - new THREE.Vector3(0, 40, 40), - new THREE.Vector3(0, -40, 40), -]); - -sampleClosedSpline.curveType = 'catmullrom'; -sampleClosedSpline.closed = true; - -// Keep a dictionary of Curve instances -const splines = { - GrannyKnot: new Curves.GrannyKnot(), - HeartCurve: new Curves.HeartCurve(3.5), - VivianiCurve: new Curves.VivianiCurve(70), - KnotCurve: new Curves.KnotCurve(), - HelixCurve: new Curves.HelixCurve(), - TrefoilKnot: new Curves.TrefoilKnot(), - TorusKnot: new Curves.TorusKnot(20), - CinquefoilKnot: new Curves.CinquefoilKnot(20), - TrefoilPolynomialKnot: new Curves.TrefoilPolynomialKnot(14), - FigureEightPolynomialKnot: new Curves.FigureEightPolynomialKnot(), - DecoratedTorusKnot4a: new Curves.DecoratedTorusKnot4a(), - DecoratedTorusKnot4b: new Curves.DecoratedTorusKnot4b(), - DecoratedTorusKnot5a: new Curves.DecoratedTorusKnot5a(), - DecoratedTorusKnot5c: new Curves.DecoratedTorusKnot5c(), - PipeSpline: pipeSpline, - SampleClosedSpline: sampleClosedSpline, -}; - -let parent, tubeGeometry, mesh; - -const params = { - spline: 'GrannyKnot', - scale: 4, - extrusionSegments: 100, - radiusSegments: 3, - closed: true, - animationView: false, - lookAhead: false, - cameraHelper: false, -}; - -const material = new THREE.MeshLambertMaterial({ color: 0xff00ff }); - -const wireframeMaterial = new THREE.MeshBasicMaterial({ - color: 0x000000, - opacity: 0.3, - wireframe: true, - transparent: true, -}); - -function addTube() { - if (mesh !== undefined) { - parent.remove(mesh); - mesh.geometry.dispose(); - } - - const extrudePath = splines[params.spline]; - - tubeGeometry = new THREE.TubeGeometry( - extrudePath, - params.extrusionSegments, - 2, - params.radiusSegments, - params.closed, - ); - - addGeometry(tubeGeometry); - - setScale(); -} - -function setScale() { - mesh.scale.set(params.scale, params.scale, params.scale); -} - -function addGeometry(geometry) { - // 3D shape - - mesh = new THREE.Mesh(geometry, material); - const wireframe = new THREE.Mesh(geometry, wireframeMaterial); - mesh.add(wireframe); - - parent.add(mesh); -} - -function animateCamera() { - cameraHelper.visible = params.cameraHelper; - cameraEye.visible = params.cameraHelper; -} - -init(); - -function init() { - container = document.getElementById('container'); - - // camera - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 10000); - camera.position.set(0, 50, 500); - - // scene - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - // light - - scene.add(new THREE.AmbientLight(0xffffff)); - - const light = new THREE.DirectionalLight(0xffffff, 1.5); - light.position.set(0, 0, 1); - scene.add(light); - - // tube - - parent = new THREE.Object3D(); - scene.add(parent); - - splineCamera = new THREE.PerspectiveCamera(84, window.innerWidth / window.innerHeight, 0.01, 1000); - parent.add(splineCamera); - - cameraHelper = new THREE.CameraHelper(splineCamera); - scene.add(cameraHelper); - - addTube(); - - // debug camera - - cameraEye = new THREE.Mesh(new THREE.SphereGeometry(5), new THREE.MeshBasicMaterial({ color: 0xdddddd })); - parent.add(cameraEye); - - cameraHelper.visible = params.cameraHelper; - cameraEye.visible = params.cameraHelper; - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // stats - - stats = new Stats(); - container.appendChild(stats.dom); - - // dat.GUI - - const gui = new GUI({ width: 285 }); - - const folderGeometry = gui.addFolder('Geometry'); - folderGeometry.add(params, 'spline', Object.keys(splines)).onChange(function () { - addTube(); - }); - folderGeometry - .add(params, 'scale', 2, 10) - .step(2) - .onChange(function () { - setScale(); - }); - folderGeometry - .add(params, 'extrusionSegments', 50, 500) - .step(50) - .onChange(function () { - addTube(); - }); - folderGeometry - .add(params, 'radiusSegments', 2, 12) - .step(1) - .onChange(function () { - addTube(); - }); - folderGeometry.add(params, 'closed').onChange(function () { - addTube(); - }); - folderGeometry.open(); - - const folderCamera = gui.addFolder('Camera'); - folderCamera.add(params, 'animationView').onChange(function () { - animateCamera(); - }); - folderCamera.add(params, 'lookAhead').onChange(function () { - animateCamera(); - }); - folderCamera.add(params, 'cameraHelper').onChange(function () { - animateCamera(); - }); - folderCamera.open(); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 100; - controls.maxDistance = 2000; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - // animate camera along spline - - const time = Date.now(); - const looptime = 20 * 1000; - const t = (time % looptime) / looptime; - - tubeGeometry.parameters.path.getPointAt(t, position); - position.multiplyScalar(params.scale); - - // interpolation - - const segments = tubeGeometry.tangents.length; - const pickt = t * segments; - const pick = Math.floor(pickt); - const pickNext = (pick + 1) % segments; - - binormal.subVectors(tubeGeometry.binormals[pickNext], tubeGeometry.binormals[pick]); - binormal.multiplyScalar(pickt - pick).add(tubeGeometry.binormals[pick]); - - tubeGeometry.parameters.path.getTangentAt(t, direction); - const offset = 15; - - normal.copy(binormal).cross(direction); - - // we move on a offset on its binormal - - position.add(normal.clone().multiplyScalar(offset)); - - splineCamera.position.copy(position); - cameraEye.position.copy(position); - - // using arclength for stablization in look ahead - - tubeGeometry.parameters.path.getPointAt((t + 30 / tubeGeometry.parameters.path.getLength()) % 1, lookAt); - lookAt.multiplyScalar(params.scale); - - // camera orientation 2 - up orientation via normal - - if (!params.lookAhead) lookAt.copy(position).add(direction); - splineCamera.matrix.lookAt(splineCamera.position, lookAt, normal); - splineCamera.quaternion.setFromRotationMatrix(splineCamera.matrix); - - cameraHelper.update(); - - renderer.render(scene, params.animationView === true ? splineCamera : camera); -} diff --git a/examples-testing/examples/webgl_geometry_minecraft.ts b/examples-testing/examples/webgl_geometry_minecraft.ts deleted file mode 100644 index 765aa1e49..000000000 --- a/examples-testing/examples/webgl_geometry_minecraft.ts +++ /dev/null @@ -1,183 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; -import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let container, stats; - -let camera, controls, scene, renderer; - -const worldWidth = 128, - worldDepth = 128; -const worldHalfWidth = worldWidth / 2; -const worldHalfDepth = worldDepth / 2; -const data = generateHeight(worldWidth, worldDepth); - -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 20000); - camera.position.y = getY(worldHalfWidth, worldHalfDepth) * 100 + 100; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xbfd1e5); - - // sides - - const matrix = new THREE.Matrix4(); - - const pxGeometry = new THREE.PlaneGeometry(100, 100); - pxGeometry.attributes.uv.array[1] = 0.5; - pxGeometry.attributes.uv.array[3] = 0.5; - pxGeometry.rotateY(Math.PI / 2); - pxGeometry.translate(50, 0, 0); - - const nxGeometry = new THREE.PlaneGeometry(100, 100); - nxGeometry.attributes.uv.array[1] = 0.5; - nxGeometry.attributes.uv.array[3] = 0.5; - nxGeometry.rotateY(-Math.PI / 2); - nxGeometry.translate(-50, 0, 0); - - const pyGeometry = new THREE.PlaneGeometry(100, 100); - pyGeometry.attributes.uv.array[5] = 0.5; - pyGeometry.attributes.uv.array[7] = 0.5; - pyGeometry.rotateX(-Math.PI / 2); - pyGeometry.translate(0, 50, 0); - - const pzGeometry = new THREE.PlaneGeometry(100, 100); - pzGeometry.attributes.uv.array[1] = 0.5; - pzGeometry.attributes.uv.array[3] = 0.5; - pzGeometry.translate(0, 0, 50); - - const nzGeometry = new THREE.PlaneGeometry(100, 100); - nzGeometry.attributes.uv.array[1] = 0.5; - nzGeometry.attributes.uv.array[3] = 0.5; - nzGeometry.rotateY(Math.PI); - nzGeometry.translate(0, 0, -50); - - // - - const geometries = []; - - for (let z = 0; z < worldDepth; z++) { - for (let x = 0; x < worldWidth; x++) { - const h = getY(x, z); - - matrix.makeTranslation(x * 100 - worldHalfWidth * 100, h * 100, z * 100 - worldHalfDepth * 100); - - const px = getY(x + 1, z); - const nx = getY(x - 1, z); - const pz = getY(x, z + 1); - const nz = getY(x, z - 1); - - geometries.push(pyGeometry.clone().applyMatrix4(matrix)); - - if ((px !== h && px !== h + 1) || x === 0) { - geometries.push(pxGeometry.clone().applyMatrix4(matrix)); - } - - if ((nx !== h && nx !== h + 1) || x === worldWidth - 1) { - geometries.push(nxGeometry.clone().applyMatrix4(matrix)); - } - - if ((pz !== h && pz !== h + 1) || z === worldDepth - 1) { - geometries.push(pzGeometry.clone().applyMatrix4(matrix)); - } - - if ((nz !== h && nz !== h + 1) || z === 0) { - geometries.push(nzGeometry.clone().applyMatrix4(matrix)); - } - } - } - - const geometry = BufferGeometryUtils.mergeGeometries(geometries); - geometry.computeBoundingSphere(); - - const texture = new THREE.TextureLoader().load('textures/minecraft/atlas.png'); - texture.colorSpace = THREE.SRGBColorSpace; - texture.magFilter = THREE.NearestFilter; - - const mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ map: texture, side: THREE.DoubleSide })); - scene.add(mesh); - - const ambientLight = new THREE.AmbientLight(0xeeeeee, 3); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 12); - directionalLight.position.set(1, 1, 0.5).normalize(); - scene.add(directionalLight); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - controls = new FirstPersonControls(camera, renderer.domElement); - - controls.movementSpeed = 1000; - controls.lookSpeed = 0.125; - controls.lookVertical = true; - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - controls.handleResize(); -} - -function generateHeight(width, height) { - const data = [], - perlin = new ImprovedNoise(), - size = width * height, - z = Math.random() * 100; - - let quality = 2; - - for (let j = 0; j < 4; j++) { - if (j === 0) for (let i = 0; i < size; i++) data[i] = 0; - - for (let i = 0; i < size; i++) { - const x = i % width, - y = (i / width) | 0; - data[i] += perlin.noise(x / quality, y / quality, z) * quality; - } - - quality *= 4; - } - - return data; -} - -function getY(x, z) { - return (data[x + z * worldWidth] * 0.15) | 0; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - controls.update(clock.getDelta()); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_nurbs.ts b/examples-testing/examples/webgl_geometry_nurbs.ts deleted file mode 100644 index a603710bd..000000000 --- a/examples-testing/examples/webgl_geometry_nurbs.ts +++ /dev/null @@ -1,298 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { NURBSCurve } from 'three/addons/curves/NURBSCurve.js'; -import { NURBSSurface } from 'three/addons/curves/NURBSSurface.js'; -import { NURBSVolume } from 'three/addons/curves/NURBSVolume.js'; -import { ParametricGeometry } from 'three/addons/geometries/ParametricGeometry.js'; - -let container, stats; - -let camera, scene, renderer; -let group; - -let targetRotation = 0; -let targetRotationOnPointerDown = 0; - -let pointerX = 0; -let pointerXOnPointerDown = 0; - -let windowHalfX = window.innerWidth / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(0, 150, 750); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - scene.add(new THREE.AmbientLight(0xffffff)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(1, 1, 1); - scene.add(light); - - group = new THREE.Group(); - group.position.y = 50; - scene.add(group); - - // NURBS curve - - const nurbsControlPoints = []; - const nurbsKnots = []; - const nurbsDegree = 3; - - for (let i = 0; i <= nurbsDegree; i++) { - nurbsKnots.push(0); - } - - for (let i = 0, j = 20; i < j; i++) { - nurbsControlPoints.push( - new THREE.Vector4( - Math.random() * 400 - 200, - Math.random() * 400, - Math.random() * 400 - 200, - 1, // weight of control point: higher means stronger attraction - ), - ); - - const knot = (i + 1) / (j - nurbsDegree); - nurbsKnots.push(THREE.MathUtils.clamp(knot, 0, 1)); - } - - const nurbsCurve = new NURBSCurve(nurbsDegree, nurbsKnots, nurbsControlPoints); - - const nurbsGeometry = new THREE.BufferGeometry(); - nurbsGeometry.setFromPoints(nurbsCurve.getPoints(200)); - - const nurbsMaterial = new THREE.LineBasicMaterial({ color: 0x333333 }); - - const nurbsLine = new THREE.Line(nurbsGeometry, nurbsMaterial); - nurbsLine.position.set(0, -100, 0); - group.add(nurbsLine); - - const nurbsControlPointsGeometry = new THREE.BufferGeometry(); - nurbsControlPointsGeometry.setFromPoints(nurbsCurve.controlPoints); - - const nurbsControlPointsMaterial = new THREE.LineBasicMaterial({ - color: 0x333333, - opacity: 0.25, - transparent: true, - }); - - const nurbsControlPointsLine = new THREE.Line(nurbsControlPointsGeometry, nurbsControlPointsMaterial); - nurbsControlPointsLine.position.copy(nurbsLine.position); - group.add(nurbsControlPointsLine); - - // NURBS surface - { - const nsControlPoints = [ - [ - new THREE.Vector4(-200, -200, 100, 1), - new THREE.Vector4(-200, -100, -200, 1), - new THREE.Vector4(-200, 100, 250, 1), - new THREE.Vector4(-200, 200, -100, 1), - ], - [ - new THREE.Vector4(0, -200, 0, 1), - new THREE.Vector4(0, -100, -100, 5), - new THREE.Vector4(0, 100, 150, 5), - new THREE.Vector4(0, 200, 0, 1), - ], - [ - new THREE.Vector4(200, -200, -100, 1), - new THREE.Vector4(200, -100, 200, 1), - new THREE.Vector4(200, 100, -250, 1), - new THREE.Vector4(200, 200, 100, 1), - ], - ]; - const degree1 = 2; - const degree2 = 3; - const knots1 = [0, 0, 0, 1, 1, 1]; - const knots2 = [0, 0, 0, 0, 1, 1, 1, 1]; - const nurbsSurface = new NURBSSurface(degree1, degree2, knots1, knots2, nsControlPoints); - - const map = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - map.wrapS = map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.colorSpace = THREE.SRGBColorSpace; - - function getSurfacePoint(u, v, target) { - return nurbsSurface.getPoint(u, v, target); - } - - const geometry = new ParametricGeometry(getSurfacePoint, 20, 20); - const material = new THREE.MeshLambertMaterial({ map: map, side: THREE.DoubleSide }); - const object = new THREE.Mesh(geometry, material); - object.position.set(-400, 100, 0); - object.scale.multiplyScalar(1); - group.add(object); - } - - // NURBS volume - { - const nsControlPoints = [ - [ - [new THREE.Vector4(-200, -200, -200, 1), new THREE.Vector4(-200, -200, 200, 1)], - [new THREE.Vector4(-200, -100, -200, 1), new THREE.Vector4(-200, -100, 200, 1)], - [new THREE.Vector4(-200, 100, -200, 1), new THREE.Vector4(-200, 100, 200, 1)], - [new THREE.Vector4(-200, 200, -200, 1), new THREE.Vector4(-200, 200, 200, 1)], - ], - [ - [new THREE.Vector4(0, -200, -200, 1), new THREE.Vector4(0, -200, 200, 1)], - [new THREE.Vector4(0, -100, -200, 1), new THREE.Vector4(0, -100, 200, 1)], - [new THREE.Vector4(0, 100, -200, 1), new THREE.Vector4(0, 100, 200, 1)], - [new THREE.Vector4(0, 200, -200, 1), new THREE.Vector4(0, 200, 200, 1)], - ], - [ - [new THREE.Vector4(200, -200, -200, 1), new THREE.Vector4(200, -200, 200, 1)], - [new THREE.Vector4(200, -100, 0, 1), new THREE.Vector4(200, -100, 100, 1)], - [new THREE.Vector4(200, 100, 0, 1), new THREE.Vector4(200, 100, 100, 1)], - [new THREE.Vector4(200, 200, 0, 1), new THREE.Vector4(200, 200, 100, 1)], - ], - ]; - const degree1 = 2; - const degree2 = 3; - const degree3 = 1; - const knots1 = [0, 0, 0, 1, 1, 1]; - const knots2 = [0, 0, 0, 0, 1, 1, 1, 1]; - const knots3 = [0, 0, 1, 1]; - const nurbsVolume = new NURBSVolume(degree1, degree2, degree3, knots1, knots2, knots3, nsControlPoints); - - const map = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - map.wrapS = map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.colorSpace = THREE.SRGBColorSpace; - - // Since ParametricGeometry() only support bi-variate parametric geometries - // we create evaluation functions for different surfaces with one of the three - // parameter values (u, v, w) kept constant and create multiple THREE.Mesh - // objects one for each surface - function getSurfacePointFront(u, v, target) { - return nurbsVolume.getPoint(u, v, 0, target); - } - - function getSurfacePointMiddle(u, v, target) { - return nurbsVolume.getPoint(u, v, 0.5, target); - } - - function getSurfacePointBack(u, v, target) { - return nurbsVolume.getPoint(u, v, 1, target); - } - - function getSurfacePointTop(u, w, target) { - return nurbsVolume.getPoint(u, 1, w, target); - } - - function getSurfacePointSide(v, w, target) { - return nurbsVolume.getPoint(0, v, w, target); - } - - const geometryFront = new ParametricGeometry(getSurfacePointFront, 20, 20); - const materialFront = new THREE.MeshLambertMaterial({ map: map, side: THREE.DoubleSide }); - const objectFront = new THREE.Mesh(geometryFront, materialFront); - objectFront.position.set(400, 100, 0); - objectFront.scale.multiplyScalar(0.5); - group.add(objectFront); - - const geometryMiddle = new ParametricGeometry(getSurfacePointMiddle, 20, 20); - const materialMiddle = new THREE.MeshLambertMaterial({ map: map, side: THREE.DoubleSide }); - const objectMiddle = new THREE.Mesh(geometryMiddle, materialMiddle); - objectMiddle.position.set(400, 100, 0); - objectMiddle.scale.multiplyScalar(0.5); - group.add(objectMiddle); - - const geometryBack = new ParametricGeometry(getSurfacePointBack, 20, 20); - const materialBack = new THREE.MeshLambertMaterial({ map: map, side: THREE.DoubleSide }); - const objectBack = new THREE.Mesh(geometryBack, materialBack); - objectBack.position.set(400, 100, 0); - objectBack.scale.multiplyScalar(0.5); - group.add(objectBack); - - const geometryTop = new ParametricGeometry(getSurfacePointTop, 20, 20); - const materialTop = new THREE.MeshLambertMaterial({ map: map, side: THREE.DoubleSide }); - const objectTop = new THREE.Mesh(geometryTop, materialTop); - objectTop.position.set(400, 100, 0); - objectTop.scale.multiplyScalar(0.5); - group.add(objectTop); - - const geometrySide = new ParametricGeometry(getSurfacePointSide, 20, 20); - const materialSide = new THREE.MeshLambertMaterial({ map: map, side: THREE.DoubleSide }); - const objectSide = new THREE.Mesh(geometrySide, materialSide); - objectSide.position.set(400, 100, 0); - objectSide.scale.multiplyScalar(0.5); - group.add(objectSide); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - container.style.touchAction = 'none'; - container.addEventListener('pointerdown', onPointerDown); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function onPointerDown(event) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; - targetRotationOnPointerDown = targetRotation; - - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; - - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; -} - -function onPointerUp() { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); - document.removeEventListener('pointerup', onPointerUp); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - group.rotation.y += (targetRotation - group.rotation.y) * 0.05; - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_shapes.ts b/examples-testing/examples/webgl_geometry_shapes.ts deleted file mode 100644 index f1d00f011..000000000 --- a/examples-testing/examples/webgl_geometry_shapes.ts +++ /dev/null @@ -1,363 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let group; - -let targetRotation = 0; -let targetRotationOnPointerDown = 0; - -let pointerX = 0; -let pointerXOnPointerDown = 0; - -let windowHalfX = window.innerWidth / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 150, 500); - scene.add(camera); - - const light = new THREE.PointLight(0xffffff, 2.5, 0, 0); - camera.add(light); - - group = new THREE.Group(); - group.position.y = 50; - scene.add(group); - - const loader = new THREE.TextureLoader(); - const texture = loader.load('textures/uv_grid_opengl.jpg'); - texture.colorSpace = THREE.SRGBColorSpace; - - // it's necessary to apply these settings in order to correctly display the texture on a shape geometry - - texture.wrapS = texture.wrapT = THREE.RepeatWrapping; - texture.repeat.set(0.008, 0.008); - - function addShape(shape, extrudeSettings, color, x, y, z, rx, ry, rz, s) { - // flat shape with texture - // note: default UVs generated by THREE.ShapeGeometry are simply the x- and y-coordinates of the vertices - - let geometry = new THREE.ShapeGeometry(shape); - - let mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, map: texture })); - mesh.position.set(x, y, z - 175); - mesh.rotation.set(rx, ry, rz); - mesh.scale.set(s, s, s); - group.add(mesh); - - // flat shape - - geometry = new THREE.ShapeGeometry(shape); - - mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ color: color, side: THREE.DoubleSide })); - mesh.position.set(x, y, z - 125); - mesh.rotation.set(rx, ry, rz); - mesh.scale.set(s, s, s); - group.add(mesh); - - // extruded shape - - geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); - - mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ color: color })); - mesh.position.set(x, y, z - 75); - mesh.rotation.set(rx, ry, rz); - mesh.scale.set(s, s, s); - group.add(mesh); - - addLineShape(shape, color, x, y, z, rx, ry, rz, s); - } - - function addLineShape(shape, color, x, y, z, rx, ry, rz, s) { - // lines - - shape.autoClose = true; - - const points = shape.getPoints(); - const spacedPoints = shape.getSpacedPoints(50); - - const geometryPoints = new THREE.BufferGeometry().setFromPoints(points); - const geometrySpacedPoints = new THREE.BufferGeometry().setFromPoints(spacedPoints); - - // solid line - - let line = new THREE.Line(geometryPoints, new THREE.LineBasicMaterial({ color: color })); - line.position.set(x, y, z - 25); - line.rotation.set(rx, ry, rz); - line.scale.set(s, s, s); - group.add(line); - - // line from equidistance sampled points - - line = new THREE.Line(geometrySpacedPoints, new THREE.LineBasicMaterial({ color: color })); - line.position.set(x, y, z + 25); - line.rotation.set(rx, ry, rz); - line.scale.set(s, s, s); - group.add(line); - - // vertices from real points - - let particles = new THREE.Points(geometryPoints, new THREE.PointsMaterial({ color: color, size: 4 })); - particles.position.set(x, y, z + 75); - particles.rotation.set(rx, ry, rz); - particles.scale.set(s, s, s); - group.add(particles); - - // equidistance sampled points - - particles = new THREE.Points(geometrySpacedPoints, new THREE.PointsMaterial({ color: color, size: 4 })); - particles.position.set(x, y, z + 125); - particles.rotation.set(rx, ry, rz); - particles.scale.set(s, s, s); - group.add(particles); - } - - // California - - const californiaPts = []; - - californiaPts.push(new THREE.Vector2(610, 320)); - californiaPts.push(new THREE.Vector2(450, 300)); - californiaPts.push(new THREE.Vector2(392, 392)); - californiaPts.push(new THREE.Vector2(266, 438)); - californiaPts.push(new THREE.Vector2(190, 570)); - californiaPts.push(new THREE.Vector2(190, 600)); - californiaPts.push(new THREE.Vector2(160, 620)); - californiaPts.push(new THREE.Vector2(160, 650)); - californiaPts.push(new THREE.Vector2(180, 640)); - californiaPts.push(new THREE.Vector2(165, 680)); - californiaPts.push(new THREE.Vector2(150, 670)); - californiaPts.push(new THREE.Vector2(90, 737)); - californiaPts.push(new THREE.Vector2(80, 795)); - californiaPts.push(new THREE.Vector2(50, 835)); - californiaPts.push(new THREE.Vector2(64, 870)); - californiaPts.push(new THREE.Vector2(60, 945)); - californiaPts.push(new THREE.Vector2(300, 945)); - californiaPts.push(new THREE.Vector2(300, 743)); - californiaPts.push(new THREE.Vector2(600, 473)); - californiaPts.push(new THREE.Vector2(626, 425)); - californiaPts.push(new THREE.Vector2(600, 370)); - californiaPts.push(new THREE.Vector2(610, 320)); - - for (let i = 0; i < californiaPts.length; i++) californiaPts[i].multiplyScalar(0.25); - - const californiaShape = new THREE.Shape(californiaPts); - - // Triangle - - const triangleShape = new THREE.Shape().moveTo(80, 20).lineTo(40, 80).lineTo(120, 80).lineTo(80, 20); // close path - - // Heart - - const x = 0, - y = 0; - - const heartShape = new THREE.Shape() - .moveTo(x + 25, y + 25) - .bezierCurveTo(x + 25, y + 25, x + 20, y, x, y) - .bezierCurveTo(x - 30, y, x - 30, y + 35, x - 30, y + 35) - .bezierCurveTo(x - 30, y + 55, x - 10, y + 77, x + 25, y + 95) - .bezierCurveTo(x + 60, y + 77, x + 80, y + 55, x + 80, y + 35) - .bezierCurveTo(x + 80, y + 35, x + 80, y, x + 50, y) - .bezierCurveTo(x + 35, y, x + 25, y + 25, x + 25, y + 25); - - // Square - - const sqLength = 80; - - const squareShape = new THREE.Shape() - .moveTo(0, 0) - .lineTo(0, sqLength) - .lineTo(sqLength, sqLength) - .lineTo(sqLength, 0) - .lineTo(0, 0); - - // Rounded rectangle - - const roundedRectShape = new THREE.Shape(); - - (function roundedRect(ctx, x, y, width, height, radius) { - ctx.moveTo(x, y + radius); - ctx.lineTo(x, y + height - radius); - ctx.quadraticCurveTo(x, y + height, x + radius, y + height); - ctx.lineTo(x + width - radius, y + height); - ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius); - ctx.lineTo(x + width, y + radius); - ctx.quadraticCurveTo(x + width, y, x + width - radius, y); - ctx.lineTo(x + radius, y); - ctx.quadraticCurveTo(x, y, x, y + radius); - })(roundedRectShape, 0, 0, 50, 50, 20); - - // Track - - const trackShape = new THREE.Shape() - .moveTo(40, 40) - .lineTo(40, 160) - .absarc(60, 160, 20, Math.PI, 0, true) - .lineTo(80, 40) - .absarc(60, 40, 20, 2 * Math.PI, Math.PI, true); - - // Circle - - const circleRadius = 40; - const circleShape = new THREE.Shape() - .moveTo(0, circleRadius) - .quadraticCurveTo(circleRadius, circleRadius, circleRadius, 0) - .quadraticCurveTo(circleRadius, -circleRadius, 0, -circleRadius) - .quadraticCurveTo(-circleRadius, -circleRadius, -circleRadius, 0) - .quadraticCurveTo(-circleRadius, circleRadius, 0, circleRadius); - - // Fish - - const fishShape = new THREE.Shape() - .moveTo(x, y) - .quadraticCurveTo(x + 50, y - 80, x + 90, y - 10) - .quadraticCurveTo(x + 100, y - 10, x + 115, y - 40) - .quadraticCurveTo(x + 115, y, x + 115, y + 40) - .quadraticCurveTo(x + 100, y + 10, x + 90, y + 10) - .quadraticCurveTo(x + 50, y + 80, x, y); - - // Arc circle - - const arcShape = new THREE.Shape().moveTo(50, 10).absarc(10, 10, 40, 0, Math.PI * 2, false); - - const holePath = new THREE.Path().moveTo(20, 10).absarc(10, 10, 10, 0, Math.PI * 2, true); - - arcShape.holes.push(holePath); - - // Smiley - - const smileyShape = new THREE.Shape().moveTo(80, 40).absarc(40, 40, 40, 0, Math.PI * 2, false); - - const smileyEye1Path = new THREE.Path().moveTo(35, 20).absellipse(25, 20, 10, 10, 0, Math.PI * 2, true); - - const smileyEye2Path = new THREE.Path().moveTo(65, 20).absarc(55, 20, 10, 0, Math.PI * 2, true); - - const smileyMouthPath = new THREE.Path() - .moveTo(20, 40) - .quadraticCurveTo(40, 60, 60, 40) - .bezierCurveTo(70, 45, 70, 50, 60, 60) - .quadraticCurveTo(40, 80, 20, 60) - .quadraticCurveTo(5, 50, 20, 40); - - smileyShape.holes.push(smileyEye1Path); - smileyShape.holes.push(smileyEye2Path); - smileyShape.holes.push(smileyMouthPath); - - // Spline shape - - const splinepts = []; - splinepts.push(new THREE.Vector2(70, 20)); - splinepts.push(new THREE.Vector2(80, 90)); - splinepts.push(new THREE.Vector2(-30, 70)); - splinepts.push(new THREE.Vector2(0, 0)); - - const splineShape = new THREE.Shape().moveTo(0, 0).splineThru(splinepts); - - const extrudeSettings = { - depth: 8, - bevelEnabled: true, - bevelSegments: 2, - steps: 2, - bevelSize: 1, - bevelThickness: 1, - }; - - // addShape( shape, color, x, y, z, rx, ry,rz, s ); - - addShape(californiaShape, extrudeSettings, 0xf08000, -300, -100, 0, 0, 0, 0, 1); - addShape(triangleShape, extrudeSettings, 0x8080f0, -180, 0, 0, 0, 0, 0, 1); - addShape(roundedRectShape, extrudeSettings, 0x008000, -150, 150, 0, 0, 0, 0, 1); - addShape(trackShape, extrudeSettings, 0x008080, 200, -100, 0, 0, 0, 0, 1); - addShape(squareShape, extrudeSettings, 0x0040f0, 150, 100, 0, 0, 0, 0, 1); - addShape(heartShape, extrudeSettings, 0xf00000, 60, 100, 0, 0, 0, Math.PI, 1); - addShape(circleShape, extrudeSettings, 0x00f000, 120, 250, 0, 0, 0, 0, 1); - addShape(fishShape, extrudeSettings, 0x404040, -60, 200, 0, 0, 0, 0, 1); - addShape(smileyShape, extrudeSettings, 0xf000f0, -200, 250, 0, 0, 0, Math.PI, 1); - addShape(arcShape, extrudeSettings, 0x804000, 150, 0, 0, 0, 0, 0, 1); - addShape(splineShape, extrudeSettings, 0x808080, -50, -100, 0, 0, 0, 0, 1); - - addLineShape(arcShape.holes[0], 0x804000, 150, 0, 0, 0, 0, 0, 1); - - for (let i = 0; i < smileyShape.holes.length; i += 1) { - addLineShape(smileyShape.holes[i], 0xf000f0, -200, 250, 0, 0, 0, Math.PI, 1); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - container.style.touchAction = 'none'; - container.addEventListener('pointerdown', onPointerDown); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function onPointerDown(event) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; - targetRotationOnPointerDown = targetRotation; - - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; - - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; -} - -function onPointerUp() { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); - document.removeEventListener('pointerup', onPointerUp); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - group.rotation.y += (targetRotation - group.rotation.y) * 0.05; - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_teapot.ts b/examples-testing/examples/webgl_geometry_teapot.ts deleted file mode 100644 index 4c884a559..000000000 --- a/examples-testing/examples/webgl_geometry_teapot.ts +++ /dev/null @@ -1,180 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js'; - -let camera, scene, renderer; -let cameraControls; -let effectController; -const teapotSize = 300; -let ambientLight, light; - -let tess = -1; // force initialization -let bBottom; -let bLid; -let bBody; -let bFitLid; -let bNonBlinn; -let shading; - -let teapot, textureCube; -const materials = {}; - -init(); -render(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - const canvasWidth = window.innerWidth; - const canvasHeight = window.innerHeight; - - // CAMERA - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 80000); - camera.position.set(-600, 550, 1300); - - // LIGHTS - ambientLight = new THREE.AmbientLight(0x7c7c7c, 3.0); - - light = new THREE.DirectionalLight(0xffffff, 3.0); - light.position.set(0.32, 0.39, 0.7); - - // RENDERER - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(canvasWidth, canvasHeight); - container.appendChild(renderer.domElement); - - // EVENTS - window.addEventListener('resize', onWindowResize); - - // CONTROLS - cameraControls = new OrbitControls(camera, renderer.domElement); - cameraControls.addEventListener('change', render); - - // TEXTURE MAP - const textureMap = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - textureMap.wrapS = textureMap.wrapT = THREE.RepeatWrapping; - textureMap.anisotropy = 16; - textureMap.colorSpace = THREE.SRGBColorSpace; - - // REFLECTION MAP - const path = 'textures/cube/pisa/'; - const urls = ['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']; - - textureCube = new THREE.CubeTextureLoader().setPath(path).load(urls); - - materials['wireframe'] = new THREE.MeshBasicMaterial({ wireframe: true }); - materials['flat'] = new THREE.MeshPhongMaterial({ specular: 0x000000, flatShading: true, side: THREE.DoubleSide }); - materials['smooth'] = new THREE.MeshLambertMaterial({ side: THREE.DoubleSide }); - materials['glossy'] = new THREE.MeshPhongMaterial({ side: THREE.DoubleSide }); - materials['textured'] = new THREE.MeshPhongMaterial({ map: textureMap, side: THREE.DoubleSide }); - materials['reflective'] = new THREE.MeshPhongMaterial({ envMap: textureCube, side: THREE.DoubleSide }); - - // scene itself - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xaaaaaa); - - scene.add(ambientLight); - scene.add(light); - - // GUI - setupGui(); -} - -// EVENT HANDLERS - -function onWindowResize() { - const canvasWidth = window.innerWidth; - const canvasHeight = window.innerHeight; - - renderer.setSize(canvasWidth, canvasHeight); - - camera.aspect = canvasWidth / canvasHeight; - camera.updateProjectionMatrix(); - - render(); -} - -function setupGui() { - effectController = { - newTess: 15, - bottom: true, - lid: true, - body: true, - fitLid: false, - nonblinn: false, - newShading: 'glossy', - }; - - const gui = new GUI(); - gui.add(effectController, 'newTess', [2, 3, 4, 5, 6, 8, 10, 15, 20, 30, 40, 50]) - .name('Tessellation Level') - .onChange(render); - gui.add(effectController, 'lid').name('display lid').onChange(render); - gui.add(effectController, 'body').name('display body').onChange(render); - gui.add(effectController, 'bottom').name('display bottom').onChange(render); - gui.add(effectController, 'fitLid').name('snug lid').onChange(render); - gui.add(effectController, 'nonblinn').name('original scale').onChange(render); - gui.add(effectController, 'newShading', ['wireframe', 'flat', 'smooth', 'glossy', 'textured', 'reflective']) - .name('Shading') - .onChange(render); -} - -// - -function render() { - if ( - effectController.newTess !== tess || - effectController.bottom !== bBottom || - effectController.lid !== bLid || - effectController.body !== bBody || - effectController.fitLid !== bFitLid || - effectController.nonblinn !== bNonBlinn || - effectController.newShading !== shading - ) { - tess = effectController.newTess; - bBottom = effectController.bottom; - bLid = effectController.lid; - bBody = effectController.body; - bFitLid = effectController.fitLid; - bNonBlinn = effectController.nonblinn; - shading = effectController.newShading; - - createNewTeapot(); - } - - // skybox is rendered separately, so that it is always behind the teapot. - if (shading === 'reflective') { - scene.background = textureCube; - } else { - scene.background = null; - } - - renderer.render(scene, camera); -} - -// Whenever the teapot changes, the scene is rebuilt from scratch (not much to it). -function createNewTeapot() { - if (teapot !== undefined) { - teapot.geometry.dispose(); - scene.remove(teapot); - } - - const geometry = new TeapotGeometry( - teapotSize, - tess, - effectController.bottom, - effectController.lid, - effectController.body, - effectController.fitLid, - !effectController.nonblinn, - ); - - teapot = new THREE.Mesh(geometry, materials[shading]); - - scene.add(teapot); -} diff --git a/examples-testing/examples/webgl_geometry_terrain.ts b/examples-testing/examples/webgl_geometry_terrain.ts deleted file mode 100644 index 8b6ed84ea..000000000 --- a/examples-testing/examples/webgl_geometry_terrain.ts +++ /dev/null @@ -1,173 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; -import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - -let container, stats; -let camera, controls, scene, renderer; -let mesh, texture; - -const worldWidth = 256, - worldDepth = 256; -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xefd1b5); - scene.fog = new THREE.FogExp2(0xefd1b5, 0.0025); - - const data = generateHeight(worldWidth, worldDepth); - - camera.position.set(100, 800, -800); - camera.lookAt(-100, 810, -800); - - const geometry = new THREE.PlaneGeometry(7500, 7500, worldWidth - 1, worldDepth - 1); - geometry.rotateX(-Math.PI / 2); - - const vertices = geometry.attributes.position.array; - - for (let i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) { - vertices[j + 1] = data[i] * 10; - } - - texture = new THREE.CanvasTexture(generateTexture(data, worldWidth, worldDepth)); - texture.wrapS = THREE.ClampToEdgeWrapping; - texture.wrapT = THREE.ClampToEdgeWrapping; - texture.colorSpace = THREE.SRGBColorSpace; - - mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map: texture })); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - controls = new FirstPersonControls(camera, renderer.domElement); - controls.movementSpeed = 150; - controls.lookSpeed = 0.1; - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - controls.handleResize(); -} - -function generateHeight(width, height) { - let seed = Math.PI / 4; - window.Math.random = function () { - const x = Math.sin(seed++) * 10000; - return x - Math.floor(x); - }; - - const size = width * height, - data = new Uint8Array(size); - const perlin = new ImprovedNoise(), - z = Math.random() * 100; - - let quality = 1; - - for (let j = 0; j < 4; j++) { - for (let i = 0; i < size; i++) { - const x = i % width, - y = ~~(i / width); - data[i] += Math.abs(perlin.noise(x / quality, y / quality, z) * quality * 1.75); - } - - quality *= 5; - } - - return data; -} - -function generateTexture(data, width, height) { - let context, image, imageData, shade; - - const vector3 = new THREE.Vector3(0, 0, 0); - - const sun = new THREE.Vector3(1, 1, 1); - sun.normalize(); - - const canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - - context = canvas.getContext('2d'); - context.fillStyle = '#000'; - context.fillRect(0, 0, width, height); - - image = context.getImageData(0, 0, canvas.width, canvas.height); - imageData = image.data; - - for (let i = 0, j = 0, l = imageData.length; i < l; i += 4, j++) { - vector3.x = data[j - 2] - data[j + 2]; - vector3.y = 2; - vector3.z = data[j - width * 2] - data[j + width * 2]; - vector3.normalize(); - - shade = vector3.dot(sun); - - imageData[i] = (96 + shade * 128) * (0.5 + data[j] * 0.007); - imageData[i + 1] = (32 + shade * 96) * (0.5 + data[j] * 0.007); - imageData[i + 2] = shade * 96 * (0.5 + data[j] * 0.007); - } - - context.putImageData(image, 0, 0); - - // Scaled 4x - - const canvasScaled = document.createElement('canvas'); - canvasScaled.width = width * 4; - canvasScaled.height = height * 4; - - context = canvasScaled.getContext('2d'); - context.scale(4, 4); - context.drawImage(canvas, 0, 0); - - image = context.getImageData(0, 0, canvasScaled.width, canvasScaled.height); - imageData = image.data; - - for (let i = 0, l = imageData.length; i < l; i += 4) { - const v = ~~(Math.random() * 5); - - imageData[i] += v; - imageData[i + 1] += v; - imageData[i + 2] += v; - } - - context.putImageData(image, 0, 0); - - return canvasScaled; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - controls.update(clock.getDelta()); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_terrain_raycast.ts b/examples-testing/examples/webgl_geometry_terrain_raycast.ts deleted file mode 100644 index f1383c138..000000000 --- a/examples-testing/examples/webgl_geometry_terrain_raycast.ts +++ /dev/null @@ -1,206 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - -let container, stats; - -let camera, controls, scene, renderer; - -let mesh, texture; - -const worldWidth = 256, - worldDepth = 256, - worldHalfWidth = worldWidth / 2, - worldHalfDepth = worldDepth / 2; - -let helper; - -const raycaster = new THREE.Raycaster(); -const pointer = new THREE.Vector2(); - -init(); - -function init() { - container = document.getElementById('container'); - container.innerHTML = ''; - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xbfd1e5); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 10, 20000); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1000; - controls.maxDistance = 10000; - controls.maxPolarAngle = Math.PI / 2; - - // - - const data = generateHeight(worldWidth, worldDepth); - - controls.target.y = data[worldHalfWidth + worldHalfDepth * worldWidth] + 500; - camera.position.y = controls.target.y + 2000; - camera.position.x = 2000; - controls.update(); - - const geometry = new THREE.PlaneGeometry(7500, 7500, worldWidth - 1, worldDepth - 1); - geometry.rotateX(-Math.PI / 2); - - const vertices = geometry.attributes.position.array; - - for (let i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) { - vertices[j + 1] = data[i] * 10; - } - - // - - texture = new THREE.CanvasTexture(generateTexture(data, worldWidth, worldDepth)); - texture.wrapS = THREE.ClampToEdgeWrapping; - texture.wrapT = THREE.ClampToEdgeWrapping; - texture.colorSpace = THREE.SRGBColorSpace; - - mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map: texture })); - scene.add(mesh); - - const geometryHelper = new THREE.ConeGeometry(20, 100, 3); - geometryHelper.translate(0, 50, 0); - geometryHelper.rotateX(Math.PI / 2); - helper = new THREE.Mesh(geometryHelper, new THREE.MeshNormalMaterial()); - scene.add(helper); - - container.addEventListener('pointermove', onPointerMove); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function generateHeight(width, height) { - const size = width * height, - data = new Uint8Array(size), - perlin = new ImprovedNoise(), - z = Math.random() * 100; - - let quality = 1; - - for (let j = 0; j < 4; j++) { - for (let i = 0; i < size; i++) { - const x = i % width, - y = ~~(i / width); - data[i] += Math.abs(perlin.noise(x / quality, y / quality, z) * quality * 1.75); - } - - quality *= 5; - } - - return data; -} - -function generateTexture(data, width, height) { - // bake lighting into texture - - let context, image, imageData, shade; - - const vector3 = new THREE.Vector3(0, 0, 0); - - const sun = new THREE.Vector3(1, 1, 1); - sun.normalize(); - - const canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - - context = canvas.getContext('2d'); - context.fillStyle = '#000'; - context.fillRect(0, 0, width, height); - - image = context.getImageData(0, 0, canvas.width, canvas.height); - imageData = image.data; - - for (let i = 0, j = 0, l = imageData.length; i < l; i += 4, j++) { - vector3.x = data[j - 2] - data[j + 2]; - vector3.y = 2; - vector3.z = data[j - width * 2] - data[j + width * 2]; - vector3.normalize(); - - shade = vector3.dot(sun); - - imageData[i] = (96 + shade * 128) * (0.5 + data[j] * 0.007); - imageData[i + 1] = (32 + shade * 96) * (0.5 + data[j] * 0.007); - imageData[i + 2] = shade * 96 * (0.5 + data[j] * 0.007); - } - - context.putImageData(image, 0, 0); - - // Scaled 4x - - const canvasScaled = document.createElement('canvas'); - canvasScaled.width = width * 4; - canvasScaled.height = height * 4; - - context = canvasScaled.getContext('2d'); - context.scale(4, 4); - context.drawImage(canvas, 0, 0); - - image = context.getImageData(0, 0, canvasScaled.width, canvasScaled.height); - imageData = image.data; - - for (let i = 0, l = imageData.length; i < l; i += 4) { - const v = ~~(Math.random() * 5); - - imageData[i] += v; - imageData[i + 1] += v; - imageData[i + 2] += v; - } - - context.putImageData(image, 0, 0); - - return canvasScaled; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - renderer.render(scene, camera); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1; - pointer.y = -(event.clientY / renderer.domElement.clientHeight) * 2 + 1; - raycaster.setFromCamera(pointer, camera); - - // See if the ray from the camera into the world hits one of our meshes - const intersects = raycaster.intersectObject(mesh); - - // Toggle rotation bool for meshes that we clicked - if (intersects.length > 0) { - helper.position.set(0, 0, 0); - helper.lookAt(intersects[0].face.normal); - - helper.position.copy(intersects[0].point); - } -} diff --git a/examples-testing/examples/webgl_geometry_text.ts b/examples-testing/examples/webgl_geometry_text.ts deleted file mode 100644 index 831ebcd6b..000000000 --- a/examples-testing/examples/webgl_geometry_text.ts +++ /dev/null @@ -1,312 +0,0 @@ -import * as THREE from 'three'; - -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -THREE.Cache.enabled = true; - -let container; - -let camera, cameraTarget, scene, renderer; - -let group, textMesh1, textMesh2, textGeo, materials; - -let firstLetter = true; - -let text = 'three.js', - bevelEnabled = true, - font = undefined, - fontName = 'optimer', // helvetiker, optimer, gentilis, droid sans, droid serif - fontWeight = 'bold'; // normal bold - -const depth = 20, - size = 70, - hover = 30, - curveSegments = 4, - bevelThickness = 2, - bevelSize = 1.5; - -const mirror = true; - -const fontMap = { - helvetiker: 0, - optimer: 1, - gentilis: 2, - 'droid/droid_sans': 3, - 'droid/droid_serif': 4, -}; - -const weightMap = { - regular: 0, - bold: 1, -}; - -const reverseFontMap = []; -const reverseWeightMap = []; - -for (const i in fontMap) reverseFontMap[fontMap[i]] = i; -for (const i in weightMap) reverseWeightMap[weightMap[i]] = i; - -let targetRotation = 0; -let targetRotationOnPointerDown = 0; - -let pointerX = 0; -let pointerXOnPointerDown = 0; - -let windowHalfX = window.innerWidth / 2; - -let fontIndex = 1; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 1500); - camera.position.set(0, 400, 700); - - cameraTarget = new THREE.Vector3(0, 150, 0); - - // SCENE - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x000000); - scene.fog = new THREE.Fog(0x000000, 250, 1400); - - // LIGHTS - - const dirLight = new THREE.DirectionalLight(0xffffff, 0.4); - dirLight.position.set(0, 0, 1).normalize(); - scene.add(dirLight); - - const pointLight = new THREE.PointLight(0xffffff, 4.5, 0, 0); - pointLight.color.setHSL(Math.random(), 1, 0.5); - pointLight.position.set(0, 100, 90); - scene.add(pointLight); - - materials = [ - new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }), // front - new THREE.MeshPhongMaterial({ color: 0xffffff }), // side - ]; - - group = new THREE.Group(); - group.position.y = 100; - - scene.add(group); - - loadFont(); - - const plane = new THREE.Mesh( - new THREE.PlaneGeometry(10000, 10000), - new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.5, transparent: true }), - ); - plane.position.y = 100; - plane.rotation.x = -Math.PI / 2; - scene.add(plane); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // EVENTS - - container.style.touchAction = 'none'; - container.addEventListener('pointerdown', onPointerDown); - - document.addEventListener('keypress', onDocumentKeyPress); - document.addEventListener('keydown', onDocumentKeyDown); - - // - - const params = { - changeColor: function () { - pointLight.color.setHSL(Math.random(), 1, 0.5); - }, - changeFont: function () { - fontIndex++; - - fontName = reverseFontMap[fontIndex % reverseFontMap.length]; - - loadFont(); - }, - changeWeight: function () { - if (fontWeight === 'bold') { - fontWeight = 'regular'; - } else { - fontWeight = 'bold'; - } - - loadFont(); - }, - changeBevel: function () { - bevelEnabled = !bevelEnabled; - - refreshText(); - }, - }; - - // - - const gui = new GUI(); - - gui.add(params, 'changeColor').name('change color'); - gui.add(params, 'changeFont').name('change font'); - gui.add(params, 'changeWeight').name('change weight'); - gui.add(params, 'changeBevel').name('change bevel'); - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function onDocumentKeyDown(event) { - if (firstLetter) { - firstLetter = false; - text = ''; - } - - const keyCode = event.keyCode; - - // backspace - - if (keyCode == 8) { - event.preventDefault(); - - text = text.substring(0, text.length - 1); - refreshText(); - - return false; - } -} - -function onDocumentKeyPress(event) { - const keyCode = event.which; - - // backspace - - if (keyCode == 8) { - event.preventDefault(); - } else { - const ch = String.fromCharCode(keyCode); - text += ch; - - refreshText(); - } -} - -function loadFont() { - const loader = new FontLoader(); - loader.load('fonts/' + fontName + '_' + fontWeight + '.typeface.json', function (response) { - font = response; - - refreshText(); - }); -} - -function createText() { - textGeo = new TextGeometry(text, { - font: font, - - size: size, - depth: depth, - curveSegments: curveSegments, - - bevelThickness: bevelThickness, - bevelSize: bevelSize, - bevelEnabled: bevelEnabled, - }); - - textGeo.computeBoundingBox(); - - const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); - - textMesh1 = new THREE.Mesh(textGeo, materials); - - textMesh1.position.x = centerOffset; - textMesh1.position.y = hover; - textMesh1.position.z = 0; - - textMesh1.rotation.x = 0; - textMesh1.rotation.y = Math.PI * 2; - - group.add(textMesh1); - - if (mirror) { - textMesh2 = new THREE.Mesh(textGeo, materials); - - textMesh2.position.x = centerOffset; - textMesh2.position.y = -hover; - textMesh2.position.z = depth; - - textMesh2.rotation.x = Math.PI; - textMesh2.rotation.y = Math.PI * 2; - - group.add(textMesh2); - } -} - -function refreshText() { - group.remove(textMesh1); - if (mirror) group.remove(textMesh2); - - if (!text) return; - - createText(); -} - -function onPointerDown(event) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; - targetRotationOnPointerDown = targetRotation; - - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; - - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; -} - -function onPointerUp() { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); - document.removeEventListener('pointerup', onPointerUp); -} - -// - -function animate() { - group.rotation.y += (targetRotation - group.rotation.y) * 0.05; - - camera.lookAt(cameraTarget); - - renderer.clear(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_text_shapes.ts b/examples-testing/examples/webgl_geometry_text_shapes.ts deleted file mode 100644 index adfb6008d..000000000 --- a/examples-testing/examples/webgl_geometry_text_shapes.ts +++ /dev/null @@ -1,112 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(0, -400, 600); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_regular.typeface.json', function (font) { - const color = 0x006699; - - const matDark = new THREE.LineBasicMaterial({ - color: color, - side: THREE.DoubleSide, - }); - - const matLite = new THREE.MeshBasicMaterial({ - color: color, - transparent: true, - opacity: 0.4, - side: THREE.DoubleSide, - }); - - const message = ' Three.js\nSimple text.'; - - const shapes = font.generateShapes(message, 100); - - const geometry = new THREE.ShapeGeometry(shapes); - - geometry.computeBoundingBox(); - - const xMid = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x); - - geometry.translate(xMid, 0, 0); - - // make shape ( N.B. edge view not visible ) - - const text = new THREE.Mesh(geometry, matLite); - text.position.z = -150; - scene.add(text); - - // make line shape ( N.B. edge view remains visible ) - - const holeShapes = []; - - for (let i = 0; i < shapes.length; i++) { - const shape = shapes[i]; - - if (shape.holes && shape.holes.length > 0) { - for (let j = 0; j < shape.holes.length; j++) { - const hole = shape.holes[j]; - holeShapes.push(hole); - } - } - } - - shapes.push.apply(shapes, holeShapes); - - const lineText = new THREE.Object3D(); - - for (let i = 0; i < shapes.length; i++) { - const shape = shapes[i]; - - const points = shape.getPoints(); - const geometry = new THREE.BufferGeometry().setFromPoints(points); - - geometry.translate(xMid, 0, 0); - - const lineMesh = new THREE.Line(geometry, matDark); - lineText.add(lineMesh); - } - - scene.add(lineText); - - render(); - }); //end load function - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0, 0); - controls.update(); - - controls.addEventListener('change', render); - - window.addEventListener('resize', onWindowResize); -} // end init - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_geometry_text_stroke.ts b/examples-testing/examples/webgl_geometry_text_stroke.ts deleted file mode 100644 index 9a1983253..000000000 --- a/examples-testing/examples/webgl_geometry_text_stroke.ts +++ /dev/null @@ -1,116 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { SVGLoader } from 'three/addons/loaders/SVGLoader.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(0, -400, 600); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_regular.typeface.json', function (font) { - const color = new THREE.Color(0x006699); - - const matDark = new THREE.MeshBasicMaterial({ - color: color, - side: THREE.DoubleSide, - }); - - const matLite = new THREE.MeshBasicMaterial({ - color: color, - transparent: true, - opacity: 0.4, - side: THREE.DoubleSide, - }); - - const message = ' Three.js\nStroke text.'; - - const shapes = font.generateShapes(message, 100); - - const geometry = new THREE.ShapeGeometry(shapes); - - geometry.computeBoundingBox(); - - const xMid = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x); - - geometry.translate(xMid, 0, 0); - - // make shape ( N.B. edge view not visible ) - - const text = new THREE.Mesh(geometry, matLite); - text.position.z = -150; - scene.add(text); - - // make line shape ( N.B. edge view remains visible ) - - const holeShapes = []; - - for (let i = 0; i < shapes.length; i++) { - const shape = shapes[i]; - - if (shape.holes && shape.holes.length > 0) { - for (let j = 0; j < shape.holes.length; j++) { - const hole = shape.holes[j]; - holeShapes.push(hole); - } - } - } - - shapes.push.apply(shapes, holeShapes); - - const style = SVGLoader.getStrokeStyle(5, color.getStyle()); - - const strokeText = new THREE.Group(); - - for (let i = 0; i < shapes.length; i++) { - const shape = shapes[i]; - - const points = shape.getPoints(); - - const geometry = SVGLoader.pointsToStroke(points, style); - - geometry.translate(xMid, 0, 0); - - const strokeMesh = new THREE.Mesh(geometry, matDark); - strokeText.add(strokeMesh); - } - - scene.add(strokeText); - - render(); - }); //end load function - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0, 0); - controls.update(); - - controls.addEventListener('change', render); - - window.addEventListener('resize', onWindowResize); -} // end init - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_gpgpu_birds.ts b/examples-testing/examples/webgl_gpgpu_birds.ts deleted file mode 100644 index 20a5e0d97..000000000 --- a/examples-testing/examples/webgl_gpgpu_birds.ts +++ /dev/null @@ -1,313 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; - -/* TEXTURE WIDTH FOR SIMULATION */ -const WIDTH = 32; - -const BIRDS = WIDTH * WIDTH; - -// Custom Geometry - using 3 triangles each. No UVs, no normals currently. -class BirdGeometry extends THREE.BufferGeometry { - constructor() { - super(); - - const trianglesPerBird = 3; - const triangles = BIRDS * trianglesPerBird; - const points = triangles * 3; - - const vertices = new THREE.BufferAttribute(new Float32Array(points * 3), 3); - const birdColors = new THREE.BufferAttribute(new Float32Array(points * 3), 3); - const references = new THREE.BufferAttribute(new Float32Array(points * 2), 2); - const birdVertex = new THREE.BufferAttribute(new Float32Array(points), 1); - - this.setAttribute('position', vertices); - this.setAttribute('birdColor', birdColors); - this.setAttribute('reference', references); - this.setAttribute('birdVertex', birdVertex); - - // this.setAttribute( 'normal', new Float32Array( points * 3 ), 3 ); - - let v = 0; - - function verts_push() { - for (let i = 0; i < arguments.length; i++) { - vertices.array[v++] = arguments[i]; - } - } - - const wingsSpan = 20; - - for (let f = 0; f < BIRDS; f++) { - // Body - - verts_push(0, -0, -20, 0, 4, -20, 0, 0, 30); - - // Wings - - verts_push(0, 0, -15, -wingsSpan, 0, 0, 0, 0, 15); - - verts_push(0, 0, 15, wingsSpan, 0, 0, 0, 0, -15); - } - - for (let v = 0; v < triangles * 3; v++) { - const triangleIndex = ~~(v / 3); - const birdIndex = ~~(triangleIndex / trianglesPerBird); - const x = (birdIndex % WIDTH) / WIDTH; - const y = ~~(birdIndex / WIDTH) / WIDTH; - - const c = new THREE.Color(0x666666 + (~~(v / 9) / BIRDS) * 0x666666); - - birdColors.array[v * 3 + 0] = c.r; - birdColors.array[v * 3 + 1] = c.g; - birdColors.array[v * 3 + 2] = c.b; - - references.array[v * 2] = x; - references.array[v * 2 + 1] = y; - - birdVertex.array[v] = v % 9; - } - - this.scale(0.2, 0.2, 0.2); - } -} - -// - -let container, stats; -let camera, scene, renderer; -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -const BOUNDS = 800, - BOUNDS_HALF = BOUNDS / 2; - -let last = performance.now(); - -let gpuCompute; -let velocityVariable; -let positionVariable; -let positionUniforms; -let velocityUniforms; -let birdUniforms; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 3000); - camera.position.z = 350; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - scene.fog = new THREE.Fog(0xffffff, 100, 1000); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - initComputeRenderer(); - - stats = new Stats(); - container.appendChild(stats.dom); - - container.style.touchAction = 'none'; - container.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - const effectController = { - separation: 20.0, - alignment: 20.0, - cohesion: 20.0, - freedom: 0.75, - }; - - const valuesChanger = function () { - velocityUniforms['separationDistance'].value = effectController.separation; - velocityUniforms['alignmentDistance'].value = effectController.alignment; - velocityUniforms['cohesionDistance'].value = effectController.cohesion; - velocityUniforms['freedomFactor'].value = effectController.freedom; - }; - - valuesChanger(); - - gui.add(effectController, 'separation', 0.0, 100.0, 1.0).onChange(valuesChanger); - gui.add(effectController, 'alignment', 0.0, 100, 0.001).onChange(valuesChanger); - gui.add(effectController, 'cohesion', 0.0, 100, 0.025).onChange(valuesChanger); - gui.close(); - - initBirds(); -} - -function initComputeRenderer() { - gpuCompute = new GPUComputationRenderer(WIDTH, WIDTH, renderer); - - const dtPosition = gpuCompute.createTexture(); - const dtVelocity = gpuCompute.createTexture(); - fillPositionTexture(dtPosition); - fillVelocityTexture(dtVelocity); - - velocityVariable = gpuCompute.addVariable( - 'textureVelocity', - document.getElementById('fragmentShaderVelocity').textContent, - dtVelocity, - ); - positionVariable = gpuCompute.addVariable( - 'texturePosition', - document.getElementById('fragmentShaderPosition').textContent, - dtPosition, - ); - - gpuCompute.setVariableDependencies(velocityVariable, [positionVariable, velocityVariable]); - gpuCompute.setVariableDependencies(positionVariable, [positionVariable, velocityVariable]); - - positionUniforms = positionVariable.material.uniforms; - velocityUniforms = velocityVariable.material.uniforms; - - positionUniforms['time'] = { value: 0.0 }; - positionUniforms['delta'] = { value: 0.0 }; - velocityUniforms['time'] = { value: 1.0 }; - velocityUniforms['delta'] = { value: 0.0 }; - velocityUniforms['testing'] = { value: 1.0 }; - velocityUniforms['separationDistance'] = { value: 1.0 }; - velocityUniforms['alignmentDistance'] = { value: 1.0 }; - velocityUniforms['cohesionDistance'] = { value: 1.0 }; - velocityUniforms['freedomFactor'] = { value: 1.0 }; - velocityUniforms['predator'] = { value: new THREE.Vector3() }; - velocityVariable.material.defines.BOUNDS = BOUNDS.toFixed(2); - - velocityVariable.wrapS = THREE.RepeatWrapping; - velocityVariable.wrapT = THREE.RepeatWrapping; - positionVariable.wrapS = THREE.RepeatWrapping; - positionVariable.wrapT = THREE.RepeatWrapping; - - const error = gpuCompute.init(); - - if (error !== null) { - console.error(error); - } -} - -function initBirds() { - const geometry = new BirdGeometry(); - - // For Vertex and Fragment - birdUniforms = { - color: { value: new THREE.Color(0xff2200) }, - texturePosition: { value: null }, - textureVelocity: { value: null }, - time: { value: 1.0 }, - delta: { value: 0.0 }, - }; - - // THREE.ShaderMaterial - const material = new THREE.ShaderMaterial({ - uniforms: birdUniforms, - vertexShader: document.getElementById('birdVS').textContent, - fragmentShader: document.getElementById('birdFS').textContent, - side: THREE.DoubleSide, - }); - - const birdMesh = new THREE.Mesh(geometry, material); - birdMesh.rotation.y = Math.PI / 2; - birdMesh.matrixAutoUpdate = false; - birdMesh.updateMatrix(); - - scene.add(birdMesh); -} - -function fillPositionTexture(texture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { - const x = Math.random() * BOUNDS - BOUNDS_HALF; - const y = Math.random() * BOUNDS - BOUNDS_HALF; - const z = Math.random() * BOUNDS - BOUNDS_HALF; - - theArray[k + 0] = x; - theArray[k + 1] = y; - theArray[k + 2] = z; - theArray[k + 3] = 1; - } -} - -function fillVelocityTexture(texture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { - const x = Math.random() - 0.5; - const y = Math.random() - 0.5; - const z = Math.random() - 0.5; - - theArray[k + 0] = x * 10; - theArray[k + 1] = y * 10; - theArray[k + 2] = z * 10; - theArray[k + 3] = 1; - } -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const now = performance.now(); - let delta = (now - last) / 1000; - - if (delta > 1) delta = 1; // safety cap on large deltas - last = now; - - positionUniforms['time'].value = now; - positionUniforms['delta'].value = delta; - velocityUniforms['time'].value = now; - velocityUniforms['delta'].value = delta; - birdUniforms['time'].value = now; - birdUniforms['delta'].value = delta; - - velocityUniforms['predator'].value.set((0.5 * mouseX) / windowHalfX, (-0.5 * mouseY) / windowHalfY, 0); - - mouseX = 10000; - mouseY = 10000; - - gpuCompute.compute(); - - birdUniforms['texturePosition'].value = gpuCompute.getCurrentRenderTarget(positionVariable).texture; - birdUniforms['textureVelocity'].value = gpuCompute.getCurrentRenderTarget(velocityVariable).texture; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_gpgpu_birds_gltf.ts b/examples-testing/examples/webgl_gpgpu_birds_gltf.ts deleted file mode 100644 index 3176b95a9..000000000 --- a/examples-testing/examples/webgl_gpgpu_birds_gltf.ts +++ /dev/null @@ -1,415 +0,0 @@ -import * as THREE from 'three'; -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; - -/* TEXTURE WIDTH FOR SIMULATION */ -const WIDTH = 64; -const BIRDS = WIDTH * WIDTH; - -/* BAKE ANIMATION INTO TEXTURE and CREATE GEOMETRY FROM BASE MODEL */ -const BirdGeometry = new THREE.BufferGeometry(); -let textureAnimation, durationAnimation, birdMesh, materialShader, indicesPerBird; - -function nextPowerOf2(n) { - return Math.pow(2, Math.ceil(Math.log(n) / Math.log(2))); -} - -Math.lerp = function (value1, value2, amount) { - amount = Math.max(Math.min(amount, 1), 0); - return value1 + (value2 - value1) * amount; -}; - -const gltfs = ['models/gltf/Parrot.glb', 'models/gltf/Flamingo.glb']; -const colors = [0xccffff, 0xffdeff]; -const sizes = [0.2, 0.1]; -const selectModel = Math.floor(Math.random() * gltfs.length); -new GLTFLoader().load(gltfs[selectModel], function (gltf) { - const animations = gltf.animations; - durationAnimation = Math.round(animations[0].duration * 60); - const birdGeo = gltf.scene.children[0].geometry; - const morphAttributes = birdGeo.morphAttributes.position; - const tHeight = nextPowerOf2(durationAnimation); - const tWidth = nextPowerOf2(birdGeo.getAttribute('position').count); - indicesPerBird = birdGeo.index.count; - const tData = new Float32Array(4 * tWidth * tHeight); - - for (let i = 0; i < tWidth; i++) { - for (let j = 0; j < tHeight; j++) { - const offset = j * tWidth * 4; - - const curMorph = Math.floor((j / durationAnimation) * morphAttributes.length); - const nextMorph = - (Math.floor((j / durationAnimation) * morphAttributes.length) + 1) % morphAttributes.length; - const lerpAmount = ((j / durationAnimation) * morphAttributes.length) % 1; - - if (j < durationAnimation) { - let d0, d1; - - d0 = morphAttributes[curMorph].array[i * 3]; - d1 = morphAttributes[nextMorph].array[i * 3]; - - if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4] = Math.lerp(d0, d1, lerpAmount); - - d0 = morphAttributes[curMorph].array[i * 3 + 1]; - d1 = morphAttributes[nextMorph].array[i * 3 + 1]; - - if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4 + 1] = Math.lerp(d0, d1, lerpAmount); - - d0 = morphAttributes[curMorph].array[i * 3 + 2]; - d1 = morphAttributes[nextMorph].array[i * 3 + 2]; - - if (d0 !== undefined && d1 !== undefined) tData[offset + i * 4 + 2] = Math.lerp(d0, d1, lerpAmount); - - tData[offset + i * 4 + 3] = 1; - } - } - } - - textureAnimation = new THREE.DataTexture(tData, tWidth, tHeight, THREE.RGBAFormat, THREE.FloatType); - textureAnimation.needsUpdate = true; - - const vertices = [], - color = [], - reference = [], - seeds = [], - indices = []; - const totalVertices = birdGeo.getAttribute('position').count * 3 * BIRDS; - for (let i = 0; i < totalVertices; i++) { - const bIndex = i % (birdGeo.getAttribute('position').count * 3); - vertices.push(birdGeo.getAttribute('position').array[bIndex]); - color.push(birdGeo.getAttribute('color').array[bIndex]); - } - - let r = Math.random(); - for (let i = 0; i < birdGeo.getAttribute('position').count * BIRDS; i++) { - const bIndex = i % birdGeo.getAttribute('position').count; - const bird = Math.floor(i / birdGeo.getAttribute('position').count); - if (bIndex == 0) r = Math.random(); - const j = ~~bird; - const x = (j % WIDTH) / WIDTH; - const y = ~~(j / WIDTH) / WIDTH; - reference.push(x, y, bIndex / tWidth, durationAnimation / tHeight); - seeds.push(bird, r, Math.random(), Math.random()); - } - - for (let i = 0; i < birdGeo.index.array.length * BIRDS; i++) { - const offset = Math.floor(i / birdGeo.index.array.length) * birdGeo.getAttribute('position').count; - indices.push(birdGeo.index.array[i % birdGeo.index.array.length] + offset); - } - - BirdGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3)); - BirdGeometry.setAttribute('birdColor', new THREE.BufferAttribute(new Float32Array(color), 3)); - BirdGeometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(color), 3)); - BirdGeometry.setAttribute('reference', new THREE.BufferAttribute(new Float32Array(reference), 4)); - BirdGeometry.setAttribute('seeds', new THREE.BufferAttribute(new Float32Array(seeds), 4)); - - BirdGeometry.setIndex(indices); - - init(); -}); - -let container, stats; -let camera, scene, renderer; -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -const BOUNDS = 800, - BOUNDS_HALF = BOUNDS / 2; - -let last = performance.now(); - -let gpuCompute; -let velocityVariable; -let positionVariable; -let positionUniforms; -let velocityUniforms; - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 3000); - camera.position.z = 350; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(colors[selectModel]); - scene.fog = new THREE.Fog(colors[selectModel], 100, 1000); - - // LIGHTS - - const hemiLight = new THREE.HemisphereLight(colors[selectModel], 0xffffff, 4.5); - hemiLight.color.setHSL(0.6, 1, 0.6, THREE.SRGBColorSpace); - hemiLight.groundColor.setHSL(0.095, 1, 0.75, THREE.SRGBColorSpace); - hemiLight.position.set(0, 50, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0x00ced1, 2.0); - dirLight.color.setHSL(0.1, 1, 0.95, THREE.SRGBColorSpace); - dirLight.position.set(-1, 1.75, 1); - dirLight.position.multiplyScalar(30); - scene.add(dirLight); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - initComputeRenderer(); - - stats = new Stats(); - container.appendChild(stats.dom); - - container.style.touchAction = 'none'; - container.addEventListener('pointermove', onPointerMove); - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - const effectController = { - separation: 20.0, - alignment: 20.0, - cohesion: 20.0, - freedom: 0.75, - size: sizes[selectModel], - count: Math.floor(BIRDS / 4), - }; - - const valuesChanger = function () { - velocityUniforms['separationDistance'].value = effectController.separation; - velocityUniforms['alignmentDistance'].value = effectController.alignment; - velocityUniforms['cohesionDistance'].value = effectController.cohesion; - velocityUniforms['freedomFactor'].value = effectController.freedom; - if (materialShader) materialShader.uniforms['size'].value = effectController.size; - BirdGeometry.setDrawRange(0, indicesPerBird * effectController.count); - }; - - valuesChanger(); - - gui.add(effectController, 'separation', 0.0, 100.0, 1.0).onChange(valuesChanger); - gui.add(effectController, 'alignment', 0.0, 100, 0.001).onChange(valuesChanger); - gui.add(effectController, 'cohesion', 0.0, 100, 0.025).onChange(valuesChanger); - gui.add(effectController, 'size', 0, 1, 0.01).onChange(valuesChanger); - gui.add(effectController, 'count', 0, BIRDS, 1).onChange(valuesChanger); - gui.close(); - - initBirds(effectController); -} - -function initComputeRenderer() { - gpuCompute = new GPUComputationRenderer(WIDTH, WIDTH, renderer); - - const dtPosition = gpuCompute.createTexture(); - const dtVelocity = gpuCompute.createTexture(); - fillPositionTexture(dtPosition); - fillVelocityTexture(dtVelocity); - - velocityVariable = gpuCompute.addVariable( - 'textureVelocity', - document.getElementById('fragmentShaderVelocity').textContent, - dtVelocity, - ); - positionVariable = gpuCompute.addVariable( - 'texturePosition', - document.getElementById('fragmentShaderPosition').textContent, - dtPosition, - ); - - gpuCompute.setVariableDependencies(velocityVariable, [positionVariable, velocityVariable]); - gpuCompute.setVariableDependencies(positionVariable, [positionVariable, velocityVariable]); - - positionUniforms = positionVariable.material.uniforms; - velocityUniforms = velocityVariable.material.uniforms; - - positionUniforms['time'] = { value: 0.0 }; - positionUniforms['delta'] = { value: 0.0 }; - velocityUniforms['time'] = { value: 1.0 }; - velocityUniforms['delta'] = { value: 0.0 }; - velocityUniforms['testing'] = { value: 1.0 }; - velocityUniforms['separationDistance'] = { value: 1.0 }; - velocityUniforms['alignmentDistance'] = { value: 1.0 }; - velocityUniforms['cohesionDistance'] = { value: 1.0 }; - velocityUniforms['freedomFactor'] = { value: 1.0 }; - velocityUniforms['predator'] = { value: new THREE.Vector3() }; - velocityVariable.material.defines.BOUNDS = BOUNDS.toFixed(2); - - velocityVariable.wrapS = THREE.RepeatWrapping; - velocityVariable.wrapT = THREE.RepeatWrapping; - positionVariable.wrapS = THREE.RepeatWrapping; - positionVariable.wrapT = THREE.RepeatWrapping; - - const error = gpuCompute.init(); - - if (error !== null) { - console.error(error); - } -} - -function initBirds(effectController) { - const geometry = BirdGeometry; - - const m = new THREE.MeshStandardMaterial({ - vertexColors: true, - flatShading: true, - roughness: 1, - metalness: 0, - }); - - m.onBeforeCompile = shader => { - shader.uniforms.texturePosition = { value: null }; - shader.uniforms.textureVelocity = { value: null }; - shader.uniforms.textureAnimation = { value: textureAnimation }; - shader.uniforms.time = { value: 1.0 }; - shader.uniforms.size = { value: effectController.size }; - shader.uniforms.delta = { value: 0.0 }; - - let token = '#define STANDARD'; - - let insert = /* glsl */ ` - attribute vec4 reference; - attribute vec4 seeds; - attribute vec3 birdColor; - uniform sampler2D texturePosition; - uniform sampler2D textureVelocity; - uniform sampler2D textureAnimation; - uniform float size; - uniform float time; - `; - - shader.vertexShader = shader.vertexShader.replace(token, token + insert); - - token = '#include '; - - insert = /* glsl */ ` - vec4 tmpPos = texture2D( texturePosition, reference.xy ); - - vec3 pos = tmpPos.xyz; - vec3 velocity = normalize(texture2D( textureVelocity, reference.xy ).xyz); - vec3 aniPos = texture2D( textureAnimation, vec2( reference.z, mod( time + ( seeds.x ) * ( ( 0.0004 + seeds.y / 10000.0) + normalize( velocity ) / 20000.0 ), reference.w ) ) ).xyz; - vec3 newPosition = position; - - newPosition = mat3( modelMatrix ) * ( newPosition + aniPos ); - newPosition *= size + seeds.y * size * 0.2; - - velocity.z *= -1.; - float xz = length( velocity.xz ); - float xyz = 1.; - float x = sqrt( 1. - velocity.y * velocity.y ); - - float cosry = velocity.x / xz; - float sinry = velocity.z / xz; - - float cosrz = x / xyz; - float sinrz = velocity.y / xyz; - - mat3 maty = mat3( cosry, 0, -sinry, 0 , 1, 0 , sinry, 0, cosry ); - mat3 matz = mat3( cosrz , sinrz, 0, -sinrz, cosrz, 0, 0 , 0 , 1 ); - - newPosition = maty * matz * newPosition; - newPosition += pos; - - vec3 transformed = vec3( newPosition ); - `; - - shader.vertexShader = shader.vertexShader.replace(token, insert); - - materialShader = shader; - }; - - birdMesh = new THREE.Mesh(geometry, m); - birdMesh.rotation.y = Math.PI / 2; - - birdMesh.castShadow = true; - birdMesh.receiveShadow = true; - - scene.add(birdMesh); -} - -function fillPositionTexture(texture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { - const x = Math.random() * BOUNDS - BOUNDS_HALF; - const y = Math.random() * BOUNDS - BOUNDS_HALF; - const z = Math.random() * BOUNDS - BOUNDS_HALF; - - theArray[k + 0] = x; - theArray[k + 1] = y; - theArray[k + 2] = z; - theArray[k + 3] = 1; - } -} - -function fillVelocityTexture(texture) { - const theArray = texture.image.data; - - for (let k = 0, kl = theArray.length; k < kl; k += 4) { - const x = Math.random() - 0.5; - const y = Math.random() - 0.5; - const z = Math.random() - 0.5; - - theArray[k + 0] = x * 10; - theArray[k + 1] = y * 10; - theArray[k + 2] = z * 10; - theArray[k + 3] = 1; - } -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const now = performance.now(); - let delta = (now - last) / 1000; - - if (delta > 1) delta = 1; // safety cap on large deltas - last = now; - - positionUniforms['time'].value = now; - positionUniforms['delta'].value = delta; - velocityUniforms['time'].value = now; - velocityUniforms['delta'].value = delta; - if (materialShader) materialShader.uniforms['time'].value = now / 1000; - if (materialShader) materialShader.uniforms['delta'].value = delta; - - velocityUniforms['predator'].value.set((0.5 * mouseX) / windowHalfX, (-0.5 * mouseY) / windowHalfY, 0); - - mouseX = 10000; - mouseY = 10000; - - gpuCompute.compute(); - - if (materialShader) - materialShader.uniforms['texturePosition'].value = gpuCompute.getCurrentRenderTarget(positionVariable).texture; - if (materialShader) - materialShader.uniforms['textureVelocity'].value = gpuCompute.getCurrentRenderTarget(velocityVariable).texture; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_gpgpu_protoplanet.ts b/examples-testing/examples/webgl_gpgpu_protoplanet.ts deleted file mode 100644 index 30444ddba..000000000 --- a/examples-testing/examples/webgl_gpgpu_protoplanet.ts +++ /dev/null @@ -1,280 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; - -// Texture width for simulation (each texel is a debris particle) -const WIDTH = 64; - -let container, stats; -let camera, scene, renderer, geometry; - -const PARTICLES = WIDTH * WIDTH; - -let gpuCompute; -let velocityVariable; -let positionVariable; -let velocityUniforms; -let particleUniforms; -let effectController; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 5, 15000); - camera.position.y = 120; - camera.position.z = 400; - - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 100; - controls.maxDistance = 1000; - - effectController = { - // Can be changed dynamically - gravityConstant: 100.0, - density: 0.45, - - // Must restart simulation - radius: 300, - height: 8, - exponent: 0.4, - maxMass: 15.0, - velocity: 70, - velocityExponent: 0.2, - randVelocity: 0.001, - }; - - initComputeRenderer(); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - - initGUI(); - - initProtoplanets(); - - dynamicValuesChanger(); -} - -function initComputeRenderer() { - gpuCompute = new GPUComputationRenderer(WIDTH, WIDTH, renderer); - - const dtPosition = gpuCompute.createTexture(); - const dtVelocity = gpuCompute.createTexture(); - - fillTextures(dtPosition, dtVelocity); - - velocityVariable = gpuCompute.addVariable( - 'textureVelocity', - document.getElementById('computeShaderVelocity').textContent, - dtVelocity, - ); - positionVariable = gpuCompute.addVariable( - 'texturePosition', - document.getElementById('computeShaderPosition').textContent, - dtPosition, - ); - - gpuCompute.setVariableDependencies(velocityVariable, [positionVariable, velocityVariable]); - gpuCompute.setVariableDependencies(positionVariable, [positionVariable, velocityVariable]); - - velocityUniforms = velocityVariable.material.uniforms; - - velocityUniforms['gravityConstant'] = { value: 0.0 }; - velocityUniforms['density'] = { value: 0.0 }; - - const error = gpuCompute.init(); - - if (error !== null) { - console.error(error); - } -} - -function restartSimulation() { - const dtPosition = gpuCompute.createTexture(); - const dtVelocity = gpuCompute.createTexture(); - - fillTextures(dtPosition, dtVelocity); - - gpuCompute.renderTexture(dtPosition, positionVariable.renderTargets[0]); - gpuCompute.renderTexture(dtPosition, positionVariable.renderTargets[1]); - gpuCompute.renderTexture(dtVelocity, velocityVariable.renderTargets[0]); - gpuCompute.renderTexture(dtVelocity, velocityVariable.renderTargets[1]); -} - -function initProtoplanets() { - geometry = new THREE.BufferGeometry(); - - const positions = new Float32Array(PARTICLES * 3); - let p = 0; - - for (let i = 0; i < PARTICLES; i++) { - positions[p++] = (Math.random() * 2 - 1) * effectController.radius; - positions[p++] = 0; //( Math.random() * 2 - 1 ) * effectController.radius; - positions[p++] = (Math.random() * 2 - 1) * effectController.radius; - } - - const uvs = new Float32Array(PARTICLES * 2); - p = 0; - - for (let j = 0; j < WIDTH; j++) { - for (let i = 0; i < WIDTH; i++) { - uvs[p++] = i / (WIDTH - 1); - uvs[p++] = j / (WIDTH - 1); - } - } - - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2)); - - particleUniforms = { - texturePosition: { value: null }, - textureVelocity: { value: null }, - cameraConstant: { value: getCameraConstant(camera) }, - density: { value: 0.0 }, - }; - - // THREE.ShaderMaterial - const material = new THREE.ShaderMaterial({ - uniforms: particleUniforms, - vertexShader: document.getElementById('particleVertexShader').textContent, - fragmentShader: document.getElementById('particleFragmentShader').textContent, - }); - - const particles = new THREE.Points(geometry, material); - particles.matrixAutoUpdate = false; - particles.updateMatrix(); - - scene.add(particles); -} - -function fillTextures(texturePosition, textureVelocity) { - const posArray = texturePosition.image.data; - const velArray = textureVelocity.image.data; - - const radius = effectController.radius; - const height = effectController.height; - const exponent = effectController.exponent; - const maxMass = (effectController.maxMass * 1024) / PARTICLES; - const maxVel = effectController.velocity; - const velExponent = effectController.velocityExponent; - const randVel = effectController.randVelocity; - - for (let k = 0, kl = posArray.length; k < kl; k += 4) { - // Position - let x, z, rr; - - do { - x = Math.random() * 2 - 1; - z = Math.random() * 2 - 1; - rr = x * x + z * z; - } while (rr > 1); - - rr = Math.sqrt(rr); - - const rExp = radius * Math.pow(rr, exponent); - - // Velocity - const vel = maxVel * Math.pow(rr, velExponent); - - const vx = vel * z + (Math.random() * 2 - 1) * randVel; - const vy = (Math.random() * 2 - 1) * randVel * 0.05; - const vz = -vel * x + (Math.random() * 2 - 1) * randVel; - - x *= rExp; - z *= rExp; - const y = (Math.random() * 2 - 1) * height; - - const mass = Math.random() * maxMass + 1; - - // Fill in texture values - posArray[k + 0] = x; - posArray[k + 1] = y; - posArray[k + 2] = z; - posArray[k + 3] = 1; - - velArray[k + 0] = vx; - velArray[k + 1] = vy; - velArray[k + 2] = vz; - velArray[k + 3] = mass; - } -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - particleUniforms['cameraConstant'].value = getCameraConstant(camera); -} - -function dynamicValuesChanger() { - velocityUniforms['gravityConstant'].value = effectController.gravityConstant; - velocityUniforms['density'].value = effectController.density; - particleUniforms['density'].value = effectController.density; -} - -function initGUI() { - const gui = new GUI({ width: 280 }); - - const folder1 = gui.addFolder('Dynamic parameters'); - - folder1.add(effectController, 'gravityConstant', 0.0, 1000.0, 0.05).onChange(dynamicValuesChanger); - folder1.add(effectController, 'density', 0.0, 10.0, 0.001).onChange(dynamicValuesChanger); - - const folder2 = gui.addFolder('Static parameters'); - - folder2.add(effectController, 'radius', 10.0, 1000.0, 1.0); - folder2.add(effectController, 'height', 0.0, 50.0, 0.01); - folder2.add(effectController, 'exponent', 0.0, 2.0, 0.001); - folder2.add(effectController, 'maxMass', 1.0, 50.0, 0.1); - folder2.add(effectController, 'velocity', 0.0, 150.0, 0.1); - folder2.add(effectController, 'velocityExponent', 0.0, 1.0, 0.01); - folder2.add(effectController, 'randVelocity', 0.0, 50.0, 0.1); - - const buttonRestart = { - restartSimulation: function () { - restartSimulation(); - }, - }; - - folder2.add(buttonRestart, 'restartSimulation'); - - folder1.open(); - folder2.open(); -} - -function getCameraConstant(camera) { - return window.innerHeight / (Math.tan(THREE.MathUtils.DEG2RAD * 0.5 * camera.fov) / camera.zoom); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - gpuCompute.compute(); - - particleUniforms['texturePosition'].value = gpuCompute.getCurrentRenderTarget(positionVariable).texture; - particleUniforms['textureVelocity'].value = gpuCompute.getCurrentRenderTarget(velocityVariable).texture; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_gpgpu_water.ts b/examples-testing/examples/webgl_gpgpu_water.ts deleted file mode 100644 index 00c32f229..000000000 --- a/examples-testing/examples/webgl_gpgpu_water.ts +++ /dev/null @@ -1,397 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js'; -import { SimplexNoise } from 'three/addons/math/SimplexNoise.js'; - -// Texture width for simulation -const WIDTH = 128; - -// Water size in system units -const BOUNDS = 512; -const BOUNDS_HALF = BOUNDS * 0.5; - -let container, stats; -let camera, scene, renderer; -let mouseMoved = false; -const mouseCoords = new THREE.Vector2(); -const raycaster = new THREE.Raycaster(); - -let waterMesh; -let meshRay; -let gpuCompute; -let heightmapVariable; -let waterUniforms; -let smoothShader; -let readWaterLevelShader; -let readWaterLevelRenderTarget; -let readWaterLevelImage; -const waterNormal = new THREE.Vector3(); - -const NUM_SPHERES = 5; -const spheres = []; -let spheresEnabled = true; - -const simplex = new SimplexNoise(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 3000); - camera.position.set(0, 200, 350); - camera.lookAt(0, 0, 0); - - scene = new THREE.Scene(); - - const sun = new THREE.DirectionalLight(0xffffff, 3.0); - sun.position.set(300, 400, 175); - scene.add(sun); - - const sun2 = new THREE.DirectionalLight(0x40a040, 2.0); - sun2.position.set(-100, 350, -200); - scene.add(sun2); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - container.style.touchAction = 'none'; - container.addEventListener('pointermove', onPointerMove); - - document.addEventListener('keydown', function (event) { - // W Pressed: Toggle wireframe - if (event.keyCode === 87) { - waterMesh.material.wireframe = !waterMesh.material.wireframe; - waterMesh.material.needsUpdate = true; - } - }); - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - const effectController = { - mouseSize: 20.0, - viscosity: 0.98, - spheresEnabled: spheresEnabled, - }; - - const valuesChanger = function () { - heightmapVariable.material.uniforms['mouseSize'].value = effectController.mouseSize; - heightmapVariable.material.uniforms['viscosityConstant'].value = effectController.viscosity; - spheresEnabled = effectController.spheresEnabled; - for (let i = 0; i < NUM_SPHERES; i++) { - if (spheres[i]) { - spheres[i].visible = spheresEnabled; - } - } - }; - - gui.add(effectController, 'mouseSize', 1.0, 100.0, 1.0).onChange(valuesChanger); - gui.add(effectController, 'viscosity', 0.9, 0.999, 0.001).onChange(valuesChanger); - gui.add(effectController, 'spheresEnabled').onChange(valuesChanger); - const buttonSmooth = { - smoothWater: function () { - smoothWater(); - }, - }; - gui.add(buttonSmooth, 'smoothWater'); - - initWater(); - - createSpheres(); - - valuesChanger(); -} - -function initWater() { - const materialColor = 0x0040c0; - - const geometry = new THREE.PlaneGeometry(BOUNDS, BOUNDS, WIDTH - 1, WIDTH - 1); - - // material: make a THREE.ShaderMaterial clone of THREE.MeshPhongMaterial, with customized vertex shader - const material = new THREE.ShaderMaterial({ - uniforms: THREE.UniformsUtils.merge([ - THREE.ShaderLib['phong'].uniforms, - { - heightmap: { value: null }, - }, - ]), - vertexShader: document.getElementById('waterVertexShader').textContent, - fragmentShader: THREE.ShaderChunk['meshphong_frag'], - }); - - material.lights = true; - - // Material attributes from THREE.MeshPhongMaterial - // Sets the uniforms with the material values - material.uniforms['diffuse'].value = new THREE.Color(materialColor); - material.uniforms['specular'].value = new THREE.Color(0x111111); - material.uniforms['shininess'].value = Math.max(50, 1e-4); - material.uniforms['opacity'].value = material.opacity; - - // Defines - material.defines.WIDTH = WIDTH.toFixed(1); - material.defines.BOUNDS = BOUNDS.toFixed(1); - - waterUniforms = material.uniforms; - - waterMesh = new THREE.Mesh(geometry, material); - waterMesh.rotation.x = -Math.PI / 2; - waterMesh.matrixAutoUpdate = false; - waterMesh.updateMatrix(); - - scene.add(waterMesh); - - // THREE.Mesh just for mouse raycasting - const geometryRay = new THREE.PlaneGeometry(BOUNDS, BOUNDS, 1, 1); - meshRay = new THREE.Mesh(geometryRay, new THREE.MeshBasicMaterial({ color: 0xffffff, visible: false })); - meshRay.rotation.x = -Math.PI / 2; - meshRay.matrixAutoUpdate = false; - meshRay.updateMatrix(); - scene.add(meshRay); - - // Creates the gpu computation class and sets it up - - gpuCompute = new GPUComputationRenderer(WIDTH, WIDTH, renderer); - - const heightmap0 = gpuCompute.createTexture(); - - fillTexture(heightmap0); - - heightmapVariable = gpuCompute.addVariable( - 'heightmap', - document.getElementById('heightmapFragmentShader').textContent, - heightmap0, - ); - - gpuCompute.setVariableDependencies(heightmapVariable, [heightmapVariable]); - - heightmapVariable.material.uniforms['mousePos'] = { value: new THREE.Vector2(10000, 10000) }; - heightmapVariable.material.uniforms['mouseSize'] = { value: 20.0 }; - heightmapVariable.material.uniforms['viscosityConstant'] = { value: 0.98 }; - heightmapVariable.material.uniforms['heightCompensation'] = { value: 0 }; - heightmapVariable.material.defines.BOUNDS = BOUNDS.toFixed(1); - - const error = gpuCompute.init(); - if (error !== null) { - console.error(error); - } - - // Create compute shader to smooth the water surface and velocity - smoothShader = gpuCompute.createShaderMaterial(document.getElementById('smoothFragmentShader').textContent, { - smoothTexture: { value: null }, - }); - - // Create compute shader to read water level - readWaterLevelShader = gpuCompute.createShaderMaterial( - document.getElementById('readWaterLevelFragmentShader').textContent, - { - point1: { value: new THREE.Vector2() }, - levelTexture: { value: null }, - }, - ); - readWaterLevelShader.defines.WIDTH = WIDTH.toFixed(1); - readWaterLevelShader.defines.BOUNDS = BOUNDS.toFixed(1); - - // Create a 4x1 pixel image and a render target (Uint8, 4 channels, 1 byte per channel) to read water height and orientation - readWaterLevelImage = new Uint8Array(4 * 1 * 4); - - readWaterLevelRenderTarget = new THREE.WebGLRenderTarget(4, 1, { - wrapS: THREE.ClampToEdgeWrapping, - wrapT: THREE.ClampToEdgeWrapping, - minFilter: THREE.NearestFilter, - magFilter: THREE.NearestFilter, - format: THREE.RGBAFormat, - type: THREE.UnsignedByteType, - depthBuffer: false, - }); -} - -function fillTexture(texture) { - const waterMaxHeight = 10; - - function noise(x, y) { - let multR = waterMaxHeight; - let mult = 0.025; - let r = 0; - for (let i = 0; i < 15; i++) { - r += multR * simplex.noise(x * mult, y * mult); - multR *= 0.53 + 0.025 * i; - mult *= 1.25; - } - - return r; - } - - const pixels = texture.image.data; - - let p = 0; - for (let j = 0; j < WIDTH; j++) { - for (let i = 0; i < WIDTH; i++) { - const x = (i * 128) / WIDTH; - const y = (j * 128) / WIDTH; - - pixels[p + 0] = noise(x, y); - pixels[p + 1] = pixels[p + 0]; - pixels[p + 2] = 0; - pixels[p + 3] = 1; - - p += 4; - } - } -} - -function smoothWater() { - const currentRenderTarget = gpuCompute.getCurrentRenderTarget(heightmapVariable); - const alternateRenderTarget = gpuCompute.getAlternateRenderTarget(heightmapVariable); - - for (let i = 0; i < 10; i++) { - smoothShader.uniforms['smoothTexture'].value = currentRenderTarget.texture; - gpuCompute.doRenderTarget(smoothShader, alternateRenderTarget); - - smoothShader.uniforms['smoothTexture'].value = alternateRenderTarget.texture; - gpuCompute.doRenderTarget(smoothShader, currentRenderTarget); - } -} - -function createSpheres() { - const sphereTemplate = new THREE.Mesh( - new THREE.SphereGeometry(4, 24, 12), - new THREE.MeshPhongMaterial({ color: 0xffff00 }), - ); - - for (let i = 0; i < NUM_SPHERES; i++) { - let sphere = sphereTemplate; - if (i < NUM_SPHERES - 1) { - sphere = sphereTemplate.clone(); - } - - sphere.position.x = (Math.random() - 0.5) * BOUNDS * 0.7; - sphere.position.z = (Math.random() - 0.5) * BOUNDS * 0.7; - - sphere.userData.velocity = new THREE.Vector3(); - - scene.add(sphere); - - spheres[i] = sphere; - } -} - -function sphereDynamics() { - const currentRenderTarget = gpuCompute.getCurrentRenderTarget(heightmapVariable); - - readWaterLevelShader.uniforms['levelTexture'].value = currentRenderTarget.texture; - - for (let i = 0; i < NUM_SPHERES; i++) { - const sphere = spheres[i]; - - if (sphere) { - // Read water level and orientation - const u = (0.5 * sphere.position.x) / BOUNDS_HALF + 0.5; - const v = 1 - ((0.5 * sphere.position.z) / BOUNDS_HALF + 0.5); - readWaterLevelShader.uniforms['point1'].value.set(u, v); - gpuCompute.doRenderTarget(readWaterLevelShader, readWaterLevelRenderTarget); - - renderer.readRenderTargetPixels(readWaterLevelRenderTarget, 0, 0, 4, 1, readWaterLevelImage); - const pixels = new Float32Array(readWaterLevelImage.buffer); - - // Get orientation - waterNormal.set(pixels[1], 0, -pixels[2]); - - const pos = sphere.position; - - // Set height - pos.y = pixels[0]; - - // Move sphere - waterNormal.multiplyScalar(0.1); - sphere.userData.velocity.add(waterNormal); - sphere.userData.velocity.multiplyScalar(0.998); - pos.add(sphere.userData.velocity); - - if (pos.x < -BOUNDS_HALF) { - pos.x = -BOUNDS_HALF + 0.001; - sphere.userData.velocity.x *= -0.3; - } else if (pos.x > BOUNDS_HALF) { - pos.x = BOUNDS_HALF - 0.001; - sphere.userData.velocity.x *= -0.3; - } - - if (pos.z < -BOUNDS_HALF) { - pos.z = -BOUNDS_HALF + 0.001; - sphere.userData.velocity.z *= -0.3; - } else if (pos.z > BOUNDS_HALF) { - pos.z = BOUNDS_HALF - 0.001; - sphere.userData.velocity.z *= -0.3; - } - } - } -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function setMouseCoords(x, y) { - mouseCoords.set((x / renderer.domElement.clientWidth) * 2 - 1, -(y / renderer.domElement.clientHeight) * 2 + 1); - mouseMoved = true; -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - setMouseCoords(event.clientX, event.clientY); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - // Set uniforms: mouse interaction - const uniforms = heightmapVariable.material.uniforms; - if (mouseMoved) { - raycaster.setFromCamera(mouseCoords, camera); - - const intersects = raycaster.intersectObject(meshRay); - - if (intersects.length > 0) { - const point = intersects[0].point; - uniforms['mousePos'].value.set(point.x, point.z); - } else { - uniforms['mousePos'].value.set(10000, 10000); - } - - mouseMoved = false; - } else { - uniforms['mousePos'].value.set(10000, 10000); - } - - // Do the gpu computation - gpuCompute.compute(); - - if (spheresEnabled) { - sphereDynamics(); - } - - // Get compute output in custom uniform - waterUniforms['heightmap'].value = gpuCompute.getCurrentRenderTarget(heightmapVariable).texture; - - // Render - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_helpers.ts b/examples-testing/examples/webgl_helpers.ts deleted file mode 100644 index a8c3b9773..000000000 --- a/examples-testing/examples/webgl_helpers.ts +++ /dev/null @@ -1,117 +0,0 @@ -import * as THREE from 'three'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import { VertexNormalsHelper } from 'three/addons/helpers/VertexNormalsHelper.js'; -import { VertexTangentsHelper } from 'three/addons/helpers/VertexTangentsHelper.js'; - -let scene, renderer; -let camera, light; -let vnh; -let vth; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 400; - - scene = new THREE.Scene(); - - light = new THREE.PointLight(); - light.position.set(200, 100, 150); - scene.add(light); - - scene.add(new THREE.PointLightHelper(light, 15)); - - const gridHelper = new THREE.GridHelper(400, 40, 0x0000ff, 0x808080); - gridHelper.position.y = -150; - gridHelper.position.x = -150; - scene.add(gridHelper); - - const polarGridHelper = new THREE.PolarGridHelper(200, 16, 8, 64, 0x0000ff, 0x808080); - polarGridHelper.position.y = -150; - polarGridHelper.position.x = 200; - scene.add(polarGridHelper); - - const loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - - mesh.geometry.computeTangents(); // generates bad data due to degenerate UVs - - const group = new THREE.Group(); - group.scale.multiplyScalar(50); - scene.add(group); - - // To make sure that the matrixWorld is up to date for the boxhelpers - group.updateMatrixWorld(true); - - group.add(mesh); - - vnh = new VertexNormalsHelper(mesh, 5); - scene.add(vnh); - - vth = new VertexTangentsHelper(mesh, 5); - scene.add(vth); - - scene.add(new THREE.BoxHelper(mesh)); - - const wireframe = new THREE.WireframeGeometry(mesh.geometry); - let line = new THREE.LineSegments(wireframe); - line.material.depthTest = false; - line.material.opacity = 0.25; - line.material.transparent = true; - line.position.x = 4; - group.add(line); - scene.add(new THREE.BoxHelper(line)); - - const edges = new THREE.EdgesGeometry(mesh.geometry); - line = new THREE.LineSegments(edges); - line.material.depthTest = false; - line.material.opacity = 0.25; - line.material.transparent = true; - line.position.x = -4; - group.add(line); - scene.add(new THREE.BoxHelper(line)); - - scene.add(new THREE.BoxHelper(group)); - scene.add(new THREE.BoxHelper(scene)); - }); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = -performance.now() * 0.0003; - - camera.position.x = 400 * Math.cos(time); - camera.position.z = 400 * Math.sin(time); - camera.lookAt(scene.position); - - light.position.x = Math.sin(time * 1.7) * 300; - light.position.y = Math.cos(time * 1.5) * 400; - light.position.z = Math.cos(time * 1.3) * 300; - - if (vnh) vnh.update(); - if (vth) vth.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_instancing_dynamic.ts b/examples-testing/examples/webgl_instancing_dynamic.ts deleted file mode 100644 index 88562fc5a..000000000 --- a/examples-testing/examples/webgl_instancing_dynamic.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats; - -let mesh; -const amount = parseInt(window.location.search.slice(1)) || 10; -const count = Math.pow(amount, 3); -const dummy = new THREE.Object3D(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(amount * 0.9, amount * 0.9, amount * 0.9); - camera.lookAt(0, 0, 0); - - scene = new THREE.Scene(); - - const loader = new THREE.BufferGeometryLoader(); - loader.load('models/json/suzanne_buffergeometry.json', function (geometry) { - geometry.computeVertexNormals(); - geometry.scale(0.5, 0.5, 0.5); - - const material = new THREE.MeshNormalMaterial(); - // check overdraw - // let material = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.1, transparent: true } ); - - mesh = new THREE.InstancedMesh(geometry, material, count); - mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // will be updated every frame - scene.add(mesh); - - // - - const gui = new GUI(); - gui.add(mesh, 'count', 0, count); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - if (mesh) { - const time = Date.now() * 0.001; - - mesh.rotation.x = Math.sin(time / 4); - mesh.rotation.y = Math.sin(time / 2); - - let i = 0; - const offset = (amount - 1) / 2; - - for (let x = 0; x < amount; x++) { - for (let y = 0; y < amount; y++) { - for (let z = 0; z < amount; z++) { - dummy.position.set(offset - x, offset - y, offset - z); - dummy.rotation.y = Math.sin(x / 4 + time) + Math.sin(y / 4 + time) + Math.sin(z / 4 + time); - dummy.rotation.z = dummy.rotation.y * 2; - - dummy.updateMatrix(); - - mesh.setMatrixAt(i++, dummy.matrix); - } - } - } - - mesh.instanceMatrix.needsUpdate = true; - mesh.computeBoundingSphere(); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_instancing_morph.ts b/examples-testing/examples/webgl_instancing_morph.ts deleted file mode 100644 index 8686a75b9..000000000 --- a/examples-testing/examples/webgl_instancing_morph.ts +++ /dev/null @@ -1,147 +0,0 @@ -import * as THREE from 'three'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats, mesh, mixer, dummy; - -const offset = 5000; - -const timeOffsets = new Float32Array(1024); - -for (let i = 0; i < 1024; i++) { - timeOffsets[i] = Math.random() * 3; -} - -const clock = new THREE.Clock(true); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 10000); - - scene = new THREE.Scene(); - - scene.background = new THREE.Color(0x99ddff); - - scene.fog = new THREE.Fog(0x99ddff, 5000, 10000); - - const light = new THREE.DirectionalLight(0xffffff, 1); - - light.position.set(200, 1000, 50); - - light.castShadow = true; - - light.shadow.camera.left = -5000; - light.shadow.camera.right = 5000; - light.shadow.camera.top = 5000; - light.shadow.camera.bottom = -5000; - light.shadow.camera.far = 2000; - - light.shadow.bias = -0.01; - - light.shadow.camera.updateProjectionMatrix(); - - scene.add(light); - - const hemi = new THREE.HemisphereLight(0x99ddff, 0x669933, 1 / 3); - - scene.add(hemi); - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(1000000, 1000000), - new THREE.MeshStandardMaterial({ color: 0x669933, depthWrite: true }), - ); - - ground.rotation.x = -Math.PI / 2; - - ground.receiveShadow = true; - - scene.add(ground); - - const loader = new GLTFLoader(); - - loader.load('models/gltf/Horse.glb', function (glb) { - dummy = glb.scene.children[0]; - - mesh = new THREE.InstancedMesh(dummy.geometry, dummy.material, 1024); - - mesh.castShadow = true; - - for (let x = 0, i = 0; x < 32; x++) { - for (let y = 0; y < 32; y++) { - dummy.position.set(offset - 300 * x + 200 * Math.random(), 0, offset - 300 * y); - - dummy.updateMatrix(); - - mesh.setMatrixAt(i, dummy.matrix); - - mesh.setColorAt(i, new THREE.Color(`hsl(${Math.random() * 360}, 50%, 66%)`)); - - i++; - } - } - - scene.add(mesh); - - mixer = new THREE.AnimationMixer(glb.scene); - - const action = mixer.clipAction(glb.animations[0]); - - action.play(); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.VSMShadowMap; - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - const time = clock.getElapsedTime(); - - const r = 3000; - camera.position.set(Math.sin(time / 10) * r, 1500 + 1000 * Math.cos(time / 5), Math.cos(time / 10) * r); - camera.lookAt(0, 0, 0); - - if (mesh) { - for (let i = 0; i < 1024; i++) { - mixer.setTime(time + timeOffsets[i]); - - mesh.setMorphAt(i, dummy); - } - - mesh.morphTexture.needsUpdate = true; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_instancing_performance.ts b/examples-testing/examples/webgl_instancing_performance.ts deleted file mode 100644 index bf1deabad..000000000 --- a/examples-testing/examples/webgl_instancing_performance.ts +++ /dev/null @@ -1,262 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let container, stats, gui, guiStatsEl; -let camera, controls, scene, renderer, material; - -// gui - -const Method = { - INSTANCED: 'INSTANCED', - MERGED: 'MERGED', - NAIVE: 'NAIVE', -}; - -const api = { - method: Method.INSTANCED, - count: 1000, -}; - -// - -init(); -initMesh(); - -// - -function clean() { - const meshes = []; - - scene.traverse(function (object) { - if (object.isMesh) meshes.push(object); - }); - - for (let i = 0; i < meshes.length; i++) { - const mesh = meshes[i]; - mesh.material.dispose(); - mesh.geometry.dispose(); - - scene.remove(mesh); - } -} - -const randomizeMatrix = (function () { - const position = new THREE.Vector3(); - const quaternion = new THREE.Quaternion(); - const scale = new THREE.Vector3(); - - return function (matrix) { - position.x = Math.random() * 40 - 20; - position.y = Math.random() * 40 - 20; - position.z = Math.random() * 40 - 20; - - quaternion.random(); - - scale.x = scale.y = scale.z = Math.random() * 1; - - matrix.compose(position, quaternion, scale); - }; -})(); - -function initMesh() { - clean(); - - // make instances - new THREE.BufferGeometryLoader().setPath('models/json/').load('suzanne_buffergeometry.json', function (geometry) { - material = new THREE.MeshNormalMaterial(); - - geometry.computeVertexNormals(); - - console.time(api.method + ' (build)'); - - switch (api.method) { - case Method.INSTANCED: - makeInstanced(geometry); - break; - - case Method.MERGED: - makeMerged(geometry); - break; - - case Method.NAIVE: - makeNaive(geometry); - break; - } - - console.timeEnd(api.method + ' (build)'); - }); -} - -function makeInstanced(geometry) { - const matrix = new THREE.Matrix4(); - const mesh = new THREE.InstancedMesh(geometry, material, api.count); - - for (let i = 0; i < api.count; i++) { - randomizeMatrix(matrix); - mesh.setMatrixAt(i, matrix); - } - - scene.add(mesh); - - // - - const geometryByteLength = getGeometryByteLength(geometry); - - guiStatsEl.innerHTML = [ - 'GPU draw calls: 1', - 'GPU memory: ' + formatBytes(api.count * 16 + geometryByteLength, 2), - ].join('
'); -} - -function makeMerged(geometry) { - const geometries = []; - const matrix = new THREE.Matrix4(); - - for (let i = 0; i < api.count; i++) { - randomizeMatrix(matrix); - - const instanceGeometry = geometry.clone(); - instanceGeometry.applyMatrix4(matrix); - - geometries.push(instanceGeometry); - } - - const mergedGeometry = BufferGeometryUtils.mergeGeometries(geometries); - - scene.add(new THREE.Mesh(mergedGeometry, material)); - - // - - guiStatsEl.innerHTML = [ - 'GPU draw calls: 1', - 'GPU memory: ' + formatBytes(getGeometryByteLength(mergedGeometry), 2), - ].join('
'); -} - -function makeNaive(geometry) { - const matrix = new THREE.Matrix4(); - - for (let i = 0; i < api.count; i++) { - randomizeMatrix(matrix); - - const mesh = new THREE.Mesh(geometry, material); - mesh.applyMatrix4(matrix); - - scene.add(mesh); - } - - // - - const geometryByteLength = getGeometryByteLength(geometry); - - guiStatsEl.innerHTML = [ - 'GPU draw calls: ' + api.count, - 'GPU memory: ' + formatBytes(api.count * 16 + geometryByteLength, 2), - ].join('
'); -} - -function init() { - const width = window.innerWidth; - const height = window.innerHeight; - - // camera - - camera = new THREE.PerspectiveCamera(70, width / height, 1, 100); - camera.position.z = 30; - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - // scene - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - - // stats - - stats = new Stats(); - container.appendChild(stats.dom); - - // gui - - gui = new GUI(); - gui.add(api, 'method', Method).onChange(initMesh); - gui.add(api, 'count', 1, 10000).step(1).onChange(initMesh); - - const perfFolder = gui.addFolder('Performance'); - - guiStatsEl = document.createElement('div'); - guiStatsEl.classList.add('gui-stats'); - - perfFolder.$children.appendChild(guiStatsEl); - perfFolder.open(); - - // listeners - - window.addEventListener('resize', onWindowResize); - - Object.assign(window, { scene }); -} - -// - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - controls.update(); - - renderer.render(scene, camera); - - stats.update(); -} - -// - -function getGeometryByteLength(geometry) { - let total = 0; - - if (geometry.index) total += geometry.index.array.byteLength; - - for (const name in geometry.attributes) { - total += geometry.attributes[name].array.byteLength; - } - - return total; -} - -// Source: https://stackoverflow.com/a/18650828/1314762 -function formatBytes(bytes, decimals) { - if (bytes === 0) return '0 bytes'; - - const k = 1024; - const dm = decimals < 0 ? 0 : decimals; - const sizes = ['bytes', 'KB', 'MB']; - - const i = Math.floor(Math.log(bytes) / Math.log(k)); - - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; -} diff --git a/examples-testing/examples/webgl_instancing_raycast.ts b/examples-testing/examples/webgl_instancing_raycast.ts deleted file mode 100644 index 371ea070b..000000000 --- a/examples-testing/examples/webgl_instancing_raycast.ts +++ /dev/null @@ -1,116 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, controls, stats; - -let mesh; -const amount = parseInt(window.location.search.slice(1)) || 10; -const count = Math.pow(amount, 3); - -const raycaster = new THREE.Raycaster(); -const mouse = new THREE.Vector2(1, 1); - -const color = new THREE.Color(); -const white = new THREE.Color().setHex(0xffffff); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(amount, amount, amount); - camera.lookAt(0, 0, 0); - - scene = new THREE.Scene(); - - const light = new THREE.HemisphereLight(0xffffff, 0x888888, 3); - light.position.set(0, 1, 0); - scene.add(light); - - const geometry = new THREE.IcosahedronGeometry(0.5, 3); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff }); - - mesh = new THREE.InstancedMesh(geometry, material, count); - - let i = 0; - const offset = (amount - 1) / 2; - - const matrix = new THREE.Matrix4(); - - for (let x = 0; x < amount; x++) { - for (let y = 0; y < amount; y++) { - for (let z = 0; z < amount; z++) { - matrix.setPosition(offset - x, offset - y, offset - z); - - mesh.setMatrixAt(i, matrix); - mesh.setColorAt(i, color); - - i++; - } - } - } - - scene.add(mesh); - - // - - const gui = new GUI(); - gui.add(mesh, 'count', 0, count); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.enableZoom = false; - controls.enablePan = false; - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - document.addEventListener('mousemove', onMouseMove); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onMouseMove(event) { - event.preventDefault(); - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -function animate() { - controls.update(); - - raycaster.setFromCamera(mouse, camera); - - const intersection = raycaster.intersectObject(mesh); - - if (intersection.length > 0) { - const instanceId = intersection[0].instanceId; - - mesh.getColorAt(instanceId, color); - - if (color.equals(white)) { - mesh.setColorAt(instanceId, color.setHex(Math.random() * 0xffffff)); - - mesh.instanceColor.needsUpdate = true; - } - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_instancing_scatter.ts b/examples-testing/examples/webgl_instancing_scatter.ts deleted file mode 100644 index fc3b9cc9f..000000000 --- a/examples-testing/examples/webgl_instancing_scatter.ts +++ /dev/null @@ -1,257 +0,0 @@ -import * as THREE from 'three'; - -import { MeshSurfaceSampler } from 'three/addons/math/MeshSurfaceSampler.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats; - -const api = { - count: 2000, - distribution: 'random', - resample: resample, - surfaceColor: 0xfff784, - backgroundColor: 0xe39469, -}; - -let stemMesh, blossomMesh; -let stemGeometry, blossomGeometry; -let stemMaterial, blossomMaterial; - -let sampler; -const count = api.count; -const ages = new Float32Array(count); -const scales = new Float32Array(count); -const dummy = new THREE.Object3D(); - -const _position = new THREE.Vector3(); -const _normal = new THREE.Vector3(); -const _scale = new THREE.Vector3(); - -// let surfaceGeometry = new THREE.BoxGeometry( 10, 10, 10 ).toNonIndexed(); -const surfaceGeometry = new THREE.TorusKnotGeometry(10, 3, 100, 16).toNonIndexed(); -const surfaceMaterial = new THREE.MeshLambertMaterial({ color: api.surfaceColor, wireframe: false }); -const surface = new THREE.Mesh(surfaceGeometry, surfaceMaterial); - -// Source: https://gist.github.com/gre/1650294 -const easeOutCubic = function (t) { - return --t * t * t + 1; -}; - -// Scaling curve causes particles to grow quickly, ease gradually into full scale, then -// disappear quickly. More of the particle's lifetime is spent around full scale. -const scaleCurve = function (t) { - return Math.abs(easeOutCubic((t > 0.5 ? 1 - t : t) * 2)); -}; - -const loader = new GLTFLoader(); - -loader.load('./models/gltf/Flower/Flower.glb', function (gltf) { - const _stemMesh = gltf.scene.getObjectByName('Stem'); - const _blossomMesh = gltf.scene.getObjectByName('Blossom'); - - stemGeometry = _stemMesh.geometry.clone(); - blossomGeometry = _blossomMesh.geometry.clone(); - - const defaultTransform = new THREE.Matrix4() - .makeRotationX(Math.PI) - .multiply(new THREE.Matrix4().makeScale(7, 7, 7)); - - stemGeometry.applyMatrix4(defaultTransform); - blossomGeometry.applyMatrix4(defaultTransform); - - stemMaterial = _stemMesh.material; - blossomMaterial = _blossomMesh.material; - - stemMesh = new THREE.InstancedMesh(stemGeometry, stemMaterial, count); - blossomMesh = new THREE.InstancedMesh(blossomGeometry, blossomMaterial, count); - - // Assign random colors to the blossoms. - const color = new THREE.Color(); - const blossomPalette = [0xf20587, 0xf2d479, 0xf2c879, 0xf2b077, 0xf24405]; - - for (let i = 0; i < count; i++) { - color.setHex(blossomPalette[Math.floor(Math.random() * blossomPalette.length)]); - blossomMesh.setColorAt(i, color); - } - - // Instance matrices will be updated every frame. - stemMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); - blossomMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); - - resample(); - - init(); -}); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(25, 25, 25); - camera.lookAt(0, 0, 0); - - // - - scene = new THREE.Scene(); - scene.background = new THREE.Color(api.backgroundColor); - - const pointLight = new THREE.PointLight(0xaa8899, 2.5, 0, 0); - pointLight.position.set(50, -25, 75); - scene.add(pointLight); - - scene.add(new THREE.AmbientLight(0xffffff, 3)); - - // - - scene.add(stemMesh); - scene.add(blossomMesh); - - scene.add(surface); - - // - - const gui = new GUI(); - gui.add(api, 'count', 0, count).onChange(function () { - stemMesh.count = api.count; - blossomMesh.count = api.count; - }); - - // gui.addColor( api, 'backgroundColor' ).onChange( function () { - - // scene.background.setHex( api.backgroundColor ); - - // } ); - - // gui.addColor( api, 'surfaceColor' ).onChange( function () { - - // surfaceMaterial.color.setHex( api.surfaceColor ); - - // } ); - - gui.add(api, 'distribution').options(['random', 'weighted']).onChange(resample); - gui.add(api, 'resample'); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function resample() { - const vertexCount = surface.geometry.getAttribute('position').count; - - console.info('Sampling ' + count + ' points from a surface with ' + vertexCount + ' vertices...'); - - // - - console.time('.build()'); - - sampler = new MeshSurfaceSampler(surface).setWeightAttribute(api.distribution === 'weighted' ? 'uv' : null).build(); - - console.timeEnd('.build()'); - - // - - console.time('.sample()'); - - for (let i = 0; i < count; i++) { - ages[i] = Math.random(); - scales[i] = scaleCurve(ages[i]); - - resampleParticle(i); - } - - console.timeEnd('.sample()'); - - stemMesh.instanceMatrix.needsUpdate = true; - blossomMesh.instanceMatrix.needsUpdate = true; -} - -function resampleParticle(i) { - sampler.sample(_position, _normal); - _normal.add(_position); - - dummy.position.copy(_position); - dummy.scale.set(scales[i], scales[i], scales[i]); - dummy.lookAt(_normal); - dummy.updateMatrix(); - - stemMesh.setMatrixAt(i, dummy.matrix); - blossomMesh.setMatrixAt(i, dummy.matrix); -} - -function updateParticle(i) { - // Update lifecycle. - - ages[i] += 0.005; - - if (ages[i] >= 1) { - ages[i] = 0.001; - scales[i] = scaleCurve(ages[i]); - - resampleParticle(i); - - return; - } - - // Update scale. - - const prevScale = scales[i]; - scales[i] = scaleCurve(ages[i]); - _scale.set(scales[i] / prevScale, scales[i] / prevScale, scales[i] / prevScale); - - // Update transform. - - stemMesh.getMatrixAt(i, dummy.matrix); - dummy.matrix.scale(_scale); - stemMesh.setMatrixAt(i, dummy.matrix); - blossomMesh.setMatrixAt(i, dummy.matrix); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - if (stemMesh && blossomMesh) { - const time = Date.now() * 0.001; - - scene.rotation.x = Math.sin(time / 4); - scene.rotation.y = Math.sin(time / 2); - - for (let i = 0; i < api.count; i++) { - updateParticle(i); - } - - stemMesh.instanceMatrix.needsUpdate = true; - blossomMesh.instanceMatrix.needsUpdate = true; - - stemMesh.computeBoundingSphere(); - blossomMesh.computeBoundingSphere(); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_buffergeometry.ts b/examples-testing/examples/webgl_interactive_buffergeometry.ts deleted file mode 100644 index 1d6608b13..000000000 --- a/examples-testing/examples/webgl_interactive_buffergeometry.ts +++ /dev/null @@ -1,244 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene, renderer; - -let raycaster, pointer; - -let mesh, line; - -init(); - -function init() { - container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 3500); - camera.position.z = 2750; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - scene.fog = new THREE.Fog(0x050505, 2000, 3500); - - // - - scene.add(new THREE.AmbientLight(0x444444, 3)); - - const light1 = new THREE.DirectionalLight(0xffffff, 1.5); - light1.position.set(1, 1, 1); - scene.add(light1); - - const light2 = new THREE.DirectionalLight(0xffffff, 4.5); - light2.position.set(0, -1, 0); - scene.add(light2); - - // - - const triangles = 5000; - - let geometry = new THREE.BufferGeometry(); - - const positions = new Float32Array(triangles * 3 * 3); - const normals = new Float32Array(triangles * 3 * 3); - const colors = new Float32Array(triangles * 3 * 3); - - const color = new THREE.Color(); - - const n = 800, - n2 = n / 2; // triangles spread in the cube - const d = 120, - d2 = d / 2; // individual triangle size - - const pA = new THREE.Vector3(); - const pB = new THREE.Vector3(); - const pC = new THREE.Vector3(); - - const cb = new THREE.Vector3(); - const ab = new THREE.Vector3(); - - for (let i = 0; i < positions.length; i += 9) { - // positions - - const x = Math.random() * n - n2; - const y = Math.random() * n - n2; - const z = Math.random() * n - n2; - - const ax = x + Math.random() * d - d2; - const ay = y + Math.random() * d - d2; - const az = z + Math.random() * d - d2; - - const bx = x + Math.random() * d - d2; - const by = y + Math.random() * d - d2; - const bz = z + Math.random() * d - d2; - - const cx = x + Math.random() * d - d2; - const cy = y + Math.random() * d - d2; - const cz = z + Math.random() * d - d2; - - positions[i] = ax; - positions[i + 1] = ay; - positions[i + 2] = az; - - positions[i + 3] = bx; - positions[i + 4] = by; - positions[i + 5] = bz; - - positions[i + 6] = cx; - positions[i + 7] = cy; - positions[i + 8] = cz; - - // flat face normals - - pA.set(ax, ay, az); - pB.set(bx, by, bz); - pC.set(cx, cy, cz); - - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - - cb.normalize(); - - const nx = cb.x; - const ny = cb.y; - const nz = cb.z; - - normals[i] = nx; - normals[i + 1] = ny; - normals[i + 2] = nz; - - normals[i + 3] = nx; - normals[i + 4] = ny; - normals[i + 5] = nz; - - normals[i + 6] = nx; - normals[i + 7] = ny; - normals[i + 8] = nz; - - // colors - - const vx = x / n + 0.5; - const vy = y / n + 0.5; - const vz = z / n + 0.5; - - color.setRGB(vx, vy, vz); - - colors[i] = color.r; - colors[i + 1] = color.g; - colors[i + 2] = color.b; - - colors[i + 3] = color.r; - colors[i + 4] = color.g; - colors[i + 5] = color.b; - - colors[i + 6] = color.r; - colors[i + 7] = color.g; - colors[i + 8] = color.b; - } - - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3)); - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); - - geometry.computeBoundingSphere(); - - let material = new THREE.MeshPhongMaterial({ - color: 0xaaaaaa, - specular: 0xffffff, - shininess: 250, - side: THREE.DoubleSide, - vertexColors: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - raycaster = new THREE.Raycaster(); - - pointer = new THREE.Vector2(); - - geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(4 * 3), 3)); - - material = new THREE.LineBasicMaterial({ color: 0xffffff, transparent: true }); - - line = new THREE.Line(geometry, material); - scene.add(line); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - document.addEventListener('pointermove', onPointerMove); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.001; - - mesh.rotation.x = time * 0.15; - mesh.rotation.y = time * 0.25; - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObject(mesh); - - if (intersects.length > 0) { - const intersect = intersects[0]; - const face = intersect.face; - - const linePosition = line.geometry.attributes.position; - const meshPosition = mesh.geometry.attributes.position; - - linePosition.copyAt(0, meshPosition, face.a); - linePosition.copyAt(1, meshPosition, face.b); - linePosition.copyAt(2, meshPosition, face.c); - linePosition.copyAt(3, meshPosition, face.a); - - mesh.updateMatrix(); - - line.geometry.applyMatrix4(mesh.matrix); - - line.visible = true; - } else { - line.visible = false; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_cubes.ts b/examples-testing/examples/webgl_interactive_cubes.ts deleted file mode 100644 index adfcfddf8..000000000 --- a/examples-testing/examples/webgl_interactive_cubes.ts +++ /dev/null @@ -1,114 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let stats; -let camera, scene, raycaster, renderer; - -let INTERSECTED; -let theta = 0; - -const pointer = new THREE.Vector2(); -const radius = 5; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(1, 1, 1).normalize(); - scene.add(light); - - const geometry = new THREE.BoxGeometry(); - - for (let i = 0; i < 2000; i++) { - const object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff })); - - object.position.x = Math.random() * 40 - 20; - object.position.y = Math.random() * 40 - 20; - object.position.z = Math.random() * 40 - 20; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() + 0.5; - object.scale.y = Math.random() + 0.5; - object.scale.z = Math.random() + 0.5; - - scene.add(object); - } - - raycaster = new THREE.Raycaster(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - document.addEventListener('mousemove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - theta += 0.1; - - camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta)); - camera.lookAt(scene.position); - - camera.updateMatrixWorld(); - - // find intersections - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObjects(scene.children, false); - - if (intersects.length > 0) { - if (INTERSECTED != intersects[0].object) { - if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); - - INTERSECTED = intersects[0].object; - INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); - INTERSECTED.material.emissive.setHex(0xff0000); - } - } else { - if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); - - INTERSECTED = null; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_cubes_gpu.ts b/examples-testing/examples/webgl_interactive_cubes_gpu.ts deleted file mode 100644 index 2644469c3..000000000 --- a/examples-testing/examples/webgl_interactive_cubes_gpu.ts +++ /dev/null @@ -1,229 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let container, stats; -let camera, controls, scene, renderer; -let pickingTexture, pickingScene; -let highlightBox; - -const pickingData = []; - -const pointer = new THREE.Vector2(); -const offset = new THREE.Vector3(10, 10, 10); -const clearColor = new THREE.Color(); - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 500, 2000); - scene.add(light); - - const defaultMaterial = new THREE.MeshPhongMaterial({ - color: 0xffffff, - flatShading: true, - vertexColors: true, - shininess: 0, - }); - - // set up the picking texture to use a 32 bit integer so we can write and read integer ids from it - pickingScene = new THREE.Scene(); - pickingTexture = new THREE.WebGLRenderTarget(1, 1, { - type: THREE.IntType, - format: THREE.RGBAIntegerFormat, - internalFormat: 'RGBA32I', - }); - const pickingMaterial = new THREE.ShaderMaterial({ - glslVersion: THREE.GLSL3, - - vertexShader: /* glsl */ ` - attribute int id; - flat varying int vid; - void main() { - - vid = id; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - - } - `, - - fragmentShader: /* glsl */ ` - layout(location = 0) out int out_id; - flat varying int vid; - - void main() { - - out_id = vid; - - } - `, - }); - - function applyId(geometry, id) { - const position = geometry.attributes.position; - const array = new Int16Array(position.count); - array.fill(id); - - const bufferAttribute = new THREE.Int16BufferAttribute(array, 1, false); - bufferAttribute.gpuType = THREE.IntType; - geometry.setAttribute('id', bufferAttribute); - } - - function applyVertexColors(geometry, color) { - const position = geometry.attributes.position; - const colors = []; - - for (let i = 0; i < position.count; i++) { - colors.push(color.r, color.g, color.b); - } - - geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - } - - const geometries = []; - const matrix = new THREE.Matrix4(); - const quaternion = new THREE.Quaternion(); - const color = new THREE.Color(); - - for (let i = 0; i < 5000; i++) { - const geometry = new THREE.BoxGeometry(); - - const position = new THREE.Vector3(); - position.x = Math.random() * 10000 - 5000; - position.y = Math.random() * 6000 - 3000; - position.z = Math.random() * 8000 - 4000; - - const rotation = new THREE.Euler(); - rotation.x = Math.random() * 2 * Math.PI; - rotation.y = Math.random() * 2 * Math.PI; - rotation.z = Math.random() * 2 * Math.PI; - - const scale = new THREE.Vector3(); - scale.x = Math.random() * 200 + 100; - scale.y = Math.random() * 200 + 100; - scale.z = Math.random() * 200 + 100; - - quaternion.setFromEuler(rotation); - matrix.compose(position, quaternion, scale); - - geometry.applyMatrix4(matrix); - - // give the geometry's vertices a random color to be displayed and an integer - // identifier as a vertex attribute so boxes can be identified after being merged. - applyVertexColors(geometry, color.setHex(Math.random() * 0xffffff)); - applyId(geometry, i); - - geometries.push(geometry); - - pickingData[i] = { - position: position, - rotation: rotation, - scale: scale, - }; - } - - const mergedGeometry = BufferGeometryUtils.mergeGeometries(geometries); - scene.add(new THREE.Mesh(mergedGeometry, defaultMaterial)); - pickingScene.add(new THREE.Mesh(mergedGeometry, pickingMaterial)); - - highlightBox = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshLambertMaterial({ color: 0xffff00 })); - scene.add(highlightBox); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - controls = new TrackballControls(camera, renderer.domElement); - controls.rotateSpeed = 1.0; - controls.zoomSpeed = 1.2; - controls.panSpeed = 0.8; - controls.noZoom = false; - controls.noPan = false; - controls.staticMoving = true; - controls.dynamicDampingFactor = 0.3; - - stats = new Stats(); - container.appendChild(stats.dom); - - renderer.domElement.addEventListener('pointermove', onPointerMove); -} - -// - -function onPointerMove(e) { - pointer.x = e.clientX; - pointer.y = e.clientY; -} - -function animate() { - render(); - stats.update(); -} - -function pick() { - // render the picking scene off-screen - // set the view offset to represent just a single pixel under the mouse - const dpr = window.devicePixelRatio; - camera.setViewOffset( - renderer.domElement.width, - renderer.domElement.height, - Math.floor(pointer.x * dpr), - Math.floor(pointer.y * dpr), - 1, - 1, - ); - - // render the scene - renderer.setRenderTarget(pickingTexture); - - // clear the background to - 1 meaning no item was hit - clearColor.setRGB(-1, -1, -1); - renderer.setClearColor(clearColor); - renderer.render(pickingScene, camera); - - // clear the view offset so rendering returns to normal - camera.clearViewOffset(); - - // create buffer for reading single pixel - const pixelBuffer = new Int32Array(4); - - // read the pixel - renderer.readRenderTargetPixelsAsync(pickingTexture, 0, 0, 1, 1, pixelBuffer).then(() => { - const id = pixelBuffer[0]; - if (id !== -1) { - // move our highlightBox so that it surrounds the picked object - const data = pickingData[id]; - highlightBox.position.copy(data.position); - highlightBox.rotation.copy(data.rotation); - highlightBox.scale.copy(data.scale).add(offset); - highlightBox.visible = true; - } else { - highlightBox.visible = false; - } - }); -} - -function render() { - controls.update(); - - pick(); - - renderer.setRenderTarget(null); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_cubes_ortho.ts b/examples-testing/examples/webgl_interactive_cubes_ortho.ts deleted file mode 100644 index 520674b5f..000000000 --- a/examples-testing/examples/webgl_interactive_cubes_ortho.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let stats; -let camera, scene, raycaster, renderer; - -let theta = 0; -let INTERSECTED; - -const pointer = new THREE.Vector2(); -const radius = 25; -const frustumSize = 50; - -init(); - -function init() { - const aspect = window.innerWidth / window.innerHeight; - camera = new THREE.OrthographicCamera( - (frustumSize * aspect) / -2, - (frustumSize * aspect) / 2, - frustumSize / 2, - frustumSize / -2, - 0.1, - 100, - ); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(1, 1, 1).normalize(); - scene.add(light); - - const geometry = new THREE.BoxGeometry(); - - for (let i = 0; i < 2000; i++) { - const object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff })); - - object.position.x = Math.random() * 40 - 20; - object.position.y = Math.random() * 40 - 20; - object.position.z = Math.random() * 40 - 20; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() + 0.5; - object.scale.y = Math.random() + 0.5; - object.scale.z = Math.random() + 0.5; - - scene.add(object); - } - - raycaster = new THREE.Raycaster(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - document.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - camera.left = (-frustumSize * aspect) / 2; - camera.right = (frustumSize * aspect) / 2; - camera.top = frustumSize / 2; - camera.bottom = -frustumSize / 2; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - theta += 0.1; - - camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta)); - camera.lookAt(scene.position); - - camera.updateMatrixWorld(); - - // find intersections - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObjects(scene.children, false); - - if (intersects.length > 0) { - if (INTERSECTED != intersects[0].object) { - if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); - - INTERSECTED = intersects[0].object; - INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); - INTERSECTED.material.emissive.setHex(0xff0000); - } - } else { - if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex); - - INTERSECTED = null; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_lines.ts b/examples-testing/examples/webgl_interactive_lines.ts deleted file mode 100644 index b137c5501..000000000 --- a/examples-testing/examples/webgl_interactive_lines.ts +++ /dev/null @@ -1,160 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; -let camera, scene, raycaster, renderer, parentTransform, sphereInter; - -const pointer = new THREE.Vector2(); -const radius = 100; -let theta = 0; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - const info = document.createElement('div'); - info.style.position = 'absolute'; - info.style.top = '10px'; - info.style.width = '100%'; - info.style.textAlign = 'center'; - info.innerHTML = - 'three.js webgl - interactive lines'; - container.appendChild(info); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - const geometry = new THREE.SphereGeometry(5); - const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); - - sphereInter = new THREE.Mesh(geometry, material); - sphereInter.visible = false; - scene.add(sphereInter); - - const lineGeometry = new THREE.BufferGeometry(); - const points = []; - - const point = new THREE.Vector3(); - const direction = new THREE.Vector3(); - - for (let i = 0; i < 50; i++) { - direction.x += Math.random() - 0.5; - direction.y += Math.random() - 0.5; - direction.z += Math.random() - 0.5; - direction.normalize().multiplyScalar(10); - - point.add(direction); - points.push(point.x, point.y, point.z); - } - - lineGeometry.setAttribute('position', new THREE.Float32BufferAttribute(points, 3)); - - parentTransform = new THREE.Object3D(); - parentTransform.position.x = Math.random() * 40 - 20; - parentTransform.position.y = Math.random() * 40 - 20; - parentTransform.position.z = Math.random() * 40 - 20; - - parentTransform.rotation.x = Math.random() * 2 * Math.PI; - parentTransform.rotation.y = Math.random() * 2 * Math.PI; - parentTransform.rotation.z = Math.random() * 2 * Math.PI; - - parentTransform.scale.x = Math.random() + 0.5; - parentTransform.scale.y = Math.random() + 0.5; - parentTransform.scale.z = Math.random() + 0.5; - - for (let i = 0; i < 50; i++) { - let object; - - const lineMaterial = new THREE.LineBasicMaterial({ color: Math.random() * 0xffffff }); - - if (Math.random() > 0.5) { - object = new THREE.Line(lineGeometry, lineMaterial); - } else { - object = new THREE.LineSegments(lineGeometry, lineMaterial); - } - - object.position.x = Math.random() * 400 - 200; - object.position.y = Math.random() * 400 - 200; - object.position.z = Math.random() * 400 - 200; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() + 0.5; - object.scale.y = Math.random() + 0.5; - object.scale.z = Math.random() + 0.5; - - parentTransform.add(object); - } - - scene.add(parentTransform); - - raycaster = new THREE.Raycaster(); - raycaster.params.Line.threshold = 3; - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - document.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - theta += 0.1; - - camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta)); - camera.lookAt(scene.position); - - camera.updateMatrixWorld(); - - // find intersections - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObjects(parentTransform.children, true); - - if (intersects.length > 0) { - sphereInter.visible = true; - sphereInter.position.copy(intersects[0].point); - } else { - sphereInter.visible = false; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_points.ts b/examples-testing/examples/webgl_interactive_points.ts deleted file mode 100644 index 93113b867..000000000 --- a/examples-testing/examples/webgl_interactive_points.ts +++ /dev/null @@ -1,143 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -let renderer, scene, camera, stats; - -let particles; - -const PARTICLE_SIZE = 20; - -let raycaster, intersects; -let pointer, INTERSECTED; - -init(); - -function init() { - const container = document.getElementById('container'); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 250; - - // - - let boxGeometry = new THREE.BoxGeometry(200, 200, 200, 16, 16, 16); - - // if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data - - boxGeometry.deleteAttribute('normal'); - boxGeometry.deleteAttribute('uv'); - - boxGeometry = BufferGeometryUtils.mergeVertices(boxGeometry); - - // - - const positionAttribute = boxGeometry.getAttribute('position'); - - const colors = []; - const sizes = []; - - const color = new THREE.Color(); - - for (let i = 0, l = positionAttribute.count; i < l; i++) { - color.setHSL(0.01 + 0.1 * (i / l), 1.0, 0.5); - color.toArray(colors, i * 3); - - sizes[i] = PARTICLE_SIZE * 0.5; - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', positionAttribute); - geometry.setAttribute('customColor', new THREE.Float32BufferAttribute(colors, 3)); - geometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1)); - - // - - const material = new THREE.ShaderMaterial({ - uniforms: { - color: { value: new THREE.Color(0xffffff) }, - pointTexture: { value: new THREE.TextureLoader().load('textures/sprites/disc.png') }, - alphaTest: { value: 0.9 }, - }, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - }); - - // - - particles = new THREE.Points(geometry, material); - scene.add(particles); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - raycaster = new THREE.Raycaster(); - pointer = new THREE.Vector2(); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - document.addEventListener('pointermove', onPointerMove); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - particles.rotation.x += 0.0005; - particles.rotation.y += 0.001; - - const geometry = particles.geometry; - const attributes = geometry.attributes; - - raycaster.setFromCamera(pointer, camera); - - intersects = raycaster.intersectObject(particles); - - if (intersects.length > 0) { - if (INTERSECTED != intersects[0].index) { - attributes.size.array[INTERSECTED] = PARTICLE_SIZE; - - INTERSECTED = intersects[0].index; - - attributes.size.array[INTERSECTED] = PARTICLE_SIZE * 1.25; - attributes.size.needsUpdate = true; - } - } else if (INTERSECTED !== null) { - attributes.size.array[INTERSECTED] = PARTICLE_SIZE; - attributes.size.needsUpdate = true; - INTERSECTED = null; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_raycasting_points.ts b/examples-testing/examples/webgl_interactive_raycasting_points.ts deleted file mode 100644 index 41c158a43..000000000 --- a/examples-testing/examples/webgl_interactive_raycasting_points.ts +++ /dev/null @@ -1,220 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let renderer, scene, camera, stats; -let pointclouds; -let raycaster; -let intersection = null; -let spheresIndex = 0; -let clock; -let toggle = 0; - -const pointer = new THREE.Vector2(); -const spheres = []; - -const threshold = 0.1; -const pointSize = 0.05; -const width = 80; -const length = 160; -const rotateY = new THREE.Matrix4().makeRotationY(0.005); - -init(); - -function generatePointCloudGeometry(color, width, length) { - const geometry = new THREE.BufferGeometry(); - const numPoints = width * length; - - const positions = new Float32Array(numPoints * 3); - const colors = new Float32Array(numPoints * 3); - - let k = 0; - - for (let i = 0; i < width; i++) { - for (let j = 0; j < length; j++) { - const u = i / width; - const v = j / length; - const x = u - 0.5; - const y = (Math.cos(u * Math.PI * 4) + Math.sin(v * Math.PI * 8)) / 20; - const z = v - 0.5; - - positions[3 * k] = x; - positions[3 * k + 1] = y; - positions[3 * k + 2] = z; - - const intensity = (y + 0.1) * 5; - colors[3 * k] = color.r * intensity; - colors[3 * k + 1] = color.g * intensity; - colors[3 * k + 2] = color.b * intensity; - - k++; - } - } - - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); - geometry.computeBoundingBox(); - - return geometry; -} - -function generatePointcloud(color, width, length) { - const geometry = generatePointCloudGeometry(color, width, length); - const material = new THREE.PointsMaterial({ size: pointSize, vertexColors: true }); - - return new THREE.Points(geometry, material); -} - -function generateIndexedPointcloud(color, width, length) { - const geometry = generatePointCloudGeometry(color, width, length); - const numPoints = width * length; - const indices = new Uint16Array(numPoints); - - let k = 0; - - for (let i = 0; i < width; i++) { - for (let j = 0; j < length; j++) { - indices[k] = k; - k++; - } - } - - geometry.setIndex(new THREE.BufferAttribute(indices, 1)); - - const material = new THREE.PointsMaterial({ size: pointSize, vertexColors: true }); - - return new THREE.Points(geometry, material); -} - -function generateIndexedWithOffsetPointcloud(color, width, length) { - const geometry = generatePointCloudGeometry(color, width, length); - const numPoints = width * length; - const indices = new Uint16Array(numPoints); - - let k = 0; - - for (let i = 0; i < width; i++) { - for (let j = 0; j < length; j++) { - indices[k] = k; - k++; - } - } - - geometry.setIndex(new THREE.BufferAttribute(indices, 1)); - geometry.addGroup(0, indices.length); - - const material = new THREE.PointsMaterial({ size: pointSize, vertexColors: true }); - - return new THREE.Points(geometry, material); -} - -function init() { - const container = document.getElementById('container'); - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(10, 10, 10); - camera.lookAt(scene.position); - camera.updateMatrix(); - - // - - const pcBuffer = generatePointcloud(new THREE.Color(1, 0, 0), width, length); - pcBuffer.scale.set(5, 10, 10); - pcBuffer.position.set(-5, 0, 0); - scene.add(pcBuffer); - - const pcIndexed = generateIndexedPointcloud(new THREE.Color(0, 1, 0), width, length); - pcIndexed.scale.set(5, 10, 10); - pcIndexed.position.set(0, 0, 0); - scene.add(pcIndexed); - - const pcIndexedOffset = generateIndexedWithOffsetPointcloud(new THREE.Color(0, 1, 1), width, length); - pcIndexedOffset.scale.set(5, 10, 10); - pcIndexedOffset.position.set(5, 0, 0); - scene.add(pcIndexedOffset); - - pointclouds = [pcBuffer, pcIndexed, pcIndexedOffset]; - - // - - const sphereGeometry = new THREE.SphereGeometry(0.1, 32, 32); - const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); - - for (let i = 0; i < 40; i++) { - const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - scene.add(sphere); - spheres.push(sphere); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - raycaster = new THREE.Raycaster(); - raycaster.params.Points.threshold = threshold; - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - document.addEventListener('pointermove', onPointerMove); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - camera.applyMatrix4(rotateY); - camera.updateMatrixWorld(); - - raycaster.setFromCamera(pointer, camera); - - const intersections = raycaster.intersectObjects(pointclouds, false); - intersection = intersections.length > 0 ? intersections[0] : null; - - if (toggle > 0.02 && intersection !== null) { - spheres[spheresIndex].position.copy(intersection.point); - spheres[spheresIndex].scale.set(1, 1, 1); - spheresIndex = (spheresIndex + 1) % spheres.length; - - toggle = 0; - } - - for (let i = 0; i < spheres.length; i++) { - const sphere = spheres[i]; - sphere.scale.multiplyScalar(0.98); - sphere.scale.clampScalar(0.01, 1); - } - - toggle += clock.getDelta(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_interactive_voxelpainter.ts b/examples-testing/examples/webgl_interactive_voxelpainter.ts deleted file mode 100644 index 48b16f3b7..000000000 --- a/examples-testing/examples/webgl_interactive_voxelpainter.ts +++ /dev/null @@ -1,158 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; -let plane; -let pointer, - raycaster, - isShiftDown = false; - -let rollOverMesh, rollOverMaterial; -let cubeGeo, cubeMaterial; - -const objects = []; - -init(); -render(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(500, 800, 1300); - camera.lookAt(0, 0, 0); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - // roll-over helpers - - const rollOverGeo = new THREE.BoxGeometry(50, 50, 50); - rollOverMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, opacity: 0.5, transparent: true }); - rollOverMesh = new THREE.Mesh(rollOverGeo, rollOverMaterial); - scene.add(rollOverMesh); - - // cubes - - const map = new THREE.TextureLoader().load('textures/square-outline-textured.png'); - map.colorSpace = THREE.SRGBColorSpace; - cubeGeo = new THREE.BoxGeometry(50, 50, 50); - cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xfeb74c, map: map }); - - // grid - - const gridHelper = new THREE.GridHelper(1000, 20); - scene.add(gridHelper); - - // - - raycaster = new THREE.Raycaster(); - pointer = new THREE.Vector2(); - - const geometry = new THREE.PlaneGeometry(1000, 1000); - geometry.rotateX(-Math.PI / 2); - - plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ visible: false })); - scene.add(plane); - - objects.push(plane); - - // lights - - const ambientLight = new THREE.AmbientLight(0x606060, 3); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 3); - directionalLight.position.set(1, 0.75, 0.5).normalize(); - scene.add(directionalLight); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerdown', onPointerDown); - document.addEventListener('keydown', onDocumentKeyDown); - document.addEventListener('keyup', onDocumentKeyUp); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function onPointerMove(event) { - pointer.set((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1); - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObjects(objects, false); - - if (intersects.length > 0) { - const intersect = intersects[0]; - - rollOverMesh.position.copy(intersect.point).add(intersect.face.normal); - rollOverMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25); - - render(); - } -} - -function onPointerDown(event) { - pointer.set((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1); - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObjects(objects, false); - - if (intersects.length > 0) { - const intersect = intersects[0]; - - // delete cube - - if (isShiftDown) { - if (intersect.object !== plane) { - scene.remove(intersect.object); - - objects.splice(objects.indexOf(intersect.object), 1); - } - - // create cube - } else { - const voxel = new THREE.Mesh(cubeGeo, cubeMaterial); - voxel.position.copy(intersect.point).add(intersect.face.normal); - voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25); - scene.add(voxel); - - objects.push(voxel); - } - - render(); - } -} - -function onDocumentKeyDown(event) { - switch (event.keyCode) { - case 16: - isShiftDown = true; - break; - } -} - -function onDocumentKeyUp(event) { - switch (event.keyCode) { - case 16: - isShiftDown = false; - break; - } -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_layers.ts b/examples-testing/examples/webgl_layers.ts deleted file mode 100644 index 8bdcda7f9..000000000 --- a/examples-testing/examples/webgl_layers.ts +++ /dev/null @@ -1,125 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let container, stats; -let camera, scene, renderer; - -let theta = 0; -const radius = 5; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.layers.enable(0); // enabled by default - camera.layers.enable(1); - camera.layers.enable(2); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - const light = new THREE.PointLight(0xffffff, 3, 0, 0); - light.layers.enable(0); - light.layers.enable(1); - light.layers.enable(2); - - scene.add(camera); - camera.add(light); - - const colors = [0xff0000, 0x00ff00, 0x0000ff]; - const geometry = new THREE.BoxGeometry(); - - for (let i = 0; i < 300; i++) { - const layer = i % 3; - - const object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: colors[layer] })); - - object.position.x = Math.random() * 40 - 20; - object.position.y = Math.random() * 40 - 20; - object.position.z = Math.random() * 40 - 20; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() + 0.5; - object.scale.y = Math.random() + 0.5; - object.scale.z = Math.random() + 0.5; - - object.layers.set(layer); - - scene.add(object); - } - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - const layers = { - 'toggle red': function () { - camera.layers.toggle(0); - }, - - 'toggle green': function () { - camera.layers.toggle(1); - }, - - 'toggle blue': function () { - camera.layers.toggle(2); - }, - - 'enable all': function () { - camera.layers.enableAll(); - }, - - 'disable all': function () { - camera.layers.disableAll(); - }, - }; - - // - // Init gui - const gui = new GUI(); - gui.add(layers, 'toggle red'); - gui.add(layers, 'toggle green'); - gui.add(layers, 'toggle blue'); - gui.add(layers, 'enable all'); - gui.add(layers, 'disable all'); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - theta += 0.1; - - camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta)); - camera.lookAt(scene.position); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lensflares.ts b/examples-testing/examples/webgl_lensflares.ts deleted file mode 100644 index 230cebfa0..000000000 --- a/examples-testing/examples/webgl_lensflares.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FlyControls } from 'three/addons/controls/FlyControls.js'; -import { Lensflare, LensflareElement } from 'three/addons/objects/Lensflare.js'; - -let container, stats; - -let camera, scene, renderer; -let controls; - -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // camera - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 15000); - camera.position.z = 250; - - // scene - - scene = new THREE.Scene(); - scene.background = new THREE.Color().setHSL(0.51, 0.4, 0.01, THREE.SRGBColorSpace); - scene.fog = new THREE.Fog(scene.background, 3500, 15000); - - // world - - const s = 250; - - const geometry = new THREE.BoxGeometry(s, s, s); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0xffffff, shininess: 50 }); - - for (let i = 0; i < 3000; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = 8000 * (2.0 * Math.random() - 1.0); - mesh.position.y = 8000 * (2.0 * Math.random() - 1.0); - mesh.position.z = 8000 * (2.0 * Math.random() - 1.0); - - mesh.rotation.x = Math.random() * Math.PI; - mesh.rotation.y = Math.random() * Math.PI; - mesh.rotation.z = Math.random() * Math.PI; - - mesh.matrixAutoUpdate = false; - mesh.updateMatrix(); - - scene.add(mesh); - } - - // lights - - const dirLight = new THREE.DirectionalLight(0xffffff, 0.15); - dirLight.position.set(0, -1, 0).normalize(); - dirLight.color.setHSL(0.1, 0.7, 0.5); - scene.add(dirLight); - - // lensflares - const textureLoader = new THREE.TextureLoader(); - - const textureFlare0 = textureLoader.load('textures/lensflare/lensflare0.png'); - const textureFlare3 = textureLoader.load('textures/lensflare/lensflare3.png'); - - addLight(0.55, 0.9, 0.5, 5000, 0, -1000); - addLight(0.08, 0.8, 0.5, 0, 0, -1000); - addLight(0.995, 0.5, 0.9, 5000, 5000, -1000); - - function addLight(h, s, l, x, y, z) { - const light = new THREE.PointLight(0xffffff, 1.5, 2000, 0); - light.color.setHSL(h, s, l); - light.position.set(x, y, z); - scene.add(light); - - const lensflare = new Lensflare(); - lensflare.addElement(new LensflareElement(textureFlare0, 700, 0, light.color)); - lensflare.addElement(new LensflareElement(textureFlare3, 60, 0.6)); - lensflare.addElement(new LensflareElement(textureFlare3, 70, 0.7)); - lensflare.addElement(new LensflareElement(textureFlare3, 120, 0.9)); - lensflare.addElement(new LensflareElement(textureFlare3, 70, 1)); - light.add(lensflare); - } - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - controls = new FlyControls(camera, renderer.domElement); - - controls.movementSpeed = 2500; - controls.domElement = container; - controls.rollSpeed = Math.PI / 6; - controls.autoForward = false; - controls.dragToLook = false; - - // stats - - stats = new Stats(); - container.appendChild(stats.dom); - - // events - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - controls.update(delta); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lightprobe.ts b/examples-testing/examples/webgl_lightprobe.ts deleted file mode 100644 index 58f021e6d..000000000 --- a/examples-testing/examples/webgl_lightprobe.ts +++ /dev/null @@ -1,142 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js'; - -import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelper.js'; - -let mesh, renderer, scene, camera; - -let gui; - -let lightProbe; -let directionalLight; - -// linear color space -const API = { - lightProbeIntensity: 1.0, - directionalLightIntensity: 0.6, - envMapIntensity: 1, -}; - -init(); - -function init() { - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // tone mapping - renderer.toneMapping = THREE.NoToneMapping; - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 30); - - // controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.minDistance = 10; - controls.maxDistance = 50; - controls.enablePan = false; - - // probe - lightProbe = new THREE.LightProbe(); - scene.add(lightProbe); - - // light - directionalLight = new THREE.DirectionalLight(0xffffff, API.directionalLightIntensity); - directionalLight.position.set(10, 10, 10); - scene.add(directionalLight); - - // envmap - const genCubeUrls = function (prefix, postfix) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, - prefix + 'py' + postfix, - prefix + 'ny' + postfix, - prefix + 'pz' + postfix, - prefix + 'nz' + postfix, - ]; - }; - - const urls = genCubeUrls('textures/cube/pisa/', '.png'); - - new THREE.CubeTextureLoader().load(urls, function (cubeTexture) { - scene.background = cubeTexture; - - lightProbe.copy(LightProbeGenerator.fromCubeTexture(cubeTexture)); - lightProbe.intensity = API.lightProbeIntensity; - lightProbe.position.set(-10, 0, 0); // position not used in scene lighting calculations (helper honors the position, however) - - const geometry = new THREE.SphereGeometry(5, 64, 32); - //const geometry = new THREE.TorusKnotGeometry( 4, 1.5, 256, 32, 2, 3 ); - - const material = new THREE.MeshStandardMaterial({ - color: 0xffffff, - metalness: 0, - roughness: 0, - envMap: cubeTexture, - envMapIntensity: API.envMapIntensity, - }); - - // mesh - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // helper - const helper = new LightProbeHelper(lightProbe, 1); - scene.add(helper); - - render(); - }); - - // gui - gui = new GUI({ title: 'Intensity' }); - - gui.add(API, 'lightProbeIntensity', 0, 1, 0.02) - .name('light probe') - .onChange(function () { - lightProbe.intensity = API.lightProbeIntensity; - render(); - }); - - gui.add(API, 'directionalLightIntensity', 0, 1, 0.02) - .name('directional light') - .onChange(function () { - directionalLight.intensity = API.directionalLightIntensity; - render(); - }); - - gui.add(API, 'envMapIntensity', 0, 1, 0.02) - .name('envMap') - .onChange(function () { - mesh.material.envMapIntensity = API.envMapIntensity; - render(); - }); - - // listener - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lightprobe_cubecamera.ts b/examples-testing/examples/webgl_lightprobe_cubecamera.ts deleted file mode 100644 index 65425d4e7..000000000 --- a/examples-testing/examples/webgl_lightprobe_cubecamera.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelper.js'; -import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js'; - -let renderer, scene, camera, cubeCamera; - -let lightProbe; - -init(); - -function init() { - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 30); - - const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256); - - cubeCamera = new THREE.CubeCamera(1, 1000, cubeRenderTarget); - - // controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.minDistance = 10; - controls.maxDistance = 50; - controls.enablePan = false; - - // probe - lightProbe = new THREE.LightProbe(); - scene.add(lightProbe); - - // envmap - const genCubeUrls = function (prefix, postfix) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, - prefix + 'py' + postfix, - prefix + 'ny' + postfix, - prefix + 'pz' + postfix, - prefix + 'nz' + postfix, - ]; - }; - - const urls = genCubeUrls('textures/cube/pisa/', '.png'); - - new THREE.CubeTextureLoader().load(urls, async function (cubeTexture) { - scene.background = cubeTexture; - - cubeCamera.update(renderer, scene); - - const probe = await LightProbeGenerator.fromCubeRenderTarget(renderer, cubeRenderTarget); - - lightProbe.copy(probe); - - scene.add(new LightProbeHelper(lightProbe, 5)); - - render(); - }); - - // listener - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lights_hemisphere.ts b/examples-testing/examples/webgl_lights_hemisphere.ts deleted file mode 100644 index 15bc76099..000000000 --- a/examples-testing/examples/webgl_lights_hemisphere.ts +++ /dev/null @@ -1,188 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, scene, renderer; -const mixers = []; -let stats; - -const clock = new THREE.Clock(); - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.set(0, 0, 250); - - scene = new THREE.Scene(); - scene.background = new THREE.Color().setHSL(0.6, 0, 1); - scene.fog = new THREE.Fog(scene.background, 1, 5000); - - // LIGHTS - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 2); - hemiLight.color.setHSL(0.6, 1, 0.6); - hemiLight.groundColor.setHSL(0.095, 1, 0.75); - hemiLight.position.set(0, 50, 0); - scene.add(hemiLight); - - const hemiLightHelper = new THREE.HemisphereLightHelper(hemiLight, 10); - scene.add(hemiLightHelper); - - // - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.color.setHSL(0.1, 1, 0.95); - dirLight.position.set(-1, 1.75, 1); - dirLight.position.multiplyScalar(30); - scene.add(dirLight); - - dirLight.castShadow = true; - - dirLight.shadow.mapSize.width = 2048; - dirLight.shadow.mapSize.height = 2048; - - const d = 50; - - dirLight.shadow.camera.left = -d; - dirLight.shadow.camera.right = d; - dirLight.shadow.camera.top = d; - dirLight.shadow.camera.bottom = -d; - - dirLight.shadow.camera.far = 3500; - dirLight.shadow.bias = -0.0001; - - const dirLightHelper = new THREE.DirectionalLightHelper(dirLight, 10); - scene.add(dirLightHelper); - - // GROUND - - const groundGeo = new THREE.PlaneGeometry(10000, 10000); - const groundMat = new THREE.MeshLambertMaterial({ color: 0xffffff }); - groundMat.color.setHSL(0.095, 1, 0.75); - - const ground = new THREE.Mesh(groundGeo, groundMat); - ground.position.y = -33; - ground.rotation.x = -Math.PI / 2; - ground.receiveShadow = true; - scene.add(ground); - - // SKYDOME - - const vertexShader = document.getElementById('vertexShader').textContent; - const fragmentShader = document.getElementById('fragmentShader').textContent; - const uniforms = { - topColor: { value: new THREE.Color(0x0077ff) }, - bottomColor: { value: new THREE.Color(0xffffff) }, - offset: { value: 33 }, - exponent: { value: 0.6 }, - }; - uniforms['topColor'].value.copy(hemiLight.color); - - scene.fog.color.copy(uniforms['bottomColor'].value); - - const skyGeo = new THREE.SphereGeometry(4000, 32, 15); - const skyMat = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: vertexShader, - fragmentShader: fragmentShader, - side: THREE.BackSide, - }); - - const sky = new THREE.Mesh(skyGeo, skyMat); - scene.add(sky); - - // MODEL - - const loader = new GLTFLoader(); - - loader.load('models/gltf/Flamingo.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - - const s = 0.35; - mesh.scale.set(s, s, s); - mesh.position.y = 15; - mesh.rotation.y = -1; - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - - const mixer = new THREE.AnimationMixer(mesh); - mixer.clipAction(gltf.animations[0]).setDuration(1).play(); - mixers.push(mixer); - }); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - renderer.shadowMap.enabled = true; - - // STATS - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - const params = { - toggleHemisphereLight: function () { - hemiLight.visible = !hemiLight.visible; - hemiLightHelper.visible = !hemiLightHelper.visible; - }, - toggleDirectionalLight: function () { - dirLight.visible = !dirLight.visible; - dirLightHelper.visible = !dirLightHelper.visible; - }, - shadowIntensity: 1, - }; - - const gui = new GUI(); - - gui.add(params, 'toggleHemisphereLight').name('toggle hemisphere light'); - gui.add(params, 'toggleDirectionalLight').name('toggle directional light'); - gui.add(params, 'shadowIntensity', 0, 1) - .name('shadow intensity') - .onChange(value => { - dirLight.shadow.intensity = value; - }); - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - for (let i = 0; i < mixers.length; i++) { - mixers[i].update(delta); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lights_physical.ts b/examples-testing/examples/webgl_lights_physical.ts deleted file mode 100644 index 707ef200e..000000000 --- a/examples-testing/examples/webgl_lights_physical.ts +++ /dev/null @@ -1,237 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, bulbLight, bulbMat, hemiLight, stats; -let ballMat, cubeMat, floorMat; - -let previousShadowMap = false; - -// ref for lumens: http://www.power-sure.com/lumens.htm -const bulbLuminousPowers = { - '110000 lm (1000W)': 110000, - '3500 lm (300W)': 3500, - '1700 lm (100W)': 1700, - '800 lm (60W)': 800, - '400 lm (40W)': 400, - '180 lm (25W)': 180, - '20 lm (4W)': 20, - Off: 0, -}; - -// ref for solar irradiances: https://en.wikipedia.org/wiki/Lux -const hemiLuminousIrradiances = { - '0.0001 lx (Moonless Night)': 0.0001, - '0.002 lx (Night Airglow)': 0.002, - '0.5 lx (Full Moon)': 0.5, - '3.4 lx (City Twilight)': 3.4, - '50 lx (Living Room)': 50, - '100 lx (Very Overcast)': 100, - '350 lx (Office Room)': 350, - '400 lx (Sunrise/Sunset)': 400, - '1000 lx (Overcast)': 1000, - '18000 lx (Daylight)': 18000, - '50000 lx (Direct Sun)': 50000, -}; - -const params = { - shadows: true, - exposure: 0.68, - bulbPower: Object.keys(bulbLuminousPowers)[4], - hemiIrradiance: Object.keys(hemiLuminousIrradiances)[0], -}; - -init(); - -function init() { - const container = document.getElementById('container'); - - stats = new Stats(); - container.appendChild(stats.dom); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.x = -4; - camera.position.z = 4; - camera.position.y = 2; - - scene = new THREE.Scene(); - - const bulbGeometry = new THREE.SphereGeometry(0.02, 16, 8); - bulbLight = new THREE.PointLight(0xffee88, 1, 100, 2); - - bulbMat = new THREE.MeshStandardMaterial({ - emissive: 0xffffee, - emissiveIntensity: 1, - color: 0x000000, - }); - bulbLight.add(new THREE.Mesh(bulbGeometry, bulbMat)); - bulbLight.position.set(0, 2, 0); - bulbLight.castShadow = true; - scene.add(bulbLight); - - hemiLight = new THREE.HemisphereLight(0xddeeff, 0x0f0e0d, 0.02); - scene.add(hemiLight); - - floorMat = new THREE.MeshStandardMaterial({ - roughness: 0.8, - color: 0xffffff, - metalness: 0.2, - bumpScale: 1, - }); - const textureLoader = new THREE.TextureLoader(); - textureLoader.load('textures/hardwood2_diffuse.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(10, 24); - map.colorSpace = THREE.SRGBColorSpace; - floorMat.map = map; - floorMat.needsUpdate = true; - }); - textureLoader.load('textures/hardwood2_bump.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(10, 24); - floorMat.bumpMap = map; - floorMat.needsUpdate = true; - }); - textureLoader.load('textures/hardwood2_roughness.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(10, 24); - floorMat.roughnessMap = map; - floorMat.needsUpdate = true; - }); - - cubeMat = new THREE.MeshStandardMaterial({ - roughness: 0.7, - color: 0xffffff, - bumpScale: 1, - metalness: 0.2, - }); - textureLoader.load('textures/brick_diffuse.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(1, 1); - map.colorSpace = THREE.SRGBColorSpace; - cubeMat.map = map; - cubeMat.needsUpdate = true; - }); - textureLoader.load('textures/brick_bump.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(1, 1); - cubeMat.bumpMap = map; - cubeMat.needsUpdate = true; - }); - - ballMat = new THREE.MeshStandardMaterial({ - color: 0xffffff, - roughness: 0.5, - metalness: 1.0, - }); - textureLoader.load('textures/planets/earth_atmos_2048.jpg', function (map) { - map.anisotropy = 4; - map.colorSpace = THREE.SRGBColorSpace; - ballMat.map = map; - ballMat.needsUpdate = true; - }); - textureLoader.load('textures/planets/earth_specular_2048.jpg', function (map) { - map.anisotropy = 4; - map.colorSpace = THREE.SRGBColorSpace; - ballMat.metalnessMap = map; - ballMat.needsUpdate = true; - }); - - const floorGeometry = new THREE.PlaneGeometry(20, 20); - const floorMesh = new THREE.Mesh(floorGeometry, floorMat); - floorMesh.receiveShadow = true; - floorMesh.rotation.x = -Math.PI / 2.0; - scene.add(floorMesh); - - const ballGeometry = new THREE.SphereGeometry(0.25, 32, 32); - const ballMesh = new THREE.Mesh(ballGeometry, ballMat); - ballMesh.position.set(1, 0.25, 1); - ballMesh.rotation.y = Math.PI; - ballMesh.castShadow = true; - scene.add(ballMesh); - - const boxGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); - const boxMesh = new THREE.Mesh(boxGeometry, cubeMat); - boxMesh.position.set(-0.5, 0.25, -1); - boxMesh.castShadow = true; - scene.add(boxMesh); - - const boxMesh2 = new THREE.Mesh(boxGeometry, cubeMat); - boxMesh2.position.set(0, 0.25, -5); - boxMesh2.castShadow = true; - scene.add(boxMesh2); - - const boxMesh3 = new THREE.Mesh(boxGeometry, cubeMat); - boxMesh3.position.set(7, 0.25, 0); - boxMesh3.castShadow = true; - scene.add(boxMesh3); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.toneMapping = THREE.ReinhardToneMapping; - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 20; - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'hemiIrradiance', Object.keys(hemiLuminousIrradiances)); - gui.add(params, 'bulbPower', Object.keys(bulbLuminousPowers)); - gui.add(params, 'exposure', 0, 1); - gui.add(params, 'shadows'); - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.toneMappingExposure = Math.pow(params.exposure, 5.0); // to allow for very bright scenes. - renderer.shadowMap.enabled = params.shadows; - bulbLight.castShadow = params.shadows; - - if (params.shadows !== previousShadowMap) { - ballMat.needsUpdate = true; - cubeMat.needsUpdate = true; - floorMat.needsUpdate = true; - previousShadowMap = params.shadows; - } - - bulbLight.power = bulbLuminousPowers[params.bulbPower]; - bulbMat.emissiveIntensity = bulbLight.intensity / Math.pow(0.02, 2.0); // convert from intensity to irradiance at bulb surface - - hemiLight.intensity = hemiLuminousIrradiances[params.hemiIrradiance]; - const time = Date.now() * 0.0005; - - bulbLight.position.y = Math.cos(time) * 0.75 + 1.25; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_lights_pointlights.ts b/examples-testing/examples/webgl_lights_pointlights.ts deleted file mode 100644 index ea95070ce..000000000 --- a/examples-testing/examples/webgl_lights_pointlights.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - -let camera, scene, renderer, light1, light2, light3, light4, object, stats; - -const clock = new THREE.Clock(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 100; - - scene = new THREE.Scene(); - - //model - - const loader = new OBJLoader(); - loader.load('models/obj/walt/WaltHead.obj', function (obj) { - object = obj; - object.scale.multiplyScalar(0.8); - object.position.y = -30; - scene.add(object); - }); - - const sphere = new THREE.SphereGeometry(0.5, 16, 8); - - //lights - - light1 = new THREE.PointLight(0xff0040, 400); - light1.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0xff0040 }))); - scene.add(light1); - - light2 = new THREE.PointLight(0x0040ff, 400); - light2.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0x0040ff }))); - scene.add(light2); - - light3 = new THREE.PointLight(0x80ff80, 400); - light3.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0x80ff80 }))); - scene.add(light3); - - light4 = new THREE.PointLight(0xffaa00, 400); - light4.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0xffaa00 }))); - scene.add(light4); - - //renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - //stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.0005; - const delta = clock.getDelta(); - - if (object) object.rotation.y -= 0.5 * delta; - - light1.position.x = Math.sin(time * 0.7) * 30; - light1.position.y = Math.cos(time * 0.5) * 40; - light1.position.z = Math.cos(time * 0.3) * 30; - - light2.position.x = Math.cos(time * 0.3) * 30; - light2.position.y = Math.sin(time * 0.5) * 40; - light2.position.z = Math.sin(time * 0.7) * 30; - - light3.position.x = Math.sin(time * 0.7) * 30; - light3.position.y = Math.cos(time * 0.3) * 40; - light3.position.z = Math.sin(time * 0.5) * 30; - - light4.position.x = Math.sin(time * 0.3) * 30; - light4.position.y = Math.cos(time * 0.7) * 40; - light4.position.z = Math.sin(time * 0.5) * 30; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lights_rectarealight.ts b/examples-testing/examples/webgl_lights_rectarealight.ts deleted file mode 100644 index b841fa6b5..000000000 --- a/examples-testing/examples/webgl_lights_rectarealight.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js'; -import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js'; - -let renderer, scene, camera; -let stats, meshKnot; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animation); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 5, -15); - - scene = new THREE.Scene(); - - RectAreaLightUniformsLib.init(); - - const rectLight1 = new THREE.RectAreaLight(0xff0000, 5, 4, 10); - rectLight1.position.set(-5, 5, 5); - scene.add(rectLight1); - - const rectLight2 = new THREE.RectAreaLight(0x00ff00, 5, 4, 10); - rectLight2.position.set(0, 5, 5); - scene.add(rectLight2); - - const rectLight3 = new THREE.RectAreaLight(0x0000ff, 5, 4, 10); - rectLight3.position.set(5, 5, 5); - scene.add(rectLight3); - - scene.add(new RectAreaLightHelper(rectLight1)); - scene.add(new RectAreaLightHelper(rectLight2)); - scene.add(new RectAreaLightHelper(rectLight3)); - - const geoFloor = new THREE.BoxGeometry(2000, 0.1, 2000); - const matStdFloor = new THREE.MeshStandardMaterial({ color: 0xbcbcbc, roughness: 0.1, metalness: 0 }); - const mshStdFloor = new THREE.Mesh(geoFloor, matStdFloor); - scene.add(mshStdFloor); - - const geoKnot = new THREE.TorusKnotGeometry(1.5, 0.5, 200, 16); - const matKnot = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0, metalness: 0 }); - meshKnot = new THREE.Mesh(geoKnot, matKnot); - meshKnot.position.set(0, 5, 0); - scene.add(meshKnot); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.copy(meshKnot.position); - controls.update(); - - // - - window.addEventListener('resize', onWindowResize); - - stats = new Stats(); - document.body.appendChild(stats.dom); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -function animation(time) { - meshKnot.rotation.y = time / 1000; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_lights_spotlight.ts b/examples-testing/examples/webgl_lights_spotlight.ts deleted file mode 100644 index 894abaf6f..000000000 --- a/examples-testing/examples/webgl_lights_spotlight.ts +++ /dev/null @@ -1,183 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let renderer, scene, camera; - -let spotLight, lightHelper; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(7, 4, 1); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 10; - controls.maxPolarAngle = Math.PI / 2; - controls.target.set(0, 1, 0); - controls.update(); - - const ambient = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 0.15); - scene.add(ambient); - - const loader = new THREE.TextureLoader().setPath('textures/'); - const filenames = ['disturb.jpg', 'colors.png', 'uv_grid_opengl.jpg']; - - const textures = { none: null }; - - for (let i = 0; i < filenames.length; i++) { - const filename = filenames[i]; - - const texture = loader.load(filename); - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.colorSpace = THREE.SRGBColorSpace; - - textures[filename] = texture; - } - - spotLight = new THREE.SpotLight(0xffffff, 100); - spotLight.position.set(2.5, 5, 2.5); - spotLight.angle = Math.PI / 6; - spotLight.penumbra = 1; - spotLight.decay = 2; - spotLight.distance = 0; - spotLight.map = textures['disturb.jpg']; - - spotLight.castShadow = true; - spotLight.shadow.mapSize.width = 1024; - spotLight.shadow.mapSize.height = 1024; - spotLight.shadow.camera.near = 1; - spotLight.shadow.camera.far = 10; - spotLight.shadow.focus = 1; - scene.add(spotLight); - - lightHelper = new THREE.SpotLightHelper(spotLight); - scene.add(lightHelper); - - // - - const geometry = new THREE.PlaneGeometry(200, 200); - const material = new THREE.MeshLambertMaterial({ color: 0xbcbcbc }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(0, -1, 0); - mesh.rotation.x = -Math.PI / 2; - mesh.receiveShadow = true; - scene.add(mesh); - - // - - new PLYLoader().load('models/ply/binary/Lucy100k.ply', function (geometry) { - geometry.scale(0.0024, 0.0024, 0.0024); - geometry.computeVertexNormals(); - - const material = new THREE.MeshLambertMaterial(); - - const mesh = new THREE.Mesh(geometry, material); - mesh.rotation.y = -Math.PI / 2; - mesh.position.y = 0.8; - mesh.castShadow = true; - mesh.receiveShadow = true; - scene.add(mesh); - }); - - window.addEventListener('resize', onWindowResize); - - // GUI - - const gui = new GUI(); - - const params = { - map: textures['disturb.jpg'], - color: spotLight.color.getHex(), - intensity: spotLight.intensity, - distance: spotLight.distance, - angle: spotLight.angle, - penumbra: spotLight.penumbra, - decay: spotLight.decay, - focus: spotLight.shadow.focus, - shadows: true, - }; - - gui.add(params, 'map', textures).onChange(function (val) { - spotLight.map = val; - }); - - gui.addColor(params, 'color').onChange(function (val) { - spotLight.color.setHex(val); - }); - - gui.add(params, 'intensity', 0, 500).onChange(function (val) { - spotLight.intensity = val; - }); - - gui.add(params, 'distance', 0, 20).onChange(function (val) { - spotLight.distance = val; - }); - - gui.add(params, 'angle', 0, Math.PI / 3).onChange(function (val) { - spotLight.angle = val; - }); - - gui.add(params, 'penumbra', 0, 1).onChange(function (val) { - spotLight.penumbra = val; - }); - - gui.add(params, 'decay', 1, 2).onChange(function (val) { - spotLight.decay = val; - }); - - gui.add(params, 'focus', 0, 1).onChange(function (val) { - spotLight.shadow.focus = val; - }); - - gui.add(params, 'shadows').onChange(function (val) { - renderer.shadowMap.enabled = val; - - scene.traverse(function (child) { - if (child.material) { - child.material.needsUpdate = true; - } - }); - }); - - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = performance.now() / 3000; - - spotLight.position.x = Math.cos(time) * 2.5; - spotLight.position.z = Math.sin(time) * 2.5; - - lightHelper.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lights_spotlights.ts b/examples-testing/examples/webgl_lights_spotlights.ts deleted file mode 100644 index 70caf5a58..000000000 --- a/examples-testing/examples/webgl_lights_spotlights.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as THREE from 'three'; -import TWEEN from 'three/addons/libs/tween.module.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -const renderer = new THREE.WebGLRenderer({ antialias: true }); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.setAnimationLoop(animate); - -const camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100); - -const controls = new OrbitControls(camera, renderer.domElement); - -const scene = new THREE.Scene(); - -const matFloor = new THREE.MeshPhongMaterial({ color: 0x808080 }); -const matBox = new THREE.MeshPhongMaterial({ color: 0xaaaaaa }); - -const geoFloor = new THREE.PlaneGeometry(100, 100); -const geoBox = new THREE.BoxGeometry(0.3, 0.1, 0.2); - -const mshFloor = new THREE.Mesh(geoFloor, matFloor); -mshFloor.rotation.x = -Math.PI * 0.5; -const mshBox = new THREE.Mesh(geoBox, matBox); - -const ambient = new THREE.AmbientLight(0x444444); - -const spotLight1 = createSpotlight(0xff7f00); -const spotLight2 = createSpotlight(0x00ff7f); -const spotLight3 = createSpotlight(0x7f00ff); - -let lightHelper1, lightHelper2, lightHelper3; - -function init() { - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - - camera.position.set(4.6, 2.2, -2.1); - - spotLight1.position.set(1.5, 4, 4.5); - spotLight2.position.set(0, 4, 3.5); - spotLight3.position.set(-1.5, 4, 4.5); - - lightHelper1 = new THREE.SpotLightHelper(spotLight1); - lightHelper2 = new THREE.SpotLightHelper(spotLight2); - lightHelper3 = new THREE.SpotLightHelper(spotLight3); - - mshFloor.receiveShadow = true; - mshFloor.position.set(0, -0.05, 0); - - mshBox.castShadow = true; - mshBox.receiveShadow = true; - mshBox.position.set(0, 0.5, 0); - - scene.add(mshFloor); - scene.add(mshBox); - scene.add(ambient); - scene.add(spotLight1, spotLight2, spotLight3); - scene.add(lightHelper1, lightHelper2, lightHelper3); - - document.body.appendChild(renderer.domElement); - window.addEventListener('resize', onWindowResize); - - controls.target.set(0, 0.5, 0); - controls.maxPolarAngle = Math.PI / 2; - controls.minDistance = 1; - controls.maxDistance = 10; - controls.update(); -} - -function createSpotlight(color) { - const newObj = new THREE.SpotLight(color, 10); - - newObj.castShadow = true; - newObj.angle = 0.3; - newObj.penumbra = 0.2; - newObj.decay = 2; - newObj.distance = 50; - - return newObj; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function tween(light) { - new TWEEN.Tween(light) - .to( - { - angle: Math.random() * 0.7 + 0.1, - penumbra: Math.random() + 1, - }, - Math.random() * 3000 + 2000, - ) - .easing(TWEEN.Easing.Quadratic.Out) - .start(); - - new TWEEN.Tween(light.position) - .to( - { - x: Math.random() * 3 - 1.5, - y: Math.random() * 1 + 1.5, - z: Math.random() * 3 - 1.5, - }, - Math.random() * 3000 + 2000, - ) - .easing(TWEEN.Easing.Quadratic.Out) - .start(); -} - -function updateTweens() { - tween(spotLight1); - tween(spotLight2); - tween(spotLight3); - - setTimeout(updateTweens, 5000); -} - -function animate() { - TWEEN.update(); - - if (lightHelper1) lightHelper1.update(); - if (lightHelper2) lightHelper2.update(); - if (lightHelper3) lightHelper3.update(); - - renderer.render(scene, camera); -} - -init(); -updateTweens(); diff --git a/examples-testing/examples/webgl_lines_colors.ts b/examples-testing/examples/webgl_lines_colors.ts deleted file mode 100644 index 9da19ee2e..000000000 --- a/examples-testing/examples/webgl_lines_colors.ts +++ /dev/null @@ -1,181 +0,0 @@ -import * as THREE from 'three'; - -import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -let camera, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(33, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - const hilbertPoints = GeometryUtils.hilbert3D(new THREE.Vector3(0, 0, 0), 200.0, 1, 0, 1, 2, 3, 4, 5, 6, 7); - - const geometry1 = new THREE.BufferGeometry(); - const geometry2 = new THREE.BufferGeometry(); - const geometry3 = new THREE.BufferGeometry(); - - const subdivisions = 6; - - let vertices = []; - let colors1 = []; - let colors2 = []; - let colors3 = []; - - const point = new THREE.Vector3(); - const color = new THREE.Color(); - - const spline = new THREE.CatmullRomCurve3(hilbertPoints); - - for (let i = 0; i < hilbertPoints.length * subdivisions; i++) { - const t = i / (hilbertPoints.length * subdivisions); - spline.getPoint(t, point); - - vertices.push(point.x, point.y, point.z); - - color.setHSL(0.6, 1.0, Math.max(0, -point.x / 200) + 0.5, THREE.SRGBColorSpace); - colors1.push(color.r, color.g, color.b); - - color.setHSL(0.9, 1.0, Math.max(0, -point.y / 200) + 0.5, THREE.SRGBColorSpace); - colors2.push(color.r, color.g, color.b); - - color.setHSL(i / (hilbertPoints.length * subdivisions), 1.0, 0.5, THREE.SRGBColorSpace); - colors3.push(color.r, color.g, color.b); - } - - geometry1.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry2.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry3.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - - geometry1.setAttribute('color', new THREE.Float32BufferAttribute(colors1, 3)); - geometry2.setAttribute('color', new THREE.Float32BufferAttribute(colors2, 3)); - geometry3.setAttribute('color', new THREE.Float32BufferAttribute(colors3, 3)); - - // - - const geometry4 = new THREE.BufferGeometry(); - const geometry5 = new THREE.BufferGeometry(); - const geometry6 = new THREE.BufferGeometry(); - - vertices = []; - colors1 = []; - colors2 = []; - colors3 = []; - - for (let i = 0; i < hilbertPoints.length; i++) { - const point = hilbertPoints[i]; - - vertices.push(point.x, point.y, point.z); - - color.setHSL(0.6, 1.0, Math.max(0, (200 - hilbertPoints[i].x) / 400) * 0.5 + 0.5, THREE.SRGBColorSpace); - colors1.push(color.r, color.g, color.b); - - color.setHSL(0.3, 1.0, Math.max(0, (200 + hilbertPoints[i].x) / 400) * 0.5, THREE.SRGBColorSpace); - colors2.push(color.r, color.g, color.b); - - color.setHSL(i / hilbertPoints.length, 1.0, 0.5, THREE.SRGBColorSpace); - colors3.push(color.r, color.g, color.b); - } - - geometry4.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry5.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - geometry6.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - - geometry4.setAttribute('color', new THREE.Float32BufferAttribute(colors1, 3)); - geometry5.setAttribute('color', new THREE.Float32BufferAttribute(colors2, 3)); - geometry6.setAttribute('color', new THREE.Float32BufferAttribute(colors3, 3)); - - // Create lines and add to scene - - const material = new THREE.LineBasicMaterial({ color: 0xffffff, vertexColors: true }); - - let line, p; - const scale = 0.3, - d = 225; - - const parameters = [ - [material, scale * 1.5, [-d, -d / 2, 0], geometry1], - [material, scale * 1.5, [0, -d / 2, 0], geometry2], - [material, scale * 1.5, [d, -d / 2, 0], geometry3], - - [material, scale * 1.5, [-d, d / 2, 0], geometry4], - [material, scale * 1.5, [0, d / 2, 0], geometry5], - [material, scale * 1.5, [d, d / 2, 0], geometry6], - ]; - - for (let i = 0; i < parameters.length; i++) { - p = parameters[i]; - line = new THREE.Line(p[3], p[0]); - line.scale.x = line.scale.y = line.scale.z = p[1]; - line.position.x = p[2][0]; - line.position.y = p[2][1]; - line.position.z = p[2][2]; - scene.add(line); - } - - // - - document.body.style.touchAction = 'none'; - document.body.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY + 200 - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - const time = Date.now() * 0.0005; - - for (let i = 0; i < scene.children.length; i++) { - const object = scene.children[i]; - - if (object.isLine) { - object.rotation.y = time * (i % 2 ? 1 : -1); - } - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lines_dashed.ts b/examples-testing/examples/webgl_lines_dashed.ts deleted file mode 100644 index 4849e7c3a..000000000 --- a/examples-testing/examples/webgl_lines_dashed.ts +++ /dev/null @@ -1,186 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - -let renderer, scene, camera, stats; -const objects = []; - -const WIDTH = window.innerWidth, - HEIGHT = window.innerHeight; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, WIDTH / HEIGHT, 1, 200); - camera.position.z = 150; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x111111); - scene.fog = new THREE.Fog(0x111111, 150, 200); - - const subdivisions = 6; - const recursion = 1; - - const points = GeometryUtils.hilbert3D(new THREE.Vector3(0, 0, 0), 25.0, recursion, 0, 1, 2, 3, 4, 5, 6, 7); - const spline = new THREE.CatmullRomCurve3(points); - - const samples = spline.getPoints(points.length * subdivisions); - const geometrySpline = new THREE.BufferGeometry().setFromPoints(samples); - - const line = new THREE.Line( - geometrySpline, - new THREE.LineDashedMaterial({ color: 0xffffff, dashSize: 1, gapSize: 0.5 }), - ); - line.computeLineDistances(); - - objects.push(line); - scene.add(line); - - const geometryBox = box(50, 50, 50); - - const lineSegments = new THREE.LineSegments( - geometryBox, - new THREE.LineDashedMaterial({ color: 0xffaa00, dashSize: 3, gapSize: 1 }), - ); - lineSegments.computeLineDistances(); - - objects.push(lineSegments); - scene.add(lineSegments); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function box(width, height, depth) { - (width = width * 0.5), (height = height * 0.5), (depth = depth * 0.5); - - const geometry = new THREE.BufferGeometry(); - const position = []; - - position.push( - -width, - -height, - -depth, - -width, - height, - -depth, - - -width, - height, - -depth, - width, - height, - -depth, - - width, - height, - -depth, - width, - -height, - -depth, - - width, - -height, - -depth, - -width, - -height, - -depth, - - -width, - -height, - depth, - -width, - height, - depth, - - -width, - height, - depth, - width, - height, - depth, - - width, - height, - depth, - width, - -height, - depth, - - width, - -height, - depth, - -width, - -height, - depth, - - -width, - -height, - -depth, - -width, - -height, - depth, - - -width, - height, - -depth, - -width, - height, - depth, - - width, - height, - -depth, - width, - height, - depth, - - width, - -height, - -depth, - width, - -height, - depth, - ); - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3)); - - return geometry; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.001; - - scene.traverse(function (object) { - if (object.isLine) { - object.rotation.x = 0.25 * time; - object.rotation.y = 0.25 * time; - } - }); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lines_fat.ts b/examples-testing/examples/webgl_lines_fat.ts deleted file mode 100644 index 7c7fee657..000000000 --- a/examples-testing/examples/webgl_lines_fat.ts +++ /dev/null @@ -1,245 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'stats-gl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Line2 } from 'three/addons/lines/Line2.js'; -import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; -import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; -import * as GeometryUtils from 'three/addons/utils/GeometryUtils.js'; - -let line, renderer, scene, camera, camera2, controls; -let line1; -let matLine, matLineBasic, matLineDashed; -let stats; -let gui; - -// viewport -let insetWidth; -let insetHeight; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setClearColor(0x000000, 0.0); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(-40, 0, 60); - - camera2 = new THREE.PerspectiveCamera(40, 1, 1, 1000); - camera2.position.copy(camera.position); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 10; - controls.maxDistance = 500; - - // Position and THREE.Color Data - - const positions = []; - const colors = []; - - const points = GeometryUtils.hilbert3D(new THREE.Vector3(0, 0, 0), 20.0, 1, 0, 1, 2, 3, 4, 5, 6, 7); - - const spline = new THREE.CatmullRomCurve3(points); - const divisions = Math.round(12 * points.length); - const point = new THREE.Vector3(); - const color = new THREE.Color(); - - for (let i = 0, l = divisions; i < l; i++) { - const t = i / l; - - spline.getPoint(t, point); - positions.push(point.x, point.y, point.z); - - color.setHSL(t, 1.0, 0.5, THREE.SRGBColorSpace); - colors.push(color.r, color.g, color.b); - } - - // Line2 ( LineGeometry, LineMaterial ) - - const geometry = new LineGeometry(); - geometry.setPositions(positions); - geometry.setColors(colors); - - matLine = new LineMaterial({ - color: 0xffffff, - linewidth: 5, // in world units with size attenuation, pixels otherwise - vertexColors: true, - - dashed: false, - alphaToCoverage: true, - }); - - line = new Line2(geometry, matLine); - line.computeLineDistances(); - line.scale.set(1, 1, 1); - scene.add(line); - - // THREE.Line ( THREE.BufferGeometry, THREE.LineBasicMaterial ) - rendered with gl.LINE_STRIP - - const geo = new THREE.BufferGeometry(); - geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geo.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - matLineBasic = new THREE.LineBasicMaterial({ vertexColors: true }); - matLineDashed = new THREE.LineDashedMaterial({ vertexColors: true, scale: 2, dashSize: 1, gapSize: 1 }); - - line1 = new THREE.Line(geo, matLineBasic); - line1.computeLineDistances(); - line1.visible = false; - scene.add(line1); - - // - - window.addEventListener('resize', onWindowResize); - onWindowResize(); - - stats = new Stats({ horizontal: false }); - stats.init(renderer); - document.body.appendChild(stats.dom); - - initGui(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - insetWidth = window.innerHeight / 4; // square - insetHeight = window.innerHeight / 4; - - camera2.aspect = insetWidth / insetHeight; - camera2.updateProjectionMatrix(); -} - -function animate() { - // main scene - - renderer.setClearColor(0x000000, 0); - - renderer.setViewport(0, 0, window.innerWidth, window.innerHeight); - - controls.update(); - - renderer.render(scene, camera); - - // inset scene - - renderer.setClearColor(0x222222, 1); - - renderer.clearDepth(); // important! - - renderer.setScissorTest(true); - - renderer.setScissor(20, 20, insetWidth, insetHeight); - - renderer.setViewport(20, 20, insetWidth, insetHeight); - - camera2.position.copy(camera.position); - camera2.quaternion.copy(camera.quaternion); - - renderer.render(scene, camera2); - - renderer.setScissorTest(false); - - stats.update(); -} - -// - -function initGui() { - gui = new GUI(); - - const param = { - 'line type': 0, - 'world units': false, - width: 5, - alphaToCoverage: true, - dashed: false, - 'dash scale': 1, - 'dash / gap': 1, - }; - - gui.add(param, 'line type', { LineGeometry: 0, 'gl.LINE': 1 }).onChange(function (val) { - switch (val) { - case 0: - line.visible = true; - - line1.visible = false; - - break; - - case 1: - line.visible = false; - - line1.visible = true; - - break; - } - }); - - gui.add(param, 'world units').onChange(function (val) { - matLine.worldUnits = val; - matLine.needsUpdate = true; - }); - - gui.add(param, 'width', 1, 10).onChange(function (val) { - matLine.linewidth = val; - }); - - gui.add(param, 'alphaToCoverage').onChange(function (val) { - matLine.alphaToCoverage = val; - }); - - gui.add(param, 'dashed').onChange(function (val) { - matLine.dashed = val; - line1.material = val ? matLineDashed : matLineBasic; - }); - - gui.add(param, 'dash scale', 0.5, 2, 0.1).onChange(function (val) { - matLine.dashScale = val; - matLineDashed.scale = val; - }); - - gui.add(param, 'dash / gap', { '2 : 1': 0, '1 : 1': 1, '1 : 2': 2 }).onChange(function (val) { - switch (val) { - case 0: - matLine.dashSize = 2; - matLine.gapSize = 1; - - matLineDashed.dashSize = 2; - matLineDashed.gapSize = 1; - - break; - - case 1: - matLine.dashSize = 1; - matLine.gapSize = 1; - - matLineDashed.dashSize = 1; - matLineDashed.gapSize = 1; - - break; - - case 2: - matLine.dashSize = 1; - matLine.gapSize = 2; - - matLineDashed.dashSize = 1; - matLineDashed.gapSize = 2; - - break; - } - }); -} diff --git a/examples-testing/examples/webgl_lines_fat_raycasting.ts b/examples-testing/examples/webgl_lines_fat_raycasting.ts deleted file mode 100644 index 872058e0f..000000000 --- a/examples-testing/examples/webgl_lines_fat_raycasting.ts +++ /dev/null @@ -1,289 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'stats-gl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; -import { LineSegments2 } from 'three/addons/lines/LineSegments2.js'; -import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js'; -import { Line2 } from 'three/addons/lines/Line2.js'; -import { LineGeometry } from 'three/addons/lines/LineGeometry.js'; - -let line, thresholdLine, segments, thresholdSegments; -let renderer, scene, camera, controls; -let sphereInter, sphereOnLine; -let stats; -let gui; -let clock; - -const color = new THREE.Color(); - -const pointer = new THREE.Vector2(Infinity, Infinity); - -const raycaster = new THREE.Raycaster(); - -raycaster.params.Line2 = {}; -raycaster.params.Line2.threshold = 0; - -const matLine = new LineMaterial({ - color: 0xffffff, - linewidth: 1, // in world units with size attenuation, pixels otherwise - worldUnits: true, - vertexColors: true, - - alphaToCoverage: true, -}); - -const matThresholdLine = new LineMaterial({ - color: 0xffffff, - linewidth: matLine.linewidth, // in world units with size attenuation, pixels otherwise - worldUnits: true, - // vertexColors: true, - transparent: true, - opacity: 0.2, - depthTest: false, - visible: false, -}); - -const params = { - 'line type': 0, - 'world units': matLine.worldUnits, - 'visualize threshold': matThresholdLine.visible, - width: matLine.linewidth, - alphaToCoverage: matLine.alphaToCoverage, - threshold: raycaster.params.Line2.threshold, - translation: raycaster.params.Line2.threshold, - animate: true, -}; - -init(); - -function init() { - clock = new THREE.Clock(); - - renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setClearColor(0x000000, 0.0); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(-40, 0, 60); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 10; - controls.maxDistance = 500; - - const sphereGeometry = new THREE.SphereGeometry(0.25, 8, 4); - const sphereInterMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, depthTest: false }); - const sphereOnLineMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, depthTest: false }); - - sphereInter = new THREE.Mesh(sphereGeometry, sphereInterMaterial); - sphereOnLine = new THREE.Mesh(sphereGeometry, sphereOnLineMaterial); - sphereInter.visible = false; - sphereOnLine.visible = false; - sphereInter.renderOrder = 10; - sphereOnLine.renderOrder = 10; - scene.add(sphereInter); - scene.add(sphereOnLine); - - // Position and THREE.Color Data - - const positions = []; - const colors = []; - const points = []; - for (let i = -50; i < 50; i++) { - const t = i / 3; - points.push(new THREE.Vector3(t * Math.sin(2 * t), t, t * Math.cos(2 * t))); - } - - const spline = new THREE.CatmullRomCurve3(points); - const divisions = Math.round(3 * points.length); - const point = new THREE.Vector3(); - const color = new THREE.Color(); - - for (let i = 0, l = divisions; i < l; i++) { - const t = i / l; - - spline.getPoint(t, point); - positions.push(point.x, point.y, point.z); - - color.setHSL(t, 1.0, 0.5, THREE.SRGBColorSpace); - colors.push(color.r, color.g, color.b); - } - - const lineGeometry = new LineGeometry(); - lineGeometry.setPositions(positions); - lineGeometry.setColors(colors); - - const segmentsGeometry = new LineSegmentsGeometry(); - segmentsGeometry.setPositions(positions); - segmentsGeometry.setColors(colors); - - segments = new LineSegments2(segmentsGeometry, matLine); - segments.computeLineDistances(); - segments.scale.set(1, 1, 1); - scene.add(segments); - segments.visible = false; - - thresholdSegments = new LineSegments2(segmentsGeometry, matThresholdLine); - thresholdSegments.computeLineDistances(); - thresholdSegments.scale.set(1, 1, 1); - scene.add(thresholdSegments); - thresholdSegments.visible = false; - - line = new Line2(lineGeometry, matLine); - line.computeLineDistances(); - line.scale.set(1, 1, 1); - scene.add(line); - - thresholdLine = new Line2(lineGeometry, matThresholdLine); - thresholdLine.computeLineDistances(); - thresholdLine.scale.set(1, 1, 1); - scene.add(thresholdLine); - - const geo = new THREE.BufferGeometry(); - geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); - geo.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); - - // - - document.addEventListener('pointermove', onPointerMove); - window.addEventListener('resize', onWindowResize); - onWindowResize(); - - stats = new Stats({ horizontal: false }); - stats.init(renderer); - document.body.appendChild(stats.dom); - - initGui(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -function animate() { - const delta = clock.getDelta(); - - const obj = line.visible ? line : segments; - thresholdLine.position.copy(line.position); - thresholdLine.quaternion.copy(line.quaternion); - thresholdSegments.position.copy(segments.position); - thresholdSegments.quaternion.copy(segments.quaternion); - - if (params.animate) { - line.rotation.y += delta * 0.1; - - segments.rotation.y = line.rotation.y; - } - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObject(obj); - - if (intersects.length > 0) { - sphereInter.visible = true; - sphereOnLine.visible = true; - - sphereInter.position.copy(intersects[0].point); - sphereOnLine.position.copy(intersects[0].pointOnLine); - - const index = intersects[0].faceIndex; - const colors = obj.geometry.getAttribute('instanceColorStart'); - - color.fromBufferAttribute(colors, index); - - sphereInter.material.color.copy(color).offsetHSL(0.3, 0, 0); - sphereOnLine.material.color.copy(color).offsetHSL(0.7, 0, 0); - - renderer.domElement.style.cursor = 'crosshair'; - } else { - sphereInter.visible = false; - sphereOnLine.visible = false; - renderer.domElement.style.cursor = ''; - } - - renderer.render(scene, camera); - - stats.update(); -} - -// - -function switchLine(val) { - switch (val) { - case 0: - line.visible = true; - thresholdLine.visible = true; - - segments.visible = false; - thresholdSegments.visible = false; - - break; - - case 1: - line.visible = false; - thresholdLine.visible = false; - - segments.visible = true; - thresholdSegments.visible = true; - - break; - } -} - -function initGui() { - gui = new GUI(); - - gui.add(params, 'line type', { LineGeometry: 0, LineSegmentsGeometry: 1 }) - .onChange(function (val) { - switchLine(val); - }) - .setValue(1); - - gui.add(params, 'world units').onChange(function (val) { - matLine.worldUnits = val; - matLine.needsUpdate = true; - - matThresholdLine.worldUnits = val; - matThresholdLine.needsUpdate = true; - }); - - gui.add(params, 'visualize threshold').onChange(function (val) { - matThresholdLine.visible = val; - }); - - gui.add(params, 'width', 1, 10).onChange(function (val) { - matLine.linewidth = val; - matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2.threshold; - }); - - gui.add(params, 'alphaToCoverage').onChange(function (val) { - matLine.alphaToCoverage = val; - }); - - gui.add(params, 'threshold', 0, 10).onChange(function (val) { - raycaster.params.Line2.threshold = val; - matThresholdLine.linewidth = matLine.linewidth + raycaster.params.Line2.threshold; - }); - - gui.add(params, 'translation', 0, 10).onChange(function (val) { - line.position.x = val; - segments.position.x = val; - }); - - gui.add(params, 'animate'); -} diff --git a/examples-testing/examples/webgl_lines_fat_wireframe.ts b/examples-testing/examples/webgl_lines_fat_wireframe.ts deleted file mode 100644 index 59660ad7e..000000000 --- a/examples-testing/examples/webgl_lines_fat_wireframe.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { LineMaterial } from 'three/addons/lines/LineMaterial.js'; -import { Wireframe } from 'three/addons/lines/Wireframe.js'; -import { WireframeGeometry2 } from 'three/addons/lines/WireframeGeometry2.js'; - -let wireframe, renderer, scene, camera, camera2, controls; -let wireframe1; -let matLine, matLineBasic, matLineDashed; -let stats; -let gui; - -// viewport -let insetWidth; -let insetHeight; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setClearColor(0x000000, 0.0); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(-50, 0, 50); - - camera2 = new THREE.PerspectiveCamera(40, 1, 1, 1000); - camera2.position.copy(camera.position); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 10; - controls.maxDistance = 500; - - // Wireframe ( WireframeGeometry2, LineMaterial ) - - let geo = new THREE.IcosahedronGeometry(20, 1); - - const geometry = new WireframeGeometry2(geo); - - matLine = new LineMaterial({ - color: 0x4080ff, - linewidth: 5, // in pixels - dashed: false, - }); - - wireframe = new Wireframe(geometry, matLine); - wireframe.computeLineDistances(); - wireframe.scale.set(1, 1, 1); - scene.add(wireframe); - - // Line ( THREE.WireframeGeometry, THREE.LineBasicMaterial ) - rendered with gl.LINE - - geo = new THREE.WireframeGeometry(geo); - - matLineBasic = new THREE.LineBasicMaterial({ color: 0x4080ff }); - matLineDashed = new THREE.LineDashedMaterial({ scale: 2, dashSize: 1, gapSize: 1 }); - - wireframe1 = new THREE.LineSegments(geo, matLineBasic); - wireframe1.computeLineDistances(); - wireframe1.visible = false; - scene.add(wireframe1); - - // - - window.addEventListener('resize', onWindowResize); - onWindowResize(); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - initGui(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - insetWidth = window.innerHeight / 4; // square - insetHeight = window.innerHeight / 4; - - camera2.aspect = insetWidth / insetHeight; - camera2.updateProjectionMatrix(); -} - -function animate() { - // main scene - - renderer.setClearColor(0x000000, 0); - - renderer.setViewport(0, 0, window.innerWidth, window.innerHeight); - - renderer.render(scene, camera); - - // inset scene - - renderer.setClearColor(0x222222, 1); - - renderer.clearDepth(); // important! - - renderer.setScissorTest(true); - - renderer.setScissor(20, 20, insetWidth, insetHeight); - - renderer.setViewport(20, 20, insetWidth, insetHeight); - - camera2.position.copy(camera.position); - camera2.quaternion.copy(camera.quaternion); - - renderer.render(scene, camera2); - - renderer.setScissorTest(false); - - stats.update(); -} - -// - -function initGui() { - gui = new GUI(); - - const param = { - 'line type': 0, - 'width (px)': 5, - dashed: false, - 'dash scale': 1, - 'dash / gap': 1, - }; - - gui.add(param, 'line type', { LineGeometry: 0, 'gl.LINE': 1 }).onChange(function (val) { - switch (val) { - case 0: - wireframe.visible = true; - - wireframe1.visible = false; - - break; - - case 1: - wireframe.visible = false; - - wireframe1.visible = true; - - break; - } - }); - - gui.add(param, 'width (px)', 1, 10).onChange(function (val) { - matLine.linewidth = val; - }); - - gui.add(param, 'dashed').onChange(function (val) { - matLine.dashed = val; - - // dashed is implemented as a defines -- not as a uniform. this could be changed. - // ... or THREE.LineDashedMaterial could be implemented as a separate material - // temporary hack - renderer should do this eventually - if (val) matLine.defines.USE_DASH = ''; - else delete matLine.defines.USE_DASH; - matLine.needsUpdate = true; - - wireframe1.material = val ? matLineDashed : matLineBasic; - }); - - gui.add(param, 'dash scale', 0.5, 1, 0.1).onChange(function (val) { - matLine.dashScale = val; - matLineDashed.scale = val; - }); - - gui.add(param, 'dash / gap', { '2 : 1': 0, '1 : 1': 1, '1 : 2': 2 }).onChange(function (val) { - switch (val) { - case 0: - matLine.dashSize = 2; - matLine.gapSize = 1; - - matLineDashed.dashSize = 2; - matLineDashed.gapSize = 1; - - break; - - case 1: - matLine.dashSize = 1; - matLine.gapSize = 1; - - matLineDashed.dashSize = 1; - matLineDashed.gapSize = 1; - - break; - - case 2: - matLine.dashSize = 1; - matLine.gapSize = 2; - - matLineDashed.dashSize = 1; - matLineDashed.gapSize = 2; - - break; - } - }); -} diff --git a/examples-testing/examples/webgl_loader_3dm.ts b/examples-testing/examples/webgl_loader_3dm.ts deleted file mode 100644 index 7570306fd..000000000 --- a/examples-testing/examples/webgl_loader_3dm.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Rhino3dmLoader } from 'three/addons/loaders/3DMLoader.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; -let controls, gui; - -init(); - -function init() { - THREE.Object3D.DEFAULT_UP.set(0, 0, 1); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(26, -40, 5); - - scene = new THREE.Scene(); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 6); - directionalLight.position.set(0, 0, 2); - scene.add(directionalLight); - - const loader = new Rhino3dmLoader(); - //generally, use this for the Library Path: https://cdn.jsdelivr.net/npm/rhino3dm@8.0.1 - loader.setLibraryPath('jsm/libs/rhino3dm/'); - loader.load( - 'models/3dm/Rhino_Logo.3dm', - function (object) { - scene.add(object); - initGUI(object.userData.layers); - - // hide spinner - document.getElementById('loader').style.display = 'none'; - }, - function (progress) { - console.log((progress.loaded / progress.total) * 100 + '%'); - }, - function (error) { - console.log(error); - }, - ); - - controls = new OrbitControls(camera, renderer.domElement); - - window.addEventListener('resize', resize); -} - -function resize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - controls.update(); - renderer.render(scene, camera); -} - -function initGUI(layers) { - gui = new GUI({ title: 'layers' }); - - for (let i = 0; i < layers.length; i++) { - const layer = layers[i]; - gui.add(layer, 'visible') - .name(layer.name) - .onChange(function (val) { - const name = this.object.name; - - scene.traverse(function (child) { - if (child.userData.hasOwnProperty('attributes')) { - if ('layerIndex' in child.userData.attributes) { - const layerName = layers[child.userData.attributes.layerIndex].name; - - if (layerName === name) { - child.visible = val; - layer.visible = val; - } - } - } - }); - }); - } -} diff --git a/examples-testing/examples/webgl_loader_3ds.ts b/examples-testing/examples/webgl_loader_3ds.ts deleted file mode 100644 index 10ce34076..000000000 --- a/examples-testing/examples/webgl_loader_3ds.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as THREE from 'three'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { TDSLoader } from 'three/addons/loaders/TDSLoader.js'; - -let container, controls; -let camera, scene, renderer; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10); - camera.position.z = 2; - - scene = new THREE.Scene(); - scene.add(new THREE.AmbientLight(0xffffff, 3)); - - const directionalLight = new THREE.DirectionalLight(0xffeedd, 3); - directionalLight.position.set(0, 0, 2); - scene.add(directionalLight); - - //3ds files dont store normal maps - const normal = new THREE.TextureLoader().load('models/3ds/portalgun/textures/normal.jpg'); - - const loader = new TDSLoader(); - loader.setResourcePath('models/3ds/portalgun/textures/'); - loader.load('models/3ds/portalgun/portalgun.3ds', function (object) { - object.traverse(function (child) { - if (child.isMesh) { - child.material.specular.setScalar(0.1); - child.material.normalMap = normal; - } - }); - - scene.add(object); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - controls = new TrackballControls(camera, renderer.domElement); - - window.addEventListener('resize', resize); -} - -function resize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_3mf.ts b/examples-testing/examples/webgl_loader_3mf.ts deleted file mode 100644 index c31e32196..000000000 --- a/examples-testing/examples/webgl_loader_3mf.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, object, loader, controls; - -const params = { - asset: 'cube_gears', -}; - -const assets = ['cube_gears', 'facecolors', 'multipletextures', 'vertexcolors']; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x333333); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500); - - // Z is up for objects intended to be 3D printed. - - camera.up.set(0, 0, 1); - camera.position.set(-100, -250, 100); - scene.add(camera); - - controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.minDistance = 50; - controls.maxDistance = 400; - controls.enablePan = false; - controls.update(); - - scene.add(new THREE.AmbientLight(0xffffff, 0.6)); - - const light = new THREE.DirectionalLight(0xffffff, 2); - light.position.set(-1, -2.5, 1); - scene.add(light); - - const manager = new THREE.LoadingManager(); - - manager.onLoad = function () { - const aabb = new THREE.Box3().setFromObject(object); - const center = aabb.getCenter(new THREE.Vector3()); - - object.position.x += object.position.x - center.x; - object.position.y += object.position.y - center.y; - object.position.z += object.position.z - center.z; - - controls.reset(); - - scene.add(object); - render(); - }; - - loader = new ThreeMFLoader(manager); - loadAsset(params.asset); - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - gui.add(params, 'asset', assets).onChange(function (value) { - loadAsset(value); - }); -} - -function loadAsset(asset) { - loader.load('models/3mf/' + asset + '.3mf', function (group) { - if (object) { - object.traverse(function (child) { - if (child.material) child.material.dispose(); - if (child.material && child.material.map) child.material.map.dispose(); - if (child.geometry) child.geometry.dispose(); - }); - - scene.remove(object); - } - - // - - object = group; - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_3mf_materials.ts b/examples-testing/examples/webgl_loader_3mf_materials.ts deleted file mode 100644 index fcdd7308e..000000000 --- a/examples-testing/examples/webgl_loader_3mf_materials.ts +++ /dev/null @@ -1,106 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 10, 500); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500); - camera.position.set(-50, 40, 50); - scene.add(camera); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 3); - hemiLight.position.set(0, 100, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(-0, 40, 50); - dirLight.castShadow = true; - dirLight.shadow.camera.top = 50; - dirLight.shadow.camera.bottom = -25; - dirLight.shadow.camera.left = -25; - dirLight.shadow.camera.right = 25; - dirLight.shadow.camera.near = 0.1; - dirLight.shadow.camera.far = 200; - dirLight.shadow.mapSize.set(1024, 1024); - scene.add(dirLight); - - // scene.add( new THREE.CameraHelper( dirLight.shadow.camera ) ); - - // - - const manager = new THREE.LoadingManager(); - - const loader = new ThreeMFLoader(manager); - loader.load('./models/3mf/truck.3mf', function (object) { - object.rotation.set(-Math.PI / 2, 0, 0); // z-up conversion - - object.traverse(function (child) { - child.castShadow = true; - }); - - scene.add(object); - }); - - // - - manager.onLoad = function () { - render(); - }; - - // - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(1000, 1000), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }), - ); - ground.rotation.x = -Math.PI / 2; - ground.position.y = 11; - ground.receiveShadow = true; - scene.add(ground); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.minDistance = 50; - controls.maxDistance = 200; - controls.enablePan = false; - controls.target.set(0, 20, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); - - render(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_amf.ts b/examples-testing/examples/webgl_loader_amf.ts deleted file mode 100644 index ee576e04f..000000000 --- a/examples-testing/examples/webgl_loader_amf.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { AMFLoader } from 'three/addons/loaders/AMFLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x999999); - - scene.add(new THREE.AmbientLight(0x999999)); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500); - - // Z is up for objects intended to be 3D printed. - - camera.up.set(0, 0, 1); - camera.position.set(0, -9, 6); - - camera.add(new THREE.PointLight(0xffffff, 250)); - - scene.add(camera); - - const grid = new THREE.GridHelper(50, 50, 0xffffff, 0x555555); - grid.rotateOnAxis(new THREE.Vector3(1, 0, 0), 90 * (Math.PI / 180)); - scene.add(grid); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const loader = new AMFLoader(); - loader.load('./models/amf/rook.amf', function (amfobject) { - scene.add(amfobject); - render(); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.target.set(0, 0, 2); - controls.enableZoom = false; - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_bvh.ts b/examples-testing/examples/webgl_loader_bvh.ts deleted file mode 100644 index 0be3add4d..000000000 --- a/examples-testing/examples/webgl_loader_bvh.ts +++ /dev/null @@ -1,61 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { BVHLoader } from 'three/addons/loaders/BVHLoader.js'; - -const clock = new THREE.Clock(); - -let camera, controls, scene, renderer; -let mixer; - -init(); - -const loader = new BVHLoader(); -loader.load('models/bvh/pirouette.bvh', function (result) { - const skeletonHelper = new THREE.SkeletonHelper(result.skeleton.bones[0]); - - scene.add(result.skeleton.bones[0]); - scene.add(skeletonHelper); - - // play animation - mixer = new THREE.AnimationMixer(result.skeleton.bones[0]); - mixer.clipAction(result.clip).play(); -}); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 200, 300); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xeeeeee); - - scene.add(new THREE.GridHelper(400, 10)); - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 300; - controls.maxDistance = 700; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) mixer.update(delta); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_collada.ts b/examples-testing/examples/webgl_loader_collada.ts deleted file mode 100644 index 62588b698..000000000 --- a/examples-testing/examples/webgl_loader_collada.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; - -let container, stats, clock; -let camera, scene, renderer, elf; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); - camera.position.set(8, 10, 8); - camera.lookAt(0, 3, 0); - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - // loading manager - - const loadingManager = new THREE.LoadingManager(function () { - scene.add(elf); - }); - - // collada - - const loader = new ColladaLoader(loadingManager); - loader.load('./models/collada/elf/elf.dae', function (collada) { - elf = collada.scene; - }); - - // - - const ambientLight = new THREE.AmbientLight(0xffffff); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5); - directionalLight.position.set(1, 1, 0).normalize(); - scene.add(directionalLight); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - if (elf !== undefined) { - elf.rotation.z += delta * 0.5; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_collada_skinning.ts b/examples-testing/examples/webgl_loader_collada_skinning.ts deleted file mode 100644 index 5cb808b17..000000000 --- a/examples-testing/examples/webgl_loader_collada_skinning.ts +++ /dev/null @@ -1,97 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container, stats, clock, controls; -let camera, scene, renderer, mixer; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(15, 10, -15); - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - // collada - - const loader = new ColladaLoader(); - loader.load('./models/collada/stormtrooper/stormtrooper.dae', function (collada) { - const avatar = collada.scene; - const animations = avatar.animations; - - mixer = new THREE.AnimationMixer(avatar); - mixer.clipAction(animations[0]).play(); - - scene.add(avatar); - }); - - // - - const gridHelper = new THREE.GridHelper(10, 20, 0xc1c1c1, 0x8d8d8d); - scene.add(gridHelper); - - // - - const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 3); - directionalLight.position.set(1.5, 1, -1.5); - scene.add(directionalLight); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.screenSpacePanning = true; - controls.minDistance = 5; - controls.maxDistance = 40; - controls.target.set(0, 2, 0); - controls.update(); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - if (mixer !== undefined) { - mixer.update(delta); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_draco.ts b/examples-testing/examples/webgl_loader_draco.ts deleted file mode 100644 index c9947c693..000000000 --- a/examples-testing/examples/webgl_loader_draco.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as THREE from 'three'; - -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -let camera, scene, renderer; - -const container = document.querySelector('#container'); - -// Configure and create Draco decoder. -const dracoLoader = new DRACOLoader(); -dracoLoader.setDecoderPath('jsm/libs/draco/'); -dracoLoader.setDecoderConfig({ type: 'js' }); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 15); - camera.position.set(3, 0.25, 3); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x443333); - scene.fog = new THREE.Fog(0x443333, 1, 4); - - // Ground - const plane = new THREE.Mesh( - new THREE.PlaneGeometry(8, 8), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, specular: 0x101010 }), - ); - plane.rotation.x = -Math.PI / 2; - plane.position.y = 0.03; - plane.receiveShadow = true; - scene.add(plane); - - // Lights - const hemiLight = new THREE.HemisphereLight(0x8d7c7c, 0x494966, 3); - scene.add(hemiLight); - - const spotLight = new THREE.SpotLight(); - spotLight.intensity = 7; - spotLight.angle = Math.PI / 16; - spotLight.penumbra = 0.5; - spotLight.castShadow = true; - spotLight.position.set(-1, 1, 1); - scene.add(spotLight); - - dracoLoader.load('models/draco/bunny.drc', function (geometry) { - geometry.computeVertexNormals(); - - const material = new THREE.MeshStandardMaterial({ color: 0xa5a5a5 }); - const mesh = new THREE.Mesh(geometry, material); - mesh.castShadow = true; - mesh.receiveShadow = true; - scene.add(mesh); - - // Release decoder resources. - dracoLoader.dispose(); - }); - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const timer = Date.now() * 0.0003; - - camera.position.x = Math.sin(timer) * 0.5; - camera.position.z = Math.cos(timer) * 0.5; - camera.lookAt(0, 0.1, 0); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_fbx.ts b/examples-testing/examples/webgl_loader_fbx.ts deleted file mode 100644 index 3b157a222..000000000 --- a/examples-testing/examples/webgl_loader_fbx.ts +++ /dev/null @@ -1,162 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const manager = new THREE.LoadingManager(); - -let camera, scene, renderer, stats, object, loader, guiMorphsFolder; -let mixer; - -const clock = new THREE.Clock(); - -const params = { - asset: 'Samba Dancing', -}; - -const assets = ['Samba Dancing', 'morph_test']; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(100, 200, 300); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000); - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 5); - hemiLight.position.set(0, 200, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 5); - dirLight.position.set(0, 200, 100); - dirLight.castShadow = true; - dirLight.shadow.camera.top = 180; - dirLight.shadow.camera.bottom = -100; - dirLight.shadow.camera.left = -120; - dirLight.shadow.camera.right = 120; - scene.add(dirLight); - - // scene.add( new THREE.CameraHelper( dirLight.shadow.camera ) ); - - // ground - const mesh = new THREE.Mesh( - new THREE.PlaneGeometry(2000, 2000), - new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false }), - ); - mesh.rotation.x = -Math.PI / 2; - mesh.receiveShadow = true; - scene.add(mesh); - - const grid = new THREE.GridHelper(2000, 20, 0x000000, 0x000000); - grid.material.opacity = 0.2; - grid.material.transparent = true; - scene.add(grid); - - loader = new FBXLoader(manager); - loadAsset(params.asset); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 100, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); - - // stats - stats = new Stats(); - container.appendChild(stats.dom); - - const gui = new GUI(); - gui.add(params, 'asset', assets).onChange(function (value) { - loadAsset(value); - }); - - guiMorphsFolder = gui.addFolder('Morphs').hide(); -} - -function loadAsset(asset) { - loader.load('models/fbx/' + asset + '.fbx', function (group) { - if (object) { - object.traverse(function (child) { - if (child.material) { - const materials = Array.isArray(child.material) ? child.material : [child.material]; - materials.forEach(material => { - if (material.map) material.map.dispose(); - material.dispose(); - }); - } - - if (child.geometry) child.geometry.dispose(); - }); - - scene.remove(object); - } - - // - - object = group; - - if (object.animations && object.animations.length) { - mixer = new THREE.AnimationMixer(object); - - const action = mixer.clipAction(object.animations[0]); - action.play(); - } else { - mixer = null; - } - - guiMorphsFolder.children.forEach(child => child.destroy()); - guiMorphsFolder.hide(); - - object.traverse(function (child) { - if (child.isMesh) { - child.castShadow = true; - child.receiveShadow = true; - - if (child.morphTargetDictionary) { - guiMorphsFolder.show(); - const meshFolder = guiMorphsFolder.addFolder(child.name || child.uuid); - Object.keys(child.morphTargetDictionary).forEach(key => { - meshFolder.add(child.morphTargetInfluences, child.morphTargetDictionary[key], 0, 1, 0.01); - }); - } - } - }); - - scene.add(object); - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const delta = clock.getDelta(); - - if (mixer) mixer.update(delta); - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_loader_fbx_nurbs.ts b/examples-testing/examples/webgl_loader_fbx_nurbs.ts deleted file mode 100644 index f2e45bcb5..000000000 --- a/examples-testing/examples/webgl_loader_fbx_nurbs.ts +++ /dev/null @@ -1,61 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(2, 18, 28); - - scene = new THREE.Scene(); - - // grid - const gridHelper = new THREE.GridHelper(28, 28, 0x303030, 0x303030); - scene.add(gridHelper); - - // stats - stats = new Stats(); - container.appendChild(stats.dom); - - // model - const loader = new FBXLoader(); - loader.load('models/fbx/nurbs.fbx', function (object) { - scene.add(object); - }); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 12, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_loader_gcode.ts b/examples-testing/examples/webgl_loader_gcode.ts deleted file mode 100644 index 6fd3e149d..000000000 --- a/examples-testing/examples/webgl_loader_gcode.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GCodeLoader } from 'three/addons/loaders/GCodeLoader.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 70); - - scene = new THREE.Scene(); - - const loader = new GCodeLoader(); - loader.load('models/gcode/benchy.gcode', function (object) { - object.position.set(-100, -20, 100); - scene.add(object); - - render(); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 10; - controls.maxDistance = 100; - - window.addEventListener('resize', resize); -} - -function resize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf.ts b/examples-testing/examples/webgl_loader_gltf.ts deleted file mode 100644 index e1b0adc51..000000000 --- a/examples-testing/examples/webgl_loader_gltf.ts +++ /dev/null @@ -1,74 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - render(); - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', async function (gltf) { - const model = gltf.scene; - - // wait until the model can be added to the scene without blocking due to shader compilation - - await renderer.compileAsync(model, camera, scene); - - scene.add(model); - - render(); - }); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 2; - controls.maxDistance = 10; - controls.target.set(0, 0, -0.2); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_anisotropy.ts b/examples-testing/examples/webgl_loader_gltf_anisotropy.ts deleted file mode 100644 index 6e240a272..000000000 --- a/examples-testing/examples/webgl_loader_gltf_anisotropy.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let renderer, scene, camera, controls; - -init(); - -async function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1.35; - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.set(-0.35, -0.2, 0.35); - - controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, -0.08, 0.11); - controls.minDistance = 0.1; - controls.maxDistance = 2; - controls.addEventListener('change', render); - controls.update(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - const gltfLoader = new GLTFLoader().setPath('models/gltf/'); - - const [texture, gltf] = await Promise.all([ - rgbeLoader.loadAsync('royal_esplanade_1k.hdr'), - gltfLoader.loadAsync('AnisotropyBarnLamp.glb'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.backgroundBlurriness = 0.5; - scene.environment = texture; - - // model - - scene.add(gltf.scene); - - render(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_avif.ts b/examples-testing/examples/webgl_loader_gltf_avif.ts deleted file mode 100644 index 37d63859e..000000000 --- a/examples-testing/examples/webgl_loader_gltf_avif.ts +++ /dev/null @@ -1,61 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(1.5, 4, 9); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf6eedc); - - // - - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('jsm/libs/draco/gltf/'); - - const loader = new GLTFLoader(); - loader.setDRACOLoader(dracoLoader); - loader.setPath('models/gltf/AVIFTest/'); - loader.load('forest_house.glb', function (gltf) { - scene.add(gltf.scene); - - render(); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.target.set(0, 2, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_compressed.ts b/examples-testing/examples/webgl_loader_gltf_compressed.ts deleted file mode 100644 index 3bdcea8ec..000000000 --- a/examples-testing/examples/webgl_loader_gltf_compressed.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as THREE from 'three'; - -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; -import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(0, 100, 0); - - const environment = new RoomEnvironment(); - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xbbbbbb); - scene.environment = pmremGenerator.fromScene(environment).texture; - environment.dispose(); - - const grid = new THREE.GridHelper(500, 10, 0xffffff, 0xffffff); - grid.material.opacity = 0.5; - grid.material.depthWrite = false; - grid.material.transparent = true; - scene.add(grid); - - const ktx2Loader = new KTX2Loader().setTranscoderPath('jsm/libs/basis/').detectSupport(renderer); - - const loader = new GLTFLoader().setPath('models/gltf/'); - loader.setKTX2Loader(ktx2Loader); - loader.setMeshoptDecoder(MeshoptDecoder); - loader.load('coffeemat.glb', function (gltf) { - // coffeemat.glb was produced from the source scene using gltfpack: - // gltfpack -i coffeemat/scene.gltf -o coffeemat.glb -cc -tc - // The resulting model uses EXT_meshopt_compression (for geometry) and KHR_texture_basisu (for texture compression using ETC1S/BasisLZ) - - gltf.scene.position.y = 8; - - scene.add(gltf.scene); - - render(); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 400; - controls.maxDistance = 1000; - controls.target.set(10, 90, -16); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_dispersion.ts b/examples-testing/examples/webgl_loader_gltf_dispersion.ts deleted file mode 100644 index 100badcab..000000000 --- a/examples-testing/examples/webgl_loader_gltf_dispersion.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - -let camera, scene, renderer; - -init().then(render); - -async function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 5); - camera.position.set(0.1, 0.05, 0.15); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.NeutralToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - const environment = new RoomEnvironment(); - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene = new THREE.Scene(); - scene.backgroundBlurriness = 0.5; - - const env = pmremGenerator.fromScene(environment).texture; - scene.background = env; - scene.environment = env; - environment.dispose(); - - const loader = new GLTFLoader(); - const gltf = await loader.loadAsync('models/gltf/DispersionTest.glb'); - - scene.add(gltf.scene); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 0.1; - controls.maxDistance = 10; - controls.target.set(0, 0, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_instancing.ts b/examples-testing/examples/webgl_loader_gltf_instancing.ts deleted file mode 100644 index 5d23e7750..000000000 --- a/examples-testing/examples/webgl_loader_gltf_instancing.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-0.9, 0.41, -0.89); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - render(); - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF-instancing/'); - loader.load('DamagedHelmetGpuInstancing.gltf', function (gltf) { - scene.add(gltf.scene); - - render(); - }); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 0.2; - controls.maxDistance = 10; - controls.target.set(0, 0.25, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_iridescence.ts b/examples-testing/examples/webgl_loader_gltf_iridescence.ts deleted file mode 100644 index eb0f8d914..000000000 --- a/examples-testing/examples/webgl_loader_gltf_iridescence.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let renderer, scene, camera, controls; - -init().catch(function (err) { - console.error(err); -}); - -async function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setAnimationLoop(animate); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.05, 20); - camera.position.set(0.35, 0.05, 0.35); - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = -0.5; - controls.target.set(0, 0.2, 0); - controls.update(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - - const gltfLoader = new GLTFLoader().setPath('models/gltf/'); - - const [texture, gltf] = await Promise.all([ - rgbeLoader.loadAsync('venice_sunset_1k.hdr'), - gltfLoader.loadAsync('IridescenceLamp.glb'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - scene.add(gltf.scene); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_sheen.ts b/examples-testing/examples/webgl_loader_gltf_sheen.ts deleted file mode 100644 index bd258d5c1..000000000 --- a/examples-testing/examples/webgl_loader_gltf_sheen.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, controls; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 20); - camera.position.set(-0.75, 0.7, 1.25); - - scene = new THREE.Scene(); - - // model - - new GLTFLoader().setPath('models/gltf/').load('SheenChair.glb', function (gltf) { - scene.add(gltf.scene); - - const object = gltf.scene.getObjectByName('SheenChair_fabric'); - - const gui = new GUI(); - - gui.add(object.material, 'sheen', 0, 1); - gui.open(); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - const environment = new RoomEnvironment(); - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene.background = new THREE.Color(0xbbbbbb); - scene.environment = pmremGenerator.fromScene(environment).texture; - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 1; - controls.maxDistance = 10; - controls.target.set(0, 0.35, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - controls.update(); // required if damping enabled - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_gltf_transmission.ts b/examples-testing/examples/webgl_loader_gltf_transmission.ts deleted file mode 100644 index 87a47d2c0..000000000 --- a/examples-testing/examples/webgl_loader_gltf_transmission.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -let camera, scene, renderer, controls, clock, mixer; - -init(); - -function init() { - clock = new THREE.Clock(); - - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(0, 0.4, 0.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.backgroundBlurriness = 0.35; - - scene.environment = texture; - - // model - - new GLTFLoader() - .setPath('models/gltf/') - .setDRACOLoader(new DRACOLoader().setDecoderPath('jsm/libs/draco/gltf/')) - .load('IridescentDishWithOlives.glb', function (gltf) { - mixer = new THREE.AnimationMixer(gltf.scene); - mixer.clipAction(gltf.animations[0]).play(); - - scene.add(gltf.scene); - }); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = -0.75; - controls.enableDamping = true; - controls.minDistance = 0.5; - controls.maxDistance = 1; - controls.target.set(0, 0.1, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - if (mixer) mixer.update(clock.getDelta()); - - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_imagebitmap.ts b/examples-testing/examples/webgl_loader_imagebitmap.ts deleted file mode 100644 index 1049e9857..000000000 --- a/examples-testing/examples/webgl_loader_imagebitmap.ts +++ /dev/null @@ -1,109 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; -let group, cubes; - -init(); - -function addImageBitmap() { - new THREE.ImageBitmapLoader().load( - 'textures/planets/earth_atmos_2048.jpg?' + performance.now(), - function (imageBitmap) { - const texture = new THREE.CanvasTexture(imageBitmap); - texture.colorSpace = THREE.SRGBColorSpace; - const material = new THREE.MeshBasicMaterial({ map: texture }); - - /* ImageBitmap should be disposed when done with it - Can't be done until it's actually uploaded to WebGLTexture */ - - // imageBitmap.close(); - - addCube(material); - }, - function (p) { - console.log(p); - }, - function (e) { - console.log(e); - }, - ); -} - -function addImage() { - new THREE.ImageLoader() - .setCrossOrigin('*') - .load('textures/planets/earth_atmos_2048.jpg?' + performance.now(), function (image) { - const texture = new THREE.CanvasTexture(image); - texture.colorSpace = THREE.SRGBColorSpace; - const material = new THREE.MeshBasicMaterial({ color: 0xff8888, map: texture }); - addCube(material); - }); -} - -const geometry = new THREE.BoxGeometry(); - -function addCube(material) { - const cube = new THREE.Mesh(geometry, material); - cube.position.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1); - cube.rotation.set(Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI); - cubes.add(cube); -} - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 1500); - camera.position.set(0, 4, 7); - camera.lookAt(0, 0, 0); - - // SCENE - - scene = new THREE.Scene(); - - // - - group = new THREE.Group(); - scene.add(group); - - group.add(new THREE.GridHelper(4, 12, 0x888888, 0x444444)); - - cubes = new THREE.Group(); - group.add(cubes); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // TESTS - - setTimeout(addImage, 300); - setTimeout(addImage, 600); - setTimeout(addImage, 900); - setTimeout(addImageBitmap, 1300); - setTimeout(addImageBitmap, 1600); - setTimeout(addImageBitmap, 1900); - - // EVENTS - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - group.rotation.y = performance.now() / 3000; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_kmz.ts b/examples-testing/examples/webgl_loader_kmz.ts deleted file mode 100644 index f93555e41..000000000 --- a/examples-testing/examples/webgl_loader_kmz.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { KMZLoader } from 'three/addons/loaders/KMZLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x999999); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0.5, 1.0, 0.5).normalize(); - - scene.add(light); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500); - - camera.position.y = 5; - camera.position.z = 10; - - scene.add(camera); - - const grid = new THREE.GridHelper(50, 50, 0xffffff, 0x7b7b7b); - scene.add(grid); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - const loader = new KMZLoader(); - loader.load('./models/kmz/Box.kmz', function (kmz) { - kmz.scene.position.y = 0.5; - scene.add(kmz.scene); - render(); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_lwo.ts b/examples-testing/examples/webgl_loader_lwo.ts deleted file mode 100644 index fb10c8340..000000000 --- a/examples-testing/examples/webgl_loader_lwo.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { LWOLoader } from 'three/addons/loaders/LWOLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 200); - camera.position.set(0.7, 14.6, -43.2); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xa0a0a0); - - const ambientLight = new THREE.AmbientLight(0xbbbbbb); - scene.add(ambientLight); - - const light1 = new THREE.DirectionalLight(0xc1c1c1, 3); - light1.position.set(0, 200, -100); - scene.add(light1); - - const grid = new THREE.GridHelper(200, 20, 0x000000, 0x000000); - grid.material.opacity = 0.3; - grid.material.transparent = true; - scene.add(grid); - - const loader = new LWOLoader(); - loader.load('models/lwo/Objects/LWO3/Demo.lwo', function (object) { - const phong = object.meshes[0]; - phong.position.set(2, 12, 0); - - const standard = object.meshes[1]; - standard.position.set(-2, 12, 0); - - const rocket = object.meshes[2]; - rocket.position.set(0, 10.5, 1); - - scene.add(phong, standard, rocket); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(-1.33, 10, 6.7); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_md2_control.ts b/examples-testing/examples/webgl_loader_md2_control.ts deleted file mode 100644 index 683e4c2ad..000000000 --- a/examples-testing/examples/webgl_loader_md2_control.ts +++ /dev/null @@ -1,289 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { MD2CharacterComplex } from 'three/addons/misc/MD2CharacterComplex.js'; -import { Gyroscope } from 'three/addons/misc/Gyroscope.js'; - -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; - -let container, stats; -let camera, scene, renderer; - -const characters = []; -let nCharacters = 0; - -let cameraControls; - -const controls = { - moveForward: false, - moveBackward: false, - moveLeft: false, - moveRight: false, -}; - -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 4000); - camera.position.set(0, 150, 1300); - - // SCENE - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - scene.fog = new THREE.Fog(0xffffff, 1000, 4000); - - scene.add(camera); - - // LIGHTS - - scene.add(new THREE.AmbientLight(0x666666, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 7); - light.position.set(200, 450, 500); - - light.castShadow = true; - - light.shadow.mapSize.width = 1024; - light.shadow.mapSize.height = 512; - - light.shadow.camera.near = 100; - light.shadow.camera.far = 1200; - - light.shadow.camera.left = -1000; - light.shadow.camera.right = 1000; - light.shadow.camera.top = 350; - light.shadow.camera.bottom = -350; - - scene.add(light); - // scene.add( new THREE.CameraHelper( light.shadow.camera ) ); - - // GROUND - - const gt = new THREE.TextureLoader().load('textures/terrain/grasslight-big.jpg'); - const gg = new THREE.PlaneGeometry(16000, 16000); - const gm = new THREE.MeshPhongMaterial({ color: 0xffffff, map: gt }); - - const ground = new THREE.Mesh(gg, gm); - ground.rotation.x = -Math.PI / 2; - ground.material.map.repeat.set(64, 64); - ground.material.map.wrapS = THREE.RepeatWrapping; - ground.material.map.wrapT = THREE.RepeatWrapping; - ground.material.map.colorSpace = THREE.SRGBColorSpace; - // note that because the ground does not cast a shadow, .castShadow is left false - ground.receiveShadow = true; - - scene.add(ground); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - - // STATS - - stats = new Stats(); - container.appendChild(stats.dom); - - // EVENTS - - window.addEventListener('resize', onWindowResize); - document.addEventListener('keydown', onKeyDown); - document.addEventListener('keyup', onKeyUp); - - // CONTROLS - - cameraControls = new OrbitControls(camera, renderer.domElement); - cameraControls.target.set(0, 50, 0); - cameraControls.update(); - - // CHARACTER - - const configOgro = { - baseUrl: 'models/md2/ogro/', - - body: 'ogro.md2', - skins: [ - 'grok.jpg', - 'ogrobase.png', - 'arboshak.png', - 'ctf_r.png', - 'ctf_b.png', - 'darkam.png', - 'freedom.png', - 'gib.png', - 'gordogh.png', - 'igdosh.png', - 'khorne.png', - 'nabogro.png', - 'sharokh.png', - ], - weapons: [['weapon.md2', 'weapon.jpg']], - animations: { - move: 'run', - idle: 'stand', - jump: 'jump', - attack: 'attack', - crouchMove: 'cwalk', - crouchIdle: 'cstand', - crouchAttach: 'crattack', - }, - - walkSpeed: 350, - crouchSpeed: 175, - }; - - const nRows = 1; - const nSkins = configOgro.skins.length; - - nCharacters = nSkins * nRows; - - for (let i = 0; i < nCharacters; i++) { - const character = new MD2CharacterComplex(); - character.scale = 3; - character.controls = controls; - characters.push(character); - } - - const baseCharacter = new MD2CharacterComplex(); - baseCharacter.scale = 3; - - baseCharacter.onLoadComplete = function () { - let k = 0; - - for (let j = 0; j < nRows; j++) { - for (let i = 0; i < nSkins; i++) { - const cloneCharacter = characters[k]; - - cloneCharacter.shareParts(baseCharacter); - - // cast and receive shadows - cloneCharacter.enableShadows(true); - - cloneCharacter.setWeapon(0); - cloneCharacter.setSkin(i); - - cloneCharacter.root.position.x = (i - nSkins / 2) * 150; - cloneCharacter.root.position.z = j * 250; - - scene.add(cloneCharacter.root); - - k++; - } - } - - const gyro = new Gyroscope(); - gyro.add(camera); - gyro.add(light, light.target); - - characters[Math.floor(nSkins / 2)].root.add(gyro); - }; - - baseCharacter.loadParts(configOgro); -} - -// EVENT HANDLERS - -function onWindowResize() { - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); -} - -function onKeyDown(event) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': - controls.moveForward = true; - break; - - case 'ArrowDown': - case 'KeyS': - controls.moveBackward = true; - break; - - case 'ArrowLeft': - case 'KeyA': - controls.moveLeft = true; - break; - - case 'ArrowRight': - case 'KeyD': - controls.moveRight = true; - break; - - // case 'KeyC': controls.crouch = true; break; - // case 'Space': controls.jump = true; break; - // case 'ControlLeft': - // case 'ControlRight': controls.attack = true; break; - } -} - -function onKeyUp(event) { - switch (event.code) { - case 'ArrowUp': - case 'KeyW': - controls.moveForward = false; - break; - - case 'ArrowDown': - case 'KeyS': - controls.moveBackward = false; - break; - - case 'ArrowLeft': - case 'KeyA': - controls.moveLeft = false; - break; - - case 'ArrowRight': - case 'KeyD': - controls.moveRight = false; - break; - - // case 'KeyC': controls.crouch = false; break; - // case 'Space': controls.jump = false; break; - // case 'ControlLeft': - // case 'ControlRight': controls.attack = false; break; - } -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - for (let i = 0; i < nCharacters; i++) { - characters[i].update(delta); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_mdd.ts b/examples-testing/examples/webgl_loader_mdd.ts deleted file mode 100644 index 5b13e8f4b..000000000 --- a/examples-testing/examples/webgl_loader_mdd.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as THREE from 'three'; - -import { MDDLoader } from 'three/addons/loaders/MDDLoader.js'; - -let camera, scene, renderer, mixer, clock; - -init(); - -function init() { - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(8, 8, 8); - camera.lookAt(scene.position); - - clock = new THREE.Clock(); - - // - - const loader = new MDDLoader(); - loader.load('models/mdd/cube.mdd', function (result) { - const morphTargets = result.morphTargets; - const clip = result.clip; - // clip.optimize(); // optional - - const geometry = new THREE.BoxGeometry(); - geometry.morphAttributes.position = morphTargets; // apply morph targets - - const material = new THREE.MeshNormalMaterial(); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - mixer = new THREE.AnimationMixer(mesh); - mixer.clipAction(clip).play(); // use clip - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) mixer.update(delta); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_obj.ts b/examples-testing/examples/webgl_loader_obj.ts deleted file mode 100644 index f61eeb758..000000000 --- a/examples-testing/examples/webgl_loader_obj.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as THREE from 'three'; - -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -let object; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 20); - camera.position.z = 2.5; - - // scene - - scene = new THREE.Scene(); - - const ambientLight = new THREE.AmbientLight(0xffffff); - scene.add(ambientLight); - - const pointLight = new THREE.PointLight(0xffffff, 15); - camera.add(pointLight); - scene.add(camera); - - // manager - - function loadModel() { - object.traverse(function (child) { - if (child.isMesh) child.material.map = texture; - }); - - object.position.y = -0.95; - object.scale.setScalar(0.01); - scene.add(object); - - render(); - } - - const manager = new THREE.LoadingManager(loadModel); - - // texture - - const textureLoader = new THREE.TextureLoader(manager); - const texture = textureLoader.load('textures/uv_grid_opengl.jpg', render); - texture.colorSpace = THREE.SRGBColorSpace; - - // model - - function onProgress(xhr) { - if (xhr.lengthComputable) { - const percentComplete = (xhr.loaded / xhr.total) * 100; - console.log('model ' + percentComplete.toFixed(2) + '% downloaded'); - } - } - - function onError() {} - - const loader = new OBJLoader(manager); - loader.load( - 'models/obj/male02/male02.obj', - function (obj) { - object = obj; - }, - onProgress, - onError, - ); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 5; - controls.addEventListener('change', render); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_obj_mtl.ts b/examples-testing/examples/webgl_loader_obj_mtl.ts deleted file mode 100644 index 4308aee7b..000000000 --- a/examples-testing/examples/webgl_loader_obj_mtl.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as THREE from 'three'; - -import { MTLLoader } from 'three/addons/loaders/MTLLoader.js'; -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 20); - camera.position.z = 2.5; - - // scene - - scene = new THREE.Scene(); - - const ambientLight = new THREE.AmbientLight(0xffffff); - scene.add(ambientLight); - - const pointLight = new THREE.PointLight(0xffffff, 15); - camera.add(pointLight); - scene.add(camera); - - // model - - const onProgress = function (xhr) { - if (xhr.lengthComputable) { - const percentComplete = (xhr.loaded / xhr.total) * 100; - console.log(percentComplete.toFixed(2) + '% downloaded'); - } - }; - - new MTLLoader().setPath('models/obj/male02/').load('male02.mtl', function (materials) { - materials.preload(); - - new OBJLoader() - .setMaterials(materials) - .setPath('models/obj/male02/') - .load( - 'male02.obj', - function (object) { - object.position.y = -0.95; - object.scale.setScalar(0.01); - scene.add(object); - }, - onProgress, - ); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 5; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_pcd.ts b/examples-testing/examples/webgl_loader_pcd.ts deleted file mode 100644 index d69e3fa2a..000000000 --- a/examples-testing/examples/webgl_loader_pcd.ts +++ /dev/null @@ -1,65 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { PCDLoader } from 'three/addons/loaders/PCDLoader.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.01, 40); - camera.position.set(0, 0, 1); - scene.add(camera); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 0.5; - controls.maxDistance = 10; - - //scene.add( new THREE.AxesHelper( 1 ) ); - - const loader = new PCDLoader(); - loader.load('./models/pcd/binary/Zaghetto.pcd', function (points) { - points.geometry.center(); - points.geometry.rotateX(Math.PI); - points.name = 'Zaghetto.pcd'; - scene.add(points); - - // - - const gui = new GUI(); - - gui.add(points.material, 'size', 0.001, 0.01).onChange(render); - gui.addColor(points.material, 'color').onChange(render); - gui.open(); - - // - - render(); - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_pdb.ts b/examples-testing/examples/webgl_loader_pdb.ts deleted file mode 100644 index b560efa73..000000000 --- a/examples-testing/examples/webgl_loader_pdb.ts +++ /dev/null @@ -1,208 +0,0 @@ -import * as THREE from 'three'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { PDBLoader } from 'three/addons/loaders/PDBLoader.js'; -import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, labelRenderer; -let controls; - -let root; - -const MOLECULES = { - Ethanol: 'ethanol.pdb', - Aspirin: 'aspirin.pdb', - Caffeine: 'caffeine.pdb', - Nicotine: 'nicotine.pdb', - LSD: 'lsd.pdb', - Cocaine: 'cocaine.pdb', - Cholesterol: 'cholesterol.pdb', - Lycopene: 'lycopene.pdb', - Glucose: 'glucose.pdb', - 'Aluminium oxide': 'Al2O3.pdb', - Cubane: 'cubane.pdb', - Copper: 'cu.pdb', - Fluorite: 'caf2.pdb', - Salt: 'nacl.pdb', - 'YBCO superconductor': 'ybco.pdb', - Buckyball: 'buckyball.pdb', - Graphite: 'graphite.pdb', -}; - -const params = { - molecule: 'caffeine.pdb', -}; - -const loader = new PDBLoader(); -const offset = new THREE.Vector3(); - -init(); - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.z = 1000; - scene.add(camera); - - const light1 = new THREE.DirectionalLight(0xffffff, 2.5); - light1.position.set(1, 1, 1); - scene.add(light1); - - const light2 = new THREE.DirectionalLight(0xffffff, 1.5); - light2.position.set(-1, -1, 1); - scene.add(light2); - - root = new THREE.Group(); - scene.add(root); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.getElementById('container').appendChild(renderer.domElement); - - labelRenderer = new CSS2DRenderer(); - labelRenderer.setSize(window.innerWidth, window.innerHeight); - labelRenderer.domElement.style.position = 'absolute'; - labelRenderer.domElement.style.top = '0px'; - labelRenderer.domElement.style.pointerEvents = 'none'; - document.getElementById('container').appendChild(labelRenderer.domElement); - - // - - controls = new TrackballControls(camera, renderer.domElement); - controls.minDistance = 500; - controls.maxDistance = 2000; - - // - - loadMolecule(params.molecule); - - // - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - - gui.add(params, 'molecule', MOLECULES).onChange(loadMolecule); - gui.open(); -} - -// - -function loadMolecule(model) { - const url = 'models/pdb/' + model; - - while (root.children.length > 0) { - const object = root.children[0]; - object.parent.remove(object); - } - - loader.load(url, function (pdb) { - const geometryAtoms = pdb.geometryAtoms; - const geometryBonds = pdb.geometryBonds; - const json = pdb.json; - - const boxGeometry = new THREE.BoxGeometry(1, 1, 1); - const sphereGeometry = new THREE.IcosahedronGeometry(1, 3); - - geometryAtoms.computeBoundingBox(); - geometryAtoms.boundingBox.getCenter(offset).negate(); - - geometryAtoms.translate(offset.x, offset.y, offset.z); - geometryBonds.translate(offset.x, offset.y, offset.z); - - let positions = geometryAtoms.getAttribute('position'); - const colors = geometryAtoms.getAttribute('color'); - - const position = new THREE.Vector3(); - const color = new THREE.Color(); - - for (let i = 0; i < positions.count; i++) { - position.x = positions.getX(i); - position.y = positions.getY(i); - position.z = positions.getZ(i); - - color.r = colors.getX(i); - color.g = colors.getY(i); - color.b = colors.getZ(i); - - const material = new THREE.MeshPhongMaterial({ color: color }); - - const object = new THREE.Mesh(sphereGeometry, material); - object.position.copy(position); - object.position.multiplyScalar(75); - object.scale.multiplyScalar(25); - root.add(object); - - const atom = json.atoms[i]; - - const text = document.createElement('div'); - text.className = 'label'; - text.style.color = 'rgb(' + atom[3][0] + ',' + atom[3][1] + ',' + atom[3][2] + ')'; - text.textContent = atom[4]; - - const label = new CSS2DObject(text); - label.position.copy(object.position); - root.add(label); - } - - positions = geometryBonds.getAttribute('position'); - - const start = new THREE.Vector3(); - const end = new THREE.Vector3(); - - for (let i = 0; i < positions.count; i += 2) { - start.x = positions.getX(i); - start.y = positions.getY(i); - start.z = positions.getZ(i); - - end.x = positions.getX(i + 1); - end.y = positions.getY(i + 1); - end.z = positions.getZ(i + 1); - - start.multiplyScalar(75); - end.multiplyScalar(75); - - const object = new THREE.Mesh(boxGeometry, new THREE.MeshPhongMaterial({ color: 0xffffff })); - object.position.copy(start); - object.position.lerp(end, 0.5); - object.scale.set(5, 5, start.distanceTo(end)); - object.lookAt(end); - root.add(object); - } - }); -} - -// - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - labelRenderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - - const time = Date.now() * 0.0004; - - root.rotation.x = time; - root.rotation.y = time * 0.7; - - render(); -} - -function render() { - renderer.render(scene, camera); - labelRenderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_ply.ts b/examples-testing/examples/webgl_loader_ply.ts deleted file mode 100644 index 0f4042b7d..000000000 --- a/examples-testing/examples/webgl_loader_ply.ts +++ /dev/null @@ -1,146 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; - -let container, stats; - -let camera, cameraTarget, scene, renderer; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 15); - camera.position.set(3, 0.15, 3); - - cameraTarget = new THREE.Vector3(0, -0.1, 0); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x72645b); - scene.fog = new THREE.Fog(0x72645b, 2, 15); - - // Ground - - const plane = new THREE.Mesh( - new THREE.PlaneGeometry(40, 40), - new THREE.MeshPhongMaterial({ color: 0xcbcbcb, specular: 0x474747 }), - ); - plane.rotation.x = -Math.PI / 2; - plane.position.y = -0.5; - scene.add(plane); - - plane.receiveShadow = true; - - // PLY file - - const loader = new PLYLoader(); - loader.load('./models/ply/ascii/dolphins.ply', function (geometry) { - geometry.computeVertexNormals(); - - const material = new THREE.MeshStandardMaterial({ color: 0x009cff, flatShading: true }); - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.y = -0.2; - mesh.position.z = 0.3; - mesh.rotation.x = -Math.PI / 2; - mesh.scale.multiplyScalar(0.001); - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - }); - - loader.load('./models/ply/binary/Lucy100k.ply', function (geometry) { - geometry.computeVertexNormals(); - - const material = new THREE.MeshStandardMaterial({ color: 0x009cff, flatShading: true }); - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = -0.2; - mesh.position.y = -0.02; - mesh.position.z = -0.2; - mesh.scale.multiplyScalar(0.0006); - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - }); - - // Lights - - scene.add(new THREE.HemisphereLight(0x8d7c7c, 0x494966, 3)); - - addShadowedLight(1, 1, 1, 0xffffff, 3.5); - addShadowedLight(0.5, 1, -1, 0xffd500, 3); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - renderer.shadowMap.enabled = true; - - container.appendChild(renderer.domElement); - - // stats - - stats = new Stats(); - container.appendChild(stats.dom); - - // resize - - window.addEventListener('resize', onWindowResize); -} - -function addShadowedLight(x, y, z, color, intensity) { - const directionalLight = new THREE.DirectionalLight(color, intensity); - directionalLight.position.set(x, y, z); - scene.add(directionalLight); - - directionalLight.castShadow = true; - - const d = 1; - directionalLight.shadow.camera.left = -d; - directionalLight.shadow.camera.right = d; - directionalLight.shadow.camera.top = d; - directionalLight.shadow.camera.bottom = -d; - - directionalLight.shadow.camera.near = 1; - directionalLight.shadow.camera.far = 4; - - directionalLight.shadow.mapSize.width = 1024; - directionalLight.shadow.mapSize.height = 1024; - - directionalLight.shadow.bias = -0.001; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const timer = Date.now() * 0.0005; - - camera.position.x = Math.sin(timer) * 2.5; - camera.position.z = Math.cos(timer) * 2.5; - - camera.lookAt(cameraTarget); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_svg.ts b/examples-testing/examples/webgl_loader_svg.ts deleted file mode 100644 index 45361b92f..000000000 --- a/examples-testing/examples/webgl_loader_svg.ts +++ /dev/null @@ -1,193 +0,0 @@ -import * as THREE from 'three'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { SVGLoader } from 'three/addons/loaders/SVGLoader.js'; - -let renderer, scene, camera, gui, guiData; - -init(); - -// - -function init() { - const container = document.getElementById('container'); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 200); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - container.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.screenSpacePanning = true; - - // - - window.addEventListener('resize', onWindowResize); - - guiData = { - currentURL: 'models/svg/tiger.svg', - drawFillShapes: true, - drawStrokes: true, - fillShapesWireframe: false, - strokesWireframe: false, - }; - - loadSVG(guiData.currentURL); - - createGUI(); -} - -function createGUI() { - if (gui) gui.destroy(); - - gui = new GUI(); - - gui.add(guiData, 'currentURL', { - Tiger: 'models/svg/tiger.svg', - 'Joins and caps': 'models/svg/lineJoinsAndCaps.svg', - Hexagon: 'models/svg/hexagon.svg', - Energy: 'models/svg/energy.svg', - 'Test 1': 'models/svg/tests/1.svg', - 'Test 2': 'models/svg/tests/2.svg', - 'Test 3': 'models/svg/tests/3.svg', - 'Test 4': 'models/svg/tests/4.svg', - 'Test 5': 'models/svg/tests/5.svg', - 'Test 6': 'models/svg/tests/6.svg', - 'Test 7': 'models/svg/tests/7.svg', - 'Test 8': 'models/svg/tests/8.svg', - 'Test 9': 'models/svg/tests/9.svg', - Units: 'models/svg/tests/units.svg', - Ordering: 'models/svg/tests/ordering.svg', - Defs: 'models/svg/tests/testDefs/Svg-defs.svg', - Defs2: 'models/svg/tests/testDefs/Svg-defs2.svg', - Defs3: 'models/svg/tests/testDefs/Wave-defs.svg', - Defs4: 'models/svg/tests/testDefs/defs4.svg', - Defs5: 'models/svg/tests/testDefs/defs5.svg', - 'Style CSS inside defs': 'models/svg/style-css-inside-defs.svg', - 'Multiple CSS classes': 'models/svg/multiple-css-classes.svg', - 'Zero Radius': 'models/svg/zero-radius.svg', - 'Styles in svg tag': 'models/svg/tests/styles.svg', - 'Round join': 'models/svg/tests/roundJoinPrecisionIssue.svg', - 'Ellipse Transformations': 'models/svg/tests/ellipseTransform.svg', - singlePointTest: 'models/svg/singlePointTest.svg', - singlePointTest2: 'models/svg/singlePointTest2.svg', - singlePointTest3: 'models/svg/singlePointTest3.svg', - emptyPath: 'models/svg/emptyPath.svg', - }) - .name('SVG File') - .onChange(update); - - gui.add(guiData, 'drawStrokes').name('Draw strokes').onChange(update); - - gui.add(guiData, 'drawFillShapes').name('Draw fill shapes').onChange(update); - - gui.add(guiData, 'strokesWireframe').name('Wireframe strokes').onChange(update); - - gui.add(guiData, 'fillShapesWireframe').name('Wireframe fill shapes').onChange(update); - - function update() { - loadSVG(guiData.currentURL); - } -} - -function loadSVG(url) { - // - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xb0b0b0); - - // - - const helper = new THREE.GridHelper(160, 10, 0x8d8d8d, 0xc1c1c1); - helper.rotation.x = Math.PI / 2; - scene.add(helper); - - // - - const loader = new SVGLoader(); - - loader.load(url, function (data) { - const group = new THREE.Group(); - group.scale.multiplyScalar(0.25); - group.position.x = -70; - group.position.y = 70; - group.scale.y *= -1; - - let renderOrder = 0; - - for (const path of data.paths) { - const fillColor = path.userData.style.fill; - - if (guiData.drawFillShapes && fillColor !== undefined && fillColor !== 'none') { - const material = new THREE.MeshBasicMaterial({ - color: new THREE.Color().setStyle(fillColor), - opacity: path.userData.style.fillOpacity, - transparent: true, - side: THREE.DoubleSide, - depthWrite: false, - wireframe: guiData.fillShapesWireframe, - }); - - const shapes = SVGLoader.createShapes(path); - - for (const shape of shapes) { - const geometry = new THREE.ShapeGeometry(shape); - const mesh = new THREE.Mesh(geometry, material); - mesh.renderOrder = renderOrder++; - - group.add(mesh); - } - } - - const strokeColor = path.userData.style.stroke; - - if (guiData.drawStrokes && strokeColor !== undefined && strokeColor !== 'none') { - const material = new THREE.MeshBasicMaterial({ - color: new THREE.Color().setStyle(strokeColor), - opacity: path.userData.style.strokeOpacity, - transparent: true, - side: THREE.DoubleSide, - depthWrite: false, - wireframe: guiData.strokesWireframe, - }); - - for (const subPath of path.subPaths) { - const geometry = SVGLoader.pointsToStroke(subPath.getPoints(), path.userData.style); - - if (geometry) { - const mesh = new THREE.Mesh(geometry, material); - mesh.renderOrder = renderOrder++; - - group.add(mesh); - } - } - } - } - - scene.add(group); - - render(); - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_texture_dds.ts b/examples-testing/examples/webgl_loader_texture_dds.ts deleted file mode 100644 index bc4bd0572..000000000 --- a/examples-testing/examples/webgl_loader_texture_dds.ts +++ /dev/null @@ -1,207 +0,0 @@ -import * as THREE from 'three'; - -import { DDSLoader } from 'three/addons/loaders/DDSLoader.js'; - -let camera, scene, renderer; -const meshes = []; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 15; - - scene = new THREE.Scene(); - - const geometry = new THREE.BoxGeometry(2, 2, 2); - - /* - This is how compressed textures are supposed to be used: - - DXT1 - RGB - opaque textures - DXT3 - RGBA - transparent textures with sharp alpha transitions - DXT5 - RGBA - transparent textures with full alpha range - */ - - const loader = new DDSLoader(); - - const map1 = loader.load('textures/compressed/disturb_dxt1_nomip.dds'); - map1.minFilter = map1.magFilter = THREE.LinearFilter; - map1.anisotropy = 4; - map1.colorSpace = THREE.SRGBColorSpace; - - const map2 = loader.load('textures/compressed/disturb_dxt1_mip.dds'); - map2.anisotropy = 4; - map2.colorSpace = THREE.SRGBColorSpace; - - const map3 = loader.load('textures/compressed/hepatica_dxt3_mip.dds'); - map3.anisotropy = 4; - map3.colorSpace = THREE.SRGBColorSpace; - - const map4 = loader.load('textures/compressed/explosion_dxt5_mip.dds'); - map4.anisotropy = 4; - map4.colorSpace = THREE.SRGBColorSpace; - - const map5 = loader.load('textures/compressed/disturb_argb_nomip.dds'); - map5.minFilter = map5.magFilter = THREE.LinearFilter; - map5.anisotropy = 4; - map5.colorSpace = THREE.SRGBColorSpace; - - const map6 = loader.load('textures/compressed/disturb_argb_mip.dds'); - map6.anisotropy = 4; - map6.colorSpace = THREE.SRGBColorSpace; - - const map7 = loader.load('textures/compressed/disturb_dx10_bc6h_signed_nomip.dds'); - map7.anisotropy = 4; - - const map8 = loader.load('textures/compressed/disturb_dx10_bc6h_signed_mip.dds'); - map8.anisotropy = 4; - - const map9 = loader.load('textures/compressed/disturb_dx10_bc6h_unsigned_nomip.dds'); - map9.anisotropy = 4; - - const map10 = loader.load('textures/compressed/disturb_dx10_bc6h_unsigned_mip.dds'); - map10.anisotropy = 4; - - const cubemap1 = loader.load('textures/compressed/Mountains.dds', function (texture) { - texture.magFilter = THREE.LinearFilter; - texture.minFilter = THREE.LinearFilter; - texture.mapping = THREE.CubeReflectionMapping; - texture.colorSpace = THREE.SRGBColorSpace; - material1.needsUpdate = true; - }); - - const cubemap2 = loader.load('textures/compressed/Mountains_argb_mip.dds', function (texture) { - texture.magFilter = THREE.LinearFilter; - texture.minFilter = THREE.LinearFilter; - texture.mapping = THREE.CubeReflectionMapping; - texture.colorSpace = THREE.SRGBColorSpace; - material5.needsUpdate = true; - }); - - const cubemap3 = loader.load('textures/compressed/Mountains_argb_nomip.dds', function (texture) { - texture.magFilter = THREE.LinearFilter; - texture.minFilter = THREE.LinearFilter; - texture.mapping = THREE.CubeReflectionMapping; - texture.colorSpace = THREE.SRGBColorSpace; - material6.needsUpdate = true; - }); - - const material1 = new THREE.MeshBasicMaterial({ map: map1, envMap: cubemap1 }); - const material2 = new THREE.MeshBasicMaterial({ map: map2 }); - const material3 = new THREE.MeshBasicMaterial({ map: map3, alphaTest: 0.5, side: THREE.DoubleSide }); - const material4 = new THREE.MeshBasicMaterial({ - map: map4, - side: THREE.DoubleSide, - blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, - }); - const material5 = new THREE.MeshBasicMaterial({ envMap: cubemap2 }); - const material6 = new THREE.MeshBasicMaterial({ envMap: cubemap3 }); - const material7 = new THREE.MeshBasicMaterial({ map: map5 }); - const material8 = new THREE.MeshBasicMaterial({ map: map6 }); - const material9 = new THREE.MeshBasicMaterial({ map: map7 }); - const material10 = new THREE.MeshBasicMaterial({ map: map8 }); - const material11 = new THREE.MeshBasicMaterial({ map: map9 }); - const material12 = new THREE.MeshBasicMaterial({ map: map10 }); - - let mesh = new THREE.Mesh(new THREE.TorusGeometry(), material1); - mesh.position.x = -10; - mesh.position.y = -2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material2); - mesh.position.x = -6; - mesh.position.y = -2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material3); - mesh.position.x = -6; - mesh.position.y = 2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material4); - mesh.position.x = -10; - mesh.position.y = 2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material5); - mesh.position.x = -2; - mesh.position.y = 2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material6); - mesh.position.x = -2; - mesh.position.y = -2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material7); - mesh.position.x = 2; - mesh.position.y = -2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material8); - mesh.position.x = 2; - mesh.position.y = 2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material9); - mesh.position.x = 6; - mesh.position.y = -2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material10); - mesh.position.x = 6; - mesh.position.y = 2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material11); - mesh.position.x = 10; - mesh.position.y = -2; - scene.add(mesh); - meshes.push(mesh); - - mesh = new THREE.Mesh(geometry, material12); - mesh.position.x = 10; - mesh.position.y = 2; - scene.add(mesh); - meshes.push(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = Date.now() * 0.001; - - for (let i = 0; i < meshes.length; i++) { - const mesh = meshes[i]; - mesh.rotation.x = time; - mesh.rotation.y = time; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_texture_ktx.ts b/examples-testing/examples/webgl_loader_texture_ktx.ts deleted file mode 100644 index af66eb810..000000000 --- a/examples-testing/examples/webgl_loader_texture_ktx.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import { KTXLoader } from 'three/addons/loaders/KTXLoader.js'; - -/* - This is how compressed textures are supposed to be used: - - best for desktop: - BC1(DXT1) - opaque textures - BC3(DXT5) - transparent textures with full alpha range - - best for iOS: - PVR2, PVR4 - opaque textures or alpha - - best for Android: - ETC1 - opaque textures - ASTC_4x4, ASTC8x8 - transparent textures with full alpha range - */ - -let camera, scene, renderer; -const meshes = []; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - const formats = { - astc: renderer.extensions.has('WEBGL_compressed_texture_astc'), - etc1: renderer.extensions.has('WEBGL_compressed_texture_etc1'), - s3tc: renderer.extensions.has('WEBGL_compressed_texture_s3tc'), - pvrtc: renderer.extensions.has('WEBGL_compressed_texture_pvrtc'), - }; - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - - const geometry = new THREE.BoxGeometry(200, 200, 200); - let material1, material2; - - // TODO: add cubemap support - const loader = new KTXLoader(); - - if (formats.pvrtc) { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_PVR2bpp.ktx'), - }); - material1.map.colorSpace = THREE.SRGBColorSpace; - material2 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/lensflare_PVR4bpp.ktx'), - depthTest: false, - transparent: true, - side: THREE.DoubleSide, - }); - material2.map.colorSpace = THREE.SRGBColorSpace; - - meshes.push(new THREE.Mesh(geometry, material1)); - meshes.push(new THREE.Mesh(geometry, material2)); - } - - if (formats.s3tc) { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_BC1.ktx'), - }); - material1.map.colorSpace = THREE.SRGBColorSpace; - material2 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/lensflare_BC3.ktx'), - depthTest: false, - transparent: true, - side: THREE.DoubleSide, - }); - material2.map.colorSpace = THREE.SRGBColorSpace; - - meshes.push(new THREE.Mesh(geometry, material1)); - meshes.push(new THREE.Mesh(geometry, material2)); - } - - if (formats.etc1) { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_ETC1.ktx'), - }); - - meshes.push(new THREE.Mesh(geometry, material1)); - } - - if (formats.astc) { - material1 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/disturb_ASTC4x4.ktx'), - }); - material1.map.colorSpace = THREE.SRGBColorSpace; - material2 = new THREE.MeshBasicMaterial({ - map: loader.load('textures/compressed/lensflare_ASTC8x8.ktx'), - depthTest: false, - transparent: true, - side: THREE.DoubleSide, - }); - material2.map.colorSpace = THREE.SRGBColorSpace; - - meshes.push(new THREE.Mesh(geometry, material1)); - meshes.push(new THREE.Mesh(geometry, material2)); - } - - let x = (-meshes.length / 2) * 150; - for (let i = 0; i < meshes.length; ++i, x += 300) { - const mesh = meshes[i]; - mesh.position.x = x; - mesh.position.y = 0; - scene.add(mesh); - } - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = Date.now() * 0.001; - - for (let i = 0; i < meshes.length; i++) { - const mesh = meshes[i]; - mesh.rotation.x = time; - mesh.rotation.y = time; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_texture_rgbm.ts b/examples-testing/examples/webgl_loader_texture_rgbm.ts deleted file mode 100644 index a882cdbc5..000000000 --- a/examples-testing/examples/webgl_loader_texture_rgbm.ts +++ /dev/null @@ -1,75 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { RGBMLoader } from 'three/addons/loaders/RGBMLoader.js'; - -const params = { - exposure: 2.0, -}; - -let renderer, scene, camera; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = THREE.ReinhardToneMapping; - renderer.toneMappingExposure = params.exposure; - - scene = new THREE.Scene(); - - const aspect = window.innerWidth / window.innerHeight; - - camera = new THREE.OrthographicCamera(-aspect, aspect, 1, -1, 0, 1); - - new RGBMLoader().setMaxRange(16).load('textures/memorial.png', function (texture) { - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const quad = new THREE.PlaneGeometry(1, 1.5); - - const mesh = new THREE.Mesh(quad, material); - - scene.add(mesh); - - render(); - }); - - // - - const gui = new GUI(); - - gui.add(params, 'exposure', 0, 4, 0.01).onChange(render); - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - const frustumHeight = camera.top - camera.bottom; - - camera.left = (-frustumHeight * aspect) / 2; - camera.right = (frustumHeight * aspect) / 2; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.toneMappingExposure = params.exposure; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_texture_tga.ts b/examples-testing/examples/webgl_loader_texture_tga.ts deleted file mode 100644 index c4f65b79a..000000000 --- a/examples-testing/examples/webgl_loader_texture_tga.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { TGALoader } from 'three/addons/loaders/TGALoader.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 1, 5); - - scene = new THREE.Scene(); - - // - - const loader = new TGALoader(); - const geometry = new THREE.BoxGeometry(); - - // add box 1 - grey8 texture - - const texture1 = loader.load('textures/crate_grey8.tga'); - texture1.colorSpace = THREE.SRGBColorSpace; - const material1 = new THREE.MeshPhongMaterial({ color: 0xffffff, map: texture1 }); - - const mesh1 = new THREE.Mesh(geometry, material1); - mesh1.position.x = -1; - - scene.add(mesh1); - - // add box 2 - tga texture - - const texture2 = loader.load('textures/crate_color8.tga'); - texture2.colorSpace = THREE.SRGBColorSpace; - const material2 = new THREE.MeshPhongMaterial({ color: 0xffffff, map: texture2 }); - - const mesh2 = new THREE.Mesh(geometry, material2); - mesh2.position.x = 1; - - scene.add(mesh2); - - // - - const ambientLight = new THREE.AmbientLight(0xffffff, 1.5); - scene.add(ambientLight); - - const light = new THREE.DirectionalLight(0xffffff, 2.5); - light.position.set(1, 1, 1); - scene.add(light); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); - stats.update(); -} diff --git a/examples-testing/examples/webgl_loader_texture_tiff.ts b/examples-testing/examples/webgl_loader_texture_tiff.ts deleted file mode 100644 index f097774aa..000000000 --- a/examples-testing/examples/webgl_loader_texture_tiff.ts +++ /dev/null @@ -1,87 +0,0 @@ -import * as THREE from 'three'; - -import { TIFFLoader } from 'three/addons/loaders/TIFFLoader.js'; - -let renderer, scene, camera; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.set(0, 0, 4); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - const loader = new TIFFLoader(); - - const geometry = new THREE.PlaneGeometry(); - - // uncompressed - - loader.load('textures/tiff/crate_uncompressed.tif', function (texture) { - texture.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(-1.5, 0, 0); - - scene.add(mesh); - - render(); - }); - - // LZW - - loader.load('textures/tiff/crate_lzw.tif', function (texture) { - texture.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(0, 0, 0); - - scene.add(mesh); - - render(); - }); - - // JPEG - - loader.load('textures/tiff/crate_jpeg.tif', function (texture) { - texture.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(1.5, 0, 0); - - scene.add(mesh); - - render(); - }); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_texture_ultrahdr.ts b/examples-testing/examples/webgl_loader_texture_ultrahdr.ts deleted file mode 100644 index c8bce4bf9..000000000 --- a/examples-testing/examples/webgl_loader_texture_ultrahdr.ts +++ /dev/null @@ -1,101 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { UltraHDRLoader } from 'three/addons/loaders/UltraHDRLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -const params = { - autoRotate: true, - metalness: 1.0, - roughness: 0.0, - exposure: 1.0, - resolution: '2k', - type: 'HalfFloatType', -}; - -let renderer, scene, camera, controls, torusMesh, loader; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = params.exposure; - - renderer.setAnimationLoop(render); - - scene = new THREE.Scene(); - - torusMesh = new THREE.Mesh( - new THREE.TorusKnotGeometry(1, 0.4, 128, 128, 1, 3), - new THREE.MeshStandardMaterial({ roughness: params.roughness, metalness: params.metalness }), - ); - scene.add(torusMesh); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 500); - camera.position.set(0.0, 0.0, -6.0); - - controls = new OrbitControls(camera, renderer.domElement); - - loader = new UltraHDRLoader(); - loader.setDataType(THREE.FloatType); - - const loadEnvironment = function (resolution = '2k', type = 'HalfFloatType') { - loader.setDataType(THREE[type]); - - loader.load(`textures/equirectangular/spruit_sunrise_${resolution}.hdr.jpg`, function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - texture.needsUpdate = true; - - scene.background = texture; - scene.environment = texture; - }); - }; - - loadEnvironment(params.resolution, params.type); - - const gui = new GUI(); - - gui.add(params, 'autoRotate'); - gui.add(params, 'metalness', 0, 1, 0.01); - gui.add(params, 'roughness', 0, 1, 0.01); - gui.add(params, 'exposure', 0, 4, 0.01); - gui.add(params, 'resolution', ['2k', '4k']).onChange(value => { - loadEnvironment(value, params.type); - }); - gui.add(params, 'type', ['HalfFloatType', 'FloatType']).onChange(value => { - loadEnvironment(params.resolution, value); - }); - - gui.open(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function render() { - torusMesh.material.roughness = params.roughness; - torusMesh.material.metalness = params.metalness; - - if (params.autoRotate) { - torusMesh.rotation.y += 0.005; - } - - renderer.toneMappingExposure = params.exposure; - - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_tilt.ts b/examples-testing/examples/webgl_loader_tilt.ts deleted file mode 100644 index 843b3cfd4..000000000 --- a/examples-testing/examples/webgl_loader_tilt.ts +++ /dev/null @@ -1,51 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { TiltLoader } from 'three/addons/loaders/TiltLoader.js'; - -let camera, scene, renderer; - -init(); - -function init() { - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500); - - camera.position.y = 43; - camera.position.z = 100; - - scene.add(camera); - - const grid = new THREE.GridHelper(50, 50, 0xffffff, 0x555555); - scene.add(grid); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - const loader = new TiltLoader(); - loader.load('./models/tilt/BRUSH_DOME.tilt', function (object) { - // console.log( object.children.length ); - scene.add(object); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.y = camera.position.y; - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_ttf.ts b/examples-testing/examples/webgl_loader_ttf.ts deleted file mode 100644 index 168371a14..000000000 --- a/examples-testing/examples/webgl_loader_ttf.ts +++ /dev/null @@ -1,231 +0,0 @@ -import * as THREE from 'three'; - -import { TTFLoader } from 'three/addons/loaders/TTFLoader.js'; -import { Font } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -let container; -let camera, cameraTarget, scene, renderer; -let group, textMesh1, textMesh2, textGeo, material; -let firstLetter = true; - -let text = 'three.js'; -const depth = 20, - size = 70, - hover = 30, - curveSegments = 4, - bevelThickness = 2, - bevelSize = 1.5; - -let font = null; -const mirror = true; - -let targetRotation = 0; -let targetRotationOnPointerDown = 0; - -let pointerX = 0; -let pointerXOnPointerDown = 0; - -let windowHalfX = window.innerWidth / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 1500); - camera.position.set(0, 400, 700); - - cameraTarget = new THREE.Vector3(0, 150, 0); - - // SCENE - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x000000); - scene.fog = new THREE.Fog(0x000000, 250, 1400); - - // LIGHTS - - const dirLight1 = new THREE.DirectionalLight(0xffffff, 0.4); - dirLight1.position.set(0, 0, 1).normalize(); - scene.add(dirLight1); - - const dirLight2 = new THREE.DirectionalLight(0xffffff, 2); - dirLight2.position.set(0, hover, 10).normalize(); - dirLight2.color.setHSL(Math.random(), 1, 0.5, THREE.SRGBColorSpace); - scene.add(dirLight2); - - material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }); - - group = new THREE.Group(); - group.position.y = 100; - - scene.add(group); - - const loader = new TTFLoader(); - - loader.load('fonts/ttf/kenpixel.ttf', function (json) { - font = new Font(json); - createText(); - }); - - const plane = new THREE.Mesh( - new THREE.PlaneGeometry(10000, 10000), - new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.5, transparent: true }), - ); - plane.position.y = 100; - plane.rotation.x = -Math.PI / 2; - scene.add(plane); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // EVENTS - - container.style.touchAction = 'none'; - container.addEventListener('pointerdown', onPointerDown); - - document.addEventListener('keypress', onDocumentKeyPress); - document.addEventListener('keydown', onDocumentKeyDown); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentKeyDown(event) { - if (firstLetter) { - firstLetter = false; - text = ''; - } - - const keyCode = event.keyCode; - - // backspace - - if (keyCode === 8) { - event.preventDefault(); - - text = text.substring(0, text.length - 1); - refreshText(); - - return false; - } -} - -function onDocumentKeyPress(event) { - const keyCode = event.which; - - // backspace - - if (keyCode === 8) { - event.preventDefault(); - } else { - const ch = String.fromCharCode(keyCode); - text += ch; - - refreshText(); - } -} - -function createText() { - textGeo = new TextGeometry(text, { - font: font, - - size: size, - depth: depth, - curveSegments: curveSegments, - - bevelThickness: bevelThickness, - bevelSize: bevelSize, - bevelEnabled: true, - }); - - textGeo.computeBoundingBox(); - textGeo.computeVertexNormals(); - - const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); - - textMesh1 = new THREE.Mesh(textGeo, material); - - textMesh1.position.x = centerOffset; - textMesh1.position.y = hover; - textMesh1.position.z = 0; - - textMesh1.rotation.x = 0; - textMesh1.rotation.y = Math.PI * 2; - - group.add(textMesh1); - - if (mirror) { - textMesh2 = new THREE.Mesh(textGeo, material); - - textMesh2.position.x = centerOffset; - textMesh2.position.y = -hover; - textMesh2.position.z = depth; - - textMesh2.rotation.x = Math.PI; - textMesh2.rotation.y = Math.PI * 2; - - group.add(textMesh2); - } -} - -function refreshText() { - group.remove(textMesh1); - if (mirror) group.remove(textMesh2); - - if (!text) return; - - createText(); -} - -function onPointerDown(event) { - if (event.isPrimary === false) return; - - pointerXOnPointerDown = event.clientX - windowHalfX; - targetRotationOnPointerDown = targetRotation; - - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - pointerX = event.clientX - windowHalfX; - - targetRotation = targetRotationOnPointerDown + (pointerX - pointerXOnPointerDown) * 0.02; -} - -function onPointerUp() { - if (event.isPrimary === false) return; - - document.removeEventListener('pointermove', onPointerMove); - document.removeEventListener('pointerup', onPointerUp); -} - -// - -function animate() { - group.rotation.y += (targetRotation - group.rotation.y) * 0.05; - - camera.lookAt(cameraTarget); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_usdz.ts b/examples-testing/examples/webgl_loader_usdz.ts deleted file mode 100644 index d75823d88..000000000 --- a/examples-testing/examples/webgl_loader_usdz.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { USDZLoader } from 'three/addons/loaders/USDZLoader.js'; - -let camera, scene, renderer; - -init(); - -async function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0.75, -1.5); - - scene = new THREE.Scene(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - - const usdzLoader = new USDZLoader().setPath('models/usdz/'); - - const [texture, model] = await Promise.all([ - rgbeLoader.loadAsync('venice_sunset_1k.hdr'), - usdzLoader.loadAsync('saeukkang.usdz'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.backgroundBlurriness = 0.5; - scene.environment = texture; - - // model - - model.position.y = 0.25; - model.position.z = -0.25; - scene.add(model); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 2.0; - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 8; - // controls.target.y = 15; - // controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_vox.ts b/examples-testing/examples/webgl_loader_vox.ts deleted file mode 100644 index 061848012..000000000 --- a/examples-testing/examples/webgl_loader_vox.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { VOXLoader, VOXMesh } from 'three/addons/loaders/VOXLoader.js'; - -let camera, controls, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.set(0.175, 0.075, 0.175); - - scene = new THREE.Scene(); - scene.add(camera); - - // light - - const hemiLight = new THREE.HemisphereLight(0xcccccc, 0x444444, 3); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 2.5); - dirLight.position.set(1.5, 3, 2.5); - scene.add(dirLight); - - const dirLight2 = new THREE.DirectionalLight(0xffffff, 1.5); - dirLight2.position.set(-1.5, -3, -2.5); - scene.add(dirLight2); - - const loader = new VOXLoader(); - loader.load('models/vox/monu10.vox', function (chunks) { - for (let i = 0; i < chunks.length; i++) { - const chunk = chunks[i]; - - // displayPalette( chunk.palette ); - - const mesh = new VOXMesh(chunk); - mesh.scale.setScalar(0.0015); - scene.add(mesh); - } - }); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 0.1; - controls.maxDistance = 0.5; - - // - - window.addEventListener('resize', onWindowResize); -} - -/* - function displayPalette( palette ) { - - const canvas = document.createElement( 'canvas' ); - canvas.width = 8; - canvas.height = 32; - canvas.style.position = 'absolute'; - canvas.style.top = '0'; - canvas.style.width = '100px'; - canvas.style.imageRendering = 'pixelated'; - document.body.appendChild( canvas ); - - const context = canvas.getContext( '2d' ); - - for ( let c = 0; c < 256; c ++ ) { - - const x = c % 8; - const y = Math.floor( c / 8 ); - - const hex = palette[ c + 1 ]; - const r = hex >> 0 & 0xff; - const g = hex >> 8 & 0xff; - const b = hex >> 16 & 0xff; - context.fillStyle = `rgba(${r},${g},${b},1)`; - context.fillRect( x, 31 - y, 1, 1 ); - - } - - } - */ - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_loader_vrml.ts b/examples-testing/examples/webgl_loader_vrml.ts deleted file mode 100644 index fecf4bb45..000000000 --- a/examples-testing/examples/webgl_loader_vrml.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats, controls, loader; - -const params = { - asset: 'house', -}; - -const assets = [ - 'creaseAngle', - 'crystal', - 'house', - 'elevationGrid1', - 'elevationGrid2', - 'extrusion1', - 'extrusion2', - 'extrusion3', - 'lines', - 'linesTransparent', - 'meshWithLines', - 'meshWithTexture', - 'pixelTexture', - 'points', -]; - -let vrmlScene; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1e10); - camera.position.set(-10, 5, 10); - - scene = new THREE.Scene(); - scene.add(camera); - - // light - - const ambientLight = new THREE.AmbientLight(0xffffff, 1.2); - scene.add(ambientLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 2.0); - dirLight.position.set(200, 200, 200); - scene.add(dirLight); - - loader = new VRMLLoader(); - loadAsset(params.asset); - - // renderer - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 200; - controls.enableDamping = true; - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - gui.add(params, 'asset', assets).onChange(function (value) { - if (vrmlScene) { - vrmlScene.traverse(function (object) { - if (object.material) object.material.dispose(); - if (object.material && object.material.map) object.material.map.dispose(); - if (object.geometry) object.geometry.dispose(); - }); - - scene.remove(vrmlScene); - } - - loadAsset(value); - }); -} - -function loadAsset(asset) { - loader.load('models/vrml/' + asset + '.wrl', function (object) { - vrmlScene = object; - scene.add(object); - controls.reset(); - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); // to support damping - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_loader_vtk.ts b/examples-testing/examples/webgl_loader_vtk.ts deleted file mode 100644 index dfc798657..000000000 --- a/examples-testing/examples/webgl_loader_vtk.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { VTKLoader } from 'three/addons/loaders/VTKLoader.js'; - -let stats; - -let camera, controls, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 100); - camera.position.z = 0.2; - - scene = new THREE.Scene(); - - scene.add(camera); - - // light - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x000000, 3); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 1.5); - dirLight.position.set(2, 2, 2); - scene.add(dirLight); - - const loader = new VTKLoader(); - loader.load('models/vtk/bunny.vtk', function (geometry) { - geometry.center(); - geometry.computeVertexNormals(); - - const material = new THREE.MeshLambertMaterial({ color: 0xffffff }); - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(-0.075, 0.005, 0); - mesh.scale.multiplyScalar(0.2); - scene.add(mesh); - }); - - const loader1 = new VTKLoader(); - loader1.load('models/vtk/cube_ascii.vtp', function (geometry) { - geometry.computeVertexNormals(); - geometry.center(); - - const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 }); - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.set(-0.025, 0, 0); - mesh.scale.multiplyScalar(0.01); - - scene.add(mesh); - }); - - const loader2 = new VTKLoader(); - loader2.load('models/vtk/cube_binary.vtp', function (geometry) { - geometry.computeVertexNormals(); - geometry.center(); - - const material = new THREE.MeshLambertMaterial({ color: 0x0000ff }); - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.set(0.025, 0, 0); - mesh.scale.multiplyScalar(0.01); - - scene.add(mesh); - }); - - const loader3 = new VTKLoader(); - loader3.load('models/vtk/cube_no_compression.vtp', function (geometry) { - geometry.computeVertexNormals(); - geometry.center(); - - const material = new THREE.MeshLambertMaterial({ color: 0xff0000 }); - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.set(0.075, 0, 0); - mesh.scale.multiplyScalar(0.01); - - scene.add(mesh); - }); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // controls - - controls = new TrackballControls(camera, renderer.domElement); - controls.minDistance = 0.1; - controls.maxDistance = 0.5; - controls.rotateSpeed = 5.0; - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - controls.handleResize(); -} - -function animate() { - controls.update(); - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_loader_xyz.ts b/examples-testing/examples/webgl_loader_xyz.ts deleted file mode 100644 index 90e009840..000000000 --- a/examples-testing/examples/webgl_loader_xyz.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as THREE from 'three'; - -import { XYZLoader } from 'three/addons/loaders/XYZLoader.js'; - -let camera, scene, renderer, clock; - -let points; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(10, 7, 10); - - scene = new THREE.Scene(); - scene.add(camera); - camera.lookAt(scene.position); - - clock = new THREE.Clock(); - - const loader = new XYZLoader(); - loader.load('models/xyz/helix_201.xyz', function (geometry) { - geometry.center(); - - const vertexColors = geometry.hasAttribute('color') === true; - - const material = new THREE.PointsMaterial({ size: 0.1, vertexColors: vertexColors }); - - points = new THREE.Points(geometry, material); - scene.add(points); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (points) { - points.rotation.x += delta * 0.2; - points.rotation.y += delta * 0.5; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_lod.ts b/examples-testing/examples/webgl_lod.ts deleted file mode 100644 index 0bb9e7be0..000000000 --- a/examples-testing/examples/webgl_lod.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as THREE from 'three'; - -import { FlyControls } from 'three/addons/controls/FlyControls.js'; - -let container; - -let camera, scene, renderer, controls; - -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 15000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1, 15000); - - const pointLight = new THREE.PointLight(0xff2200, 3, 0, 0); - pointLight.position.set(0, 0, 0); - scene.add(pointLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(0, 0, 1).normalize(); - scene.add(dirLight); - - const geometry = [ - [new THREE.IcosahedronGeometry(100, 16), 50], - [new THREE.IcosahedronGeometry(100, 8), 300], - [new THREE.IcosahedronGeometry(100, 4), 1000], - [new THREE.IcosahedronGeometry(100, 2), 2000], - [new THREE.IcosahedronGeometry(100, 1), 8000], - ]; - - const material = new THREE.MeshLambertMaterial({ color: 0xffffff, wireframe: true }); - - for (let j = 0; j < 1000; j++) { - const lod = new THREE.LOD(); - - for (let i = 0; i < geometry.length; i++) { - const mesh = new THREE.Mesh(geometry[i][0], material); - mesh.scale.set(1.5, 1.5, 1.5); - mesh.updateMatrix(); - mesh.matrixAutoUpdate = false; - lod.addLevel(mesh, geometry[i][1]); - } - - lod.position.x = 10000 * (0.5 - Math.random()); - lod.position.y = 7500 * (0.5 - Math.random()); - lod.position.z = 10000 * (0.5 - Math.random()); - lod.updateMatrix(); - lod.matrixAutoUpdate = false; - scene.add(lod); - } - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - controls = new FlyControls(camera, renderer.domElement); - controls.movementSpeed = 1000; - controls.rollSpeed = Math.PI / 10; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(clock.getDelta()); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_marchingcubes.ts b/examples-testing/examples/webgl_marchingcubes.ts deleted file mode 100644 index d11df56a4..000000000 --- a/examples-testing/examples/webgl_marchingcubes.ts +++ /dev/null @@ -1,311 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { MarchingCubes } from 'three/addons/objects/MarchingCubes.js'; -import { ToonShader1, ToonShader2, ToonShaderHatching, ToonShaderDotted } from 'three/addons/shaders/ToonShader.js'; - -let container, stats; - -let camera, scene, renderer; - -let materials, current_material; - -let light, pointLight, ambientLight; - -let effect, resolution; - -let effectController; - -let time = 0; - -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.getElementById('container'); - - // CAMERA - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(-500, 500, 1500); - - // SCENE - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - - // LIGHTS - - light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0.5, 0.5, 1); - scene.add(light); - - pointLight = new THREE.PointLight(0xff7c00, 3, 0, 0); - pointLight.position.set(0, 0, 100); - scene.add(pointLight); - - ambientLight = new THREE.AmbientLight(0x323232, 3); - scene.add(ambientLight); - - // MATERIALS - - materials = generateMaterials(); - current_material = 'shiny'; - - // MARCHING CUBES - - resolution = 28; - - effect = new MarchingCubes(resolution, materials[current_material], true, true, 100000); - effect.position.set(0, 0, 0); - effect.scale.set(700, 700, 700); - - effect.enableUvs = false; - effect.enableColors = false; - - scene.add(effect); - - // RENDERER - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // CONTROLS - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 500; - controls.maxDistance = 5000; - - // STATS - - stats = new Stats(); - container.appendChild(stats.dom); - - // GUI - - setupGui(); - - // EVENTS - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function generateMaterials() { - // environment map - - const path = 'textures/cube/SwedishRoyalCastle/'; - const format = '.jpg'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const cubeTextureLoader = new THREE.CubeTextureLoader(); - - const reflectionCube = cubeTextureLoader.load(urls); - const refractionCube = cubeTextureLoader.load(urls); - refractionCube.mapping = THREE.CubeRefractionMapping; - - // toons - - const toonMaterial1 = createShaderMaterial(ToonShader1, light, ambientLight); - const toonMaterial2 = createShaderMaterial(ToonShader2, light, ambientLight); - const hatchingMaterial = createShaderMaterial(ToonShaderHatching, light, ambientLight); - const dottedMaterial = createShaderMaterial(ToonShaderDotted, light, ambientLight); - - const texture = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - texture.colorSpace = THREE.SRGBColorSpace; - - const materials = { - shiny: new THREE.MeshStandardMaterial({ - color: 0x9c0000, - envMap: reflectionCube, - roughness: 0.1, - metalness: 1.0, - }), - chrome: new THREE.MeshLambertMaterial({ color: 0xffffff, envMap: reflectionCube }), - liquid: new THREE.MeshLambertMaterial({ color: 0xffffff, envMap: refractionCube, refractionRatio: 0.85 }), - matte: new THREE.MeshPhongMaterial({ specular: 0x494949, shininess: 1 }), - flat: new THREE.MeshLambertMaterial({ - /*TODO flatShading: true */ - }), - textured: new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0x111111, shininess: 1, map: texture }), - colors: new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0xffffff, shininess: 2, vertexColors: true }), - multiColors: new THREE.MeshPhongMaterial({ shininess: 2, vertexColors: true }), - plastic: new THREE.MeshPhongMaterial({ specular: 0xc1c1c1, shininess: 250 }), - toon1: toonMaterial1, - toon2: toonMaterial2, - hatching: hatchingMaterial, - dotted: dottedMaterial, - }; - - return materials; -} - -function createShaderMaterial(shader, light, ambientLight) { - const u = THREE.UniformsUtils.clone(shader.uniforms); - - const vs = shader.vertexShader; - const fs = shader.fragmentShader; - - const material = new THREE.ShaderMaterial({ uniforms: u, vertexShader: vs, fragmentShader: fs }); - - material.uniforms['uDirLightPos'].value = light.position; - material.uniforms['uDirLightColor'].value = light.color; - - material.uniforms['uAmbientLightColor'].value = ambientLight.color; - - return material; -} - -// - -function setupGui() { - const createHandler = function (id) { - return function () { - current_material = id; - - effect.material = materials[id]; - effect.enableUvs = current_material === 'textured' ? true : false; - effect.enableColors = current_material === 'colors' || current_material === 'multiColors' ? true : false; - }; - }; - - effectController = { - material: 'shiny', - - speed: 1.0, - numBlobs: 10, - resolution: 28, - isolation: 80, - - floor: true, - wallx: false, - wallz: false, - - dummy: function () {}, - }; - - let h; - - const gui = new GUI(); - - // material (type) - - h = gui.addFolder('Materials'); - - for (const m in materials) { - effectController[m] = createHandler(m); - h.add(effectController, m).name(m); - } - - // simulation - - h = gui.addFolder('Simulation'); - - h.add(effectController, 'speed', 0.1, 8.0, 0.05); - h.add(effectController, 'numBlobs', 1, 50, 1); - h.add(effectController, 'resolution', 14, 100, 1); - h.add(effectController, 'isolation', 10, 300, 1); - - h.add(effectController, 'floor'); - h.add(effectController, 'wallx'); - h.add(effectController, 'wallz'); -} - -// this controls content of marching cubes voxel field - -function updateCubes(object, time, numblobs, floor, wallx, wallz) { - object.reset(); - - // fill the field with some metaballs - - const rainbow = [ - new THREE.Color(0xff0000), - new THREE.Color(0xffbb00), - new THREE.Color(0xffff00), - new THREE.Color(0x00ff00), - new THREE.Color(0x0000ff), - new THREE.Color(0x9400bd), - new THREE.Color(0xc800eb), - ]; - const subtract = 12; - const strength = 1.2 / ((Math.sqrt(numblobs) - 1) / 4 + 1); - - for (let i = 0; i < numblobs; i++) { - const ballx = Math.sin(i + 1.26 * time * (1.03 + 0.5 * Math.cos(0.21 * i))) * 0.27 + 0.5; - const bally = Math.abs(Math.cos(i + 1.12 * time * Math.cos(1.22 + 0.1424 * i))) * 0.77; // dip into the floor - const ballz = Math.cos(i + 1.32 * time * 0.1 * Math.sin(0.92 + 0.53 * i)) * 0.27 + 0.5; - - if (current_material === 'multiColors') { - object.addBall(ballx, bally, ballz, strength, subtract, rainbow[i % 7]); - } else { - object.addBall(ballx, bally, ballz, strength, subtract); - } - } - - if (floor) object.addPlaneY(2, 12); - if (wallz) object.addPlaneZ(2, 12); - if (wallx) object.addPlaneX(2, 12); - - object.update(); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - time += delta * effectController.speed * 0.5; - - // marching cubes - - if (effectController.resolution !== resolution) { - resolution = effectController.resolution; - effect.init(Math.floor(resolution)); - } - - if (effectController.isolation !== effect.isolation) { - effect.isolation = effectController.isolation; - } - - updateCubes( - effect, - time, - effectController.numBlobs, - effectController.floor, - effectController.wallx, - effectController.wallz, - ); - - // render - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_alphahash.ts b/examples-testing/examples/webgl_materials_alphahash.ts deleted file mode 100644 index 1ecf95f26..000000000 --- a/examples-testing/examples/webgl_materials_alphahash.ts +++ /dev/null @@ -1,178 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, scene, renderer, controls, stats, mesh, material; - -let composer, renderPass, taaRenderPass, outputPass; - -let needsUpdate = false; - -const amount = parseInt(window.location.search.slice(1)) || 3; -const count = Math.pow(amount, 3); - -const color = new THREE.Color(); - -const params = { - alpha: 0.5, - alphaHash: true, - taa: true, - sampleLevel: 2, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(amount, amount, amount); - camera.lookAt(0, 0, 0); - - scene = new THREE.Scene(); - - const geometry = new THREE.IcosahedronGeometry(0.5, 3); - - material = new THREE.MeshStandardMaterial({ - color: 0xffffff, - alphaHash: params.alphaHash, - opacity: params.alpha, - }); - - mesh = new THREE.InstancedMesh(geometry, material, count); - - let i = 0; - const offset = (amount - 1) / 2; - - const matrix = new THREE.Matrix4(); - - for (let x = 0; x < amount; x++) { - for (let y = 0; y < amount; y++) { - for (let z = 0; z < amount; z++) { - matrix.setPosition(offset - x, offset - y, offset - z); - - mesh.setMatrixAt(i, matrix); - mesh.setColorAt(i, color.setHex(Math.random() * 0xffffff)); - - i++; - } - } - } - - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - const environment = new RoomEnvironment(); - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene.environment = pmremGenerator.fromScene(environment).texture; - environment.dispose(); - - // - - composer = new EffectComposer(renderer); - - renderPass = new RenderPass(scene, camera); - renderPass.enabled = false; - - taaRenderPass = new TAARenderPass(scene, camera); - - outputPass = new OutputPass(); - - composer.addPass(renderPass); - composer.addPass(taaRenderPass); - composer.addPass(outputPass); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enablePan = false; - - controls.addEventListener('change', () => (needsUpdate = true)); - - // - - const gui = new GUI(); - - gui.add(params, 'alpha', 0, 1).onChange(onMaterialUpdate); - gui.add(params, 'alphaHash').onChange(onMaterialUpdate); - - const taaFolder = gui.addFolder('Temporal Anti-Aliasing'); - - taaFolder - .add(params, 'taa') - .name('enabled') - .onChange(() => { - renderPass.enabled = !params.taa; - taaRenderPass.enabled = params.taa; - - sampleLevelCtrl.enable(params.taa); - - needsUpdate = true; - }); - - const sampleLevelCtrl = taaFolder.add(params, 'sampleLevel', 0, 6, 1).onChange(() => (needsUpdate = true)); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); - - needsUpdate = true; -} - -function onMaterialUpdate() { - material.opacity = params.alpha; - material.alphaHash = params.alphaHash; - material.transparent = !params.alphaHash; - material.depthWrite = params.alphaHash; - - material.needsUpdate = true; - needsUpdate = true; -} - -function animate() { - render(); - - stats.update(); -} - -function render() { - if (needsUpdate) { - taaRenderPass.accumulate = false; - taaRenderPass.sampleLevel = 0; - - needsUpdate = false; - } else { - taaRenderPass.accumulate = true; - taaRenderPass.sampleLevel = params.sampleLevel; - } - - composer.render(); -} diff --git a/examples-testing/examples/webgl_materials_blending.ts b/examples-testing/examples/webgl_materials_blending.ts deleted file mode 100644 index 11cc009bc..000000000 --- a/examples-testing/examples/webgl_materials_blending.ts +++ /dev/null @@ -1,147 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; -let mapBg; - -const textureLoader = new THREE.TextureLoader(); - -init(); - -function init() { - // CAMERA - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 600; - - // SCENE - - scene = new THREE.Scene(); - - // BACKGROUND - - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - canvas.width = canvas.height = 128; - ctx.fillStyle = '#ddd'; - ctx.fillRect(0, 0, 128, 128); - ctx.fillStyle = '#555'; - ctx.fillRect(0, 0, 64, 64); - ctx.fillStyle = '#999'; - ctx.fillRect(32, 32, 32, 32); - ctx.fillStyle = '#555'; - ctx.fillRect(64, 64, 64, 64); - ctx.fillStyle = '#777'; - ctx.fillRect(96, 96, 32, 32); - - mapBg = new THREE.CanvasTexture(canvas); - mapBg.colorSpace = THREE.SRGBColorSpace; - mapBg.wrapS = mapBg.wrapT = THREE.RepeatWrapping; - mapBg.repeat.set(64, 32); - - scene.background = mapBg; - - // OBJECTS - - const blendings = [ - { name: 'No', constant: THREE.NoBlending }, - { name: 'Normal', constant: THREE.NormalBlending }, - { name: 'Additive', constant: THREE.AdditiveBlending }, - { name: 'Subtractive', constant: THREE.SubtractiveBlending }, - { name: 'Multiply', constant: THREE.MultiplyBlending }, - ]; - - const assignSRGB = texture => { - texture.colorSpace = THREE.SRGBColorSpace; - }; - - const map0 = textureLoader.load('textures/uv_grid_opengl.jpg', assignSRGB); - const map1 = textureLoader.load('textures/sprite0.jpg', assignSRGB); - const map2 = textureLoader.load('textures/sprite0.png', assignSRGB); - const map3 = textureLoader.load('textures/lensflare/lensflare0.png', assignSRGB); - const map4 = textureLoader.load('textures/lensflare/lensflare0_alpha.png', assignSRGB); - - const geo1 = new THREE.PlaneGeometry(100, 100); - const geo2 = new THREE.PlaneGeometry(100, 25); - - addImageRow(map0, 300); - addImageRow(map1, 150); - addImageRow(map2, 0); - addImageRow(map3, -150); - addImageRow(map4, -300); - - function addImageRow(map, y) { - for (let i = 0; i < blendings.length; i++) { - const blending = blendings[i]; - - const material = new THREE.MeshBasicMaterial({ map: map }); - material.transparent = true; - material.blending = blending.constant; - - const x = (i - blendings.length / 2) * 110; - const z = 0; - - let mesh = new THREE.Mesh(geo1, material); - mesh.position.set(x, y, z); - scene.add(mesh); - - mesh = new THREE.Mesh(geo2, generateLabelMaterial(blending.name)); - mesh.position.set(x, y - 75, z); - scene.add(mesh); - } - } - - // RENDERER - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // EVENTS - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - const SCREEN_WIDTH = window.innerWidth; - const SCREEN_HEIGHT = window.innerHeight; - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); -} - -function generateLabelMaterial(text) { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - canvas.width = 128; - canvas.height = 32; - - ctx.fillStyle = 'rgba( 0, 0, 0, 0.95 )'; - ctx.fillRect(0, 0, 128, 32); - - ctx.fillStyle = 'white'; - ctx.font = 'bold 12pt arial'; - ctx.fillText(text, 10, 22); - - const map = new THREE.CanvasTexture(canvas); - map.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshBasicMaterial({ map: map, transparent: true }); - - return material; -} - -function animate() { - const time = Date.now() * 0.00025; - const ox = (time * -0.01 * mapBg.repeat.x) % 1; - const oy = (time * -0.01 * mapBg.repeat.y) % 1; - - mapBg.offset.set(ox, oy); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_blending_custom.ts b/examples-testing/examples/webgl_materials_blending_custom.ts deleted file mode 100644 index 072447426..000000000 --- a/examples-testing/examples/webgl_materials_blending_custom.ts +++ /dev/null @@ -1,214 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -let mapBg; -const materials = []; - -const params = { - blendEquation: THREE.AddEquation, -}; - -const equations = { - Add: THREE.AddEquation, - Subtract: THREE.SubtractEquation, - ReverseSubtract: THREE.ReverseSubtractEquation, - Min: THREE.MinEquation, - Max: THREE.MaxEquation, -}; - -init(); - -function init() { - // CAMERA - - camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 700; - - // SCENE - - scene = new THREE.Scene(); - - // BACKGROUND - - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - canvas.width = canvas.height = 128; - ctx.fillStyle = '#ddd'; - ctx.fillRect(0, 0, 128, 128); - ctx.fillStyle = '#555'; - ctx.fillRect(0, 0, 64, 64); - ctx.fillStyle = '#999'; - ctx.fillRect(32, 32, 32, 32); - ctx.fillStyle = '#555'; - ctx.fillRect(64, 64, 64, 64); - ctx.fillStyle = '#777'; - ctx.fillRect(96, 96, 32, 32); - - mapBg = new THREE.CanvasTexture(canvas); - mapBg.colorSpace = THREE.SRGBColorSpace; - mapBg.wrapS = mapBg.wrapT = THREE.RepeatWrapping; - mapBg.repeat.set(64, 32); - - scene.background = mapBg; - - // FOREGROUND OBJECTS - - const src = [ - { name: 'Zero', constant: THREE.ZeroFactor }, - { name: 'One', constant: THREE.OneFactor }, - { name: 'SrcColor', constant: THREE.SrcColorFactor }, - { name: 'OneMinusSrcColor', constant: THREE.OneMinusSrcColorFactor }, - { name: 'SrcAlpha', constant: THREE.SrcAlphaFactor }, - { name: 'OneMinusSrcAlpha', constant: THREE.OneMinusSrcAlphaFactor }, - { name: 'DstAlpha', constant: THREE.DstAlphaFactor }, - { name: 'OneMinusDstAlpha', constant: THREE.OneMinusDstAlphaFactor }, - { name: 'DstColor', constant: THREE.DstColorFactor }, - { name: 'OneMinusDstColor', constant: THREE.OneMinusDstColorFactor }, - { name: 'SrcAlphaSaturate', constant: THREE.SrcAlphaSaturateFactor }, - ]; - - const dst = [ - { name: 'Zero', constant: THREE.ZeroFactor }, - { name: 'One', constant: THREE.OneFactor }, - { name: 'SrcColor', constant: THREE.SrcColorFactor }, - { name: 'OneMinusSrcColor', constant: THREE.OneMinusSrcColorFactor }, - { name: 'SrcAlpha', constant: THREE.SrcAlphaFactor }, - { name: 'OneMinusSrcAlpha', constant: THREE.OneMinusSrcAlphaFactor }, - { name: 'DstAlpha', constant: THREE.DstAlphaFactor }, - { name: 'OneMinusDstAlpha', constant: THREE.OneMinusDstAlphaFactor }, - { name: 'DstColor', constant: THREE.DstColorFactor }, - { name: 'OneMinusDstColor', constant: THREE.OneMinusDstColorFactor }, - ]; - - const geo1 = new THREE.PlaneGeometry(100, 100); - const geo2 = new THREE.PlaneGeometry(100, 25); - - const texture = new THREE.TextureLoader().load('textures/lensflare/lensflare0_alpha.png'); - texture.colorSpace = THREE.SRGBColorSpace; - - for (let i = 0; i < dst.length; i++) { - const blendDst = dst[i]; - - for (let j = 0; j < src.length; j++) { - const blendSrc = src[j]; - - const material = new THREE.MeshBasicMaterial({ map: texture }); - material.transparent = true; - - material.blending = THREE.CustomBlending; - material.blendSrc = blendSrc.constant; - material.blendDst = blendDst.constant; - material.blendEquation = THREE.AddEquation; - - const x = (j - src.length / 2) * 110; - const z = 0; - const y = (i - dst.length / 2) * 110 + 50; - - const mesh = new THREE.Mesh(geo1, material); - mesh.position.set(x, -y, z); - mesh.matrixAutoUpdate = false; - mesh.updateMatrix(); - scene.add(mesh); - - materials.push(material); - } - } - - for (let j = 0; j < src.length; j++) { - const blendSrc = src[j]; - - const x = (j - src.length / 2) * 110; - const z = 0; - const y = (0 - dst.length / 2) * 110 + 50; - - const mesh = new THREE.Mesh(geo2, generateLabelMaterial(blendSrc.name, 'rgba( 0, 150, 0, 1 )')); - mesh.position.set(x, -(y - 70), z); - mesh.matrixAutoUpdate = false; - mesh.updateMatrix(); - scene.add(mesh); - } - - for (let i = 0; i < dst.length; i++) { - const blendDst = dst[i]; - - const x = (0 - src.length / 2) * 110 - 125; - const z = 0; - const y = (i - dst.length / 2) * 110 + 165; - - const mesh = new THREE.Mesh(geo2, generateLabelMaterial(blendDst.name, 'rgba( 150, 0, 0, 1 )')); - mesh.position.set(x, -(y - 120), z); - mesh.matrixAutoUpdate = false; - mesh.updateMatrix(); - scene.add(mesh); - } - - // RENDERER - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // EVENTS - - window.addEventListener('resize', onWindowResize); - - // GUI - - // - const gui = new GUI({ width: 300 }); - - gui.add(params, 'blendEquation', equations).onChange(updateBlendEquation); - gui.open(); -} - -// - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -// - -function generateLabelMaterial(text, bg) { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - canvas.width = 128; - canvas.height = 32; - - ctx.fillStyle = bg; - ctx.fillRect(0, 0, 128, 32); - - ctx.fillStyle = 'white'; - ctx.font = 'bold 11pt arial'; - ctx.fillText(text, 8, 22); - - const map = new THREE.CanvasTexture(canvas); - map.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.MeshBasicMaterial({ map: map, transparent: true }); - return material; -} - -function updateBlendEquation(value) { - for (const material of materials) { - material.blendEquation = value; - } -} - -function animate() { - const time = Date.now() * 0.00025; - const ox = (time * -0.01 * mapBg.repeat.x) % 1; - const oy = (time * -0.01 * mapBg.repeat.y) % 1; - - mapBg.offset.set(ox, oy); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_bumpmap.ts b/examples-testing/examples/webgl_materials_bumpmap.ts deleted file mode 100644 index d954fab7e..000000000 --- a/examples-testing/examples/webgl_materials_bumpmap.ts +++ /dev/null @@ -1,140 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let container, stats, loader; - -let camera, scene, renderer; - -let mesh; - -let spotLight; - -let mouseX = 0; -let mouseY = 0; - -let targetX = 0; -let targetY = 0; - -const windowHalfX = window.innerWidth / 2; -const windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 12; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x060708); - - // LIGHTS - - scene.add(new THREE.HemisphereLight(0x8d7c7c, 0x494966, 3)); - - spotLight = new THREE.SpotLight(0xffffde, 200); - spotLight.position.set(3.5, 0, 7); - scene.add(spotLight); - - spotLight.castShadow = true; - - spotLight.shadow.mapSize.width = 2048; - spotLight.shadow.mapSize.height = 2048; - - spotLight.shadow.camera.near = 2; - spotLight.shadow.camera.far = 15; - - spotLight.shadow.camera.fov = 40; - - spotLight.shadow.bias = -0.005; - - // - - const mapHeight = new THREE.TextureLoader().load( - 'models/gltf/LeePerrySmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg', - ); - - const material = new THREE.MeshPhongMaterial({ - color: 0x9c6e49, - specular: 0x666666, - shininess: 25, - bumpMap: mapHeight, - bumpScale: 10, - }); - - loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { - createScene(gltf.scene.children[0].geometry, 1, material); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - renderer.shadowMap.enabled = true; - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // EVENTS - - document.addEventListener('mousemove', onDocumentMouseMove); - window.addEventListener('resize', onWindowResize); -} - -function createScene(geometry, scale, material) { - mesh = new THREE.Mesh(geometry, material); - - mesh.position.y = -0.5; - mesh.scale.set(scale, scale, scale); - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); -} - -// - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - targetX = mouseX * 0.001; - targetY = mouseY * 0.001; - - if (mesh) { - mesh.rotation.y += 0.05 * (targetX - mesh.rotation.y); - mesh.rotation.x += 0.05 * (targetY - mesh.rotation.x); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_car.ts b/examples-testing/examples/webgl_materials_car.ts deleted file mode 100644 index e810f7b7d..000000000 --- a/examples-testing/examples/webgl_materials_car.ts +++ /dev/null @@ -1,167 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let camera, scene, renderer; -let stats; - -let grid; -let controls; - -const wheels = []; - -function init() { - const container = document.getElementById('container'); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 0.85; - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(4.25, 1.4, -4.5); - - controls = new OrbitControls(camera, container); - controls.maxDistance = 9; - controls.maxPolarAngle = THREE.MathUtils.degToRad(90); - controls.target.set(0, 0.5, 0); - controls.update(); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x333333); - scene.environment = new RGBELoader().load('textures/equirectangular/venice_sunset_1k.hdr'); - scene.environment.mapping = THREE.EquirectangularReflectionMapping; - scene.fog = new THREE.Fog(0x333333, 10, 15); - - grid = new THREE.GridHelper(20, 40, 0xffffff, 0xffffff); - grid.material.opacity = 0.2; - grid.material.depthWrite = false; - grid.material.transparent = true; - scene.add(grid); - - // materials - - const bodyMaterial = new THREE.MeshPhysicalMaterial({ - color: 0xff0000, - metalness: 1.0, - roughness: 0.5, - clearcoat: 1.0, - clearcoatRoughness: 0.03, - }); - - const detailsMaterial = new THREE.MeshStandardMaterial({ - color: 0xffffff, - metalness: 1.0, - roughness: 0.5, - }); - - const glassMaterial = new THREE.MeshPhysicalMaterial({ - color: 0xffffff, - metalness: 0.25, - roughness: 0, - transmission: 1.0, - }); - - const bodyColorInput = document.getElementById('body-color'); - bodyColorInput.addEventListener('input', function () { - bodyMaterial.color.set(this.value); - }); - - const detailsColorInput = document.getElementById('details-color'); - detailsColorInput.addEventListener('input', function () { - detailsMaterial.color.set(this.value); - }); - - const glassColorInput = document.getElementById('glass-color'); - glassColorInput.addEventListener('input', function () { - glassMaterial.color.set(this.value); - }); - - // Car - - const shadow = new THREE.TextureLoader().load('models/gltf/ferrari_ao.png'); - - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('jsm/libs/draco/gltf/'); - - const loader = new GLTFLoader(); - loader.setDRACOLoader(dracoLoader); - - loader.load('models/gltf/ferrari.glb', function (gltf) { - const carModel = gltf.scene.children[0]; - - carModel.getObjectByName('body').material = bodyMaterial; - - carModel.getObjectByName('rim_fl').material = detailsMaterial; - carModel.getObjectByName('rim_fr').material = detailsMaterial; - carModel.getObjectByName('rim_rr').material = detailsMaterial; - carModel.getObjectByName('rim_rl').material = detailsMaterial; - carModel.getObjectByName('trim').material = detailsMaterial; - - carModel.getObjectByName('glass').material = glassMaterial; - - wheels.push( - carModel.getObjectByName('wheel_fl'), - carModel.getObjectByName('wheel_fr'), - carModel.getObjectByName('wheel_rl'), - carModel.getObjectByName('wheel_rr'), - ); - - // shadow - const mesh = new THREE.Mesh( - new THREE.PlaneGeometry(0.655 * 4, 1.3 * 4), - new THREE.MeshBasicMaterial({ - map: shadow, - blending: THREE.MultiplyBlending, - toneMapped: false, - transparent: true, - }), - ); - mesh.rotation.x = -Math.PI / 2; - mesh.renderOrder = 2; - carModel.add(mesh); - - scene.add(carModel); - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - - const time = -performance.now() / 1000; - - for (let i = 0; i < wheels.length; i++) { - wheels[i].rotation.x = time * Math.PI * 2; - } - - grid.position.z = -time % 1; - - renderer.render(scene, camera); - - stats.update(); -} - -init(); diff --git a/examples-testing/examples/webgl_materials_cubemap.ts b/examples-testing/examples/webgl_materials_cubemap.ts deleted file mode 100644 index 5f2692751..000000000 --- a/examples-testing/examples/webgl_materials_cubemap.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - -let container, stats; - -let camera, scene, renderer; - -let pointLight; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 13; - - //cubemap - const path = 'textures/cube/SwedishRoyalCastle/'; - const format = '.jpg'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const reflectionCube = new THREE.CubeTextureLoader().load(urls); - const refractionCube = new THREE.CubeTextureLoader().load(urls); - refractionCube.mapping = THREE.CubeRefractionMapping; - - scene = new THREE.Scene(); - scene.background = reflectionCube; - - //lights - const ambient = new THREE.AmbientLight(0xffffff, 3); - scene.add(ambient); - - pointLight = new THREE.PointLight(0xffffff, 200); - scene.add(pointLight); - - //materials - const cubeMaterial3 = new THREE.MeshLambertMaterial({ - color: 0xffaa00, - envMap: reflectionCube, - combine: THREE.MixOperation, - reflectivity: 0.3, - }); - const cubeMaterial2 = new THREE.MeshLambertMaterial({ - color: 0xfff700, - envMap: refractionCube, - refractionRatio: 0.95, - }); - const cubeMaterial1 = new THREE.MeshLambertMaterial({ color: 0xffffff, envMap: reflectionCube }); - - //models - const objLoader = new OBJLoader(); - - objLoader.setPath('models/obj/walt/'); - objLoader.load('WaltHead.obj', function (object) { - const head = object.children[0]; - head.scale.setScalar(0.1); - head.position.y = -3; - head.material = cubeMaterial1; - - const head2 = head.clone(); - head2.position.x = -6; - head2.material = cubeMaterial2; - - const head3 = head.clone(); - head3.position.x = 6; - head3.material = cubeMaterial3; - - scene.add(head, head2, head3); - }); - - //renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - //controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enablePan = false; - controls.minPolarAngle = Math.PI / 4; - controls.maxPolarAngle = Math.PI / 1.5; - - //stats - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); - stats.update(); -} diff --git a/examples-testing/examples/webgl_materials_cubemap_dynamic.ts b/examples-testing/examples/webgl_materials_cubemap_dynamic.ts deleted file mode 100644 index 13a268901..000000000 --- a/examples-testing/examples/webgl_materials_cubemap_dynamic.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats; -let cube, sphere, torus, material; - -let cubeCamera, cubeRenderTarget; - -let controls; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResized); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 75; - - scene = new THREE.Scene(); - scene.rotation.y = 0.5; // avoid flying objects occluding the sun - - new RGBELoader().setPath('textures/equirectangular/').load('quarry_01_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - }); - - // - - cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256); - cubeRenderTarget.texture.type = THREE.HalfFloatType; - - cubeCamera = new THREE.CubeCamera(1, 1000, cubeRenderTarget); - - // - - material = new THREE.MeshStandardMaterial({ - envMap: cubeRenderTarget.texture, - roughness: 0.05, - metalness: 1, - }); - - const gui = new GUI(); - gui.add(material, 'roughness', 0, 1); - gui.add(material, 'metalness', 0, 1); - gui.add(renderer, 'toneMappingExposure', 0, 2).name('exposure'); - - sphere = new THREE.Mesh(new THREE.IcosahedronGeometry(15, 8), material); - scene.add(sphere); - - const material2 = new THREE.MeshStandardMaterial({ - roughness: 0.1, - metalness: 0, - }); - - cube = new THREE.Mesh(new THREE.BoxGeometry(15, 15, 15), material2); - scene.add(cube); - - torus = new THREE.Mesh(new THREE.TorusKnotGeometry(8, 3, 128, 16), material2); - scene.add(torus); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; -} - -function onWindowResized() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -function animate(msTime) { - const time = msTime / 1000; - - cube.position.x = Math.cos(time) * 30; - cube.position.y = Math.sin(time) * 30; - cube.position.z = Math.sin(time) * 30; - - cube.rotation.x += 0.02; - cube.rotation.y += 0.03; - - torus.position.x = Math.cos(time + 10) * 30; - torus.position.y = Math.sin(time + 10) * 30; - torus.position.z = Math.sin(time + 10) * 30; - - torus.rotation.x += 0.02; - torus.rotation.y += 0.03; - - cubeCamera.update(renderer, scene); - - controls.update(); - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts b/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts deleted file mode 100644 index 944f4c18e..000000000 --- a/examples-testing/examples/webgl_materials_cubemap_mipmaps.ts +++ /dev/null @@ -1,119 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container; - -let camera, scene, renderer; - -init(); - -//load customized cube texture -async function loadCubeTextureWithMipmaps() { - const path = 'textures/cube/angus/'; - const format = '.jpg'; - const mipmaps = []; - const maxLevel = 8; - - async function loadCubeTexture(urls) { - return new Promise(function (resolve) { - new THREE.CubeTextureLoader().load(urls, function (cubeTexture) { - resolve(cubeTexture); - }); - }); - } - - // load mipmaps - const pendings = []; - - for (let level = 0; level <= maxLevel; ++level) { - const urls = []; - - for (let face = 0; face < 6; ++face) { - urls.push(path + 'cube_m0' + level + '_c0' + face + format); - } - - const mipmapLevel = level; - - pendings.push( - loadCubeTexture(urls).then(function (cubeTexture) { - mipmaps[mipmapLevel] = cubeTexture; - }), - ); - } - - await Promise.all(pendings); - - const customizedCubeTexture = mipmaps.shift(); - customizedCubeTexture.mipmaps = mipmaps; - customizedCubeTexture.colorSpace = THREE.SRGBColorSpace; - customizedCubeTexture.minFilter = THREE.LinearMipMapLinearFilter; - customizedCubeTexture.magFilter = THREE.LinearFilter; - customizedCubeTexture.generateMipmaps = false; - customizedCubeTexture.needsUpdate = true; - - return customizedCubeTexture; -} - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 500; - - scene = new THREE.Scene(); - - loadCubeTextureWithMipmaps().then(function (cubeTexture) { - //model - const sphere = new THREE.SphereGeometry(100, 128, 128); - - //manual mipmaps - let material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: cubeTexture }); - material.name = 'manual mipmaps'; - - let mesh = new THREE.Mesh(sphere, material); - mesh.position.set(100, 0, 0); - scene.add(mesh); - - //webgl mipmaps - material = material.clone(); - material.name = 'auto mipmaps'; - - const autoCubeTexture = cubeTexture.clone(); - autoCubeTexture.mipmaps = []; - autoCubeTexture.generateMipmaps = true; - autoCubeTexture.needsUpdate = true; - - material.envMap = autoCubeTexture; - - mesh = new THREE.Mesh(sphere, material); - mesh.position.set(-100, 0, 0); - scene.add(mesh); - }); - - //renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - //controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.minPolarAngle = Math.PI / 4; - controls.maxPolarAngle = Math.PI / 1.5; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_cubemap_refraction.ts b/examples-testing/examples/webgl_materials_cubemap_refraction.ts deleted file mode 100644 index 8c025071f..000000000 --- a/examples-testing/examples/webgl_materials_cubemap_refraction.ts +++ /dev/null @@ -1,126 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; - -let container, stats; - -let camera, scene, renderer; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 100000); - camera.position.z = -4000; - - // - - const r = 'textures/cube/Park3Med/'; - - const urls = [r + 'px.jpg', r + 'nx.jpg', r + 'py.jpg', r + 'ny.jpg', r + 'pz.jpg', r + 'nz.jpg']; - - const textureCube = new THREE.CubeTextureLoader().load(urls); - textureCube.mapping = THREE.CubeRefractionMapping; - - scene = new THREE.Scene(); - scene.background = textureCube; - - // LIGHTS - - const ambient = new THREE.AmbientLight(0xffffff, 3.5); - scene.add(ambient); - - // material samples - - const cubeMaterial3 = new THREE.MeshPhongMaterial({ - color: 0xccddff, - envMap: textureCube, - refractionRatio: 0.98, - reflectivity: 0.9, - }); - const cubeMaterial2 = new THREE.MeshPhongMaterial({ color: 0xccfffd, envMap: textureCube, refractionRatio: 0.985 }); - const cubeMaterial1 = new THREE.MeshPhongMaterial({ color: 0xffffff, envMap: textureCube, refractionRatio: 0.98 }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - const loader = new PLYLoader(); - loader.load('models/ply/binary/Lucy100k.ply', function (geometry) { - createScene(geometry, cubeMaterial1, cubeMaterial2, cubeMaterial3); - }); - - document.addEventListener('mousemove', onDocumentMouseMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function createScene(geometry, m1, m2, m3) { - geometry.computeVertexNormals(); - - const s = 1.5; - - let mesh = new THREE.Mesh(geometry, m1); - mesh.scale.x = mesh.scale.y = mesh.scale.z = s; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry, m2); - mesh.position.x = -1500; - mesh.scale.x = mesh.scale.y = mesh.scale.z = s; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry, m3); - mesh.position.x = 1500; - mesh.scale.x = mesh.scale.y = mesh.scale.z = s; - scene.add(mesh); -} - -function onDocumentMouseMove(event) { - mouseX = (event.clientX - windowHalfX) * 4; - mouseY = (event.clientY - windowHalfY) * 4; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts b/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts deleted file mode 100644 index 599a1369b..000000000 --- a/examples-testing/examples/webgl_materials_cubemap_render_to_mipmaps.ts +++ /dev/null @@ -1,183 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container; -let camera, scene, renderer; - -const CubemapFilterShader = { - name: 'CubemapFilterShader', - - uniforms: { - cubeTexture: { value: null }, - mipIndex: { value: 0 }, - }, - - vertexShader: /* glsl */ ` - - varying vec3 vWorldDirection; - - #include - - void main() { - vWorldDirection = transformDirection(position, modelMatrix); - #include - #include - gl_Position.z = gl_Position.w; // set z to camera.far - } - - `, - - fragmentShader: /* glsl */ ` - - uniform samplerCube cubeTexture; - varying vec3 vWorldDirection; - - uniform float mipIndex; - - #include - - void main() { - vec3 cubeCoordinates = normalize(vWorldDirection); - - // Colorize mip levels - vec4 color = vec4(1.0, 0.0, 0.0, 1.0); - if (mipIndex == 0.0) color.rgb = vec3(1.0, 1.0, 1.0); - else if (mipIndex == 1.0) color.rgb = vec3(0.0, 0.0, 1.0); - else if (mipIndex == 2.0) color.rgb = vec3(0.0, 1.0, 1.0); - else if (mipIndex == 3.0) color.rgb = vec3(0.0, 1.0, 0.0); - else if (mipIndex == 4.0) color.rgb = vec3(1.0, 1.0, 0.0); - - gl_FragColor = textureCube(cubeTexture, cubeCoordinates, 0.0) * color; - } - - `, -}; - -init(); - -async function loadCubeTexture(urls) { - return new Promise(function (resolve) { - new THREE.CubeTextureLoader().load(urls, function (cubeTexture) { - resolve(cubeTexture); - }); - }); -} - -function allocateCubemapRenderTarget(cubeMapSize) { - const params = { - magFilter: THREE.LinearFilter, - minFilter: THREE.LinearMipMapLinearFilter, - generateMipmaps: false, - type: THREE.HalfFloatType, - format: THREE.RGBAFormat, - colorSpace: THREE.LinearSRGBColorSpace, - depthBuffer: false, - }; - - const rt = new THREE.WebGLCubeRenderTarget(cubeMapSize, params); - - const mipLevels = Math.log(cubeMapSize) * Math.LOG2E + 1.0; - for (let i = 0; i < mipLevels; i++) rt.texture.mipmaps.push({}); - - rt.texture.mapping = THREE.CubeReflectionMapping; - return rt; -} - -function renderToCubeTexture(cubeMapRenderTarget, sourceCubeTexture) { - const geometry = new THREE.BoxGeometry(5, 5, 5); - - const material = new THREE.ShaderMaterial({ - name: CubemapFilterShader.name, - uniforms: THREE.UniformsUtils.clone(CubemapFilterShader.uniforms), - vertexShader: CubemapFilterShader.vertexShader, - fragmentShader: CubemapFilterShader.fragmentShader, - side: THREE.BackSide, - blending: THREE.NoBlending, - }); - - material.uniforms.cubeTexture.value = sourceCubeTexture; - - const mesh = new THREE.Mesh(geometry, material); - const cubeCamera = new THREE.CubeCamera(1, 10, cubeMapRenderTarget); - const mipmapCount = Math.floor(Math.log2(Math.max(cubeMapRenderTarget.width, cubeMapRenderTarget.height))); - - for (let mipmap = 0; mipmap < mipmapCount; mipmap++) { - material.uniforms.mipIndex.value = mipmap; - material.needsUpdate = true; - - cubeMapRenderTarget.viewport.set( - 0, - 0, - cubeMapRenderTarget.width >> mipmap, - cubeMapRenderTarget.height >> mipmap, - ); - - cubeCamera.activeMipmapLevel = mipmap; - cubeCamera.update(renderer, mesh); - } - - mesh.geometry.dispose(); - mesh.material.dispose(); -} - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // Create renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 500; - - // Create controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.minPolarAngle = Math.PI / 4; - controls.maxPolarAngle = Math.PI / 1.5; - - window.addEventListener('resize', onWindowResize); - - // Load a cube texture - const r = 'textures/cube/Park3Med/'; - const urls = [r + 'px.jpg', r + 'nx.jpg', r + 'py.jpg', r + 'ny.jpg', r + 'pz.jpg', r + 'nz.jpg']; - - loadCubeTexture(urls).then(cubeTexture => { - // Allocate a cube map render target - const cubeMapRenderTarget = allocateCubemapRenderTarget(512); - - // Render to all the mip levels of cubeMapRenderTarget - renderToCubeTexture(cubeMapRenderTarget, cubeTexture); - - // Create geometry - const sphere = new THREE.SphereGeometry(100, 128, 128); - let material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: cubeTexture }); - - let mesh = new THREE.Mesh(sphere, material); - mesh.position.set(-100, 0, 0); - scene.add(mesh); - - material = material.clone(); - material.envMap = cubeMapRenderTarget.texture; - - mesh = new THREE.Mesh(sphere, material); - mesh.position.set(100, 0, 0); - scene.add(mesh); - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_displacementmap.ts b/examples-testing/examples/webgl_materials_displacementmap.ts deleted file mode 100644 index fd0be9a5e..000000000 --- a/examples-testing/examples/webgl_materials_displacementmap.ts +++ /dev/null @@ -1,224 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - -let stats; -let camera, scene, renderer, controls; - -const settings = { - metalness: 1.0, - roughness: 0.4, - ambientIntensity: 0.2, - aoMapIntensity: 1.0, - envMapIntensity: 1.0, - displacementScale: 2.436143, // from original model - normalScale: 1.0, -}; - -let mesh, material; - -let pointLight, ambientLight; - -const height = 500; // of camera frustum - -let r = 0.0; - -init(); -initGui(); - -// Init gui -function initGui() { - const gui = new GUI(); - //let gui = gui.addFolder( "Material" ); - gui.add(settings, 'metalness') - .min(0) - .max(1) - .onChange(function (value) { - material.metalness = value; - }); - - gui.add(settings, 'roughness') - .min(0) - .max(1) - .onChange(function (value) { - material.roughness = value; - }); - - gui.add(settings, 'aoMapIntensity') - .min(0) - .max(1) - .onChange(function (value) { - material.aoMapIntensity = value; - }); - - gui.add(settings, 'ambientIntensity') - .min(0) - .max(1) - .onChange(function (value) { - ambientLight.intensity = value; - }); - - gui.add(settings, 'envMapIntensity') - .min(0) - .max(3) - .onChange(function (value) { - material.envMapIntensity = value; - }); - - gui.add(settings, 'displacementScale') - .min(0) - .max(3.0) - .onChange(function (value) { - material.displacementScale = value; - }); - - gui.add(settings, 'normalScale') - .min(-1) - .max(1) - .onChange(function (value) { - material.normalScale.set(1, -1).multiplyScalar(value); - }); -} - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - scene = new THREE.Scene(); - - const aspect = window.innerWidth / window.innerHeight; - camera = new THREE.OrthographicCamera(-height * aspect, height * aspect, height, -height, 1, 10000); - camera.position.z = 1500; - scene.add(camera); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enableDamping = true; - - // lights - - ambientLight = new THREE.AmbientLight(0xffffff, settings.ambientIntensity); - scene.add(ambientLight); - - pointLight = new THREE.PointLight(0xff0000, 1.5, 0, 0); - pointLight.position.z = 2500; - scene.add(pointLight); - - const pointLight2 = new THREE.PointLight(0xff6666, 3, 0, 0); - camera.add(pointLight2); - - const pointLight3 = new THREE.PointLight(0x0000ff, 1.5, 0, 0); - pointLight3.position.x = -1000; - pointLight3.position.z = 1000; - scene.add(pointLight3); - - // env map - - const path = 'textures/cube/SwedishRoyalCastle/'; - const format = '.jpg'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const reflectionCube = new THREE.CubeTextureLoader().load(urls); - - // textures - - const textureLoader = new THREE.TextureLoader(); - const normalMap = textureLoader.load('models/obj/ninja/normal.png'); - const aoMap = textureLoader.load('models/obj/ninja/ao.jpg'); - const displacementMap = textureLoader.load('models/obj/ninja/displacement.jpg'); - - // material - - material = new THREE.MeshStandardMaterial({ - color: 0xc1c1c1, - roughness: settings.roughness, - metalness: settings.metalness, - - normalMap: normalMap, - normalScale: new THREE.Vector2(1, -1), // why does the normal map require negation in this case? - - aoMap: aoMap, - aoMapIntensity: 1, - - displacementMap: displacementMap, - displacementScale: settings.displacementScale, - displacementBias: -0.428408, // from original model - - envMap: reflectionCube, - envMapIntensity: settings.envMapIntensity, - - side: THREE.DoubleSide, - }); - - // - - const loader = new OBJLoader(); - loader.load('models/obj/ninja/ninjaHead_Low.obj', function (group) { - const geometry = group.children[0].geometry; - geometry.center(); - - mesh = new THREE.Mesh(geometry, material); - mesh.scale.multiplyScalar(25); - scene.add(mesh); - }); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - camera.left = -height * aspect; - camera.right = height * aspect; - camera.top = height; - camera.bottom = -height; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - controls.update(); - - stats.begin(); - render(); - stats.end(); -} - -function render() { - pointLight.position.x = 2500 * Math.cos(r); - pointLight.position.z = 2500 * Math.sin(r); - - r += 0.01; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_envmaps.ts b/examples-testing/examples/webgl_materials_envmaps.ts deleted file mode 100644 index 18a5542ed..000000000 --- a/examples-testing/examples/webgl_materials_envmaps.ts +++ /dev/null @@ -1,131 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let controls, camera, scene, renderer; -let textureEquirec, textureCube; -let sphereMesh, sphereMaterial, params; - -init(); - -function init() { - // CAMERAS - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 2.5); - - // SCENE - - scene = new THREE.Scene(); - - // Textures - - const loader = new THREE.CubeTextureLoader(); - loader.setPath('textures/cube/Bridge2/'); - - textureCube = loader.load(['posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg']); - - const textureLoader = new THREE.TextureLoader(); - - textureEquirec = textureLoader.load('textures/2294472375_24a3b8ef46_o.jpg'); - textureEquirec.mapping = THREE.EquirectangularReflectionMapping; - textureEquirec.colorSpace = THREE.SRGBColorSpace; - - scene.background = textureCube; - - // - - const geometry = new THREE.IcosahedronGeometry(1, 15); - sphereMaterial = new THREE.MeshBasicMaterial({ envMap: textureCube }); - sphereMesh = new THREE.Mesh(geometry, sphereMaterial); - scene.add(sphereMesh); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1.5; - controls.maxDistance = 6; - - // - - params = { - Cube: function () { - scene.background = textureCube; - - sphereMaterial.envMap = textureCube; - sphereMaterial.needsUpdate = true; - }, - Equirectangular: function () { - scene.background = textureEquirec; - - sphereMaterial.envMap = textureEquirec; - sphereMaterial.needsUpdate = true; - }, - Refraction: false, - backgroundRotationX: false, - backgroundRotationY: false, - backgroundRotationZ: false, - syncMaterial: false, - }; - - const gui = new GUI({ width: 300 }); - gui.add(params, 'Cube'); - gui.add(params, 'Equirectangular'); - gui.add(params, 'Refraction').onChange(function (value) { - if (value) { - textureEquirec.mapping = THREE.EquirectangularRefractionMapping; - textureCube.mapping = THREE.CubeRefractionMapping; - } else { - textureEquirec.mapping = THREE.EquirectangularReflectionMapping; - textureCube.mapping = THREE.CubeReflectionMapping; - } - - sphereMaterial.needsUpdate = true; - }); - gui.add(params, 'backgroundRotationX'); - gui.add(params, 'backgroundRotationY'); - gui.add(params, 'backgroundRotationZ'); - gui.add(params, 'syncMaterial'); - gui.open(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - if (params.backgroundRotationX) { - scene.backgroundRotation.x += 0.001; - } - - if (params.backgroundRotationY) { - scene.backgroundRotation.y += 0.001; - } - - if (params.backgroundRotationZ) { - scene.backgroundRotation.z += 0.001; - } - - if (params.syncMaterial) { - sphereMesh.material.envMapRotation.copy(scene.backgroundRotation); - } - - camera.lookAt(scene.position); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_envmaps_exr.ts b/examples-testing/examples/webgl_materials_envmaps_exr.ts deleted file mode 100644 index c3f3f4f7d..000000000 --- a/examples-testing/examples/webgl_materials_envmaps_exr.ts +++ /dev/null @@ -1,153 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { EXRLoader } from 'three/addons/loaders/EXRLoader.js'; - -const params = { - envMap: 'EXR', - roughness: 0.0, - metalness: 0.0, - exposure: 1.0, - debug: false, -}; - -let container, stats; -let camera, scene, renderer, controls; -let torusMesh, planeMesh; -let pngCubeRenderTarget, exrCubeRenderTarget; -let pngBackground, exrBackground; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 120); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - - // - - let geometry = new THREE.TorusKnotGeometry(18, 8, 150, 20); - let material = new THREE.MeshStandardMaterial({ - metalness: params.metalness, - roughness: params.roughness, - envMapIntensity: 1.0, - }); - - torusMesh = new THREE.Mesh(geometry, material); - scene.add(torusMesh); - - geometry = new THREE.PlaneGeometry(200, 200); - material = new THREE.MeshBasicMaterial(); - - planeMesh = new THREE.Mesh(geometry, material); - planeMesh.position.y = -50; - planeMesh.rotation.x = -Math.PI * 0.5; - scene.add(planeMesh); - - THREE.DefaultLoadingManager.onLoad = function () { - pmremGenerator.dispose(); - }; - - new EXRLoader().load('textures/piz_compressed.exr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture); - exrBackground = texture; - }); - - new THREE.TextureLoader().load('textures/equirectangular.png', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - texture.colorSpace = THREE.SRGBColorSpace; - - pngCubeRenderTarget = pmremGenerator.fromEquirectangular(texture); - pngBackground = texture; - }); - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - pmremGenerator.compileEquirectangularShader(); - - stats = new Stats(); - container.appendChild(stats.dom); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 50; - controls.maxDistance = 300; - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'envMap', ['EXR', 'PNG']); - gui.add(params, 'roughness', 0, 1, 0.01); - gui.add(params, 'metalness', 0, 1, 0.01); - gui.add(params, 'exposure', 0, 2, 0.01); - gui.add(params, 'debug'); - gui.open(); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - torusMesh.material.roughness = params.roughness; - torusMesh.material.metalness = params.metalness; - - let newEnvMap = torusMesh.material.envMap; - let background = scene.background; - - switch (params.envMap) { - case 'EXR': - newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null; - background = exrBackground; - break; - case 'PNG': - newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null; - background = pngBackground; - break; - } - - if (newEnvMap !== torusMesh.material.envMap) { - torusMesh.material.envMap = newEnvMap; - torusMesh.material.needsUpdate = true; - - planeMesh.material.map = newEnvMap; - planeMesh.material.needsUpdate = true; - } - - torusMesh.rotation.y += 0.005; - planeMesh.visible = params.debug; - - scene.background = background; - renderer.toneMappingExposure = params.exposure; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts b/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts deleted file mode 100644 index 48e0077f4..000000000 --- a/examples-testing/examples/webgl_materials_envmaps_groundprojected.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GroundedSkybox } from 'three/addons/objects/GroundedSkybox.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -const params = { - height: 15, - radius: 100, - enabled: true, -}; - -let camera, scene, renderer, skybox; - -init().then(render); - -async function init() { - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(-20, 7, 20); - camera.lookAt(0, 4, 0); - - scene = new THREE.Scene(); - - const hdrLoader = new RGBELoader(); - const envMap = await hdrLoader.loadAsync('textures/equirectangular/blouberg_sunrise_2_1k.hdr'); - envMap.mapping = THREE.EquirectangularReflectionMapping; - - skybox = new GroundedSkybox(envMap, params.height, params.radius); - skybox.position.y = params.height - 0.01; - scene.add(skybox); - - scene.environment = envMap; - - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('jsm/libs/draco/gltf/'); - - const loader = new GLTFLoader(); - loader.setDRACOLoader(dracoLoader); - - const shadow = new THREE.TextureLoader().load('models/gltf/ferrari_ao.png'); - - loader.load('models/gltf/ferrari.glb', function (gltf) { - const bodyMaterial = new THREE.MeshPhysicalMaterial({ - color: 0x000000, - metalness: 1.0, - roughness: 0.8, - clearcoat: 1.0, - clearcoatRoughness: 0.2, - }); - - const detailsMaterial = new THREE.MeshStandardMaterial({ - color: 0xffffff, - metalness: 1.0, - roughness: 0.5, - }); - - const glassMaterial = new THREE.MeshPhysicalMaterial({ - color: 0xffffff, - metalness: 0.25, - roughness: 0, - transmission: 1.0, - }); - - const carModel = gltf.scene.children[0]; - carModel.scale.multiplyScalar(4); - carModel.rotation.y = Math.PI; - - carModel.getObjectByName('body').material = bodyMaterial; - - carModel.getObjectByName('rim_fl').material = detailsMaterial; - carModel.getObjectByName('rim_fr').material = detailsMaterial; - carModel.getObjectByName('rim_rr').material = detailsMaterial; - carModel.getObjectByName('rim_rl').material = detailsMaterial; - carModel.getObjectByName('trim').material = detailsMaterial; - - carModel.getObjectByName('glass').material = glassMaterial; - - // shadow - const mesh = new THREE.Mesh( - new THREE.PlaneGeometry(0.655 * 4, 1.3 * 4), - new THREE.MeshBasicMaterial({ - map: shadow, - blending: THREE.MultiplyBlending, - toneMapped: false, - transparent: true, - }), - ); - mesh.rotation.x = -Math.PI / 2; - carModel.add(mesh); - - scene.add(carModel); - - render(); - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.target.set(0, 2, 0); - controls.maxPolarAngle = THREE.MathUtils.degToRad(90); - controls.maxDistance = 80; - controls.minDistance = 20; - controls.enablePan = false; - controls.update(); - - document.body.appendChild(renderer.domElement); - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'enabled') - .name('Grounded') - .onChange(function (value) { - if (value) { - scene.add(skybox); - scene.background = null; - } else { - scene.remove(skybox); - scene.background = scene.environment; - } - - render(); - }); - - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_envmaps_hdr.ts b/examples-testing/examples/webgl_materials_envmaps_hdr.ts deleted file mode 100644 index b4c6f64ef..000000000 --- a/examples-testing/examples/webgl_materials_envmaps_hdr.ts +++ /dev/null @@ -1,176 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader.js'; -import { RGBMLoader } from 'three/addons/loaders/RGBMLoader.js'; -import { DebugEnvironment } from 'three/addons/environments/DebugEnvironment.js'; - -const params = { - envMap: 'HDR', - roughness: 0.0, - metalness: 0.0, - exposure: 1.0, - debug: false, -}; - -let container, stats; -let camera, scene, renderer, controls; -let torusMesh, planeMesh; -let generatedCubeRenderTarget, ldrCubeRenderTarget, hdrCubeRenderTarget, rgbmCubeRenderTarget; -let ldrCubeMap, hdrCubeMap, rgbmCubeMap; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 120); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x000000); - - renderer = new THREE.WebGLRenderer(); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - - // - - let geometry = new THREE.TorusKnotGeometry(18, 8, 150, 20); - // let geometry = new THREE.SphereGeometry( 26, 64, 32 ); - let material = new THREE.MeshStandardMaterial({ - color: 0xffffff, - metalness: params.metalness, - roughness: params.roughness, - }); - - torusMesh = new THREE.Mesh(geometry, material); - scene.add(torusMesh); - - geometry = new THREE.PlaneGeometry(200, 200); - material = new THREE.MeshBasicMaterial(); - - planeMesh = new THREE.Mesh(geometry, material); - planeMesh.position.y = -50; - planeMesh.rotation.x = -Math.PI * 0.5; - scene.add(planeMesh); - - THREE.DefaultLoadingManager.onLoad = function () { - pmremGenerator.dispose(); - }; - - const hdrUrls = ['px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr']; - hdrCubeMap = new HDRCubeTextureLoader().setPath('./textures/cube/pisaHDR/').load(hdrUrls, function () { - hdrCubeRenderTarget = pmremGenerator.fromCubemap(hdrCubeMap); - - hdrCubeMap.magFilter = THREE.LinearFilter; - hdrCubeMap.needsUpdate = true; - }); - - const ldrUrls = ['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']; - ldrCubeMap = new THREE.CubeTextureLoader().setPath('./textures/cube/pisa/').load(ldrUrls, function () { - ldrCubeRenderTarget = pmremGenerator.fromCubemap(ldrCubeMap); - }); - - const rgbmUrls = ['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']; - rgbmCubeMap = new RGBMLoader() - .setMaxRange(16) - .setPath('./textures/cube/pisaRGBM16/') - .loadCubemap(rgbmUrls, function () { - rgbmCubeRenderTarget = pmremGenerator.fromCubemap(rgbmCubeMap); - }); - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - pmremGenerator.compileCubemapShader(); - - const envScene = new DebugEnvironment(); - generatedCubeRenderTarget = pmremGenerator.fromScene(envScene); - - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - //renderer.toneMapping = ReinhardToneMapping; - - stats = new Stats(); - container.appendChild(stats.dom); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 50; - controls.maxDistance = 300; - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - gui.add(params, 'envMap', ['Generated', 'LDR', 'HDR', 'RGBM16']); - gui.add(params, 'roughness', 0, 1, 0.01); - gui.add(params, 'metalness', 0, 1, 0.01); - gui.add(params, 'exposure', 0, 2, 0.01); - gui.add(params, 'debug'); - gui.open(); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - torusMesh.material.roughness = params.roughness; - torusMesh.material.metalness = params.metalness; - - let renderTarget, cubeMap; - - switch (params.envMap) { - case 'Generated': - renderTarget = generatedCubeRenderTarget; - cubeMap = generatedCubeRenderTarget.texture; - break; - case 'LDR': - renderTarget = ldrCubeRenderTarget; - cubeMap = ldrCubeMap; - break; - case 'HDR': - renderTarget = hdrCubeRenderTarget; - cubeMap = hdrCubeMap; - break; - case 'RGBM16': - renderTarget = rgbmCubeRenderTarget; - cubeMap = rgbmCubeMap; - break; - } - - const newEnvMap = renderTarget ? renderTarget.texture : null; - - if (newEnvMap && newEnvMap !== torusMesh.material.envMap) { - torusMesh.material.envMap = newEnvMap; - torusMesh.material.needsUpdate = true; - - planeMesh.material.map = newEnvMap; - planeMesh.material.needsUpdate = true; - } - - torusMesh.rotation.y += 0.005; - planeMesh.visible = params.debug; - - scene.background = cubeMap; - renderer.toneMappingExposure = params.exposure; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_modified.ts b/examples-testing/examples/webgl_materials_modified.ts deleted file mode 100644 index c6ee5af3c..000000000 --- a/examples-testing/examples/webgl_materials_modified.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 20; - - scene = new THREE.Scene(); - - const loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { - const geometry = gltf.scene.children[0].geometry; - - let mesh = new THREE.Mesh(geometry, buildTwistMaterial(2.0)); - mesh.position.x = -3.5; - mesh.position.y = -0.5; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry, buildTwistMaterial(-2.0)); - mesh.position.x = 3.5; - mesh.position.y = -0.5; - scene.add(mesh); - }); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 10; - controls.maxDistance = 50; - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // EVENTS - - window.addEventListener('resize', onWindowResize); -} - -function buildTwistMaterial(amount) { - const material = new THREE.MeshNormalMaterial(); - material.onBeforeCompile = function (shader) { - shader.uniforms.time = { value: 0 }; - - shader.vertexShader = 'uniform float time;\n' + shader.vertexShader; - shader.vertexShader = shader.vertexShader.replace( - '#include ', - [ - `float theta = sin( time + position.y ) / ${amount.toFixed(1)};`, - 'float c = cos( theta );', - 'float s = sin( theta );', - 'mat3 m = mat3( c, 0, s, 0, 1, 0, -s, 0, c );', - 'vec3 transformed = vec3( position ) * m;', - 'vNormal = vNormal * m;', - ].join('\n'), - ); - - material.userData.shader = shader; - }; - - // Make sure WebGLRenderer doesnt reuse a single program - - material.customProgramCacheKey = function () { - return amount.toFixed(1); - }; - - return material; -} - -// - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - scene.traverse(function (child) { - if (child.isMesh) { - const shader = child.material.userData.shader; - - if (shader) { - shader.uniforms.time.value = performance.now() / 1000; - } - } - }); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_normalmap_object_space.ts b/examples-testing/examples/webgl_materials_normalmap_object_space.ts deleted file mode 100644 index 1fc6f8066..000000000 --- a/examples-testing/examples/webgl_materials_normalmap_object_space.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let renderer, scene, camera; - -init(); - -function init() { - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(-10, 0, 23); - scene.add(camera); - - // controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.minDistance = 10; - controls.maxDistance = 50; - controls.enablePan = false; - - // ambient - scene.add(new THREE.AmbientLight(0xffffff, 0.6)); - - // light - const light = new THREE.PointLight(0xffffff, 4.5, 0, 0); - camera.add(light); - - // model - new GLTFLoader().load('models/gltf/Nefertiti/Nefertiti.glb', function (gltf) { - gltf.scene.traverse(function (child) { - if (child.isMesh) { - // glTF currently supports only tangent-space normal maps. - // this model has been modified to demonstrate the use of an object-space normal map. - - child.material.normalMapType = THREE.ObjectSpaceNormalMap; - - // attribute normals are not required with an object-space normal map. remove them. - - child.geometry.deleteAttribute('normal'); - - // - - child.material.side = THREE.DoubleSide; - - child.scale.multiplyScalar(0.5); - - // recenter - - new THREE.Box3().setFromObject(child).getCenter(child.position).multiplyScalar(-1); - - scene.add(child); - } - }); - - render(); - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_physical_clearcoat.ts b/examples-testing/examples/webgl_materials_physical_clearcoat.ts deleted file mode 100644 index 408fd9921..000000000 --- a/examples-testing/examples/webgl_materials_physical_clearcoat.ts +++ /dev/null @@ -1,208 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader.js'; - -import { FlakesTexture } from 'three/addons/textures/FlakesTexture.js'; - -let container, stats; - -let camera, scene, renderer; - -let particleLight; -let group; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 0.25, 50); - camera.position.z = 10; - - scene = new THREE.Scene(); - - group = new THREE.Group(); - scene.add(group); - - new HDRCubeTextureLoader() - .setPath('textures/cube/pisaHDR/') - .load(['px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr'], function (texture) { - const geometry = new THREE.SphereGeometry(0.8, 64, 32); - - const textureLoader = new THREE.TextureLoader(); - - const diffuse = textureLoader.load('textures/carbon/Carbon.png'); - diffuse.colorSpace = THREE.SRGBColorSpace; - diffuse.wrapS = THREE.RepeatWrapping; - diffuse.wrapT = THREE.RepeatWrapping; - diffuse.repeat.x = 10; - diffuse.repeat.y = 10; - - const normalMap = textureLoader.load('textures/carbon/Carbon_Normal.png'); - normalMap.wrapS = THREE.RepeatWrapping; - normalMap.wrapT = THREE.RepeatWrapping; - normalMap.repeat.x = 10; - normalMap.repeat.y = 10; - - const normalMap2 = textureLoader.load('textures/water/Water_1_M_Normal.jpg'); - - const normalMap3 = new THREE.CanvasTexture(new FlakesTexture()); - normalMap3.wrapS = THREE.RepeatWrapping; - normalMap3.wrapT = THREE.RepeatWrapping; - normalMap3.repeat.x = 10; - normalMap3.repeat.y = 6; - normalMap3.anisotropy = 16; - - const normalMap4 = textureLoader.load('textures/golfball.jpg'); - - const clearcoatNormalMap = textureLoader.load( - 'textures/pbr/Scratched_gold/Scratched_gold_01_1K_Normal.png', - ); - - // car paint - - let material = new THREE.MeshPhysicalMaterial({ - clearcoat: 1.0, - clearcoatRoughness: 0.1, - metalness: 0.9, - roughness: 0.5, - color: 0x0000ff, - normalMap: normalMap3, - normalScale: new THREE.Vector2(0.15, 0.15), - }); - - let mesh = new THREE.Mesh(geometry, material); - mesh.position.x = -1; - mesh.position.y = 1; - group.add(mesh); - - // fibers - - material = new THREE.MeshPhysicalMaterial({ - roughness: 0.5, - clearcoat: 1.0, - clearcoatRoughness: 0.1, - map: diffuse, - normalMap: normalMap, - }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.x = 1; - mesh.position.y = 1; - group.add(mesh); - - // golf - - material = new THREE.MeshPhysicalMaterial({ - metalness: 0.0, - roughness: 0.1, - clearcoat: 1.0, - normalMap: normalMap4, - clearcoatNormalMap: clearcoatNormalMap, - - // y scale is negated to compensate for normal map handedness. - clearcoatNormalScale: new THREE.Vector2(2.0, -2.0), - }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.x = -1; - mesh.position.y = -1; - group.add(mesh); - - // clearcoat + normalmap - - material = new THREE.MeshPhysicalMaterial({ - clearcoat: 1.0, - metalness: 1.0, - color: 0xff0000, - normalMap: normalMap2, - normalScale: new THREE.Vector2(0.15, 0.15), - clearcoatNormalMap: clearcoatNormalMap, - - // y scale is negated to compensate for normal map handedness. - clearcoatNormalScale: new THREE.Vector2(2.0, -2.0), - }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.x = 1; - mesh.position.y = -1; - group.add(mesh); - - // - - scene.background = texture; - scene.environment = texture; - }); - - // LIGHTS - - particleLight = new THREE.Mesh( - new THREE.SphereGeometry(0.05, 8, 8), - new THREE.MeshBasicMaterial({ color: 0xffffff }), - ); - scene.add(particleLight); - - particleLight.add(new THREE.PointLight(0xffffff, 30)); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1.25; - - // - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // EVENTS - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 3; - controls.maxDistance = 30; - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - const timer = Date.now() * 0.00025; - - particleLight.position.x = Math.sin(timer * 7) * 3; - particleLight.position.y = Math.cos(timer * 5) * 4; - particleLight.position.z = Math.cos(timer * 3) * 3; - - for (let i = 0; i < group.children.length; i++) { - const child = group.children[i]; - child.rotation.y += 0.005; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_physical_transmission.ts b/examples-testing/examples/webgl_materials_physical_transmission.ts deleted file mode 100644 index d45967971..000000000 --- a/examples-testing/examples/webgl_materials_physical_transmission.ts +++ /dev/null @@ -1,182 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -const params = { - color: 0xffffff, - transmission: 1, - opacity: 1, - metalness: 0, - roughness: 0, - ior: 1.5, - thickness: 0.01, - specularIntensity: 1, - specularColor: 0xffffff, - envMapIntensity: 1, - lightIntensity: 1, - exposure: 1, -}; - -let camera, scene, renderer; - -let mesh; - -const hdrEquirect = new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function () { - hdrEquirect.mapping = THREE.EquirectangularReflectionMapping; - - init(); - render(); -}); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = params.exposure; - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(0, 0, 120); - - // - - scene.background = hdrEquirect; - - // - - const geometry = new THREE.SphereGeometry(20, 64, 32); - - const texture = new THREE.CanvasTexture(generateTexture()); - texture.magFilter = THREE.NearestFilter; - texture.wrapT = THREE.RepeatWrapping; - texture.wrapS = THREE.RepeatWrapping; - texture.repeat.set(1, 3.5); - - const material = new THREE.MeshPhysicalMaterial({ - color: params.color, - metalness: params.metalness, - roughness: params.roughness, - ior: params.ior, - alphaMap: texture, - envMap: hdrEquirect, - envMapIntensity: params.envMapIntensity, - transmission: params.transmission, // use material.transmission for glass materials - specularIntensity: params.specularIntensity, - specularColor: params.specularColor, - opacity: params.opacity, - side: THREE.DoubleSide, - transparent: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 10; - controls.maxDistance = 150; - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - - gui.addColor(params, 'color').onChange(function () { - material.color.set(params.color); - render(); - }); - - gui.add(params, 'transmission', 0, 1, 0.01).onChange(function () { - material.transmission = params.transmission; - render(); - }); - - gui.add(params, 'opacity', 0, 1, 0.01).onChange(function () { - material.opacity = params.opacity; - render(); - }); - - gui.add(params, 'metalness', 0, 1, 0.01).onChange(function () { - material.metalness = params.metalness; - render(); - }); - - gui.add(params, 'roughness', 0, 1, 0.01).onChange(function () { - material.roughness = params.roughness; - render(); - }); - - gui.add(params, 'ior', 1, 2, 0.01).onChange(function () { - material.ior = params.ior; - render(); - }); - - gui.add(params, 'thickness', 0, 5, 0.01).onChange(function () { - material.thickness = params.thickness; - render(); - }); - - gui.add(params, 'specularIntensity', 0, 1, 0.01).onChange(function () { - material.specularIntensity = params.specularIntensity; - render(); - }); - - gui.addColor(params, 'specularColor').onChange(function () { - material.specularColor.set(params.specularColor); - render(); - }); - - gui.add(params, 'envMapIntensity', 0, 1, 0.01) - .name('envMap intensity') - .onChange(function () { - material.envMapIntensity = params.envMapIntensity; - render(); - }); - - gui.add(params, 'exposure', 0, 1, 0.01).onChange(function () { - renderer.toneMappingExposure = params.exposure; - render(); - }); - - gui.open(); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - - render(); -} - -// - -function generateTexture() { - const canvas = document.createElement('canvas'); - canvas.width = 2; - canvas.height = 2; - - const context = canvas.getContext('2d'); - context.fillStyle = 'white'; - context.fillRect(0, 1, 2, 1); - - return canvas; -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts b/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts deleted file mode 100644 index d81f59c37..000000000 --- a/examples-testing/examples/webgl_materials_physical_transmission_alpha.ts +++ /dev/null @@ -1,192 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -const params = { - color: 0xffffff, - transmission: 1, - opacity: 1, - metalness: 0, - roughness: 0, - ior: 1.5, - thickness: 0.01, - attenuationColor: 0xffffff, - attenuationDistance: 1, - specularIntensity: 1, - specularColor: 0xffffff, - envMapIntensity: 1, - lightIntensity: 1, - exposure: 1, -}; - -let camera, scene, renderer; - -let mesh, material; - -const hdrEquirect = new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function () { - hdrEquirect.mapping = THREE.EquirectangularReflectionMapping; - - new GLTFLoader().setPath('models/gltf/').load('DragonAttenuation.glb', function (gltf) { - gltf.scene.traverse(function (child) { - if (child.isMesh && child.material.isMeshPhysicalMaterial) { - mesh = child; - material = mesh.material; - - const color = new THREE.Color(); - - params.color = color.copy(mesh.material.color).getHex(); - params.roughness = mesh.material.roughness; - params.metalness = mesh.material.metalness; - - params.ior = mesh.material.ior; - params.specularIntensity = mesh.material.specularIntensity; - - params.transmission = mesh.material.transmission; - params.thickness = mesh.material.thickness; - params.attenuationColor = color.copy(mesh.material.attenuationColor).getHex(); - params.attenuationDistance = mesh.material.attenuationDistance; - } - }); - - init(); - - scene.add(gltf.scene); - - scene.environment = hdrEquirect; - //scene.background = hdrEquirect; - - render(); - }); -}); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = params.exposure; - - // accommodate CSS table - renderer.domElement.style.position = 'absolute'; - renderer.domElement.style.top = 0; - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(-5, 0.5, 0); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 5; - controls.maxDistance = 20; - controls.target.y = 0.5; - controls.update(); - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - - gui.addColor(params, 'color').onChange(function () { - material.color.set(params.color); - render(); - }); - - gui.add(params, 'transmission', 0, 1, 0.01).onChange(function () { - material.transmission = params.transmission; - render(); - }); - - gui.add(params, 'opacity', 0, 1, 0.01).onChange(function () { - material.opacity = params.opacity; - const transparent = params.opacity < 1; - - if (transparent !== material.transparent) { - material.transparent = transparent; - material.needsUpdate = true; - } - - render(); - }); - - gui.add(params, 'metalness', 0, 1, 0.01).onChange(function () { - material.metalness = params.metalness; - render(); - }); - - gui.add(params, 'roughness', 0, 1, 0.01).onChange(function () { - material.roughness = params.roughness; - render(); - }); - - gui.add(params, 'ior', 1, 2, 0.01).onChange(function () { - material.ior = params.ior; - render(); - }); - - gui.add(params, 'thickness', 0, 5, 0.01).onChange(function () { - material.thickness = params.thickness; - render(); - }); - - gui.addColor(params, 'attenuationColor') - .name('attenuation color') - .onChange(function () { - material.attenuationColor.set(params.attenuationColor); - render(); - }); - - gui.add(params, 'attenuationDistance', 0, 1, 0.01).onChange(function () { - material.attenuationDistance = params.attenuationDistance; - render(); - }); - - gui.add(params, 'specularIntensity', 0, 1, 0.01).onChange(function () { - material.specularIntensity = params.specularIntensity; - render(); - }); - - gui.addColor(params, 'specularColor').onChange(function () { - material.specularColor.set(params.specularColor); - render(); - }); - - gui.add(params, 'envMapIntensity', 0, 1, 0.01) - .name('envMap intensity') - .onChange(function () { - material.envMapIntensity = params.envMapIntensity; - render(); - }); - - gui.add(params, 'exposure', 0, 1, 0.01).onChange(function () { - renderer.toneMappingExposure = params.exposure; - render(); - }); - - gui.open(); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - - render(); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_texture_anisotropy.ts b/examples-testing/examples/webgl_materials_texture_anisotropy.ts deleted file mode 100644 index 1e030d64d..000000000 --- a/examples-testing/examples/webgl_materials_texture_anisotropy.ts +++ /dev/null @@ -1,143 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -const SCREEN_WIDTH = window.innerWidth; -const SCREEN_HEIGHT = window.innerHeight; - -let container, stats; - -let camera, scene1, scene2, renderer; - -let mouseX = 0, - mouseY = 0; - -const windowHalfX = window.innerWidth / 2; -const windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - - // - - camera = new THREE.PerspectiveCamera(35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 25000); - camera.position.z = 1500; - - scene1 = new THREE.Scene(); - scene1.background = new THREE.Color(0xf2f7ff); - scene1.fog = new THREE.Fog(0xf2f7ff, 1, 25000); - - scene2 = new THREE.Scene(); - scene2.background = new THREE.Color(0xf2f7ff); - scene2.fog = new THREE.Fog(0xf2f7ff, 1, 25000); - - scene1.add(new THREE.AmbientLight(0xeef0ff, 3)); - scene2.add(new THREE.AmbientLight(0xeef0ff, 3)); - - const light1 = new THREE.DirectionalLight(0xffffff, 6); - light1.position.set(1, 1, 1); - scene1.add(light1); - - const light2 = new THREE.DirectionalLight(0xffffff, 6); - light2.position.set(1, 1, 1); - scene2.add(light2); - - // GROUND - - const textureLoader = new THREE.TextureLoader(); - - const maxAnisotropy = renderer.capabilities.getMaxAnisotropy(); - - const texture1 = textureLoader.load('textures/crate.gif'); - const material1 = new THREE.MeshPhongMaterial({ color: 0xffffff, map: texture1 }); - - texture1.colorSpace = THREE.SRGBColorSpace; - texture1.anisotropy = maxAnisotropy; - texture1.wrapS = texture1.wrapT = THREE.RepeatWrapping; - texture1.repeat.set(512, 512); - - const texture2 = textureLoader.load('textures/crate.gif'); - const material2 = new THREE.MeshPhongMaterial({ color: 0xffffff, map: texture2 }); - - texture2.colorSpace = THREE.SRGBColorSpace; - texture2.anisotropy = 1; - texture2.wrapS = texture2.wrapT = THREE.RepeatWrapping; - texture2.repeat.set(512, 512); - - if (maxAnisotropy > 0) { - document.getElementById('val_left').innerHTML = texture1.anisotropy; - document.getElementById('val_right').innerHTML = texture2.anisotropy; - } else { - document.getElementById('val_left').innerHTML = 'not supported'; - document.getElementById('val_right').innerHTML = 'not supported'; - } - - // - - const geometry = new THREE.PlaneGeometry(100, 100); - - const mesh1 = new THREE.Mesh(geometry, material1); - mesh1.rotation.x = -Math.PI / 2; - mesh1.scale.set(1000, 1000, 1000); - - const mesh2 = new THREE.Mesh(geometry, material2); - mesh2.rotation.x = -Math.PI / 2; - mesh2.scale.set(1000, 1000, 1000); - - scene1.add(mesh1); - scene2.add(mesh2); - - // RENDERER - - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - renderer.domElement.style.position = 'relative'; - container.appendChild(renderer.domElement); - - // STATS1 - - stats = new Stats(); - container.appendChild(stats.dom); - - document.addEventListener('mousemove', onDocumentMouseMove); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -function animate() { - render(); - stats.update(); -} - -function render() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y = THREE.MathUtils.clamp( - camera.position.y + (-(mouseY - 200) - camera.position.y) * 0.05, - 50, - 1000, - ); - - camera.lookAt(scene1.position); - - renderer.clear(); - renderer.setScissorTest(true); - - renderer.setScissor(0, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene1, camera); - - renderer.setScissor(SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene2, camera); - - renderer.setScissorTest(false); -} diff --git a/examples-testing/examples/webgl_materials_texture_canvas.ts b/examples-testing/examples/webgl_materials_texture_canvas.ts deleted file mode 100644 index d23c68436..000000000 --- a/examples-testing/examples/webgl_materials_texture_canvas.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, mesh, material; -const drawStartPos = new THREE.Vector2(); - -init(); -setupCanvasDrawing(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.z = 500; - - scene = new THREE.Scene(); - - material = new THREE.MeshBasicMaterial(); - - mesh = new THREE.Mesh(new THREE.BoxGeometry(200, 200, 200), material); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -// Sets up the drawing canvas and adds it as the material map - -function setupCanvasDrawing() { - // get canvas and context - - const drawingCanvas = document.getElementById('drawing-canvas'); - const drawingContext = drawingCanvas.getContext('2d'); - - // draw white background - - drawingContext.fillStyle = '#FFFFFF'; - drawingContext.fillRect(0, 0, 128, 128); - - // set canvas as material.map (this could be done to any map, bump, displacement etc.) - - material.map = new THREE.CanvasTexture(drawingCanvas); - - // set the variable to keep track of when to draw - - let paint = false; - - // add canvas event listeners - drawingCanvas.addEventListener('pointerdown', function (e) { - paint = true; - drawStartPos.set(e.offsetX, e.offsetY); - }); - - drawingCanvas.addEventListener('pointermove', function (e) { - if (paint) draw(drawingContext, e.offsetX, e.offsetY); - }); - - drawingCanvas.addEventListener('pointerup', function () { - paint = false; - }); - - drawingCanvas.addEventListener('pointerleave', function () { - paint = false; - }); -} - -function draw(drawContext, x, y) { - drawContext.moveTo(drawStartPos.x, drawStartPos.y); - drawContext.strokeStyle = '#000000'; - drawContext.lineTo(x, y); - drawContext.stroke(); - // reset drawing start position to current position. - drawStartPos.set(x, y); - // need to flag the map as needing updating. - material.map.needsUpdate = true; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - mesh.rotation.x += 0.01; - mesh.rotation.y += 0.01; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_texture_filters.ts b/examples-testing/examples/webgl_materials_texture_filters.ts deleted file mode 100644 index 178c2ce49..000000000 --- a/examples-testing/examples/webgl_materials_texture_filters.ts +++ /dev/null @@ -1,164 +0,0 @@ -import * as THREE from 'three'; - -const SCREEN_WIDTH = window.innerWidth; -const SCREEN_HEIGHT = window.innerHeight; - -let container; - -let camera, scene, scene2, renderer; - -let mouseX = 0, - mouseY = 0; - -const windowHalfX = window.innerWidth / 2; -const windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 5000); - camera.position.z = 1500; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x000000); - scene.fog = new THREE.Fog(0x000000, 1500, 4000); - - scene2 = new THREE.Scene(); - scene2.background = new THREE.Color(0x000000); - scene2.fog = new THREE.Fog(0x000000, 1500, 4000); - - // GROUND - - const imageCanvas = document.createElement('canvas'); - const context = imageCanvas.getContext('2d'); - - imageCanvas.width = imageCanvas.height = 128; - - context.fillStyle = '#444'; - context.fillRect(0, 0, 128, 128); - - context.fillStyle = '#fff'; - context.fillRect(0, 0, 64, 64); - context.fillRect(64, 64, 64, 64); - - const textureCanvas = new THREE.CanvasTexture(imageCanvas); - textureCanvas.colorSpace = THREE.SRGBColorSpace; - textureCanvas.repeat.set(1000, 1000); - textureCanvas.wrapS = THREE.RepeatWrapping; - textureCanvas.wrapT = THREE.RepeatWrapping; - - const textureCanvas2 = textureCanvas.clone(); - textureCanvas2.magFilter = THREE.NearestFilter; - textureCanvas2.minFilter = THREE.NearestFilter; - - const materialCanvas = new THREE.MeshBasicMaterial({ map: textureCanvas }); - const materialCanvas2 = new THREE.MeshBasicMaterial({ color: 0xffccaa, map: textureCanvas2 }); - - const geometry = new THREE.PlaneGeometry(100, 100); - - const meshCanvas = new THREE.Mesh(geometry, materialCanvas); - meshCanvas.rotation.x = -Math.PI / 2; - meshCanvas.scale.set(1000, 1000, 1000); - - const meshCanvas2 = new THREE.Mesh(geometry, materialCanvas2); - meshCanvas2.rotation.x = -Math.PI / 2; - meshCanvas2.scale.set(1000, 1000, 1000); - - // PAINTING - - const callbackPainting = function () { - const image = texturePainting.image; - - texturePainting2.image = image; - texturePainting2.needsUpdate = true; - - scene.add(meshCanvas); - scene2.add(meshCanvas2); - - const geometry = new THREE.PlaneGeometry(100, 100); - const mesh = new THREE.Mesh(geometry, materialPainting); - const mesh2 = new THREE.Mesh(geometry, materialPainting2); - - addPainting(scene, mesh); - addPainting(scene2, mesh2); - - function addPainting(zscene, zmesh) { - zmesh.scale.x = image.width / 100; - zmesh.scale.y = image.height / 100; - - zscene.add(zmesh); - - const meshFrame = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: 0x000000 })); - meshFrame.position.z = -10.0; - meshFrame.scale.x = (1.1 * image.width) / 100; - meshFrame.scale.y = (1.1 * image.height) / 100; - zscene.add(meshFrame); - - const meshShadow = new THREE.Mesh( - geometry, - new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.75, transparent: true }), - ); - meshShadow.position.y = (-1.1 * image.height) / 2; - meshShadow.position.z = (-1.1 * image.height) / 2; - meshShadow.rotation.x = -Math.PI / 2; - meshShadow.scale.x = (1.1 * image.width) / 100; - meshShadow.scale.y = (1.1 * image.height) / 100; - zscene.add(meshShadow); - - const floorHeight = (-1.117 * image.height) / 2; - meshCanvas.position.y = meshCanvas2.position.y = floorHeight; - } - }; - - const texturePainting = new THREE.TextureLoader().load( - 'textures/758px-Canestra_di_frutta_(Caravaggio).jpg', - callbackPainting, - ); - const texturePainting2 = new THREE.Texture(); - - const materialPainting = new THREE.MeshBasicMaterial({ color: 0xffffff, map: texturePainting }); - const materialPainting2 = new THREE.MeshBasicMaterial({ color: 0xffccaa, map: texturePainting2 }); - - texturePainting.colorSpace = THREE.SRGBColorSpace; - texturePainting2.colorSpace = THREE.SRGBColorSpace; - texturePainting2.minFilter = texturePainting2.magFilter = THREE.NearestFilter; - texturePainting.minFilter = texturePainting.magFilter = THREE.LinearFilter; - texturePainting.mapping = THREE.UVMapping; - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - renderer.domElement.style.position = 'relative'; - container.appendChild(renderer.domElement); - - document.addEventListener('mousemove', onDocumentMouseMove); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -function animate() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-(mouseY - 200) - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - renderer.clear(); - renderer.setScissorTest(true); - - renderer.setScissor(0, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene, camera); - - renderer.setScissor(SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene2, camera); - - renderer.setScissorTest(false); -} diff --git a/examples-testing/examples/webgl_materials_texture_manualmipmap.ts b/examples-testing/examples/webgl_materials_texture_manualmipmap.ts deleted file mode 100644 index 24bd4eb9f..000000000 --- a/examples-testing/examples/webgl_materials_texture_manualmipmap.ts +++ /dev/null @@ -1,175 +0,0 @@ -import * as THREE from 'three'; - -const SCREEN_WIDTH = window.innerWidth; -const SCREEN_HEIGHT = window.innerHeight; - -let container; - -let camera, scene1, scene2, renderer; - -let mouseX = 0, - mouseY = 0; - -const windowHalfX = window.innerWidth / 2; -const windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 5000); - camera.position.z = 1500; - - scene1 = new THREE.Scene(); - scene1.background = new THREE.Color(0x000000); - scene1.fog = new THREE.Fog(0x000000, 1500, 4000); - - scene2 = new THREE.Scene(); - scene2.background = new THREE.Color(0x000000); - scene2.fog = new THREE.Fog(0x000000, 1500, 4000); - - // GROUND - - function mipmap(size, color) { - const imageCanvas = document.createElement('canvas'); - const context = imageCanvas.getContext('2d'); - - imageCanvas.width = imageCanvas.height = size; - - context.fillStyle = '#444'; - context.fillRect(0, 0, size, size); - - context.fillStyle = color; - context.fillRect(0, 0, size / 2, size / 2); - context.fillRect(size / 2, size / 2, size / 2, size / 2); - return imageCanvas; - } - - const canvas = mipmap(128, '#f00'); - const textureCanvas1 = new THREE.CanvasTexture(canvas); - textureCanvas1.mipmaps[0] = canvas; - textureCanvas1.mipmaps[1] = mipmap(64, '#0f0'); - textureCanvas1.mipmaps[2] = mipmap(32, '#00f'); - textureCanvas1.mipmaps[3] = mipmap(16, '#400'); - textureCanvas1.mipmaps[4] = mipmap(8, '#040'); - textureCanvas1.mipmaps[5] = mipmap(4, '#004'); - textureCanvas1.mipmaps[6] = mipmap(2, '#044'); - textureCanvas1.mipmaps[7] = mipmap(1, '#404'); - textureCanvas1.colorSpace = THREE.SRGBColorSpace; - textureCanvas1.repeat.set(1000, 1000); - textureCanvas1.wrapS = THREE.RepeatWrapping; - textureCanvas1.wrapT = THREE.RepeatWrapping; - - const textureCanvas2 = textureCanvas1.clone(); - textureCanvas2.magFilter = THREE.NearestFilter; - textureCanvas2.minFilter = THREE.NearestMipmapNearestFilter; - - const materialCanvas1 = new THREE.MeshBasicMaterial({ map: textureCanvas1 }); - const materialCanvas2 = new THREE.MeshBasicMaterial({ color: 0xffccaa, map: textureCanvas2 }); - - const geometry = new THREE.PlaneGeometry(100, 100); - - const meshCanvas1 = new THREE.Mesh(geometry, materialCanvas1); - meshCanvas1.rotation.x = -Math.PI / 2; - meshCanvas1.scale.set(1000, 1000, 1000); - - const meshCanvas2 = new THREE.Mesh(geometry, materialCanvas2); - meshCanvas2.rotation.x = -Math.PI / 2; - meshCanvas2.scale.set(1000, 1000, 1000); - - // PAINTING - - const callbackPainting = function () { - const image = texturePainting1.image; - - texturePainting2.image = image; - texturePainting2.needsUpdate = true; - - scene1.add(meshCanvas1); - scene2.add(meshCanvas2); - - const geometry = new THREE.PlaneGeometry(100, 100); - const mesh1 = new THREE.Mesh(geometry, materialPainting1); - const mesh2 = new THREE.Mesh(geometry, materialPainting2); - - addPainting(scene1, mesh1); - addPainting(scene2, mesh2); - - function addPainting(zscene, zmesh) { - zmesh.scale.x = image.width / 100; - zmesh.scale.y = image.height / 100; - - zscene.add(zmesh); - - const meshFrame = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: 0x000000 })); - meshFrame.position.z = -10.0; - meshFrame.scale.x = (1.1 * image.width) / 100; - meshFrame.scale.y = (1.1 * image.height) / 100; - zscene.add(meshFrame); - - const meshShadow = new THREE.Mesh( - geometry, - new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.75, transparent: true }), - ); - meshShadow.position.y = (-1.1 * image.height) / 2; - meshShadow.position.z = (-1.1 * image.height) / 2; - meshShadow.rotation.x = -Math.PI / 2; - meshShadow.scale.x = (1.1 * image.width) / 100; - meshShadow.scale.y = (1.1 * image.height) / 100; - zscene.add(meshShadow); - - const floorHeight = (-1.117 * image.height) / 2; - meshCanvas1.position.y = meshCanvas2.position.y = floorHeight; - } - }; - - const texturePainting1 = new THREE.TextureLoader().load( - 'textures/758px-Canestra_di_frutta_(Caravaggio).jpg', - callbackPainting, - ); - const texturePainting2 = new THREE.Texture(); - const materialPainting1 = new THREE.MeshBasicMaterial({ color: 0xffffff, map: texturePainting1 }); - const materialPainting2 = new THREE.MeshBasicMaterial({ color: 0xffccaa, map: texturePainting2 }); - - texturePainting1.colorSpace = THREE.SRGBColorSpace; - texturePainting2.colorSpace = THREE.SRGBColorSpace; - texturePainting2.minFilter = texturePainting2.magFilter = THREE.NearestFilter; - texturePainting1.minFilter = texturePainting1.magFilter = THREE.LinearFilter; - texturePainting1.mapping = THREE.UVMapping; - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - renderer.domElement.style.position = 'relative'; - container.appendChild(renderer.domElement); - - document.addEventListener('mousemove', onDocumentMouseMove); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -function animate() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-(mouseY - 200) - camera.position.y) * 0.05; - - camera.lookAt(scene1.position); - - renderer.clear(); - renderer.setScissorTest(true); - - renderer.setScissor(0, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene1, camera); - - renderer.setScissor(SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene2, camera); - - renderer.setScissorTest(false); -} diff --git a/examples-testing/examples/webgl_materials_texture_partialupdate.ts b/examples-testing/examples/webgl_materials_texture_partialupdate.ts deleted file mode 100644 index 5adfc8e69..000000000 --- a/examples-testing/examples/webgl_materials_texture_partialupdate.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, clock, dataTexture, diffuseMap; - -let last = 0; -const position = new THREE.Vector2(); -const color = new THREE.Color(); - -init(); - -async function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.z = 2; - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - const loader = new THREE.TextureLoader(); - diffuseMap = await loader.loadAsync('textures/floors/FloorsCheckerboard_S_Diffuse.jpg'); - diffuseMap.colorSpace = THREE.SRGBColorSpace; - diffuseMap.minFilter = THREE.LinearFilter; - diffuseMap.generateMipmaps = false; - - const geometry = new THREE.PlaneGeometry(2, 2); - const material = new THREE.MeshBasicMaterial({ map: diffuseMap }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const width = 32; - const height = 32; - - const data = new Uint8Array(width * height * 4); - dataTexture = new THREE.DataTexture(data, width, height); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const elapsedTime = clock.getElapsedTime(); - - if (elapsedTime - last > 0.1) { - last = elapsedTime; - - position.x = 32 * THREE.MathUtils.randInt(1, 16) - 32; - position.y = 32 * THREE.MathUtils.randInt(1, 16) - 32; - - // generate new color data - - updateDataTexture(dataTexture); - - // perform copy from src to dest texture to a random position - - renderer.copyTextureToTexture(dataTexture, diffuseMap, null, position); - } - - renderer.render(scene, camera); -} - -function updateDataTexture(texture) { - const size = texture.image.width * texture.image.height; - const data = texture.image.data; - - // generate a random color and update texture data - - color.setHex(Math.random() * 0xffffff); - - const r = Math.floor(color.r * 255); - const g = Math.floor(color.g * 255); - const b = Math.floor(color.b * 255); - - for (let i = 0; i < size; i++) { - const stride = i * 4; - - data[stride] = r; - data[stride + 1] = g; - data[stride + 2] = b; - data[stride + 3] = 1; - } -} diff --git a/examples-testing/examples/webgl_materials_texture_rotation.ts b/examples-testing/examples/webgl_materials_texture_rotation.ts deleted file mode 100644 index 2666d09d6..000000000 --- a/examples-testing/examples/webgl_materials_texture_rotation.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let mesh, renderer, scene, camera; - -let gui; - -const API = { - offsetX: 0, - offsetY: 0, - repeatX: 0.25, - repeatY: 0.25, - rotation: Math.PI / 4, // positive is counterclockwise - centerX: 0.5, - centerY: 0.5, -}; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(10, 15, 25); - scene.add(camera); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.minDistance = 20; - controls.maxDistance = 50; - controls.maxPolarAngle = Math.PI / 2; - - const geometry = new THREE.BoxGeometry(10, 10, 10); - - new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg', function (texture) { - texture.wrapS = texture.wrapT = THREE.RepeatWrapping; - texture.anisotropy = renderer.capabilities.getMaxAnisotropy(); - texture.colorSpace = THREE.SRGBColorSpace; - - //texture.matrixAutoUpdate = false; // default true; set to false to update texture.matrix manually - - const material = new THREE.MeshBasicMaterial({ map: texture }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - updateUvTransform(); - - initGui(); - - render(); - }); - - window.addEventListener('resize', onWindowResize); -} - -function render() { - renderer.render(scene, camera); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function updateUvTransform() { - const texture = mesh.material.map; - - if (texture.matrixAutoUpdate === true) { - texture.offset.set(API.offsetX, API.offsetY); - texture.repeat.set(API.repeatX, API.repeatY); - texture.center.set(API.centerX, API.centerY); - texture.rotation = API.rotation; // rotation is around center - } else { - // setting the matrix uv transform directly - //texture.matrix.setUvTransform( API.offsetX, API.offsetY, API.repeatX, API.repeatY, API.rotation, API.centerX, API.centerY ); - - // another way... - texture.matrix - .identity() - .translate(-API.centerX, -API.centerY) - .rotate(API.rotation) // I don't understand how rotation can preceed scale, but it seems to be required... - .scale(API.repeatX, API.repeatY) - .translate(API.centerX, API.centerY) - .translate(API.offsetX, API.offsetY); - } - - render(); -} - -function initGui() { - gui = new GUI(); - - gui.add(API, 'offsetX', 0.0, 1.0).name('offset.x').onChange(updateUvTransform); - gui.add(API, 'offsetY', 0.0, 1.0).name('offset.y').onChange(updateUvTransform); - gui.add(API, 'repeatX', 0.25, 2.0).name('repeat.x').onChange(updateUvTransform); - gui.add(API, 'repeatY', 0.25, 2.0).name('repeat.y').onChange(updateUvTransform); - gui.add(API, 'rotation', -2.0, 2.0).name('rotation').onChange(updateUvTransform); - gui.add(API, 'centerX', 0.0, 1.0).name('center.x').onChange(updateUvTransform); - gui.add(API, 'centerY', 0.0, 1.0).name('center.y').onChange(updateUvTransform); -} diff --git a/examples-testing/examples/webgl_materials_toon.ts b/examples-testing/examples/webgl_materials_toon.ts deleted file mode 100644 index 03db286ad..000000000 --- a/examples-testing/examples/webgl_materials_toon.ts +++ /dev/null @@ -1,152 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OutlineEffect } from 'three/addons/effects/OutlineEffect.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -let container, stats; - -let camera, scene, renderer, effect; -let particleLight; - -const loader = new FontLoader(); -loader.load('fonts/gentilis_regular.typeface.json', function (font) { - init(font); -}); - -function init(font) { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 2500); - camera.position.set(0.0, 400, 400 * 3.5); - - // - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x444488); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // Materials - - const cubeWidth = 400; - const numberOfSphersPerSide = 5; - const sphereRadius = (cubeWidth / numberOfSphersPerSide) * 0.8 * 0.5; - const stepSize = 1.0 / numberOfSphersPerSide; - - const geometry = new THREE.SphereGeometry(sphereRadius, 32, 16); - - for (let alpha = 0, alphaIndex = 0; alpha <= 1.0; alpha += stepSize, alphaIndex++) { - const colors = new Uint8Array(alphaIndex + 2); - - for (let c = 0; c <= colors.length; c++) { - colors[c] = (c / colors.length) * 256; - } - - const gradientMap = new THREE.DataTexture(colors, colors.length, 1, THREE.RedFormat); - gradientMap.needsUpdate = true; - - for (let beta = 0; beta <= 1.0; beta += stepSize) { - for (let gamma = 0; gamma <= 1.0; gamma += stepSize) { - // basic monochromatic energy preservation - const diffuseColor = new THREE.Color() - .setHSL(alpha, 0.5, gamma * 0.5 + 0.1) - .multiplyScalar(1 - beta * 0.2); - - const material = new THREE.MeshToonMaterial({ - color: diffuseColor, - gradientMap: gradientMap, - }); - - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = alpha * 400 - 200; - mesh.position.y = beta * 400 - 200; - mesh.position.z = gamma * 400 - 200; - - scene.add(mesh); - } - } - } - - function addLabel(name, location) { - const textGeo = new TextGeometry(name, { - font: font, - - size: 20, - depth: 1, - curveSegments: 1, - }); - - const textMaterial = new THREE.MeshBasicMaterial(); - const textMesh = new THREE.Mesh(textGeo, textMaterial); - textMesh.position.copy(location); - scene.add(textMesh); - } - - addLabel('-gradientMap', new THREE.Vector3(-350, 0, 0)); - addLabel('+gradientMap', new THREE.Vector3(350, 0, 0)); - - addLabel('-diffuse', new THREE.Vector3(0, 0, -300)); - addLabel('+diffuse', new THREE.Vector3(0, 0, 300)); - - particleLight = new THREE.Mesh(new THREE.SphereGeometry(4, 8, 8), new THREE.MeshBasicMaterial({ color: 0xffffff })); - scene.add(particleLight); - - // Lights - - scene.add(new THREE.AmbientLight(0xc1c1c1, 3)); - - const pointLight = new THREE.PointLight(0xffffff, 2, 800, 0); - particleLight.add(pointLight); - - // - - effect = new OutlineEffect(renderer); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 200; - controls.maxDistance = 2000; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - const timer = Date.now() * 0.00025; - - particleLight.position.x = Math.sin(timer * 7) * 300; - particleLight.position.y = Math.cos(timer * 5) * 400; - particleLight.position.z = Math.cos(timer * 3) * 300; - - effect.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_video.ts b/examples-testing/examples/webgl_materials_video.ts deleted file mode 100644 index 4f0d26a18..000000000 --- a/examples-testing/examples/webgl_materials_video.ts +++ /dev/null @@ -1,208 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let container; - -let camera, scene, renderer; - -let video, texture, material, mesh; - -let composer; - -let mouseX = 0; -let mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -let cube_count; - -const meshes = [], - materials = [], - xgrid = 20, - ygrid = 10; - -const startButton = document.getElementById('startButton'); -startButton.addEventListener('click', function () { - init(); -}); - -function init() { - const overlay = document.getElementById('overlay'); - overlay.remove(); - - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 500; - - scene = new THREE.Scene(); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0.5, 1, 1).normalize(); - scene.add(light); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - video = document.getElementById('video'); - video.play(); - video.addEventListener('play', function () { - this.currentTime = 3; - }); - - texture = new THREE.VideoTexture(video); - texture.colorSpace = THREE.SRGBColorSpace; - - // - - let i, j, ox, oy, geometry; - - const ux = 1 / xgrid; - const uy = 1 / ygrid; - - const xsize = 480 / xgrid; - const ysize = 204 / ygrid; - - const parameters = { color: 0xffffff, map: texture }; - - cube_count = 0; - - for (i = 0; i < xgrid; i++) { - for (j = 0; j < ygrid; j++) { - ox = i; - oy = j; - - geometry = new THREE.BoxGeometry(xsize, ysize, xsize); - - change_uvs(geometry, ux, uy, ox, oy); - - materials[cube_count] = new THREE.MeshLambertMaterial(parameters); - - material = materials[cube_count]; - - material.hue = i / xgrid; - material.saturation = 1 - j / ygrid; - - material.color.setHSL(material.hue, material.saturation, 0.5); - - mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = (i - xgrid / 2) * xsize; - mesh.position.y = (j - ygrid / 2) * ysize; - mesh.position.z = 0; - - mesh.scale.x = mesh.scale.y = mesh.scale.z = 1; - - scene.add(mesh); - - mesh.dx = 0.001 * (0.5 - Math.random()); - mesh.dy = 0.001 * (0.5 - Math.random()); - - meshes[cube_count] = mesh; - - cube_count += 1; - } - } - - renderer.autoClear = false; - - document.addEventListener('mousemove', onDocumentMouseMove); - - // postprocessing - - const renderPass = new RenderPass(scene, camera); - const bloomPass = new BloomPass(1.3); - const outputPass = new OutputPass(); - - composer = new EffectComposer(renderer); - - composer.addPass(renderPass); - composer.addPass(bloomPass); - composer.addPass(outputPass); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -function change_uvs(geometry, unitx, unity, offsetx, offsety) { - const uvs = geometry.attributes.uv.array; - - for (let i = 0; i < uvs.length; i += 2) { - uvs[i] = (uvs[i] + offsetx) * unitx; - uvs[i + 1] = (uvs[i + 1] + offsety) * unity; - } -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = (event.clientY - windowHalfY) * 0.3; -} - -// - -let h, - counter = 1; - -function animate() { - const time = Date.now() * 0.00005; - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - for (let i = 0; i < cube_count; i++) { - material = materials[i]; - - h = ((360 * (material.hue + time)) % 360) / 360; - material.color.setHSL(h, material.saturation, 0.5); - } - - if (counter % 1000 > 200) { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - - mesh.rotation.x += 10 * mesh.dx; - mesh.rotation.y += 10 * mesh.dy; - - mesh.position.x -= 150 * mesh.dx; - mesh.position.y += 150 * mesh.dy; - mesh.position.z += 300 * mesh.dx; - } - } - - if (counter % 1000 === 0) { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - - mesh.dx *= -1; - mesh.dy *= -1; - } - } - - counter++; - - renderer.clear(); - composer.render(); -} diff --git a/examples-testing/examples/webgl_materials_video_webcam.ts b/examples-testing/examples/webgl_materials_video_webcam.ts deleted file mode 100644 index cf6f8d50c..000000000 --- a/examples-testing/examples/webgl_materials_video_webcam.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, video; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 0.01; - - scene = new THREE.Scene(); - - video = document.getElementById('video'); - - const texture = new THREE.VideoTexture(video); - texture.colorSpace = THREE.SRGBColorSpace; - - const geometry = new THREE.PlaneGeometry(16, 9); - geometry.scale(0.5, 0.5, 0.5); - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const count = 128; - const radius = 32; - - for (let i = 1, l = count; i <= l; i++) { - const phi = Math.acos(-1 + (2 * i) / l); - const theta = Math.sqrt(l * Math.PI) * phi; - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.setFromSphericalCoords(radius, phi, theta); - mesh.lookAt(camera.position); - scene.add(mesh); - } - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enablePan = false; - - window.addEventListener('resize', onWindowResize); - - // - - if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - const constraints = { video: { width: 1280, height: 720, facingMode: 'user' } }; - - navigator.mediaDevices - .getUserMedia(constraints) - .then(function (stream) { - // apply the stream to the video element used in the texture - - video.srcObject = stream; - video.play(); - }) - .catch(function (error) { - console.error('Unable to access the camera/webcam.', error); - }); - } else { - console.error('MediaDevices interface not available.'); - } -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_materials_wireframe.ts b/examples-testing/examples/webgl_materials_wireframe.ts deleted file mode 100644 index 8adbd71d6..000000000 --- a/examples-testing/examples/webgl_materials_wireframe.ts +++ /dev/null @@ -1,107 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const API = { - thickness: 1, -}; - -let renderer, scene, camera, mesh2; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 500); - camera.position.z = 200; - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.enablePan = false; - controls.enableZoom = false; - - new THREE.BufferGeometryLoader().load('models/json/WaltHeadLo_buffergeometry.json', function (geometry) { - geometry.deleteAttribute('normal'); - geometry.deleteAttribute('uv'); - - setupAttributes(geometry); - - // left - - const material1 = new THREE.MeshBasicMaterial({ - color: 0xe0e0ff, - wireframe: true, - }); - - const mesh1 = new THREE.Mesh(geometry, material1); - mesh1.position.set(-40, 0, 0); - - scene.add(mesh1); - - // right - - const material2 = new THREE.ShaderMaterial({ - uniforms: { thickness: { value: API.thickness } }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - side: THREE.DoubleSide, - alphaToCoverage: true, // only works when WebGLRenderer's "antialias" is set to "true" - }); - - mesh2 = new THREE.Mesh(geometry, material2); - mesh2.position.set(40, 0, 0); - - scene.add(mesh2); - - // - - render(); - }); - - // - - const gui = new GUI(); - - gui.add(API, 'thickness', 0, 4).onChange(function () { - mesh2.material.uniforms.thickness.value = API.thickness; - render(); - }); - - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function setupAttributes(geometry) { - const vectors = [new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 1)]; - - const position = geometry.attributes.position; - const centers = new Float32Array(position.count * 3); - - for (let i = 0, l = position.count; i < l; i++) { - vectors[i % 3].toArray(centers, i * 3); - } - - geometry.setAttribute('center', new THREE.BufferAttribute(centers, 3)); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_math_obb.ts b/examples-testing/examples/webgl_math_obb.ts deleted file mode 100644 index 48480d10b..000000000 --- a/examples-testing/examples/webgl_math_obb.ts +++ /dev/null @@ -1,189 +0,0 @@ -import * as THREE from 'three'; - -import { OBB } from 'three/addons/math/OBB.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, clock, controls, stats, raycaster, hitbox; - -const objects = [], - mouse = new THREE.Vector2(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 75); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - clock = new THREE.Clock(); - - raycaster = new THREE.Raycaster(); - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x222222, 4); - hemiLight.position.set(1, 1, 1); - scene.add(hemiLight); - - const size = new THREE.Vector3(10, 5, 6); - const geometry = new THREE.BoxGeometry(size.x, size.y, size.z); - - // setup OBB on geometry level (doing this manually for now) - - geometry.userData.obb = new OBB(); - geometry.userData.obb.halfSize.copy(size).multiplyScalar(0.5); - - for (let i = 0; i < 100; i++) { - const object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: 0x00ff00 })); - object.matrixAutoUpdate = false; - - object.position.x = Math.random() * 80 - 40; - object.position.y = Math.random() * 80 - 40; - object.position.z = Math.random() * 80 - 40; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.x = Math.random() + 0.5; - object.scale.y = Math.random() + 0.5; - object.scale.z = Math.random() + 0.5; - - scene.add(object); - - // bounding volume on object level (this will reflect the current world transform) - - object.userData.obb = new OBB(); - - objects.push(object); - } - - // - - hitbox = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: 0x000000, wireframe: true })); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - - document.addEventListener('click', onClick); -} - -function onClick(event) { - event.preventDefault(); - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - raycaster.setFromCamera(mouse, camera); - - const intersectionPoint = new THREE.Vector3(); - const intersections = []; - - for (let i = 0, il = objects.length; i < il; i++) { - const object = objects[i]; - const obb = object.userData.obb; - - const ray = raycaster.ray; - - if (obb.intersectRay(ray, intersectionPoint) !== null) { - const distance = ray.origin.distanceTo(intersectionPoint); - intersections.push({ distance: distance, object: object }); - } - } - - if (intersections.length > 0) { - // determine closest intersection and highlight the respective 3D object - - intersections.sort(sortIntersections); - - intersections[0].object.add(hitbox); - } else { - const parent = hitbox.parent; - - if (parent) parent.remove(hitbox); - } -} - -function sortIntersections(a, b) { - return a.distance - b.distance; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - controls.update(); - - // transform cubes - - const delta = clock.getDelta(); - - for (let i = 0, il = objects.length; i < il; i++) { - const object = objects[i]; - - object.rotation.x += delta * Math.PI * 0.2; - object.rotation.y += delta * Math.PI * 0.1; - - object.updateMatrix(); - object.updateMatrixWorld(); - - // update OBB - - object.userData.obb.copy(object.geometry.userData.obb); - object.userData.obb.applyMatrix4(object.matrixWorld); - - // reset - - object.material.color.setHex(0x00ff00); - } - - // collision detection - - for (let i = 0, il = objects.length; i < il; i++) { - const object = objects[i]; - const obb = object.userData.obb; - - for (let j = i + 1, jl = objects.length; j < jl; j++) { - const objectToTest = objects[j]; - const obbToTest = objectToTest.userData.obb; - - // now perform intersection test - - if (obb.intersectsOBB(obbToTest) === true) { - object.material.color.setHex(0xff0000); - objectToTest.material.color.setHex(0xff0000); - } - } - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_math_orientation_transform.ts b/examples-testing/examples/webgl_math_orientation_transform.ts deleted file mode 100644 index 99be247d8..000000000 --- a/examples-testing/examples/webgl_math_orientation_transform.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, mesh, target; - -const spherical = new THREE.Spherical(); -const rotationMatrix = new THREE.Matrix4(); -const targetQuaternion = new THREE.Quaternion(); -const clock = new THREE.Clock(); -const speed = 2; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.z = 5; - - scene = new THREE.Scene(); - - const geometry = new THREE.ConeGeometry(0.1, 0.5, 8); - geometry.rotateX(Math.PI * 0.5); - const material = new THREE.MeshNormalMaterial(); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const targetGeometry = new THREE.SphereGeometry(0.05); - const targetMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); - target = new THREE.Mesh(targetGeometry, targetMaterial); - scene.add(target); - - // - - const sphereGeometry = new THREE.SphereGeometry(2, 32, 32); - const sphereMaterial = new THREE.MeshBasicMaterial({ - color: 0xcccccc, - wireframe: true, - transparent: true, - opacity: 0.3, - }); - const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - scene.add(sphere); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); - - // - - generateTarget(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (!mesh.quaternion.equals(targetQuaternion)) { - const step = speed * delta; - mesh.quaternion.rotateTowards(targetQuaternion, step); - } - - renderer.render(scene, camera); -} - -function generateTarget() { - // generate a random point on a sphere - - spherical.theta = Math.random() * Math.PI * 2; - spherical.phi = Math.acos(2 * Math.random() - 1); - spherical.radius = 2; - - target.position.setFromSpherical(spherical); - - // compute target rotation - - rotationMatrix.lookAt(target.position, mesh.position, mesh.up); - targetQuaternion.setFromRotationMatrix(rotationMatrix); - - setTimeout(generateTarget, 2000); -} diff --git a/examples-testing/examples/webgl_mesh_batch.ts b/examples-testing/examples/webgl_mesh_batch.ts deleted file mode 100644 index f93e5fb85..000000000 --- a/examples-testing/examples/webgl_mesh_batch.ts +++ /dev/null @@ -1,305 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { radixSort } from 'three/addons/utils/SortUtils.js'; - -let stats, gui, guiStatsEl; -let camera, controls, scene, renderer; -let geometries, mesh, material; -const ids = []; -const matrix = new THREE.Matrix4(); - -// - -const position = new THREE.Vector3(); -const rotation = new THREE.Euler(); -const quaternion = new THREE.Quaternion(); -const scale = new THREE.Vector3(); - -// - -const MAX_GEOMETRY_COUNT = 20000; - -const Method = { - BATCHED: 'BATCHED', - NAIVE: 'NAIVE', -}; - -const api = { - method: Method.BATCHED, - count: 256, - dynamic: 16, - - sortObjects: true, - perObjectFrustumCulled: true, - opacity: 1, - useCustomSort: true, -}; - -init(); -initGeometries(); -initMesh(); - -// - -function randomizeMatrix(matrix) { - position.x = Math.random() * 40 - 20; - position.y = Math.random() * 40 - 20; - position.z = Math.random() * 40 - 20; - - rotation.x = Math.random() * 2 * Math.PI; - rotation.y = Math.random() * 2 * Math.PI; - rotation.z = Math.random() * 2 * Math.PI; - - quaternion.setFromEuler(rotation); - - scale.x = scale.y = scale.z = 0.5 + Math.random() * 0.5; - - return matrix.compose(position, quaternion, scale); -} - -function randomizeRotationSpeed(rotation) { - rotation.x = Math.random() * 0.01; - rotation.y = Math.random() * 0.01; - rotation.z = Math.random() * 0.01; - return rotation; -} - -function initGeometries() { - geometries = [ - new THREE.ConeGeometry(1.0, 2.0), - new THREE.BoxGeometry(2.0, 2.0, 2.0), - new THREE.SphereGeometry(1.0, 16, 8), - ]; -} - -function createMaterial() { - if (!material) { - material = new THREE.MeshNormalMaterial(); - } - - return material; -} - -function cleanup() { - if (mesh) { - mesh.parent.remove(mesh); - - if (mesh.dispose) { - mesh.dispose(); - } - } -} - -function initMesh() { - cleanup(); - - if (api.method === Method.BATCHED) { - initBatchedMesh(); - } else { - initRegularMesh(); - } -} - -function initRegularMesh() { - mesh = new THREE.Group(); - const material = createMaterial(); - - for (let i = 0; i < api.count; i++) { - const child = new THREE.Mesh(geometries[i % geometries.length], material); - randomizeMatrix(child.matrix); - child.matrix.decompose(child.position, child.quaternion, child.scale); - child.userData.rotationSpeed = randomizeRotationSpeed(new THREE.Euler()); - mesh.add(child); - } - - scene.add(mesh); -} - -function initBatchedMesh() { - const geometryCount = api.count; - const vertexCount = geometries.length * 512; - const indexCount = geometries.length * 1024; - - const euler = new THREE.Euler(); - const matrix = new THREE.Matrix4(); - mesh = new THREE.BatchedMesh(geometryCount, vertexCount, indexCount, createMaterial()); - mesh.userData.rotationSpeeds = []; - - // disable full-object frustum culling since all of the objects can be dynamic. - mesh.frustumCulled = false; - - ids.length = 0; - - const geometryIds = [ - mesh.addGeometry(geometries[0]), - mesh.addGeometry(geometries[1]), - mesh.addGeometry(geometries[2]), - ]; - - for (let i = 0; i < api.count; i++) { - const id = mesh.addInstance(geometryIds[i % geometryIds.length]); - mesh.setMatrixAt(id, randomizeMatrix(matrix)); - - const rotationMatrix = new THREE.Matrix4(); - rotationMatrix.makeRotationFromEuler(randomizeRotationSpeed(euler)); - mesh.userData.rotationSpeeds.push(rotationMatrix); - - ids.push(id); - } - - scene.add(mesh); -} - -function init() { - const width = window.innerWidth; - const height = window.innerHeight; - - // camera - - camera = new THREE.PerspectiveCamera(70, width / height, 1, 100); - camera.position.z = 30; - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // scene - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = 1.0; - - // stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // gui - - gui = new GUI(); - gui.add(api, 'count', 1, MAX_GEOMETRY_COUNT).step(1).onChange(initMesh); - gui.add(api, 'dynamic', 0, MAX_GEOMETRY_COUNT).step(1); - gui.add(api, 'method', Method).onChange(initMesh); - gui.add(api, 'opacity', 0, 1).onChange(v => { - if (v < 1) { - material.transparent = true; - material.depthWrite = false; - } else { - material.transparent = false; - material.depthWrite = true; - } - - material.opacity = v; - material.needsUpdate = true; - }); - gui.add(api, 'sortObjects'); - gui.add(api, 'perObjectFrustumCulled'); - gui.add(api, 'useCustomSort'); - - guiStatsEl = document.createElement('li'); - guiStatsEl.classList.add('gui-stats'); - - // listeners - - window.addEventListener('resize', onWindowResize); -} - -// - -function sortFunction(list) { - // initialize options - this._options = this._options || { - get: el => el.z, - aux: new Array(this.maxInstanceCount), - }; - - const options = this._options; - options.reversed = this.material.transparent; - - let minZ = Infinity; - let maxZ = -Infinity; - for (let i = 0, l = list.length; i < l; i++) { - const z = list[i].z; - if (z > maxZ) maxZ = z; - if (z < minZ) minZ = z; - } - - // convert depth to unsigned 32 bit range - const depthDelta = maxZ - minZ; - const factor = (2 ** 32 - 1) / depthDelta; // UINT32_MAX / z range - for (let i = 0, l = list.length; i < l; i++) { - list[i].z -= minZ; - list[i].z *= factor; - } - - // perform a fast-sort using the hybrid radix sort function - radixSort(list, options); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - animateMeshes(); - - controls.update(); - stats.update(); - - render(); -} - -function animateMeshes() { - const loopNum = Math.min(api.count, api.dynamic); - - if (api.method === Method.BATCHED) { - for (let i = 0; i < loopNum; i++) { - const rotationMatrix = mesh.userData.rotationSpeeds[i]; - const id = ids[i]; - - mesh.getMatrixAt(id, matrix); - matrix.multiply(rotationMatrix); - mesh.setMatrixAt(id, matrix); - } - } else { - for (let i = 0; i < loopNum; i++) { - const child = mesh.children[i]; - const rotationSpeed = child.userData.rotationSpeed; - - child.rotation.set( - child.rotation.x + rotationSpeed.x, - child.rotation.y + rotationSpeed.y, - child.rotation.z + rotationSpeed.z, - ); - } - } -} - -function render() { - if (mesh.isBatchedMesh) { - mesh.sortObjects = api.sortObjects; - mesh.perObjectFrustumCulled = api.perObjectFrustumCulled; - mesh.setCustomSort(api.useCustomSort ? sortFunction : null); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_mirror.ts b/examples-testing/examples/webgl_mirror.ts deleted file mode 100644 index 8b27363a8..000000000 --- a/examples-testing/examples/webgl_mirror.ts +++ /dev/null @@ -1,168 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Reflector } from 'three/addons/objects/Reflector.js'; - -let camera, scene, renderer; - -let cameraControls; - -let sphereGroup, smallSphere; - -let groundMirror, verticalMirror; - -init(); - -function init() { - const container = document.getElementById('container'); - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500); - camera.position.set(0, 75, 160); - - cameraControls = new OrbitControls(camera, renderer.domElement); - cameraControls.target.set(0, 40, 0); - cameraControls.maxDistance = 400; - cameraControls.minDistance = 10; - cameraControls.update(); - - // - - const planeGeo = new THREE.PlaneGeometry(100.1, 100.1); - - // reflectors/mirrors - - let geometry, material; - - geometry = new THREE.CircleGeometry(40, 64); - groundMirror = new Reflector(geometry, { - clipBias: 0.003, - textureWidth: window.innerWidth * window.devicePixelRatio, - textureHeight: window.innerHeight * window.devicePixelRatio, - color: 0xb5b5b5, - }); - groundMirror.position.y = 0.5; - groundMirror.rotateX(-Math.PI / 2); - scene.add(groundMirror); - - geometry = new THREE.PlaneGeometry(100, 100); - verticalMirror = new Reflector(geometry, { - clipBias: 0.003, - textureWidth: window.innerWidth * window.devicePixelRatio, - textureHeight: window.innerHeight * window.devicePixelRatio, - color: 0xc1cbcb, - }); - verticalMirror.position.y = 50; - verticalMirror.position.z = -50; - scene.add(verticalMirror); - - sphereGroup = new THREE.Object3D(); - scene.add(sphereGroup); - - geometry = new THREE.CylinderGeometry(0.1, 15 * Math.cos((Math.PI / 180) * 30), 0.1, 24, 1); - material = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x8d8d8d }); - const sphereCap = new THREE.Mesh(geometry, material); - sphereCap.position.y = -15 * Math.sin((Math.PI / 180) * 30) - 0.05; - sphereCap.rotateX(-Math.PI); - - geometry = new THREE.SphereGeometry(15, 24, 24, Math.PI / 2, Math.PI * 2, 0, (Math.PI / 180) * 120); - const halfSphere = new THREE.Mesh(geometry, material); - halfSphere.add(sphereCap); - halfSphere.rotateX((-Math.PI / 180) * 135); - halfSphere.rotateZ((-Math.PI / 180) * 20); - halfSphere.position.y = 7.5 + 15 * Math.sin((Math.PI / 180) * 30); - - sphereGroup.add(halfSphere); - - geometry = new THREE.IcosahedronGeometry(5, 0); - material = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x7b7b7b, flatShading: true }); - smallSphere = new THREE.Mesh(geometry, material); - scene.add(smallSphere); - - // walls - const planeTop = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeTop.position.y = 100; - planeTop.rotateX(Math.PI / 2); - scene.add(planeTop); - - const planeBottom = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeBottom.rotateX(-Math.PI / 2); - scene.add(planeBottom); - - const planeFront = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x7f7fff })); - planeFront.position.z = 50; - planeFront.position.y = 50; - planeFront.rotateY(Math.PI); - scene.add(planeFront); - - const planeRight = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x00ff00 })); - planeRight.position.x = 50; - planeRight.position.y = 50; - planeRight.rotateY(-Math.PI / 2); - scene.add(planeRight); - - const planeLeft = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xff0000 })); - planeLeft.position.x = -50; - planeLeft.position.y = 50; - planeLeft.rotateY(Math.PI / 2); - scene.add(planeLeft); - - // lights - const mainLight = new THREE.PointLight(0xe7e7e7, 2.5, 250, 0); - mainLight.position.y = 60; - scene.add(mainLight); - - const greenLight = new THREE.PointLight(0x00ff00, 0.5, 1000, 0); - greenLight.position.set(550, 50, 0); - scene.add(greenLight); - - const redLight = new THREE.PointLight(0xff0000, 0.5, 1000, 0); - redLight.position.set(-550, 50, 0); - scene.add(redLight); - - const blueLight = new THREE.PointLight(0xbbbbfe, 0.5, 1000, 0); - blueLight.position.set(0, 50, 550); - scene.add(blueLight); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - groundMirror - .getRenderTarget() - .setSize(window.innerWidth * window.devicePixelRatio, window.innerHeight * window.devicePixelRatio); - verticalMirror - .getRenderTarget() - .setSize(window.innerWidth * window.devicePixelRatio, window.innerHeight * window.devicePixelRatio); -} - -function animate() { - const timer = Date.now() * 0.01; - - sphereGroup.rotation.y -= 0.002; - - smallSphere.position.set( - Math.cos(timer * 0.1) * 30, - Math.abs(Math.cos(timer * 0.2)) * 20 + 5, - Math.sin(timer * 0.1) * 30, - ); - smallSphere.rotation.y = Math.PI / 2 - timer * 0.1; - smallSphere.rotation.z = timer * 0.8; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_modifier_edgesplit.ts b/examples-testing/examples/webgl_modifier_edgesplit.ts deleted file mode 100644 index 4725eff62..000000000 --- a/examples-testing/examples/webgl_modifier_edgesplit.ts +++ /dev/null @@ -1,136 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; -import { EdgeSplitModifier } from 'three/addons/modifiers/EdgeSplitModifier.js'; -import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let renderer, scene, camera; -let modifier, mesh, baseGeometry; -let map; - -const params = { - smoothShading: true, - edgeSplit: true, - cutOffAngle: 20, - showMap: false, - tryKeepNormals: true, -}; - -init(); - -function init() { - const info = document.createElement('div'); - info.style.position = 'absolute'; - info.style.top = '10px'; - info.style.width = '100%'; - info.style.textAlign = 'center'; - info.innerHTML = 'three.js - Edge Split modifier'; - document.body.appendChild(info); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.enableDamping = true; - controls.dampingFactor = 0.25; - controls.rotateSpeed = 0.35; - controls.minZoom = 1; - camera.position.set(0, 0, 4); - - scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 3)); - - new OBJLoader().load('./models/obj/cerberus/Cerberus.obj', function (group) { - const cerberus = group.children[0]; - const modelGeometry = cerberus.geometry; - - modifier = new EdgeSplitModifier(); - baseGeometry = BufferGeometryUtils.mergeVertices(modelGeometry); - - mesh = new THREE.Mesh(getGeometry(), new THREE.MeshStandardMaterial()); - mesh.material.flatShading = !params.smoothShading; - mesh.rotateY(-Math.PI / 2); - mesh.scale.set(3.5, 3.5, 3.5); - mesh.translateZ(1.5); - scene.add(mesh); - - if (map !== undefined && params.showMap) { - mesh.material.map = map; - mesh.material.needsUpdate = true; - } - - render(); - }); - - window.addEventListener('resize', onWindowResize); - - new THREE.TextureLoader().load('./models/obj/cerberus/Cerberus_A.jpg', function (texture) { - map = texture; - map.colorSpace = THREE.SRGBColorSpace; - - if (mesh !== undefined && params.showMap) { - mesh.material.map = map; - mesh.material.needsUpdate = true; - } - }); - - const gui = new GUI({ title: 'Edge split modifier parameters' }); - - gui.add(params, 'showMap').onFinishChange(updateMesh); - gui.add(params, 'smoothShading').onFinishChange(updateMesh); - gui.add(params, 'edgeSplit').onFinishChange(updateMesh); - gui.add(params, 'cutOffAngle').min(0).max(180).onFinishChange(updateMesh); - gui.add(params, 'tryKeepNormals').onFinishChange(updateMesh); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - render(); -} - -function getGeometry() { - let geometry; - - if (params.edgeSplit) { - geometry = modifier.modify(baseGeometry, (params.cutOffAngle * Math.PI) / 180, params.tryKeepNormals); - } else { - geometry = baseGeometry; - } - - return geometry; -} - -function updateMesh() { - if (mesh !== undefined) { - mesh.geometry = getGeometry(); - - let needsUpdate = mesh.material.flatShading === params.smoothShading; - mesh.material.flatShading = params.smoothShading === false; - - if (map !== undefined) { - needsUpdate = needsUpdate || mesh.material.map !== (params.showMap ? map : null); - mesh.material.map = params.showMap ? map : null; - } - - mesh.material.needsUpdate = needsUpdate; - - render(); - } -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_modifier_simplifier.ts b/examples-testing/examples/webgl_modifier_simplifier.ts deleted file mode 100644 index e6ea453b3..000000000 --- a/examples-testing/examples/webgl_modifier_simplifier.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { SimplifyModifier } from 'three/addons/modifiers/SimplifyModifier.js'; - -let renderer, scene, camera; - -init(); - -function init() { - const info = document.createElement('div'); - info.style.position = 'absolute'; - info.style.top = '10px'; - info.style.width = '100%'; - info.style.textAlign = 'center'; - info.innerHTML = - 'three.js - Vertex Reduction using SimplifyModifier'; - document.body.appendChild(info); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 15; - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.enablePan = false; - controls.enableZoom = false; - - scene.add(new THREE.AmbientLight(0xffffff, 0.6)); - - const light = new THREE.PointLight(0xffffff, 400); - camera.add(light); - scene.add(camera); - - new GLTFLoader().load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - mesh.position.x = -3; - mesh.rotation.y = Math.PI / 2; - scene.add(mesh); - - const modifier = new SimplifyModifier(); - - const simplified = mesh.clone(); - simplified.material = simplified.material.clone(); - simplified.material.flatShading = true; - const count = Math.floor(simplified.geometry.attributes.position.count * 0.875); // number of vertices to remove - simplified.geometry = modifier.modify(simplified.geometry, count); - - simplified.position.x = 3; - simplified.rotation.y = -Math.PI / 2; - scene.add(simplified); - - render(); - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_modifier_tessellation.ts b/examples-testing/examples/webgl_modifier_tessellation.ts deleted file mode 100644 index 4600fc6cb..000000000 --- a/examples-testing/examples/webgl_modifier_tessellation.ts +++ /dev/null @@ -1,142 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import { TessellateModifier } from 'three/addons/modifiers/TessellateModifier.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -let renderer, scene, camera, stats; - -let controls; - -let mesh, uniforms; - -const WIDTH = window.innerWidth; -const HEIGHT = window.innerHeight; - -const loader = new FontLoader(); -loader.load('fonts/helvetiker_bold.typeface.json', function (font) { - init(font); -}); - -function init(font) { - camera = new THREE.PerspectiveCamera(40, WIDTH / HEIGHT, 1, 10000); - camera.position.set(-100, 100, 200); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x050505); - - // - - let geometry = new TextGeometry('THREE.JS', { - font: font, - - size: 40, - depth: 5, - curveSegments: 3, - - bevelThickness: 2, - bevelSize: 1, - bevelEnabled: true, - }); - - geometry.center(); - - const tessellateModifier = new TessellateModifier(8, 6); - - geometry = tessellateModifier.modify(geometry); - - // - - const numFaces = geometry.attributes.position.count / 3; - - const colors = new Float32Array(numFaces * 3 * 3); - const displacement = new Float32Array(numFaces * 3 * 3); - - const color = new THREE.Color(); - - for (let f = 0; f < numFaces; f++) { - const index = 9 * f; - - const h = 0.2 * Math.random(); - const s = 0.5 + 0.5 * Math.random(); - const l = 0.5 + 0.5 * Math.random(); - - color.setHSL(h, s, l); - - const d = 10 * (0.5 - Math.random()); - - for (let i = 0; i < 3; i++) { - colors[index + 3 * i] = color.r; - colors[index + 3 * i + 1] = color.g; - colors[index + 3 * i + 2] = color.b; - - displacement[index + 3 * i] = d; - displacement[index + 3 * i + 1] = d; - displacement[index + 3 * i + 2] = d; - } - } - - geometry.setAttribute('customColor', new THREE.BufferAttribute(colors, 3)); - geometry.setAttribute('displacement', new THREE.BufferAttribute(displacement, 3)); - - // - - uniforms = { - amplitude: { value: 0.0 }, - }; - - const shaderMaterial = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - }); - - // - - mesh = new THREE.Mesh(geometry, shaderMaterial); - - scene.add(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(WIDTH, HEIGHT); - renderer.setAnimationLoop(animate); - - const container = document.getElementById('container'); - container.appendChild(renderer.domElement); - - controls = new TrackballControls(camera, renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - - stats.update(); -} - -function render() { - const time = Date.now() * 0.001; - - uniforms.amplitude.value = 1.0 + Math.sin(time * 0.5); - - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_morphtargets.ts b/examples-testing/examples/webgl_morphtargets.ts deleted file mode 100644 index 40d605f8d..000000000 --- a/examples-testing/examples/webgl_morphtargets.ts +++ /dev/null @@ -1,120 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container, camera, scene, renderer, mesh; - -init(); - -function init() { - container = document.getElementById('container'); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x8fbcd4); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20); - camera.position.z = 10; - scene.add(camera); - - scene.add(new THREE.AmbientLight(0x8fbcd4, 1.5)); - - const pointLight = new THREE.PointLight(0xffffff, 200); - camera.add(pointLight); - - const geometry = createGeometry(); - - const material = new THREE.MeshPhongMaterial({ - color: 0xff0000, - flatShading: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - initGUI(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(function () { - renderer.render(scene, camera); - }); - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - - window.addEventListener('resize', onWindowResize); -} - -function createGeometry() { - const geometry = new THREE.BoxGeometry(2, 2, 2, 32, 32, 32); - - // create an empty array to hold targets for the attribute we want to morph - // morphing positions and normals is supported - geometry.morphAttributes.position = []; - - // the original positions of the cube's vertices - const positionAttribute = geometry.attributes.position; - - // for the first morph target we'll move the cube's vertices onto the surface of a sphere - const spherePositions = []; - - // for the second morph target, we'll twist the cubes vertices - const twistPositions = []; - const direction = new THREE.Vector3(1, 0, 0); - const vertex = new THREE.Vector3(); - - for (let i = 0; i < positionAttribute.count; i++) { - const x = positionAttribute.getX(i); - const y = positionAttribute.getY(i); - const z = positionAttribute.getZ(i); - - spherePositions.push( - x * Math.sqrt(1 - (y * y) / 2 - (z * z) / 2 + (y * y * z * z) / 3), - y * Math.sqrt(1 - (z * z) / 2 - (x * x) / 2 + (z * z * x * x) / 3), - z * Math.sqrt(1 - (x * x) / 2 - (y * y) / 2 + (x * x * y * y) / 3), - ); - - // stretch along the x-axis so we can see the twist better - vertex.set(x * 2, y, z); - - vertex.applyAxisAngle(direction, (Math.PI * x) / 2).toArray(twistPositions, twistPositions.length); - } - - // add the spherical positions as the first morph target - geometry.morphAttributes.position[0] = new THREE.Float32BufferAttribute(spherePositions, 3); - - // add the twisted positions as the second morph target - geometry.morphAttributes.position[1] = new THREE.Float32BufferAttribute(twistPositions, 3); - - return geometry; -} - -function initGUI() { - // Set up dat.GUI to control targets - const params = { - Spherify: 0, - Twist: 0, - }; - const gui = new GUI({ title: 'Morph Targets' }); - - gui.add(params, 'Spherify', 0, 1) - .step(0.01) - .onChange(function (value) { - mesh.morphTargetInfluences[0] = value; - }); - gui.add(params, 'Twist', 0, 1) - .step(0.01) - .onChange(function (value) { - mesh.morphTargetInfluences[1] = value; - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} diff --git a/examples-testing/examples/webgl_morphtargets_face.ts b/examples-testing/examples/webgl_morphtargets_face.ts deleted file mode 100644 index 76179d902..000000000 --- a/examples-testing/examples/webgl_morphtargets_face.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; -import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats, mixer, clock, controls; - -init(); - -function init() { - clock = new THREE.Clock(); - - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20); - camera.position.set(-1.8, 0.8, 3); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - - container.appendChild(renderer.domElement); - - const ktx2Loader = new KTX2Loader().setTranscoderPath('jsm/libs/basis/').detectSupport(renderer); - - new GLTFLoader() - .setKTX2Loader(ktx2Loader) - .setMeshoptDecoder(MeshoptDecoder) - .load('models/gltf/facecap.glb', gltf => { - const mesh = gltf.scene.children[0]; - - scene.add(mesh); - - mixer = new THREE.AnimationMixer(mesh); - - mixer.clipAction(gltf.animations[0]).play(); - - // GUI - - const head = mesh.getObjectByName('mesh_2'); - const influences = head.morphTargetInfluences; - - const gui = new GUI(); - gui.close(); - - for (const [key, value] of Object.entries(head.morphTargetDictionary)) { - gui.add(influences, value, 0, 1, 0.01).name(key.replace('blendShape1.', '')).listen(); - } - }); - - const environment = new RoomEnvironment(); - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene.background = new THREE.Color(0x666666); - scene.environment = pmremGenerator.fromScene(environment).texture; - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 2.5; - controls.maxDistance = 5; - controls.minAzimuthAngle = -Math.PI / 2; - controls.maxAzimuthAngle = Math.PI / 2; - controls.maxPolarAngle = Math.PI / 1.8; - controls.target.set(0, 0.15, -0.2); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) { - mixer.update(delta); - } - - renderer.render(scene, camera); - - controls.update(); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_morphtargets_horse.ts b/examples-testing/examples/webgl_morphtargets_horse.ts deleted file mode 100644 index 2c29e9c0e..000000000 --- a/examples-testing/examples/webgl_morphtargets_horse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let container, stats; -let camera, scene, renderer; -let mesh, mixer; - -const radius = 600; -let theta = 0; -let prevTime = Date.now(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.y = 300; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xf0f0f0); - - // - - const light1 = new THREE.DirectionalLight(0xefefff, 5); - light1.position.set(1, 1, 1).normalize(); - scene.add(light1); - - const light2 = new THREE.DirectionalLight(0xffefef, 5); - light2.position.set(-1, -1, -1).normalize(); - scene.add(light2); - - const loader = new GLTFLoader(); - loader.load('models/gltf/Horse.glb', function (gltf) { - mesh = gltf.scene.children[0]; - mesh.scale.set(1.5, 1.5, 1.5); - scene.add(mesh); - - mixer = new THREE.AnimationMixer(mesh); - - mixer.clipAction(gltf.animations[0]).setDuration(1).play(); - }); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - theta += 0.1; - - camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta)); - camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta)); - - camera.lookAt(0, 150, 0); - - if (mixer) { - const time = Date.now(); - - mixer.update((time - prevTime) * 0.001); - - prevTime = time; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_morphtargets_sphere.ts b/examples-testing/examples/webgl_morphtargets_sphere.ts deleted file mode 100644 index 2b8899111..000000000 --- a/examples-testing/examples/webgl_morphtargets_sphere.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { Timer } from 'three/addons/misc/Timer.js'; - -let camera, scene, renderer, timer; - -let mesh; - -let sign = 1; -const speed = 0.5; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.2, 100); - camera.position.set(0, 5, 5); - - scene = new THREE.Scene(); - - timer = new Timer(); - - const light1 = new THREE.PointLight(0xff2200, 50000); - light1.position.set(100, 100, 100); - scene.add(light1); - - const light2 = new THREE.PointLight(0x22ff00, 10000); - light2.position.set(-100, -100, -100); - scene.add(light2); - - scene.add(new THREE.AmbientLight(0x111111)); - - const loader = new GLTFLoader(); - loader.load('models/gltf/AnimatedMorphSphere/glTF/AnimatedMorphSphere.gltf', function (gltf) { - mesh = gltf.scene.getObjectByName('AnimatedMorphSphere'); - mesh.rotation.z = Math.PI / 2; - scene.add(mesh); - - // - - const pointsMaterial = new THREE.PointsMaterial({ - size: 10, - sizeAttenuation: false, - map: new THREE.TextureLoader().load('textures/sprites/disc.png'), - alphaTest: 0.5, - }); - - const points = new THREE.Points(mesh.geometry, pointsMaterial); - points.morphTargetInfluences = mesh.morphTargetInfluences; - points.morphTargetDictionary = mesh.morphTargetDictionary; - mesh.add(points); - }); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - container.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 20; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - timer.update(); - render(); -} - -function render() { - const delta = timer.getDelta(); - - if (mesh !== undefined) { - const step = delta * speed; - - mesh.rotation.y += step; - - mesh.morphTargetInfluences[1] = mesh.morphTargetInfluences[1] + step * sign; - - if (mesh.morphTargetInfluences[1] <= 0 || mesh.morphTargetInfluences[1] >= 1) { - sign *= -1; - } - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_multiple_elements.ts b/examples-testing/examples/webgl_multiple_elements.ts deleted file mode 100644 index 64f8a9c5f..000000000 --- a/examples-testing/examples/webgl_multiple_elements.ts +++ /dev/null @@ -1,139 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let canvas, renderer; - -const scenes = []; - -init(); - -function init() { - canvas = document.getElementById('c'); - - const geometries = [ - new THREE.BoxGeometry(1, 1, 1), - new THREE.SphereGeometry(0.5, 12, 8), - new THREE.DodecahedronGeometry(0.5), - new THREE.CylinderGeometry(0.5, 0.5, 1, 12), - ]; - - const content = document.getElementById('content'); - - for (let i = 0; i < 40; i++) { - const scene = new THREE.Scene(); - - // make a list item - const element = document.createElement('div'); - element.className = 'list-item'; - - const sceneElement = document.createElement('div'); - element.appendChild(sceneElement); - - const descriptionElement = document.createElement('div'); - descriptionElement.innerText = 'Scene ' + (i + 1); - element.appendChild(descriptionElement); - - // the element that represents the area we want to render the scene - scene.userData.element = sceneElement; - content.appendChild(element); - - const camera = new THREE.PerspectiveCamera(50, 1, 1, 10); - camera.position.z = 2; - scene.userData.camera = camera; - - const controls = new OrbitControls(scene.userData.camera, scene.userData.element); - controls.minDistance = 2; - controls.maxDistance = 5; - controls.enablePan = false; - controls.enableZoom = false; - scene.userData.controls = controls; - - // add one random mesh to each scene - const geometry = geometries[(geometries.length * Math.random()) | 0]; - - const material = new THREE.MeshStandardMaterial({ - color: new THREE.Color().setHSL(Math.random(), 1, 0.75, THREE.SRGBColorSpace), - roughness: 0.5, - metalness: 0, - flatShading: true, - }); - - scene.add(new THREE.Mesh(geometry, material)); - - scene.add(new THREE.HemisphereLight(0xaaaaaa, 0x444444, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 1.5); - light.position.set(1, 1, 1); - scene.add(light); - - scenes.push(scene); - } - - renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true }); - renderer.setClearColor(0xffffff, 1); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); -} - -function updateSize() { - const width = canvas.clientWidth; - const height = canvas.clientHeight; - - if (canvas.width !== width || canvas.height !== height) { - renderer.setSize(width, height, false); - } -} - -function animate() { - updateSize(); - - canvas.style.transform = `translateY(${window.scrollY}px)`; - - renderer.setClearColor(0xffffff); - renderer.setScissorTest(false); - renderer.clear(); - - renderer.setClearColor(0xe0e0e0); - renderer.setScissorTest(true); - - scenes.forEach(function (scene) { - // so something moves - scene.children[0].rotation.y = Date.now() * 0.001; - - // get the element that is a place holder for where we want to - // draw the scene - const element = scene.userData.element; - - // get its position relative to the page's viewport - const rect = element.getBoundingClientRect(); - - // check if it's offscreen. If so skip it - if ( - rect.bottom < 0 || - rect.top > renderer.domElement.clientHeight || - rect.right < 0 || - rect.left > renderer.domElement.clientWidth - ) { - return; // it's off screen - } - - // set the viewport - const width = rect.right - rect.left; - const height = rect.bottom - rect.top; - const left = rect.left; - const bottom = renderer.domElement.clientHeight - rect.bottom; - - renderer.setViewport(left, bottom, width, height); - renderer.setScissor(left, bottom, width, height); - - const camera = scene.userData.camera; - - //camera.aspect = width / height; // not changing in this example - //camera.updateProjectionMatrix(); - - //scene.userData.controls.update(); - - renderer.render(scene, camera); - }); -} diff --git a/examples-testing/examples/webgl_multiple_rendertargets.ts b/examples-testing/examples/webgl_multiple_rendertargets.ts deleted file mode 100644 index 86708082b..000000000 --- a/examples-testing/examples/webgl_multiple_rendertargets.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, controls; -let renderTarget; -let postScene, postCamera; - -const parameters = { - samples: 4, - wireframe: false, -}; - -const gui = new GUI(); -gui.add(parameters, 'samples', 0, 4).step(1); -gui.add(parameters, 'wireframe'); -gui.onChange(render); - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // Create a multi render target with Float buffers - - renderTarget = new THREE.WebGLRenderTarget( - window.innerWidth * window.devicePixelRatio, - window.innerHeight * window.devicePixelRatio, - { - count: 2, - minFilter: THREE.NearestFilter, - magFilter: THREE.NearestFilter, - }, - ); - - // Name our G-Buffer attachments for debugging - - renderTarget.textures[0].name = 'diffuse'; - renderTarget.textures[1].name = 'normal'; - - // Scene setup - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x222222); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50); - camera.position.z = 4; - - const loader = new THREE.TextureLoader(); - - const diffuse = loader.load('textures/hardwood2_diffuse.jpg', render); - diffuse.wrapS = THREE.RepeatWrapping; - diffuse.wrapT = THREE.RepeatWrapping; - diffuse.colorSpace = THREE.SRGBColorSpace; - - scene.add( - new THREE.Mesh( - new THREE.TorusKnotGeometry(1, 0.3, 128, 32), - new THREE.RawShaderMaterial({ - name: 'G-Buffer Shader', - vertexShader: document.querySelector('#gbuffer-vert').textContent.trim(), - fragmentShader: document.querySelector('#gbuffer-frag').textContent.trim(), - uniforms: { - tDiffuse: { value: diffuse }, - repeat: { value: new THREE.Vector2(5, 0.5) }, - }, - glslVersion: THREE.GLSL3, - }), - ), - ); - - // PostProcessing setup - - postScene = new THREE.Scene(); - postCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); - - postScene.add( - new THREE.Mesh( - new THREE.PlaneGeometry(2, 2), - new THREE.RawShaderMaterial({ - name: 'Post-FX Shader', - vertexShader: document.querySelector('#render-vert').textContent.trim(), - fragmentShader: document.querySelector('#render-frag').textContent.trim(), - uniforms: { - tDiffuse: { value: renderTarget.textures[0] }, - tNormal: { value: renderTarget.textures[1] }, - }, - glslVersion: THREE.GLSL3, - }), - ), - ); - - // Controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - const dpr = renderer.getPixelRatio(); - renderTarget.setSize(window.innerWidth * dpr, window.innerHeight * dpr); - - render(); -} - -function render() { - renderTarget.samples = parameters.samples; - - scene.traverse(function (child) { - if (child.material !== undefined) { - child.material.wireframe = parameters.wireframe; - } - }); - - // render scene into target - renderer.setRenderTarget(renderTarget); - renderer.render(scene, camera); - - // render post FX - renderer.setRenderTarget(null); - renderer.render(postScene, postCamera); -} diff --git a/examples-testing/examples/webgl_multiple_scenes_comparison.ts b/examples-testing/examples/webgl_multiple_scenes_comparison.ts deleted file mode 100644 index 41a5130d4..000000000 --- a/examples-testing/examples/webgl_multiple_scenes_comparison.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container, camera, renderer, controls; -let sceneL, sceneR; - -let sliderPos = window.innerWidth / 2; - -init(); - -function init() { - container = document.querySelector('.container'); - - sceneL = new THREE.Scene(); - sceneL.background = new THREE.Color(0xbcd48f); - - sceneR = new THREE.Scene(); - sceneR.background = new THREE.Color(0x8fbcd4); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 6; - - controls = new OrbitControls(camera, container); - - const light = new THREE.HemisphereLight(0xffffff, 0x444444, 3); - light.position.set(-2, 2, 2); - sceneL.add(light.clone()); - sceneR.add(light.clone()); - - initMeshes(); - initSlider(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setScissorTest(true); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function initMeshes() { - const geometry = new THREE.IcosahedronGeometry(1, 3); - - const meshL = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial()); - sceneL.add(meshL); - - const meshR = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ wireframe: true })); - sceneR.add(meshR); -} - -function initSlider() { - const slider = document.querySelector('.slider'); - - function onPointerDown() { - if (event.isPrimary === false) return; - - controls.enabled = false; - - window.addEventListener('pointermove', onPointerMove); - window.addEventListener('pointerup', onPointerUp); - } - - function onPointerUp() { - controls.enabled = true; - - window.removeEventListener('pointermove', onPointerMove); - window.removeEventListener('pointerup', onPointerUp); - } - - function onPointerMove(e) { - if (event.isPrimary === false) return; - - sliderPos = Math.max(0, Math.min(window.innerWidth, e.pageX)); - - slider.style.left = sliderPos - slider.offsetWidth / 2 + 'px'; - } - - slider.style.touchAction = 'none'; // disable touch scroll - slider.addEventListener('pointerdown', onPointerDown); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.setScissor(0, 0, sliderPos, window.innerHeight); - renderer.render(sceneL, camera); - - renderer.setScissor(sliderPos, 0, window.innerWidth, window.innerHeight); - renderer.render(sceneR, camera); -} diff --git a/examples-testing/examples/webgl_multiple_views.ts b/examples-testing/examples/webgl_multiple_views.ts deleted file mode 100644 index 29126b013..000000000 --- a/examples-testing/examples/webgl_multiple_views.ts +++ /dev/null @@ -1,237 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let stats; - -let scene, renderer; - -let mouseX = 0, - mouseY = 0; - -let windowWidth, windowHeight; - -const views = [ - { - left: 0, - bottom: 0, - width: 0.5, - height: 1.0, - background: new THREE.Color().setRGB(0.5, 0.5, 0.7, THREE.SRGBColorSpace), - eye: [0, 300, 1800], - up: [0, 1, 0], - fov: 30, - updateCamera: function (camera, scene, mouseX) { - camera.position.x += mouseX * 0.05; - camera.position.x = Math.max(Math.min(camera.position.x, 2000), -2000); - camera.lookAt(scene.position); - }, - }, - { - left: 0.5, - bottom: 0, - width: 0.5, - height: 0.5, - background: new THREE.Color().setRGB(0.7, 0.5, 0.5, THREE.SRGBColorSpace), - eye: [0, 1800, 0], - up: [0, 0, 1], - fov: 45, - updateCamera: function (camera, scene, mouseX) { - camera.position.x -= mouseX * 0.05; - camera.position.x = Math.max(Math.min(camera.position.x, 2000), -2000); - camera.lookAt(camera.position.clone().setY(0)); - }, - }, - { - left: 0.5, - bottom: 0.5, - width: 0.5, - height: 0.5, - background: new THREE.Color().setRGB(0.5, 0.7, 0.7, THREE.SRGBColorSpace), - eye: [1400, 800, 1400], - up: [0, 1, 0], - fov: 60, - updateCamera: function (camera, scene, mouseX) { - camera.position.y -= mouseX * 0.05; - camera.position.y = Math.max(Math.min(camera.position.y, 1600), -1600); - camera.lookAt(scene.position); - }, - }, -]; - -init(); - -function init() { - const container = document.getElementById('container'); - - for (let ii = 0; ii < views.length; ++ii) { - const view = views[ii]; - const camera = new THREE.PerspectiveCamera(view.fov, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.fromArray(view.eye); - camera.up.fromArray(view.up); - view.camera = camera; - } - - scene = new THREE.Scene(); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 0, 1); - scene.add(light); - - // shadow - - const canvas = document.createElement('canvas'); - canvas.width = 128; - canvas.height = 128; - - const context = canvas.getContext('2d'); - const gradient = context.createRadialGradient( - canvas.width / 2, - canvas.height / 2, - 0, - canvas.width / 2, - canvas.height / 2, - canvas.width / 2, - ); - gradient.addColorStop(0.1, 'rgba(0,0,0,0.15)'); - gradient.addColorStop(1, 'rgba(0,0,0,0)'); - - context.fillStyle = gradient; - context.fillRect(0, 0, canvas.width, canvas.height); - - const shadowTexture = new THREE.CanvasTexture(canvas); - - const shadowMaterial = new THREE.MeshBasicMaterial({ map: shadowTexture, transparent: true }); - const shadowGeo = new THREE.PlaneGeometry(300, 300, 1, 1); - - let shadowMesh; - - shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial); - shadowMesh.position.y = -250; - shadowMesh.rotation.x = -Math.PI / 2; - scene.add(shadowMesh); - - shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial); - shadowMesh.position.x = -400; - shadowMesh.position.y = -250; - shadowMesh.rotation.x = -Math.PI / 2; - scene.add(shadowMesh); - - shadowMesh = new THREE.Mesh(shadowGeo, shadowMaterial); - shadowMesh.position.x = 400; - shadowMesh.position.y = -250; - shadowMesh.rotation.x = -Math.PI / 2; - scene.add(shadowMesh); - - const radius = 200; - - const geometry1 = new THREE.IcosahedronGeometry(radius, 1); - - const count = geometry1.attributes.position.count; - geometry1.setAttribute('color', new THREE.BufferAttribute(new Float32Array(count * 3), 3)); - - const geometry2 = geometry1.clone(); - const geometry3 = geometry1.clone(); - - const color = new THREE.Color(); - const positions1 = geometry1.attributes.position; - const positions2 = geometry2.attributes.position; - const positions3 = geometry3.attributes.position; - const colors1 = geometry1.attributes.color; - const colors2 = geometry2.attributes.color; - const colors3 = geometry3.attributes.color; - - for (let i = 0; i < count; i++) { - color.setHSL((positions1.getY(i) / radius + 1) / 2, 1.0, 0.5, THREE.SRGBColorSpace); - colors1.setXYZ(i, color.r, color.g, color.b); - - color.setHSL(0, (positions2.getY(i) / radius + 1) / 2, 0.5, THREE.SRGBColorSpace); - colors2.setXYZ(i, color.r, color.g, color.b); - - color.setRGB(1, 0.8 - (positions3.getY(i) / radius + 1) / 2, 0, THREE.SRGBColorSpace); - colors3.setXYZ(i, color.r, color.g, color.b); - } - - const material = new THREE.MeshPhongMaterial({ - color: 0xffffff, - flatShading: true, - vertexColors: true, - shininess: 0, - }); - - const wireframeMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, wireframe: true, transparent: true }); - - let mesh = new THREE.Mesh(geometry1, material); - let wireframe = new THREE.Mesh(geometry1, wireframeMaterial); - mesh.add(wireframe); - mesh.position.x = -400; - mesh.rotation.x = -1.87; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry2, material); - wireframe = new THREE.Mesh(geometry2, wireframeMaterial); - mesh.add(wireframe); - mesh.position.x = 400; - scene.add(mesh); - - mesh = new THREE.Mesh(geometry3, material); - wireframe = new THREE.Mesh(geometry3, wireframeMaterial); - mesh.add(wireframe); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - document.addEventListener('mousemove', onDocumentMouseMove); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowWidth / 2; - mouseY = event.clientY - windowHeight / 2; -} - -function updateSize() { - if (windowWidth != window.innerWidth || windowHeight != window.innerHeight) { - windowWidth = window.innerWidth; - windowHeight = window.innerHeight; - - renderer.setSize(windowWidth, windowHeight); - } -} - -function animate() { - render(); - stats.update(); -} - -function render() { - updateSize(); - - for (let ii = 0; ii < views.length; ++ii) { - const view = views[ii]; - const camera = view.camera; - - view.updateCamera(camera, scene, mouseX, mouseY); - - const left = Math.floor(windowWidth * view.left); - const bottom = Math.floor(windowHeight * view.bottom); - const width = Math.floor(windowWidth * view.width); - const height = Math.floor(windowHeight * view.height); - - renderer.setViewport(left, bottom, width, height); - renderer.setScissor(left, bottom, width, height); - renderer.setScissorTest(true); - renderer.setClearColor(view.background); - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.render(scene, camera); - } -} diff --git a/examples-testing/examples/webgl_multisampled_renderbuffers.ts b/examples-testing/examples/webgl_multisampled_renderbuffers.ts deleted file mode 100644 index df84fb144..000000000 --- a/examples-testing/examples/webgl_multisampled_renderbuffers.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, renderer, group, container; - -let composer1, composer2; - -const params = { - animate: true, -}; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, container.offsetWidth / container.offsetHeight, 10, 2000); - camera.position.z = 500; - - const scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - scene.fog = new THREE.Fog(0xcccccc, 100, 1500); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x222222, 5); - hemiLight.position.set(1, 1, 1); - scene.add(hemiLight); - - // - - group = new THREE.Group(); - - const geometry = new THREE.SphereGeometry(10, 64, 40); - const material = new THREE.MeshLambertMaterial({ - color: 0xee0808, - polygonOffset: true, - polygonOffsetFactor: 1, // positive value pushes polygon further away - polygonOffsetUnits: 1, - }); - const material2 = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }); - - for (let i = 0; i < 50; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 600 - 300; - mesh.position.y = Math.random() * 600 - 300; - mesh.position.z = Math.random() * 600 - 300; - mesh.rotation.x = Math.random(); - mesh.rotation.z = Math.random(); - mesh.scale.setScalar(Math.random() * 5 + 5); - group.add(mesh); - - const mesh2 = new THREE.Mesh(geometry, material2); - mesh2.position.copy(mesh.position); - mesh2.rotation.copy(mesh.rotation); - mesh2.scale.copy(mesh.scale); - group.add(mesh2); - } - - scene.add(group); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(container.offsetWidth, container.offsetHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - container.appendChild(renderer.domElement); - - // - - const size = renderer.getDrawingBufferSize(new THREE.Vector2()); - const renderTarget = new THREE.WebGLRenderTarget(size.width, size.height, { - samples: 4, - type: THREE.HalfFloatType, - }); - - const renderPass = new RenderPass(scene, camera); - const outputPass = new OutputPass(); - - // - - composer1 = new EffectComposer(renderer); - composer1.addPass(renderPass); - composer1.addPass(outputPass); - - // - - composer2 = new EffectComposer(renderer, renderTarget); - composer2.addPass(renderPass); - composer2.addPass(outputPass); - - // - - const gui = new GUI(); - gui.add(params, 'animate'); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = container.offsetWidth / container.offsetHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(container.offsetWidth, container.offsetHeight); - composer1.setSize(container.offsetWidth, container.offsetHeight); - composer2.setSize(container.offsetWidth, container.offsetHeight); -} - -function animate() { - const halfWidth = container.offsetWidth / 2; - - if (params.animate) { - group.rotation.y += 0.002; - } - - renderer.setScissorTest(true); - - renderer.setScissor(0, 0, halfWidth - 1, container.offsetHeight); - composer1.render(); - - renderer.setScissor(halfWidth, 0, halfWidth, container.offsetHeight); - composer2.render(); - - renderer.setScissorTest(false); -} diff --git a/examples-testing/examples/webgl_panorama_cube.ts b/examples-testing/examples/webgl_panorama_cube.ts deleted file mode 100644 index efd09cfc5..000000000 --- a/examples-testing/examples/webgl_panorama_cube.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, controls; -let renderer; -let scene; - -init(); - -function init() { - const container = document.getElementById('container'); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 0.01; - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enablePan = false; - controls.enableDamping = true; - controls.rotateSpeed = -0.25; - - const textures = getTexturesFromAtlasFile('textures/cube/sun_temple_stripe.jpg', 6); - - const materials = []; - - for (let i = 0; i < 6; i++) { - materials.push(new THREE.MeshBasicMaterial({ map: textures[i] })); - } - - const skyBox = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), materials); - skyBox.geometry.scale(1, 1, -1); - scene.add(skyBox); - - window.addEventListener('resize', onWindowResize); -} - -function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) { - const textures = []; - - for (let i = 0; i < tilesNum; i++) { - textures[i] = new THREE.Texture(); - } - - new THREE.ImageLoader().load(atlasImgUrl, image => { - let canvas, context; - const tileWidth = image.height; - - for (let i = 0; i < textures.length; i++) { - canvas = document.createElement('canvas'); - context = canvas.getContext('2d'); - canvas.height = tileWidth; - canvas.width = tileWidth; - context.drawImage(image, tileWidth * i, 0, tileWidth, tileWidth, 0, 0, tileWidth, tileWidth); - textures[i].colorSpace = THREE.SRGBColorSpace; - textures[i].image = canvas; - textures[i].needsUpdate = true; - } - }); - - return textures; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); // required when damping is enabled - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_panorama_equirectangular.ts b/examples-testing/examples/webgl_panorama_equirectangular.ts deleted file mode 100644 index 40796f6e2..000000000 --- a/examples-testing/examples/webgl_panorama_equirectangular.ts +++ /dev/null @@ -1,112 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; - -let isUserInteracting = false, - onPointerDownMouseX = 0, - onPointerDownMouseY = 0, - lon = 0, - onPointerDownLon = 0, - lat = 0, - onPointerDownLat = 0, - phi = 0, - theta = 0; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100); - - scene = new THREE.Scene(); - - const geometry = new THREE.SphereGeometry(500, 60, 40); - // invert the geometry on the x-axis so that all of the faces point inward - geometry.scale(-1, 1, 1); - - const texture = new THREE.TextureLoader().load('textures/2294472375_24a3b8ef46_o.jpg'); - texture.colorSpace = THREE.SRGBColorSpace; - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh = new THREE.Mesh(geometry, material); - - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - container.style.touchAction = 'none'; - container.addEventListener('pointerdown', onPointerDown); - - document.addEventListener('wheel', onDocumentMouseWheel); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerDown(event) { - if (event.isPrimary === false) return; - - isUserInteracting = true; - - onPointerDownMouseX = event.clientX; - onPointerDownMouseY = event.clientY; - - onPointerDownLon = lon; - onPointerDownLat = lat; - - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - lon = (onPointerDownMouseX - event.clientX) * 0.1 + onPointerDownLon; - lat = (event.clientY - onPointerDownMouseY) * 0.1 + onPointerDownLat; -} - -function onPointerUp() { - if (event.isPrimary === false) return; - - isUserInteracting = false; - - document.removeEventListener('pointermove', onPointerMove); - document.removeEventListener('pointerup', onPointerUp); -} - -function onDocumentMouseWheel(event) { - const fov = camera.fov + event.deltaY * 0.05; - - camera.fov = THREE.MathUtils.clamp(fov, 10, 75); - - camera.updateProjectionMatrix(); -} - -function animate() { - if (isUserInteracting === false) { - lon += 0.1; - } - - lat = Math.max(-85, Math.min(85, lat)); - phi = THREE.MathUtils.degToRad(90 - lat); - theta = THREE.MathUtils.degToRad(lon); - - const x = 500 * Math.sin(phi) * Math.cos(theta); - const y = 500 * Math.cos(phi); - const z = 500 * Math.sin(phi) * Math.sin(theta); - - camera.lookAt(x, y, z); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_performance.ts b/examples-testing/examples/webgl_performance.ts deleted file mode 100644 index 3700386a3..000000000 --- a/examples-testing/examples/webgl_performance.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(60, 60, 60); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - - renderer.setAnimationLoop(render); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.environment = texture; - - // model - - const loader = new GLTFLoader().setPath('models/gltf/'); - loader.load('dungeon_warkarma.glb', async function (gltf) { - const model = gltf.scene; - - // wait until the model can be added to the scene without blocking due to shader compilation - - await renderer.compileAsync(model, camera, scene); - - scene.add(model); - }); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 60; - controls.target.set(0, 0, -0.2); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_pmrem_test.ts b/examples-testing/examples/webgl_pmrem_test.ts deleted file mode 100644 index b33e4e2f1..000000000 --- a/examples-testing/examples/webgl_pmrem_test.ts +++ /dev/null @@ -1,141 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, camera, controls, renderer; - -function init() { - const width = window.innerWidth; - const height = window.innerHeight; - const aspect = width / height; - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - - // tonemapping - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - // scene - - scene = new THREE.Scene(); - - // camera - - camera = new THREE.PerspectiveCamera(40, aspect, 1, 30); - updateCamera(); - camera.position.set(0, 0, 16); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 4; - controls.maxDistance = 20; - - // light - - const directionalLight = new THREE.DirectionalLight(0xffffff, 0); // set intensity to 0 to start - const x = 597; - const y = 213; - const theta = ((x + 0.5) * Math.PI) / 512; - const phi = ((y + 0.5) * Math.PI) / 512; - - directionalLight.position.setFromSphericalCoords(100, -phi, Math.PI / 2 - theta); - - scene.add(directionalLight); - // scene.add( new THREE.DirectionalLightHelper( directionalLight ) ); - - // The spot1Lux HDR environment map is expressed in nits (lux / sr). The directional light has units of lux, - // so to match a 1 lux light, we set a single pixel with a value equal to 1 divided by the solid - // angle of the pixel in steradians. This image is 1024 x 512, - // so the value is 1 / ( sin( phi ) * ( pi / 512 ) ^ 2 ) = 27,490 nits. - - const gui = new GUI(); - gui.add({ enabled: true }, 'enabled') - .name('PMREM') - .onChange(value => { - directionalLight.intensity = value ? 0 : 1; - - scene.traverse(function (child) { - if (child.isMesh) { - child.material.envMapIntensity = 1 - directionalLight.intensity; - } - }); - - render(); - }); -} - -function createObjects() { - let radianceMap = null; - new RGBELoader() - // .setDataType( THREE.FloatType ) - .setPath('textures/equirectangular/') - .load('spot1Lux.hdr', function (texture) { - radianceMap = pmremGenerator.fromEquirectangular(texture).texture; - pmremGenerator.dispose(); - - scene.background = radianceMap; - - const geometry = new THREE.SphereGeometry(0.4, 32, 32); - - for (let x = 0; x <= 10; x++) { - for (let y = 0; y <= 2; y++) { - const material = new THREE.MeshPhysicalMaterial({ - roughness: x / 10, - metalness: y < 1 ? 1 : 0, - color: y < 2 ? 0xffffff : 0x000000, - envMap: radianceMap, - envMapIntensity: 1, - }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = x - 5; - mesh.position.y = 1 - y; - scene.add(mesh); - } - } - - render(); - }); - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - pmremGenerator.compileEquirectangularShader(); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - updateCamera(); - - renderer.setSize(width, height); - - render(); -} - -function updateCamera() { - const horizontalFoV = 40; - const verticalFoV = - (2 * Math.atan(Math.tan(((horizontalFoV / 2) * Math.PI) / 180) / camera.aspect) * 180) / Math.PI; - camera.fov = verticalFoV; - camera.updateProjectionMatrix(); -} - -function render() { - renderer.render(scene, camera); -} - -Promise.resolve().then(init).then(createObjects).then(render); diff --git a/examples-testing/examples/webgl_points_billboards.ts b/examples-testing/examples/webgl_points_billboards.ts deleted file mode 100644 index 24d4de1a9..000000000 --- a/examples-testing/examples/webgl_points_billboards.ts +++ /dev/null @@ -1,120 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats, material; -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 2, 2000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - scene.fog = new THREE.FogExp2(0x000000, 0.001); - - const geometry = new THREE.BufferGeometry(); - const vertices = []; - - const sprite = new THREE.TextureLoader().load('textures/sprites/disc.png'); - sprite.colorSpace = THREE.SRGBColorSpace; - - for (let i = 0; i < 10000; i++) { - const x = 2000 * Math.random() - 1000; - const y = 2000 * Math.random() - 1000; - const z = 2000 * Math.random() - 1000; - - vertices.push(x, y, z); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - - material = new THREE.PointsMaterial({ - size: 35, - sizeAttenuation: true, - map: sprite, - alphaTest: 0.5, - transparent: true, - }); - material.color.setHSL(1.0, 0.3, 0.7, THREE.SRGBColorSpace); - - const particles = new THREE.Points(geometry, material); - scene.add(particles); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const gui = new GUI(); - - gui.add(material, 'sizeAttenuation').onChange(function () { - material.needsUpdate = true; - }); - - gui.open(); - - // - - document.body.style.touchAction = 'none'; - document.body.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.00005; - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - const h = ((360 * (1.0 + time)) % 360) / 360; - material.color.setHSL(h, 0.5, 0.5); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_points_sprites.ts b/examples-testing/examples/webgl_points_sprites.ts deleted file mode 100644 index 31b9e2ce1..000000000 --- a/examples-testing/examples/webgl_points_sprites.ts +++ /dev/null @@ -1,167 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, stats, parameters; -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -const materials = []; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - scene.fog = new THREE.FogExp2(0x000000, 0.0008); - - const geometry = new THREE.BufferGeometry(); - const vertices = []; - - const textureLoader = new THREE.TextureLoader(); - - const assignSRGB = texture => { - texture.colorSpace = THREE.SRGBColorSpace; - }; - - const sprite1 = textureLoader.load('textures/sprites/snowflake1.png', assignSRGB); - const sprite2 = textureLoader.load('textures/sprites/snowflake2.png', assignSRGB); - const sprite3 = textureLoader.load('textures/sprites/snowflake3.png', assignSRGB); - const sprite4 = textureLoader.load('textures/sprites/snowflake4.png', assignSRGB); - const sprite5 = textureLoader.load('textures/sprites/snowflake5.png', assignSRGB); - - for (let i = 0; i < 10000; i++) { - const x = Math.random() * 2000 - 1000; - const y = Math.random() * 2000 - 1000; - const z = Math.random() * 2000 - 1000; - - vertices.push(x, y, z); - } - - geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); - - parameters = [ - [[1.0, 0.2, 0.5], sprite2, 20], - [[0.95, 0.1, 0.5], sprite3, 15], - [[0.9, 0.05, 0.5], sprite1, 10], - [[0.85, 0, 0.5], sprite5, 8], - [[0.8, 0, 0.5], sprite4, 5], - ]; - - for (let i = 0; i < parameters.length; i++) { - const color = parameters[i][0]; - const sprite = parameters[i][1]; - const size = parameters[i][2]; - - materials[i] = new THREE.PointsMaterial({ - size: size, - map: sprite, - blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, - }); - materials[i].color.setHSL(color[0], color[1], color[2], THREE.SRGBColorSpace); - - const particles = new THREE.Points(geometry, materials[i]); - - particles.rotation.x = Math.random() * 6; - particles.rotation.y = Math.random() * 6; - particles.rotation.z = Math.random() * 6; - - scene.add(particles); - } - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - const gui = new GUI(); - - const params = { - texture: true, - }; - - gui.add(params, 'texture').onChange(function (value) { - for (let i = 0; i < materials.length; i++) { - materials[i].map = value === true ? parameters[i][1] : null; - materials[i].needsUpdate = true; - } - }); - - gui.open(); - - document.body.style.touchAction = 'none'; - document.body.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.00005; - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - for (let i = 0; i < scene.children.length; i++) { - const object = scene.children[i]; - - if (object instanceof THREE.Points) { - object.rotation.y = time * (i < 4 ? i + 1 : -(i + 1)); - } - } - - for (let i = 0; i < materials.length; i++) { - const color = parameters[i][0]; - - const h = ((360 * (color[0] + time)) % 360) / 360; - materials[i].color.setHSL(h, color[1], color[2], THREE.SRGBColorSpace); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_points_waves.ts b/examples-testing/examples/webgl_points_waves.ts deleted file mode 100644 index 91986e9e9..000000000 --- a/examples-testing/examples/webgl_points_waves.ts +++ /dev/null @@ -1,145 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -const SEPARATION = 100, - AMOUNTX = 50, - AMOUNTY = 50; - -let container, stats; -let camera, scene, renderer; - -let particles, - count = 0; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 1000; - - scene = new THREE.Scene(); - - // - - const numParticles = AMOUNTX * AMOUNTY; - - const positions = new Float32Array(numParticles * 3); - const scales = new Float32Array(numParticles); - - let i = 0, - j = 0; - - for (let ix = 0; ix < AMOUNTX; ix++) { - for (let iy = 0; iy < AMOUNTY; iy++) { - positions[i] = ix * SEPARATION - (AMOUNTX * SEPARATION) / 2; // x - positions[i + 1] = 0; // y - positions[i + 2] = iy * SEPARATION - (AMOUNTY * SEPARATION) / 2; // z - - scales[j] = 1; - - i += 3; - j++; - } - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute('scale', new THREE.BufferAttribute(scales, 1)); - - const material = new THREE.ShaderMaterial({ - uniforms: { - color: { value: new THREE.Color(0xffffff) }, - }, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - }); - - // - - particles = new THREE.Points(geometry, material); - scene.add(particles); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - container.style.touchAction = 'none'; - container.addEventListener('pointermove', onPointerMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - camera.lookAt(scene.position); - - const positions = particles.geometry.attributes.position.array; - const scales = particles.geometry.attributes.scale.array; - - let i = 0, - j = 0; - - for (let ix = 0; ix < AMOUNTX; ix++) { - for (let iy = 0; iy < AMOUNTY; iy++) { - positions[i + 1] = Math.sin((ix + count) * 0.3) * 50 + Math.sin((iy + count) * 0.5) * 50; - - scales[j] = (Math.sin((ix + count) * 0.3) + 1) * 20 + (Math.sin((iy + count) * 0.5) + 1) * 20; - - i += 3; - j++; - } - } - - particles.geometry.attributes.position.needsUpdate = true; - particles.geometry.attributes.scale.needsUpdate = true; - - renderer.render(scene, camera); - - count += 0.1; -} diff --git a/examples-testing/examples/webgl_portal.ts b/examples-testing/examples/webgl_portal.ts deleted file mode 100644 index 4bc59593f..000000000 --- a/examples-testing/examples/webgl_portal.ts +++ /dev/null @@ -1,218 +0,0 @@ -import * as THREE from 'three'; - -import * as CameraUtils from 'three/addons/utils/CameraUtils.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -let cameraControls; - -let smallSphereOne, smallSphereTwo; - -let portalCamera, - leftPortal, - rightPortal, - leftPortalTexture, - reflectedPosition, - rightPortalTexture, - bottomLeftCorner, - bottomRightCorner, - topLeftCorner; - -init(); - -function init() { - const container = document.getElementById('container'); - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.localClippingEnabled = true; - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000); - camera.position.set(0, 75, 160); - - cameraControls = new OrbitControls(camera, renderer.domElement); - cameraControls.target.set(0, 40, 0); - cameraControls.maxDistance = 400; - cameraControls.minDistance = 10; - cameraControls.update(); - - // - - const planeGeo = new THREE.PlaneGeometry(100.1, 100.1); - - // bouncing icosphere - const portalPlane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0.0); - const geometry = new THREE.IcosahedronGeometry(5, 0); - const material = new THREE.MeshPhongMaterial({ - color: 0xffffff, - emissive: 0x333333, - flatShading: true, - clippingPlanes: [portalPlane], - clipShadows: true, - }); - smallSphereOne = new THREE.Mesh(geometry, material); - scene.add(smallSphereOne); - smallSphereTwo = new THREE.Mesh(geometry, material); - scene.add(smallSphereTwo); - - // portals - portalCamera = new THREE.PerspectiveCamera(45, 1.0, 0.1, 500.0); - scene.add(portalCamera); - //frustumHelper = new THREE.CameraHelper( portalCamera ); - //scene.add( frustumHelper ); - bottomLeftCorner = new THREE.Vector3(); - bottomRightCorner = new THREE.Vector3(); - topLeftCorner = new THREE.Vector3(); - reflectedPosition = new THREE.Vector3(); - - leftPortalTexture = new THREE.WebGLRenderTarget(256, 256); - leftPortal = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({ map: leftPortalTexture.texture })); - leftPortal.position.x = -30; - leftPortal.position.y = 20; - leftPortal.scale.set(0.35, 0.35, 0.35); - scene.add(leftPortal); - - rightPortalTexture = new THREE.WebGLRenderTarget(256, 256); - rightPortal = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({ map: rightPortalTexture.texture })); - rightPortal.position.x = 30; - rightPortal.position.y = 20; - rightPortal.scale.set(0.35, 0.35, 0.35); - scene.add(rightPortal); - - // walls - const planeTop = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeTop.position.y = 100; - planeTop.rotateX(Math.PI / 2); - scene.add(planeTop); - - const planeBottom = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeBottom.rotateX(-Math.PI / 2); - scene.add(planeBottom); - - const planeFront = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x7f7fff })); - planeFront.position.z = 50; - planeFront.position.y = 50; - planeFront.rotateY(Math.PI); - scene.add(planeFront); - - const planeBack = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xff7fff })); - planeBack.position.z = -50; - planeBack.position.y = 50; - //planeBack.rotateY( Math.PI ); - scene.add(planeBack); - - const planeRight = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x00ff00 })); - planeRight.position.x = 50; - planeRight.position.y = 50; - planeRight.rotateY(-Math.PI / 2); - scene.add(planeRight); - - const planeLeft = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xff0000 })); - planeLeft.position.x = -50; - planeLeft.position.y = 50; - planeLeft.rotateY(Math.PI / 2); - scene.add(planeLeft); - - // lights - const mainLight = new THREE.PointLight(0xe7e7e7, 2.5, 250, 0); - mainLight.position.y = 60; - scene.add(mainLight); - - const greenLight = new THREE.PointLight(0x00ff00, 0.5, 1000, 0); - greenLight.position.set(550, 50, 0); - scene.add(greenLight); - - const redLight = new THREE.PointLight(0xff0000, 0.5, 1000, 0); - redLight.position.set(-550, 50, 0); - scene.add(redLight); - - const blueLight = new THREE.PointLight(0xbbbbfe, 0.5, 1000, 0); - blueLight.position.set(0, 50, 550); - scene.add(blueLight); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function renderPortal(thisPortalMesh, otherPortalMesh, thisPortalTexture) { - // set the portal camera position to be reflected about the portal plane - thisPortalMesh.worldToLocal(reflectedPosition.copy(camera.position)); - reflectedPosition.x *= -1.0; - reflectedPosition.z *= -1.0; - otherPortalMesh.localToWorld(reflectedPosition); - portalCamera.position.copy(reflectedPosition); - - // grab the corners of the other portal - // - note: the portal is viewed backwards; flip the left/right coordinates - otherPortalMesh.localToWorld(bottomLeftCorner.set(50.05, -50.05, 0.0)); - otherPortalMesh.localToWorld(bottomRightCorner.set(-50.05, -50.05, 0.0)); - otherPortalMesh.localToWorld(topLeftCorner.set(50.05, 50.05, 0.0)); - // set the projection matrix to encompass the portal's frame - CameraUtils.frameCorners(portalCamera, bottomLeftCorner, bottomRightCorner, topLeftCorner, false); - - // render the portal - thisPortalTexture.texture.colorSpace = renderer.outputColorSpace; - renderer.setRenderTarget(thisPortalTexture); - renderer.state.buffers.depth.setMask(true); // make sure the depth buffer is writable so it can be properly cleared, see #18897 - if (renderer.autoClear === false) renderer.clear(); - thisPortalMesh.visible = false; // hide this portal from its own rendering - renderer.render(scene, portalCamera); - thisPortalMesh.visible = true; // re-enable this portal's visibility for general rendering -} - -function animate() { - // move the bouncing sphere(s) - const timerOne = Date.now() * 0.01; - const timerTwo = timerOne + Math.PI * 10.0; - - smallSphereOne.position.set( - Math.cos(timerOne * 0.1) * 30, - Math.abs(Math.cos(timerOne * 0.2)) * 20 + 5, - Math.sin(timerOne * 0.1) * 30, - ); - smallSphereOne.rotation.y = Math.PI / 2 - timerOne * 0.1; - smallSphereOne.rotation.z = timerOne * 0.8; - - smallSphereTwo.position.set( - Math.cos(timerTwo * 0.1) * 30, - Math.abs(Math.cos(timerTwo * 0.2)) * 20 + 5, - Math.sin(timerTwo * 0.1) * 30, - ); - smallSphereTwo.rotation.y = Math.PI / 2 - timerTwo * 0.1; - smallSphereTwo.rotation.z = timerTwo * 0.8; - - // save the original camera properties - const currentRenderTarget = renderer.getRenderTarget(); - const currentXrEnabled = renderer.xr.enabled; - const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; - renderer.xr.enabled = false; // Avoid camera modification - renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows - - // render the portal effect - renderPortal(leftPortal, rightPortal, leftPortalTexture); - renderPortal(rightPortal, leftPortal, rightPortalTexture); - - // restore the original rendering properties - renderer.xr.enabled = currentXrEnabled; - renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; - renderer.setRenderTarget(currentRenderTarget); - - // render the main scene - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_postprocessing.ts b/examples-testing/examples/webgl_postprocessing.ts deleted file mode 100644 index ecc9b28ee..000000000 --- a/examples-testing/examples/webgl_postprocessing.ts +++ /dev/null @@ -1,86 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; - -import { RGBShiftShader } from 'three/addons/shaders/RGBShiftShader.js'; -import { DotScreenShader } from 'three/addons/shaders/DotScreenShader.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, renderer, composer; -let object; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 400; - - const scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1, 1000); - - object = new THREE.Object3D(); - scene.add(object); - - const geometry = new THREE.SphereGeometry(1, 4, 4); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }); - - for (let i = 0; i < 100; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize(); - mesh.position.multiplyScalar(Math.random() * 400); - mesh.rotation.set(Math.random() * 2, Math.random() * 2, Math.random() * 2); - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50; - object.add(mesh); - } - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(1, 1, 1); - scene.add(light); - - // postprocessing - - composer = new EffectComposer(renderer); - composer.addPass(new RenderPass(scene, camera)); - - const effect1 = new ShaderPass(DotScreenShader); - effect1.uniforms['scale'].value = 4; - composer.addPass(effect1); - - const effect2 = new ShaderPass(RGBShiftShader); - effect2.uniforms['amount'].value = 0.0015; - composer.addPass(effect2); - - const effect3 = new OutputPass(); - composer.addPass(effect3); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - object.rotation.x += 0.005; - object.rotation.y += 0.01; - - composer.render(); -} diff --git a/examples-testing/examples/webgl_postprocessing_advanced.ts b/examples-testing/examples/webgl_postprocessing_advanced.ts deleted file mode 100644 index 82fc39be3..000000000 --- a/examples-testing/examples/webgl_postprocessing_advanced.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; -import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; -import { FilmPass } from 'three/addons/postprocessing/FilmPass.js'; -import { DotScreenPass } from 'three/addons/postprocessing/DotScreenPass.js'; -import { MaskPass, ClearMaskPass } from 'three/addons/postprocessing/MaskPass.js'; -import { TexturePass } from 'three/addons/postprocessing/TexturePass.js'; - -import { BleachBypassShader } from 'three/addons/shaders/BleachBypassShader.js'; -import { ColorifyShader } from 'three/addons/shaders/ColorifyShader.js'; -import { HorizontalBlurShader } from 'three/addons/shaders/HorizontalBlurShader.js'; -import { VerticalBlurShader } from 'three/addons/shaders/VerticalBlurShader.js'; -import { SepiaShader } from 'three/addons/shaders/SepiaShader.js'; -import { VignetteShader } from 'three/addons/shaders/VignetteShader.js'; -import { GammaCorrectionShader } from 'three/addons/shaders/GammaCorrectionShader.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let container, stats; - -let composerScene, composer1, composer2, composer3, composer4; - -let cameraOrtho, cameraPerspective, sceneModel, sceneBG, renderer, mesh, directionalLight; - -const width = window.innerWidth || 2; -const height = window.innerHeight || 2; - -let halfWidth = width / 2; -let halfHeight = height / 2; - -let quadBG, quadMask, renderScene; - -const delta = 0.01; - -init(); - -function init() { - container = document.getElementById('container'); - - // - - cameraOrtho = new THREE.OrthographicCamera(-halfWidth, halfWidth, halfHeight, -halfHeight, -10000, 10000); - cameraOrtho.position.z = 100; - - cameraPerspective = new THREE.PerspectiveCamera(50, width / height, 1, 10000); - cameraPerspective.position.z = 900; - - // - - sceneModel = new THREE.Scene(); - sceneBG = new THREE.Scene(); - - // - - directionalLight = new THREE.DirectionalLight(0xffffff, 3); - directionalLight.position.set(0, -0.1, 1).normalize(); - sceneModel.add(directionalLight); - - const loader = new GLTFLoader(); - loader.load('models/gltf/LeePerrySmith/LeePerrySmith.glb', function (gltf) { - createMesh(gltf.scene.children[0].geometry, sceneModel, 100); - }); - - // - - const diffuseMap = new THREE.TextureLoader().load('textures/cube/SwedishRoyalCastle/pz.jpg'); - diffuseMap.colorSpace = THREE.SRGBColorSpace; - - const materialColor = new THREE.MeshBasicMaterial({ - map: diffuseMap, - depthTest: false, - }); - - quadBG = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), materialColor); - quadBG.position.z = -500; - quadBG.scale.set(width, height, 1); - sceneBG.add(quadBG); - - // - - const sceneMask = new THREE.Scene(); - - quadMask = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), new THREE.MeshBasicMaterial({ color: 0xffaa00 })); - quadMask.position.z = -300; - quadMask.scale.set(width / 2, height / 2, 1); - sceneMask.add(quadMask); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - // - - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - const shaderBleach = BleachBypassShader; - const shaderSepia = SepiaShader; - const shaderVignette = VignetteShader; - - const effectBleach = new ShaderPass(shaderBleach); - const effectSepia = new ShaderPass(shaderSepia); - const effectVignette = new ShaderPass(shaderVignette); - const gammaCorrection = new ShaderPass(GammaCorrectionShader); - - effectBleach.uniforms['opacity'].value = 0.95; - - effectSepia.uniforms['amount'].value = 0.9; - - effectVignette.uniforms['offset'].value = 1.6; - effectVignette.uniforms['darkness'].value = 0.95; - - const effectBloom = new BloomPass(0.5); - const effectFilm = new FilmPass(0.35); - const effectFilmBW = new FilmPass(0.35, true); - const effectDotScreen = new DotScreenPass(new THREE.Vector2(0, 0), 0.5, 0.8); - - const effectHBlur = new ShaderPass(HorizontalBlurShader); - const effectVBlur = new ShaderPass(VerticalBlurShader); - effectHBlur.uniforms['h'].value = 2 / (width / 2); - effectVBlur.uniforms['v'].value = 2 / (height / 2); - - const effectColorify1 = new ShaderPass(ColorifyShader); - const effectColorify2 = new ShaderPass(ColorifyShader); - effectColorify1.uniforms['color'] = new THREE.Uniform(new THREE.Color(1, 0.8, 0.8)); - effectColorify2.uniforms['color'] = new THREE.Uniform(new THREE.Color(1, 0.75, 0.5)); - - const clearMask = new ClearMaskPass(); - const renderMask = new MaskPass(sceneModel, cameraPerspective); - const renderMaskInverse = new MaskPass(sceneModel, cameraPerspective); - - renderMaskInverse.inverse = true; - - // - - const rtParameters = { - stencilBuffer: true, - }; - - const rtWidth = width / 2; - const rtHeight = height / 2; - - // - - const renderBackground = new RenderPass(sceneBG, cameraOrtho); - const renderModel = new RenderPass(sceneModel, cameraPerspective); - - renderModel.clear = false; - - composerScene = new EffectComposer(renderer, new THREE.WebGLRenderTarget(rtWidth * 2, rtHeight * 2, rtParameters)); - - composerScene.addPass(renderBackground); - composerScene.addPass(renderModel); - composerScene.addPass(renderMaskInverse); - composerScene.addPass(effectHBlur); - composerScene.addPass(effectVBlur); - composerScene.addPass(clearMask); - - // - - renderScene = new TexturePass(composerScene.renderTarget2.texture); - - // - - composer1 = new EffectComposer(renderer, new THREE.WebGLRenderTarget(rtWidth, rtHeight, rtParameters)); - - composer1.addPass(renderScene); - composer1.addPass(gammaCorrection); - composer1.addPass(effectFilmBW); - composer1.addPass(effectVignette); - - // - - composer2 = new EffectComposer(renderer, new THREE.WebGLRenderTarget(rtWidth, rtHeight, rtParameters)); - - composer2.addPass(renderScene); - composer2.addPass(gammaCorrection); - composer2.addPass(effectDotScreen); - composer2.addPass(renderMask); - composer2.addPass(effectColorify1); - composer2.addPass(clearMask); - composer2.addPass(renderMaskInverse); - composer2.addPass(effectColorify2); - composer2.addPass(clearMask); - composer2.addPass(effectVignette); - - // - - composer3 = new EffectComposer(renderer, new THREE.WebGLRenderTarget(rtWidth, rtHeight, rtParameters)); - - composer3.addPass(renderScene); - composer3.addPass(gammaCorrection); - composer3.addPass(effectSepia); - composer3.addPass(effectFilm); - composer3.addPass(effectVignette); - - // - - composer4 = new EffectComposer(renderer, new THREE.WebGLRenderTarget(rtWidth, rtHeight, rtParameters)); - - composer4.addPass(renderScene); - composer4.addPass(gammaCorrection); - composer4.addPass(effectBloom); - composer4.addPass(effectFilm); - composer4.addPass(effectBleach); - composer4.addPass(effectVignette); - - renderScene.uniforms['tDiffuse'].value = composerScene.renderTarget2.texture; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - halfWidth = window.innerWidth / 2; - halfHeight = window.innerHeight / 2; - - cameraPerspective.aspect = window.innerWidth / window.innerHeight; - cameraPerspective.updateProjectionMatrix(); - - cameraOrtho.left = -halfWidth; - cameraOrtho.right = halfWidth; - cameraOrtho.top = halfHeight; - cameraOrtho.bottom = -halfHeight; - - cameraOrtho.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - composerScene.setSize(halfWidth * 2, halfHeight * 2); - - composer1.setSize(halfWidth, halfHeight); - composer2.setSize(halfWidth, halfHeight); - composer3.setSize(halfWidth, halfHeight); - composer4.setSize(halfWidth, halfHeight); - - renderScene.uniforms['tDiffuse'].value = composerScene.renderTarget2.texture; - - quadBG.scale.set(window.innerWidth, window.innerHeight, 1); - quadMask.scale.set(window.innerWidth / 2, window.innerHeight / 2, 1); -} - -function createMesh(geometry, scene, scale) { - const diffuseMap = new THREE.TextureLoader().load('models/gltf/LeePerrySmith/Map-COL.jpg'); - diffuseMap.colorSpace = THREE.SRGBColorSpace; - - const mat2 = new THREE.MeshPhongMaterial({ - color: 0xcbcbcb, - specular: 0x080808, - shininess: 20, - map: diffuseMap, - normalMap: new THREE.TextureLoader().load('models/gltf/LeePerrySmith/Infinite-Level_02_Tangent_SmoothUV.jpg'), - normalScale: new THREE.Vector2(0.75, 0.75), - }); - - mesh = new THREE.Mesh(geometry, mat2); - mesh.position.set(0, -50, 0); - mesh.scale.set(scale, scale, scale); - - scene.add(mesh); -} - -// - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - const time = Date.now() * 0.0004; - - if (mesh) mesh.rotation.y = -time; - - renderer.setViewport(0, 0, halfWidth, halfHeight); - composerScene.render(delta); - - renderer.setViewport(0, 0, halfWidth, halfHeight); - composer1.render(delta); - - renderer.setViewport(halfWidth, 0, halfWidth, halfHeight); - composer2.render(delta); - - renderer.setViewport(0, halfHeight, halfWidth, halfHeight); - composer3.render(delta); - - renderer.setViewport(halfWidth, halfHeight, halfWidth, halfHeight); - composer4.render(delta); -} diff --git a/examples-testing/examples/webgl_postprocessing_afterimage.ts b/examples-testing/examples/webgl_postprocessing_afterimage.ts deleted file mode 100644 index 508f90b89..000000000 --- a/examples-testing/examples/webgl_postprocessing_afterimage.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { AfterimagePass } from 'three/addons/postprocessing/AfterimagePass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, scene, renderer, composer; -let mesh; - -let afterimagePass; - -const params = { - enable: true, -}; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 400; - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1, 1000); - - const geometry = new THREE.BoxGeometry(150, 150, 150, 2, 2, 2); - const material = new THREE.MeshNormalMaterial(); - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // postprocessing - - composer = new EffectComposer(renderer); - composer.addPass(new RenderPass(scene, camera)); - - afterimagePass = new AfterimagePass(); - composer.addPass(afterimagePass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI({ title: 'Damp setting' }); - gui.add(afterimagePass.uniforms['damp'], 'value', 0, 1).step(0.001); - gui.add(params, 'enable'); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - mesh.rotation.x += 0.005; - mesh.rotation.y += 0.01; - - afterimagePass.enabled = params.enable; - - composer.render(); -} diff --git a/examples-testing/examples/webgl_postprocessing_backgrounds.ts b/examples-testing/examples/webgl_postprocessing_backgrounds.ts deleted file mode 100644 index 57a6a2dbd..000000000 --- a/examples-testing/examples/webgl_postprocessing_backgrounds.ts +++ /dev/null @@ -1,214 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { TexturePass } from 'three/addons/postprocessing/TexturePass.js'; -import { CubeTexturePass } from 'three/addons/postprocessing/CubeTexturePass.js'; -import { ClearPass } from 'three/addons/postprocessing/ClearPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let scene, renderer, composer; -let clearPass, texturePass, renderPass; -let cameraP, cubeTexturePassP; -let gui, stats; - -const params = { - clearPass: true, - clearColor: 'white', - clearAlpha: 1.0, - - texturePass: true, - texturePassOpacity: 1.0, - - cubeTexturePass: true, - cubeTexturePassOpacity: 1.0, - - renderPass: true, -}; - -init(); - -clearGui(); - -function clearGui() { - if (gui) gui.destroy(); - - gui = new GUI(); - - gui.add(params, 'clearPass'); - gui.add(params, 'clearColor', ['black', 'white', 'blue', 'green', 'red']); - gui.add(params, 'clearAlpha', 0, 1); - - gui.add(params, 'texturePass'); - gui.add(params, 'texturePassOpacity', 0, 1); - - gui.add(params, 'cubeTexturePass'); - gui.add(params, 'cubeTexturePassOpacity', 0, 1); - - gui.add(params, 'renderPass'); - - gui.open(); -} - -function init() { - const container = document.getElementById('container'); - - const width = window.innerWidth || 1; - const height = window.innerHeight || 1; - const aspect = width / height; - const devicePixelRatio = window.devicePixelRatio || 1; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - cameraP = new THREE.PerspectiveCamera(65, aspect, 1, 10); - cameraP.position.z = 7; - - scene = new THREE.Scene(); - - const group = new THREE.Group(); - scene.add(group); - - const light = new THREE.PointLight(0xefffef, 500); - light.position.z = 10; - light.position.y = -10; - light.position.x = -10; - scene.add(light); - - const light2 = new THREE.PointLight(0xffefef, 500); - light2.position.z = 10; - light2.position.x = -10; - light2.position.y = 10; - scene.add(light2); - - const light3 = new THREE.PointLight(0xefefff, 500); - light3.position.z = 10; - light3.position.x = 10; - light3.position.y = -10; - scene.add(light3); - - const geometry = new THREE.SphereGeometry(1, 48, 24); - - const material = new THREE.MeshStandardMaterial(); - material.roughness = 0.5 * Math.random() + 0.25; - material.metalness = 0; - material.color.setHSL(Math.random(), 1.0, 0.3); - - const mesh = new THREE.Mesh(geometry, material); - group.add(mesh); - - // postprocessing - - const genCubeUrls = function (prefix, postfix) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, - prefix + 'py' + postfix, - prefix + 'ny' + postfix, - prefix + 'pz' + postfix, - prefix + 'nz' + postfix, - ]; - }; - - composer = new EffectComposer(renderer); - - clearPass = new ClearPass(params.clearColor, params.clearAlpha); - composer.addPass(clearPass); - - texturePass = new TexturePass(); - composer.addPass(texturePass); - - const textureLoader = new THREE.TextureLoader(); - textureLoader.load('textures/hardwood2_diffuse.jpg', function (map) { - map.colorSpace = THREE.SRGBColorSpace; - texturePass.map = map; - }); - - cubeTexturePassP = null; - - const ldrUrls = genCubeUrls('textures/cube/pisa/', '.png'); - new THREE.CubeTextureLoader().load(ldrUrls, function (ldrCubeMap) { - cubeTexturePassP = new CubeTexturePass(cameraP, ldrCubeMap); - composer.insertPass(cubeTexturePassP, 2); - }); - - renderPass = new RenderPass(scene, cameraP); - renderPass.clear = false; - composer.addPass(renderPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - const controls = new OrbitControls(cameraP, renderer.domElement); - controls.enableZoom = false; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - const aspect = width / height; - - cameraP.aspect = aspect; - cameraP.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - stats.begin(); - - cameraP.updateMatrixWorld(true); - - let newColor = clearPass.clearColor; - - switch (params.clearColor) { - case 'blue': - newColor = 0x0000ff; - break; - case 'red': - newColor = 0xff0000; - break; - case 'green': - newColor = 0x00ff00; - break; - case 'white': - newColor = 0xffffff; - break; - case 'black': - newColor = 0x000000; - break; - } - - clearPass.enabled = params.clearPass; - clearPass.clearColor = newColor; - clearPass.clearAlpha = params.clearAlpha; - - texturePass.enabled = params.texturePass; - texturePass.opacity = params.texturePassOpacity; - - if (cubeTexturePassP !== null) { - cubeTexturePassP.enabled = params.cubeTexturePass; - cubeTexturePassP.opacity = params.cubeTexturePassOpacity; - } - - renderPass.enabled = params.renderPass; - - composer.render(); - - stats.end(); -} diff --git a/examples-testing/examples/webgl_postprocessing_fxaa.ts b/examples-testing/examples/webgl_postprocessing_fxaa.ts deleted file mode 100644 index 55745f88e..000000000 --- a/examples-testing/examples/webgl_postprocessing_fxaa.ts +++ /dev/null @@ -1,132 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; - -let camera, scene, renderer, clock, group, container; - -let composer1, composer2, fxaaPass; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, container.offsetWidth / container.offsetHeight, 1, 2000); - camera.position.z = 500; - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d); - hemiLight.position.set(0, 1000, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(-3000, 1000, -1000); - scene.add(dirLight); - - // - - group = new THREE.Group(); - - const geometry = new THREE.TetrahedronGeometry(10); - const material = new THREE.MeshStandardMaterial({ color: 0xf73232, flatShading: true }); - - for (let i = 0; i < 100; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = Math.random() * 500 - 250; - mesh.position.y = Math.random() * 500 - 250; - mesh.position.z = Math.random() * 500 - 250; - - mesh.scale.setScalar(Math.random() * 2 + 1); - - mesh.rotation.x = Math.random() * Math.PI; - mesh.rotation.y = Math.random() * Math.PI; - mesh.rotation.z = Math.random() * Math.PI; - - group.add(mesh); - } - - scene.add(group); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(container.offsetWidth, container.offsetHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - container.appendChild(renderer.domElement); - - // - - const renderPass = new RenderPass(scene, camera); - renderPass.clearAlpha = 0; - - // - - fxaaPass = new ShaderPass(FXAAShader); - - const outputPass = new OutputPass(); - - composer1 = new EffectComposer(renderer); - composer1.addPass(renderPass); - composer1.addPass(outputPass); - - // - - const pixelRatio = renderer.getPixelRatio(); - - fxaaPass.material.uniforms['resolution'].value.x = 1 / (container.offsetWidth * pixelRatio); - fxaaPass.material.uniforms['resolution'].value.y = 1 / (container.offsetHeight * pixelRatio); - - composer2 = new EffectComposer(renderer); - composer2.addPass(renderPass); - composer2.addPass(outputPass); - - // FXAA is engineered to be applied towards the end of engine post processing after conversion to low dynamic range and conversion to the sRGB color space for display. - - composer2.addPass(fxaaPass); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = container.offsetWidth / container.offsetHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(container.offsetWidth, container.offsetHeight); - composer1.setSize(container.offsetWidth, container.offsetHeight); - composer2.setSize(container.offsetWidth, container.offsetHeight); - - const pixelRatio = renderer.getPixelRatio(); - - fxaaPass.material.uniforms['resolution'].value.x = 1 / (container.offsetWidth * pixelRatio); - fxaaPass.material.uniforms['resolution'].value.y = 1 / (container.offsetHeight * pixelRatio); -} - -function animate() { - const halfWidth = container.offsetWidth / 2; - - group.rotation.y += clock.getDelta() * 0.1; - - renderer.setScissorTest(true); - - renderer.setScissor(0, 0, halfWidth - 1, container.offsetHeight); - composer1.render(); - - renderer.setScissor(halfWidth, 0, halfWidth, container.offsetHeight); - composer2.render(); - - renderer.setScissorTest(false); -} diff --git a/examples-testing/examples/webgl_postprocessing_glitch.ts b/examples-testing/examples/webgl_postprocessing_glitch.ts deleted file mode 100644 index f846c0ce6..000000000 --- a/examples-testing/examples/webgl_postprocessing_glitch.ts +++ /dev/null @@ -1,97 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, scene, renderer, composer; -let object, light; - -let glitchPass; - -const button = document.querySelector('#startButton'); -button.addEventListener('click', function () { - const overlay = document.getElementById('overlay'); - overlay.remove(); - - init(); -}); - -function updateOptions() { - const wildGlitch = document.getElementById('wildGlitch'); - glitchPass.goWild = wildGlitch.checked; -} - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 400; - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1, 1000); - - object = new THREE.Object3D(); - scene.add(object); - - const geometry = new THREE.SphereGeometry(1, 4, 4); - - for (let i = 0; i < 100; i++) { - const material = new THREE.MeshPhongMaterial({ color: 0xffffff * Math.random(), flatShading: true }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize(); - mesh.position.multiplyScalar(Math.random() * 400); - mesh.rotation.set(Math.random() * 2, Math.random() * 2, Math.random() * 2); - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50; - object.add(mesh); - } - - scene.add(new THREE.AmbientLight(0xcccccc)); - - light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(1, 1, 1); - scene.add(light); - - // postprocessing - - composer = new EffectComposer(renderer); - composer.addPass(new RenderPass(scene, camera)); - - glitchPass = new GlitchPass(); - composer.addPass(glitchPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - // - - window.addEventListener('resize', onWindowResize); - - const wildGlitchOption = document.getElementById('wildGlitch'); - wildGlitchOption.addEventListener('change', updateOptions); - - updateOptions(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - object.rotation.x += 0.005; - object.rotation.y += 0.01; - - composer.render(); -} diff --git a/examples-testing/examples/webgl_postprocessing_godrays.ts b/examples-testing/examples/webgl_postprocessing_godrays.ts deleted file mode 100644 index fb7604411..000000000 --- a/examples-testing/examples/webgl_postprocessing_godrays.ts +++ /dev/null @@ -1,347 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { - GodRaysFakeSunShader, - GodRaysDepthMaskShader, - GodRaysCombineShader, - GodRaysGenerateShader, -} from 'three/addons/shaders/GodRaysShader.js'; - -let container, stats; -let camera, scene, renderer, materialDepth; - -let sphereMesh; - -const sunPosition = new THREE.Vector3(0, 1000, -1000); -const clipPosition = new THREE.Vector4(); -const screenSpacePosition = new THREE.Vector3(); - -const postprocessing = { enabled: true }; - -const orbitRadius = 200; - -const bgColor = 0x000511; -const sunColor = 0xffee00; - -// Use a smaller size for some of the god-ray render targets for better performance. -const godrayRenderTargetResolutionMultiplier = 1.0 / 4.0; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 3000); - camera.position.z = 200; - - scene = new THREE.Scene(); - - // - - materialDepth = new THREE.MeshDepthMaterial(); - - // tree - - const loader = new OBJLoader(); - loader.load('models/obj/tree.obj', function (object) { - object.position.set(0, -150, -150); - object.scale.multiplyScalar(400); - scene.add(object); - }); - - // sphere - - const geo = new THREE.SphereGeometry(1, 20, 10); - sphereMesh = new THREE.Mesh(geo, new THREE.MeshBasicMaterial({ color: 0x000000 })); - sphereMesh.scale.multiplyScalar(20); - scene.add(sphereMesh); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setClearColor(0xffffff); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - renderer.autoClear = false; - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 50; - controls.maxDistance = 500; - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); - - // - - initPostprocessing(window.innerWidth, window.innerHeight); -} - -// - -function onWindowResize() { - const renderTargetWidth = window.innerWidth; - const renderTargetHeight = window.innerHeight; - - camera.aspect = renderTargetWidth / renderTargetHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(renderTargetWidth, renderTargetHeight); - postprocessing.rtTextureColors.setSize(renderTargetWidth, renderTargetHeight); - postprocessing.rtTextureDepth.setSize(renderTargetWidth, renderTargetHeight); - postprocessing.rtTextureDepthMask.setSize(renderTargetWidth, renderTargetHeight); - - const adjustedWidth = renderTargetWidth * godrayRenderTargetResolutionMultiplier; - const adjustedHeight = renderTargetHeight * godrayRenderTargetResolutionMultiplier; - postprocessing.rtTextureGodRays1.setSize(adjustedWidth, adjustedHeight); - postprocessing.rtTextureGodRays2.setSize(adjustedWidth, adjustedHeight); -} - -function initPostprocessing(renderTargetWidth, renderTargetHeight) { - postprocessing.scene = new THREE.Scene(); - - postprocessing.camera = new THREE.OrthographicCamera(-0.5, 0.5, 0.5, -0.5, -10000, 10000); - postprocessing.camera.position.z = 100; - - postprocessing.scene.add(postprocessing.camera); - - postprocessing.rtTextureColors = new THREE.WebGLRenderTarget(renderTargetWidth, renderTargetHeight, { - type: THREE.HalfFloatType, - }); - - // Switching the depth formats to luminance from rgb doesn't seem to work. I didn't - // investigate further for now. - // pars.format = LuminanceFormat; - - // I would have this quarter size and use it as one of the ping-pong render - // targets but the aliasing causes some temporal flickering - - postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget(renderTargetWidth, renderTargetHeight, { - type: THREE.HalfFloatType, - }); - postprocessing.rtTextureDepthMask = new THREE.WebGLRenderTarget(renderTargetWidth, renderTargetHeight, { - type: THREE.HalfFloatType, - }); - - // The ping-pong render targets can use an adjusted resolution to minimize cost - - const adjustedWidth = renderTargetWidth * godrayRenderTargetResolutionMultiplier; - const adjustedHeight = renderTargetHeight * godrayRenderTargetResolutionMultiplier; - postprocessing.rtTextureGodRays1 = new THREE.WebGLRenderTarget(adjustedWidth, adjustedHeight, { - type: THREE.HalfFloatType, - }); - postprocessing.rtTextureGodRays2 = new THREE.WebGLRenderTarget(adjustedWidth, adjustedHeight, { - type: THREE.HalfFloatType, - }); - - // god-ray shaders - - const godraysMaskShader = GodRaysDepthMaskShader; - postprocessing.godrayMaskUniforms = THREE.UniformsUtils.clone(godraysMaskShader.uniforms); - postprocessing.materialGodraysDepthMask = new THREE.ShaderMaterial({ - uniforms: postprocessing.godrayMaskUniforms, - vertexShader: godraysMaskShader.vertexShader, - fragmentShader: godraysMaskShader.fragmentShader, - }); - - const godraysGenShader = GodRaysGenerateShader; - postprocessing.godrayGenUniforms = THREE.UniformsUtils.clone(godraysGenShader.uniforms); - postprocessing.materialGodraysGenerate = new THREE.ShaderMaterial({ - uniforms: postprocessing.godrayGenUniforms, - vertexShader: godraysGenShader.vertexShader, - fragmentShader: godraysGenShader.fragmentShader, - }); - - const godraysCombineShader = GodRaysCombineShader; - postprocessing.godrayCombineUniforms = THREE.UniformsUtils.clone(godraysCombineShader.uniforms); - postprocessing.materialGodraysCombine = new THREE.ShaderMaterial({ - uniforms: postprocessing.godrayCombineUniforms, - vertexShader: godraysCombineShader.vertexShader, - fragmentShader: godraysCombineShader.fragmentShader, - }); - - const godraysFakeSunShader = GodRaysFakeSunShader; - postprocessing.godraysFakeSunUniforms = THREE.UniformsUtils.clone(godraysFakeSunShader.uniforms); - postprocessing.materialGodraysFakeSun = new THREE.ShaderMaterial({ - uniforms: postprocessing.godraysFakeSunUniforms, - vertexShader: godraysFakeSunShader.vertexShader, - fragmentShader: godraysFakeSunShader.fragmentShader, - }); - - postprocessing.godraysFakeSunUniforms.bgColor.value.setHex(bgColor); - postprocessing.godraysFakeSunUniforms.sunColor.value.setHex(sunColor); - - postprocessing.godrayCombineUniforms.fGodRayIntensity.value = 0.75; - - postprocessing.quad = new THREE.Mesh(new THREE.PlaneGeometry(1.0, 1.0), postprocessing.materialGodraysGenerate); - postprocessing.quad.position.z = -9900; - postprocessing.scene.add(postprocessing.quad); -} - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function getStepSize(filterLen, tapsPerPass, pass) { - return filterLen * Math.pow(tapsPerPass, -pass); -} - -function filterGodRays(inputTex, renderTarget, stepSize) { - postprocessing.scene.overrideMaterial = postprocessing.materialGodraysGenerate; - - postprocessing.godrayGenUniforms['fStepSize'].value = stepSize; - postprocessing.godrayGenUniforms['tInput'].value = inputTex; - - renderer.setRenderTarget(renderTarget); - renderer.render(postprocessing.scene, postprocessing.camera); - postprocessing.scene.overrideMaterial = null; -} - -function render() { - const time = Date.now() / 4000; - - sphereMesh.position.x = orbitRadius * Math.cos(time); - sphereMesh.position.z = orbitRadius * Math.sin(time) - 100; - - if (postprocessing.enabled) { - clipPosition.x = sunPosition.x; - clipPosition.y = sunPosition.y; - clipPosition.z = sunPosition.z; - clipPosition.w = 1; - - clipPosition.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); - - // perspective divide (produce NDC space) - - clipPosition.x /= clipPosition.w; - clipPosition.y /= clipPosition.w; - - screenSpacePosition.x = (clipPosition.x + 1) / 2; // transform from [-1,1] to [0,1] - screenSpacePosition.y = (clipPosition.y + 1) / 2; // transform from [-1,1] to [0,1] - screenSpacePosition.z = clipPosition.z; // needs to stay in clip space for visibilty checks - - // Give it to the god-ray and sun shaders - - postprocessing.godrayGenUniforms['vSunPositionScreenSpace'].value.copy(screenSpacePosition); - postprocessing.godraysFakeSunUniforms['vSunPositionScreenSpace'].value.copy(screenSpacePosition); - - // -- Draw sky and sun -- - - // Clear colors and depths, will clear to sky color - - renderer.setRenderTarget(postprocessing.rtTextureColors); - renderer.clear(true, true, false); - - // Sun render. Runs a shader that gives a brightness based on the screen - // space distance to the sun. Not very efficient, so i make a scissor - // rectangle around the suns position to avoid rendering surrounding pixels. - - const sunsqH = 0.74 * window.innerHeight; // 0.74 depends on extent of sun from shader - const sunsqW = 0.74 * window.innerHeight; // both depend on height because sun is aspect-corrected - - screenSpacePosition.x *= window.innerWidth; - screenSpacePosition.y *= window.innerHeight; - - renderer.setScissor(screenSpacePosition.x - sunsqW / 2, screenSpacePosition.y - sunsqH / 2, sunsqW, sunsqH); - renderer.setScissorTest(true); - - postprocessing.godraysFakeSunUniforms['fAspect'].value = window.innerWidth / window.innerHeight; - - postprocessing.scene.overrideMaterial = postprocessing.materialGodraysFakeSun; - renderer.setRenderTarget(postprocessing.rtTextureColors); - renderer.render(postprocessing.scene, postprocessing.camera); - - renderer.setScissorTest(false); - - // -- Draw scene objects -- - - // Colors - - scene.overrideMaterial = null; - renderer.setRenderTarget(postprocessing.rtTextureColors); - renderer.render(scene, camera); - - // Depth - - scene.overrideMaterial = materialDepth; - renderer.setRenderTarget(postprocessing.rtTextureDepth); - renderer.clear(); - renderer.render(scene, camera); - - // - - postprocessing.godrayMaskUniforms['tInput'].value = postprocessing.rtTextureDepth.texture; - - postprocessing.scene.overrideMaterial = postprocessing.materialGodraysDepthMask; - renderer.setRenderTarget(postprocessing.rtTextureDepthMask); - renderer.render(postprocessing.scene, postprocessing.camera); - - // -- Render god-rays -- - - // Maximum length of god-rays (in texture space [0,1]X[0,1]) - - const filterLen = 1.0; - - // Samples taken by filter - - const TAPS_PER_PASS = 6.0; - - // Pass order could equivalently be 3,2,1 (instead of 1,2,3), which - // would start with a small filter support and grow to large. however - // the large-to-small order produces less objectionable aliasing artifacts that - // appear as a glimmer along the length of the beams - - // pass 1 - render into first ping-pong target - filterGodRays( - postprocessing.rtTextureDepthMask.texture, - postprocessing.rtTextureGodRays2, - getStepSize(filterLen, TAPS_PER_PASS, 1.0), - ); - - // pass 2 - render into second ping-pong target - filterGodRays( - postprocessing.rtTextureGodRays2.texture, - postprocessing.rtTextureGodRays1, - getStepSize(filterLen, TAPS_PER_PASS, 2.0), - ); - - // pass 3 - 1st RT - filterGodRays( - postprocessing.rtTextureGodRays1.texture, - postprocessing.rtTextureGodRays2, - getStepSize(filterLen, TAPS_PER_PASS, 3.0), - ); - - // final pass - composite god-rays onto colors - - postprocessing.godrayCombineUniforms['tColors'].value = postprocessing.rtTextureColors.texture; - postprocessing.godrayCombineUniforms['tGodRays'].value = postprocessing.rtTextureGodRays2.texture; - - postprocessing.scene.overrideMaterial = postprocessing.materialGodraysCombine; - - renderer.setRenderTarget(null); - renderer.render(postprocessing.scene, postprocessing.camera); - postprocessing.scene.overrideMaterial = null; - } else { - renderer.setRenderTarget(null); - renderer.clear(); - renderer.render(scene, camera); - } -} diff --git a/examples-testing/examples/webgl_postprocessing_gtao.ts b/examples-testing/examples/webgl_postprocessing_gtao.ts deleted file mode 100644 index 4f16d1554..000000000 --- a/examples-testing/examples/webgl_postprocessing_gtao.ts +++ /dev/null @@ -1,215 +0,0 @@ -import * as THREE from 'three'; -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { GTAOPass } from 'three/addons/postprocessing/GTAOPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, scene, renderer, composer, controls, clock, stats, mixer; - -init(); - -function init() { - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('jsm/libs/draco/'); - dracoLoader.setDecoderConfig({ type: 'js' }); - const loader = new GLTFLoader(); - loader.setDRACOLoader(dracoLoader); - loader.setPath('models/gltf/'); - - clock = new THREE.Clock(); - const container = document.createElement('div'); - document.body.appendChild(container); - - stats = new Stats(); - container.appendChild(stats.dom); - - renderer = new THREE.WebGLRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xbfe3dd); - scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture; - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(5, 2, 8); - - controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0.5, 0); - controls.update(); - controls.enablePan = false; - controls.enableDamping = true; - - const width = window.innerWidth; - const height = window.innerHeight; - - composer = new EffectComposer(renderer); - - const renderPass = new RenderPass(scene, camera); - composer.addPass(renderPass); - - const gtaoPass = new GTAOPass(scene, camera, width, height); - gtaoPass.output = GTAOPass.OUTPUT.Denoise; - composer.addPass(gtaoPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - // - - loader.load( - 'LittlestTokyo.glb', - gltf => { - const model = gltf.scene; - model.position.set(1, 1, 0); - model.scale.set(0.01, 0.01, 0.01); - scene.add(model); - - mixer = new THREE.AnimationMixer(model); - mixer.clipAction(gltf.animations[0]).play(); - - const box = new THREE.Box3().setFromObject(scene); - gtaoPass.setSceneClipBox(box); - }, - undefined, - e => console.error(e), - ); - - // Init gui - const gui = new GUI(); - - gui.add(gtaoPass, 'output', { - Default: GTAOPass.OUTPUT.Default, - Diffuse: GTAOPass.OUTPUT.Diffuse, - 'AO Only': GTAOPass.OUTPUT.AO, - 'AO Only + Denoise': GTAOPass.OUTPUT.Denoise, - Depth: GTAOPass.OUTPUT.Depth, - Normal: GTAOPass.OUTPUT.Normal, - }).onChange(function (value) { - gtaoPass.output = value; - }); - - const aoParameters = { - radius: 0.25, - distanceExponent: 1, - thickness: 1, - scale: 1, - samples: 16, - distanceFallOff: 1, - screenSpaceRadius: false, - }; - const pdParameters = { - lumaPhi: 10, - depthPhi: 2, - normalPhi: 3, - radius: 4, - radiusExponent: 1, - rings: 2, - samples: 16, - }; - gtaoPass.updateGtaoMaterial(aoParameters); - gtaoPass.updatePdMaterial(pdParameters); - gui.add(gtaoPass, 'blendIntensity').min(0).max(1).step(0.01); - gui.add(aoParameters, 'radius') - .min(0.01) - .max(1) - .step(0.01) - .onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(aoParameters, 'distanceExponent') - .min(1) - .max(4) - .step(0.01) - .onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(aoParameters, 'thickness') - .min(0.01) - .max(10) - .step(0.01) - .onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(aoParameters, 'distanceFallOff') - .min(0) - .max(1) - .step(0.01) - .onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(aoParameters, 'scale') - .min(0.01) - .max(2.0) - .step(0.01) - .onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(aoParameters, 'samples') - .min(2) - .max(32) - .step(1) - .onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(aoParameters, 'screenSpaceRadius').onChange(() => gtaoPass.updateGtaoMaterial(aoParameters)); - gui.add(pdParameters, 'lumaPhi') - .min(0) - .max(20) - .step(0.01) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - gui.add(pdParameters, 'depthPhi') - .min(0.01) - .max(20) - .step(0.01) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - gui.add(pdParameters, 'normalPhi') - .min(0.01) - .max(20) - .step(0.01) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - gui.add(pdParameters, 'radius') - .min(0) - .max(32) - .step(1) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - gui.add(pdParameters, 'radiusExponent') - .min(0.1) - .max(4) - .step(0.1) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - gui.add(pdParameters, 'rings') - .min(1) - .max(16) - .step(0.125) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - gui.add(pdParameters, 'samples') - .min(2) - .max(32) - .step(1) - .onChange(() => gtaoPass.updatePdMaterial(pdParameters)); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) { - mixer.update(delta); - } - - controls.update(); - - stats.begin(); - composer.render(); - stats.end(); -} diff --git a/examples-testing/examples/webgl_postprocessing_masking.ts b/examples-testing/examples/webgl_postprocessing_masking.ts deleted file mode 100644 index f6e7310bf..000000000 --- a/examples-testing/examples/webgl_postprocessing_masking.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { TexturePass } from 'three/addons/postprocessing/TexturePass.js'; -import { ClearPass } from 'three/addons/postprocessing/ClearPass.js'; -import { MaskPass, ClearMaskPass } from 'three/addons/postprocessing/MaskPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, composer, renderer; -let box, torus; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 10; - - const scene1 = new THREE.Scene(); - const scene2 = new THREE.Scene(); - - box = new THREE.Mesh(new THREE.BoxGeometry(4, 4, 4)); - scene1.add(box); - - torus = new THREE.Mesh(new THREE.TorusGeometry(3, 1, 16, 32)); - scene2.add(torus); - - renderer = new THREE.WebGLRenderer(); - renderer.setClearColor(0xe0e0e0); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - document.body.appendChild(renderer.domElement); - - // - - const clearPass = new ClearPass(); - - const clearMaskPass = new ClearMaskPass(); - - const maskPass1 = new MaskPass(scene1, camera); - const maskPass2 = new MaskPass(scene2, camera); - - const texture1 = new THREE.TextureLoader().load('textures/758px-Canestra_di_frutta_(Caravaggio).jpg'); - texture1.colorSpace = THREE.SRGBColorSpace; - texture1.minFilter = THREE.LinearFilter; - const texture2 = new THREE.TextureLoader().load('textures/2294472375_24a3b8ef46_o.jpg'); - texture2.colorSpace = THREE.SRGBColorSpace; - - const texturePass1 = new TexturePass(texture1); - const texturePass2 = new TexturePass(texture2); - - const outputPass = new OutputPass(); - - const parameters = { - stencilBuffer: true, - }; - - const renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, parameters); - - composer = new EffectComposer(renderer, renderTarget); - composer.addPass(clearPass); - composer.addPass(maskPass1); - composer.addPass(texturePass1); - composer.addPass(clearMaskPass); - composer.addPass(maskPass2); - composer.addPass(texturePass2); - composer.addPass(clearMaskPass); - composer.addPass(outputPass); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - const time = performance.now() * 0.001 + 6000; - - box.position.x = Math.cos(time / 1.5) * 2; - box.position.y = Math.sin(time) * 2; - box.rotation.x = time; - box.rotation.y = time / 2; - - torus.position.x = Math.cos(time) * 2; - torus.position.y = Math.sin(time / 1.5) * 2; - torus.rotation.x = time; - torus.rotation.y = time / 2; - - renderer.clear(); - composer.render(time); -} diff --git a/examples-testing/examples/webgl_postprocessing_material_ao.ts b/examples-testing/examples/webgl_postprocessing_material_ao.ts deleted file mode 100644 index 2f17a5304..000000000 --- a/examples-testing/examples/webgl_postprocessing_material_ao.ts +++ /dev/null @@ -1,277 +0,0 @@ -import * as THREE from 'three'; -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { GTAOPass } from 'three/addons/postprocessing/GTAOPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { MeshPostProcessingMaterial } from 'three/addons/materials/MeshPostProcessingMaterial.js'; - -let renderer, camera, scene, composer, controls, stats; -const sceneParameters = { - output: 0, - envMapIntensity: 1.0, - ambientLightIntensity: 0.0, - lightIntensity: 50, - shadow: true, -}; -const aoParameters = { - radius: 0.5, - distanceExponent: 2, - thickness: 10, - scale: 1, - samples: 16, - distanceFallOff: 1, -}; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - stats = new Stats(); - container.appendChild(stats.dom); - - renderer = new THREE.WebGLRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - renderer.shadowMap.enabled = sceneParameters.shadow; - - const plyLoader = new PLYLoader(); - const rgbeloader = new RGBELoader(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 50); - camera.position.set(0, 3, 5); - controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 1, 0); - controls.update(); - controls.enablePan = false; - controls.enableDamping = true; - - const width = window.innerWidth; - const height = window.innerHeight; - - scene = new THREE.Scene(); - composer = new EffectComposer(renderer); - - const gtaoPass = new GTAOPass(scene, camera, width, height); - gtaoPass.output = GTAOPass.OUTPUT.Off; - const renderPasse = new RenderPass(scene, camera); - const outputPass = new OutputPass(); - - composer.addPass(gtaoPass); - composer.addPass(renderPasse); - composer.addPass(outputPass); - - rgbeloader.load('textures/equirectangular/royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - scene.environment = texture; - }); - - const groundMaterial = new MeshPostProcessingMaterial({ - color: 0x7f7f7f, - envMapIntensity: sceneParameters.envMapIntensity, - aoPassMap: gtaoPass.gtaoMap, - }); - const objectMaterial = new MeshPostProcessingMaterial({ - color: 0xffffff, - roughness: 0.5, - metalness: 0.5, - envMapIntensity: sceneParameters.envMapIntensity, - aoPassMap: gtaoPass.gtaoMap, - }); - const emissiveMaterial = new MeshPostProcessingMaterial({ - color: 0, - emissive: 0xffffff, - aoPassMap: gtaoPass.gtaoMap, - }); - plyLoader.load('models/ply/binary/Lucy100k.ply', geometry => { - geometry.computeVertexNormals(); - const lucy = new THREE.Mesh(geometry, objectMaterial); - lucy.receiveShadow = true; - lucy.castShadow = true; - lucy.scale.setScalar(0.001); - lucy.rotation.set(0, Math.PI, 0); - lucy.position.set(0.04, 1.8, 0.02); - scene.add(lucy); - }); - const ambientLight = new THREE.AmbientLight(0xffffff, sceneParameters.ambientLightIntensity); - const lightGroup = new THREE.Group(); - const planeGeometry = new THREE.PlaneGeometry(6, 6); - const cylinderGeometry = new THREE.CylinderGeometry(0.5, 0.5, 1, 64); - const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32); - const lightSphereGeometry = new THREE.SphereGeometry(0.1, 32, 32); - scene.background = new THREE.Color(0xbfe3dd); - scene.add(ambientLight); - scene.add(lightGroup); - const targetObject = new THREE.Object3D(); - targetObject.position.set(0, 1, 0); - scene.add(targetObject); - const lightColors = [0xff4040, 0x40ff40, 0x4040ff]; - for (let j = 0; j < 3; ++j) { - const light = new THREE.SpotLight(lightColors[j], sceneParameters.lightIntensity, 0, Math.PI / 9); - light.castShadow = true; - light.shadow.camera.far = 15; - light.position.set(5 * Math.cos((Math.PI * j * 2) / 3), 2.5, 5 * Math.sin((Math.PI * j * 2) / 3)); - light.target = targetObject; - lightGroup.add(light); - } - - const groundPlane = new THREE.Mesh(planeGeometry, groundMaterial); - groundPlane.rotation.x = -Math.PI / 2; - groundPlane.position.set(0, 0, 0); - groundPlane.receiveShadow = true; - scene.add(groundPlane); - const pedestal = new THREE.Mesh(cylinderGeometry, groundMaterial); - pedestal.position.set(0, 0.5, 0); - pedestal.receiveShadow = true; - pedestal.castShadow = true; - scene.add(pedestal); - const sphereMesh = new THREE.InstancedMesh(sphereGeometry, objectMaterial, 6); - sphereMesh.receiveShadow = true; - sphereMesh.castShadow = true; - scene.add(sphereMesh); - [...Array(6).keys()].forEach(i => - sphereMesh.setMatrixAt( - i, - new THREE.Matrix4().makeTranslation(Math.cos((Math.PI * i) / 3), 0.5, Math.sin((Math.PI * i) / 3)), - ), - ); - const lightSphereMesh = new THREE.InstancedMesh(lightSphereGeometry, emissiveMaterial, 4); - scene.add(lightSphereMesh); - [...Array(4).keys()].forEach(i => - lightSphereMesh.setMatrixAt( - i, - new THREE.Matrix4().makeTranslation( - 0.4 * Math.cos((Math.PI * (i + 0.5)) / 2), - 1.1, - 0.45 * Math.sin((Math.PI * (i + 0.5)) / 2), - ), - ), - ); - - const updateGtaoMaterial = () => gtaoPass.updateGtaoMaterial(aoParameters); - const updateOutput = () => { - composer.removePass(gtaoPass); - composer.insertPass(gtaoPass, sceneParameters.output == 1 ? 1 : 0); - - switch (sceneParameters.output) { - default: - case 0: - gtaoPass.output = GTAOPass.OUTPUT.Off; - gtaoPass.enabled = true; - renderPasse.enabled = true; - break; - case 1: - gtaoPass.output = GTAOPass.OUTPUT.Default; - gtaoPass.enabled = true; - renderPasse.enabled = true; - break; - case 2: - gtaoPass.output = GTAOPass.OUTPUT.Diffuse; - gtaoPass.enabled = false; - renderPasse.enabled = true; - break; - case 3: - gtaoPass.output = GTAOPass.OUTPUT.Denoise; - gtaoPass.enabled = true; - renderPasse.enabled = false; - break; - } - - groundMaterial.aoPassMap = sceneParameters.output === 0 ? gtaoPass.gtaoMap : null; - objectMaterial.aoPassMap = sceneParameters.output === 0 ? gtaoPass.gtaoMap : null; - }; - - updateOutput(); - updateGtaoMaterial(); - - const gui = new GUI(); - gui.add(sceneParameters, 'output', { - 'material AO': 0, - 'post blended AO': 1, - 'only diffuse': 2, - 'only AO': 3, - }).onChange(() => updateOutput()); - gui.add(sceneParameters, 'envMapIntensity') - .min(0) - .max(1) - .step(0.01) - .onChange(() => { - groundMaterial.envMapIntensity = sceneParameters.envMapIntensity; - objectMaterial.envMapIntensity = sceneParameters.envMapIntensity; - }); - gui.add(sceneParameters, 'ambientLightIntensity') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(() => { - ambientLight.intensity = sceneParameters.ambientLightIntensity; - }); - gui.add(sceneParameters, 'lightIntensity') - .min(0) - .max(100) - .step(1) - .onChange(() => { - lightGroup.children.forEach(light => (light.intensity = sceneParameters.lightIntensity)); - }); - gui.add(sceneParameters, 'shadow').onChange(value => { - renderer.shadowMap.enabled = value; - lightGroup.children.forEach(light => (light.castShadow = value)); - }); - gui.add(aoParameters, 'radius') - .min(0.01) - .max(2) - .step(0.01) - .onChange(() => updateGtaoMaterial()); - gui.add(aoParameters, 'distanceExponent') - .min(1) - .max(4) - .step(0.01) - .onChange(() => updateGtaoMaterial()); - gui.add(aoParameters, 'thickness') - .min(0.01) - .max(10) - .step(0.01) - .onChange(() => updateGtaoMaterial()); - gui.add(aoParameters, 'distanceFallOff') - .min(0) - .max(1) - .step(0.01) - .onChange(() => updateGtaoMaterial()); - gui.add(aoParameters, 'scale') - .min(0.01) - .max(2.0) - .step(0.01) - .onChange(() => updateGtaoMaterial()); - gui.add(aoParameters, 'samples') - .min(2) - .max(32) - .step(1) - .onChange(() => updateGtaoMaterial()); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - controls.update(); - stats.begin(); - composer.render(); - stats.end(); -} diff --git a/examples-testing/examples/webgl_postprocessing_outline.ts b/examples-testing/examples/webgl_postprocessing_outline.ts deleted file mode 100644 index 356575460..000000000 --- a/examples-testing/examples/webgl_postprocessing_outline.ts +++ /dev/null @@ -1,282 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; -import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; - -let container, stats; -let camera, scene, renderer, controls; -let composer, effectFXAA, outlinePass; - -let selectedObjects = []; - -const raycaster = new THREE.Raycaster(); -const mouse = new THREE.Vector2(); - -const obj3d = new THREE.Object3D(); -const group = new THREE.Group(); - -const params = { - edgeStrength: 3.0, - edgeGlow: 0.0, - edgeThickness: 1.0, - pulsePeriod: 0, - rotate: false, - usePatternTexture: false, -}; - -// Init gui - -const gui = new GUI({ width: 280 }); - -gui.add(params, 'edgeStrength', 0.01, 10).onChange(function (value) { - outlinePass.edgeStrength = Number(value); -}); - -gui.add(params, 'edgeGlow', 0.0, 1).onChange(function (value) { - outlinePass.edgeGlow = Number(value); -}); - -gui.add(params, 'edgeThickness', 1, 4).onChange(function (value) { - outlinePass.edgeThickness = Number(value); -}); - -gui.add(params, 'pulsePeriod', 0.0, 5).onChange(function (value) { - outlinePass.pulsePeriod = Number(value); -}); - -gui.add(params, 'rotate'); - -gui.add(params, 'usePatternTexture').onChange(function (value) { - outlinePass.usePatternTexture = value; -}); - -function Configuration() { - this.visibleEdgeColor = '#ffffff'; - this.hiddenEdgeColor = '#190a05'; -} - -const conf = new Configuration(); - -gui.addColor(conf, 'visibleEdgeColor').onChange(function (value) { - outlinePass.visibleEdgeColor.set(value); -}); - -gui.addColor(conf, 'hiddenEdgeColor').onChange(function (value) { - outlinePass.hiddenEdgeColor.set(value); -}); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - const width = window.innerWidth; - const height = window.innerHeight; - - renderer = new THREE.WebGLRenderer(); - renderer.shadowMap.enabled = true; - // todo - support pixelRatio in this demo - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100); - camera.position.set(0, 0, 8); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 5; - controls.maxDistance = 20; - controls.enablePan = false; - controls.enableDamping = true; - controls.dampingFactor = 0.05; - - // - - scene.add(new THREE.AmbientLight(0xaaaaaa, 0.6)); - - const light = new THREE.DirectionalLight(0xddffdd, 2); - light.position.set(1, 1, 1); - light.castShadow = true; - light.shadow.mapSize.width = 1024; - light.shadow.mapSize.height = 1024; - - const d = 10; - - light.shadow.camera.left = -d; - light.shadow.camera.right = d; - light.shadow.camera.top = d; - light.shadow.camera.bottom = -d; - light.shadow.camera.far = 1000; - - scene.add(light); - - // model - - const loader = new OBJLoader(); - loader.load('models/obj/tree.obj', function (object) { - let scale = 1.0; - - object.traverse(function (child) { - if (child instanceof THREE.Mesh) { - child.geometry.center(); - child.geometry.computeBoundingSphere(); - scale = 0.2 * child.geometry.boundingSphere.radius; - - const phongMaterial = new THREE.MeshPhongMaterial({ - color: 0xffffff, - specular: 0x111111, - shininess: 5, - }); - child.material = phongMaterial; - child.receiveShadow = true; - child.castShadow = true; - } - }); - - object.position.y = 1; - object.scale.divideScalar(scale); - obj3d.add(object); - }); - - scene.add(group); - - group.add(obj3d); - - // - - const geometry = new THREE.SphereGeometry(3, 48, 24); - - for (let i = 0; i < 20; i++) { - const material = new THREE.MeshLambertMaterial(); - material.color.setHSL(Math.random(), 1.0, 0.3); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 4 - 2; - mesh.position.y = Math.random() * 4 - 2; - mesh.position.z = Math.random() * 4 - 2; - mesh.receiveShadow = true; - mesh.castShadow = true; - mesh.scale.multiplyScalar(Math.random() * 0.3 + 0.1); - group.add(mesh); - } - - const floorMaterial = new THREE.MeshLambertMaterial({ side: THREE.DoubleSide }); - - const floorGeometry = new THREE.PlaneGeometry(12, 12); - const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial); - floorMesh.rotation.x -= Math.PI * 0.5; - floorMesh.position.y -= 1.5; - group.add(floorMesh); - floorMesh.receiveShadow = true; - - const torusGeometry = new THREE.TorusGeometry(1, 0.3, 16, 100); - const torusMaterial = new THREE.MeshPhongMaterial({ color: 0xffaaff }); - const torus = new THREE.Mesh(torusGeometry, torusMaterial); - torus.position.z = -4; - group.add(torus); - torus.receiveShadow = true; - torus.castShadow = true; - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // postprocessing - - composer = new EffectComposer(renderer); - - const renderPass = new RenderPass(scene, camera); - composer.addPass(renderPass); - - outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera); - composer.addPass(outlinePass); - - const textureLoader = new THREE.TextureLoader(); - textureLoader.load('textures/tri_pattern.jpg', function (texture) { - outlinePass.patternTexture = texture; - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - }); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - effectFXAA = new ShaderPass(FXAAShader); - effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight); - composer.addPass(effectFXAA); - - window.addEventListener('resize', onWindowResize); - - renderer.domElement.style.touchAction = 'none'; - renderer.domElement.addEventListener('pointermove', onPointerMove); - - function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - checkIntersection(); - } - - function addSelectedObject(object) { - selectedObjects = []; - selectedObjects.push(object); - } - - function checkIntersection() { - raycaster.setFromCamera(mouse, camera); - - const intersects = raycaster.intersectObject(scene, true); - - if (intersects.length > 0) { - const selectedObject = intersects[0].object; - addSelectedObject(selectedObject); - outlinePass.selectedObjects = selectedObjects; - } else { - // outlinePass.selectedObjects = []; - } - } -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); - - effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight); -} - -function animate() { - stats.begin(); - - const timer = performance.now(); - - if (params.rotate) { - group.rotation.y = timer * 0.0001; - } - - controls.update(); - - composer.render(); - - stats.end(); -} diff --git a/examples-testing/examples/webgl_postprocessing_pixel.ts b/examples-testing/examples/webgl_postprocessing_pixel.ts deleted file mode 100644 index 15b54d072..000000000 --- a/examples-testing/examples/webgl_postprocessing_pixel.ts +++ /dev/null @@ -1,228 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPixelatedPass } from 'three/addons/postprocessing/RenderPixelatedPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, composer, crystalMesh, clock; -let gui, params; - -init(); - -function init() { - const aspectRatio = window.innerWidth / window.innerHeight; - - camera = new THREE.OrthographicCamera(-aspectRatio, aspectRatio, 1, -1, 0.1, 10); - camera.position.y = 2 * Math.tan(Math.PI / 6); - camera.position.z = 2; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x151729); - - clock = new THREE.Clock(); - - renderer = new THREE.WebGLRenderer(); - renderer.shadowMap.enabled = true; - //renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - composer = new EffectComposer(renderer); - const renderPixelatedPass = new RenderPixelatedPass(6, scene, camera); - composer.addPass(renderPixelatedPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - window.addEventListener('resize', onWindowResize); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.maxZoom = 2; - - // gui - - gui = new GUI(); - params = { pixelSize: 6, normalEdgeStrength: 0.3, depthEdgeStrength: 0.4, pixelAlignedPanning: true }; - gui.add(params, 'pixelSize') - .min(1) - .max(16) - .step(1) - .onChange(() => { - renderPixelatedPass.setPixelSize(params.pixelSize); - }); - gui.add(renderPixelatedPass, 'normalEdgeStrength').min(0).max(2).step(0.05); - gui.add(renderPixelatedPass, 'depthEdgeStrength').min(0).max(1).step(0.05); - gui.add(params, 'pixelAlignedPanning'); - - // textures - - const loader = new THREE.TextureLoader(); - const texChecker = pixelTexture(loader.load('textures/checker.png')); - const texChecker2 = pixelTexture(loader.load('textures/checker.png')); - texChecker.repeat.set(3, 3); - texChecker2.repeat.set(1.5, 1.5); - - // meshes - - const boxMaterial = new THREE.MeshPhongMaterial({ map: texChecker2 }); - - function addBox(boxSideLength, x, z, rotation) { - const mesh = new THREE.Mesh(new THREE.BoxGeometry(boxSideLength, boxSideLength, boxSideLength), boxMaterial); - mesh.castShadow = true; - mesh.receiveShadow = true; - mesh.rotation.y = rotation; - mesh.position.y = boxSideLength / 2; - mesh.position.set(x, boxSideLength / 2 + 0.0001, z); - scene.add(mesh); - return mesh; - } - - addBox(0.4, 0, 0, Math.PI / 4); - addBox(0.5, -0.5, -0.5, Math.PI / 4); - - const planeSideLength = 2; - const planeMesh = new THREE.Mesh( - new THREE.PlaneGeometry(planeSideLength, planeSideLength), - new THREE.MeshPhongMaterial({ map: texChecker }), - ); - planeMesh.receiveShadow = true; - planeMesh.rotation.x = -Math.PI / 2; - scene.add(planeMesh); - - const radius = 0.2; - const geometry = new THREE.IcosahedronGeometry(radius); - crystalMesh = new THREE.Mesh( - geometry, - new THREE.MeshPhongMaterial({ - color: 0x68b7e9, - emissive: 0x4f7e8b, - shininess: 10, - specular: 0xffffff, - }), - ); - crystalMesh.receiveShadow = true; - crystalMesh.castShadow = true; - scene.add(crystalMesh); - - // lights - - scene.add(new THREE.AmbientLight(0x757f8e, 3)); - - const directionalLight = new THREE.DirectionalLight(0xfffecd, 1.5); - directionalLight.position.set(100, 100, 100); - directionalLight.castShadow = true; - directionalLight.shadow.mapSize.set(2048, 2048); - scene.add(directionalLight); - - const spotLight = new THREE.SpotLight(0xffc100, 10, 10, Math.PI / 16, 0.02, 2); - spotLight.position.set(2, 2, 0); - const target = spotLight.target; - scene.add(target); - target.position.set(0, 0, 0); - spotLight.castShadow = true; - scene.add(spotLight); -} - -function onWindowResize() { - const aspectRatio = window.innerWidth / window.innerHeight; - camera.left = -aspectRatio; - camera.right = aspectRatio; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const t = clock.getElapsedTime(); - - crystalMesh.material.emissiveIntensity = Math.sin(t * 3) * 0.5 + 0.5; - crystalMesh.position.y = 0.7 + Math.sin(t * 2) * 0.05; - crystalMesh.rotation.y = stopGoEased(t, 2, 4) * 2 * Math.PI; - - const rendererSize = renderer.getSize(new THREE.Vector2()); - const aspectRatio = rendererSize.x / rendererSize.y; - if (params['pixelAlignedPanning']) { - pixelAlignFrustum( - camera, - aspectRatio, - Math.floor(rendererSize.x / params['pixelSize']), - Math.floor(rendererSize.y / params['pixelSize']), - ); - } else if (camera.left != -aspectRatio || camera.top != 1.0) { - // Reset the Camera Frustum if it has been modified - camera.left = -aspectRatio; - camera.right = aspectRatio; - camera.top = 1.0; - camera.bottom = -1.0; - camera.updateProjectionMatrix(); - } - - composer.render(); -} - -// Helper functions - -function pixelTexture(texture) { - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.generateMipmaps = false; - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - texture.colorSpace = THREE.SRGBColorSpace; - return texture; -} - -function easeInOutCubic(x) { - return x ** 2 * 3 - x ** 3 * 2; -} - -function linearStep(x, edge0, edge1) { - const w = edge1 - edge0; - const m = 1 / w; - const y0 = -m * edge0; - return THREE.MathUtils.clamp(y0 + m * x, 0, 1); -} - -function stopGoEased(x, downtime, period) { - const cycle = (x / period) | 0; - const tween = x - cycle * period; - const linStep = easeInOutCubic(linearStep(tween, downtime, period)); - return cycle + linStep; -} - -function pixelAlignFrustum(camera, aspectRatio, pixelsPerScreenWidth, pixelsPerScreenHeight) { - // 0. Get Pixel Grid Units - const worldScreenWidth = (camera.right - camera.left) / camera.zoom; - const worldScreenHeight = (camera.top - camera.bottom) / camera.zoom; - const pixelWidth = worldScreenWidth / pixelsPerScreenWidth; - const pixelHeight = worldScreenHeight / pixelsPerScreenHeight; - - // 1. Project the current camera position along its local rotation bases - const camPos = new THREE.Vector3(); - camera.getWorldPosition(camPos); - const camRot = new THREE.Quaternion(); - camera.getWorldQuaternion(camRot); - const camRight = new THREE.Vector3(1.0, 0.0, 0.0).applyQuaternion(camRot); - const camUp = new THREE.Vector3(0.0, 1.0, 0.0).applyQuaternion(camRot); - const camPosRight = camPos.dot(camRight); - const camPosUp = camPos.dot(camUp); - - // 2. Find how far along its position is along these bases in pixel units - const camPosRightPx = camPosRight / pixelWidth; - const camPosUpPx = camPosUp / pixelHeight; - - // 3. Find the fractional pixel units and convert to world units - const fractX = camPosRightPx - Math.round(camPosRightPx); - const fractY = camPosUpPx - Math.round(camPosUpPx); - - // 4. Add fractional world units to the left/right top/bottom to align with the pixel grid - camera.left = -aspectRatio - fractX * pixelWidth; - camera.right = aspectRatio - fractX * pixelWidth; - camera.top = 1.0 - fractY * pixelHeight; - camera.bottom = -1.0 - fractY * pixelHeight; - camera.updateProjectionMatrix(); -} diff --git a/examples-testing/examples/webgl_postprocessing_procedural.ts b/examples-testing/examples/webgl_postprocessing_procedural.ts deleted file mode 100644 index 869824270..000000000 --- a/examples-testing/examples/webgl_postprocessing_procedural.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let postCamera, postScene, renderer; -let postMaterial, noiseRandom1DMaterial, noiseRandom2DMaterial, noiseRandom3DMaterial, postQuad; -let stats; - -const params = { procedure: 'noiseRandom3D' }; - -init(); - -function init() { - const container = document.getElementById('container'); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // Setup post processing stage - postCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); - noiseRandom1DMaterial = new THREE.ShaderMaterial({ - vertexShader: document.querySelector('#procedural-vert').textContent.trim(), - fragmentShader: document.querySelector('#noiseRandom1D-frag').textContent.trim(), - }); - noiseRandom2DMaterial = new THREE.ShaderMaterial({ - vertexShader: document.querySelector('#procedural-vert').textContent.trim(), - fragmentShader: document.querySelector('#noiseRandom2D-frag').textContent.trim(), - }); - noiseRandom3DMaterial = new THREE.ShaderMaterial({ - vertexShader: document.querySelector('#procedural-vert').textContent.trim(), - fragmentShader: document.querySelector('#noiseRandom3D-frag').textContent.trim(), - }); - postMaterial = noiseRandom3DMaterial; - const postPlane = new THREE.PlaneGeometry(2, 2); - postQuad = new THREE.Mesh(postPlane, postMaterial); - postScene = new THREE.Scene(); - postScene.add(postQuad); - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - gui.add(params, 'procedure', ['noiseRandom1D', 'noiseRandom2D', 'noiseRandom3D']); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - switch (params.procedure) { - case 'noiseRandom1D': - postMaterial = noiseRandom1DMaterial; - break; - case 'noiseRandom2D': - postMaterial = noiseRandom2DMaterial; - break; - case 'noiseRandom3D': - postMaterial = noiseRandom3DMaterial; - break; - } - - postQuad.material = postMaterial; - - // render post FX - renderer.render(postScene, postCamera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts b/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts deleted file mode 100644 index fa46d4c8d..000000000 --- a/examples-testing/examples/webgl_postprocessing_rgb_halftone.ts +++ /dev/null @@ -1,167 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { HalftonePass } from 'three/addons/postprocessing/HalftonePass.js'; - -let renderer, clock, camera, stats; - -const rotationSpeed = Math.PI / 64; - -let composer, group; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - - clock = new THREE.Clock(); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 12; - - stats = new Stats(); - - document.body.appendChild(renderer.domElement); - document.body.appendChild(stats.dom); - - // camera controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0, 0); - controls.update(); - - // scene - - const scene = new THREE.Scene(); - scene.background = new THREE.Color(0x444444); - - group = new THREE.Group(); - const floor = new THREE.Mesh(new THREE.BoxGeometry(100, 1, 100), new THREE.MeshPhongMaterial({})); - floor.position.y = -10; - const light = new THREE.PointLight(0xffffff, 250); - light.position.y = 2; - group.add(floor, light); - scene.add(group); - - const mat = new THREE.ShaderMaterial({ - uniforms: {}, - - vertexShader: [ - 'varying vec2 vUV;', - 'varying vec3 vNormal;', - - 'void main() {', - - 'vUV = uv;', - 'vNormal = vec3( normal );', - 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', - - '}', - ].join('\n'), - - fragmentShader: [ - 'varying vec2 vUV;', - 'varying vec3 vNormal;', - - 'void main() {', - - 'vec4 c = vec4( abs( vNormal ) + vec3( vUV, 0.0 ), 0.0 );', - 'gl_FragColor = c;', - - '}', - ].join('\n'), - }); - - for (let i = 0; i < 50; ++i) { - // fill scene with coloured cubes - const mesh = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 2), mat); - mesh.position.set(Math.random() * 16 - 8, Math.random() * 16 - 8, Math.random() * 16 - 8); - mesh.rotation.set(Math.random() * Math.PI * 2, Math.random() * Math.PI * 2, Math.random() * Math.PI * 2); - group.add(mesh); - } - - // post-processing - - composer = new EffectComposer(renderer); - const renderPass = new RenderPass(scene, camera); - const params = { - shape: 1, - radius: 4, - rotateR: Math.PI / 12, - rotateB: (Math.PI / 12) * 2, - rotateG: (Math.PI / 12) * 3, - scatter: 0, - blending: 1, - blendingMode: 1, - greyscale: false, - disable: false, - }; - const halftonePass = new HalftonePass(window.innerWidth, window.innerHeight, params); - composer.addPass(renderPass); - composer.addPass(halftonePass); - - window.onresize = function () { - // resize composer - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - }; - - // GUI - - const controller = { - radius: halftonePass.uniforms['radius'].value, - rotateR: halftonePass.uniforms['rotateR'].value / (Math.PI / 180), - rotateG: halftonePass.uniforms['rotateG'].value / (Math.PI / 180), - rotateB: halftonePass.uniforms['rotateB'].value / (Math.PI / 180), - scatter: halftonePass.uniforms['scatter'].value, - shape: halftonePass.uniforms['shape'].value, - greyscale: halftonePass.uniforms['greyscale'].value, - blending: halftonePass.uniforms['blending'].value, - blendingMode: halftonePass.uniforms['blendingMode'].value, - disable: halftonePass.uniforms['disable'].value, - }; - - function onGUIChange() { - // update uniforms - halftonePass.uniforms['radius'].value = controller.radius; - halftonePass.uniforms['rotateR'].value = controller.rotateR * (Math.PI / 180); - halftonePass.uniforms['rotateG'].value = controller.rotateG * (Math.PI / 180); - halftonePass.uniforms['rotateB'].value = controller.rotateB * (Math.PI / 180); - halftonePass.uniforms['scatter'].value = controller.scatter; - halftonePass.uniforms['shape'].value = controller.shape; - halftonePass.uniforms['greyscale'].value = controller.greyscale; - halftonePass.uniforms['blending'].value = controller.blending; - halftonePass.uniforms['blendingMode'].value = controller.blendingMode; - halftonePass.uniforms['disable'].value = controller.disable; - } - - const gui = new GUI(); - gui.add(controller, 'shape', { Dot: 1, Ellipse: 2, Line: 3, Square: 4 }).onChange(onGUIChange); - gui.add(controller, 'radius', 1, 25).onChange(onGUIChange); - gui.add(controller, 'rotateR', 0, 90).onChange(onGUIChange); - gui.add(controller, 'rotateG', 0, 90).onChange(onGUIChange); - gui.add(controller, 'rotateB', 0, 90).onChange(onGUIChange); - gui.add(controller, 'scatter', 0, 1, 0.01).onChange(onGUIChange); - gui.add(controller, 'greyscale').onChange(onGUIChange); - gui.add(controller, 'blending', 0, 1, 0.01).onChange(onGUIChange); - gui.add(controller, 'blendingMode', { Linear: 1, Multiply: 2, Add: 3, Lighter: 4, Darker: 5 }).onChange( - onGUIChange, - ); - gui.add(controller, 'disable').onChange(onGUIChange); -} - -function animate() { - const delta = clock.getDelta(); - stats.update(); - group.rotation.y += delta * rotationSpeed; - composer.render(delta); -} diff --git a/examples-testing/examples/webgl_postprocessing_sao.ts b/examples-testing/examples/webgl_postprocessing_sao.ts deleted file mode 100644 index bf40d026b..000000000 --- a/examples-testing/examples/webgl_postprocessing_sao.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { SAOPass } from 'three/addons/postprocessing/SAOPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let container, stats; -let camera, scene, renderer; -let composer, renderPass, saoPass; -let group; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - const width = window.innerWidth; - const height = window.innerHeight; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(65, width / height, 3, 10); - camera.position.z = 7; - - scene = new THREE.Scene(); - - group = new THREE.Object3D(); - scene.add(group); - - const light = new THREE.PointLight(0xefffef, 500); - light.position.z = 10; - light.position.y = -10; - light.position.x = -10; - scene.add(light); - - const light2 = new THREE.PointLight(0xffefef, 500); - light2.position.z = 10; - light2.position.x = -10; - light2.position.y = 10; - scene.add(light2); - - const light3 = new THREE.PointLight(0xefefff, 500); - light3.position.z = 10; - light3.position.x = 10; - light3.position.y = -10; - scene.add(light3); - - const light4 = new THREE.AmbientLight(0xffffff, 0.2); - scene.add(light4); - - const geometry = new THREE.SphereGeometry(3, 48, 24); - - for (let i = 0; i < 120; i++) { - const material = new THREE.MeshStandardMaterial(); - material.roughness = 0.5 * Math.random() + 0.25; - material.metalness = 0; - material.color.setHSL(Math.random(), 1.0, 0.3); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 4 - 2; - mesh.position.y = Math.random() * 4 - 2; - mesh.position.z = Math.random() * 4 - 2; - mesh.rotation.x = Math.random(); - mesh.rotation.y = Math.random(); - mesh.rotation.z = Math.random(); - - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 0.2 + 0.05; - group.add(mesh); - } - - stats = new Stats(); - container.appendChild(stats.dom); - - composer = new EffectComposer(renderer); - renderPass = new RenderPass(scene, camera); - composer.addPass(renderPass); - saoPass = new SAOPass(scene, camera); - composer.addPass(saoPass); - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - // Init gui - const gui = new GUI(); - gui.add(saoPass.params, 'output', { - Default: SAOPass.OUTPUT.Default, - 'SAO Only': SAOPass.OUTPUT.SAO, - Normal: SAOPass.OUTPUT.Normal, - }).onChange(function (value) { - saoPass.params.output = value; - }); - gui.add(saoPass.params, 'saoBias', -1, 1); - gui.add(saoPass.params, 'saoIntensity', 0, 1); - gui.add(saoPass.params, 'saoScale', 0, 10); - gui.add(saoPass.params, 'saoKernelRadius', 1, 100); - gui.add(saoPass.params, 'saoMinResolution', 0, 1); - gui.add(saoPass.params, 'saoBlur'); - gui.add(saoPass.params, 'saoBlurRadius', 0, 200); - gui.add(saoPass.params, 'saoBlurStdDev', 0.5, 150); - gui.add(saoPass.params, 'saoBlurDepthCutoff', 0.0, 0.1); - gui.add(saoPass, 'enabled'); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth || 1; - const height = window.innerHeight || 1; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - renderer.setSize(width, height); - - composer.setSize(width, height); -} - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - const timer = performance.now(); - group.rotation.x = timer * 0.0002; - group.rotation.y = timer * 0.0001; - - composer.render(); -} diff --git a/examples-testing/examples/webgl_postprocessing_smaa.ts b/examples-testing/examples/webgl_postprocessing_smaa.ts deleted file mode 100644 index 6f71f6478..000000000 --- a/examples-testing/examples/webgl_postprocessing_smaa.ts +++ /dev/null @@ -1,109 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, scene, renderer, composer, stats, smaaPass; - -const params = { - enabled: true, - autoRotate: true, -}; - -init(); - -function init() { - const container = document.getElementById('container'); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 300; - - scene = new THREE.Scene(); - - const geometry = new THREE.BoxGeometry(120, 120, 120); - const material1 = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }); - - const mesh1 = new THREE.Mesh(geometry, material1); - mesh1.position.x = -100; - scene.add(mesh1); - - const texture = new THREE.TextureLoader().load('textures/brick_diffuse.jpg'); - texture.anisotropy = renderer.capabilities.getMaxAnisotropy(); - texture.colorSpace = THREE.SRGBColorSpace; - - const material2 = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh2 = new THREE.Mesh(geometry, material2); - mesh2.position.x = 100; - scene.add(mesh2); - - // postprocessing - - composer = new EffectComposer(renderer); - composer.addPass(new RenderPass(scene, camera)); - - smaaPass = new SMAAPass( - window.innerWidth * renderer.getPixelRatio(), - window.innerHeight * renderer.getPixelRatio(), - ); - composer.addPass(smaaPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - window.addEventListener('resize', onWindowResize); - - const gui = new GUI(); - - const smaaFolder = gui.addFolder('SMAA'); - smaaFolder.add(params, 'enabled'); - - const sceneFolder = gui.addFolder('Scene'); - sceneFolder.add(params, 'autoRotate'); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - stats.begin(); - - if (params.autoRotate === true) { - for (let i = 0; i < scene.children.length; i++) { - const child = scene.children[i]; - - child.rotation.x += 0.005; - child.rotation.y += 0.01; - } - } - - smaaPass.enabled = params.enabled; - - composer.render(); - - stats.end(); -} diff --git a/examples-testing/examples/webgl_postprocessing_sobel.ts b/examples-testing/examples/webgl_postprocessing_sobel.ts deleted file mode 100644 index 55d88dc02..000000000 --- a/examples-testing/examples/webgl_postprocessing_sobel.ts +++ /dev/null @@ -1,111 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; - -import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js'; -import { SobelOperatorShader } from 'three/addons/shaders/SobelOperatorShader.js'; - -let camera, scene, renderer, composer; - -let effectSobel; - -const params = { - enable: true, -}; - -init(); - -function init() { - // - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 1, 3); - camera.lookAt(scene.position); - - // - - const geometry = new THREE.TorusKnotGeometry(1, 0.3, 256, 32); - const material = new THREE.MeshPhongMaterial({ color: 0xffff00 }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const ambientLight = new THREE.AmbientLight(0xe7e7e7); - scene.add(ambientLight); - - const pointLight = new THREE.PointLight(0xffffff, 20); - camera.add(pointLight); - scene.add(camera); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // postprocessing - - composer = new EffectComposer(renderer); - const renderPass = new RenderPass(scene, camera); - composer.addPass(renderPass); - - // color to grayscale conversion - - const effectGrayScale = new ShaderPass(LuminosityShader); - composer.addPass(effectGrayScale); - - // you might want to use a gaussian blur filter before - // the next pass to improve the result of the Sobel operator - - // Sobel operator - - effectSobel = new ShaderPass(SobelOperatorShader); - effectSobel.uniforms['resolution'].value.x = window.innerWidth * window.devicePixelRatio; - effectSobel.uniforms['resolution'].value.y = window.innerHeight * window.devicePixelRatio; - composer.addPass(effectSobel); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - - // - - const gui = new GUI(); - - gui.add(params, 'enable'); - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); - - effectSobel.uniforms['resolution'].value.x = window.innerWidth * window.devicePixelRatio; - effectSobel.uniforms['resolution'].value.y = window.innerHeight * window.devicePixelRatio; -} - -function animate() { - if (params.enable === true) { - composer.render(); - } else { - renderer.render(scene, camera); - } -} diff --git a/examples-testing/examples/webgl_postprocessing_ssaa.ts b/examples-testing/examples/webgl_postprocessing_ssaa.ts deleted file mode 100644 index 429e02dee..000000000 --- a/examples-testing/examples/webgl_postprocessing_ssaa.ts +++ /dev/null @@ -1,206 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { SSAARenderPass } from 'three/addons/postprocessing/SSAARenderPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let scene, renderer, composer; -let cameraP, ssaaRenderPassP; -let cameraO, ssaaRenderPassO; -let gui, stats; - -const params = { - sampleLevel: 4, - unbiased: true, - camera: 'perspective', - clearColor: 'black', - clearAlpha: 1.0, - viewOffsetX: 0, - autoRotate: true, -}; - -init(); - -clearGui(); - -function clearGui() { - if (gui) gui.destroy(); - - gui = new GUI(); - - gui.add(params, 'unbiased'); - gui.add(params, 'sampleLevel', { - 'Level 0: 1 Sample': 0, - 'Level 1: 2 Samples': 1, - 'Level 2: 4 Samples': 2, - 'Level 3: 8 Samples': 3, - 'Level 4: 16 Samples': 4, - 'Level 5: 32 Samples': 5, - }); - gui.add(params, 'camera', ['perspective', 'orthographic']); - gui.add(params, 'clearColor', ['black', 'white', 'blue', 'green', 'red']); - gui.add(params, 'clearAlpha', 0, 1); - gui.add(params, 'viewOffsetX', -100, 100); - gui.add(params, 'autoRotate'); - - gui.open(); -} - -function init() { - const container = document.getElementById('container'); - - const width = window.innerWidth || 1; - const height = window.innerHeight || 1; - const aspect = width / height; - const devicePixelRatio = window.devicePixelRatio || 1; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - cameraP = new THREE.PerspectiveCamera(65, aspect, 3, 10); - cameraP.position.z = 7; - cameraP.setViewOffset(width, height, params.viewOffsetX, 0, width, height); - - cameraO = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 3, 10); - cameraO.position.z = 7; - - const fov = THREE.MathUtils.degToRad(cameraP.fov); - const hyperfocus = (cameraP.near + cameraP.far) / 2; - const _height = 2 * Math.tan(fov / 2) * hyperfocus; - cameraO.zoom = height / _height; - - scene = new THREE.Scene(); - - const group = new THREE.Group(); - scene.add(group); - - const light = new THREE.PointLight(0xefffef, 500); - light.position.z = 10; - light.position.y = -10; - light.position.x = -10; - scene.add(light); - - const light2 = new THREE.PointLight(0xffefef, 500); - light2.position.z = 10; - light2.position.x = -10; - light2.position.y = 10; - scene.add(light2); - - const light3 = new THREE.PointLight(0xefefff, 500); - light3.position.z = 10; - light3.position.x = 10; - light3.position.y = -10; - scene.add(light3); - - const light4 = new THREE.AmbientLight(0xffffff, 0.2); - scene.add(light4); - - const geometry = new THREE.SphereGeometry(3, 48, 24); - - for (let i = 0; i < 120; i++) { - const material = new THREE.MeshStandardMaterial(); - material.roughness = 0.5 * Math.random() + 0.25; - material.metalness = 0; - material.color.setHSL(Math.random(), 1.0, 0.3); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 4 - 2; - mesh.position.y = Math.random() * 4 - 2; - mesh.position.z = Math.random() * 4 - 2; - mesh.rotation.x = Math.random(); - mesh.rotation.y = Math.random(); - mesh.rotation.z = Math.random(); - - mesh.scale.setScalar(Math.random() * 0.2 + 0.05); - group.add(mesh); - } - - // postprocessing - - composer = new EffectComposer(renderer); - composer.setPixelRatio(1); // ensure pixel ratio is always 1 for performance reasons - ssaaRenderPassP = new SSAARenderPass(scene, cameraP); - composer.addPass(ssaaRenderPassP); - ssaaRenderPassO = new SSAARenderPass(scene, cameraO); - composer.addPass(ssaaRenderPassO); - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - const aspect = width / height; - - cameraP.aspect = aspect; - cameraP.setViewOffset(width, height, params.viewOffsetX, 0, width, height); - cameraO.updateProjectionMatrix(); - - cameraO.left = -height * aspect; - cameraO.right = height * aspect; - cameraO.top = height; - cameraO.bottom = -height; - cameraO.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - stats.begin(); - - if (params.autoRotate) { - for (let i = 0; i < scene.children.length; i++) { - const child = scene.children[i]; - - child.rotation.x += 0.005; - child.rotation.y += 0.01; - } - } - - let newColor = ssaaRenderPassP.clearColor; - - switch (params.clearColor) { - case 'blue': - newColor = 0x0000ff; - break; - case 'red': - newColor = 0xff0000; - break; - case 'green': - newColor = 0x00ff00; - break; - case 'white': - newColor = 0xffffff; - break; - case 'black': - newColor = 0x000000; - break; - } - - ssaaRenderPassP.clearColor = ssaaRenderPassO.clearColor = newColor; - ssaaRenderPassP.clearAlpha = ssaaRenderPassO.clearAlpha = params.clearAlpha; - - ssaaRenderPassP.sampleLevel = ssaaRenderPassO.sampleLevel = params.sampleLevel; - ssaaRenderPassP.unbiased = ssaaRenderPassO.unbiased = params.unbiased; - - ssaaRenderPassP.enabled = params.camera === 'perspective'; - ssaaRenderPassO.enabled = params.camera === 'orthographic'; - - cameraP.view.offsetX = params.viewOffsetX; - - composer.render(); - - stats.end(); -} diff --git a/examples-testing/examples/webgl_postprocessing_ssao.ts b/examples-testing/examples/webgl_postprocessing_ssao.ts deleted file mode 100644 index e55ab0446..000000000 --- a/examples-testing/examples/webgl_postprocessing_ssao.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { SSAOPass } from 'three/addons/postprocessing/SSAOPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let container, stats; -let camera, scene, renderer; -let composer; -let group; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGLRenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 100, 700); - camera.position.z = 500; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xaaaaaa); - - scene.add(new THREE.DirectionalLight(0xffffff, 4)); - scene.add(new THREE.AmbientLight(0xffffff)); - - group = new THREE.Group(); - scene.add(group); - - const geometry = new THREE.BoxGeometry(10, 10, 10); - - for (let i = 0; i < 100; i++) { - const material = new THREE.MeshLambertMaterial({ - color: Math.random() * 0xffffff, - }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.x = Math.random() * 400 - 200; - mesh.position.y = Math.random() * 400 - 200; - mesh.position.z = Math.random() * 400 - 200; - mesh.rotation.x = Math.random(); - mesh.rotation.y = Math.random(); - mesh.rotation.z = Math.random(); - - mesh.scale.setScalar(Math.random() * 10 + 2); - group.add(mesh); - } - - stats = new Stats(); - container.appendChild(stats.dom); - - const width = window.innerWidth; - const height = window.innerHeight; - - composer = new EffectComposer(renderer); - - const renderPass = new RenderPass(scene, camera); - composer.addPass(renderPass); - - const ssaoPass = new SSAOPass(scene, camera, width, height); - composer.addPass(ssaoPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - // Init gui - const gui = new GUI(); - - gui.add(ssaoPass, 'output', { - Default: SSAOPass.OUTPUT.Default, - 'SSAO Only': SSAOPass.OUTPUT.SSAO, - 'SSAO Only + Blur': SSAOPass.OUTPUT.Blur, - Depth: SSAOPass.OUTPUT.Depth, - Normal: SSAOPass.OUTPUT.Normal, - }).onChange(function (value) { - ssaoPass.output = value; - }); - gui.add(ssaoPass, 'kernelRadius').min(0).max(32); - gui.add(ssaoPass, 'minDistance').min(0.001).max(0.02); - gui.add(ssaoPass, 'maxDistance').min(0.01).max(0.3); - gui.add(ssaoPass, 'enabled'); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - const timer = performance.now(); - group.rotation.x = timer * 0.0002; - group.rotation.y = timer * 0.0001; - - composer.render(); -} diff --git a/examples-testing/examples/webgl_postprocessing_ssr.ts b/examples-testing/examples/webgl_postprocessing_ssr.ts deleted file mode 100644 index 307cfd1de..000000000 --- a/examples-testing/examples/webgl_postprocessing_ssr.ts +++ /dev/null @@ -1,261 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { SSRPass } from 'three/addons/postprocessing/SSRPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; -import { ReflectorForSSRPass } from 'three/addons/objects/ReflectorForSSRPass.js'; - -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -const params = { - enableSSR: true, - autoRotate: true, - otherMeshes: true, - groundReflector: true, -}; -let composer; -let ssrPass; -let gui; -let stats; -let controls; -let camera, scene, renderer; -const otherMeshes = []; -let groundReflector; -const selects = []; - -const container = document.querySelector('#container'); - -// Configure and create Draco decoder. -const dracoLoader = new DRACOLoader(); -dracoLoader.setDecoderPath('jsm/libs/draco/'); -dracoLoader.setDecoderConfig({ type: 'js' }); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 15); - camera.position.set(0.13271600513224902, 0.3489546826045913, 0.43921296427927076); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x443333); - scene.fog = new THREE.Fog(0x443333, 1, 4); - - // Ground - const plane = new THREE.Mesh(new THREE.PlaneGeometry(8, 8), new THREE.MeshPhongMaterial({ color: 0xcbcbcb })); - plane.rotation.x = -Math.PI / 2; - plane.position.y = -0.0001; - // plane.receiveShadow = true; - scene.add(plane); - - // Lights - const hemiLight = new THREE.HemisphereLight(0x8d7c7c, 0x494966, 3); - scene.add(hemiLight); - - const spotLight = new THREE.SpotLight(); - spotLight.intensity = 8; - spotLight.angle = Math.PI / 16; - spotLight.penumbra = 0.5; - // spotLight.castShadow = true; - spotLight.position.set(-1, 1, 1); - scene.add(spotLight); - - dracoLoader.load('models/draco/bunny.drc', function (geometry) { - geometry.computeVertexNormals(); - - const material = new THREE.MeshStandardMaterial({ color: 0xa5a5a5 }); - const mesh = new THREE.Mesh(geometry, material); - mesh.position.y = -0.0365; - scene.add(mesh); - selects.push(mesh); - - // Release decoder resources. - dracoLoader.dispose(); - }); - - let geometry, material, mesh; - - geometry = new THREE.BoxGeometry(0.05, 0.05, 0.05); - material = new THREE.MeshStandardMaterial({ color: 'green' }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.set(-0.12, 0.025, 0.015); - scene.add(mesh); - otherMeshes.push(mesh); - selects.push(mesh); - - geometry = new THREE.IcosahedronGeometry(0.025, 4); - material = new THREE.MeshStandardMaterial({ color: 'cyan' }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.set(-0.05, 0.025, 0.08); - scene.add(mesh); - otherMeshes.push(mesh); - selects.push(mesh); - - geometry = new THREE.ConeGeometry(0.025, 0.05, 64); - material = new THREE.MeshStandardMaterial({ color: 'yellow' }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.set(-0.05, 0.025, -0.055); - scene.add(mesh); - otherMeshes.push(mesh); - selects.push(mesh); - - geometry = new THREE.PlaneGeometry(1, 1); - groundReflector = new ReflectorForSSRPass(geometry, { - clipBias: 0.0003, - textureWidth: window.innerWidth, - textureHeight: window.innerHeight, - color: 0x888888, - useDepthTexture: true, - }); - groundReflector.material.depthWrite = false; - groundReflector.rotation.x = -Math.PI / 2; - groundReflector.visible = false; - scene.add(groundReflector); - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: false }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.target.set(0, 0.0635, 0); - controls.update(); - controls.enabled = !params.autoRotate; - - // STATS - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - - // composer - - composer = new EffectComposer(renderer); - ssrPass = new SSRPass({ - renderer, - scene, - camera, - width: innerWidth, - height: innerHeight, - groundReflector: params.groundReflector ? groundReflector : null, - selects: params.groundReflector ? selects : null, - }); - - composer.addPass(ssrPass); - composer.addPass(new OutputPass()); - - // GUI - - gui = new GUI({ width: 260 }); - gui.add(params, 'enableSSR').name('Enable SSR'); - gui.add(params, 'groundReflector').onChange(() => { - if (params.groundReflector) { - (ssrPass.groundReflector = groundReflector), (ssrPass.selects = selects); - } else { - (ssrPass.groundReflector = null), (ssrPass.selects = null); - } - }); - ssrPass.thickness = 0.018; - gui.add(ssrPass, 'thickness').min(0).max(0.1).step(0.0001); - ssrPass.infiniteThick = false; - gui.add(ssrPass, 'infiniteThick'); - gui.add(params, 'autoRotate').onChange(() => { - controls.enabled = !params.autoRotate; - }); - - const folder = gui.addFolder('more settings'); - folder.add(ssrPass, 'fresnel').onChange(() => { - groundReflector.fresnel = ssrPass.fresnel; - }); - folder.add(ssrPass, 'distanceAttenuation').onChange(() => { - groundReflector.distanceAttenuation = ssrPass.distanceAttenuation; - }); - ssrPass.maxDistance = 0.1; - groundReflector.maxDistance = ssrPass.maxDistance; - folder - .add(ssrPass, 'maxDistance') - .min(0) - .max(0.5) - .step(0.001) - .onChange(() => { - groundReflector.maxDistance = ssrPass.maxDistance; - }); - folder.add(params, 'otherMeshes').onChange(() => { - if (params.otherMeshes) { - otherMeshes.forEach(mesh => (mesh.visible = true)); - } else { - otherMeshes.forEach(mesh => (mesh.visible = false)); - } - }); - folder.add(ssrPass, 'bouncing'); - folder - .add(ssrPass, 'output', { - Default: SSRPass.OUTPUT.Default, - 'SSR Only': SSRPass.OUTPUT.SSR, - Beauty: SSRPass.OUTPUT.Beauty, - Depth: SSRPass.OUTPUT.Depth, - Normal: SSRPass.OUTPUT.Normal, - Metalness: SSRPass.OUTPUT.Metalness, - }) - .onChange(function (value) { - ssrPass.output = value; - }); - ssrPass.opacity = 1; - groundReflector.opacity = ssrPass.opacity; - folder - .add(ssrPass, 'opacity') - .min(0) - .max(1) - .onChange(() => { - groundReflector.opacity = ssrPass.opacity; - }); - folder.add(ssrPass, 'blur'); - // folder.open() - // gui.close() -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); - groundReflector.getRenderTarget().setSize(window.innerWidth, window.innerHeight); - groundReflector.resolution.set(window.innerWidth, window.innerHeight); -} - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - if (params.autoRotate) { - const timer = Date.now() * 0.0003; - - camera.position.x = Math.sin(timer) * 0.5; - camera.position.y = 0.2135; - camera.position.z = Math.cos(timer) * 0.5; - camera.lookAt(0, 0.0635, 0); - } else { - controls.update(); - } - - if (params.enableSSR) { - // TODO: groundReflector has full ground info, need use it to solve reflection gaps problem on objects when camera near ground. - // TODO: the normal and depth info where groundReflector reflected need to be changed. - composer.render(); - } else { - renderer.render(scene, camera); - } -} diff --git a/examples-testing/examples/webgl_postprocessing_taa.ts b/examples-testing/examples/webgl_postprocessing_taa.ts deleted file mode 100644 index 11a986741..000000000 --- a/examples-testing/examples/webgl_postprocessing_taa.ts +++ /dev/null @@ -1,139 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, scene, renderer, composer, taaRenderPass, renderPass; -let gui, stats; -let index = 0; - -const param = { TAAEnabled: '1', TAASampleLevel: 0 }; - -init(); - -clearGui(); - -function clearGui() { - if (gui) gui.destroy(); - - gui = new GUI(); - - gui.add(param, 'TAAEnabled', { - Disabled: '0', - Enabled: '1', - }).onFinishChange(function () { - if (taaRenderPass) { - taaRenderPass.enabled = param.TAAEnabled === '1'; - renderPass.enabled = param.TAAEnabled !== '1'; - } - }); - - gui.add(param, 'TAASampleLevel', { - 'Level 0: 1 Sample': 0, - 'Level 1: 2 Samples': 1, - 'Level 2: 4 Samples': 2, - 'Level 3: 8 Samples': 3, - 'Level 4: 16 Samples': 4, - 'Level 5: 32 Samples': 5, - }).onFinishChange(function () { - if (taaRenderPass) { - taaRenderPass.sampleLevel = param.TAASampleLevel; - } - }); - - gui.open(); -} - -function init() { - const container = document.getElementById('container'); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 300; - - scene = new THREE.Scene(); - - const geometry = new THREE.BoxGeometry(120, 120, 120); - const material1 = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }); - - const mesh1 = new THREE.Mesh(geometry, material1); - mesh1.position.x = -100; - scene.add(mesh1); - - const texture = new THREE.TextureLoader().load('textures/brick_diffuse.jpg'); - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.anisotropy = 1; - texture.generateMipmaps = false; - texture.colorSpace = THREE.SRGBColorSpace; - - const material2 = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh2 = new THREE.Mesh(geometry, material2); - mesh2.position.x = 100; - scene.add(mesh2); - - // postprocessing - - composer = new EffectComposer(renderer); - - taaRenderPass = new TAARenderPass(scene, camera); - taaRenderPass.unbiased = false; - composer.addPass(taaRenderPass); - - renderPass = new RenderPass(scene, camera); - renderPass.enabled = false; - composer.addPass(renderPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - index++; - - if (Math.round(index / 200) % 2 === 0) { - for (let i = 0; i < scene.children.length; i++) { - const child = scene.children[i]; - - child.rotation.x += 0.005; - child.rotation.y += 0.01; - } - - if (taaRenderPass) taaRenderPass.accumulate = false; - } else { - if (taaRenderPass) taaRenderPass.accumulate = true; - } - - composer.render(); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_postprocessing_transition.ts b/examples-testing/examples/webgl_postprocessing_transition.ts deleted file mode 100644 index d05466131..000000000 --- a/examples-testing/examples/webgl_postprocessing_transition.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import TWEEN from 'three/addons/libs/tween.module.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderTransitionPass } from 'three/addons/postprocessing/RenderTransitionPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let stats; -let renderer, composer, renderTransitionPass; - -const textures = []; -const clock = new THREE.Clock(); - -const params = { - sceneAnimate: true, - transitionAnimate: true, - transition: 0, - useTexture: true, - texture: 5, - cycle: true, - threshold: 0.1, -}; - -const fxSceneA = new FXScene(new THREE.BoxGeometry(2, 2, 2), new THREE.Vector3(0, -0.4, 0), 0xffffff); -const fxSceneB = new FXScene(new THREE.IcosahedronGeometry(1, 1), new THREE.Vector3(0, 0.2, 0.1), 0x000000); - -init(); - -function init() { - initGUI(); - initTextures(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - composer = new EffectComposer(renderer); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - renderTransitionPass = new RenderTransitionPass(fxSceneA.scene, fxSceneA.camera, fxSceneB.scene, fxSceneB.camera); - renderTransitionPass.setTexture(textures[0]); - composer.addPass(renderTransitionPass); - - const outputPass = new OutputPass(); - composer.addPass(outputPass); -} - -window.addEventListener('resize', onWindowResize); - -function onWindowResize() { - fxSceneA.resize(); - fxSceneB.resize(); - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -new TWEEN.Tween(params) - .to({ transition: 1 }, 1500) - .onUpdate(function () { - renderTransitionPass.setTransition(params.transition); - - // Change the current alpha texture after each transition - if (params.cycle) { - if (params.transition == 0 || params.transition == 1) { - params.texture = (params.texture + 1) % textures.length; - renderTransitionPass.setTexture(textures[params.texture]); - } - } - }) - .repeat(Infinity) - .delay(2000) - .yoyo(true) - .start(); - -function animate() { - // Transition animation - if (params.transitionAnimate) TWEEN.update(); - - const delta = clock.getDelta(); - fxSceneA.update(delta); - fxSceneB.update(delta); - - render(); - stats.update(); -} - -function initTextures() { - const loader = new THREE.TextureLoader(); - - for (let i = 0; i < 6; i++) { - textures[i] = loader.load('textures/transition/transition' + (i + 1) + '.png'); - } -} - -function initGUI() { - const gui = new GUI(); - - gui.add(params, 'sceneAnimate').name('Animate scene'); - gui.add(params, 'transitionAnimate').name('Animate transition'); - gui.add(params, 'transition', 0, 1, 0.01) - .onChange(function (value) { - renderTransitionPass.setTransition(value); - }) - .listen(); - - gui.add(params, 'useTexture').onChange(function (value) { - renderTransitionPass.useTexture(value); - }); - - gui.add(params, 'texture', { Perlin: 0, Squares: 1, Cells: 2, Distort: 3, Gradient: 4, Radial: 5 }) - .onChange(function (value) { - renderTransitionPass.setTexture(textures[value]); - }) - .listen(); - - gui.add(params, 'cycle'); - - gui.add(params, 'threshold', 0, 1, 0.01).onChange(function (value) { - renderTransitionPass.setTextureThreshold(value); - }); -} - -function render() { - // Prevent render both scenes when it's not necessary - if (params.transition === 0) { - renderer.render(fxSceneB.scene, fxSceneB.camera); - } else if (params.transition === 1) { - renderer.render(fxSceneA.scene, fxSceneA.camera); - } else { - // When 0 < transition < 1 render transition between two scenes - composer.render(); - } -} - -function FXScene(geometry, rotationSpeed, backgroundColor) { - const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 20; - - // Setup scene - const scene = new THREE.Scene(); - scene.background = new THREE.Color(backgroundColor); - scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 1, 4); - scene.add(light); - - this.rotationSpeed = rotationSpeed; - - const color = geometry.type === 'BoxGeometry' ? 0x0000ff : 0xff0000; - const material = new THREE.MeshPhongMaterial({ color: color, flatShading: true }); - const mesh = generateInstancedMesh(geometry, material, 500); - scene.add(mesh); - - this.scene = scene; - this.camera = camera; - this.mesh = mesh; - - this.update = function (delta) { - if (params.sceneAnimate) { - mesh.rotation.x += this.rotationSpeed.x * delta; - mesh.rotation.y += this.rotationSpeed.y * delta; - mesh.rotation.z += this.rotationSpeed.z * delta; - } - }; - - this.resize = function () { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - }; -} - -function generateInstancedMesh(geometry, material, count) { - const mesh = new THREE.InstancedMesh(geometry, material, count); - - const dummy = new THREE.Object3D(); - const color = new THREE.Color(); - - for (let i = 0; i < count; i++) { - dummy.position.x = Math.random() * 100 - 50; - dummy.position.y = Math.random() * 60 - 30; - dummy.position.z = Math.random() * 80 - 40; - - dummy.rotation.x = Math.random() * 2 * Math.PI; - dummy.rotation.y = Math.random() * 2 * Math.PI; - dummy.rotation.z = Math.random() * 2 * Math.PI; - - dummy.scale.x = Math.random() * 2 + 1; - - if (geometry.type === 'BoxGeometry') { - dummy.scale.y = Math.random() * 2 + 1; - dummy.scale.z = Math.random() * 2 + 1; - } else { - dummy.scale.y = dummy.scale.x; - dummy.scale.z = dummy.scale.x; - } - - dummy.updateMatrix(); - - mesh.setMatrixAt(i, dummy.matrix); - mesh.setColorAt(i, color.setScalar(0.1 + 0.9 * Math.random())); - } - - return mesh; -} diff --git a/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts b/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts deleted file mode 100644 index 53ec2fe2f..000000000 --- a/examples-testing/examples/webgl_postprocessing_unreal_bloom.ts +++ /dev/null @@ -1,136 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, stats; -let composer, renderer, mixer, clock; - -const params = { - threshold: 0, - strength: 1, - radius: 0, - exposure: 1, -}; - -init(); - -async function init() { - const container = document.getElementById('container'); - - clock = new THREE.Clock(); - - const scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(-5, 2.5, -3.5); - scene.add(camera); - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const pointLight = new THREE.PointLight(0xffffff, 100); - camera.add(pointLight); - - const loader = new GLTFLoader(); - const gltf = await loader.loadAsync('models/gltf/PrimaryIonDrive.glb'); - - const model = gltf.scene; - scene.add(model); - - mixer = new THREE.AnimationMixer(model); - const clip = gltf.animations[0]; - mixer.clipAction(clip.optimize()).play(); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ReinhardToneMapping; - container.appendChild(renderer.domElement); - - // - - const renderScene = new RenderPass(scene, camera); - - const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85); - bloomPass.threshold = params.threshold; - bloomPass.strength = params.strength; - bloomPass.radius = params.radius; - - const outputPass = new OutputPass(); - - composer = new EffectComposer(renderer); - composer.addPass(renderScene); - composer.addPass(bloomPass); - composer.addPass(outputPass); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = Math.PI * 0.5; - controls.minDistance = 3; - controls.maxDistance = 8; - - // - - const gui = new GUI(); - - const bloomFolder = gui.addFolder('bloom'); - - bloomFolder.add(params, 'threshold', 0.0, 1.0).onChange(function (value) { - bloomPass.threshold = Number(value); - }); - - bloomFolder.add(params, 'strength', 0.0, 3.0).onChange(function (value) { - bloomPass.strength = Number(value); - }); - - gui.add(params, 'radius', 0.0, 1.0) - .step(0.01) - .onChange(function (value) { - bloomPass.radius = Number(value); - }); - - const toneMappingFolder = gui.addFolder('tone mapping'); - - toneMappingFolder.add(params, 'exposure', 0.1, 2).onChange(function (value) { - renderer.toneMappingExposure = Math.pow(value, 4.0); - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - composer.setSize(width, height); -} - -function animate() { - const delta = clock.getDelta(); - - mixer.update(delta); - - stats.update(); - - composer.render(); -} diff --git a/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts b/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts deleted file mode 100644 index d633806ee..000000000 --- a/examples-testing/examples/webgl_postprocessing_unreal_bloom_selective.ts +++ /dev/null @@ -1,195 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; -import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -const BLOOM_SCENE = 1; - -const bloomLayer = new THREE.Layers(); -bloomLayer.set(BLOOM_SCENE); - -const params = { - threshold: 0, - strength: 1, - radius: 0.5, - exposure: 1, -}; - -const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' }); -const materials = {}; - -const renderer = new THREE.WebGLRenderer({ antialias: true }); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.toneMapping = THREE.ReinhardToneMapping; -document.body.appendChild(renderer.domElement); - -const scene = new THREE.Scene(); - -const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 200); -camera.position.set(0, 0, 20); -camera.lookAt(0, 0, 0); - -const controls = new OrbitControls(camera, renderer.domElement); -controls.maxPolarAngle = Math.PI * 0.5; -controls.minDistance = 1; -controls.maxDistance = 100; -controls.addEventListener('change', render); - -const renderScene = new RenderPass(scene, camera); - -const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85); -bloomPass.threshold = params.threshold; -bloomPass.strength = params.strength; -bloomPass.radius = params.radius; - -const bloomComposer = new EffectComposer(renderer); -bloomComposer.renderToScreen = false; -bloomComposer.addPass(renderScene); -bloomComposer.addPass(bloomPass); - -const mixPass = new ShaderPass( - new THREE.ShaderMaterial({ - uniforms: { - baseTexture: { value: null }, - bloomTexture: { value: bloomComposer.renderTarget2.texture }, - }, - vertexShader: document.getElementById('vertexshader').textContent, - fragmentShader: document.getElementById('fragmentshader').textContent, - defines: {}, - }), - 'baseTexture', -); -mixPass.needsSwap = true; - -const outputPass = new OutputPass(); - -const finalComposer = new EffectComposer(renderer); -finalComposer.addPass(renderScene); -finalComposer.addPass(mixPass); -finalComposer.addPass(outputPass); - -const raycaster = new THREE.Raycaster(); - -const mouse = new THREE.Vector2(); - -window.addEventListener('pointerdown', onPointerDown); - -const gui = new GUI(); - -const bloomFolder = gui.addFolder('bloom'); - -bloomFolder.add(params, 'threshold', 0.0, 1.0).onChange(function (value) { - bloomPass.threshold = Number(value); - render(); -}); - -bloomFolder.add(params, 'strength', 0.0, 3).onChange(function (value) { - bloomPass.strength = Number(value); - render(); -}); - -bloomFolder - .add(params, 'radius', 0.0, 1.0) - .step(0.01) - .onChange(function (value) { - bloomPass.radius = Number(value); - render(); - }); - -const toneMappingFolder = gui.addFolder('tone mapping'); - -toneMappingFolder.add(params, 'exposure', 0.1, 2).onChange(function (value) { - renderer.toneMappingExposure = Math.pow(value, 4.0); - render(); -}); - -setupScene(); - -function onPointerDown(event) { - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - raycaster.setFromCamera(mouse, camera); - const intersects = raycaster.intersectObjects(scene.children, false); - if (intersects.length > 0) { - const object = intersects[0].object; - object.layers.toggle(BLOOM_SCENE); - render(); - } -} - -window.onresize = function () { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - - bloomComposer.setSize(width, height); - finalComposer.setSize(width, height); - - render(); -}; - -function setupScene() { - scene.traverse(disposeMaterial); - scene.children.length = 0; - - const geometry = new THREE.IcosahedronGeometry(1, 15); - - for (let i = 0; i < 50; i++) { - const color = new THREE.Color(); - color.setHSL(Math.random(), 0.7, Math.random() * 0.2 + 0.05); - - const material = new THREE.MeshBasicMaterial({ color: color }); - const sphere = new THREE.Mesh(geometry, material); - sphere.position.x = Math.random() * 10 - 5; - sphere.position.y = Math.random() * 10 - 5; - sphere.position.z = Math.random() * 10 - 5; - sphere.position.normalize().multiplyScalar(Math.random() * 4.0 + 2.0); - sphere.scale.setScalar(Math.random() * Math.random() + 0.5); - scene.add(sphere); - - if (Math.random() < 0.25) sphere.layers.enable(BLOOM_SCENE); - } - - render(); -} - -function disposeMaterial(obj) { - if (obj.material) { - obj.material.dispose(); - } -} - -function render() { - scene.traverse(darkenNonBloomed); - bloomComposer.render(); - scene.traverse(restoreMaterial); - - // render the entire scene, then render bloom scene on top - finalComposer.render(); -} - -function darkenNonBloomed(obj) { - if (obj.isMesh && bloomLayer.test(obj.layers) === false) { - materials[obj.uuid] = obj.material; - obj.material = darkMaterial; - } -} - -function restoreMaterial(obj) { - if (materials[obj.uuid]) { - obj.material = materials[obj.uuid]; - delete materials[obj.uuid]; - } -} diff --git a/examples-testing/examples/webgl_raycaster_sprite.ts b/examples-testing/examples/webgl_raycaster_sprite.ts deleted file mode 100644 index f35d5de17..000000000 --- a/examples-testing/examples/webgl_raycaster_sprite.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let renderer, scene, camera; -let group; - -let selectedObject = null; -const raycaster = new THREE.Raycaster(); -const pointer = new THREE.Vector2(); - -init(); - -function init() { - // init renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // init scene - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - group = new THREE.Group(); - scene.add(group); - - // init camera - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(15, 15, 15); - camera.lookAt(scene.position); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 15; - controls.maxDistance = 250; - - // add sprites - - const sprite1 = new THREE.Sprite(new THREE.SpriteMaterial({ color: '#69f' })); - sprite1.position.set(6, 5, 5); - sprite1.scale.set(2, 5, 1); - group.add(sprite1); - - const sprite2 = new THREE.Sprite(new THREE.SpriteMaterial({ color: '#69f', sizeAttenuation: false })); - sprite2.material.rotation = (Math.PI / 3) * 4; - sprite2.position.set(8, -2, 2); - sprite2.center.set(0.5, 0); - sprite2.scale.set(0.1, 0.5, 0.1); - group.add(sprite2); - - const group2 = new THREE.Object3D(); - group2.scale.set(1, 2, 1); - group2.position.set(-5, 0, 0); - group2.rotation.set(Math.PI / 2, 0, 0); - group.add(group2); - - const sprite3 = new THREE.Sprite(new THREE.SpriteMaterial({ color: '#69f' })); - sprite3.position.set(0, 2, 5); - sprite3.scale.set(10, 2, 3); - sprite3.center.set(-0.1, 0); - sprite3.material.rotation = Math.PI / 3; - group2.add(sprite3); - - window.addEventListener('resize', onWindowResize); - document.addEventListener('pointermove', onPointerMove); -} - -function animate() { - renderer.render(scene, camera); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerMove(event) { - if (selectedObject) { - selectedObject.material.color.set('#69f'); - selectedObject = null; - } - - pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - - raycaster.setFromCamera(pointer, camera); - - const intersects = raycaster.intersectObject(group, true); - - if (intersects.length > 0) { - const res = intersects.filter(function (res) { - return res && res.object; - })[0]; - - if (res && res.object) { - selectedObject = res.object; - selectedObject.material.color.set('#f00'); - } - } -} diff --git a/examples-testing/examples/webgl_raycaster_texture.ts b/examples-testing/examples/webgl_raycaster_texture.ts deleted file mode 100644 index 72c7054dc..000000000 --- a/examples-testing/examples/webgl_raycaster_texture.ts +++ /dev/null @@ -1,286 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const WRAPPING = { - RepeatWrapping: THREE.RepeatWrapping, - ClampToEdgeWrapping: THREE.ClampToEdgeWrapping, - MirroredRepeatWrapping: THREE.MirroredRepeatWrapping, -}; - -const params = { - wrapS: THREE.RepeatWrapping, - wrapT: THREE.RepeatWrapping, - offsetX: 0, - offsetY: 0, - repeatX: 1, - repeatY: 1, - rotation: 0, -}; - -function CanvasTexture(parentTexture) { - this._canvas = document.createElement('canvas'); - this._canvas.width = this._canvas.height = 1024; - this._context2D = this._canvas.getContext('2d'); - - if (parentTexture) { - this._parentTexture.push(parentTexture); - parentTexture.image = this._canvas; - } - - const that = this; - this._background = document.createElement('img'); - this._background.addEventListener('load', function () { - that._canvas.width = that._background.naturalWidth; - that._canvas.height = that._background.naturalHeight; - - that._crossRadius = Math.ceil(Math.min(that._canvas.width, that._canvas.height / 30)); - that._crossMax = Math.ceil(0.70710678 * that._crossRadius); - that._crossMin = Math.ceil(that._crossMax / 10); - that._crossThickness = Math.ceil(that._crossMax / 10); - - that._draw(); - }); - this._background.crossOrigin = ''; - this._background.src = 'textures/uv_grid_opengl.jpg'; - - this._draw(); -} - -CanvasTexture.prototype = { - constructor: CanvasTexture, - - _canvas: null, - _context2D: null, - _xCross: 0, - _yCross: 0, - - _crossRadius: 57, - _crossMax: 40, - _crossMin: 4, - _crossThickness: 4, - - _parentTexture: [], - - addParent: function (parentTexture) { - if (this._parentTexture.indexOf(parentTexture) === -1) { - this._parentTexture.push(parentTexture); - parentTexture.image = this._canvas; - } - }, - - setCrossPosition: function (x, y) { - this._xCross = x * this._canvas.width; - this._yCross = y * this._canvas.height; - - this._draw(); - }, - - _draw: function () { - if (!this._context2D) return; - - this._context2D.clearRect(0, 0, this._canvas.width, this._canvas.height); - - // Background. - this._context2D.drawImage(this._background, 0, 0); - - // Yellow cross. - this._context2D.lineWidth = this._crossThickness * 3; - this._context2D.strokeStyle = '#FFFF00'; - - this._context2D.beginPath(); - this._context2D.moveTo(this._xCross - this._crossMax - 2, this._yCross - this._crossMax - 2); - this._context2D.lineTo(this._xCross - this._crossMin, this._yCross - this._crossMin); - - this._context2D.moveTo(this._xCross + this._crossMin, this._yCross + this._crossMin); - this._context2D.lineTo(this._xCross + this._crossMax + 2, this._yCross + this._crossMax + 2); - - this._context2D.moveTo(this._xCross - this._crossMax - 2, this._yCross + this._crossMax + 2); - this._context2D.lineTo(this._xCross - this._crossMin, this._yCross + this._crossMin); - - this._context2D.moveTo(this._xCross + this._crossMin, this._yCross - this._crossMin); - this._context2D.lineTo(this._xCross + this._crossMax + 2, this._yCross - this._crossMax - 2); - - this._context2D.stroke(); - - for (let i = 0; i < this._parentTexture.length; i++) { - this._parentTexture[i].needsUpdate = true; - } - }, -}; - -const width = window.innerWidth; -const height = window.innerHeight; - -let canvas; -let planeTexture, cubeTexture, circleTexture; - -let container; - -let camera, scene, renderer; - -const raycaster = new THREE.Raycaster(); -const mouse = new THREE.Vector2(); -const onClickPosition = new THREE.Vector2(); - -init(); - -function init() { - container = document.getElementById('container'); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xeeeeee); - - camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); - camera.position.x = -30; - camera.position.y = 40; - camera.position.z = 50; - camera.lookAt(scene.position); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(width, height); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // A cube, in the middle. - cubeTexture = new THREE.Texture(undefined, THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping); - cubeTexture.colorSpace = THREE.SRGBColorSpace; - canvas = new CanvasTexture(cubeTexture); - const cubeMaterial = new THREE.MeshBasicMaterial({ map: cubeTexture }); - const cubeGeometry = new THREE.BoxGeometry(20, 20, 20); - let uvs = cubeGeometry.attributes.uv.array; - // Set a specific texture mapping. - for (let i = 0; i < uvs.length; i++) { - uvs[i] *= 2; - } - - const cube = new THREE.Mesh(cubeGeometry, cubeMaterial); - cube.position.x = 4; - cube.position.y = -5; - cube.position.z = 0; - scene.add(cube); - - // A plane on the left - - planeTexture = new THREE.Texture( - undefined, - THREE.UVMapping, - THREE.MirroredRepeatWrapping, - THREE.MirroredRepeatWrapping, - ); - planeTexture.colorSpace = THREE.SRGBColorSpace; - canvas.addParent(planeTexture); - const planeMaterial = new THREE.MeshBasicMaterial({ map: planeTexture }); - const planeGeometry = new THREE.PlaneGeometry(25, 25, 1, 1); - uvs = planeGeometry.attributes.uv.array; - - // Set a specific texture mapping. - - for (let i = 0; i < uvs.length; i++) { - uvs[i] *= 2; - } - - const plane = new THREE.Mesh(planeGeometry, planeMaterial); - plane.position.x = -16; - plane.position.y = -5; - plane.position.z = 0; - scene.add(plane); - - // A circle on the right. - - circleTexture = new THREE.Texture(undefined, THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping); - circleTexture.colorSpace = THREE.SRGBColorSpace; - canvas.addParent(circleTexture); - const circleMaterial = new THREE.MeshBasicMaterial({ map: circleTexture }); - const circleGeometry = new THREE.CircleGeometry(25, 40, 0, Math.PI * 2); - uvs = circleGeometry.attributes.uv.array; - - // Set a specific texture mapping. - - for (let i = 0; i < uvs.length; i++) { - uvs[i] = (uvs[i] - 0.25) * 2; - } - - const circle = new THREE.Mesh(circleGeometry, circleMaterial); - circle.position.x = 24; - circle.position.y = -5; - circle.position.z = 0; - scene.add(circle); - - window.addEventListener('resize', onWindowResize); - container.addEventListener('mousemove', onMouseMove); - - // - - const gui = new GUI(); - gui.title('Circle Texture Settings'); - - gui.add(params, 'wrapS', WRAPPING).onChange(setwrapS); - gui.add(params, 'wrapT', WRAPPING).onChange(setwrapT); - gui.add(params, 'offsetX', 0, 5); - gui.add(params, 'offsetY', 0, 5); - gui.add(params, 'repeatX', 0, 5); - gui.add(params, 'repeatY', 0, 5); - gui.add(params, 'rotation', 0, 2 * Math.PI); - gui.open(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onMouseMove(evt) { - evt.preventDefault(); - - const array = getMousePosition(container, evt.clientX, evt.clientY); - onClickPosition.fromArray(array); - - const intersects = getIntersects(onClickPosition, scene.children); - - if (intersects.length > 0 && intersects[0].uv) { - const uv = intersects[0].uv; - intersects[0].object.material.map.transformUv(uv); - canvas.setCrossPosition(uv.x, uv.y); - } -} - -function getMousePosition(dom, x, y) { - const rect = dom.getBoundingClientRect(); - return [(x - rect.left) / rect.width, (y - rect.top) / rect.height]; -} - -function getIntersects(point, objects) { - mouse.set(point.x * 2 - 1, -(point.y * 2) + 1); - - raycaster.setFromCamera(mouse, camera); - - return raycaster.intersectObjects(objects, false); -} - -function animate() { - // update texture parameters - - circleTexture.offset.x = params.offsetX; - circleTexture.offset.y = params.offsetY; - circleTexture.repeat.x = params.repeatX; - circleTexture.repeat.y = params.repeatY; - circleTexture.rotation = params.rotation; - - // - - renderer.render(scene, camera); -} - -function setwrapS(value) { - circleTexture.wrapS = value; - circleTexture.needsUpdate = true; -} - -function setwrapT(value) { - circleTexture.wrapT = value; - circleTexture.needsUpdate = true; -} diff --git a/examples-testing/examples/webgl_raymarching_reflect.ts b/examples-testing/examples/webgl_raymarching_reflect.ts deleted file mode 100644 index e5448ebbd..000000000 --- a/examples-testing/examples/webgl_raymarching_reflect.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let dolly, camera, scene, renderer; -let geometry, material, mesh; -let stats, clock; - -const canvas = document.querySelector('#canvas'); - -const config = { - saveImage: function () { - renderer.render(scene, camera); - window.open(canvas.toDataURL()); - }, - resolution: '512', -}; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer({ canvas: canvas }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(parseInt(config.resolution), parseInt(config.resolution)); - renderer.setAnimationLoop(animate); - - window.addEventListener('resize', onWindowResize); - - // THREE.Scene - scene = new THREE.Scene(); - - dolly = new THREE.Group(); - scene.add(dolly); - - clock = new THREE.Clock(); - - camera = new THREE.PerspectiveCamera(60, canvas.width / canvas.height, 1, 2000); - camera.position.z = 4; - dolly.add(camera); - - geometry = new THREE.PlaneGeometry(2.0, 2.0); - material = new THREE.RawShaderMaterial({ - uniforms: { - resolution: { value: new THREE.Vector2(canvas.width, canvas.height) }, - cameraWorldMatrix: { value: camera.matrixWorld }, - cameraProjectionMatrixInverse: { value: camera.projectionMatrixInverse.clone() }, - }, - vertexShader: document.getElementById('vertex_shader').textContent, - fragmentShader: document.getElementById('fragment_shader').textContent, - }); - mesh = new THREE.Mesh(geometry, material); - mesh.frustumCulled = false; - scene.add(mesh); - - // Controls - const controls = new OrbitControls(camera, canvas); - controls.enableZoom = false; - - // GUI - const gui = new GUI(); - gui.add(config, 'saveImage').name('Save Image'); - gui.add(config, 'resolution', ['256', '512', '800', 'full']).name('Resolution').onChange(onWindowResize); - - stats = new Stats(); - document.body.appendChild(stats.dom); -} - -function onWindowResize() { - if (config.resolution === 'full') { - renderer.setSize(window.innerWidth, window.innerHeight); - } else { - renderer.setSize(parseInt(config.resolution), parseInt(config.resolution)); - } - - camera.aspect = canvas.width / canvas.height; - camera.updateProjectionMatrix(); - - material.uniforms.resolution.value.set(canvas.width, canvas.height); - material.uniforms.cameraProjectionMatrixInverse.value.copy(camera.projectionMatrixInverse); -} - -function animate() { - stats.begin(); - - const elapsedTime = clock.getElapsedTime(); - - dolly.position.z = -elapsedTime; - - renderer.render(scene, camera); - - stats.end(); -} diff --git a/examples-testing/examples/webgl_read_float_buffer.ts b/examples-testing/examples/webgl_read_float_buffer.ts deleted file mode 100644 index 68452a12a..000000000 --- a/examples-testing/examples/webgl_read_float_buffer.ts +++ /dev/null @@ -1,153 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let cameraRTT, sceneRTT, sceneScreen, renderer, zmesh1, zmesh2; - -let mouseX = 0, - mouseY = 0; - -const windowHalfX = window.innerWidth / 2; -const windowHalfY = window.innerHeight / 2; - -let rtTexture, material, quad; - -let delta = 0.01; -let valueNode; - -init(); - -function init() { - container = document.getElementById('container'); - - cameraRTT = new THREE.OrthographicCamera( - window.innerWidth / -2, - window.innerWidth / 2, - window.innerHeight / 2, - window.innerHeight / -2, - -10000, - 10000, - ); - cameraRTT.position.z = 100; - - // - - sceneRTT = new THREE.Scene(); - sceneScreen = new THREE.Scene(); - - let light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 0, 1).normalize(); - sceneRTT.add(light); - - light = new THREE.DirectionalLight(0xffd5d5, 4.5); - light.position.set(0, 0, -1).normalize(); - sceneRTT.add(light); - - rtTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { - minFilter: THREE.LinearFilter, - magFilter: THREE.NearestFilter, - format: THREE.RGBAFormat, - type: THREE.FloatType, - }); - - material = new THREE.ShaderMaterial({ - uniforms: { time: { value: 0.0 } }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragment_shader_pass_1').textContent, - }); - - const materialScreen = new THREE.ShaderMaterial({ - uniforms: { tDiffuse: { value: rtTexture.texture } }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragment_shader_screen').textContent, - - depthWrite: false, - }); - - const plane = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight); - - quad = new THREE.Mesh(plane, material); - quad.position.z = -100; - sceneRTT.add(quad); - - const geometry = new THREE.TorusGeometry(100, 25, 15, 30); - - const mat1 = new THREE.MeshPhongMaterial({ color: 0x9c9c9c, specular: 0xffaa00, shininess: 5 }); - const mat2 = new THREE.MeshPhongMaterial({ color: 0x9c0000, specular: 0xff2200, shininess: 5 }); - - zmesh1 = new THREE.Mesh(geometry, mat1); - zmesh1.position.set(0, 0, 100); - zmesh1.scale.set(1.5, 1.5, 1.5); - sceneRTT.add(zmesh1); - - zmesh2 = new THREE.Mesh(geometry, mat2); - zmesh2.position.set(0, 150, 100); - zmesh2.scale.set(0.75, 0.75, 0.75); - sceneRTT.add(zmesh2); - - quad = new THREE.Mesh(plane, materialScreen); - quad.position.z = -100; - sceneScreen.add(quad); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - valueNode = document.getElementById('values'); - - document.addEventListener('mousemove', onDocumentMouseMove); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.0015; - - if (zmesh1 && zmesh2) { - zmesh1.rotation.y = -time; - zmesh2.rotation.y = -time + Math.PI / 2; - } - - if (material.uniforms['time'].value > 1 || material.uniforms['time'].value < 0) { - delta *= -1; - } - - material.uniforms['time'].value += delta; - - renderer.clear(); - - // Render first scene into texture - - renderer.setRenderTarget(rtTexture); - renderer.clear(); - renderer.render(sceneRTT, cameraRTT); - - // Render full screen quad with generated texture - - renderer.setRenderTarget(null); - renderer.render(sceneScreen, cameraRTT); - - const read = new Float32Array(4); - renderer.readRenderTargetPixels(rtTexture, windowHalfX + mouseX, windowHalfY - mouseY, 1, 1, read); - - valueNode.innerHTML = 'r:' + read[0] + '
g:' + read[1] + '
b:' + read[2]; -} diff --git a/examples-testing/examples/webgl_refraction.ts b/examples-testing/examples/webgl_refraction.ts deleted file mode 100644 index 572575afa..000000000 --- a/examples-testing/examples/webgl_refraction.ts +++ /dev/null @@ -1,135 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Refractor } from 'three/addons/objects/Refractor.js'; -import { WaterRefractionShader } from 'three/addons/shaders/WaterRefractionShader.js'; - -let camera, scene, renderer, clock; - -let refractor, smallSphere; - -init(); - -async function init() { - const container = document.getElementById('container'); - - clock = new THREE.Clock(); - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500); - camera.position.set(0, 75, 160); - - // refractor - - const refractorGeometry = new THREE.PlaneGeometry(90, 90); - - refractor = new Refractor(refractorGeometry, { - color: 0xcbcbcb, - textureWidth: 1024, - textureHeight: 1024, - shader: WaterRefractionShader, - }); - - refractor.position.set(0, 50, 0); - - scene.add(refractor); - - // load dudv map for distortion effect - - const loader = new THREE.TextureLoader(); - const dudvMap = await loader.loadAsync('textures/waterdudv.jpg'); - - dudvMap.wrapS = dudvMap.wrapT = THREE.RepeatWrapping; - refractor.material.uniforms.tDudv.value = dudvMap; - - // - - const geometry = new THREE.IcosahedronGeometry(5, 0); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x333333, flatShading: true }); - smallSphere = new THREE.Mesh(geometry, material); - scene.add(smallSphere); - - // walls - const planeGeo = new THREE.PlaneGeometry(100.1, 100.1); - - const planeTop = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeTop.position.y = 100; - planeTop.rotateX(Math.PI / 2); - scene.add(planeTop); - - const planeBottom = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeBottom.rotateX(-Math.PI / 2); - scene.add(planeBottom); - - const planeBack = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x7f7fff })); - planeBack.position.z = -50; - planeBack.position.y = 50; - scene.add(planeBack); - - const planeRight = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x00ff00 })); - planeRight.position.x = 50; - planeRight.position.y = 50; - planeRight.rotateY(-Math.PI / 2); - scene.add(planeRight); - - const planeLeft = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xff0000 })); - planeLeft.position.x = -50; - planeLeft.position.y = 50; - planeLeft.rotateY(Math.PI / 2); - scene.add(planeLeft); - - // lights - const mainLight = new THREE.PointLight(0xe7e7e7, 2.5, 250, 0); - mainLight.position.y = 60; - scene.add(mainLight); - - const greenLight = new THREE.PointLight(0x00ff00, 0.5, 1000, 0); - greenLight.position.set(550, 50, 0); - scene.add(greenLight); - - const redLight = new THREE.PointLight(0xff0000, 0.5, 1000, 0); - redLight.position.set(-550, 50, 0); - scene.add(redLight); - - const blueLight = new THREE.PointLight(0xbbbbfe, 0.5, 1000, 0); - blueLight.position.set(0, 50, 550); - scene.add(blueLight); - - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 40, 0); - controls.maxDistance = 400; - controls.minDistance = 10; - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = clock.getElapsedTime(); - - refractor.material.uniforms.time.value = time; - - smallSphere.position.set(Math.cos(time) * 30, Math.abs(Math.cos(time * 2)) * 20 + 5, Math.sin(time) * 30); - smallSphere.rotation.y = Math.PI / 2 - time; - smallSphere.rotation.z = time * 8; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_rtt.ts b/examples-testing/examples/webgl_rtt.ts deleted file mode 100644 index 9f16fdab8..000000000 --- a/examples-testing/examples/webgl_rtt.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let cameraRTT, camera, sceneRTT, sceneScreen, scene, renderer, zmesh1, zmesh2; - -let mouseX = 0, - mouseY = 0; - -const windowHalfX = window.innerWidth / 2; -const windowHalfY = window.innerHeight / 2; - -let rtTexture, material, quad; - -let delta = 0.01; - -init(); - -function init() { - container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 100; - - cameraRTT = new THREE.OrthographicCamera( - window.innerWidth / -2, - window.innerWidth / 2, - window.innerHeight / 2, - window.innerHeight / -2, - -10000, - 10000, - ); - cameraRTT.position.z = 100; - - // - - scene = new THREE.Scene(); - sceneRTT = new THREE.Scene(); - sceneScreen = new THREE.Scene(); - - let light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 0, 1).normalize(); - sceneRTT.add(light); - - light = new THREE.DirectionalLight(0xffd5d5, 4.5); - light.position.set(0, 0, -1).normalize(); - sceneRTT.add(light); - - rtTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); - - material = new THREE.ShaderMaterial({ - uniforms: { time: { value: 0.0 } }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragment_shader_pass_1').textContent, - }); - - const materialScreen = new THREE.ShaderMaterial({ - uniforms: { tDiffuse: { value: rtTexture.texture } }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragment_shader_screen').textContent, - - depthWrite: false, - }); - - const plane = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight); - - quad = new THREE.Mesh(plane, material); - quad.position.z = -100; - sceneRTT.add(quad); - - const torusGeometry = new THREE.TorusGeometry(100, 25, 15, 30); - - const mat1 = new THREE.MeshPhongMaterial({ color: 0x9c9c9c, specular: 0xffaa00, shininess: 5 }); - const mat2 = new THREE.MeshPhongMaterial({ color: 0x9c0000, specular: 0xff2200, shininess: 5 }); - - zmesh1 = new THREE.Mesh(torusGeometry, mat1); - zmesh1.position.set(0, 0, 100); - zmesh1.scale.set(1.5, 1.5, 1.5); - sceneRTT.add(zmesh1); - - zmesh2 = new THREE.Mesh(torusGeometry, mat2); - zmesh2.position.set(0, 150, 100); - zmesh2.scale.set(0.75, 0.75, 0.75); - sceneRTT.add(zmesh2); - - quad = new THREE.Mesh(plane, materialScreen); - quad.position.z = -100; - sceneScreen.add(quad); - - const n = 5, - geometry = new THREE.SphereGeometry(10, 64, 32), - material2 = new THREE.MeshBasicMaterial({ color: 0xffffff, map: rtTexture.texture }); - - for (let j = 0; j < n; j++) { - for (let i = 0; i < n; i++) { - const mesh = new THREE.Mesh(geometry, material2); - - mesh.position.x = (i - (n - 1) / 2) * 20; - mesh.position.y = (j - (n - 1) / 2) * 20; - mesh.position.z = 0; - - mesh.rotation.y = -Math.PI / 2; - - scene.add(mesh); - } - } - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - container.appendChild(renderer.domElement); - - stats = new Stats(); - container.appendChild(stats.dom); - - document.addEventListener('mousemove', onDocumentMouseMove); -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = Date.now() * 0.0015; - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - if (zmesh1 && zmesh2) { - zmesh1.rotation.y = -time; - zmesh2.rotation.y = -time + Math.PI / 2; - } - - if (material.uniforms['time'].value > 1 || material.uniforms['time'].value < 0) { - delta *= -1; - } - - material.uniforms['time'].value += delta; - - // Render first scene into texture - - renderer.setRenderTarget(rtTexture); - renderer.clear(); - renderer.render(sceneRTT, cameraRTT); - - // Render full screen quad with generated texture - - renderer.setRenderTarget(null); - renderer.clear(); - renderer.render(sceneScreen, cameraRTT); - - // Render second scene to screen - // (using first scene as regular texture) - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_shader.ts b/examples-testing/examples/webgl_shader.ts deleted file mode 100644 index 47a6c7ece..000000000 --- a/examples-testing/examples/webgl_shader.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; - -let uniforms; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); - - scene = new THREE.Scene(); - - const geometry = new THREE.PlaneGeometry(2, 2); - - uniforms = { - time: { value: 1.0 }, - }; - - const material = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - uniforms['time'].value = performance.now() / 1000; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_shader_lava.ts b/examples-testing/examples/webgl_shader_lava.ts deleted file mode 100644 index 973a580eb..000000000 --- a/examples-testing/examples/webgl_shader_lava.ts +++ /dev/null @@ -1,101 +0,0 @@ -import * as THREE from 'three'; - -import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; -import { BloomPass } from 'three/addons/postprocessing/BloomPass.js'; -import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; - -let camera, renderer, composer, clock; - -let uniforms, mesh; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 3000); - camera.position.z = 4; - - const scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - const textureLoader = new THREE.TextureLoader(); - - const cloudTexture = textureLoader.load('textures/lava/cloud.png'); - const lavaTexture = textureLoader.load('textures/lava/lavatile.jpg'); - - lavaTexture.colorSpace = THREE.SRGBColorSpace; - - cloudTexture.wrapS = cloudTexture.wrapT = THREE.RepeatWrapping; - lavaTexture.wrapS = lavaTexture.wrapT = THREE.RepeatWrapping; - - uniforms = { - fogDensity: { value: 0.45 }, - fogColor: { value: new THREE.Vector3(0, 0, 0) }, - time: { value: 1.0 }, - uvScale: { value: new THREE.Vector2(3.0, 1.0) }, - texture1: { value: cloudTexture }, - texture2: { value: lavaTexture }, - }; - - const size = 0.65; - - const material = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - }); - - mesh = new THREE.Mesh(new THREE.TorusGeometry(size, 0.3, 30, 30), material); - mesh.rotation.x = 0.3; - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - container.appendChild(renderer.domElement); - - // - - const renderModel = new RenderPass(scene, camera); - const effectBloom = new BloomPass(1.25); - const outputPass = new OutputPass(); - - composer = new EffectComposer(renderer); - - composer.addPass(renderModel); - composer.addPass(effectBloom); - composer.addPass(outputPass); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - composer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const delta = 5 * clock.getDelta(); - - uniforms['time'].value += 0.2 * delta; - - mesh.rotation.y += 0.0125 * delta; - mesh.rotation.x += 0.05 * delta; - - renderer.clear(); - composer.render(0.01); -} diff --git a/examples-testing/examples/webgl_shaders_ocean.ts b/examples-testing/examples/webgl_shaders_ocean.ts deleted file mode 100644 index 8b0f9a738..000000000 --- a/examples-testing/examples/webgl_shaders_ocean.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Water } from 'three/addons/objects/Water.js'; -import { Sky } from 'three/addons/objects/Sky.js'; - -let container, stats; -let camera, scene, renderer; -let controls, water, sun, mesh; - -init(); - -function init() { - container = document.getElementById('container'); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 0.5; - container.appendChild(renderer.domElement); - - // - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000); - camera.position.set(30, 30, 100); - - // - - sun = new THREE.Vector3(); - - // Water - - const waterGeometry = new THREE.PlaneGeometry(10000, 10000); - - water = new Water(waterGeometry, { - textureWidth: 512, - textureHeight: 512, - waterNormals: new THREE.TextureLoader().load('textures/waternormals.jpg', function (texture) { - texture.wrapS = texture.wrapT = THREE.RepeatWrapping; - }), - sunDirection: new THREE.Vector3(), - sunColor: 0xffffff, - waterColor: 0x001e0f, - distortionScale: 3.7, - fog: scene.fog !== undefined, - }); - - water.rotation.x = -Math.PI / 2; - - scene.add(water); - - // Skybox - - const sky = new Sky(); - sky.scale.setScalar(10000); - scene.add(sky); - - const skyUniforms = sky.material.uniforms; - - skyUniforms['turbidity'].value = 10; - skyUniforms['rayleigh'].value = 2; - skyUniforms['mieCoefficient'].value = 0.005; - skyUniforms['mieDirectionalG'].value = 0.8; - - const parameters = { - elevation: 2, - azimuth: 180, - }; - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - const sceneEnv = new THREE.Scene(); - - let renderTarget; - - function updateSun() { - const phi = THREE.MathUtils.degToRad(90 - parameters.elevation); - const theta = THREE.MathUtils.degToRad(parameters.azimuth); - - sun.setFromSphericalCoords(1, phi, theta); - - sky.material.uniforms['sunPosition'].value.copy(sun); - water.material.uniforms['sunDirection'].value.copy(sun).normalize(); - - if (renderTarget !== undefined) renderTarget.dispose(); - - sceneEnv.add(sky); - renderTarget = pmremGenerator.fromScene(sceneEnv); - scene.add(sky); - - scene.environment = renderTarget.texture; - } - - updateSun(); - - // - - const geometry = new THREE.BoxGeometry(30, 30, 30); - const material = new THREE.MeshStandardMaterial({ roughness: 0 }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = Math.PI * 0.495; - controls.target.set(0, 10, 0); - controls.minDistance = 40.0; - controls.maxDistance = 200.0; - controls.update(); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // GUI - - const gui = new GUI(); - - const folderSky = gui.addFolder('Sky'); - folderSky.add(parameters, 'elevation', 0, 90, 0.1).onChange(updateSun); - folderSky.add(parameters, 'azimuth', -180, 180, 0.1).onChange(updateSun); - folderSky.open(); - - const waterUniforms = water.material.uniforms; - - const folderWater = gui.addFolder('Water'); - folderWater.add(waterUniforms.distortionScale, 'value', 0, 8, 0.1).name('distortionScale'); - folderWater.add(waterUniforms.size, 'value', 0.1, 10, 0.1).name('size'); - folderWater.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = performance.now() * 0.001; - - mesh.position.y = Math.sin(time) * 20 + 5; - mesh.rotation.x = time * 0.5; - mesh.rotation.z = time * 0.51; - - water.material.uniforms['time'].value += 1.0 / 60.0; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_shaders_sky.ts b/examples-testing/examples/webgl_shaders_sky.ts deleted file mode 100644 index 18020f78f..000000000 --- a/examples-testing/examples/webgl_shaders_sky.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Sky } from 'three/addons/objects/Sky.js'; - -let camera, scene, renderer; - -let sky, sun; - -init(); -render(); - -function initSky() { - // Add Sky - sky = new Sky(); - sky.scale.setScalar(450000); - scene.add(sky); - - sun = new THREE.Vector3(); - - /// GUI - - const effectController = { - turbidity: 10, - rayleigh: 3, - mieCoefficient: 0.005, - mieDirectionalG: 0.7, - elevation: 2, - azimuth: 180, - exposure: renderer.toneMappingExposure, - }; - - function guiChanged() { - const uniforms = sky.material.uniforms; - uniforms['turbidity'].value = effectController.turbidity; - uniforms['rayleigh'].value = effectController.rayleigh; - uniforms['mieCoefficient'].value = effectController.mieCoefficient; - uniforms['mieDirectionalG'].value = effectController.mieDirectionalG; - - const phi = THREE.MathUtils.degToRad(90 - effectController.elevation); - const theta = THREE.MathUtils.degToRad(effectController.azimuth); - - sun.setFromSphericalCoords(1, phi, theta); - - uniforms['sunPosition'].value.copy(sun); - - renderer.toneMappingExposure = effectController.exposure; - renderer.render(scene, camera); - } - - const gui = new GUI(); - - gui.add(effectController, 'turbidity', 0.0, 20.0, 0.1).onChange(guiChanged); - gui.add(effectController, 'rayleigh', 0.0, 4, 0.001).onChange(guiChanged); - gui.add(effectController, 'mieCoefficient', 0.0, 0.1, 0.001).onChange(guiChanged); - gui.add(effectController, 'mieDirectionalG', 0.0, 1, 0.001).onChange(guiChanged); - gui.add(effectController, 'elevation', 0, 90, 0.1).onChange(guiChanged); - gui.add(effectController, 'azimuth', -180, 180, 0.1).onChange(guiChanged); - gui.add(effectController, 'exposure', 0, 1, 0.0001).onChange(guiChanged); - - guiChanged(); -} - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 2000000); - camera.position.set(0, 100, 2000); - - scene = new THREE.Scene(); - - const helper = new THREE.GridHelper(10000, 2, 0xffffff, 0xffffff); - scene.add(helper); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 0.5; - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - //controls.maxPolarAngle = Math.PI / 2; - controls.enableZoom = false; - controls.enablePan = false; - - initSky(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_shadow_contact.ts b/examples-testing/examples/webgl_shadow_contact.ts deleted file mode 100644 index 9eda35b83..000000000 --- a/examples-testing/examples/webgl_shadow_contact.ts +++ /dev/null @@ -1,272 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { HorizontalBlurShader } from 'three/addons/shaders/HorizontalBlurShader.js'; -import { VerticalBlurShader } from 'three/addons/shaders/VerticalBlurShader.js'; - -let camera, scene, renderer, stats, gui; - -const meshes = []; - -const PLANE_WIDTH = 2.5; -const PLANE_HEIGHT = 2.5; -const CAMERA_HEIGHT = 0.3; - -const state = { - shadow: { - blur: 3.5, - darkness: 1, - opacity: 1, - }, - plane: { - color: '#ffffff', - opacity: 1, - }, - showWireframe: false, -}; - -let shadowGroup, - renderTarget, - renderTargetBlur, - shadowCamera, - cameraHelper, - depthMaterial, - horizontalBlurMaterial, - verticalBlurMaterial; - -let plane, blurPlane, fillPlane; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0.5, 1, 2); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); - - // add the example meshes - - const geometries = [ - new THREE.BoxGeometry(0.4, 0.4, 0.4), - new THREE.IcosahedronGeometry(0.3), - new THREE.TorusKnotGeometry(0.4, 0.05, 256, 24, 1, 3), - ]; - - const material = new THREE.MeshNormalMaterial(); - - for (let i = 0, l = geometries.length; i < l; i++) { - const angle = (i / l) * Math.PI * 2; - - const geometry = geometries[i]; - const mesh = new THREE.Mesh(geometry, material); - mesh.position.y = 0.1; - mesh.position.x = Math.cos(angle) / 2.0; - mesh.position.z = Math.sin(angle) / 2.0; - scene.add(mesh); - meshes.push(mesh); - } - - // the container, if you need to move the plane just move this - shadowGroup = new THREE.Group(); - shadowGroup.position.y = -0.3; - scene.add(shadowGroup); - - // the render target that will show the shadows in the plane texture - renderTarget = new THREE.WebGLRenderTarget(512, 512); - renderTarget.texture.generateMipmaps = false; - - // the render target that we will use to blur the first render target - renderTargetBlur = new THREE.WebGLRenderTarget(512, 512); - renderTargetBlur.texture.generateMipmaps = false; - - // make a plane and make it face up - const planeGeometry = new THREE.PlaneGeometry(PLANE_WIDTH, PLANE_HEIGHT).rotateX(Math.PI / 2); - const planeMaterial = new THREE.MeshBasicMaterial({ - map: renderTarget.texture, - opacity: state.shadow.opacity, - transparent: true, - depthWrite: false, - }); - plane = new THREE.Mesh(planeGeometry, planeMaterial); - // make sure it's rendered after the fillPlane - plane.renderOrder = 1; - shadowGroup.add(plane); - - // the y from the texture is flipped! - plane.scale.y = -1; - - // the plane onto which to blur the texture - blurPlane = new THREE.Mesh(planeGeometry); - blurPlane.visible = false; - shadowGroup.add(blurPlane); - - // the plane with the color of the ground - const fillPlaneMaterial = new THREE.MeshBasicMaterial({ - color: state.plane.color, - opacity: state.plane.opacity, - transparent: true, - depthWrite: false, - }); - fillPlane = new THREE.Mesh(planeGeometry, fillPlaneMaterial); - fillPlane.rotateX(Math.PI); - shadowGroup.add(fillPlane); - - // the camera to render the depth material from - shadowCamera = new THREE.OrthographicCamera( - -PLANE_WIDTH / 2, - PLANE_WIDTH / 2, - PLANE_HEIGHT / 2, - -PLANE_HEIGHT / 2, - 0, - CAMERA_HEIGHT, - ); - shadowCamera.rotation.x = Math.PI / 2; // get the camera to look up - shadowGroup.add(shadowCamera); - - cameraHelper = new THREE.CameraHelper(shadowCamera); - - // like MeshDepthMaterial, but goes from black to transparent - depthMaterial = new THREE.MeshDepthMaterial(); - depthMaterial.userData.darkness = { value: state.shadow.darkness }; - depthMaterial.onBeforeCompile = function (shader) { - shader.uniforms.darkness = depthMaterial.userData.darkness; - shader.fragmentShader = /* glsl */ ` - uniform float darkness; - ${shader.fragmentShader.replace( - 'gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );', - 'gl_FragColor = vec4( vec3( 0.0 ), ( 1.0 - fragCoordZ ) * darkness );', - )} - `; - }; - - depthMaterial.depthTest = false; - depthMaterial.depthWrite = false; - - horizontalBlurMaterial = new THREE.ShaderMaterial(HorizontalBlurShader); - horizontalBlurMaterial.depthTest = false; - - verticalBlurMaterial = new THREE.ShaderMaterial(VerticalBlurShader); - verticalBlurMaterial.depthTest = false; - - // - - gui = new GUI(); - const shadowFolder = gui.addFolder('shadow'); - shadowFolder.open(); - const planeFolder = gui.addFolder('plane'); - planeFolder.open(); - - shadowFolder.add(state.shadow, 'blur', 0, 15, 0.1); - shadowFolder.add(state.shadow, 'darkness', 1, 5, 0.1).onChange(function () { - depthMaterial.userData.darkness.value = state.shadow.darkness; - }); - shadowFolder.add(state.shadow, 'opacity', 0, 1, 0.01).onChange(function () { - plane.material.opacity = state.shadow.opacity; - }); - planeFolder.addColor(state.plane, 'color').onChange(function () { - fillPlane.material.color = new THREE.Color(state.plane.color); - }); - planeFolder.add(state.plane, 'opacity', 0, 1, 0.01).onChange(function () { - fillPlane.material.opacity = state.plane.opacity; - }); - - gui.add(state, 'showWireframe').onChange(function () { - if (state.showWireframe) { - scene.add(cameraHelper); - } else { - scene.remove(cameraHelper); - } - }); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - new OrbitControls(camera, renderer.domElement); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// renderTarget --> blurPlane (horizontalBlur) --> renderTargetBlur --> blurPlane (verticalBlur) --> renderTarget -function blurShadow(amount) { - blurPlane.visible = true; - - // blur horizontally and draw in the renderTargetBlur - blurPlane.material = horizontalBlurMaterial; - blurPlane.material.uniforms.tDiffuse.value = renderTarget.texture; - horizontalBlurMaterial.uniforms.h.value = (amount * 1) / 256; - - renderer.setRenderTarget(renderTargetBlur); - renderer.render(blurPlane, shadowCamera); - - // blur vertically and draw in the main renderTarget - blurPlane.material = verticalBlurMaterial; - blurPlane.material.uniforms.tDiffuse.value = renderTargetBlur.texture; - verticalBlurMaterial.uniforms.v.value = (amount * 1) / 256; - - renderer.setRenderTarget(renderTarget); - renderer.render(blurPlane, shadowCamera); - - blurPlane.visible = false; -} - -function animate() { - meshes.forEach(mesh => { - mesh.rotation.x += 0.01; - mesh.rotation.y += 0.02; - }); - - // - - // remove the background - const initialBackground = scene.background; - scene.background = null; - - // force the depthMaterial to everything - cameraHelper.visible = false; - scene.overrideMaterial = depthMaterial; - - // set renderer clear alpha - const initialClearAlpha = renderer.getClearAlpha(); - renderer.setClearAlpha(0); - - // render to the render target to get the depths - renderer.setRenderTarget(renderTarget); - renderer.render(scene, shadowCamera); - - // and reset the override material - scene.overrideMaterial = null; - cameraHelper.visible = true; - - blurShadow(state.shadow.blur); - - // a second pass to reduce the artifacts - // (0.4 is the minimum blur amout so that the artifacts are gone) - blurShadow(state.shadow.blur * 0.4); - - // reset and render the normal scene - renderer.setRenderTarget(null); - renderer.setClearAlpha(initialClearAlpha); - scene.background = initialBackground; - - renderer.render(scene, camera); - stats.update(); -} diff --git a/examples-testing/examples/webgl_shadowmap.ts b/examples-testing/examples/webgl_shadowmap.ts deleted file mode 100644 index 6d0ac3adb..000000000 --- a/examples-testing/examples/webgl_shadowmap.ts +++ /dev/null @@ -1,311 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; -import { ShadowMapViewer } from 'three/addons/utils/ShadowMapViewer.js'; - -const SHADOW_MAP_WIDTH = 2048, - SHADOW_MAP_HEIGHT = 1024; - -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; -const FLOOR = -250; - -let camera, controls, scene, renderer; -let container, stats; - -const NEAR = 10, - FAR = 3000; - -let mixer; - -const morphs = []; - -let light; -let lightShadowMapViewer; - -const clock = new THREE.Clock(); - -let showHUD = false; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(23, SCREEN_WIDTH / SCREEN_HEIGHT, NEAR, FAR); - camera.position.set(700, 50, 1900); - - // SCENE - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x59472b); - scene.fog = new THREE.Fog(0x59472b, 1000, FAR); - - // LIGHTS - - const ambient = new THREE.AmbientLight(0xffffff); - scene.add(ambient); - - light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 1500, 1000); - light.castShadow = true; - light.shadow.camera.top = 2000; - light.shadow.camera.bottom = -2000; - light.shadow.camera.left = -2000; - light.shadow.camera.right = 2000; - light.shadow.camera.near = 1200; - light.shadow.camera.far = 2500; - light.shadow.bias = 0.0001; - - light.shadow.mapSize.width = SHADOW_MAP_WIDTH; - light.shadow.mapSize.height = SHADOW_MAP_HEIGHT; - - scene.add(light); - - createHUD(); - createScene(); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - renderer.autoClear = false; - - // - - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFShadowMap; - - // CONTROLS - - controls = new FirstPersonControls(camera, renderer.domElement); - - controls.lookSpeed = 0.0125; - controls.movementSpeed = 500; - controls.lookVertical = true; - - controls.lookAt(scene.position); - - // STATS - - stats = new Stats(); - //container.appendChild( stats.dom ); - - // - - window.addEventListener('resize', onWindowResize); - window.addEventListener('keydown', onKeyDown); -} - -function onWindowResize() { - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - controls.handleResize(); -} - -function onKeyDown(event) { - switch (event.keyCode) { - case 84 /*t*/: - showHUD = !showHUD; - break; - } -} - -function createHUD() { - lightShadowMapViewer = new ShadowMapViewer(light); - lightShadowMapViewer.position.x = 10; - lightShadowMapViewer.position.y = SCREEN_HEIGHT - SHADOW_MAP_HEIGHT / 4 - 10; - lightShadowMapViewer.size.width = SHADOW_MAP_WIDTH / 4; - lightShadowMapViewer.size.height = SHADOW_MAP_HEIGHT / 4; - lightShadowMapViewer.update(); -} - -function createScene() { - // GROUND - - const geometry = new THREE.PlaneGeometry(100, 100); - const planeMaterial = new THREE.MeshPhongMaterial({ color: 0xffdd99 }); - - const ground = new THREE.Mesh(geometry, planeMaterial); - - ground.position.set(0, FLOOR, 0); - ground.rotation.x = -Math.PI / 2; - ground.scale.set(100, 100, 100); - - ground.castShadow = false; - ground.receiveShadow = true; - - scene.add(ground); - - // TEXT - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_bold.typeface.json', function (font) { - const textGeo = new TextGeometry('THREE.JS', { - font: font, - - size: 200, - depth: 50, - curveSegments: 12, - - bevelThickness: 2, - bevelSize: 5, - bevelEnabled: true, - }); - - textGeo.computeBoundingBox(); - const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); - - const textMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000, specular: 0xffffff }); - - const mesh = new THREE.Mesh(textGeo, textMaterial); - mesh.position.x = centerOffset; - mesh.position.y = FLOOR + 67; - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - }); - - // CUBES - - const cubes1 = new THREE.Mesh(new THREE.BoxGeometry(1500, 220, 150), planeMaterial); - - cubes1.position.y = FLOOR - 50; - cubes1.position.z = 20; - - cubes1.castShadow = true; - cubes1.receiveShadow = true; - - scene.add(cubes1); - - const cubes2 = new THREE.Mesh(new THREE.BoxGeometry(1600, 170, 250), planeMaterial); - - cubes2.position.y = FLOOR - 50; - cubes2.position.z = 20; - - cubes2.castShadow = true; - cubes2.receiveShadow = true; - - scene.add(cubes2); - - // MORPHS - - mixer = new THREE.AnimationMixer(scene); - - function addMorph(mesh, clip, speed, duration, x, y, z, fudgeColor) { - mesh = mesh.clone(); - mesh.material = mesh.material.clone(); - - if (fudgeColor) { - mesh.material.color.offsetHSL(0, Math.random() * 0.5 - 0.25, Math.random() * 0.5 - 0.25); - } - - mesh.speed = speed; - - mixer - .clipAction(clip, mesh) - .setDuration(duration) - // to shift the playback out of phase: - .startAt(-duration * Math.random()) - .play(); - - mesh.position.set(x, y, z); - mesh.rotation.y = Math.PI / 2; - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - - morphs.push(mesh); - } - - const gltfloader = new GLTFLoader(); - - gltfloader.load('models/gltf/Horse.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 1000, FLOOR, 300, true); - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 1000, FLOOR, 450, true); - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 1000, FLOOR, 600, true); - - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 1000, FLOOR, -300, true); - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 1000, FLOOR, -450, true); - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 1000, FLOOR, -600, true); - }); - - gltfloader.load('models/gltf/Flamingo.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 500, 1, 500 - Math.random() * 500, FLOOR + 350, 40); - }); - - gltfloader.load('models/gltf/Stork.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 350, 1, 500 - Math.random() * 500, FLOOR + 350, 340); - }); - - gltfloader.load('models/gltf/Parrot.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - const clip = gltf.animations[0]; - - addMorph(mesh, clip, 450, 0.5, 500 - Math.random() * 500, FLOOR + 300, 700); - }); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - mixer.update(delta); - - for (let i = 0; i < morphs.length; i++) { - const morph = morphs[i]; - - morph.position.x += morph.speed * delta; - - if (morph.position.x > 2000) { - morph.position.x = -1000 - Math.random() * 500; - } - } - - controls.update(delta); - - renderer.clear(); - renderer.render(scene, camera); - - // Render debug HUD with shadow map - - if (showHUD) { - lightShadowMapViewer.render(renderer); - } -} diff --git a/examples-testing/examples/webgl_shadowmap_csm.ts b/examples-testing/examples/webgl_shadowmap_csm.ts deleted file mode 100644 index c89bc02df..000000000 --- a/examples-testing/examples/webgl_shadowmap_csm.ts +++ /dev/null @@ -1,253 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { CSM } from 'three/addons/csm/CSM.js'; -import { CSMHelper } from 'three/addons/csm/CSMHelper.js'; - -let renderer, scene, camera, orthoCamera, controls, csm, csmHelper; - -const params = { - orthographic: false, - fade: false, - shadows: true, - far: 1000, - mode: 'practical', - lightX: -1, - lightY: -1, - lightZ: -1, - margin: 100, - lightFar: 5000, - lightNear: 1, - autoUpdateHelper: true, - updateHelper: function () { - csmHelper.update(); - }, -}; - -init(); - -function updateOrthoCamera() { - const size = controls.target.distanceTo(camera.position); - const aspect = camera.aspect; - - orthoCamera.left = (size * aspect) / -2; - orthoCamera.right = (size * aspect) / 2; - - orthoCamera.top = size / 2; - orthoCamera.bottom = size / -2; - orthoCamera.position.copy(camera.position); - orthoCamera.rotation.copy(camera.rotation); - orthoCamera.updateProjectionMatrix(); -} - -function init() { - scene = new THREE.Scene(); - scene.background = new THREE.Color('#454e61'); - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 5000); - orthoCamera = new THREE.OrthographicCamera(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - renderer.shadowMap.enabled = params.shadows; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - - controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = Math.PI / 2; - camera.position.set(60, 60, 0); - controls.target = new THREE.Vector3(-100, 10, 0); - controls.update(); - - const ambientLight = new THREE.AmbientLight(0xffffff, 1.5); - scene.add(ambientLight); - - const additionalDirectionalLight = new THREE.DirectionalLight(0x000020, 1.5); - additionalDirectionalLight.position - .set(params.lightX, params.lightY, params.lightZ) - .normalize() - .multiplyScalar(-200); - scene.add(additionalDirectionalLight); - - csm = new CSM({ - maxFar: params.far, - cascades: 4, - mode: params.mode, - parent: scene, - shadowMapSize: 1024, - lightDirection: new THREE.Vector3(params.lightX, params.lightY, params.lightZ).normalize(), - camera: camera, - }); - - csmHelper = new CSMHelper(csm); - csmHelper.visible = false; - scene.add(csmHelper); - - const floorMaterial = new THREE.MeshPhongMaterial({ color: '#252a34' }); - csm.setupMaterial(floorMaterial); - - const floor = new THREE.Mesh(new THREE.PlaneGeometry(10000, 10000, 8, 8), floorMaterial); - floor.rotation.x = -Math.PI / 2; - floor.castShadow = true; - floor.receiveShadow = true; - scene.add(floor); - - const material1 = new THREE.MeshPhongMaterial({ color: '#08d9d6' }); - csm.setupMaterial(material1); - - const material2 = new THREE.MeshPhongMaterial({ color: '#ff2e63' }); - csm.setupMaterial(material2); - - const geometry = new THREE.BoxGeometry(10, 10, 10); - - for (let i = 0; i < 40; i++) { - const cube1 = new THREE.Mesh(geometry, i % 2 === 0 ? material1 : material2); - cube1.castShadow = true; - cube1.receiveShadow = true; - scene.add(cube1); - cube1.position.set(-i * 25, 20, 30); - cube1.scale.y = Math.random() * 2 + 6; - - const cube2 = new THREE.Mesh(geometry, i % 2 === 0 ? material2 : material1); - cube2.castShadow = true; - cube2.receiveShadow = true; - scene.add(cube2); - cube2.position.set(-i * 25, 20, -30); - cube2.scale.y = Math.random() * 2 + 6; - } - - const gui = new GUI(); - - gui.add(params, 'orthographic').onChange(function (value) { - csm.camera = value ? orthoCamera : camera; - csm.updateFrustums(); - }); - - gui.add(params, 'fade').onChange(function (value) { - csm.fade = value; - csm.updateFrustums(); - }); - - gui.add(params, 'shadows').onChange(function (value) { - renderer.shadowMap.enabled = value; - - scene.traverse(function (child) { - if (child.material) { - child.material.needsUpdate = true; - } - }); - }); - - gui.add(params, 'far', 1, 5000) - .step(1) - .name('shadow far') - .onChange(function (value) { - csm.maxFar = value; - csm.updateFrustums(); - }); - - gui.add(params, 'mode', ['uniform', 'logarithmic', 'practical']) - .name('frustum split mode') - .onChange(function (value) { - csm.mode = value; - csm.updateFrustums(); - }); - - gui.add(params, 'lightX', -1, 1) - .name('light direction x') - .onChange(function (value) { - csm.lightDirection.x = value; - }); - - gui.add(params, 'lightY', -1, 1) - .name('light direction y') - .onChange(function (value) { - csm.lightDirection.y = value; - }); - - gui.add(params, 'lightZ', -1, 1) - .name('light direction z') - .onChange(function (value) { - csm.lightDirection.z = value; - }); - - gui.add(params, 'margin', 0, 200) - .name('light margin') - .onChange(function (value) { - csm.lightMargin = value; - }); - - gui.add(params, 'lightNear', 1, 10000) - .name('light near') - .onChange(function (value) { - for (let i = 0; i < csm.lights.length; i++) { - csm.lights[i].shadow.camera.near = value; - csm.lights[i].shadow.camera.updateProjectionMatrix(); - } - }); - - gui.add(params, 'lightFar', 1, 10000) - .name('light far') - .onChange(function (value) { - for (let i = 0; i < csm.lights.length; i++) { - csm.lights[i].shadow.camera.far = value; - csm.lights[i].shadow.camera.updateProjectionMatrix(); - } - }); - - const helperFolder = gui.addFolder('helper'); - - helperFolder.add(csmHelper, 'visible'); - - helperFolder.add(csmHelper, 'displayFrustum').onChange(function () { - csmHelper.updateVisibility(); - }); - - helperFolder.add(csmHelper, 'displayPlanes').onChange(function () { - csmHelper.updateVisibility(); - }); - - helperFolder.add(csmHelper, 'displayShadowBounds').onChange(function () { - csmHelper.updateVisibility(); - }); - - helperFolder.add(params, 'autoUpdateHelper').name('auto update'); - - helperFolder.add(params, 'updateHelper').name('update'); - - helperFolder.open(); - - window.addEventListener('resize', function () { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - updateOrthoCamera(); - csm.updateFrustums(); - - renderer.setSize(window.innerWidth, window.innerHeight); - }); -} - -function animate() { - camera.updateMatrixWorld(); - csm.update(); - controls.update(); - - if (params.orthographic) { - updateOrthoCamera(); - csm.updateFrustums(); - - if (params.autoUpdateHelper) { - csmHelper.update(); - } - - renderer.render(scene, orthoCamera); - } else { - if (params.autoUpdateHelper) { - csmHelper.update(); - } - - renderer.render(scene, camera); - } -} diff --git a/examples-testing/examples/webgl_shadowmap_pcss.ts b/examples-testing/examples/webgl_shadowmap_pcss.ts deleted file mode 100644 index a47a011ff..000000000 --- a/examples-testing/examples/webgl_shadowmap_pcss.ts +++ /dev/null @@ -1,161 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let stats; -let camera, scene, renderer; - -let group; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - // scene - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0xcce0ff, 5, 100); - - // camera - - camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000); - - // We use this particular camera position in order to expose a bug that can sometimes happen presumably - // due to lack of precision when interpolating values over really large triangles. - // It reproduced on at least NVIDIA GTX 1080 and GTX 1050 Ti GPUs when the ground plane was not - // subdivided into segments. - camera.position.x = 7; - camera.position.y = 13; - camera.position.z = 7; - - scene.add(camera); - - // lights - - scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); - - const light = new THREE.DirectionalLight(0xf0f6ff, 4.5); - light.position.set(2, 8, 4); - - light.castShadow = true; - light.shadow.mapSize.width = 1024; - light.shadow.mapSize.height = 1024; - light.shadow.camera.far = 20; - - scene.add(light); - - // scene.add( new DirectionalLightHelper( light ) ); - scene.add(new THREE.CameraHelper(light.shadow.camera)); - - // group - - group = new THREE.Group(); - scene.add(group); - - const geometry = new THREE.SphereGeometry(0.3, 20, 20); - - for (let i = 0; i < 20; i++) { - const material = new THREE.MeshPhongMaterial({ color: Math.random() * 0xffffff }); - - const sphere = new THREE.Mesh(geometry, material); - sphere.position.x = Math.random() - 0.5; - sphere.position.z = Math.random() - 0.5; - sphere.position.normalize(); - sphere.position.multiplyScalar(Math.random() * 2 + 1); - sphere.castShadow = true; - sphere.receiveShadow = true; - sphere.userData.phase = Math.random() * Math.PI; - group.add(sphere); - } - - // ground - - const groundMaterial = new THREE.MeshPhongMaterial({ color: 0x898989 }); - - const ground = new THREE.Mesh(new THREE.PlaneGeometry(20000, 20000, 8, 8), groundMaterial); - ground.rotation.x = -Math.PI / 2; - ground.receiveShadow = true; - scene.add(ground); - - // column - - const column = new THREE.Mesh(new THREE.BoxGeometry(1, 4, 1), groundMaterial); - column.position.y = 2; - column.castShadow = true; - column.receiveShadow = true; - scene.add(column); - - // overwrite shadowmap code - - let shader = THREE.ShaderChunk.shadowmap_pars_fragment; - - shader = shader.replace( - '#ifdef USE_SHADOWMAP', - '#ifdef USE_SHADOWMAP' + document.getElementById('PCSS').textContent, - ); - - shader = shader.replace( - '#if defined( SHADOWMAP_TYPE_PCF )', - document.getElementById('PCSSGetShadow').textContent + '#if defined( SHADOWMAP_TYPE_PCF )', - ); - - THREE.ShaderChunk.shadowmap_pars_fragment = shader; - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.setClearColor(scene.fog.color); - - container.appendChild(renderer.domElement); - - renderer.shadowMap.enabled = true; - - // controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = Math.PI * 0.5; - controls.minDistance = 10; - controls.maxDistance = 75; - controls.target.set(0, 2.5, 0); - controls.update(); - - // performance monitor - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = performance.now() / 1000; - - group.traverse(function (child) { - if ('phase' in child.userData) { - child.position.y = Math.abs(Math.sin(time + child.userData.phase)) * 4 + 0.3; - } - }); - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_shadowmap_performance.ts b/examples-testing/examples/webgl_shadowmap_performance.ts deleted file mode 100644 index 0e45b63f9..000000000 --- a/examples-testing/examples/webgl_shadowmap_performance.ts +++ /dev/null @@ -1,281 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -const SHADOW_MAP_WIDTH = 2048, - SHADOW_MAP_HEIGHT = 1024; - -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; -const FLOOR = -250; - -const ANIMATION_GROUPS = 25; - -let camera, controls, scene, renderer; -let stats; - -const NEAR = 5, - FAR = 3000; - -let morph, mixer; - -const morphs = [], - animGroups = []; - -const clock = new THREE.Clock(); - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(23, SCREEN_WIDTH / SCREEN_HEIGHT, NEAR, FAR); - camera.position.set(700, 50, 1900); - - // SCENE - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x59472b); - scene.fog = new THREE.Fog(0x59472b, 1000, FAR); - - // LIGHTS - - const ambient = new THREE.AmbientLight(0xffffff); - scene.add(ambient); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 1500, 1000); - light.castShadow = true; - light.shadow.camera.top = 2000; - light.shadow.camera.bottom = -2000; - light.shadow.camera.left = -2000; - light.shadow.camera.right = 2000; - light.shadow.camera.near = 1200; - light.shadow.camera.far = 2500; - light.shadow.bias = 0.0001; - - light.shadow.mapSize.width = SHADOW_MAP_WIDTH; - light.shadow.mapSize.height = SHADOW_MAP_HEIGHT; - - scene.add(light); - - createScene(); - - // RENDERER - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - renderer.autoClear = false; - - // - - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFSoftShadowMap; - - // CONTROLS - - controls = new FirstPersonControls(camera, renderer.domElement); - - controls.lookSpeed = 0.0125; - controls.movementSpeed = 500; - controls.lookVertical = true; - - controls.lookAt(scene.position); - - // STATS - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - controls.handleResize(); -} - -function createScene() { - // GROUND - - const geometry = new THREE.PlaneGeometry(100, 100); - const planeMaterial = new THREE.MeshPhongMaterial({ color: 0xffdd99 }); - - const ground = new THREE.Mesh(geometry, planeMaterial); - - ground.position.set(0, FLOOR, 0); - ground.rotation.x = -Math.PI / 2; - ground.scale.set(100, 100, 100); - - ground.castShadow = false; - ground.receiveShadow = true; - - scene.add(ground); - - // TEXT - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_bold.typeface.json', function (font) { - const textGeo = new TextGeometry('THREE.JS', { - font: font, - - size: 200, - depth: 50, - curveSegments: 12, - - bevelThickness: 2, - bevelSize: 5, - bevelEnabled: true, - }); - - textGeo.computeBoundingBox(); - const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x); - - const textMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000, specular: 0xffffff }); - - const mesh = new THREE.Mesh(textGeo, textMaterial); - mesh.position.x = centerOffset; - mesh.position.y = FLOOR + 67; - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - }); - - // CUBES - - const cubes1 = new THREE.Mesh(new THREE.BoxGeometry(1500, 220, 150), planeMaterial); - - cubes1.position.y = FLOOR - 50; - cubes1.position.z = 20; - - cubes1.castShadow = true; - cubes1.receiveShadow = true; - - scene.add(cubes1); - - const cubes2 = new THREE.Mesh(new THREE.BoxGeometry(1600, 170, 250), planeMaterial); - - cubes2.position.y = FLOOR - 50; - cubes2.position.z = 20; - - cubes2.castShadow = true; - cubes2.receiveShadow = true; - - scene.add(cubes2); - - mixer = new THREE.AnimationMixer(scene); - - for (let i = 0; i !== ANIMATION_GROUPS; ++i) { - const group = new THREE.AnimationObjectGroup(); - animGroups.push(group); - } - - // MORPHS - - function addMorph(mesh, clip, speed, duration, x, y, z, fudgeColor, massOptimization) { - mesh = mesh.clone(); - mesh.material = mesh.material.clone(); - - if (fudgeColor) { - mesh.material.color.offsetHSL(0, Math.random() * 0.5 - 0.25, Math.random() * 0.5 - 0.25); - } - - mesh.speed = speed; - - if (massOptimization) { - const index = Math.floor(Math.random() * ANIMATION_GROUPS), - animGroup = animGroups[index]; - - animGroup.add(mesh); - - if (!mixer.existingAction(clip, animGroup)) { - const randomness = 0.6 * Math.random() - 0.3; - const phase = (index + randomness) / ANIMATION_GROUPS; - - mixer - .clipAction(clip, animGroup) - .setDuration(duration) - .startAt(-duration * phase) - .play(); - } - } else { - mixer - .clipAction(clip, mesh) - .setDuration(duration) - .startAt(-duration * Math.random()) - .play(); - } - - mesh.position.set(x, y, z); - mesh.rotation.y = Math.PI / 2; - - mesh.castShadow = true; - mesh.receiveShadow = true; - - scene.add(mesh); - - morphs.push(mesh); - } - - const gltfLoader = new GLTFLoader(); - gltfLoader.load('models/gltf/Horse.glb', function (gltf) { - const mesh = gltf.scene.children[0]; - const clip = gltf.animations[0]; - - for (let i = -600; i < 601; i += 2) { - addMorph(mesh, clip, 550, 1, 100 - Math.random() * 3000, FLOOR, i, true, true); - } - }); -} - -// - -function animate() { - stats.begin(); - render(); - stats.end(); -} - -function render() { - const delta = clock.getDelta(); - - if (mixer) mixer.update(delta); - - for (let i = 0; i < morphs.length; i++) { - morph = morphs[i]; - - morph.position.x += morph.speed * delta; - - if (morph.position.x > 2000) { - morph.position.x = -1000 - Math.random() * 500; - } - } - - controls.update(delta); - - renderer.clear(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_shadowmap_pointlight.ts b/examples-testing/examples/webgl_shadowmap_pointlight.ts deleted file mode 100644 index c68d69749..000000000 --- a/examples-testing/examples/webgl_shadowmap_pointlight.ts +++ /dev/null @@ -1,139 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, stats; -let pointLight, pointLight2; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 10, 40); - - scene = new THREE.Scene(); - scene.add(new THREE.AmbientLight(0x111122, 3)); - - // lights - - function createLight(color) { - const intensity = 200; - - const light = new THREE.PointLight(color, intensity, 20); - light.castShadow = true; - light.shadow.bias = -0.005; // reduces self-shadowing on double-sided objects - - let geometry = new THREE.SphereGeometry(0.3, 12, 6); - let material = new THREE.MeshBasicMaterial({ color: color }); - material.color.multiplyScalar(intensity); - let sphere = new THREE.Mesh(geometry, material); - light.add(sphere); - - const texture = new THREE.CanvasTexture(generateTexture()); - texture.magFilter = THREE.NearestFilter; - texture.wrapT = THREE.RepeatWrapping; - texture.wrapS = THREE.RepeatWrapping; - texture.repeat.set(1, 4.5); - - geometry = new THREE.SphereGeometry(2, 32, 8); - material = new THREE.MeshPhongMaterial({ - side: THREE.DoubleSide, - alphaMap: texture, - alphaTest: 0.5, - }); - - sphere = new THREE.Mesh(geometry, material); - sphere.castShadow = true; - sphere.receiveShadow = true; - light.add(sphere); - - return light; - } - - pointLight = createLight(0x0088ff); - scene.add(pointLight); - - pointLight2 = createLight(0xff8888); - scene.add(pointLight2); - // - - const geometry = new THREE.BoxGeometry(30, 30, 30); - - const material = new THREE.MeshPhongMaterial({ - color: 0xa0adaf, - shininess: 10, - specular: 0x111111, - side: THREE.BackSide, - }); - - const mesh = new THREE.Mesh(geometry, material); - mesh.position.y = 10; - mesh.receiveShadow = true; - scene.add(mesh); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.BasicShadowMap; - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 10, 0); - controls.update(); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function generateTexture() { - const canvas = document.createElement('canvas'); - canvas.width = 2; - canvas.height = 2; - - const context = canvas.getContext('2d'); - context.fillStyle = 'white'; - context.fillRect(0, 1, 2, 1); - - return canvas; -} - -function animate() { - let time = performance.now() * 0.001; - - pointLight.position.x = Math.sin(time * 0.6) * 9; - pointLight.position.y = Math.sin(time * 0.7) * 9 + 6; - pointLight.position.z = Math.sin(time * 0.8) * 9; - - pointLight.rotation.x = time; - pointLight.rotation.z = time; - - time += 10000; - - pointLight2.position.x = Math.sin(time * 0.6) * 9; - pointLight2.position.y = Math.sin(time * 0.7) * 9 + 6; - pointLight2.position.z = Math.sin(time * 0.8) * 9; - - pointLight2.rotation.x = time; - pointLight2.rotation.z = time; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_shadowmap_progressive.ts b/examples-testing/examples/webgl_shadowmap_progressive.ts deleted file mode 100644 index e9f6b5b91..000000000 --- a/examples-testing/examples/webgl_shadowmap_progressive.ts +++ /dev/null @@ -1,204 +0,0 @@ -import * as THREE from 'three'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { TransformControls } from 'three/addons/controls/TransformControls.js'; -import { ProgressiveLightMap } from 'three/addons/misc/ProgressiveLightMap.js'; - -// ShadowMap + LightMap Res and Number of Directional Lights -const shadowMapRes = 512, - lightMapRes = 1024, - lightCount = 8; -let camera, - scene, - renderer, - controls, - control, - control2, - object = new THREE.Mesh(), - lightOrigin = null, - progressiveSurfacemap; -const dirLights = [], - lightmapObjects = []; -const params = { - Enable: true, - 'Blur Edges': true, - 'Blend Window': 200, - 'Light Radius': 50, - 'Ambient Weight': 0.5, - 'Debug Lightmap': false, -}; -init(); -createGUI(); - -function init() { - // renderer - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - document.body.appendChild(renderer.domElement); - - // camera - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 100, 200); - camera.name = 'Camera'; - - // scene - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x949494); - scene.fog = new THREE.Fog(0x949494, 1000, 3000); - - // progressive lightmap - progressiveSurfacemap = new ProgressiveLightMap(renderer, lightMapRes); - - // directional lighting "origin" - lightOrigin = new THREE.Group(); - lightOrigin.position.set(60, 150, 100); - scene.add(lightOrigin); - - // transform gizmo - control = new TransformControls(camera, renderer.domElement); - control.addEventListener('dragging-changed', event => { - controls.enabled = !event.value; - }); - control.attach(lightOrigin); - scene.add(control.getHelper()); - - // create 8 directional lights to speed up the convergence - for (let l = 0; l < lightCount; l++) { - const dirLight = new THREE.DirectionalLight(0xffffff, 1.0 / lightCount); - dirLight.name = 'Dir. Light ' + l; - dirLight.position.set(200, 200, 200); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 100; - dirLight.shadow.camera.far = 5000; - dirLight.shadow.camera.right = 150; - dirLight.shadow.camera.left = -150; - dirLight.shadow.camera.top = 150; - dirLight.shadow.camera.bottom = -150; - dirLight.shadow.mapSize.width = shadowMapRes; - dirLight.shadow.mapSize.height = shadowMapRes; - lightmapObjects.push(dirLight); - dirLights.push(dirLight); - } - - // ground - const groundMesh = new THREE.Mesh( - new THREE.PlaneGeometry(600, 600), - new THREE.MeshPhongMaterial({ color: 0xffffff, depthWrite: true }), - ); - groundMesh.position.y = -0.1; - groundMesh.rotation.x = -Math.PI / 2; - groundMesh.name = 'Ground Mesh'; - lightmapObjects.push(groundMesh); - scene.add(groundMesh); - - // model - function loadModel() { - object.traverse(function (child) { - if (child.isMesh) { - child.name = 'Loaded Mesh'; - child.castShadow = true; - child.receiveShadow = true; - child.material = new THREE.MeshPhongMaterial(); - - // This adds the model to the lightmap - lightmapObjects.push(child); - progressiveSurfacemap.addObjectsToLightMap(lightmapObjects); - } else { - child.layers.disableAll(); // Disable Rendering for this - } - }); - scene.add(object); - object.scale.set(2, 2, 2); - object.position.set(0, -16, 0); - control2 = new TransformControls(camera, renderer.domElement); - control2.addEventListener('dragging-changed', event => { - controls.enabled = !event.value; - }); - control2.attach(object); - scene.add(control2.getHelper()); - const lightTarget = new THREE.Group(); - lightTarget.position.set(0, 20, 0); - for (let l = 0; l < dirLights.length; l++) { - dirLights[l].target = lightTarget; - } - - object.add(lightTarget); - } - - const manager = new THREE.LoadingManager(loadModel); - const loader = new GLTFLoader(manager); - loader.load('models/gltf/ShadowmappableMesh.glb', function (obj) { - object = obj.scene.children[0]; - }); - - // controls - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled - controls.dampingFactor = 0.05; - controls.screenSpacePanning = true; - controls.minDistance = 100; - controls.maxDistance = 500; - controls.maxPolarAngle = Math.PI / 1.5; - controls.target.set(0, 100, 0); - - window.addEventListener('resize', onWindowResize); -} - -function createGUI() { - const gui = new GUI({ title: 'Accumulation Settings' }); - gui.add(params, 'Enable'); - gui.add(params, 'Blur Edges'); - gui.add(params, 'Blend Window', 1, 500).step(1); - gui.add(params, 'Light Radius', 0, 200).step(10); - gui.add(params, 'Ambient Weight', 0, 1).step(0.1); - gui.add(params, 'Debug Lightmap'); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - // Update the inertia on the orbit controls - controls.update(); - - // Accumulate Surface Maps - if (params['Enable']) { - progressiveSurfacemap.update(camera, params['Blend Window'], params['Blur Edges']); - - if (!progressiveSurfacemap.firstUpdate) { - progressiveSurfacemap.showDebugLightmap(params['Debug Lightmap']); - } - } - - // Manually Update the Directional Lights - for (let l = 0; l < dirLights.length; l++) { - // Sometimes they will be sampled from the target direction - // Sometimes they will be uniformly sampled from the upper hemisphere - if (Math.random() > params['Ambient Weight']) { - dirLights[l].position.set( - lightOrigin.position.x + Math.random() * params['Light Radius'], - lightOrigin.position.y + Math.random() * params['Light Radius'], - lightOrigin.position.z + Math.random() * params['Light Radius'], - ); - } else { - // Uniform Hemispherical Surface Distribution for Ambient Occlusion - const lambda = Math.acos(2 * Math.random() - 1) - 3.14159 / 2.0; - const phi = 2 * 3.14159 * Math.random(); - dirLights[l].position.set( - Math.cos(lambda) * Math.cos(phi) * 300 + object.position.x, - Math.abs(Math.cos(lambda) * Math.sin(phi) * 300) + object.position.y + 20, - Math.sin(lambda) * 300 + object.position.z, - ); - } - } - - // Render Scene - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_shadowmap_viewer.ts b/examples-testing/examples/webgl_shadowmap_viewer.ts deleted file mode 100644 index f974ef038..000000000 --- a/examples-testing/examples/webgl_shadowmap_viewer.ts +++ /dev/null @@ -1,178 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ShadowMapViewer } from 'three/addons/utils/ShadowMapViewer.js'; - -let camera, scene, renderer, clock, stats; -let dirLight, spotLight; -let torusKnot, cube; -let dirLightShadowMapViewer, spotLightShadowMapViewer; - -init(); - -function init() { - initScene(); - initShadowMapViewers(); - initMisc(); - - document.body.appendChild(renderer.domElement); - window.addEventListener('resize', onWindowResize); -} - -function initScene() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 15, 35); - - scene = new THREE.Scene(); - - // Lights - - scene.add(new THREE.AmbientLight(0x404040, 3)); - - spotLight = new THREE.SpotLight(0xffffff, 500); - spotLight.name = 'Spot Light'; - spotLight.angle = Math.PI / 5; - spotLight.penumbra = 0.3; - spotLight.position.set(10, 10, 5); - spotLight.castShadow = true; - spotLight.shadow.camera.near = 8; - spotLight.shadow.camera.far = 30; - spotLight.shadow.mapSize.width = 1024; - spotLight.shadow.mapSize.height = 1024; - scene.add(spotLight); - - scene.add(new THREE.CameraHelper(spotLight.shadow.camera)); - - dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.name = 'Dir. Light'; - dirLight.position.set(0, 10, 0); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 1; - dirLight.shadow.camera.far = 10; - dirLight.shadow.camera.right = 15; - dirLight.shadow.camera.left = -15; - dirLight.shadow.camera.top = 15; - dirLight.shadow.camera.bottom = -15; - dirLight.shadow.mapSize.width = 1024; - dirLight.shadow.mapSize.height = 1024; - scene.add(dirLight); - - scene.add(new THREE.CameraHelper(dirLight.shadow.camera)); - - // Geometry - let geometry = new THREE.TorusKnotGeometry(25, 8, 75, 20); - let material = new THREE.MeshPhongMaterial({ - color: 0xff0000, - shininess: 150, - specular: 0x222222, - }); - - torusKnot = new THREE.Mesh(geometry, material); - torusKnot.scale.multiplyScalar(1 / 18); - torusKnot.position.y = 3; - torusKnot.castShadow = true; - torusKnot.receiveShadow = true; - scene.add(torusKnot); - - geometry = new THREE.BoxGeometry(3, 3, 3); - cube = new THREE.Mesh(geometry, material); - cube.position.set(8, 3, 8); - cube.castShadow = true; - cube.receiveShadow = true; - scene.add(cube); - - geometry = new THREE.BoxGeometry(10, 0.15, 10); - material = new THREE.MeshPhongMaterial({ - color: 0xa0adaf, - shininess: 150, - specular: 0x111111, - }); - - const ground = new THREE.Mesh(geometry, material); - ground.scale.multiplyScalar(3); - ground.castShadow = false; - ground.receiveShadow = true; - scene.add(ground); -} - -function initShadowMapViewers() { - dirLightShadowMapViewer = new ShadowMapViewer(dirLight); - spotLightShadowMapViewer = new ShadowMapViewer(spotLight); - resizeShadowMapViewers(); -} - -function initMisc() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.BasicShadowMap; - - // Mouse control - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 2, 0); - controls.update(); - - clock = new THREE.Clock(); - - stats = new Stats(); - document.body.appendChild(stats.dom); -} - -function resizeShadowMapViewers() { - const size = window.innerWidth * 0.15; - - dirLightShadowMapViewer.position.x = 10; - dirLightShadowMapViewer.position.y = 10; - dirLightShadowMapViewer.size.width = size; - dirLightShadowMapViewer.size.height = size; - dirLightShadowMapViewer.update(); //Required when setting position or size directly - - spotLightShadowMapViewer.size.set(size, size); - spotLightShadowMapViewer.position.set(size + 20, 10); - // spotLightShadowMapViewer.update(); //NOT required because .set updates automatically -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - resizeShadowMapViewers(); - dirLightShadowMapViewer.updateForWindowResize(); - spotLightShadowMapViewer.updateForWindowResize(); -} - -function animate() { - render(); - - stats.update(); -} - -function renderScene() { - renderer.render(scene, camera); -} - -function renderShadowMapViewers() { - dirLightShadowMapViewer.render(renderer); - spotLightShadowMapViewer.render(renderer); -} - -function render() { - const delta = clock.getDelta(); - - renderScene(); - renderShadowMapViewers(); - - torusKnot.rotation.x += 0.25 * delta; - torusKnot.rotation.y += 2 * delta; - torusKnot.rotation.z += 1 * delta; - - cube.rotation.x += 0.25 * delta; - cube.rotation.y += 2 * delta; - cube.rotation.z += 1 * delta; -} diff --git a/examples-testing/examples/webgl_shadowmap_vsm.ts b/examples-testing/examples/webgl_shadowmap_vsm.ts deleted file mode 100644 index 4867c7315..000000000 --- a/examples-testing/examples/webgl_shadowmap_vsm.ts +++ /dev/null @@ -1,200 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, clock, stats; -let dirLight, spotLight; -let torusKnot, dirGroup; - -init(); - -function init() { - initScene(); - initMisc(); - - // Init gui - const gui = new GUI(); - - const config = { - spotlightRadius: 4, - spotlightSamples: 8, - dirlightRadius: 4, - dirlightSamples: 8, - }; - - const spotlightFolder = gui.addFolder('Spotlight'); - spotlightFolder - .add(config, 'spotlightRadius') - .name('radius') - .min(0) - .max(25) - .onChange(function (value) { - spotLight.shadow.radius = value; - }); - - spotlightFolder - .add(config, 'spotlightSamples', 1, 25, 1) - .name('samples') - .onChange(function (value) { - spotLight.shadow.blurSamples = value; - }); - spotlightFolder.open(); - - const dirlightFolder = gui.addFolder('Directional Light'); - dirlightFolder - .add(config, 'dirlightRadius') - .name('radius') - .min(0) - .max(25) - .onChange(function (value) { - dirLight.shadow.radius = value; - }); - - dirlightFolder - .add(config, 'dirlightSamples', 1, 25, 1) - .name('samples') - .onChange(function (value) { - dirLight.shadow.blurSamples = value; - }); - dirlightFolder.open(); - - document.body.appendChild(renderer.domElement); - window.addEventListener('resize', onWindowResize); -} - -function initScene() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 10, 30); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x222244); - scene.fog = new THREE.Fog(0x222244, 50, 100); - - // Lights - - scene.add(new THREE.AmbientLight(0x444444)); - - spotLight = new THREE.SpotLight(0xff8888, 400); - spotLight.angle = Math.PI / 5; - spotLight.penumbra = 0.3; - spotLight.position.set(8, 10, 5); - spotLight.castShadow = true; - spotLight.shadow.camera.near = 8; - spotLight.shadow.camera.far = 200; - spotLight.shadow.mapSize.width = 256; - spotLight.shadow.mapSize.height = 256; - spotLight.shadow.bias = -0.002; - spotLight.shadow.radius = 4; - scene.add(spotLight); - - dirLight = new THREE.DirectionalLight(0x8888ff, 3); - dirLight.position.set(3, 12, 17); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 0.1; - dirLight.shadow.camera.far = 500; - dirLight.shadow.camera.right = 17; - dirLight.shadow.camera.left = -17; - dirLight.shadow.camera.top = 17; - dirLight.shadow.camera.bottom = -17; - dirLight.shadow.mapSize.width = 512; - dirLight.shadow.mapSize.height = 512; - dirLight.shadow.radius = 4; - dirLight.shadow.bias = -0.0005; - - dirGroup = new THREE.Group(); - dirGroup.add(dirLight); - scene.add(dirGroup); - - // Geometry - - const geometry = new THREE.TorusKnotGeometry(25, 8, 75, 20); - const material = new THREE.MeshPhongMaterial({ - color: 0x999999, - shininess: 0, - specular: 0x222222, - }); - - torusKnot = new THREE.Mesh(geometry, material); - torusKnot.scale.multiplyScalar(1 / 18); - torusKnot.position.y = 3; - torusKnot.castShadow = true; - torusKnot.receiveShadow = true; - scene.add(torusKnot); - - const cylinderGeometry = new THREE.CylinderGeometry(0.75, 0.75, 7, 32); - - const pillar1 = new THREE.Mesh(cylinderGeometry, material); - pillar1.position.set(8, 3.5, 8); - pillar1.castShadow = true; - pillar1.receiveShadow = true; - - const pillar2 = pillar1.clone(); - pillar2.position.set(8, 3.5, -8); - const pillar3 = pillar1.clone(); - pillar3.position.set(-8, 3.5, 8); - const pillar4 = pillar1.clone(); - pillar4.position.set(-8, 3.5, -8); - - scene.add(pillar1); - scene.add(pillar2); - scene.add(pillar3); - scene.add(pillar4); - - const planeGeometry = new THREE.PlaneGeometry(200, 200); - const planeMaterial = new THREE.MeshPhongMaterial({ - color: 0x999999, - shininess: 0, - specular: 0x111111, - }); - - const ground = new THREE.Mesh(planeGeometry, planeMaterial); - ground.rotation.x = -Math.PI / 2; - ground.scale.multiplyScalar(3); - ground.castShadow = true; - ground.receiveShadow = true; - scene.add(ground); -} - -function initMisc() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.VSMShadowMap; - - // Mouse control - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 2, 0); - controls.update(); - - clock = new THREE.Clock(); - - stats = new Stats(); - document.body.appendChild(stats.dom); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate(time) { - const delta = clock.getDelta(); - - torusKnot.rotation.x += 0.25 * delta; - torusKnot.rotation.y += 0.5 * delta; - torusKnot.rotation.z += 1 * delta; - - dirGroup.rotation.y += 0.7 * delta; - dirLight.position.z = 17 + Math.sin(time * 0.001) * 5; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_shadowmesh.ts b/examples-testing/examples/webgl_shadowmesh.ts deleted file mode 100644 index 412fc0283..000000000 --- a/examples-testing/examples/webgl_shadowmesh.ts +++ /dev/null @@ -1,250 +0,0 @@ -import * as THREE from 'three'; - -import { ShadowMesh } from 'three/addons/objects/ShadowMesh.js'; - -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; - -const scene = new THREE.Scene(); -const camera = new THREE.PerspectiveCamera(55, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 3000); -const clock = new THREE.Clock(); -const renderer = new THREE.WebGLRenderer({ stencil: true }); - -const sunLight = new THREE.DirectionalLight('rgb(255,255,255)', 3); -let useDirectionalLight = true; -let arrowHelper1, arrowHelper2, arrowHelper3; -const arrowDirection = new THREE.Vector3(); -const arrowPosition1 = new THREE.Vector3(); -const arrowPosition2 = new THREE.Vector3(); -const arrowPosition3 = new THREE.Vector3(); -let groundMesh; -let lightSphere, lightHolder; -let pyramid, pyramidShadow; -let sphere, sphereShadow; -let cube, cubeShadow; -let cylinder, cylinderShadow; -let torus, torusShadow; -const normalVector = new THREE.Vector3(0, 1, 0); -const planeConstant = 0.01; // this value must be slightly higher than the groundMesh's y position of 0.0 -const groundPlane = new THREE.Plane(normalVector, planeConstant); -const lightPosition4D = new THREE.Vector4(); -let verticalAngle = 0; -let horizontalAngle = 0; -let frameTime = 0; -const TWO_PI = Math.PI * 2; - -init(); - -function init() { - scene.background = new THREE.Color(0x0096ff); - - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - document.getElementById('container').appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - camera.position.set(0, 2.5, 10); - scene.add(camera); - onWindowResize(); - - sunLight.position.set(5, 7, -1); - sunLight.lookAt(scene.position); - scene.add(sunLight); - - lightPosition4D.x = sunLight.position.x; - lightPosition4D.y = sunLight.position.y; - lightPosition4D.z = sunLight.position.z; - // amount of light-ray divergence. Ranging from: - // 0.001 = sunlight(min divergence) to 1.0 = pointlight(max divergence) - lightPosition4D.w = 0.001; // must be slightly greater than 0, due to 0 causing matrixInverse errors - - // YELLOW ARROW HELPERS - arrowDirection.subVectors(scene.position, sunLight.position).normalize(); - - arrowPosition1.copy(sunLight.position); - arrowHelper1 = new THREE.ArrowHelper(arrowDirection, arrowPosition1, 0.9, 0xffff00, 0.25, 0.08); - scene.add(arrowHelper1); - - arrowPosition2.copy(sunLight.position).add(new THREE.Vector3(0, 0.2, 0)); - arrowHelper2 = new THREE.ArrowHelper(arrowDirection, arrowPosition2, 0.9, 0xffff00, 0.25, 0.08); - scene.add(arrowHelper2); - - arrowPosition3.copy(sunLight.position).add(new THREE.Vector3(0, -0.2, 0)); - arrowHelper3 = new THREE.ArrowHelper(arrowDirection, arrowPosition3, 0.9, 0xffff00, 0.25, 0.08); - scene.add(arrowHelper3); - - // LIGHTBULB - const lightSphereGeometry = new THREE.SphereGeometry(0.09); - const lightSphereMaterial = new THREE.MeshBasicMaterial({ color: 'rgb(255,255,255)' }); - lightSphere = new THREE.Mesh(lightSphereGeometry, lightSphereMaterial); - scene.add(lightSphere); - lightSphere.visible = false; - - const lightHolderGeometry = new THREE.CylinderGeometry(0.05, 0.05, 0.13); - const lightHolderMaterial = new THREE.MeshBasicMaterial({ color: 'rgb(75,75,75)' }); - lightHolder = new THREE.Mesh(lightHolderGeometry, lightHolderMaterial); - scene.add(lightHolder); - lightHolder.visible = false; - - // GROUND - const groundGeometry = new THREE.BoxGeometry(30, 0.01, 40); - const groundMaterial = new THREE.MeshLambertMaterial({ color: 'rgb(0,130,0)' }); - groundMesh = new THREE.Mesh(groundGeometry, groundMaterial); - groundMesh.position.y = 0.0; //this value must be slightly lower than the planeConstant (0.01) parameter above - scene.add(groundMesh); - - // RED CUBE and CUBE's SHADOW - const cubeGeometry = new THREE.BoxGeometry(1, 1, 1); - const cubeMaterial = new THREE.MeshLambertMaterial({ color: 'rgb(255,0,0)', emissive: 0x200000 }); - cube = new THREE.Mesh(cubeGeometry, cubeMaterial); - cube.position.z = -1; - scene.add(cube); - - cubeShadow = new ShadowMesh(cube); - scene.add(cubeShadow); - - // BLUE CYLINDER and CYLINDER's SHADOW - const cylinderGeometry = new THREE.CylinderGeometry(0.3, 0.3, 2); - const cylinderMaterial = new THREE.MeshPhongMaterial({ color: 'rgb(0,0,255)', emissive: 0x000020 }); - cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial); - cylinder.position.z = -2.5; - scene.add(cylinder); - - cylinderShadow = new ShadowMesh(cylinder); - scene.add(cylinderShadow); - - // MAGENTA TORUS and TORUS' SHADOW - const torusGeometry = new THREE.TorusGeometry(1, 0.2, 10, 16, TWO_PI); - const torusMaterial = new THREE.MeshPhongMaterial({ color: 'rgb(255,0,255)', emissive: 0x200020 }); - torus = new THREE.Mesh(torusGeometry, torusMaterial); - torus.position.z = -6; - scene.add(torus); - - torusShadow = new ShadowMesh(torus); - scene.add(torusShadow); - - // WHITE SPHERE and SPHERE'S SHADOW - const sphereGeometry = new THREE.SphereGeometry(0.5, 20, 10); - const sphereMaterial = new THREE.MeshPhongMaterial({ color: 'rgb(255,255,255)', emissive: 0x222222 }); - sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - sphere.position.set(4, 0.5, 2); - scene.add(sphere); - - sphereShadow = new ShadowMesh(sphere); - scene.add(sphereShadow); - - // YELLOW PYRAMID and PYRAMID'S SHADOW - const pyramidGeometry = new THREE.CylinderGeometry(0, 0.5, 2, 4); - const pyramidMaterial = new THREE.MeshPhongMaterial({ - color: 'rgb(255,255,0)', - emissive: 0x440000, - flatShading: true, - shininess: 0, - }); - pyramid = new THREE.Mesh(pyramidGeometry, pyramidMaterial); - pyramid.position.set(-4, 1, 2); - scene.add(pyramid); - - pyramidShadow = new ShadowMesh(pyramid); - scene.add(pyramidShadow); - - document.getElementById('lightButton').addEventListener('click', lightButtonHandler); -} - -function animate() { - frameTime = clock.getDelta(); - - cube.rotation.x += 1.0 * frameTime; - cube.rotation.y += 1.0 * frameTime; - - cylinder.rotation.y += 1.0 * frameTime; - cylinder.rotation.z -= 1.0 * frameTime; - - torus.rotation.x -= 1.0 * frameTime; - torus.rotation.y -= 1.0 * frameTime; - - pyramid.rotation.y += 0.5 * frameTime; - - horizontalAngle += 0.5 * frameTime; - if (horizontalAngle > TWO_PI) horizontalAngle -= TWO_PI; - cube.position.x = Math.sin(horizontalAngle) * 4; - cylinder.position.x = Math.sin(horizontalAngle) * -4; - torus.position.x = Math.cos(horizontalAngle) * 4; - - verticalAngle += 1.5 * frameTime; - if (verticalAngle > TWO_PI) verticalAngle -= TWO_PI; - cube.position.y = Math.sin(verticalAngle) * 2 + 2.9; - cylinder.position.y = Math.sin(verticalAngle) * 2 + 3.1; - torus.position.y = Math.cos(verticalAngle) * 2 + 3.3; - - // update the ShadowMeshes to follow their shadow-casting objects - cubeShadow.update(groundPlane, lightPosition4D); - cylinderShadow.update(groundPlane, lightPosition4D); - torusShadow.update(groundPlane, lightPosition4D); - sphereShadow.update(groundPlane, lightPosition4D); - pyramidShadow.update(groundPlane, lightPosition4D); - - renderer.render(scene, camera); -} - -function onWindowResize() { - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - - camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT; - camera.updateProjectionMatrix(); -} - -function lightButtonHandler() { - useDirectionalLight = !useDirectionalLight; - - if (useDirectionalLight) { - scene.background.setHex(0x0096ff); - - groundMesh.material.color.setHex(0x008200); - sunLight.position.set(5, 7, -1); - sunLight.lookAt(scene.position); - - lightPosition4D.x = sunLight.position.x; - lightPosition4D.y = sunLight.position.y; - lightPosition4D.z = sunLight.position.z; - lightPosition4D.w = 0.001; // more of a directional Light value - - arrowHelper1.visible = true; - arrowHelper2.visible = true; - arrowHelper3.visible = true; - - lightSphere.visible = false; - lightHolder.visible = false; - - document.getElementById('lightButton').value = 'Switch to PointLight'; - } else { - scene.background.setHex(0x000000); - - groundMesh.material.color.setHex(0x969696); - - sunLight.position.set(0, 6, -2); - sunLight.lookAt(scene.position); - lightSphere.position.copy(sunLight.position); - lightHolder.position.copy(lightSphere.position); - lightHolder.position.y += 0.12; - - lightPosition4D.x = sunLight.position.x; - lightPosition4D.y = sunLight.position.y; - lightPosition4D.z = sunLight.position.z; - lightPosition4D.w = 0.9; // more of a point Light value - - arrowHelper1.visible = false; - arrowHelper2.visible = false; - arrowHelper3.visible = false; - - lightSphere.visible = true; - lightHolder.visible = true; - - document.getElementById('lightButton').value = 'Switch to THREE.DirectionalLight'; - } -} diff --git a/examples-testing/examples/webgl_simple_gi.ts b/examples-testing/examples/webgl_simple_gi.ts deleted file mode 100644 index 4ab6dc895..000000000 --- a/examples-testing/examples/webgl_simple_gi.ts +++ /dev/null @@ -1,172 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -class GIMesh extends THREE.Mesh { - copy(source) { - super.copy(source); - - this.geometry = source.geometry.clone(); - - return this; - } -} - -// - -const SimpleGI = function (renderer, scene) { - const SIZE = 32, - SIZE2 = SIZE * SIZE; - - const camera = new THREE.PerspectiveCamera(90, 1, 0.01, 100); - - scene.updateMatrixWorld(true); - - let clone = scene.clone(); - clone.matrixWorldAutoUpdate = false; - - const rt = new THREE.WebGLRenderTarget(SIZE, SIZE); - - const normalMatrix = new THREE.Matrix3(); - - const position = new THREE.Vector3(); - const normal = new THREE.Vector3(); - - let bounces = 0; - let currentVertex = 0; - - const color = new Float32Array(3); - const buffer = new Uint8Array(SIZE2 * 4); - - function compute() { - if (bounces === 3) return; - - const object = scene.children[0]; // torusKnot - const geometry = object.geometry; - - const attributes = geometry.attributes; - const positions = attributes.position.array; - const normals = attributes.normal.array; - - if (attributes.color === undefined) { - const colors = new Float32Array(positions.length); - geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3).setUsage(THREE.DynamicDrawUsage)); - } - - const colors = attributes.color.array; - - const startVertex = currentVertex; - const totalVertex = positions.length / 3; - - for (let i = 0; i < 32; i++) { - if (currentVertex >= totalVertex) break; - - position.fromArray(positions, currentVertex * 3); - position.applyMatrix4(object.matrixWorld); - - normal.fromArray(normals, currentVertex * 3); - normal.applyMatrix3(normalMatrix.getNormalMatrix(object.matrixWorld)).normalize(); - - camera.position.copy(position); - camera.lookAt(position.add(normal)); - - renderer.setRenderTarget(rt); - renderer.render(clone, camera); - - renderer.readRenderTargetPixels(rt, 0, 0, SIZE, SIZE, buffer); - - color[0] = 0; - color[1] = 0; - color[2] = 0; - - for (let k = 0, kl = buffer.length; k < kl; k += 4) { - color[0] += buffer[k + 0]; - color[1] += buffer[k + 1]; - color[2] += buffer[k + 2]; - } - - colors[currentVertex * 3 + 0] = color[0] / (SIZE2 * 255); - colors[currentVertex * 3 + 1] = color[1] / (SIZE2 * 255); - colors[currentVertex * 3 + 2] = color[2] / (SIZE2 * 255); - - currentVertex++; - } - - attributes.color.addUpdateRange(startVertex * 3, (currentVertex - startVertex) * 3); - attributes.color.needsUpdate = true; - - if (currentVertex >= totalVertex) { - clone = scene.clone(); - clone.matrixWorldAutoUpdate = false; - - bounces++; - currentVertex = 0; - } - - requestAnimationFrame(compute); - } - - requestAnimationFrame(compute); -}; - -// - -let camera, scene, renderer; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 4; - - scene = new THREE.Scene(); - - // torus knot - - const torusGeometry = new THREE.TorusKnotGeometry(0.75, 0.3, 128, 32, 1); - const material = new THREE.MeshBasicMaterial({ vertexColors: true }); - - const torusKnot = new GIMesh(torusGeometry, material); - scene.add(torusKnot); - - // room - - const materials = []; - - for (let i = 0; i < 8; i++) { - materials.push(new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, side: THREE.BackSide })); - } - - const boxGeometry = new THREE.BoxGeometry(3, 3, 3); - - const box = new THREE.Mesh(boxGeometry, materials); - scene.add(box); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - new SimpleGI(renderer, scene); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 10; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.setRenderTarget(null); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_sprites.ts b/examples-testing/examples/webgl_sprites.ts deleted file mode 100644 index 2e4189347..000000000 --- a/examples-testing/examples/webgl_sprites.ts +++ /dev/null @@ -1,187 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; -let cameraOrtho, sceneOrtho; - -let spriteTL, spriteTR, spriteBL, spriteBR, spriteC; - -let mapC; - -let group; - -init(); - -function init() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera = new THREE.PerspectiveCamera(60, width / height, 1, 2100); - camera.position.z = 1500; - - cameraOrtho = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 1, 10); - cameraOrtho.position.z = 10; - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1500, 2100); - - sceneOrtho = new THREE.Scene(); - - // create sprites - - const amount = 200; - const radius = 500; - - const textureLoader = new THREE.TextureLoader(); - - textureLoader.load('textures/sprite0.png', createHUDSprites); - const mapB = textureLoader.load('textures/sprite1.png'); - mapC = textureLoader.load('textures/sprite2.png'); - - mapB.colorSpace = THREE.SRGBColorSpace; - mapC.colorSpace = THREE.SRGBColorSpace; - - group = new THREE.Group(); - - const materialC = new THREE.SpriteMaterial({ map: mapC, color: 0xffffff, fog: true }); - const materialB = new THREE.SpriteMaterial({ map: mapB, color: 0xffffff, fog: true }); - - for (let a = 0; a < amount; a++) { - const x = Math.random() - 0.5; - const y = Math.random() - 0.5; - const z = Math.random() - 0.5; - - let material; - - if (z < 0) { - material = materialB.clone(); - } else { - material = materialC.clone(); - material.color.setHSL(0.5 * Math.random(), 0.75, 0.5); - material.map.offset.set(-0.5, -0.5); - material.map.repeat.set(2, 2); - } - - const sprite = new THREE.Sprite(material); - - sprite.position.set(x, y, z); - sprite.position.normalize(); - sprite.position.multiplyScalar(radius); - - group.add(sprite); - } - - scene.add(group); - - // renderer - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; // To allow render overlay on top of sprited sphere - - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function createHUDSprites(texture) { - texture.colorSpace = THREE.SRGBColorSpace; - - const material = new THREE.SpriteMaterial({ map: texture }); - - const width = material.map.image.width; - const height = material.map.image.height; - - spriteTL = new THREE.Sprite(material); - spriteTL.center.set(0.0, 1.0); - spriteTL.scale.set(width, height, 1); - sceneOrtho.add(spriteTL); - - spriteTR = new THREE.Sprite(material); - spriteTR.center.set(1.0, 1.0); - spriteTR.scale.set(width, height, 1); - sceneOrtho.add(spriteTR); - - spriteBL = new THREE.Sprite(material); - spriteBL.center.set(0.0, 0.0); - spriteBL.scale.set(width, height, 1); - sceneOrtho.add(spriteBL); - - spriteBR = new THREE.Sprite(material); - spriteBR.center.set(1.0, 0.0); - spriteBR.scale.set(width, height, 1); - sceneOrtho.add(spriteBR); - - spriteC = new THREE.Sprite(material); - spriteC.center.set(0.5, 0.5); - spriteC.scale.set(width, height, 1); - sceneOrtho.add(spriteC); - - updateHUDSprites(); -} - -function updateHUDSprites() { - const width = window.innerWidth / 2; - const height = window.innerHeight / 2; - - spriteTL.position.set(-width, height, 1); // top left - spriteTR.position.set(width, height, 1); // top right - spriteBL.position.set(-width, -height, 1); // bottom left - spriteBR.position.set(width, -height, 1); // bottom right - spriteC.position.set(0, 0, 1); // center -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - cameraOrtho.left = -width / 2; - cameraOrtho.right = width / 2; - cameraOrtho.top = height / 2; - cameraOrtho.bottom = -height / 2; - cameraOrtho.updateProjectionMatrix(); - - updateHUDSprites(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = Date.now() / 1000; - - for (let i = 0, l = group.children.length; i < l; i++) { - const sprite = group.children[i]; - const material = sprite.material; - const scale = Math.sin(time + sprite.position.x * 0.01) * 0.3 + 1.0; - - let imageWidth = 1; - let imageHeight = 1; - - if (material.map && material.map.image && material.map.image.width) { - imageWidth = material.map.image.width; - imageHeight = material.map.image.height; - } - - sprite.material.rotation += 0.1 * (i / l); - sprite.scale.set(scale * imageWidth, scale * imageHeight, 1.0); - - if (material.map !== mapC) { - material.opacity = Math.sin(time + sprite.position.x * 0.01) * 0.4 + 0.6; - } - } - - group.rotation.x = time * 0.5; - group.rotation.y = time * 0.75; - group.rotation.z = time * 1.0; - - renderer.clear(); - renderer.render(scene, camera); - renderer.clearDepth(); - renderer.render(sceneOrtho, cameraOrtho); -} diff --git a/examples-testing/examples/webgl_test_memory.ts b/examples-testing/examples/webgl_test_memory.ts deleted file mode 100644 index f5d0e112d..000000000 --- a/examples-testing/examples/webgl_test_memory.ts +++ /dev/null @@ -1,65 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 200; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); -} - -function createImage() { - const canvas = document.createElement('canvas'); - canvas.width = 256; - canvas.height = 256; - - const context = canvas.getContext('2d'); - context.fillStyle = - 'rgb(' + - Math.floor(Math.random() * 256) + - ',' + - Math.floor(Math.random() * 256) + - ',' + - Math.floor(Math.random() * 256) + - ')'; - context.fillRect(0, 0, 256, 256); - - return canvas; -} - -// - -function animate() { - const geometry = new THREE.SphereGeometry(50, Math.random() * 64, Math.random() * 32); - - const texture = new THREE.CanvasTexture(createImage()); - - const material = new THREE.MeshBasicMaterial({ map: texture, wireframe: true }); - - const mesh = new THREE.Mesh(geometry, material); - - scene.add(mesh); - - renderer.render(scene, camera); - - scene.remove(mesh); - - // clean up - - geometry.dispose(); - material.dispose(); - texture.dispose(); -} diff --git a/examples-testing/examples/webgl_test_memory2.ts b/examples-testing/examples/webgl_test_memory2.ts deleted file mode 100644 index 366a27914..000000000 --- a/examples-testing/examples/webgl_test_memory2.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as THREE from 'three'; - -const N = 100; - -let container; - -let camera, scene, renderer; - -let geometry; - -const meshes = []; - -let fragmentShader, vertexShader; - -init(); -setInterval(render, 1000 / 60); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - vertexShader = document.getElementById('vertexShader').textContent; - fragmentShader = document.getElementById('fragmentShader').textContent; - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 2000; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - geometry = new THREE.SphereGeometry(15, 64, 32); - - for (let i = 0; i < N; i++) { - const material = new THREE.ShaderMaterial({ - vertexShader: vertexShader, - fragmentShader: generateFragmentShader(), - }); - - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = (0.5 - Math.random()) * 1000; - mesh.position.y = (0.5 - Math.random()) * 1000; - mesh.position.z = (0.5 - Math.random()) * 1000; - - scene.add(mesh); - - meshes.push(mesh); - } - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - container.appendChild(renderer.domElement); -} - -// - -function generateFragmentShader() { - return fragmentShader.replace('XXX', Math.random() + ',' + Math.random() + ',' + Math.random()); -} - -function render() { - for (let i = 0; i < N; i++) { - const mesh = meshes[i]; - mesh.material = new THREE.ShaderMaterial({ - vertexShader: vertexShader, - fragmentShader: generateFragmentShader(), - }); - } - - renderer.render(scene, camera); - - console.log('before', renderer.info.programs.length); - - for (let i = 0; i < N; i++) { - const mesh = meshes[i]; - mesh.material.dispose(); - } - - console.log('after', renderer.info.programs.length); -} diff --git a/examples-testing/examples/webgl_test_wide_gamut.ts b/examples-testing/examples/webgl_test_wide_gamut.ts deleted file mode 100644 index 693dd4593..000000000 --- a/examples-testing/examples/webgl_test_wide_gamut.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as THREE from 'three'; - -import WebGL from 'three/addons/capabilities/WebGL.js'; - -let container, camera, renderer, loader; -let sceneL, sceneR, textureL, textureR; - -let sliderPos = window.innerWidth / 2; - -const slider = document.querySelector('.slider'); - -const isP3Context = WebGL.isColorSpaceAvailable(THREE.DisplayP3ColorSpace); - -if (isP3Context) { - THREE.ColorManagement.workingColorSpace = THREE.LinearDisplayP3ColorSpace; -} - -init(); - -function init() { - container = document.querySelector('.container'); - - sceneL = new THREE.Scene(); - sceneR = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 6; - - loader = new THREE.TextureLoader(); - - initTextures(); - initSlider(); - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.setScissorTest(true); - container.appendChild(renderer.domElement); - - if (isP3Context && window.matchMedia('( color-gamut: p3 )').matches) { - renderer.outputColorSpace = THREE.DisplayP3ColorSpace; - } - - window.addEventListener('resize', onWindowResize); - window.matchMedia('( color-gamut: p3 )').addEventListener('change', onGamutChange); -} - -async function initTextures() { - const path = 'textures/wide_gamut/logo_{colorSpace}.png'; - - textureL = await loader.loadAsync(path.replace('{colorSpace}', 'srgb')); - textureR = await loader.loadAsync(path.replace('{colorSpace}', 'p3')); - - textureL.colorSpace = THREE.SRGBColorSpace; - textureR.colorSpace = THREE.DisplayP3ColorSpace; - - sceneL.background = THREE.TextureUtils.contain(textureL, window.innerWidth / window.innerHeight); - sceneR.background = THREE.TextureUtils.contain(textureR, window.innerWidth / window.innerHeight); -} - -function initSlider() { - function onPointerDown() { - if (event.isPrimary === false) return; - - window.addEventListener('pointermove', onPointerMove); - window.addEventListener('pointerup', onPointerUp); - } - - function onPointerUp() { - window.removeEventListener('pointermove', onPointerMove); - window.removeEventListener('pointerup', onPointerUp); - } - - function onPointerMove(e) { - if (event.isPrimary === false) return; - - updateSlider(e.pageX); - } - - updateSlider(sliderPos); - - slider.style.touchAction = 'none'; // disable touch scroll - slider.addEventListener('pointerdown', onPointerDown); -} - -function updateSlider(offset) { - sliderPos = Math.max(10, Math.min(window.innerWidth - 10, offset)); - - slider.style.left = sliderPos - slider.offsetWidth / 2 + 'px'; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - THREE.TextureUtils.contain(sceneL.background, window.innerWidth / window.innerHeight); - THREE.TextureUtils.contain(sceneR.background, window.innerWidth / window.innerHeight); - - updateSlider(sliderPos); -} - -function onGamutChange({ matches }) { - renderer.outputColorSpace = isP3Context && matches ? THREE.DisplayP3ColorSpace : THREE.SRGBColorSpace; - - textureL.needsUpdate = true; - textureR.needsUpdate = true; -} - -function animate() { - renderer.setScissor(0, 0, sliderPos, window.innerHeight); - renderer.render(sceneL, camera); - - renderer.setScissor(sliderPos, 0, window.innerWidth, window.innerHeight); - renderer.render(sceneR, camera); -} diff --git a/examples-testing/examples/webgl_texture2darray_compressed.ts b/examples-testing/examples/webgl_texture2darray_compressed.ts deleted file mode 100644 index f263be706..000000000 --- a/examples-testing/examples/webgl_texture2darray_compressed.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - -let camera, scene, mesh, renderer, stats, clock; - -const planeWidth = 50; -const planeHeight = 25; - -let depthStep = 1; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); - camera.position.z = 70; - - scene = new THREE.Scene(); - - // - clock = new THREE.Clock(); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - const ktx2Loader = new KTX2Loader(); - ktx2Loader.setTranscoderPath('jsm/libs/basis/'); - ktx2Loader.detectSupport(renderer); - - ktx2Loader.load('textures/spiritedaway.ktx2', function (texturearray) { - const material = new THREE.ShaderMaterial({ - uniforms: { - diffuse: { value: texturearray }, - depth: { value: 55 }, - size: { value: new THREE.Vector2(planeWidth, planeHeight) }, - }, - vertexShader: document.getElementById('vs').textContent.trim(), - fragmentShader: document.getElementById('fs').textContent.trim(), - glslVersion: THREE.GLSL3, - }); - - const geometry = new THREE.PlaneGeometry(planeWidth, planeHeight); - - mesh = new THREE.Mesh(geometry, material); - - scene.add(mesh); - }); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - if (mesh) { - const delta = clock.getDelta() * 10; - - depthStep += delta; - - const value = depthStep % 5; - - mesh.material.uniforms['depth'].value = value; - } - - render(); - stats.update(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_texture2darray_layerupdate.ts b/examples-testing/examples/webgl_texture2darray_layerupdate.ts deleted file mode 100644 index 0cc136cb7..000000000 --- a/examples-testing/examples/webgl_texture2darray_layerupdate.ts +++ /dev/null @@ -1,131 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - -let camera, scene, mesh, renderer; - -const planeWidth = 20; -const planeHeight = 10; - -init(); - -async function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); - camera.position.z = 70; - - scene = new THREE.Scene(); - - // Configure the renderer. - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - container.appendChild(renderer.domElement); - - // Configure the KTX2 loader. - - const ktx2Loader = new KTX2Loader(); - ktx2Loader.setTranscoderPath('jsm/libs/basis/'); - ktx2Loader.detectSupport(renderer); - - // Load several KTX2 textures which will later be used to modify - // specific texture array layers. - - const spiritedaway = await ktx2Loader.loadAsync('textures/spiritedaway.ktx2'); - - // Create a texture array for rendering. - - const layerByteLength = THREE.TextureUtils.getByteLength( - spiritedaway.image.width, - spiritedaway.image.height, - spiritedaway.format, - spiritedaway.type, - ); - - const textureArray = new THREE.CompressedArrayTexture( - [ - { - data: new Uint8Array(layerByteLength * 3), - width: spiritedaway.image.width, - height: spiritedaway.image.height, - }, - ], - spiritedaway.image.width, - spiritedaway.image.height, - 3, - spiritedaway.format, - spiritedaway.type, - ); - - // Setup the GUI - - const formData = { - srcLayer: 0, - destLayer: 0, - transfer() { - const layerElementLength = layerByteLength / spiritedaway.mipmaps[0].data.BYTES_PER_ELEMENT; - textureArray.mipmaps[0].data.set( - spiritedaway.mipmaps[0].data.subarray( - layerElementLength * (formData.srcLayer % spiritedaway.image.depth), - layerElementLength * ((formData.srcLayer % spiritedaway.image.depth) + 1), - ), - layerByteLength * formData.destLayer, - ); - textureArray.addLayerUpdate(formData.destLayer); - textureArray.needsUpdate = true; - - renderer.render(scene, camera); - }, - }; - - const gui = new GUI(); - gui.add(formData, 'srcLayer', 0, spiritedaway.image.depth - 1, 1); - gui.add(formData, 'destLayer', 0, textureArray.image.depth - 1, 1); - gui.add(formData, 'transfer'); - - /// Setup the scene. - - const material = new THREE.ShaderMaterial({ - uniforms: { - diffuse: { value: textureArray }, - size: { value: new THREE.Vector2(planeWidth, planeHeight) }, - }, - vertexShader: document.getElementById('vs').textContent.trim(), - fragmentShader: document.getElementById('fs').textContent.trim(), - glslVersion: THREE.GLSL3, - }); - - const geometry = new THREE.InstancedBufferGeometry(); - geometry.copy(new THREE.PlaneGeometry(planeWidth, planeHeight)); - geometry.instanceCount = 3; - - const instancedIndexAttribute = new THREE.InstancedBufferAttribute(new Uint16Array([0, 1, 2]), 1, false, 1); - instancedIndexAttribute.gpuType = THREE.IntType; - geometry.setAttribute('instancedIndex', instancedIndexAttribute); - - mesh = new THREE.InstancedMesh(geometry, material, 3); - - scene.add(mesh); - - window.addEventListener('resize', onWindowResize); - - // Initialize the texture array by first rendering the spirited away - // frames in order. - - textureArray.mipmaps[0].data.set(spiritedaway.mipmaps[0].data.subarray(0, textureArray.mipmaps[0].data.length)); - textureArray.needsUpdate = true; - renderer.render(scene, camera); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_texture3d.ts b/examples-testing/examples/webgl_texture3d.ts deleted file mode 100644 index 977dbadb7..000000000 --- a/examples-testing/examples/webgl_texture3d.ts +++ /dev/null @@ -1,128 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { NRRDLoader } from 'three/addons/loaders/NRRDLoader.js'; -import { VolumeRenderShader1 } from 'three/addons/shaders/VolumeShader.js'; - -let renderer, scene, camera, controls, material, volconfig, cmtextures; - -init(); - -function init() { - scene = new THREE.Scene(); - - // Create renderer - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - // Create camera (The volume renderer does not work very well with perspective yet) - const h = 512; // frustum height - const aspect = window.innerWidth / window.innerHeight; - camera = new THREE.OrthographicCamera((-h * aspect) / 2, (h * aspect) / 2, h / 2, -h / 2, 1, 1000); - camera.position.set(-64, -64, 128); - camera.up.set(0, 0, 1); // In our data, z is up - - // Create controls - controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); - controls.target.set(64, 64, 128); - controls.minZoom = 0.5; - controls.maxZoom = 4; - controls.enablePan = false; - controls.update(); - - // scene.add( new AxesHelper( 128 ) ); - - // Lighting is baked into the shader a.t.m. - // let dirLight = new DirectionalLight( 0xffffff ); - - // The gui for interaction - volconfig = { clim1: 0, clim2: 1, renderstyle: 'iso', isothreshold: 0.15, colormap: 'viridis' }; - const gui = new GUI(); - gui.add(volconfig, 'clim1', 0, 1, 0.01).onChange(updateUniforms); - gui.add(volconfig, 'clim2', 0, 1, 0.01).onChange(updateUniforms); - gui.add(volconfig, 'colormap', { gray: 'gray', viridis: 'viridis' }).onChange(updateUniforms); - gui.add(volconfig, 'renderstyle', { mip: 'mip', iso: 'iso' }).onChange(updateUniforms); - gui.add(volconfig, 'isothreshold', 0, 1, 0.01).onChange(updateUniforms); - - // Load the data ... - new NRRDLoader().load('models/nrrd/stent.nrrd', function (volume) { - // Texture to hold the volume. We have scalars, so we put our data in the red channel. - // THREEJS will select R32F (33326) based on the THREE.RedFormat and THREE.FloatType. - // Also see https://www.khronos.org/registry/webgl/specs/latest/2.0/#TEXTURE_TYPES_FORMATS_FROM_DOM_ELEMENTS_TABLE - // TODO: look the dtype up in the volume metadata - const texture = new THREE.Data3DTexture(volume.data, volume.xLength, volume.yLength, volume.zLength); - texture.format = THREE.RedFormat; - texture.type = THREE.FloatType; - texture.minFilter = texture.magFilter = THREE.LinearFilter; - texture.unpackAlignment = 1; - texture.needsUpdate = true; - - // Colormap textures - cmtextures = { - viridis: new THREE.TextureLoader().load('textures/cm_viridis.png', render), - gray: new THREE.TextureLoader().load('textures/cm_gray.png', render), - }; - - // Material - const shader = VolumeRenderShader1; - - const uniforms = THREE.UniformsUtils.clone(shader.uniforms); - - uniforms['u_data'].value = texture; - uniforms['u_size'].value.set(volume.xLength, volume.yLength, volume.zLength); - uniforms['u_clim'].value.set(volconfig.clim1, volconfig.clim2); - uniforms['u_renderstyle'].value = volconfig.renderstyle == 'mip' ? 0 : 1; // 0: MIP, 1: ISO - uniforms['u_renderthreshold'].value = volconfig.isothreshold; // For ISO renderstyle - uniforms['u_cmdata'].value = cmtextures[volconfig.colormap]; - - material = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - side: THREE.BackSide, // The volume shader uses the backface as its "reference point" - }); - - // THREE.Mesh - const geometry = new THREE.BoxGeometry(volume.xLength, volume.yLength, volume.zLength); - geometry.translate(volume.xLength / 2 - 0.5, volume.yLength / 2 - 0.5, volume.zLength / 2 - 0.5); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - render(); - }); - - window.addEventListener('resize', onWindowResize); -} - -function updateUniforms() { - material.uniforms['u_clim'].value.set(volconfig.clim1, volconfig.clim2); - material.uniforms['u_renderstyle'].value = volconfig.renderstyle == 'mip' ? 0 : 1; // 0: MIP, 1: ISO - material.uniforms['u_renderthreshold'].value = volconfig.isothreshold; // For ISO renderstyle - material.uniforms['u_cmdata'].value = cmtextures[volconfig.colormap]; - - render(); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - const aspect = window.innerWidth / window.innerHeight; - - const frustumHeight = camera.top - camera.bottom; - - camera.left = (-frustumHeight * aspect) / 2; - camera.right = (frustumHeight * aspect) / 2; - - camera.updateProjectionMatrix(); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_texture3d_partialupdate.ts b/examples-testing/examples/webgl_texture3d_partialupdate.ts deleted file mode 100644 index 1ad6d2646..000000000 --- a/examples-testing/examples/webgl_texture3d_partialupdate.ts +++ /dev/null @@ -1,326 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const INITIAL_CLOUD_SIZE = 128; - -let renderer, scene, camera; -let mesh; -let prevTime = performance.now(); -let cloudTexture = null; - -init(); - -function generateCloudTexture(size, scaleFactor = 1.0) { - const data = new Uint8Array(size * size * size); - const scale = (scaleFactor * 10.0) / size; - - let i = 0; - const perlin = new ImprovedNoise(); - const vector = new THREE.Vector3(); - - for (let z = 0; z < size; z++) { - for (let y = 0; y < size; y++) { - for (let x = 0; x < size; x++) { - const dist = vector - .set(x, y, z) - .subScalar(size / 2) - .divideScalar(size) - .length(); - const fadingFactor = (1.0 - dist) * (1.0 - dist); - data[i] = (128 + 128 * perlin.noise((x * scale) / 1.5, y * scale, (z * scale) / 1.5)) * fadingFactor; - - i++; - } - } - } - - return new THREE.Data3DTexture(data, size, size, size); -} - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 1.5); - - new OrbitControls(camera, renderer.domElement); - - // Sky - - const canvas = document.createElement('canvas'); - canvas.width = 1; - canvas.height = 32; - - const context = canvas.getContext('2d'); - const gradient = context.createLinearGradient(0, 0, 0, 32); - gradient.addColorStop(0.0, '#014a84'); - gradient.addColorStop(0.5, '#0561a0'); - gradient.addColorStop(1.0, '#437ab6'); - context.fillStyle = gradient; - context.fillRect(0, 0, 1, 32); - - const skyMap = new THREE.CanvasTexture(canvas); - skyMap.colorSpace = THREE.SRGBColorSpace; - - const sky = new THREE.Mesh( - new THREE.SphereGeometry(10), - new THREE.MeshBasicMaterial({ map: skyMap, side: THREE.BackSide }), - ); - scene.add(sky); - - // Texture - - const texture = new THREE.Data3DTexture( - new Uint8Array(INITIAL_CLOUD_SIZE * INITIAL_CLOUD_SIZE * INITIAL_CLOUD_SIZE).fill(0), - INITIAL_CLOUD_SIZE, - INITIAL_CLOUD_SIZE, - INITIAL_CLOUD_SIZE, - ); - texture.format = THREE.RedFormat; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.unpackAlignment = 1; - texture.needsUpdate = true; - - cloudTexture = texture; - - // Material - - const vertexShader = /* glsl */ ` - in vec3 position; - - uniform mat4 modelMatrix; - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - uniform vec3 cameraPos; - - out vec3 vOrigin; - out vec3 vDirection; - - void main() { - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - - vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz; - vDirection = position - vOrigin; - - gl_Position = projectionMatrix * mvPosition; - } - `; - - const fragmentShader = /* glsl */ ` - precision highp float; - precision highp sampler3D; - - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - - in vec3 vOrigin; - in vec3 vDirection; - - out vec4 color; - - uniform vec3 base; - uniform sampler3D map; - - uniform float threshold; - uniform float range; - uniform float opacity; - uniform float steps; - uniform float frame; - - uint wang_hash(uint seed) - { - seed = (seed ^ 61u) ^ (seed >> 16u); - seed *= 9u; - seed = seed ^ (seed >> 4u); - seed *= 0x27d4eb2du; - seed = seed ^ (seed >> 15u); - return seed; - } - - float randomFloat(inout uint seed) - { - return float(wang_hash(seed)) / 4294967296.; - } - - vec2 hitBox( vec3 orig, vec3 dir ) { - const vec3 box_min = vec3( - 0.5 ); - const vec3 box_max = vec3( 0.5 ); - vec3 inv_dir = 1.0 / dir; - vec3 tmin_tmp = ( box_min - orig ) * inv_dir; - vec3 tmax_tmp = ( box_max - orig ) * inv_dir; - vec3 tmin = min( tmin_tmp, tmax_tmp ); - vec3 tmax = max( tmin_tmp, tmax_tmp ); - float t0 = max( tmin.x, max( tmin.y, tmin.z ) ); - float t1 = min( tmax.x, min( tmax.y, tmax.z ) ); - return vec2( t0, t1 ); - } - - float sample1( vec3 p ) { - return texture( map, p ).r; - } - - float shading( vec3 coord ) { - float step = 0.01; - return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) ); - } - - vec4 linearToSRGB( in vec4 value ) { - return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); - } - - void main(){ - vec3 rayDir = normalize( vDirection ); - vec2 bounds = hitBox( vOrigin, rayDir ); - - if ( bounds.x > bounds.y ) discard; - - bounds.x = max( bounds.x, 0.0 ); - - vec3 p = vOrigin + bounds.x * rayDir; - vec3 inc = 1.0 / abs( rayDir ); - float delta = min( inc.x, min( inc.y, inc.z ) ); - delta /= steps; - - // Jitter - - // Nice little seed from - // https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/ - uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 ); - vec3 size = vec3( textureSize( map, 0 ) ); - float randNum = randomFloat( seed ) * 2.0 - 1.0; - p += rayDir * randNum * ( 1.0 / size ); - - // - - vec4 ac = vec4( base, 0.0 ); - - for ( float t = bounds.x; t < bounds.y; t += delta ) { - - float d = sample1( p + 0.5 ); - - d = smoothstep( threshold - range, threshold + range, d ) * opacity; - - float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2; - - ac.rgb += ( 1.0 - ac.a ) * d * col; - - ac.a += ( 1.0 - ac.a ) * d; - - if ( ac.a >= 0.95 ) break; - - p += rayDir * delta; - - } - - color = linearToSRGB( ac ); - - if ( color.a == 0.0 ) discard; - - } - `; - - const geometry = new THREE.BoxGeometry(1, 1, 1); - const material = new THREE.RawShaderMaterial({ - glslVersion: THREE.GLSL3, - uniforms: { - base: { value: new THREE.Color(0x798aa0) }, - map: { value: texture }, - cameraPos: { value: new THREE.Vector3() }, - threshold: { value: 0.25 }, - opacity: { value: 0.25 }, - range: { value: 0.1 }, - steps: { value: 100 }, - frame: { value: 0 }, - }, - vertexShader, - fragmentShader, - side: THREE.BackSide, - transparent: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const parameters = { - threshold: 0.25, - opacity: 0.25, - range: 0.1, - steps: 100, - }; - - function update() { - material.uniforms.threshold.value = parameters.threshold; - material.uniforms.opacity.value = parameters.opacity; - material.uniforms.range.value = parameters.range; - material.uniforms.steps.value = parameters.steps; - } - - const gui = new GUI(); - gui.add(parameters, 'threshold', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'opacity', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'range', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'steps', 0, 200, 1).onChange(update); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -let curr = 0; -const countPerRow = 4; -const countPerSlice = countPerRow * countPerRow; -const sliceCount = 4; -const totalCount = sliceCount * countPerSlice; -const margins = 8; - -const perElementPaddedSize = (INITIAL_CLOUD_SIZE - margins) / countPerRow; -const perElementSize = Math.floor((INITIAL_CLOUD_SIZE - 1) / countPerRow); - -function animate() { - const time = performance.now(); - if (time - prevTime > 1500.0 && curr < totalCount) { - const position = new THREE.Vector3( - Math.floor(curr % countPerRow) * perElementSize + margins * 0.5, - Math.floor((curr % countPerSlice) / countPerRow) * perElementSize + margins * 0.5, - Math.floor(curr / countPerSlice) * perElementSize + margins * 0.5, - ).floor(); - - const maxDimension = perElementPaddedSize - 1; - const box = new THREE.Box3( - new THREE.Vector3(0, 0, 0), - new THREE.Vector3(maxDimension, maxDimension, maxDimension), - ); - const scaleFactor = (Math.random() + 0.5) * 0.5; - const source = generateCloudTexture(perElementPaddedSize, scaleFactor); - - renderer.copyTextureToTexture3D(source, cloudTexture, box, position); - - prevTime = time; - - curr++; - } - - mesh.material.uniforms.cameraPos.value.copy(camera.position); - // mesh.rotation.y = - performance.now() / 7500; - - mesh.material.uniforms.frame.value++; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_tonemapping.ts b/examples-testing/examples/webgl_tonemapping.ts deleted file mode 100644 index 9945826c5..000000000 --- a/examples-testing/examples/webgl_tonemapping.ts +++ /dev/null @@ -1,163 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let mesh, renderer, scene, camera, controls; -let gui, - guiExposure = null; - -const params = { - exposure: 1.0, - toneMapping: 'AgX', - blurriness: 0.3, - intensity: 1.0, -}; - -const toneMappingOptions = { - None: THREE.NoToneMapping, - Linear: THREE.LinearToneMapping, - Reinhard: THREE.ReinhardToneMapping, - Cineon: THREE.CineonToneMapping, - ACESFilmic: THREE.ACESFilmicToneMapping, - AgX: THREE.AgXToneMapping, - Neutral: THREE.NeutralToneMapping, - Custom: THREE.CustomToneMapping, -}; - -init().catch(function (err) { - console.error(err); -}); - -async function init() { - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = toneMappingOptions[params.toneMapping]; - renderer.toneMappingExposure = params.exposure; - - // Set CustomToneMapping to Uncharted2 - // source: http://filmicworlds.com/blog/filmic-tonemapping-operators/ - - THREE.ShaderChunk.tonemapping_pars_fragment = THREE.ShaderChunk.tonemapping_pars_fragment.replace( - 'vec3 CustomToneMapping( vec3 color ) { return color; }', - - `#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) ) - - float toneMappingWhitePoint = 1.0; - - vec3 CustomToneMapping( vec3 color ) { - color *= toneMappingExposure; - return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) ); - - }`, - ); - - scene = new THREE.Scene(); - scene.backgroundBlurriness = params.blurriness; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.enableZoom = false; - controls.enablePan = false; - controls.target.set(0, 0, -0.2); - controls.update(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - - const gltfLoader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - - const [texture, gltf] = await Promise.all([ - rgbeLoader.loadAsync('venice_sunset_1k.hdr'), - gltfLoader.loadAsync('DamagedHelmet.gltf'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - mesh = gltf.scene.getObjectByName('node_damagedHelmet_-6514'); - scene.add(mesh); - - render(); - - window.addEventListener('resize', onWindowResize); - - gui = new GUI(); - const toneMappingFolder = gui.addFolder('Tone Mapping'); - - toneMappingFolder - .add(params, 'toneMapping', Object.keys(toneMappingOptions)) - - .name('type') - .onChange(function () { - updateGUI(toneMappingFolder); - - renderer.toneMapping = toneMappingOptions[params.toneMapping]; - render(); - }); - - guiExposure = toneMappingFolder - .add(params, 'exposure', 0, 2) - - .onChange(function (value) { - renderer.toneMappingExposure = value; - render(); - }); - - const backgroundFolder = gui.addFolder('Background'); - - backgroundFolder - .add(params, 'blurriness', 0, 1) - - .onChange(function (value) { - scene.backgroundBlurriness = value; - render(); - }); - - backgroundFolder - .add(params, 'intensity', 0, 1) - - .onChange(function (value) { - scene.backgroundIntensity = value; - render(); - }); - - updateGUI(toneMappingFolder); - - gui.open(); -} - -function updateGUI(folder) { - if (params.toneMapping === 'None') { - guiExposure.hide(); - } else { - guiExposure.show(); - } -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_ubo.ts b/examples-testing/examples/webgl_ubo.ts deleted file mode 100644 index 01064f115..000000000 --- a/examples-testing/examples/webgl_ubo.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, clock; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 25); - - scene = new THREE.Scene(); - camera.lookAt(scene.position); - - clock = new THREE.Clock(); - - // geometry - - const geometry1 = new THREE.TetrahedronGeometry(); - const geometry2 = new THREE.BoxGeometry(); - - // texture - - const texture = new THREE.TextureLoader().load('textures/crate.gif'); - texture.colorSpace = THREE.SRGBColorSpace; - - // uniforms groups - - // Camera and lighting related data are perfect examples of using UBOs since you have to store these - // data just once. They can be shared across all shader programs. - - const cameraUniformsGroup = new THREE.UniformsGroup(); - cameraUniformsGroup.setName('ViewData'); - cameraUniformsGroup.add(new THREE.Uniform(camera.projectionMatrix)); // projection matrix - cameraUniformsGroup.add(new THREE.Uniform(camera.matrixWorldInverse)); // view matrix - - const lightingUniformsGroup = new THREE.UniformsGroup(); - lightingUniformsGroup.setName('LightingData'); - lightingUniformsGroup.add(new THREE.Uniform(new THREE.Vector3(0, 0, 10))); // light position - lightingUniformsGroup.add(new THREE.Uniform(new THREE.Color(0x7c7c7c))); // ambient color - lightingUniformsGroup.add(new THREE.Uniform(new THREE.Color(0xd5d5d5))); // diffuse color - lightingUniformsGroup.add(new THREE.Uniform(new THREE.Color(0xe7e7e7))); // specular color - lightingUniformsGroup.add(new THREE.Uniform(64)); // shininess - - // materials - - const material1 = new THREE.RawShaderMaterial({ - uniforms: { - modelMatrix: { value: null }, - normalMatrix: { value: null }, - color: { value: null }, - }, - vertexShader: document.getElementById('vertexShader1').textContent, - fragmentShader: document.getElementById('fragmentShader1').textContent, - glslVersion: THREE.GLSL3, - }); - - const material2 = new THREE.RawShaderMaterial({ - uniforms: { - modelMatrix: { value: null }, - diffuseMap: { value: null }, - }, - vertexShader: document.getElementById('vertexShader2').textContent, - fragmentShader: document.getElementById('fragmentShader2').textContent, - glslVersion: THREE.GLSL3, - }); - - // meshes - - for (let i = 0; i < 200; i++) { - let mesh; - - if (i % 2 === 0) { - mesh = new THREE.Mesh(geometry1, material1.clone()); - - mesh.material.uniformsGroups = [cameraUniformsGroup, lightingUniformsGroup]; - mesh.material.uniforms.modelMatrix.value = mesh.matrixWorld; - mesh.material.uniforms.normalMatrix.value = mesh.normalMatrix; - mesh.material.uniforms.color.value = new THREE.Color(0xffffff * Math.random()); - } else { - mesh = new THREE.Mesh(geometry2, material2.clone()); - - mesh.material.uniformsGroups = [cameraUniformsGroup, lightingUniformsGroup]; - mesh.material.uniforms.modelMatrix.value = mesh.matrixWorld; - mesh.material.uniforms.diffuseMap.value = texture; - } - - scene.add(mesh); - - const s = 1 + Math.random() * 0.5; - - mesh.scale.x = s; - mesh.scale.y = s; - mesh.scale.z = s; - - mesh.rotation.x = Math.random() * Math.PI; - mesh.rotation.y = Math.random() * Math.PI; - mesh.rotation.z = Math.random() * Math.PI; - - mesh.position.x = Math.random() * 40 - 20; - mesh.position.y = Math.random() * 40 - 20; - mesh.position.z = Math.random() * 20 - 10; - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize, false); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const delta = clock.getDelta(); - - scene.traverse(function (child) { - if (child.isMesh) { - child.rotation.x += delta * 0.5; - child.rotation.y += delta * 0.3; - } - }); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_ubo_arrays.ts b/examples-testing/examples/webgl_ubo_arrays.ts deleted file mode 100644 index d846e1443..000000000 --- a/examples-testing/examples/webgl_ubo_arrays.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, clock, stats; - -let lightingUniformsGroup, lightCenters; - -const container = document.getElementById('container'); - -const pointLightsMax = 300; - -const api = { - count: 200, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 50, 50); - - scene = new THREE.Scene(); - camera.lookAt(scene.position); - - clock = new THREE.Clock(); - - // geometry - - const geometry = new THREE.SphereGeometry(); - - // uniforms groups - - lightingUniformsGroup = new THREE.UniformsGroup(); - lightingUniformsGroup.setName('LightingData'); - - const data = []; - const dataColors = []; - lightCenters = []; - - for (let i = 0; i < pointLightsMax; i++) { - const col = new THREE.Color(0xffffff * Math.random()).toArray(); - const x = Math.random() * 50 - 25; - const z = Math.random() * 50 - 25; - - data.push(new THREE.Uniform(new THREE.Vector4(x, 1, z, 0))); // light position - dataColors.push(new THREE.Uniform(new THREE.Vector4(col[0], col[1], col[2], 0))); // light color - - // Store the center positions - lightCenters.push({ x, z }); - } - - lightingUniformsGroup.add(data); // light position - lightingUniformsGroup.add(dataColors); // light position - lightingUniformsGroup.add(new THREE.Uniform(pointLightsMax)); // light position - - const cameraUniformsGroup = new THREE.UniformsGroup(); - cameraUniformsGroup.setName('ViewData'); - cameraUniformsGroup.add(new THREE.Uniform(camera.projectionMatrix)); // projection matrix - cameraUniformsGroup.add(new THREE.Uniform(camera.matrixWorldInverse)); // view matrix - - const material = new THREE.RawShaderMaterial({ - uniforms: { - modelMatrix: { value: null }, - normalMatrix: { value: null }, - }, - // uniformsGroups: [ cameraUniformsGroup, lightingUniformsGroup ], - name: 'Box', - defines: { - POINTLIGHTS_MAX: pointLightsMax, - }, - vertexShader: document.getElementById('vertexShader').textContent, - fragmentShader: document.getElementById('fragmentShader').textContent, - glslVersion: THREE.GLSL3, - }); - - const plane = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), material.clone()); - plane.material.uniformsGroups = [cameraUniformsGroup, lightingUniformsGroup]; - plane.material.uniforms.modelMatrix.value = plane.matrixWorld; - plane.material.uniforms.normalMatrix.value = plane.normalMatrix; - plane.rotation.x = -Math.PI / 2; - plane.position.y = -1; - scene.add(plane); - - // meshes - const gridSize = { x: 10, y: 1, z: 10 }; - const spacing = 6; - - for (let i = 0; i < gridSize.x; i++) { - for (let j = 0; j < gridSize.y; j++) { - for (let k = 0; k < gridSize.z; k++) { - const mesh = new THREE.Mesh(geometry, material.clone()); - mesh.name = 'Sphere'; - mesh.material.uniformsGroups = [cameraUniformsGroup, lightingUniformsGroup]; - mesh.material.uniforms.modelMatrix.value = mesh.matrixWorld; - mesh.material.uniforms.normalMatrix.value = mesh.normalMatrix; - scene.add(mesh); - - mesh.position.x = i * spacing - (gridSize.x * spacing) / 2; - mesh.position.y = 0; - mesh.position.z = k * spacing - (gridSize.z * spacing) / 2; - } - } - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize, false); - - // controls - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enablePan = false; - - // stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // gui - const gui = new GUI(); - gui.add(api, 'count', 1, pointLightsMax) - .step(1) - .onChange(function () { - lightingUniformsGroup.uniforms[2].value = api.count; - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const elapsedTime = clock.getElapsedTime(); - - const lights = lightingUniformsGroup.uniforms[0]; - - // Parameters for circular movement - const radius = 5; // Smaller radius for individual circular movements - const speed = 0.5; // Speed of rotation - - // Update each light's position - for (let i = 0; i < lights.length; i++) { - const light = lights[i]; - const center = lightCenters[i]; - - // Calculate circular movement around the light's center - const angle = speed * elapsedTime + i * 0.5; // Phase difference for each light - const x = center.x + Math.sin(angle) * radius; - const z = center.z + Math.cos(angle) * radius; - - // Update the light's position - light.value.set(x, 1, z, 0); - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgl_video_kinect.ts b/examples-testing/examples/webgl_video_kinect.ts deleted file mode 100644 index 4f0e2f113..000000000 --- a/examples-testing/examples/webgl_video_kinect.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, camera, renderer; -let geometry, mesh, material; -let mouse, center; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - const info = document.createElement('div'); - info.id = 'info'; - info.innerHTML = 'three.js - kinect'; - document.body.appendChild(info); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.set(0, 0, 500); - - scene = new THREE.Scene(); - center = new THREE.Vector3(); - center.z = -1000; - - const video = document.getElementById('video'); - - const texture = new THREE.VideoTexture(video); - texture.minFilter = THREE.NearestFilter; - - const width = 640, - height = 480; - const nearClipping = 850, - farClipping = 4000; - - geometry = new THREE.BufferGeometry(); - - const vertices = new Float32Array(width * height * 3); - - for (let i = 0, j = 0, l = vertices.length; i < l; i += 3, j++) { - vertices[i] = j % width; - vertices[i + 1] = Math.floor(j / width); - } - - geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)); - - material = new THREE.ShaderMaterial({ - uniforms: { - map: { value: texture }, - width: { value: width }, - height: { value: height }, - nearClipping: { value: nearClipping }, - farClipping: { value: farClipping }, - - pointSize: { value: 2 }, - zOffset: { value: 1000 }, - }, - vertexShader: document.getElementById('vs').textContent, - fragmentShader: document.getElementById('fs').textContent, - blending: THREE.AdditiveBlending, - depthTest: false, - depthWrite: false, - transparent: true, - }); - - mesh = new THREE.Points(geometry, material); - scene.add(mesh); - - const gui = new GUI(); - gui.add(material.uniforms.nearClipping, 'value', 1, 10000, 1.0).name('nearClipping'); - gui.add(material.uniforms.farClipping, 'value', 1, 10000, 1.0).name('farClipping'); - gui.add(material.uniforms.pointSize, 'value', 1, 10, 1.0).name('pointSize'); - gui.add(material.uniforms.zOffset, 'value', 0, 4000, 1.0).name('zOffset'); - - video.play(); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - mouse = new THREE.Vector3(0, 0, 1); - - document.addEventListener('mousemove', onDocumentMouseMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouse.x = (event.clientX - window.innerWidth / 2) * 8; - mouse.y = (event.clientY - window.innerHeight / 2) * 8; -} - -function animate() { - camera.position.x += (mouse.x - camera.position.x) * 0.05; - camera.position.y += (-mouse.y - camera.position.y) * 0.05; - camera.lookAt(center); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_video_panorama_equirectangular.ts b/examples-testing/examples/webgl_video_panorama_equirectangular.ts deleted file mode 100644 index 866eca16a..000000000 --- a/examples-testing/examples/webgl_video_panorama_equirectangular.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; - -let isUserInteracting = false, - lon = 0, - lat = 0, - phi = 0, - theta = 0, - onPointerDownPointerX = 0, - onPointerDownPointerY = 0, - onPointerDownLon = 0, - onPointerDownLat = 0; - -const distance = 0.5; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.25, 10); - - scene = new THREE.Scene(); - - const geometry = new THREE.SphereGeometry(5, 60, 40); - // invert the geometry on the x-axis so that all of the faces point inward - geometry.scale(-1, 1, 1); - - const video = document.getElementById('video'); - video.play(); - - const texture = new THREE.VideoTexture(video); - texture.colorSpace = THREE.SRGBColorSpace; - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - document.addEventListener('pointerdown', onPointerDown); - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerDown(event) { - isUserInteracting = true; - - onPointerDownPointerX = event.clientX; - onPointerDownPointerY = event.clientY; - - onPointerDownLon = lon; - onPointerDownLat = lat; -} - -function onPointerMove(event) { - if (isUserInteracting === true) { - lon = (onPointerDownPointerX - event.clientX) * 0.1 + onPointerDownLon; - lat = (onPointerDownPointerY - event.clientY) * 0.1 + onPointerDownLat; - } -} - -function onPointerUp() { - isUserInteracting = false; -} - -function animate() { - lat = Math.max(-85, Math.min(85, lat)); - phi = THREE.MathUtils.degToRad(90 - lat); - theta = THREE.MathUtils.degToRad(lon); - - camera.position.x = distance * Math.sin(phi) * Math.cos(theta); - camera.position.y = distance * Math.cos(phi); - camera.position.z = distance * Math.sin(phi) * Math.sin(theta); - - camera.lookAt(0, 0, 0); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_volume_cloud.ts b/examples-testing/examples/webgl_volume_cloud.ts deleted file mode 100644 index 77dd8de43..000000000 --- a/examples-testing/examples/webgl_volume_cloud.ts +++ /dev/null @@ -1,279 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let renderer, scene, camera; -let mesh; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 1.5); - - new OrbitControls(camera, renderer.domElement); - - // Sky - - const canvas = document.createElement('canvas'); - canvas.width = 1; - canvas.height = 32; - - const context = canvas.getContext('2d'); - const gradient = context.createLinearGradient(0, 0, 0, 32); - gradient.addColorStop(0.0, '#014a84'); - gradient.addColorStop(0.5, '#0561a0'); - gradient.addColorStop(1.0, '#437ab6'); - context.fillStyle = gradient; - context.fillRect(0, 0, 1, 32); - - const skyMap = new THREE.CanvasTexture(canvas); - skyMap.colorSpace = THREE.SRGBColorSpace; - - const sky = new THREE.Mesh( - new THREE.SphereGeometry(10), - new THREE.MeshBasicMaterial({ map: skyMap, side: THREE.BackSide }), - ); - scene.add(sky); - - // Texture - - const size = 128; - const data = new Uint8Array(size * size * size); - - let i = 0; - const scale = 0.05; - const perlin = new ImprovedNoise(); - const vector = new THREE.Vector3(); - - for (let z = 0; z < size; z++) { - for (let y = 0; y < size; y++) { - for (let x = 0; x < size; x++) { - const d = - 1.0 - - vector - .set(x, y, z) - .subScalar(size / 2) - .divideScalar(size) - .length(); - data[i] = (128 + 128 * perlin.noise((x * scale) / 1.5, y * scale, (z * scale) / 1.5)) * d * d; - i++; - } - } - } - - const texture = new THREE.Data3DTexture(data, size, size, size); - texture.format = THREE.RedFormat; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.unpackAlignment = 1; - texture.needsUpdate = true; - - // Material - - const vertexShader = /* glsl */ ` - in vec3 position; - - uniform mat4 modelMatrix; - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - uniform vec3 cameraPos; - - out vec3 vOrigin; - out vec3 vDirection; - - void main() { - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - - vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz; - vDirection = position - vOrigin; - - gl_Position = projectionMatrix * mvPosition; - } - `; - - const fragmentShader = /* glsl */ ` - precision highp float; - precision highp sampler3D; - - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - - in vec3 vOrigin; - in vec3 vDirection; - - out vec4 color; - - uniform vec3 base; - uniform sampler3D map; - - uniform float threshold; - uniform float range; - uniform float opacity; - uniform float steps; - uniform float frame; - - uint wang_hash(uint seed) - { - seed = (seed ^ 61u) ^ (seed >> 16u); - seed *= 9u; - seed = seed ^ (seed >> 4u); - seed *= 0x27d4eb2du; - seed = seed ^ (seed >> 15u); - return seed; - } - - float randomFloat(inout uint seed) - { - return float(wang_hash(seed)) / 4294967296.; - } - - vec2 hitBox( vec3 orig, vec3 dir ) { - const vec3 box_min = vec3( - 0.5 ); - const vec3 box_max = vec3( 0.5 ); - vec3 inv_dir = 1.0 / dir; - vec3 tmin_tmp = ( box_min - orig ) * inv_dir; - vec3 tmax_tmp = ( box_max - orig ) * inv_dir; - vec3 tmin = min( tmin_tmp, tmax_tmp ); - vec3 tmax = max( tmin_tmp, tmax_tmp ); - float t0 = max( tmin.x, max( tmin.y, tmin.z ) ); - float t1 = min( tmax.x, min( tmax.y, tmax.z ) ); - return vec2( t0, t1 ); - } - - float sample1( vec3 p ) { - return texture( map, p ).r; - } - - float shading( vec3 coord ) { - float step = 0.01; - return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) ); - } - - vec4 linearToSRGB( in vec4 value ) { - return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); - } - - void main(){ - vec3 rayDir = normalize( vDirection ); - vec2 bounds = hitBox( vOrigin, rayDir ); - - if ( bounds.x > bounds.y ) discard; - - bounds.x = max( bounds.x, 0.0 ); - - vec3 p = vOrigin + bounds.x * rayDir; - vec3 inc = 1.0 / abs( rayDir ); - float delta = min( inc.x, min( inc.y, inc.z ) ); - delta /= steps; - - // Jitter - - // Nice little seed from - // https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/ - uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 ); - vec3 size = vec3( textureSize( map, 0 ) ); - float randNum = randomFloat( seed ) * 2.0 - 1.0; - p += rayDir * randNum * ( 1.0 / size ); - - // - - vec4 ac = vec4( base, 0.0 ); - - for ( float t = bounds.x; t < bounds.y; t += delta ) { - - float d = sample1( p + 0.5 ); - - d = smoothstep( threshold - range, threshold + range, d ) * opacity; - - float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2; - - ac.rgb += ( 1.0 - ac.a ) * d * col; - - ac.a += ( 1.0 - ac.a ) * d; - - if ( ac.a >= 0.95 ) break; - - p += rayDir * delta; - - } - - color = linearToSRGB( ac ); - - if ( color.a == 0.0 ) discard; - - } - `; - - const geometry = new THREE.BoxGeometry(1, 1, 1); - const material = new THREE.RawShaderMaterial({ - glslVersion: THREE.GLSL3, - uniforms: { - base: { value: new THREE.Color(0x798aa0) }, - map: { value: texture }, - cameraPos: { value: new THREE.Vector3() }, - threshold: { value: 0.25 }, - opacity: { value: 0.25 }, - range: { value: 0.1 }, - steps: { value: 100 }, - frame: { value: 0 }, - }, - vertexShader, - fragmentShader, - side: THREE.BackSide, - transparent: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const parameters = { - threshold: 0.25, - opacity: 0.25, - range: 0.1, - steps: 100, - }; - - function update() { - material.uniforms.threshold.value = parameters.threshold; - material.uniforms.opacity.value = parameters.opacity; - material.uniforms.range.value = parameters.range; - material.uniforms.steps.value = parameters.steps; - } - - const gui = new GUI(); - gui.add(parameters, 'threshold', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'opacity', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'range', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'steps', 0, 200, 1).onChange(update); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - mesh.material.uniforms.cameraPos.value.copy(camera.position); - mesh.rotation.y = -performance.now() / 7500; - - mesh.material.uniforms.frame.value++; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_volume_instancing.ts b/examples-testing/examples/webgl_volume_instancing.ts deleted file mode 100644 index bf90eeea9..000000000 --- a/examples-testing/examples/webgl_volume_instancing.ts +++ /dev/null @@ -1,192 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { VOXLoader, VOXData3DTexture } from 'three/addons/loaders/VOXLoader.js'; - -let renderer, scene, camera, controls, clock; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); - camera.position.set(0, 0, 4); - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = -1.0; - controls.enableDamping = true; - - clock = new THREE.Clock(); - - // Material - - const vertexShader = /* glsl */ ` - in vec3 position; - in mat4 instanceMatrix; - - uniform mat4 modelMatrix; - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - uniform vec3 cameraPos; - - out vec3 vOrigin; - out vec3 vDirection; - - void main() { - vec4 mvPosition = modelViewMatrix * instanceMatrix * vec4( position, 1.0 ); - - vOrigin = vec3( inverse( instanceMatrix * modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz; - vDirection = position - vOrigin; - - gl_Position = projectionMatrix * mvPosition; - } - `; - - const fragmentShader = /* glsl */ ` - precision highp float; - precision highp sampler3D; - - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - - in vec3 vOrigin; - in vec3 vDirection; - - out vec4 color; - - uniform sampler3D map; - - uniform float threshold; - uniform float steps; - - vec2 hitBox( vec3 orig, vec3 dir ) { - const vec3 box_min = vec3( - 0.5 ); - const vec3 box_max = vec3( 0.5 ); - vec3 inv_dir = 1.0 / dir; - vec3 tmin_tmp = ( box_min - orig ) * inv_dir; - vec3 tmax_tmp = ( box_max - orig ) * inv_dir; - vec3 tmin = min( tmin_tmp, tmax_tmp ); - vec3 tmax = max( tmin_tmp, tmax_tmp ); - float t0 = max( tmin.x, max( tmin.y, tmin.z ) ); - float t1 = min( tmax.x, min( tmax.y, tmax.z ) ); - return vec2( t0, t1 ); - } - - float sample1( vec3 p ) { - return texture( map, p ).r; - } - - #define epsilon .0001 - - vec3 normal( vec3 coord ) { - if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 ); - if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 ); - if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 ); - if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 ); - if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 ); - if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 ); - - float step = 0.01; - float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) ); - float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) ); - float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) ); - - return normalize( vec3( x, y, z ) ); - } - - void main(){ - - vec3 rayDir = normalize( vDirection ); - vec2 bounds = hitBox( vOrigin, rayDir ); - - if ( bounds.x > bounds.y ) discard; - - bounds.x = max( bounds.x, 0.0 ); - - vec3 p = vOrigin + bounds.x * rayDir; - vec3 inc = 1.0 / abs( rayDir ); - float delta = min( inc.x, min( inc.y, inc.z ) ); - delta /= 50.0; - - for ( float t = bounds.x; t < bounds.y; t += delta ) { - - float d = sample1( p + 0.5 ); - - if ( d > 0.5 ) { - - color.rgb = p * 2.0; // normal( p + 0.5 ); // * 0.5 + ( p * 1.5 + 0.25 ); - color.a = 1.; - break; - - } - - p += rayDir * delta; - - } - - if ( color.a == 0.0 ) discard; - - } - `; - - const loader = new VOXLoader(); - loader.load('models/vox/menger.vox', function (chunks) { - for (let i = 0; i < chunks.length; i++) { - const chunk = chunks[i]; - - const geometry = new THREE.BoxGeometry(1, 1, 1); - const material = new THREE.RawShaderMaterial({ - glslVersion: THREE.GLSL3, - uniforms: { - map: { value: new VOXData3DTexture(chunk) }, - cameraPos: { value: new THREE.Vector3() }, - }, - vertexShader, - fragmentShader, - side: THREE.BackSide, - }); - - const mesh = new THREE.InstancedMesh(geometry, material, 50000); - mesh.onBeforeRender = function () { - this.material.uniforms.cameraPos.value.copy(camera.position); - }; - - const transform = new THREE.Object3D(); - - for (let i = 0; i < mesh.count; i++) { - transform.position.random().subScalar(0.5).multiplyScalar(150); - transform.rotation.x = Math.random() * Math.PI; - transform.rotation.y = Math.random() * Math.PI; - transform.rotation.z = Math.random() * Math.PI; - transform.updateMatrix(); - - mesh.setMatrixAt(i, transform.matrix); - } - - scene.add(mesh); - } - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - controls.update(delta); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_volume_perlin.ts b/examples-testing/examples/webgl_volume_perlin.ts deleted file mode 100644 index a98f9a682..000000000 --- a/examples-testing/examples/webgl_volume_perlin.ts +++ /dev/null @@ -1,208 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let renderer, scene, camera; -let mesh; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 2); - - new OrbitControls(camera, renderer.domElement); - - // Texture - - const size = 128; - const data = new Uint8Array(size * size * size); - - let i = 0; - const perlin = new ImprovedNoise(); - const vector = new THREE.Vector3(); - - for (let z = 0; z < size; z++) { - for (let y = 0; y < size; y++) { - for (let x = 0; x < size; x++) { - vector.set(x, y, z).divideScalar(size); - - const d = perlin.noise(vector.x * 6.5, vector.y * 6.5, vector.z * 6.5); - - data[i++] = d * 128 + 128; - } - } - } - - const texture = new THREE.Data3DTexture(data, size, size, size); - texture.format = THREE.RedFormat; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.unpackAlignment = 1; - texture.needsUpdate = true; - - // Material - - const vertexShader = /* glsl */ ` - in vec3 position; - - uniform mat4 modelMatrix; - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - uniform vec3 cameraPos; - - out vec3 vOrigin; - out vec3 vDirection; - - void main() { - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - - vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz; - vDirection = position - vOrigin; - - gl_Position = projectionMatrix * mvPosition; - } - `; - - const fragmentShader = /* glsl */ ` - precision highp float; - precision highp sampler3D; - - uniform mat4 modelViewMatrix; - uniform mat4 projectionMatrix; - - in vec3 vOrigin; - in vec3 vDirection; - - out vec4 color; - - uniform sampler3D map; - - uniform float threshold; - uniform float steps; - - vec2 hitBox( vec3 orig, vec3 dir ) { - const vec3 box_min = vec3( - 0.5 ); - const vec3 box_max = vec3( 0.5 ); - vec3 inv_dir = 1.0 / dir; - vec3 tmin_tmp = ( box_min - orig ) * inv_dir; - vec3 tmax_tmp = ( box_max - orig ) * inv_dir; - vec3 tmin = min( tmin_tmp, tmax_tmp ); - vec3 tmax = max( tmin_tmp, tmax_tmp ); - float t0 = max( tmin.x, max( tmin.y, tmin.z ) ); - float t1 = min( tmax.x, min( tmax.y, tmax.z ) ); - return vec2( t0, t1 ); - } - - float sample1( vec3 p ) { - return texture( map, p ).r; - } - - #define epsilon .0001 - - vec3 normal( vec3 coord ) { - if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 ); - if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 ); - if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 ); - if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 ); - if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 ); - if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 ); - - float step = 0.01; - float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) ); - float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) ); - float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) ); - - return normalize( vec3( x, y, z ) ); - } - - void main(){ - - vec3 rayDir = normalize( vDirection ); - vec2 bounds = hitBox( vOrigin, rayDir ); - - if ( bounds.x > bounds.y ) discard; - - bounds.x = max( bounds.x, 0.0 ); - - vec3 p = vOrigin + bounds.x * rayDir; - vec3 inc = 1.0 / abs( rayDir ); - float delta = min( inc.x, min( inc.y, inc.z ) ); - delta /= steps; - - for ( float t = bounds.x; t < bounds.y; t += delta ) { - - float d = sample1( p + 0.5 ); - - if ( d > threshold ) { - - color.rgb = normal( p + 0.5 ) * 0.5 + ( p * 1.5 + 0.25 ); - color.a = 1.; - break; - - } - - p += rayDir * delta; - - } - - if ( color.a == 0.0 ) discard; - - } - `; - - const geometry = new THREE.BoxGeometry(1, 1, 1); - const material = new THREE.RawShaderMaterial({ - glslVersion: THREE.GLSL3, - uniforms: { - map: { value: texture }, - cameraPos: { value: new THREE.Vector3() }, - threshold: { value: 0.6 }, - steps: { value: 200 }, - }, - vertexShader, - fragmentShader, - side: THREE.BackSide, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const parameters = { threshold: 0.6, steps: 200 }; - - function update() { - material.uniforms.threshold.value = parameters.threshold; - material.uniforms.steps.value = parameters.steps; - } - - const gui = new GUI(); - gui.add(parameters, 'threshold', 0, 1, 0.01).onChange(update); - gui.add(parameters, 'steps', 0, 300, 1).onChange(update); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - mesh.material.uniforms.cameraPos.value.copy(camera.position); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_water.ts b/examples-testing/examples/webgl_water.ts deleted file mode 100644 index 496a5f855..000000000 --- a/examples-testing/examples/webgl_water.ts +++ /dev/null @@ -1,162 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Water } from 'three/addons/objects/Water2.js'; - -let scene, camera, clock, renderer, water; - -let torusKnot; - -const params = { - color: '#ffffff', - scale: 4, - flowX: 1, - flowY: 1, -}; - -init(); - -function init() { - // scene - - scene = new THREE.Scene(); - - // camera - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); - camera.position.set(-15, 7, 15); - camera.lookAt(scene.position); - - // clock - - clock = new THREE.Clock(); - - // mesh - - const torusKnotGeometry = new THREE.TorusKnotGeometry(3, 1, 256, 32); - const torusKnotMaterial = new THREE.MeshNormalMaterial(); - - torusKnot = new THREE.Mesh(torusKnotGeometry, torusKnotMaterial); - torusKnot.position.y = 4; - torusKnot.scale.set(0.5, 0.5, 0.5); - scene.add(torusKnot); - - // ground - - const groundGeometry = new THREE.PlaneGeometry(20, 20); - const groundMaterial = new THREE.MeshStandardMaterial({ roughness: 0.8, metalness: 0.4 }); - const ground = new THREE.Mesh(groundGeometry, groundMaterial); - ground.rotation.x = Math.PI * -0.5; - scene.add(ground); - - const textureLoader = new THREE.TextureLoader(); - textureLoader.load('textures/hardwood2_diffuse.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.repeat.set(4, 4); - map.colorSpace = THREE.SRGBColorSpace; - groundMaterial.map = map; - groundMaterial.needsUpdate = true; - }); - - // water - - const waterGeometry = new THREE.PlaneGeometry(20, 20); - - water = new Water(waterGeometry, { - color: params.color, - scale: params.scale, - flowDirection: new THREE.Vector2(params.flowX, params.flowY), - textureWidth: 1024, - textureHeight: 1024, - }); - - water.position.y = 1; - water.rotation.x = Math.PI * -0.5; - scene.add(water); - - // skybox - - const cubeTextureLoader = new THREE.CubeTextureLoader(); - cubeTextureLoader.setPath('textures/cube/Park2/'); - - const cubeTexture = cubeTextureLoader.load([ - 'posx.jpg', - 'negx.jpg', - 'posy.jpg', - 'negy.jpg', - 'posz.jpg', - 'negz.jpg', - ]); - - scene.background = cubeTexture; - - // light - - const ambientLight = new THREE.AmbientLight(0xe7e7e7, 1.2); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 2); - directionalLight.position.set(-1, 1, 1); - scene.add(directionalLight); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // gui - - const gui = new GUI(); - - gui.addColor(params, 'color').onChange(function (value) { - water.material.uniforms['color'].value.set(value); - }); - gui.add(params, 'scale', 1, 10).onChange(function (value) { - water.material.uniforms['config'].value.w = value; - }); - gui.add(params, 'flowX', -1, 1) - .step(0.01) - .onChange(function (value) { - water.material.uniforms['flowDirection'].value.x = value; - water.material.uniforms['flowDirection'].value.normalize(); - }); - gui.add(params, 'flowY', -1, 1) - .step(0.01) - .onChange(function (value) { - water.material.uniforms['flowDirection'].value.y = value; - water.material.uniforms['flowDirection'].value.normalize(); - }); - - gui.open(); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 5; - controls.maxDistance = 50; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - torusKnot.rotation.x += delta; - torusKnot.rotation.y += delta * 0.5; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgl_water_flowmap.ts b/examples-testing/examples/webgl_water_flowmap.ts deleted file mode 100644 index d0255e431..000000000 --- a/examples-testing/examples/webgl_water_flowmap.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Water } from 'three/addons/objects/Water2.js'; - -let scene, camera, renderer, water; - -init(); - -function init() { - // scene - - scene = new THREE.Scene(); - - // camera - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); - camera.position.set(0, 25, 0); - camera.lookAt(scene.position); - - // ground - - const groundGeometry = new THREE.PlaneGeometry(20, 20, 10, 10); - const groundMaterial = new THREE.MeshBasicMaterial({ color: 0xe7e7e7 }); - const ground = new THREE.Mesh(groundGeometry, groundMaterial); - ground.rotation.x = Math.PI * -0.5; - scene.add(ground); - - const textureLoader = new THREE.TextureLoader(); - textureLoader.load('textures/floors/FloorsCheckerboard_S_Diffuse.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.repeat.set(4, 4); - map.colorSpace = THREE.SRGBColorSpace; - groundMaterial.map = map; - groundMaterial.needsUpdate = true; - }); - - // water - - const waterGeometry = new THREE.PlaneGeometry(20, 20); - const flowMap = textureLoader.load('textures/water/Water_1_M_Flow.jpg'); - - water = new Water(waterGeometry, { - scale: 2, - textureWidth: 1024, - textureHeight: 1024, - flowMap: flowMap, - }); - - water.position.y = 1; - water.rotation.x = Math.PI * -0.5; - scene.add(water); - - // flow map helper - - const helperGeometry = new THREE.PlaneGeometry(20, 20); - const helperMaterial = new THREE.MeshBasicMaterial({ map: flowMap }); - const helper = new THREE.Mesh(helperGeometry, helperMaterial); - helper.position.y = 1.01; - helper.rotation.x = Math.PI * -0.5; - helper.visible = false; - scene.add(helper); - - // renderer - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - const gui = new GUI(); - gui.add(helper, 'visible').name('Show Flow Map'); - gui.open(); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 5; - controls.maxDistance = 50; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts b/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts deleted file mode 100644 index b0aed6132..000000000 --- a/examples-testing/examples/webgpu_animation_retargeting_readyplayer.ts +++ /dev/null @@ -1,167 +0,0 @@ -import * as THREE from 'three'; -import { screenUV, color, vec2, vec4, reflector, positionWorld } from 'three/tsl'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; - -import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js'; - -const [sourceModel, targetModel] = await Promise.all([ - new Promise((resolve, reject) => { - new FBXLoader().load('./models/fbx/mixamo.fbx', resolve, undefined, reject); - }), - - new Promise((resolve, reject) => { - new GLTFLoader().load('./models/gltf/readyplayer.me.glb', resolve, undefined, reject); - }), -]); - -// - -const clock = new THREE.Clock(); - -const stats = new Stats(); -document.body.appendChild(stats.dom); - -// scene - -const scene = new THREE.Scene(); - -// background - -const horizontalEffect = screenUV.x.mix(color(0x13172b), color(0x311649)); -const lightEffect = screenUV.distance(vec2(0.5, 1.0)).oneMinus().mul(color(0x0c5d68)); - -scene.backgroundNode = horizontalEffect.add(lightEffect); - -// - -const light = new THREE.HemisphereLight(0x311649, 0x0c5d68, 10); -scene.add(light); - -const backLight = new THREE.DirectionalLight(0xffffff, 10); -backLight.position.set(0, 5, -5); -scene.add(backLight); - -const keyLight = new THREE.DirectionalLight(0xfff9ea, 4); -keyLight.position.set(3, 5, 3); -scene.add(keyLight); - -const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.25, 50); -camera.position.set(0, 3, 5); - -// add models to scene -scene.add(sourceModel); -scene.add(targetModel.scene); - -// reposition models -sourceModel.position.x -= 0.9; -targetModel.scene.position.x += 0.9; - -// reajust model - mixamo use centimeters, readyplayer.me use meters (three.js scale is meters) -sourceModel.scale.setScalar(0.01); - -// retarget -const source = getSource(sourceModel); -const mixer = retargetModel(source, targetModel); - -// renderer -const renderer = new THREE.WebGPURenderer({ antialias: true }); -renderer.toneMapping = THREE.NeutralToneMapping; -renderer.setAnimationLoop(animate); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -document.body.appendChild(renderer.domElement); - -const controls = new OrbitControls(camera, renderer.domElement); -controls.minDistance = 3; -controls.maxDistance = 12; -controls.target.set(0, 1, 0); -controls.maxPolarAngle = Math.PI / 2; - -// floor -const reflection = reflector(); -reflection.target.rotateX(-Math.PI / 2); -scene.add(reflection.target); - -const reflectionMask = positionWorld.xz.distance(0).mul(0.1).clamp().oneMinus(); - -const floorMaterial = new THREE.NodeMaterial(); -floorMaterial.colorNode = vec4(reflection.rgb, reflectionMask); -floorMaterial.opacity = 0.2; -floorMaterial.transparent = true; - -const floor = new THREE.Mesh(new THREE.BoxGeometry(50, 0.001, 50), floorMaterial); -floor.receiveShadow = true; - -floor.position.set(0, 0, 0); -scene.add(floor); - -// - -function getSource(sourceModel) { - const clip = sourceModel.animations[0]; - - const helper = new THREE.SkeletonHelper(sourceModel); - const skeleton = new THREE.Skeleton(helper.bones); - - const mixer = new THREE.AnimationMixer(sourceModel); - mixer.clipAction(sourceModel.animations[0]).play(); - - return { clip, skeleton, mixer }; -} - -function retargetModel(sourceModel, targetModel) { - const targetSkin = targetModel.scene.children[0].children[1]; - - const retargetOptions = { - // specify the name of the source's hip bone. - hip: 'mixamorigHips', - - // preserve the scale of the target model - scale: 0.01, - - // use ( 0, 1, 0 ) to ignore xz hip movement. - //hipInfluence: new THREE.Vector3( 0, 1, 0 ), - - // Map of target's bone names to source's bone names -> { targetBoneName: sourceBoneName } - getBoneName: function (bone) { - return 'mixamorig' + bone.name; - }, - }; - - const retargetedClip = SkeletonUtils.retargetClip( - targetSkin, - sourceModel.skeleton, - sourceModel.clip, - retargetOptions, - ); - - const mixer = new THREE.AnimationMixer(targetSkin); - mixer.clipAction(retargetedClip).play(); - - return mixer; -} - -window.onresize = function () { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -}; - -function animate() { - const delta = clock.getDelta(); - - source.mixer.update(delta); - mixer.update(delta); - - controls.update(); - - stats.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_backdrop_area.ts b/examples-testing/examples/webgpu_backdrop_area.ts deleted file mode 100644 index 5ccf2fa1c..000000000 --- a/examples-testing/examples/webgpu_backdrop_area.ts +++ /dev/null @@ -1,164 +0,0 @@ -import * as THREE from 'three'; -import { - color, - linearDepth, - viewportLinearDepth, - viewportSharedTexture, - textureBicubic, - viewportMipTexture, - screenUV, - checker, - uv, - modelScale, -} from 'three/tsl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; -let mixer, clock; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.25, 25); - camera.position.set(3, 2, 3); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x777777); - camera.lookAt(0, 1, 0); - - clock = new THREE.Clock(); - - const light = new THREE.PointLight(0xffffff, 50); - camera.add(light); - scene.add(camera); - - const ambient = new THREE.AmbientLight(0x4466ff, 1); - scene.add(ambient); - - // model - - const loader = new GLTFLoader(); - loader.load('models/gltf/Michelle.glb', function (gltf) { - const object = gltf.scene; - mixer = new THREE.AnimationMixer(object); - - const action = mixer.clipAction(gltf.animations[0]); - action.play(); - - scene.add(object); - }); - - // volume - - // compare depth from viewportLinearDepth with linearDepth() to create a distance field - // viewportLinearDepth return the linear depth of the scene - // linearDepth() returns the linear depth of the mesh - const depthDistance = viewportLinearDepth.distance(linearDepth()); - - const depthAlphaNode = depthDistance.oneMinus().smoothstep(0.9, 2).mul(10).saturate(); - const depthBlurred = textureBicubic( - viewportMipTexture(), - depthDistance - .smoothstep(0, 0.6) - .mul(40 * 5) - .clamp(0, 5), - ); - - const blurredBlur = new THREE.MeshBasicNodeMaterial(); - blurredBlur.backdropNode = depthBlurred.add(depthAlphaNode.mix(color(0x0066ff), 0)); - blurredBlur.transparent = true; - blurredBlur.side = THREE.DoubleSide; - - const volumeMaterial = new THREE.MeshBasicNodeMaterial(); - volumeMaterial.colorNode = color(0x0066ff); - volumeMaterial.backdropNode = viewportSharedTexture(); - volumeMaterial.backdropAlphaNode = depthAlphaNode; - volumeMaterial.transparent = true; - volumeMaterial.side = THREE.DoubleSide; - - const depthMaterial = new THREE.MeshBasicNodeMaterial(); - depthMaterial.backdropNode = depthAlphaNode; - depthMaterial.transparent = true; - depthMaterial.side = THREE.DoubleSide; - - const bicubicMaterial = new THREE.MeshBasicNodeMaterial(); - bicubicMaterial.backdropNode = textureBicubic(viewportMipTexture(), 5); // @TODO: Move to alpha value [ 0, 1 ] - bicubicMaterial.backdropAlphaNode = checker(uv().mul(3).mul(modelScale.xy)); - bicubicMaterial.opacityNode = bicubicMaterial.backdropAlphaNode; - bicubicMaterial.transparent = true; - bicubicMaterial.side = THREE.DoubleSide; - - const pixelMaterial = new THREE.MeshBasicNodeMaterial(); - pixelMaterial.backdropNode = viewportSharedTexture(screenUV.mul(100).floor().div(100)); - pixelMaterial.transparent = true; - - // box / floor - - const box = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 2), volumeMaterial); - box.position.set(0, 1, 0); - scene.add(box); - - const floor = new THREE.Mesh( - new THREE.BoxGeometry(1.99, 0.01, 1.99), - new THREE.MeshBasicNodeMaterial({ color: 0x333333 }), - ); - floor.position.set(0, 0, 0); - scene.add(floor); - - // renderer - - renderer = new THREE.WebGPURenderer(/*{ antialias: true }*/); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.LinearToneMapping; - renderer.toneMappingExposure = 0.2; - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 1, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); - - // gui - - const materials = { - blurred: blurredBlur, - volume: volumeMaterial, - depth: depthMaterial, - bicubic: bicubicMaterial, - pixel: pixelMaterial, - }; - - const gui = new GUI(); - const options = { material: 'blurred' }; - - box.material = materials[options.material]; - - gui.add(box.scale, 'x', 0.1, 2, 0.01); - gui.add(box.scale, 'z', 0.1, 2, 0.01); - gui.add(options, 'material', Object.keys(materials)).onChange(name => { - box.material = materials[name]; - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) mixer.update(delta); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts b/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts deleted file mode 100644 index 155276322..000000000 --- a/examples-testing/examples/webgpu_camera_logarithmicdepthbuffer.ts +++ /dev/null @@ -1,245 +0,0 @@ -import * as THREE from 'three'; - -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -// 1 micrometer to 100 billion light years in one scene, with 1 unit = 1 meter? preposterous! and yet... -const NEAR = 1e-6, - FAR = 1e27; -let SCREEN_WIDTH = window.innerWidth; -let SCREEN_HEIGHT = window.innerHeight; -let screensplit = 0.25, - screensplit_right = 0; -const mouse = [0.5, 0.5]; -let zoompos = -100, - minzoomspeed = 0.015; -let zoomspeed = minzoomspeed; - -let container, border, stats; -const objects = {}; - -// Generate a number of text labels, from 1µm in size up to 100,000,000 light years -// Try to use some descriptive real-world examples of objects at each scale - -const labeldata = [ - { size: 0.01, scale: 0.0001, label: 'microscopic (1µm)' }, // FIXME - triangulating text fails at this size, so we scale instead - { size: 0.01, scale: 0.1, label: 'minuscule (1mm)' }, - { size: 0.01, scale: 1.0, label: 'tiny (1cm)' }, - { size: 1, scale: 1.0, label: 'child-sized (1m)' }, - { size: 10, scale: 1.0, label: 'tree-sized (10m)' }, - { size: 100, scale: 1.0, label: 'building-sized (100m)' }, - { size: 1000, scale: 1.0, label: 'medium (1km)' }, - { size: 10000, scale: 1.0, label: 'city-sized (10km)' }, - { size: 3400000, scale: 1.0, label: 'moon-sized (3,400 Km)' }, - { size: 12000000, scale: 1.0, label: 'planet-sized (12,000 km)' }, - { size: 1400000000, scale: 1.0, label: 'sun-sized (1,400,000 km)' }, - { size: 7.47e12, scale: 1.0, label: 'solar system-sized (50Au)' }, - { size: 9.4605284e15, scale: 1.0, label: 'gargantuan (1 light year)' }, - { size: 3.08567758e16, scale: 1.0, label: 'ludicrous (1 parsec)' }, - { size: 1e19, scale: 1.0, label: 'mind boggling (1000 light years)' }, -]; - -init().then(animate); - -async function init() { - container = document.getElementById('container'); - - const loader = new FontLoader(); - const font = await loader.loadAsync('fonts/helvetiker_regular.typeface.json'); - - const scene = initScene(font); - - // Initialize two copies of the same scene, one with normal z-buffer and one with logarithmic z-buffer - objects.normal = await initView(scene, 'normal', false); - objects.logzbuf = await initView(scene, 'logzbuf', true); - - stats = new Stats(); - container.appendChild(stats.dom); - - // Resize border allows the user to easily compare effects of logarithmic depth buffer over the whole scene - border = document.getElementById('renderer_border'); - border.addEventListener('pointerdown', onBorderPointerDown); - - window.addEventListener('mousemove', onMouseMove); - window.addEventListener('resize', onWindowResize); - window.addEventListener('wheel', onMouseWheel); -} - -async function initView(scene, name, logDepthBuf) { - const framecontainer = document.getElementById('container_' + name); - - const camera = new THREE.PerspectiveCamera(50, (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT, NEAR, FAR); - scene.add(camera); - - const renderer = new THREE.WebGPURenderer({ antialias: true, logarithmicDepthBuffer: logDepthBuf }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH / 2, SCREEN_HEIGHT); - renderer.domElement.style.position = 'relative'; - renderer.domElement.id = 'renderer_' + name; - framecontainer.appendChild(renderer.domElement); - - await renderer.init(); - - return { container: framecontainer, renderer: renderer, scene: scene, camera: camera }; -} - -function initScene(font) { - const scene = new THREE.Scene(); - - scene.add(new THREE.AmbientLight(0x777777)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(100, 100, 100); - scene.add(light); - - const materialargs = { - color: 0xffffff, - specular: 0x050505, - shininess: 50, - emissive: 0x000000, - }; - - const geometry = new THREE.SphereGeometry(0.5, 24, 12); - - for (let i = 0; i < labeldata.length; i++) { - const scale = labeldata[i].scale || 1; - - const labelgeo = new TextGeometry(labeldata[i].label, { - font: font, - size: labeldata[i].size, - depth: labeldata[i].size / 2, - }); - - labelgeo.computeBoundingSphere(); - - // center text - labelgeo.translate(-labelgeo.boundingSphere.radius, 0, 0); - - materialargs.color = new THREE.Color().setHSL(Math.random(), 0.5, 0.5); - - const material = new THREE.MeshPhongMaterial(materialargs); - - const group = new THREE.Group(); - group.position.z = -labeldata[i].size * scale; - scene.add(group); - - const textmesh = new THREE.Mesh(labelgeo, material); - textmesh.scale.set(scale, scale, scale); - textmesh.position.z = -labeldata[i].size * scale; - textmesh.position.y = (labeldata[i].size / 4) * scale; - group.add(textmesh); - - const dotmesh = new THREE.Mesh(geometry, material); - dotmesh.position.y = (-labeldata[i].size / 4) * scale; - dotmesh.scale.multiplyScalar(labeldata[i].size * scale); - group.add(dotmesh); - } - - return scene; -} - -function updateRendererSizes() { - // Recalculate size for both renderers when screen size or split location changes - - SCREEN_WIDTH = window.innerWidth; - SCREEN_HEIGHT = window.innerHeight; - - screensplit_right = 1 - screensplit; - - objects.normal.renderer.setSize(screensplit * SCREEN_WIDTH, SCREEN_HEIGHT); - objects.normal.camera.aspect = (screensplit * SCREEN_WIDTH) / SCREEN_HEIGHT; - objects.normal.camera.updateProjectionMatrix(); - objects.normal.camera.setViewOffset(SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH * screensplit, SCREEN_HEIGHT); - objects.normal.container.style.width = screensplit * 100 + '%'; - - objects.logzbuf.renderer.setSize(screensplit_right * SCREEN_WIDTH, SCREEN_HEIGHT); - objects.logzbuf.camera.aspect = (screensplit_right * SCREEN_WIDTH) / SCREEN_HEIGHT; - objects.logzbuf.camera.updateProjectionMatrix(); - objects.logzbuf.camera.setViewOffset( - SCREEN_WIDTH, - SCREEN_HEIGHT, - SCREEN_WIDTH * screensplit, - 0, - SCREEN_WIDTH * screensplit_right, - SCREEN_HEIGHT, - ); - objects.logzbuf.container.style.width = screensplit_right * 100 + '%'; - - border.style.left = screensplit * 100 + '%'; -} - -function animate() { - requestAnimationFrame(animate); - - // Put some limits on zooming - const minzoom = labeldata[0].size * labeldata[0].scale * 1; - const maxzoom = labeldata[labeldata.length - 1].size * labeldata[labeldata.length - 1].scale * 100; - let damping = Math.abs(zoomspeed) > minzoomspeed ? 0.95 : 1.0; - - // Zoom out faster the further out you go - const zoom = THREE.MathUtils.clamp(Math.pow(Math.E, zoompos), minzoom, maxzoom); - zoompos = Math.log(zoom); - - // Slow down quickly at the zoom limits - if ((zoom == minzoom && zoomspeed < 0) || (zoom == maxzoom && zoomspeed > 0)) { - damping = 0.85; - } - - zoompos += zoomspeed; - zoomspeed *= damping; - - objects.normal.camera.position.x = Math.sin(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; - objects.normal.camera.position.y = Math.sin(0.25 * Math.PI * (mouse[1] - 0.5)) * zoom; - objects.normal.camera.position.z = Math.cos(0.5 * Math.PI * (mouse[0] - 0.5)) * zoom; - objects.normal.camera.lookAt(objects.normal.scene.position); - - // Clone camera settings across both scenes - objects.logzbuf.camera.position.copy(objects.normal.camera.position); - objects.logzbuf.camera.quaternion.copy(objects.normal.camera.quaternion); - - // Update renderer sizes if the split has changed - if (screensplit_right != 1 - screensplit) { - updateRendererSizes(); - } - - objects.normal.renderer.render(objects.normal.scene, objects.normal.camera); - objects.logzbuf.renderer.render(objects.logzbuf.scene, objects.logzbuf.camera); - - stats.update(); -} - -function onWindowResize() { - updateRendererSizes(); -} - -function onBorderPointerDown() { - // activate draggable window resizing bar - window.addEventListener('pointermove', onBorderPointerMove); - window.addEventListener('pointerup', onBorderPointerUp); -} - -function onBorderPointerMove(ev) { - screensplit = Math.max(0, Math.min(1, ev.clientX / window.innerWidth)); -} - -function onBorderPointerUp() { - window.removeEventListener('pointermove', onBorderPointerMove); - window.removeEventListener('pointerup', onBorderPointerUp); -} - -function onMouseMove(ev) { - mouse[0] = ev.clientX / window.innerWidth; - mouse[1] = ev.clientY / window.innerHeight; -} - -function onMouseWheel(ev) { - const amount = ev.deltaY; - if (amount === 0) return; - const dir = amount / Math.abs(amount); - zoomspeed = dir / 10; - - // Slow down default zoom speed after user starts zooming, to give them more control - minzoomspeed = 0.001; -} diff --git a/examples-testing/examples/webgpu_clearcoat.ts b/examples-testing/examples/webgpu_clearcoat.ts deleted file mode 100644 index 0d5b70a2f..000000000 --- a/examples-testing/examples/webgpu_clearcoat.ts +++ /dev/null @@ -1,205 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { HDRCubeTextureLoader } from 'three/addons/loaders/HDRCubeTextureLoader.js'; - -import { FlakesTexture } from 'three/addons/textures/FlakesTexture.js'; - -let container, stats; - -let camera, scene, renderer; - -let particleLight; -let group; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 0.25, 50); - camera.position.z = 10; - - scene = new THREE.Scene(); - - group = new THREE.Group(); - scene.add(group); - - new HDRCubeTextureLoader() - .setPath('textures/cube/pisaHDR/') - .load(['px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr'], function (texture) { - const geometry = new THREE.SphereGeometry(0.8, 64, 32); - - const textureLoader = new THREE.TextureLoader(); - - const diffuse = textureLoader.load('textures/carbon/Carbon.png'); - diffuse.colorSpace = THREE.SRGBColorSpace; - diffuse.wrapS = THREE.RepeatWrapping; - diffuse.wrapT = THREE.RepeatWrapping; - diffuse.repeat.x = 10; - diffuse.repeat.y = 10; - - const normalMap = textureLoader.load('textures/carbon/Carbon_Normal.png'); - normalMap.wrapS = THREE.RepeatWrapping; - normalMap.wrapT = THREE.RepeatWrapping; - normalMap.repeat.x = 10; - normalMap.repeat.y = 10; - - const normalMap2 = textureLoader.load('textures/water/Water_1_M_Normal.jpg'); - - const normalMap3 = new THREE.CanvasTexture(new FlakesTexture()); - normalMap3.wrapS = THREE.RepeatWrapping; - normalMap3.wrapT = THREE.RepeatWrapping; - normalMap3.repeat.x = 10; - normalMap3.repeat.y = 6; - normalMap3.anisotropy = 16; - - const normalMap4 = textureLoader.load('textures/golfball.jpg'); - - const clearcoatNormalMap = textureLoader.load( - 'textures/pbr/Scratched_gold/Scratched_gold_01_1K_Normal.png', - ); - - // car paint - - let material = new THREE.MeshPhysicalMaterial({ - clearcoat: 1.0, - clearcoatRoughness: 0.1, - metalness: 0.9, - roughness: 0.5, - color: 0x0000ff, - normalMap: normalMap3, - normalScale: new THREE.Vector2(0.15, 0.15), - }); - let mesh = new THREE.Mesh(geometry, material); - mesh.position.x = -1; - mesh.position.y = 1; - group.add(mesh); - - // fibers - - material = new THREE.MeshPhysicalMaterial({ - roughness: 0.5, - clearcoat: 1.0, - clearcoatRoughness: 0.1, - map: diffuse, - normalMap: normalMap, - }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.x = 1; - mesh.position.y = 1; - group.add(mesh); - - // golf - - material = new THREE.MeshPhysicalMaterial({ - metalness: 0.0, - roughness: 0.1, - clearcoat: 1.0, - normalMap: normalMap4, - clearcoatNormalMap: clearcoatNormalMap, - - // y scale is negated to compensate for normal map handedness. - clearcoatNormalScale: new THREE.Vector2(2.0, -2.0), - }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.x = -1; - mesh.position.y = -1; - group.add(mesh); - - // clearcoat + normalmap - - material = new THREE.MeshPhysicalMaterial({ - clearcoat: 1.0, - metalness: 1.0, - color: 0xff0000, - normalMap: normalMap2, - normalScale: new THREE.Vector2(0.15, 0.15), - clearcoatNormalMap: clearcoatNormalMap, - - // y scale is negated to compensate for normal map handedness. - clearcoatNormalScale: new THREE.Vector2(2.0, -2.0), - }); - mesh = new THREE.Mesh(geometry, material); - mesh.position.x = 1; - mesh.position.y = -1; - group.add(mesh); - - // - - scene.background = texture; - scene.environment = texture; - }); - - // LIGHTS - - particleLight = new THREE.Mesh( - new THREE.SphereGeometry(0.05, 8, 8), - new THREE.MeshBasicMaterial({ color: 0xffffff }), - ); - scene.add(particleLight); - - particleLight.add(new THREE.PointLight(0xffffff, 30)); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1.25; - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // EVENTS - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 3; - controls.maxDistance = 30; - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -// - -function animate() { - render(); - - stats.update(); -} - -function render() { - const timer = Date.now() * 0.00025; - - particleLight.position.x = Math.sin(timer * 7) * 3; - particleLight.position.y = Math.cos(timer * 5) * 4; - particleLight.position.z = Math.cos(timer * 3) * 3; - - for (let i = 0; i < group.children.length; i++) { - const child = group.children[i]; - child.rotation.y += 0.005; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_clipping.ts b/examples-testing/examples/webgpu_clipping.ts deleted file mode 100644 index e57a7e96c..000000000 --- a/examples-testing/examples/webgpu_clipping.ts +++ /dev/null @@ -1,207 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, startTime, object, stats; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 0.25, 16); - - camera.position.set(0, 1.3, 3); - - scene = new THREE.Scene(); - - // Lights - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const spotLight = new THREE.SpotLight(0xffffff, 60); - spotLight.angle = Math.PI / 5; - spotLight.penumbra = 0.2; - spotLight.position.set(2, 3, 3); - spotLight.castShadow = true; - spotLight.shadow.camera.near = 3; - spotLight.shadow.camera.far = 10; - spotLight.shadow.mapSize.width = 2048; - spotLight.shadow.mapSize.height = 2048; - spotLight.shadow.bias = -0.002; - spotLight.shadow.radius = 4; - scene.add(spotLight); - - const dirLight = new THREE.DirectionalLight(0x55505a, 3); - dirLight.position.set(0, 3, 0); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 1; - dirLight.shadow.camera.far = 10; - - dirLight.shadow.camera.right = 1; - dirLight.shadow.camera.left = -1; - dirLight.shadow.camera.top = 1; - dirLight.shadow.camera.bottom = -1; - - dirLight.shadow.mapSize.width = 1024; - dirLight.shadow.mapSize.height = 1024; - scene.add(dirLight); - - // ***** Clipping planes: ***** - - const localPlane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.8); - const localPlane2 = new THREE.Plane(new THREE.Vector3(0, 0, -1), 0.1); - const globalPlane = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.1); - - // Geometry - - const material = new THREE.MeshPhongNodeMaterial({ - color: 0x80ee10, - shininess: 0, - side: THREE.DoubleSide, - - // ***** Clipping setup (material): ***** - clippingPlanes: [localPlane, localPlane2], - clipShadows: true, - alphaToCoverage: true, - clipIntersection: true, - }); - - const geometry = new THREE.TorusKnotGeometry(0.4, 0.08, 95, 20); - - object = new THREE.Mesh(geometry, material); - object.castShadow = true; - scene.add(object); - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(9, 9, 1, 1), - new THREE.MeshPhongNodeMaterial({ color: 0xa0adaf, shininess: 150 }), - ); - - ground.rotation.x = -Math.PI / 2; // rotates X/Y to X/Z - ground.receiveShadow = true; - scene.add(ground); - - // Stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // Renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.shadowMap.enabled = true; - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - window.addEventListener('resize', onWindowResize); - document.body.appendChild(renderer.domElement); - - // ***** Clipping setup (renderer): ***** - const globalPlanes = [globalPlane]; - const Empty = Object.freeze([]); - - renderer.clippingPlanes = Empty; // GUI sets it to globalPlanes - renderer.localClippingEnabled = true; - - // Controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 1, 0); - controls.update(); - - // GUI - - const gui = new GUI(), - props = { - alphaToCoverage: true, - }, - folderLocal = gui.addFolder('Local Clipping'), - propsLocal = { - get Enabled() { - return renderer.localClippingEnabled; - }, - set Enabled(v) { - renderer.localClippingEnabled = v; - }, - - get Shadows() { - return material.clipShadows; - }, - set Shadows(v) { - material.clipShadows = v; - }, - - get Intersection() { - return material.clipIntersection; - }, - - set Intersection(v) { - material.clipIntersection = v; - }, - - get Plane() { - return localPlane.constant; - }, - set Plane(v) { - localPlane.constant = v; - }, - }, - folderGlobal = gui.addFolder('Global Clipping'), - propsGlobal = { - get Enabled() { - return renderer.clippingPlanes !== Empty; - }, - set Enabled(v) { - renderer.clippingPlanes = v ? globalPlanes : Empty; - }, - - get Plane() { - return globalPlane.constant; - }, - set Plane(v) { - globalPlane.constant = v; - }, - }; - - gui.add(props, 'alphaToCoverage').onChange(function (value) { - ground.material.alphaToCoverage = value; - ground.material.needsUpdate = true; - - material.alphaToCoverage = value; - material.needsUpdate = true; - }); - - folderLocal.add(propsLocal, 'Enabled'); - folderLocal.add(propsLocal, 'Shadows'); - folderLocal.add(propsLocal, 'Intersection'); - folderLocal.add(propsLocal, 'Plane', 0.3, 1.25); - - folderGlobal.add(propsGlobal, 'Enabled'); - folderGlobal.add(propsGlobal, 'Plane', -0.4, 3); - - // Start - - startTime = Date.now(); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate(currentTime) { - const time = (currentTime - startTime) / 1000; - - object.position.y = 0.8; - object.rotation.x = time * 0.5; - object.rotation.y = time * 0.2; - object.scale.setScalar(Math.cos(time) * 0.125 + 0.875); - - stats.begin(); - renderer.render(scene, camera); - stats.end(); -} diff --git a/examples-testing/examples/webgpu_custom_fog_background.ts b/examples-testing/examples/webgpu_custom_fog_background.ts deleted file mode 100644 index 4a2e6c800..000000000 --- a/examples-testing/examples/webgpu_custom_fog_background.ts +++ /dev/null @@ -1,93 +0,0 @@ -import * as THREE from 'three'; -import { pass, color, rangeFog } from 'three/tsl'; - -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, scene, renderer; -let postProcessing; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - //renderer.toneMapping = THREE.ACESFilmicToneMapping; // apply tone mapping in post processing - container.appendChild(renderer.domElement); - - // post processing - - // render scene pass ( the same of css ) - const scenePass = pass(scene, camera); - const scenePassViewZ = scenePass.getViewZNode(); - - // background color - const backgroundColor = color(0x0066ff); - - // get fog factor from scene pass context - // equivalent to: scene.fog = new THREE.Fog( 0x0066ff, 2.7, 4 ); - const fogFactor = rangeFog(null, 2.7, 4).context({ getViewZ: () => scenePassViewZ }); - - // tone mapping scene pass - const scenePassTM = scenePass.toneMapping(THREE.ACESFilmicToneMapping); - - // mix fog from fog factor and background color - const compose = fogFactor.mix(scenePassTM, backgroundColor); - - postProcessing = new THREE.PostProcessing(renderer); - postProcessing.outputNode = compose; - - // - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.environment = texture; - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', function (gltf) { - scene.add(gltf.scene); - - render(); - }); - }); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 5; - controls.target.set(0, -0.1, -0.2); - controls.update(); - controls.addEventListener('change', render); // use if there is no animation loop - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - postProcessing.renderAsync(); -} diff --git a/examples-testing/examples/webgpu_display_stereo.ts b/examples-testing/examples/webgpu_display_stereo.ts deleted file mode 100644 index 7eb45fa2a..000000000 --- a/examples-testing/examples/webgpu_display_stereo.ts +++ /dev/null @@ -1,139 +0,0 @@ -import * as THREE from 'three'; - -import { stereoPass, anaglyphPass, parallaxBarrierPass } from 'three/tsl'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Timer } from 'three/addons/misc/Timer.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, postProcessing; - -let stereo, anaglyph, parallaxBarrier; - -let mesh, dummy, timer; - -const position = new THREE.Vector3(); - -const params = { - effect: 'stereo', - eyeSep: 0.064, -}; - -const effects = { Stereo: 'stereo', Anaglyph: 'anaglyph', ParallaxBarrier: 'parallaxBarrier' }; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 3; - - scene = new THREE.Scene(); - scene.background = new THREE.CubeTextureLoader() - .setPath('textures/cube/Park3Med/') - .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']); - - timer = new Timer(); - - const geometry = new THREE.SphereGeometry(0.1, 32, 16); - - const textureCube = new THREE.CubeTextureLoader() - .setPath('textures/cube/Park3Med/') - .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']); - - const material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: textureCube }); - - mesh = new THREE.InstancedMesh(geometry, material, 500); - mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); - - dummy = new THREE.Mesh(); - - for (let i = 0; i < 500; i++) { - dummy.position.x = Math.random() * 10 - 5; - dummy.position.y = Math.random() * 10 - 5; - dummy.position.z = Math.random() * 10 - 5; - dummy.scale.x = dummy.scale.y = dummy.scale.z = Math.random() * 3 + 1; - - dummy.updateMatrix(); - - mesh.setMatrixAt(i, dummy.matrix); - } - - scene.add(mesh); - - // - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - postProcessing = new THREE.PostProcessing(renderer); - stereo = stereoPass(scene, camera); - anaglyph = anaglyphPass(scene, camera); - parallaxBarrier = parallaxBarrierPass(scene, camera); - - postProcessing.outputNode = stereo; - - const gui = new GUI(); - gui.add(params, 'effect', effects).onChange(update); - gui.add(params, 'eyeSep', 0.001, 0.15, 0.001).onChange(function (value) { - stereo.stereo.eyeSep = value; - - anaglyph.stereo.eyeSep = value; - parallaxBarrier.stereo.eyeSep = value; - }); - - window.addEventListener('resize', onWindowResize); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 25; -} - -function update(value) { - if (value === 'stereo') { - postProcessing.outputNode = stereo; - } else if (value === 'anaglyph') { - postProcessing.outputNode = anaglyph; - } else if (value === 'parallaxBarrier') { - postProcessing.outputNode = parallaxBarrier; - } - - postProcessing.needsUpdate = true; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function extractPosition(matrix, position) { - position.x = matrix.elements[12]; - position.y = matrix.elements[13]; - position.z = matrix.elements[14]; -} - -function animate() { - timer.update(); - - const elapsedTime = timer.getElapsed() * 0.1; - - for (let i = 0; i < mesh.count; i++) { - mesh.getMatrixAt(i, dummy.matrix); - - extractPosition(dummy.matrix, position); - - position.x = 5 * Math.cos(elapsedTime + i); - position.y = 5 * Math.sin(elapsedTime + i * 1.1); - - dummy.matrix.setPosition(position); - - mesh.setMatrixAt(i, dummy.matrix); - - mesh.instanceMatrix.needsUpdate = true; - } - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_instancing_morph.ts b/examples-testing/examples/webgpu_instancing_morph.ts deleted file mode 100644 index cfd721721..000000000 --- a/examples-testing/examples/webgpu_instancing_morph.ts +++ /dev/null @@ -1,148 +0,0 @@ -import * as THREE from 'three'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer, stats, mesh, mixer, dummy; - -const offset = 5000; - -const timeOffsets = new Float32Array(1024); - -for (let i = 0; i < 1024; i++) { - timeOffsets[i] = Math.random() * 3; -} - -const clock = new THREE.Clock(true); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 10000); - - scene = new THREE.Scene(); - - scene.background = new THREE.Color(0x99ddff); - - scene.fog = new THREE.Fog(0x99ddff, 5000, 10000); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - const light = new THREE.DirectionalLight(0xffffff, 1); - - light.position.set(200, 1000, 50); - - light.shadow.mapSize.width = 2048; - light.shadow.mapSize.height = 2048; - light.castShadow = true; - - light.shadow.camera.left = -5000; - light.shadow.camera.right = 5000; - light.shadow.camera.top = 5000; - light.shadow.camera.bottom = -5000; - light.shadow.camera.far = 2000; - - light.shadow.bias = -0.01; - - light.shadow.camera.updateProjectionMatrix(); - - scene.add(light); - - const hemi = new THREE.HemisphereLight(0x99ddff, 0x669933, 1 / 3); - - scene.add(hemi); - - const ground = new THREE.Mesh( - new THREE.PlaneGeometry(1000000, 1000000), - new THREE.MeshStandardMaterial({ color: 0x669933 }), - ); - - ground.rotation.x = -Math.PI / 2; - - ground.receiveShadow = true; - - scene.add(ground); - - const loader = new GLTFLoader(); - - loader.load('models/gltf/Horse.glb', function (glb) { - dummy = glb.scene.children[0]; - - mesh = new THREE.InstancedMesh( - dummy.geometry, - new THREE.MeshStandardNodeMaterial({ - flatShading: true, - }), - 1024, - ); - - mesh.castShadow = true; - - for (let x = 0, i = 0; x < 32; x++) { - for (let y = 0; y < 32; y++) { - dummy.position.set(offset - 300 * x + 200 * Math.random(), 0, offset - 300 * y); - - dummy.updateMatrix(); - - mesh.setMatrixAt(i, dummy.matrix); - - mesh.setColorAt(i, new THREE.Color(`hsl(${Math.random() * 360}, 50%, 66%)`)); - - i++; - } - } - - scene.add(mesh); - - mixer = new THREE.AnimationMixer(glb.scene); - - const action = mixer.clipAction(glb.animations[0]); - - action.play(); - }); - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setAnimationLoop(animate); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const time = clock.getElapsedTime(); - - const r = 3000; - camera.position.set(Math.sin(time / 10) * r, 1500 + 1000 * Math.cos(time / 5), Math.cos(time / 10) * r); - camera.lookAt(0, 0, 0); - - if (mesh) { - for (let i = 0; i < 1024; i++) { - mixer.setTime(time + timeOffsets[i]); - - mesh.setMorphAt(i, dummy); - } - - mesh.morphTexture.needsUpdate = true; - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_lensflares.ts b/examples-testing/examples/webgpu_lensflares.ts deleted file mode 100644 index 8c157b4b1..000000000 --- a/examples-testing/examples/webgpu_lensflares.ts +++ /dev/null @@ -1,140 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { FlyControls } from 'three/addons/controls/FlyControls.js'; -import { LensflareMesh, LensflareElement } from 'three/addons/objects/LensflareMesh.js'; - -let container, stats; - -let camera, scene, renderer; -let controls; - -const clock = new THREE.Clock(); - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - // camera - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 15000); - camera.position.z = 250; - - // scene - - scene = new THREE.Scene(); - scene.background = new THREE.Color().setHSL(0.51, 0.4, 0.01, THREE.SRGBColorSpace); - scene.fog = new THREE.Fog(scene.background, 3500, 15000); - - // world - - const s = 250; - - const geometry = new THREE.BoxGeometry(s, s, s); - const material = new THREE.MeshPhongNodeMaterial({ color: 0xffffff, specular: 0xffffff, shininess: 50 }); - - for (let i = 0; i < 3000; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = 8000 * (2.0 * Math.random() - 1.0); - mesh.position.y = 8000 * (2.0 * Math.random() - 1.0); - mesh.position.z = 8000 * (2.0 * Math.random() - 1.0); - - mesh.rotation.x = Math.random() * Math.PI; - mesh.rotation.y = Math.random() * Math.PI; - mesh.rotation.z = Math.random() * Math.PI; - - mesh.matrixAutoUpdate = false; - mesh.updateMatrix(); - - scene.add(mesh); - } - - // lights - - const dirLight = new THREE.DirectionalLight(0xffffff, 0.15); - dirLight.position.set(0, -1, 0).normalize(); - dirLight.color.setHSL(0.1, 0.7, 0.5); - scene.add(dirLight); - - // lensflares - const textureLoader = new THREE.TextureLoader(); - - const textureFlare0 = textureLoader.load('textures/lensflare/lensflare0.png'); - const textureFlare3 = textureLoader.load('textures/lensflare/lensflare3.png'); - - textureFlare0.colorSpace = THREE.SRGBColorSpace; - textureFlare3.colorSpace = THREE.SRGBColorSpace; - - addLight(0.55, 0.95, 0.6, 5000, 0, -1000); - addLight(0.1, 0.85, 0.65, 0, 0, -1000); - addLight(0.995, 0.5, 0.95, 5000, 5000, -1000); - - function addLight(h, s, l, x, y, z) { - const light = new THREE.PointLight(0xffffff, 1.5, 2000, 0); - light.color.setHSL(h, s, l); - light.position.set(x, y, z); - scene.add(light); - - const lensflare = new LensflareMesh(); - lensflare.addElement(new LensflareElement(textureFlare0, 700, 0, light.color)); - lensflare.addElement(new LensflareElement(textureFlare3, 60, 0.6)); - lensflare.addElement(new LensflareElement(textureFlare3, 70, 0.7)); - lensflare.addElement(new LensflareElement(textureFlare3, 120, 0.9)); - lensflare.addElement(new LensflareElement(textureFlare3, 70, 1)); - light.add(lensflare); - } - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: false }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - controls = new FlyControls(camera, renderer.domElement); - - controls.movementSpeed = 2500; - controls.domElement = container; - controls.rollSpeed = Math.PI / 6; - controls.autoForward = false; - controls.dragToLook = false; - - // stats - - stats = new Stats(); - container.appendChild(stats.dom); - - // events - - window.addEventListener('resize', onWindowResize); -} - -// - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -// - -function animate() { - render(); - stats.update(); -} - -function render() { - const delta = clock.getDelta(); - - controls.update(delta); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_lightprobe.ts b/examples-testing/examples/webgpu_lightprobe.ts deleted file mode 100644 index 66f9ffcb2..000000000 --- a/examples-testing/examples/webgpu_lightprobe.ts +++ /dev/null @@ -1,135 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { LightProbeGenerator } from 'three/addons/lights/LightProbeGenerator.js'; - -import { LightProbeHelper } from 'three/addons/helpers/LightProbeHelperGPU.js'; - -let mesh, renderer, scene, camera; - -let gui; - -let lightProbe; -let directionalLight; - -// linear color space -const API = { - lightProbeIntensity: 1.0, - directionalLightIntensity: 0.6, - envMapIntensity: 1, -}; - -init(); - -function init() { - // renderer - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // tone mapping - renderer.toneMapping = THREE.NoToneMapping; - - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 0, 30); - - // controls - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 10; - controls.maxDistance = 50; - controls.enablePan = false; - - // probe - lightProbe = new THREE.LightProbe(); - scene.add(lightProbe); - - // light - directionalLight = new THREE.DirectionalLight(0xffffff, API.directionalLightIntensity); - directionalLight.position.set(10, 10, 10); - scene.add(directionalLight); - - // envmap - const genCubeUrls = function (prefix, postfix) { - return [ - prefix + 'px' + postfix, - prefix + 'nx' + postfix, - prefix + 'py' + postfix, - prefix + 'ny' + postfix, - prefix + 'pz' + postfix, - prefix + 'nz' + postfix, - ]; - }; - - const urls = genCubeUrls('textures/cube/pisa/', '.png'); - - new THREE.CubeTextureLoader().load(urls, function (cubeTexture) { - scene.background = cubeTexture; - - lightProbe.copy(LightProbeGenerator.fromCubeTexture(cubeTexture)); - lightProbe.intensity = API.lightProbeIntensity; - lightProbe.position.set(-10, 0, 0); // position not used in scene lighting calculations (helper honors the position, however) - - const geometry = new THREE.SphereGeometry(5, 64, 32); - //const geometry = new THREE.TorusKnotGeometry( 4, 1.5, 256, 32, 2, 3 ); - - const material = new THREE.MeshStandardMaterial({ - color: 0xffffff, - metalness: 0, - roughness: 0, - envMap: cubeTexture, - envMapIntensity: API.envMapIntensity, - }); - - // mesh - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // helper - const helper = new LightProbeHelper(lightProbe, 1); - scene.add(helper); - }); - - // gui - gui = new GUI({ title: 'Intensity' }); - - gui.add(API, 'lightProbeIntensity', 0, 1, 0.02) - .name('light probe') - .onChange(function () { - lightProbe.intensity = API.lightProbeIntensity; - }); - - gui.add(API, 'directionalLightIntensity', 0, 1, 0.02) - .name('directional light') - .onChange(function () { - directionalLight.intensity = API.directionalLightIntensity; - }); - - gui.add(API, 'envMapIntensity', 0, 1, 0.02) - .name('envMap') - .onChange(function () { - mesh.material.envMapIntensity = API.envMapIntensity; - }); - - // listener - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_lights_ies_spotlight.ts b/examples-testing/examples/webgpu_lights_ies_spotlight.ts deleted file mode 100644 index 41b56de88..000000000 --- a/examples-testing/examples/webgpu_lights_ies_spotlight.ts +++ /dev/null @@ -1,117 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from './jsm/controls/OrbitControls.js'; - -import { IESLoader } from 'three/addons/loaders/IESLoader.js'; - -let renderer, scene, camera; -let lights; - -async function init() { - const iesLoader = new IESLoader().setPath('./ies/'); - //iesLoader.type = THREE.UnsignedByteType; // LDR - - const [iesTexture1, iesTexture2, iesTexture3, iesTexture4] = await Promise.all([ - iesLoader.loadAsync('007cfb11e343e2f42e3b476be4ab684e.ies'), - iesLoader.loadAsync('06b4cfdc8805709e767b5e2e904be8ad.ies'), - iesLoader.loadAsync('02a7562c650498ebb301153dbbf59207.ies'), - iesLoader.loadAsync('1a936937a49c63374e6d4fbed9252b29.ies'), - ]); - - // - - scene = new THREE.Scene(); - - // - - const spotLight = new THREE.IESSpotLight(0xff0000, 500); - spotLight.position.set(6.5, 1.5, 6.5); - spotLight.angle = Math.PI / 8; - spotLight.penumbra = 0.7; - spotLight.distance = 20; - spotLight.iesMap = iesTexture1; - scene.add(spotLight); - - // - - const spotLight2 = new THREE.IESSpotLight(0x00ff00, 500); - spotLight2.position.set(6.5, 1.5, -6.5); - spotLight2.angle = Math.PI / 8; - spotLight2.penumbra = 0.7; - spotLight2.distance = 20; - spotLight2.iesMap = iesTexture2; - scene.add(spotLight2); - - // - - const spotLight3 = new THREE.IESSpotLight(0x0000ff, 500); - spotLight3.position.set(-6.5, 1.5, -6.5); - spotLight3.angle = Math.PI / 8; - spotLight3.penumbra = 0.7; - spotLight3.distance = 20; - spotLight3.iesMap = iesTexture3; - scene.add(spotLight3); - - // - - const spotLight4 = new THREE.IESSpotLight(0xffffff, 500); - spotLight4.position.set(-6.5, 1.5, 6.5); - spotLight4.angle = Math.PI / 8; - spotLight4.penumbra = 0.7; - spotLight4.distance = 20; - spotLight4.iesMap = iesTexture4; - scene.add(spotLight4); - - // - - lights = [spotLight, spotLight2, spotLight3, spotLight4]; - - // - - const material = new THREE.MeshPhongMaterial({ color: 0x808080 /*, dithering: true*/ }); - - const geometry = new THREE.PlaneGeometry(200, 200); - - const mesh = new THREE.Mesh(geometry, material); - mesh.rotation.x = -Math.PI * 0.5; - scene.add(mesh); - - // - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(16, 4, 1); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 50; - controls.enablePan = false; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function render(time) { - time = (time / 1000) * 2.0; - - for (let i = 0; i < lights.length; i++) { - lights[i].position.y = Math.sin(time + i) + 0.97; - } - - renderer.render(scene, camera); -} - -init(); diff --git a/examples-testing/examples/webgpu_lights_rectarealight.ts b/examples-testing/examples/webgpu_lights_rectarealight.ts deleted file mode 100644 index 5638c9029..000000000 --- a/examples-testing/examples/webgpu_lights_rectarealight.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RectAreaLightHelper } from 'three/addons/helpers/RectAreaLightHelper.js'; -import { RectAreaLightTexturesLib } from 'three/addons/lights/RectAreaLightTexturesLib.js'; - -let renderer, scene, camera; -let stats, meshKnot; - -init(); - -function init() { - THREE.RectAreaLightNode.setLTC(RectAreaLightTexturesLib.init()); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animation); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 5, -15); - - scene = new THREE.Scene(); - - const rectLight1 = new THREE.RectAreaLight(0xff0000, 5, 4, 10); - rectLight1.position.set(-5, 5, 5); - scene.add(rectLight1); - - const rectLight2 = new THREE.RectAreaLight(0x00ff00, 5, 4, 10); - rectLight2.position.set(0, 5, 5); - scene.add(rectLight2); - - const rectLight3 = new THREE.RectAreaLight(0x0000ff, 5, 4, 10); - rectLight3.position.set(5, 5, 5); - scene.add(rectLight3); - - scene.add(new RectAreaLightHelper(rectLight1)); - scene.add(new RectAreaLightHelper(rectLight2)); - scene.add(new RectAreaLightHelper(rectLight3)); - - const geoFloor = new THREE.BoxGeometry(2000, 0.1, 2000); - const matStdFloor = new THREE.MeshStandardMaterial({ color: 0xbcbcbc, roughness: 0.1, metalness: 0 }); - const mshStdFloor = new THREE.Mesh(geoFloor, matStdFloor); - scene.add(mshStdFloor); - - const geoKnot = new THREE.TorusKnotGeometry(1.5, 0.5, 200, 16); - const matKnot = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0, metalness: 0 }); - meshKnot = new THREE.Mesh(geoKnot, matKnot); - meshKnot.position.set(0, 5, 0); - scene.add(meshKnot); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.copy(meshKnot.position); - controls.update(); - - // - - window.addEventListener('resize', onWindowResize); - - stats = new Stats(); - document.body.appendChild(stats.dom); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); -} - -function animation(time) { - meshKnot.rotation.y = time / 1000; - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_loader_gltf.ts b/examples-testing/examples/webgpu_loader_gltf.ts deleted file mode 100644 index 64d1fda4b..000000000 --- a/examples-testing/examples/webgpu_loader_gltf.ts +++ /dev/null @@ -1,71 +0,0 @@ -import * as THREE from 'three'; - -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - //texture.minFilter = THREE.LinearMipmapLinearFilter; - //texture.generateMipmaps = true; - - scene.background = texture; - scene.environment = texture; - - render(); - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', function (gltf) { - scene.add(gltf.scene); - - render(); - }); - }); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.addEventListener('change', render); // use if there is no animation loop - controls.minDistance = 2; - controls.maxDistance = 10; - controls.target.set(0, 0, -0.2); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -// - -function render() { - renderer.renderAsync(scene, camera); -} diff --git a/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts b/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts deleted file mode 100644 index d100e8c81..000000000 --- a/examples-testing/examples/webgpu_loader_gltf_anisotropy.ts +++ /dev/null @@ -1,65 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let renderer, scene, camera, controls; - -init(); - -async function init() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1.35; - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.set(-0.35, -0.2, 0.35); - - controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, -0.08, 0.11); - controls.minDistance = 0.1; - controls.maxDistance = 2; - controls.addEventListener('change', render); - controls.update(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - const gltfLoader = new GLTFLoader().setPath('models/gltf/'); - - const [texture, gltf] = await Promise.all([ - rgbeLoader.loadAsync('royal_esplanade_1k.hdr'), - gltfLoader.loadAsync('AnisotropyBarnLamp.glb'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.backgroundBlurriness = 0.5; - scene.environment = texture; - - // model - - scene.add(gltf.scene); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function render() { - renderer.renderAsync(scene, camera); -} diff --git a/examples-testing/examples/webgpu_loader_gltf_compressed.ts b/examples-testing/examples/webgpu_loader_gltf_compressed.ts deleted file mode 100644 index 9405b64ae..000000000 --- a/examples-testing/examples/webgpu_loader_gltf_compressed.ts +++ /dev/null @@ -1,67 +0,0 @@ -import * as THREE from 'three'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; -import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -init(); - -async function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 20); - camera.position.set(2, 2, 2); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xeeeeee); - - //lights - - const light = new THREE.PointLight(0xffffff); - light.power = 1300; - camera.add(light); - scene.add(camera); - - //renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ReinhardToneMapping; - renderer.toneMappingExposure = 1; - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 3; - controls.maxDistance = 6; - controls.update(); - - const ktx2Loader = await new KTX2Loader().setTranscoderPath('jsm/libs/basis/').detectSupportAsync(renderer); - - const loader = new GLTFLoader(); - loader.setKTX2Loader(ktx2Loader); - loader.setMeshoptDecoder(MeshoptDecoder); - loader.load('models/gltf/coffeemat.glb', function (gltf) { - const gltfScene = gltf.scene; - gltfScene.position.y = -0.8; - gltfScene.scale.setScalar(0.01); - - scene.add(gltfScene); - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_loader_gltf_dispersion.ts b/examples-testing/examples/webgpu_loader_gltf_dispersion.ts deleted file mode 100644 index c0290b98f..000000000 --- a/examples-testing/examples/webgpu_loader_gltf_dispersion.ts +++ /dev/null @@ -1,63 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let camera, scene, renderer; - -init(); - -async function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 5); - camera.position.set(0.1, 0.05, 0.15); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - renderer.toneMapping = THREE.ReinhardToneMapping; // TODO: Add THREE.NeutralToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - const rgbeLoader = await new RGBELoader() - .setPath('textures/equirectangular/') - .loadAsync('pedestrian_overpass_1k.hdr'); - rgbeLoader.mapping = THREE.EquirectangularReflectionMapping; - - scene = new THREE.Scene(); - scene.backgroundBlurriness = 0.5; - scene.environment = rgbeLoader; - scene.background = rgbeLoader; - - const loader = new GLTFLoader(); - const gltf = await loader.loadAsync('models/gltf/DispersionTest.glb'); - - scene.add(gltf.scene); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 0.1; - controls.maxDistance = 10; - controls.target.set(0, 0, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_loader_gltf_iridescence.ts b/examples-testing/examples/webgpu_loader_gltf_iridescence.ts deleted file mode 100644 index f163ea770..000000000 --- a/examples-testing/examples/webgpu_loader_gltf_iridescence.ts +++ /dev/null @@ -1,70 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let renderer, scene, camera, controls; - -init().catch(function (err) { - console.error(err); -}); - -async function init() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setAnimationLoop(render); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - document.body.appendChild(renderer.domElement); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.05, 20); - camera.position.set(0.35, 0.05, 0.35); - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = -0.5; - controls.target.set(0, 0.2, 0); - controls.update(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - - const gltfLoader = new GLTFLoader().setPath('models/gltf/'); - - const [texture, gltf] = await Promise.all([ - rgbeLoader.loadAsync('venice_sunset_1k.hdr'), - gltfLoader.loadAsync('IridescenceLamp.glb'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - scene.add(gltf.scene); - - render(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - render(); -} - -function render() { - controls.update(); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_loader_gltf_sheen.ts b/examples-testing/examples/webgpu_loader_gltf_sheen.ts deleted file mode 100644 index 788ef2a89..000000000 --- a/examples-testing/examples/webgpu_loader_gltf_sheen.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, controls; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 20); - camera.position.set(-0.75, 0.7, 1.25); - - scene = new THREE.Scene(); - //scene.add( new THREE.DirectionalLight( 0xffffff, 2 ) ); - - // model - - new GLTFLoader().setPath('models/gltf/').load('SheenChair.glb', function (gltf) { - scene.add(gltf.scene); - - const object = gltf.scene.getObjectByName('SheenChair_fabric'); - - const gui = new GUI(); - - gui.add(object.material, 'sheen', 0, 1); - gui.open(); - }); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - scene.background = new THREE.Color(0xaaaaaa); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - //scene.backgroundBlurriness = 1; // @TODO: Needs PMREM - scene.environment = texture; - }); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 1; - controls.maxDistance = 10; - controls.target.set(0, 0.35, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - controls.update(); // required if damping enabled - - render(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_loader_gltf_transmission.ts b/examples-testing/examples/webgpu_loader_gltf_transmission.ts deleted file mode 100644 index 040233262..000000000 --- a/examples-testing/examples/webgpu_loader_gltf_transmission.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -let camera, scene, renderer, controls, clock, mixer; - -init(); - -function init() { - clock = new THREE.Clock(); - - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(0, 0.4, 0.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.backgroundBlurriness = 0.35; - - scene.environment = texture; - - // model - - new GLTFLoader() - .setPath('models/gltf/') - .setDRACOLoader(new DRACOLoader().setDecoderPath('jsm/libs/draco/gltf/')) - .load('IridescentDishWithOlives.glb', function (gltf) { - mixer = new THREE.AnimationMixer(gltf.scene); - mixer.clipAction(gltf.animations[0]).play(); - - scene.add(gltf.scene); - }); - }); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setAnimationLoop(render); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - container.appendChild(renderer.domElement); - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = -0.75; - controls.enableDamping = true; - controls.minDistance = 0.5; - controls.maxDistance = 1; - controls.target.set(0, 0.1, 0); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - if (mixer) mixer.update(clock.getDelta()); - - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_materials_arrays.ts b/examples-testing/examples/webgpu_materials_arrays.ts deleted file mode 100644 index 35a25f77e..000000000 --- a/examples-testing/examples/webgpu_materials_arrays.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let renderer, scene, camera, controls; -let planeMesh, boxMesh, boxMeshWireframe, planeMeshWireframe; -let materials; - -const api = { - webgpu: true, -}; - -init(!api.webgpu); - -function init(forceWebGL = false) { - if (renderer) { - renderer.dispose(); - controls.dispose(); - document.body.removeChild(renderer.domElement); - } - - // renderer - renderer = new THREE.WebGPURenderer({ - forceWebGL, - antialias: true, - }); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // scene - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x000000); - - // camera - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(0, 0, 10); - - // controls - controls = new OrbitControls(camera, renderer.domElement); - - // materials - materials = [ - new THREE.MeshBasicMaterial({ color: 0xff1493, side: THREE.DoubleSide }), - new THREE.MeshBasicMaterial({ color: 0x0000ff, side: THREE.DoubleSide }), - new THREE.MeshBasicMaterial({ color: 0x00ff00, side: THREE.DoubleSide }), - ]; - - // plane geometry - const planeGeometry = new THREE.PlaneGeometry(1, 1, 4, 4); - - planeGeometry.clearGroups(); - const numFacesPerRow = 4; // Number of faces in a row (since each face is made of 2 triangles) - - planeGeometry.addGroup(0, 6 * numFacesPerRow, 0); - planeGeometry.addGroup(6 * numFacesPerRow, 6 * numFacesPerRow, 1); - planeGeometry.addGroup(12 * numFacesPerRow, 6 * numFacesPerRow, 2); - - // box geometry - const boxGeometry = new THREE.BoxGeometry(0.75, 0.75, 0.75); - - boxGeometry.clearGroups(); - boxGeometry.addGroup(0, 6, 0); // front face - boxGeometry.addGroup(6, 6, 0); // back face - boxGeometry.addGroup(12, 6, 2); // top face - boxGeometry.addGroup(18, 6, 2); // bottom face - boxGeometry.addGroup(24, 6, 1); // left face - boxGeometry.addGroup(30, 6, 1); // right face - - scene.background = forceWebGL ? new THREE.Color(0x000000) : new THREE.Color(0x222222); - - // meshes - planeMesh = new THREE.Mesh(planeGeometry, materials); - - const materialsWireframe = []; - - for (let index = 0; index < materials.length; index++) { - const material = new THREE.MeshBasicMaterial({ - color: materials[index].color, - side: THREE.DoubleSide, - wireframe: true, - }); - materialsWireframe.push(material); - } - - planeMeshWireframe = new THREE.Mesh(planeGeometry, materialsWireframe); - boxMeshWireframe = new THREE.Mesh(boxGeometry, materialsWireframe); - - boxMesh = new THREE.Mesh(boxGeometry, materials); - - planeMesh.position.set(-1.5, -1, 0); - boxMesh.position.set(1.5, -0.75, 0); - boxMesh.rotation.set(-Math.PI / 8, Math.PI / 4, Math.PI / 4); - - planeMeshWireframe.position.set(-1.5, 1, 0); - boxMeshWireframe.position.set(1.5, 1.25, 0); - boxMeshWireframe.rotation.set(-Math.PI / 8, Math.PI / 4, Math.PI / 4); - - scene.add(planeMesh, planeMeshWireframe); - scene.add(boxMesh, boxMeshWireframe); -} - -function animate() { - boxMesh.rotation.y += 0.005; - boxMesh.rotation.x += 0.005; - boxMeshWireframe.rotation.y += 0.005; - boxMeshWireframe.rotation.x += 0.005; - renderer.render(scene, camera); -} - -// gui - -const gui = new GUI(); - -gui.add(api, 'webgpu').onChange(() => { - init(!api.webgpu); -}); - -// listeners - -window.addEventListener('resize', onWindowResize); - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} diff --git a/examples-testing/examples/webgpu_materials_basic.ts b/examples-testing/examples/webgpu_materials_basic.ts deleted file mode 100644 index 0161a9c7b..000000000 --- a/examples-testing/examples/webgpu_materials_basic.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -const spheres = []; - -let mouseX = 0; -let mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -const params = { - color: '#ffffff', - mapping: THREE.CubeReflectionMapping, - refractionRatio: 0.98, - transparent: false, - opacity: 1, -}; - -const mappings = { ReflectionMapping: THREE.CubeReflectionMapping, RefractionMapping: THREE.CubeRefractionMapping }; - -document.addEventListener('mousemove', onDocumentMouseMove); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 100); - camera.position.z = 3; - - const path = './textures/cube/pisa/'; - const format = '.png'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const textureCube = new THREE.CubeTextureLoader().load(urls); - - scene = new THREE.Scene(); - scene.background = textureCube; - - const geometry = new THREE.SphereGeometry(0.1, 32, 16); - const material = new THREE.MeshBasicMaterial({ color: 0xffffff, envMap: textureCube }); - - for (let i = 0; i < 500; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = Math.random() * 10 - 5; - mesh.position.y = Math.random() * 10 - 5; - mesh.position.z = Math.random() * 10 - 5; - - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 3 + 1; - - scene.add(mesh); - - spheres.push(mesh); - } - - // - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - const gui = new GUI({ width: 300 }); - - gui.addColor(params, 'color').onChange(value => material.color.set(value)); - gui.add(params, 'mapping', mappings).onChange(value => { - textureCube.mapping = value; - material.needsUpdate = true; - }); - gui.add(params, 'refractionRatio') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(value => (material.refractionRatio = value)); - gui.add(params, 'transparent').onChange(value => { - material.transparent = value; - material.needsUpdate = true; - }); - gui.add(params, 'opacity') - .min(0.0) - .max(1.0) - .step(0.01) - .onChange(value => (material.opacity = value)); - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - mouseX = (event.clientX - windowHalfX) / 100; - mouseY = (event.clientY - windowHalfY) / 100; -} - -// - -function animate() { - const timer = 0.0001 * Date.now(); - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - for (let i = 0, il = spheres.length; i < il; i++) { - const sphere = spheres[i]; - - sphere.position.x = 5 * Math.cos(timer + i); - sphere.position.y = 5 * Math.sin(timer + i * 1.1); - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_materials_displacementmap.ts b/examples-testing/examples/webgpu_materials_displacementmap.ts deleted file mode 100644 index 54d26d65e..000000000 --- a/examples-testing/examples/webgpu_materials_displacementmap.ts +++ /dev/null @@ -1,224 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; - -let stats; -let camera, scene, renderer, controls; - -const settings = { - metalness: 1.0, - roughness: 0.4, - ambientIntensity: 0.2, - aoMapIntensity: 1.0, - envMapIntensity: 1.0, - displacementScale: 2.436143, // from original model - normalScale: 1.0, -}; - -let mesh, material; - -let pointLight, ambientLight; - -const height = 500; // of camera frustum - -let r = 0.0; - -init(); -initGui(); - -// Init gui -function initGui() { - const gui = new GUI(); - - gui.add(settings, 'metalness') - .min(0) - .max(1) - .onChange(function (value) { - material.metalness = value; - }); - - gui.add(settings, 'roughness') - .min(0) - .max(1) - .onChange(function (value) { - material.roughness = value; - }); - - gui.add(settings, 'aoMapIntensity') - .min(0) - .max(1) - .onChange(function (value) { - material.aoMapIntensity = value; - }); - - gui.add(settings, 'ambientIntensity') - .min(0) - .max(1) - .onChange(function (value) { - ambientLight.intensity = value; - }); - - gui.add(settings, 'envMapIntensity') - .min(0) - .max(3) - .onChange(function (value) { - material.envMapIntensity = value; - }); - - gui.add(settings, 'displacementScale') - .min(0) - .max(3.0) - .onChange(function (value) { - material.displacementScale = value; - }); - - gui.add(settings, 'normalScale') - .min(-1) - .max(1) - .onChange(function (value) { - material.normalScale.set(1, -1).multiplyScalar(value); - }); -} - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGPURenderer(); - renderer.setAnimationLoop(animate); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - container.appendChild(renderer.domElement); - - // - - scene = new THREE.Scene(); - - const aspect = window.innerWidth / window.innerHeight; - camera = new THREE.OrthographicCamera(-height * aspect, height * aspect, height, -height, 1, 10000); - camera.position.z = 1500; - scene.add(camera); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enableDamping = true; - - // lights - - ambientLight = new THREE.AmbientLight(0xffffff, settings.ambientIntensity); - scene.add(ambientLight); - - pointLight = new THREE.PointLight(0xff0000, 1.5, 0, 0); - pointLight.position.z = 2500; - scene.add(pointLight); - - const pointLight2 = new THREE.PointLight(0xff6666, 3, 0, 0); - camera.add(pointLight2); - - const pointLight3 = new THREE.PointLight(0x0000ff, 1.5, 0, 0); - pointLight3.position.x = -1000; - pointLight3.position.z = 1000; - scene.add(pointLight3); - - // env map - - const path = 'textures/cube/SwedishRoyalCastle/'; - const format = '.jpg'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const reflectionCube = new THREE.CubeTextureLoader().load(urls); - - // textures - - const textureLoader = new THREE.TextureLoader(); - const normalMap = textureLoader.load('models/obj/ninja/normal.png'); - const aoMap = textureLoader.load('models/obj/ninja/ao.jpg'); - const displacementMap = textureLoader.load('models/obj/ninja/displacement.jpg'); - - // material - - material = new THREE.MeshStandardNodeMaterial({ - color: 0xc1c1c1, - roughness: settings.roughness, - metalness: settings.metalness, - - normalMap: normalMap, - normalScale: new THREE.Vector2(1, -1), // why does the normal map require negation in this case? - - aoMap: aoMap, - aoMapIntensity: 1, - - displacementMap: displacementMap, - displacementScale: settings.displacementScale, - displacementBias: -0.428408, // from original model - - envMap: reflectionCube, - envMapIntensity: settings.envMapIntensity, - - side: THREE.DoubleSide, - }); - - // - - const loader = new OBJLoader(); - loader.load('models/obj/ninja/ninjaHead_Low.obj', function (group) { - const geometry = group.children[0].geometry; - geometry.center(); - - mesh = new THREE.Mesh(geometry, material); - mesh.scale.multiplyScalar(25); - scene.add(mesh); - }); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const aspect = window.innerWidth / window.innerHeight; - - camera.left = -height * aspect; - camera.right = height * aspect; - camera.top = height; - camera.bottom = -height; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - controls.update(); - - stats.begin(); - render(); - stats.end(); -} - -function render() { - pointLight.position.x = 2500 * Math.cos(r); - pointLight.position.z = 2500 * Math.sin(r); - - r += 0.01; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_materials_envmaps.ts b/examples-testing/examples/webgpu_materials_envmaps.ts deleted file mode 100644 index f49b4ca1e..000000000 --- a/examples-testing/examples/webgpu_materials_envmaps.ts +++ /dev/null @@ -1,107 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let controls, camera, scene, renderer; -let textureEquirec, textureCube; -let sphereMesh, sphereMaterial, params; - -init(); - -function init() { - // CAMERAS - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 0, 2.5); - - // SCENE - - scene = new THREE.Scene(); - - // Textures - - const loader = new THREE.CubeTextureLoader(); - loader.setPath('textures/cube/Bridge2/'); - - textureCube = loader.load(['posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg']); - - const textureLoader = new THREE.TextureLoader(); - - textureEquirec = textureLoader.load('textures/2294472375_24a3b8ef46_o.jpg'); - textureEquirec.mapping = THREE.EquirectangularReflectionMapping; - textureEquirec.colorSpace = THREE.SRGBColorSpace; - - scene.background = textureCube; - - // - - const geometry = new THREE.IcosahedronGeometry(1, 15); - sphereMaterial = new THREE.MeshBasicMaterial({ envMap: textureCube }); - sphereMesh = new THREE.Mesh(geometry, sphereMaterial); - scene.add(sphereMesh); - - // - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1.5; - controls.maxDistance = 6; - - // - - params = { - Cube: function () { - scene.background = textureCube; - - sphereMaterial.envMap = textureCube; - sphereMaterial.needsUpdate = true; - }, - Equirectangular: function () { - scene.background = textureEquirec; - - sphereMaterial.envMap = textureEquirec; - sphereMaterial.needsUpdate = true; - }, - Refraction: false, - }; - - const gui = new GUI({ width: 300 }); - gui.add(params, 'Cube'); - gui.add(params, 'Equirectangular'); - gui.add(params, 'Refraction').onChange(function (value) { - if (value) { - textureEquirec.mapping = THREE.EquirectangularRefractionMapping; - textureCube.mapping = THREE.CubeRefractionMapping; - } else { - textureEquirec.mapping = THREE.EquirectangularReflectionMapping; - textureCube.mapping = THREE.CubeReflectionMapping; - } - - sphereMaterial.needsUpdate = true; - }); - gui.open(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - camera.lookAt(scene.position); - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_materials_lightmap.ts b/examples-testing/examples/webgpu_materials_lightmap.ts deleted file mode 100644 index 616645aab..000000000 --- a/examples-testing/examples/webgpu_materials_lightmap.ts +++ /dev/null @@ -1,94 +0,0 @@ -import * as THREE from 'three'; -import { vec4, color, positionLocal, mix } from 'three/tsl'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container, stats; -let camera, scene, renderer; - -init(); - -async function init() { - const { innerWidth, innerHeight } = window; - - container = document.createElement('div'); - document.body.appendChild(container); - - // CAMERA - - camera = new THREE.PerspectiveCamera(40, innerWidth / innerHeight, 1, 10000); - camera.position.set(700, 200, -500); - - // SCENE - - scene = new THREE.Scene(); - - // LIGHTS - - const light = new THREE.DirectionalLight(0xd5deff); - light.position.x = 300; - light.position.y = 250; - light.position.z = -500; - scene.add(light); - - // SKYDOME - - const topColor = new THREE.Color().copy(light.color); - const bottomColor = new THREE.Color(0xffffff); - const offset = 400; - const exponent = 0.6; - - const h = positionLocal.add(offset).normalize().y; - - const skyMat = new THREE.MeshBasicNodeMaterial(); - skyMat.colorNode = vec4(mix(color(bottomColor), color(topColor), h.max(0.0).pow(exponent)), 1.0); - skyMat.side = THREE.BackSide; - - const sky = new THREE.Mesh(new THREE.SphereGeometry(4000, 32, 15), skyMat); - scene.add(sky); - - // MODEL - - const loader = new THREE.ObjectLoader(); - const object = await loader.loadAsync('models/json/lightmap/lightmap.json'); - scene.add(object); - - // RENDERER - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setAnimationLoop(animate); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(innerWidth, innerHeight); - container.appendChild(renderer.domElement); - - // CONTROLS - - const controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = (0.9 * Math.PI) / 2; - controls.enableZoom = false; - - // STATS - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); - stats.update(); -} diff --git a/examples-testing/examples/webgpu_materials_toon.ts b/examples-testing/examples/webgpu_materials_toon.ts deleted file mode 100644 index 217460596..000000000 --- a/examples-testing/examples/webgpu_materials_toon.ts +++ /dev/null @@ -1,148 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -let container, stats; - -let camera, scene, renderer; -let particleLight; - -const loader = new FontLoader(); -loader.load('fonts/gentilis_regular.typeface.json', function (font) { - init(font); -}); - -function init(font) { - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 2500); - camera.position.set(0.0, 400, 400 * 3.5); - - // - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x444488); - - // - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - container.appendChild(renderer.domElement); - - // Materials - - const cubeWidth = 400; - const numberOfSphersPerSide = 5; - const sphereRadius = (cubeWidth / numberOfSphersPerSide) * 0.8 * 0.5; - const stepSize = 1.0 / numberOfSphersPerSide; - - const geometry = new THREE.SphereGeometry(sphereRadius, 32, 16); - - for (let alpha = 0, alphaIndex = 0; alpha <= 1.0; alpha += stepSize, alphaIndex++) { - const colors = new Uint8Array(alphaIndex + 2); - - for (let c = 0; c <= colors.length; c++) { - colors[c] = (c / colors.length) * 256; - } - - const gradientMap = new THREE.DataTexture(colors, colors.length, 1, THREE.RedFormat); - gradientMap.needsUpdate = true; - - for (let beta = 0; beta <= 1.0; beta += stepSize) { - for (let gamma = 0; gamma <= 1.0; gamma += stepSize) { - // basic monochromatic energy preservation - const diffuseColor = new THREE.Color() - .setHSL(alpha, 0.5, gamma * 0.5 + 0.1) - .multiplyScalar(1 - beta * 0.2); - - const material = new THREE.MeshToonNodeMaterial({ - color: diffuseColor, - gradientMap: gradientMap, - }); - - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = alpha * 400 - 200; - mesh.position.y = beta * 400 - 200; - mesh.position.z = gamma * 400 - 200; - - scene.add(mesh); - } - } - } - - function addLabel(name, location) { - const textGeo = new TextGeometry(name, { - font: font, - - size: 20, - depth: 1, - curveSegments: 1, - }); - - const textMaterial = new THREE.MeshBasicNodeMaterial(); - const textMesh = new THREE.Mesh(textGeo, textMaterial); - textMesh.position.copy(location); - scene.add(textMesh); - } - - addLabel('-gradientMap', new THREE.Vector3(-350, 0, 0)); - addLabel('+gradientMap', new THREE.Vector3(350, 0, 0)); - - addLabel('-diffuse', new THREE.Vector3(0, 0, -300)); - addLabel('+diffuse', new THREE.Vector3(0, 0, 300)); - - particleLight = new THREE.Mesh( - new THREE.SphereGeometry(4, 8, 8), - new THREE.MeshBasicNodeMaterial({ color: 0xffffff }), - ); - scene.add(particleLight); - - // Lights - - scene.add(new THREE.AmbientLight(0xc1c1c1, 3)); - - const pointLight = new THREE.PointLight(0xffffff, 2, 800, 0); - particleLight.add(pointLight); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 200; - controls.maxDistance = 2000; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - const timer = Date.now() * 0.00025; - - particleLight.position.x = Math.sin(timer * 7) * 300; - particleLight.position.y = Math.cos(timer * 5) * 400; - particleLight.position.z = Math.cos(timer * 3) * 300; - - stats.begin(); - - renderer.render(scene, camera); - - stats.end(); -} diff --git a/examples-testing/examples/webgpu_materials_transmission.ts b/examples-testing/examples/webgpu_materials_transmission.ts deleted file mode 100644 index 0e04ddad9..000000000 --- a/examples-testing/examples/webgpu_materials_transmission.ts +++ /dev/null @@ -1,168 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -const params = { - color: 0xffffff, - transmission: 1, - opacity: 1, - metalness: 0, - roughness: 0, - ior: 1.5, - thickness: 0.01, - specularIntensity: 1, - specularColor: 0xffffff, - envMapIntensity: 1, - lightIntensity: 1, - exposure: 1, -}; - -let camera, scene, renderer; - -let mesh; - -const hdrEquirect = new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function () { - hdrEquirect.mapping = THREE.EquirectangularReflectionMapping; - - init(); - render(); -}); - -function init() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = params.exposure; - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 2000); - camera.position.set(0, 0, 120); - - // - - scene.background = hdrEquirect; - - // - - const geometry = new THREE.SphereGeometry(20, 64, 32); - - const texture = new THREE.CanvasTexture(generateTexture()); - texture.magFilter = THREE.NearestFilter; - texture.wrapT = THREE.RepeatWrapping; - texture.wrapS = THREE.RepeatWrapping; - texture.repeat.set(1, 3.5); - - const material = new THREE.MeshPhysicalMaterial({ - color: params.color, - metalness: params.metalness, - roughness: params.roughness, - ior: params.ior, - alphaMap: texture, - envMap: hdrEquirect, - envMapIntensity: params.envMapIntensity, - transmission: params.transmission, // use material.transmission for glass materials - specularIntensity: params.specularIntensity, - specularColor: params.specularColor, - opacity: params.opacity, - side: THREE.DoubleSide, - transparent: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 10; - controls.maxDistance = 150; - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - - gui.addColor(params, 'color').onChange(function () { - material.color.set(params.color); - }); - - gui.add(params, 'transmission', 0, 1, 0.01).onChange(function () { - material.transmission = params.transmission; - }); - - gui.add(params, 'opacity', 0, 1, 0.01).onChange(function () { - material.opacity = params.opacity; - }); - - gui.add(params, 'metalness', 0, 1, 0.01).onChange(function () { - material.metalness = params.metalness; - }); - - gui.add(params, 'roughness', 0, 1, 0.01).onChange(function () { - material.roughness = params.roughness; - }); - - gui.add(params, 'ior', 1, 2, 0.01).onChange(function () { - material.ior = params.ior; - }); - - gui.add(params, 'thickness', 0, 5, 0.01).onChange(function () { - material.thickness = params.thickness; - }); - - gui.add(params, 'specularIntensity', 0, 1, 0.01).onChange(function () { - material.specularIntensity = params.specularIntensity; - }); - - gui.addColor(params, 'specularColor').onChange(function () { - material.specularColor.set(params.specularColor); - }); - - gui.add(params, 'envMapIntensity', 0, 1, 0.01) - .name('envMap intensity') - .onChange(function () { - material.envMapIntensity = params.envMapIntensity; - }); - - gui.add(params, 'exposure', 0, 1, 0.01).onChange(function () { - renderer.toneMappingExposure = params.exposure; - }); - - gui.open(); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -// - -function generateTexture() { - const canvas = document.createElement('canvas'); - canvas.width = 2; - canvas.height = 2; - - const context = canvas.getContext('2d'); - context.fillStyle = 'white'; - context.fillRect(0, 1, 2, 1); - - return canvas; -} - -function render() { - renderer.renderAsync(scene, camera); -} diff --git a/examples-testing/examples/webgpu_materials_video.ts b/examples-testing/examples/webgpu_materials_video.ts deleted file mode 100644 index bd84aba0f..000000000 --- a/examples-testing/examples/webgpu_materials_video.ts +++ /dev/null @@ -1,184 +0,0 @@ -import * as THREE from 'three'; - -let container; - -let camera, scene, renderer; - -let video, texture, material, mesh; - -let mouseX = 0; -let mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -let cube_count; - -const meshes = [], - materials = [], - xgrid = 20, - ygrid = 10; - -const startButton = document.getElementById('startButton'); -startButton.addEventListener('click', function () { - init(); -}); - -function init() { - const overlay = document.getElementById('overlay'); - overlay.remove(); - - container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000); - camera.position.z = 500; - - scene = new THREE.Scene(); - - const light = new THREE.DirectionalLight(0xffffff, 7); - light.position.set(0.5, 1, 1).normalize(); - scene.add(light); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - container.appendChild(renderer.domElement); - - video = document.getElementById('video'); - video.play(); - video.addEventListener('play', function () { - this.currentTime = 3; - }); - - texture = new THREE.VideoTexture(video); - - // - - let i, j, ox, oy, geometry; - - const ux = 1 / xgrid; - const uy = 1 / ygrid; - - const xsize = 480 / xgrid; - const ysize = 204 / ygrid; - - const parameters = { color: 0xffffff, map: texture }; - - cube_count = 0; - - for (i = 0; i < xgrid; i++) { - for (j = 0; j < ygrid; j++) { - ox = i; - oy = j; - - geometry = new THREE.BoxGeometry(xsize, ysize, xsize); - - change_uvs(geometry, ux, uy, ox, oy); - - materials[cube_count] = new THREE.MeshPhongMaterial(parameters); - - material = materials[cube_count]; - - material.hue = i / xgrid; - material.saturation = 1 - j / ygrid; - - material.color.setHSL(material.hue, material.saturation, 0.5); - - mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = (i - xgrid / 2) * xsize; - mesh.position.y = (j - ygrid / 2) * ysize; - mesh.position.z = 0; - - mesh.scale.x = mesh.scale.y = mesh.scale.z = 1; - - scene.add(mesh); - - mesh.dx = 0.001 * (0.5 - Math.random()); - mesh.dy = 0.001 * (0.5 - Math.random()); - - meshes[cube_count] = mesh; - - cube_count += 1; - } - } - - document.addEventListener('mousemove', onDocumentMouseMove); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function change_uvs(geometry, unitx, unity, offsetx, offsety) { - const uvs = geometry.attributes.uv.array; - - for (let i = 0; i < uvs.length; i += 2) { - uvs[i] = (uvs[i] + offsetx) * unitx; - uvs[i + 1] = (uvs[i + 1] + offsety) * unity; - } -} - -function onDocumentMouseMove(event) { - mouseX = event.clientX - windowHalfX; - mouseY = (event.clientY - windowHalfY) * 0.3; -} - -// - -let h, - counter = 1; - -function render() { - const time = Date.now() * 0.00005; - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y += (-mouseY - camera.position.y) * 0.05; - - camera.lookAt(scene.position); - - for (let i = 0; i < cube_count; i++) { - material = materials[i]; - - h = ((360 * (material.hue + time)) % 360) / 360; - material.color.setHSL(h, material.saturation, 0.5); - } - - if (counter % 1000 > 200) { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - - mesh.rotation.x += 10 * mesh.dx; - mesh.rotation.y += 10 * mesh.dy; - - mesh.position.x -= 150 * mesh.dx; - mesh.position.y += 150 * mesh.dy; - mesh.position.z += 300 * mesh.dx; - } - } - - if (counter % 1000 === 0) { - for (let i = 0; i < cube_count; i++) { - mesh = meshes[i]; - - mesh.dx *= -1; - mesh.dy *= -1; - } - } - - counter++; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_mesh_batch.ts b/examples-testing/examples/webgpu_mesh_batch.ts deleted file mode 100644 index 17bc8440f..000000000 --- a/examples-testing/examples/webgpu_mesh_batch.ts +++ /dev/null @@ -1,275 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { radixSort } from 'three/addons/utils/SortUtils.js'; - -import { transformedNormalView, directionToColor, diffuseColor } from 'three/tsl'; - -let camera, scene, renderer; -let controls, stats; -let gui; -let geometries, mesh, material; -const ids = []; - -const matrix = new THREE.Matrix4(); - -// - -const position = new THREE.Vector3(); -const rotation = new THREE.Euler(); -const quaternion = new THREE.Quaternion(); -const scale = new THREE.Vector3(); - -// - -const MAX_GEOMETRY_COUNT = 20000; - -const api = { - webgpu: true, - count: 512, - dynamic: 16, - - sortObjects: true, - perObjectFrustumCulled: true, - opacity: 1, - useCustomSort: true, - randomizeGeometry: () => { - for (let i = 0; i < api.count; i++) { - mesh.setGeometryIdAt(i, Math.floor(Math.random() * geometries.length)); - } - }, -}; - -init(); - -// - -function randomizeMatrix(matrix) { - position.x = Math.random() * 40 - 20; - position.y = Math.random() * 40 - 20; - position.z = Math.random() * 40 - 20; - - rotation.x = Math.random() * 2 * Math.PI; - rotation.y = Math.random() * 2 * Math.PI; - rotation.z = Math.random() * 2 * Math.PI; - - quaternion.setFromEuler(rotation); - - scale.x = scale.y = scale.z = 0.5 + Math.random() * 0.5; - - return matrix.compose(position, quaternion, scale); -} - -function randomizeRotationSpeed(rotation) { - rotation.x = Math.random() * 0.01; - rotation.y = Math.random() * 0.01; - rotation.z = Math.random() * 0.01; - return rotation; -} - -function initGeometries() { - geometries = [ - new THREE.ConeGeometry(1.0, 2.0), - new THREE.BoxGeometry(2.0, 2.0, 2.0), - new THREE.SphereGeometry(1.0, 16, 8), - ]; -} - -function createMaterial() { - if (!material) { - material = new THREE.MeshBasicNodeMaterial(); - material.outputNode = diffuseColor.mul(directionToColor(transformedNormalView).y.add(0.5)); - } - - return material; -} - -function cleanup() { - if (mesh) { - mesh.parent.remove(mesh); - - if (mesh.dispose) { - mesh.dispose(); - } - } -} - -function initMesh() { - cleanup(); - initBatchedMesh(); -} - -function initBatchedMesh() { - const geometryCount = api.count; - const vertexCount = geometries.length * 512; - const indexCount = geometries.length * 1024; - - const euler = new THREE.Euler(); - const matrix = new THREE.Matrix4(); - mesh = new THREE.BatchedMesh(geometryCount, vertexCount, indexCount, createMaterial()); - mesh.userData.rotationSpeeds = []; - - // disable full-object frustum culling since all of the objects can be dynamic. - mesh.frustumCulled = false; - - ids.length = 0; - - const geometryIds = [ - mesh.addGeometry(geometries[0]), - mesh.addGeometry(geometries[1]), - mesh.addGeometry(geometries[2]), - ]; - for (let i = 0; i < api.count; i++) { - const id = mesh.addInstance(geometryIds[i % geometryIds.length]); - mesh.setMatrixAt(id, randomizeMatrix(matrix)); - mesh.setColorAt(id, new THREE.Color(Math.random() * 0xffffff)); - - const rotationMatrix = new THREE.Matrix4(); - rotationMatrix.makeRotationFromEuler(randomizeRotationSpeed(euler)); - mesh.userData.rotationSpeeds.push(rotationMatrix); - - ids.push(id); - } - - scene.add(mesh); -} - -function init(forceWebGL = false) { - if (renderer) { - renderer.dispose(); - controls.dispose(); - document.body.removeChild(stats.dom); - document.body.removeChild(renderer.domElement); - } - - // camera - - const aspect = window.innerWidth / window.innerHeight; - - camera = new THREE.PerspectiveCamera(70, aspect, 1, 100); - camera.position.z = 30; - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true, forceWebGL }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - - renderer.setAnimationLoop(animate); - - // scene - - scene = new THREE.Scene(); - scene.background = forceWebGL ? new THREE.Color(0xffc1c1) : new THREE.Color(0xc1c1ff); - - document.body.appendChild(renderer.domElement); - - initGeometries(); - initMesh(); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.autoRotate = true; - controls.autoRotateSpeed = 1.0; - - // stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // gui - - gui = new GUI(); - gui.add(api, 'webgpu').onChange(() => { - init(!api.webgpu); - }); - gui.add(api, 'count', 1, MAX_GEOMETRY_COUNT).step(1).onChange(initMesh); - gui.add(api, 'dynamic', 0, MAX_GEOMETRY_COUNT).step(1); - - gui.add(api, 'opacity', 0, 1).onChange(v => { - if (v < 1) { - material.transparent = true; - material.depthWrite = false; - } else { - material.transparent = false; - material.depthWrite = true; - } - - material.opacity = v; - material.needsUpdate = true; - }); - gui.add(api, 'sortObjects'); - gui.add(api, 'perObjectFrustumCulled'); - gui.add(api, 'useCustomSort'); - gui.add(api, 'randomizeGeometry'); - - // listeners - - window.addEventListener('resize', onWindowResize); - - function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - } - - async function animate() { - animateMeshes(); - - controls.update(); - - if (mesh.isBatchedMesh) { - mesh.sortObjects = api.sortObjects; - mesh.perObjectFrustumCulled = api.perObjectFrustumCulled; - mesh.setCustomSort(api.useCustomSort ? sortFunction : null); - } - - await renderer.renderAsync(scene, camera); - - stats.update(); - } - - function animateMeshes() { - const loopNum = Math.min(api.count, api.dynamic); - - for (let i = 0; i < loopNum; i++) { - const rotationMatrix = mesh.userData.rotationSpeeds[i]; - const id = ids[i]; - - mesh.getMatrixAt(id, matrix); - matrix.multiply(rotationMatrix); - mesh.setMatrixAt(id, matrix); - } - } -} - -// - -function sortFunction(list, camera) { - // initialize options - this._options = this._options || { - get: el => el.z, - aux: new Array(this.maxInstanceCount), - }; - - const options = this._options; - options.reversed = this.material.transparent; - - // convert depth to unsigned 32 bit range - const factor = (2 ** 32 - 1) / camera.far; // UINT32_MAX / max_depth - for (let i = 0, l = list.length; i < l; i++) { - list[i].z *= factor; - } - - // perform a fast-sort using the hybrid radix sort function - radixSort(list, options); -} diff --git a/examples-testing/examples/webgpu_modifier_curve.ts b/examples-testing/examples/webgpu_modifier_curve.ts deleted file mode 100644 index 4879a9e5b..000000000 --- a/examples-testing/examples/webgpu_modifier_curve.ts +++ /dev/null @@ -1,160 +0,0 @@ -import * as THREE from 'three'; -import { TransformControls } from 'three/addons/controls/TransformControls.js'; -import Stats from 'three/addons/libs/stats.module.js'; -import { Flow } from 'three/addons/modifiers/CurveModifierGPU.js'; -import { FontLoader } from 'three/addons/loaders/FontLoader.js'; -import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; - -const ACTION_SELECT = 1, - ACTION_NONE = 0; -const curveHandles = []; -const mouse = new THREE.Vector2(); - -let stats; -let scene, - camera, - renderer, - rayCaster, - control, - flow, - action = ACTION_NONE; - -init(); - -function init() { - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(2, 2, 4); - camera.lookAt(scene.position); - - const initialPoints = [ - { x: 1, y: 0, z: -1 }, - { x: 1, y: 0, z: 1 }, - { x: -1, y: 0, z: 1 }, - { x: -1, y: 0, z: -1 }, - ]; - - const boxGeometry = new THREE.BoxGeometry(0.1, 0.1, 0.1); - const boxMaterial = new THREE.MeshBasicNodeMaterial(); - - for (const handlePos of initialPoints) { - const handle = new THREE.Mesh(boxGeometry, boxMaterial); - handle.position.copy(handlePos); - curveHandles.push(handle); - scene.add(handle); - } - - const curve = new THREE.CatmullRomCurve3(curveHandles.map(handle => handle.position)); - curve.curveType = 'centripetal'; - curve.closed = true; - - const points = curve.getPoints(50); - const line = new THREE.Line( - new THREE.BufferGeometry().setFromPoints(points), - new THREE.LineBasicMaterial({ color: 0x00ff00 }), - ); - - scene.add(line); - - // - - const light = new THREE.DirectionalLight(0xffaa33, 3); - light.position.set(-10, 10, 10); - scene.add(light); - - const light2 = new THREE.AmbientLight(0x003973, 3); - scene.add(light2); - - // - - const loader = new FontLoader(); - loader.load('fonts/helvetiker_regular.typeface.json', function (font) { - const geometry = new TextGeometry('Hello three.js!', { - font: font, - size: 0.2, - depth: 0.05, - curveSegments: 12, - bevelEnabled: true, - bevelThickness: 0.02, - bevelSize: 0.01, - bevelOffset: 0, - bevelSegments: 5, - }); - - geometry.rotateX(Math.PI); - - const material = new THREE.MeshStandardNodeMaterial({ - color: 0x99ffff, - }); - - const objectToCurve = new THREE.Mesh(geometry, material); - - flow = new Flow(objectToCurve); - flow.updateCurve(0, curve); - scene.add(flow.object3D); - }); - - // - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - renderer.domElement.addEventListener('pointerdown', onPointerDown); - - rayCaster = new THREE.Raycaster(); - control = new TransformControls(camera, renderer.domElement); - control.addEventListener('dragging-changed', function (event) { - if (!event.value) { - const points = curve.getPoints(50); - line.geometry.setFromPoints(points); - flow.updateCurve(0, curve); - } - }); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerDown(event) { - action = ACTION_SELECT; - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; -} - -function animate() { - if (action === ACTION_SELECT) { - rayCaster.setFromCamera(mouse, camera); - action = ACTION_NONE; - const intersects = rayCaster.intersectObjects(curveHandles, false); - if (intersects.length) { - const target = intersects[0].object; - control.attach(target); - scene.add(control.getHelper()); - } - } - - if (flow) { - flow.moveAlongCurve(0.001); - } - - render(); -} - -function render() { - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_morphtargets.ts b/examples-testing/examples/webgpu_morphtargets.ts deleted file mode 100644 index 9fb7075cb..000000000 --- a/examples-testing/examples/webgpu_morphtargets.ts +++ /dev/null @@ -1,121 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let container, camera, scene, renderer, mesh; - -init(); - -function init() { - container = document.getElementById('container'); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x8fbcd4); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20); - camera.position.z = 10; - scene.add(camera); - - scene.add(new THREE.AmbientLight(0x8fbcd4, 1.5)); - - const pointLight = new THREE.PointLight(0xffffff, 200); - camera.add(pointLight); - - const geometry = createGeometry(); - - const material = new THREE.MeshPhongMaterial({ - color: 0xff0000, - flatShading: true, - }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - initGUI(); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(function () { - renderer.render(scene, camera); - }); - container.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - - window.addEventListener('resize', onWindowResize); -} - -function createGeometry() { - const geometry = new THREE.BoxGeometry(2, 2, 2, 32, 32, 32); - - // create an empty array to hold targets for the attribute we want to morph - // morphing positions and normals is supported - geometry.morphAttributes.position = []; - - // the original positions of the cube's vertices - const positionAttribute = geometry.attributes.position; - - // for the first morph target we'll move the cube's vertices onto the surface of a sphere - const spherePositions = []; - - // for the second morph target, we'll twist the cubes vertices - const twistPositions = []; - const direction = new THREE.Vector3(1, 0, 0); - const vertex = new THREE.Vector3(); - - for (let i = 0; i < positionAttribute.count; i++) { - const x = positionAttribute.getX(i); - const y = positionAttribute.getY(i); - const z = positionAttribute.getZ(i); - - spherePositions.push( - x * Math.sqrt(1 - (y * y) / 2 - (z * z) / 2 + (y * y * z * z) / 3), - y * Math.sqrt(1 - (z * z) / 2 - (x * x) / 2 + (z * z * x * x) / 3), - z * Math.sqrt(1 - (x * x) / 2 - (y * y) / 2 + (x * x * y * y) / 3), - ); - - // stretch along the x-axis so we can see the twist better - vertex.set(x * 2, y, z); - - vertex.applyAxisAngle(direction, (Math.PI * x) / 2).toArray(twistPositions, twistPositions.length); - } - - // add the spherical positions as the first morph target - geometry.morphAttributes.position[0] = new THREE.Float32BufferAttribute(spherePositions, 3); - - // add the twisted positions as the second morph target - geometry.morphAttributes.position[1] = new THREE.Float32BufferAttribute(twistPositions, 3); - - return geometry; -} - -function initGUI() { - // Set up dat.GUI to control targets - const params = { - Spherify: 0, - Twist: 0, - }; - const gui = new GUI({ title: 'Morph Targets' }); - - gui.add(params, 'Spherify', 0, 1) - .step(0.01) - .onChange(function (value) { - mesh.morphTargetInfluences[0] = value; - }); - gui.add(params, 'Twist', 0, 1) - .step(0.01) - .onChange(function (value) { - mesh.morphTargetInfluences[1] = value; - }); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} diff --git a/examples-testing/examples/webgpu_morphtargets_face.ts b/examples-testing/examples/webgpu_morphtargets_face.ts deleted file mode 100644 index ea9f86588..000000000 --- a/examples-testing/examples/webgpu_morphtargets_face.ts +++ /dev/null @@ -1,102 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; -import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -init(); - -async function init() { - let mixer; - - const clock = new THREE.Clock(); - - const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 20); - camera.position.set(-1.8, 0.8, 3); - - const scene = new THREE.Scene(); - - const renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - document.body.appendChild(renderer.domElement); - - await renderer.init(); - - const environment = new RoomEnvironment(); - const pmremGenerator = new THREE.PMREMGenerator(renderer); - - scene.background = new THREE.Color(0x666666); - scene.environment = pmremGenerator.fromScene(environment).texture; - - const ktx2Loader = await new KTX2Loader().setTranscoderPath('jsm/libs/basis/').detectSupportAsync(renderer); - - new GLTFLoader() - .setKTX2Loader(ktx2Loader) - .setMeshoptDecoder(MeshoptDecoder) - .load('models/gltf/facecap.glb', gltf => { - const mesh = gltf.scene.children[0]; - - scene.add(mesh); - - mixer = new THREE.AnimationMixer(mesh); - - mixer.clipAction(gltf.animations[0]).play(); - - // GUI - - const head = mesh.getObjectByName('mesh_2'); - const influences = head.morphTargetInfluences; - - const gui = new GUI(); - gui.close(); - - for (const [key, value] of Object.entries(head.morphTargetDictionary)) { - gui.add(influences, value, 0, 1, 0.01).name(key.replace('blendShape1.', '')).listen(); - } - }); - - scene.background = new THREE.Color(0x666666); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 2.5; - controls.maxDistance = 5; - controls.minAzimuthAngle = -Math.PI / 2; - controls.maxAzimuthAngle = Math.PI / 2; - controls.maxPolarAngle = Math.PI / 1.8; - controls.target.set(0, 0.15, -0.2); - - const stats = new Stats(); - document.body.appendChild(stats.dom); - - function animate() { - const delta = clock.getDelta(); - - if (mixer) { - mixer.update(delta); - } - - renderer.render(scene, camera); - - controls.update(); - - stats.update(); - } - - window.addEventListener('resize', () => { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - }); -} diff --git a/examples-testing/examples/webgpu_mrt.ts b/examples-testing/examples/webgpu_mrt.ts deleted file mode 100644 index a749bd6da..000000000 --- a/examples-testing/examples/webgpu_mrt.ts +++ /dev/null @@ -1,120 +0,0 @@ -import * as THREE from 'three'; -import { - output, - transformedNormalView, - pass, - step, - diffuseColor, - emissive, - directionToColor, - screenUV, - mix, - mrt, - Fn, -} from 'three/tsl'; - -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, scene, renderer; -let postProcessing; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - // scene - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', function (gltf) { - scene.add(gltf.scene); - }); - }); - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - // post processing - - const scenePass = pass(scene, camera, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter }); - scenePass.setMRT( - mrt({ - output: output, - normal: directionToColor(transformedNormalView), - diffuse: diffuseColor, - emissive: emissive, - }), - ); - - // optimize textures - - const normalTexture = scenePass.getTexture('normal'); - const diffuseTexture = scenePass.getTexture('diffuse'); - const emissiveTexture = scenePass.getTexture('emissive'); - - normalTexture.type = diffuseTexture.type = emissiveTexture.type = THREE.UnsignedByteType; - - // post processing - mrt - - postProcessing = new THREE.PostProcessing(renderer); - postProcessing.outputColorTransform = false; - postProcessing.outputNode = Fn(() => { - const output = scenePass.getTextureNode('output'); // output name is optional here - const normal = scenePass.getTextureNode('normal'); - const diffuse = scenePass.getTextureNode('diffuse'); - const emissive = scenePass.getTextureNode('emissive'); - - const out = mix(output.renderOutput(), output, step(0.2, screenUV.x)); - const nor = mix(out, normal, step(0.4, screenUV.x)); - const emi = mix(nor, emissive, step(0.6, screenUV.x)); - const dif = mix(emi, diffuse, step(0.8, screenUV.x)); - - return dif; - })(); - - // controls - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 10; - controls.target.set(0, 0, -0.2); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts b/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts deleted file mode 100644 index 989361b6f..000000000 --- a/examples-testing/examples/webgpu_multiple_rendertargets_readback.ts +++ /dev/null @@ -1,156 +0,0 @@ -import * as THREE from 'three'; -import { mix, step, texture, screenUV, mrt, output, transformedNormalWorld, uv, vec2 } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, torus; -let quadMesh, sceneMRT, renderTarget, readbackTarget, material, readbackMaterial, pixelBuffer, pixelBufferTexture; - -const gui = new GUI(); - -const options = { - selection: 'mrt', -}; - -gui.add(options, 'selection', ['mrt', 'diffuse', 'normal']); - -init(); - -function init() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - document.body.appendChild(renderer.domElement); - - // Create a multi render target with Float buffers - - renderTarget = new THREE.RenderTarget( - window.innerWidth * window.devicePixelRatio, - window.innerHeight * window.devicePixelRatio, - { count: 2, minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter }, - ); - - // Name our G-Buffer attachments for debugging - - renderTarget.textures[0].name = 'output'; - renderTarget.textures[1].name = 'normal'; - - // Init readback render target, readback data texture, readback material - // Be careful with the size! 512 is already big. Reading data back from the GPU is computationally intensive - - const size = 512; - - readbackTarget = new THREE.RenderTarget(size, size, { count: 2 }); - - pixelBuffer = new Uint8Array(size ** 2 * 4).fill(0); - pixelBufferTexture = new THREE.DataTexture(pixelBuffer, size, size); - pixelBufferTexture.type = THREE.UnsignedByteType; - pixelBufferTexture.format = THREE.RGBAFormat; - - readbackMaterial = new THREE.MeshBasicNodeMaterial(); - readbackMaterial.colorNode = texture(pixelBufferTexture); - - // MRT - - sceneMRT = mrt({ - output: output, - normal: transformedNormalWorld, - }); - - // Scene - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x222222); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50); - camera.position.z = 4; - - const loader = new THREE.TextureLoader(); - - const diffuse = loader.load('textures/hardwood2_diffuse.jpg'); - diffuse.colorSpace = THREE.SRGBColorSpace; - diffuse.wrapS = THREE.RepeatWrapping; - diffuse.wrapT = THREE.RepeatWrapping; - - const torusMaterial = new THREE.NodeMaterial(); - torusMaterial.colorNode = texture(diffuse, uv().mul(vec2(10, 4))); - - torus = new THREE.Mesh(new THREE.TorusKnotGeometry(1, 0.3, 128, 32), torusMaterial); - scene.add(torus); - - // Output - - material = new THREE.NodeMaterial(); - material.colorNode = mix( - texture(renderTarget.textures[0]), - texture(renderTarget.textures[1]), - step(0.5, screenUV.x), - ); - - quadMesh = new THREE.QuadMesh(material); - - // Controls - - new OrbitControls(camera, renderer.domElement); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); - - const dpr = renderer.getPixelRatio(); - renderTarget.setSize(window.innerWidth * dpr, window.innerHeight * dpr); -} - -async function render(time) { - const selection = options.selection; - - torus.rotation.y = (time / 1000) * 0.4; - - const isMRT = selection === 'mrt'; - - // render scene into target - renderer.setMRT(isMRT ? sceneMRT : null); - renderer.setRenderTarget(isMRT ? renderTarget : readbackTarget); - renderer.render(scene, camera); - - // render post FX - renderer.setMRT(null); - renderer.setRenderTarget(null); - - if (isMRT) { - quadMesh.material = material; - } else { - quadMesh.material = readbackMaterial; - - await readback(); - } - - quadMesh.render(renderer); -} - -async function readback() { - const width = readbackTarget.width; - const height = readbackTarget.height; - - const selection = options.selection; - - if (selection === 'diffuse') { - pixelBuffer = await renderer.readRenderTargetPixelsAsync(readbackTarget, 0, 0, width, height, 0); // zero is optional - - pixelBufferTexture.image.data = pixelBuffer; - pixelBufferTexture.needsUpdate = true; - } else if (selection === 'normal') { - pixelBuffer = await renderer.readRenderTargetPixelsAsync(readbackTarget, 0, 0, width, height, 1); - - pixelBufferTexture.image.data = pixelBuffer; - pixelBufferTexture.needsUpdate = true; - } -} diff --git a/examples-testing/examples/webgpu_ocean.ts b/examples-testing/examples/webgpu_ocean.ts deleted file mode 100644 index 9eb9922dd..000000000 --- a/examples-testing/examples/webgpu_ocean.ts +++ /dev/null @@ -1,161 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { WaterMesh } from 'three/addons/objects/WaterMesh.js'; -import { SkyMesh } from 'three/addons/objects/SkyMesh.js'; - -let container, stats; -let camera, scene, renderer; -let controls, water, sun, mesh; - -init(); - -function init() { - container = document.getElementById('container'); - - // - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 0.5; - container.appendChild(renderer.domElement); - - // - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000); - camera.position.set(30, 30, 100); - - // - - sun = new THREE.Vector3(); - - // Water - - const waterGeometry = new THREE.PlaneGeometry(10000, 10000); - const loader = new THREE.TextureLoader(); - const waterNormals = loader.load('textures/waternormals.jpg'); - waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping; - - water = new WaterMesh(waterGeometry, { - waterNormals: waterNormals, - sunDirection: new THREE.Vector3(), - sunColor: 0xffffff, - waterColor: 0x001e0f, - distortionScale: 3.7, - }); - - water.rotation.x = -Math.PI / 2; - - scene.add(water); - - // Skybox - - const sky = new SkyMesh(); - sky.scale.setScalar(10000); - scene.add(sky); - - sky.turbidity.value = 10; - sky.rayleigh.value = 2; - sky.mieCoefficient.value = 0.005; - sky.mieDirectionalG.value = 0.8; - - const parameters = { - elevation: 2, - azimuth: 180, - }; - - const pmremGenerator = new THREE.PMREMGenerator(renderer); - const sceneEnv = new THREE.Scene(); - - let renderTarget; - - function updateSun() { - const phi = THREE.MathUtils.degToRad(90 - parameters.elevation); - const theta = THREE.MathUtils.degToRad(parameters.azimuth); - - sun.setFromSphericalCoords(1, phi, theta); - - sky.sunPosition.value.copy(sun); - water.sunDirection.value.copy(sun).normalize(); - - if (renderTarget !== undefined) renderTarget.dispose(); - - sceneEnv.add(sky); - renderTarget = pmremGenerator.fromScene(sceneEnv); - scene.add(sky); - - scene.environment = renderTarget.texture; - } - - renderer.init().then(updateSun); - - // - - const geometry = new THREE.BoxGeometry(30, 30, 30); - const material = new THREE.MeshStandardMaterial({ roughness: 0 }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = Math.PI * 0.495; - controls.target.set(0, 10, 0); - controls.minDistance = 40.0; - controls.maxDistance = 200.0; - controls.update(); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // GUI - - const gui = new GUI(); - - const folderSky = gui.addFolder('Sky'); - folderSky.add(parameters, 'elevation', 0, 90, 0.1).onChange(updateSun); - folderSky.add(parameters, 'azimuth', -180, 180, 0.1).onChange(updateSun); - folderSky.open(); - - const folderWater = gui.addFolder('Water'); - folderWater.add(water.distortionScale, 'value', 0, 8, 0.1).name('distortionScale'); - folderWater.add(water.size, 'value', 0.1, 10, 0.1).name('size'); - folderWater.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const time = performance.now() * 0.001; - - mesh.position.y = Math.sin(time) * 20 + 5; - mesh.rotation.x = time * 0.5; - mesh.rotation.z = time * 0.51; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_parallax_uv.ts b/examples-testing/examples/webgpu_parallax_uv.ts deleted file mode 100644 index 775399bfb..000000000 --- a/examples-testing/examples/webgpu_parallax_uv.ts +++ /dev/null @@ -1,112 +0,0 @@ -import * as THREE from 'three'; -import { texture, parallaxUV, overlay, uv } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -let controls; - -init(); - -async function init() { - // scene - - scene = new THREE.Scene(); - - // camera - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 50); - camera.position.set(10, 14, 10); - - // environment - - const environmentTexture = await new THREE.CubeTextureLoader() - .setPath('./textures/cube/Park2/') - .loadAsync(['posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg']); - - scene.environment = environmentTexture; - scene.background = environmentTexture; - - // textures - - const loader = new THREE.TextureLoader(); - - const topTexture = await loader.loadAsync('textures/ambientcg/Ice002_1K-JPG_Color.jpg'); - topTexture.colorSpace = THREE.SRGBColorSpace; - - const roughnessTexture = await loader.loadAsync('textures/ambientcg/Ice002_1K-JPG_Roughness.jpg'); - roughnessTexture.colorSpace = THREE.NoColorSpace; - - const normalTexture = await loader.loadAsync('textures/ambientcg/Ice002_1K-JPG_NormalGL.jpg'); - normalTexture.colorSpace = THREE.NoColorSpace; - - const displaceTexture = await loader.loadAsync('textures/ambientcg/Ice002_1K-JPG_Displacement.jpg'); - displaceTexture.colorSpace = THREE.NoColorSpace; - - // - - const bottomTexture = await loader.loadAsync('textures/ambientcg/Ice003_1K-JPG_Color.jpg'); - bottomTexture.colorSpace = THREE.SRGBColorSpace; - bottomTexture.wrapS = THREE.RepeatWrapping; - bottomTexture.wrapT = THREE.RepeatWrapping; - - // paralax effect - - const parallaxScale = 0.3; - const offsetUV = texture(displaceTexture).mul(parallaxScale); - - const parallaxUVOffset = parallaxUV(uv(), offsetUV); - const parallaxResult = texture(bottomTexture, parallaxUVOffset); - - const iceNode = overlay(texture(topTexture), parallaxResult); - - // material - - const material = new THREE.MeshStandardNodeMaterial(); - material.colorNode = iceNode.mul(5); // increase the color intensity to 5 ( contrast ) - material.roughnessNode = texture(roughnessTexture); - material.normalMap = normalTexture; - material.metalness = 0; - - const geometry = new THREE.BoxGeometry(10, 10, 10); - - const ground = new THREE.Mesh(geometry, material); - ground.rotateX(-Math.PI / 2); - scene.add(ground); - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ReinhardToneMapping; - renderer.toneMappingExposure = 6; - document.body.appendChild(renderer.domElement); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0, 0); - controls.maxDistance = 40; - controls.minDistance = 10; - controls.autoRotate = true; - controls.autoRotateSpeed = -1; - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_performance.ts b/examples-testing/examples/webgpu_performance.ts deleted file mode 100644 index 315eba252..000000000 --- a/examples-testing/examples/webgpu_performance.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; - -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let camera, scene, renderer, stats; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(60, 60, 60); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGPURenderer({ antialias: true, forceWebGL: false }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - - renderer.setAnimationLoop(render); - container.appendChild(renderer.domElement); - - // - - stats = new Stats(); - document.body.appendChild(stats.dom); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.environment = texture; - - // model - - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('jsm/libs/draco/gltf/'); - - const loader = new GLTFLoader().setPath('models/gltf/'); - loader.setDRACOLoader(dracoLoader); - - loader.load('dungeon_warkarma.glb', async function (gltf) { - const model = gltf.scene; - - // wait until the model can be added to the scene without blocking due to shader compilation - - await renderer.compileAsync(model, camera, scene); - - scene.add(model); - }); - }); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 60; - controls.target.set(0, 0, -0.2); - controls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - renderer.renderAsync(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_postprocessing.ts b/examples-testing/examples/webgpu_postprocessing.ts deleted file mode 100644 index 7ae63a39d..000000000 --- a/examples-testing/examples/webgpu_postprocessing.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as THREE from 'three'; -import { pass, dotScreen, rgbShift } from 'three/tsl'; - -let camera, renderer, postProcessing; -let object; - -init(); - -function init() { - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 400; - - const scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1, 1000); - - object = new THREE.Object3D(); - scene.add(object); - - const geometry = new THREE.SphereGeometry(1, 4, 4); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true }); - - for (let i = 0; i < 100; i++) { - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize(); - mesh.position.multiplyScalar(Math.random() * 400); - mesh.rotation.set(Math.random() * 2, Math.random() * 2, Math.random() * 2); - mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50; - object.add(mesh); - } - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(1, 1, 1); - scene.add(light); - - // postprocessing - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - const scenePassColor = scenePass.getTextureNode(); - - const dotScreenPass = dotScreen(scenePassColor); - dotScreenPass.scale.value = 0.3; - - const rgbShiftPass = rgbShift(dotScreenPass); - rgbShiftPass.amount.value = 0.001; - - postProcessing.outputNode = rgbShiftPass; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - object.rotation.x += 0.005; - object.rotation.y += 0.01; - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_3dlut.ts b/examples-testing/examples/webgpu_postprocessing_3dlut.ts deleted file mode 100644 index 27500a079..000000000 --- a/examples-testing/examples/webgpu_postprocessing_3dlut.ts +++ /dev/null @@ -1,139 +0,0 @@ -import * as THREE from 'three'; -import { pass, texture3D, uniform, lut3D, renderOutput } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { LUTCubeLoader } from 'three/addons/loaders/LUTCubeLoader.js'; -import { LUT3dlLoader } from 'three/addons/loaders/LUT3dlLoader.js'; -import { LUTImageLoader } from 'three/addons/loaders/LUTImageLoader.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const params = { - lut: 'Bourbon 64.CUBE', - intensity: 1, -}; - -const lutMap = { - 'Bourbon 64.CUBE': null, - 'Chemical 168.CUBE': null, - 'Clayton 33.CUBE': null, - 'Cubicle 99.CUBE': null, - 'Remy 24.CUBE': null, - 'Presetpro-Cinematic.3dl': null, - NeutralLUT: null, - 'B&WLUT': null, - NightLUT: null, -}; - -let gui; -let camera, scene, renderer; -let postProcessing, lutPass; - -init(); - -async function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', function (gltf) { - scene.add(gltf.scene); - }); - }); - - const lutCubeLoader = new LUTCubeLoader(); - const lutImageLoader = new LUTImageLoader(); - const lut3dlLoader = new LUT3dlLoader(); - - for (const name in lutMap) { - if (/\.CUBE$/i.test(name)) { - lutMap[name] = lutCubeLoader.loadAsync('luts/' + name); - } else if (/\LUT$/i.test(name)) { - lutMap[name] = lutImageLoader.loadAsync(`luts/${name}.png`); - } else { - lutMap[name] = lut3dlLoader.loadAsync('luts/' + name); - } - } - - const pendings = Object.values(lutMap); - await Promise.all(pendings); - - for (const name in lutMap) { - lutMap[name] = await lutMap[name]; - } - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - // post processing - - postProcessing = new THREE.PostProcessing(renderer); - - // ignore default output color transform ( toneMapping and outputColorSpace ) - // use renderOutput() for control the sequence - - postProcessing.outputColorTransform = false; - - // scene pass - - const scenePass = pass(scene, camera); - const outputPass = renderOutput(scenePass); - - const lut = lutMap[params.lut]; - lutPass = lut3D(outputPass, texture3D(lut.texture3D), lut.texture3D.image.width, uniform(1)); - - postProcessing.outputNode = lutPass; - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 10; - controls.target.set(0, 0, -0.2); - controls.update(); - - gui = new GUI(); - gui.add(params, 'lut', Object.keys(lutMap)); - gui.add(params, 'intensity').min(0).max(1); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - lutPass.intensityNode.value = params.intensity; - - if (lutMap[params.lut]) { - const lut = lutMap[params.lut]; - lutPass.lutNode.value = lut.texture3D; - lutPass.size.value = lut.texture3D.image.width; - } - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_afterimage.ts b/examples-testing/examples/webgpu_postprocessing_afterimage.ts deleted file mode 100644 index d0775d49b..000000000 --- a/examples-testing/examples/webgpu_postprocessing_afterimage.ts +++ /dev/null @@ -1,70 +0,0 @@ -import * as THREE from 'three'; -import { pass, afterImage } from 'three/tsl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; -let mesh, postProcessing, combinedPass; - -const params = { - damp: 0.96, -}; - -init(); -createGUI(); - -function init() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 400; - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x000000, 1, 1000); - - const geometry = new THREE.TorusKnotGeometry(100, 30, 100, 16); - const material = new THREE.MeshNormalMaterial(); - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // postprocessing - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - const scenePassColor = scenePass.getTextureNode(); - - combinedPass = scenePassColor; - combinedPass = afterImage(combinedPass, params.damp); - - postProcessing.outputNode = combinedPass; - - window.addEventListener('resize', onWindowResize); -} - -function createGUI() { - const gui = new GUI({ title: 'Damp setting' }); - gui.add(combinedPass.damp, 'value', 0, 1).step(0.001); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function render() { - mesh.rotation.x += 0.0075; - mesh.rotation.y += 0.015; - - postProcessing.render(); -} - -function animate() { - render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_ao.ts b/examples-testing/examples/webgpu_postprocessing_ao.ts deleted file mode 100644 index 432d641a0..000000000 --- a/examples-testing/examples/webgpu_postprocessing_ao.ts +++ /dev/null @@ -1,204 +0,0 @@ -import * as THREE from 'three'; -import { pass, mrt, output, transformedNormalView, texture, ao, denoise } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { SimplexNoise } from 'three/addons/math/SimplexNoise.js'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer, postProcessing, controls, clock, stats, mixer; - -let aoPass, denoisePass, blendPassAO, blendPassDenoise, scenePassColor; - -const params = { - distanceExponent: 1, - distanceFallOff: 1, - radius: 0.25, - scale: 1, - thickness: 1, - denoised: true, - enabled: true, - denoiseRadius: 5, - lumaPhi: 5, - depthPhi: 5, - normalPhi: 5, -}; - -init(); - -async function init() { - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(5, 2, 8); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xbfe3dd); - - clock = new THREE.Clock(); - - const hdrloader = new RGBELoader(); - const envMap = await hdrloader.loadAsync('textures/equirectangular/quarry_01_1k.hdr'); - envMap.mapping = THREE.EquirectangularReflectionMapping; - - scene.environment = envMap; - - renderer = new THREE.WebGPURenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 0.5, 0); - controls.update(); - controls.enablePan = false; - controls.enableDamping = true; - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - scenePass.setMRT( - mrt({ - output: output, - normal: transformedNormalView, - }), - ); - - scenePassColor = scenePass.getTextureNode('output'); - const scenePassNormal = scenePass.getTextureNode('normal'); - const scenePassDepth = scenePass.getTextureNode('depth'); - - // ao - - aoPass = ao(scenePassDepth, scenePassNormal, camera); - blendPassAO = aoPass.getTextureNode().mul(scenePassColor); - - // denoise (optional) - - const noiseTexture = texture(generateNoise()); - denoisePass = denoise(aoPass.getTextureNode(), scenePassDepth, scenePassNormal, noiseTexture, camera); - blendPassDenoise = denoisePass.mul(scenePassColor); - - postProcessing.outputNode = blendPassDenoise; - - // - - const dracoLoader = new DRACOLoader(); - dracoLoader.setDecoderPath('jsm/libs/draco/'); - dracoLoader.setDecoderConfig({ type: 'js' }); - const loader = new GLTFLoader(); - loader.setDRACOLoader(dracoLoader); - loader.setPath('models/gltf/'); - - const gltf = await loader.loadAsync('LittlestTokyo.glb'); - - const model = gltf.scene; - model.position.set(1, 1, 0); - model.scale.set(0.01, 0.01, 0.01); - scene.add(model); - - mixer = new THREE.AnimationMixer(model); - mixer.clipAction(gltf.animations[0]).play(); - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - gui.title('AO settings'); - gui.add(params, 'distanceExponent').min(1).max(4).onChange(updateParameters); - gui.add(params, 'distanceFallOff').min(0.01).max(1).onChange(updateParameters); - gui.add(params, 'radius').min(0.01).max(1).onChange(updateParameters); - gui.add(params, 'scale').min(0.01).max(2).onChange(updateParameters); - gui.add(params, 'thickness').min(0.01).max(2).onChange(updateParameters); - gui.add(params, 'denoised').onChange(updatePassChain); - gui.add(params, 'enabled').onChange(updatePassChain); - const folder = gui.addFolder('Denoise settings'); - folder.add(params, 'denoiseRadius').min(0.01).max(10).name('radius').onChange(updateParameters); - folder.add(params, 'lumaPhi').min(0.01).max(10).onChange(updateParameters); - folder.add(params, 'depthPhi').min(0.01).max(10).onChange(updateParameters); - folder.add(params, 'normalPhi').min(0.01).max(10).onChange(updateParameters); -} - -function updatePassChain() { - if (params.enabled === true) { - if (params.denoised === true) { - postProcessing.outputNode = blendPassDenoise; - } else { - postProcessing.outputNode = blendPassAO; - } - } else { - postProcessing.outputNode = scenePassColor; - } - - postProcessing.needsUpdate = true; -} - -function updateParameters() { - aoPass.distanceExponent.value = params.distanceExponent; - aoPass.distanceFallOff.value = params.distanceFallOff; - aoPass.radius.value = params.radius; - aoPass.scale.value = params.scale; - aoPass.thickness.value = params.thickness; - - denoisePass.radius.value = params.denoiseRadius; - denoisePass.lumaPhi.value = params.lumaPhi; - denoisePass.depthPhi.value = params.depthPhi; - denoisePass.normalPhi.value = params.normalPhi; -} - -function generateNoise(size = 64) { - const simplex = new SimplexNoise(); - - const arraySize = size * size * 4; - const data = new Uint8Array(arraySize); - - for (let i = 0; i < size; i++) { - for (let j = 0; j < size; j++) { - const x = i; - const y = j; - - data[(i * size + j) * 4] = (simplex.noise(x, y) * 0.5 + 0.5) * 255; - data[(i * size + j) * 4 + 1] = (simplex.noise(x + size, y) * 0.5 + 0.5) * 255; - data[(i * size + j) * 4 + 2] = (simplex.noise(x, y + size) * 0.5 + 0.5) * 255; - data[(i * size + j) * 4 + 3] = (simplex.noise(x + size, y + size) * 0.5 + 0.5) * 255; - } - } - - const noiseTexture = new THREE.DataTexture(data, size, size); - noiseTexture.wrapS = THREE.RepeatWrapping; - noiseTexture.wrapT = THREE.RepeatWrapping; - noiseTexture.needsUpdate = true; - - return noiseTexture; -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - const delta = clock.getDelta(); - - if (mixer) { - mixer.update(delta); - } - - controls.update(); - - postProcessing.render(); - stats.update(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_bloom.ts b/examples-testing/examples/webgpu_postprocessing_bloom.ts deleted file mode 100644 index d38a7abb1..000000000 --- a/examples-testing/examples/webgpu_postprocessing_bloom.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as THREE from 'three'; -import { pass, bloom } from 'three/tsl'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, stats; -let postProcessing, renderer, mixer, clock; - -const params = { - threshold: 0, - strength: 1, - radius: 0, - exposure: 1, -}; - -init(); - -async function init() { - const container = document.getElementById('container'); - - clock = new THREE.Clock(); - - const scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(-5, 2.5, -3.5); - scene.add(camera); - - scene.add(new THREE.AmbientLight(0xcccccc)); - - const pointLight = new THREE.PointLight(0xffffff, 100); - camera.add(pointLight); - - const loader = new GLTFLoader(); - const gltf = await loader.loadAsync('models/gltf/PrimaryIonDrive.glb'); - - const model = gltf.scene; - scene.add(model); - - mixer = new THREE.AnimationMixer(model); - const clip = gltf.animations[0]; - mixer.clipAction(clip.optimize()).play(); - - // - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ReinhardToneMapping; - container.appendChild(renderer.domElement); - - // - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - const scenePassColor = scenePass.getTextureNode('output'); - - const bloomPass = bloom(scenePassColor); - - postProcessing.outputNode = scenePassColor.add(bloomPass); - - // - - stats = new Stats(); - container.appendChild(stats.dom); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.maxPolarAngle = Math.PI * 0.5; - controls.minDistance = 3; - controls.maxDistance = 8; - - // - - const gui = new GUI(); - - const bloomFolder = gui.addFolder('bloom'); - - bloomFolder.add(params, 'threshold', 0.0, 1.0).onChange(function (value) { - bloomPass.threshold.value = value; - }); - - bloomFolder.add(params, 'strength', 0.0, 3.0).onChange(function (value) { - bloomPass.strength.value = value; - }); - - gui.add(params, 'radius', 0.0, 1.0) - .step(0.01) - .onChange(function (value) { - bloomPass.radius.value = value; - }); - - const toneMappingFolder = gui.addFolder('tone mapping'); - - toneMappingFolder.add(params, 'exposure', 0.1, 2).onChange(function (value) { - renderer.toneMappingExposure = Math.pow(value, 4.0); - }); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - const delta = clock.getDelta(); - - mixer.update(delta); - - postProcessing.render(); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts b/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts deleted file mode 100644 index 7a6569f94..000000000 --- a/examples-testing/examples/webgpu_postprocessing_bloom_emissive.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as THREE from 'three'; -import { pass, mrt, output, bloom, emissive } from 'three/tsl'; - -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; -let postProcessing; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - // - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('moonless_golf_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - const loader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - loader.load('DamagedHelmet.gltf', function (gltf) { - scene.add(gltf.scene); - }); - }); - - // - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - container.appendChild(renderer.domElement); - - // - - const scenePass = pass(scene, camera); - scenePass.setMRT( - mrt({ - output, - emissive, - }), - ); - - const outputPass = scenePass.getTextureNode(); - const emissivePass = scenePass.getTextureNode('emissive'); - - const bloomPass = bloom(emissivePass, 2.5, 0.5); - - postProcessing = new THREE.PostProcessing(renderer); - postProcessing.outputNode = outputPass.add(bloomPass); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 10; - controls.target.set(0, 0, -0.2); - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - - const bloomFolder = gui.addFolder('bloom'); - bloomFolder.add(bloomPass.strength, 'value', 0.0, 5.0).name('strength'); - bloomFolder.add(bloomPass.radius, 'value', 0.0, 1.0).name('radius'); - - const toneMappingFolder = gui.addFolder('tone mapping'); - toneMappingFolder.add(renderer, 'toneMappingExposure', 0.1, 2).name('exposure'); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function render() { - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts b/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts deleted file mode 100644 index 55d6b6bbe..000000000 --- a/examples-testing/examples/webgpu_postprocessing_bloom_selective.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as THREE from 'three'; -import { pass, mrt, output, float, bloom, uniform } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -// scene - -const scene = new THREE.Scene(); - -const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 200); -camera.position.set(0, 0, 20); -camera.lookAt(0, 0, 0); - -const geometry = new THREE.IcosahedronGeometry(1, 15); - -for (let i = 0; i < 50; i++) { - const color = new THREE.Color(); - color.setHSL(Math.random(), 0.7, Math.random() * 0.2 + 0.05); - - const bloomIntensity = Math.random() > 0.5 ? 1 : 0; - - const material = new THREE.MeshBasicNodeMaterial({ color: color }); - material.mrtNode = mrt({ - bloomIntensity: uniform(bloomIntensity), - }); - - const sphere = new THREE.Mesh(geometry, material); - sphere.position.x = Math.random() * 10 - 5; - sphere.position.y = Math.random() * 10 - 5; - sphere.position.z = Math.random() * 10 - 5; - sphere.position.normalize().multiplyScalar(Math.random() * 4.0 + 2.0); - sphere.scale.setScalar(Math.random() * Math.random() + 0.5); - scene.add(sphere); -} - -// renderer - -const renderer = new THREE.WebGPURenderer(); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.setAnimationLoop(animate); -renderer.toneMapping = THREE.NeutralToneMapping; -document.body.appendChild(renderer.domElement); - -// post processing - -const scenePass = pass(scene, camera); -scenePass.setMRT( - mrt({ - output, - bloomIntensity: float(0), // default bloom intensity - }), -); - -const outputPass = scenePass.getTextureNode(); -const bloomIntensityPass = scenePass.getTextureNode('bloomIntensity'); - -const bloomPass = bloom(outputPass.mul(bloomIntensityPass)); - -const postProcessing = new THREE.PostProcessing(renderer); -postProcessing.outputColorTransform = false; -postProcessing.outputNode = outputPass.add(bloomPass).renderOutput(); - -// controls - -const controls = new OrbitControls(camera, renderer.domElement); -controls.maxPolarAngle = Math.PI * 0.5; -controls.minDistance = 1; -controls.maxDistance = 100; - -// raycaster - -const raycaster = new THREE.Raycaster(); -const mouse = new THREE.Vector2(); - -window.addEventListener('pointerdown', event => { - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - raycaster.setFromCamera(mouse, camera); - - const intersects = raycaster.intersectObjects(scene.children, false); - - if (intersects.length > 0) { - const material = intersects[0].object.material; - - const bloomIntensity = material.mrtNode.get('bloomIntensity'); - bloomIntensity.value = bloomIntensity.value === 0 ? 1 : 0; - } -}); - -// gui - -const gui = new GUI(); - -const bloomFolder = gui.addFolder('bloom'); -bloomFolder.add(bloomPass.threshold, 'value', 0.0, 1.0).name('threshold'); -bloomFolder.add(bloomPass.strength, 'value', 0.0, 3).name('strength'); -bloomFolder.add(bloomPass.radius, 'value', 0.0, 1.0).name('radius'); - -const toneMappingFolder = gui.addFolder('tone mapping'); -toneMappingFolder.add(renderer, 'toneMappingExposure', 0.1, 3).name('exposure'); - -// events - -window.onresize = function () { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -}; - -// animate - -function animate() { - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_difference.ts b/examples-testing/examples/webgpu_postprocessing_difference.ts deleted file mode 100644 index dc30eb604..000000000 --- a/examples-testing/examples/webgpu_postprocessing_difference.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as THREE from 'three'; -import { pass, luminance, saturation } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { Timer } from 'three/addons/misc/Timer.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const params = { - speed: 0, -}; - -let camera, renderer, postProcessing; -let timer, mesh, controls; - -init(); - -function init() { - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.NeutralToneMapping; - document.body.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 100); - camera.position.set(1, 2, 3); - - const scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x0487e2, 7, 25); - scene.background = new THREE.Color(0x0487e2); - - timer = new Timer(); - - const texture = new THREE.TextureLoader().load('textures/crate.gif'); - texture.colorSpace = THREE.SRGBColorSpace; - - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshBasicMaterial({ map: texture }); - - mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // post processing - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - - const currentTexture = scenePass.getTextureNode(); - const previousTexture = scenePass.getPreviousTextureNode(); - - const frameDiff = previousTexture.sub(currentTexture).abs(); - - const saturationAmount = luminance(frameDiff).mul(1000).clamp(0, 3); - - postProcessing.outputNode = saturation(currentTexture, saturationAmount); - - // - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 2; - controls.maxDistance = 10; - controls.enableDamping = true; - controls.dampingFactor = 0.01; - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - gui.add(params, 'speed', 0, 2); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - timer.update(); - - controls.update(); - - mesh.rotation.y += timer.getDelta() * 5 * params.speed; - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_dof.ts b/examples-testing/examples/webgpu_postprocessing_dof.ts deleted file mode 100644 index 26d034fba..000000000 --- a/examples-testing/examples/webgpu_postprocessing_dof.ts +++ /dev/null @@ -1,160 +0,0 @@ -import * as THREE from 'three'; -import { cubeTexture, positionWorld, oscSine, timerGlobal, pass, dof, uniform } from 'three/tsl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -// - -let camera, scene, renderer, mesh, stats; - -let mouseX = 0, - mouseY = 0; - -let windowHalfX = window.innerWidth / 2; -let windowHalfY = window.innerHeight / 2; - -let width = window.innerWidth; -let height = window.innerHeight; - -let postProcessing; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, width / height, 1, 3000); - camera.position.z = 200; - - scene = new THREE.Scene(); - - const path = 'textures/cube/SwedishRoyalCastle/'; - const format = '.jpg'; - const urls = [ - path + 'px' + format, - path + 'nx' + format, - path + 'py' + format, - path + 'ny' + format, - path + 'pz' + format, - path + 'nz' + format, - ]; - - const xgrid = 14, - ygrid = 9, - zgrid = 14; - const count = xgrid * ygrid * zgrid; - - const textureCube = new THREE.CubeTextureLoader().load(urls); - const cubeTextureNode = cubeTexture(textureCube); - const oscPos = oscSine(positionWorld.div(1000 /* scene distance */).add(timerGlobal(0.2 /* speed */))); - - const geometry = new THREE.SphereGeometry(60, 20, 10); - const material = new THREE.MeshBasicNodeMaterial(); - material.colorNode = cubeTextureNode.mul(oscPos); - - mesh = new THREE.InstancedMesh(geometry, material, count); - scene.add(mesh); - - const matrix = new THREE.Matrix4(); - - let index = 0; - - for (let i = 0; i < xgrid; i++) { - for (let j = 0; j < ygrid; j++) { - for (let k = 0; k < zgrid; k++) { - const x = 200 * (i - xgrid / 2); - const y = 200 * (j - ygrid / 2); - const z = 200 * (k - zgrid / 2); - - mesh.setMatrixAt(index, matrix.identity().setPosition(x, y, z)); - index++; - } - } - } - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - const effectController = { - focus: uniform(500.0), - aperture: uniform(5), - maxblur: uniform(0.01), - }; - - // post processing - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - - const scenePassColor = scenePass.getTextureNode(); - const scenePassViewZ = scenePass.getViewZNode(); - - const dofPass = dof( - scenePassColor, - scenePassViewZ, - effectController.focus, - effectController.aperture.mul(0.00001), - effectController.maxblur, - ); - - postProcessing.outputNode = dofPass; - - // controls - - renderer.domElement.style.touchAction = 'none'; - renderer.domElement.addEventListener('pointermove', onPointerMove); - - window.addEventListener('resize', onWindowResize); - - // stats - - stats = new Stats(); - document.body.appendChild(stats.dom); - - // gui - - const gui = new GUI(); - gui.add(effectController.focus, 'value', 10.0, 3000.0, 10).name('focus'); - gui.add(effectController.aperture, 'value', 0, 10, 0.1).name('aperture'); - gui.add(effectController.maxblur, 'value', 0.0, 0.01, 0.001).name('maxblur'); -} - -function onPointerMove(event) { - if (event.isPrimary === false) return; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -function onWindowResize() { - windowHalfX = window.innerWidth / 2; - windowHalfY = window.innerHeight / 2; - - width = window.innerWidth; - height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - render(); - //stats.update(); -} - -function render() { - camera.position.x += (mouseX - camera.position.x) * 0.036; - camera.position.y += (-mouseY - camera.position.y) * 0.036; - - camera.lookAt(scene.position); - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_fxaa.ts b/examples-testing/examples/webgpu_postprocessing_fxaa.ts deleted file mode 100644 index 3221614b7..000000000 --- a/examples-testing/examples/webgpu_postprocessing_fxaa.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as THREE from 'three'; -import { pass, fxaa, renderOutput } from 'three/tsl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -const params = { - enabled: true, - animated: false, -}; - -let camera, scene, renderer, clock, group; -let postProcessing; - -init(); - -async function init() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); - camera.position.z = 50; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0xffffff); - - clock = new THREE.Clock(); - - // - - const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d); - hemiLight.position.set(0, 1000, 0); - scene.add(hemiLight); - - const dirLight = new THREE.DirectionalLight(0xffffff, 3); - dirLight.position.set(-3000, 1000, -1000); - scene.add(dirLight); - - // - - group = new THREE.Group(); - - const geometry = new THREE.TetrahedronGeometry(); - const material = new THREE.MeshStandardMaterial({ color: 0xf73232, flatShading: true }); - - for (let i = 0; i < 100; i++) { - const mesh = new THREE.Mesh(geometry, material); - - mesh.position.x = Math.random() * 50 - 25; - mesh.position.y = Math.random() * 50 - 25; - mesh.position.z = Math.random() * 50 - 25; - - mesh.scale.setScalar(Math.random() * 2 + 1); - - mesh.rotation.x = Math.random() * Math.PI; - mesh.rotation.y = Math.random() * Math.PI; - mesh.rotation.z = Math.random() * Math.PI; - - group.add(mesh); - } - - scene.add(group); - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // post processing - - postProcessing = new THREE.PostProcessing(renderer); - - // ignore default output color transform ( toneMapping and outputColorSpace ) - // use renderOutput() for control the sequence - - postProcessing.outputColorTransform = false; - - // scene pass - - const scenePass = pass(scene, camera); - const outputPass = renderOutput(scenePass); - - // FXAA must be computed in sRGB color space (so after tone mapping and color space conversion) - - const fxaaPass = fxaa(outputPass); - postProcessing.outputNode = fxaaPass; - - // - - window.addEventListener('resize', onWindowResize); - - // - - const gui = new GUI(); - gui.title('FXAA settings'); - gui.add(params, 'enabled').onChange(value => { - if (value === true) { - postProcessing.outputNode = fxaaPass; - } else { - postProcessing.outputNode = outputPass; - } - - postProcessing.needsUpdate = true; - }); - gui.add(params, 'animated'); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - const delta = clock.getDelta(); - - if (params.animated === true) { - group.rotation.y += delta * 0.1; - } - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_masking.ts b/examples-testing/examples/webgpu_postprocessing_masking.ts deleted file mode 100644 index a4f56b170..000000000 --- a/examples-testing/examples/webgpu_postprocessing_masking.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as THREE from 'three'; -import { pass, texture } from 'three/tsl'; - -let camera, postProcessing, renderer; -let box, torus; - -init(); - -function init() { - // scene - - const baseScene = new THREE.Scene(); - baseScene.background = new THREE.Color(0xe0e0e0); - - const maskScene1 = new THREE.Scene(); - box = new THREE.Mesh(new THREE.BoxGeometry(4, 4, 4)); - maskScene1.add(box); - - const maskScene2 = new THREE.Scene(); - torus = new THREE.Mesh(new THREE.TorusGeometry(3, 1, 16, 32)); - maskScene2.add(torus); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.z = 10; - - // textures - - const texture1 = new THREE.TextureLoader().load('textures/758px-Canestra_di_frutta_(Caravaggio).jpg'); - texture1.colorSpace = THREE.SRGBColorSpace; - texture1.minFilter = THREE.LinearFilter; - texture1.flipY = false; - - const texture2 = new THREE.TextureLoader().load('textures/2294472375_24a3b8ef46_o.jpg'); - texture2.colorSpace = THREE.SRGBColorSpace; - texture2.flipY = false; - - // renderer - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - // post processing - - const base = pass(baseScene, camera); - const sceneMask1 = pass(maskScene1, camera).a; - const sceneMask2 = pass(maskScene2, camera).a; - - let compose = base; - compose = sceneMask1.mix(compose, texture(texture1)); - compose = sceneMask2.mix(compose, texture(texture2)); - - postProcessing = new THREE.PostProcessing(renderer); - postProcessing.outputNode = compose; -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - const time = performance.now() * 0.001 + 6000; - - box.position.x = Math.cos(time / 1.5) * 2; - box.position.y = Math.sin(time) * 2; - box.rotation.x = time; - box.rotation.y = time / 2; - - torus.position.x = Math.cos(time) * 2; - torus.position.y = Math.sin(time / 1.5) * 2; - torus.rotation.x = time; - torus.rotation.y = time / 2; - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_motion_blur.ts b/examples-testing/examples/webgpu_postprocessing_motion_blur.ts deleted file mode 100644 index 1330953cc..000000000 --- a/examples-testing/examples/webgpu_postprocessing_motion_blur.ts +++ /dev/null @@ -1,205 +0,0 @@ -import * as THREE from 'three'; -import { pass, texture, motionBlur, uniform, output, mrt, mix, velocity, uv, screenUV } from 'three/tsl'; - -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer; -let boxLeft, boxRight, model, mixer, clock; -let postProcessing; -let controls; -let stats; - -const params = { - speed: 1.0, -}; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.25, 30); - camera.position.set(0, 1.5, 4.5); - - scene = new THREE.Scene(); - scene.fog = new THREE.Fog(0x0487e2, 7, 25); - - const sunLight = new THREE.DirectionalLight(0xffe499, 5); - sunLight.castShadow = true; - sunLight.shadow.camera.near = 0.1; - sunLight.shadow.camera.far = 10; - sunLight.shadow.camera.right = 2; - sunLight.shadow.camera.left = -2; - sunLight.shadow.camera.top = 2; - sunLight.shadow.camera.bottom = -2; - sunLight.shadow.mapSize.width = 2048; - sunLight.shadow.mapSize.height = 2048; - sunLight.shadow.bias = -0.001; - sunLight.position.set(4, 4, 2); - - const waterAmbientLight = new THREE.HemisphereLight(0x333366, 0x74ccf4, 5); - const skyAmbientLight = new THREE.HemisphereLight(0x74ccf4, 0, 1); - - scene.add(sunLight); - scene.add(skyAmbientLight); - scene.add(waterAmbientLight); - - clock = new THREE.Clock(); - - // animated model - - const loader = new GLTFLoader(); - loader.load('models/gltf/Xbot.glb', function (gltf) { - model = gltf.scene; - - model.rotation.y = Math.PI / 2; - - model.traverse(function (child) { - if (child.isMesh) { - child.castShadow = true; - child.receiveShadow = true; - } - }); - - mixer = new THREE.AnimationMixer(model); - - const action = mixer.clipAction(gltf.animations[3]); - action.play(); - - scene.add(model); - }); - - // textures - - const textureLoader = new THREE.TextureLoader(); - - const floorColor = textureLoader.load('textures/floors/FloorsCheckerboard_S_Diffuse.jpg'); - floorColor.wrapS = THREE.RepeatWrapping; - floorColor.wrapT = THREE.RepeatWrapping; - floorColor.colorSpace = THREE.SRGBColorSpace; - - const floorNormal = textureLoader.load('textures/floors/FloorsCheckerboard_S_Normal.jpg'); - floorNormal.wrapS = THREE.RepeatWrapping; - floorNormal.wrapT = THREE.RepeatWrapping; - - // floor - - const floorUV = uv().mul(5); - - const floorMaterial = new THREE.MeshPhongNodeMaterial(); - floorMaterial.colorNode = texture(floorColor, floorUV); - - const floor = new THREE.Mesh(new THREE.BoxGeometry(15, 0.001, 15), floorMaterial); - floor.receiveShadow = true; - - floor.position.set(0, 0, 0); - scene.add(floor); - - const walls = new THREE.Mesh( - new THREE.BoxGeometry(15, 15, 15), - new THREE.MeshPhongNodeMaterial({ colorNode: floorMaterial.colorNode, side: THREE.BackSide }), - ); - scene.add(walls); - - const map = new THREE.TextureLoader().load('textures/uv_grid_opengl.jpg'); - map.colorSpace = THREE.SRGBColorSpace; - - const geometry = new THREE.TorusGeometry(0.8); - const material = new THREE.MeshBasicMaterial({ map }); - - boxRight = new THREE.Mesh(geometry, material); - boxRight.position.set(3.5, 1.5, -4); - scene.add(boxRight); - - boxLeft = new THREE.Mesh(geometry, material); - boxLeft.position.set(-3.5, 1.5, -4); - scene.add(boxLeft); - - // renderer - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 1; - controls.maxDistance = 10; - controls.maxPolarAngle = Math.PI / 2; - controls.autoRotate = true; - controls.autoRotateSpeed = 1; - controls.target.set(0, 1, 0); - controls.enableDamping = true; - controls.dampingFactor = 0.05; - controls.update(); - - // post-processing - - const blurAmount = uniform(1); - const showVelocity = uniform(0); - - const scenePass = pass(scene, camera); - - scenePass.setMRT( - mrt({ - output, - velocity, - }), - ); - - const beauty = scenePass.getTextureNode(); - const vel = scenePass.getTextureNode('velocity').mul(blurAmount); - - const mBlur = motionBlur(beauty, vel); - - const vignet = screenUV.distance(0.5).remap(0.6, 1).mul(2).clamp().oneMinus(); - - postProcessing = new THREE.PostProcessing(renderer); - postProcessing.outputNode = mix(mBlur, vel, showVelocity).mul(vignet); - - // - - const gui = new GUI(); - gui.title('Motion Blur Settings'); - gui.add(controls, 'autoRotate'); - gui.add(blurAmount, 'value', 0, 3).name('blur amount'); - gui.add(params, 'speed', 0, 2); - gui.add(showVelocity, 'value', 0, 1).name('show velocity'); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - stats.update(); - - controls.update(); - - const delta = clock.getDelta(); - const speed = params.speed; - - boxRight.rotation.y += delta * 4 * speed; - boxLeft.scale.setScalar(1 + Math.sin(clock.elapsedTime * 10 * speed) * 0.2); - - if (model) { - mixer.update(delta * speed); - } - - postProcessing.render(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_pixel.ts b/examples-testing/examples/webgpu_postprocessing_pixel.ts deleted file mode 100644 index d7e51008d..000000000 --- a/examples-testing/examples/webgpu_postprocessing_pixel.ts +++ /dev/null @@ -1,234 +0,0 @@ -import * as THREE from 'three'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { uniform, pixelationPass } from 'three/tsl'; - -let camera, scene, renderer, postProcessing, crystalMesh, clock; -let gui, effectController; - -init(); - -function init() { - const aspectRatio = window.innerWidth / window.innerHeight; - - camera = new THREE.OrthographicCamera(-aspectRatio, aspectRatio, 1, -1, 0.1, 10); - camera.position.y = 2 * Math.tan(Math.PI / 6); - camera.position.z = 2; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x151729); - - clock = new THREE.Clock(); - - // textures - - const loader = new THREE.TextureLoader(); - const texChecker = pixelTexture(loader.load('textures/checker.png')); - const texChecker2 = pixelTexture(loader.load('textures/checker.png')); - texChecker.repeat.set(3, 3); - texChecker2.repeat.set(1.5, 1.5); - - // meshes - - const boxMaterial = new THREE.MeshPhongMaterial({ map: texChecker2 }); - - function addBox(boxSideLength, x, z, rotation) { - const mesh = new THREE.Mesh(new THREE.BoxGeometry(boxSideLength, boxSideLength, boxSideLength), boxMaterial); - mesh.castShadow = true; - mesh.receiveShadow = true; - mesh.rotation.y = rotation; - mesh.position.y = boxSideLength / 2; - mesh.position.set(x, boxSideLength / 2 + 0.0001, z); - scene.add(mesh); - return mesh; - } - - addBox(0.4, 0, 0, Math.PI / 4); - addBox(0.5, -0.5, -0.5, Math.PI / 4); - - const planeSideLength = 2; - const planeMesh = new THREE.Mesh( - new THREE.PlaneGeometry(planeSideLength, planeSideLength), - new THREE.MeshPhongMaterial({ map: texChecker }), - ); - planeMesh.receiveShadow = true; - planeMesh.rotation.x = -Math.PI / 2; - scene.add(planeMesh); - - const radius = 0.2; - const geometry = new THREE.IcosahedronGeometry(radius); - crystalMesh = new THREE.Mesh( - geometry, - new THREE.MeshPhongMaterial({ - color: 0x68b7e9, - emissive: 0x4f7e8b, - shininess: 10, - specular: 0xffffff, - }), - ); - crystalMesh.receiveShadow = true; - crystalMesh.castShadow = true; - scene.add(crystalMesh); - - // lights - - scene.add(new THREE.AmbientLight(0x757f8e, 3)); - - const directionalLight = new THREE.DirectionalLight(0xfffecd, 1.5); - directionalLight.position.set(100, 100, 100); - directionalLight.castShadow = true; - directionalLight.shadow.mapSize.set(2048, 2048); - directionalLight.shadow.bias = -0.0001; - scene.add(directionalLight); - - const spotLight = new THREE.SpotLight(0xffc100, 10, 10, Math.PI / 16, 0.02, 2); - spotLight.position.set(2, 2, 0); - const target = spotLight.target; - scene.add(target); - target.position.set(0, 0, 0); - spotLight.castShadow = true; - spotLight.shadow.bias = -0.001; - scene.add(spotLight); - - renderer = new THREE.WebGPURenderer(); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.BasicShadowMap; - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - effectController = { - pixelSize: uniform(6), - normalEdgeStrength: uniform(0.3), - depthEdgeStrength: uniform(0.4), - pixelAlignedPanning: true, - }; - - postProcessing = new THREE.PostProcessing(renderer); - const scenePass = pixelationPass( - scene, - camera, - effectController.pixelSize, - effectController.normalEdgeStrength, - effectController.depthEdgeStrength, - ); - postProcessing.outputNode = scenePass; - - window.addEventListener('resize', onWindowResize); - - const controls = new OrbitControls(camera, renderer.domElement); - controls.maxZoom = 2; - - // gui - - gui = new GUI(); - gui.add(effectController.pixelSize, 'value', 1, 16, 1).name('Pixel Size'); - gui.add(effectController.normalEdgeStrength, 'value', 0, 2, 0.05).name('Normal Edge Strength'); - gui.add(effectController.depthEdgeStrength, 'value', 0, 1, 0.05).name('Depth Edge Strength'); - gui.add(effectController, 'pixelAlignedPanning'); -} - -function onWindowResize() { - const aspectRatio = window.innerWidth / window.innerHeight; - camera.left = -aspectRatio; - camera.right = aspectRatio; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const t = clock.getElapsedTime(); - - crystalMesh.material.emissiveIntensity = Math.sin(t * 3) * 0.5 + 0.5; - crystalMesh.position.y = 0.7 + Math.sin(t * 2) * 0.05; - crystalMesh.rotation.y = stopGoEased(t, 2, 4) * 2 * Math.PI; - - const rendererSize = renderer.getSize(new THREE.Vector2()); - const aspectRatio = rendererSize.x / rendererSize.y; - - if (effectController.pixelAlignedPanning) { - const pixelSize = effectController.pixelSize.value; - - pixelAlignFrustum( - camera, - aspectRatio, - Math.floor(rendererSize.x / pixelSize), - Math.floor(rendererSize.y / pixelSize), - ); - } else if (camera.left != -aspectRatio || camera.top != 1.0) { - // Reset the Camera Frustum if it has been modified - camera.left = -aspectRatio; - camera.right = aspectRatio; - camera.top = 1.0; - camera.bottom = -1.0; - camera.updateProjectionMatrix(); - } - - postProcessing.render(); -} - -// Helper functions - -function pixelTexture(texture) { - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.generateMipmaps = false; - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - texture.colorSpace = THREE.SRGBColorSpace; - return texture; -} - -function easeInOutCubic(x) { - return x ** 2 * 3 - x ** 3 * 2; -} - -function linearStep(x, edge0, edge1) { - const w = edge1 - edge0; - const m = 1 / w; - const y0 = -m * edge0; - return THREE.MathUtils.clamp(y0 + m * x, 0, 1); -} - -function stopGoEased(x, downtime, period) { - const cycle = (x / period) | 0; - const tween = x - cycle * period; - const linStep = easeInOutCubic(linearStep(tween, downtime, period)); - return cycle + linStep; -} - -function pixelAlignFrustum(camera, aspectRatio, pixelsPerScreenWidth, pixelsPerScreenHeight) { - // 0. Get Pixel Grid Units - const worldScreenWidth = (camera.right - camera.left) / camera.zoom; - const worldScreenHeight = (camera.top - camera.bottom) / camera.zoom; - const pixelWidth = worldScreenWidth / pixelsPerScreenWidth; - const pixelHeight = worldScreenHeight / pixelsPerScreenHeight; - - // 1. Project the current camera position along its local rotation bases - const camPos = new THREE.Vector3(); - camera.getWorldPosition(camPos); - const camRot = new THREE.Quaternion(); - camera.getWorldQuaternion(camRot); - const camRight = new THREE.Vector3(1.0, 0.0, 0.0).applyQuaternion(camRot); - const camUp = new THREE.Vector3(0.0, 1.0, 0.0).applyQuaternion(camRot); - const camPosRight = camPos.dot(camRight); - const camPosUp = camPos.dot(camUp); - - // 2. Find how far along its position is along these bases in pixel units - const camPosRightPx = camPosRight / pixelWidth; - const camPosUpPx = camPosUp / pixelHeight; - - // 3. Find the fractional pixel units and convert to world units - const fractX = camPosRightPx - Math.round(camPosRightPx); - const fractY = camPosUpPx - Math.round(camPosUpPx); - - // 4. Add fractional world units to the left/right top/bottom to align with the pixel grid - camera.left = -aspectRatio - fractX * pixelWidth; - camera.right = aspectRatio - fractX * pixelWidth; - camera.top = 1.0 - fractY * pixelHeight; - camera.bottom = -1.0 - fractY * pixelHeight; - camera.updateProjectionMatrix(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_sobel.ts b/examples-testing/examples/webgpu_postprocessing_sobel.ts deleted file mode 100644 index 01aa16ecd..000000000 --- a/examples-testing/examples/webgpu_postprocessing_sobel.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as THREE from 'three'; -import { pass, sobel } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; -let postProcessing; - -const params = { - enable: true, -}; - -init(); - -function init() { - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(0, 1, 3); - camera.lookAt(scene.position); - - // - - const ambientLight = new THREE.AmbientLight(0xe7e7e7); - scene.add(ambientLight); - - const pointLight = new THREE.PointLight(0xffffff, 20); - camera.add(pointLight); - scene.add(camera); - - // - - const geometry = new THREE.TorusKnotGeometry(1, 0.3, 256, 32); - const material = new THREE.MeshPhongMaterial({ color: 0xffff00 }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.outputColorSpace = THREE.LinearSRGBColorSpace; - document.body.appendChild(renderer.domElement); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - - // postprocessing - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePass = pass(scene, camera); - const scenePassColor = scenePass.getTextureNode(); - - postProcessing.outputNode = sobel(scenePassColor); - - // - - const gui = new GUI(); - - gui.add(params, 'enable'); - gui.open(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - if (params.enable === true) { - postProcessing.render(); - } else { - renderer.render(scene, camera); - } -} diff --git a/examples-testing/examples/webgpu_postprocessing_ssaa.ts b/examples-testing/examples/webgpu_postprocessing_ssaa.ts deleted file mode 100644 index 76e3a95cd..000000000 --- a/examples-testing/examples/webgpu_postprocessing_ssaa.ts +++ /dev/null @@ -1,181 +0,0 @@ -import * as THREE from 'three'; -import { ssaaPass } from 'three/tsl'; - -import { Timer } from 'three/addons/misc/Timer.js'; -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let scene, mesh, renderer, postProcessing; -let camera, ssaaRenderPass; -let gui, stats, timer; - -const params = { - sampleLevel: 3, - camera: 'perspective', - clearColor: 'black', - clearAlpha: 1.0, - viewOffsetX: 0, - autoRotate: true, -}; - -init(); - -clearGui(); - -function clearGui() { - if (gui) gui.destroy(); - - gui = new GUI(); - - gui.add(params, 'sampleLevel', { - 'Level 0: 1 Sample': 0, - 'Level 1: 2 Samples': 1, - 'Level 2: 4 Samples': 2, - 'Level 3: 8 Samples': 3, - 'Level 4: 16 Samples': 4, - 'Level 5: 32 Samples': 5, - }); - gui.add(params, 'clearColor', ['black', 'white', 'blue', 'green', 'red']); - gui.add(params, 'clearAlpha', 0, 1); - gui.add(params, 'viewOffsetX', -100, 100); - gui.add(params, 'autoRotate'); - - gui.open(); -} - -function init() { - const width = window.innerWidth; - const height = window.innerHeight; - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - stats = new Stats(); - document.body.appendChild(stats.dom); - - timer = new Timer(); - - camera = new THREE.PerspectiveCamera(65, width / height, 3, 10); - camera.position.z = 7; - camera.setViewOffset(width, height, params.viewOffsetX, 0, width, height); - - scene = new THREE.Scene(); - - const group = new THREE.Group(); - scene.add(group); - - const light = new THREE.PointLight(0xefffef, 500); - light.position.z = 10; - light.position.y = -10; - light.position.x = -10; - scene.add(light); - - const light2 = new THREE.PointLight(0xffefef, 500); - light2.position.z = 10; - light2.position.x = -10; - light2.position.y = 10; - scene.add(light2); - - const light3 = new THREE.PointLight(0xefefff, 500); - light3.position.z = 10; - light3.position.x = 10; - light3.position.y = -10; - scene.add(light3); - - const light4 = new THREE.AmbientLight(0xffffff, 0.2); - scene.add(light4); - - const geometry = new THREE.SphereGeometry(3, 48, 24); - const material = new THREE.MeshStandardMaterial(); - - mesh = new THREE.InstancedMesh(geometry, material, 120); - - const dummy = new THREE.Mesh(); - const color = new THREE.Color(); - - for (let i = 0; i < mesh.count; i++) { - dummy.position.x = Math.random() * 4 - 2; - dummy.position.y = Math.random() * 4 - 2; - dummy.position.z = Math.random() * 4 - 2; - dummy.rotation.x = Math.random(); - dummy.rotation.y = Math.random(); - dummy.rotation.z = Math.random(); - dummy.scale.setScalar(Math.random() * 0.2 + 0.05); - - dummy.updateMatrix(); - - color.setHSL(Math.random(), 1.0, 0.3); - - mesh.setMatrixAt(i, dummy.matrix); - mesh.setColorAt(i, color); - } - - scene.add(mesh); - - // postprocessing - - postProcessing = new THREE.PostProcessing(renderer); - - ssaaRenderPass = ssaaPass(scene, camera); - const scenePassColor = ssaaRenderPass.getTextureNode(); - - postProcessing.outputNode = scenePassColor; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.setViewOffset(width, height, params.viewOffsetX, 0, width, height); - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); -} - -function animate() { - timer.update(); - - if (params.autoRotate) { - const delta = timer.getDelta(); - - mesh.rotation.x += delta * 0.25; - mesh.rotation.y += delta * 0.5; - } - - let newColor = ssaaRenderPass.clearColor; - - switch (params.clearColor) { - case 'blue': - newColor = 0x0000ff; - break; - case 'red': - newColor = 0xff0000; - break; - case 'green': - newColor = 0x00ff00; - break; - case 'white': - newColor = 0xffffff; - break; - case 'black': - newColor = 0x000000; - break; - } - - ssaaRenderPass.clearColor.set(newColor); - ssaaRenderPass.clearAlpha = params.clearAlpha; - - ssaaRenderPass.sampleLevel = params.sampleLevel; - - camera.view.offsetX = params.viewOffsetX; - - postProcessing.render(); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_postprocessing_transition.ts b/examples-testing/examples/webgpu_postprocessing_transition.ts deleted file mode 100644 index b66bad12c..000000000 --- a/examples-testing/examples/webgpu_postprocessing_transition.ts +++ /dev/null @@ -1,200 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import TWEEN from 'three/addons/libs/tween.module.js'; -import { uniform, transition, pass } from 'three/tsl'; - -let renderer, postProcessing, transitionController, transitionPass; - -const textures = []; -const clock = new THREE.Clock(); - -const effectController = { - animateScene: true, - animateTransition: true, - transition: 0, - _transition: uniform(0), - useTexture: true, - _useTexture: uniform(1), - texture: 5, - cycle: true, - threshold: uniform(0.1), -}; - -function generateInstancedMesh(geometry, material, count) { - const mesh = new THREE.InstancedMesh(geometry, material, count); - - const dummy = new THREE.Object3D(); - const color = new THREE.Color(); - - for (let i = 0; i < count; i++) { - dummy.position.x = Math.random() * 100 - 50; - dummy.position.y = Math.random() * 60 - 30; - dummy.position.z = Math.random() * 80 - 40; - - dummy.rotation.x = Math.random() * 2 * Math.PI; - dummy.rotation.y = Math.random() * 2 * Math.PI; - dummy.rotation.z = Math.random() * 2 * Math.PI; - - dummy.scale.x = Math.random() * 2 + 1; - - if (geometry.type === 'BoxGeometry') { - dummy.scale.y = Math.random() * 2 + 1; - dummy.scale.z = Math.random() * 2 + 1; - } else { - dummy.scale.y = dummy.scale.x; - dummy.scale.z = dummy.scale.x; - } - - dummy.updateMatrix(); - - mesh.setMatrixAt(i, dummy.matrix); - mesh.setColorAt(i, color.setScalar(0.1 + 0.9 * Math.random())); - } - - return mesh; -} - -function FXScene(geometry, rotationSpeed, backgroundColor) { - const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.z = 20; - - // Setup scene - const scene = new THREE.Scene(); - scene.background = new THREE.Color(backgroundColor); - scene.add(new THREE.AmbientLight(0xaaaaaa, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 1, 4); - scene.add(light); - - this.rotationSpeed = rotationSpeed; - - const color = geometry.type === 'BoxGeometry' ? 0x0000ff : 0xff0000; - const material = new THREE.MeshPhongNodeMaterial({ color: color, flatShading: true }); - const mesh = generateInstancedMesh(geometry, material, 500); - scene.add(mesh); - - this.scene = scene; - this.camera = camera; - this.mesh = mesh; - - this.update = function (delta) { - if (effectController.animateScene) { - mesh.rotation.x += this.rotationSpeed.x * delta; - mesh.rotation.y += this.rotationSpeed.y * delta; - mesh.rotation.z += this.rotationSpeed.z * delta; - } - }; - - this.resize = function () { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - }; -} - -const fxSceneA = new FXScene(new THREE.BoxGeometry(2, 2, 2), new THREE.Vector3(0, -0.4, 0), 0xffffff); -const fxSceneB = new FXScene(new THREE.IcosahedronGeometry(1, 1), new THREE.Vector3(0, 0.2, 0.1), 0x000000); - -function init() { - // Initialize textures - - const loader = new THREE.TextureLoader(); - - for (let i = 0; i < 6; i++) { - textures[i] = loader.load('textures/transition/transition' + (i + 1) + '.png'); - } - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - postProcessing = new THREE.PostProcessing(renderer); - - const scenePassA = pass(fxSceneA.scene, fxSceneA.camera); - const scenePassB = pass(fxSceneB.scene, fxSceneB.camera); - - transitionPass = transition( - scenePassA, - scenePassB, - new THREE.TextureNode(textures[effectController.texture]), - effectController._transition, - effectController.threshold, - effectController._useTexture, - ); - - postProcessing.outputNode = transitionPass; - - const gui = new GUI(); - - gui.add(effectController, 'animateScene').name('Animate Scene'); - gui.add(effectController, 'animateTransition').name('Animate Transition'); - transitionController = gui - .add(effectController, 'transition', 0, 1, 0.01) - .name('transition') - .onChange(() => { - effectController._transition.value = effectController.transition; - }); - gui.add(effectController, 'useTexture').onChange(() => { - const value = effectController.useTexture ? 1 : 0; - effectController._useTexture.value = value; - }); - gui.add(effectController, 'texture', { Perlin: 0, Squares: 1, Cells: 2, Distort: 3, Gradient: 4, Radial: 5 }); - gui.add(effectController, 'cycle'); - gui.add(effectController.threshold, 'value', 0, 1, 0.01).name('threshold'); -} - -window.addEventListener('resize', onWindowResize); - -function onWindowResize() { - fxSceneA.resize(); - fxSceneB.resize(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -new TWEEN.Tween(effectController) - .to({ transition: 1 }, 1500) - .onUpdate(function () { - transitionController.setValue(effectController.transition); - - // Change the current alpha texture after each transition - if (effectController.cycle) { - if (effectController.transition == 0 || effectController.transition == 1) { - effectController.texture = (effectController.texture + 1) % textures.length; - } - } - }) - .repeat(Infinity) - .delay(2000) - .yoyo(true) - .start(); - -function animate() { - if (effectController.animateTransition) TWEEN.update(); - - if (textures[effectController.texture]) { - const mixTexture = textures[effectController.texture]; - transitionPass.mixTextureNode.value = mixTexture; - } - - const delta = clock.getDelta(); - fxSceneA.update(delta); - fxSceneB.update(delta); - - render(); -} - -function render() { - // Prevent render both scenes when it's not necessary - if (effectController.transition === 0) { - renderer.render(fxSceneB.scene, fxSceneB.camera); - } else if (effectController.transition === 1) { - renderer.render(fxSceneA.scene, fxSceneA.camera); - } else { - postProcessing.render(); - } -} - -init(); diff --git a/examples-testing/examples/webgpu_procedural_texture.ts b/examples-testing/examples/webgpu_procedural_texture.ts deleted file mode 100644 index 84e8ba9e4..000000000 --- a/examples-testing/examples/webgpu_procedural_texture.ts +++ /dev/null @@ -1,74 +0,0 @@ -import * as THREE from 'three'; -import { checker, uv, uniform, gaussianBlur, convertToTexture } from 'three/tsl'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -let camera, scene, renderer; - -init(); -render(); - -function init() { - const aspect = window.innerWidth / window.innerHeight; - camera = new THREE.OrthographicCamera(-aspect, aspect, 1, -1, 0, 2); - camera.position.z = 1; - - scene = new THREE.Scene(); - - // procedural to texture - - const uvScale = uniform(4); - const blurAmount = uniform(0.5); - - const procedural = checker(uv().mul(uvScale)); - const proceduralToTexture = convertToTexture(procedural, 512, 512); // ( node, width, height ) - - const colorNode = gaussianBlur(proceduralToTexture, blurAmount, 10); - - // extra - - //proceduralToTexture.autoUpdate = false; // update just once - //proceduralToTexture.textureNeedsUpdate = true; // manually update - - // scene - - const material = new THREE.MeshBasicNodeMaterial(); - material.colorNode = colorNode; - - const plane = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), material); - scene.add(plane); - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(render); - document.body.appendChild(renderer.domElement); - - window.addEventListener('resize', onWindowResize); - - // gui - - const gui = new GUI(); - gui.add(uvScale, 'value', 1, 10).name('uv scale ( before rtt )'); - gui.add(blurAmount, 'value', 0, 2).name('blur amount ( after rtt )'); - gui.add(proceduralToTexture, 'autoUpdate').name('auto update'); -} - -function onWindowResize() { - renderer.setSize(window.innerWidth, window.innerHeight); - - const aspect = window.innerWidth / window.innerHeight; - - const frustumHeight = camera.top - camera.bottom; - - camera.left = (-frustumHeight * aspect) / 2; - camera.right = (frustumHeight * aspect) / 2; - - camera.updateProjectionMatrix(); -} - -function render() { - renderer.renderAsync(scene, camera); -} diff --git a/examples-testing/examples/webgpu_refraction.ts b/examples-testing/examples/webgpu_refraction.ts deleted file mode 100644 index 4ce8b0a77..000000000 --- a/examples-testing/examples/webgpu_refraction.ts +++ /dev/null @@ -1,141 +0,0 @@ -import * as THREE from 'three'; -import { viewportSafeUV, viewportSharedTexture, screenUV, texture, uv } from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer; - -let cameraControls; - -let smallSphere; - -init(); - -function init() { - // scene - scene = new THREE.Scene(); - - // camera - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500); - camera.position.set(0, 50, 160); - - // - - const geometry = new THREE.IcosahedronGeometry(5, 0); - const material = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x7b7b7b, flatShading: true }); - smallSphere = new THREE.Mesh(geometry, material); - scene.add(smallSphere); - - // textures - - const loader = new THREE.TextureLoader(); - - const floorNormal = loader.load('textures/floors/FloorsCheckerboard_S_Normal.jpg'); - floorNormal.wrapS = THREE.RepeatWrapping; - floorNormal.wrapT = THREE.RepeatWrapping; - - // refractor - - const verticalNormalScale = 0.1; - const verticalUVOffset = texture(floorNormal, uv().mul(5)).xy.mul(2).sub(1).mul(verticalNormalScale); - - const refractorUV = screenUV.add(verticalUVOffset); - const verticalRefractor = viewportSharedTexture(viewportSafeUV(refractorUV)); - - const planeGeo = new THREE.PlaneGeometry(100.1, 100.1); - - const planeRefractor = new THREE.Mesh( - planeGeo, - new THREE.MeshBasicNodeMaterial({ - backdropNode: verticalRefractor, - }), - ); - planeRefractor.material.transparent = true; - planeRefractor.position.y = 50; - scene.add(planeRefractor); - - // walls - - const planeTop = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeTop.position.y = 100; - planeTop.rotateX(Math.PI / 2); - scene.add(planeTop); - - const planeBottom = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xffffff })); - planeBottom.rotateX(-Math.PI / 2); - scene.add(planeBottom); - - const planeBack = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x7f7fff })); - planeBack.position.z = -50; - planeBack.position.y = 50; - scene.add(planeBack); - - const planeRight = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0x00ff00 })); - planeRight.position.x = 50; - planeRight.position.y = 50; - planeRight.rotateY(-Math.PI / 2); - scene.add(planeRight); - - const planeLeft = new THREE.Mesh(planeGeo, new THREE.MeshPhongMaterial({ color: 0xff0000 })); - planeLeft.position.x = -50; - planeLeft.position.y = 50; - planeLeft.rotateY(Math.PI / 2); - scene.add(planeLeft); - - // lights - - const mainLight = new THREE.PointLight(0xe7e7e7, 2.5, 250, 0); - mainLight.position.y = 60; - scene.add(mainLight); - - const greenLight = new THREE.PointLight(0x00ff00, 0.5, 1000, 0); - greenLight.position.set(550, 50, 0); - scene.add(greenLight); - - const redLight = new THREE.PointLight(0xff0000, 0.5, 1000, 0); - redLight.position.set(-550, 50, 0); - scene.add(redLight); - - const blueLight = new THREE.PointLight(0xbbbbfe, 0.5, 1000, 0); - blueLight.position.set(0, 50, 550); - scene.add(blueLight); - - // renderer - - renderer = new THREE.WebGPURenderer(/*{ antialias: true }*/); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // controls - - cameraControls = new OrbitControls(camera, renderer.domElement); - cameraControls.target.set(0, 50, 0); - cameraControls.maxDistance = 400; - cameraControls.minDistance = 10; - cameraControls.update(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const timer = Date.now() * 0.01; - - smallSphere.position.set( - Math.cos(timer * 0.1) * 30, - Math.abs(Math.cos(timer * 0.2)) * 20 + 5, - Math.sin(timer * 0.1) * 30, - ); - smallSphere.rotation.y = Math.PI / 2 - timer * 0.1; - smallSphere.rotation.z = timer * 0.8; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_shadowmap_vsm.ts b/examples-testing/examples/webgpu_shadowmap_vsm.ts deleted file mode 100644 index a9f6f0e53..000000000 --- a/examples-testing/examples/webgpu_shadowmap_vsm.ts +++ /dev/null @@ -1,206 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, clock, stats; -let dirLight, spotLight; -let torusKnot, dirGroup; -let config; - -init(); - -function init() { - initScene(); - initMisc(); - - // Init gui - const gui = new GUI(); - - config = { - spotlightRadius: 4, - spotlightSamples: 8, - dirlightRadius: 4, - dirlightSamples: 8, - animate: true, - }; - - const spotlightFolder = gui.addFolder('Spotlight'); - spotlightFolder - .add(config, 'spotlightRadius') - .name('radius') - .min(0) - .max(25) - .onChange(function (value) { - spotLight.shadow.radius = value; - }); - - spotlightFolder - .add(config, 'spotlightSamples', 1, 25, 1) - .name('samples') - .onChange(function (value) { - spotLight.shadow.blurSamples = value; - }); - spotlightFolder.open(); - - const dirlightFolder = gui.addFolder('Directional Light'); - dirlightFolder - .add(config, 'dirlightRadius') - .name('radius') - .min(0) - .max(25) - .onChange(function (value) { - dirLight.shadow.radius = value; - }); - - dirlightFolder - .add(config, 'dirlightSamples', 1, 25, 1) - .name('samples') - .onChange(function (value) { - dirLight.shadow.blurSamples = value; - }); - dirlightFolder.open(); - - gui.add(config, 'animate'); - - document.body.appendChild(renderer.domElement); - window.addEventListener('resize', onWindowResize); -} - -function initScene() { - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); - camera.position.set(0, 10, 30); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x222244); - scene.fog = new THREE.Fog(0x222244, 50, 100); - - // Lights - - scene.add(new THREE.AmbientLight(0x444444)); - - spotLight = new THREE.SpotLight(0xff8888, 400); - spotLight.angle = Math.PI / 5; - spotLight.penumbra = 0.3; - spotLight.position.set(8, 10, 5); - spotLight.castShadow = true; - spotLight.shadow.camera.near = 8; - spotLight.shadow.camera.far = 200; - spotLight.shadow.mapSize.width = 256; - spotLight.shadow.mapSize.height = 256; - spotLight.shadow.bias = -0.002; - spotLight.shadow.radius = 4; - scene.add(spotLight); - - dirLight = new THREE.DirectionalLight(0x8888ff, 3); - dirLight.position.set(3, 12, 17); - dirLight.castShadow = true; - dirLight.shadow.camera.near = 0.1; - dirLight.shadow.camera.far = 500; - dirLight.shadow.camera.right = 17; - dirLight.shadow.camera.left = -17; - dirLight.shadow.camera.top = 17; - dirLight.shadow.camera.bottom = -17; - dirLight.shadow.mapSize.width = 512; - dirLight.shadow.mapSize.height = 512; - dirLight.shadow.radius = 4; - dirLight.shadow.bias = -0.0005; - - dirGroup = new THREE.Group(); - dirGroup.add(dirLight); - scene.add(dirGroup); - - // Geometry - - const geometry = new THREE.TorusKnotGeometry(25, 8, 75, 20); - const material = new THREE.MeshPhongMaterial({ - color: 0x999999, - shininess: 0, - specular: 0x222222, - }); - - torusKnot = new THREE.Mesh(geometry, material); - torusKnot.scale.multiplyScalar(1 / 18); - torusKnot.position.y = 3; - torusKnot.castShadow = true; - torusKnot.receiveShadow = true; - scene.add(torusKnot); - - const cylinderGeometry = new THREE.CylinderGeometry(0.75, 0.75, 7, 32); - - const pillar1 = new THREE.Mesh(cylinderGeometry, material); - pillar1.position.set(8, 3.5, 8); - pillar1.castShadow = true; - pillar1.receiveShadow = true; - - const pillar2 = pillar1.clone(); - pillar2.position.set(8, 3.5, -8); - const pillar3 = pillar1.clone(); - pillar3.position.set(-8, 3.5, 8); - const pillar4 = pillar1.clone(); - pillar4.position.set(-8, 3.5, -8); - - scene.add(pillar1); - scene.add(pillar2); - scene.add(pillar3); - scene.add(pillar4); - - const planeGeometry = new THREE.PlaneGeometry(200, 200); - const planeMaterial = new THREE.MeshPhongMaterial({ - color: 0x999999, - shininess: 0, - specular: 0x111111, - }); - - const ground = new THREE.Mesh(planeGeometry, planeMaterial); - ground.rotation.x = -Math.PI / 2; - ground.scale.multiplyScalar(3); - ground.castShadow = true; - ground.receiveShadow = true; - scene.add(ground); -} - -function initMisc() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.VSMShadowMap; - - // Mouse control - const controls = new OrbitControls(camera, renderer.domElement); - controls.target.set(0, 2, 0); - controls.update(); - - clock = new THREE.Clock(); - - stats = new Stats(); - document.body.appendChild(stats.dom); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate(time) { - const delta = clock.getDelta(); - - if (config.animate === true) { - torusKnot.rotation.x += 0.25 * delta; - torusKnot.rotation.y += 0.5 * delta; - torusKnot.rotation.z += 1 * delta; - - dirGroup.rotation.y += 0.7 * delta; - dirLight.position.z = 17 + Math.sin(time * 0.001) * 5; - } - - renderer.render(scene, camera); - - stats.update(); -} diff --git a/examples-testing/examples/webgpu_sky.ts b/examples-testing/examples/webgpu_sky.ts deleted file mode 100644 index 097d06af6..000000000 --- a/examples-testing/examples/webgpu_sky.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { SkyMesh } from 'three/addons/objects/SkyMesh.js'; - -let camera, scene, renderer; - -let sky, sun; - -init(); - -function initSky() { - // Add Sky - sky = new SkyMesh(); - sky.scale.setScalar(450000); - scene.add(sky); - - sun = new THREE.Vector3(); - - /// GUI - - const effectController = { - turbidity: 10, - rayleigh: 3, - mieCoefficient: 0.005, - mieDirectionalG: 0.7, - elevation: 2, - azimuth: 180, - exposure: renderer.toneMappingExposure, - }; - - function guiChanged() { - sky.turbidity.value = effectController.turbidity; - sky.rayleigh.value = effectController.rayleigh; - sky.mieCoefficient.value = effectController.mieCoefficient; - sky.mieDirectionalG.value = effectController.mieDirectionalG; - - const phi = THREE.MathUtils.degToRad(90 - effectController.elevation); - const theta = THREE.MathUtils.degToRad(effectController.azimuth); - - sun.setFromSphericalCoords(1, phi, theta); - - sky.sunPosition.value.copy(sun); - - renderer.toneMappingExposure = effectController.exposure; - } - - const gui = new GUI(); - - gui.add(effectController, 'turbidity', 0.0, 20.0, 0.1).onChange(guiChanged); - gui.add(effectController, 'rayleigh', 0.0, 4, 0.001).onChange(guiChanged); - gui.add(effectController, 'mieCoefficient', 0.0, 0.1, 0.001).onChange(guiChanged); - gui.add(effectController, 'mieDirectionalG', 0.0, 1, 0.001).onChange(guiChanged); - gui.add(effectController, 'elevation', 0, 90, 0.1).onChange(guiChanged); - gui.add(effectController, 'azimuth', -180, 180, 0.1).onChange(guiChanged); - gui.add(effectController, 'exposure', 0, 1, 0.0001).onChange(guiChanged); - - guiChanged(); -} - -function init() { - camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 2000000); - camera.position.set(0, 100, 2000); - - scene = new THREE.Scene(); - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 0.5; - document.body.appendChild(renderer.domElement); - - const controls = new OrbitControls(camera, renderer.domElement); - //controls.maxPolarAngle = Math.PI / 2; - controls.enableZoom = false; - controls.enablePan = false; - - initSky(); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_textures_2d-array_compressed.ts b/examples-testing/examples/webgpu_textures_2d-array_compressed.ts deleted file mode 100644 index 3e8bf7ee6..000000000 --- a/examples-testing/examples/webgpu_textures_2d-array_compressed.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as THREE from 'three'; - -import { texture, uniform, uv } from 'three/tsl'; - -import Stats from 'three/addons/libs/stats.module.js'; -import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; - -let camera, scene, mesh, renderer, stats, clock; - -const depth = uniform(0); - -const planeWidth = 50; -const planeHeight = 25; - -let depthStep = 1; - -init(); - -async function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); - camera.position.z = 70; - - scene = new THREE.Scene(); - - // - clock = new THREE.Clock(); - - renderer = new THREE.WebGPURenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - // - - const ktx2Loader = new KTX2Loader(); - ktx2Loader.setTranscoderPath('jsm/libs/basis/'); - await ktx2Loader.detectSupportAsync(renderer); - - ktx2Loader.load('textures/spiritedaway.ktx2', function (texturearray) { - const material = new THREE.NodeMaterial(); - - material.colorNode = texture(texturearray, uv().flipY()).depth(depth); - const geometry = new THREE.PlaneGeometry(planeWidth, planeHeight); - - mesh = new THREE.Mesh(geometry, material); - - scene.add(mesh); - }); - - stats = new Stats(); - container.appendChild(stats.dom); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - if (mesh) { - const delta = clock.getDelta() * 10; - - depthStep += delta; - - const value = depthStep % 5; - - depth.value = value; - } - - render(); - stats.update(); -} - -function render() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_textures_anisotropy.ts b/examples-testing/examples/webgpu_textures_anisotropy.ts deleted file mode 100644 index 7eb0ce1b3..000000000 --- a/examples-testing/examples/webgpu_textures_anisotropy.ts +++ /dev/null @@ -1,155 +0,0 @@ -import * as THREE from 'three'; - -import Stats from 'three/addons/libs/stats.module.js'; - -let container, stats; - -let camera, scene1, scene2, renderer; - -let mouseX = 0, - mouseY = 0; - -init(); - -function init() { - const SCREEN_WIDTH = window.innerWidth; - const SCREEN_HEIGHT = window.innerHeight; - - container = document.createElement('div'); - document.body.appendChild(container); - - renderer = new THREE.WebGPURenderer({ antialias: true, forceWebGL: false }); - - // RENDERER - - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); - renderer.setAnimationLoop(animate); - renderer.autoClear = false; - - renderer.domElement.style.position = 'relative'; - container.appendChild(renderer.domElement); - - // - - camera = new THREE.PerspectiveCamera(35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 25000); - camera.position.z = 1500; - - scene1 = new THREE.Scene(); - scene1.fog = new THREE.Fog(0xf2f7ff, 1, 25000); - - scene2 = new THREE.Scene(); - scene2.fog = new THREE.Fog(0xf2f7ff, 1, 25000); - - scene1.add(new THREE.AmbientLight(0xeef0ff, 3)); - scene2.add(new THREE.AmbientLight(0xeef0ff, 3)); - - const light1 = new THREE.DirectionalLight(0xffffff, 6); - light1.position.set(1, 1, 1); - scene1.add(light1); - - const light2 = new THREE.DirectionalLight(0xffffff, 6); - light2.position.set(1, 1, 1); - scene2.add(light2); - - // GROUND - - const textureLoader = new THREE.TextureLoader(); - - const maxAnisotropy = renderer.getMaxAnisotropy(); - - const texture1 = textureLoader.load('textures/crate.gif'); - const material1 = new THREE.MeshPhongMaterial({ color: 0xffffff, map: texture1 }); - - texture1.colorSpace = THREE.SRGBColorSpace; - texture1.anisotropy = renderer.getMaxAnisotropy(); - texture1.wrapS = texture1.wrapT = THREE.RepeatWrapping; - texture1.repeat.set(512, 512); - - const texture2 = textureLoader.load('textures/crate.gif'); - const material2 = new THREE.MeshPhongMaterial({ color: 0xffffff, map: texture2 }); - - texture2.colorSpace = THREE.SRGBColorSpace; - texture2.anisotropy = 1; - texture2.wrapS = texture2.wrapT = THREE.RepeatWrapping; - texture2.repeat.set(512, 512); - - if (maxAnisotropy > 0) { - document.getElementById('val_left').innerHTML = texture1.anisotropy; - document.getElementById('val_right').innerHTML = texture2.anisotropy; - } else { - document.getElementById('val_left').innerHTML = 'not supported'; - document.getElementById('val_right').innerHTML = 'not supported'; - } - - // - - const geometry = new THREE.PlaneGeometry(100, 100); - - const mesh1 = new THREE.Mesh(geometry, material1); - mesh1.rotation.x = -Math.PI / 2; - mesh1.scale.set(1000, 1000, 1000); - - const mesh2 = new THREE.Mesh(geometry, material2); - mesh2.rotation.x = -Math.PI / 2; - mesh2.scale.set(1000, 1000, 1000); - - scene1.add(mesh1); - scene2.add(mesh2); - - // STATS1 - - stats = new Stats(); - container.appendChild(stats.dom); - - document.addEventListener('mousemove', onDocumentMouseMove); - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onDocumentMouseMove(event) { - const windowHalfX = window.innerWidth / 2; - const windowHalfY = window.innerHeight / 2; - - mouseX = event.clientX - windowHalfX; - mouseY = event.clientY - windowHalfY; -} - -function animate() { - render(); - stats.update(); -} - -function render() { - const SCREEN_WIDTH = window.innerWidth; - const SCREEN_HEIGHT = window.innerHeight; - - camera.position.x += (mouseX - camera.position.x) * 0.05; - camera.position.y = THREE.MathUtils.clamp( - camera.position.y + (-(mouseY - 200) - camera.position.y) * 0.05, - 50, - 1000, - ); - - camera.lookAt(scene1.position); - renderer.clear(); - - renderer.setScissorTest(true); - - renderer.setScissor(0, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene1, camera); - - renderer.setScissorTest(true); - - renderer.setScissor(SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT); - renderer.render(scene2, camera); - - renderer.setScissorTest(false); -} diff --git a/examples-testing/examples/webgpu_textures_partialupdate.ts b/examples-testing/examples/webgpu_textures_partialupdate.ts deleted file mode 100644 index e8ebe87db..000000000 --- a/examples-testing/examples/webgpu_textures_partialupdate.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer, clock, dataTexture, diffuseMap; - -let last = 0; -const position = new THREE.Vector2(); -const color = new THREE.Color(); - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10); - camera.position.z = 2; - - scene = new THREE.Scene(); - - clock = new THREE.Clock(); - - const loader = new THREE.TextureLoader(); - diffuseMap = loader.load('textures/carbon/Carbon.png', animate); - diffuseMap.colorSpace = THREE.SRGBColorSpace; - diffuseMap.minFilter = THREE.LinearFilter; - diffuseMap.generateMipmaps = false; - - const geometry = new THREE.PlaneGeometry(2, 2); - const material = new THREE.MeshBasicMaterial({ map: diffuseMap }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - // - - const width = 32; - const height = 32; - - const data = new Uint8Array(width * height * 4); - dataTexture = new THREE.DataTexture(data, width, height); - - // - - renderer = new THREE.WebGPURenderer({ antialias: true, forceWebGL: false }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - - document.body.appendChild(renderer.domElement); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -async function animate() { - requestAnimationFrame(animate); - - const elapsedTime = clock.getElapsedTime(); - - await renderer.renderAsync(scene, camera); - - if (elapsedTime - last > 0.1) { - last = elapsedTime; - - position.x = 32 * THREE.MathUtils.randInt(1, 16) - 32; - position.y = 32 * THREE.MathUtils.randInt(1, 16) - 32; - - // generate new color data - updateDataTexture(dataTexture); - - // perform copy from src to dest texture to a random position - - renderer.copyTextureToTexture(dataTexture, diffuseMap, null, position); - } -} - -function updateDataTexture(texture) { - const size = texture.image.width * texture.image.height; - const data = texture.image.data; - - // generate a random color and update texture data - - color.setHex(Math.random() * 0xffffff); - - const r = Math.floor(color.r * 255); - const g = Math.floor(color.g * 255); - const b = Math.floor(color.b * 255); - - for (let i = 0; i < size; i++) { - const stride = i * 4; - - data[stride] = r; - data[stride + 1] = g; - data[stride + 2] = b; - data[stride + 3] = 1; - } - - texture.needsUpdate = true; -} diff --git a/examples-testing/examples/webgpu_tonemapping.ts b/examples-testing/examples/webgpu_tonemapping.ts deleted file mode 100644 index 07fb8d272..000000000 --- a/examples-testing/examples/webgpu_tonemapping.ts +++ /dev/null @@ -1,137 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; - -let mesh, renderer, scene, camera, controls; -let gui, - guiExposure = null; - -const params = { - exposure: 1.0, - toneMapping: 'AgX', - blurriness: 0.3, - intensity: 1.0, -}; - -const toneMappingOptions = { - None: THREE.NoToneMapping, - Linear: THREE.LinearToneMapping, - Reinhard: THREE.ReinhardToneMapping, - Cineon: THREE.CineonToneMapping, - ACESFilmic: THREE.ACESFilmicToneMapping, - AgX: THREE.AgXToneMapping, - Neutral: THREE.NeutralToneMapping, -}; - -init().catch(function (err) { - console.error(err); -}); - -async function init() { - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - renderer.toneMapping = toneMappingOptions[params.toneMapping]; - renderer.toneMappingExposure = params.exposure; - - scene = new THREE.Scene(); - scene.backgroundBlurriness = params.blurriness; - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20); - camera.position.set(-1.8, 0.6, 2.7); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableZoom = false; - controls.enablePan = false; - controls.target.set(0, 0, -0.2); - controls.update(); - - const rgbeLoader = new RGBELoader().setPath('textures/equirectangular/'); - - const gltfLoader = new GLTFLoader().setPath('models/gltf/DamagedHelmet/glTF/'); - - const [texture, gltf] = await Promise.all([ - rgbeLoader.loadAsync('venice_sunset_1k.hdr'), - gltfLoader.loadAsync('DamagedHelmet.gltf'), - ]); - - // environment - - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - - // model - - mesh = gltf.scene.getObjectByName('node_damagedHelmet_-6514'); - scene.add(mesh); - - window.addEventListener('resize', onWindowResize); - - gui = new GUI(); - const toneMappingFolder = gui.addFolder('Tone Mapping'); - - toneMappingFolder - .add(params, 'toneMapping', Object.keys(toneMappingOptions)) - - .name('type') - .onChange(function () { - updateGUI(toneMappingFolder); - - renderer.toneMapping = toneMappingOptions[params.toneMapping]; - }); - - guiExposure = toneMappingFolder - .add(params, 'exposure', 0, 2) - - .onChange(function (value) { - renderer.toneMappingExposure = value; - }); - - const backgroundFolder = gui.addFolder('Background'); - - backgroundFolder - .add(params, 'blurriness', 0, 1) - - .onChange(function (value) { - scene.backgroundBlurriness = value; - }); - - backgroundFolder - .add(params, 'intensity', 0, 1) - - .onChange(function (value) { - scene.backgroundIntensity = value; - }); - - updateGUI(toneMappingFolder); - - gui.open(); -} - -function updateGUI(folder) { - if (params.toneMapping === 'None') { - guiExposure.hide(); - } else { - guiExposure.show(); - } -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_tsl_coffee_smoke.ts b/examples-testing/examples/webgpu_tsl_coffee_smoke.ts deleted file mode 100644 index 9e2404cc8..000000000 --- a/examples-testing/examples/webgpu_tsl_coffee_smoke.ts +++ /dev/null @@ -1,146 +0,0 @@ -import * as THREE from 'three'; -import { - mix, - mul, - oneMinus, - positionLocal, - smoothstep, - texture, - timerLocal, - rotateUV, - Fn, - uv, - vec2, - vec3, - vec4, -} from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; - -let camera, scene, renderer, controls; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(8, 10, 12); - - scene = new THREE.Scene(); - - // Loaders - - const gltfLoader = new GLTFLoader(); - const textureLoader = new THREE.TextureLoader(); - - // baked model - - gltfLoader.load('./models/gltf/coffeeMug.glb', gltf => { - gltf.scene.getObjectByName('baked').material.map.anisotropy = 8; - scene.add(gltf.scene); - }); - - // geometry - - const smokeGeometry = new THREE.PlaneGeometry(1, 1, 16, 64); - smokeGeometry.translate(0, 0.5, 0); - smokeGeometry.scale(1.5, 6, 1.5); - - // texture - - const noiseTexture = textureLoader.load('./textures/noises/perlin/128x128.png'); - noiseTexture.wrapS = THREE.RepeatWrapping; - noiseTexture.wrapT = THREE.RepeatWrapping; - - // material - - const smokeMaterial = new THREE.MeshBasicNodeMaterial({ - transparent: true, - side: THREE.DoubleSide, - depthWrite: false, - }); - const time = timerLocal(); - - // position - - smokeMaterial.positionNode = Fn(() => { - // twist - - const twistNoiseUv = vec2(0.5, uv().y.mul(0.2).sub(time.mul(0.005)).mod(1)); - const twist = texture(noiseTexture, twistNoiseUv).r.mul(10); - positionLocal.xz.assign(rotateUV(positionLocal.xz, twist, vec2(0))); - - // wind - - const windOffset = vec2( - texture(noiseTexture, vec2(0.25, time.mul(0.01)).mod(1)).r.sub(0.5), - texture(noiseTexture, vec2(0.75, time.mul(0.01)).mod(1)).r.sub(0.5), - ).mul(uv().y.pow(2).mul(10)); - positionLocal.addAssign(windOffset); - - return positionLocal; - })(); - - // color - - smokeMaterial.colorNode = Fn(() => { - // alpha - - const alphaNoiseUv = uv() - .mul(vec2(0.5, 0.3)) - .add(vec2(0, time.mul(0.03).negate())); - const alpha = mul( - // pattern - texture(noiseTexture, alphaNoiseUv).r.smoothstep(0.4, 1), - - // edges fade - smoothstep(0, 0.1, uv().x), - smoothstep(0, 0.1, oneMinus(uv().x)), - smoothstep(0, 0.1, uv().y), - smoothstep(0, 0.1, oneMinus(uv().y)), - ); - - // color - - const finalColor = mix(vec3(0.6, 0.3, 0.2), vec3(1, 1, 1), alpha.pow(3)); - - return vec4(finalColor, alpha); - })(); - - // mesh - - const smoke = new THREE.Mesh(smokeGeometry, smokeMaterial); - smoke.position.y = 1.83; - scene.add(smoke); - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // controls - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 0.1; - controls.maxDistance = 50; - controls.target.y = 3; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -async function animate() { - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_tsl_vfx_flames.ts b/examples-testing/examples/webgpu_tsl_vfx_flames.ts deleted file mode 100644 index 6e72392a2..000000000 --- a/examples-testing/examples/webgpu_tsl_vfx_flames.ts +++ /dev/null @@ -1,204 +0,0 @@ -import * as THREE from 'three'; -import { - PI2, - oneMinus, - spherizeUV, - sin, - step, - texture, - timerLocal, - Fn, - uv, - vec2, - vec3, - vec4, - mix, - billboarding, -} from 'three/tsl'; - -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -let camera, scene, renderer, controls; - -init(); - -function init() { - camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 0.1, 100); - camera.position.set(1, 1, 3); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x201919); - - // textures - - const textureLoader = new THREE.TextureLoader(); - - const cellularTexture = textureLoader.load('./textures/noises/voronoi/grayscale-256x256.png'); - const perlinTexture = textureLoader.load('./textures/noises/perlin/rgb-256x256.png'); - - // gradient canvas - - const gradient = {}; - gradient.element = document.createElement('canvas'); - gradient.element.width = 128; - gradient.element.height = 1; - gradient.context = gradient.element.getContext('2d'); - - gradient.colors = ['#090033', '#5f1f93', '#e02e96', '#ffbd80', '#fff0db']; - - gradient.texture = new THREE.CanvasTexture(gradient.element); - gradient.texture.colorSpace = THREE.SRGBColorSpace; - - gradient.update = () => { - const fillGradient = gradient.context.createLinearGradient(0, 0, gradient.element.width, 0); - - for (let i = 0; i < gradient.colors.length; i++) { - const progress = i / (gradient.colors.length - 1); - const color = gradient.colors[i]; - fillGradient.addColorStop(progress, color); - } - - gradient.context.fillStyle = fillGradient; - gradient.context.fillRect(0, 0, gradient.element.width, gradient.element.height); - - gradient.texture.needsUpdate = true; - }; - - gradient.update(); - - // flame 1 material - - const flame1Material = new THREE.SpriteNodeMaterial({ transparent: true, side: THREE.DoubleSide }); - - flame1Material.colorNode = Fn(() => { - const time = timerLocal(); - - // main UV - const mainUv = uv().toVar(); - mainUv.assign(spherizeUV(mainUv, 10).mul(0.6).add(0.2)); // spherize - mainUv.assign(mainUv.pow(vec2(1, 2))); // stretch - mainUv.assign(mainUv.mul(2, 1).sub(vec2(0.5, 0))); // scale - - // gradients - const gradient1 = sin(time.mul(10).sub(mainUv.y.mul(PI2).mul(2))).toVar(); - const gradient2 = mainUv.y.smoothstep(0, 1).toVar(); - mainUv.x.addAssign(gradient1.mul(gradient2).mul(0.2)); - - // cellular noise - const cellularUv = mainUv - .mul(0.5) - .add(vec2(0, time.negate().mul(0.5))) - .mod(1); - const cellularNoise = texture(cellularTexture, cellularUv, 0).r.oneMinus().smoothstep(0, 0.5).oneMinus(); - cellularNoise.mulAssign(gradient2); - - // shape - const shape = mainUv.sub(0.5).mul(vec2(3, 2)).length().oneMinus().toVar(); - shape.assign(shape.sub(cellularNoise)); - - // gradient color - const gradientColor = texture(gradient.texture, vec2(shape.remap(0, 1, 0, 1), 0)); - - // output - const color = mix(gradientColor, vec3(1), shape.step(0.8).oneMinus()); - const alpha = shape.smoothstep(0, 0.3); - return vec4(color.rgb, alpha); - })(); - - // flame 2 material - - const flame2Material = new THREE.SpriteNodeMaterial({ transparent: true, side: THREE.DoubleSide }); - - flame2Material.colorNode = Fn(() => { - const time = timerLocal(); - - // main UV - const mainUv = uv().toVar(); - mainUv.assign(spherizeUV(mainUv, 10).mul(0.6).add(0.2)); // spherize - mainUv.assign(mainUv.pow(vec2(1, 3))); // stretch - mainUv.assign(mainUv.mul(2, 1).sub(vec2(0.5, 0))); // scale - - // perlin noise - const perlinUv = mainUv.add(vec2(0, time.negate().mul(1))).mod(1); - const perlinNoise = texture(perlinTexture, perlinUv, 0).sub(0.5).mul(1); - mainUv.x.addAssign(perlinNoise.x.mul(0.5)); - - // gradients - const gradient1 = sin(time.mul(10).sub(mainUv.y.mul(PI2).mul(2))); - const gradient2 = mainUv.y.smoothstep(0, 1); - const gradient3 = oneMinus(mainUv.y).smoothstep(0, 0.3); - mainUv.x.addAssign(gradient1.mul(gradient2).mul(0.2)); - - // displaced perlin noise - const displacementPerlinUv = mainUv - .mul(0.5) - .add(vec2(0, time.negate().mul(0.25))) - .mod(1); - const displacementPerlinNoise = texture(perlinTexture, displacementPerlinUv, 0).sub(0.5).mul(1); - const displacedPerlinUv = mainUv - .add(vec2(0, time.negate().mul(0.5))) - .add(displacementPerlinNoise) - .mod(1); - const displacedPerlinNoise = texture(perlinTexture, displacedPerlinUv, 0).sub(0.5).mul(1); - mainUv.x.addAssign(displacedPerlinNoise.mul(0.5)); - - // cellular noise - const cellularUv = mainUv.add(vec2(0, time.negate().mul(1.5))).mod(1); - const cellularNoise = texture(cellularTexture, cellularUv, 0).r.oneMinus().smoothstep(0.25, 1); - - // shape - const shape = mainUv.sub(0.5).mul(vec2(6, 1)).length().step(0.5); - shape.assign(shape.mul(cellularNoise)); - shape.mulAssign(gradient3); - shape.assign(step(0.01, shape)); - - // output - return vec4(vec3(1), shape); - })(); - - // billboarding - follow the camera rotation only horizontally - - flame1Material.vertexNode = billboarding(); - flame2Material.vertexNode = billboarding(); - - // meshes - - const flame1 = new THREE.Sprite(flame1Material); - flame1.center.set(0.5, 0); - flame1.scale.x = 0.5; // optional - flame1.position.x = -0.5; - scene.add(flame1); - - const flame2 = new THREE.Sprite(flame2Material); - flame2.center.set(0.5, 0); - flame2.position.x = 0.5; - scene.add(flame2); - - // renderer - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - controls = new OrbitControls(camera, renderer.domElement); - controls.enableDamping = true; - controls.minDistance = 0.1; - controls.maxDistance = 50; - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -async function animate() { - controls.update(); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_video_panorama.ts b/examples-testing/examples/webgpu_video_panorama.ts deleted file mode 100644 index e409b3c07..000000000 --- a/examples-testing/examples/webgpu_video_panorama.ts +++ /dev/null @@ -1,99 +0,0 @@ -import * as THREE from 'three'; - -let camera, scene, renderer; - -let isUserInteracting = false, - lon = 0, - lat = 0, - phi = 0, - theta = 0, - onPointerDownPointerX = 0, - onPointerDownPointerY = 0, - onPointerDownLon = 0, - onPointerDownLat = 0; - -const distance = 0.5; - -init(); - -function init() { - const container = document.getElementById('container'); - - camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.25, 10); - - scene = new THREE.Scene(); - - const geometry = new THREE.SphereGeometry(5, 60, 40); - // invert the geometry on the x-axis so that all of the faces point inward - geometry.scale(-1, 1, 1); - - const video = document.getElementById('video'); - video.play(); - - const texture = new THREE.VideoTexture(video); - texture.colorSpace = THREE.SRGBColorSpace; - const material = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh = new THREE.Mesh(geometry, material); - scene.add(mesh); - - renderer = new THREE.WebGPURenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - container.appendChild(renderer.domElement); - - document.addEventListener('pointerdown', onPointerDown); - document.addEventListener('pointermove', onPointerMove); - document.addEventListener('pointerup', onPointerUp); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onPointerDown(event) { - isUserInteracting = true; - - onPointerDownPointerX = event.clientX; - onPointerDownPointerY = event.clientY; - - onPointerDownLon = lon; - onPointerDownLat = lat; -} - -function onPointerMove(event) { - if (isUserInteracting === true) { - lon = (onPointerDownPointerX - event.clientX) * 0.1 + onPointerDownLon; - lat = (onPointerDownPointerY - event.clientY) * 0.1 + onPointerDownLat; - } -} - -function onPointerUp() { - isUserInteracting = false; -} - -function animate() { - update(); -} - -function update() { - lat = Math.max(-85, Math.min(85, lat)); - phi = THREE.MathUtils.degToRad(90 - lat); - theta = THREE.MathUtils.degToRad(lon); - - camera.position.x = distance * Math.sin(phi) * Math.cos(theta); - camera.position.y = distance * Math.cos(phi); - camera.position.z = distance * Math.sin(phi) * Math.sin(theta); - - camera.lookAt(0, 0, 0); - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webgpu_water.ts b/examples-testing/examples/webgpu_water.ts deleted file mode 100644 index 76e09f1f8..000000000 --- a/examples-testing/examples/webgpu_water.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as THREE from 'three'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { WaterMesh } from 'three/addons/objects/Water2Mesh.js'; - -let scene, camera, clock, renderer, water; - -let torusKnot; - -const params = { - color: '#ffffff', - scale: 4, - flowX: 1, - flowY: 1, -}; - -init(); - -function init() { - // scene - - scene = new THREE.Scene(); - - // camera - - camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); - camera.position.set(-15, 7, 15); - camera.lookAt(scene.position); - - // clock - - clock = new THREE.Clock(); - - // mesh - - const torusKnotGeometry = new THREE.TorusKnotGeometry(3, 1, 256, 32); - const torusKnotMaterial = new THREE.MeshNormalMaterial(); - - torusKnot = new THREE.Mesh(torusKnotGeometry, torusKnotMaterial); - torusKnot.position.y = 4; - torusKnot.scale.set(0.5, 0.5, 0.5); - scene.add(torusKnot); - - // ground - - const groundGeometry = new THREE.PlaneGeometry(20, 20); - const groundMaterial = new THREE.MeshStandardMaterial({ roughness: 0.8, metalness: 0.4 }); - const ground = new THREE.Mesh(groundGeometry, groundMaterial); - ground.rotation.x = Math.PI * -0.5; - scene.add(ground); - - const textureLoader = new THREE.TextureLoader(); - textureLoader.load('textures/hardwood2_diffuse.jpg', function (map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 16; - map.repeat.set(4, 4); - map.colorSpace = THREE.SRGBColorSpace; - groundMaterial.map = map; - groundMaterial.needsUpdate = true; - }); - - // - - const normalMap0 = textureLoader.load('textures/water/Water_1_M_Normal.jpg'); - const normalMap1 = textureLoader.load('textures/water/Water_2_M_Normal.jpg'); - - normalMap0.wrapS = normalMap0.wrapT = THREE.RepeatWrapping; - normalMap1.wrapS = normalMap1.wrapT = THREE.RepeatWrapping; - - // water - - const waterGeometry = new THREE.PlaneGeometry(20, 20); - - water = new WaterMesh(waterGeometry, { - color: params.color, - scale: params.scale, - flowDirection: new THREE.Vector2(params.flowX, params.flowY), - normalMap0: normalMap0, - normalMap1: normalMap1, - }); - - water.position.y = 1; - water.rotation.x = Math.PI * -0.5; - scene.add(water); - - // skybox - - const cubeTextureLoader = new THREE.CubeTextureLoader(); - cubeTextureLoader.setPath('textures/cube/Park2/'); - - const cubeTexture = cubeTextureLoader.load([ - 'posx.jpg', - 'negx.jpg', - 'posy.jpg', - 'negy.jpg', - 'posz.jpg', - 'negz.jpg', - ]); - - scene.background = cubeTexture; - - // light - - const ambientLight = new THREE.AmbientLight(0xe7e7e7, 1.2); - scene.add(ambientLight); - - const directionalLight = new THREE.DirectionalLight(0xffffff, 2); - directionalLight.position.set(-1, 1, 1); - scene.add(directionalLight); - - // renderer - - renderer = new THREE.WebGPURenderer(); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setAnimationLoop(animate); - document.body.appendChild(renderer.domElement); - - // gui - - const gui = new GUI(); - const waterNode = water.material.fragmentNode; - - gui.addColor(params, 'color').onChange(function (value) { - waterNode.color.value.set(value); - }); - gui.add(params, 'scale', 1, 10).onChange(function (value) { - waterNode.scale.value = value; - }); - gui.add(params, 'flowX', -1, 1) - .step(0.01) - .onChange(function (value) { - waterNode.flowDirection.value.x = value; - waterNode.flowDirection.value.normalize(); - }); - gui.add(params, 'flowY', -1, 1) - .step(0.01) - .onChange(function (value) { - waterNode.flowDirection.value.y = value; - waterNode.flowDirection.value.normalize(); - }); - - gui.open(); - - // - - const controls = new OrbitControls(camera, renderer.domElement); - controls.minDistance = 5; - controls.maxDistance = 50; - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const delta = clock.getDelta(); - - torusKnot.rotation.x += delta; - torusKnot.rotation.y += delta * 0.5; - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_ar_cones.ts b/examples-testing/examples/webxr_ar_cones.ts deleted file mode 100644 index 95eb34393..000000000 --- a/examples-testing/examples/webxr_ar_cones.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as THREE from 'three'; -import { ARButton } from 'three/addons/webxr/ARButton.js'; - -let camera, scene, renderer; -let controller; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 20); - - const light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 3); - light.position.set(0.5, 1, 0.25); - scene.add(light); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - container.appendChild(renderer.domElement); - - // - - document.body.appendChild(ARButton.createButton(renderer)); - - // - - const geometry = new THREE.CylinderGeometry(0, 0.05, 0.2, 32).rotateX(Math.PI / 2); - - function onSelect() { - const material = new THREE.MeshPhongMaterial({ color: 0xffffff * Math.random() }); - const mesh = new THREE.Mesh(geometry, material); - mesh.position.set(0, 0, -0.3).applyMatrix4(controller.matrixWorld); - mesh.quaternion.setFromRotationMatrix(controller.matrixWorld); - scene.add(mesh); - } - - controller = renderer.xr.getController(0); - controller.addEventListener('select', onSelect); - scene.add(controller); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_ar_hittest.ts b/examples-testing/examples/webxr_ar_hittest.ts deleted file mode 100644 index 1867cc470..000000000 --- a/examples-testing/examples/webxr_ar_hittest.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as THREE from 'three'; -import { ARButton } from 'three/addons/webxr/ARButton.js'; - -let container; -let camera, scene, renderer; -let controller; - -let reticle; - -let hitTestSource = null; -let hitTestSourceRequested = false; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 20); - - const light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 3); - light.position.set(0.5, 1, 0.25); - scene.add(light); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - container.appendChild(renderer.domElement); - - // - - document.body.appendChild(ARButton.createButton(renderer, { requiredFeatures: ['hit-test'] })); - - // - - const geometry = new THREE.CylinderGeometry(0.1, 0.1, 0.2, 32).translate(0, 0.1, 0); - - function onSelect() { - if (reticle.visible) { - const material = new THREE.MeshPhongMaterial({ color: 0xffffff * Math.random() }); - const mesh = new THREE.Mesh(geometry, material); - reticle.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale); - mesh.scale.y = Math.random() * 2 + 1; - scene.add(mesh); - } - } - - controller = renderer.xr.getController(0); - controller.addEventListener('select', onSelect); - scene.add(controller); - - reticle = new THREE.Mesh( - new THREE.RingGeometry(0.15, 0.2, 32).rotateX(-Math.PI / 2), - new THREE.MeshBasicMaterial(), - ); - reticle.matrixAutoUpdate = false; - reticle.visible = false; - scene.add(reticle); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate(timestamp, frame) { - if (frame) { - const referenceSpace = renderer.xr.getReferenceSpace(); - const session = renderer.xr.getSession(); - - if (hitTestSourceRequested === false) { - session.requestReferenceSpace('viewer').then(function (referenceSpace) { - session.requestHitTestSource({ space: referenceSpace }).then(function (source) { - hitTestSource = source; - }); - }); - - session.addEventListener('end', function () { - hitTestSourceRequested = false; - hitTestSource = null; - }); - - hitTestSourceRequested = true; - } - - if (hitTestSource) { - const hitTestResults = frame.getHitTestResults(hitTestSource); - - if (hitTestResults.length) { - const hit = hitTestResults[0]; - - reticle.visible = true; - reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix); - } else { - reticle.visible = false; - } - } - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_ar_lighting.ts b/examples-testing/examples/webxr_ar_lighting.ts deleted file mode 100644 index 9de23ad94..000000000 --- a/examples-testing/examples/webxr_ar_lighting.ts +++ /dev/null @@ -1,124 +0,0 @@ -import * as THREE from 'three'; -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { ARButton } from 'three/addons/webxr/ARButton.js'; -import { XREstimatedLight } from 'three/addons/webxr/XREstimatedLight.js'; - -let camera, scene, renderer; -let controller; -let defaultEnvironment; - -init(); - -function init() { - const container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 20); - - const defaultLight = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 1); - defaultLight.position.set(0.5, 1, 0.25); - scene.add(defaultLight); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - container.appendChild(renderer.domElement); - - // Don't add the XREstimatedLight to the scene initially. - // It doesn't have any estimated lighting values until an AR session starts. - - const xrLight = new XREstimatedLight(renderer); - - xrLight.addEventListener('estimationstart', () => { - // Swap the default light out for the estimated one one we start getting some estimated values. - scene.add(xrLight); - scene.remove(defaultLight); - - // The estimated lighting also provides an environment cubemap, which we can apply here. - if (xrLight.environment) { - scene.environment = xrLight.environment; - } - }); - - xrLight.addEventListener('estimationend', () => { - // Swap the lights back when we stop receiving estimated values. - scene.add(defaultLight); - scene.remove(xrLight); - - // Revert back to the default environment. - scene.environment = defaultEnvironment; - }); - - // - - new RGBELoader().setPath('textures/equirectangular/').load('royal_esplanade_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - defaultEnvironment = texture; - - scene.environment = defaultEnvironment; - }); - - // - - // In order for lighting estimation to work, 'light-estimation' must be included as either an optional or required feature. - document.body.appendChild(ARButton.createButton(renderer, { optionalFeatures: ['light-estimation'] })); - - // - - const ballGeometry = new THREE.SphereGeometry(0.175, 32, 32); - const ballGroup = new THREE.Group(); - ballGroup.position.z = -2; - - const rows = 3; - const cols = 3; - - for (let i = 0; i < rows; i++) { - for (let j = 0; j < cols; j++) { - const ballMaterial = new THREE.MeshStandardMaterial({ - color: 0xdddddd, - roughness: i / rows, - metalness: j / cols, - }); - const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial); - ballMesh.position.set((i + 0.5 - rows * 0.5) * 0.4, (j + 0.5 - cols * 0.5) * 0.4, 0); - ballGroup.add(ballMesh); - } - } - - scene.add(ballGroup); - - // - - function onSelect() { - ballGroup.position.set(0, 0, -2).applyMatrix4(controller.matrixWorld); - ballGroup.quaternion.setFromRotationMatrix(controller.matrixWorld); - } - - controller = renderer.xr.getController(0); - controller.addEventListener('select', onSelect); - scene.add(controller); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_ar_plane_detection.ts b/examples-testing/examples/webxr_ar_plane_detection.ts deleted file mode 100644 index 841b6b04b..000000000 --- a/examples-testing/examples/webxr_ar_plane_detection.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as THREE from 'three'; -import { ARButton } from 'three/addons/webxr/ARButton.js'; -import { XRPlanes } from 'three/addons/webxr/XRPlanes.js'; - -// - -const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.setAnimationLoop(animate); -renderer.xr.enabled = true; -document.body.appendChild(renderer.domElement); - -document.body.appendChild( - ARButton.createButton(renderer, { - requiredFeatures: ['plane-detection'], - }), -); - -window.addEventListener('resize', onWindowResize); - -// - -const scene = new THREE.Scene(); - -const planes = new XRPlanes(renderer); -scene.add(planes); - -const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 20); - -const light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 3); -light.position.set(0.5, 1, 0.25); -scene.add(light); - -// - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_vr_handinput.ts b/examples-testing/examples/webxr_vr_handinput.ts deleted file mode 100644 index d746e4582..000000000 --- a/examples-testing/examples/webxr_vr_handinput.ts +++ /dev/null @@ -1,126 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { VRButton } from 'three/addons/webxr/VRButton.js'; -import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; -import { XRHandModelFactory } from 'three/addons/webxr/XRHandModelFactory.js'; - -let container; -let camera, scene, renderer; -let hand1, hand2; -let controller1, controller2; -let controllerGrip1, controllerGrip2; - -let controls; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x444444); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10); - camera.position.set(0, 1.6, 3); - - controls = new OrbitControls(camera, container); - controls.target.set(0, 1.6, 0); - controls.update(); - - const floorGeometry = new THREE.PlaneGeometry(4, 4); - const floorMaterial = new THREE.MeshStandardMaterial({ color: 0x666666 }); - const floor = new THREE.Mesh(floorGeometry, floorMaterial); - floor.rotation.x = -Math.PI / 2; - floor.receiveShadow = true; - scene.add(floor); - - scene.add(new THREE.HemisphereLight(0xbcbcbc, 0xa5a5a5, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 6, 0); - light.castShadow = true; - light.shadow.camera.top = 2; - light.shadow.camera.bottom = -2; - light.shadow.camera.right = 2; - light.shadow.camera.left = -2; - light.shadow.mapSize.set(4096, 4096); - scene.add(light); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.xr.enabled = true; - - container.appendChild(renderer.domElement); - - const sessionInit = { - requiredFeatures: ['hand-tracking'], - }; - - document.body.appendChild(VRButton.createButton(renderer, sessionInit)); - - // controllers - - controller1 = renderer.xr.getController(0); - scene.add(controller1); - - controller2 = renderer.xr.getController(1); - scene.add(controller2); - - const controllerModelFactory = new XRControllerModelFactory(); - const handModelFactory = new XRHandModelFactory(); - - // Hand 1 - controllerGrip1 = renderer.xr.getControllerGrip(0); - controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1)); - scene.add(controllerGrip1); - - hand1 = renderer.xr.getHand(0); - hand1.add(handModelFactory.createHandModel(hand1)); - - scene.add(hand1); - - // Hand 2 - controllerGrip2 = renderer.xr.getControllerGrip(1); - controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2)); - scene.add(controllerGrip2); - - hand2 = renderer.xr.getHand(1); - hand2.add(handModelFactory.createHandModel(hand2)); - scene.add(hand2); - - // - - const geometry = new THREE.BufferGeometry().setFromPoints([ - new THREE.Vector3(0, 0, 0), - new THREE.Vector3(0, 0, -1), - ]); - - const line = new THREE.Line(geometry); - line.name = 'line'; - line.scale.z = 5; - - controller1.add(line.clone()); - controller2.add(line.clone()); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} -// - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_vr_panorama.ts b/examples-testing/examples/webxr_vr_panorama.ts deleted file mode 100644 index 535e1c937..000000000 --- a/examples-testing/examples/webxr_vr_panorama.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as THREE from 'three'; -import { VRButton } from 'three/addons/webxr/VRButton.js'; - -let camera; -let renderer; -let scene; - -init(); - -function init() { - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - renderer.xr.setReferenceSpaceType('local'); - document.body.appendChild(renderer.domElement); - - document.body.appendChild(VRButton.createButton(renderer)); - - // - - scene = new THREE.Scene(); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000); - camera.layers.enable(1); - - const geometry = new THREE.BoxGeometry(100, 100, 100); - geometry.scale(1, 1, -1); - - const textures = getTexturesFromAtlasFile('textures/cube/sun_temple_stripe_stereo.jpg', 12); - - const materials = []; - - for (let i = 0; i < 6; i++) { - materials.push(new THREE.MeshBasicMaterial({ map: textures[i] })); - } - - const skyBox = new THREE.Mesh(geometry, materials); - skyBox.layers.set(1); - scene.add(skyBox); - - const materialsR = []; - - for (let i = 6; i < 12; i++) { - materialsR.push(new THREE.MeshBasicMaterial({ map: textures[i] })); - } - - const skyBoxR = new THREE.Mesh(geometry, materialsR); - skyBoxR.layers.set(2); - scene.add(skyBoxR); - - window.addEventListener('resize', onWindowResize); -} - -function getTexturesFromAtlasFile(atlasImgUrl, tilesNum) { - const textures = []; - - for (let i = 0; i < tilesNum; i++) { - textures[i] = new THREE.Texture(); - } - - const loader = new THREE.ImageLoader(); - loader.load(atlasImgUrl, function (imageObj) { - let canvas, context; - const tileWidth = imageObj.height; - - for (let i = 0; i < textures.length; i++) { - canvas = document.createElement('canvas'); - context = canvas.getContext('2d'); - canvas.height = tileWidth; - canvas.width = tileWidth; - context.drawImage(imageObj, tileWidth * i, 0, tileWidth, tileWidth, 0, 0, tileWidth, tileWidth); - textures[i].colorSpace = THREE.SRGBColorSpace; - textures[i].image = canvas; - textures[i].needsUpdate = true; - } - }); - - return textures; -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_vr_panorama_depth.ts b/examples-testing/examples/webxr_vr_panorama_depth.ts deleted file mode 100644 index 66215469d..000000000 --- a/examples-testing/examples/webxr_vr_panorama_depth.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as THREE from 'three'; -import { VRButton } from 'three/addons/webxr/VRButton.js'; - -let camera, scene, renderer, sphere, clock; - -init(); - -function init() { - const container = document.getElementById('container'); - - clock = new THREE.Clock(); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x101010); - - const light = new THREE.AmbientLight(0xffffff, 3); - scene.add(light); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 2000); - scene.add(camera); - - // Create the panoramic sphere geometery - const panoSphereGeo = new THREE.SphereGeometry(6, 256, 256); - - // Create the panoramic sphere material - const panoSphereMat = new THREE.MeshStandardMaterial({ - side: THREE.BackSide, - displacementScale: -4.0, - }); - - // Create the panoramic sphere mesh - sphere = new THREE.Mesh(panoSphereGeo, panoSphereMat); - - // Load and assign the texture and depth map - const manager = new THREE.LoadingManager(); - const loader = new THREE.TextureLoader(manager); - - loader.load('./textures/kandao3.jpg', function (texture) { - texture.colorSpace = THREE.SRGBColorSpace; - texture.minFilter = THREE.NearestFilter; - texture.generateMipmaps = false; - sphere.material.map = texture; - }); - - loader.load('./textures/kandao3_depthmap.jpg', function (depth) { - depth.minFilter = THREE.NearestFilter; - depth.generateMipmaps = false; - sphere.material.displacementMap = depth; - }); - - // On load complete add the panoramic sphere to the scene - manager.onLoad = function () { - scene.add(sphere); - }; - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - renderer.xr.setReferenceSpaceType('local'); - container.appendChild(renderer.domElement); - - document.body.appendChild(VRButton.createButton(renderer)); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - // If we are not presenting move the camera a little so the effect is visible - - if (renderer.xr.isPresenting === false) { - const time = clock.getElapsedTime(); - - sphere.rotation.y += 0.001; - sphere.position.x = Math.sin(time) * 0.2; - sphere.position.z = Math.cos(time) * 0.2; - } - - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_vr_rollercoaster.ts b/examples-testing/examples/webxr_vr_rollercoaster.ts deleted file mode 100644 index b8c35a9e3..000000000 --- a/examples-testing/examples/webxr_vr_rollercoaster.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as THREE from 'three'; - -import { - RollerCoasterGeometry, - RollerCoasterShadowGeometry, - RollerCoasterLiftersGeometry, - TreesGeometry, - SkyGeometry, -} from 'three/addons/misc/RollerCoaster.js'; -import { VRButton } from 'three/addons/webxr/VRButton.js'; - -let mesh, material, geometry; - -const renderer = new THREE.WebGLRenderer({ antialias: true }); -renderer.setPixelRatio(window.devicePixelRatio); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.setAnimationLoop(animate); -renderer.xr.enabled = true; -renderer.xr.setReferenceSpaceType('local'); -document.body.appendChild(renderer.domElement); - -document.body.appendChild(VRButton.createButton(renderer)); - -// - -const scene = new THREE.Scene(); -scene.background = new THREE.Color(0xf0f0ff); - -const light = new THREE.HemisphereLight(0xfff0f0, 0x60606, 3); -light.position.set(1, 1, 1); -scene.add(light); - -const train = new THREE.Object3D(); -scene.add(train); - -const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 500); -train.add(camera); - -// environment - -geometry = new THREE.PlaneGeometry(500, 500, 15, 15); -geometry.rotateX(-Math.PI / 2); - -const positions = geometry.attributes.position.array; -const vertex = new THREE.Vector3(); - -for (let i = 0; i < positions.length; i += 3) { - vertex.fromArray(positions, i); - - vertex.x += Math.random() * 10 - 5; - vertex.z += Math.random() * 10 - 5; - - const distance = vertex.distanceTo(scene.position) / 5 - 25; - vertex.y = Math.random() * Math.max(0, distance); - - vertex.toArray(positions, i); -} - -geometry.computeVertexNormals(); - -material = new THREE.MeshLambertMaterial({ - color: 0x407000, -}); - -mesh = new THREE.Mesh(geometry, material); -scene.add(mesh); - -geometry = new TreesGeometry(mesh); -material = new THREE.MeshBasicMaterial({ - side: THREE.DoubleSide, - vertexColors: true, -}); -mesh = new THREE.Mesh(geometry, material); -scene.add(mesh); - -geometry = new SkyGeometry(); -material = new THREE.MeshBasicMaterial({ color: 0xffffff }); -mesh = new THREE.Mesh(geometry, material); -scene.add(mesh); - -// - -const PI2 = Math.PI * 2; - -const curve = (function () { - const vector = new THREE.Vector3(); - const vector2 = new THREE.Vector3(); - - return { - getPointAt: function (t) { - t = t * PI2; - - const x = Math.sin(t * 3) * Math.cos(t * 4) * 50; - const y = Math.sin(t * 10) * 2 + Math.cos(t * 17) * 2 + 5; - const z = Math.sin(t) * Math.sin(t * 4) * 50; - - return vector.set(x, y, z).multiplyScalar(2); - }, - - getTangentAt: function (t) { - const delta = 0.0001; - const t1 = Math.max(0, t - delta); - const t2 = Math.min(1, t + delta); - - return vector2.copy(this.getPointAt(t2)).sub(this.getPointAt(t1)).normalize(); - }, - }; -})(); - -geometry = new RollerCoasterGeometry(curve, 1500); -material = new THREE.MeshPhongMaterial({ - vertexColors: true, -}); -mesh = new THREE.Mesh(geometry, material); -scene.add(mesh); - -geometry = new RollerCoasterLiftersGeometry(curve, 100); -material = new THREE.MeshPhongMaterial(); -mesh = new THREE.Mesh(geometry, material); -mesh.position.y = 0.1; -scene.add(mesh); - -geometry = new RollerCoasterShadowGeometry(curve, 500); -material = new THREE.MeshBasicMaterial({ - color: 0x305000, - depthWrite: false, - transparent: true, -}); -mesh = new THREE.Mesh(geometry, material); -mesh.position.y = 0.1; -scene.add(mesh); - -const funfairs = []; - -// - -geometry = new THREE.CylinderGeometry(10, 10, 5, 15); -material = new THREE.MeshLambertMaterial({ - color: 0xff8080, -}); -mesh = new THREE.Mesh(geometry, material); -mesh.position.set(-80, 10, -70); -mesh.rotation.x = Math.PI / 2; -scene.add(mesh); - -funfairs.push(mesh); - -geometry = new THREE.CylinderGeometry(5, 6, 4, 10); -material = new THREE.MeshLambertMaterial({ - color: 0x8080ff, -}); -mesh = new THREE.Mesh(geometry, material); -mesh.position.set(50, 2, 30); -scene.add(mesh); - -funfairs.push(mesh); - -// - -window.addEventListener('resize', onWindowResize); - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -const position = new THREE.Vector3(); -const tangent = new THREE.Vector3(); - -const lookAt = new THREE.Vector3(); - -let velocity = 0; -let progress = 0; - -let prevTime = performance.now(); - -function animate() { - const time = performance.now(); - const delta = time - prevTime; - - for (let i = 0; i < funfairs.length; i++) { - funfairs[i].rotation.y = time * 0.0004; - } - - // - - progress += velocity; - progress = progress % 1; - - position.copy(curve.getPointAt(progress)); - position.y += 0.3; - - train.position.copy(position); - - tangent.copy(curve.getTangentAt(progress)); - - velocity -= tangent.y * 0.0000001 * delta; - velocity = Math.max(0.00004, Math.min(0.0002, velocity)); - - train.lookAt(lookAt.copy(position).sub(tangent)); - - // - - renderer.render(scene, camera); - - prevTime = time; -} diff --git a/examples-testing/examples/webxr_vr_sandbox.ts b/examples-testing/examples/webxr_vr_sandbox.ts deleted file mode 100644 index 9e8e75909..000000000 --- a/examples-testing/examples/webxr_vr_sandbox.ts +++ /dev/null @@ -1,192 +0,0 @@ -import * as THREE from 'three'; - -import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; -import { Reflector } from 'three/addons/objects/Reflector.js'; -import { VRButton } from 'three/addons/webxr/VRButton.js'; - -import { HTMLMesh } from 'three/addons/interactive/HTMLMesh.js'; -import { InteractiveGroup } from 'three/addons/interactive/InteractiveGroup.js'; -import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - -import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; -import Stats from 'three/addons/libs/stats.module.js'; - -let camera, scene, renderer; -let reflector; -let stats, statsMesh; - -const parameters = { - radius: 0.6, - tube: 0.2, - tubularSegments: 150, - radialSegments: 20, - p: 2, - q: 3, - thickness: 0.5, -}; - -init(); - -function init() { - scene = new THREE.Scene(); - - new RGBELoader().setPath('textures/equirectangular/').load('moonless_golf_1k.hdr', function (texture) { - texture.mapping = THREE.EquirectangularReflectionMapping; - - scene.background = texture; - scene.environment = texture; - }); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10); - camera.position.set(0, 1.6, 1.5); - - // - - const torusGeometry = new THREE.TorusKnotGeometry(...Object.values(parameters)); - const torusMaterial = new THREE.MeshPhysicalMaterial({ - transmission: 1.0, - roughness: 0, - metalness: 0.25, - thickness: 0.5, - side: THREE.DoubleSide, - }); - const torus = new THREE.Mesh(torusGeometry, torusMaterial); - torus.name = 'torus'; - torus.position.y = 1.5; - torus.position.z = -2; - scene.add(torus); - - const cylinderGeometry = new THREE.CylinderGeometry(1, 1, 0.1, 50); - const cylinderMaterial = new THREE.MeshStandardMaterial(); - const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial); - cylinder.position.z = -2; - scene.add(cylinder); - - // - - reflector = new Reflector(new THREE.PlaneGeometry(2, 2), { - textureWidth: window.innerWidth, - textureHeight: window.innerHeight, - }); - reflector.position.x = 1; - reflector.position.y = 1.5; - reflector.position.z = -3; - reflector.rotation.y = -Math.PI / 4; - scene.add(reflector); - - const frameGeometry = new THREE.BoxGeometry(2.1, 2.1, 0.1); - const frameMaterial = new THREE.MeshPhongMaterial(); - const frame = new THREE.Mesh(frameGeometry, frameMaterial); - frame.position.z = -0.07; - reflector.add(frame); - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.autoClear = false; - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - renderer.toneMapping = THREE.ACESFilmicToneMapping; - renderer.toneMappingExposure = 1; - document.body.appendChild(renderer.domElement); - - document.body.appendChild(VRButton.createButton(renderer)); - - window.addEventListener('resize', onWindowResize); - - // - - const geometry = new THREE.BufferGeometry(); - geometry.setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -5)]); - - const controller1 = renderer.xr.getController(0); - controller1.add(new THREE.Line(geometry)); - scene.add(controller1); - - const controller2 = renderer.xr.getController(1); - controller2.add(new THREE.Line(geometry)); - scene.add(controller2); - - // - - const controllerModelFactory = new XRControllerModelFactory(); - - const controllerGrip1 = renderer.xr.getControllerGrip(0); - controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1)); - scene.add(controllerGrip1); - - const controllerGrip2 = renderer.xr.getControllerGrip(1); - controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2)); - scene.add(controllerGrip2); - - // GUI - - function onChange() { - torus.geometry.dispose(); - torus.geometry = new THREE.TorusKnotGeometry(...Object.values(parameters)); - } - - function onThicknessChange() { - torus.material.thickness = parameters.thickness; - } - - const gui = new GUI({ width: 300 }); - gui.add(parameters, 'radius', 0.0, 1.0).onChange(onChange); - gui.add(parameters, 'tube', 0.0, 1.0).onChange(onChange); - gui.add(parameters, 'tubularSegments', 10, 150, 1).onChange(onChange); - gui.add(parameters, 'radialSegments', 2, 20, 1).onChange(onChange); - gui.add(parameters, 'p', 1, 10, 1).onChange(onChange); - gui.add(parameters, 'q', 0, 10, 1).onChange(onChange); - gui.add(parameters, 'thickness', 0, 1).onChange(onThicknessChange); - gui.domElement.style.visibility = 'hidden'; - - const group = new InteractiveGroup(); - group.listenToPointerEvents(renderer, camera); - group.listenToXRControllerEvents(controller1); - group.listenToXRControllerEvents(controller2); - scene.add(group); - - const mesh = new HTMLMesh(gui.domElement); - mesh.position.x = -0.75; - mesh.position.y = 1.5; - mesh.position.z = -0.5; - mesh.rotation.y = Math.PI / 4; - mesh.scale.setScalar(2); - group.add(mesh); - - // Add stats.js - stats = new Stats(); - stats.dom.style.width = '80px'; - stats.dom.style.height = '48px'; - document.body.appendChild(stats.dom); - - statsMesh = new HTMLMesh(stats.dom); - statsMesh.position.x = -0.75; - statsMesh.position.y = 2; - statsMesh.position.z = -0.6; - statsMesh.rotation.y = Math.PI / 4; - statsMesh.scale.setScalar(2.5); - group.add(statsMesh); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - const time = performance.now() * 0.0002; - const torus = scene.getObjectByName('torus'); - torus.rotation.x = time * 0.4; - torus.rotation.y = time; - - renderer.render(scene, camera); - stats.update(); - - // Canvas elements doesn't trigger DOM updates, so we have to update the texture - statsMesh.material.map.update(); -} diff --git a/examples-testing/examples/webxr_vr_video.ts b/examples-testing/examples/webxr_vr_video.ts deleted file mode 100644 index 50a990412..000000000 --- a/examples-testing/examples/webxr_vr_video.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as THREE from 'three'; -import { VRButton } from 'three/addons/webxr/VRButton.js'; - -let camera, scene, renderer; - -init(); - -function init() { - const container = document.getElementById('container'); - container.addEventListener('click', function () { - video.play(); - }); - - camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 2000); - camera.layers.enable(1); // render left view when no stereo available - - // video - - const video = document.getElementById('video'); - video.play(); - - const texture = new THREE.VideoTexture(video); - texture.colorSpace = THREE.SRGBColorSpace; - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x101010); - - // left - - const geometry1 = new THREE.SphereGeometry(500, 60, 40); - // invert the geometry on the x-axis so that all of the faces point inward - geometry1.scale(-1, 1, 1); - - const uvs1 = geometry1.attributes.uv.array; - - for (let i = 0; i < uvs1.length; i += 2) { - uvs1[i] *= 0.5; - } - - const material1 = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh1 = new THREE.Mesh(geometry1, material1); - mesh1.rotation.y = -Math.PI / 2; - mesh1.layers.set(1); // display in left eye only - scene.add(mesh1); - - // right - - const geometry2 = new THREE.SphereGeometry(500, 60, 40); - geometry2.scale(-1, 1, 1); - - const uvs2 = geometry2.attributes.uv.array; - - for (let i = 0; i < uvs2.length; i += 2) { - uvs2[i] *= 0.5; - uvs2[i] += 0.5; - } - - const material2 = new THREE.MeshBasicMaterial({ map: texture }); - - const mesh2 = new THREE.Mesh(geometry2, material2); - mesh2.rotation.y = -Math.PI / 2; - mesh2.layers.set(2); // display in right eye only - scene.add(mesh2); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.xr.enabled = true; - renderer.xr.setReferenceSpaceType('local'); - container.appendChild(renderer.domElement); - - document.body.appendChild(VRButton.createButton(renderer)); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_xr_controls_transform.ts b/examples-testing/examples/webxr_xr_controls_transform.ts deleted file mode 100644 index 6e6901416..000000000 --- a/examples-testing/examples/webxr_xr_controls_transform.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as THREE from 'three'; -import { TransformControls } from 'three/addons/controls/TransformControls.js'; -import { XRButton } from 'three/addons/webxr/XRButton.js'; -import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - -let container; -let camera, scene, renderer; -let controller1, controller2, line; -let controllerGrip1, controllerGrip2; - -let raycaster; - -let controls, group; - -init(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x808080); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10); - camera.position.set(0, 1.6, 0); - - const floorGeometry = new THREE.PlaneGeometry(6, 6); - const floorMaterial = new THREE.ShadowMaterial({ - opacity: 0.25, - blending: THREE.CustomBlending, - transparent: false, - }); - const floor = new THREE.Mesh(floorGeometry, floorMaterial); - floor.rotation.x = -Math.PI / 2; - floor.receiveShadow = true; - scene.add(floor); - - scene.add(new THREE.HemisphereLight(0xbcbcbc, 0xa5a5a5, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 6, 0); - light.castShadow = true; - light.shadow.camera.top = 3; - light.shadow.camera.bottom = -3; - light.shadow.camera.right = 3; - light.shadow.camera.left = -3; - light.shadow.mapSize.set(4096, 4096); - scene.add(light); - - group = new THREE.Group(); - scene.add(group); - - const geometries = [ - new THREE.BoxGeometry(0.2, 0.2, 0.2), - new THREE.ConeGeometry(0.2, 0.4, 64), - new THREE.CylinderGeometry(0.2, 0.2, 0.2, 64), - new THREE.IcosahedronGeometry(0.2, 8), - new THREE.TorusGeometry(0.2, 0.04, 64, 32), - ]; - - for (let i = 0; i < 16; i++) { - const geometry = geometries[Math.floor(Math.random() * geometries.length)]; - const material = new THREE.MeshStandardMaterial({ - color: Math.random() * 0xffffff, - roughness: 0.7, - metalness: 0.0, - }); - - const object = new THREE.Mesh(geometry, material); - - object.position.x = Math.random() - 0.5; - object.position.y = Math.random() * 2 + 0.5; - object.position.z = Math.random() - 2.5; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.setScalar(Math.random() + 0.5); - - object.castShadow = true; - object.receiveShadow = true; - - group.add(object); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.setAnimationLoop(animate); - renderer.shadowMap.enabled = true; - renderer.xr.enabled = true; - container.appendChild(renderer.domElement); - - document.body.appendChild(XRButton.createButton(renderer)); - - // controllers - - controller1 = renderer.xr.getController(0); - controller1.addEventListener('select', onSelect); - controller1.addEventListener('selectstart', onControllerEvent); - controller1.addEventListener('selectend', onControllerEvent); - controller1.addEventListener('move', onControllerEvent); - controller1.userData.active = false; - scene.add(controller1); - - controller2 = renderer.xr.getController(1); - controller2.addEventListener('select', onSelect); - controller2.addEventListener('selectstart', onControllerEvent); - controller2.addEventListener('selectend', onControllerEvent); - controller2.addEventListener('move', onControllerEvent); - controller2.userData.active = true; - scene.add(controller2); - - const controllerModelFactory = new XRControllerModelFactory(); - - controllerGrip1 = renderer.xr.getControllerGrip(0); - controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1)); - scene.add(controllerGrip1); - - controllerGrip2 = renderer.xr.getControllerGrip(1); - controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2)); - scene.add(controllerGrip2); - - // - - const geometry = new THREE.BufferGeometry().setFromPoints([ - new THREE.Vector3(0, 0, 0), - new THREE.Vector3(0, 0, -1), - ]); - - line = new THREE.Line(geometry); - line.name = 'line'; - line.scale.z = 5; - - raycaster = new THREE.Raycaster(); - - // controls - - controls = new TransformControls(camera, renderer.domElement); - controls.attach(group.children[0]); - scene.add(controls.getHelper()); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onSelect(event) { - const controller = event.target; - - controller1.userData.active = false; - controller2.userData.active = false; - - if (controller === controller1) { - controller1.userData.active = true; - controller1.add(line); - } - - if (controller === controller2) { - controller2.userData.active = true; - controller2.add(line); - } - - raycaster.setFromXRController(controller); - - const intersects = raycaster.intersectObjects(group.children); - - if (intersects.length > 0) { - controls.attach(intersects[0].object); - } -} - -function onControllerEvent(event) { - const controller = event.target; - - if (controller.userData.active === false) return; - - controls.getRaycaster().setFromXRController(controller); - - switch (event.type) { - case 'selectstart': - controls.pointerDown(null); - break; - - case 'selectend': - controls.pointerUp(null); - break; - - case 'move': - controls.pointerHover(null); - controls.pointerMove(null); - break; - } -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -// - -function animate() { - renderer.render(scene, camera); -} diff --git a/examples-testing/examples/webxr_xr_dragging_custom_depth.ts b/examples-testing/examples/webxr_xr_dragging_custom_depth.ts deleted file mode 100644 index 2cd50ba4c..000000000 --- a/examples-testing/examples/webxr_xr_dragging_custom_depth.ts +++ /dev/null @@ -1,395 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; -import { XRButton } from 'three/addons/webxr/XRButton.js'; -import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; - -let container; -let camera, scene, renderer; -let controller1, controller2; -let controllerGrip1, controllerGrip2; -let isDepthSupplied = false; - -let raycaster; - -const intersected = []; -const tempMatrix = new THREE.Matrix4(); - -let controls, group; - -init(); -animate(); - -function init() { - container = document.createElement('div'); - document.body.appendChild(container); - - scene = new THREE.Scene(); - scene.background = new THREE.Color(0x808080); - - camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10); - camera.position.set(0, 1.6, 3); - - controls = new OrbitControls(camera, container); - controls.target.set(0, 1.6, 0); - controls.update(); - - const floorGeometry = new THREE.PlaneGeometry(6, 6); - const floorMaterial = new THREE.ShadowMaterial({ - opacity: 0.25, - blending: THREE.CustomBlending, - transparent: false, - }); - const floor = new THREE.Mesh(floorGeometry, floorMaterial); - floor.rotation.x = -Math.PI / 2; - floor.receiveShadow = true; - scene.add(floor); - - scene.add(new THREE.HemisphereLight(0xbcbcbc, 0xa5a5a5, 3)); - - const light = new THREE.DirectionalLight(0xffffff, 3); - light.position.set(0, 6, 0); - light.castShadow = true; - light.shadow.camera.top = 3; - light.shadow.camera.bottom = -3; - light.shadow.camera.right = 3; - light.shadow.camera.left = -3; - light.shadow.mapSize.set(4096, 4096); - scene.add(light); - - group = new THREE.Group(); - scene.add(group); - - const geometries = [ - new THREE.BoxGeometry(0.2, 0.2, 0.2), - new THREE.ConeGeometry(0.2, 0.2, 64), - new THREE.CylinderGeometry(0.2, 0.2, 0.2, 64), - new THREE.IcosahedronGeometry(0.2, 8), - new THREE.TorusGeometry(0.2, 0.04, 64, 32), - ]; - - for (let i = 0; i < 50; i++) { - const geometry = geometries[Math.floor(Math.random() * geometries.length)]; - const material = new THREE.ShaderMaterial({ - vertexShader: /* glsl */ ` - varying vec3 vNormal; - varying vec2 vUv; - void main() { - vNormal = normalize(normalMatrix * normal); - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); - } - `, - - fragmentShader: /* glsl */ ` - uniform vec3 diffuseColor; - uniform float roughness; - uniform float metalness; - uniform float emissive; - varying vec3 vNormal; - varying vec2 vUv; - uniform sampler2DArray depthColor; - uniform float depthWidth; - uniform float depthHeight; - #define saturate( a ) clamp( a, 0.0, 1.0 ) - float Depth_GetCameraDepthInMeters(const sampler2DArray depthTexture, - const vec2 depthUv, int arrayIndex) { - return texture(depthColor, vec3(depthUv.x, depthUv.y, arrayIndex)).r; - } - float Depth_GetOcclusion(const sampler2DArray depthTexture, const vec2 depthUv, float assetDepthM, int arrayIndex) { - float depthMm = Depth_GetCameraDepthInMeters(depthTexture, depthUv, arrayIndex); - const float kDepthTolerancePerM = 0.001; - return clamp(1.0 - - 0.5 * (depthMm - assetDepthM) / - (kDepthTolerancePerM * assetDepthM) + - 0.5, 0.0, 1.0); - } - float Depth_GetBlurredOcclusionAroundUV(const sampler2DArray depthTexture, const vec2 uv, float assetDepthM, int arrayIndex) { - // Kernel used: - // 0 4 7 4 0 - // 4 16 26 16 4 - // 7 26 41 26 7 - // 4 16 26 16 4 - // 0 4 7 4 0 - const float kKernelTotalWeights = 269.0; - float sum = 0.0; - const float kOcclusionBlurAmount = 0.0005; - vec2 blurriness = - vec2(kOcclusionBlurAmount, kOcclusionBlurAmount /** u_DepthAspectRatio*/); - float current = 0.0; - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-1.0, -2.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+1.0, -2.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-1.0, +2.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+1.0, +2.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-2.0, +1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+2.0, +1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-2.0, -1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+2.0, -1.0) * blurriness, assetDepthM, arrayIndex); - sum += current * 4.0; - current = 0.0; - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-2.0, -0.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+2.0, +0.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+0.0, +2.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-0.0, -2.0) * blurriness, assetDepthM, arrayIndex); - sum += current * 7.0; - current = 0.0; - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-1.0, -1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+1.0, -1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-1.0, +1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+1.0, +1.0) * blurriness, assetDepthM, arrayIndex); - sum += current * 16.0; - current = 0.0; - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+0.0, +1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-0.0, -1.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(-1.0, -0.0) * blurriness, assetDepthM, arrayIndex); - current += Depth_GetOcclusion( - depthTexture, uv + vec2(+1.0, +0.0) * blurriness, assetDepthM, arrayIndex); - sum += current * 26.0; - sum += Depth_GetOcclusion(depthTexture, uv, assetDepthM, arrayIndex) * 41.0; - return sum / kKernelTotalWeights; - } - void main() { - vec3 normal = normalize(vNormal); - vec3 diffuse = diffuseColor; - float specularIntensity = pow(max(dot(normal, normalize(vec3(0, 0, 1))), 0.0), 64.0); - vec3 specular = vec3(specularIntensity) * mix(vec3(0.04), diffuse, metalness); - gl_FragColor = vec4(diffuse * (1.0 - specular) + specular, 1.0) * (1.0 + emissive); - - if (depthWidth > 0.0) { - int arrayIndex = 0; - vec2 depthUv; - if (gl_FragCoord.x>=depthWidth) { - arrayIndex = 1; - depthUv = vec2((gl_FragCoord.x-depthWidth)/depthWidth, gl_FragCoord.y/depthHeight); - } else { - depthUv = vec2(gl_FragCoord.x/depthWidth, gl_FragCoord.y/depthHeight); - } - float assetDepthM = gl_FragCoord.z; - - float occlusion = Depth_GetBlurredOcclusionAroundUV(depthColor, depthUv, assetDepthM, arrayIndex); - float depthMm = Depth_GetCameraDepthInMeters(depthColor, depthUv, arrayIndex); - - float absDistance = abs(assetDepthM - depthMm); - float v = 0.0025; - absDistance = saturate(v - absDistance) / v; - - gl_FragColor.rgb += vec3(absDistance * 2.0, absDistance * 2.0, absDistance * 12.0); - gl_FragColor = mix(gl_FragColor, vec4(0.0, 0.0, 0.0, 0.0), occlusion * 0.7); - } - } - `, - - uniforms: { - diffuseColor: { value: new THREE.Color(Math.random() * 0xffffff) }, - roughness: { value: 0.7 }, - metalness: { value: 0.0 }, - emissive: { value: 0.0 }, - depthWidth: { value: 0.0 }, - depthHeight: { value: 0.0 }, - depthColor: { value: new THREE.Texture() }, - }, - }); - - const object = new THREE.Mesh(geometry, material); - - object.position.x = Math.random() * 4 - 2; - object.position.y = Math.random() * 2; - object.position.z = Math.random() * 4 - 2; - - object.rotation.x = Math.random() * 2 * Math.PI; - object.rotation.y = Math.random() * 2 * Math.PI; - object.rotation.z = Math.random() * 2 * Math.PI; - - object.scale.setScalar(Math.random() + 0.5); - - group.add(object); - } - - // - - renderer = new THREE.WebGLRenderer({ antialias: true }); - renderer.setPixelRatio(window.devicePixelRatio); - renderer.setSize(window.innerWidth, window.innerHeight); - renderer.shadowMap.enabled = true; - renderer.xr.enabled = true; - container.appendChild(renderer.domElement); - - document.body.appendChild( - XRButton.createButton(renderer, { - optionalFeatures: ['depth-sensing'], - depthSensing: { usagePreference: ['gpu-optimized'], dataFormatPreference: [] }, - }), - ); - - // controllers - - controller1 = renderer.xr.getController(0); - controller1.addEventListener('selectstart', onSelectStart); - controller1.addEventListener('selectend', onSelectEnd); - scene.add(controller1); - - controller2 = renderer.xr.getController(1); - controller2.addEventListener('selectstart', onSelectStart); - controller2.addEventListener('selectend', onSelectEnd); - scene.add(controller2); - - const controllerModelFactory = new XRControllerModelFactory(); - - controllerGrip1 = renderer.xr.getControllerGrip(0); - controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1)); - scene.add(controllerGrip1); - - controllerGrip2 = renderer.xr.getControllerGrip(1); - controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2)); - scene.add(controllerGrip2); - - // - - const geometry = new THREE.BufferGeometry().setFromPoints([ - new THREE.Vector3(0, 0, 0), - new THREE.Vector3(0, 0, -1), - ]); - - const line = new THREE.Line(geometry); - line.name = 'line'; - line.scale.z = 5; - - controller1.add(line.clone()); - controller2.add(line.clone()); - - raycaster = new THREE.Raycaster(); - - // - - window.addEventListener('resize', onWindowResize); -} - -function onWindowResize() { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize(window.innerWidth, window.innerHeight); -} - -function onSelectStart(event) { - const controller = event.target; - - const intersections = getIntersections(controller); - - if (intersections.length > 0) { - const intersection = intersections[0]; - - const object = intersection.object; - object.material.uniforms.emissive.value = 1; - controller.attach(object); - - controller.userData.selected = object; - } - - controller.userData.targetRayMode = event.data.targetRayMode; -} - -function onSelectEnd(event) { - const controller = event.target; - - if (controller.userData.selected !== undefined) { - const object = controller.userData.selected; - object.material.uniforms.emissive.value = 0; - group.attach(object); - - controller.userData.selected = undefined; - } -} - -function getIntersections(controller) { - controller.updateMatrixWorld(); - - tempMatrix.identity().extractRotation(controller.matrixWorld); - - raycaster.ray.origin.setFromMatrixPosition(controller.matrixWorld); - raycaster.ray.direction.set(0, 0, -1).applyMatrix4(tempMatrix); - - return raycaster.intersectObjects(group.children, false); -} - -function intersectObjects(controller) { - // Do not highlight in mobile-ar - - if (controller.userData.targetRayMode === 'screen') return; - - // Do not highlight when already selected - - if (controller.userData.selected !== undefined) return; - - const line = controller.getObjectByName('line'); - const intersections = getIntersections(controller); - - if (intersections.length > 0) { - const intersection = intersections[0]; - - const object = intersection.object; - object.material.uniforms.emissive.value = 1; - intersected.push(object); - - line.scale.z = intersection.distance; - } else { - line.scale.z = 5; - } -} - -function cleanIntersected() { - while (intersected.length) { - const object = intersected.pop(); - object.material.uniforms.emissive.value = 0; - } -} - -// - -function animate() { - renderer.setAnimationLoop(render); -} - -function render() { - if (renderer.xr.hasDepthSensing() && !isDepthSupplied) { - group.children.forEach(child => { - child.material.uniforms.depthColor.value = renderer.xr.getDepthTexture(); - child.material.uniforms.depthWidth.value = 1680; - child.material.uniforms.depthHeight.value = 1760; - - isDepthSupplied = true; - }); - } else if (!renderer.xr.hasDepthSensing() && isDepthSupplied) { - group.children.forEach(child => { - child.material.uniforms.depthWidth.value = 0; - child.material.uniforms.depthHeight.value = 0; - - isDepthSupplied = false; - }); - } - - cleanIntersected(); - - intersectObjects(controller1); - intersectObjects(controller2); - - renderer.render(scene, camera); -}