【问题标题】:WebGL - Problems Loading a TextureWebGL - 加载纹理的问题
【发布时间】:2020-12-18 19:25:48
【问题描述】:

我正在尝试创建一个纹理(到处都是灰色)并使用 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.log(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 中加载纹理的理解是,我们按照以下过程加载纹理:

  • 我们使用gl.uniform1i(gl.getUniformLocation(program, 'myTexture'), 0) 指定我们为uniform sampler2D 使用的纹理单元。
  • 我们使用gl.createTexture() 创建纹理。
  • 然后我们使用GL.activeTexture 选择要加载的纹理单元。
  • 我们使用GL.bindTexture将刚刚创建的纹理绑定到纹理单元。
  • 我们使用GL.texImage2D 加载纹理。

我尝试在上面的 JSFiddle 中实现它,但我认为纹理加载不正确。我希望看到一个灰屏 (128,128,128),这应该是我加载的纹理,但我看到的只是一个黑屏。

有人知道我是否正确加载了纹理吗?

【问题讨论】:

    标签: webgl textures


    【解决方案1】:

    当我在 Chrome 中运行您的代码时,我在 JavaScript 控制台中收到此警告

    [.WebGL-0x7f9d4101ce00]渲染警告:绑定到纹理单元 0 的纹理不可渲染。它可能不是 2 的幂次方或具有不兼容的纹理过滤(可能)?

    您的纹理没有 mips,因此您需要通过调用 gl.generateMipmap(gl.TEXTURE_2D) 创建 mips,或者您需要通过调用 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) 设置过滤以便不需要 mips

    this

    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.log(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>

    下次请使用snippet

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-12
      • 1970-01-01
      • 2017-01-19
      • 2018-11-18
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多