Excuse me, I’ll send the code below, researching on my own I discovered that the problem is because of the gigantic sizes, but shrinking is not an option for me because I need it, the real problem is how shaky the ship is.
import * as THREE from “./modules/three.module.js”;
import { OrbitControls } from “./modules/OrbitControls.js”;
import { Lensflare, LensflareElement } from ‘./modules/Lensflare.js’;
import { UnrealBloomPass } from ‘./modules/UnrealBloomPass.js’;
import { RenderPass } from ‘./modules/RenderPass.js’;
import { GLTFLoader } from ‘./modules/GLTFLoader.js’;
import { EffectComposer } from ‘./modules/EffectComposer.js’;
let scene, camera, renderer;
let planets = {};
let bloomPass;
let composer;
let escalaModelo = 0.1;
let moons = {};
let velocidadeDaLuz = false;
let currentControls;
let startTime;
let spaceship;
let spaceshipSpeed = 0;
let cameraDistance = 0.0001;
let targetCameraDistance = 3;
let spaceshipAccelerating = false;
let spaceshipControls;
let clock = new THREE.Clock();
function init() {
setupScene();
setupCamera();
setupRenderer();
loadSpaceshipModel();
createPlanets();
createSun();
startTime = Date.now();
spaceshipControls = {
moveForward: false,
moveBackward: false,
rotateLeft: false,
rotateRight: false,
};
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);
}
const listener = new THREE.AudioListener();
const ambientSound = new THREE.Audio(listener);
const ambientSoundLoader = new THREE.AudioLoader();
ambientSoundLoader.load(‘./deep-space-ambiance-48854.mp3’, (buffer) => {
ambientSound.setBuffer(buffer);
ambientSound.setLoop(true);
ambientSound.setVolume(1);
ambientSound.play();
});
function setupScene() {
scene = new THREE.Scene();
}
function setupCamera() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.0001, 10000000000000);
camera.position.set(0, 5, -10);
}
function setupRenderer() {
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: false
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
}
function loadSpaceshipModel() {
const loader = new GLTFLoader();
const listener = new THREE.AudioListener();
loader.load('./nave/scene.gltf', (gltf) => {
spaceship = gltf.scene;
scene.add(spaceship);
spaceship.position.set(0, 0, 0);
spaceship.scale.set(0.00001, 0.00001, 0.00001);
const mixer = new THREE.AnimationMixer(spaceship);
gltf.animations.forEach((clip) => {
mixer.clipAction(clip).play();
});
scene.mixer = mixer;
scene.add(listener);
const accelerationSound = new THREE.Audio(listener);
const speedSound = new THREE.Audio(listener);
spaceship.add(accelerationSound);
spaceship.add(speedSound);
const accelerationSoundLoader = new THREE.AudioLoader();
const speedSoundLoader = new THREE.AudioLoader();
accelerationSoundLoader.load('./spacecraft-engine-loop-01-58205.mp3', (buffer) => {
accelerationSound.setBuffer(buffer);
accelerationSound.setLoop(false);
accelerationSound.setVolume(1);
});
speedSoundLoader.load('./alien-ship-takeoff-28339.mp3', (buffer) => {
speedSound.setBuffer(buffer);
speedSound.setLoop(false);
speedSound.setVolume(1);
});
});
}
const cameraSmoothingFactor = 0.1;
let cameraTargetPosition = new THREE.Vector3();
function lateUpdateCamera() {
if (spaceship) {
cameraTargetPosition.copy(spaceship.position);
}
camera.position.lerp(cameraTargetPosition, 0.01);
const forwardDirection = new THREE.Vector3(0, 0, 1);
forwardDirection.applyQuaternion(spaceship.quaternion);
const lookAtPosition = new THREE.Vector3().addVectors(camera.position, forwardDirection);
camera.lookAt(lookAtPosition);
}
function animateSpaceship() {
if (spaceship) {
const acceleration = 5000;
const deceleration = 0.01;
const maxSpeed = velocidadeDaLuz ? 29979245860 : 1000000;
const maxCameraDistance = 0.0005;
const minCameraDistance = 0.0002;
const zoomSpeed = 0.005;
if (spaceshipAccelerating) {
if (velocidadeDaLuz) {
spaceshipSpeed = maxSpeed;
} else {
spaceshipSpeed += acceleration;
}
} else {
spaceshipSpeed -= deceleration * spaceshipSpeed;
}
spaceshipSpeed = Math.max(spaceshipSpeed, 0);
spaceshipSpeed = Math.min(spaceshipSpeed, maxSpeed);
const direction = new THREE.Vector3(0, 0, 1);
direction.applyQuaternion(spaceship.quaternion);
spaceship.position.add(direction.multiplyScalar(spaceshipSpeed * clock.getDelta()));
targetCameraDistance = minCameraDistance + (maxCameraDistance - minCameraDistance) * (spaceshipSpeed / maxSpeed);
cameraDistance += (targetCameraDistance - cameraDistance);
const cameraOffset = new THREE.Vector3(0, 0.00001, -cameraDistance);
const relativeCameraOffset = cameraOffset.applyQuaternion(spaceship.quaternion);
const cameraPosition = spaceship.position.clone().add(relativeCameraOffset);
camera.position.copy(cameraPosition);
const forwardDirection = new THREE.Vector3(0, 0, 1);
forwardDirection.applyQuaternion(spaceship.quaternion);
const lookAtPosition = new THREE.Vector3().addVectors(spaceship.position, forwardDirection);
const upDirection = new THREE.Vector3(0, 1, 0);
upDirection.applyQuaternion(spaceship.quaternion);
camera.up.copy(upDirection);
camera.lookAt(lookAtPosition);
spaceship.rotation.z = 0;
spaceship.children[1].setVolume(spaceshipSpeed / maxSpeed);
if (spaceshipSpeed > 0 && !spaceship.children[1].isPlaying) {
spaceship.children[1].play();
} else if (spaceshipSpeed === 0 && spaceship.children[1].isPlaying) {
spaceship.children[1].pause();
}
const spaceshipSpeedKM = spaceshipSpeed * escalaModelo;
document.getElementById('velocidadeNave').textContent = spaceshipSpeedKM.toFixed(0) + ' KM/S';
}
}
function onKeyDown(event) {
switch (event.code) {
case ‘KeyW’:
spaceshipAccelerating = true;
break;
case ‘KeyF’:
toggleSpeedOfLight();
break;
}
}
function toggleSpeedOfLight() {
if (velocidadeDaLuz) {
velocidadeDaLuz = false;
spaceshipSpeed = 0;
spaceship.visible = camera.position.distanceTo(spaceship.position) < 100000;
} else {
velocidadeDaLuz = true;
spaceshipSpeed = 299792;
spaceship.visible = true;
}
}
function onKeyUp(event) {
switch (event.code) {
case ‘KeyW’:
spaceshipAccelerating = false;
break;
}
}
let crosshairX = 0;
let crosshairY = 0;
let azimuth = 0;
let inclination = 0;
function updateSpaceshipRotation() {
if (spaceship) {
const rotationSpeed = 0.1;
const mouseXNormalized = (crosshairX / window.innerWidth) * 2 - 1;
const mouseYNormalized = (crosshairY / window.innerHeight) * 2 - 1;
azimuth += rotationSpeed * mouseXNormalized;
inclination -= rotationSpeed * mouseYNormalized;
const forward = new THREE.Vector3(
Math.sin(azimuth) * Math.cos(inclination),
Math.sin(inclination),
Math.cos(azimuth) * Math.cos(inclination)
);
const right = new THREE.Vector3(-forward.z, 0, forward.x).normalize();
const up = new THREE.Vector3().crossVectors(forward, right).normalize();
spaceship.matrix.identity();
spaceship.matrix.makeBasis(right, up, forward);
spaceship.rotation.setFromRotationMatrix(spaceship.matrix);
}
}
document.addEventListener(‘mousemove’, (event) => {
crosshairX = event.clientX;
crosshairY = event.clientY;
const deltaX = crosshairX - window.innerWidth / 2;
const deltaY = crosshairY - window.innerHeight / 2;
});
const crosshair = document.getElementById(‘crosshair’);
document.addEventListener(‘mousemove’, (event) => {
crosshair.style.left = ${crosshairX - crosshair.clientWidth / 2}px
;
crosshair.style.top = ${crosshairY - crosshair.clientHeight / 2}px
;
});
function createPlanet(options) {
const { radius, texturePath, orbitRadius, rotationSpeed, inclination, colorLine, axialTilt, AxialRotate, orbitalPeriod, axialPeriod } = options;
const planet = createSphere(radius, texturePath);
planet.orbitRadius = orbitRadius * 5000;
planet.rotationSpeed = rotationSpeed;
planet.inclination = inclination;
planet.AxialRotate = AxialRotate;
planet.axialTilt = axialTilt;
planet.orbitalPeriod = orbitalPeriod;
planet.axialPeriod = axialPeriod;
planet.castShadow = true;
planet.receiveShadow = true;
const initialPosition = options.initialPosition || new THREE.Vector3(0, 0, 0);
planet.positionOffset = options.positionOffset || new THREE.Vector3(0, 0, 0);
planet.position.copy(initialPosition);
if (options.parentPlanet) {
options.parentPlanet.add(planet);
} else {
scene.add(planet);
}
planet.orbitLineColor = options.colorLine || 0xFFFFFF;
planet.scale.set(radius, radius, radius);
planet.rotation.x = inclination;
if (options.moons) {
planet.moons = options.moons;
moons = { ...moons, ...options.moons.reduce((acc, moon) => ({ ...acc, [moon.id]: moon }), {}) };
}
return planet;
}
function createMoon(parentPlanet, options) {
const {
id,
radius,
texturePath,
orbitRadius1,
rotationSpeed,
inclination1,
axialTilt,
orbitalPeriod,
axialPeriod,
moonOptions,
} = options;
const moon = createPlanet({
id,
radius,
texturePath,
orbitRadius: orbitRadius1,
rotationSpeed,
orbitalPeriod,
axialPeriod,
axialTilt,
inclination: inclination1,
});
parentPlanet.add(moon);
moons[id] = moon;
if (moonOptions && moonOptions.showOrbitLine) {
createMoonOrbitLine(moon, moonOptions.orbitRadius, moonOptions.inclination, moonOptions.colorLine);
}
return moon;
}
function createSun() {
const sunGeometry = new THREE.SphereGeometry(696340 * 5000, 64, 64);
const textureLoader = new THREE.TextureLoader();
const sunTexture = textureLoader.load(‘/images/sun_present.png’);
const sunMaterial = new THREE.MeshBasicMaterial({
map: sunTexture,
transparent: true,
});
const sun = new THREE.Mesh(sunGeometry, sunMaterial);
sun.position.set(0, 0, 0);
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 2, 0, 0.3);
composer = new EffectComposer(renderer);
composer.addPass(renderScene);
composer.addPass(bloomPass);
scene.add(sun);
const textureFlare0 = textureLoader.load("./images/sunligh1.png");
const lensflare = new Lensflare();
lensflare.addElement(new LensflareElement(textureFlare0, 10, 0));
lensflare.renderOrder = 0;
scene.add(lensflare);
const sunLight = new THREE.PointLight(0xffffff, 2, 10000000000000000);
sunLight.position.set(0, 0, 0);
sunLight.castShadow = true;
sunLight.shadow.mapSize.width = 2048;
sunLight.shadow.mapSize.height = 2048;
sunLight.shadow.camera.left = -sunLight.distance;
sunLight.shadow.camera.right = sunLight.distance;
sunLight.shadow.camera.top = sunLight.distance;
sunLight.shadow.camera.bottom = -sunLight.distance;
sunLight.decay = 0;
scene.add(sunLight);
return sun;
}
function createPlanets() {
planets.mercury = createPlanet({ radius: 2349, texturePath: ‘/images/planetas/mercurio.jpg’, orbitRadius: 57910000, rotationSpeed: 0.000000005, inclination: 0.0701, axialTilt: 0.034,colorLine: 0x800080, orbitalPeriod: 88 * 24 * 60 * 60, axialPeriod: 58.65 * 24 * 60 * 60, initialPosition: new THREE.Vector3(-4600120 , 0 , -6981690), positionOffset: new THREE.Vector3(-4600120, 0, -6981690)});
planets.venus = createPlanet({ radius: 6051, texturePath: ‘/images/planetas/venus.jpg’, orbitRadius: 108200000, rotationSpeed: 0.000000005, inclination: 0.0339, axialTilt: 0.177, colorLine: 0xCCCC00, orbitalPeriod: 225 * 24 * 60 * 60, axialPeriod: -116.75 * 24 * 60 * 60, initialPosition: new THREE.Vector3(10747600, 0, 10894200), positionOffset: new THREE.Vector3(10747600, 0, 10894200)});
planets.earth = createPlanet({ radius: 6378, texturePath: ‘./images/planetas/terra day.jpg’, orbitRadius: 149600000, rotationSpeed: 0.000000002, inclination: 0, axialTilt: 0, colorLine: 0x0000FF, orbitalPeriod: 365 * 24 * 60 * 60, axialPeriod: 1 * 24 * 60 * 60, initialPosition: new THREE.Vector3(14709829, 0, 15209823), positionOffset: new THREE.Vector3(14709829, 0, 15209823)});
planets.earth.moons = [
createMoon(planets.earth, { id: “lua”, radius: 1737, texturePath:‘./images/luas/moon2.jpg’, orbitRadius1: 3840, rotationSpeed: 0.0005, inclination1: 0.0514, axialTilt: 0.2, orbitalPeriod: 0.0005 * 24 * 60 * 60, axialPeriod: 27.32 * 24 * 60 * 60, moonOptions: {
showOrbitLine: true,
orbitRadius: 305,
inclination: 0.0514,
colorLine: 0xFFFF,
},}),
];
planets.mars = createPlanet({ radius: 3396, texturePath: '/images/planetas/marte.jpg', orbitRadius: 227940000, rotationSpeed: 0.000000000002, inclination: 0.0185, axialTilt: 0.25,colorLine: 0x800000, orbitalPeriod: 687 * 24 * 60 * 60, axialPeriod: 1.03 * 24 * 60 * 60, initialPosition: new THREE.Vector3(-20666900, 0, 24920930), positionOffset: new THREE.Vector3(-20666900, 0, 24920930)});
planets.jupiter = createPlanet({ radius: 71492, texturePath: './images/planetas/jupiter.jpg', orbitRadius: 778330000, rotationSpeed: 0.0000000000000002, inclination: 0.0131, axialTilt: 0.3, colorLine: 0x8B4513, orbitalPeriod: 4333 * 24 * 60 * 60, axialPeriod: 0.41 * 24 * 60 * 60, initialPosition: new THREE.Vector3(74057360, 0, 81652080), positionOffset: new THREE.Vector3(74057360, 0, 81652080)});
planets.jupiter.moons = [
createMoon(planets.jupiter, { id: "io", radius: 3.642, texturePath:'./images/luas/luas jupiter/io.jpg', orbitRadius1: 42170,rotationSpeed: 0.0005, inclination1: 0, orbitalPeriod: 0.005 * 24 * 60 * 60, axialPeriod: 1.77 * 24 * 60 * 60, moonOptions: {
showOrbitLine: true,
orbitRadius: 301.5,
inclination: 0,
colorLine: 0xFFFF,
},}),
createMoon(planets.jupiter, { id: "europa", radius: 3.131, texturePath:'./images/luas/luas jupiter/europa.jpg', orbitRadius1: 67103,rotationSpeed: 0.0005, inclination1: 0, axialTilt: 0.2 ,orbitalPeriod: 3.55 * 24 * 60 * 60, axialPeriod: 3.55 * 24 * 60 * 60 }),
createMoon(planets.jupiter, { id: "ganymedes", radius: 5.268, texturePath:'./images/luas/luas jupiter/ganymedes.jpg', orbitRadius1: 107041,rotationSpeed: 0.0005, inclination1: 0, orbitalPeriod: 7.15 * 24 * 60 * 60, axialPeriod: 7.15 * 24 * 60 * 60 }),
createMoon(planets.jupiter, { id: "calisto", radius: 4.820, texturePath:'./images/luas/luas jupiter/callisto.jpg', orbitRadius1: 188270,rotationSpeed: 0.0005, inclination1: 0, orbitalPeriod: 16.69 * 24 * 60 * 60, axialPeriod: 16.69 * 24 * 60 * 60 }),
];
planets.saturn = createPlanet({ radius: 60268, texturePath: './images/planetas/saturno.jpg', orbitRadius: 1429400000, rotationSpeed: 0.0000000000000002, inclination: 0.0249, colorLine: 0xCD853F, axialTilt: 0.26,orbitalPeriod: 10759 * 24 * 60 * 60, axialPeriod: 0.43 * 24 * 60 * 60, initialPosition: new THREE.Vector3(135357295, 0, 151332578), positionOffset: new THREE.Vector3(135357295, 0, 151332578)});
planets.urano = createPlanet({ radius: 25559 , texturePath: './images/planetas/urano.jpg', orbitRadius: 2870990000, rotationSpeed: 0.0000000000000002, inclination: 0.0077, colorLine: 0x008B8B, axialTilt: 0.82,orbitalPeriod: 30687 * 24 * 60 * 60, axialPeriod: -0.72 * 24 * 60 * 60, initialPosition: new THREE.Vector3(274893846, 0, 300441970), positionOffset: new THREE.Vector3(274893846, 0, 300441970)});
planets.netuno = createPlanet({ radius: 24764, texturePath: './images/planetas/netuno.jpg', orbitRadius: 4504300000, rotationSpeed: 0.0000000000000002, inclination: 0.0177 , colorLine: 0x000080, axialTilt: 0.28,orbitalPeriod: 60190 * 24 * 60 * 60, axialPeriod: 0.67 * 24 * 60 * 60, initialPosition: new THREE.Vector3(445294083, 0, 455394649), positionOffset: new THREE.Vector3(445294083, 0, 455394649)});
for (const planetKey in planets) {
if (planets.hasOwnProperty(planetKey)) {
const planet = planets[planetKey];
createPlanetOrbitLine(planet, planet.orbitRadius, planet.inclination, planet.colorLine);
}
}
scene.add(planets.mercury, planets.venus, planets.earth, ...planets.earth.moons, planets.mars, planets.jupiter, ...planets.jupiter.moons,planets.saturn, planets.urano, planets.netuno);
}
function createSphere(radius, texturePath) {
const geometry = new THREE.SphereGeometry(radius, 64, 64);
const texture = new THREE.TextureLoader().load(texturePath);
const material = new THREE.MeshStandardMaterial({
map: texture,
metalness: 1,
depthWrite: false,
opacity: 1,
transparent: true,
});
const object = new THREE.Mesh(geometry, material);
texture.castShadow = true;
texture.receiveShadow = true;
return object;
}
function createMoonOrbitLine(parentObject, orbitRadius, inclination, lineColor) {
const points = ;
const parentPosition = parentObject.parent.position.clone();
for (let i = 0; i <= 360; i += 0.2) {
const angle = i * (Math.PI / 180);
const x = orbitRadius * Math.cos(angle);
const z = orbitRadius * Math.sin(angle);
const y = orbitRadius * Math.sin(inclination) * Math.cos(angle);
points.push(new THREE.Vector3().copy(parentPosition).add(new THREE.Vector3(x, y, z)));
}
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: new THREE.Color(lineColor) });
const line = new THREE.Line(geometry, material);
parentObject.parent.add(line);
return line;
}
function createPlanetOrbitLine(planet) {
const lineColor = planet.orbitLineColor || 0xFFFFFF;
const points = [];
const planetPosition = planet.position.clone();
for (let i = 0; i <= 360; i += 0.2) {
const angle = i * (Math.PI / 180);
const x = planet.orbitRadius * Math.cos(angle);
const z = planet.orbitRadius * Math.sin(angle);
const y = planet.orbitRadius * Math.sin(planet.inclination) * Math.cos(angle);
points.push(new THREE.Vector3().copy(planetPosition).add(new THREE.Vector3(x, y, z)));
}
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: new THREE.Color(lineColor) });
const line = new THREE.Line(geometry, material);
scene.add(line);
return line;
}
function updateOrbitingObjectPosition(object, parentObject, startTime) {
const timeElapsed = (Date.now() - startTime) / 1000;
const orbitalAngle = (timeElapsed object.orbitalPeriod) / object.orbitalPeriod * 2 * Math.PI;
const axialAngle = (timeElapsed object.axialPeriod) / object.axialPeriod * 2 * Math.PI;
const inclinationAngle = object.inclination;
if (parentObject) {
const xWithoutOffset = parentObject.position.x + object.orbitRadius * Math.cos(orbitalAngle);
const zWithoutOffset = parentObject.position.z + object.orbitRadius * Math.sin(orbitalAngle);
const yWithoutOffset = parentObject.position.y + object.orbitRadius * Math.sin(inclinationAngle) * Math.cos(orbitalAngle);
const x = xWithoutOffset + object.positionOffset.x;
const z = zWithoutOffset + object.positionOffset.z;
const y = yWithoutOffset + object.positionOffset.y;
object.position.set(x, y, z);
object.rotation.x = inclinationAngle + axialAngle;
}
if (!object.visible) {
// Defina a visibilidade do objeto com base na sua posição
object.visible = camera.position.distanceTo(object.position) < 100000;
}
}
function focusCameraOnPlanet(planetId) {
selectedMoonId = null;
selectedPlanetId = planetId;
if (planetId && planets[planetId]) {
const selectedPlanet = planets[planetId];
currentControls.target.copy(selectedPlanet.position);
}
}
function focusMoon(moonId) {
selectedPlanetId = null;
selectedMoonId = moonId;
if (moonId && moons[moonId]) {
const selectedMoon = moons[moonId];
camera.lookAt(selectedMoon.position);
currentControls.target = selectedMoon.position;
}
}
function animate() {
requestAnimationFrame(animate);
animateSpaceship();
updateSpaceshipRotation();
lateUpdateCamera();
for (const planet in planets) {
if (planets.hasOwnProperty(planet)) {
const obj = planets[planet];
updateOrbitingObjectPosition(obj, scene, startTime);
if (obj.moons) {
obj.moons.forEach((moon, index) => {
updateOrbitingObjectPosition(moon, obj, startTime);
});
}
}
}
composer.render();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
}
init();
animate();