[READ-ONLY] Mirror of https://github.com/flo-bit/tiny-planets. procedurally generated tiny planets in the browsers flo-bit.dev/tiny-planets/
low-poly planets procedural-generation threejs
0

Configure Feed

Select the types of activity you want to include in your feed.

tiny-planets / src / script.ts
3.4 kB 135 lines
1import * as THREE from "three"; 2import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; 3import { Planet } from "./worlds/planet"; 4import { Stars } from "./worlds/stars"; 5import { planetPresets } from "./worlds/presets"; 6 7const presets = ["beach", "forest", "snowForest"]; 8 9const width = window.innerWidth, 10 height = window.innerHeight; 11 12const canvas = document.getElementById("root"); 13 14if (!canvas) { 15 throw new Error("Canvas not found"); 16} 17const scene = new THREE.Scene(); 18const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 30); 19camera.position.set(0, 0, 2.5); 20 21const renderer = new THREE.WebGLRenderer({ 22 antialias: true, 23 canvas, 24 alpha: true, 25}); 26 27renderer.toneMapping = THREE.ACESFilmicToneMapping; 28renderer.shadowMap.enabled = true; 29 30const _ = new OrbitControls(camera, renderer.domElement); 31 32let hasPlanet = false; 33 34let sphereGeometry = new THREE.IcosahedronGeometry(1, 20); 35let sphereMaterial = new THREE.MeshStandardMaterial({ 36 color: "white", 37 wireframe: true, 38 wireframeLinewidth: 10, 39}); 40let planetMesh: THREE.Mesh = new THREE.Mesh(sphereGeometry, sphereMaterial); 41scene.add(planetMesh); 42 43const light = new THREE.DirectionalLight(); 44light.intensity = 2; 45light.position.set(2, 1, 0); 46scene.add(light); 47light.castShadow = true; 48light.shadow.mapSize.width = 512; 49light.shadow.mapSize.height = 512; 50light.shadow.camera.far = 10; 51light.shadow.camera.near = 0.1; 52 53light.shadow.bias = 0.01; 54light.shadow.camera.top = 2; 55light.shadow.camera.right = 2; 56light.shadow.camera.bottom = -2; 57light.shadow.camera.left = -2; 58 59const ambientLight = new THREE.AmbientLight(0xffffff, 0.1); 60scene.add(ambientLight); 61 62let total = 0; 63let lastDelta = 0; 64renderer.setAnimationLoop((delta) => { 65 renderer.render(scene, camera); 66 67 planetMesh.rotation.y += 0.001; 68 69 if (lastDelta > 0) { 70 total += delta - lastDelta; 71 } 72 lastDelta = delta; 73 74 if (!hasPlanet) { 75 console.log("Creating planet"); 76 createPlanet("beach"); 77 hasPlanet = true; 78 } 79}); 80 81let stars = new Stars(); 82 83scene.add(stars); 84 85// add keydown event listener 86document.addEventListener("keydown", (event) => { 87 if (event.key === "1") { 88 createPlanet("beach"); 89 } else if (event.key === "2") { 90 createPlanet("forest"); 91 } else if (event.key === "3") { 92 createPlanet("snowForest"); 93 } 94}); 95 96// button press 97let button = document.getElementById("button"); 98if (button) { 99 console.log("Button found"); 100 button.addEventListener("click", () => { 101 let randomPreset = presets[Math.floor(Math.random() * presets.length)]; 102 createPlanet(randomPreset); 103 }); 104} 105 106async function createPlanet(preset: string | undefined = undefined) { 107 if (!preset) { 108 preset = presets[Math.floor(Math.random() * presets.length)]; 109 } 110 111 console.time("planet"); 112 const planet = new Planet({ 113 detail: 50, 114 ...planetPresets[preset], 115 }); 116 let mesh = await planet.create(); 117 scene.remove(planetMesh); 118 scene.add(mesh); 119 planetMesh = mesh; 120 121 // planetMesh.add(camera); 122 // planet.updatePosition(camera, new THREE.Vector3(0, 0, 1.1)); 123 124 console.timeEnd("planet"); 125} 126 127function updateSize() { 128 renderer.setSize(window.innerWidth, window.innerHeight); 129 renderer.setPixelRatio(window.devicePixelRatio); 130 camera.aspect = window.innerWidth / window.innerHeight; 131 camera.updateProjectionMatrix(); 132} 133 134updateSize(); 135window.addEventListener("resize", updateSize);