Shadow Umbra help

I am making a solarsystem, but with large scale (distance are in thousands). Point light is at center of sun. I want to make umbra of shadow made from that pointlight to be infinity (or atleast be more than the distance between them), so the moon and earth can cast shadows on them.
Currently, making distance between earth and moon makes them cast shadows on each other. But when I put them back, then no shadows right now.

Here is my code (Its big but labelled).

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

import { EffectComposer } from 'three/examples/jsm/Addons.js';
import { RenderPass } from 'three/examples/jsm/Addons.js';
import { UnrealBloomPass } from 'three/examples/jsm/Addons.js';

import { GUI } from 'dat.gui';

import sun from './textures/8k_sun.jpg';
import earth from './textures/2k_earth.jpg';
import moon from './textures/2k_moon.jpg';
import stars from './textures/2k_stars.jpg';
import galaxy from './textures/2k_stars_milky_way_square.jpg';

/* Initialization */
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.shadowMap.enabled = true;

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000000);

const orbit = new OrbitControls(camera, renderer.domElement);
camera.position.set(228500, 0, 175);
// orbit.update();


/* sun glow effect */
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1, 0, 0);
const bloomComposer = new EffectComposer(renderer);
bloomComposer.setSize(window.innerWidth, window.innerHeight);
bloomComposer.renderToScreen = true;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);


/* All visible stuff */

// const axesHelper = new THREE.AxesHelper(240000);
// scene.add(axesHelper);

const ambientLight = new THREE.AmbientLight(0x303030);
scene.add(ambientLight);

const textureLoader = new THREE.TextureLoader();
const cubeTextureLoader = new THREE.CubeTextureLoader();
scene.background = cubeTextureLoader.load([stars, stars, stars, stars, stars, galaxy]);

const sunGeometry = new THREE.SphereGeometry(8400, 1000, 1000);
const sunMaterial = new THREE.MeshBasicMaterial({map: textureLoader.load(sun)});
const sunObject = new THREE.Mesh(sunGeometry, sunMaterial);
scene.add(sunObject);

const earthGeometry = new THREE.SphereGeometry(105, 1000, 1000);
const earthMaterial = new THREE.MeshLambertMaterial({map: textureLoader.load(earth)});
const earthObject = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earthObject);
earthObject.position.set(228000, 0, 0);
camera.lookAt(earthObject.position);
earthObject.castShadow = true;
earthObject.receiveShadow = true;


const moonGeometry = new THREE.SphereGeometry(30, 500, 500);
const moonMaterial = new THREE.MeshLambertMaterial({map: textureLoader.load(moon)});
const moonObject = new THREE.Mesh(moonGeometry, moonMaterial);
moonObject.position.set(-150, 0, 0);
moonObject.castShadow = true;
moonObject.receiveShadow = true;
// earthObject.add(moonObject);

const moonOrbit = new THREE.Group();
scene.add(moonOrbit);
moonOrbit.add(moonObject);
earthObject.add(moonOrbit);
moonOrbit.castShadow = true;
moonOrbit.receiveShadow = true;

const revoluter = new THREE.Group();
revoluter.add(earthObject);
scene.add(revoluter);

/* Light */
const pointLight = new THREE.PointLight(0xFFFFFF, 50000000000, 1000000);
pointLight.position.set(0, 0, 0);
pointLight.castShadow = true;
pointLight.shadow.near = 0.5;
pointLight.shadow.far = 500000;
pointLight.shadow.camera.near = 0.5;
pointLight.shadow.camera.far = 500000;
pointLight.shadow.mapSize.width = 4096;
pointLight.shadow.mapSize.height = 4096;
pointLight.shadow.bias = -0.0001;
scene.add(pointLight);

/* GUI stuff */
const gui = new GUI();

let cameraPositions = {
    Earth: { position: new THREE.Vector3(228500, 0, 175), zoom: camera.zoom },
    Sun: { position: new THREE.Vector3(10000, 0, 20000), zoom: camera.zoom }};

let targetFocus = 'Earth';

gui.add({ focus: targetFocus }, 'focus', ['Sun', 'Earth']).name('Focus on').onChange(function (value) {
    cameraPositions[targetFocus] = { position: camera.position.clone(), zoom: camera.zoom };

    targetFocus = value;

    camera.position.copy(cameraPositions[targetFocus].position);
    camera.zoom = cameraPositions[targetFocus].zoom;
    camera.updateProjectionMatrix();
});

/* Animation */
function animate() {
    requestAnimationFrame(animate);

    earthObject.rotateOnAxis(new THREE.Vector3(0,0.95, 0.2), 0.005);
    sunObject.rotateOnAxis(new THREE.Vector3(0,1,0), 0.0001);
    revoluter.rotateY(0.00001);
    moonOrbit.rotateY(0.001);

    const earthPos = new THREE.Vector3();
    earthObject.getWorldPosition(earthPos);
    const sunPos = new THREE.Vector3();
    sunObject.getWorldPosition(sunPos);

    if (targetFocus === 'Earth') {
        orbit.target.copy(earthPos);
    } else {
        orbit.target.copy(sunPos);
    }

    orbit.update();

    renderer.render(scene, camera);
    bloomComposer.render();
}

animate();

Never mind! That crazy ass numbers need mapSize some exponentially high figure, which is definitely unhealthy for my pc.

Instead I will make another light just outside the orbit of moon, just bigger than the size of earth, always in between the sun and earth, so eclipses happen.

1 Like