1385 lines
49 KiB
C++
1385 lines
49 KiB
C++
#pragma once
|
|
#include "CommonInclude.h"
|
|
#include "wiEnums.h"
|
|
#include "wiGraphicsDevice.h"
|
|
#include "wiScene.h"
|
|
#include "wiECS.h"
|
|
#include "wiRectPacker.h"
|
|
#include "wiPrimitive.h"
|
|
#include "wiCanvas.h"
|
|
#include "wiMath.h"
|
|
#include "shaders/ShaderInterop_Renderer.h"
|
|
#include "shaders/ShaderInterop_SurfelGI.h"
|
|
#include "wiVector.h"
|
|
#include "wiSpinLock.h"
|
|
#include "wiAllocator.h"
|
|
|
|
#include <memory>
|
|
#include <limits>
|
|
|
|
namespace wi
|
|
{
|
|
struct VoxelGrid;
|
|
struct PathQuery;
|
|
struct TrailRenderer;
|
|
}
|
|
|
|
namespace wi::renderer
|
|
{
|
|
constexpr wi::graphics::Format format_depthbuffer_main = wi::graphics::Format::D32_FLOAT_S8X24_UINT;
|
|
constexpr wi::graphics::Format format_rendertarget_main = wi::graphics::Format::R11G11B10_FLOAT;
|
|
constexpr wi::graphics::Format format_idbuffer = wi::graphics::Format::R32_UINT;
|
|
constexpr wi::graphics::Format format_rendertarget_shadowmap = wi::graphics::Format::R16G16B16A16_FLOAT;
|
|
constexpr wi::graphics::Format format_depthbuffer_shadowmap = wi::graphics::Format::D16_UNORM;
|
|
//constexpr wi::graphics::Format format_depthbuffer_shadowmap = wi::graphics::Format::D32_FLOAT;
|
|
constexpr wi::graphics::Format format_rendertarget_envprobe = wi::graphics::Format::R11G11B10_FLOAT;
|
|
constexpr wi::graphics::Format format_depthbuffer_envprobe = wi::graphics::Format::D16_UNORM;
|
|
|
|
constexpr uint8_t raytracing_inclusion_mask_shadow = 1 << 0;
|
|
constexpr uint8_t raytracing_inclusion_mask_reflection = 1 << 1;
|
|
|
|
constexpr uint32_t CombineStencilrefs(wi::enums::STENCILREF engineStencilRef, uint8_t userStencilRef)
|
|
{
|
|
return (userStencilRef << 4) | static_cast<uint8_t>(engineStencilRef);
|
|
}
|
|
constexpr XMUINT2 GetEntityCullingTileCount(XMUINT2 internalResolution)
|
|
{
|
|
return XMUINT2(
|
|
(internalResolution.x + TILED_CULLING_BLOCKSIZE - 1) / TILED_CULLING_BLOCKSIZE,
|
|
(internalResolution.y + TILED_CULLING_BLOCKSIZE - 1) / TILED_CULLING_BLOCKSIZE
|
|
);
|
|
}
|
|
constexpr XMUINT2 GetVisibilityTileCount(XMUINT2 internalResolution)
|
|
{
|
|
return XMUINT2(
|
|
(internalResolution.x + VISIBILITY_BLOCKSIZE - 1) / VISIBILITY_BLOCKSIZE,
|
|
(internalResolution.y + VISIBILITY_BLOCKSIZE - 1) / VISIBILITY_BLOCKSIZE
|
|
);
|
|
}
|
|
|
|
const wi::graphics::Sampler* GetSampler(wi::enums::SAMPLERTYPES id);
|
|
const wi::graphics::Shader* GetShader(wi::enums::SHADERTYPE id);
|
|
const wi::graphics::InputLayout* GetInputLayout(wi::enums::ILTYPES id);
|
|
const wi::graphics::RasterizerState* GetRasterizerState(wi::enums::RSTYPES id);
|
|
const wi::graphics::DepthStencilState* GetDepthStencilState(wi::enums::DSSTYPES id);
|
|
const wi::graphics::BlendState* GetBlendState(wi::enums::BSTYPES id);
|
|
const wi::graphics::GPUBuffer* GetBuffer(wi::enums::BUFFERTYPES id);
|
|
const wi::graphics::Texture* GetTexture(wi::enums::TEXTYPES id);
|
|
|
|
// Returns a buffer preinitialized for quad index buffer laid out as:
|
|
// vertexID * 4 + [0, 1, 2, 2, 1, 3]
|
|
// Note: it will return 16-bit or 32-bit index buffer depending on max_quad_count
|
|
const wi::graphics::GPUBuffer& GetIndexBufferForQuads(uint32_t max_quad_count);
|
|
|
|
struct BufferSuballocation
|
|
{
|
|
wi::graphics::GPUBuffer alias;
|
|
wi::allocator::PageAllocator::Allocation allocation;
|
|
inline bool IsValid() const { return allocation.IsValid(); }
|
|
};
|
|
// Sub-allocate (thread-safe) from a global GPU buffer for memory aliasing purpose:
|
|
// The buffer will be DEFAULT usage, useable as vertex buffer, index buffer, shader resource and unordered access
|
|
// The purpose is to suballocate smaller GPUBuffers inside a larger GPUBuffer and bind the large GPUBuffer once as index buffer,
|
|
// while the small buffers can be allocated/deallocated from it with memory aliasing and also used regularly by themselves
|
|
BufferSuballocation SuballocateGPUBuffer(uint64_t size);
|
|
void UpdateGPUSuballocator(); // called every frame for deferred release of GPU suballocations
|
|
|
|
void ModifyObjectSampler(const wi::graphics::SamplerDesc& desc);
|
|
|
|
// Initializes the renderer
|
|
void Initialize();
|
|
|
|
// Clears the scene and the associated renderer resources
|
|
void ClearWorld(wi::scene::Scene& scene);
|
|
|
|
// Returns the shader binary directory
|
|
const std::string& GetShaderPath();
|
|
// Sets the shader binary directory
|
|
void SetShaderPath(const std::string& path);
|
|
// Returns the shader source directory
|
|
const std::string& GetShaderSourcePath();
|
|
// Sets the shader source directory
|
|
void SetShaderSourcePath(const std::string& path);
|
|
// Reload shaders
|
|
void ReloadShaders();
|
|
// Returns how many shaders are embedded (if wiShaderDump.h is used)
|
|
// wiShaderDump.h can be generated by OfflineShaderCompiler.exe using shaderdump argument
|
|
size_t GetShaderDumpCount();
|
|
size_t GetShaderErrorCount();
|
|
size_t GetShaderMissingCount();
|
|
|
|
bool LoadShader(
|
|
wi::graphics::ShaderStage stage,
|
|
wi::graphics::Shader& shader,
|
|
const std::string& filename,
|
|
wi::graphics::ShaderModel minshadermodel = wi::graphics::ShaderModel::SM_6_0,
|
|
const wi::vector<std::string>& permutation_defines = {}
|
|
);
|
|
|
|
// Whether background pipeline compilations are active (returns number of active jobs)
|
|
int IsPipelineCreationActive();
|
|
|
|
struct Visibility
|
|
{
|
|
// User fills these:
|
|
uint32_t layerMask = ~0u;
|
|
const wi::scene::Scene* scene = nullptr;
|
|
const wi::scene::CameraComponent* camera = nullptr;
|
|
enum FLAGS
|
|
{
|
|
EMPTY = 0,
|
|
ALLOW_OBJECTS = 1 << 0,
|
|
ALLOW_LIGHTS = 1 << 1,
|
|
ALLOW_DECALS = 1 << 2,
|
|
ALLOW_ENVPROBES = 1 << 3,
|
|
ALLOW_EMITTERS = 1 << 4,
|
|
ALLOW_HAIRS = 1 << 5,
|
|
ALLOW_COLLIDERS = 1 << 6,
|
|
ALLOW_REQUEST_REFLECTION = 1 << 7,
|
|
ALLOW_OCCLUSION_CULLING = 1 << 8,
|
|
ALLOW_SHADOW_ATLAS_PACKING = 1 << 9,
|
|
|
|
ALLOW_EVERYTHING = ~0u
|
|
};
|
|
uint32_t flags = EMPTY;
|
|
|
|
// wi::renderer::UpdateVisibility() fills these:
|
|
wi::primitive::Frustum frustum;
|
|
wi::vector<uint32_t> visibleObjects;
|
|
wi::vector<uint32_t> visibleDecals;
|
|
wi::vector<uint32_t> visibleEnvProbes;
|
|
wi::vector<uint32_t> visibleEmitters;
|
|
wi::vector<uint32_t> visibleHairs;
|
|
wi::vector<uint32_t> visibleLights;
|
|
wi::vector<wi::scene::ColliderComponent> visibleColliders;
|
|
wi::rectpacker::State shadow_packer;
|
|
wi::rectpacker::Rect rain_blocker_shadow_rect;
|
|
wi::vector<wi::rectpacker::Rect> visibleLightShadowRects;
|
|
|
|
std::atomic<uint32_t> object_counter;
|
|
std::atomic<uint32_t> light_counter;
|
|
|
|
wi::SpinLock locker;
|
|
bool planar_reflection_visible = false;
|
|
float closestRefPlane = std::numeric_limits<float>::max();
|
|
XMFLOAT4 reflectionPlane = XMFLOAT4(0, 1, 0, 0);
|
|
std::atomic_bool volumetriclight_request{ false };
|
|
std::atomic_bool transparents_visible{ false };
|
|
std::atomic_bool mesh_blend_visible{ false };
|
|
|
|
void Clear()
|
|
{
|
|
visibleObjects.clear();
|
|
visibleLights.clear();
|
|
visibleDecals.clear();
|
|
visibleEnvProbes.clear();
|
|
visibleEmitters.clear();
|
|
visibleHairs.clear();
|
|
visibleColliders.clear();
|
|
|
|
object_counter.store(0);
|
|
light_counter.store(0);
|
|
|
|
closestRefPlane = std::numeric_limits<float>::max();
|
|
planar_reflection_visible = false;
|
|
volumetriclight_request.store(false);
|
|
transparents_visible.store(false);
|
|
mesh_blend_visible.store(false);
|
|
}
|
|
|
|
bool IsRequestedPlanarReflections() const
|
|
{
|
|
return planar_reflection_visible;
|
|
}
|
|
bool IsRequestedVolumetricLights() const
|
|
{
|
|
return volumetriclight_request.load();
|
|
}
|
|
bool IsTransparentsVisible() const
|
|
{
|
|
return transparents_visible.load();
|
|
}
|
|
bool IsMeshBlendVisible() const
|
|
{
|
|
return mesh_blend_visible.load();
|
|
}
|
|
};
|
|
|
|
// Performs frustum culling.
|
|
void UpdateVisibility(Visibility& vis);
|
|
// Prepares the scene for rendering
|
|
void UpdatePerFrameData(
|
|
wi::scene::Scene& scene,
|
|
const Visibility& vis,
|
|
FrameCB& frameCB,
|
|
float dt
|
|
);
|
|
// Updates the GPU state according to the previously called UpdatePerFrameData()
|
|
void UpdateRenderData(
|
|
const Visibility& vis,
|
|
const FrameCB& frameCB,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// Updates those GPU states that can be async
|
|
void UpdateRenderDataAsync(
|
|
const Visibility& vis,
|
|
const FrameCB& frameCB,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// Copies the texture streaming requests from GPU to CPU
|
|
void TextureStreamingReadbackCopy(
|
|
const wi::scene::Scene& scene,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// Updates the ocean, can be on async compute
|
|
void UpdateOcean(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Readback the ocean, can be on async compute or async copy
|
|
void ReadbackOcean(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
void UpdateRaytracingAccelerationStructures(const wi::scene::Scene& scene, wi::graphics::CommandList cmd);
|
|
|
|
// Binds all common constant buffers and samplers that may be used in all shaders
|
|
void BindCommonResources(wi::graphics::CommandList cmd);
|
|
// Updates the per camera constant buffer need to call for each different camera that is used when calling DrawScene() and the like
|
|
// camera_previous : camera from previous frame, used for reprojection effects.
|
|
// camera_reflection : camera that renders planar reflection
|
|
void BindCameraCB(
|
|
const wi::scene::CameraComponent& camera,
|
|
const wi::scene::CameraComponent& camera_previous,
|
|
const wi::scene::CameraComponent& camera_reflection,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
|
|
enum DRAWSCENE_FLAGS
|
|
{
|
|
DRAWSCENE_OPAQUE = 1 << 0, // include opaque objects
|
|
DRAWSCENE_TRANSPARENT = 1 << 1, // include transparent objects
|
|
DRAWSCENE_OCCLUSIONCULLING = 1 << 2, // enable skipping objects based on occlusion culling results
|
|
DRAWSCENE_TESSELLATION = 1 << 3, // enable tessellation
|
|
DRAWSCENE_HAIRPARTICLE = 1 << 4, // include hair particles
|
|
DRAWSCENE_IMPOSTOR = 1 << 5, // include impostors
|
|
DRAWSCENE_OCEAN = 1 << 6, // include ocean
|
|
DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS = 1 << 7, // don't draw subsets which have planar reflection material
|
|
DRAWSCENE_FOREGROUND_ONLY = 1 << 8, // only include objects that are tagged as foreground
|
|
DRAWSCENE_MAINCAMERA = 1 << 9, // If this is active, then ObjectComponent with SetNotVisibleInMainCamera(true) won't be drawn
|
|
DRAWSCENE_WIREFRAME_OVERLAY = 1 << 10, // draw wireframe overlay
|
|
};
|
|
|
|
// Draw the world from a camera. You must call BindCameraCB() at least once in this command list prior to this
|
|
void DrawScene(
|
|
const Visibility& vis,
|
|
wi::enums::RENDERPASS renderPass,
|
|
wi::graphics::CommandList cmd,
|
|
uint32_t flags = DRAWSCENE_OPAQUE
|
|
);
|
|
|
|
// Process deferred requests such as AddDeferredMIPGen and AddDeferredBlockCompression:
|
|
void ProcessDeferredTextureRequests(wi::graphics::CommandList cmd);
|
|
|
|
// Compute volumetric cloud shadow data
|
|
void ComputeVolumetricCloudShadows(
|
|
wi::graphics::CommandList cmd,
|
|
const wi::graphics::Texture* weatherMapFirst = nullptr,
|
|
const wi::graphics::Texture* weatherMapSecond = nullptr
|
|
);
|
|
|
|
// Compute essential SkyAtmosphere textures for lighting, skyviewlut and cameravolume.
|
|
void ComputeSkyAtmosphereTextures(wi::graphics::CommandList cmd);
|
|
// Update SkyViewLut independently, used primarily for environtment probes.
|
|
void ComputeSkyAtmosphereSkyViewLut(wi::graphics::CommandList cmd);
|
|
// Update CameraVolumeLut independently, used primarily for environtment probes.
|
|
void ComputeSkyAtmosphereCameraVolumeLut(wi::graphics::CommandList cmd);
|
|
|
|
// Draw skydome centered to camera.
|
|
void DrawSky(const wi::scene::Scene& scene, wi::graphics::CommandList cmd);
|
|
// Draw shadow maps for each visible light that has associated shadow maps
|
|
void DrawSun(wi::graphics::CommandList cmd);
|
|
// Draw shadow maps for each visible light that has associated shadow maps
|
|
void DrawShadowmaps(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Draw debug world. You must also enable what parts to draw, eg. SetToDrawGridHelper, etc, see implementation for details what can be enabled.
|
|
void DrawDebugWorld(
|
|
const wi::scene::Scene& scene,
|
|
const wi::scene::CameraComponent& camera,
|
|
const wi::Canvas& canvas,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Draw wireframe overlay on top of scene geometry when wireframe mode is enabled
|
|
void DrawWireframeOverlay(
|
|
const Visibility& vis,
|
|
wi::enums::RENDERPASS renderPass,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Draw Soft offscreen particles.
|
|
void DrawSoftParticles(
|
|
const Visibility& vis,
|
|
bool distortion,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Draw the sprites and fonts from the scene
|
|
void DrawSpritesAndFonts(
|
|
const wi::scene::Scene& scene,
|
|
const wi::scene::CameraComponent& camera,
|
|
bool distortion,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Draw simple light visualizer geometries
|
|
// instance_replication is used to render them into multiple texture slices
|
|
void DrawLightVisualizers(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd,
|
|
uint32_t instance_replication = 1
|
|
);
|
|
// Draw volumetric light scattering effects
|
|
void DrawVolumeLights(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Draw Lens Flares for lights that have them enabled
|
|
void DrawLensFlares(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd,
|
|
const wi::graphics::Texture* texture_directional_occlusion = nullptr
|
|
);
|
|
// Call once per frame to re-render out of date environment probes
|
|
void RefreshEnvProbes(const Visibility& vis, wi::graphics::CommandList cmd);
|
|
// Call once per frame to re-render out of date impostors
|
|
void RefreshImpostors(const wi::scene::Scene& scene, wi::graphics::CommandList cmd);
|
|
// Call once per frame to render lightmaps
|
|
void RefreshLightmaps(const wi::scene::Scene& scene, wi::graphics::CommandList cmd);
|
|
// Call once per frame to render wetmaps
|
|
void RefreshWetmaps(const Visibility& vis, wi::graphics::CommandList cmd);
|
|
// Call once per frame to render PaintDecalIntoMeshSpaceTexture requests
|
|
void PaintDecals(const wi::scene::Scene& scene, wi::graphics::CommandList cmd);
|
|
|
|
// Run a compute shader that will resolve a MSAA depth buffer to a single-sample texture
|
|
void ResolveMSAADepthBuffer(const wi::graphics::Texture& dst, const wi::graphics::Texture& src, wi::graphics::CommandList cmd);
|
|
void DownsampleDepthBuffer(const wi::graphics::Texture& src, wi::graphics::CommandList cmd);
|
|
|
|
struct TiledLightResources
|
|
{
|
|
XMUINT2 tileCount = {};
|
|
wi::graphics::GPUBuffer entityTiles; // culled entity indices
|
|
};
|
|
void CreateTiledLightResources(TiledLightResources& res, XMUINT2 resolution);
|
|
// Compute light grid tiles
|
|
void ComputeTiledLightCulling(
|
|
const TiledLightResources& res,
|
|
const Visibility& vis,
|
|
const wi::graphics::Texture& debugUAV,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
struct LuminanceResources
|
|
{
|
|
wi::graphics::GPUBuffer luminance; // result luminance value
|
|
};
|
|
void CreateLuminanceResources(LuminanceResources& res, XMUINT2 resolution);
|
|
void ComputeLuminance(
|
|
const LuminanceResources& res,
|
|
const wi::graphics::Texture& sourceImage,
|
|
wi::graphics::CommandList cmd,
|
|
float adaption_rate = 1,
|
|
float eyeadaptionkey = 0.115f
|
|
);
|
|
|
|
struct BloomResources
|
|
{
|
|
wi::graphics::Texture texture_bloom;
|
|
wi::graphics::Texture texture_temp;
|
|
};
|
|
void CreateBloomResources(BloomResources& res, XMUINT2 resolution);
|
|
void ComputeBloom(
|
|
const BloomResources& res,
|
|
const wi::graphics::Texture& input,
|
|
wi::graphics::CommandList cmd,
|
|
float threshold = 1.0f, // cutoff value, pixels below this will not contribute to bloom
|
|
float exposure = 1.0f,
|
|
const wi::graphics::GPUBuffer* buffer_luminance = nullptr
|
|
);
|
|
|
|
void ComputeShadingRateClassification(
|
|
const wi::graphics::Texture& output,
|
|
const wi::graphics::Texture& debugUAV,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
struct VisibilityResources
|
|
{
|
|
XMUINT2 tile_count = {};
|
|
wi::graphics::GPUBuffer bins;
|
|
wi::graphics::GPUBuffer binned_tiles;
|
|
wi::graphics::Texture texture_payload_0;
|
|
wi::graphics::Texture texture_payload_1;
|
|
wi::graphics::Texture texture_normals;
|
|
wi::graphics::Texture texture_roughness;
|
|
|
|
// You can request any of these extra outputs to be written by VisibilityResolve:
|
|
const wi::graphics::Texture* depthbuffer = nullptr; // depth buffer that matches with post projection
|
|
const wi::graphics::Texture* lineardepth = nullptr; // depth buffer in linear space in [0,1] range
|
|
const wi::graphics::Texture* primitiveID_resolved = nullptr; // resolved from MSAA texture_visibility input
|
|
|
|
inline bool IsValid() const { return bins.IsValid(); }
|
|
};
|
|
void CreateVisibilityResources(VisibilityResources& res, XMUINT2 resolution);
|
|
void Visibility_Prepare(
|
|
const VisibilityResources& res,
|
|
const wi::graphics::Texture& input_primitiveID, // can be MSAA
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Visibility_Surface(
|
|
const VisibilityResources& res,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Visibility_Surface_Reduced(
|
|
const VisibilityResources& res,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Visibility_Shade(
|
|
const VisibilityResources& res,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Visibility_Velocity(
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// Surfel GI: diffuse GI with ray tracing from surfels
|
|
struct SurfelGIResources
|
|
{
|
|
wi::graphics::Texture result_halfres;
|
|
wi::graphics::Texture result;
|
|
};
|
|
void CreateSurfelGIResources(SurfelGIResources& res, XMUINT2 resolution);
|
|
void SurfelGI_Coverage(
|
|
const SurfelGIResources& res,
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& debugUAV,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void SurfelGI(
|
|
const SurfelGIResources& res,
|
|
const wi::scene::Scene& scene,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// DDGI: Dynamic Diffuse Global Illumination (probe-based ray tracing)
|
|
void DDGI(
|
|
const wi::scene::Scene& scene,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// VXGI: Voxel-based Global Illumination (voxel cone tracing-based)
|
|
struct VXGIResources
|
|
{
|
|
wi::graphics::Texture diffuse;
|
|
wi::graphics::Texture specular;
|
|
mutable bool pre_clear = true;
|
|
|
|
bool IsValid() const { return diffuse.IsValid(); }
|
|
};
|
|
void CreateVXGIResources(VXGIResources& res, XMUINT2 resolution);
|
|
void VXGI_Voxelize(
|
|
const Visibility& vis,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
// Resolve VXGI to screen
|
|
void VXGI_Resolve(
|
|
const VXGIResources& res,
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::Texture& texture_lineardepth,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
void Postprocess_Blur_Gaussian(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& temp,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
int mip_src = -1,
|
|
int mip_dst = -1,
|
|
bool wide = false
|
|
);
|
|
void Postprocess_Blur_Bilateral(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& temp,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float depth_threshold = 1.0f,
|
|
int mip_src = -1,
|
|
int mip_dst = -1,
|
|
bool wide = false
|
|
);
|
|
struct SSAOResources
|
|
{
|
|
wi::graphics::Texture temp;
|
|
};
|
|
void CreateSSAOResources(SSAOResources& res, XMUINT2 resolution);
|
|
void Postprocess_SSAO(
|
|
const SSAOResources& res,
|
|
const wi::graphics::Texture& output,
|
|
const wi::graphics::Texture& lineardepth,
|
|
wi::graphics::CommandList cmd,
|
|
float range = 1.0f,
|
|
uint32_t samplecount = 16,
|
|
float power = 1.0f
|
|
);
|
|
void Postprocess_HBAO(
|
|
const SSAOResources& res,
|
|
const wi::scene::CameraComponent& camera,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float power = 1.0f
|
|
);
|
|
struct MSAOResources
|
|
{
|
|
mutable bool cleared = false;
|
|
wi::graphics::Texture texture_lineardepth_downsize1;
|
|
wi::graphics::Texture texture_lineardepth_tiled1;
|
|
wi::graphics::Texture texture_lineardepth_downsize2;
|
|
wi::graphics::Texture texture_lineardepth_tiled2;
|
|
wi::graphics::Texture texture_lineardepth_downsize3;
|
|
wi::graphics::Texture texture_lineardepth_tiled3;
|
|
wi::graphics::Texture texture_lineardepth_downsize4;
|
|
wi::graphics::Texture texture_lineardepth_tiled4;
|
|
wi::graphics::Texture texture_ao_merged1;
|
|
wi::graphics::Texture texture_ao_hq1;
|
|
wi::graphics::Texture texture_ao_smooth1;
|
|
wi::graphics::Texture texture_ao_merged2;
|
|
wi::graphics::Texture texture_ao_hq2;
|
|
wi::graphics::Texture texture_ao_smooth2;
|
|
wi::graphics::Texture texture_ao_merged3;
|
|
wi::graphics::Texture texture_ao_hq3;
|
|
wi::graphics::Texture texture_ao_smooth3;
|
|
wi::graphics::Texture texture_ao_merged4;
|
|
wi::graphics::Texture texture_ao_hq4;
|
|
};
|
|
void CreateMSAOResources(MSAOResources& res, XMUINT2 resolution);
|
|
void Postprocess_MSAO(
|
|
const MSAOResources& res,
|
|
const wi::scene::CameraComponent& camera,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float power = 1.0f
|
|
);
|
|
struct RTAOResources
|
|
{
|
|
wi::graphics::Texture normals;
|
|
wi::graphics::Texture denoised;
|
|
|
|
mutable int frame = 0;
|
|
wi::graphics::GPUBuffer tiles;
|
|
wi::graphics::GPUBuffer metadata;
|
|
wi::graphics::Texture scratch[2];
|
|
wi::graphics::Texture moments[2];
|
|
};
|
|
void CreateRTAOResources(RTAOResources& res, XMUINT2 resolution);
|
|
void Postprocess_RTAO(
|
|
const RTAOResources& res,
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float range = 1.0f,
|
|
float power = 1.0f
|
|
);
|
|
struct RTDiffuseResources
|
|
{
|
|
mutable int frame = 0;
|
|
wi::graphics::Texture texture_rayIndirectDiffuse;
|
|
wi::graphics::Texture texture_spatial;
|
|
wi::graphics::Texture texture_spatial_variance;
|
|
wi::graphics::Texture texture_temporal[2];
|
|
wi::graphics::Texture texture_temporal_variance[2];
|
|
};
|
|
void CreateRTDiffuseResources(RTDiffuseResources& res, XMUINT2 resolution);
|
|
void Postprocess_RTDiffuse(
|
|
const RTDiffuseResources& res,
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float range = 1000.0f
|
|
);
|
|
struct SSGIResources
|
|
{
|
|
mutable bool cleared = false;
|
|
wi::graphics::Texture texture_atlas_depth;
|
|
wi::graphics::Texture texture_atlas_color;
|
|
wi::graphics::Texture texture_depth_mips;
|
|
wi::graphics::Texture texture_normal_mips;
|
|
wi::graphics::Texture texture_diffuse_mips;
|
|
};
|
|
void CreateSSGIResources(SSGIResources& res, XMUINT2 resolution);
|
|
void Postprocess_SSGI(
|
|
const SSGIResources& res,
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& input_depth,
|
|
const wi::graphics::Texture& input_normal,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float depthRejection = 8
|
|
);
|
|
struct RTReflectionResources
|
|
{
|
|
mutable int frame = 0;
|
|
wi::graphics::Texture texture_rayIndirectSpecular;
|
|
wi::graphics::Texture texture_rayDirectionPDF;
|
|
wi::graphics::Texture texture_rayLengths;
|
|
wi::graphics::Texture texture_resolve;
|
|
wi::graphics::Texture texture_resolve_variance;
|
|
wi::graphics::Texture texture_resolve_reprojectionDepth;
|
|
wi::graphics::Texture texture_temporal[2];
|
|
wi::graphics::Texture texture_temporal_variance[2];
|
|
};
|
|
void CreateRTReflectionResources(RTReflectionResources& res, XMUINT2 resolution);
|
|
void Postprocess_RTReflection(
|
|
const RTReflectionResources& res,
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float range = 1000.0f,
|
|
float roughnessCutoff = 0.5f
|
|
);
|
|
struct SSRResources
|
|
{
|
|
mutable int frame = 0;
|
|
wi::graphics::Texture texture_tile_minmax_roughness_horizontal;
|
|
wi::graphics::Texture texture_tile_minmax_roughness;
|
|
wi::graphics::Texture texture_depth_hierarchy;
|
|
wi::graphics::Texture texture_rayIndirectSpecular;
|
|
wi::graphics::Texture texture_rayDirectionPDF;
|
|
wi::graphics::Texture texture_rayLengths;
|
|
wi::graphics::Texture texture_resolve;
|
|
wi::graphics::Texture texture_resolve_variance;
|
|
wi::graphics::Texture texture_resolve_reprojectionDepth;
|
|
wi::graphics::Texture texture_temporal[2];
|
|
wi::graphics::Texture texture_temporal_variance[2];
|
|
wi::graphics::GPUBuffer buffer_tile_tracing_statistics;
|
|
wi::graphics::GPUBuffer buffer_tiles_tracing_earlyexit;
|
|
wi::graphics::GPUBuffer buffer_tiles_tracing_cheap;
|
|
wi::graphics::GPUBuffer buffer_tiles_tracing_expensive;
|
|
};
|
|
void CreateSSRResources(SSRResources& res, XMUINT2 resolution);
|
|
void Postprocess_SSR(
|
|
const SSRResources& res,
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float roughnessCutoff = 0.6f
|
|
);
|
|
struct RTShadowResources
|
|
{
|
|
wi::graphics::Texture raytraced;
|
|
wi::graphics::Texture temporal[2];
|
|
wi::graphics::Texture normals;
|
|
|
|
mutable int frame = 0;
|
|
wi::graphics::GPUBuffer tiles;
|
|
wi::graphics::GPUBuffer metadata;
|
|
wi::graphics::Texture scratch[4][2];
|
|
wi::graphics::Texture moments[4][2];
|
|
wi::graphics::Texture denoised;
|
|
};
|
|
void CreateRTShadowResources(RTShadowResources& res, XMUINT2 resolution);
|
|
void Postprocess_RTShadow(
|
|
const RTShadowResources& res,
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::GPUBuffer& entityTiles_Opaque,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
struct ScreenSpaceShadowResources
|
|
{
|
|
wi::graphics::Texture lowres;
|
|
};
|
|
void CreateScreenSpaceShadowResources(ScreenSpaceShadowResources& res, XMUINT2 resolution);
|
|
void Postprocess_ScreenSpaceShadow(
|
|
const ScreenSpaceShadowResources& res,
|
|
const wi::graphics::GPUBuffer& entityTiles_Opaque,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float range = 1,
|
|
uint32_t samplecount = 16
|
|
);
|
|
void Postprocess_LightShafts(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
const XMFLOAT2& center,
|
|
float strength = 0.1f
|
|
);
|
|
struct DepthOfFieldResources
|
|
{
|
|
wi::graphics::Texture texture_tilemax_horizontal;
|
|
wi::graphics::Texture texture_tilemin_horizontal;
|
|
wi::graphics::Texture texture_tilemax;
|
|
wi::graphics::Texture texture_tilemin;
|
|
wi::graphics::Texture texture_neighborhoodmax;
|
|
wi::graphics::Texture texture_presort;
|
|
wi::graphics::Texture texture_prefilter;
|
|
wi::graphics::Texture texture_main;
|
|
wi::graphics::Texture texture_postfilter;
|
|
wi::graphics::Texture texture_alpha1;
|
|
wi::graphics::Texture texture_alpha2;
|
|
wi::graphics::GPUBuffer buffer_tile_statistics;
|
|
wi::graphics::GPUBuffer buffer_tiles_earlyexit;
|
|
wi::graphics::GPUBuffer buffer_tiles_cheap;
|
|
wi::graphics::GPUBuffer buffer_tiles_expensive;
|
|
|
|
bool IsValid() const { return texture_tilemax_horizontal.IsValid(); }
|
|
};
|
|
void CreateDepthOfFieldResources(DepthOfFieldResources& res, XMUINT2 resolution);
|
|
void Postprocess_DepthOfField(
|
|
const DepthOfFieldResources& res,
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float coc_scale = 10,
|
|
float max_coc = 18
|
|
);
|
|
void Postprocess_Outline(
|
|
const wi::graphics::Texture& input,
|
|
wi::graphics::CommandList cmd,
|
|
float threshold = 0.1f,
|
|
float thickness = 1.0f,
|
|
const XMFLOAT4& color = XMFLOAT4(0, 0, 0, 1)
|
|
);
|
|
struct MotionBlurResources
|
|
{
|
|
wi::graphics::Texture texture_tilemin_horizontal;
|
|
wi::graphics::Texture texture_tilemax_horizontal;
|
|
wi::graphics::Texture texture_tilemax;
|
|
wi::graphics::Texture texture_tilemin;
|
|
wi::graphics::Texture texture_neighborhoodmax;
|
|
wi::graphics::GPUBuffer buffer_tile_statistics;
|
|
wi::graphics::GPUBuffer buffer_tiles_earlyexit;
|
|
wi::graphics::GPUBuffer buffer_tiles_cheap;
|
|
wi::graphics::GPUBuffer buffer_tiles_expensive;
|
|
|
|
bool IsValid() const { return texture_tilemax_horizontal.IsValid(); }
|
|
};
|
|
void CreateMotionBlurResources(MotionBlurResources& res, XMUINT2 resolution);
|
|
void Postprocess_MotionBlur(
|
|
float dt, // delta time in seconds
|
|
const MotionBlurResources& res,
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float strength = 100.0f
|
|
);
|
|
struct AerialPerspectiveResources
|
|
{
|
|
wi::graphics::Texture texture_output;
|
|
};
|
|
void CreateAerialPerspectiveResources(AerialPerspectiveResources& res, XMUINT2 resolution);
|
|
void Postprocess_AerialPerspective(
|
|
const AerialPerspectiveResources& res,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
struct VolumetricCloudResources
|
|
{
|
|
mutable int frame = -1;
|
|
XMUINT2 final_resolution = {};
|
|
wi::graphics::Texture texture_cloudRender;
|
|
wi::graphics::Texture texture_cloudDepth;
|
|
wi::graphics::Texture texture_reproject[2];
|
|
wi::graphics::Texture texture_reproject_depth[2];
|
|
wi::graphics::Texture texture_reproject_additional[2];
|
|
wi::graphics::Texture texture_cloudMask;
|
|
|
|
void ResetFrame() const { frame = -1; }
|
|
void AdvanceFrame() const { frame++; }
|
|
int GetTemporalOutputIndex() const { return frame % 2; }
|
|
int GetTemporalInputIndex() const { return 1 - GetTemporalOutputIndex(); }
|
|
};
|
|
void CreateVolumetricCloudResources(VolumetricCloudResources& res, XMUINT2 resolution);
|
|
void Postprocess_VolumetricClouds(
|
|
const VolumetricCloudResources& res,
|
|
wi::graphics::CommandList cmd,
|
|
const wi::scene::CameraComponent& camera,
|
|
const wi::scene::CameraComponent& camera_previous,
|
|
const wi::scene::CameraComponent& camera_reflection,
|
|
const bool jitterEnabled,
|
|
const wi::graphics::Texture* weatherMapFirst = nullptr,
|
|
const wi::graphics::Texture* weatherMapSecond = nullptr
|
|
);
|
|
void Postprocess_VolumetricClouds_Upsample(
|
|
const VolumetricCloudResources& res,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Postprocess_FXAA(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
struct TemporalAAResources
|
|
{
|
|
mutable int frame = 0;
|
|
wi::graphics::Texture texture_temporal[2];
|
|
|
|
bool IsValid() const { return texture_temporal[0].IsValid(); }
|
|
const wi::graphics::Texture* GetCurrent() const { return &texture_temporal[frame % arraysize(texture_temporal)]; }
|
|
const wi::graphics::Texture* GetHistory() const { return &texture_temporal[(frame + 1) % arraysize(texture_temporal)]; }
|
|
};
|
|
void CreateTemporalAAResources(TemporalAAResources& res, XMUINT2 resolution);
|
|
void Postprocess_TemporalAA(
|
|
const TemporalAAResources& res,
|
|
const wi::graphics::Texture& input,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Postprocess_Sharpen(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float amount = 1.0f
|
|
);
|
|
void Postprocess_CRT(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float flicker_amount = 0,
|
|
float flicker_timer = 0,
|
|
bool srgb = true // if true, then srgb->linear->crt filter->srgb conversion will be done
|
|
);
|
|
enum class Tonemap
|
|
{
|
|
Reinhard,
|
|
ACES
|
|
};
|
|
void Postprocess_Tonemap(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float exposure,
|
|
float brightness,
|
|
float contrast,
|
|
float saturation,
|
|
bool dither,
|
|
const wi::graphics::Texture* texture_colorgradinglut = nullptr,
|
|
const wi::graphics::Texture* texture_distortion = nullptr,
|
|
const wi::graphics::GPUBuffer* buffer_luminance = nullptr,
|
|
const wi::graphics::Texture* texture_bloom = nullptr,
|
|
wi::graphics::ColorSpace display_colorspace = wi::graphics::ColorSpace::SRGB,
|
|
Tonemap tonemap = Tonemap::Reinhard,
|
|
const wi::graphics::Texture* texture_distortion_overlay = nullptr,
|
|
float hdr_calibration = 1
|
|
);
|
|
void Postprocess_FSR(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& temp,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float sharpness = 1.0f
|
|
);
|
|
struct FSR2Resources
|
|
{
|
|
struct Fsr2Constants
|
|
{
|
|
int32_t renderSize[2];
|
|
int32_t displaySize[2];
|
|
uint32_t lumaMipDimensions[2];
|
|
uint32_t lumaMipLevelToUse;
|
|
uint32_t frameIndex;
|
|
float displaySizeRcp[2];
|
|
float jitterOffset[2];
|
|
float deviceToViewDepth[4];
|
|
float depthClipUVScale[2];
|
|
float postLockStatusUVScale[2];
|
|
float reactiveMaskDimRcp[2];
|
|
float motionVectorScale[2];
|
|
float downscaleFactor[2];
|
|
float preExposure;
|
|
float tanHalfFOV;
|
|
float motionVectorJitterCancellation[2];
|
|
float jitterPhaseCount;
|
|
float lockInitialLifetime;
|
|
float lockTickDelta;
|
|
float deltaTime;
|
|
float dynamicResChangeFactor;
|
|
float lumaMipRcp;
|
|
};
|
|
mutable Fsr2Constants fsr2_constants = {};
|
|
wi::graphics::Texture adjusted_color;
|
|
wi::graphics::Texture luminance_current;
|
|
wi::graphics::Texture luminance_history;
|
|
wi::graphics::Texture exposure;
|
|
wi::graphics::Texture previous_depth;
|
|
wi::graphics::Texture dilated_depth;
|
|
wi::graphics::Texture dilated_motion;
|
|
wi::graphics::Texture dilated_reactive;
|
|
wi::graphics::Texture disocclusion_mask;
|
|
wi::graphics::Texture lock_status[2];
|
|
wi::graphics::Texture reactive_mask;
|
|
wi::graphics::Texture lanczos_lut;
|
|
wi::graphics::Texture maximum_bias_lut;
|
|
wi::graphics::Texture spd_global_atomic;
|
|
wi::graphics::Texture output_internal[2];
|
|
|
|
bool IsValid() const { return adjusted_color.IsValid(); }
|
|
|
|
XMFLOAT2 GetJitter() const;
|
|
};
|
|
void CreateFSR2Resources(FSR2Resources& res, XMUINT2 render_resolution, XMUINT2 presentation_resolution);
|
|
void Postprocess_FSR2(
|
|
const FSR2Resources& res,
|
|
const wi::scene::CameraComponent& camera,
|
|
const wi::graphics::Texture& input_pre_alpha,
|
|
const wi::graphics::Texture& input_post_alpha,
|
|
const wi::graphics::Texture& input_depth,
|
|
const wi::graphics::Texture& input_velocity,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float dt, // delta time in seconds
|
|
float sharpness = 0.5f
|
|
);
|
|
void Postprocess_Chromatic_Aberration(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
float amount = 1.0f
|
|
);
|
|
void Postprocess_Upsample_Bilateral(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& lineardepth,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
bool is_pixelshader = false,
|
|
float threshold = 1.0f
|
|
);
|
|
void Postprocess_Downsample4x(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
bool hdrToSRGB = false
|
|
);
|
|
void Postprocess_Lineardepth(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Postprocess_NormalsFromDepth(
|
|
const wi::graphics::Texture& depthbuffer,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Postprocess_Underwater(
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
struct MeshBlendResources
|
|
{
|
|
wi::graphics::Texture mask;
|
|
wi::graphics::Texture tmp;
|
|
wi::graphics::Texture expand[2];
|
|
|
|
bool IsValid() const { return mask.IsValid(); }
|
|
};
|
|
void CreateMeshBlendResources(MeshBlendResources& res, XMUINT2 resolution);
|
|
void PostProcess_MeshBlend_EdgeProcess( // this part can be run on async compute, it doesn't need color buffer, only the primID
|
|
const MeshBlendResources& res,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void PostProcess_MeshBlend_Resolve( // this part can only be run on gfx queue, it will use renderpass internally (to support MSAA)
|
|
const MeshBlendResources& res,
|
|
const wi::graphics::Texture& output,
|
|
const wi::graphics::RenderPassImage* renderpass_images,
|
|
uint32_t renderpass_image_count,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
void Postprocess_Custom(
|
|
const wi::graphics::Shader& computeshader,
|
|
const wi::graphics::Texture& input,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd,
|
|
const XMFLOAT4& params0 = XMFLOAT4(0, 0, 0, 0),
|
|
const XMFLOAT4& params1 = XMFLOAT4(0, 0, 0, 0),
|
|
const char* debug_name = "Postprocess_Custom"
|
|
);
|
|
|
|
void YUV_to_RGB(
|
|
const wi::graphics::Texture& input,
|
|
int input_subresource_luminance,
|
|
int input_subresource_chrominance,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// This performs copies from separate depth and stencil shader resource textures
|
|
// into hardware depthStencil buffer that supports depth/stencil testing
|
|
// This is only supported by QUEUE_GRAPHICS!
|
|
// stencil_bits_to_copy : bitmask can be specified to mask out stencil bits that will be copied
|
|
// depthstencil_already_cleared : if false, it will be fully cleared if required; if true, it will be left intact
|
|
void CopyDepthStencil(
|
|
const wi::graphics::Texture* input_depth,
|
|
const wi::graphics::Texture* input_stencil,
|
|
const wi::graphics::Texture& output_depth_stencil,
|
|
wi::graphics::CommandList cmd,
|
|
uint8_t stencil_bits_to_copy = 0xFF,
|
|
bool depthstencil_already_cleared = false
|
|
);
|
|
|
|
// The input texture mask is scaled into the stencil of the current render pass with the specified viewport
|
|
void ScaleStencilMask(
|
|
const wi::graphics::Viewport& vp,
|
|
const wi::graphics::Texture& input,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// Extract stencil from a depth stencil texture into a R8_UINT format texture
|
|
void ExtractStencil(
|
|
const wi::graphics::Texture& input_depthstencil,
|
|
const wi::graphics::Texture& output,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
// Render the scene with ray tracing
|
|
void RayTraceScene(
|
|
const wi::scene::Scene& scene,
|
|
const wi::graphics::Texture& output,
|
|
int accumulation_sample,
|
|
wi::graphics::CommandList cmd,
|
|
const wi::graphics::Texture* output_albedo = nullptr,
|
|
const wi::graphics::Texture* output_normal = nullptr,
|
|
const wi::graphics::Texture* output_depth = nullptr,
|
|
const wi::graphics::Texture* output_stencil = nullptr,
|
|
const wi::graphics::Texture* output_depth_stencil = nullptr,
|
|
const wi::graphics::Texture* output_primitiveID = nullptr
|
|
);
|
|
// Render the scene BVH with ray tracing to the screen
|
|
void RayTraceSceneBVH(const wi::scene::Scene& scene, wi::graphics::CommandList cmd);
|
|
|
|
// Render occluders against a depth buffer
|
|
void OcclusionCulling_Reset(const Visibility& vis, wi::graphics::CommandList cmd);
|
|
void OcclusionCulling_Render(const wi::scene::CameraComponent& camera, const Visibility& vis, wi::graphics::CommandList cmd);
|
|
void OcclusionCulling_Resolve(const Visibility& vis, wi::graphics::CommandList cmd);
|
|
|
|
void ComputeReprojectedDepthPyramid(
|
|
const wi::graphics::Texture& input_depth,
|
|
const wi::graphics::Texture& input_velocity,
|
|
const wi::graphics::Texture& output_depth_pyramid,
|
|
wi::graphics::CommandList cmd
|
|
);
|
|
|
|
enum MIPGENFILTER
|
|
{
|
|
MIPGENFILTER_POINT,
|
|
MIPGENFILTER_LINEAR,
|
|
MIPGENFILTER_GAUSSIAN,
|
|
};
|
|
struct MIPGEN_OPTIONS
|
|
{
|
|
int arrayIndex = -1;
|
|
const wi::graphics::Texture* gaussian_temp = nullptr;
|
|
bool preserve_coverage = false;
|
|
bool wide_gauss = false;
|
|
};
|
|
void GenerateMipChain(const wi::graphics::Texture& texture, MIPGENFILTER filter, wi::graphics::CommandList cmd, const MIPGEN_OPTIONS& options = {});
|
|
|
|
// Compress a texture into Block Compressed format
|
|
// texture_src : source uncompressed texture
|
|
// texture_bc : destination comporessed texture, must be a supported BC format (BC1/BC3/BC4/BC5/BC6H_UFLOAT)
|
|
// Currently this will handle simple Texture2D with mip levels, and additionally BC6H cubemap
|
|
void BlockCompress(const wi::graphics::Texture& texture_src, const wi::graphics::Texture& texture_bc, wi::graphics::CommandList cmd, uint32_t dst_slice_offset = 0);
|
|
|
|
enum BORDEREXPANDSTYLE
|
|
{
|
|
BORDEREXPAND_DISABLE,
|
|
BORDEREXPAND_WRAP,
|
|
BORDEREXPAND_CLAMP,
|
|
};
|
|
// Performs copy operation even between different texture formats
|
|
// NOTE: DstMIP can be specified as -1 to use main subresource, otherwise the subresource (>=0) must have been generated explicitly!
|
|
// Can also expand border region according to desired sampler func
|
|
void CopyTexture2D(
|
|
const wi::graphics::Texture& dst, int DstMIP, int DstX, int DstY,
|
|
const wi::graphics::Texture& src, int SrcMIP, int SrcX, int SrcY,
|
|
wi::graphics::CommandList cmd,
|
|
BORDEREXPANDSTYLE borderExpand = BORDEREXPAND_DISABLE,
|
|
bool srgb_convert = false
|
|
);
|
|
// Performs copy operation even between different texture formats
|
|
// Simplified function overload
|
|
void CopyTexture2D(
|
|
const wi::graphics::Texture& dst,
|
|
const wi::graphics::Texture& src,
|
|
wi::graphics::CommandList cmd,
|
|
BORDEREXPANDSTYLE borderExpand = BORDEREXPAND_DISABLE,
|
|
bool srgb_convert = false
|
|
);
|
|
|
|
void DrawWaterRipples(const Visibility& vis, wi::graphics::CommandList cmd);
|
|
|
|
|
|
void DrawWaveEffect(const XMFLOAT4& color, wi::graphics::CommandList cmd);
|
|
|
|
|
|
|
|
void SetShadowProps2D(int max_resolution);
|
|
void SetShadowPropsCube(int max_resolution);
|
|
|
|
enum WIREFRAME_MODE
|
|
{
|
|
WIREFRAME_DISABLED = 0,
|
|
WIREFRAME_ONLY = 1,
|
|
WIREFRAME_OVERLAY = 2,
|
|
};
|
|
|
|
void SetWireRender(bool value);
|
|
bool IsWireRender();
|
|
void SetWireframeMode(WIREFRAME_MODE mode);
|
|
WIREFRAME_MODE GetWireframeMode();
|
|
void SetToDrawDebugBoneLines(bool param);
|
|
bool GetToDrawDebugBoneLines();
|
|
void SetToDrawDebugPartitionTree(bool param);
|
|
bool GetToDrawDebugPartitionTree();
|
|
bool GetToDrawDebugEnvProbes();
|
|
void SetToDrawDebugEnvProbes(bool value);
|
|
void SetToDrawDebugEmitters(bool param);
|
|
bool GetToDrawDebugEmitters();
|
|
void SetToDrawDebugForceFields(bool param);
|
|
bool GetToDrawDebugForceFields();
|
|
void SetToDrawDebugCameras(bool param);
|
|
bool GetToDrawDebugCameras();
|
|
void SetToDrawDebugColliders(bool param);
|
|
bool GetToDrawDebugColliders();
|
|
void SetToDrawDebugSprings(bool param);
|
|
bool GetToDrawDebugSprings();
|
|
bool GetToDrawGridHelper();
|
|
void SetToDrawGridHelper(bool value);
|
|
bool GetToDrawVoxelHelper();
|
|
void SetToDrawVoxelHelper(bool value, int clipmap_level);
|
|
void SetDebugLightCulling(bool enabled);
|
|
bool GetDebugLightCulling();
|
|
void SetAdvancedLightCulling(bool enabled);
|
|
bool GetAdvancedLightCulling();
|
|
void SetVariableRateShadingClassification(bool enabled);
|
|
bool GetVariableRateShadingClassification();
|
|
void SetVariableRateShadingClassificationDebug(bool enabled);
|
|
bool GetVariableRateShadingClassificationDebug();
|
|
void SetOcclusionCullingEnabled(bool enabled);
|
|
bool GetOcclusionCullingEnabled();
|
|
void SetTemporalAAEnabled(bool enabled);
|
|
bool GetTemporalAAEnabled();
|
|
void SetTemporalAADebugEnabled(bool enabled);
|
|
bool GetTemporalAADebugEnabled();
|
|
void SetFreezeCullingCameraEnabled(bool enabled);
|
|
bool GetFreezeCullingCameraEnabled();
|
|
void SetVXGIEnabled(bool enabled);
|
|
bool GetVXGIEnabled();
|
|
void SetVXGIReflectionsEnabled(bool enabled);
|
|
bool GetVXGIReflectionsEnabled();
|
|
void SetGameSpeed(float value);
|
|
float GetGameSpeed();
|
|
void SetShadowsEnabled(bool value);
|
|
bool IsShadowsEnabled();
|
|
void SetRaytraceBounceCount(uint32_t bounces);
|
|
uint32_t GetRaytraceBounceCount();
|
|
void SetRaytraceDebugBVHVisualizerEnabled(bool value);
|
|
bool GetRaytraceDebugBVHVisualizerEnabled();
|
|
void SetRaytracedShadowsEnabled(bool value);
|
|
bool GetRaytracedShadowsEnabled();
|
|
void SetTessellationEnabled(bool value);
|
|
bool GetTessellationEnabled();
|
|
void SetDisableAlbedoMaps(bool value);
|
|
bool IsDisableAlbedoMaps();
|
|
void SetForceDiffuseLighting(bool value);
|
|
bool IsForceDiffuseLighting();
|
|
void SetScreenSpaceShadowsEnabled(bool value);
|
|
bool GetScreenSpaceShadowsEnabled();
|
|
void SetSurfelGIEnabled(bool value);
|
|
bool GetSurfelGIEnabled();
|
|
void SetSurfelGIDebugEnabled(SURFEL_DEBUG value);
|
|
SURFEL_DEBUG GetSurfelGIDebugEnabled();
|
|
void SetDDGIEnabled(bool value);
|
|
bool GetDDGIEnabled();
|
|
void SetDDGIDebugEnabled(bool value);
|
|
bool GetDDGIDebugEnabled();
|
|
void SetDDGIRayCount(uint32_t value);
|
|
uint32_t GetDDGIRayCount();
|
|
void SetDDGIBlendSpeed(float value);
|
|
float GetDDGIBlendSpeed();
|
|
void SetGIBoost(float value);
|
|
float GetGIBoost();
|
|
void SetMeshShaderAllowed(bool value);
|
|
bool IsMeshShaderAllowed();
|
|
void SetMeshletOcclusionCullingEnabled(bool value);
|
|
bool IsMeshletOcclusionCullingEnabled();
|
|
void Workaround( const int bug, wi::graphics::CommandList cmd);
|
|
void SetCapsuleShadowEnabled(bool value);
|
|
bool IsCapsuleShadowEnabled();
|
|
void SetCapsuleShadowAngle(float value); // cone angle in radians
|
|
float GetCapsuleShadowAngle();
|
|
void SetCapsuleShadowFade(float value);
|
|
float GetCapsuleShadowFade();
|
|
void SetShadowLODOverrideEnabled(bool value); // Allow shadowmap rendering to request custom LOD for objects (can result in shadow mismatch, but increased GPU performance)
|
|
bool IsShadowLODOverrideEnabled();
|
|
|
|
// Gets pick ray according to the current screen resolution and pointer coordinates. Can be used as input into RayIntersectWorld()
|
|
wi::primitive::Ray GetPickRay(long cursorX, long cursorY, const wi::Canvas& canvas, const wi::scene::CameraComponent& camera = wi::scene::GetCamera());
|
|
|
|
|
|
// Add box to render in next frame. It will be rendered in DrawDebugWorld()
|
|
void DrawBox(const wi::primitive::AABB& aabb, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1), bool depth = true);
|
|
void DrawBox(const XMMATRIX& boxMatrix, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1), bool depth = true);
|
|
void DrawBox(const XMFLOAT4X4& boxMatrix, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1), bool depth = true);
|
|
void DrawBox(const BoundingOrientedBox& obb, const XMFLOAT4& color = XMFLOAT4(1,1,1,1), bool depth = true);
|
|
// Add sphere to render in next frame. It will be rendered in DrawDebugWorld()
|
|
void DrawSphere(const wi::primitive::Sphere& sphere, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1), bool depth = true);
|
|
// Add capsule to render in next frame. It will be rendered in DrawDebugWorld()
|
|
void DrawCapsule(const wi::primitive::Capsule& capsule, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1), bool depth = true);
|
|
|
|
struct RenderableLine
|
|
{
|
|
XMFLOAT3 start = XMFLOAT3(0, 0, 0);
|
|
XMFLOAT3 end = XMFLOAT3(0, 0, 0);
|
|
XMFLOAT4 color_start = XMFLOAT4(1, 1, 1, 1);
|
|
XMFLOAT4 color_end = XMFLOAT4(1, 1, 1, 1);
|
|
};
|
|
// Add line to render in the next frame. It will be rendered in DrawDebugWorld()
|
|
void DrawLine(const RenderableLine& line, bool depth = false);
|
|
|
|
struct RenderableLine2D
|
|
{
|
|
XMFLOAT2 start = XMFLOAT2(0, 0);
|
|
XMFLOAT2 end = XMFLOAT2(0, 0);
|
|
XMFLOAT4 color_start = XMFLOAT4(1, 1, 1, 1);
|
|
XMFLOAT4 color_end = XMFLOAT4(1, 1, 1, 1);
|
|
};
|
|
// Add 2D line to render in the next frame. It will be rendered in DrawDebugWorld() in screen space
|
|
void DrawLine(const RenderableLine2D& line);
|
|
|
|
void DrawAxis(const XMMATRIX& matrix, float size, bool depth = false);
|
|
|
|
struct RenderablePoint
|
|
{
|
|
XMFLOAT3 position = XMFLOAT3(0, 0, 0);
|
|
float size = 1.0f;
|
|
XMFLOAT4 color = XMFLOAT4(1, 1, 1, 1);
|
|
};
|
|
// Add point to render in the next frame. It will be rendered in DrawDebugWorld() as an X
|
|
void DrawPoint(const RenderablePoint& point, bool depth = false);
|
|
|
|
struct RenderableTriangle
|
|
{
|
|
XMFLOAT3 positionA = XMFLOAT3(0, 0, 0);
|
|
XMFLOAT4 colorA = XMFLOAT4(1, 1, 1, 1);
|
|
XMFLOAT3 positionB = XMFLOAT3(0, 0, 0);
|
|
XMFLOAT4 colorB = XMFLOAT4(1, 1, 1, 1);
|
|
XMFLOAT3 positionC = XMFLOAT3(0, 0, 0);
|
|
XMFLOAT4 colorC = XMFLOAT4(1, 1, 1, 1);
|
|
};
|
|
// Add triangle to render in the next frame. It will be rendered in DrawDebugWorld()
|
|
void DrawTriangle(const RenderableTriangle& triangle, bool wireframe = false, bool depth = true);
|
|
|
|
struct DebugTextParams
|
|
{
|
|
XMFLOAT3 position = XMFLOAT3(0, 0, 0);
|
|
int pixel_height = 32;
|
|
float scaling = 1;
|
|
XMFLOAT4 color = XMFLOAT4(1, 1, 1, 1);
|
|
enum FLAGS // do not change values, it's bound to lua manually!
|
|
{
|
|
NONE = 0,
|
|
DEPTH_TEST = 1 << 0, // text can be occluded by geometry
|
|
CAMERA_FACING = 1 << 1, // text will be rotated to face the camera
|
|
CAMERA_SCALING = 1 << 2, // text will be always the same size, independent of distance to camera
|
|
};
|
|
uint32_t flags = NONE;
|
|
};
|
|
// Add text to render in the next frame. It will be rendered in DrawDebugWorld()
|
|
// The memory to text doesn't need to be retained by the caller, as it will be copied internally
|
|
void DrawDebugText(const char* text, const DebugTextParams& params);
|
|
|
|
struct PaintRadius
|
|
{
|
|
wi::ecs::Entity objectEntity = wi::ecs::INVALID_ENTITY;
|
|
int subset = -1;
|
|
uint32_t uvset = 0;
|
|
float radius = 0;
|
|
XMUINT2 center = {};
|
|
XMUINT2 dimensions = {};
|
|
float rotation = 0;
|
|
uint shape = 0; // 0: circle, 1 : square
|
|
};
|
|
void DrawPaintRadius(const PaintRadius& paintrad);
|
|
|
|
struct PaintTextureParams
|
|
{
|
|
wi::graphics::Texture editTex; // UAV writable texture
|
|
wi::graphics::Texture brushTex; // splat texture (optional)
|
|
wi::graphics::Texture revealTex; // mask texture that can be revealed (optional)
|
|
PaintTexturePushConstants push = {}; // shader parameters
|
|
};
|
|
void PaintIntoTexture(const PaintTextureParams& params);
|
|
wi::Resource CreatePaintableTexture(uint32_t width, uint32_t height, uint32_t mips = 0, wi::Color initialColor = wi::Color::Transparent());
|
|
|
|
struct PaintDecalParams
|
|
{
|
|
wi::ecs::Entity objectEntity = wi::ecs::INVALID_ENTITY;
|
|
XMFLOAT4X4 decalMatrix = wi::math::IDENTITY_MATRIX;
|
|
wi::graphics::Texture in_texture;
|
|
wi::graphics::Texture out_texture;
|
|
float slopeBlendPower = 0;
|
|
};
|
|
// Render a decal into a texture mapped onto a mesh (supports skinned mesh)
|
|
// objectEntity : entity that has an ObjectComponent in the scene
|
|
// decalMatrix : decal projection matrix in world space
|
|
// in_texture : texture containing the source decal
|
|
// out_texture : texture containing the result decal(s) wrapped onto the object
|
|
void PaintDecalIntoObjectSpaceTexture(const PaintDecalParams& params);
|
|
|
|
// Add voxel grid to be drawn in debug rendering phase.
|
|
// WARNING: This retains pointer until next call to DrawDebugScene(), so voxel grid must not be destroyed until then!
|
|
void DrawVoxelGrid(const wi::VoxelGrid* voxelgrid);
|
|
|
|
// Add path query to be drawn in debug rendering phase.
|
|
// WARNING: This retains pointer until next call to DrawDebugScene(), so path query must not be destroyed until then!
|
|
void DrawPathQuery(const wi::PathQuery* pathquery);
|
|
|
|
// Add trail to be drawn in debug rendering phase.
|
|
// WARNING: This retains pointer until next call to DrawDebugScene(), so trail must not be destroyed until then!
|
|
void DrawTrail(const wi::TrailRenderer* trail);
|
|
|
|
// Add a texture that should be mipmapped whenever it is feasible to do so
|
|
void AddDeferredMIPGen(const wi::graphics::Texture& texture, bool preserve_coverage = false);
|
|
void AddDeferredBlockCompression(const wi::graphics::Texture& texture_src, const wi::graphics::Texture& texture_bc);
|
|
|
|
struct CustomShader
|
|
{
|
|
std::string name;
|
|
uint32_t filterMask = wi::enums::FILTER_OPAQUE;
|
|
wi::graphics::PipelineState pso[wi::enums::RENDERPASS_COUNT] = {};
|
|
};
|
|
// Registers a custom shader that can be set to materials.
|
|
// Returns the ID of the custom shader that can be used with MaterialComponent::SetCustomShaderID()
|
|
int RegisterCustomShader(const CustomShader& customShader);
|
|
const wi::vector<CustomShader>& GetCustomShaders();
|
|
|
|
// Thread-local barrier batching helpers:
|
|
void PushBarrier(const wi::graphics::GPUBarrier& barrier);
|
|
void FlushBarriers(wi::graphics::CommandList cmd);
|
|
|
|
};
|
|
|