Javascript 在修改统一值时,为什么要首先使用getUniform
我正在阅读《WebGL初学者指南》一书,其中涉及通过按键事件更改灯光方向的代码:Javascript 在修改统一值时,为什么要首先使用getUniform,javascript,webgl,Javascript,Webgl,我正在阅读《WebGL初学者指南》一书,其中涉及通过按键事件更改灯光方向的代码: function processKey(ev){ var lightDirection = gl.getUniform(prg, prg.uLightDirection); var incrAzimuth = 10; var incrElevation = 10; switch(ev.keyCode){ case 37: // left arrow
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光照方向代码>但程序无法按预期工作。您不应该这样做。您应该将值缓存在变量中,或者每次都重新计算它。对于您的特定代码,第二个选项非常有效:
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)
);
}
你不应该。您应该将值缓存在变量中,或者每次都重新计算它。对于您的特定代码,第二个选项非常有效:
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)
);
}
将lightDirection
初始化为数组?@gre\u gor是。您可以看到的getUniform的返回值。当我使用var lightDirection=[]时,我工作得很好代码>在这种情况下。但是很明显,这个数组与返回的数组不同,然后将其初始化为var lightDirection=new Float32Array(3)编码>。初始化lightDirection
到数组?@gre\u gor是。您可以看到的getUniform的返回值。当我使用var lightDirection=[]时,我工作得很好代码>在这种情况下。但是很明显,这个数组与返回的数组不同,然后将其初始化为var lightDirection=new Float32Array(3)
.thx^.^,var lightDirection=gl.getUniform(prg,prg.uLightDirection)代码>将值初始化为正确的数据类型。@aMoving60Kg这是一种非常昂贵的方法:)一般来说,您应该避免调用读取WebGL状态的函数,或者尽早执行这些函数并缓存结果。在每个事件处理程序中调用getUniform
,只是为了初始化一个变量(并且使用您甚至不需要的值)是多余的。@如果是60公斤,请将此答案标记为已接受,以便让其他人知道问题已得到充分回答。thx^,var lightDirection=gl.getUniform(prg,prg.uLightDirection)代码>将值初始化为正确的数据类型。@aMoving60Kg这是一种非常昂贵的方法:)一般来说,您应该避免调用读取WebGL状态的函数,或者尽早执行这些函数并缓存结果。在每个事件处理程序中调用getUniform
,只是初始化一个变量(并且使用您甚至不需要的值)是过分的。@在60公斤的范围内,请将此答案标记为已接受,以便让其他人知道问题已得到充分的回答。