我正在实施与buffer geometry instancing dynamic example类似的内容。
基本上这个想法是让一个bufferGeometry重复并且有一个属性数组,其中包含我的对象的偏移量(就像他们在上面的例子中一样)。
如果我尝试添加阴影,我只会在1个对象上获得阴影,我认为这是因为我们只有1个几何体。
有没有办法为我的所有物体添加阴影?
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);
}
示例JsFiddle