2017-12-27 827 views
2

我正在學習three.js。Three.js - 爲什麼這些項目的影子看起來像這樣?

我舉一個例子來練習,但項目的陰影看起來不對或陌生。

This is my problem: the shadows

應該是這樣的(這個形象是一個老教程):

Good shadows

和代碼是這樣的:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js"></script> 
 

 
<div id="WebGL-salida"> 
 
</div> 
 

 
<script type="text/javascript"> 
 
    $(function() { 
 
    var scene = new THREE.Scene(); 
 

 
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 
 

 
    var renderer = new THREE.WebGLRenderer(); 
 

 
    var color = new THREE.Color("rgb(200, 250, 250)"); 
 
    renderer.setClearColor(new THREE.Color(color)); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
    renderer.shadowMap.enabled = true; 
 
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap 
 

 

 
    var ejesAyuda = new THREE.AxesHelper(20); //son los ejes de ayuda creo 
 
    scene.add(ejesAyuda); 
 

 
    var planeGeometry = new THREE.PlaneGeometry(60, 20); 
 

 
    var planeMaterial = new THREE.MeshLambertMaterial({ 
 
     color: 0xcccccc 
 
    }); 
 

 
    var plane = new THREE.Mesh(planeGeometry, planeMaterial); 
 

 
    plane.receiveShadow = true; 
 

 

 
    plane.rotation.x = -0.5 * Math.PI; // -90º 
 
    plane.position.x = 15; 
 
    plane.position.y = 0; 
 
    plane.position.z = 0; 
 

 
    scene.add(plane); 
 

 

 
    var cubeGeometry = new THREE.CubeGeometry(4, 4, 4); 
 

 

 
    var cubeMaterial = new THREE.MeshLambertMaterial({ 
 
     color: 0xff0000 
 
    }); 
 
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); 
 

 
    cube.castShadow = true; //con esto le indicamos que queremos que emita sombra 
 

 
    cube.position.x = -4; 
 
    cube.position.y = 3; 
 
    cube.position.z = 0; 
 

 
    scene.add(cube); 
 

 
    var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); 
 
    var sphereMaterial = new THREE.MeshLambertMaterial({ 
 
     color: 0x7777ff 
 
    }); 
 
    var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); 
 

 
    sphere.castShadow = true; //con esto le indicamos que queremos que emita sombra 
 

 
    sphere.position.x = 20; 
 
    sphere.position.y = 4; 
 
    sphere.position.z = 2; 
 
    scene.add(sphere); 
 

 
    camera.position.x = -30; 
 
    camera.position.y = 40; 
 
    camera.position.z = 30; 
 
    camera.lookAt(scene.position); 
 

 
    var spotLight = new THREE.SpotLight(0xffffff, 0.8); 
 
    spotLight.position.set(-40, 60, -10); 
 
    spotLight.castShadow = true; 
 
    scene.add(spotLight); 
 

 
    $("#WebGL-salida").append(renderer.domElement); 
 
    renderer.render(scene, camera); 
 
    }); 
 
</script>

如果你知道一個好的初學者three.js教程或者課程(我不在乎它是不是免費的),那麼請告訴我,因爲我有點迷失在這裏,喜歡web開發者興趣在這個世界上的WebGL :)

回答

3

可以通過增加陰影貼圖的大小,提高了陰影質量(見SpotLight):

var spotLight = new THREE.SpotLight(0xffffff, 0.8); 
spotLight.position.set(-40, 60, -10); 
spotLight.castShadow = true; 

spotLight.shadow.mapSize.width = 2048; 
spotLight.shadow.mapSize.height = 2048; 

質量可以進一步通過限制光錐增加現貨角度:

spotLight.angle = Math.PI/8.0; 

請注意,這cau認爲陰影圖的分辨率增加並且陰影圖被映射到的區域減小。

見代碼片段:

var renderer, camera, scene, controls; 
 

 
var init = function(){ 
 
    scene = new THREE.Scene(); 
 
    camera = new THREE.PerspectiveCamera (45, window.innerWidth/window.innerHeight, 0.1, 1000); 
 
    renderer = new THREE.WebGLRenderer(); 
 
    controls = new THREE.OrbitControls(camera); 
 

 
    var color = new THREE.Color("rgb(200, 250, 250)"); 
 
    renderer.setClearColor(new THREE.Color(color)); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
    renderer.shadowMap.enabled = true; 
 
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap 
 

 

 
    var ejesAyuda = new THREE.AxesHelper(20); //son los ejes de ayuda creo 
 
    scene.add(ejesAyuda); 
 

 
    var planeGeometry = new THREE.PlaneGeometry(60, 20); 
 
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc}); 
 

 
    var plane = new THREE.Mesh(planeGeometry, planeMaterial); 
 
    plane.receiveShadow = true; 
 
    plane.rotation.x = -0.5*Math.PI; // -90º 
 
    plane.position.x = 15; 
 
    plane.position.y = 0; 
 
    plane.position.z = 0; 
 
    scene.add(plane); 
 

 

 
    var cubeGeometry = new THREE.CubeGeometry(4, 4, 4); 
 
    var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); 
 
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); 
 
    cube.castShadow = true; //con esto le indicamos que queremos que emita sombra 
 
    cube.position.x= -4; 
 
    cube.position.y = 3; 
 
    cube.position.z = 0; 
 
    scene.add(cube); 
 

 
    var sphereGeometry = new THREE.SphereGeometry (4, 20, 20); 
 
    var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff}); 
 
    var sphere = new THREE.Mesh (sphereGeometry, sphereMaterial); 
 
    sphere.castShadow = true; //con esto le indicamos que queremos que emita sombra 
 
    sphere.position.x = 20; 
 
    sphere.position.y = 4; 
 
    sphere.position.z = 2; 
 
    scene.add(sphere); 
 

 
    camera.position.x = -30; 
 
    camera.position.y = 40; 
 
    camera.position.z = 30; 
 
    camera.lookAt(scene.position); 
 

 
    var spotLight = new THREE.SpotLight(0xffffff, 0.8); 
 
    spotLight.position.set(-40, 60, -10); 
 
    spotLight.castShadow = true; 
 
    spotLight.angle = Math.PI/8.0; 
 
    spotLight.shadow.mapSize.width = 2048; 
 
    spotLight.shadow.mapSize.height = 2048; 
 
    scene.add(spotLight); 
 

 
    document.getElementById("WebGL-salida").append(renderer.domElement); 
 
    resize(); 
 
    window.onresize = resize; 
 
}; 
 

 
function animate() { 
 
    requestAnimationFrame(animate); 
 
    renderer.render(scene, camera); 
 
} 
 

 
function resize() { 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
    camera.aspect = window.innerWidth/window.innerHeight; 
 
    camera.updateProjectionMatrix(); 
 
//controls.handleResize(); 
 
} 
 

 
init(); 
 
animate();
<script src="https://threejs.org/build/three.min.js"></script> 
 
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script> 
 
<div id="WebGL-salida"> 
 
</div>

+1

偉大的思想同時思考。哈哈 – TheJim01

+0

@ TheJim01噢,我明白了。我會給你一個upvote。 – Rabbid76

+0

'spotLight.shadow.mapSize.width'是訪問'spotLight.shadowMapWidth'的首選方式嗎?在這種情況下,你的答案更準確。 – TheJim01

0

還可以增加段數。現在你有

var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); 

這兩個'20是略低的好渲染。我一般使用32,32

相關問題