Re: computeshader & rendertexture in cryengine 5

#3
You can use compute shaders and rendertargets in cryengine ofcourse with lightning speeds since you have access to source code itself. The render stages are packed nicely in cryrender. Add a stage to standardgraphics pipeline, and implement a compute shader in it. Also add a manager with an interface in crycommon to set get data from buffers. Rendering done in a different thread as usual. There are predefined passes like scene, fullscreen etc where you can do all sorts of things. I have made an infinite terrain doing all height and normal calculation in gpu so yes. Cryengine is a huge program, the renderer written very well. It was a good read.

Re: computeshader & rendertexture in cryengine 5

#5
Okey, here is an example.

Code: Select all

//// These are stucts for gpu in CryCommon IRenderNode.h ////////////////// struct TerrainDataIn { Matrix44 heightfield; float findex_x; float findex_y; }; struct TerrainDataOut { Vec3 position; Vec3 tangent; Vec3 bitangent; }; /////////////////////////////////////////////////////////////

Code: Select all

//// A Manager to communicate with render thread. This is in IRenderer.h and implemented in CD3D9Renderer //// class ITerrainManager { public: ..... virtual void PushTerrainComputeItem(TerrainComputeItem* pTerrainItem) = 0; virtual TerrainComputeItem* PopTerrainComputeItem(int pId) = 0; }; ////////////////////////////////////////////////////////////

Code: Select all

//// An example stage TerrainStage.h implemented in CryRenderD3D11/GraphicsPipeline //// #pragma once #include "Gpu/GpuComputeBackend.h" #include "Common/GraphicsPipelineStage.h" #include "GraphicsPipeline/Common/ComputeRenderPass.h" class CTerrainStage : public CGraphicsPipelineStage { public: CTerrainStage(); ~CTerrainStage(); void Init() final; void Execute(); CTerrainManager* GetTerrainManager() { return m_pTerrainManager.get(); } private: std::unique_ptr<CTerrainManager> m_pTerrainManager; CGpuBuffer m_bufferIn; gpu::CTypedResource<TerrainDataOut, gpu::BufferFlagsReadWriteReadback> m_bufferOut; CComputeRenderPass m_Pass; };

Code: Select all

//// TerrainStage.cpp implemented at CryRenderD3D11/GraphicsPipeline //// #include "StdAfx.h" #include "TerrainStage.h" #include "../../Common/RenderPipeline.h" #include "DriverD3D.h" CTerrainStage::CTerrainStage() : m_Pass(CComputeRenderPass::eFlags_None), m_bufferOut(VertexCount) // Total number of vertices in a patch, defined in somewhere { m_bufferOut.CreateDeviceBuffer(); } CTerrainStage::~CTerrainStage() { m_bufferOut.FreeDeviceBuffer(); m_bufferIn.Release(); m_Pass.Reset(); } void CTerrainStage::Init() { if (!m_pTerrainManager) m_pTerrainManager = std::unique_ptr<CTerrainManager>(new CTerrainManager()); m_bufferIn.Create(VertexCount, sizeof(TerrainDataIn), DXGI_FORMAT_UNKNOWN, CDeviceObjectFactory::USAGE_STRUCTURED | CDeviceObjectFactory::BIND_SHADER_RESOURCE, NULL); } void CTerrainStage::Execute() { PROFILE_LABEL_SCOPE("TERRAIN_STAGE"); TerrainComputeItem* item = m_pTerrainManager->PopTerrainComputeItem(); TerrainDataIn* data = item->m_Data; CDeviceCommandListRef pCoreInterface(GetDeviceObjectFactory().GetCoreCommandList()); m_bufferIn.UpdateBufferContent(data, sizeof(TerrainDataIn)); static CCryNameTSCRC technique("ComputeTerrain"); // This name should be same as in cfx file m_Pass.SetTechnique(CShaderMan::s_shDeferredShading, technique, 0); m_Pass.SetBuffer(0, &m_bufferIn); // bind input m_Pass.SetOutputUAV(0, &m_bufferOut.GetBuffer()); // bind output m_Pass.PrepareResourcesForUse(pCoreInterface); const bool bAsynchronousCompute = CRenderer::CV_r_D3D12AsynchronousCompute & BIT((eStage_Terrain - eStage_FIRST_ASYNC_COMPUTE)) ? true : false; SScopedComputeCommandList computeCommandList(bAsynchronousCompute); m_Pass.Execute(computeCommandList, EShaderStage_Compute); m_bufferOut.Readback(VertexCount); const TerrainDataOut* out = m_bufferOut.Map(VertexCount); // Get the output if (out) { // Do stuff, pass data out } m_bufferOut.Unmap(); // clean uint clearNull[4] = { 0 }; pCoreInterface.GetComputeInterface()->ClearUAV(m_bufferOut.GetBuffer().GetDevBuffer()->LookupUAV(EDefaultResourceViews::UnorderedAccess), clearNull, 0, nullptr); } ITerrainManager* CD3D9Renderer::GetTerrainManager() { return GetGraphicsPipeline().GetTerrainStage()->GetTerrainManager(); }

Who is online

Users browsing this forum: No registered users and 2 guests