WebGL、Three.js - 灯光、阴影

问题描述 投票:0回答:1

我在灯光聚焦到目标时遇到问题(需要将其聚焦在主角上并使背景变暗)。第二个问题是,阴影不起作用。下面是处理灯光和阴影的部分代码。有什么想法吗?

index.html 文件

//////////////////////////////////////////////////////////////////////////////////
//      renderer setup                          //
//////////////////////////////////////////////////////////////////////////////////

var renderer    = new THREE.WebGLRenderer();
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

//////////////////////////////////////////////////////////////////////////////////
//      default 3 points lightning                  //
//////////////////////////////////////////////////////////////////////////////////

var ambientLight= new THREE.AmbientLight( 0x020202 )
scene.add( ambientLight)

var frontLight  = new THREE.DirectionalLight('white', 1)
frontLight.position.set(0.5, 0.5, 0.5)
frontLight.castShadow = true
scene.add( frontLight )

var backLight   = new THREE.DirectionalLight('white', 0.5)
backLight.position.set(-0.5, -0.5, -0.5)
scene.add( backLight )

frontLight.shadowMapSize = new THREE.Vector2( 512, 512 )
frontLight.shadowCamera = new THREE.OrthographicCamera( 0, 0, 0, 0, 0.5, 500 )

var pointLight  = new THREE.SpotLight('white', 0.1)
pointLight.position.set(0,5,5)
scene.add( pointLight )

//////////////////////////////////////////////////////////////////////////////////
//      obstacle (short version)                                            //
//////////////////////////////////////////////////////////////////////////////////

scene.add(obstacle)
obstacle.position.x = 0.00
obstacle.castShadow = true

//////////////////////////////////////////////////////////////////////////////////
//      Init floor                  //
//////////////////////////////////////////////////////////////////////////////////
function generateRoad(z){
    var road = THREEx.Environment.road()
    road.receiveShadow =  true
    scene.add(road)
    var velocity    = new THREE.Vector3(0, 0, z);
    road.position.add(velocity)
}
javascript three.js shadow light
1个回答
1
投票

一般来说,你的代码可以工作。唯一的问题是阴影相机,它在 x 和 y 方向上的范围为 0.0。将其更改为类似的内容:

frontLight.shadow.camera = new THREE.OrthographicCamera( -10, 10, 10, -10, 0.5, 500 );

注意,

https://threejs.org/docs/#api/cameras/OrthographicCamera
定义了视图矩阵和正交投影矩阵。

投影矩阵描述了从场景的 3D 点到视口的 2D 点的映射。投影矩阵从视图空间变换到剪辑空间。通过除以剪辑坐标的

w
分量,剪辑空间中的坐标将转换为 (-1, -1, -1) 到 (1, 1, 1) 范围内的标准化设备坐标 (NDC)。 NDC 之外的每个几何体都会被剪裁。
在正交投影中,眼睛空间中的坐标线性映射到标准化设备坐标。

当您使用

THREE.OrthographicCamera( 0, 0, 0, 0, 0.5, 500 )
时,
left
right
top
bottom
为 0。这意味着您尝试将 0.0 和 0.0 之间的区域映射到 NDC。


请参阅代码片段:

var renderer, scene, controls, camera;

var init = function (){
  scene  = new THREE.Scene();
  renderer = new THREE.WebGLRenderer(); 

  var color = new THREE.Color("rgb(200, 250, 250)");
  renderer.setClearColor(new THREE.Color(color));
  renderer.setSize(window.innerWidth, window.innerHeight);

  camera = new THREE.PerspectiveCamera (45, window.innerWidth/window.innerHeight, 0.1, 1000); 
  camera.position.x = -20;
  camera.position.y = -30;
  camera.position.z = 20;
  camera.up = new THREE.Vector3( 0, 0, 1 );
  camera.lookAt(scene.position); 
  controls = new THREE.OrbitControls( camera );

  var ambientLight= new THREE.AmbientLight( 0x020202 )
  scene.add( ambientLight)

  var frontLight  = new THREE.DirectionalLight('white', 1)
  frontLight.position.set(0.5, 0.5, 0.5)
  frontLight.castShadow = true
  scene.add( frontLight )

  var backLight   = new THREE.DirectionalLight('white', 0.5)
  backLight.position.set(-0.5, -0.5, -0.5)
  scene.add( backLight )

  frontLight.shadowMapSize = new THREE.Vector2( 512, 512 );
  frontLight.shadow.camera = new THREE.OrthographicCamera( -10, 10, 10, -10, 0.5, 500 );

  var pointLight  = new THREE.SpotLight('white', 0.1)
  pointLight.position.set(0,5,5)
  scene.add( pointLight )

  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap

  var ejesAyuda = new THREE.AxesHelper(20); //son los ejes de ayuda creo
  scene.add(ejesAyuda); 

  var planeGeometry = new THREE.PlaneGeometry(60, 20);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});

  var cubeGeometry = new THREE.CubeGeometry( 4, 4, 4);
  var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
  var obstacle = new THREE.Mesh(cubeGeometry, cubeMaterial);
  obstacle.castShadow = true; //con esto le indicamos que queremos que emita sombra
  obstacle.position.x = 0;
  scene.add(obstacle);

  generateRoad(-3);

  document.getElementById("WebGL-salida").append(renderer.domElement);
  resize();
  window.onresize = resize;
};

function generateRoad(z){
    var planeGeometry = new THREE.PlaneGeometry(60, 20);
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});
    var road = new THREE.Mesh(planeGeometry, planeMaterial);
    
    //var road = THREEx.Environment.road()
    road.receiveShadow =  true
    scene.add(road)
    var velocity    = new THREE.Vector3(0, 0, z);
    road.position.add(velocity)
}

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

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

init();
animate();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

<div id="WebGL-salida"></div>

© www.soinside.com 2019 - 2024. All rights reserved.