3D 模型不在 ThreeJS 中投射阴影
3D model not casting shadows in ThreeJS
我正在将 glTF 模型导入到 ThreeJS and have a PlaneGeometry 作为基础。我需要模型将阴影投射到 plane/ground.
我试过启用
renderer.shadowMap.enabled = true;
在
const renderer = new THREE.WebGLRenderer({ alpha: true });
我还有2个灯:
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 10, 0);
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(0, 0, 10);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 200;
dirLight.shadow.camera.bottom = -200;
dirLight.shadow.camera.left = - 200;
dirLight.shadow.camera.right = 200;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 500;
scene.add( dirLight );
最终代码
body
{
margin: 0px;
padding: 0px;
}
div#container canvas
{
cursor: grab;
}
div#container canvas:active
{
cursor: grabbing;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Import 3D Model into Three JS</title>
<script type="module" defer>
import * as THREE from 'https://cdn.skypack.dev/three@0.129.0/build/three.module.js';
import { GLTFLoader } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/GLTFLoader.js'; // for .glb and .gltf.glb
// import { OBJLoader } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/OBJLoader.js'; // for .obj
import { OrbitControls } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/controls/OrbitControls.js';
const container = document.querySelector('div#container');
const path_to_model = './ImportModel/Mini-Game Variety Pack/Models/gltf/tree_forest.gltf.glb';
const loader = new GLTFLoader();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 500);
// Add lights
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 10, 0);
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(0, 0, 10);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 200;
dirLight.shadow.camera.bottom = -200;
dirLight.shadow.camera.left = - 200;
dirLight.shadow.camera.right = 200;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 500;
scene.add( dirLight );
// Make renderer
const renderer = new THREE.WebGLRenderer({
alpha: true
});
// Make transparent
renderer.setClearColor(0xffffff, 0);
// Set it to window size
renderer.setSize(window.innerWidth, window.innerHeight);
// Force shadows
renderer.shadowMap.enabled = true;
// Helper (optional)
// const camera_helper = new THREE.CameraHelper(dirLight.shadow.camera);
// scene.add(camera_helper);
// Double quality
const quality = 2;
renderer.setSize(window.innerWidth * quality, window.innerHeight * quality, false);
// Add mouse movement
const controls = new OrbitControls(camera, renderer.domElement);
// Add floor (plane)
const plane_geometry = new THREE.PlaneGeometry(10, 10);
const plane_material = new THREE.MeshPhongMaterial({
color: 0xffff00,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(
plane_geometry,
plane_material
);
plane.rotation.x = 1.5708;
plane.castShadow = true;
plane.receiveShadow = true;
scene.add(plane);
console.log(plane);
// Import glTF
loader.load(path_to_model, function (gltf)
{
//gltf.scene.position.y = -5;
//gltf.scene.center();
//gltf.scene.scale.set(0.1, 0.1, 0.1);
// Make it cast shadows
gltf.scene.castShadow = true;
gltf.scene.traverse(function(node)
{
if (node.isMesh)
{
node.castShadow = true;
//node.receiveShadow = true;
}
});
console.log(gltf);
console.log('Adding glTF model to scene...');
scene.add(gltf.scene);
console.log('Model added.');
console.log('Moving camera 5z...');
camera.position.z = 5;
console.log('Camera moved.');
}, undefined, function (error)
{
console.error(error);
});
container.appendChild(renderer.domElement);
function animate()
{
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
</script>
</head>
<body>
<div id="container">
</div>
</body>
</html>
更新: 按照 的建议将平面中的 MeshBasicMaterial
更改为 MeshPhongMaterial
。
半球光似乎是罪魁祸首。如果你改变它的位置,你可以开始获得阴影。很可能它到处都在投射光线,从而淹没了任何可能出现的阴影。把它从飞机上移开有帮助。 dirLight.shadow.camera.top/bottom/left/right
也太高了。我用了2,vice 200,同时换了半光,好像还行。
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Import 3D Model into Three JS</title>
</head>
<body>
<div id="container">
</div>
</body>
</html>
CSS
body
{
margin: 0px;
padding: 0px;
}
div#container canvas
{
cursor: grab;
}
div#container canvas:active
{
cursor: grabbing;
}
JS
import * as THREE from "https://cdn.skypack.dev/three@0.129.0/build/three.module.js";
import { GLTFLoader } from "https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/GLTFLoader.js"; // for .glb and .gltf.glb
// import { OBJLoader } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/OBJLoader.js'; // for .obj
import { OrbitControls } from "https://cdn.skypack.dev/three@0.129.0/examples/jsm/controls/OrbitControls.js";
const container = document.querySelector("div#container");
const path_to_model =
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy_lightweight.glb";
const loader = new GLTFLoader();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
500
);
// Add lights
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(20, 20, 10);
scene.add(hemiLight);
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(-10, 20, 6);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 2;
dirLight.shadow.camera.bottom = -2;
dirLight.shadow.camera.left = -2;
dirLight.shadow.camera.right = 2;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 500;
scene.add(dirLight);
// Make renderer
const renderer = new THREE.WebGLRenderer({
alpha: true
});
// Make transparent
renderer.setClearColor(0xffffff, 0);
// Set it to window size
renderer.setSize(window.innerWidth, window.innerHeight);
// Force shadows
renderer.shadowMap.enabled = true;
// Helper (optional)
// const camera_helper = new THREE.CameraHelper(dirLight.shadow.camera);
// scene.add(camera_helper);
// Double quality
const quality = 2;
renderer.setSize(
window.innerWidth * quality,
window.innerHeight * quality,
false
);
// Add mouse movement
const controls = new OrbitControls(camera, renderer.domElement);
// Add floor (plane)
const plane_geometry = new THREE.PlaneGeometry(10, 10);
const plane_material = new THREE.MeshPhongMaterial({
color: 0xffff00,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(plane_geometry, plane_material);
plane.rotation.x = 1.5708;
plane.castShadow = true;
plane.receiveShadow = true;
scene.add(plane);
console.log(plane);
//scene.add(box)
// Import glTF
loader.load(
path_to_model,
function (gltf) {
//gltf.scene.position.y = -5;
//gltf.scene.center();
//gltf.scene.scale.set(0.1, 0.1, 0.1);
// Make it cast shadows
gltf.scene.castShadow = true;
gltf.scene.traverse(function (node) {
if (node.isMesh) {
node.castShadow = true;
//node.receiveShadow = true;
}
});
console.log(gltf);
console.log("Adding glTF model to scene...");
scene.add(gltf.scene);
console.log("Model added.");
console.log("Moving camera 5z...");
camera.position.z = 5;
console.log("Camera moved.");
},
undefined,
function (error) {
console.error(error);
}
);
container.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
我正在将 glTF 模型导入到 ThreeJS and have a PlaneGeometry 作为基础。我需要模型将阴影投射到 plane/ground.
我试过启用
renderer.shadowMap.enabled = true;
在
const renderer = new THREE.WebGLRenderer({ alpha: true });
我还有2个灯:
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 10, 0);
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(0, 0, 10);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 200;
dirLight.shadow.camera.bottom = -200;
dirLight.shadow.camera.left = - 200;
dirLight.shadow.camera.right = 200;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 500;
scene.add( dirLight );
最终代码
body
{
margin: 0px;
padding: 0px;
}
div#container canvas
{
cursor: grab;
}
div#container canvas:active
{
cursor: grabbing;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Import 3D Model into Three JS</title>
<script type="module" defer>
import * as THREE from 'https://cdn.skypack.dev/three@0.129.0/build/three.module.js';
import { GLTFLoader } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/GLTFLoader.js'; // for .glb and .gltf.glb
// import { OBJLoader } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/OBJLoader.js'; // for .obj
import { OrbitControls } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/controls/OrbitControls.js';
const container = document.querySelector('div#container');
const path_to_model = './ImportModel/Mini-Game Variety Pack/Models/gltf/tree_forest.gltf.glb';
const loader = new GLTFLoader();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 500);
// Add lights
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 10, 0);
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(0, 0, 10);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 200;
dirLight.shadow.camera.bottom = -200;
dirLight.shadow.camera.left = - 200;
dirLight.shadow.camera.right = 200;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 500;
scene.add( dirLight );
// Make renderer
const renderer = new THREE.WebGLRenderer({
alpha: true
});
// Make transparent
renderer.setClearColor(0xffffff, 0);
// Set it to window size
renderer.setSize(window.innerWidth, window.innerHeight);
// Force shadows
renderer.shadowMap.enabled = true;
// Helper (optional)
// const camera_helper = new THREE.CameraHelper(dirLight.shadow.camera);
// scene.add(camera_helper);
// Double quality
const quality = 2;
renderer.setSize(window.innerWidth * quality, window.innerHeight * quality, false);
// Add mouse movement
const controls = new OrbitControls(camera, renderer.domElement);
// Add floor (plane)
const plane_geometry = new THREE.PlaneGeometry(10, 10);
const plane_material = new THREE.MeshPhongMaterial({
color: 0xffff00,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(
plane_geometry,
plane_material
);
plane.rotation.x = 1.5708;
plane.castShadow = true;
plane.receiveShadow = true;
scene.add(plane);
console.log(plane);
// Import glTF
loader.load(path_to_model, function (gltf)
{
//gltf.scene.position.y = -5;
//gltf.scene.center();
//gltf.scene.scale.set(0.1, 0.1, 0.1);
// Make it cast shadows
gltf.scene.castShadow = true;
gltf.scene.traverse(function(node)
{
if (node.isMesh)
{
node.castShadow = true;
//node.receiveShadow = true;
}
});
console.log(gltf);
console.log('Adding glTF model to scene...');
scene.add(gltf.scene);
console.log('Model added.');
console.log('Moving camera 5z...');
camera.position.z = 5;
console.log('Camera moved.');
}, undefined, function (error)
{
console.error(error);
});
container.appendChild(renderer.domElement);
function animate()
{
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
</script>
</head>
<body>
<div id="container">
</div>
</body>
</html>
更新: 按照 MeshBasicMaterial
更改为 MeshPhongMaterial
。
半球光似乎是罪魁祸首。如果你改变它的位置,你可以开始获得阴影。很可能它到处都在投射光线,从而淹没了任何可能出现的阴影。把它从飞机上移开有帮助。 dirLight.shadow.camera.top/bottom/left/right
也太高了。我用了2,vice 200,同时换了半光,好像还行。
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Import 3D Model into Three JS</title>
</head>
<body>
<div id="container">
</div>
</body>
</html>
CSS
body
{
margin: 0px;
padding: 0px;
}
div#container canvas
{
cursor: grab;
}
div#container canvas:active
{
cursor: grabbing;
}
JS
import * as THREE from "https://cdn.skypack.dev/three@0.129.0/build/three.module.js";
import { GLTFLoader } from "https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/GLTFLoader.js"; // for .glb and .gltf.glb
// import { OBJLoader } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/loaders/OBJLoader.js'; // for .obj
import { OrbitControls } from "https://cdn.skypack.dev/three@0.129.0/examples/jsm/controls/OrbitControls.js";
const container = document.querySelector("div#container");
const path_to_model =
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy_lightweight.glb";
const loader = new GLTFLoader();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
500
);
// Add lights
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(20, 20, 10);
scene.add(hemiLight);
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(-10, 20, 6);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 2;
dirLight.shadow.camera.bottom = -2;
dirLight.shadow.camera.left = -2;
dirLight.shadow.camera.right = 2;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 500;
scene.add(dirLight);
// Make renderer
const renderer = new THREE.WebGLRenderer({
alpha: true
});
// Make transparent
renderer.setClearColor(0xffffff, 0);
// Set it to window size
renderer.setSize(window.innerWidth, window.innerHeight);
// Force shadows
renderer.shadowMap.enabled = true;
// Helper (optional)
// const camera_helper = new THREE.CameraHelper(dirLight.shadow.camera);
// scene.add(camera_helper);
// Double quality
const quality = 2;
renderer.setSize(
window.innerWidth * quality,
window.innerHeight * quality,
false
);
// Add mouse movement
const controls = new OrbitControls(camera, renderer.domElement);
// Add floor (plane)
const plane_geometry = new THREE.PlaneGeometry(10, 10);
const plane_material = new THREE.MeshPhongMaterial({
color: 0xffff00,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(plane_geometry, plane_material);
plane.rotation.x = 1.5708;
plane.castShadow = true;
plane.receiveShadow = true;
scene.add(plane);
console.log(plane);
//scene.add(box)
// Import glTF
loader.load(
path_to_model,
function (gltf) {
//gltf.scene.position.y = -5;
//gltf.scene.center();
//gltf.scene.scale.set(0.1, 0.1, 0.1);
// Make it cast shadows
gltf.scene.castShadow = true;
gltf.scene.traverse(function (node) {
if (node.isMesh) {
node.castShadow = true;
//node.receiveShadow = true;
}
});
console.log(gltf);
console.log("Adding glTF model to scene...");
scene.add(gltf.scene);
console.log("Model added.");
console.log("Moving camera 5z...");
camera.position.z = 5;
console.log("Camera moved.");
},
undefined,
function (error) {
console.error(error);
}
);
container.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();