DirectX 11计算着色器 - 不写入所有值

时间:2009-11-20 18:32:24

标签: directx-11 compute-shader

我正在尝试使用DirectX11计算着色器进行分形渲染的一些实验。 提供的示例在FeatureLevel_10设备上运行。

我的RwStructured输出缓冲区的数据格式为R32G32B32A32_FLOAT

问题是,当写入缓冲区时,似乎只有ALPHA(w)值才会被写入其他内容.... 这是着色器代码:

struct BufType { float4 value; };

cbuffer ScreenConstants : register(b0) { float2 ScreenDimensions; float2 Padding; };

RWStructuredBuffer BufferOut : register(u0);

[numthreads(1, 1, 1)] void Main( uint3 DTid : SV_DispatchThreadID ) { uint index = DTid.y * ScreenDimensions.x + DTid.x;

float minRe = -2.0f;
float maxRe = 1.0f;
float minIm = -1.2;
float maxIm = minIm + ( maxRe - minRe ) * ScreenDimensions.y / ScreenDimensions.x;
float reFactor = (maxRe - minRe ) / (ScreenDimensions.x - 1.0f);
float imFactor = (maxIm - minIm ) / (ScreenDimensions.y - 1.0f);
float cim = maxIm - DTid.y * imFactor;

uint maxIterations = 30;

float cre = minRe + DTid.x * reFactor;
float zre = cre;
float zim = cim;

bool isInside = true;
uint iterationsRun = 0;

for( uint n = 0; n < maxIterations; ++n )
{
    float zre2 = zre * zre;
    float zim2 = zim * zim;

    if ( zre2 + zim2 > 4.0f )
    {
        isInside = false;
        iterationsRun = n;
    }

    zim = 2 * zre * zim + cim;
    zre = zre2 - zim2 + cre;
}

if ( isInside )
{ 
    BufferOut[index].value = float4(1.0f,0.0f,0.0f,1.0f);
}

}

代码实际上在某种意义上产生了正确的结果(2D Mandelbrot集),但似乎只是触摸了alpha值而没有写任何其他内容,尽管集合中的像素应该是红色的......(图像是黑与白)

任何人都知道这里发生了什么?

5 个答案:

答案 0 :(得分:1)

经过一番摆弄后,我发现了问题。 我没有找到MS提到的任何文档,所以它也可能是一个Nvidia 具体的司机问题。

显然,您只能将每个计算着色器调用的ONCE写入RWSructuredBuffer中的相同元素。而且你也必须写ONCE。

我更改了代码以在局部变量中累积正确的颜色,现在只在着色器的末尾写一次。

现在这一切都很完美。

答案 1 :(得分:0)

我不确定,但不应该是BufferOut decl:

RWStructuredBuffer<BufType> BufferOut : register(u0);

而不是:

RWStructuredBuffer BufferOut : register(u0);

如果您只使用float4写入目标,为什么不使用:

RWBuffer<float4> BufferOut : register (u0);

也许这可能有所帮助。

答案 2 :(得分:0)

今天再玩一遍之后,我又遇到了同样的问题。 以下代码生成了所有白色输出:

[numthreads(1, 1, 1)]
void Main( uint3 dispatchId : SV_DispatchThreadID )
{
    float4 color = float4(1.0f,0.0f,0.0f,1.0f);
    WriteResult(dispatchId,color);
}

WriteResult方法是我的hlsl标准库中的实用方法。

长话短说。在我从驱动程序版本192升级到195(测试版)后,问题就消失了。 似乎驱动程序在计算着色器支持中存在一些明确的问题,所以要小心。

答案 3 :(得分:-1)

从我看到的情况来看,计算机着色器仅在您需要比传统像素着色器更通用的计算模型时才有用,或者如果您可以加载数据然后在快速共享内存中的线程之间共享它。我相当肯定你会用mandelbrot着色器的像素着色器获得更好的性能。

在我的设置(win7,feb 10 dx sdk,gtx480)上,我的计算着色器的设置时间超过0.2-0.3ms(绑定SRV和UAV然后调用dispatch())。

如果您执行PS实施,请发布您的经验。

答案 4 :(得分:-3)

我对DX计算着色器没有直接经验,但是......

为什么要设置alpha = 1.0?

IIRC,它使像素100%透明,因此你的内部像素是透明的红色,并显示为在它们后面绘制的任何颜色。 当alpha = 1.0时,从不使用RGB组件。