1

I'm implementing something similar to the buffer geometry instancing dynamic example.

Basically the idea is having one bufferGeometry duplicated and having an attribute array with the offsets of my objects (like they have in the above example).

If I try to add shadows, I only get shadows on 1 object, which I assume is because we only have 1 geometry.

Is there a way of adding shadows to all my objects?

var scene, camera, renderer, controls;
var offsets;

init();
animate();

function init() {

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.set(0, 250, 1000);

    renderer = new THREE.WebGLRenderer();
    renderer.shadowMap.enabled = true
    renderer.shadowMap.type = THREE.PCFSoftShadowMap
    renderer.gammaInput = true
    renderer.gammaOutput = true
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    controls = new THREE.OrbitControls(camera, renderer.domElement);

    // Lights
    var ambient = new THREE.AmbientLight(0xcccccc);
    scene.add(ambient);

    var spot = new THREE.SpotLight(0x999999, 1, 0, Math.PI / 2, 1);
    spot.position.set(700, 700, 700)
    spot.target.position.set(0, 0, 0);
    spot.castShadow = true
    spot.angle = Math.PI / 4
    spot.penumbra = 0.05
    spot.decay = 2
    spot.distance = 10000
    spot.shadow.mapSize.width = 1024
    spot.shadow.mapSize.height = 1024
    spot.shadow.camera.near = 1
    spot.shadow.camera.far = 10000
    scene.add(spot);

    var spotHelper = new THREE.SpotLightHelper(spot)
    scene.add(spotHelper);

    // Floor
    var geometry = new THREE.PlaneGeometry(3000, 3000, 10, 10);
    var material = new THREE.MeshPhongMaterial({
        color: new THREE.Color(0x777777),
        shininess: 5
    });

    var ground = new THREE.Mesh(geometry, material);
    ground.rotation.x = -1.57;
    ground.receiveShadow = true;
    scene.add(ground);

    // instanced geometry
    var instances = 10;
    var geometry = new THREE.InstancedBufferGeometry();
    var icosahedron = new THREE.BufferGeometry().fromGeometry(new THREE.IcosahedronGeometry(200, 3));

    geometry.addAttribute('position', icosahedron.attributes.position);
    geometry.addAttribute('normal', icosahedron.attributes.normal);
    geometry.addAttribute('uv', icosahedron.attributes.uv);
    geometry.setIndex(icosahedron.index);

    offsets = new THREE.InstancedBufferAttribute(new Float32Array(instances * 3), 3, 1);

    var vector = new THREE.Vector3();
    for (var i = 0; i < offsets.count; i++) {
        var x = Math.random() * 1000 - 500;
        var y = Math.random() * 1000 - 500;
        var z = Math.random() * 1000 - 500;
        vector.set(x, y, z).normalize();
        offsets.setXYZ(i, x + vector.x * 5, y + vector.y * 5, z + vector.z * 5);
    }
    geometry.addAttribute('offset', offsets);
    var material = new THREE.ShaderMaterial({
        uniforms: {},
        vertexShader: document.getElementById('vertexShader').textContent,
        fragmentShader: document.getElementById('fragmentShader').textContent,
        side: THREE.DoubleSide,
    });

    var mesh = new THREE.Mesh(geometry, material);
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    scene.add(mesh);
}

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

Example JsFiddle

andrevenancio
  • 494
  • 4
  • 19

0 Answers0