【问题标题】:Are 1D Textures Supported in WebGL yet?WebGL 是否支持一维纹理?
【发布时间】:2014-06-25 17:34:18
【问题描述】:

我一直在努力寻找一个明确的答案,但似乎没有人明确提出这个问题。

我可以在 WebGL Chrome、Firefox、Safari、IE 等中使用一维采样器和一维纹理吗?

编辑

可以理解,1 确实是 2 的幂 (2^0=1),这意味着您可以有效地使用 2D 采样器和使用高度为 1 和宽度为 256 或 512 等的纹理来复制一维纹理。

1D 纹理没有实际意义,它们之所以存在,是因为它们不仅有目的,而且旨在转化为 GPU 本身的优化(与 2D 纹理相反)。请记住,每个参数都需要时间加载到调用堆栈上,几乎所有 GPU 编程都是优化每一个可能的操作的艺术。

计算着色器经常需要一个没有额外维度的浮点列表,使用 1D 纹理和采样器提供与强类型相同的清晰度。即以一维结构表示一维数据,并以二维结构表示二维数据。它还删除了索引到行/列转换所需的额外操作。

问题不是他们是否有充分的理由,而是他们是否得到支持。

WebGL 1.0 中基于 OpenGL ES 2.009/MAY/2014

  • 目前没有一维纹理或采样器支持。

【问题讨论】:

  • 我会将“yet”更改为“WebGL 1.0”或类似的东西。 WebGL 2 肯定会拥有它们。
  • @BartekBanachewicz:他们为什么要添加一维纹理?它们是一个完全多余的功能。它们不允许你做任何你不能用 2D 纹理做的事情。正如下面的答案所暗示的,您创建了一个高度为 1 的 2D 纹理,并具有 1D 纹理。事实上,如果 API 是从头开始创建的,那么只有 3D 纹理就足够了。 2D 和 1D 纹理只是 3D 纹理的简化情况。
  • @RetoKoradi:没有ARB_texture_non_power_of_two extension mipmapping 和 GL_CLAMP_TO_EDGE 以外的包裹模式仅支持二次幂纹理,因此一维纹理有合法的用例。
  • @JensNolte:好点。我认为下一个主要的 WebGL 版本将基于 ES 3.0?这解除了 ES 2.0 中对 NPOT 纹理的限制。
  • @RetoKoradi:不完全是。缓冲区纹理实际上是精美的 1D 纹理,可让您远远超过 GL_MAX_TEXTURE_SIZE^2(2D 限制)的存储空间。但是您不能将它们与一维坐标以外的任何东西一起使用。

标签: glsl webgl shader fragment-shader glsles


【解决方案1】:

为什么需要一维纹理?只需制作 N 像素宽和 1 像素高的 2D 纹理。

var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);

// 3x1 pixel 1d texture
var oneDTextureTexels = new Uint8Array([
    255,0,0,255, 
    0,255,0,255,
    0,0,255,255,
]);

var width = 3;
var height = 1;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
              oneDTextureTexels);

生成mips或设置过滤,因此不需要mips

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_W, gl.CLAMP_TO_EDGE);

使用0.5y 进行采样

uniform sampler2D u_texture;
varying float v_texcoord;

void main() {
  vec4 color = texture2D(u_texture, vec2(v_texcoord, 0.5));
  ...

Here's a sample using 1D textures。它使用典型光照计算的点积从一维渐变纹理中查找一个值来为对象着色。

直接回答您的问题。 WebGL 中不会有 1D 纹理,因为 WebGL 基于 OpenGL ES 2.0 而 OpenGL ES 2.0 不支持 1D 纹理。 OpenGL ES 3.0 和 3.1 都没有。如果他们在合并 OpenGL 和 OpenGL ES 时没有完全删除 1D 纹理,我会感到惊讶

【讨论】:

  • 你好。这是对这种伪一维纹理的完全合法使用吗?如果将内容渲染到缓冲区,将 nx1 渲染目标设为有意义吗?
  • 我不确定你在问什么。如果您需要一个 nx1 渲染目标,请创建一个 nx1 渲染目标。如果您需要,nx1 渲染目标没有任何问题。
  • 我意识到我们被限制在一定的宽度,所以我猜最多 4096 或 8192 个值?我想我对真正的一维纹理的作用感到困惑,我试图弄清楚什么时候会使用它。我尝试使用 mods 和 fracts 来跟踪具有线性索引的 2d 纹理(噪声或某种模式)以跟踪行和列。 nx1 易于访问,但可以容纳的数据少得多?
  • 我不确定您要做什么。答案中链接了一个一维纹理的示例。 Here's another。但是你可以在 1d 中做的任何事情你也可以在 2d 中做。只需在处理 2d 纹理时更改您的数学。
  • 说我想上传一堆随机数作为种子在一些粒子系统或一些类似的。制作 nx1 纹理对此有限制,“真实”的 1d 纹理是否也这样做?
【解决方案2】:

WebGL 1.0 基于不支持一维纹理的 OpenGL ES 2.0。 WebGL 规范中的Texture Objects 部分通过仅具有texImage2DcompressedTexImage2D 方法来反映这一点。

您可以改用高度为 1 的纹理。

【讨论】:

    【解决方案3】:

    正如 Jens Nolte 所说,它在 WebGL 中不受支持,因为它基于 OpenGL ES。您可以使用具有单位宽度或高度的 2D 纹理。 例如(256 宽和 1 高):

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, ColorMap.optimalIB);
    

    然后在采样器中,您可以使用任何高度值对纹理进行采样(因为它无关紧要)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多