我做了一个数据纹理,非常基本,但它没有正确显示

I make a data texture, very basic, but it does not display correctly

提问人:oceanGermanique 提问时间:11/14/2023 更新时间:11/14/2023 访问量:31

问:

我认为这一定是我的代码中一个明显的错误,但我找不到它。因此,我创建了一个 4x2 纹理,并用绿色和红色像素网格填充它。

预期结果是此图像,一个由红色和绿色交替组成的 4x2 像素网格:

enter image description here

但是,不,这是结果(您可以通过运行下面的代码来观察)。

enter image description here

一定有一个小错误,一些明显的东西,但我看不出是什么......

"use strict";

let canvas = document.getElementById("canvas");
let gl = canvas.getContext("webgl");

let width = 4;
let height = 2;

gl.canvas.width = width;
gl.canvas.height = height;

gl.viewport(0, 0, width, height);


let vertex = `
      attribute vec2 a_position;
      attribute vec2 a_texCoord;

      varying vec2 v_texCoord;

      void main() {

        gl_Position = vec4(a_position, 0, 1);
        v_texCoord = a_texCoord;
      }
    `;

let fragment = `
      precision mediump float;

      uniform sampler2D u_image;

      varying vec2 v_texCoord;

      void main() {
        gl_FragColor = texture2D(u_image, v_texCoord);
      }
    `;

let shader = gl.createProgram();
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
gl.attachShader(shader, vertexShader);
gl.attachShader(shader, fragmentShader);
gl.linkProgram(shader);

let positionLocation = gl.getAttribLocation(shader,"a_position");
let texcoordLocation = gl.getAttribLocation(shader,"a_texCoord");

let positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  -1,-1,
  -1,+1,
  +1,-1,
  +1,-1,
  -1,+1,
  +1,+1
 ]),gl.STATIC_DRAW);
 
let texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0.0, 0.0,
    1.0, 0.0,
    0.0, 1.0,
    0.0, 1.0,
    1.0, 0.0,
    1.0, 1.0,
]), gl.STATIC_DRAW);


let   texture= gl.createTexture();
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

let r=[255,0,0,255];
let g=[0,255,0,255];
gl.texImage2D(
     gl.TEXTURE_2D,
     0,        // mip level
     gl.RGBA,  // internal format
     4,        // width
     2,        // height
     0,        // border
     gl.RGBA,  // data format
     gl.UNSIGNED_BYTE,   // data type
     new Uint8Array([    // data
        ...r, ...g, ...r, ...g,
        ...g, ...r, ...g, ...r,
     ]));

gl.useProgram(shader);

gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  let size = 2;
  let type = gl.FLOAT;
  let normalize = false;
  let stride = 0;
  let offset = 0;
  gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);

  gl.enableVertexAttribArray(texcoordLocation);
  gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
  size = 2;
  type = gl.FLOAT;
  normalize = false;
  stride = 0;
  offset = 0;
  gl.vertexAttribPointer(texcoordLocation, size, type, normalize, stride, offset);

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
let utexture = gl.getUniformLocation(shader, 'u_image');

gl.uniform1i(utexture, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
canvas {
  width: 160px;
  height: 80px;
  image-rendering: pixelated;
}
<canvas id="canvas"></canvas>

JavaScript WebGL

评论


答:

1赞 Rabbid76 11/14/2023 #1

纹理坐标错误。将它们更改为:

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0.0, 1.0,
    0.0, 0.0,
    1.0, 1.0,
    1.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
]), gl.STATIC_DRAW);

"use strict";

let canvas = document.getElementById("canvas");
let gl = canvas.getContext("webgl");

let width = 4;
let height = 2;

gl.canvas.width = width;
gl.canvas.height = height;

gl.viewport(0, 0, width, height);


let vertex = `
      attribute vec2 a_position;
      attribute vec2 a_texCoord;

      varying vec2 v_texCoord;

      void main() {

        gl_Position = vec4(a_position, 0, 1);
        v_texCoord = a_texCoord;
      }
    `;

let fragment = `
      precision mediump float;

      uniform sampler2D u_image;

      varying vec2 v_texCoord;

      void main() {
        gl_FragColor = texture2D(u_image, v_texCoord);
      }
    `;

let shader = gl.createProgram();
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
gl.attachShader(shader, vertexShader);
gl.attachShader(shader, fragmentShader);
gl.linkProgram(shader);

let positionLocation = gl.getAttribLocation(shader,"a_position");
let texcoordLocation = gl.getAttribLocation(shader,"a_texCoord");

let positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  -1,-1,
  -1,+1,
  +1,-1,
  +1,-1,
  -1,+1,
  +1,+1
 ]),gl.STATIC_DRAW);
 
let texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0.0, 1.0,
    0.0, 0.0,
    1.0, 1.0,
    1.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
]), gl.STATIC_DRAW);


let   texture= gl.createTexture();
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

let r=[255,0,0,255];
let g=[0,255,0,255];
gl.texImage2D(
     gl.TEXTURE_2D,
     0,        // mip level
     gl.RGBA,  // internal format
     4,        // width
     2,        // height
     0,        // border
     gl.RGBA,  // data format
     gl.UNSIGNED_BYTE,   // data type
     new Uint8Array([    // data
        ...r, ...g, ...r, ...g,
        ...g, ...r, ...g, ...r,
     ]));

gl.useProgram(shader);

gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  let size = 2;
  let type = gl.FLOAT;
  let normalize = false;
  let stride = 0;
  let offset = 0;
  gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);

  gl.enableVertexAttribArray(texcoordLocation);
  gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
  size = 2;
  type = gl.FLOAT;
  normalize = false;
  stride = 0;
  offset = 0;
  gl.vertexAttribPointer(texcoordLocation, size, type, normalize, stride, offset);

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
let utexture = gl.getUniformLocation(shader, 'u_image');

gl.uniform1i(utexture, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
canvas {
  width: 160px;
  height: 80px;
  image-rendering: pixelated;
}
<canvas id="canvas"></canvas>

评论

0赞 oceanGermanique 11/14/2023
我不明白我的纹理坐标在哪里不正确。然而,它们代表 2 个三角形,并且顶点之间的顺序相同?
1赞 Rabbid76 11/14/2023
不,顶点的顺序不同 只需查看代码中的第一个和第二个顶点坐标,即 -1、-1 和 -1,+1,但对应的纹理坐标是 0.0、0.0 和 1.0、0.0、...拿一张纸,画出 2 个三角形,并用顶点坐标和纹理坐标叠加它们,然后你会看到问题。