【问题标题】:Setting neighbor fragment color via GLSL通过 GLSL 设置相邻片段颜色
【发布时间】:2019-09-04 23:22:37
【问题描述】:

我需要设置一个 GLSL 片段着色器来更改当前正在处理的片段以外的片段的颜色。由于这似乎不太理想,我将提供一个非常简短的上下文。

该项目利用渲染通道将给定模型绘制到 FBO 中,该 FBO 具有与纹理贴图中的 UV 坐标相对应的独特颜色。然后对这些颜色进行采样并转换为图像坐标,以便可以根据相机可见的内容更新模型的纹理贴图。本质上:

Render model to FBO
For each FBO pixel
   1. sample secondary texture based on FBO pixel position
   2. convert color at current pixel to image coordinate for the model's texture map
   3. update model's texture with sampled secondary texture at calculated coordinate
End loop

问题是当前的实现非常受 CPU 限制,所以我从 FBO 中读取像素然后对其进行操作。理想情况下,由于我已经在片段着色器中处理了片段的颜色,因此我只想完成该过程的最后几个步骤,并将所有内容都保留在 GPU 上。

我遇到的具体问题是我不太清楚如何(或者是否有可能)让片段着色器设置它未处理的片段的颜色。如果我无法通过使用超大 FBO 并仅偏移我想要设置颜色的片段来处理某些内容,我可以处理直接写入纹理的内容吗?

有什么帮助/建议吗?

【问题讨论】:

    标签: opengl glsl shader


    【解决方案1】:

    片段着色器不能写入它正在处理的片段以外的任何地方。您可能想要做的是乒乓渲染。

    在您的代码中,您将拥有三种纹理,与您列出的任务相匹配:

    1. 次要纹理
    2. 源模型纹理贴图
    3. 目标模型纹理贴图

    在第一次运行时,您将使用 (1) 和 (2) 作为源纹理,以绘制到 (3)。下次通过循环时,您将使用 (1) 和 (3) 写入 (2)。然后,您将切换回使用 (1) 和 (2) 写入 (3)。以此类推。

    所以 (2) 和 (3) 与帧缓冲区对象连接,其中纹理作为颜色缓冲区提供,而不是渲染缓冲区。

    NVidia 在 2009 年编写了GL_NV_texture_barrier extension,它允许您将 (2) 和 (3) 压缩成一个纹理,前提是您明确了解阅读位置和写作位置之间的分界线。我没有专业知识来说明它的普及程度。

    尝试读取和写入相同的纹理(就像使用 FBO 一样)否则会在 OpenGL 中产生未定义的结果。硬件级别的提示问题与缓存和多重采样有关。

    【讨论】:

    • 太好了,谢谢您的解释。我只是在脑海中思考过这个问题,我想我知道它对我有什么作用。
    • 很抱歉撤销了我对此的接受,但我认为 kvark 是正确的,因为进行乒乓球通行证实际上不会让我写信到任意位置...除非我遗漏了什么?
    • 不,完全正确。我把请求当作不是的东西;希望我在某种程度上有所帮助。
    【解决方案2】:

    据我了解,您需要在 OpenGL 中执行散射操作(统一 FBO 像素空间 -> 随机网格 UV 纹理目标)。有一种方法可以做到这一点,不像你想象的那么简单,甚至没有那么快,但我找不到更好的方法:

    • 运行 GL_POINTS 类型的绘图调用,大小等于源 FBO 的宽度*高度。
    • 选择模型纹理作为目标 FBO 颜色层,没有附加深度层
    • 在顶点着色器中,使用gl_VertexID 计算原始屏幕坐标。
    • 从源 FBO 纹理采样以获得颜色和目标位置(假设您的原始 FBO 表面是纹理)。分配适当的gl_Position 并将目标颜色传递给片段着色器。
    • 在片段着色器中,只需将颜色复制到输出即可。

    这将使 GPU 遍历每个原始 FBO 像素,并将计算出的颜色分散到目标纹理上。

    【讨论】:

    • 嗯.. 这是一个非常有趣的想法。 Tommy 的方法更符合我已经实施的方法,所以我想我会先试一试。不过,我也可以尝试一下。
    • @Xenethyl。我可能没有完全理解你的任务,但据我所知 - 分散不能以@Tommy 描述的方式实现。因此,如果您认为他的想法符合您的需求,请继续使用它,当然,因为它比我的要简单得多。
    • 今晚晚餐后想了想,我开始意识到打乒乓球并不能真正解决我的问题。我不知道您的解决方案是否适用于我当前的设置,但我确实认为它比 Tommy 所讨论的更正确。现在我已将此标记为已接受。感谢您指出我的误解。
    • @Xenethyl。谢谢你。不要犹豫,询问任何细节。我在 GL-3 中实现了很多类似的方案。
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 2020-11-20
    • 2014-07-26
    • 2020-12-05
    • 1970-01-01
    • 2023-03-27
    • 2011-10-04
    • 2022-01-09
    相关资源
    最近更新 更多