相交对象 - 阴影问题 - Three.js

发布于 2025-01-17 19:31:29 字数 3707 浏览 5 评论 0原文

当我具有相交对象时,阴影中的对象相交的阴影有一条怪异的光线。我尝试了不同类型的灯光,材料,浏览器(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文