DirectX:用计算着色器写入纹理
DirectX : Write to texture with Compute Shader
我试图用hlsl中的compute着色器写入纹理。
创建纹理:
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = 512;
textureDesc.Height = 512;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
m_tex = 0;
hr = device->CreateTexture2D(&textureDesc, 0, &m_tex);
创建无人机:
D3D11_UNORDERED_ACCESS_VIEW_DESC descUAV;
ZeroMemory(&descUAV, sizeof(descUAV));
descUAV.Format = DXGI_FORMAT_UNKNOWN;
descUAV.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
descUAV.Texture2D.MipSlice = 0;
hr = device->CreateUnorderedAccessView(m_tex, &descUAV, &m_uavAccess);
创建SRV(查看纹理(:`
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = textureDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = 1;
hr = device->CreateShaderResourceView(m_tex, &srvDesc, &m_srvTexOutput);
着色器:
RWTexture2D<float4> gOutput : register(u0);
[numthreads(16, 16, 1)]
void main(int3 dispatchThreadID : SV_DispatchThreadID) // Thread ID
{
gOutput[dispatchThreadID.xy] = float4(0.0f, 1.0f, 0.0f, 1.0f);
}
问题是纹理总是黑色的(计算着色器不写入纹理(。
感谢您的帮助!:D
问题在于,您需要在将其用作不同着色器调用(draw/ps(的输入之前使GPU冲洗表面。您可以通过将无效资源绑定到上一个着色器阶段来做到这一点。
ID3D11UnorderedAccessView *NullUav = nullptr;
m_DeviceContext->CSSetUnorderedAccessViews(0, 1, &NullUav, nullptr);
这应该足以告诉图形驱动程序将资源从写入或过渡到读取资源。
如果您使用D3D12或Vulkan,则在从写入到阅读时需要资源障碍。
示例渲染循环:
// Run compute kernel output to UAV.
m_DeviceContext->CSSetShader(m_ComputeShader, NULL, 0);
m_DeviceContext->CSSetUnorderedAccessViews(0, 1, &m_UAV, nullptr);
m_DeviceContext->Dispatch(DispatchX, DispatchY, DispatchZ);
// Run the raster pipeline to present the UAV values to screen.
ID3D11UnorderedAccessView *NullUav = nullptr;
ID3D11ShaderResourceView* NullSrv = nullptr;
ID3D11DepthStencilView *NullDsv = nullptr;
m_DeviceContext->PSSetShader(m_PixelShader, NULL, 0);
m_DeviceContext->VSSetShader(m_VertexShader, NULL, 0);
m_DeviceContext->CSSetUnorderedAccessViews(0, 1, &NullUav, nullptr);
m_DeviceContext->PSSetShaderResources(0, 1, &m_SRV);
m_DeviceContext->IASetIndexBuffer(m_IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
m_DeviceContext->PSSetSamplers(0, 1, &m_SamplerState);
m_DeviceContext->OMSetRenderTargets(1, &m_RenderTarget, NullDsv);
m_ViewPort.Width = (float)RTWidth;
m_ViewPort.Height = (float)RTHeight;
m_ViewPort.MaxDepth = 1.0f;
m_DeviceContext->RSSetViewports(1, &m_ViewPort);
m_DeviceContext->DrawIndexed(4, 0, 0);
// Present the final result.
int Result = m_SwapChain->Present(1, 0);
if (Result == DXGI_ERROR_DEVICE_REMOVED || Result == DXGI_ERROR_DEVICE_RESET) {
// Reinitialize the renderer..
}
// Unset the SRV
m_DeviceContext->PSSetShaderResources(0, 1, &NullSrv);
问题是我在同一纹理上绑定了无人机和srv。
我解决了创建两个纹理的问题:一种绑定到无人机,另一个绑定到SRV。
Compute着色器在UAV上写入,每帧,我都会用deviceContext->CopyResource(m_texSRV, m_texUAV);
现在的问题是性能,CopyResource
是一个昂贵的操作。它还有其他解决方案较便宜吗?
感谢您的帮助!:D
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- SFML纹理像播放器
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 计算着色器 OpenGL 写入纹理
- DirectX:用计算着色器写入纹理
- 在计算着色器中的无序访问视图中写入纹理记录
- 从2D纹理上的位置(x,y)计算.obj文件中的vt(u,v)坐标
- 阴影贴图的纹理坐标计算不正确