2013-10-09 55 views
1

我在寫一個交互式程序,用戶可以在其中更改顯示的材質,光線和對象。我寫了所有HTML表格和JavaScript事件來處理用戶交互的部分,我認爲這很好,所以我只在這裏發佈相關部分,我將添加一個鏈接到整個文件。光線運動不起作用

在這裏,我創建場景,對象,光和呈現功能:

var scene= new THREE.Scene(); 
var camera= new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000); 
var renderer= new THREE.WebGLRenderer(); 
renderer.setSize(window.innerWidth,window.innerHeight); 
document.body.appendChild(renderer.domElement); 
camera.position.z=5; 


var geometry= new THREE.SphereGeometry(1,15,15); 
var material= new THREE.MeshLambertMaterial({color:0xffffff, ambient:0xffffff, emissive:0xffffff}); 
var object= new THREE.Mesh(geometry,material); 
material.name= "lambert"; 
object.name= "sphere"; 
scene.add(object); 

var light= new THREE.PointLight(0xffffff); 
light.position.set(0,0,20); 
light.name= "point"; 
scene.add(light); 


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

然後每個用戶,通過按鈕,改變一個參數的時間,我使用這些函數來改變材料光特性:

function changeLightParameters() { 
    var lightParameters= getLightParameters(); 
    if(lightParameters== null) { 
     alert("Invalid values"); 
     return; 
    } 
    if(light.name!= lightParameters.type) { 
     scene.remove(light); 
     if(lightParameters.type== "spot") { 
      light= new THREE.SpotLight(lightParameters.color); 
     } 
     else if(lightParameters.type== "point") { 
      light= new THREE.PointLight(lightParameters.color); 
     } 
     else if(lightParameters.type== "ambient") { 
      light= new THREE.AmbientLight(lightParameters.color); 
     } 
     else if(lightParameters.type== "area") { 
      light= new THREE.AreaLight(lightParameters.color); 
     } 
     else if(lightParameters.type== "directional") { 
      light= new THREE.DirectionalLight(lightParameters.color); 
     } 
     light.position.set(lightParameters.position.x, lightParameters.position.y, lightParameters.position.z); 
     light.name= lightParameters.name; 
     scene.add(light); 
    } 
    else { 
     light.position= lightParameters.position; 
     light.color= new THREE.Color(lightParameters.color); 
    } 
} 


function changeMaterialParameters() { 
    var materialParameters= getMaterialParameters(); 
    if(materialParameters== null) { 
     alert("Invalid values"); 
     return; 
    } 
    if(materialParameters.type!= material.name) { 
     scene.remove(object); 
     if(materialParameters.type== "lambert") { 
      material= new THREE.MeshLambertMaterial({ 
     color:materialParameters.diffuse, 
       ambient:materialParameters.ambient, 
       emissive:materialParameters.emissive }); 
     } 
     else if(materialParameters.type== "normal") { 
      material= new THREE.MeshNormalMaterial(); 
     } 
     else if(materialParameters.type== "phong") { 
      material= new THREE.MeshPhongMaterial({ 
       color:materialParameters.diffuse, 
       ambient:materialParameters.ambient, 
       emissive:materialParameters.emissive, 
       specular:materialParameters.specular, 
       shininess:materialParameters.shininess }); 
     } 
     material.name= materialParameters.type; 
     object= new THREE.Mesh(geometry,material); 
     scene.add(object); 
    } 
    else { 
     material.color= new THREE.Color(materialParameters.diffuse); 
     material.ambient= new THREE.Color(materialParameters.ambient); 
     material.emissive= new THREE.Color(materialParameters.emissive); 
     material.specular= new THREE.Color(materialParameters.specular); 
     material.shininess= new THREE.Color(materialParameters.shininess); 
     material.needsUpdate= true; 
    } 
} 

在這些功能中我使用getMaterialParameters()getLightParameters()得到包含一些文本字段來處理值的兩個表,將所有的參數。我已經測試過這些函數,它們都可以工作,所以沒必要看代碼。這些函數返回一個對象,具有這樣的結構:

Light : color (number) 
     position (THREE.Vector3) 
     type (string, possibile values "ambient", "point", "spot", "point", "directional") 

Material: diffuse (number) 
      ambient (number) 
      emissive (number) 
      specular (number) 
      shininess (number) 
      type (string, possible values "phong", "normal", "lambert") 

一旦拿到的材料特性,如果材料類型發生了變化,我創建了一個新材料從頭開始,如果而不只是它的屬性被更改更新它。燈光相同。

問題是,對象似乎對燈光變化沒有反應:如果我改變燈光位置/顏色,什麼都不會發生。我也可以將光線的z設置爲-1000,即沒有任何變化。 Phong模型對我來說看起來並不正確,但是物體並不像它應該發光一樣。例如:

enter image description here

的參數是:蓬材料,反光100,漫射光0x00abb1,發射光0x006063,鏡面光0xa9fcff,反光光在位置(20,20,200)100白點的光。如果我將光移動到(0,0,0),那麼球看起來是一樣的。這看起來應該不現實,我認爲我做錯了什麼。

請告訴我,如果我需要添加更多的細節,完整的代碼是在這裏:http://pastebin.com/3uwgwvfE

更新

我發現,問題在於這樣的事實,我不能夠添加場景已經初始化時的新燈。我做了一個新的程序,這是一個如何重現問題的例子:我開始使用射燈,然後當用戶點擊畫布時,我從場景中移除光線,並添加一個新光線(方向)。但它不起作用:沒有照明,我只看到環境組件。代碼在這裏:http://pastebin.com/BVU0dPi3

+2

參見維基文章[如何更新WebGLRenderer事情(https://github.com/mrdoob/three.js/wiki/Updates)。同時刪除所有'needsUpdate'標誌並將它們僅添加回需要的地方。避免'material.color = new THREE.Color()';改爲使用'material.color.copy(color)'。 「閃亮」不是「THREE.Color」。 – WestLangley

+0

它說:「這些變化需要建立新的着色器程序,你需要將material.needsUpdate標誌設置爲true」。所以當我將燈光設置爲material.needsUpdate爲true時,我需要做什麼?它不起作用(仍然是同樣的問題)。 –

+0

如果您只是移動燈光,則不需要設置'material.needsUpdate = true'。設置'material.emissive = 0x000000'。設置'material.specular = 0x050505'。將'material.ambient'設置爲與'material.color'相同的值。 – WestLangley

回答

0

問題是,當我改變燈的類型時,我不得不更新材料;當我移動燈光時,這也是無效的。因此,通過加入這一行工作的程序:

// Change type of light and add it to the scene 
material.needsUpdate= true;