【问题标题】:Three.js pointLight seems not workingThree.js pointLight 似乎不起作用
【发布时间】:2018-07-08 15:30:45
【问题描述】:

我对 WebGL 和 Three.js 也很陌生,所以这可能是非常基本的问题,而且总是有人问过。

我正在使用我的代码制作小型太阳系。

我将 SpotLight 与 SpotLightHelper 以及 PointLight 和 PointLightHelper 一起使用。 我使用的几何图形是 BoxGeometry 和 SphereGeometry。尽管 BoxGeometry 似乎从 PointLight 中获得了光,但 SphereGeometry 却没有。

你认为我做错了什么问题? 提前感谢您的宝贵时间。

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

这里是链接:https://jsfiddle.net/ne7gjdnq/623/

【问题讨论】:

    标签: three.js light


    【解决方案1】:

    看不到点光源的光,因为光的颜色是红色0xff0000,球体几何的颜色是绿色0x00ff00
    光源的红光不影响绿球。盒子受到影响,因为它的颜色是0xfff0f0

    请注意,在灯光模型中,颜色或多或少会成倍增加。如果颜色通道相乘的一侧为 0,则结​​果也为 0。

    要么改变光源的颜色

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

    或者球体的颜色

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

    解决问题。

    查看示例中的结果:

    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>

    【讨论】:

    • 很好的解释,谢谢。你认为我应该使用什么光来制作太阳系作为练习?我想要中心圆,代表太阳作为唯一的光,照亮它周围的所有行星
    猜你喜欢
    • 2016-11-29
    • 2016-02-01
    • 2020-09-23
    • 2010-12-05
    • 2011-06-14
    • 2015-01-10
    • 2016-02-24
    • 2011-01-18
    • 2018-06-20
    相关资源
    最近更新 更多