我正在使用从 this page 复制的 webgl
。我想用鼠标来控制灯光位置。
如果我只是将静态值从 js
发送到片段着色器
,它将起作用:
mouseLocation = gl.getUniformLocation(program, "mouse");
gl.uniform2f(mouseLocation, 0,0);
我有一个更新鼠标位置的函数:
function updateMousePosition(e){
console.log(e.pageX);
mousex = e.pageX;
mousey = e.pageY;
}
鼠标移动时调用:
canvas.addEventListener( 'mousemove', updateMousePosition, false );
然后每帧将鼠标位置发送到片段着色器
:
gl.uniform2f(mouseLocation, mousex,mousey);
之后我将从片段着色器
获取鼠标位置:
uniform vec2 mouse;
void main(void) {
//mp - mouse position
vec2 mp = vec2(mouse.x / resolution.x, 1.0 - mouse.y / resolution.y);
//lp depend on mp
vec3 lp = vec3(mp.x, mp.y, -1.0);
//other calculation ...
}
它不起作用。
但是当我从 updateMousePosition(e)
中的 console.log
发送静态值时:
gl.uniform2f(mouseLocation, 679, 590);//number taken from console.log
它有效。
我不确定什么不起作用,但我怀疑是数字的格式或类型,js
不是严格类型,但 glsl
是。
我该如何解决这个问题?
最佳答案
最终决定放置这个答案(已编辑)。
正如 Gman 评论的那样,您的代码显然没有任何问题。从技术上讲,这应该可行。然而,您指出了与 OpenGL 相比,WebGL/Javascript 组合的一个真正棘手的方面:字体。由于 Javascript 变量的工作方式,您很容易产生奇怪的错误。
想象一下这种荒谬的情况:
var x = 55;
var y = 128;
// some code here...
x = "blah"; // oups !
// some code here...
gl.uniform2f(mouseLocation, x, y);
对于C、C++或其他强类型语言,这种荒谬的事情几乎是不可能做到的(通过指针这是可能的,但这是另一个主题),因为编译器严格禁止它并抛出错误。但在javascript中,没有问题,在这种情况下,x
数字变量变成了字符串变量,当传递到WebGL时,它变成了NaN
。如果您没有正确跟踪 x
变量,您将搜索很长时间为什么这不起作用。
所有WebGL函数仅在最后阶段接受类型化数据,因为最后阶段是GPU,而GPU是低级的。也就是说,即使您将纯 Javascript Number 变量传递给 WebGL 函数,该 Javascript 变量也会之前转换为类型化数据。但事实是,Javascript 永远不会抛出有关错误变量类型的错误:它将其转换(强制转换)为类型化数据,即使您尝试做的事情是荒谬的,它也永远不会警告您,它会转换不可转换的数据转换为“NaN”。
幸运的是,为了避免任何歧义,WebGL 附带了一堆新的 Javascript 对象:类型化数组:https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/TypedArray
使用类型化数组,您可以在 javascript 代码中知道存储了哪些数据,以及在发送数据之前将哪些数据发送到 GPU。 也就是说,您可以使用类型化数组在将 Javascript 变量发送到 GPU 之前将其转换(转换)为已知的类型化数据。
var mousePos = new Float32Array(2);
function updateMousePosition(e){
mousePos[0] = e.pageX;
mousePos[1] = e.pageY;
}
// do something
console.log(mousePos);
gl.uniform2fv(mouseLocation, mousePos);
在上面的示例中,变量e.pageX
和e.pageY
直接转换为WebGL兼容的类型数据。这样,如果您现在使用 console.log
打印 mousePos
变量,您将看到真正发送到 WebGL 的内容。出于调试目的,您可以将 console.log
放在调用 gl.uniform2fv
之前,以确保“在 View 之外”没有发生任何错误。
在此示例中,如果任何数据被错误转换,您将在输出日志中看到类似 NaN
, NaN
的内容,因此您知道必须在某个地方进行搜索您的代码中有一个错误。
关于javascript - Webgl - 动态鼠标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46616344/