Re: computeshader & rendertexture in cryengine 5

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

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
   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
   void Init() final;
   void Execute();

   CTerrainManager* GetTerrainManager() { return m_pTerrainManager.get(); }

   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"

   : m_Pass(CComputeRenderPass::eFlags_None),
   m_bufferOut(VertexCount) // Total number of vertices in a patch, defined in somewhere



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()
   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


   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);
   const TerrainDataOut* out = m_bufferOut.Map(VertexCount); // Get the output
   if (out)
      // Do stuff, pass data out
   // 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 1 guest