OpenGL GLSL:从着色器到内存的输出

时间:2016-11-10 23:37:49

标签: opengl shader fragment-shader opengl-4

我需要在图形内存中有一些变量/对象,可以在我的片段着色器和我的普通C#代码中访问。优选16Byte vec4

我想做什么:

  1. [在C#中]从图形内存读取变量到cpu内存
  2. [在C#中]将变量设置为零
  3. [在C#中]执行我的场景的正常绘制
  4. [在着色器中] 一个片段传递将某些内容写入变量( UPDATE
  5. 重新启动循环
  6. 更新的) 我将当前鼠标坐标传递给具有统一变量的片段着色器。片段着色器然后检查它是否是相应的像素。如果是,它会将特定颜色写入变量中。我不写FS输出的原因是我在互联网上找不到任何关于如何将此输出输入正常内存的解决方案。另外,我会为每个像素而不是一个

    输出

    我想要的基本上是着色器可以写入的统一变量。

    是否有任何类型的变量/对象符合我的需求,如果有,它的性能如何?

1 个答案:

答案 0 :(得分:3)

A"制服"你的着色器可以写入的是错误的术语。均匀意味着统一(如同各处的相同值)。如果特定着色器调用正在更改该值,则它将不再均匀。

你可以使用atomic counters来做这类事情;为每个通过的测试递增计数器,然后检查非零状态。这比设置一个通用的着色器存储缓冲区对象要简单得多,然后担心让内存访问它一致。

遮挡查询也可用于旧硬件。它们的工作方式与原子计数器类似,您可以(非常粗略地)计算通过深度测试的片段数量。不要指望它的准确性,在片段着色器中对任何未通过测试条件的像素使用discard,然后在查询回读中测试非零片段计数。

至于性能,只要你可以在发出命令和稍后使用结果之间处理几帧延迟,你应该没问题。

如果您尝试使用原子计数器或遮挡查询并在同一帧中回读结果,您将停止管道并消除CPU / GPU并行性。

我建议在命令流中插入一个fence同步对象,然后在尝试读回结果之前每帧检查一次fence的状态。这样可以防止停滞。