WebGL — проблемы с загрузкой текстуры

Я пытаюсь создать текстуру (просто везде серая) и отобразить ее на холсте с помощью WebGL.

Я пытался здесь:

function tryToDraw() {
  vertexShaderCode = `#version 100
      precision mediump float;
      attribute vec2 vertex_attrib;

      void main (void)
      {
          gl_Position = vec4 (vertex_attrib, 0.0, 1.0) ;
      }
  `;

  fragmentShaderCode = `#version 100
      precision mediump float;

      uniform sampler2D myTexture;

      void main (void) {
          vec2 texcoord = gl_FragCoord.xy / 1024.0;
          gl_FragColor = vec4(texture2D (myTexture, texcoord).rgb, 1.0);
      }
  `;

  var canvas = document.getElementById('waves_canvas');
  var gl = canvas.getContext('webgl');
  var program = gl.createProgram();

  var textureArr = new Uint8Array(1024 * 1024 * 3).fill(128);

  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, vertexShaderCode);
  gl.compileShader(vertexShader);
  gl.attachShader(program, vertexShader);

  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, fragmentShaderCode);
  gl.compileShader(fragmentShader);
  gl.attachShader(program, fragmentShader);

  gl.linkProgram(program);
  gl.validateProgram(program);
  console.info(gl.getProgramParameter(program, gl.VALIDATE_STATUS));
  gl.useProgram(program);

  var location = gl.getUniformLocation(program, 'myTexture');
  gl.uniform1i(location, 0);
  var texture = gl.createTexture();
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  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.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 1024, 0, gl.RGB, gl.UNSIGNED_BYTE, textureArr);

  var vertexPositions = new Float32Array([-1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0]);
  var vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);

  var vPosAttrLoc = gl.getAttribLocation(program, 'vertex_attrib');
  gl.enableVertexAttribArray(vPosAttrLoc);
  gl.vertexAttribPointer(vPosAttrLoc, 2, gl.FLOAT, false, 2 * vertexPositions.BYTES_PER_ELEMENT, null);
  gl.drawArrays(gl.TRIANGLES, 0, 6);
}

tryToDraw();
<canvas id = "waves_canvas"></canvas>

Мое понимание загрузки текстур в WebGL заключается в том, что мы загружаем текстуры в соответствии со следующей процедурой:

  • Мы указываем, какой модуль текстуры мы используем для нашего uniform sampler2D, используя gl.uniform1i(gl.getUniformLocation(program, 'myTexture'), 0).
  • Мы создаем текстуру с помощью gl.createTexture().
  • Затем мы выбираем, какой текстурный модуль мы хотим загрузить, используя GL.activeTexture.
  • Мы привязываем только что созданную текстуру к текстурному блоку с помощью GL.bindTexture.
  • Мы загружаем текстуру с помощью GL.texImage2D.

Я пытался реализовать это в JSFiddle выше, но я не думаю, что текстура загружается правильно. Я ожидаю увидеть серый экран (128 128 128), который должен быть текстурой, которую я загрузил, однако все, что я вижу, это черный экран.

Кто-нибудь знает, правильно ли я загружаю текстуру?

Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда я запускаю ваш код в Chrome, я получаю это предупреждение в консоли JavaScript

[.WebGL-0x7f9d4101ce00]ВНИМАНИЕ: текстура, привязанная к текстурному блоку 0, не может быть обработана. Это может быть не степень двойки или несовместимая фильтрация текстур (возможно)?

В вашей текстуре нет мипов, поэтому вам нужно либо создать мипы, вызвав gl.generateMipmap(gl.TEXTURE_2D), либо вам нужно установить фильтрацию, чтобы мипы не нужны, вызвав gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)

Смотрите это

function tryToDraw() {
  vertexShaderCode = `#version 100
      precision mediump float;
      attribute vec2 vertex_attrib;

      void main (void)
      {
          gl_Position = vec4 (vertex_attrib, 0.0, 1.0) ;
      }
  `;

  fragmentShaderCode = `#version 100
      precision mediump float;

      uniform sampler2D myTexture;

      void main (void) {
          vec2 texcoord = gl_FragCoord.xy / 1024.0;
          gl_FragColor = vec4(texture2D (myTexture, texcoord).rgb, 1.0);
      }
  `;

  var canvas = document.getElementById('waves_canvas');
  var gl = canvas.getContext('webgl');
  var program = gl.createProgram();

  var textureArr = new Uint8Array(1024 * 1024 * 3).fill(128);

  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, vertexShaderCode);
  gl.compileShader(vertexShader);
  gl.attachShader(program, vertexShader);

  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, fragmentShaderCode);
  gl.compileShader(fragmentShader);
  gl.attachShader(program, fragmentShader);

  gl.linkProgram(program);
  gl.validateProgram(program);
  console.info(gl.getProgramParameter(program, gl.VALIDATE_STATUS));
  gl.useProgram(program);

  var location = gl.getUniformLocation(program, 'myTexture');
  gl.uniform1i(location, 0);
  var texture = gl.createTexture();
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1024, 1024, 0, gl.RGB, gl.UNSIGNED_BYTE, textureArr);

  var vertexPositions = new Float32Array([-1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0]);
  var vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);

  var vPosAttrLoc = gl.getAttribLocation(program, 'vertex_attrib');
  gl.enableVertexAttribArray(vPosAttrLoc);
  gl.vertexAttribPointer(vPosAttrLoc, 2, gl.FLOAT, false, 2 * vertexPositions.BYTES_PER_ELEMENT, null);
  gl.drawArrays(gl.TRIANGLES, 0, 6);
}

tryToDraw();
<canvas id = "waves_canvas"></canvas>

Пожалуйста, используйте фрагмент в следующий раз.

Другие вопросы по теме