2012-04-11 111 views
1

使用图像的加载和存储,我想这样做在GLSL 4.2以下:GLSL 4.2图像的加载和存储与内存屏障

vec3 someColor = ...; 
vec4 currentPixel = imageLoad(myImage, uv); 
float a = currentPixel.a/(currentPixel.a+1.0f); 
vec4 newPixel = vec4(currentPixel.rgb*a+someColor*(1.0f-a),currentPixel.a+1.0f); 
imageStore(myImage, uv, newPixel); 

关于“UV”的值可以作为多个光栅化的像素是相同的。为了得到正确的结果,我当然不希望其他的sharerexecution在imageLoad()和imageStore()的调用之间写入我的像素中。

这是可能用memoryBarrier做某事吗?如果是这样,这个代码如何使用?

回答

2

对于多个光栅化像素,'uv'的值可以相同。

然后你不能这样做。

memoryBarrier不是创建原子操作的方法。它只有只有保证了单个着色器操作的顺序。因此,如果特定的着色器调用读取图像,将其写入并再次读取,则需要一个memoryBarrier以确保读取的内容是之前写入的内容。如果某些其他着色器调用写到它,那么你运气不好(除非它是一个依赖调用。这些东西的规则很复杂)。

如果您正在尝试编程混合,那么您需要确保每个片段着色器调用读取/写入到唯一的值。否则,它不会工作。

你不会说你想要实现的是什么,所以不可能提供一个更好的方式来获得你想要的东西。我只能说这个的方式是不行的。

+0

好吗 - 已thoght左右。非常感谢您的澄清。是的,我尝试做混合。我可以使用ImageAtomicAdd(..,vec4(someColor,1.0f)),并在读取除以它们的.a值的像素 - 但问题是,像素最初已经有一个颜色以及一个重量,这个重量是介于0和1之间 – user1282931 2012-04-12 09:38:34

+0

@ user1282931:如果您尝试进行混合,为什么您有多个片段写入相同的值? – 2012-04-12 17:43:28

+0

它是反射映射上的一种反投影。呈现的反射以及每个像素的对象正常,并且由此反射图应该是近似的 - 因此多个片段可以映射到相同的反射纹素,并且为了避免我想要使用混合的噪声 – user1282931 2012-04-12 18:44:49

0

您需要实现锁定系统(锁定/互斥锁)。 为此,最好使用imageAtomicCompSwap或使用缓冲区atomicCompSwap。当然,你需要使用全局变量(比如纹理)而不是局部变量。

为了实现目的,我认为这个问题是很大一部分回答您的问题:Is my spin lock implementation correct and optimal?