为什么我无法在Three.js中投射或接收阴影?

5
我刚开始接触这个,正在尝试在我刚刚制作的物体上创建闪电和阴影。如下图所示,它们实际上都没有产生或接收到阴影。 我已经为渲染器启用了阴影映射,并且还为所有对象启用了投射和接收阴影。我做错了什么?

enter image description here

<head>
    <meta charset=utf-8>
    <title>Three.js Object Tester</title>
    <style>
        body { margin: 0; overflow: hidden; }
        canvas { width: 100%; height: 100% }
    </style>
</head>

<body>

<script type="module">
    import * as THREE from './js-r119/build/three.module.js';
    import { TrackballControls } from './js-r119/examples/jsm/controls/TrackballControls.js';

    var WIDTH, HEIGHT, aspectRatio;
    var renderer;
    var scene, camera;
    var controls;
    var mesh;

    init();
    animate();
    function init() {
        HEIGHT = window.innerHeight;
        WIDTH = window.innerWidth;
        aspectRatio = WIDTH / HEIGHT;

        renderer = new THREE.WebGLRenderer( { antialias: true } );
        renderer.setSize( WIDTH, HEIGHT );
        renderer.setClearColor( 0x000000 );
        renderer.shadowMap.enabled = true;
        document.body.appendChild( renderer.domElement );


        scene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera( 75, aspectRatio, 0.1, 1000 );
        camera.position.set( 0, 40, 80 );
        camera.lookAt( scene.position );

        var light = new THREE.AmbientLight( 0xF5F5F3 ); //ambiens fény

        scene.add( light );

        var floorgeometry = new THREE.PlaneGeometry( 150, 150, 1, 1 );
        var floormaterial = new THREE.MeshLambertMaterial( { color: 0xFFFFFF, wireframe: false } );
        var floor = new THREE.Mesh( floorgeometry, floormaterial );
        floor.material.side = THREE.DoubleSide;
        floor.rotation.x = 1.57;
        floor.position.z = 0;
        floor.position.x = 0;
        floor.position.y = -42.5;
        floor.receiveShadow = true;
        floor.castShadow = true;
        scene.add( floor );


        var vertgeometry = new THREE.BoxGeometry( 20, 45, 20);
        var vertmaterial = new THREE.MeshLambertMaterial( { color: 0xD5D8DC, wireframe: false } );
        var vert = new THREE.Mesh( vertgeometry, vertmaterial );
        vert.castShadow = true;
        vert.receiveShadow = true;
        vert.rotation.z = 0;
        vert.rotation.x = 0;
        vert.rotation.y = 0;
        vert.position.z = 0;
        vert.position.x = 0;
        vert.position.y = -20;


        var horgeometry = new THREE.BoxGeometry( 20, 40, 20);
        var hormaterial = new THREE.MeshLambertMaterial( { color: 0xD5D8DC, wireframe: false } );
        var hor = new THREE.Mesh( horgeometry, hormaterial );
        hor.castShadow = true;
        hor.position.z = 0;
        hor.position.y = -32.5;
        hor.position.x = 30;
        hor.rotation.z = 1.57;
        hor.rotation.x = 0;
        hor.rotation.y = 0;

        scene.add( hor );

        var roofgeometry = new THREE.ConeGeometry( 14.142, 40, 4);

        var roofmaterial = new THREE.MeshLambertMaterial( { color: 0xF98E76, wireframe: false } );
        var roof = new THREE.Mesh( roofgeometry, roofmaterial );
        roof.castShadow = true;
        roof.position.z = 0;
        roof.position.y = 22.5;
        roof.position.x = 0;
        roof.rotation.z = 0;
        roof.rotation.x = 0;
        roof.rotation.y = 0.775;

        scene.add( roof );

        scene.add( vert );

        var lampgeometry = new THREE.BoxGeometry( 2, 25, 2);
        var lampmaterial = new THREE.MeshLambertMaterial( { color: 0x566573, wireframe: false } );
        var lamp = new THREE.Mesh( lampgeometry, lampmaterial );
        lamp.castShadow = true;
        lamp.rotation.z = 0;
        lamp.rotation.y = 0;
        lamp.position.z = 0;
        lamp.position.x = -60;
        lamp.position.y = -30;

        var spotgeometry = new THREE.BoxGeometry( 3, 3, 3);
        var spotmaterial = new THREE.MeshLambertMaterial( { color: 0xF6F50B, wireframe: false } );
        var spot = new THREE.Mesh( spotgeometry, spotmaterial );
        spot.position.z = 0;
        spot.position.y = -17.5;
        spot.position.x = -60;

        scene.add( lamp );
        scene.add( spot );

        var geometry = new THREE.SphereGeometry( 200, 20, 20);
        var appearence = new THREE.MeshLambertMaterial ({
            color: 0xa2a7a9,
            wireframe: false
        });

        var objgeometry = new THREE.BoxGeometry(8,12,8);
        var objmaterial = new THREE.MeshLambertMaterial({color: 0x1C1C03, wireframe: false});
        var obj = new THREE.Mesh(objgeometry, objmaterial);
        obj.castShadow = true;
        obj.receiveShadow = true;
        obj.position.z = 0;
        obj.position.x = -40;
        obj.position.y = -36.5;
        scene.add(obj);



        var sLight = new THREE.SpotLight( 0xF6F50B, 3 ); // spotfény segédgeometriával
        sLight.position.set( -60, -17.5, 0 );
        sLight.castShadow = true;
        sLight.distance = 100;
        sLight.target = obj;
        sLight.castShadow = true;
        sLight.shadow.mapSize.width = 2048;
        sLight.shadow.mapSize.height = 2048;

        scene.add( sLight );

        var spotLightHelper = new THREE.SpotLightHelper( sLight );
        scene.add( spotLightHelper );


        window.addEventListener( 'resize', handleWindowResize, false );



        controls = new TrackballControls( camera, renderer.domElement );
        controls.rotateSpeed = 5.0;
        controls.panSpeed = 1.0;
    }

    function handleWindowResize() {
        HEIGHT = window.innerHeight;
        WIDTH = window.innerWidth;
        console.log( 'WIDTH=' + WIDTH + '; HEIGHT=' + HEIGHT );
        renderer.setSize( WIDTH, HEIGHT );
        aspectRatio = WIDTH / HEIGHT;
        camera.aspect = aspectRatio;
        camera.updateProjectionMatrix();

        render();
    }

    function animate() {

        requestAnimationFrame( animate );
        controls.update();

        render();
    }

    function render() {
        renderer.render( scene, camera );
    }

