mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
896 lines
22 KiB
C++
896 lines
22 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_mblur;
|
|
extern cvar_t* crp_mblur_exposure;
|
|
extern cvar_t* crp_sunlight;
|
|
extern cvar_t* crp_volLight;
|
|
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 MotionBlurModes
|
|
{
|
|
enum Flags
|
|
{
|
|
CameraBit = 1 << 0,
|
|
ObjectBit = 1 << 1
|
|
};
|
|
|
|
enum Id
|
|
{
|
|
None,
|
|
CameraOnly = CameraBit,
|
|
ObjectOnly = ObjectBit,
|
|
Full = CameraOnly + ObjectOnly
|
|
};
|
|
};
|
|
|
|
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;
|
|
int batchEntityId;
|
|
float batchMotionScale;
|
|
|
|
HPipeline skyboxMotionPipeline;
|
|
};
|
|
|
|
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 TranspResolve
|
|
{
|
|
void Init();
|
|
void Draw(const drawSceneViewCommand_t& cmd);
|
|
|
|
private:
|
|
HPipeline noVolPipeline;
|
|
HPipeline volPipeline;
|
|
};
|
|
|
|
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 tileTextureWidth;
|
|
uint32_t tileTextureHeight;
|
|
};
|
|
|
|
struct MotionBlur
|
|
{
|
|
void Init();
|
|
void Draw();
|
|
|
|
private:
|
|
void DrawPack();
|
|
void DrawTileGen();
|
|
void DrawTileMax();
|
|
void DrawBlur();
|
|
|
|
HPipeline packPipeline;
|
|
HPipeline tileGenPipeline;
|
|
HPipeline tileMaxPipeline;
|
|
HPipeline blurPipeline;
|
|
HTexture tileTexture;
|
|
HTexture tileTexture2;
|
|
HTexture packedTexture;
|
|
uint32_t tileTextureWidth;
|
|
uint32_t tileTextureHeight;
|
|
};
|
|
|
|
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,
|
|
MotionVectorRaw,
|
|
MotionVectorMB,
|
|
SunlightVisibility,
|
|
SunlightPenumbra,
|
|
Sunlight,
|
|
Count
|
|
};
|
|
};
|
|
|
|
HPipeline linearizeDepthPipeline;
|
|
HPipeline decodeNormalsPipeline;
|
|
HPipeline decodeShadingPositionPipeline;
|
|
HPipeline motionVectorPipeline;
|
|
bool windowActive = false;
|
|
int textureIndex = 0;
|
|
bool coloredPositionDelta = false;
|
|
bool fullResolution = false;
|
|
};
|
|
|
|
struct DynamicLights
|
|
{
|
|
void Init();
|
|
void DrawBegin();
|
|
void DrawPointLight(const dlight_t& light);
|
|
bool WantRTASUpdate(const trRefdef_t& scene);
|
|
|
|
private:
|
|
HPipeline pipeline;
|
|
HPipeline denoisingPipeline;
|
|
};
|
|
|
|
struct Raytracing
|
|
{
|
|
void Init();
|
|
void ProcessWorld(world_t& world);
|
|
void BeforeFrame(bool wantUpdate);
|
|
void BeginFrame(bool wantUpdate);
|
|
uint32_t GetTLASBufferIndex();
|
|
uint32_t GetInstanceBufferIndex();
|
|
bool CanRaytrace();
|
|
|
|
private:
|
|
struct BLASBuildBuffers;
|
|
struct BLASBuffers;
|
|
struct ISurfaceList;
|
|
void TagMapSurfacesRecursively(mnode_t* node);
|
|
void ProcessStaticSurfaces();
|
|
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);
|
|
uint32_t GetRTFrameIndex() { return frameCount % RTFrameCount; }
|
|
|
|
enum Constants
|
|
{
|
|
RTFrameCount = RHI::FrameCount
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
struct FrameData
|
|
{
|
|
BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {};
|
|
BLASBuffers dynamicBLASBuffers[BLASBucket::Count] = {};
|
|
HBuffer tlasBuffer = RHI_MAKE_NULL_HANDLE();
|
|
HBuffer tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
|
|
};
|
|
|
|
FrameData frameData[RTFrameCount];
|
|
BLASBuffers staticBLASBuffers[BLASBucket::Count] = {};
|
|
StaticArray<TLASInstanceDesc, 2 * BLASBucket::Count> tlasInstanceDescs;
|
|
uint32_t staticTLASInstanceCount = 0;
|
|
bool pendingWorldProcess = false;
|
|
uint32_t frameCount = 0;
|
|
// we have a local frame counter because (for now)
|
|
// RHI::GetFrameIndex() increments during RHI::BeginFrame()
|
|
// in a given frame, we need BeforeFrame and BeginFrame to use the same buffer index
|
|
};
|
|
|
|
struct SunlightEditor
|
|
{
|
|
void Init();
|
|
void ProcessWorld(world_t& world);
|
|
void DrawOverlay();
|
|
void DrawGUI();
|
|
|
|
private:
|
|
HPipeline pipeline;
|
|
bool windowActive = false;
|
|
bool drawOverlay = false;
|
|
const shader_t* skyShader = NULL;
|
|
};
|
|
|
|
struct Sunlight
|
|
{
|
|
void Init();
|
|
void Draw();
|
|
bool WantRTASUpdate(const trRefdef_t& scene);
|
|
|
|
//private:
|
|
HPipeline visibilityPipeline;
|
|
HPipeline blurPipeline;
|
|
HTexture visibilityTexture;
|
|
HTexture penumbraTexture;
|
|
};
|
|
|
|
struct VDBSequenceDesc
|
|
{
|
|
const char* folderPath = NULL;
|
|
const char* smokeGridName = "density";
|
|
const char* fireGridName = "flames";
|
|
vec3_t originOffset = {}; // index space
|
|
vec3_t position = { 700 }; // world space
|
|
vec3_t anglesRad = {}; // in radians
|
|
vec3_t scale = { 1.0f, 1.0f, 1.0f };
|
|
float smokeExtinctionScale = 1.0f;
|
|
float smokeAlbedo = 0.9f; // real smoke: 0.9 to 0.97
|
|
float fireEmissionScale = 0.1f;
|
|
float fireTemperatureScale = 1000.0f;
|
|
float frameRate = 60.0f;
|
|
int startTimeMS = 0;
|
|
int startTimeUS = 0;
|
|
bool loop = false;
|
|
bool useSequenceOffset = true;
|
|
bool gpuResident = false;
|
|
};
|
|
|
|
struct NanoVDBManager
|
|
{
|
|
struct Instance;
|
|
struct DrawInstance;
|
|
struct CPUFrame;
|
|
|
|
void Init();
|
|
void DrawGUI();
|
|
void DrawIm3d();
|
|
void BeforeFrame();
|
|
bool AddSequence(const VDBSequenceDesc& desc);
|
|
void MakeWorldToIndexMatrix(matrix3x3_t matrix, const Instance& instance);
|
|
void Purge();
|
|
int FindStreamedFrameIndex(uint32_t sequenceIndex, uint32_t frameIndex);
|
|
|
|
struct Sequence
|
|
{
|
|
char folderPath[64];
|
|
vec3_t originOffset;
|
|
vec3_t scale;
|
|
HBuffer buffer;
|
|
uint32_t bufferByteCount;
|
|
uint32_t frameCount;
|
|
uint32_t firstFrameIndex;
|
|
};
|
|
|
|
struct Instance
|
|
{
|
|
char smokeGridName[64];
|
|
char fireGridName[64];
|
|
vec3_t originOffset; // index space
|
|
vec3_t position; // world space
|
|
vec3_t anglesRad; // in radians
|
|
vec3_t scale;
|
|
float smokeExtinctionScale;
|
|
float smokeAlbedo;
|
|
float fireEmissionScale;
|
|
float fireTemperatureScale;
|
|
float frameRate;
|
|
int startTimeMS;
|
|
int startTimeUS;
|
|
uint32_t sequenceIndex;
|
|
bool loop;
|
|
};
|
|
|
|
struct DrawInstance
|
|
{
|
|
HBuffer buffer;
|
|
uint32_t smokeByteOffset;
|
|
uint32_t fireByteOffset;
|
|
uint32_t smokeByteOffset2;
|
|
uint32_t fireByteOffset2;
|
|
float t;
|
|
};
|
|
|
|
struct GPUFrame
|
|
{
|
|
uint32_t smokeByteOffset;
|
|
uint32_t fireByteOffset;
|
|
};
|
|
|
|
struct CPUFrame
|
|
{
|
|
char filePath[64];
|
|
uint32_t smokeByteOffset;
|
|
uint32_t smokeByteCount;
|
|
uint32_t fireByteOffset;
|
|
uint32_t fireByteCount;
|
|
};
|
|
|
|
struct StreamedFrame
|
|
{
|
|
uint32_t sequenceIndex;
|
|
uint32_t frameIndex;
|
|
uint32_t smokeByteOffset;
|
|
uint32_t flamesByteOffset;
|
|
};
|
|
|
|
StaticArray<Sequence, 16> sequences;
|
|
StaticArray<Instance, 64> instances;
|
|
StaticArray<DrawInstance, 64> drawInstances; // for the current frame
|
|
StaticArray<StreamedFrame, 128> streamedFrames; // for the current frame
|
|
StaticArray<GPUFrame, 4096> gpuFrames;
|
|
StaticArray<CPUFrame, 4096> cpuFrames;
|
|
HBuffer streamBuffers[FrameCount + 1];
|
|
uint32_t streamBufferByteCount;
|
|
uint32_t streamBufferIndex;
|
|
bool windowActive = false;
|
|
bool linearInterpolation = false;
|
|
bool accurateOverlapTest = false;
|
|
bool supersampling = false;
|
|
int ambientRaymarchLOD = 8;
|
|
bool ambientIncreasedCoverage = true;
|
|
bool previewMode = false;
|
|
float emissiveScatterScale = 0.5f;
|
|
int activeInstanceIndex = -1;
|
|
};
|
|
|
|
struct ParticleSystem
|
|
{
|
|
void Init();
|
|
void Draw();
|
|
|
|
//private:
|
|
HPipeline clearPipeline;
|
|
HPipeline setupPipeline;
|
|
HPipeline emitPipeline;
|
|
HPipeline simulatePipeline;
|
|
HBuffer particleBuffer;
|
|
HBuffer liveBuffers[2]; // indices before and after simulation
|
|
HBuffer deadBuffer; // indices
|
|
HBuffer emitterBuffer;
|
|
HBuffer indirectBuffer; // 0: emit dispatch, 1: simulate dispatch
|
|
uint32_t liveBufferReadIndex;
|
|
bool needsClearing;
|
|
};
|
|
|
|
struct VolumetricLight
|
|
{
|
|
void Init();
|
|
void ProcessWorld(world_t& world);
|
|
void DrawBegin();
|
|
void DrawPointLight(const dlight_t& light);
|
|
void DrawSunlight();
|
|
void DrawEnd();
|
|
void DrawDebug();
|
|
void DrawGUI();
|
|
void DrawIm3d();
|
|
bool WantRTASUpdate(const trRefdef_t& scene);
|
|
bool ShouldDraw();
|
|
bool ShouldDrawDebug();
|
|
bool LoadFogFile(const char* filePath);
|
|
void SaveFogFile(const char* filePath);
|
|
void SetLightGridRootConstants(struct LightGridRC& rc);
|
|
|
|
// GUI/user-friendly data layout
|
|
struct Fog
|
|
{
|
|
vec3_t scatterColor;
|
|
vec3_t emissiveColor;
|
|
vec3_t boxCenter;
|
|
vec3_t boxSize;
|
|
float extinction;
|
|
float albedo; // thin fog: 0.3 to 0.5, thick fog: 0.6 to 0.9
|
|
float emissive;
|
|
float anisotropy; // thin fog: 0.9, thick fog: 0.9 with strong backscatter
|
|
float noiseStrength;
|
|
float noiseSpatialPeriod;
|
|
float noiseTimePeriod;
|
|
bool isGlobalFog;
|
|
bool isHeightFog;
|
|
};
|
|
|
|
Fog fogs[64];
|
|
uint32_t fogCount = 0;
|
|
HPipeline extinctionFogPipeline;
|
|
HPipeline extinctionVDBPipeline;
|
|
HPipeline frustumAmbientPipeline;
|
|
HPipeline frustumAnisotropyPipeline;
|
|
HPipeline frustumFogPipeline;
|
|
HPipeline frustumLightPropNXPipeline;
|
|
HPipeline frustumLightPropNYPipeline;
|
|
HPipeline frustumLightPropPXPipeline;
|
|
HPipeline frustumLightPropPYPipeline;
|
|
HPipeline frustumParticlePipeline;
|
|
HPipeline frustumPointLightScatterPipeline;
|
|
HPipeline frustumRaymarchPipeline;
|
|
HPipeline frustumSunlightVisPipeline;
|
|
HPipeline frustumTemporalFloatPipeline;
|
|
HPipeline frustumTemporalFloat4Pipeline;
|
|
HPipeline frustumVDBPipeline;
|
|
HPipeline frustumVDBLQPipeline;
|
|
HPipeline frustumDepthTestPipeline;
|
|
HPipeline particleClearPipeline;
|
|
HPipeline particleHitPipeline;
|
|
HPipeline particleListPipeline;
|
|
HPipeline particleTilesPipeline;
|
|
HPipeline pointLightShadowPipeline;
|
|
HPipeline sunlightScatterPipeline;
|
|
HPipeline sunlightShadowPipeline;
|
|
HPipeline ambientVizPipeline;
|
|
HPipeline extinctionVizPipeline;
|
|
HPipeline sunShadowVizPipeline;
|
|
HTexture materialTextureA; // frustum, RGB = scatter, A = absorption
|
|
HTexture materialTextureB; // frustum, RGB = emissive, A = anisotropy (g)
|
|
HTexture materialTextureC; // frustum, R = anisotropy (g) weight sum
|
|
HTexture sunlightVisTexture; // frustum, R = sunlight visibility
|
|
HTexture prevSunlightVisTexture; // frustum, R = sunlight visibility
|
|
HTexture scatterExtTexture; // frustum, RGB = in-scattering, A = extinction
|
|
HTexture scatterTransTexture; // frustum, RGB = in-scattering, A = transmittance
|
|
HTexture extinctionTextures[4]; // cube, R = extinction
|
|
HTexture pointShadowTexture; // cube, R = transmittance
|
|
HTexture sunShadowTextures[4]; // cube, R = transmittance
|
|
HTexture ambientLightTextureA; // box, can be NULL, RGB = ambient.rgb, A = directional.r
|
|
HTexture ambientLightTextureB; // box, can be NULL, RG = directional.gb, B = longitude, A = latitude
|
|
HTexture frustumVisTexture; // screen tiles, R = Z index of furthest visible froxel tile
|
|
HBuffer particleTileBuffer; // voxel tiles: StructuredBuffer<Tile>
|
|
HBuffer particleCounterBuffer; // global counters: StructuredBuffer<Counters>
|
|
HBuffer particleTileIndexBuffer; // flattened voxel tile indices: StructuredBuffer<uint>
|
|
HBuffer particleIndexBuffer; // particle indices: StructuredBuffer<uint>
|
|
HBuffer particleDispatchBuffer; // indirect dispatch buffer
|
|
uvec3_t frustumSize; // frustum volume pixel counts
|
|
uvec3_t frustumTileScale; // by how much do we divide
|
|
uvec3_t frustumTileSize; // frustum volume tile pixel counts
|
|
uvec3_t extinctionSize; // extinction volume pixel counts
|
|
uvec3_t extinctionTileScale; // by how much do we divide
|
|
uvec3_t extinctionTileSize; // extinction volume tile pixel counts
|
|
uint32_t maxParticleIndexCount; // uint count in particleIndexBuffer
|
|
uint32_t shadowPixelCount; // @TODO: transform into uvec3_t as well
|
|
uint32_t jitterCounter;
|
|
uint32_t depthMip; // has to match the X/Y scale of frustumSize
|
|
vec4_t extinctionVolumeScale; // how many world units per pixel
|
|
float pointShadowVolumeScale; // how many world units per pixel
|
|
vec4_t sunShadowVolumeScale; // how many world units per pixel
|
|
uvec3_t sunShadowSize; // sunlight shadow volume pixel counts
|
|
vec3_t ambientColorGUI;
|
|
vec3_t ambientColor; // normalized to 0.5 brightness
|
|
float ambientIntensity;
|
|
float pointLightIntensity = 20.0f;
|
|
vec3_t debugCameraPosition;
|
|
float debugBoxScale = 1.0f;
|
|
float debugExtinctionScale = 50.0f;
|
|
int debugExtinctionCascadeIndex = 0;
|
|
int debugSunShadowCascadeIndex = 0;
|
|
bool drawExtinctionDebug = false;
|
|
bool drawSunShadowDebug = false;
|
|
bool drawAmbientDebug = false;
|
|
bool lockCameraPosition = false;
|
|
bool firstFrame = true;
|
|
bool windowActive = false;
|
|
bool drawSunlight = true;
|
|
bool enableLightGrid = true;
|
|
vec3_t mapBoxMin;
|
|
vec3_t mapBoxMax;
|
|
vec3_t lightGridCenter;
|
|
float debugSphereScale = 0.5f;
|
|
int xySubsampling = 2;
|
|
int zResolution = 256;
|
|
int extinctionResolution = 128;
|
|
int sunShadowResolution = 128;
|
|
int pointShadowResolution = 64;
|
|
int activeFogIndex = -1; // tab GUI index
|
|
};
|
|
|
|
#pragma pack(push, 1)
|
|
struct SunlightData
|
|
{
|
|
vec3_t direction;
|
|
vec3_t color;
|
|
float intensityVL = 40.0f;
|
|
float intensityDL = 2.0f;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
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 FreezeFrame
|
|
{
|
|
enum Id
|
|
{
|
|
Inactive,
|
|
Pending,
|
|
Active,
|
|
PendingBeforeMB,
|
|
ActiveBeforeMB
|
|
};
|
|
};
|
|
|
|
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 DrawSceneView3D(const drawSceneViewCommand_t& cmd);
|
|
void UploadSceneViewData();
|
|
void BuildDepthPyramid();
|
|
|
|
HTexture GetReadRenderTarget();
|
|
HTexture GetWriteRenderTarget();
|
|
void SwapRenderTargets();
|
|
|
|
// general
|
|
float frameSeed;
|
|
HTexture readbackRenderTarget;
|
|
HTexture depthTexture;
|
|
HTexture depthMinMaxTexture;
|
|
HTexture normalTexture;
|
|
HTexture motionVectorTexture; // raw, for TAA/denoisers/etc
|
|
HTexture motionVectorMBTexture; // mangled, for motion blur only
|
|
HTexture sunlightTexture;
|
|
HTexture lightTexture;
|
|
HTexture shadingPositionTexture;
|
|
HTexture renderTarget;
|
|
HTexture blackbodyTexture;
|
|
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;
|
|
FreezeFrame::Id freezeFrame;
|
|
HTexture frozenTexture;
|
|
HPipeline depthPyramidPipeline;
|
|
|
|
// 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;
|
|
Im3D im3d;
|
|
Nuklear nuklear;
|
|
Prepass prepass;
|
|
WorldOpaque opaque;
|
|
WorldTransp transp;
|
|
TranspResolve transpResolve;
|
|
ToneMap toneMap;
|
|
GatherDepthOfField gatherDof;
|
|
AccumDepthOfField accumDof;
|
|
MotionBlur motionBlur;
|
|
Magnifier magnifier;
|
|
DynamicLights dynamicLights;
|
|
Sunlight sunlight;
|
|
VolumetricLight volumetricLight;
|
|
Raytracing raytracing;
|
|
GBufferViz gbufferViz;
|
|
SunlightEditor sunlightEditor;
|
|
SunlightData sunlightData;
|
|
ParticleSystem particleSystem;
|
|
NanoVDBManager vdbManager;
|
|
};
|
|
|
|
HPipeline CreateComputePipeline(const char* name, const ShaderByteCode& shader);
|
|
void MakeFullScreenPipeline(GraphicsPipelineDesc& desc, const ShaderByteCode& pixelShader);
|
|
void DirectionToAzimuthInclination(float* sc, const float* dir);
|
|
void AzimuthInclinationToDirection(float* dir, const float* sc);
|
|
|
|
extern CRP crp;
|