javascriptthree.jslight

Three.js pointLight seems not working


I am very new to WebGL and Three.js as well, so this might be very basic question and always somebody have asked before.

What I was playing with my codes was making the small solar system.

I used SpotLight with SpotLightHelper, and PointLight and PointLightHelper. Geometries I've used are BoxGeometry and SphereGeometry. Though BoxGeometry seems to get a light from PointLight, SphereGeometry does not.

What do you think is the problem I made wrong? Thank you for your time, in advance.

var width, height;
    var camera, renderer, scene;

    var position = {
        earth: {
            x: 200,
            y: 1,
            z: 0,
            theta: 0,
            traceRadius: 200
        }
    };

    width = window.innerWidth;
    height = window.innerHeight;

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(45,        // Field of view
        400 / 400,  // Aspect ratio
        .1,         // Near
        10000       // Far);
    );
    camera.lookAt(scene.position);
    camera.position.set(0, 0, 1000);
    scene.add(camera);

    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x000000, 1);
    renderer.setSize(width, height);
    renderer.shadowMapEnabled = false;

    var sunGeo = new THREE.SphereGeometry(70, 128, 128);
    var sunMat = new THREE.MeshLambertMaterial({color: 0x00ff00});
    var sunMesh = new THREE.Mesh(sunGeo, sunMat);
    sunMesh.position.set(0, 0, 0);
    sunMesh.castShadow = true;
    sunMesh.receiveShadow = false;
    scene.add(sunMesh);

    var boxGeo = new THREE.BoxGeometry(50, 50, 50);
    var boxMat = new THREE.MeshLambertMaterial({color: 0xfff0f0});
    var boxMesh = new THREE.Mesh(boxGeo, boxMat);
    boxMesh.position.set(-100, 100, 0);
    boxMesh.castShadow = true;
    scene.add(boxMesh);

    var earthTraceGeo = new THREE.CircleGeometry(position.earth.traceRadius, 128, 128);
    var edges = new THREE.EdgesGeometry(earthTraceGeo);
    var line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0xffffff}));
    scene.add(line);

    var earthGeo = new THREE.SphereGeometry(30, 128, 128);
    var earthMat = new THREE.MeshLambertMaterial({color: 0x0000ff});
    var earthMesh = new THREE.Mesh(earthGeo, earthMat);
    earthMesh.position.set(position.earth.traceRadius, 0, 0);
    earthMesh.castShadow = true;
    earthMesh.receiveShadow = true;
    scene.add(earthMesh);

    var lightSize = 250;
    var pointLight = new THREE.PointLight(0xff0000, 1000, lightSize, 2);
    pointLight.position.set(110, 0, 110);
    pointLight.castShadow = true;
    scene.add(pointLight);

    var spotLight = new THREE.SpotLight(0xffffff, 1, 1000);
    spotLight.position.set(-200, 120, 200);
    spotLight.castShadow = true;
    scene.add(spotLight);

    var spotLightHelper = new THREE.SpotLightHelper( spotLight, 0xffbbaa);
    scene.add( spotLightHelper );

    var pointLightHelper = new THREE.PointLightHelper( pointLight, lightSize );
    scene.add( pointLightHelper );

    var ambientLight = new THREE.AmbientLight(0x404040);
//    scene.add(ambientLight);
    renderer.render(scene, camera);

    render();
    document.getElementById("WebGL-output").appendChild(renderer.domElement);

    function render() {
//        spotLightHelper.update();

        position.earth.theta += 1;
        position.earth.x = getX(0, position.earth.theta, position.earth.traceRadius);
        position.earth.y = getY(0, position.earth.theta, position.earth.traceRadius);
        earthMesh.position.set(position.earth.x, position.earth.y, 0);

        renderer.render(scene, camera);

        requestAnimationFrame(render);
    }

    function getX(x, theta, radius) {
        return x + Math.cos((Math.PI / 180) * theta) * radius;
    }

    function getY(y, theta, radius) {
        return y + Math.sin((Math.PI / 180) * theta) * radius;
    }

Here is the link: https://jsfiddle.net/ne7gjdnq/623/


