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

发布于 2024-08-12 03:54:51 字数 1616 浏览 13 评论 0原文

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

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

问题是,在写入缓冲区时,似乎只写入了 ALPHA ( w ) 值,没有写入其他值...... 这是着色器代码:

struct BufType
{
    float4 value;
};

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

RWStructuredBuffer<BufType> 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 值,而没有写入任何其他内容,尽管该集内的像素应为红色...... (图像是黑白的)

有人知道这里发生了什么吗?

I am trying some experiments in fractal rendering with DirectX11 Compute Shaders.
The provided example runs on a FeatureLevel_10 device.

My RwStructured output buffer has a data format of R32G32B32A32_FLOAT

The problem is that when writing to the buffer, it seems that only the ALPHA ( w ) value gets written nothing else....
Here is the shader code:

struct BufType
{
    float4 value;
};

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

RWStructuredBuffer<BufType> 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);
    }
}

The code actually produces in a sense the correct result ( 2D Mandelbrot set ) but it seems somehow only the alpha value is touched and nothing else is written, although the pixels inside the set should be colored red... ( the image is black & white )

Anybody has a clue what's going on here ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

远山浅 2024-08-19 03:54:51

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

显然,每次计算着色器调用只能向 RWSructuredBuffer 中的同一元素写入一次。而且你还必须写一次。

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

现在一切都以这种方式完美运行。

After some fiddling around i found the problem.
I have not found any documentation from MS mentioning this, so it could also be a Nvidia
specific driver issue.

Apparently you are only allowed to write ONCE per Compute Shader Invocation to the same element in a RWSructuredBuffer. And you also HAVE to write ONCE.

I changed the code to accumulate the correct color in a local variable, and write it now only once at the end of the shader.

Everything works perfectly now in that way.

时光与爱终年不遇 2024-08-19 03:54:51

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

RWStructuredBuffer<BufType> BufferOut : register(u0);

而不是 :

RWStructuredBuffer BufferOut : register(u0);

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

RWBuffer<float4> BufferOut : register (u0);

也许这会有所帮助。

I'm not sure but, shouldn't it be for BufferOut decl:

RWStructuredBuffer<BufType> BufferOut : register(u0);

instead of :

RWStructuredBuffer BufferOut : register(u0);

If you are only using a float4 write target, why not use just:

RWBuffer<float4> BufferOut : register (u0);

Maybe this could help.

最笨的告白 2024-08-19 03:54:51

今天又玩了一下,又遇到了同样的问题。
以下代码产生全白色输出:

[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(测试版)后,问题就消失了。
看起来驱动程序在计算着色器支持方面还存在一些明确的问题,所以要小心。

After playing around today again, i ran into the same problem once again.
The following code produced all white output:

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

The WriteResult method is a utility method from my hlsl standard library.

Long story short. After i upgraded from Driver version 192 to 195(beta) the problem went away.
Seems like the drivers have some definitive problems in compute shader support left, so beware.

暮凉 2024-08-19 03:54:51

据我所知,只有当您需要比传统像素着色器更通用的计算模型,或者您可以加载数据然后在快速共享内存中的线程之间共享数据时,计算机着色器才有用。我相当确定使用 Mandelbrot 着色器的像素着色器会获得更好的性能。

在我的设置(win7、2 月 10 日 dx sdk、gtx480)中,我的计算着色器的设置时间超过 0.2-0.3 毫秒(绑定 SRV 和 UAV,然后调用调度())。

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

from what ive seen, computer shaders are only useful if you need a more general computational model than the tradition pixel shader, or if you can load data and then share it between threads in fast shared memory. im fairly sure u would get better performance with a pixel shader for the mandelbrot shader.

on my setup (win7, feb 10 dx sdk, gtx480) my compute shaders have a punishing setup time of over 0.2-0.3ms (binding a SRV and a UAV and then calling dispatch()).

if u do a PS implementation please post your experiences.

○愚か者の日 2024-08-19 03:54:51

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

为什么要设置 alpha = 1.0?

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

I have no direct experience with DX compute shaders but...

Why are you setting alpha = 1.0?

IIRC, that makes the pixel 100% transparent, so your inside pixels are transparent red, and show up as whatever color was drawn behind them.
When alpha = 1.0, the RGB components are never used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文