</script>
</body>
</html>
1个回答

2
如果在场景中放置聚光灯,你需要确保没有投射阴影的网格物体挡住了光线的发射。这是因为灯光被放置在“内部”的lamp网格中所导致的。更新代码如下:

var WIDTH, HEIGHT, aspectRatio;
var renderer;
var scene, camera;
var controls;
var mesh, spotLightHelper;

init();
animate();

function init() {
  HEIGHT = window.innerHeight;
  WIDTH = window.innerWidth;
  aspectRatio = WIDTH / HEIGHT;

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(WIDTH, HEIGHT);
  renderer.setClearColor(0x000000);
  renderer.shadowMap.enabled = true;
  document.body.appendChild(renderer.domElement);


  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
  camera.position.set(0, 40, 80);
  camera.lookAt(scene.position);

  var light = new THREE.AmbientLight(0xF5F5F3, 0.4); //ambiens fény

  scene.add(light);

  var floorgeometry = new THREE.PlaneGeometry(150, 150, 1, 1);
  var floormaterial = new THREE.MeshPhongMaterial({
    color: 0xFFFFFF,
    wireframe: false
  });
  var floor = new THREE.Mesh(floorgeometry, floormaterial);
  //floor.material.side = THREE.DoubleSide;
  floor.rotation.x = -Math.PI * 0.5;
  floor.position.z = 0;
  floor.position.x = 0;
  floor.position.y = -42.5;
  floor.receiveShadow = true;
  scene.add(floor);


  var vertgeometry = new THREE.BoxGeometry(20, 45, 20);
  var vertmaterial = new THREE.MeshPhongMaterial({
    color: 0xD5D8DC,
    wireframe: false
  });
  var vert = new THREE.Mesh(vertgeometry, vertmaterial);
  vert.castShadow = true;
  vert.receiveShadow = true;
  vert.rotation.z = 0;
  vert.rotation.x = 0;
  vert.rotation.y = 0;
  vert.position.z = 0;
  vert.position.x = 0;
  vert.position.y = -20;


  var horgeometry = new THREE.BoxGeometry(20, 40, 20);
  var hormaterial = new THREE.MeshPhongMaterial({
    color: 0xD5D8DC,
    wireframe: false
  });
  var hor = new THREE.Mesh(horgeometry, hormaterial);
  hor.castShadow = true;
  hor.position.z = 0;
  hor.position.y = -32.5;
  hor.position.x = 30;
  hor.rotation.z = 1.57;
  hor.rotation.x = 0;
  hor.rotation.y = 0;

  scene.add(hor);

  var roofgeometry = new THREE.ConeGeometry(14.142, 40, 4);

  var roofmaterial = new THREE.MeshPhongMaterial({
    color: 0xF98E76,
    wireframe: false
  });
  var roof = new THREE.Mesh(roofgeometry, roofmaterial);
  roof.castShadow = true;
  roof.position.z = 0;
  roof.position.y = 22.5;
  roof.position.x = 0;
  roof.rotation.z = 0;
  roof.rotation.x = 0;
  roof.rotation.y = 0.775;

  scene.add(roof);

  scene.add(vert);

  var lampgeometry = new THREE.BoxGeometry(2, 25, 2);
  var lampmaterial = new THREE.MeshPhongMaterial({
    color: 0x566573,
    wireframe: false
  });
  var lamp = new THREE.Mesh(lampgeometry, lampmaterial);
  lamp.rotation.z = 0;
  lamp.rotation.y = 0;
  lamp.position.z = 0;
  lamp.position.x = -60;
  lamp.position.y = -30;

  var spotgeometry = new THREE.BoxGeometry(3, 3, 3);
  var spotmaterial = new THREE.MeshPhongMaterial({
    color: 0xF6F50B,
    wireframe: false
  });
  var spot = new THREE.Mesh(spotgeometry, spotmaterial);
  spot.position.z = 0;
  spot.position.y = -17.5;
  spot.position.x = -60;

  scene.add(lamp);
  scene.add(spot);

  var geometry = new THREE.SphereGeometry(200, 20, 20);
  var appearence = new THREE.MeshPhongMaterial({
    color: 0xa2a7a9,
    wireframe: false
  });

  var objgeometry = new THREE.BoxGeometry(8, 12, 8);
  var objmaterial = new THREE.MeshPhongMaterial({
    color: 0x1C1C03,
    wireframe: false
  });
  var obj = new THREE.Mesh(objgeometry, objmaterial);
  obj.castShadow = true;
  obj.receiveShadow = true;
  obj.position.z = 0;
  obj.position.x = -40;
  obj.position.y = -36.5;
  scene.add(obj);



  var sLight = new THREE.SpotLight(0xF6F50B, 1); // spotfény segédgeometriával
  sLight.position.set(-60, -17.5, 0);
  sLight.castShadow = true;
  sLight.distance = 100;
  sLight.target = obj;
  sLight.angle = Math.PI * 0.2;
  sLight.shadow.camera.near = 0.1;
  sLight.shadow.camera.far = 100;
  sLight.shadow.mapSize.width = 2048;
  sLight.shadow.mapSize.height = 2048;

  scene.add(sLight);

  spotLightHelper = new THREE.SpotLightHelper(sLight);
  scene.add(spotLightHelper);

  var cameraHelper = new THREE.CameraHelper(sLight.shadow.camera);
  scene.add(cameraHelper)


  window.addEventListener('resize', handleWindowResize, false);

}

function handleWindowResize() {
  HEIGHT = window.innerHeight;
  WIDTH = window.innerWidth;
  renderer.setSize(WIDTH, HEIGHT);
  aspectRatio = WIDTH / HEIGHT;
  camera.aspect = aspectRatio;
  camera.updateProjectionMatrix();

  render();
}

function animate() {

  requestAnimationFrame(animate);
  spotLightHelper.update();

  render();
}

function render() {
  renderer.render(scene, camera);
}
body {
  margin: 0;
}
canvas {
  display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.js"></script>

顺便提一下:在使用SpotLightHelper时,确保在动画循环中更新此辅助程序。此外,CameraHelper可用于调试阴影视锥。


1
谢谢,现在没问题了。 - scylla0120

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接