相交对象 - 阴影问题 - Three.js
当我具有相交对象时,阴影中的对象相交的阴影有一条怪异的光线。我尝试了不同类型的灯光,材料,浏览器(MACOS)和渲染设置。它发生在一个或多个灯光下。
我发现调整阴影偏置(Spotlight.shadow.bias = 0.0005),并且使用相对较大的影子图有助于减少线条,但并没有完全摆脱它们。我猜这是问题与暗图的渲染方式有关。
有人对造成这种情况以及如何解决它有任何想法吗?
示例图像在相交对象上显示光线 - 演示代码:
import * as THREE from 'three';
import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
let scene, camera, renderer, controls;
let cube_mesh;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 0.1,1000);
camera.position.set(0,1.5,-10);
renderer = new THREE.WebGLRenderer({ antialias:true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
//renderer.shadowMap.type = THREE.PCFShadowMap;
renderer.setAnimationLoop( animation );
renderer.toneMapping = THREE.LinearToneMapping;
renderer.physicallyCorrectLights = true;
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize);
controls = new OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 1, 0);
// Spotlight
const spotLight = new THREE.SpotLight( 0xffffff, 11 );
spotLight.position.set( 2, 4, -2 );
spotLight.castShadow = true;
// spotLight.shadow.bias = 0.0005;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.angle = 0.6;
spotLight.penumbra = 1;
// spotLight.decay = 1;
// const spotLightHelper = new THREE.SpotLightHelper( spotLight );
// scene.add( spotLightHelper );
scene.add( spotLight );
// Materials
const material_1 = new THREE.MeshPhongMaterial({color: 0xffffff,});
const material_2 = new THREE.MeshPhongMaterial({color: 0xbbbbbb,});
// Ground Plane
const ground_geometry = new THREE.PlaneGeometry(20, 20);
const ground_mesh = new THREE.Mesh(ground_geometry, material_2);
ground_mesh.receiveShadow = true;
ground_mesh.rotateX(-Math.PI / 2);
scene.add(ground_mesh);
// Cube
const cube_geometry = new THREE.BoxGeometry(1, 1, 1);
cube_mesh = new THREE.Mesh(cube_geometry, material_1);
cube_mesh.castShadow = true;
cube_mesh.position.y = 2;
scene.add(cube_mesh);
// Sphere
const sphere_geometry = new THREE.SphereGeometry( .75, 128,128 );
const sphere = new THREE.Mesh( sphere_geometry, material_1 );
sphere.castShadow = true;
sphere.receiveShadow = true;
sphere.position.set(0,.75,0);
scene.add( sphere );
const sphere_2_geometry = new THREE.SphereGeometry( 1, 128, 128 );
const sphere_2 = new THREE.Mesh( sphere_2_geometry, material_1 );
sphere_2.castShadow = true;
sphere_2.receiveShadow = true;
sphere_2.position.set(-1,1.5,1);
scene.add( sphere_2 );
}
function animation(time) {
cube_mesh.rotation.x += 0.01;
cube_mesh.rotation.y += 0.01;
controls.update();
renderer.render(scene, camera);
}
// Resize Window
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
When I have intersecting objects there is a weird line of light in the shadow where the objects intersect. I’ve tried different types of lights, materials, browsers (MacOS), and render settings. It occurs with one or more lights.
I found that adjusting the shadow bias (spotLight.shadow.bias = 0.0005) and using a relatively large shadowmap helped reduce the lines but did not get rid of them entirely. I'm guessing that this is issue relates to how the shadowmap is rendered.
Does anyone have any ideas for what is causing this, and how to solve it?
Example image showing lines of light in shadow on intersecting objects - Demo code: https://codepen.io/henryegloff/pen/eYyRJpx
import * as THREE from 'three';
import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
let scene, camera, renderer, controls;
let cube_mesh;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 0.1,1000);
camera.position.set(0,1.5,-10);
renderer = new THREE.WebGLRenderer({ antialias:true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
//renderer.shadowMap.type = THREE.PCFShadowMap;
renderer.setAnimationLoop( animation );
renderer.toneMapping = THREE.LinearToneMapping;
renderer.physicallyCorrectLights = true;
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize);
controls = new OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 1, 0);
// Spotlight
const spotLight = new THREE.SpotLight( 0xffffff, 11 );
spotLight.position.set( 2, 4, -2 );
spotLight.castShadow = true;
// spotLight.shadow.bias = 0.0005;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.angle = 0.6;
spotLight.penumbra = 1;
// spotLight.decay = 1;
// const spotLightHelper = new THREE.SpotLightHelper( spotLight );
// scene.add( spotLightHelper );
scene.add( spotLight );
// Materials
const material_1 = new THREE.MeshPhongMaterial({color: 0xffffff,});
const material_2 = new THREE.MeshPhongMaterial({color: 0xbbbbbb,});
// Ground Plane
const ground_geometry = new THREE.PlaneGeometry(20, 20);
const ground_mesh = new THREE.Mesh(ground_geometry, material_2);
ground_mesh.receiveShadow = true;
ground_mesh.rotateX(-Math.PI / 2);
scene.add(ground_mesh);
// Cube
const cube_geometry = new THREE.BoxGeometry(1, 1, 1);
cube_mesh = new THREE.Mesh(cube_geometry, material_1);
cube_mesh.castShadow = true;
cube_mesh.position.y = 2;
scene.add(cube_mesh);
// Sphere
const sphere_geometry = new THREE.SphereGeometry( .75, 128,128 );
const sphere = new THREE.Mesh( sphere_geometry, material_1 );
sphere.castShadow = true;
sphere.receiveShadow = true;
sphere.position.set(0,.75,0);
scene.add( sphere );
const sphere_2_geometry = new THREE.SphereGeometry( 1, 128, 128 );
const sphere_2 = new THREE.Mesh( sphere_2_geometry, material_1 );
sphere_2.castShadow = true;
sphere_2.receiveShadow = true;
sphere_2.position.set(-1,1.5,1);
scene.add( sphere_2 );
}
function animation(time) {
cube_mesh.rotation.x += 0.01;
cube_mesh.rotation.y += 0.01;
controls.update();
renderer.render(scene, camera);
}
// Resize Window
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论