javascript - Webgl - 动态鼠标位置

标签 javascript webgl glsles

我正在使用从 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.pageXe.pageY直接转换为WebGL兼容的类型数据。这样,如果您现在使用 console.log 打印 mousePos 变量,您将看到真正发送到 WebGL 的内容。出于调试目的,您可以将 console.log 放在调用 gl.uniform2fv 之前,以确保“在 View 之外”没有发生任何错误。

在此示例中,如果任何数据被错误转换,您将在输出日志中看到类似 NaN, NaN 的内容,因此您知道必须在某个地方进行搜索您的代码中有一个错误。

关于javascript - Webgl - 动态鼠标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46616344/

相关文章:

javascript - 匹配所有字符直到下一次匹配的正则表达式

JavaScript 'for' 循环

javascript - webgl 阴影映射 gl.DEPTH_COMPONENT

javascript - 使用 Javascript 将字符串转换为对象(错误 : Unexpected token t in JSON at position 1)

javascript - 将航路点信息传递给 comgooglemaps(Google map URL 方案)

javascript - 在网络 worker 中解码图像

opengl-es - WebGL 是如何工作的?

algorithm - 在 WebGL 中使用 for 循环进行二进制搜索

ios - 前两个片段着色器输出不同

rotation - 在 GLSL ES 中的片段着色器上旋转纹理