在DirectX 12中使用geometry shader
Posted 异次元的归来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在DirectX 12中使用geometry shader相关的知识,希望对你有一定的参考价值。
几何着色器可以允许我们在GPU中增加,删除,修改传入的顶点属性。一个常见的用途是billboard,视野远处的物体直接用一个永远面向摄像机的面片来代替,并且这个面片实际上可以由1个点通过几何着色器输出4个顶点来生成。
首先,我们需要定义新的顶点类型,和相应的input layout:
struct PointVertex
{
XMFLOAT3 position;
XMFLOAT2 size;
};
mPointInputLayout =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
{"SIZE", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}
};
由于新增了一种顶点类型,也需要新增对应该类型的vertex buffer和vertex buffer view:
ThrowIfFailed(mDevice->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(mVertexBufferSize * sizeof(PointVertex)),
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&mPointVertexBufferGPU)));
mPointVertexBufferView.BufferLocation = mPointVertexBufferGPU->GetGPUVirtualAddress();
mPointVertexBufferView.SizeInBytes = mVertexBufferSize * sizeof(PointVertex);
mPointVertexBufferView.StrideInBytes = sizeof(PointVertex);
为了使用geometry shader,我们需要在编译的时候把它带进去:
D3DCompileFromFile(srcFile.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "GS", "gs_5_0", compileFlags, 0, gs, &error);
相应地,需要创建一个新的pipeline state object:
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
psoDesc.GS = { gs->GetBufferPointer(), gs->GetBufferSize() };
psoDesc.InputLayout = { mPointInputLayout.data(), mPointInputLayout.size() };
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
值得一提的是,我们可能希望为不同的billboard设置不同的texture。而设置texture需要在绘制不同的object时设置不同的shader resource view。为了避免频繁切换view,可以使用texture2darray,将相关的texture合并起来:
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Format = res->GetDesc().Format;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.ArraySize = res->GetDesc().DepthOrArraySize;
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.MipLevels = -1;
srvDesc.Texture2DArray.MostDetailedMip = 0;
srvDesc.Texture2DArray.PlaneSlice = 0;
srvDesc.Texture2DArray.ResourceMinLODClamp = 0.0f;
这里用到的geometry shader的函数声明如下:
[maxvertexcount(4)]
void GS(point VertexOut gin[1],
uint primID : SV_PrimitiveID,
inout TriangleStream<GeoOut> triStream)
如果你觉得我的文章有帮助,欢迎关注我的微信公众号(大龄社畜的游戏开发之路)-
以上是关于在DirectX 12中使用geometry shader的主要内容,如果未能解决你的问题,请参考以下文章
DirectX 12 应用程序在 Windows 11 中崩溃
DirectX/C++ 3D 引擎编程:立即学习,还是等待 DirectX 12? [关闭]
UWP 硬件视频解码 - DirectX12 与 Media Foundation