Three.js LegacyGLTFLoader.js 缺少阴影
Three.js LegacyGLTFLoader.js shadows missing
我有一个 GLTF 1.0 版模型,我正在使用 LegacyGLTFLoader.js 将其导入 Three.js。当我这样做时,一切看起来都很好,只是模型没有接收到阴影。我猜这是因为导入模型的material是THREE.RawShaderMaterial,不支持接收阴影(我认为)。我该如何解决这个问题,以便我导入的模型可以接收阴影?
示例代码如下:
// Construct scene.
var scene = new THREE.Scene();
// Get window dimensions.
var width = window.innerWidth;
var height = window.innerHeight;
// Construct camera.
var camera = new THREE.PerspectiveCamera(75, width/height);
camera.position.set(20, 20, 20);
camera.lookAt(scene.position);
// Construct renderer.
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.shadowMapEnabled = true;
document.body.appendChild(renderer.domElement);
// Construct cube.
var cubeGeometry = new THREE.BoxGeometry(10, 1, 10);
var cubeMaterial = new THREE.MeshPhongMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.translateY(15);
scene.add(cube);
// Construct floor.
var floorGeometry = new THREE.BoxGeometry(20, 1, 20);
var floorMaterial = new THREE.MeshPhongMaterial({color: 0x00ffff});
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.receiveShadow = true;
scene.add(floor);
// Construct light.
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 0);
light.castShadow = true;
scene.add(light);
// Construct light helper.
var lightHelper = new THREE.DirectionalLightHelper(light);
scene.add(lightHelper);
// Construct orbit controls.
new THREE.OrbitControls(camera, renderer.domElement);
// Construct GLTF loader.
var loader = new THREE.LegacyGLTFLoader();
// Load GLTF model.
loader.load(
"https://dl.dropboxusercontent.com/s/5piiujui3sdiaj3/1.glb",
function(event) {
var model = event.scene.children[0];
var mesh = model.children[0];
mesh.receiveShadow = true;
scene.add(model);
},
null,
function(event) {
alert("Loading model failed.");
}
);
// Animates the scene.
var animate = function () {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
// Animate the scene.
animate();
这是我的资源:
- https://dl.dropboxusercontent.com/s/y2r8bsrppv0oqp4/three.js
- https://dl.dropboxusercontent.com/s/5wh92lnsxz2ge1e/LegacyGLTFLoader.js
- https://dl.dropboxusercontent.com/s/1jygy1eavetnp0d/OrbitControls.js
- https://dl.dropboxusercontent.com/s/5piiujui3sdiaj3/1.glb
这是一个 JSFiddle:
解决此问题的一种方法是将 RawShaderMaterial
的实例替换为 MeshStandardMaterial
。要获得预期效果,您必须将现有纹理应用到新的 material,如下所示:
var newMaterial = new THREE.MeshStandardMaterial( { roughness: 1, metalness: 0 } );
newMaterial.map = child.material.uniforms.u_tex.value;
您还必须计算各个几何体的法线数据,以便正确计算光照。如果你不需要阴影,unlint MeshBasicMaterial
实际上是更好的选择。
已更新 fiddle:https://jsfiddle.net/e67hbj1q/2/
我有一个 GLTF 1.0 版模型,我正在使用 LegacyGLTFLoader.js 将其导入 Three.js。当我这样做时,一切看起来都很好,只是模型没有接收到阴影。我猜这是因为导入模型的material是THREE.RawShaderMaterial,不支持接收阴影(我认为)。我该如何解决这个问题,以便我导入的模型可以接收阴影?
示例代码如下:
// Construct scene.
var scene = new THREE.Scene();
// Get window dimensions.
var width = window.innerWidth;
var height = window.innerHeight;
// Construct camera.
var camera = new THREE.PerspectiveCamera(75, width/height);
camera.position.set(20, 20, 20);
camera.lookAt(scene.position);
// Construct renderer.
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.shadowMapEnabled = true;
document.body.appendChild(renderer.domElement);
// Construct cube.
var cubeGeometry = new THREE.BoxGeometry(10, 1, 10);
var cubeMaterial = new THREE.MeshPhongMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.translateY(15);
scene.add(cube);
// Construct floor.
var floorGeometry = new THREE.BoxGeometry(20, 1, 20);
var floorMaterial = new THREE.MeshPhongMaterial({color: 0x00ffff});
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.receiveShadow = true;
scene.add(floor);
// Construct light.
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 0);
light.castShadow = true;
scene.add(light);
// Construct light helper.
var lightHelper = new THREE.DirectionalLightHelper(light);
scene.add(lightHelper);
// Construct orbit controls.
new THREE.OrbitControls(camera, renderer.domElement);
// Construct GLTF loader.
var loader = new THREE.LegacyGLTFLoader();
// Load GLTF model.
loader.load(
"https://dl.dropboxusercontent.com/s/5piiujui3sdiaj3/1.glb",
function(event) {
var model = event.scene.children[0];
var mesh = model.children[0];
mesh.receiveShadow = true;
scene.add(model);
},
null,
function(event) {
alert("Loading model failed.");
}
);
// Animates the scene.
var animate = function () {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
// Animate the scene.
animate();
这是我的资源:
- https://dl.dropboxusercontent.com/s/y2r8bsrppv0oqp4/three.js
- https://dl.dropboxusercontent.com/s/5wh92lnsxz2ge1e/LegacyGLTFLoader.js
- https://dl.dropboxusercontent.com/s/1jygy1eavetnp0d/OrbitControls.js
- https://dl.dropboxusercontent.com/s/5piiujui3sdiaj3/1.glb
这是一个 JSFiddle:
解决此问题的一种方法是将 RawShaderMaterial
的实例替换为 MeshStandardMaterial
。要获得预期效果,您必须将现有纹理应用到新的 material,如下所示:
var newMaterial = new THREE.MeshStandardMaterial( { roughness: 1, metalness: 0 } );
newMaterial.map = child.material.uniforms.u_tex.value;
您还必须计算各个几何体的法线数据,以便正确计算光照。如果你不需要阴影,unlint MeshBasicMaterial
实际上是更好的选择。
已更新 fiddle:https://jsfiddle.net/e67hbj1q/2/