【发布时间】:2014-05-20 00:18:38
【问题描述】:
我正在尝试编写一个使用许多位操作的着色器。事实上,从 glsl 1.30 开始就支持它们,但我只在 OpenGL 2.1 上。
有什么方法可以在我的 OpenGL 版本中使用位操作吗?
【问题讨论】:
标签: opengl glsl bitwise-operators
我正在尝试编写一个使用许多位操作的着色器。事实上,从 glsl 1.30 开始就支持它们,但我只在 OpenGL 2.1 上。
有什么方法可以在我的 OpenGL 版本中使用位操作吗?
【问题讨论】:
标签: opengl glsl bitwise-operators
所有 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 着色器,它应该可以工作。
【讨论】:
这应该可以帮助您入门。
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;
}
【讨论】: