我正在尝试编写一个使用许多位操作的着色器。事实上,从glsl 1.30开始支持它们,但我只使用OpenGL 2.1。
有没有办法在我的OpenGL版本中使用位操作?
答案 0 :(得分:3)
所有兼容SM3(~OpenGL 2.1)的硬件都支持有限的整数功能。这通常通过使用浮点模拟整数来完成,并且不包含位操作。
对于位操作,您需要GLSL 1.3或EXT_gpu_shader4。
如果你只有OpenGL 2.1的原因是你的驱动程序有点过时,你可能仍然有幸有EXT_gpu_shader4(在这种情况下更新驱动程序可能是个好主意。)
如果原因是你的显卡根本不支持更好的东西,那你就不走运了。
如果你有EXT_gpu_shader4(检查扩展名字符串),你可以添加:
#extension EXT_gpu_shader4 : require
到您的GLSL 1.2着色器,它应该可以工作。
答案 1 :(得分:0)
这应该可以帮助您入门。
lowp ivec4 imod4_2(lowp ivec4 x)
{
return x - (2 * (x/2));
}
lowp ivec4 parselowbits(lowp int x)
{
// Implement (x % y) where y is known to be the constant 2
// by first dividing x by (8, 4, 2, 1) and then doing a mod
// by (2, 2, 2, 2) to generate an int vector.
lowp ivec4 numerator = ivec4(x);
lowp ivec4 denominator = ivec4(8, 4, 2, 1);
lowp ivec4 modNumerator = numerator / denominator;
lowp ivec4 modResult = imod4_2(modNumerator);
return modResult;
}
lowp ivec4 parsehighbits(lowp int x)
{
// Implement (x % y) where y is known to be the constant 2
// by first dividing by (8*16, 4*16, 2*16, 1*16) and then doing a mod
// by (2, 2, 2, 2) to generate an int vector.
lowp ivec4 numerator = ivec4(x);
lowp ivec4 denominator = ivec4(8*16, 4*16, 2*16, 1*16);
lowp ivec4 modNumerator = numerator / denominator;
lowp ivec4 modResult = imod4_2(modNumerator);
return modResult;
}
上述函数适用于像输入矢量的.r .g这样的组件的高半字节(4位)。您当然需要读入值并乘以255来进行非规范化。然后,实现AND很简单:
lowp ivec4 and4(lowp ivec4 a, lowp ivec4 b)
{
lowp ivec4 a_and_b = a * b;
return a_and_b;
}