WebGL,Three.js - 灯光,阴影

时间:2018-01-10 17:04:52

标签: three.js shadow light

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

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

1 个答案:

答案 0 :(得分: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之外的每个几何体都被剪裁 在Orthographic Projection中,眼睛空间中的坐标线性映射到标准化设备坐标。

enter image description here

当您使用THREE.OrthographicCamera( 0, 0, 0, 0, 0.5, 500 )时,leftrighttopbottom为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>
&#13;
&#13;
&#13;