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)
    

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

  • 相关阅读:
    Hive之序列化与反序列化(SerDe)
    Hive从入门到精通
    HIVE从路人到入门
    Intel IDEA 2018破解(亲测成功)
    在小红家里面,有n组开关,触摸每个开关,可以使得一组灯泡点亮。
    一个n*n 的方格,要从左上角走到右下角,一次只能往右或往下走一步,求算法得出所有走动的方法数。
    Ionic3多个自定义过滤器--管道(pipe)
    ionic3 添加多个自定义组件
    ionic3 slides轮播图手动滑动后无法自动播放问题
    Vue2.2版本学习小结
  • 原文地址:https://www.cnblogs.com/back-to-the-past/p/14766760.html
Copyright © 2011-2022 走看看