首页 文章

OpenGL:如何通过通道,通过采样和渲染到相同的纹理来写入纹理通道

提问于
浏览
0

场景是:我有一个纹理A.有3个循环 . 每个循环将一个通道写入纹理A.在3个循环之后,A中的所有3个通道都会更新 .

着色器如下:

vec3 tmpVec3 = texture(inputTexture0, vUV).rgb; // inputTexture0 is texture A tmpVec3[channelIndex_P] = texture(inputTexture1, vUV).r;  // write one channel from inputTexture1

color = vec4(tmpVec3, 1.0);

它渲染到纹理A,即inputTexture0 . 通过这种方式渲染和采样相同的纹理,我可以通过一个纹理节省内存 .

但是,结果是不希望的 .

我读了一篇文章“Sampling and Rendering to the Same Texture” . 它说:

“意味着它可以做你想要的,采样器可能得到旧数据,采样器可能得到一半旧数据,或者它可能得到垃圾数据 . 这些都是可能的结果 . ”

但由于特定像素的写入数据总是在获取特定像素的数据后发生,为什么不可能呢?

另一篇文章“Sampling from and rendering to the same texture and parallel sorting / hashing”它说:

“但是如果每个帧缓冲像素中的结果都是写入该像素的片段之一的值而不是来自多个片段的值的组合,则此功能对于在glsl中实现的并行排序/散列算法仍然有用 . “

我不明白上面的话 . 是否说在某些情况下可以使用“采样和渲染到相同纹理”并定义结果 . 那怎么办呢?如何解决我目前的情况,因为我想保存一个纹理变量 .

1 回答

  • 1

    那么请你解释为什么我的情况无法解决,因为兴趣流程的写作和阅读不是同时进行的 .

    它们绝对是在同一时间处理的,我认为你不了解如何在GPU上安排着色器 . 片段着色器不会串行运行,并且在并行调用读取相同纹理之前,您不必完成写入纹理的尝试(也不保证纹理内存不会被缓存;对内存的更改不可见) .

    这就是你需要障碍的原因 . 纹理屏障(NV特定扩展)或通用内存屏障将导致着色器调用在屏障处停止,直到着色器的每个实例完成读取或写入,然后继续 . 这样可以防止导致读取错误数据的数据危险 .

    要在GL3类实现中执行此操作,纹理障碍可能是您唯一的选择 . 在GL4.2中,图像加载/存储将是首选方法,一些较旧的实现通过GL_ARB_shader_image_load_store扩展支持此功能 .

    但是,如果没有这些东西,你现在要做的就是调用未定义的行为 . 您需要某种同步构造才能正确执行此操作,这就是障碍的来源 .

相关问题