为什么我应该在修改统一值时首先使用getUniform

时间:2017-05-24 13:10:27

标签: javascript webgl

我正在阅读“WebGL初学者指南”一书,当涉及通过keydown事件改变光线方向的代码时:

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;,但该程序无法按预期工作。

1 个答案:

答案 0 :(得分: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)
    );
}