Webgl纹理水平翻转

3

我想知道是否有函数可以水平翻转WebGL纹理。

我在谷歌上搜索了这个问题。 但是,我得到的答案是使用gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);来垂直翻转纹理,就像你知道的那样。

我还尝试编写一个简单的函数来切换像素值以获得所需的翻转纹理。 但我仍然想知道是否有任何方法可以直接水平翻转WebGL纹理?


将它倒过来绘制?翻转纹理坐标?没有一种简单的方法可以翻转数据本身。 - gman
我刚刚尝试使用gl.readPixels首先获取纹理数据,然后使用for循环交换像素值。只是想知道是否有任何快速翻转纹理的方法。 - NewWay Hsiao
或者我可以先尝试翻转图像,然后再绑定到纹理上。 - NewWay Hsiao
2个回答

6

实际上,更常见的方法是用 1 减去你想要翻转的轴:

TexCoord.y = 1.0 - TexCoord.y;

这个完美运作 - 注意你可以在着色器内部或外部执行此操作。 - Matt Haidet

5
更重要的问题是你想做什么。你说你想翻转纹理。为什么?你想实现什么目标?在绘制纹理时,有许多方法可以实现翻转方向,不需要翻转纹理的数据。比如,在一个矩形上绘制纹理,你可以:
- 翻转矩形。 - 在X轴上缩放-1。 - 更改数据中的纹理坐标。 - 在着色器中操作纹理坐标。
所有这些方法都比真正翻转纹理数据更快、更有用。今天你问如何x-翻转数据,明天你会问如何旋转数据。你通常不会x-翻转或旋转纹理,而是操作顶点和/或纹理坐标。
所以,你真正想要实现的目标是什么,你认为翻转纹理数据会解决什么问题?
旧版本的OpenGL固定函数有一个与上述最后一个想法相对应的纹理矩阵。你可能有一个像这样的顶点着色器:
attribute vec4 position;
attribute vec2 texcoord;

uniform mat4 matrix;

varying vec2 v_texcoord;

void main() {
  gl_Position = matrix * position;

  // pass through to fragment shader
  v_texcoord = texcoord;  
}

您可以像这样添加纹理矩阵。
attribute vec4 position;
attribute vec2 texcoord;

uniform mat4 matrix;
uniform mat4 textureMatrix;  // ADDED!!

varying vec2 v_texcoord;

void main() {
  gl_Position = matrix * position;

  // pass through to fragment shader after
  // multiplying by texture matrix
  v_texcoord = (textureMatrix * vec4(texcoord, 0, 1)).xy;  // CHANGED !!
}

以下是使用纹理矩阵以多种方式绘制相同纹理的示例

var m4 = twgl.m4;
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

var arrays = {
  position: { 
    numComponents: 2,
    data: [
      0, 0, 
      1, 0, 
      0, 1, 
      0, 1, 
      1, 0, 
      1, 1,
    ],
  },
  texcoord: [
      0, 0, 
      1, 0, 
      0, 1, 
      0, 1, 
      1, 0, 
      1, 1,
  ],
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
  
// make a texture from a 2d canvas. We'll make an F so we can see it's orientation
var ctx = document.createElement("canvas").getContext("2d");
ctx.width = 64;
ctx.height = 64;
ctx.fillStyle = "red";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height / 2);
ctx.fillStyle = "blue";
ctx.fillRect(0, ctx.canvas.height / 2, ctx.canvas.width, ctx.canvas.height / 2);
ctx.fillStyle = "yellow";
ctx.font = "100px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("F", ctx.canvas.width / 2, ctx.canvas.height / 2);
  
var tex = twgl.createTexture(gl, { src: ctx.canvas });

var uniforms = {
  matrix: m4.identity(),
  textureMatrix: m4.identity(),
  texture: tex,
};

gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

for (var ii = 0; ii < 10; ++ii) {
  var flipX = ii & 0x1;
  var flipY = ii & 0x2;
  var swap  = ii & 0x4;
  var rot   = ii & 0x8;
  var x     = ii % 5;
  var y     = ii / 5 | 0;
 
  var m = uniforms.matrix;
  m4.ortho(0, gl.canvas.width, gl.canvas.height, 0, -1, 1, m);
  m4.translate(m, [x * 59 + 2, y * 59 + 2, 0], m);
  m4.scale(m, [58, 58, 1], m);
  
  var tm = uniforms.textureMatrix;
  m4.identity(tm);
  if (flipX) {
    m4.translate(tm, [1, 0, 0], tm);
    m4.scale(tm, [-1, 1, 1], tm);
  }
  if (flipY) {
    m4.translate(tm, [0, 1, 0], tm);
    m4.scale(tm, [1, -1, 1], tm);
  }
  if (swap) {
    m4.multiply(tm, [
      0, 1, 0, 0,
      1, 0, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, 1,
    ], tm);
  }
  if (rot) {
   m4.translate(tm, [0.5, 0.5, 0], tm);
   m4.rotateZ(tm, Math.PI * 0.25, tm);
   m4.translate(tm, [-0.5, -0.5, 0], tm);
  }  
  twgl.setUniforms(programInfo, uniforms);
  twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo);
}
canvas { border: 1px solid black; }
  <script id="vs" type="notjs">
attribute vec4 position;
attribute vec2 texcoord;

uniform mat4 matrix;
uniform mat4 textureMatrix;

varying vec2 v_texcoord;

void main() {
  gl_Position = matrix * position;
  v_texcoord = (textureMatrix * vec4(texcoord, 0, 1)).xy;
}
  </script>
  <script id="fs" type="notjs">
precision mediump float;

uniform sampler2D texture;

varying vec2 v_texcoord;

void main() {
  gl_FragColor = texture2D(texture, v_texcoord);
}
  </script>
<script src="https://twgljs.org/dist/twgl-full.min.js"></script>
<canvas id="c"></canvas>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接