javascript - WebGL 2.0 支持短 3D 纹理

标签 javascript firefox webgl2

我正在尝试在 Firefox 的 WebGL 2.0 中加载短 3D 纹理。

虽然无符号 1 字节 3D 纹理加载没有任何问题,但我很难对任何其他像素类型执行相同的操作。 我的js代码:

var SIZE = 512;
var data = new Int16Array(SIZE * SIZE * SIZE);
data.fill(400);

var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_3D, texture);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_BASE_LEVEL, 0);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAX_LEVEL, 0);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

gl.texImage3D(
    gl.TEXTURE_3D,  // target
    0,              // level
    gl.R16I,        // internalformat
    SIZE,           // width
    SIZE,           // height
    SIZE,              // depth
    0,              // border
    gl.RED_INTEGER,         // format
    gl.SHORT,       // type
    data            // pixel
   );

我不会在此纹理上生成 mip 贴图。

当尝试在片段着色器中采样纹理时,每个像素得到 0。

FS代码:

#version 300 es

precision highp float;
precision highp int;
precision highp sampler3D;

uniform sampler3D textureData;

in vec3 v_texcoord;

out vec4 color;

void main()
{
   vec4 value = texture(textureData, v_texcoord);
   if( value.x == 0.0 )
      color = vec4(1.0, 0.0, 0.0, 1.0);
   else if( value.x == 1.0)
      color = vec4(1.0, 1.0, 0.0, 1.0);
   else if( value.x < 0.0 )
      color = vec4(0.0, 0.0, 1.0, 1.0);
   else
      color = vec4(1.0,1.0,1.0,1.0);
}

如有任何帮助,我们将不胜感激。

最佳答案

您需要使用isampler3D对整数格式纹理进行采样,在这种情况下texture返回ivec4

From the spec section 8.8

Texture lookup functions are provided that can return their result as floating point, unsigned integer or signed integer, depending on the sampler type passed to the lookup function. Care must be taken to use the right sampler type for texture access. The following table lists the supported combinations of sampler types and texture internal formats. Blank entries are unsupported. Doing a texture lookup will return undefined values for unsupported combinations.

 Internal   
 Texture           | Floating Point | Signed Integer | Unsigned Integer |
 Format            | Sampler Types  | Sampler Types  | Sampler Types    |
-------------------+----------------+----------------+------------------+
 Floating point    |   Supported    |                |                  |
-------------------+----------------+----------------+------------------+
 Normalized Integer|   Supported    |                |                  |
-------------------+----------------+----------------+------------------+
 Signed Integer    |                |   Supported    |                  |
-------------------+----------------+----------------+------------------+
 Unsigned Integer  |                |                |   Supported      |
-------------------+----------------+----------------+------------------+

var gl = document.querySelector("#c").getContext("webgl2");
if (!gl) {
  alert("needs webgl 2.0");
}

var SIZE = 512;
var data = new Int16Array(SIZE * SIZE * SIZE);
data.fill(400);

var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_3D, texture);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_BASE_LEVEL, 0);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAX_LEVEL, 0);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

gl.texImage3D(
    gl.TEXTURE_3D,  // target
    0,              // level
    gl.R16I,        // internalformat
    SIZE,           // width
    SIZE,           // height
    SIZE,              // depth
    0,              // border
    gl.RED_INTEGER,         // format
    gl.SHORT,       // type
    data            // pixel
   );

// FS code:

var fs = `#version 300 es

precision highp float;
precision highp int;
precision highp isampler3D;

uniform isampler3D textureData;

in vec3 v_texcoord;

out vec4 color;

void main()
{
   ivec4 value = texture(textureData, v_texcoord);
   if( value.x == 0 )
      color = vec4(1.0, 0.0, 0.0, 1.0);
   else if( value.x == 1)
      color = vec4(1.0, 1.0, 0.0, 1.0);
   else if( value.x < 0 )
      color = vec4(0.0, 0.0, 1.0, 1.0);
   else
      color = vec4(0.0,1.0,1.0,1.0);
}
`;

var vs = `#version 300 es
in vec4 position;
out vec3 v_texcoord;
void main() {
  gl_Position = position;
  v_texcoord = vec3(0);
}
`

var programInfo = twgl.createProgramInfo(gl, [vs, fs]);
var bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.drawBufferInfo(gl, bufferInfo);
canvas { border: 1px solid black; background: purple; }
<script src="https://twgljs.org/dist/2.x/twgl-full.min.js"></script>
<canvas id="c"><canvas>

关于javascript - WebGL 2.0 支持短 3D 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37586193/

相关文章:

javascript - 事件处理程序应该是匿名函数并且内部应该有命名函数吗?

javascript - 序列化函数调用

javascript - 创建 Google 登录页面以访问服务

html - Firefox 按钮变大

javascript - WebGLSync 始终为 UNSIGNALED

opengl-es - getUniformLocation 返回空

javascript - JQuery:如何动态引用元素?

css - 在 Firefox 24 中支持 “border-radius”

javascript - 从 overlay.js firefox 插件获取 HEAD 元素

javascript - cors 污染图像上的映射颜色变换