2017-12-27 429 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

相关问题