Both castShadow and receiveShadow in the GLB file, the 3D object have weird shadows

I check true Both castShadow and receiveShadow in the GLB file, the 3D object have weird shadows.
here’s screenshot

this screenshot is check only castShadow in glb models

below screenshot is check both castShadow and receiveShadow
스크린샷 2022-06-29 오후 5.06.25

My env

MacOS, Chrome, Three.js r141

here’s my code
“index.html”

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script type="importmap">
			{
				"imports":
				{
					"three":"./three.js-r141/build/three.module.js"
				}
			}
		</script>
		<script src="Three_Practice.js" type="module" defer></script>
	</body>
</html>

“Three_Practice.js”

import * as THREE from 'three';
import {GLTFLoader} from './three.js-r141/examples/jsm/loaders/GLTFLoader.js';
import {FBXLoader} from './three.js-r141/examples/jsm/loaders/FBXLoader.js';
import {OrbitControls} from './three.js-r141/examples/jsm/controls/OrbitControls.js';


const scene = new THREE.Scene();
scene.background = new THREE.Color(0x215a93);
scene.fog = new THREE.Fog(0x215a93, 10, 5000);
const camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 3000 );
camera.position.set(-500,300,-100);

//Renderer Setting
const renderer = new THREE.WebGLRenderer({
	antialias: true,
});
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

window.addEventListener('resize', function()
{
	console.log('resize window');
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

	renderer.setSize(window.innerWidth, window.innerHeight);
});


InitLight(scene);
InitPlane(scene);

//OrbitControl Add
let controls = new OrbitControls(camera, renderer.domElement);

//GLTFLoader
{
	const gltfLoader = new GLTFLoader();
	gltfLoader.load('./models/tumblur.glb', function(glb)
	{
		glb.scene.traverse(function(object)
		{
			if(object.isMesh) {
				console.log('Object is mesh');
				object.castShadow = true;
			}
			else
			{
				console.log('Object is not mesh');
			}
		});

		scene.add(glb.scene);
	});


	gltfLoader.load('./models/자동차.glb', function(glb)
	{
		glb.scene.traverse(function(object)
		{
			if(object.isMesh) {
				console.log('Object is mesh');
				object.castShadow = true;
				object.receiveShadow = true;
			}
			else
			{
				console.log('Object is not mesh');
			}
			object.position.set(0, 5 , 0);
			
		});

		zoomFit(glb.scene, camera);
		scene.add(glb.scene);
	});
}



animate();

//Function Collection
function animate() {
	requestAnimationFrame( animate );

	renderer.render( scene, camera );
};

function InitLight(scene)
{
	const dirLight = new THREE.DirectionalLight(0xffffff, 2);
	dirLight.position.set(100, 350, 100);
	console.log('InitLight');
	dirLight.lookAt(0,0,0);
	dirLight.castShadow = true;
	dirLight.shadow.camera.top = 400;
	dirLight.shadow.camera.bottom = - 400;
	dirLight.shadow.camera.left = - 400;
	dirLight.shadow.camera.right = 400;
	dirLight.shadow.camera.near = 0.1;
	dirLight.shadow.camera.far = 1000;
	dirLight.shadow.mapSize.width = 1024;
	dirLight.shadow.mapSize.height = 1024;
	scene.add(new THREE.CameraHelper(dirLight.shadow.camera));
	scene.add(dirLight);

	const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
	hemiLight.position.set( 0, 20, 0 );
	scene.add( hemiLight );
}

function InitPlane(scene)
{
	let planeMaterial = new THREE.MeshStandardMaterial({color:0x888888, side: THREE.DoubleSide});
	let planeGeometry = new THREE.PlaneBufferGeometry(1000,1000, 8, 8);
	let plane = new THREE.Mesh(planeGeometry, planeMaterial);
	plane.receiveShadow = true;
	plane.rotateX( - Math.PI / 2);
	scene.add(plane);
}

function zoomFit(object3D, camera)
{
        // 모델의 경계 박스
        const box = new THREE.Box3().setFromObject(object3D);

        // 모델의 경계 박스 대각 길이
        const sizeBox = box.getSize(new THREE.Vector3()).length();

        // 모델의 경계 박스 중심 위치
        const centerBox = box.getCenter(new THREE.Vector3());

        // 모델 크기의 절반값
        const halfSizeModel = sizeBox * 0.5;
        
        // 카메라의 fov의 절반값
        const halfFov = THREE.MathUtils.degToRad(camera.fov * .5);

        // 모델을 화면에 꽉 채우기 위한 적당한 거리
        const distance = halfSizeModel / Math.tan(halfFov);

        // 모델 중심에서 카메라 위치로 향하는 방향 단위 벡터 계산
        const direction = (new THREE.Vector3()).subVectors(
        camera.position, centerBox).normalize();

        // "단위 방향 벡터" 방향으로 모델 종심 위치에서 distance 거리에 대한 위치
        const position = direction.multiplyScalar(distance).add(centerBox);
            camera.position.copy(position);

        // 모델의 크기에 맞춰 카메라의 near, far 값을 대략적으로 조정
        camera.near = sizeBox / 100;
        camera.far = sizeBox * 100;

        // 카메라 기본 속성 변경에 따른 투영행렬 업데이트
        camera.updateProjectionMatrix();

        // 카메라가 모델의 중심을 바라 보도록 함
        camera.lookAt(centerBox.x, centerBox.y, centerBox.z);
}

Have any ideas?

dirLight.shadow.bias=-0.004;

2 Likes

Awesome! Thanks!!! I’ll check about shadow bias

1 Like