2016-04-19 1 views
0

J'ai un jsfiddle contenant un Soleil et des Lunes fixes et une planète en mouvement qui orbite autour du Soleil.trois.js r75 ombres PointLight au mauvais endroit

Voici le code des deux voyants (ambiant et point) et des exemples d'objets.

 var light2 = new THREE.AmbientLight(0x444444);//... for lighting the Sun and other MeshBasicMaterial meshes. 
     scene.add(light2); 

     //... PointLight 
     // http://threejs.org/docs/#Reference/Lights/PointLight 
     var light3 = new THREE.PointLight(0xffffff, 10, 150000,1); 
     light3.castShadow = true; 
     light3.shadow.camera.near = 1; 
     light3.shadow.camera.far = 5000; 
     light3.shadow.camera.fov = 90; 
     // light3.shadowCameraVisible = true; 
     light3.shadow.bias = 0.001; 
     scene.add(light3);    

     // SPHERES 

     var sphereGeom = new THREE.SphereGeometry(40, 32, 16); 
var SunMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 }); 
     this.Sun01 = new THREE.Mesh(sphereGeom.clone(), SunMaterial); 
     Sun01.position.set(-500, 0, 220);   
     scene.add(Sun01); 
     //Sun01.castShadow = false; 
     //Sun01.receiveShadow = false; 

     light3.position.set(Sun01.position.x, Sun01.position.y , Sun01.position.z); 

var moonMaterial = new THREE.MeshPhongMaterial({ color: 0xaa00aa }); 
     var Moon02 = new THREE.Mesh(sphereGeom.clone(), moonMaterial);     
     Moon02.scale.set(0.5,0.5,0.5); 
     Moon02.position.set(-200, 0, 220); 
     scene.add(Moon02); 
     Moon02.castShadow = true; 
     Moon02.receiveShadow = false; 

Il y a deux problèmes. Tout d'abord, les Lune fixes éloignées ne sont pas éclairées par le PointLight même si elles se trouvent à portée. D'autre part, des ombres provenant des lunes éloignées apparaissent sur la Terre (en orbite autour du Soleil) même si la Terre est plus proche du Soleil que ces lunes fixes.

Notez qu'une lune fixe interne (nommée Moon02, de couleur magenta) est éclairée par le PointLight et projette une ombre sur la Terre.

Voici le code Renderer set-up: -

renderer = new THREE.WebGLRenderer(); 
       renderer.setClearColor(0x000022); 
       renderer.setPixelRatio(window.devicePixelRatio); 
       renderer.setSize(window.innerWidth, window.innerHeight); 

       //... Enable Shadows 
     renderer.shadowMap.enabled = true;//.shadowMapEnabled = true; 
     //renderer.shadowMap.type = THREE.BasicShadowMap;// 
       //renderer.shadowMap.type = THREE.PCFShadowMap 
      renderer.shadowMap.type = THREE.PCFSoftShadowMap; 

Ma question = Ce qui doit être fait pour (a) éclairer les lunes extérieures et (b) assurer que les ombres des lunes extérieures ne semblent pas sur la planète Terre (intérieure, plus proche du Soleil).

Répondre

3

En termes simples, vous espacer les choses trop loin. Calculer des ombres à partir d'un point lumineux est très coûteux.

En fait, THREE.js n'a ajouté que la fonctionnalité a few months ago. Je ne peux pas encore trouver quelque chose de solide dans la documentation, mais il semble probable qu'il y ait une limite codée en dur sur la façon dont les ombres seront calculées à partir d'un point lumineux.

La solution est simple: réduisez l'espace entre vos objets. Il n'y a absolument aucune raison pour que les objets soient éloignés de milliers d'unités quand une douzaine suffira. J'ai résolu vos deux problèmes just by reducing all distances and scales by a factor of 10. J'ai également modifié l'intensité du PointLight parce que 10 était assez dur haha.

// color, intensity, falloff radius, falloff amount 
// if falloff radius is 0 then there is no falloff 
var light3 = new THREE.PointLight(0xffffff, 1, 0, 0); 
+0

« Il n'y a absolument aucune raison pour que les objets doivent être des milliers d'unités l'un de l'autre quand une douzaine suffira », mais mon application n'est pas une œuvre d'art - il est scientifique et l'introduction d'unités de distance artifical est indésirable. "réduire toutes les distances et les échelles par un facteur de 10" est une grosse affaire. Je ne vois pas pourquoi three.js devrait avoir un problème avec de grandes distances. Mais merci pour le travail (espérons-le temporaire) :-). – steveOw

+0

@steveOw Eh bien, les distances sont arbitraires. Même si votre application est scientifique, vous pouvez utiliser toutes les unités que vous voulez dans les coulisses de THREE.js car il est trivial de les convertir. Si cela vous aide à maintenir un modèle mental des distances réelles, alors divisez-les par un bon nombre propre de 1 000 et pensez en termes de millions de mètres au lieu de millions de kilomètres (ou peu importe). – jered

+0

En outre, normalement THREE.js n'a pas de gros problème avec de grandes distances, je pense que c'est seulement le PointLight qui vous donne des problèmes ici. Projeter la lumière et les ombres dans toutes les directions est difficile parce que les «rayons» projetés se déploient comme un carré de la distance, de sorte qu'ils peuvent seulement aller si loin. Une DirectionalLight par comparaison ne s'étale pas, ses rayons sont parallèles pour toujours, ce qui est beaucoup plus facile à calculer. Il pourrait y avoir une sorte de «facteur d'échelle» non documenté que vous pourriez modifier au lieu de tout changer, mais je n'en connais pas un. – jered