[C++]DirectX 12 3D游戏开发实战—第13章 学习笔记07 2019.5.18

本文介绍了在DirectX 12中使用BlurFilter类进行3D游戏开发,详细阐述了BlurFilter的实现原理,包括如何利用计算着色器进行模糊处理,探讨了线程组调度、纹理资源管理和共享内存优化。同时,提到了Sobel算子在边缘检测中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

词汇

Sobel Operator

内容

假设所使用模糊算法具有可分离性,将模糊分为两个1D模糊运算,用两个纹理分别绑定SRV和UAV进行处理。
对处理后的图像可以进行反复的模糊处理来打达到更好的模糊效果

void BlurApp::OnResize()
{
    D3DApp::OnResize();

    // The window resized, so update the aspect ratio and recompute the projection matrix.
    XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);
    XMStoreFloat4x4(&mProj, P);

	if(mBlurFilter != nullptr)
	{
		mBlurFilter->OnResize(mClientWidth, mClientHeight);
	}
}


void BlurFilter::OnResize(UINT newWidth, UINT newHeight)
{
	if((mWidth != newWidth) || (mHeight != newHeight))
	{
		mWidth = newWidth;
		mHeight = newHeight;
		//用心的大小重新构建离屏纹理资源
		BuildResources();

		//为新的资源创建新的描述符
		BuildDescriptors();
	}
}

BlurFilter类

BlurFilter封装了纹理资源,为使用绘制/分派命令,则需要将这些资源绑定到渲染流水线上,因此需要为它们创建相应的描述符。要在D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV类型的描述符堆中开辟额外的空间存储这些描述符。
BlurFilter::BuildDescriptors方法:利用堆中起始位置的描述符句柄来存储BlurFilter类要用到的描述符。该方法缓存了模糊过程中所需的一切描述符句柄,并以此来创建相应的描述符。利用该函数缓存句柄的原因在于当窗口发生改变时,它可以随资源的变化重新创建这些描述符:

void BlurFilter::BuildDescriptors()
{
	//保存对描述符的引用
	D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
	srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
	srvDesc.Format = mFormat;
	srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
	srvDesc.Texture2D.MostDetailedMip = 0;
	srvDesc.Texture2D.MipLevels = 1;

	D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};

	uavDesc.Format = mFormat;
	uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
	uavDesc.Texture2D.MipSlice = 0;

	md3dDevice->CreateShaderResourceView(mBlurMap0.Get(), &srvDesc, mBlur0CpuSrv);
	md3dDevice->CreateUnorderedAccessView(mBlurMap0.Get(), nullptr, &uavDesc, mBlur0CpuUav);

	md3dDevice->CreateShaderResourceView(mBlurMap1.Get(), &srvDesc, mBlur1CpuSrv);
	md3dDevice->CreateUnorderedAccessView(mBlurMap1.Get(), nullptr, &uavDesc, mBlur1CpuUav);
}
//创建BlurFilter
	mBlurFilter->BuildDescriptors(
		CD3DX12_CPU_DESCRIPTOR_HANDLE(mCbvSrvUavDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), 3, mCbvSrvUavDescriptorSize),
		CD3DX12_GPU_DESCRIPTOR_HANDLE(mCbvSrvUavDescriptorHeap->GetGPUDescriptorHandleForHeapStart(), 3, mCbvSrvUavDescriptorSize),
		mCbvSrvUavDescriptorSize);

模糊处理是一项代价高昂的操作,耗费的时间与待处理的图像大小有关。一般情况下,将场景渲染到离屏纹理的时候会将离屏纹理大小设为后台缓冲区尺寸的四分之一来加快离屏纹理的绘制速度。然后再将屏幕分辨率展开为完整的屏幕分辨率。

假设需要处理的图像宽为w高为h,对于1D纵向模糊而言,一个线程组用256个线程处理水平方向上的线段,而每个线程负责图像中一个像素的模糊操作。因此为了图像中每个像素都会被模糊处理,则需要在x方向分派 c e i l ( w 256 ) ceil(\frac{w}{256}) ceil(256

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值