1

我正在尝试使用 HLSL 和 Direct3D 11 进行一些 GPGPU 计算。我的目标是按顺序计算多个图像(每个图像一个渲染),然后对它们求和。

为了实现这一点,我创建了三个纹理:一个是输入,两个用于汇总结果。我正在尝试的方法:首先我渲染到纹理 2(我使用纹理和纹理 3 纹理作为输入),然后我使用稍微修改的像素着色器渲染到纹理 3(我使用纹理和纹理 2 纹理作为输入)。在此之后,我将纹理转储到 PNG 文件中。我的问题是,不知何故,第二个像素着色器没有得到第一个着色器(texture2)的结果,而是原始的空纹理。我使用 D3D11_USAGE_DEFAULT 和 D3D11_BIND_RENDER_TARGET | 定义了纹理、纹理 2 和纹理 3。D3D11_BIND_SHADER_RESOURCE 绑定标志。

我的 HLSL 着色器(shader1):

float4 main(PS_INPUT input) : SV_TARGET
{
...
float4 val5 = 0.25F * (val + val2 + val3 + val4) + tex3.Sample(sam, input.Tex4);
return val5;
}

另一个着色器(shader2):

float4 main(PS_INPUT input) : SV_TARGET
{
...
float4 val5 = 0.25F * (val + val2 + val3 + val4) + tex2.Sample(sam, input.Tex4);
return val5;
}

执行纹理渲染和转储的代码:

context->OMSetRenderTargets(1, &targetViewTexture2, NULL);

float z = 280.0F;
GenMatrix(z);
context->VSSetShader(vs, NULL, 0);
context->PSSetShader(ps, NULL, 0);
context->PSSetSamplers(0, 1, &state);
context->VSSetConstantBuffers(0, 1, &cbuf);
context->Draw(6, 0);
swapChain->Present(0, 0);

context->OMSetRenderTargets(1, &targetViewTexture3, NULL);
z = 0.0F;
GenMatrix(z);
context->VSSetShader(vs, NULL, 0);
context->PSSetShader(ps2, NULL, 0);
context->PSSetSamplers(0, 1, &state);
context->VSSetConstantBuffers(0, 1, &cbuf);
context->Draw(6, 0);
swapChain->Present(0, 0);
DirectX::ScratchImage im;
DirectX::CaptureTexture(device, context, texture3, im);
const DirectX::Image *realImage = im.GetImage(0, 0, 0);
HRESULT hr2 = DirectX::SaveToWICFile(*realImage, DirectX::WIC_FLAGS_NONE, GUID_ContainerFormatPng, L"output_tex3.png", NULL);
DirectX::CaptureTexture(device, context, texture2, im);
realImage = im.GetImage(0, 0, 0);
hr2 = DirectX::SaveToWICFile(*realImage, DirectX::WIC_FLAGS_NONE, GUID_ContainerFormatPng, L"output_tex2.png", NULL);

第一遍 (ps) 的输出是正确的,但第二遍不是。如果我只留下着色器代码:

    float4 val5 = tex2.Sample(sam, input.Tex4);

我得到一个空图像。我错过了什么吗?我是否必须调用一些方法才能在第二个像素着色器中使用纹理?我想我指出了我的大型代码库的相关部分,但如果您需要更多信息,请在评论部分询问。

4

1 回答 1

1

问题是我将纹理用作输入和输出。您可以一次性使用纹理作为输入或渲染目标。

于 2013-07-30T15:34:33.343 回答