问题 WebGL中是否支持一维纹理?


我一直试图找到一个明确的答案,但似乎没有人明确提出这个问题。

我可以在WebGL Chrome,Firefox,Safari,IE等中使用1D采样器和1D纹理吗?

编辑

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

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

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

问题不在于他们是否有充分理由,而是支持他们。

WebGL 1.0 基于 OpenGL ES 2.0 作为 09 / MAY / 2014 

  • 目前没有1D纹理或采样器支持。

3222
2018-05-08 11:00


起源

我将“尚未”改为“WebGL 1.0”或类似的东西。 WebGL 2肯定会拥有它们。 - Bartek Banachewicz
@BartekBanachewicz:他们为什么要添加1D纹理?它们是完全冗余的功能。它们不允许您对2D纹理执行任何操作。如下面的答案所示,您创建一个高度为1的2D纹理,并具有一维纹理。事实上,如果API是从头开始创建的,那么只有3D纹理就足够了。 2D和1D纹理只是减少了3D纹理的情况。 - Reto Koradi
@RetoKoradi:没有 ARB_texture_non_power_of_two扩展名 除了GL_CLAMP_TO_EDGE之外的mipmapping和wrap模式仅支持2次幂纹理,因此对于1D纹理有合法的用例。 - Jens Nolte
@JensNolte:好点。我认为下一个主要的WebGL版本将基于ES 3.0?这解除了对ES 2.0中的NPOT纹理的限制。 - Reto Koradi
@RetoKoradi:不完全。缓冲纹理实际上是花哨的1D纹理,可以让你远远超过存储空间 GL_MAX_TEXTURE_SIZE^ 2(2D限制)。但除了1D坐标之外,你不能使用它们。 - Andon M. Coleman


答案:


你为什么需要1D纹理?只需制作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

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.5 对于 y

uniform sampler2D u_texture;
varying float v_texcoord;

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

这是使用1D纹理的示例。它使用典型照明计算的点积来从1d渐变纹理中查找值以遮蔽对象。

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


8
2018-05-08 18:05



嗨gman。这是伪1d纹理的完全合法使用吗?如果将内容渲染到缓冲区,是否有必要使nx1渲染目标? - pailhead
我不确定你在问什么。如果需要nx1渲染目标,请创建nx1渲染目标。如果这是您需要的,那么nx1渲染目标没有任何问题。 - gman
我意识到我们被限制在一定的宽度,所以我想最多4096或8192的值?我想我真的混淆了真正的1d纹理,我想知道什么时候会使用它。我尝试使用mods和fracts使用线性索引来处理2d纹理(噪声或某些模式)以跟踪行和列。 nx1易于访问,但可以容纳更少的数据? - pailhead
我不确定你要做什么。在答案中链接了一个1d纹理的例子。 这是另一个。但是你可以在1d做任何事情,你也可以在2d做。只需在解决2d纹理时更改数学运算。 - gman
假设我想使用纹理来存储一堆模拟内容,数万个节点。我的经验来自webgl,所以我从来没有遇到过1d纹理。一个1024x1024的目标可以容纳一百万个节点,但我需要做一些逻辑来访问它。 1d纹理很容易访问,但似乎非常有限。我想我问的是1d纹理的目的是什么,但我现在看到这些颜色变化和渐变和东西可以用相对较少的值和线性插值来完成。 - pailhead


WebGL 1.0基于OpenGL ES 2.0,不支持1D纹理。该 纹理对象 WebGL规范中的部分仅反映了这一点 texImage2D 和 compressedTexImage2D 方法。

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


5
2018-05-08 12:23





正如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);

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


0
2018-05-08 13:20