2016-04-19 2 views
0

У меня есть jsfiddle, содержащий фиксированное Солнце и Луны и движущуюся планету Земля, которая вращается вокруг Солнца.three.js r75 pointLight тени в неправильных местах

Вот код для двух огней (Окружающая и точка) и примеры объектов.

 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; 

Есть две проблемы.

Первоначально удаленные фиксированные луны не освещаются PointLight, хотя они находятся в радиусе действия.

Во-вторых, тени на дальних лунах появляются на (Солнце-орбитальной) Земле, хотя Земля ближе к Солнцу, чем те неподвижные луны.

Обратите внимание, что внутренняя фиксированная луна (названная Moon02, пурпурный цвет) освещена PointLight, и она бросает тень на Землю.

Вот код Renderer настройки: -

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; 

Мой вопрос = Что нужно сделать, чтобы (а) осветить внешние спутники и (б) обеспечить тени внешних лун не появляются на (внутренней, ближе к Солнцу) планете Земля.

ответ

3

Проще говоря, вы слишком далеко перемещаете вещи.

Расчет теней от точечного света очень дорог. Фактически, THREE.js добавила только функциональность для него a few months ago. Я еще не могу найти что-либо твердое в документации, но кажется вероятным, что существует жестко закодированное ограничение на то, как далеко будут вычисляться тени из точечного света.

Решение легко: уменьшите пространство между объектами. Нет абсолютно никакой причины, что объекты должны быть в тысячах единиц друг от друга, когда будет достаточно дюжины. Я решил обе свои проблемы. just by reducing all distances and scales by a factor of 10. Я также изменил интенсивность PointLight, потому что 10 был довольно суровым ха-ха.

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

«Там нет абсолютно никаких оснований, что объекты должны быть тысячи единиц друг от друга, когда десяток будет достаточно», но мое приложение не является произведение искусства - это научная и введения искусственних единиц расстояния нежелательно. «сокращение всех расстояний и масштабов в 10 раз» - большое дело. Я не понимаю, почему у three.js должна быть проблема с большими расстояниями. Но спасибо за (надеюсь, временную) работу :-). – steveOw

+0

@steveOw Ну, расстояния произвольны. Даже если ваше приложение является научным, вы можете использовать любые единицы, которые вы хотите за кулисами в THREE.js, потому что тривиально конвертировать между ними. Если это поможет вам сохранить ментальную модель фактических расстояний, тогда разделите ее на чистое число, например 1000, и подумайте о миллионах метров вместо миллионов километров (или что-то еще). – jered

+0

Также, как правило, у THREE.js нет большой проблемы с большими расстояниями, я думаю, что это только PointLight, дающий вам проблемы здесь. Проецирование света и теней во всех направлениях жесткое, потому что проецируемые «лучи» распространяются как квадрат расстояния, поэтому они могут идти только до сих пор. Направленный свет по сравнению не распространяется, его лучи параллельны навсегда, что намного проще вычислить. Может быть какой-то недокументированный «масштабный фактор», который вы могли бы настроить, а не изменять все остальное, но я не знаю об этом. – jered

Смежные вопросы