简体   繁体   English

glsl片段着色器计算纹理位置

[英]glsl fragment shader calculate texture position

I'm writing a fragment shader for rendering a 1D texture containing an arbitrary byte array into a kind of barcode. 我正在编写一个片段着色器,用于将包含任意字节数组的一维纹理渲染为一种条形码。 my idea is to encode each byte into a square divided diagonally (so each of the 4 triangles represents 2 bit), like so: 我的想法是将每个字节编码为对角线划分的正方形(因此,四个三角形中的每个代表2位),如下所示:

 _____
|\ A /|  each byte encoded as binary is DDCCBBAA,
| \ / |  the colors are: Red   if 11
|D X B|                  Green if 10
| / \ |                  Blue  if 01
|/ C \|                  Black if 00
 ¯¯¯¯¯   so color can be calculated as: [(H & L), (H & !L), (!H & L)]

so for example: 198 == 11 00 01 10 would be:
 _____                 DD CC BB AA
|\ G /| 
| \ / | A=10=Green
|R X B| B=01=Blue
| / \ | C=00=Black
|/ b \| D=11=Red
 ¯¯¯¯¯  (B=Blue, b=Black)

what I got so far are a function for encoding 2 bools (H,L in the example notation) into a vec3 color and a function for encoding a byte and "corner index" (A/B/C/D in the example) into the color: 到目前为止,我得到的是将2个布尔值(在示例标记中为H,L)编码为vec3颜色的函数,以及将字节和“角索引”(在示例中为A / B / C / D)编码为的函数。颜色:

#version 400
out vec4 gl_FragColor; // the output fragment
in vec2 vf_texcoord; // normalized texture coords, 0/0=top/left
uniform isampler1D uf_texture; // the input data
uniform int uf_texLen; // the input data's byte count
vec3 encodeColor(bool H, bool L){
  return vec3(H&&L,H&&!L,!H&&L);
}
vec3 encodeByte(int data,int corner){
  int maskL = 1 << corner;
  int maskH = maskL << 1;
  int shiftL = corner/2;
  int shiftH = shiftL+1;
  bool H=bool((data&maskH)>>shiftH);
  bool L=bool((data&maskL)>>shiftL);
  return encodeColor(H,L);
}
void main(void) {

  // the part I can't figure out

  gl_FragColor.rgb=encodeByte(/* some stuff calculated by the part above*/);
  gl_FragColor.a=1;
}

the problem is I can't figure out how to calculate which byte to encode and in what "corner" the current fragment is. 问题是我无法弄清楚如何计算要编码的字节以及当前片段位于哪个“角落”。

(Note, the code here is is off the top of my head and untested, and I haven't written a lot of GLSL. The variable names are sloppy and I've probably made some stupid syntax mistakes, but it should be enough to convey the idea.) (请注意,这里的代码不在我的脑海中,并且未经测试,并且我还没有编写很多GLSL。变量名草率,而且我可能犯了一些愚蠢的语法错误,但是它足以传达想法。)

The first thing you need to do is translate the texture coordinates into a data index (which square to display colors for) and a modified set of texture coordinates that represent the position within that square. 您需要做的第一件事是将纹理坐标转换为数据索引(该正方形显示其颜色)和一组经过修改的纹理坐标,它们代表该正方形的位置。

For a horizontal arrangement, you could do something like: 对于水平排列,您可以执行以下操作:

float temp = vf_texcoord.x * uf_texLen;
float temp2 = floor(temp);
int dataIndex = temp2;
vec2 squareTexcoord = { temp2 - temp, vf_texcoord.y };

Then you'd use squareTexcoord to decide which quadrant of the square you're in: 然后,您将使用squareTexcoord来确定您所在的正方形的哪个象限:

int corner;
vec2 squareTexcoord2 = squareTexcoord - { 0.5, 0.5 }
if (abs(squareTexcoord2.x) > abs(squareTexcoord2.y)) {  // Left or right triangle
    if (squareTexcoord2.x > 0) {  // Right triangle
        corner = 0;
    }
    else {  // Left triangle
        corner = 1;
    }
}
else {  // Top or bottom triangle
    if (squareTexcoord2.y > 0) {  // Bottom triangle
        corner = 2;
    }
    else {  // Top triangle
        corner = 3;
    }
}

And now you have all you need for shading: 现在,您拥有了所有需要的阴影:

gl_FragColor = { encodeByte(int(texelFetch(uf_texture,dataIndex,0).r), corner), 1.0 };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM