【问题标题】:(glsl/hlsl) Integrating over 1 dimension of a 2D texture(glsl/hlsl) 积分超过 1 维的 2D 纹理
【发布时间】:2014-10-25 00:32:01
【问题描述】:

我的问题:

我需要一个着色器来对二维纹理的每一行执行某种累积和。例如,新纹理的像素 [3,3] 应该是源纹理的像素 [1,3]、[2,3] 和 [3,3] 的总和。换句话说,就是数值积分。

我的纹理大小最终可能会在 64x64 到 256x256 纹素之间,具体取决于性能,因此对每个像素求和可能是不可能的。

不幸的是,不能在一维纹理数组上使用自动 mipmap 生成,因为我实际上并没有进行 常规 添加。但是,我应该可能能够适应使用加法的手动解决方案。

注意:我同时使用 GLSL 和 HLSL,但它们似乎几乎完全兼容。


目前的想法:

我目前的想法是在像素着色器中执行一种手动 1d mipmap(使用非插值纹理提取),但可能将每个 mipmap 级别的大小减少 4 或 8 倍,而不仅仅是 2。

例如:

  1. 原始 (Sum-0)。 [64x64]。
  2. 总和-1。 [64x64] -> [16x64]。
  3. 总和-2。 [16x64] -> [4x64]。
  4. 总和-3。 [4x64] -> [1x64]。 (每一行的总数)。

一旦完成,我会向下遍历 mipmap 级别(从最小开始),将前一个级别的累积总和(调整大小和偏移量 1)添加到同一行段中先前纹素的总和,并放入一个新的纹理。

level-N-accum[(a*width)+b,y] =
  level-N+1-accum[a-1,y]
    +
  sum(first b pixels starting from level-N-sum[a*width,y])

例如:

  1. Accum-2。 [4x64] = (Sum-2 + Sum-3)
  2. Accum-1。 [16x64] = (Sum-1 + Accum-2)
  3. 结果(Accum-0)。 [64x64] = (Sum-0 + Accum-1)

这给了我一个 O(ln(X)) 的每像素复杂度。


我的问题:

  1. 这是正确的方法还是有更好的方法?
  2. 使用计算(尚未使用)会更好吗?

【问题讨论】:

  • "...对每个像素进行蛮力求和可能是不可能的..." 为什么这是不可能的? GPU 非常擅长做这种事情。
  • 我的意思是每个像素都会将它之前的所有像素相加,这意味着 pixel[256,N] 需要获取并添加 256 个值。总体而言,这意味着 256x256 纹理需要进行 ~((256^3)/2) 个样本(=~800 万)。我目前的方式是 (256x256xlog2(256))/log2(width) = ~262144 个样本。
  • 这与“前缀总和”或“扫描”非常相似。有很多已建立的基于 GPU 的算法应该很容易适应同时在多行上操作,并保持中间值(例如this one)。但是,如果您的纹理有超过 512 行,您将获得足够的并行度,因此蛮力选项实际上可能会更好。
  • 感谢您的链接,我会研究一下 - 首先我必须在 glsl/hlsl 上实现计算。
  • 也许我误用了蛮力这个词。我的意思是让每个像素独立地对其之前的所有像素进行自己的简单求和,这意味着对于宽度为 N 纹素的每一行,需要大约 N*N*0.5 纹素查找。不过,我不认为这就是你的意思。

标签: opengl glsl shader direct3d hlsl


【解决方案1】:
猜你喜欢
  • 2012-09-28
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多