使用计算着色器 return 纹理是否具有特定颜色
Using compute shader to return whether texture has certain colour
我正在编写一个计算着色器(在统一环境中,它使用 DirectX11 DirectCompute),我需要做一个非常简单的任务:检查图像中是否有任何像素具有绿色 == 1 和蓝色 > 0.5。 (为清楚起见 - 绿色通道是 2d "light",蓝色通道是光 "trail" - 我想检测光何时穿过它的轨迹。)
我只是出于调试目的显示重叠(以白色显示),但我不知道如何做一些简单的事情 return 指示纹理是否实际包含重叠的值.我的困惑源于线程的工作方式。我有一个浮点缓冲区,可以容纳一个浮点数——我只需要一个 1 或 0。
为了澄清,以下两张图片显示了 "before" 和 "after" - 我只需要一个 "true" 值告诉我第二张图片中存在一些白色。
计算着色器如下:
#pragma kernel CSMain
Texture2D<float4> InputTexture;
RWTexture2D<float4> OutputTexture;
RWStructuredBuffer<float> FloatBuffer;
[numthreads(8,8,1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
// need to detect any region where g == 1 and blue > 0.5
float green = InputTexture[id.xy].g;
float blue = round(InputTexture[id.xy].b);
float overlap = round((green + blue) / 2.0);
OutputTexture[id.xy] = float4(overlap, overlap, overlap, 1);
// answer here?? Note that the output texture is only for debugging purposes
FloatBuffer[0] = ??
}
您可以选择使用原子操作和计算像素。你 运行 你的计算着色器每个像素一个线程,如果像素符合标准,增加你的 rwbuffer。
像这样:
Texture2D<float4> InputTexture;
RWBuffer<uint> NotAFloatBuffer;
[numthreads(8,8,1)]
void CSMain(uint3 id : SV_DispatchThreadID {
// need to detect any region where g == 1 and blue > 0.5
float green = InputTexture[id.xy].g;
float blue = round(InputTexture[id.xy].b);
float overlap = round((green + blue) / 2.0);
if (overlap > 0)
InterlockedAdd(NotAFloatBuffer[0],1);
}
在你的情况下,你可以停在这里,但原子有一些小的成本惩罚,并且通常通过将来自你组中一个线程的调用分组并事先减少来优化它们,但这只是在最极端的情况下,你不必担心。
我正在编写一个计算着色器(在统一环境中,它使用 DirectX11 DirectCompute),我需要做一个非常简单的任务:检查图像中是否有任何像素具有绿色 == 1 和蓝色 > 0.5。 (为清楚起见 - 绿色通道是 2d "light",蓝色通道是光 "trail" - 我想检测光何时穿过它的轨迹。)
我只是出于调试目的显示重叠(以白色显示),但我不知道如何做一些简单的事情 return 指示纹理是否实际包含重叠的值.我的困惑源于线程的工作方式。我有一个浮点缓冲区,可以容纳一个浮点数——我只需要一个 1 或 0。
为了澄清,以下两张图片显示了 "before" 和 "after" - 我只需要一个 "true" 值告诉我第二张图片中存在一些白色。
计算着色器如下:
#pragma kernel CSMain
Texture2D<float4> InputTexture;
RWTexture2D<float4> OutputTexture;
RWStructuredBuffer<float> FloatBuffer;
[numthreads(8,8,1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
// need to detect any region where g == 1 and blue > 0.5
float green = InputTexture[id.xy].g;
float blue = round(InputTexture[id.xy].b);
float overlap = round((green + blue) / 2.0);
OutputTexture[id.xy] = float4(overlap, overlap, overlap, 1);
// answer here?? Note that the output texture is only for debugging purposes
FloatBuffer[0] = ??
}
您可以选择使用原子操作和计算像素。你 运行 你的计算着色器每个像素一个线程,如果像素符合标准,增加你的 rwbuffer。
像这样:
Texture2D<float4> InputTexture;
RWBuffer<uint> NotAFloatBuffer;
[numthreads(8,8,1)]
void CSMain(uint3 id : SV_DispatchThreadID {
// need to detect any region where g == 1 and blue > 0.5
float green = InputTexture[id.xy].g;
float blue = round(InputTexture[id.xy].b);
float overlap = round((green + blue) / 2.0);
if (overlap > 0)
InterlockedAdd(NotAFloatBuffer[0],1);
}
在你的情况下,你可以停在这里,但原子有一些小的成本惩罚,并且通常通过将来自你组中一个线程的调用分组并事先减少来优化它们,但这只是在最极端的情况下,你不必担心。