我不确定你是如何进行 XOR 位的(至少它应该很慢;我认为当前的任何 GPU 都不会加速),但这是我的想法:
- 有两个输入图像
- 打开遮挡查询。
- 将两个图像绘制到屏幕上(即设置了两个纹理的全屏四边形),使用计算 abs(texel1-texel2) 的片段着色器,如果像素相同(差异为零或低于某个阈值)。最简单的可能只是使用 GLSL 片段着色器,然后您只需读取两个纹理,计算差异的 abs() 并丢弃像素。非常基本的 GLSL 知识在这里就足够了。
- 获取通过查询的像素数。对于相同的像素,查询不会通过(像素将被着色器丢弃),对于不同的像素,查询将通过。
起初我想到了一种涉及深度缓冲区的更复杂的方法,但后来意识到仅仅杀死像素就足够了。这是我的原创(但上面的更简单,更有效):
- 有两个输入图像
- 清除屏幕和深度缓冲区
- 将两个图像绘制到屏幕上(即设置了两个纹理的全屏四边形),使用计算 abs(texel1-texel2) 的片段着色器,如果像素不同,则杀死像素(在 GLSL 中丢弃)。绘制四边形,使其深度缓冲区值接近平面。
- 在这一步之后,深度缓冲区将包含相同像素的小深度值和不同像素的大(远平面)深度值。
- 打开遮挡查询,并绘制另一个深度比远平面更近但比前一个四边形大的全屏四边形。
- 获取通过查询的像素数。对于相同的像素,查询不会通过(深度缓冲区已经更近了),对于不同的像素,查询将通过。您将使用 SAMPLES_PASSED_ARB 来获取此信息。CodeSampler.com上有一个遮挡查询示例可以帮助您入门。
当然,所有这些都需要具有遮挡查询支持的 GPU。自 2002 年左右以来,大多数 GPU 都支持这一点,但一些低端 GPU 除外(特别是 Intel 915(又名 GMA 900)和 Intel 945(又名 GMA 950))。