From 88227d11e6915e3a17e0e982825665bd133f8e97 Mon Sep 17 00:00:00 2001 From: zangorinilab-lab Date: Sun, 16 Nov 2025 17:54:39 +0100 Subject: [PATCH] Update index.js --- index.js | 93 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 28 deletions(-) diff --git a/index.js b/index.js index 70a5553..661c14b 100644 --- a/index.js +++ b/index.js @@ -7,12 +7,14 @@ import { getFresnelMat } from "./src/getFresnelMat.js"; const w = window.innerWidth; const h = window.innerHeight; const scene = new THREE.Scene(); + +// Camera: useremo una posizione iniziale che verrà poi regolata const camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 1000); -camera.position.z = 5; +// camera.position.z = 5; // Questa riga verrà commentata o rimossa + const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(w, h); document.body.appendChild(renderer.domElement); -// THREE.ColorManagement.enabled = true; renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.outputColorSpace = THREE.LinearSRGBColorSpace; @@ -20,33 +22,32 @@ const earthGroup = new THREE.Group(); earthGroup.rotation.z = -23.4 * Math.PI / 180; scene.add(earthGroup); new OrbitControls(camera, renderer.domElement); + const detail = 12; const loader = new THREE.TextureLoader(); -const geometry = new THREE.IcosahedronGeometry(1, detail); +const geometry = new THREE.IcosahedronGeometry(1, detail); // Il raggio è 1 const material = new THREE.MeshPhongMaterial({ - map: loader.load("./textures/00_earthmap1k.jpg"), - specularMap: loader.load("./textures/02_earthspec1k.jpg"), - bumpMap: loader.load("./textures/01_earthbump1k.jpg"), - bumpScale: 0.04, + map: loader.load("./textures/00_earthmap1k.jpg"), + specularMap: loader.load("./textures/02_earthspec1k.jpg"), + bumpMap: loader.load("./textures/01_earthbump1k.jpg"), + bumpScale: 0.04, }); -// material.map.colorSpace = THREE.SRGBColorSpace; const earthMesh = new THREE.Mesh(geometry, material); earthGroup.add(earthMesh); const lightsMat = new THREE.MeshBasicMaterial({ - map: loader.load("./textures/03_earthlights1k.jpg"), - blending: THREE.AdditiveBlending, + map: loader.load("./textures/03_earthlights1k.jpg"), + blending: THREE.AdditiveBlending, }); const lightsMesh = new THREE.Mesh(geometry, lightsMat); earthGroup.add(lightsMesh); const cloudsMat = new THREE.MeshStandardMaterial({ - map: loader.load("./textures/04_earthcloudmap.jpg"), - transparent: true, - opacity: 0.8, - blending: THREE.AdditiveBlending, - alphaMap: loader.load('./textures/05_earthcloudmaptrans.jpg'), - // alphaTest: 0.3, + map: loader.load("./textures/04_earthcloudmap.jpg"), + transparent: true, + opacity: 0.8, + blending: THREE.AdditiveBlending, + alphaMap: loader.load('./textures/05_earthcloudmaptrans.jpg'), }); const cloudsMesh = new THREE.Mesh(geometry, cloudsMat); cloudsMesh.scale.setScalar(1.003); @@ -64,22 +65,58 @@ const sunLight = new THREE.DirectionalLight(0xffffff, 2.0); sunLight.position.set(-2, 0.5, 1.5); scene.add(sunLight); +// --- Nuova funzione per calcolare la posizione Z della camera --- +function setCameraDistance() { + // Definiamo una dimensione "ideale" per la Terra nella viewport. + // Ad esempio, vogliamo che occupi circa il 60% dell'altezza dello schermo su una risoluzione "base". + // Il raggio della geometria è 1. + const objectRadius = 1; + const fov = camera.fov * (Math.PI / 180); // Converti FOV in radianti + const targetVisualHeightRatio = 0.6; // La Terra dovrebbe occupare il 60% dell'altezza dello schermo + + // Calcola la distanza necessaria + // Questo è un'approssimazione che funziona bene per oggetti al centro dello schermo. + let distance = objectRadius / Math.tan(fov / 2); + + // Ajusta la distanza in base all'altezza della viewport per mantenere la dimensione visiva + // Questo è il punto chiave. Se l'altezza della viewport raddoppia, vogliamo raddoppiare anche la distanza + // per mantenere l'oggetto della stessa dimensione percepita rispetto alla viewport. + // Possiamo definire una "altezza di riferimento" e una distanza "di riferimento". + const referenceHeight = 768; // Esempio: altezza in pixel per cui camera.position.z = 5 era ok + const referenceDistance = 5; // Corrispondente distanza z + + // Calcola la nuova distanza in proporzione all'altezza attuale della finestra + // Se l'altezza attuale è maggiore della referenceHeight, la distanza sarà maggiore, + // allontanando la camera e mantenendo l'oggetto della stessa dimensione relativa. + distance = referenceDistance * (window.innerHeight / referenceHeight); + + // Imposta un limite minimo e massimo per evitare che la camera si avvicini troppo o si allontani troppo + distance = Math.max(2.5, Math.min(distance, 20)); // Esempio: tra 2.5 e 20 unità + + camera.position.z = distance; + camera.updateProjectionMatrix(); // Importante aggiornare la matrice di proiezione +} + +// Chiama la funzione una volta all'inizio per impostare la posizione iniziale della camera +setCameraDistance(); + function animate() { - requestAnimationFrame(animate); - - earthMesh.rotation.y += 0.002; - lightsMesh.rotation.y += 0.002; - cloudsMesh.rotation.y += 0.0023; - glowMesh.rotation.y += 0.002; - stars.rotation.y -= 0.0002; - renderer.render(scene, camera); + requestAnimationFrame(animate); + + earthMesh.rotation.y += 0.002; + lightsMesh.rotation.y += 0.002; + cloudsMesh.rotation.y += 0.0023; + glowMesh.rotation.y += 0.002; + stars.rotation.y -= 0.0002; + renderer.render(scene, camera); } animate(); function handleWindowResize () { - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - renderer.setSize(window.innerWidth, window.innerHeight); + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); + setCameraDistance(); // Chiama questa funzione anche al ridimensionamento } -window.addEventListener('resize', handleWindowResize, false); \ No newline at end of file +window.addEventListener('resize', handleWindowResize, false);