简体   繁体   English

在Fragmentshader OpenGL中访问不同的片段

[英]Access different Fragment in Fragmentshader OpenGL

Can I access and change output values of another Fragment at a certain location in the Fragmentshader? 我可以在Fragmentshader中的某个位置访问和更改另一个Fragment的输出值吗?

For example in the main() loop I process everything just like usualy and output the color with some value. 例如,在main()循环中,我像平常一样处理所有内容,并输出具有一定值的颜色。 But in adition to that I also want the fragment at position vec3(5,3,6) (in world coordinates) to have the same colour. 但是除此之外,我还希望位置vec3(5,3,6)(在世界坐标中)的片段具有相同的颜色。

Now I already did some researche on the web on that. 现在我已经在网上对此进行了一些研究。 The OpenGL site says, the fragmentshader has one fragment as input and has one fragment as output, which doesnt sound very promising. OpenGL网站说,fragmenthader有一个片段作为输入,有一个片段作为输出,这听起来并不是很有希望。 Also I know that all fragments are being processed in parallel. 我也知道所有片段都是并行处理的。 But maybe it is posible to say, if the fragment at this position has not been processed yet, write this color to it and take this fragment as already processed. 但是也许可以这样说,如果尚未处理此位置上的片段,则将其涂上颜色,然后将其视为已处理。

My be someone can explain if this is posible somehow and if not, why this is not a good idea. 我可以作为某人解释这是否可行的原因,如果不是,为什么这不是一个好主意。 The best guess I would have is, to build this logic into the shader, it would have a very bad effect on the general performance. 我最好的猜测是,将此逻辑构建到着色器中,会对整体性能产生非常不利的影响。

My be someone can explain if this is posible somehow and if not, why this is not a good idea. 我可以作为某人解释这是否可行的原因,如果不是,为什么这不是一个好主意。

It's not a question of bad idea vs. good idea. 这不是坏主意还是好主意的问题。 It's simply not possible. 根本不可能。

The closest you can get to this functionality is ARB_fragment_shader_interlock . 与该功能最接近的是ARB_fragment_shader_interlock Through its interlock and ordering guarantees, it allows limited interoperation. 通过其互锁和订购保证,它允许有限的互操作。 And that limitation is... it only allows interoperation for fragments that cover the same pixel/sample. 而且这个限制是……它只允许覆盖相同像素/样本的片段互操作。

So even this functionality does not allow you to write to some other pixel. 因此,即使此功能也不允许您写入其他像素。

The absolute best you can do is use SSBOs and atomic counters to have fragment shaders write what color values and "world coordinates" they would like to write to, then have a second process execute that buffer as either a rendering command or a compute shader to actually write that data. 绝对可以做的最好的事情是使用SSBO和原子计数器让片段着色器写出他们想要写入的颜色值和“世界坐标”,然后让第二个进程将该缓冲区作为渲染命令或计算着色器执行到实际写入该数据。

As already pointed out in Nicol's answer, you can't write to additional fragments of a framebuffer surface in the fragment shader. 正如Nicol的答案中已经指出的那样,您无法在片段着色器中写入帧缓冲区表面的其他片段。

The description of your use case is not clear enough to tell what might work best. 用例的描述不够清楚,无法告诉您哪种方法最有效。 In the interest of brainstorming, the most direct approach that comes to mind is that you don't use a framebuffer draw surface at all, but output to an image instead. 为了集思广益,想到的最直接的方法是根本不使用帧缓冲区绘制表面,而是输出到图像。

If you bind a texture as an image, you can write to it in the fragment shader using the imageStore() built-in function. 如果将纹理绑定为图像,则可以使用imageStore()内置函数在片段着色器中对其进行写入。 This function takes coordinates as one of the argument, so you can write to any pixel you want, as well as write multiple pixels from the same shader invocation. 此函数将坐标作为参数之一,因此您可以写入所需的任何像素,也可以从同一着色器调用写入多个像素。

Depending on what exactly you want to achieve, I could also imagine a hybrid approach, where your primary rendering still goes to a framebuffer, but you write additional pixel values to an image at the desired positions. 根据您要实现的精确程度,我还可以想象一种混合方法,在该方法中,主渲染仍将移至帧缓冲区,但您会将其他像素值写入图像中所需的位置。 Then, in a second rendering pass, you can combine the content of the image with the primary rendering. 然后,在第二次渲染过程中,可以将图像的内容与主渲染结合在一起。 The combination could be done with blending if the math/logic is simple enough. 如果数学/逻辑足够简单,则可以通过混合完成组合。 If you need a more complex combination, you can use a texture as the framebuffer attachment of the initial pass, and then use the result of the rendering and the extra image as two inputs for the fragment shader of the combination pass. 如果需要更复杂的组合,则可以将纹理用作初始通道的帧缓冲区附件,然后将渲染结果和多余的图像用作组合通道的片段着色器的两个输入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM