mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-12-02 00:41:57 +00:00
a76dba5cfb
- brightness-corrected ImGUI drawing - upgraded shader code to HLSL 2021 - vertex normals drawing
496 lines
11 KiB
C++
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;
|