1
votes

I have a problem with focus of lights to targets (need focus it on main character and make background darker). The second problem is, that shadows doedn't work. Below is a part of code with deal with lights and shadows. Any ideas?

index.html file

//////////////////////////////////////////////////////////////////////////////////
//      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
Your shadow camera has size 0, 0, 0, 0, and on recent versions of three.js shadowCamera should be shadow.camera. See docs here.Don McCurdy
I see. Yes, I have older version of Three.js with shadowCamera, but I will try fix size. Thank you.Jakub Kubista
@DonMcCurdy I tried to chane size of camera, but I didn't work.Jakub Kubista
@Rabbid76 it is the same thing which I used.Jakub Kubista
Thank you guys, but any other ideas?Jakub Kubista

1 Answers

1
votes

In general your code works. The only issue is the shadow camera, which has a range of 0.0 in the x and y direction. Change it to somthing like that:

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

Note, https://threejs.org/docs/#api/cameras/OrthographicCamera defines a view matrix and an orthographic projection matrix.

The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. The projection matrix transforms from view space to the clip space. The coordinates in the clip space are transformed to the normalized device coordinates (NDC) in the range (-1, -1, -1) to (1, 1, 1) by dividing with the w component of the clip coordinates. Every geometry which is out of the NDC is clipped.
At Orthographic Projection the coordinates in the eye space are linearly mapped to normalized device coordinates.

enter image description here

When you use THREE.OrthographicCamera( 0, 0, 0, 0, 0.5, 500 ), then left, right, top and bottom are 0. This means you try to map the area between 0.0 and 0.0 to then NDC.


See the code snippet:

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>