【问题标题】:Writing a HLSL4 pixel shader to perform a lookup from a 2Dtexture编写 HLSL 像素着色器以从 2d 纹理执行查找
【发布时间】:2011-12-06 14:22:35
【问题描述】:

我是一个初学者像素着色器作家,我遇到了一些麻烦。我想获取一个 256x256 的 16 位输入 (DXGI_FORMAT_R16_UINT) 图像,并通过 256x256 查找纹理 (DXGI_FORMAT_R8_UNORM) 将其转换为 256x256 8 位输出。

不幸的是,我似乎遇到了很多麻烦,输出似乎总是固定为黑色或白色。

另外,我不确定我应该使用哪种 DXGI 格式,以及哪种数据类型与每种格式相关。

// Global Variables
Texture2D<uint> imgTexture : register( t0 );
Texture2D lutTexture : register( t1 );
SamplerState SampleType : register( s0 );

// Structures 
struct PS_INPUT
{
  float4 Pos : SV_POSITION;
  float2 Tex : TEXCOORD0;
};

// Pixel Shader
float4 PS( PS_INPUT input) : SV_Target
{
  uint pixelValue = imgTexture[input.Tex];
  uint2 index = { pixelValue / 256, pixelValue % 256 };
  // uint row = pixelValue / 256;
  // uint col = pixelValue % 256;

  float4 output = lutTexture[index];
  output.g = output.r;
  output.b = output.r;
  output.a = 1.0f;

  return output;    
}

在尝试将其转换为 2D 索引之前,我应该对 pixelValue 进行规范化吗?

我应该在使用索引之前对其进行规范化吗?

我应该改为抽样吗?

我在这里走对了吗?

如果有任何帮助,我将不胜感激,谢谢!

【问题讨论】:

  • 只是好奇,你为什么要这样做?显然,您想实时执行此操作(即离线转换不是一种选择)但是(好吧,我在重复自己)但是为什么呢?
  • 嗯,我正在显示医学图像数据,它以 8 位到 12 位(灰度)数据的形式出现。该数据还带有 LUT,它指定了在将图像放到屏幕之前需要应用到图像的亮度变换。所以,实际上,我只想使用最多 12 位的 16 位输入,然后将 LUT 应用到那个……困惑吗?我知道我是……
  • 一件事可能只是黑/白的问题;通常值是从 0 到 1,而不是纹理中的 0 到 255。
  • 是的,目前可能遇到了这样的问题。我的“0”和“255”值可能会出现舍入/截断错误...

标签: hlsl lookup-tables pixel-shader direct3d11


【解决方案1】:

您绝对是在正确的轨道上。但是,就像 Valmond 提到的那样,pixelValue 的值将在 [0..1] 范围内。

LUT 究竟是如何设置的?我猜第一个轴是要转换的值,但第二个是什么?一旦我知道了,我可以用代码给出一个解决方案。

【讨论】:

  • @Valmond 在此期间,我一直在做其他一些事情,但我通过乘以 65535 然后进行除法和模数数学运算,将它们组合在一起。但是,我想知道“正确”的方式。迈克,我不确定我是否完全理解你的问题。如果 LUT 是 1d,它将从索引 0-65535 运行,并且在每个索引内将是新的灰度映射(值 b/w 0-255)。然而,由于纹理不支持这一点,我将其包装成 256x256,然后做我的时髦数学将 16 位“强度”映射到 256x256 查找。
  • 因为 imgTexture 是 Texture2D 和 DXGI_FORMAT_R16_UINT,结果没有被标准化,在这种情况下它是原始值 (0 -> MAX_USHORT)
【解决方案2】:

您正在使用:

uint pixelValue = imgTexture[input.Tex];

这需要像素值,但您提供的是 input.Tex(我猜它是从 0 标准化到 1)。 因此,在这种情况下,您正在加载相同的像素。

你可以使用:

uint pixelValue = imgTexture[input.Pos.xy];

或:

uint pixelValue = imgTexture.Load(int3(input.Pos.xy, 0));

改为。

是的,您的格式对于您的用例是正确的(无需规范化或非规范化)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多