我正在尝试使用六架飞机创建一个盒子(墙)。我创造了飞机,但阴影不存在。
这就是我创建自定义平面的方法。
function createWall(vertices) {
var geometry = new THREE.Geometry(), i;
for (i = 0; i < vertices.length; i = i + 1) {
geometry.vertices.push(vertices[i]);
}
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.faces.push(new THREE.Face3(0, 2, 3));
geometry.computeVertexNormals();
geometry.computeFaceNormals();
var material = new THREE.MeshStandardMaterial({
emissive: 0x708090,
emissiveIntensity: 1,
side: THREE.DoubleSide,
color: 0xD3D3D3
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
return mesh;
}
这是完整的代码。
var camera, scene, renderer;
function addFloor() {
var material = new THREE.MeshStandardMaterial({
roughness: 0.8,
color: 0x696969,
metalness: 0.2,
bumpScale: 0.0005
});
var geometry = new THREE.PlaneBufferGeometry(2000, 2000);
var mesh = new THREE.Mesh(geometry, material);
mesh.receiveShadow = true;
mesh.rotation.x = -Math.PI / 2.0;
scene.add(mesh);
}
function createWall(vertices) {
var geometry = new THREE.Geometry(), i;
for (i = 0; i < vertices.length; i = i + 1) {
geometry.vertices.push(vertices[i]);
}
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.faces.push(new THREE.Face3(0, 2, 3));
geometry.computeVertexNormals();
geometry.computeFaceNormals();
var material = new THREE.MeshStandardMaterial({
emissive: 0x708090,
emissiveIntensity: 1,
side: THREE.DoubleSide,
color: 0xD3D3D3
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
return mesh;
}
function addBulb(location) {
var geometry = new THREE.SphereGeometry(2, 20, 20);
var light = new THREE.PointLight(0xffffff, 1, 100, 2);
var material = new THREE.MeshStandardMaterial({
emissive: 0xffffee,
emissiveIntensity: 1,
color: 0x000000
});
light.add(new THREE.Mesh(geometry, material));
light.position.set(location.x, location.y, location.z);
light.shadow.camera.near = 0.0001;
light.castShadow = true;
//light.shadow.darkness = 0.5;
//light.shadow.camera.vsible = true;
return light;
}
function addWalls() {
var wall1 = createWall([
new THREE.Vector3(0, 0, 0), //vertex0
new THREE.Vector3(200, 0, 0), //1
new THREE.Vector3(200, 100, 0), //2
new THREE.Vector3(0, 100, 0) //3
]);
var wall2 = createWall([
new THREE.Vector3(0, 0, 5), //vertex0
new THREE.Vector3(200, 0, 5), //1
new THREE.Vector3(200, 100, 5), //2
new THREE.Vector3(0, 100, 5) //3
]);
scene.add(wall1);
scene.add(wall2);
}
function addCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(50, 100, 300);
scene.add(camera);
}
function init() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMap.renderSingleSided = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1);
document.body.appendChild(renderer.domElement);
addCamera();
addFloor();
addWalls();
scene.add(addBulb({x: 100, y: 50, z: 25}));
var ambientLight = new THREE.AmbientLight(0x999999, 0.6);
scene.add(ambientLight);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
animate();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
创建自定义平面时,我可能做错了什么。我不明白这里有什么问题。
更新:
renderer.shadowMap.renderSingleSided = false;
阴影似乎正在起作用,但灯光有奇怪的方形效果。
在这里,我尝试过BoxGeometry,它的深度很小,如three-js-plane-doesnt-cast-shadow所示, 正如我所指出的,这只发生在深度较小的值上。 (深度&lt; 1)
var camera, scene, renderer;
function addFloor() {
var material = new THREE.MeshStandardMaterial({
roughness: 0.9,
color: 0xffffff,
metalness: 0.1,
bumpScale: 0.0005
});
var geometry = new THREE.PlaneBufferGeometry(2000, 2000);
var mesh = new THREE.Mesh(geometry, material);
mesh.receiveShadow = true;
mesh.rotation.x = -Math.PI / 2.0;
scene.add(mesh);
}
function createWall(location) {
var geometry = new THREE.BoxGeometry(200, 100, 0.1);
geometry.translate((location.x1 + location.x2) / 2, 150 / 2, location.z);
var material = new THREE.MeshStandardMaterial({
emissive: 0x708090,
emissiveIntensity: 1,
side: THREE.DoubleSide,
color: 0xD3D3D3,
roughness: 0.9,
metalness: 0.1
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
return mesh;
}
function addBulb(options) {
var geometry = new THREE.SphereGeometry(2, 20, 20);
var light = new THREE.PointLight(options.color, 1, 500, 2);
var material = new THREE.MeshStandardMaterial({
emissive: options.color,
emissiveIntensity: 1,
color: options.color
});
light.add(new THREE.Mesh(geometry, material));
light.position.set(options.x, options.y, options.z);
light.shadow.camera.near = 0.0001;
light.castShadow = true;
light.shadow.darkness = 0.5;
light.shadow.camera.vsible = true;
return light;
}
function addWalls() {
var wall1 = createWall({ x1: 0, x2: 200, z: 0});
var wall2 = createWall({ x1: 0, x2: 200, z: 5});
scene.add(wall1);
//scene.add(wall2);
}
function addCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(100, 100, 300);
scene.add(camera);
}
function init() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMap.renderSingleSided = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1);
document.body.appendChild(renderer.domElement);
addCamera();
addFloor();
addWalls();
scene.add(addBulb({x: 0, y: 100, z: 25, color: 0xff0000 }));
scene.add(addBulb({x: 100, y: 100, z: 25, color: 0x00ff00 }));
scene.add(addBulb({x: 200, y: 100, z: 25, color: 0x0000ff }));
var ambientLight = new THREE.AmbientLight(0x999999, 0.6);
scene.add(ambientLight);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
animate();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
答案 0 :(得分:1)
您正面临Z fighting。由于墙壁的厚度很小,两面几乎相互接触,因此它们相互投射阴影。
您可以删除墙上阴影的投射/接收,或者更好地增加几何体中的z值,如下所示:
var geometry = new THREE.BoxGeometry(200, 100, 1);
此外,由于您从平面更改为方框,因此不再需要墙材料中的线side: THREE.DoubleSide,
。事实上,它是自我遮蔽问题的一部分。改变这两行应该可以解决你的问题。
这是一个有效的Fiddle。