码迷,mamicode.com
首页 > 其他好文 > 详细

在DirectX 12中使用geometry shader

时间:2021-05-24 08:36:50      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:prope   position   float   first   load   des   游戏   for   oat   

几何着色器可以允许我们在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

标签:prope   position   float   first   load   des   游戏   for   oat   

原文地址:https://www.cnblogs.com/back-to-the-past/p/14766760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!