zoukankan      html  css  js  c++  java
  • 在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)
    

    如果你觉得我的文章有帮助,欢迎关注我的微信公众号(大龄社畜的游戏开发之路-

  • 相关阅读:
    技术每天一点点--2020.01-2020.12月
    【置顶】历史书单--程序员的文娱情怀
    【编程书籍 大系】 计算机开放电子书汇总
    Mysql基础代码(不断完善中)
    php 基础代码大全(不断完善中)
    【读书笔记】阅读美团技术团队文章《领域驱动设计在互联网业务开发中的实践》--2020.06.25 周四 端午节
    【置顶】技术每天一点点--2020.01-2020.12
    【日常】技术每天进展--2019.06.10
    【转载】Spring学习(1)——快速入门--2019.05.19
    vs创建qt dll,并使用qt控制台测试
  • 原文地址:https://www.cnblogs.com/back-to-the-past/p/14766760.html
Copyright © 2011-2022 走看看