cnq3/code/renderer/crp_local.h
myT a76dba5cfb raytracing soft shadows, normal smoothing, G-buffer viz
- brightness-corrected ImGUI drawing
- upgraded shader code to HLSL 2021
- vertex normals drawing
2024-02-06 23:15:31 +01:00

496 lines
11 KiB
C++

/*
===========================================================================
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// Cinematic Rendering Pipeline - private declarations
#pragma once
#include "srp_local.h"
extern cvar_t* crp_dof;
extern cvar_t* crp_dof_overlay;
extern cvar_t* crp_dof_blades;
extern cvar_t* crp_dof_angle;
extern cvar_t* crp_gatherDof_focusNearDist;
extern cvar_t* crp_gatherDof_focusNearRange;
extern cvar_t* crp_gatherDof_focusFarDist;
extern cvar_t* crp_gatherDof_focusFarRange;
extern cvar_t* crp_gatherDof_brightness;
extern cvar_t* crp_accumDof_focusDist;
extern cvar_t* crp_accumDof_radius;
extern cvar_t* crp_accumDof_samples;
extern cvar_t* crp_accumDof_preview;
extern cvar_t* crp_drawNormals;
extern cvar_t* crp_updateRTAS;
extern cvar_t* crp_debug0;
extern cvar_t* crp_debug1;
extern cvar_t* crp_debug2;
extern cvar_t* crp_debug3;
struct DOFMethod
{
enum Id
{
None,
Gather,
Accumulation,
Count
};
};
struct Tessellator
{
enum Id
{
None,
Prepass,
Opaque,
Transp,
Count
};
};
using namespace RHI;
struct WorldVertexRC
{
float modelViewMatrix[16];
};
struct PSOCache
{
struct Entry
{
GraphicsPipelineDesc desc;
HPipeline handle;
};
void Init(Entry* entries, uint32_t maxEntryCount);
int AddPipeline(const GraphicsPipelineDesc& desc, const char* name);
Entry* entries = NULL;
uint32_t maxEntryCount = 0;
uint32_t entryCount = 1; // we treat index 0 as invalid
};
struct Prepass
{
void Init();
void Draw(const drawSceneViewCommand_t& cmd);
void ProcessShader(shader_t& shader);
void TessellationOverflow();
private:
void BeginBatch(const shader_t* shader);
void EndBatch();
PSOCache::Entry psoCacheEntries[128];
PSOCache psoCache;
bool batchOldDepthHack;
bool batchDepthHack;
};
struct WorldOpaque
{
void Init();
void Draw(const drawSceneViewCommand_t& cmd);
void ProcessShader(shader_t& shader);
void TessellationOverflow();
void DrawSkyBox();
void DrawClouds();
private:
void BeginBatch(const shader_t* shader);
void EndBatch();
void EndSkyBatch();
PSOCache::Entry psoCacheEntries[128];
PSOCache psoCache;
bool batchOldDepthHack;
bool batchDepthHack;
HPipeline wireframeNormalsPipeline;
};
struct WorldTransp
{
void Init();
void Draw(const drawSceneViewCommand_t& cmd);
void ProcessShader(shader_t& shader);
void TessellationOverflow();
private:
void BeginBatch(const shader_t* shader);
void EndBatch();
PSOCache::Entry psoCacheEntries[32];
PSOCache psoCache;
bool batchOldDepthHack;
bool batchDepthHack;
};
struct Fog
{
void Init();
void Draw();
private:
HBuffer boxIndexBuffer;
HBuffer boxVertexBuffer;
HPipeline fogInsidePipeline;
HPipeline fogOutsidePipeline;
};
struct TranspResolve
{
void Init();
void Draw(const drawSceneViewCommand_t& cmd);
private:
HPipeline pipeline;
};
struct ToneMap
{
void Init();
void DrawToneMap();
void DrawInverseToneMap();
private:
HPipeline pipeline;
HPipeline inversePipeline;
};
struct AccumDepthOfField
{
void Init();
void Begin(const drawSceneViewCommand_t& cmd);
uint32_t GetSampleCount();
void FixCommand(drawSceneViewCommand_t& newCmd, const drawSceneViewCommand_t& cmd, uint32_t x, uint32_t y);
void Accumulate();
void Normalize();
void DrawDebug();
private:
HPipeline accumPipeline;
HPipeline normPipeline;
HPipeline debugPipeline;
HTexture accumTexture;
float maxNearCocCS;
float maxFarCocCS;
float modelViewMatrix[16];
float projMatrix[16];
};
struct GatherDepthOfField
{
void Init();
void Draw();
private:
void DrawDebug();
void DrawSplit();
void DrawNearCocTileGen();
void DrawNearCocTileMax();
void DrawBlur();
void DrawFill();
void DrawCombine();
HPipeline debugPipeline;
HPipeline splitPipeline;
HPipeline nearCocTileGenPipeline;
HPipeline nearCocTileMaxPipeline;
HPipeline blurPipeline;
HPipeline fillPipeline;
HPipeline combinePipeline;
HTexture nearColorTexture;
HTexture farColorTexture;
HTexture nearBlurTexture;
HTexture farBlurTexture;
HTexture nearCocTexture;
HTexture nearCocTexture2;
HTexture nearCocTileTexture;
HTexture nearCocTileTexture2;
HTexture farCocTexture;
uint32_t tileWidth;
uint32_t tileHeight;
};
struct Magnifier
{
void Init();
void Draw();
void DrawGUI();
private:
HPipeline pipeline;
bool magnifierActive = false;
};
struct GBufferViz
{
void Init();
void DrawGUI();
private:
struct GBufferTexture
{
enum Id
{
Depth,
Normal,
Light,
ShadingPositionDelta,
Count
};
};
HPipeline linearizeDepthPipeline;
HPipeline decodeNormalsPipeline;
HPipeline decodeShadingPositionPipeline;
bool windowActive = false;
int textureIndex = 0;
bool coloredPositionDelta = false;
};
struct DynamicLights
{
void Init();
void Draw();
private:
HPipeline pipeline;
HPipeline denoisingPipeline;
};
struct Raytracing
{
void Init();
void ProcessWorld(world_t& world);
void BeginFrame();
HBuffer GetTLAS() { return tlasBuffer; }
HBuffer GetInstanceBuffer() { return tlasInstanceBuffer; }
private:
void TagMapSurfacesRecursively(mnode_t* node);
struct BLASBucket
{
enum Constants
{
Count = CT_COUNT
};
};
struct BLASBuildBuffers
{
HBuffer vertexBuffer;
HBuffer indexBuffer;
uint32_t vertexBufferByteCount;
uint32_t indexBufferByteCount;
};
struct BLASBuffers
{
HBuffer blasBuffer;
HBuffer vertexBuffer;
HBuffer indexBuffer;
HBuffer meshBuffer;
uint32_t vertexBufferByteCount;
uint32_t indexBufferByteCount;
uint32_t meshBufferByteCount;
};
struct Surface
{
const surfaceType_t* surface;
const shader_t* shader;
int entityNum;
};
struct ISurfaceList
{
virtual uint32_t GetSurfaceCount() = 0;
virtual bool GetSurface(Surface& surface, uint32_t index) = 0; // true when skipped
};
struct WorldSurfaceList : ISurfaceList
{
uint32_t GetSurfaceCount() override;
bool GetSurface(Surface& surface, uint32_t index) override;
};
struct DynamicSurfaceList : ISurfaceList
{
uint32_t GetSurfaceCount() override;
bool GetSurface(Surface& surface, uint32_t index) override;
};
void EnsureBuffersAreLargeEnough(BLASBuildBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount);
void EnsureBuffersAreLargeEnough(BLASBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount, uint32_t maxMeshCount);
void BuildBLASes(BLASBuffers* blasBuffers, struct BLASBuilder* blasBuilders, ISurfaceList* surfaceList);
BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {};
BLASBuffers staticBLASBuffers[BLASBucket::Count] = {};
BLASBuffers dynamicBLASBuffers[BLASBucket::Count] = {};
StaticUnorderedArray<TLASInstanceDesc, 2 * BLASBucket::Count> tlasInstanceDescs;
uint32_t staticTLASInstanceCount = 0;
HBuffer tlasBuffer = RHI_MAKE_NULL_HANDLE();
HBuffer tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
};
struct BaseBufferId
{
enum Id
{
Position,
Normal,
Count
};
};
struct StageBufferId
{
enum Id
{
TexCoords,
Color,
Count
};
};
struct GeoBuffers
{
void Create(const char* name, uint32_t vertexCount, uint32_t indexCount);
void Rewind();
void BeginUpload();
void EndUpload();
void UploadBase();
void UploadStage(uint32_t svarsIndex);
void EndBaseBatch(uint32_t vertexCount);
bool CanAdd(uint32_t vertexCount, uint32_t indexCount, uint32_t stageCount);
void DrawStage(uint32_t vertexCount, uint32_t indexCount);
void DrawPositionOnly(uint32_t vertexCount, uint32_t indexCount);
void UploadAndDrawDebugNormals();
GeometryBuffer baseVertexBuffers[BaseBufferId::Count];
GeometryBuffer stageVertexBuffers[StageBufferId::Count];
IndexBuffer indexBuffer;
HBuffer vertexBuffers[BaseBufferId::Count + StageBufferId::Count];
uint32_t vertexBufferStrides[BaseBufferId::Count + StageBufferId::Count];
};
struct CRP : IRenderPipeline
{
void Init() override;
void LoadResources() override;
void ShutDown(bool fullShutDown) override;
void ProcessWorld(world_t& world) override;
void ProcessModel(model_t& model) override;
void ProcessShader(shader_t& shader) override;
void CreateTexture(image_t* image, int mipCount, int width, int height) override;
void UpoadTextureAndGenerateMipMaps(image_t* image, const byte* data) override;
void BeginTextureUpload(MappedTexture& mappedTexture, image_t* image) override;
void EndTextureUpload() override;
void ExecuteRenderCommands(const byte* data, bool readbackRequested) override;
void TessellationOverflow() override;
void DrawSkyBox() override { opaque.DrawSkyBox(); }
void DrawClouds() override { opaque.DrawClouds(); }
void ReadPixels(int w, int h, int alignment, colorSpace_t colorSpace, void* out) override;
uint32_t GetSamplerDescriptorIndexFromBaseIndex(uint32_t baseIndex) override;
void BeginFrame();
void EndFrame();
void Blit(HTexture destination, HTexture source, const char* passName, bool hdr, const vec2_t tcScale, const vec2_t tcBias);
void BlitRenderTarget(HTexture destination, const char* passName);
void DrawSceneView(const drawSceneViewCommand_t& cmd);
void UploadSceneViewData();
HTexture GetReadRenderTarget();
HTexture GetWriteRenderTarget();
void SwapRenderTargets();
// general
float frameSeed;
HTexture readbackRenderTarget;
HTexture depthTexture;
HTexture normalTexture;
HTexture motionVectorTexture;
HTexture noisyLightTexture;
HTexture lightTexture;
HTexture shadingPositionTexture;
HTexture renderTarget;
TextureFormat::Id renderTargetFormat;
HTexture renderTargets[2];
uint32_t renderTargetIndex; // the one to write to
HSampler samplers[BASE_SAMPLER_COUNT]; // all base samplers
uint32_t samplerIndices[BASE_SAMPLER_COUNT]; // descriptor heap indices
HTexture blueNoise2D;
// blit
HPipeline blitPipelineLDR;
HPipeline blitPipelineHDR;
// world geometry
GeoBuffers dynBuffers[FrameCount]; // for rendering world surfaces
// scene view data
HBuffer sceneViewUploadBuffers[FrameCount];
HBuffer sceneViewBuffer; // this is the buffer that lives at ResourceDescriptorHeap[0]
uint32_t sceneViewIndex;
// for rendering transparent world surfaces
HTexture oitIndexTexture;
HBuffer oitFragmentBuffer;
HBuffer oitCounterBuffer;
HBuffer oitCounterStagingBuffer;
UI ui;
MipMapGenerator mipMapGen;
ImGUI imgui;
Nuklear nuklear;
Prepass prepass;
WorldOpaque opaque;
WorldTransp transp;
TranspResolve transpResolve;
ToneMap toneMap;
GatherDepthOfField gatherDof;
AccumDepthOfField accumDof;
Fog fog;
Magnifier magnifier;
DynamicLights dynamicLights;
Raytracing raytracing;
GBufferViz gbufferViz;
};
extern CRP crp;