2017-12-27 8 views
2

Ich lerne über three.js.Three.js - Warum sieht der Schatten dieser Gegenstände so aus?

Ich mache ein Beispiel zu üben, aber der Schatten der Elemente sieht falsch oder fremd aus.

This is my problem: the shadows

Sollte so sein (das Bild eines alten Tutorial):

Good shadows

Und der Code ist dies:

<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>

Und bitte, wenn Sie über ein gutes Anfänger three.js Tutorial oder Kurs wissen (es ist mir egal, wenn es nicht kostenlos ist), sagen Sie mir, weil ich bin ein bisschen verloren in diesem und wie Web-Entwickler ich bin Interesse an dieser WebGL Welt :)

Antwort

3

Sie die Qualität des Schattens durch die Erhöhung der Größe der Schattenkarte (Siehe SpotLight) verbessern können:

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; 

die Qualität weiter den Lichtkegel erhöht werden kann durch die Beschränkung Winkel der Stelle:

spotLight.angle = Math.PI/8.0; 

Hinweis, diese cau Dadurch wird die Auflösung der Shadow Map erhöht und der Bereich, in den die Shadow Map abgebildet wird, verkleinert.

Siehe Code-Schnipsel:

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

Große Köpfe denken gleichermaßen zur gleichen Zeit. haha – TheJim01

+0

@ TheJim01 Oh, ich verstehe. Ich werde dir einen positiven Kommentar geben. – Rabbid76

+0

Ist 'spotLight.shadow.mapSize.width' die bevorzugte Methode für den Zugriff auf' spotLight.shadowMapWidth'? In diesem Fall ist Ihre Antwort richtiger. – TheJim01

0

Sie können auch die Anzahl der Segmente erhöhen. Jetzt haben Sie

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

Diese zwei '20 sind etwas niedrig für gutes Rendering. Ich benutze im Allgemeinen 32, 32

Verwandte Themen