修改uniform值时为什么要先get Uniform

why should i use getUniform first when modifing uniform values

我正在阅读 WebGL 初学者指南这本书,当涉及到为通过按下事件改变光线方向而编写的代码时:

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; 但程序无法按预期运行。

你不应该。您应该将值缓存在变量中或每次都重新计算它。对于您的特定代码,第二个选项非常有效:

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)
    );
}