-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add full project code and improve structure
- Implement Three.js wireframe wormhole - Add camera and orbit controls - Incorporate post-processing effects (Bloom, RenderPass) - Create spline and tube geometry for wormhole - Add animated boxes along the spline - Include detailed comments and code documentation
- Loading branch information
Showing
3 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Fly through a Wireframe Wormhole</title> | ||
<style> | ||
body { | ||
margin: 0; | ||
overflow: hidden; /* Prevents scrollbars */ | ||
} | ||
</style> | ||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js", | ||
"jsm/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/" | ||
} | ||
} | ||
</script> | ||
</head> | ||
<body> | ||
<script type="module" src="index.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import * as THREE from "three"; | ||
import { OrbitControls } from "jsm/controls/OrbitControls.js"; | ||
import spline from "./spline.js"; | ||
import { EffectComposer } from "jsm/postprocessing/EffectComposer.js"; | ||
import { RenderPass } from "jsm/postprocessing/RenderPass.js"; | ||
import { UnrealBloomPass } from "jsm/postprocessing/UnrealBloomPass.js"; | ||
|
||
// Set up scene, camera, and renderer | ||
const w = window.innerWidth; | ||
const h = window.innerHeight; | ||
const scene = new THREE.Scene(); | ||
scene.fog = new THREE.FogExp2(0x000000, 0.3); | ||
const camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 1000); | ||
camera.position.z = 5; | ||
const renderer = new THREE.WebGLRenderer(); | ||
renderer.setSize(w, h); | ||
renderer.toneMapping = THREE.ACESFilmicToneMapping; | ||
renderer.outputColorSpace = THREE.SRGBColorSpace; | ||
document.body.appendChild(renderer.domElement); | ||
|
||
// Set up orbit controls | ||
const controls = new OrbitControls(camera, renderer.domElement); | ||
controls.enableDamping = true; | ||
controls.dampingFactor = 0.03; | ||
|
||
// Post-processing setup | ||
const renderScene = new RenderPass(scene, camera); | ||
const bloomPass = new UnrealBloomPass(new THREE.Vector2(w, h), 1.5, 0.4, 100); | ||
bloomPass.threshold = 0.002; | ||
bloomPass.strength = 3.5; | ||
bloomPass.radius = 0; | ||
const composer = new EffectComposer(renderer); | ||
composer.addPass(renderScene); | ||
composer.addPass(bloomPass); | ||
|
||
// Create tube geometry from the spline | ||
const tubeGeo = new THREE.TubeGeometry(spline, 222, 0.65, 16, true); | ||
|
||
// Create edges geometry for the tube | ||
const edges = new THREE.EdgesGeometry(tubeGeo, 0.2); | ||
const lineMat = new THREE.LineBasicMaterial({ color: 0xff0000 }); | ||
const tubeLines = new THREE.LineSegments(edges, lineMat); | ||
scene.add(tubeLines); | ||
|
||
// Create and position boxes along the spline | ||
const numBoxes = 55; | ||
const size = 0.075; | ||
const boxGeo = new THREE.BoxGeometry(size, size, size); | ||
for (let i = 0; i < numBoxes; i += 1) { | ||
const boxMat = new THREE.MeshBasicMaterial({ | ||
color: 0xffffff, | ||
wireframe: true, | ||
}); | ||
const box = new THREE.Mesh(boxGeo, boxMat); | ||
const p = (i / numBoxes + Math.random() * 0.1) % 1; | ||
const pos = tubeGeo.parameters.path.getPointAt(p); | ||
pos.x += Math.random() - 0.4; | ||
pos.z += Math.random() - 0.4; | ||
box.position.copy(pos); | ||
const rote = new THREE.Vector3( | ||
Math.random() * Math.PI, | ||
Math.random() * Math.PI, | ||
Math.random() * Math.PI | ||
); | ||
box.rotation.set(rote.x, rote.y, rote.z); | ||
const edges = new THREE.EdgesGeometry(boxGeo, 0.2); | ||
const color = new THREE.Color().setHSL(0.7 - p, 1, 0.5); | ||
const lineMat = new THREE.LineBasicMaterial({ color }); | ||
const boxLines = new THREE.LineSegments(edges, lineMat); | ||
boxLines.position.copy(pos); | ||
boxLines.rotation.set(rote.x, rote.y, rote.z); | ||
scene.add(boxLines); | ||
} | ||
|
||
// Function to update camera position and direction | ||
function updateCamera(t) { | ||
const time = t * 0.1; | ||
const looptime = 10 * 1000; | ||
const p = (time % looptime) / looptime; | ||
const pos = tubeGeo.parameters.path.getPointAt(p); | ||
const lookAt = tubeGeo.parameters.path.getPointAt((p + 0.03) % 1); | ||
camera.position.copy(pos); | ||
camera.lookAt(lookAt); | ||
} | ||
|
||
// Animation loop | ||
function animate(t = 0) { | ||
requestAnimationFrame(animate); | ||
updateCamera(t); | ||
composer.render(scene, camera); | ||
controls.update(); | ||
} | ||
animate(); | ||
|
||
// Handle window resize | ||
function handleWindowResize() { | ||
camera.aspect = window.innerWidth / window.innerHeight; | ||
camera.updateProjectionMatrix(); | ||
renderer.setSize(window.innerWidth, window.innerHeight); | ||
} | ||
window.addEventListener("resize", handleWindowResize, false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import * as THREE from "three"; | ||
|
||
// Curve path data | ||
const curvePath = [ | ||
10.136184463414924, -1.374508746897471, 10.384881573913269, | ||
9.1152593889854714, -1.374508746897471, 8.5846792797570011, | ||
9.0669355709754882, -1.0665123466336568, 5.8937771631608156, | ||
10.151040177840205, -0.65913653144937956, 3.4340491740541346, | ||
10.806779203170416, 1.8859391007298545, 0.46855774212986023, | ||
10.761433540147586, 2.8724172201359197, -1.2811838605587311, | ||
9.6195923104445065, 2.8724172201359197, -3.2833099941904766, | ||
6.9763020889151646, 2.7659257976905427, -4.7591958908830172, | ||
6.0461277891353697, 1.0727045302089879, -6.6638740164090482, | ||
7.3472235778544794, -1.8228856326635698, -9.0685043046185623, | ||
7.226367212900791, -1.8228856326635698, -10.499536640855691, | ||
5.8354566696263914, -1.8228856326635698, -12.039219379199908, | ||
3.6532357452141353, -0.20463983570573391, -13.87695442281038, | ||
-0.30169589630131455, 1.5965000671484342, -14.879986418947327, | ||
-2.8925694230502157, 2.2971364614427481, -13.892095587598131, | ||
-4.537672295357936, 4.5863515759659208, -12.140831652074551, | ||
-6.1287913464117594, 5.9653814634119815, -8.9776527318875896, | ||
-6.0120301606452813, 4.4081161943855998, -6.712084358394045, | ||
-5.2138252159038974, 2.820894808418279, -4.4532820412085607, | ||
-2.3424712835109611, 2.2032065005086259, -3.0788773693500198, | ||
-0.0076956453915433265, 1.8931797788880202, -1.6577070662471063, | ||
-0.24767503988481437, 2.8845808465856684, 0.073915859214221724, | ||
-2.2174044353598896, 4.2415524507318576, 2.215992718290742, | ||
-3.4526531678364756, 3.0615192023340851, 4.7922404932096558, | ||
-3.7356278971556445, 1.4054080369354316, 7.8432021841434629, | ||
-3.4003734463804118, 1.1924069108769393, 9.2464090886227073, | ||
-1.8851803760476225, 1.5269331003449989, 10.306083896408374, | ||
0.01071077144031829, 2.1101821577522295, 10.490880699847727, | ||
0.42562058195647001, 2.2759939598834387, 11.613129436580291, | ||
0.096405262182225115, 0.032317784084054391, 16.223455375061565, | ||
2.3458797884520433, 0.38907275257695584, 19.91188266079584, | ||
5.7018400098488771, 1.73337964747396, 20.615481586999959, 7.9720939736751824, | ||
1.73337964747396, 19.303399329816457, 9.8672362721095652, | ||
0.090083018057025177, 16.893338541618121, 11.225959519544134, | ||
-1.374508746897471, 14.279002555560753, 11.288646925965876, | ||
-1.374508746897471, 11.926359497447137, 10.136184463414924, | ||
-1.374508746897471, 10.384881573913269, | ||
]; | ||
|
||
// Construct tunnel track | ||
const points = []; | ||
const len = curvePath.length; | ||
for (let p = 0; p < len; p += 3) { | ||
points.push( | ||
new THREE.Vector3(curvePath[p], curvePath[p + 1], curvePath[p + 2]) | ||
); | ||
} | ||
|
||
// Create Catmull-Rom spline from the points | ||
const spline = new THREE.CatmullRomCurve3(points); | ||
|
||
export default spline; |