2017-05-24 31 views
0

我在讀這本書的WebGL新手指南的時候,當它涉及到這是寫經keydown事件改變光線方向的代碼,爲什麼我應該使用getUniform:第一對矯正均勻值

function processKey(ev){ 
    var lightDirection = gl.getUniform(prg, prg.uLightDirection); 
    var incrAzimuth = 10; 
    var incrElevation = 10; 

    switch(ev.keyCode){ 
     case 37: // left arrow 
      azimuth -= incrAzimuth; 
      break; 
     case 38: //up arrow 
      elevation += incrElevation; 
      break; 

     case 39: // right arrow 
      azimuth += incrAzimuth; 
      break; 
     case 40: //down arrow 
      elevation -= incrElevation; 
      break; 
    } 

    azimuth %= 360; 
    elevation %=360; 

    var theta = elevation * Math.PI/180; 
    var phi = azimuth * Math.PI/180; 

    //Spherical to Cartesian coordinate transformation 
    lightDirection[0] = Math.cos(theta)* Math.sin(phi); 
    lightDirection[1] = Math.sin(theta); 
    lightDirection[2] = Math.cos(theta)* -Math.cos(phi); 

    gl.uniform3fv(prg.uLightDirection, lightDirection); 
} 

似乎這var lightDirection = gl.getUniform(prg, prg.uLightDirection);這麼想的任何意義,因爲

lightDirection[0] = Math.cos(theta)* Math.sin(phi); 
lightDirection[1] = Math.sin(theta); 
lightDirection[2] = Math.cos(theta)* -Math.cos(phi);` 

不處理由「lightDirection」任何計算,那麼它只是處理值的着色器。

所以我改線var lightDirection = gl.getUniform(prg, prg.uLightDirection);var lightDirection;,但預期該程序無法不起作用。

+2

初始化'lightDirection'到一個數組? –

+0

@gre_gor是的。 getUniform的返回值,你可以看到[MDN DOC(https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getUniform)。當我在這種情況下使用'var lightDirection = [];'時,我工作的很好。但顯然,這個數組與返回的數組不一樣。 – aMoving60Kg

+0

然後將其初始化爲var varDirection = new Float32Array(3);'。 –

回答

2

你不應該。您應該將值緩存在變量中,或者每次重新計算一次。對於您的特定代碼的第二選擇完美的作品:

function processKey(e) { 
    // ... 
    var lightDirection = [ 
     Math.cos(theta)* Math.sin(phi), 
     Math.sin(theta), 
     Math.cos(theta)* -Math.cos(phi) 
    ]; 
    gl.uniform3fv(prg.uLightDirection, lightDirection); 
} 

,甚至使用「uniform3f」並不會在所有創建磁盤陣列:

function processKey(e) { 
    // ... 
    gl.uniform3f(
     prg.uLightDirection, 
     Math.cos(theta)* Math.sin(phi), 
     Math.sin(theta), 
     Math.cos(theta)* -Math.cos(phi) 
    ); 
} 
+0

THX ^^,'VAR lightDirection = gl.getUniform(PRG,prg.uLightDirection);'初始化值,以正確的數據類型。 – aMoving60Kg

+0

@ aMoving60Kg這是相當做到這一點:)一般來說昂貴的方式,你應該避免函數調用讀WebGL的狀態或做他們早早就和緩存結果。在每個事件處理函數中調用'getUniform'只是爲了初始化一個變量(並且使用你甚至不需要的值)是過度的。 –

+0

明白了〜謝謝〜 – aMoving60Kg