15
votes

I've been trying to find a clear answer, but it seems no one has clearly asked the question.

Can I use a 1D sampler and 1D texture in WebGL Chrome, Firefox, Safari, IE, etc?

EDIT

Understandably 1 is indeed a power of 2 (2^0=1) meaning you could effectively use a 2D sampler and texture using a height of 1 and a width of 256 or 512 etc. to replicate a 1D texture.

1D textures are not moot, they exist because they not only have a purpose, but are intended to translate into optimizations on the GPU itself (as opposed to a 2D texture). Remember that each parameter takes time to load onto the call stack, and almost all GPU programming is an art of optimizing every possible operation.

Compute shaders have frequent need for a single list of floats without the extra dimension, using a 1D texture and sampler provides the same clarity strong typing provides. Ie representing 1D data in a 1D structure, and representing 2D data in a 2D structure. It also removes extra operations required in index to row/column translations.

The questions wasn't if there is a good reason for them, it was are they supported yet.

In WebGL 1.0 based on OpenGL ES 2.0 as of 09/MAY/2014

  • There is currently no 1D texture or sampler support.
3
I'd change "yet" to "WebGL 1.0" or something like that. WebGL 2 will most certainly have them. - Bartek Banachewicz
@BartekBanachewicz: Why would they add 1D textures? They are a completely redundant feature. They don't allow you to do anything you can't do with 2D textures. As the answers below suggest, you create a 2D texture with height 1, and have a 1D texture. In fact, if the API was created from scratch, having only 3D textures would be enough. 2D and 1D textures are just reduced cases of 3D textures. - Reto Koradi
@RetoKoradi: Without the ARB_texture_non_power_of_two extension mipmapping and wrap modes other than GL_CLAMP_TO_EDGE are only supported for power-of-two textures, so there are legitimate use cases for 1D textures. - Jens Nolte
@JensNolte: Good point. I figure the next major WebGL version will be based on ES 3.0? That lifts those restrictions on NPOT textures that were in ES 2.0. - Reto Koradi
@RetoKoradi: Not entirely. Buffer textures are effectively fancy 1D textures that let you far exceed the storage of GL_MAX_TEXTURE_SIZE^2 (2D limit). But you cannot use them with anything other than 1D coords. - Andon M. Coleman

3 Answers

12
votes

Why do you need 1D textures? Just make a 2D texture N pixels wide and 1 pixel tall.

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

Either generatemips or set filtering so no mips are needed

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

Sample it with with 0.5 for y

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. It uses the dot product of a typical lighting calculation to look up a value from a 1d ramp texture to shade the objects.

In direct answer to your question. There will be no 1D textures in WebGL because WebGL is based on OpenGL ES 2.0 and OpenGL ES 2.0 does not support 1D textures. Neither does OpenGL ES 3.0 nor 3.1. I'd be surprised if they didn't remove 1D textures completely when they merge OpenGL and OpenGL ES

7
votes

WebGL 1.0 is based on OpenGL ES 2.0 which does not support 1D textures. The Texture Objects section in the WebGL specification reflects this by only having texImage2D and compressedTexImage2D methods.

You can use a texture with a height of one instead.

0
votes

As Jens Nolte said it's not supported in WebGL since it's based on OpenGL ES. You can use 2D textures with a unit width or height. For example (256 width and 1 height):

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

Then in the sampler you can sample the texture by using any value for the height (since it doesn't matter).