WebGL现在支持1D纹理吗?

17

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

我能在WebGL Chrome、Firefox、Safari、IE等浏览器中使用1D采样器和1D纹理吗?

编辑

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

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

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

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

在基于OpenGL ES 2.0的WebGL 1.0中,截至2014年5月9日

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

我会把“yet”改成“WebGL 1.0”或类似的内容。WebGL 2肯定会有它们。 - Bartek Banachewicz
1
@BartekBanachewicz:为什么他们要添加1D纹理?它们是完全冗余的功能。它们不允许您执行任何使用2D纹理无法完成的操作。如下面的答案所建议的那样,您可以创建一个高度为1的2D纹理,并拥有一个1D纹理。实际上,如果API是从头开始创建的,只有3D纹理就足够了。 2D和1D纹理只是3D纹理的简化情况。 - Reto Koradi
2
@RetoKoradi:没有ARB_texture_non_power_of_two扩展,对于2的幂次方纹理外推和包裹模式以外的其他纹理功能,仅支持非2的幂次方纹理,因此存在合法的一维纹理用例。 - Jens Nolte
@WebGL 2不会包含它们,因为它们不是OpenGL ES 3.0或3.1的一部分,而WebGL 2将基于这些版本。 - gman
@gman,我已经准备好打开我硬盘上的3.1规范,并谦虚地承认我错了。 - Bartek Banachewicz
显示剩余5条评论
3个回答

11

为什么需要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,要么设置过滤器以使不需要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));
  ...

这个链接展示了使用一维纹理的样例,它使用典型光照计算的点积来查找一维斜坡纹理的值,以渲染物体的阴影。

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


嗨,gman。这是完全合法使用伪一维纹理的吗?如果将东西渲染到缓冲区,制作一个 nx1 的渲染目标有意义吗? - pailhead
我不确定你在问什么。如果你需要一个 nx1 渲染目标,就创建一个 nx1 渲染目标。如果这正是你所需要的,那么 nx1 渲染目标并没有任何问题。 - gman
我想使用纹理来存储大量的模拟数据,成千上万个节点。我的经验来自WebGL,所以我从未遇到过1D纹理。一个1024x1024的目标可以容纳一百万个节点,但我需要进行一些逻辑才能访问它。一个1D纹理很容易访问,但似乎功能非常有限。我猜我在问1D纹理的目的是什么,但现在我看到这些颜色变换和渐变等可以用相对较少的值和线性插值来完成。 - pailhead
1
假设我想上传一堆随机数字,用作某些粒子系统或类似系统中的种子。制作nx1纹理会对此造成限制,那么“真正的”1D纹理是否也会有同样的限制呢? - pailhead
“真实”的1D纹理与2D纹理具有相同的尺寸限制。在2D中上传您的随机纹理,使您的随机函数在2D中选择。我不明白问题所在。在SO上提出一个真正的问题,这样你就可以得到一个真正的答案,而不仅仅是一些微小的评论。 - gman
显示剩余2条评论

7

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

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


0

正如Jens Nolte所说,由于WebGL基于OpenGL ES,因此不支持。您可以使用宽度或高度为1的2D纹理。

例如(宽度256,高度1):
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0,
             GL_RGBA, GL_UNSIGNED_BYTE, ColorMap.optimalIB);

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接