Solution

  • The light of the point light source can't bee seen, because the color of the light is red 0xff0000 and the color of the sphere geometry is green 0x00ff00.
    The red light of the light source does not affect the green sphere. The box is affected, because its color is 0xfff0f0.

    Note, in the light model the colors are more or less multiplied. If one side of the multiplication of a color channel is 0, then the result is 0, too.

    Either change the color of the light source

    var pointLight = new THREE.PointLight(0xffff00, 1000, lightSize, 2);
    

    or the color of the sphere

    var sunGeo = new THREE.SphereGeometry(70, 128, 128);
    var sunMat = new THREE.MeshLambertMaterial({color: 0xffff00});
    var sunMesh = new THREE.Mesh(sunGeo, sunMat);
    

    to solve the issue.

    See the result in the Example:

    var width, height;
    var camera, renderer, scene;
    
    var position = {
        earth: {
            x: 200,
            y: 1,
            z: 0,
            theta: 0,
            traceRadius: 200
        }
    };
    
    width = window.innerWidth;
    height = window.innerHeight;
    
    scene = new THREE.Scene();
    //    camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
    camera = new THREE.PerspectiveCamera(45,        // Field of view
        400 / 400,  // Aspect ratio
        .1,         // Near
        10000       // Far);
    );
    camera.lookAt(scene.position);
    camera.position.set(0, 0, 1000);
    scene.add(camera);
    
    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x000000, 1);
    renderer.setSize(width, height);
    renderer.shadowMapEnabled = false;
    
    var sunGeo = new THREE.SphereGeometry(70, 128, 128);
    var sunMat = new THREE.MeshLambertMaterial({color: 0x00ff00});
    var sunMesh = new THREE.Mesh(sunGeo, sunMat);
    sunMesh.position.set(0, 0, 0);
    sunMesh.castShadow = true;
    sunMesh.receiveShadow = false;
    scene.add(sunMesh);
    
    var boxGeo = new THREE.BoxGeometry(50, 50, 50);
    var boxMat = new THREE.MeshLambertMaterial({color: 0xfff0f0});
    var boxMesh = new THREE.Mesh(boxGeo, boxMat);
    boxMesh.position.set(-100, 100, 0);
    boxMesh.castShadow = true;
    scene.add(boxMesh);
    
    var earthTraceGeo = new THREE.CircleGeometry(position.earth.traceRadius, 128, 128);
    var edges = new THREE.EdgesGeometry(earthTraceGeo);
    var line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0xffffff}));
    scene.add(line);
    
    var earthGeo = new THREE.SphereGeometry(30, 128, 128);
    var earthMat = new THREE.MeshLambertMaterial({color: 0x0000ff});
    var earthMesh = new THREE.Mesh(earthGeo, earthMat);
    earthMesh.position.set(position.earth.traceRadius, 0, 0);
    earthMesh.castShadow = true;
    earthMesh.receiveShadow = true;
    scene.add(earthMesh);
    
    var lightSize = 250;
    var pointLight = new THREE.PointLight(0xffff00, 1000, lightSize, 2);
    pointLight.position.set(110, 0, 110);
    pointLight.castShadow = true;
    scene.add(pointLight);
    
    var spotLight = new THREE.SpotLight(0xffffff, 1, 1000);
    spotLight.position.set(-200, 120, 200);
    spotLight.castShadow = true;
    scene.add(spotLight);
    
    var spotLightHelper = new THREE.SpotLightHelper( spotLight, 0xffbbaa);
    //    scene.add( spotLightHelper );
    
    var pointLightHelper = new THREE.PointLightHelper( pointLight, lightSize );
    scene.add( pointLightHelper );
    
    var ambientLight = new THREE.AmbientLight(0x404040);
    //    scene.add(ambientLight);
    renderer.render(scene, camera);
    
    window.onresize = resize;
    
    render();
    document.getElementById("WebGL-output").appendChild(renderer.domElement);
    
    function render() {
    //        spotLightHelper.update();
    
        position.earth.theta += 1;
        position.earth.x = getX(0, position.earth.theta, position.earth.traceRadius);
        position.earth.y = getY(0, position.earth.theta, position.earth.traceRadius);
        earthMesh.position.set(position.earth.x, position.earth.y, 0);
    
        renderer.render(scene, camera);
    
        requestAnimationFrame(render);
    }
    
    function getX(x, theta, radius) {
        return x + Math.cos((Math.PI / 180) * theta) * radius;
    }
    
    function getY(y, theta, radius) {
        return y + Math.sin((Math.PI / 180) * theta) * radius;
    }
    
    function resize() {
    
    var aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
    //controls.handleResize();
    }
    * { padding:0; margin:0; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <div id="WebGL-output"></div>