gpt4 book ai didi

macos - OSX 上的 WebGL 在所有浏览器中使用错误的纹理

转载 作者:行者123 更新时间:2023-12-01 06:09:29 25 4
gpt4 key购买 nike

我在某些 OSX 机器上看到一个非常奇怪的问题,我的 WebGL 程序似乎使用错误的纹理内容进行绘图。

我设置了一个 Sprite 批处理,我将一堆 Sprite 四边形缓冲到一个绘制调用中。我还使用多重纹理来进一步减少绘制调用的数量,在同一个绘制调用中为多个纹理绘制 Sprite 。

每个顶点都有以下数据:

 // 16 bytes
float x;
float y;
float u;
float v;

// 16 bytes
float texture_offset_x;
float texture_offset_y;
float texture_scale_width;
float texture_scale_height;

// 24 bytes
float t0;
float t1;
float t2;
float t3;
float t4;
float t5;

// 8 bytes
float width_scale;
float height_scale;

// 4 bytes
unsigned byte r;
unsigned byte g;
unsigned byte b;
unsigned byte a;

// Texture sampler index
float texture_index;


片段着色器组合了这样的绘制调用:

  "#version 100",
"",
"uniform lowp sampler2D sampler0;",
"uniform lowp sampler2D sampler1;",
"uniform lowp sampler2D sampler2;",
"uniform lowp sampler2D sampler3;",
"uniform lowp sampler2D sampler4;",
"uniform lowp sampler2D sampler5;",
"uniform lowp sampler2D sampler6;",
"uniform lowp sampler2D sampler7;",
"",
"varying mediump vec2 vTextureCoord;",
"varying lowp vec4 vTintColor;",
"varying lowp float vTextureIndex;",
"",
"void main(void) {",
" lowp vec4 fragColors[8];",
" fragColors[0] = texture2D(sampler0, vTextureCoord);",
" fragColors[1] = texture2D(sampler1, vTextureCoord);",
" fragColors[2] = texture2D(sampler2, vTextureCoord);",
" fragColors[3] = texture2D(sampler3, vTextureCoord);",
" fragColors[4] = texture2D(sampler4, vTextureCoord);",
" fragColors[5] = texture2D(sampler5, vTextureCoord);",
" fragColors[6] = texture2D(sampler6, vTextureCoord);",
" fragColors[7] = texture2D(sampler7, vTextureCoord);",
"",
" lowp float fragIncluded[8];",
"",
" fragIncluded[0] = float(vTextureIndex <= 0.5);",
" fragIncluded[1] = float(vTextureIndex >= 0.5 && vTextureIndex < 1.5);",
" fragIncluded[2] = float(vTextureIndex >= 1.5 && vTextureIndex < 2.5);",
" fragIncluded[3] = float(vTextureIndex >= 2.5 && vTextureIndex < 3.5);",
" fragIncluded[4] = float(vTextureIndex >= 3.5 && vTextureIndex < 4.5);",
" fragIncluded[5] = float(vTextureIndex >= 4.5 && vTextureIndex < 5.5);",
" fragIncluded[6] = float(vTextureIndex >= 5.5 && vTextureIndex < 6.5);",
" fragIncluded[7] = float(vTextureIndex >= 6.5 && vTextureIndex < 7.5);",
"",
" lowp vec4 fragColor = fragColors[0] * fragIncluded[0] + ",
" fragColors[1] * fragIncluded[1] + ",
" fragColors[2] * fragIncluded[2] + ",
" fragColors[3] * fragIncluded[3] + ",
" fragColors[4] * fragIncluded[4] + ",
" fragColors[5] * fragIncluded[5] + ",
" fragColors[6] * fragIncluded[6] + ",
" fragColors[7] * fragIncluded[7];",
"",
" gl_FragColor = fragColor * vTintColor;",
"}"


在大多数情况下一切正常。但是在某些 OSX 机器上,被采样的纹理有时会出现错误。具体来说,这似乎最常发生在基于 NVidia 的 MacBook 上,但我也能够在 Intel HD 5000 上重现它。这发生在所有 Chrome、Safari 和 Firefox 上,所以我很确定它与 WebGL 无关实现本身。这可能是 OSX 中的驱动程序错误吗?

我的场景由一堆 UI 组成。大多数 UI 元素是从一个 UI Sprite 表中绘制的,而文本是从位图字体 Sprite 表中绘制的。该错误通常表现为使用 UI Sprite 表纹理绘制文本。我已经通过着色器修改和使用 WebGL Inspector 验证了我在绘制调用时将正确的纹理绑定(bind)到正确的采样器。

我确实注意到这似乎是通过在一个绘制调用中将纹理 A 绑定(bind)到 sampler1 和纹理 B 绑定(bind)到 sampler2 来触发的,并且下一个绘制调用将它们反转,纹理 A 绑定(bind)到 sampler2,纹理 B 绑定(bind)到 sampler1。

此问题目前可以在此 URL 上实时复制: https://tinytappers.bigvikinggames.com/

通过打开两个底部菜单之一最容易看到它,并且在它打开时点击屏幕顶部的敌人。通常无论是点击本身,还是敌人死亡动画都足以让下方菜单中的文本在纹理之间快速切换。同样,这仅在少数特定的 OSX 机器上。

其他人可以重现这个吗?有谁知道发生了什么?我很确定我传递给 WebGL 的数据是正确的。任何人都可以发现数据有任何问题吗?

最佳答案

我想我可以解决这个问题。

我的代码试图变得聪明,并跟踪哪个纹理绑定(bind)到哪个纹理单元,然后只在需要更改时重新绑定(bind)它们。如果我总是在每次绘制调用之前将纹理显式绑定(bind)到相应的纹理单元,问题就会消失。

在我做这个解决方法之前,在某些情况下,我什至能够使 WebGL(在所有 3 个浏览器中)崩溃。在这种情况下,崩溃发生在 Apple Intel 5000 驱动程序中(在 NVidia 机器上没有崩溃)。

我仍然相信这是某种驱动程序错误。我认为在 Apple 的 OpenGL 实现深处的绘制调用之间,纹理绑定(bind)以某种方式被破坏了。除非假设绑定(bind)的纹理将保持绑定(bind)是不安全的?

无论如何,我的解决方法现在有效,所以我会继续这样做。

关于macos - OSX 上的 WebGL 在所有浏览器中使用错误的纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34277156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com