threejs-earth icon indicating copy to clipboard operation
threejs-earth copied to clipboard

Different result than what is shown in the video

Open SebastianKuehl opened this issue 1 year ago • 4 comments

Hi! I tried to use this code in my Angular v17 project and essentially copied everything to my ngAfterViewInit function. However, when I run the program I get a different look than what we can see in the video (see pictures). It seems that something with the meshes is off, maybe opacity? Any idea how I can fix this? The rotation/animation works flawlessly and the clouds also move faster than the earth 👍

Result from video Result from copied code
video-result copied-result

Here is the code of my component. As you can see, only thing I changed is the path to files. Edit: And removed the orbit controls.

import { Component, AfterViewInit } from '@angular/core';
import * as THREE from "three";
import { getFresnelMat } from '../../util/getFresnelMat';
import getStarfield from '../../util/getStartfield';

@Component({
  selector: 'app-main',
  standalone: true,
  templateUrl: './main.component.html',
  imports: []
})
export class MainComponent implements AfterViewInit {

  ngAfterViewInit(): void {
    const w = window.innerWidth;
    const h = window.innerHeight;
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 1000);
    camera.position.z = 5;
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(w, h);
    document.body.appendChild(renderer.domElement);

    const earthGroup = new THREE.Group();
    earthGroup.rotation.z = -23.4 * Math.PI / 180;
    scene.add(earthGroup);
    const detail = 12;
    const loader = new THREE.TextureLoader();
    const geometry = new THREE.IcosahedronGeometry(1, detail);
    const material = new THREE.MeshPhongMaterial({
      map: loader.load("../../../assets/textures/00_earthmap1k.jpg"),
      specularMap: loader.load("../../../assets/textures/02_earthspec1k.jpg"),
      bumpMap: loader.load("../../../assets/textures/01_earthbump1k.jpg"),
      bumpScale: 0.04,
    });
    const earthMesh = new THREE.Mesh(geometry, material);
    earthGroup.add(earthMesh);

    const lightsMat = new THREE.MeshBasicMaterial({
      map: loader.load("../../../assets/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("../../../assets/textures/04_earthcloudmap.jpg"),
      transparent: true,
      opacity: 0.8,
      blending: THREE.AdditiveBlending,
      alphaMap: loader.load('../../../assets/textures/05_earthcloudmaptrans.jpg'),
      // alphaTest: 0.3,
    });
    const cloudsMesh = new THREE.Mesh(geometry, cloudsMat);
    cloudsMesh.scale.setScalar(1.003);
    earthGroup.add(cloudsMesh);

    const fresnelMat = getFresnelMat();
    const glowMesh = new THREE.Mesh(geometry, fresnelMat);
    glowMesh.scale.setScalar(1.01);
    earthGroup.add(glowMesh);

    const stars = getStarfield({ numStars: 2000 });
    scene.add(stars);

    const sunLight = new THREE.DirectionalLight(0xffffff);
    sunLight.position.set(-2, 0.5, 1.5);
    scene.add(sunLight);

    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);
    }

    animate();

    function handleWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }
    window.addEventListener('resize', handleWindowResize, false);
  }
}

SebastianKuehl avatar May 20 '24 13:05 SebastianKuehl

It appears that he is using the 4k images in the video. I similarly have poor rendering, I believe the 1k cloud image is the main culprit.

cgrundman avatar Jul 14 '24 20:07 cgrundman

@cgrundman @SebastianKuehl , here u go, scroll down and get the 8K images, problem will be solved https://www.solarsystemscope.com/textures/

image

scienmanas avatar Nov 18 '24 10:11 scienmanas

I copied the code into a Next.js component (everything inside useEffect, basically) and the animation works fine, but the rendering looks different from the video (see attached images). The Earth looks off — probably a color issue.

The fix is to set .colorSpace = THREE.SRGBColorSpace on each texture. By default, Three.js assumes linear color space, but most images (like JPG or PNG) are in sRGB, so the colors will look wrong unless you specify it.

Example:

const loader = new THREE.TextureLoader();
const texture = loader.load('/assets/textures/00_earthmap1k.jpg');
texture.colorSpace = THREE.SRGBColorSpace;

Apply that to every texture (map, bumpMap, specularMap, etc.). That alone makes the rendering match the one in the video.

Earth texture with colorSpace = THREE.SRGBColorSpace vs without:

With .SRGBColorSpace Without .SRGBColorSpace
With-SRGBColorSpace Without-SRGBColorSpace

Csalcedo04 avatar Jun 12 '25 20:06 Csalcedo04

Hey @Csalcedo04, thanks for your comment, didn't know about this :)

scienmanas avatar Jun 13 '25 01:06 scienmanas