planeGeometry not casting shadows

Description of the problem

I have a series of PlaneGeometry that I merge into a larger geometry. They can receive shadow from other objects, such as BoxGeometry, but the PlaneGeometry is not casting shadows, either stitched into the larger merged geometry or added to the scene separately. Is this intended behavior? Thank you!

Code:

EO.map.HandleChunk = function(chunkObj) {

  var chunk = chunkObj.data;
  var structures = chunkObj.structures;

  //the main chunk geo
  var chunkGeometry = new THREE.Geometry();
  //material lists
  var materialListDictionary = [];
  var materialListIndex = [];

  //individual geo reference
  var geometry = new THREE.PlaneGeometry( 64, 64 );
  //blank tile material
  var material = new THREE.MeshPhongMaterial( { color: 0x001111, vertexColors: true, shading: THREE.SmoothShading } );
  //individual tile mesh
  var mesh = new THREE.Mesh( geometry, material );
  //loop through tiles
  for (var i = 0; i < chunk.length; i++) {

    if (typeof EO.tiles.library[chunk[i].tile_id] === 'undefined') {
      // tile does not exist in database, use blank tile material
      mesh.material = material;
    } else {
      // tile exists in database, clone the source from tile library
      mesh.material = EO.tiles.library[chunk[i].tile_id].clone(true);
    }
    //add material to dictionary if does not exist
    var mat_array_index = materialListIndex.indexOf(chunk[i].tile_id);
    if (mat_array_index < 0) {
      materialListIndex.push(chunk[i].tile_id);
      materialListDictionary.push(mesh.material);
      mat_array_index = materialListIndex.length - 1;
    }

    //set tile position
    mesh.position.set( chunk[i].x * 64, chunk[i].y * 64, 0 );
    mesh.updateMatrix();

    //merge to main chunk geometry
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    chunkGeometry.merge(mesh.geometry, mesh.matrix, mat_array_index);

  }

  //new structure loop, create them all as planes...
  // [ Ceiling, North, East, South, West]
  //// [ x, y, rotx, roty, rotz ];
  var pi2 = Math.PI / 2;
  var structureOffsetArray = [
    [0, 0, 0, 0, 0],
    [0, 32, pi2, 0, 0],
    [32, 0, pi2, pi2, 0],
    [0, -32, pi2, 0, 0],
    [-32, 0, pi2, pi2, 0]
  ];
  for (var s = 0; s < structures.length; s++) {

    //grab a structure,
    var structure = structures[s];
    var x = structure.x;
    var y = structure.y;
    var height = structure.height;
    var base = 32;
    var texture_id = structure.texture_id;
    //setup materials
    var material = EO.structures.library[texture_id].clone();
    var material2 = EO.structures.library[texture_id].clone();
    var wallTexture = material2.map.clone();
    mesh.material = material;
    wallTexture.needsUpdate = true;
    wallTexture.repeat.set(1, height);
    material2.map = wallTexture;
    for (var si = 0; si < 5; si++) {

      //mesh.geometry = ;
      //var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 64, base * height ), material );
      //handle material key index
      var materialKey = texture_id;

      if (si > 0) {
        mesh.geometry = new THREE.PlaneGeometry( 64, base * height );
        materialKey = texture_id+'_'+height;
        mesh.material = material2;
      } else {
        //base = 32;
        mesh.geometry =  new THREE.PlaneGeometry( 64, 64 );
      }

      var mat_array_index = materialListIndex.indexOf(materialKey);
      if (mat_array_index < 0) {
        materialListIndex.push(materialKey);
        materialListDictionary.push(mesh.material);
        mat_array_index = materialListIndex.length - 1;
      }

      var offset = structureOffsetArray[si];

      if (si === 0) {
        mesh.position.set( x * 64 + offset[0], y * 64 + offset[1], (base * height) );
      } else {
        mesh.position.set( x * 64 + offset[0], y * 64 + offset[1], (base * height) / 2 );
      }
      mesh.rotation.set( offset[2], offset[3], offset[4] );
      mesh.geometry.computeFaceNormals();
      mesh.updateMatrix();
      mesh.castShadow = true;
      mesh.receiveShadow = true;

      chunkGeometry.merge(mesh.geometry, mesh.matrix, mat_array_index);

    }

  }

  chunkGeometry.sortFacesByMaterialIndex();
  var chunkMesh = new THREE.Mesh(chunkGeometry, new THREE.MeshFaceMaterial( materialListDictionary ) );
  chunkMesh.castShadow = true;
  chunkMesh.receiveShadow = true;
  chunkMesh.name = "Chunk"

  EO.three.scene.add(chunkMesh);

}
Three.js version
  • Dev
  • r78
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS
  • macOS
Hardware Requirements (graphics card, VR Device, …)

Author: Fantashit

2 thoughts on “planeGeometry not casting shadows

  1. Shadows currently need objects to be solid and, ideally, without back side surfaces and front side surfaces in the same position. Try using a BoxGeometry with 0.01 height for now.

  2. @mrdoob

    line 105&106 at /src/renderers/webgl/WebGLShadowMap.js

    this.renderReverseSided = true;
    this.renderSingleSided = true;

    set this.renderReverseSided = false; can solve the problem.

    Is there any special reason for this line?

Comments are closed.