我正在尝试使用HLSL和Direct3D 11进行一些GPGPU计算。 我的目标是按顺序计算几个图像(每个图像一个渲染),然后将它们相加。
为了实现这一点,我创建了三个纹理:一个是输入,两个用于总结结果。我正在尝试的方法:首先我渲染到texture2(我使用纹理和纹理3纹理作为输入),然后我使用略微修改的像素着色器渲染到texture3(我使用纹理和texture2纹理作为输入)。在此之后,我将纹理转储到PNG文件。我的问题是,不知何故,第二个像素着色器没有得到第一个着色器(texture2)的结果,而是原始的空纹理。我使用D3D11_USAGE_DEFAULT和D3D11_BIND_RENDER_TARGET |来定义纹理,texture2和texture3。 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);
我得到一张空图片。我错过了什么吗?我是否必须调用某些方法在第二个像素着色器中使用纹理?我想我已经确定了我的大型代码库的相关部分,但如果您需要更多信息,请在评论部分中提出。
答案 0 :(得分:1)
问题是我使用纹理作为输入和输出。您可以在一次传递中将纹理用作输入或渲染目标。