Hallo, when I assign more than one material on single mesh (in Blender), shadows doesn’t show. Why? I use gltfLoader. in attached image are two towers. First (which cast shadow) is with one material, other (which dont cast shadow) is with two materials.
How to solve this? Thanks!
Could you share your code, and ideally a demo?
I cant send you demo, because I am loading local models, but code is here:
<html>
<html>
<head>
<script src="js/three.js/build/three.min.js"></script>
<script src="js/three.js/examples/js/controls/OrbitControls.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/three.js/examples/js/loaders/GLTFLoader.js"></script>
<script type="text/javascript">
var camera,scene,directionalLight;
$(function() {
const gltfLoader = new THREE.GLTFLoader();
//scene
scene = new THREE.Scene();
//camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set(-5,-23,8);
camera.lookAt(new THREE.Vector3( 0, 0, 0 ));
//renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
//controls
//var controls = new THREE.OrbitControls( camera, renderer.domElement );
//show canvas
$("#canvas-container").html(renderer.domElement);
//lights
//directional light
directionalLight = new THREE.DirectionalLight(0xffffff,3);
directionalLight.position.set(5, -1, 5);
directionalLight.castShadow = true;
directionalLight.shadowCameraVisible = true;
directionalLight.shadowCameraNear = 0;
directionalLight.shadowCameraFar = 15;
scene.add(directionalLight);
//spotlight
var p1,p2,p3;
p1={};
p2={};
//plane
var geometry = new THREE.PlaneGeometry(2000, 1000);
var material = new THREE.MeshPhongMaterial( { color: 0xcccccc } );
var plane = new THREE.Mesh( geometry, material );
plane.receiveShadow = true;
scene.add(plane);
gltfLoader.load('objects/m.glb',
function(gltf) {
const root = gltf.scene;
p1.model = root.getObjectByName("Cube");
//p1.model.scale.set(scale,scale,scale);
scene.add(p1.model);
p1.model.castShadow = true;
//p1.model.position.x=3;
p1.model.receiveShadow = true;
p1.model.rotation.x=1.55;
});
gltfLoader.load('objects/n.glb',
function(gltf) {
const root = gltf.scene;
p2.model = root.getObjectByName("Cube");
//p1.model.scale.set(scale,scale,scale);
scene.add(p2.model);
p2.model.castShadow = true;
p2.model.position.y=7;
p2.model.receiveShadow = true;
p2.model.rotation.x=1.55;
});
//render scene
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
});
</script>
</head>
<body style="background: black">
<div id="canvas-container" style="position: absolute; left:0px; top:0px"></div>
</body>
</html>
Your multi-material model is represented as multiple objects when loaded. If you check p1.model.children
I think you’ll find that it has meshes inside of it. If you open the JS console while looking at http://gltf-viewer.donmccurdy.com/ and open your model, you’ll see the full list of objects.
Additionally, large meshes may have to be split into multiple meshes when exported from Blender. Instead of expecting only a single mesh, traverse:
p1.model.position.set( ... );
p1.model.traverse(function(o) {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
scene.add(p1.model);
4 Likes
You are right, my model consist of more than one mesh. Solved, Thanks a lot!