Невозможно создать mipmap для текстуры half_float - PullRequest
0 голосов
/ 01 июля 2019

Я использую webgl2 и загружаю свои данные текстуры как половину с плавающей точкой. Я могу правильно отобразить изображение при использовании LINEAR MIN_FILTER. Тем не менее, я хочу использовать фильтр MIPMAP. Когда я использую фильтр MIPMAP и пытаюсь сгенерировать MIPMAP, он терпит неудачу. Документация webgl https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D указывает, что текстуры R16F являются фильтруемыми, и не указывает, что они ограничены линейными фильтрами. Есть ли шаг, который я пропускаю или это недокументированное ограничение webgl2?

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
const tex = gl.createTexture();
const unit = 1;  // Pick some texture unit
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, tex);

const numPixels = this.width * this.height;

const level = 0;

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); //Works
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST); //Does NOT work
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

// Upload the image into the texture
const pixel = new Uint16Array(this.binaryImage);

gl.texImage2D(gl.TEXTURE_2D, level, gl.R16F, this.width, this.height, 0, gl.RED, gl.HALF_FLOAT, pixel);

gl.generateMipmap(gl.TEXTURE_2D); //FAILS

const sampler2DLoc = gl.getUniformLocation(program, "u_image");
gl.uniform1i(sampler2DLoc, unit);

1 Ответ

1 голос
/ 01 июля 2019

В спецификации WebGL2 сказано, что WebGL2 - это OpenGL ES 3.0 с отличиями, перечисленными в спецификации WebGL2.В противном случае спецификация WebGL2 говорит о необходимости прочитать спецификацию OpenGL ES 3.0 для подробностей.

Из раздела спецификации OpenGL ES 3.0 3.8.10.5

3.8.10.5 Генерация Mipmap вручную

Mip-карты могут быть сгенерированы вручную с помощью команды

void GenerateMipmap(enumtarget);

...

Если базовый массив уровня не был указан с внутренним форматом без размера из таблицы 3.3 или с внутренним форматом размеракак с цветовой, так и с текстурной фильтрацией в соответствии с таблицей 3.13, генерируется ошибка INVALID_OPERATION

R16F фильтруется по текстуре, но не имеет цветовой визуализации

Youнужно проверить и включить расширение EXT_color_buffer_float , чтобы иметь возможность генерировать мипы для форматов наполовину с плавающей точкой.

'use strict';

function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  if (!gl) {
    return alert('need webgl2');
  }
  const ext = gl.getExtension('EXT_color_buffer_float');
  if (!ext){
    return alert('need EXT_color_buffer_float');
  }

  const vs = `#version 300 es
  void main() {
    gl_Position = vec4(0, 0, 0, 1);
    gl_PointSize = 120.0;
  } 
  `;

  const fs = `#version 300 es
  precision mediump float;

  uniform sampler2D tex;

  out vec4 outColor;

  void main() {
    outColor = vec4(texture(tex, gl_PointCoord.xy).r, 0, 0, 1);
  }
  `;

  // setup GLSL program
  const program = twgl.createProgram(gl, [vs, fs]);

  // a 2x2 pixel data
  const h0 = 0x0000;
  const h1 = 0x3c00;
  const pixels = new Uint16Array([
    h0, h1,
    h1, h0,
  ]);
  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texImage2D(
      gl.TEXTURE_2D,
      0,                 // level
      gl.R16F,           // internal format
      2,                 // width
      2,                 // height
      0,                 // border
      gl.RED,            // format
      gl.HALF_FLOAT,     // type
      pixels,            // data
  );
  gl.generateMipmap(gl.TEXTURE_2D);

  gl.useProgram(program);

  const offset = 0;
  const count = 1;
  gl.drawArrays(gl.POINTS, offset, count);
  console.log('gl.getError should be 0 was:', gl.getError());
}

main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>
...