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

时间:2014-07-22 06:24:23

标签: opengl glsl fragment-shader

我正在编写一个片段着色器,用于将包含任意字节数组的一维纹理渲染成一种条形码。 我的想法是将每个字节编码成对角划分的正方形(因此4个三角形中的每一个代表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)
到目前为止,我得到的函数是将2个bool(示例符号中的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;
}

问题是我无法弄清楚如何计算要编码的字节以及在&#34;角落#34;目前的片段是。

1 个答案:

答案 0 :(得分:0)

(注意,这里的代码是我的头脑而且未经测试,我没有写过很多GLSL。变量名称很草率,我可能犯了一些愚蠢的语法错误,但它应该足以传达这个想法。)

您需要做的第一件事是将纹理坐标转换为数据索引(显示颜色的方块)和一组修改的纹理坐标,它们代表中的位置。< / p>

对于水平排列,您可以执行以下操作:

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

然后您使用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;
    }
}

现在你拥有阴影所需的一切:

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