Bindless RenderPath (#328)

* remove all resource bindings from renderpath, they will be descriptor indices attached to camera CB data

* fix

* big refactor: bindings removal

* minor update renderpath3d

* version bump

* fix

* big refactor: shader weather params

* refactor

* this update will increase minor version number as interface changes were made

* dx12, vulkan fix: dirty pso state was not handled correctly

* moved lot of things to camera CB, refactors

* cameracb padding fix
This commit is contained in:
Turánszki János
2021-10-05 13:23:40 +02:00
committed by GitHub
parent fcc3c3b3b0
commit d8ad89257a
87 changed files with 1061 additions and 1137 deletions
+76 -83
View File
@@ -144,16 +144,6 @@ void RenderPath3D::ResizeBuffers()
device->CreateTexture(&desc, nullptr, &rtReflection);
device->SetName(&rtReflection, "rtReflection");
}
{
TextureDesc desc;
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
desc.Format = FORMAT_R32G32B32A32_UINT;
desc.Width = internalResolution.x / 2;
desc.Height = internalResolution.y / 2;
desc.layout = RESOURCE_STATE_SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &rtShadow);
device->SetName(&rtShadow, "rtShadow");
}
{
TextureDesc desc;
desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE;
@@ -224,7 +214,6 @@ void RenderPath3D::ResizeBuffers()
device->CreateTexture(&desc, nullptr, &rtGUIBlurredBackground[2]);
device->SetName(&rtGUIBlurredBackground[2], "rtGUIBlurredBackground[2]");
}
if(device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_VARIABLE_RATE_SHADING_TIER2) &&
wiRenderer::GetVariableRateShadingClassification())
{
@@ -240,6 +229,9 @@ void RenderPath3D::ResizeBuffers()
device->CreateTexture(&desc, nullptr, &rtShadingRate);
device->SetName(&rtShadingRate, "rtShadingRate");
}
rtAO = {};
rtShadow = {};
rtSSR = {};
// Depth buffers:
{
@@ -494,7 +486,7 @@ void RenderPath3D::ResizeBuffers()
device->SetName(&debugUAV, "debugUAV");
}
wiRenderer::CreateTiledLightResources(tiledLightResources, internalResolution);
wiRenderer::CreateTiledLightResources(tiledLightResources_planarReflection, internalResolution);
wiRenderer::CreateTiledLightResources(tiledLightResources_planarReflection, XMUINT2(depthBuffer_Reflection.desc.Width, depthBuffer_Reflection.desc.Height));
wiRenderer::CreateLuminanceResources(luminanceResources, internalResolution);
wiRenderer::CreateScreenSpaceShadowResources(screenspaceshadowResources, internalResolution);
wiRenderer::CreateDepthOfFieldResources(depthoffieldResources, internalResolution);
@@ -571,8 +563,6 @@ void RenderPath3D::Update(float dt)
*scene,
visibility_main,
frameCB,
internalResolution,
*this,
dt
);
@@ -596,8 +586,68 @@ void RenderPath3D::Update(float dt)
{
rtshadowResources.frame = 0;
}
if (!getSSREnabled() && !getRaytracedReflectionEnabled())
{
rtSSR = {};
}
if (getAO() == AO_DISABLED)
{
rtAO = {};
}
if (!wiRenderer::GetScreenSpaceShadowsEnabled() && !wiRenderer::GetRaytracedShadowsEnabled())
{
rtShadow = {};
}
GraphicsDevice* device = wiRenderer::GetDevice();
if((wiRenderer::GetScreenSpaceShadowsEnabled() || wiRenderer::GetRaytracedShadowsEnabled()) && !rtShadow.IsValid())
{
TextureDesc desc;
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
desc.Format = FORMAT_R32G32B32A32_UINT;
desc.Width = internalResolution.x / 2;
desc.Height = internalResolution.y / 2;
desc.layout = RESOURCE_STATE_SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &rtShadow);
device->SetName(&rtShadow, "rtShadow");
}
std::swap(depthBuffer_Copy, depthBuffer_Copy1);
camera->canvas = *this;
camera->width = (float)internalResolution.x;
camera->height = (float)internalResolution.y;
camera->texture_depth_index = device->GetDescriptorIndex(&depthBuffer_Copy, SRV);
camera->texture_lineardepth_index = device->GetDescriptorIndex(&rtLinearDepth, SRV);
camera->texture_gbuffer0_index = device->GetDescriptorIndex(&rtGbuffer[GBUFFER_PRIMITIVEID], SRV);
camera->texture_gbuffer1_index = device->GetDescriptorIndex(&rtGbuffer[GBUFFER_VELOCITY], SRV);
camera->buffer_entitytiles_opaque_index = device->GetDescriptorIndex(&tiledLightResources.entityTiles_Opaque, SRV);
camera->buffer_entitytiles_transparent_index = device->GetDescriptorIndex(&tiledLightResources.entityTiles_Transparent, SRV);
camera->texture_reflection_index = device->GetDescriptorIndex(&rtReflection, SRV);
camera->texture_refraction_index = device->GetDescriptorIndex(&rtSceneCopy, SRV);
camera->texture_waterriples_index = device->GetDescriptorIndex(&rtWaterRipple, SRV);
camera->texture_ao_index = device->GetDescriptorIndex(&rtAO, SRV);
camera->texture_ssr_index = device->GetDescriptorIndex(&rtSSR, SRV);
camera->texture_rtshadow_index = device->GetDescriptorIndex(&rtShadow, SRV);
camera->texture_surfelgi_index = device->GetDescriptorIndex(&surfelGIResources.result, SRV);
camera_reflection.canvas = *this;
camera_reflection.width = (float)depthBuffer_Reflection.desc.Width;
camera_reflection.height = (float)depthBuffer_Reflection.desc.Height;
camera_reflection.texture_depth_index = device->GetDescriptorIndex(&depthBuffer_Reflection, SRV);
camera_reflection.texture_lineardepth_index = -1;
camera_reflection.texture_gbuffer0_index = -1;
camera_reflection.texture_gbuffer1_index = -1;
camera_reflection.buffer_entitytiles_opaque_index = device->GetDescriptorIndex(&tiledLightResources_planarReflection.entityTiles_Opaque, SRV);
camera_reflection.buffer_entitytiles_transparent_index = device->GetDescriptorIndex(&tiledLightResources_planarReflection.entityTiles_Transparent, SRV);
camera_reflection.texture_reflection_index = -1;
camera_reflection.texture_refraction_index = -1;
camera_reflection.texture_waterriples_index = -1;
camera_reflection.texture_ao_index = -1;
camera_reflection.texture_ssr_index = -1;
camera_reflection.texture_rtshadow_index = -1;
camera_reflection.texture_surfelgi_index = -1;
}
void RenderPath3D::Render() const
@@ -619,8 +669,7 @@ void RenderPath3D::Render() const
wiJobSystem::Execute(ctx, [this, cmd](wiJobArgs args) {
GraphicsDevice* device = wiRenderer::GetDevice();
device->BindResource(&depthBuffer_Copy1, TEXSLOT_DEPTH, cmd);
wiRenderer::UpdateRenderDataAsync(visibility_main, frameCB, cmd);
wiRenderer::UpdateRenderDataAsync(visibility_main, cmd);
if (scene->IsAccelerationStructureUpdateRequested())
{
@@ -629,7 +678,7 @@ void RenderPath3D::Render() const
if (wiRenderer::GetSurfelGIEnabled())
{
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
@@ -661,7 +710,7 @@ void RenderPath3D::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
@@ -705,7 +754,7 @@ void RenderPath3D::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
@@ -726,8 +775,6 @@ void RenderPath3D::Render() const
wiRenderer::SurfelGI_Coverage(
surfelGIResources,
*scene,
depthBuffer_Copy,
rtGbuffer,
debugUAV,
cmd
);
@@ -738,8 +785,6 @@ void RenderPath3D::Render() const
if (wiRenderer::GetVariableRateShadingClassification() && device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_VARIABLE_RATE_SHADING_TIER2))
{
wiRenderer::ComputeShadingRateClassification(
rtGbuffer,
rtLinearDepth,
rtShadingRate,
debugUAV,
cmd
@@ -750,7 +795,6 @@ void RenderPath3D::Render() const
{
wiRenderer::Postprocess_VolumetricClouds(
volumetriccloudResources,
depthBuffer_Copy,
cmd
);
}
@@ -759,7 +803,6 @@ void RenderPath3D::Render() const
auto range = wiProfiler::BeginRangeGPU("Entity Culling", cmd);
wiRenderer::ComputeTiledLightCulling(
tiledLightResources,
depthBuffer_Copy,
debugUAV,
cmd
);
@@ -772,10 +815,7 @@ void RenderPath3D::Render() const
{
wiRenderer::Postprocess_ScreenSpaceShadow(
screenspaceshadowResources,
depthBuffer_Copy,
rtLinearDepth,
tiledLightResources.entityTiles_Opaque,
rtGbuffer,
rtShadow,
cmd,
getScreenSpaceShadowRange(),
@@ -788,11 +828,7 @@ void RenderPath3D::Render() const
wiRenderer::Postprocess_RTShadow(
rtshadowResources,
*scene,
depthBuffer_Copy,
rtLinearDepth,
depthBuffer_Copy1,
tiledLightResources.entityTiles_Opaque,
rtGbuffer,
rtShadow,
cmd
);
@@ -813,7 +849,7 @@ void RenderPath3D::Render() const
cmd = device->BeginCommandList();
wiJobSystem::Execute(ctx, [cmd, this](wiJobArgs args) {
wiRenderer::BindCommonResources(cmd);
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
@@ -841,7 +877,7 @@ void RenderPath3D::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
camera_reflection,
camera_reflection_previous,
camera_reflection,
@@ -866,7 +902,6 @@ void RenderPath3D::Render() const
{
wiRenderer::Postprocess_VolumetricClouds(
volumetriccloudResources_reflection,
depthBuffer_Reflection,
cmd
);
}
@@ -882,7 +917,7 @@ void RenderPath3D::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
camera_reflection,
camera_reflection_previous,
camera_reflection,
@@ -891,7 +926,6 @@ void RenderPath3D::Render() const
wiRenderer::ComputeTiledLightCulling(
tiledLightResources_planarReflection,
depthBuffer_Reflection,
Texture(),
cmd
);
@@ -907,11 +941,6 @@ void RenderPath3D::Render() const
device->RenderPassBegin(&renderpass_reflection, cmd);
device->BindResource(&tiledLightResources_planarReflection.entityTiles_Opaque, TEXSLOT_RENDERPATH_ENTITYTILES, cmd);
device->BindResource(wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_REFLECTION, cmd);
device->BindResource(wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_AO, cmd);
device->BindResource(wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd);
device->BindResource(wiTextureHelper::getUINT4(), TEXSLOT_RENDERPATH_RTSHADOW, cmd);
wiRenderer::DrawScene(visibility_reflection, RENDERPASS_MAIN, cmd, drawscene_flags_reflections);
wiRenderer::DrawSky(*scene, cmd);
@@ -940,7 +969,7 @@ void RenderPath3D::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
device->EventBegin("Opaque Scene", cmd);
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
@@ -954,9 +983,6 @@ void RenderPath3D::Render() const
wiRenderer::Postprocess_RTReflection(
rtreflectionResources,
*scene,
depthBuffer_Copy,
depthBuffer_Copy1,
rtGbuffer,
rtSSR,
cmd
);
@@ -982,18 +1008,7 @@ void RenderPath3D::Render() const
{
GPUBarrier barrier = GPUBarrier::Image(&rtShadow, rtShadow.desc.layout, RESOURCE_STATE_SHADER_RESOURCE);
device->Barrier(&barrier, 1, cmd);
device->BindResource(&rtShadow, TEXSLOT_RENDERPATH_RTSHADOW, cmd);
}
else
{
device->BindResource(wiTextureHelper::getUINT4(), TEXSLOT_RENDERPATH_RTSHADOW, cmd);
}
device->BindResource(&tiledLightResources.entityTiles_Opaque, TEXSLOT_RENDERPATH_ENTITYTILES, cmd);
device->BindResource(getReflectionsEnabled() ? &rtReflection : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_REFLECTION, cmd);
device->BindResource(getAOEnabled() ? &rtAO : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_AO, cmd);
device->BindResource(getSSREnabled() || getRaytracedReflectionEnabled() ? &rtSSR : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd);
device->BindResource(&surfelGIResources.result, TEXSLOT_RENDERPATH_SURFELGI, cmd);
device->RenderPassBegin(&renderpass_main, cmd);
@@ -1035,7 +1050,7 @@ void RenderPath3D::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
@@ -1106,7 +1121,6 @@ void RenderPath3D::RenderAO(CommandList cmd) const
case AO_SSAO:
wiRenderer::Postprocess_SSAO(
ssaoResources,
depthBuffer_Copy,
rtLinearDepth,
rtAO,
cmd,
@@ -1139,10 +1153,6 @@ void RenderPath3D::RenderAO(CommandList cmd) const
wiRenderer::Postprocess_RTAO(
rtaoResources,
*scene,
depthBuffer_Copy,
rtLinearDepth,
depthBuffer_Copy1,
rtGbuffer,
rtAO,
cmd,
getAORange(),
@@ -1158,11 +1168,7 @@ void RenderPath3D::RenderSSR(CommandList cmd) const
{
wiRenderer::Postprocess_SSR(
ssrResources,
rtSceneCopy,
depthBuffer_Copy,
rtLinearDepth,
depthBuffer_Copy1,
rtGbuffer,
rtSceneCopy,
rtSSR,
cmd
);
@@ -1237,7 +1243,7 @@ void RenderPath3D::RenderVolumetrics(CommandList cmd) const
vp.Height = (float)rtVolumetricLights[0].GetDesc().Height;
device->BindViewports(1, &vp, cmd);
wiRenderer::DrawVolumeLights(visibility_main, depthBuffer_Copy, cmd);
wiRenderer::DrawVolumeLights(visibility_main, cmd);
device->RenderPassEnd(cmd);
@@ -1314,12 +1320,6 @@ void RenderPath3D::RenderTransparents(CommandList cmd) const
auto range = wiProfiler::BeginRangeGPU("Transparent Scene", cmd);
device->EventBegin("Transparent Scene", cmd);
device->BindResource(&tiledLightResources.entityTiles_Transparent, TEXSLOT_RENDERPATH_ENTITYTILES, cmd);
device->BindResource(&rtLinearDepth, TEXSLOT_LINEARDEPTH, cmd);
device->BindResource(getReflectionsEnabled() ? &rtReflection : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_REFLECTION, cmd);
device->BindResource(&rtSceneCopy, TEXSLOT_RENDERPATH_REFRACTION, cmd);
device->BindResource(&rtWaterRipple, TEXSLOT_RENDERPATH_WATERRIPPLES, cmd);
uint32_t drawscene_flags = 0;
drawscene_flags |= wiRenderer::DRAWSCENE_TRANSPARENT;
drawscene_flags |= wiRenderer::DRAWSCENE_OCCLUSIONCULLING;
@@ -1358,7 +1358,6 @@ void RenderPath3D::RenderTransparents(CommandList cmd) const
{
wiRenderer::DrawLensFlares(
visibility_main,
depthBuffer_Copy,
cmd,
scene->weather.IsVolumetricClouds() ? &volumetriccloudResources.texture_cloudMask : nullptr
);
@@ -1399,10 +1398,7 @@ void RenderPath3D::RenderPostprocessChain(CommandList cmd) const
int output = device->GetFrameCount() % 2;
int history = 1 - output;
wiRenderer::Postprocess_TemporalAA(
*rt_read, rtTemporalAA[history],
rtLinearDepth,
depthBuffer_Copy1,
rtGbuffer,
*rt_read, rtTemporalAA[history],
rtTemporalAA[output],
cmd
);
@@ -1415,7 +1411,6 @@ void RenderPath3D::RenderPostprocessChain(CommandList cmd) const
depthoffieldResources,
rt_first == nullptr ? *rt_read : *rt_first,
*rt_write,
rtLinearDepth,
cmd,
getDepthOfFieldStrength()
);
@@ -1429,8 +1424,6 @@ void RenderPath3D::RenderPostprocessChain(CommandList cmd) const
wiRenderer::Postprocess_MotionBlur(
motionblurResources,
rt_first == nullptr ? *rt_read : *rt_first,
rtLinearDepth,
rtGbuffer,
*rt_write,
cmd,
getMotionBlurStrength()
+2 -2
View File
@@ -271,7 +271,7 @@ void RenderPath3D_PathTracing::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
*camera,
*camera,
@@ -318,7 +318,7 @@ void RenderPath3D_PathTracing::Render() const
GraphicsDevice* device = wiRenderer::GetDevice();
wiRenderer::UpdateCameraCB(
wiRenderer::BindCameraCB(
*camera,
*camera,
*camera,
-20
View File
@@ -8,16 +8,6 @@
// t slot:
// These are reserved slots for systems:
#define TEXSLOT_DEPTH 0
#define TEXSLOT_LINEARDEPTH 1
#define TEXSLOT_GBUFFER0 2
#define TEXSLOT_GBUFFER1 3
#define TEXSLOT_ACCELERATION_STRUCTURE 4
#define TEXSLOT_BVH_COUNTER 4
#define TEXSLOT_BVH_PRIMITIVES 5
#define TEXSLOT_BVH_NODES 6
@@ -61,15 +51,5 @@
#define TEXSLOT_COUNT 64
// RenderPath texture mappings:
#define TEXSLOT_RENDERPATH_ENTITYTILES TEXSLOT_ONDEMAND13
#define TEXSLOT_RENDERPATH_REFLECTION TEXSLOT_ONDEMAND14
#define TEXSLOT_RENDERPATH_REFRACTION TEXSLOT_ONDEMAND15
#define TEXSLOT_RENDERPATH_WATERRIPPLES TEXSLOT_ONDEMAND16
#define TEXSLOT_RENDERPATH_AO TEXSLOT_ONDEMAND17
#define TEXSLOT_RENDERPATH_SSR TEXSLOT_ONDEMAND18
#define TEXSLOT_RENDERPATH_RTSHADOW TEXSLOT_ONDEMAND19
#define TEXSLOT_RENDERPATH_SURFELGI TEXSLOT_ONDEMAND20
#endif // WI_RESOURCE_MAPPING_H
+55 -298
View File
@@ -1,18 +1,35 @@
#ifndef WI_SHADERINTEROP_RENDERER_H
#define WI_SHADERINTEROP_RENDERER_H
#include "ShaderInterop.h"
#include "ShaderInterop_Weather.h"
struct ShaderScene
{
int instancebuffer;
int meshbuffer;
int materialbuffer;
int TLAS;
int envmaparray;
int globalenvmap;
int padding0;
int padding1;
int padding2;
int TLAS;
int BVH_counter;
int BVH_nodes;
int BVH_primitives;
float3 aabb_min;
float padding3;
float3 aabb_max;
float padding4;
float3 aabb_extents; // enclosing AABB abs(max - min)
float padding5;
float3 aabb_extents_rcp; // enclosing AABB 1.0f / abs(max - min)
float padding6;
ShaderWeather weather;
};
static const uint SHADERMATERIAL_OPTION_BIT_USE_VERTEXCOLORS = 1 << 0;
@@ -460,252 +477,6 @@ static const uint TILED_CULLING_GRANULARITY = TILED_CULLING_BLOCKSIZE / TILED_CU
static const int impostorCaptureAngles = 36;
struct AtmosphereParameters
{
float2 padding0;
// Radius of the planet (center to ground)
float bottomRadius;
// Maximum considered atmosphere height (center to atmosphere top)
float topRadius;
// Center of the planet
float3 planetCenter;
// Rayleigh scattering exponential distribution scale in the atmosphere
float rayleighDensityExpScale;
// Rayleigh scattering coefficients
float3 rayleighScattering;
// Mie scattering exponential distribution scale in the atmosphere
float mieDensityExpScale;
// Mie scattering coefficients
float3 mieScattering; float padding1;
// Mie extinction coefficients
float3 mieExtinction; float padding2;
// Mie absorption coefficients
float3 mieAbsorption;
// Mie phase function excentricity
float miePhaseG;
// Another medium type in the atmosphere
float absorptionDensity0LayerWidth;
float absorptionDensity0ConstantTerm;
float absorptionDensity0LinearTerm;
float absorptionDensity1ConstantTerm;
float3 padding3;
float absorptionDensity1LinearTerm;
// This other medium only absorb light, e.g. useful to represent ozone in the earth atmosphere
float3 absorptionExtinction; float padding4;
// The albedo of the ground.
float3 groundAlbedo; float padding5;
// Init default values (All units in kilometers)
void init(
float earthBottomRadius = 6360.0f,
float earthTopRadius = 6460.0f, // 100km atmosphere radius, less edge visible and it contain 99.99% of the atmosphere medium https://en.wikipedia.org/wiki/K%C3%A1rm%C3%A1n_line
float earthRayleighScaleHeight = 8.0f,
float earthMieScaleHeight = 1.2f
)
{
// Values shown here are the result of integration over wavelength power spectrum integrated with paricular function.
// Refer to https://github.com/ebruneton/precomputed_atmospheric_scattering for details.
// Translation from Bruneton2017 parameterisation.
rayleighDensityExpScale = -1.0f / earthRayleighScaleHeight;
mieDensityExpScale = -1.0f / earthMieScaleHeight;
absorptionDensity0LayerWidth = 25.0f;
absorptionDensity0ConstantTerm = -2.0f / 3.0f;
absorptionDensity0LinearTerm = 1.0f / 15.0f;
absorptionDensity1ConstantTerm = 8.0f / 3.0f;
absorptionDensity1LinearTerm = -1.0f / 15.0f;
miePhaseG = 0.8f;
rayleighScattering = float3(0.005802f, 0.013558f, 0.033100f);
mieScattering = float3(0.003996f, 0.003996f, 0.003996f);
mieExtinction = float3(0.004440f, 0.004440f, 0.004440f);
mieAbsorption.x = mieExtinction.x - mieScattering.x;
mieAbsorption.y = mieExtinction.y - mieScattering.y;
mieAbsorption.z = mieExtinction.z - mieScattering.z;
absorptionExtinction = float3(0.000650f, 0.001881f, 0.000085f);
groundAlbedo = float3(0.3f, 0.3f, 0.3f); // 0.3 for earths ground albedo, see https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html
bottomRadius = earthBottomRadius;
topRadius = earthTopRadius;
planetCenter = float3(0.0f, -earthBottomRadius - 0.1f, 0.0f); // Spawn 100m in the air
}
#ifdef __cplusplus
AtmosphereParameters() { init(); }
#endif // __cplusplus
};
struct VolumetricCloudParameters
{
float3 Albedo; // Cloud albedo is normally very close to 1
float CloudAmbientGroundMultiplier; // [0; 1] Amount of ambient light to reach the bottom of clouds
float3 ExtinctionCoefficient; // * 0.05 looks good too
float BeerPowder;
float BeerPowderPower;
float PhaseG; // [-0.999; 0.999]
float PhaseG2; // [-0.999; 0.999]
float PhaseBlend; // [0; 1]
float MultiScatteringScattering;
float MultiScatteringExtinction;
float MultiScatteringEccentricity;
float ShadowStepLength;
float HorizonBlendAmount;
float HorizonBlendPower;
float WeatherDensityAmount; // Rain clouds disabled by default.
float CloudStartHeight;
float CloudThickness;
float SkewAlongWindDirection;
float TotalNoiseScale;
float DetailScale;
float WeatherScale;
float CurlScale;
float ShapeNoiseHeightGradientAmount;
float ShapeNoiseMultiplier;
float2 ShapeNoiseMinMax;
float ShapeNoisePower;
float DetailNoiseModifier;
float DetailNoiseHeightFraction;
float CurlNoiseModifier;
float CoverageAmount;
float CoverageMinimum;
float TypeAmount;
float TypeOverall;
float AnvilAmount; // Anvil clouds disabled by default.
float AnvilOverhangHeight;
// Animation
float AnimationMultiplier;
float WindSpeed;
float WindAngle;
float WindUpAmount;
float2 padding0;
float CoverageWindSpeed;
float CoverageWindAngle;
// Cloud types
// 4 positions of a black, white, white, black gradient
float4 CloudGradientSmall;
float4 CloudGradientMedium;
float4 CloudGradientLarge;
// Performance
int MaxStepCount; // Maximum number of iterations. Higher gives better images but may be slow.
float MaxMarchingDistance; // Clamping the marching steps to be within a certain distance.
float InverseDistanceStepCount; // Distance over which the raymarch steps will be evenly distributed.
float RenderDistance; // Maximum distance to march before returning a miss.
float LODDistance; // After a certain distance, noises will get higher LOD
float LODMin; //
float BigStepMarch; // How long inital rays should be until they hit something. Lower values may ives a better image but may be slower.
float TransmittanceThreshold; // Default: 0.005. If the clouds transmittance has reached it's desired opacity, there's no need to keep raymarching for performance.
float2 padding1;
float ShadowSampleCount;
float GroundContributionSampleCount;
void init()
{
// Lighting
Albedo = float3(0.9f, 0.9f, 0.9f);
CloudAmbientGroundMultiplier = 0.75f;
ExtinctionCoefficient = float3(0.71f * 0.1f, 0.86f * 0.1f, 1.0f * 0.1f);
BeerPowder = 20.0f;
BeerPowderPower = 0.5f;
PhaseG = 0.5f; // [-0.999; 0.999]
PhaseG2 = -0.5f; // [-0.999; 0.999]
PhaseBlend = 0.2f; // [0; 1]
MultiScatteringScattering = 1.0f;
MultiScatteringExtinction = 0.1f;
MultiScatteringEccentricity = 0.2f;
ShadowStepLength = 3000.0f;
HorizonBlendAmount = 1.25f;
HorizonBlendPower = 2.0f;
WeatherDensityAmount = 0.0f;
// Modelling
CloudStartHeight = 1500.0f;
CloudThickness = 4000.0f;
SkewAlongWindDirection = 700.0f;
TotalNoiseScale = 1.0f;
DetailScale = 5.0f;
WeatherScale = 0.0625f;
CurlScale = 7.5f;
ShapeNoiseHeightGradientAmount = 0.2f;
ShapeNoiseMultiplier = 0.8f;
ShapeNoisePower = 6.0f;
ShapeNoiseMinMax = float2(0.25f, 1.1f);
DetailNoiseModifier = 0.2f;
DetailNoiseHeightFraction = 10.0f;
CurlNoiseModifier = 550.0f;
CoverageAmount = 2.0f;
CoverageMinimum = 1.05f;
TypeAmount = 1.0f;
TypeOverall = 0.0f;
AnvilAmount = 0.0f;
AnvilOverhangHeight = 3.0f;
// Animation
AnimationMultiplier = 2.0f;
WindSpeed = 15.9f;
WindAngle = -0.39f;
WindUpAmount = 0.5f;
CoverageWindSpeed = 25.0f;
CoverageWindAngle = 0.087f;
// Cloud types
// 4 positions of a black, white, white, black gradient
CloudGradientSmall = float4(0.02f, 0.07f, 0.12f, 0.28f);
CloudGradientMedium = float4(0.02f, 0.07f, 0.39f, 0.59f);
CloudGradientLarge = float4(0.02f, 0.07f, 0.88f, 1.0f);
// Performance
MaxStepCount = 128;
MaxMarchingDistance = 30000.0f;
InverseDistanceStepCount = 15000.0f;
RenderDistance = 70000.0f;
LODDistance = 25000.0f;
LODMin = 0.0f;
BigStepMarch = 3.0f;
TransmittanceThreshold = 0.005f;
ShadowSampleCount = 5.0f;
GroundContributionSampleCount = 2.0f;
}
#ifdef __cplusplus
VolumetricCloudParameters() { init(); }
#endif // __cplusplus
};
// These option bits can be read from Options constant buffer value:
static const uint OPTION_BIT_TEMPORALAA_ENABLED = 1 << 0;
static const uint OPTION_BIT_TRANSPARENTSHADOWS_ENABLED = 1 << 1;
@@ -725,32 +496,9 @@ static const uint OPTION_BIT_FORCE_DIFFUSE_LIGHTING = 1 << 12;
struct FrameCB
{
float2 CanvasSize;
float2 CanvasSize_rcp;
float2 InternalResolution;
float2 InternalResolution_rcp;
float3 SunColor;
float Gamma;
float3 SunDirection;
uint ShadowCascadeCount;
float3 Horizon;
uint ConstantOne; // Just a constant 1 value as uint (can be used to force disable loop unrolling)
float3 Zenith;
float CloudScale;
float3 Ambient;
float Cloudiness;
float4 Fog; // Fog Start,End,Height Start,Height End
float padding0;
float FogHeightSky;
float SkyExposure;
float VoxelRadianceMaxDistance; // maximum raymarch distance for voxel GI in world-space
float VoxelRadianceDataSize; // voxel half-extent in world space units
@@ -766,48 +514,30 @@ struct FrameCB
float3 VoxelRadianceDataCenter; // center of the voxel grid in world space units
uint Options; // wiRenderer bool options packed into bitmask
uint3 EntityCullingTileCount;
int GlobalEnvProbeIndex;
uint EnvProbeMipCount;
float EnvProbeMipCount_rcp;
float Time;
float TimePrev;
float SunEnergy;
float WindSpeed;
float DeltaTime;
uint FrameCount;
uint LightArrayOffset; // indexing into entity array
uint LightArrayCount; // indexing into entity array
uint DecalArrayOffset; // indexing into entity array
uint DecalArrayCount; // indexing into entity array
uint ForceFieldArrayOffset; // indexing into entity array
uint ForceFieldArrayCount; // indexing into entity array
uint EnvProbeArrayOffset; // indexing into entity array
uint EnvProbeArrayCount; // indexing into entity array
float3 WindDirection;
float WindWaveSize;
float3 WorldBoundsMin; // world enclosing AABB min
float CloudSpeed;
float3 WorldBoundsMax; // world enclosing AABB max
float WindRandomness;
float3 WorldBoundsExtents; // world enclosing AABB abs(max - min)
uint EnvProbeArrayCount; // indexing into entity array
float StaticSkyGamma; // possible values (0: no static sky; 1: hdr static sky; other: actual gamma when ldr)
float3 WorldBoundsExtents_rcp; // world enclosing AABB 1.0f / abs(max - min)
uint TemporalAASampleRotation;
float ShadowKernel2D;
float ShadowKernelCube;
int ObjectShaderSamplerIndex;
float BlueNoisePhase;
int sampler_objectshader_index;
int texture_random64x64_index;
int texture_bluenoise_index;
@@ -826,11 +556,8 @@ struct FrameCB
int buffer_entityarray_index;
int buffer_entitymatrixarray_index;
int padding1;
int padding2;
AtmosphereParameters Atmosphere;
VolumetricCloudParameters VolumetricClouds;
int padding0;
int padding1;
ShaderScene scene;
};
@@ -883,6 +610,36 @@ struct CameraCB
float2 ApertureShape;
float ApertureSize;
float FocalLength;
float2 CanvasSize;
float2 CanvasSize_rcp;
uint2 InternalResolution;
float2 InternalResolution_rcp;
uint3 EntityCullingTileCount;
int padding0;
int texture_depth_index;
int texture_lineardepth_index;
int texture_gbuffer0_index;
int texture_gbuffer1_index;
int buffer_entitytiles_opaque_index;
int buffer_entitytiles_transparent_index;
int texture_reflection_index;
int texture_refraction_index;
int texture_waterriples_index;
int texture_ao_index;
int texture_ssr_index;
int texture_rtshadow_index;
int texture_surfelgi_index;
int texture_depth_index_prev;
int padding1;
int padding2;
};
@@ -71,7 +71,7 @@ inline int3 surfel_cell(float3 position)
#ifdef SURFEL_USE_HASHING
return floor(position / SURFEL_MAX_RADIUS);
#else
return floor((position - floor(g_xCamera.CamPos)) / SURFEL_MAX_RADIUS) + SURFEL_GRID_DIMENSIONS / 2;
return floor((position - floor(GetCamera().CamPos)) / SURFEL_MAX_RADIUS) + SURFEL_GRID_DIMENSIONS / 2;
#endif // SURFEL_USE_HASHING
}
float3 surfel_griduv(float3 position)
@@ -79,7 +79,7 @@ float3 surfel_griduv(float3 position)
#ifdef SURFEL_USE_HASHING
return 0; // hashed grid can't be sampled for colors, it doesn't make sense
#else
return (((position - floor(g_xCamera.CamPos)) / SURFEL_MAX_RADIUS) + SURFEL_GRID_DIMENSIONS / 2) / SURFEL_GRID_DIMENSIONS;
return (((position - floor(GetCamera().CamPos)) / SURFEL_MAX_RADIUS) + SURFEL_GRID_DIMENSIONS / 2) / SURFEL_GRID_DIMENSIONS;
#endif // SURFEL_USE_HASHING
}
inline uint surfel_cellindex(int3 cell)
@@ -119,8 +119,8 @@ inline bool surfel_cellintersects(Surfel surfel, int3 cell)
float3 gridmin = cell * SURFEL_MAX_RADIUS;
float3 gridmax = (cell + 1) * SURFEL_MAX_RADIUS;
#else
float3 gridmin = cell - SURFEL_GRID_DIMENSIONS / 2 * SURFEL_MAX_RADIUS + floor(g_xCamera.CamPos);
float3 gridmax = (cell + 1) - SURFEL_GRID_DIMENSIONS / 2 * SURFEL_MAX_RADIUS + floor(g_xCamera.CamPos);
float3 gridmin = cell - SURFEL_GRID_DIMENSIONS / 2 * SURFEL_MAX_RADIUS + floor(GetCamera().CamPos);
float3 gridmax = (cell + 1) - SURFEL_GRID_DIMENSIONS / 2 * SURFEL_MAX_RADIUS + floor(GetCamera().CamPos);
#endif // SURFEL_USE_HASHING
float3 closestPointInAabb = min(max(surfel.position, gridmin), gridmax);
@@ -0,0 +1,294 @@
#ifndef WI_SHADERINTEROP_WEATHER_H
#define WI_SHADERINTEROP_WEATHER_H
#include "ShaderInterop.h"
struct AtmosphereParameters
{
float2 padding0;
// Radius of the planet (center to ground)
float bottomRadius;
// Maximum considered atmosphere height (center to atmosphere top)
float topRadius;
// Center of the planet
float3 planetCenter;
// Rayleigh scattering exponential distribution scale in the atmosphere
float rayleighDensityExpScale;
// Rayleigh scattering coefficients
float3 rayleighScattering;
// Mie scattering exponential distribution scale in the atmosphere
float mieDensityExpScale;
// Mie scattering coefficients
float3 mieScattering; float padding1;
// Mie extinction coefficients
float3 mieExtinction; float padding2;
// Mie absorption coefficients
float3 mieAbsorption;
// Mie phase function excentricity
float miePhaseG;
// Another medium type in the atmosphere
float absorptionDensity0LayerWidth;
float absorptionDensity0ConstantTerm;
float absorptionDensity0LinearTerm;
float absorptionDensity1ConstantTerm;
float3 padding3;
float absorptionDensity1LinearTerm;
// This other medium only absorb light, e.g. useful to represent ozone in the earth atmosphere
float3 absorptionExtinction; float padding4;
// The albedo of the ground.
float3 groundAlbedo; float padding5;
// Init default values (All units in kilometers)
void init(
float earthBottomRadius = 6360.0f,
float earthTopRadius = 6460.0f, // 100km atmosphere radius, less edge visible and it contain 99.99% of the atmosphere medium https://en.wikipedia.org/wiki/K%C3%A1rm%C3%A1n_line
float earthRayleighScaleHeight = 8.0f,
float earthMieScaleHeight = 1.2f
)
{
// Values shown here are the result of integration over wavelength power spectrum integrated with paricular function.
// Refer to https://github.com/ebruneton/precomputed_atmospheric_scattering for details.
// Translation from Bruneton2017 parameterisation.
rayleighDensityExpScale = -1.0f / earthRayleighScaleHeight;
mieDensityExpScale = -1.0f / earthMieScaleHeight;
absorptionDensity0LayerWidth = 25.0f;
absorptionDensity0ConstantTerm = -2.0f / 3.0f;
absorptionDensity0LinearTerm = 1.0f / 15.0f;
absorptionDensity1ConstantTerm = 8.0f / 3.0f;
absorptionDensity1LinearTerm = -1.0f / 15.0f;
miePhaseG = 0.8f;
rayleighScattering = float3(0.005802f, 0.013558f, 0.033100f);
mieScattering = float3(0.003996f, 0.003996f, 0.003996f);
mieExtinction = float3(0.004440f, 0.004440f, 0.004440f);
mieAbsorption.x = mieExtinction.x - mieScattering.x;
mieAbsorption.y = mieExtinction.y - mieScattering.y;
mieAbsorption.z = mieExtinction.z - mieScattering.z;
absorptionExtinction = float3(0.000650f, 0.001881f, 0.000085f);
groundAlbedo = float3(0.3f, 0.3f, 0.3f); // 0.3 for earths ground albedo, see https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html
bottomRadius = earthBottomRadius;
topRadius = earthTopRadius;
planetCenter = float3(0.0f, -earthBottomRadius - 0.1f, 0.0f); // Spawn 100m in the air
}
#ifdef __cplusplus
AtmosphereParameters() { init(); }
#endif // __cplusplus
};
struct VolumetricCloudParameters
{
float3 Albedo; // Cloud albedo is normally very close to 1
float CloudAmbientGroundMultiplier; // [0; 1] Amount of ambient light to reach the bottom of clouds
float3 ExtinctionCoefficient; // * 0.05 looks good too
float BeerPowder;
float BeerPowderPower;
float PhaseG; // [-0.999; 0.999]
float PhaseG2; // [-0.999; 0.999]
float PhaseBlend; // [0; 1]
float MultiScatteringScattering;
float MultiScatteringExtinction;
float MultiScatteringEccentricity;
float ShadowStepLength;
float HorizonBlendAmount;
float HorizonBlendPower;
float WeatherDensityAmount; // Rain clouds disabled by default.
float CloudStartHeight;
float CloudThickness;
float SkewAlongWindDirection;
float TotalNoiseScale;
float DetailScale;
float WeatherScale;
float CurlScale;
float ShapeNoiseHeightGradientAmount;
float ShapeNoiseMultiplier;
float2 ShapeNoiseMinMax;
float ShapeNoisePower;
float DetailNoiseModifier;
float DetailNoiseHeightFraction;
float CurlNoiseModifier;
float CoverageAmount;
float CoverageMinimum;
float TypeAmount;
float TypeOverall;
float AnvilAmount; // Anvil clouds disabled by default.
float AnvilOverhangHeight;
// Animation
float AnimationMultiplier;
float WindSpeed;
float WindAngle;
float WindUpAmount;
float2 padding0;
float CoverageWindSpeed;
float CoverageWindAngle;
// Cloud types
// 4 positions of a black, white, white, black gradient
float4 CloudGradientSmall;
float4 CloudGradientMedium;
float4 CloudGradientLarge;
// Performance
int MaxStepCount; // Maximum number of iterations. Higher gives better images but may be slow.
float MaxMarchingDistance; // Clamping the marching steps to be within a certain distance.
float InverseDistanceStepCount; // Distance over which the raymarch steps will be evenly distributed.
float RenderDistance; // Maximum distance to march before returning a miss.
float LODDistance; // After a certain distance, noises will get higher LOD
float LODMin; //
float BigStepMarch; // How long inital rays should be until they hit something. Lower values may ives a better image but may be slower.
float TransmittanceThreshold; // Default: 0.005. If the clouds transmittance has reached it's desired opacity, there's no need to keep raymarching for performance.
float2 padding1;
float ShadowSampleCount;
float GroundContributionSampleCount;
void init()
{
// Lighting
Albedo = float3(0.9f, 0.9f, 0.9f);
CloudAmbientGroundMultiplier = 0.75f;
ExtinctionCoefficient = float3(0.71f * 0.1f, 0.86f * 0.1f, 1.0f * 0.1f);
BeerPowder = 20.0f;
BeerPowderPower = 0.5f;
PhaseG = 0.5f; // [-0.999; 0.999]
PhaseG2 = -0.5f; // [-0.999; 0.999]
PhaseBlend = 0.2f; // [0; 1]
MultiScatteringScattering = 1.0f;
MultiScatteringExtinction = 0.1f;
MultiScatteringEccentricity = 0.2f;
ShadowStepLength = 3000.0f;
HorizonBlendAmount = 1.25f;
HorizonBlendPower = 2.0f;
WeatherDensityAmount = 0.0f;
// Modelling
CloudStartHeight = 1500.0f;
CloudThickness = 4000.0f;
SkewAlongWindDirection = 700.0f;
TotalNoiseScale = 1.0f;
DetailScale = 5.0f;
WeatherScale = 0.0625f;
CurlScale = 7.5f;
ShapeNoiseHeightGradientAmount = 0.2f;
ShapeNoiseMultiplier = 0.8f;
ShapeNoisePower = 6.0f;
ShapeNoiseMinMax = float2(0.25f, 1.1f);
DetailNoiseModifier = 0.2f;
DetailNoiseHeightFraction = 10.0f;
CurlNoiseModifier = 550.0f;
CoverageAmount = 2.0f;
CoverageMinimum = 1.05f;
TypeAmount = 1.0f;
TypeOverall = 0.0f;
AnvilAmount = 0.0f;
AnvilOverhangHeight = 3.0f;
// Animation
AnimationMultiplier = 2.0f;
WindSpeed = 15.9f;
WindAngle = -0.39f;
WindUpAmount = 0.5f;
CoverageWindSpeed = 25.0f;
CoverageWindAngle = 0.087f;
// Cloud types
// 4 positions of a black, white, white, black gradient
CloudGradientSmall = float4(0.02f, 0.07f, 0.12f, 0.28f);
CloudGradientMedium = float4(0.02f, 0.07f, 0.39f, 0.59f);
CloudGradientLarge = float4(0.02f, 0.07f, 0.88f, 1.0f);
// Performance
MaxStepCount = 128;
MaxMarchingDistance = 30000.0f;
InverseDistanceStepCount = 15000.0f;
RenderDistance = 70000.0f;
LODDistance = 25000.0f;
LODMin = 0.0f;
BigStepMarch = 3.0f;
TransmittanceThreshold = 0.005f;
ShadowSampleCount = 5.0f;
GroundContributionSampleCount = 2.0f;
}
#ifdef __cplusplus
VolumetricCloudParameters() { init(); }
#endif // __cplusplus
};
struct ShaderFog
{
float start;
float end;
float height_start;
float height_end;
float height_sky;
float padding0;
float padding1;
float padding2;
};
struct ShaderWind
{
float3 direction;
float speed;
float wavesize;
float randomness;
float padding0;
float padding1;
};
struct ShaderWeather
{
float3 sun_color;
float sun_energy;
float3 sun_direction;
float sky_exposure;
float3 horizon;
float cloudiness;
float3 zenith;
float cloud_scale;
float3 ambient;
float cloud_speed;
ShaderFog fog;
ShaderWind wind;
AtmosphereParameters atmosphere;
VolumetricCloudParameters volumetric_clouds;
};
#endif // WI_SHADERINTEROP_WEATHER_H
@@ -2836,5 +2836,6 @@
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Raytracing.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Renderer.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_SurfelGI.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Weather.h" />
</ItemGroup>
</Project>
@@ -1054,5 +1054,8 @@
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_SurfelGI.h">
<Filter>interop</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop_Weather.h">
<Filter>interop</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -167,7 +167,7 @@ void main(uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex)
const BLUR_FORMAT color2 = color_cache[sam];
#ifdef BILATERAL
const float depth = depth_cache[sam];
const float weight = saturate(abs(depth - center_depth) * g_xCamera.ZFarP * depth_threshold);
const float weight = saturate(abs(depth - center_depth) * GetCamera().ZFarP * depth_threshold);
color += lerp(color2, center_color, weight) * gaussianWeightsNormalized[i];
#else
color += color2 * gaussianWeightsNormalized[i];
+1 -1
View File
@@ -323,7 +323,7 @@ struct Surface
P = p0 * w + p1 * u + p2 * v;
P = mul(inst.transform.GetMatrix(), float4(P, 1)).xyz;
V = normalize(g_xCamera.CamPos - P);
V = normalize(GetCamera().CamPos - P);
float4 uv0 = 0, uv1 = 0, uv2 = 0;
[branch]
+5 -3
View File
@@ -16,7 +16,7 @@ RAWBUFFER(primitiveCounterBuffer, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(primitiveIDBuffer, uint, TEXSLOT_ONDEMAND1);
STRUCTUREDBUFFER(primitiveMortonBuffer, float, TEXSLOT_ONDEMAND2); // float because it was sorted
RWSTRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, 0);
RWRAWBUFFER(bvhNodeBuffer, 0);
RWSTRUCTUREDBUFFER(bvhParentBuffer, uint, 1);
RWSTRUCTUREDBUFFER(bvhFlagBuffer, uint, 2);
@@ -126,8 +126,10 @@ void main( uint3 DTid : SV_DispatchThreadID )
childBIndex = internalNodeOffset + split + 1;
// write to parent:
bvhNodeBuffer[idx].LeftChildIndex = childAIndex;
bvhNodeBuffer[idx].RightChildIndex = childBIndex;
BVHNode node = bvhNodeBuffer.Load<BVHNode>(idx * sizeof(BVHNode));
node.LeftChildIndex = childAIndex;
node.RightChildIndex = childBIndex;
bvhNodeBuffer.Store<BVHNode>(idx * sizeof(BVHNode), node);
// write to children:
bvhParentBuffer[childAIndex] = idx;
bvhParentBuffer[childBIndex] = idx;
+3 -3
View File
@@ -9,7 +9,7 @@
PUSHCONSTANT(push, BVHPushConstants);
RWSTRUCTUREDBUFFER(primitiveIDBuffer, uint, 0);
RWSTRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, 1);
RWRAWBUFFER(primitiveBuffer, 1);
RWSTRUCTUREDBUFFER(primitiveMortonBuffer, float, 2); // morton buffer is float because sorting is written for floats!
[numthreads(BVH_BUILDER_GROUPSIZE, 1, 1)]
@@ -69,14 +69,14 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
bvhprim.z2 = P2.z;
uint primitiveID = push.primitiveOffset + prim.primitiveIndex;
primitiveBuffer[primitiveID] = bvhprim;
primitiveBuffer.Store<BVHPrimitive>(primitiveID * sizeof(BVHPrimitive), bvhprim);
primitiveIDBuffer[primitiveID] = primitiveID; // will be sorted by morton so we need this!
// Compute triangle morton code:
float3 minAABB = min(P0, min(P1, P2));
float3 maxAABB = max(P0, max(P1, P2));
float3 centerAABB = (minAABB + maxAABB) * 0.5f;
const uint mortoncode = morton3D((centerAABB - g_xFrame.WorldBoundsMin) * g_xFrame.WorldBoundsExtents_rcp);
const uint mortoncode = morton3D((centerAABB - GetScene().aabb_min) * GetScene().aabb_extents_rcp);
primitiveMortonBuffer[primitiveID] = (float)mortoncode; // convert to float before sorting
}
+22 -14
View File
@@ -9,10 +9,10 @@
RAWBUFFER(primitiveCounterBuffer, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(primitiveIDBuffer, uint, TEXSLOT_ONDEMAND1);
STRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, TEXSLOT_ONDEMAND2);
RAWBUFFER(primitiveBuffer, TEXSLOT_ONDEMAND2);
STRUCTUREDBUFFER(bvhParentBuffer, uint, TEXSLOT_ONDEMAND3);
RWSTRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, 0);
RWRAWBUFFER(bvhNodeBuffer, 0);
RWSTRUCTUREDBUFFER(bvhFlagBuffer, uint, 1);
[numthreads(BVH_BUILDER_GROUPSIZE, 1, 1)]
@@ -27,13 +27,17 @@ void main(uint3 DTid : SV_DispatchThreadID)
uint nodeIndex = leafNodeOffset + DTid.x;
// Leaf node will receive the corresponding primitive AABB:
BVHPrimitive prim = primitiveBuffer[primitiveID];
bvhNodeBuffer[nodeIndex].min = min(prim.v0(), min(prim.v1(), prim.v2()));
bvhNodeBuffer[nodeIndex].max = max(prim.v0(), max(prim.v1(), prim.v2()));
BVHPrimitive prim = primitiveBuffer.Load<BVHPrimitive>(primitiveID * sizeof(BVHPrimitive));
BVHNode node;
node.min = min(prim.v0(), min(prim.v1(), prim.v2()));
node.max = max(prim.v0(), max(prim.v1(), prim.v2()));
// Also store primitiveID in left child index of leaf node to avoid indirection
// with primitiveIDBuffer when tracing later:
bvhNodeBuffer[nodeIndex].LeftChildIndex = primitiveID;
node.LeftChildIndex = primitiveID;
node.RightChildIndex = ~0u;
bvhNodeBuffer.Store<BVHNode>(nodeIndex * sizeof(BVHNode), node);
// Propagate until we reach root node:
@@ -56,16 +60,20 @@ void main(uint3 DTid : SV_DispatchThreadID)
}
// Arrived at parent node, load up its two children's AABBs
const uint left_child = bvhNodeBuffer[nodeIndex].LeftChildIndex;
const uint right_child = bvhNodeBuffer[nodeIndex].RightChildIndex;
const float3 left_min = bvhNodeBuffer[left_child].min;
const float3 left_max = bvhNodeBuffer[left_child].max;
const float3 right_min = bvhNodeBuffer[right_child].min;
const float3 right_max = bvhNodeBuffer[right_child].max;
BVHNode parent_node = bvhNodeBuffer.Load<BVHNode>(nodeIndex * sizeof(BVHNode));
const uint left_child = parent_node.LeftChildIndex;
const uint right_child = parent_node.RightChildIndex;
BVHNode left_node = bvhNodeBuffer.Load<BVHNode>(left_child * sizeof(BVHNode));
BVHNode right_node = bvhNodeBuffer.Load<BVHNode>(right_child * sizeof(BVHNode));
const float3 left_min = left_node.min;
const float3 left_max = left_node.max;
const float3 right_min = right_node.min;
const float3 right_max = right_node.max;
// Merge the child AABBs:
bvhNodeBuffer[nodeIndex].min = min(left_min, right_min);
bvhNodeBuffer[nodeIndex].max = max(left_max, right_max);
parent_node.min = min(left_min, right_min);
parent_node.max = max(left_max, right_max);
bvhNodeBuffer.Store<BVHNode>(nodeIndex * sizeof(BVHNode), parent_node);
} while (nodeIndex != 0);
}
+1 -1
View File
@@ -13,6 +13,6 @@ float4 main(VSOut_Sphere input) : SV_TARGET
{
float3 P = input.pos3D;
float3 N = normalize(input.nor);
float3 V = normalize(g_xCamera.CamPos - P);
float3 V = normalize(GetCamera().CamPos - P);
return float4(cubeMap.Sample(sampler_linear_clamp, -reflect(V, N)).rgb, 1);
}
+1 -1
View File
@@ -40,7 +40,7 @@ struct Frustum
float4 ClipToView(float4 clip)
{
// View space position.
float4 view = mul(g_xCamera.InvP, clip);
float4 view = mul(GetCamera().InvP, clip);
// Perspective projection.
view = view / view.w;
+2 -2
View File
@@ -5,10 +5,10 @@ PUSHCONSTANT(postprocess, PostProcess);
inline float get_coc(in float linear_depth)
{
return min(dof_maxcoc, dof_cocscale * g_xCamera.ApertureSize * pow(abs(1 - g_xCamera.FocalLength / (linear_depth * g_xCamera.ZFarP)), 2.0f));
return min(dof_maxcoc, dof_cocscale * GetCamera().ApertureSize * pow(abs(1 - GetCamera().FocalLength / (linear_depth * GetCamera().ZFarP)), 2.0f));
}
#define DOF_DEPTH_SCALE_FOREGROUND (g_xCamera.ZFarP * 1.5)
#define DOF_DEPTH_SCALE_FOREGROUND (GetCamera().ZFarP * 1.5)
float2 DepthCmp2(float depth, float closestTileDepth)
{
float d = DOF_DEPTH_SCALE_FOREGROUND * (depth - closestTileDepth);
@@ -46,7 +46,7 @@ void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID)
const uint ringCount = clamp(ceil(pow(maxcoc, 0.5f) * DOF_RING_COUNT), 1, DOF_RING_COUNT);
const float spreadScale = ringCount / maxcoc;
const float2 ringScale = float(ringCount) / float(DOF_RING_COUNT) * maxcoc * g_xCamera.ApertureShape * postprocess.resolution_rcp;
const float2 ringScale = float(ringCount) / float(DOF_RING_COUNT) * maxcoc * GetCamera().ApertureShape * postprocess.resolution_rcp;
const float3 center_color = texture_prefilter[pixel];
const float3 center_presort = texture_presort[pixel];
@@ -47,14 +47,14 @@ void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID)
[branch]
if (backgroundFactor < 1.0f)
{
const float2 ringScale = 0.5f * coc * g_xCamera.ApertureShape * postprocess.resolution_rcp;
const float2 ringScale = 0.5f * coc * GetCamera().ApertureShape * postprocess.resolution_rcp;
[unroll]
for (uint i = ringSampleCount[0]; i < ringSampleCount[1]; ++i)
{
const float2 uv2 = uv + ringScale * disc[i].xy;
const float depth = texture_lineardepth.SampleLevel(sampler_point_clamp, uv2, 1);
const float3 color = max(0, input.SampleLevel(sampler_linear_clamp, uv2, 0).rgb);
const float weight = saturate(abs(depth - center_depth) * g_xCamera.ZFarP * 2);
const float weight = saturate(abs(depth - center_depth) * GetCamera().ZFarP * 2);
prefilter += lerp(color, center_color, weight);
}
prefilter *= ringNormFactor[1];
@@ -24,7 +24,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
const float coc = get_coc(center_depth);
float depthDelta = saturate(1.0 - g_xCamera.ZFarP * (center_depth - mindepth));
float depthDelta = saturate(1.0 - GetCamera().ZFarP * (center_depth - mindepth));
const float backgroundFactor = coc;
const float foregroundFactor = lerp(maxcoc, coc, depthDelta);
+4 -4
View File
@@ -60,7 +60,7 @@ void main(
sin(rotation), cos(rotation)
);
float3 velocity = mul((float3x3)g_xCamera.View, particle.velocity);
float3 velocity = mul((float3x3)GetCamera().View, particle.velocity);
// Transform the vertices and write them
for (uint i = 0; i < BILLBOARD_VERTEXCOUNT; ++i)
@@ -93,10 +93,10 @@ void main(
// copy to output:
Out.pos = float4(particle.position, 1);
Out.pos = mul(g_xCamera.View, Out.pos);
Out.pos = mul(GetCamera().View, Out.pos);
Out.pos.xyz += quadPos.xyz;
Out.P = mul(g_xCamera.InvV, float4(Out.pos.xyz, 1)).xyz;
Out.pos = mul(g_xCamera.Proj, Out.pos);
Out.P = mul(GetCamera().InvV, float4(Out.pos.xyz, 1)).xyz;
Out.pos = mul(GetCamera().Proj, Out.pos);
Out.tex = float4(uv, uv2);
Out.size = size;
@@ -24,8 +24,8 @@ float4 main(VertextoPixel input) : SV_TARGET
}
float2 pixel = input.pos.xy;
float2 ScreenCoord = pixel * g_xFrame.InternalResolution_rcp;
float4 depthScene = texture_lineardepth.GatherRed(sampler_linear_clamp, ScreenCoord) * g_xCamera.ZFarP;
float2 ScreenCoord = pixel * GetCamera().InternalResolution_rcp;
float4 depthScene = texture_lineardepth.GatherRed(sampler_linear_clamp, ScreenCoord) * GetCamera().ZFarP;
float depthFragment = input.pos.w;
float fade = saturate(1.0 / input.size*(max(max(depthScene.x, depthScene.y), max(depthScene.z, depthScene.w)) - depthFragment));
@@ -55,7 +55,7 @@ float4 main(VertextoPixel input) : SV_TARGET
N.x = -cos(PI * input.unrotated_uv.x);
N.y = cos(PI * input.unrotated_uv.y);
N.z = -sin(PI * length(input.unrotated_uv));
N = mul((float3x3)g_xCamera.InvV, N);
N = mul((float3x3)GetCamera().InvV, N);
N = normalize(N);
Lighting lighting;
+4 -4
View File
@@ -57,16 +57,16 @@ VertextoPixel main(uint vertexID : SV_VERTEXID, uint instanceID : SV_INSTANCEID)
quadPos *= size;
// scale the billboard along view space motion vector:
float3 velocity = mul((float3x3)g_xCamera.View, particle.velocity);
float3 velocity = mul((float3x3)GetCamera().View, particle.velocity);
quadPos += dot(quadPos, velocity) * velocity * xParticleMotionBlurAmount;
// copy to output:
Out.pos = float4(particle.position, 1);
Out.pos = mul(g_xCamera.View, Out.pos);
Out.pos = mul(GetCamera().View, Out.pos);
Out.pos.xyz += quadPos.xyz;
Out.P = mul(g_xCamera.InvV, float4(Out.pos.xyz, 1)).xyz;
Out.pos = mul(g_xCamera.Proj, Out.pos);
Out.P = mul(GetCamera().InvV, float4(Out.pos.xyz, 1)).xyz;
Out.pos = mul(GetCamera().Proj, Out.pos);
Out.tex = float4(uv, uv2);
Out.size = size;
@@ -54,18 +54,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
#ifdef DEPTHCOLLISIONS
// NOTE: We are using the textures from previous frame, so reproject against those! (PrevVP)
float4 pos2D = mul(g_xCamera.PrevVP, float4(particle.position, 1));
float4 pos2D = mul(GetCamera().PrevVP, float4(particle.position, 1));
pos2D.xyz /= pos2D.w;
if (pos2D.x > -1 && pos2D.x < 1 && pos2D.y > -1 && pos2D.y < 1)
{
float2 uv = pos2D.xy * float2(0.5f, -0.5f) + 0.5f;
uint2 pixel = uv * g_xFrame.InternalResolution;
uint2 pixel = uv * GetCamera().InternalResolution;
float depth0 = texture_depth[pixel];
float depth0 = texture_depth_history[pixel];
float surfaceLinearDepth = getLinearDepth(depth0);
float surfaceThickness = 1.5f;
@@ -76,12 +75,12 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
if ((pos2D.w + particleSize > surfaceLinearDepth) && (pos2D.w - particleSize < surfaceLinearDepth + surfaceThickness))
{
// Calculate surface normal and bounce off the particle:
float depth1 = texture_depth[pixel + uint2(1, 0)];
float depth2 = texture_depth[pixel + uint2(0, -1)];
float depth1 = texture_depth_history[pixel + uint2(1, 0)];
float depth2 = texture_depth_history[pixel + uint2(0, -1)];
float3 p0 = reconstructPosition(uv, depth0, g_xCamera.PrevInvVP);
float3 p1 = reconstructPosition(uv + float2(1, 0) * g_xFrame.InternalResolution_rcp, depth1, g_xCamera.PrevInvVP);
float3 p2 = reconstructPosition(uv + float2(0, -1) * g_xFrame.InternalResolution_rcp, depth2, g_xCamera.PrevInvVP);
float3 p0 = reconstructPosition(uv, depth0, GetCamera().PrevInvVP);
float3 p1 = reconstructPosition(uv + float2(1, 0) * GetCamera().InternalResolution_rcp, depth1, GetCamera().PrevInvVP);
float3 p2 = reconstructPosition(uv + float2(0, -1) * GetCamera().InternalResolution_rcp, depth2, GetCamera().PrevInvVP);
float3 surfaceNormal = normalize(cross(p2 - p0, p1 - p0));
@@ -92,7 +91,6 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
}
}
}
#endif // DEPTHCOLLISIONS
// integrate:
@@ -165,7 +163,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex)
#ifdef SORTING
// store squared distance to main camera:
float3 eyeVector = particle.position - g_xCamera.CamPos;
float3 eyeVector = particle.position - GetCamera().CamPos;
float distSQ = dot(eyeVector, eyeVector);
distanceBuffer[particleIndex] = -distSQ; // this can be negated to modify sorting order here instead of rewriting sorting shaders...
#endif // SORTING
@@ -30,7 +30,7 @@ float4 main(PSIn input) : SV_TARGET
}
float2 pTex = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
float4 depthScene = texture_lineardepth.GatherRed(sampler_linear_clamp, pTex) * g_xCamera.ZFarP;
float4 depthScene = texture_lineardepth.GatherRed(sampler_linear_clamp, pTex) * GetCamera().ZFarP;
float depthFragment = input.pos2D.w;
float fade = saturate(1.0 / forceField.GetConeAngleCos() * abs(forceField.GetEnergy()) * (max(max(depthScene.x, depthScene.y), max(depthScene.z, depthScene.w)) - depthFragment));
color.a *= fade;
+54 -33
View File
@@ -7,23 +7,43 @@ Texture2D bindless_textures[] : register(space1);
ByteAddressBuffer bindless_buffers[] : register(space2);
SamplerState bindless_samplers[] : register(space3);
Buffer<uint> bindless_ib[] : register(space4);
#ifdef RTAPI
RaytracingAccelerationStructure bindless_accelerationstructures[] : register(space5);
#endif // RTAPI
Texture2DArray bindless_textures2DArray[] : register(space5);
TextureCube bindless_cubemaps[] : register(space6);
TextureCubeArray bindless_cubearrays[] : register(space7);
Texture3D bindless_textures3D[] : register(space8);
RWTexture2D<float4> bindless_rwtextures[] : register(space9);
RWByteAddressBuffer bindless_rwbuffers[] : register(space10);
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space11);
RWTexture3D<float4> bindless_rwtextures3D[] : register(space12);
Texture2DArray bindless_textures2DArray[] : register(space6);
TextureCube bindless_cubemaps[] : register(space7);
TextureCubeArray bindless_cubearrays[] : register(space8);
Texture3D bindless_textures3D[] : register(space9);
RWTexture2D<float4> bindless_rwtextures[] : register(space10);
RWByteAddressBuffer bindless_rwbuffers[] : register(space11);
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space12);
RWTexture3D<float4> bindless_rwtextures3D[] : register(space13);
Texture2D<float> bindless_textures_float[] : register(space14);
Texture2D<float2> bindless_textures_float2[] : register(space15);
Texture2D<uint2> bindless_textures_uint2[] : register(space16);
Texture2D<uint4> bindless_textures_uint4[] : register(space17);
ShaderScene GetScene()
{
return g_xFrame.scene;
}
ShaderWeather GetWeather()
{
return GetScene().weather;
}
CameraCB GetCamera()
{
return g_xCamera;
}
ShaderMeshInstance load_instance(uint instanceIndex)
{
return bindless_buffers[g_xFrame.scene.instancebuffer].Load<ShaderMeshInstance>(instanceIndex * sizeof(ShaderMeshInstance));
return bindless_buffers[GetScene().instancebuffer].Load<ShaderMeshInstance>(instanceIndex * sizeof(ShaderMeshInstance));
}
ShaderMesh load_mesh(uint meshIndex)
{
return bindless_buffers[g_xFrame.scene.meshbuffer].Load<ShaderMesh>(meshIndex * sizeof(ShaderMesh));
return bindless_buffers[GetScene().meshbuffer].Load<ShaderMesh>(meshIndex * sizeof(ShaderMesh));
}
ShaderMeshSubset load_subset(ShaderMesh mesh, uint subsetIndex)
{
@@ -31,7 +51,7 @@ ShaderMeshSubset load_subset(ShaderMesh mesh, uint subsetIndex)
}
ShaderMaterial load_material(uint materialIndex)
{
return bindless_buffers[g_xFrame.scene.materialbuffer].Load<ShaderMaterial>(materialIndex * sizeof(ShaderMaterial));
return bindless_buffers[GetScene().materialbuffer].Load<ShaderMaterial>(materialIndex * sizeof(ShaderMaterial));
}
ShaderEntity load_entity(uint entityIndex)
{
@@ -42,8 +62,8 @@ float4x4 load_entitymatrix(uint matrixIndex)
return transpose(bindless_buffers[g_xFrame.buffer_entitymatrixarray_index].Load<float4x4>(matrixIndex * sizeof(float4x4)));
}
#define texture_globalenvmap bindless_cubemaps[g_xFrame.scene.globalenvmap]
#define texture_envmaparray bindless_cubearrays[g_xFrame.scene.envmaparray]
#define texture_globalenvmap bindless_cubemaps[GetScene().globalenvmap]
#define texture_envmaparray bindless_cubearrays[GetScene().envmaparray]
#define texture_random64x64 bindless_textures[g_xFrame.texture_random64x64_index]
#define texture_bluenoise bindless_textures[g_xFrame.texture_bluenoise_index]
@@ -57,11 +77,13 @@ float4x4 load_entitymatrix(uint matrixIndex)
#define texture_shadowarray_transparent_2d bindless_textures2DArray[g_xFrame.texture_shadowarray_transparent_2d_index]
#define texture_shadowarray_transparent_cube bindless_cubearrays[g_xFrame.texture_shadowarray_transparent_cube_index]
#define texture_voxelgi bindless_textures3D[g_xFrame.texture_voxelgi_index]
#define scene_acceleration_structure bindless_accelerationstructures[GetScene().TLAS]
TEXTURE2D(texture_depth, float, TEXSLOT_DEPTH);
TEXTURE2D(texture_lineardepth, float, TEXSLOT_LINEARDEPTH);
TEXTURE2D(texture_gbuffer0, uint2, TEXSLOT_GBUFFER0);
TEXTURE2D(texture_gbuffer1, float2, TEXSLOT_GBUFFER1);
#define texture_depth bindless_textures_float[GetCamera().texture_depth_index]
#define texture_depth_history bindless_textures_float[GetCamera().texture_depth_index_prev]
#define texture_lineardepth bindless_textures_float[GetCamera().texture_lineardepth_index]
#define texture_gbuffer0 bindless_textures_uint2[GetCamera().texture_gbuffer0_index]
#define texture_gbuffer1 bindless_textures_float2[GetCamera().texture_gbuffer1_index]
// These are static samplers, don't need to be bound:
SAMPLERSTATE( sampler_linear_clamp, SSLOT_LINEAR_CLAMP );
@@ -92,16 +114,16 @@ inline bool is_saturated(float4 a) { return is_saturated(a.x) && is_saturated(a.
#define DEGAMMA(x) pow(abs(x),g_xFrame.Gamma)
#define GAMMA(x) pow(abs(x),1.0/g_xFrame.Gamma)
inline float3 GetSunColor() { return g_xFrame.SunColor; }
inline float3 GetSunDirection() { return g_xFrame.SunDirection; }
inline float GetSunEnergy() { return g_xFrame.SunEnergy; }
inline float3 GetHorizonColor() { return g_xFrame.Horizon.rgb; }
inline float3 GetZenithColor() { return g_xFrame.Zenith.rgb; }
inline float3 GetAmbientColor() { return g_xFrame.Ambient.rgb; }
inline float2 GetInternalResolution() { return g_xFrame.InternalResolution; }
inline float3 GetSunColor() { return GetWeather().sun_color; }
inline float3 GetSunDirection() { return GetWeather().sun_direction; }
inline float GetSunEnergy() { return GetWeather().sun_energy; }
inline float3 GetHorizonColor() { return GetWeather().horizon.rgb; }
inline float3 GetZenithColor() { return GetWeather().zenith.rgb; }
inline float3 GetAmbientColor() { return GetWeather().ambient.rgb; }
inline uint2 GetInternalResolution() { return GetCamera().InternalResolution; }
inline float GetTime() { return g_xFrame.Time; }
inline uint2 GetTemporalAASampleRotation() { return uint2((g_xFrame.TemporalAASampleRotation >> 0u) & 0x000000FF, (g_xFrame.TemporalAASampleRotation >> 8) & 0x000000FF); }
inline bool IsStaticSky() { return g_xFrame.scene.globalenvmap >= 0; }
inline bool IsStaticSky() { return GetScene().globalenvmap >= 0; }
// Exponential height fog based on: https://www.iquilezles.org/www/articles/fog/fog.htm
// Non constant density function
@@ -110,13 +132,12 @@ inline bool IsStaticSky() { return g_xFrame.scene.globalenvmap >= 0; }
// V : sample to point vector
inline float GetFogAmount(float distance, float3 O, float3 V)
{
float fogDensity = saturate((distance - g_xFrame.Fog.x) / (g_xFrame.Fog.y - g_xFrame.Fog.x));
ShaderFog fog = GetWeather().fog;
float fogDensity = saturate((distance - fog.start) / (fog.end - fog.start));
if (g_xFrame.Options & OPTION_BIT_HEIGHT_FOG)
{
float fogHeightStart = g_xFrame.Fog.z;
float fogHeightEnd = g_xFrame.Fog.w;
float fogFalloffScale = 1.0 / max(0.01, fogHeightEnd - fogHeightStart);
float fogFalloffScale = 1.0 / max(0.01, fog.height_end - fog.height_start);
// solve for x, e^(-h * x) = 0.001
// x = 6.907755 * h^-1
@@ -128,9 +149,9 @@ inline float GetFogAmount(float distance, float3 O, float3 V)
float endLineHeight = originHeight + distance * Z; // Isolated vector equation for y
float minLineHeight = min(originHeight, endLineHeight);
float heightLineFalloff = max(minLineHeight - fogHeightStart, 0);
float heightLineFalloff = max(minLineHeight - fog.height_start, 0);
float baseHeightFogDistance = clamp((fogHeightStart - minLineHeight) / effectiveZ, 0, distance);
float baseHeightFogDistance = clamp((fog.height_start - minLineHeight) / effectiveZ, 0, distance);
float exponentialFogDistance = distance - baseHeightFogDistance; // Exclude distance below base height
float exponentialHeightLineIntegral = exp(-heightLineFalloff * fogFalloff) * (1.0 - exp(-exponentialFogDistance * effectiveZ * fogFalloff)) / (effectiveZ * fogFalloff);
@@ -303,7 +324,7 @@ inline float getLinearDepth(in float z, in float near, in float far)
}
inline float getLinearDepth(in float z)
{
return getLinearDepth(z, g_xCamera.ZNearP, g_xCamera.ZFarP);
return getLinearDepth(z, GetCamera().ZNearP, GetCamera().ZFarP);
}
inline float3x3 GetTangentSpace(in float3 normal)
@@ -358,7 +379,7 @@ inline float3 reconstructPosition(in float2 uv, in float z, in float4x4 InvVP)
}
inline float3 reconstructPosition(in float2 uv, in float z)
{
return reconstructPosition(uv, z, g_xCamera.InvVP);
return reconstructPosition(uv, z, GetCamera().InvVP);
}
#if 0
+8 -4
View File
@@ -21,13 +21,13 @@ float4 main(VertexToPixel input) : SV_Target
color *= material.baseColor;
float opacity = 1;
float3 V = g_xCamera.CamPos - input.pos3D;
float3 V = GetCamera().CamPos - input.pos3D;
float dist = length(V);
V /= dist;
float emissive = 0;
const uint2 pixel = input.pos.xy;
const float2 ScreenCoord = pixel * g_xFrame.InternalResolution_rcp;
const float2 ScreenCoord = pixel * GetCamera().InternalResolution_rcp;
Surface surface;
surface.create(material, color, 0);
@@ -39,7 +39,11 @@ float4 main(VertexToPixel input) : SV_Target
#ifndef PREPASS
#ifndef ENVMAPRENDERING
#ifndef TRANSPARENT
surface.occlusion *= texture_ao.SampleLevel(sampler_linear_clamp, ScreenCoord, 0).r;
[branch]
if (GetCamera().texture_ao_index >= 0)
{
surface.occlusion *= bindless_textures_float[GetCamera().texture_ao_index].SampleLevel(sampler_linear_clamp, ScreenCoord, 0).r;
}
#endif // TRANSPARENT
#endif // ENVMAPRENDERING
#endif // PREPASS
@@ -57,7 +61,7 @@ float4 main(VertexToPixel input) : SV_Target
ApplyLighting(surface, lighting, color);
ApplyFog(dist, g_xCamera.CamPos, V, color);
ApplyFog(dist, GetCamera().CamPos, V, color);
return color;
}
+2 -2
View File
@@ -17,12 +17,12 @@ VertexToPixel main(uint vid : SV_VERTEXID)
float3 normal = normalize(unpack_unitvector(data.w));
float2 uv = unpack_half2(bindless_buffers[mesh.vb_uv0].Load(vertexID * 4));
Out.fade = saturate(distance(position.xyz, g_xCamera.CamPos.xyz) / xHairViewDistance);
Out.fade = saturate(distance(position.xyz, GetCamera().CamPos.xyz) / xHairViewDistance);
Out.fade = saturate(Out.fade - 0.8f) * 5.0f; // fade will be on edge and inwards 20%
Out.pos = float4(position, 1);
Out.pos3D = Out.pos.xyz;
Out.pos = mul(g_xCamera.VP, Out.pos);
Out.pos = mul(GetCamera().VP, Out.pos);
Out.nor = normalize(normal);
Out.tex = uv;
@@ -208,9 +208,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
patchPos = mul(patchPos, TBN);
// simplistic wind effect only affects the top, but leaves the base as is:
const float waveoffset = dot(rootposition, g_xFrame.WindDirection) * g_xFrame.WindWaveSize + rand / 255.0f * g_xFrame.WindRandomness;
const float3 wavedir = g_xFrame.WindDirection * (segmentID + patchPos.y);
const float3 wind = sin(g_xFrame.Time * g_xFrame.WindSpeed + waveoffset) * wavedir;
const float waveoffset = dot(rootposition, GetWeather().wind.direction) * GetWeather().wind.wavesize + rand / 255.0f * GetWeather().wind.randomness;
const float3 wavedir = GetWeather().wind.direction * (segmentID + patchPos.y);
const float3 wind = sin(g_xFrame.Time * GetWeather().wind.speed + waveoffset) * wavedir;
float3 position = rootposition + patchPos + wind;
@@ -225,12 +225,12 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
uint infrustum = 1;
float3 center = (base + tip) * 0.5;
float radius = -len;
infrustum &= distance(base, g_xCamera.CamPos.xyz) < xHairViewDistance;
infrustum &= dot(g_xCamera.FrustumPlanes[0], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[2], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[3], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[4], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[5], float4(center, 1)) > radius;
infrustum &= distance(base, GetCamera().CamPos.xyz) < xHairViewDistance;
infrustum &= dot(GetCamera().FrustumPlanes[0], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[2], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[3], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[4], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[5], float4(center, 1)) > radius;
if (infrustum)
{
+2 -2
View File
@@ -91,7 +91,7 @@ void main(uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex)
{
const uint2 pixel = tile_start + hbao_direction * (i - TILE_BORDER);
const float2 uv = (pixel + 0.5f) * postprocess.resolution_rcp;
const float z = texture_lineardepth.Load(uint3(tile_start + hbao_direction * (i - TILE_BORDER), 1)) * g_xCamera.ZFarP;
const float z = texture_lineardepth.Load(uint3(tile_start + hbao_direction * (i - TILE_BORDER), 1)) * GetCamera().ZFarP;
const float2 xy = (hbao_uv_to_view_A * uv + hbao_uv_to_view_B) * z;
cache[i] = float2(horizontal ? xy.x : xy.y, z);
}
@@ -99,7 +99,7 @@ void main(uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex)
const uint2 pixel = tile_start + groupIndex * hbao_direction;
const int center = TILE_BORDER + groupIndex;
if (pixel.x >= postprocess.resolution.x || pixel.y >= postprocess.resolution.y || cache[center].y >= g_xCamera.ZFarP - 0.99)
if (pixel.x >= postprocess.resolution.x || pixel.y >= postprocess.resolution.y || cache[center].y >= GetCamera().ZFarP - 0.99)
{
return;
}
+2 -2
View File
@@ -22,7 +22,7 @@ float4 main(VSOut input) : SV_Target
float metalness = surfaceparams.b;
float reflectance = surfaceparams.a;
float3 V = g_xCamera.CamPos - input.pos3D;
float3 V = GetCamera().CamPos - input.pos3D;
float dist = length(V);
V /= dist;
@@ -44,7 +44,7 @@ float4 main(VSOut input) : SV_Target
ApplyLighting(surface, lighting, color);
ApplyFog(dist, g_xCamera.CamPos, V, color);
ApplyFog(dist, GetCamera().CamPos, V, color);
return color;
}
+2 -2
View File
@@ -39,7 +39,7 @@ VSOut main(uint fakeIndex : SV_VERTEXID)
// to the impostor (at least for now)
float3 origin = mul(instance.transform.GetMatrix(), float4(0, 0, 0, 1)).xyz;
float3 up = normalize(mul((float3x3)instance.transform.GetMatrix(), float3(0, 1, 0)));
float3 face = mul((float3x3)instance.transform.GetMatrix(), g_xCamera.CamPos - origin);
float3 face = mul((float3x3)instance.transform.GetMatrix(), GetCamera().CamPos - origin);
face.y = 0; // only rotate around Y axis!
face = normalize(face);
float3 right = normalize(cross(face, up));
@@ -57,7 +57,7 @@ VSOut main(uint fakeIndex : SV_VERTEXID)
VSOut Out;
Out.pos3D = mul(instance.transform.GetMatrix(), float4(pos, 1)).xyz;
Out.pos = mul(g_xCamera.VP, float4(Out.pos3D, 1));
Out.pos = mul(GetCamera().VP, float4(Out.pos3D, 1));
Out.uv = uv;
Out.slice = slice;
Out.dither = poi.GetDither();
+1 -1
View File
@@ -47,7 +47,7 @@ VertexOut main(uint vertexID : SV_VertexID)
float2 moddedpos = pos * push.xLensFlareOffset;
Out.opacity *= saturate(1 - length(pos - moddedpos));
Out.pos = float4(moddedpos + BILLBOARD[vertexID] * push.xLensFlareSize * g_xFrame.CanvasSize_rcp, 0, 1);
Out.pos = float4(moddedpos + BILLBOARD[vertexID] * push.xLensFlareSize * GetCamera().CanvasSize_rcp, 0, 1);
return Out;
}
+10 -10
View File
@@ -6,8 +6,8 @@
STRUCTUREDBUFFER(in_Frustums, Frustum, TEXSLOT_ONDEMAND0);
RWSTRUCTUREDBUFFER(EntityTiles_Transparent, uint, 0);
RWSTRUCTUREDBUFFER(EntityTiles_Opaque, uint, 1);
RWRAWBUFFER(EntityTiles_Transparent, 0);
RWRAWBUFFER(EntityTiles_Opaque, 1);
#ifdef DEBUG_TILEDLIGHTCULLING
@@ -94,7 +94,7 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
uint i = 0;
// Compute addresses and load frustum:
const uint flatTileIndex = flatten2D(Gid.xy, g_xFrame.EntityCullingTileCount.xy);
const uint flatTileIndex = flatten2D(Gid.xy, GetCamera().EntityCullingTileCount.xy);
const uint tileBucketsAddress = flatTileIndex * SHADER_ENTITY_TILE_BUCKET_COUNT;
const uint bucketIndex = groupIndex;
Frustum GroupFrustum = in_Frustums[flatTileIndex];
@@ -182,7 +182,7 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
// We can perform coarse AABB intersection tests with this:
GroupAABB_WS = GroupAABB;
AABBtransform(GroupAABB_WS, g_xCamera.InvV);
AABBtransform(GroupAABB_WS, GetCamera().InvV);
}
// Convert depth values to view space.
@@ -223,7 +223,7 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
{
case ENTITY_TYPE_POINTLIGHT:
{
float3 positionVS = mul(g_xCamera.View, float4(entity.position, 1)).xyz;
float3 positionVS = mul(GetCamera().View, float4(entity.position, 1)).xyz;
Sphere sphere = { positionVS.xyz, entity.GetRange() };
if (SphereInsideFrustum(sphere, GroupFrustum, nearClipVS, maxDepthVS))
{
@@ -243,8 +243,8 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
break;
case ENTITY_TYPE_SPOTLIGHT:
{
float3 positionVS = mul(g_xCamera.View, float4(entity.position, 1)).xyz;
float3 directionVS = mul((float3x3)g_xCamera.View, entity.GetDirection());
float3 positionVS = mul(GetCamera().View, float4(entity.position, 1)).xyz;
float3 directionVS = mul((float3x3)GetCamera().View, entity.GetDirection());
// Construct a tight fitting sphere around the spotlight cone:
const float r = entity.GetRange() * 0.5f / (entity.GetConeAngleCos() * entity.GetConeAngleCos());
Sphere sphere = { positionVS - directionVS * r, r };
@@ -274,7 +274,7 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
case ENTITY_TYPE_DECAL:
case ENTITY_TYPE_ENVMAP:
{
float3 positionVS = mul(g_xCamera.View, float4(entity.position, 1)).xyz;
float3 positionVS = mul(GetCamera().View, float4(entity.position, 1)).xyz;
Sphere sphere = { positionVS.xyz, entity.GetRange() };
if (SphereInsideFrustum(sphere, GroupFrustum, nearClipVS, maxDepthVS))
{
@@ -309,8 +309,8 @@ void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid :
// Each thread will export one bucket from LDS to global memory:
for (i = bucketIndex; i < SHADER_ENTITY_TILE_BUCKET_COUNT; i += TILED_CULLING_THREADSIZE * TILED_CULLING_THREADSIZE)
{
EntityTiles_Opaque[tileBucketsAddress + i] = tile_opaque[i];
EntityTiles_Transparent[tileBucketsAddress + i] = tile_transparent[i];
EntityTiles_Opaque.Store((tileBucketsAddress + i) * sizeof(uint), tile_opaque[i]);
EntityTiles_Transparent.Store((tileBucketsAddress + i) * sizeof(uint), tile_transparent[i]);
}
#ifdef DEBUG_TILEDLIGHTCULLING
+5 -5
View File
@@ -184,7 +184,7 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
float3 atmosphereTransmittance = 1;
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
{
atmosphereTransmittance = GetAtmosphericLightTransmittance(g_xFrame.Atmosphere, surface.P, L, texture_transmittancelut);
atmosphereTransmittance = GetAtmosphericLightTransmittance(GetWeather().atmosphere, surface.P, L, texture_transmittancelut);
}
float3 lightColor = light.GetColor().rgb * light.GetEnergy() * shadow * atmosphereTransmittance;
@@ -332,7 +332,7 @@ inline float3 GetAmbient(in float3 N)
#else
ambient = texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(N, g_xFrame.GlobalEnvProbeIndex), g_xFrame.EnvProbeMipCount).rgb;
ambient = texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(N, 0), g_xFrame.EnvProbeMipCount).rgb;
#endif // ENVMAPRENDERING
@@ -366,18 +366,18 @@ inline float3 EnvironmentReflection_Global(in Surface surface)
#else
float MIP = surface.roughness * g_xFrame.EnvProbeMipCount;
envColor = texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(surface.R, g_xFrame.GlobalEnvProbeIndex), MIP).rgb * surface.F;
envColor = texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(surface.R, 0), MIP).rgb * surface.F;
#ifdef BRDF_SHEEN
envColor *= surface.sheen.albedoScaling;
MIP = surface.sheen.roughness * g_xFrame.EnvProbeMipCount;
envColor += texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(surface.R, g_xFrame.GlobalEnvProbeIndex), MIP).rgb * surface.sheen.color * surface.sheen.DFG;
envColor += texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(surface.R, 0), MIP).rgb * surface.sheen.color * surface.sheen.DFG;
#endif // BRDF_SHEEN
#ifdef BRDF_CLEARCOAT
envColor *= 1 - surface.clearcoat.F;
MIP = surface.clearcoat.roughness * g_xFrame.EnvProbeMipCount;
envColor += texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(surface.clearcoat.R, g_xFrame.GlobalEnvProbeIndex), MIP).rgb * surface.clearcoat.F;
envColor += texture_envmaparray.SampleLevel(sampler_linear_clamp, float4(surface.clearcoat.R, 0), MIP).rgb * surface.clearcoat.F;
#endif // BRDF_CLEARCOAT
#endif // ENVMAPRENDERING
+2 -2
View File
@@ -101,8 +101,8 @@ void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID)
sum += float4(color1, 1);
sum += float4(color2, 1);
#else
float weight1 = SampleWeight(center_depth, depth1, neighborhood_velocity_magnitude, center_velocity_magnitude, velocity_magnitude1, 1000, g_xCamera.ZFarP);
float weight2 = SampleWeight(center_depth, depth2, neighborhood_velocity_magnitude, center_velocity_magnitude, velocity_magnitude2, 1000, g_xCamera.ZFarP);
float weight1 = SampleWeight(center_depth, depth1, neighborhood_velocity_magnitude, center_velocity_magnitude, velocity_magnitude1, 1000, GetCamera().ZFarP);
float weight2 = SampleWeight(center_depth, depth2, neighborhood_velocity_magnitude, center_velocity_magnitude, velocity_magnitude2, 1000, GetCamera().ZFarP);
bool2 mirror = bool2(depth1 > depth2, velocity_magnitude2 > velocity_magnitude1);
weight1 = all(mirror) ? weight2 : weight1;
+4 -2
View File
@@ -6,6 +6,8 @@
PUSHCONSTANT(postprocess, PostProcess);
TEXTURE2D(depthbuffer, float, TEXSLOT_ONDEMAND0);
RWTEXTURE2D(output, float3, 0);
static const uint TILE_BORDER = 1;
@@ -23,7 +25,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
{
const uint2 pixel = tile_upperleft + unflatten2D(t, TILE_SIZE);
const float2 uv = (pixel + 0.5f) * postprocess.resolution_rcp;
const float depth = texture_depth.SampleLevel(sampler_linear_clamp, uv, depth_mip);
const float depth = depthbuffer.SampleLevel(sampler_linear_clamp, uv, depth_mip);
const float3 position = reconstructPosition(uv, depth);
tile_XY[t] = position.xy;
tile_Z[t] = position.z;
@@ -48,7 +50,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
const float center_Z = tile_Z[cross_idx[0]];
[branch]
if (center_Z >= g_xCamera.ZFarP)
if (center_Z >= GetCamera().ZFarP)
return;
const uint best_Z_horizontal = abs(tile_Z[cross_idx[1]] - center_Z) < abs(tile_Z[cross_idx[2]] - center_Z) ? 1 : 2;
+88 -60
View File
@@ -52,7 +52,7 @@ inline ShaderMaterial GetMaterial3()
return load_material(GetMesh().blendmaterial3);
}
#define sampler_objectshader bindless_samplers[g_xFrame.ObjectShaderSamplerIndex]
#define sampler_objectshader bindless_samplers[g_xFrame.sampler_objectshader_index]
#define texture_basecolormap bindless_textures[GetMaterial().texture_basecolormap_index]
#define texture_normalmap bindless_textures[GetMaterial().texture_normalmap_index]
@@ -83,17 +83,14 @@ inline ShaderMaterial GetMaterial3()
#define texture_blend3_surfacemap bindless_textures[GetMaterial3().texture_surfacemap_index]
#define texture_blend3_emissivemap bindless_textures[GetMaterial3().texture_emissivemap_index]
// These are bound by RenderPath (based on Render Path):
STRUCTUREDBUFFER(EntityTiles, uint, TEXSLOT_RENDERPATH_ENTITYTILES);
TEXTURE2D(texture_reflection, float4, TEXSLOT_RENDERPATH_REFLECTION); // rgba: scene color from reflected camera angle
TEXTURE2D(texture_refraction, float4, TEXSLOT_RENDERPATH_REFRACTION); // rgba: scene color from primary camera angle
TEXTURE2D(texture_waterriples, float4, TEXSLOT_RENDERPATH_WATERRIPPLES); // rgb: snorm8 water ripple normal map
TEXTURE2D(texture_ao, float, TEXSLOT_RENDERPATH_AO); // r: ambient occlusion
TEXTURE2D(texture_ssr, float4, TEXSLOT_RENDERPATH_SSR); // rgb: screen space ray-traced reflections, a: reflection blend based on ray hit or miss
TEXTURE2D(texture_rtshadow, uint4, TEXSLOT_RENDERPATH_RTSHADOW); // bitmask for max 16 shadows' visibility
TEXTURE2D(texture_surfelgi, float3, TEXSLOT_RENDERPATH_SURFELGI);
uint load_entitytile(uint tileIndex)
{
#ifdef TRANSPARENT
return bindless_buffers[GetCamera().buffer_entitytiles_transparent_index].Load(tileIndex * sizeof(uint));
#else
return bindless_buffers[GetCamera().buffer_entitytiles_opaque_index].Load(tileIndex * sizeof(uint));
#endif // TRANSPARENT
}
// Use these to compile this file as shader prototype:
//#define OBJECTSHADER_COMPILE_VS - compile vertex shader prototype
@@ -283,9 +280,9 @@ struct VertexSurface
if (material.IsUsingWind())
{
const float windweight = input.GetWindWeight();
const float waveoffset = dot(position.xyz, g_xFrame.WindDirection) * g_xFrame.WindWaveSize + (position.x + position.y + position.z) * g_xFrame.WindRandomness;
const float3 wavedir = g_xFrame.WindDirection * windweight;
const float3 wind = sin(g_xFrame.Time * g_xFrame.WindSpeed + waveoffset) * wavedir;
const float waveoffset = dot(position.xyz, GetWeather().wind.direction) * GetWeather().wind.wavesize + (position.x + position.y + position.z) * GetWeather().wind.randomness;
const float3 wavedir = GetWeather().wind.direction * windweight;
const float3 wind = sin(g_xFrame.Time * GetWeather().wind.speed + waveoffset) * wavedir;
position.xyz += wind;
}
#endif // OBJECTSHADER_USE_WIND
@@ -387,10 +384,15 @@ inline void NormalMapping(in float4 uvsets, inout float3 N, in float3x3 TBN, out
inline float3 PlanarReflection(in Surface surface, in float2 bumpColor)
{
float4 reflectionUV = mul(g_xCamera.ReflVP, float4(surface.P, 1));
reflectionUV.xy /= reflectionUV.w;
reflectionUV.xy = reflectionUV.xy * float2(0.5, -0.5) + 0.5;
return texture_reflection.SampleLevel(sampler_linear_clamp, reflectionUV.xy + bumpColor*GetMaterial().normalMapStrength, 0).rgb;
[branch]
if (GetCamera().texture_reflection_index >= 0)
{
float4 reflectionUV = mul(GetCamera().ReflVP, float4(surface.P, 1));
reflectionUV.xy /= reflectionUV.w;
reflectionUV.xy = reflectionUV.xy * float2(0.5, -0.5) + 0.5;
return bindless_textures[GetCamera().texture_reflection_index].SampleLevel(sampler_linear_clamp, reflectionUV.xy + bumpColor * GetMaterial().normalMapStrength, 0).rgb;
}
return 0;
}
#define NUM_PARALLAX_OCCLUSION_STEPS 32
@@ -630,7 +632,7 @@ inline void ForwardLighting(inout Surface surface, inout Lighting lighting)
inline void TiledLighting(inout Surface surface, inout Lighting lighting)
{
const uint2 tileIndex = uint2(floor(surface.pixel / TILED_CULLING_BLOCKSIZE));
const uint flatTileIndex = flatten2D(tileIndex, g_xFrame.EntityCullingTileCount.xy) * SHADER_ENTITY_TILE_BUCKET_COUNT;
const uint flatTileIndex = flatten2D(tileIndex, GetCamera().EntityCullingTileCount.xy) * SHADER_ENTITY_TILE_BUCKET_COUNT;
#ifndef DISABLE_DECALS
@@ -650,7 +652,7 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
[loop]
for (uint bucket = first_bucket; bucket <= last_bucket; ++bucket)
{
uint bucket_bits = EntityTiles[flatTileIndex + bucket];
uint bucket_bits = load_entitytile(flatTileIndex + bucket);
// This is the wave scalarizer from Improved Culling - Siggraph 2017 [Drobot]:
bucket_bits = WaveReadLaneFirst(WaveActiveBitOr(bucket_bits));
@@ -738,7 +740,7 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
[loop]
for (uint bucket = first_bucket; bucket <= last_bucket; ++bucket)
{
uint bucket_bits = EntityTiles[flatTileIndex + bucket];
uint bucket_bits = load_entitytile(flatTileIndex + bucket);
// Bucket scalarizer - Siggraph 2017 - Improved Culling [Michal Drobot]:
bucket_bits = WaveReadLaneFirst(WaveActiveBitOr(bucket_bits));
@@ -809,9 +811,9 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
uint4 shadow_mask_packed = 0;
#ifdef SHADOW_MASK_ENABLED
[branch]
if (g_xFrame.Options & OPTION_BIT_SHADOW_MASK)
if (g_xFrame.Options & OPTION_BIT_SHADOW_MASK && GetCamera().texture_rtshadow_index >= 0)
{
shadow_mask_packed = texture_rtshadow[surface.pixel / 2];
shadow_mask_packed = bindless_textures_uint4[GetCamera().texture_rtshadow_index][surface.pixel / 2];
}
#endif // SHADOW_MASK_ENABLED
@@ -823,7 +825,7 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
[loop]
for (uint bucket = first_bucket; bucket <= last_bucket; ++bucket)
{
uint bucket_bits = EntityTiles[flatTileIndex + bucket];
uint bucket_bits = load_entitytile(flatTileIndex + bucket);
// Bucket scalarizer - Siggraph 2017 - Improved Culling [Michal Drobot]:
bucket_bits = WaveReadLaneFirst(WaveActiveBitOr(bucket_bits));
@@ -902,9 +904,9 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting)
#ifndef TRANSPARENT
[branch]
if (g_xFrame.Options & OPTION_BIT_SURFELGI_ENABLED && surfel_cellvalid(surfel_cell(surface.P)))
if (g_xFrame.Options & OPTION_BIT_SURFELGI_ENABLED && GetCamera().texture_surfelgi_index >= 0 && surfel_cellvalid(surfel_cell(surface.P)))
{
lighting.indirect.diffuse = texture_surfelgi[surface.pixel];
lighting.indirect.diffuse = bindless_textures[GetCamera().texture_surfelgi_index][surface.pixel].rgb;
}
#endif // TRANSPARENT
@@ -953,11 +955,11 @@ PixelInput main(VertexInput input)
Out.pos = surface.position;
#ifndef OBJECTSHADER_USE_NOCAMERA
Out.pos = mul(g_xCamera.VP, Out.pos);
Out.pos = mul(GetCamera().VP, Out.pos);
#endif // OBJECTSHADER_USE_NOCAMERA
#ifdef OBJECTSHADER_USE_CLIPPLANE
Out.clip = dot(surface.position, g_xCamera.ClipPlane);
Out.clip = dot(surface.position, GetCamera().ClipPlane);
#endif // OBJECTSHADER_USE_CLIPPLANE
#ifdef OBJECTSHADER_USE_POSITION3D
@@ -1038,7 +1040,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
const float depth = input.pos.z;
const float lineardepth = input.pos.w;
const float2 pixel = input.pos.xy;
const float2 ScreenCoord = pixel * g_xFrame.InternalResolution_rcp;
const float2 ScreenCoord = pixel * GetCamera().InternalResolution_rcp;
float3 bumpColor = 0;
#ifndef DISABLE_ALPHATEST
@@ -1067,7 +1069,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
#ifdef OBJECTSHADER_USE_POSITION3D
surface.P = input.pos3D;
surface.V = g_xCamera.CamPos - surface.P;
surface.V = GetCamera().CamPos - surface.P;
float dist = length(surface.V);
surface.V /= dist;
#endif // OBJECTSHADER_USE_POSITION3D
@@ -1467,7 +1469,11 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
#ifndef PREPASS
#ifndef ENVMAPRENDERING
#ifndef TRANSPARENT
surface.occlusion *= texture_ao.SampleLevel(sampler_linear_clamp, ScreenCoord, 0).r;
[branch]
if (GetCamera().texture_ao_index >= 0)
{
surface.occlusion *= bindless_textures_float[GetCamera().texture_ao_index].SampleLevel(sampler_linear_clamp, ScreenCoord, 0).r;
}
#endif // TRANSPARENT
#endif // ENVMAPRENDERING
#endif // PREPASS
@@ -1568,16 +1574,24 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
bumpColor0 = 2 * texture_normalmap.Sample(sampler_objectshader, UV_normalMap - GetMaterial().texMulAdd.ww).rg - 1;
bumpColor1 = 2 * texture_normalmap.Sample(sampler_objectshader, UV_normalMap + GetMaterial().texMulAdd.zw).rg - 1;
}
bumpColor2 = texture_waterriples.SampleLevel(sampler_linear_clamp, ScreenCoord, 0).rg;
[branch]
if (GetCamera().texture_waterriples_index >= 0)
{
bumpColor2 = bindless_textures_float2[GetCamera().texture_waterriples_index].SampleLevel(sampler_linear_clamp, ScreenCoord, 0).rg;
}
bumpColor = float3(bumpColor0 + bumpColor1 + bumpColor2, 1) * GetMaterial().refraction;
surface.N = normalize(lerp(surface.N, mul(normalize(bumpColor), TBN), GetMaterial().normalMapStrength));
bumpColor *= GetMaterial().normalMapStrength;
//REFLECTION
float4 reflectionUV = mul(g_xCamera.ReflVP, float4(surface.P, 1));
reflectionUV.xy /= reflectionUV.w;
reflectionUV.xy = reflectionUV.xy * float2(0.5, -0.5) + 0.5;
lighting.indirect.specular += texture_reflection.SampleLevel(sampler_linear_mirror, reflectionUV.xy + bumpColor.rg, 0).rgb * surface.F;
[branch]
if (GetCamera().texture_reflection_index >= 0)
{
//REFLECTION
float4 reflectionUV = mul(GetCamera().ReflVP, float4(surface.P, 1));
reflectionUV.xy /= reflectionUV.w;
reflectionUV.xy = reflectionUV.xy * float2(0.5, -0.5) + 0.5;
lighting.indirect.specular += bindless_textures[GetCamera().texture_reflection_index].SampleLevel(sampler_linear_mirror, reflectionUV.xy + bumpColor.rg, 0).rgb * surface.F;
}
#endif // WATER
@@ -1598,14 +1612,19 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
}
#endif // OBJECTSHADER_USE_UVSETS
float2 size;
float mipLevels;
texture_refraction.GetDimensions(0, size.x, size.y, mipLevels);
const float2 normal2D = mul((float3x3)g_xCamera.View, surface.N.xyz).xy;
float2 perturbatedRefrTexCoords = ScreenCoord.xy + normal2D * GetMaterial().refraction;
float4 refractiveColor = texture_refraction.SampleLevel(sampler_linear_clamp, perturbatedRefrTexCoords, surface.roughness * mipLevels);
surface.refraction.rgb = surface.albedo * refractiveColor.rgb;
surface.refraction.a = surface.transmission;
[branch]
if (GetCamera().texture_refraction_index >= 0)
{
Texture2D texture_refraction = bindless_textures[GetCamera().texture_refraction_index];
float2 size;
float mipLevels;
texture_refraction.GetDimensions(0, size.x, size.y, mipLevels);
const float2 normal2D = mul((float3x3)GetCamera().View, surface.N.xyz).xy;
float2 perturbatedRefrTexCoords = ScreenCoord.xy + normal2D * GetMaterial().refraction;
float4 refractiveColor = texture_refraction.SampleLevel(sampler_linear_clamp, perturbatedRefrTexCoords, surface.roughness * mipLevels);
surface.refraction.rgb = surface.albedo * refractiveColor.rgb;
surface.refraction.a = surface.transmission;
}
}
#endif // TRANSPARENT
@@ -1638,27 +1657,36 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
#ifndef WATER
#ifndef ENVMAPRENDERING
#ifndef TRANSPARENT
float4 ssr = texture_ssr.SampleLevel(sampler_linear_clamp, ScreenCoord, 0);
lighting.indirect.specular = lerp(lighting.indirect.specular, ssr.rgb * surface.F, ssr.a);
[branch]
if (GetCamera().texture_ssr_index >= 0)
{
float4 ssr = bindless_textures[GetCamera().texture_ssr_index].SampleLevel(sampler_linear_clamp, ScreenCoord, 0);
lighting.indirect.specular = lerp(lighting.indirect.specular, ssr.rgb * surface.F, ssr.a);
}
#endif // TRANSPARENT
#endif // ENVMAPRENDERING
#endif // WATER
#ifdef WATER
// WATER REFRACTION
float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + bumpColor.rg, 0) * g_xCamera.ZFarP;
float depth_difference = sampled_lineardepth - lineardepth;
surface.refraction.rgb = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + bumpColor.rg * saturate(0.5 * depth_difference), 0).rgb;
if (depth_difference < 0)
[branch]
if (GetCamera().texture_refraction_index >= 0)
{
// Fix cutoff by taking unperturbed depth diff to fill the holes with fog:
sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy, 0) * g_xCamera.ZFarP;
depth_difference = sampled_lineardepth - lineardepth;
// WATER REFRACTION
Texture2D texture_refraction = bindless_textures[GetCamera().texture_refraction_index];
float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + bumpColor.rg, 0) * GetCamera().ZFarP;
float depth_difference = sampled_lineardepth - lineardepth;
surface.refraction.rgb = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + bumpColor.rg * saturate(0.5 * depth_difference), 0).rgb;
if (depth_difference < 0)
{
// Fix cutoff by taking unperturbed depth diff to fill the holes with fog:
sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy, 0) * GetCamera().ZFarP;
depth_difference = sampled_lineardepth - lineardepth;
}
// WATER FOG:
surface.refraction.a = 1 - saturate(color.a * 0.1 * depth_difference);
color.a = 1;
}
// WATER FOG:
surface.refraction.a = 1 - saturate(color.a * 0.1 * depth_difference);
color.a = 1;
#endif // WATER
@@ -1674,7 +1702,7 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_TARGET
#ifdef OBJECTSHADER_USE_POSITION3D
ApplyFog(dist, g_xCamera.CamPos, surface.V, color);
ApplyFog(dist, GetCamera().CamPos, surface.V, color);
#endif // OBJECTSHADER_USE_POSITION3D
@@ -28,7 +28,7 @@ ConstantOutput PatchConstantFunction(InputPatch<PixelInput, 3> patch)
output.edges[ie] = GetMesh().tessellation_factor;
#else
float3 edge = patch[(ie + 1) % 3].pos.xyz - patch[ie].pos.xyz;
float3 vec = (patch[(ie + 1) % 3].pos.xyz + patch[ie].pos.xyz) / 2 - g_xCamera.CamPos.xyz;
float3 vec = (patch[(ie + 1) % 3].pos.xyz + patch[ie].pos.xyz) / 2 - GetCamera().CamPos.xyz;
float len = sqrt(dot(edge, edge) / dot(vec, vec));
output.edges[(ie + 1) % 3] = max(1, len * GetMesh().tessellation_factor);
#endif
@@ -43,9 +43,9 @@ ConstantOutput PatchConstantFunction(InputPatch<PixelInput, 3> patch)
for (int ip = 0; ip < 4; ++ip)
{
culled[ip] = 1;
culled[ip] &= dot(g_xCamera.FrustumPlanes[ip + 2], patch[0].pos) < -rad;
culled[ip] &= dot(g_xCamera.FrustumPlanes[ip + 2], patch[1].pos) < -rad;
culled[ip] &= dot(g_xCamera.FrustumPlanes[ip + 2], patch[2].pos) < -rad;
culled[ip] &= dot(GetCamera().FrustumPlanes[ip + 2], patch[0].pos) < -rad;
culled[ip] &= dot(GetCamera().FrustumPlanes[ip + 2], patch[1].pos) < -rad;
culled[ip] &= dot(GetCamera().FrustumPlanes[ip + 2], patch[2].pos) < -rad;
}
if (culled[0] || culled[1] || culled[2] || culled[3]) output.edges[0] = 0;
#endif
@@ -151,16 +151,16 @@ PixelInput main(ConstantOutput input, float3 uvw : SV_DomainLocation, const Outp
#ifdef OBJECTSHADER_USE_CLIPPLANE
output.clip = dot(output.pos, g_xCamera.ClipPlane);
output.clip = dot(output.pos, GetCamera().ClipPlane);
#endif // OBJECTSHADER_USE_CLIPPLANE
#ifndef OBJECTSHADER_USE_NOCAMERA
output.pos = mul(g_xCamera.VP, output.pos);
output.pos = mul(GetCamera().VP, output.pos);
#endif // OBJECTSHADER_USE_NOCAMERA
#ifdef OBJECTSHADER_USE_POSITIONPREV
#ifndef OBJECTSHADER_USE_NOCAMERA
output.pre = mul(g_xCamera.PrevVP, output.pre);
output.pre = mul(GetCamera().PrevVP, output.pre);
#endif // OBJECTSHADER_USE_NOCAMERA
#endif // OBJECTSHADER_USE_POSITIONPREV
+3 -3
View File
@@ -31,14 +31,14 @@ float4 main(PixelInput input) : SV_TARGET
color.rgb += emissiveColor;
float time = g_xFrame.Time;
float2 uv = input.pos.xy * g_xFrame.InternalResolution_rcp;
uv.y *= g_xFrame.InternalResolution.y * g_xFrame.InternalResolution_rcp.x;
float2 uv = input.pos.xy * GetCamera().InternalResolution_rcp;
uv.y *= GetCamera().InternalResolution.y * GetCamera().InternalResolution_rcp.x;
// wave:
color.a *= sin(input.pos3D.y * 30 + time * 10) * 0.5 + 0.5;
// rim:
color *= lerp(0.3, 6, pow(1 - saturate(dot(normalize(input.nor), normalize(g_xCamera.CamPos - input.pos3D))), 2));
color *= lerp(0.3, 6, pow(1 - saturate(dot(normalize(input.nor), normalize(GetCamera().CamPos - input.pos3D))), 2));
// keep some base color
color.a += 0.2;
+29 -20
View File
@@ -11,7 +11,7 @@ TEXTURE2D(texture_gradientmap, float4, TEXSLOT_ONDEMAND1);
float4 main(PSIn input) : SV_TARGET
{
float4 color = xOceanWaterColor;
float3 V = g_xCamera.CamPos - input.pos3D;
float3 V = GetCamera().CamPos - input.pos3D;
float dist = length(V);
V /= dist;
float emissive = 0;
@@ -40,33 +40,42 @@ float4 main(PSIn input) : SV_TARGET
TiledLighting(surface, lighting);
float2 refUV = float2(1, -1)*input.ReflectionMapSamplingPos.xy / input.ReflectionMapSamplingPos.w * 0.5f + 0.5f;
float2 ScreenCoord = surface.pixel * g_xFrame.InternalResolution_rcp;
float2 ScreenCoord = surface.pixel * GetCamera().InternalResolution_rcp;
//REFLECTION
float2 RefTex = float2(1, -1)*input.ReflectionMapSamplingPos.xy / input.ReflectionMapSamplingPos.w / 2.0f + 0.5f;
float4 reflectiveColor = texture_reflection.SampleLevel(sampler_linear_mirror, RefTex + surface.N.xz * 0.04f, 0);
lighting.indirect.specular = reflectiveColor.rgb * surface.F;
// WATER REFRACTION
float lineardepth = input.pos.w;
float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + surface.N.xz * 0.04f, 0) * g_xCamera.ZFarP;
float depth_difference = sampled_lineardepth - lineardepth;
surface.refraction.rgb = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + surface.N.xz * 0.04f * saturate(0.5 * depth_difference), 0).rgb;
if (depth_difference < 0)
[branch]
if (GetCamera().texture_reflection_index >= 0)
{
// Fix cutoff by taking unperturbed depth diff to fill the holes with fog:
sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy, 0) * g_xCamera.ZFarP;
depth_difference = sampled_lineardepth - lineardepth;
//REFLECTION
float2 RefTex = float2(1, -1) * input.ReflectionMapSamplingPos.xy / input.ReflectionMapSamplingPos.w / 2.0f + 0.5f;
float4 reflectiveColor = bindless_textures[GetCamera().texture_reflection_index].SampleLevel(sampler_linear_mirror, RefTex + surface.N.xz * 0.04f, 0);
lighting.indirect.specular = reflectiveColor.rgb * surface.F;
}
[branch]
if (GetCamera().texture_refraction_index >= 0)
{
// WATER REFRACTION
Texture2D texture_refraction = bindless_textures[GetCamera().texture_refraction_index];
float lineardepth = input.pos.w;
float sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy + surface.N.xz * 0.04f, 0) * GetCamera().ZFarP;
float depth_difference = sampled_lineardepth - lineardepth;
surface.refraction.rgb = texture_refraction.SampleLevel(sampler_linear_mirror, ScreenCoord.xy + surface.N.xz * 0.04f * saturate(0.5 * depth_difference), 0).rgb;
if (depth_difference < 0)
{
// Fix cutoff by taking unperturbed depth diff to fill the holes with fog:
sampled_lineardepth = texture_lineardepth.SampleLevel(sampler_point_clamp, ScreenCoord.xy, 0) * GetCamera().ZFarP;
depth_difference = sampled_lineardepth - lineardepth;
}
// WATER FOG:
surface.refraction.a = 1 - saturate(color.a * 0.1f * depth_difference);
}
// WATER FOG:
surface.refraction.a = 1 - saturate(color.a * 0.1f * depth_difference);
// Blend out at distance:
color.a = pow(saturate(1 - saturate(dist / g_xCamera.ZFarP)), 2);
color.a = pow(saturate(1 - saturate(dist / GetCamera().ZFarP)), 2);
ApplyLighting(surface, lighting, color);
ApplyFog(dist, g_xCamera.CamPos, V, color);
ApplyFog(dist, GetCamera().CamPos, V, color);
return color;
}
+6 -6
View File
@@ -12,7 +12,7 @@ static const float3 QUAD[] = {
float3(0, 1, 0),
};
#define infinite g_xCamera.ZFarP
#define infinite GetCamera().ZFarP
float3 intersectPlaneClampInfinite(in float3 rayOrigin, in float3 rayDirection, in float3 planeNormal, float planeHeight)
{
float dist = (planeHeight - dot(planeNormal, rayOrigin)) / dot(planeNormal, rayDirection);
@@ -42,8 +42,8 @@ PSIn main(uint fakeIndex : SV_VERTEXID)
Out.pos.xy *= max(1, xOceanSurfaceDisplacementTolerance); // extrude screen space grid to tolerate displacement
// Perform ray tracing of screen grid and plane surface to unproject to world space:
float3 o = g_xCamera.CamPos;
float4 r = mul(g_xCamera.InvVP, float4(Out.pos.xy, 0, 1));
float3 o = GetCamera().CamPos;
float4 r = mul(GetCamera().InvVP, float4(Out.pos.xy, 0, 1));
r.xyz /= r.w;
float3 d = normalize(o.xyz - r.xyz);
@@ -52,14 +52,14 @@ PSIn main(uint fakeIndex : SV_VERTEXID)
// Displace surface:
float2 uv = worldPos.xz * xOceanPatchSizeRecip;
float3 displacement = texture_displacementmap.SampleLevel(sampler_linear_wrap, uv + xOceanMapHalfTexel, 0).xzy;
displacement *= 1 - saturate(distance(g_xCamera.CamPos, worldPos) * 0.0025f);
displacement *= 1 - saturate(distance(GetCamera().CamPos, worldPos) * 0.0025f);
worldPos += displacement;
// Reproject displaced surface and output:
Out.pos = mul(g_xCamera.VP, float4(worldPos, 1));
Out.pos = mul(GetCamera().VP, float4(worldPos, 1));
Out.pos3D = worldPos;
Out.uv = uv;
Out.ReflectionMapSamplingPos = mul(g_xCamera.ReflVP, float4(worldPos, 1));
Out.ReflectionMapSamplingPos = mul(GetCamera().ReflVP, float4(worldPos, 1));
return Out;
}
+6 -6
View File
@@ -31,12 +31,12 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
RayDesc ray = CreateCameraRay(uv);
// Depth of field setup:
float3 focal_point = ray.Origin + ray.Direction * g_xCamera.FocalLength;
float3 focal_point = ray.Origin + ray.Direction * GetCamera().FocalLength;
float3 coc = float3(hemispherepoint_cos(rand(seed, uv), rand(seed, uv)).xy, 0);
coc.xy *= g_xCamera.ApertureShape.xy;
coc = mul(coc, float3x3(cross(g_xCamera.Up, g_xCamera.At), g_xCamera.Up, g_xCamera.At));
coc *= g_xCamera.FocalLength;
coc *= g_xCamera.ApertureSize;
coc.xy *= GetCamera().ApertureShape.xy;
coc = mul(coc, float3x3(cross(GetCamera().Up, GetCamera().At), GetCamera().Up, GetCamera().At));
coc *= GetCamera().FocalLength;
coc *= GetCamera().ApertureSize;
coc *= 0.1f;
ray.Origin = ray.Origin + coc;
ray.Direction = focal_point - ray.Origin; // will be normalized before tracing!
@@ -152,7 +152,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
float3 atmosphereTransmittance = 1;
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
{
AtmosphereParameters Atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters Atmosphere = GetWeather().atmosphere;
atmosphereTransmittance = GetAtmosphericLightTransmittance(Atmosphere, surface.P, L, texture_transmittancelut);
}
lightColor *= atmosphereTransmittance;
+11 -17
View File
@@ -17,11 +17,11 @@ struct RayDesc
inline RayDesc CreateCameraRay(float2 clipspace)
{
float4 unprojected = mul(g_xCamera.InvVP, float4(clipspace, 0, 1));
float4 unprojected = mul(GetCamera().InvVP, float4(clipspace, 0, 1));
unprojected.xyz /= unprojected.w;
RayDesc ray;
ray.Origin = g_xCamera.CamPos;
ray.Origin = GetCamera().CamPos;
ray.Direction = normalize(unprojected.xyz - ray.Origin);
ray.TMin = 0.001;
ray.TMax = FLT_MAX;
@@ -29,13 +29,7 @@ inline RayDesc CreateCameraRay(float2 clipspace)
return ray;
}
#ifdef RTAPI
// Hardware acceleration raytracing path:
RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATION_STRUCTURE);
#else
#ifndef RTAPI
// Software raytracing implementation:
#ifndef RAYTRACE_STACKSIZE
@@ -47,9 +41,9 @@ RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATI
groupshared uint stack[RAYTRACE_STACKSIZE][RAYTRACING_LAUNCH_BLOCKSIZE * RAYTRACING_LAUNCH_BLOCKSIZE];
#endif // RAYTRACE_STACK_SHARED
RAWBUFFER(primitiveCounterBuffer, TEXSLOT_BVH_COUNTER);
STRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, TEXSLOT_BVH_PRIMITIVES);
STRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, TEXSLOT_BVH_NODES);
#define primitiveCounterBuffer bindless_buffers[GetScene().BVH_counter]
#define bvhNodeBuffer bindless_buffers[GetScene().BVH_nodes]
#define primitiveBuffer bindless_buffers[GetScene().BVH_primitives]
struct RayHit
{
@@ -224,7 +218,7 @@ inline RayHit TraceRay_Closest(RayDesc ray, uint groupIndex = 0)
// pop untraversed node
const uint nodeIndex = stack[--stackpos][groupIndex];
BVHNode node = bvhNodeBuffer[nodeIndex];
BVHNode node = bvhNodeBuffer.Load<BVHNode>(nodeIndex * sizeof(BVHNode));
if (IntersectNode(ray, node, rcpDirection, bestHit.distance))
{
@@ -232,7 +226,7 @@ inline RayHit TraceRay_Closest(RayDesc ray, uint groupIndex = 0)
{
// Leaf node
const uint primitiveID = node.LeftChildIndex;
const BVHPrimitive prim = primitiveBuffer[primitiveID];
const BVHPrimitive prim = primitiveBuffer.Load<BVHPrimitive>(primitiveID * sizeof(BVHPrimitive));
IntersectTriangle(ray, bestHit, prim);
}
else
@@ -283,7 +277,7 @@ inline bool TraceRay_Any(RayDesc ray, uint groupIndex = 0)
// pop untraversed node
const uint nodeIndex = stack[--stackpos][groupIndex];
BVHNode node = bvhNodeBuffer[nodeIndex];
BVHNode node = bvhNodeBuffer.Load<BVHNode>(nodeIndex * sizeof(BVHNode));
if (IntersectNode(ray, node, rcpDirection))
{
@@ -291,7 +285,7 @@ inline bool TraceRay_Any(RayDesc ray, uint groupIndex = 0)
{
// Leaf node
const uint primitiveID = node.LeftChildIndex;
const BVHPrimitive prim = primitiveBuffer[primitiveID];
const BVHPrimitive prim = primitiveBuffer.Load<BVHPrimitive>(primitiveID * sizeof(BVHPrimitive));
if (IntersectTriangleANY(ray, prim))
{
@@ -345,7 +339,7 @@ inline uint TraceRay_DebugBVH(RayDesc ray)
// pop untraversed node
const uint nodeIndex = stack[--stackpos];
BVHNode node = bvhNodeBuffer[nodeIndex];
BVHNode node = bvhNodeBuffer.Load<BVHNode>(nodeIndex * sizeof(BVHNode));
if (IntersectNode(ray, node, rcpDirection))
{
+1 -1
View File
@@ -65,7 +65,7 @@ float4 main(Input input) : SV_TARGET
float3 atmosphereTransmittance = 1.0;
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
{
atmosphereTransmittance = GetAtmosphericLightTransmittance(g_xFrame.Atmosphere, surface.P, L, texture_transmittancelut);
atmosphereTransmittance = GetAtmosphericLightTransmittance(GetWeather().atmosphere, surface.P, L, texture_transmittancelut);
}
float3 lightColor = light.GetColor().rgb * light.GetEnergy() * atmosphereTransmittance;
@@ -24,7 +24,7 @@ float2 FFX_DNSR_Shadows_GetInvBufferDimensions()
}
float4x4 FFX_DNSR_Shadows_GetProjectionInverse()
{
return g_xCamera.InvP;
return GetCamera().InvP;
}
float FFX_DNSR_Shadows_GetDepthSimilaritySigma()
@@ -7,7 +7,6 @@ TEXTURE2D(normals, float3, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(tiles, uint, TEXSLOT_ONDEMAND1);
TEXTURE2D(moments_prev, float3, TEXSLOT_ONDEMAND2);
TEXTURE2D(history, float, TEXSLOT_ONDEMAND3);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND4);
RWTEXTURE2D(reprojection, float2, 0);
RWTEXTURE2D(moments, float3, 1);
@@ -27,19 +26,19 @@ float2 FFX_DNSR_Shadows_GetInvBufferDimensions()
}
float3 FFX_DNSR_Shadows_GetEye()
{
return g_xCamera.CamPos;
return GetCamera().CamPos;
}
float4x4 FFX_DNSR_Shadows_GetProjectionInverse()
{
return g_xCamera.InvP;
return GetCamera().InvP;
}
float4x4 FFX_DNSR_Shadows_GetViewProjectionInverse()
{
return g_xCamera.InvVP;
return GetCamera().InvVP;
}
float4x4 FFX_DNSR_Shadows_GetReprojectionMatrix()
{
return g_xCamera.Reprojection;
return GetCamera().Reprojection;
}
float FFX_DNSR_Shadows_ReadDepth(uint2 did)
+1 -3
View File
@@ -10,8 +10,6 @@
PUSHCONSTANT(postprocess, PostProcess);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND2);
RWTEXTURE2D(output, float4, 0);
RWTEXTURE2D(output_rayLengths, float, 1);
@@ -30,7 +28,7 @@ void RTReflection_Raygen()
return;
const float3 P = reconstructPosition(uv, depth);
const float3 V = normalize(g_xCamera.CamPos - P);
const float3 V = normalize(GetCamera().CamPos - P);
PrimitiveID prim;
prim.unpack(texture_gbuffer0[DTid.xy * 2]);
@@ -26,7 +26,7 @@ float2 FFX_DNSR_Shadows_GetInvBufferDimensions()
}
float4x4 FFX_DNSR_Shadows_GetProjectionInverse()
{
return g_xCamera.InvP;
return GetCamera().InvP;
}
float FFX_DNSR_Shadows_GetDepthSimilaritySigma()
@@ -6,7 +6,6 @@ PUSHCONSTANT(postprocess, PostProcess);
TEXTURE2D(resolve_current, uint4, TEXSLOT_ONDEMAND0);
TEXTURE2D(resolve_history, uint4, TEXSLOT_ONDEMAND1);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND2);
TEXTURE2D(denoised, float4, TEXSLOT_ONDEMAND3);
RWTEXTURE2D(temporal_output, uint4, 0);
@@ -4,7 +4,6 @@
PUSHCONSTANT(postprocess, PostProcess);
TEXTURE2D(normals, float3, TEXSLOT_ONDEMAND0);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND1);
STRUCTUREDBUFFER(tiles, uint4, TEXSLOT_ONDEMAND2);
RWSTRUCTUREDBUFFER(metadata, uint4, 0);
@@ -32,19 +31,19 @@ float2 FFX_DNSR_Shadows_GetInvBufferDimensions()
}
float3 FFX_DNSR_Shadows_GetEye()
{
return g_xCamera.CamPos;
return GetCamera().CamPos;
}
float4x4 FFX_DNSR_Shadows_GetProjectionInverse()
{
return g_xCamera.InvP;
return GetCamera().InvP;
}
float4x4 FFX_DNSR_Shadows_GetViewProjectionInverse()
{
return g_xCamera.InvVP;
return GetCamera().InvVP;
}
float4x4 FFX_DNSR_Shadows_GetReprojectionMatrix()
{
return g_xCamera.Reprojection;
return GetCamera().Reprojection;
}
float FFX_DNSR_Shadows_ReadDepth(uint2 did)
+14 -7
View File
@@ -5,7 +5,14 @@
PUSHCONSTANT(postprocess, PostProcess);
STRUCTUREDBUFFER(EntityTiles, uint, TEXSLOT_RENDERPATH_ENTITYTILES);
uint load_entitytile(uint tileIndex)
{
#ifdef TRANSPARENT
return bindless_buffers[GetCamera().buffer_entitytiles_transparent_index].Load(tileIndex * sizeof(uint));
#else
return bindless_buffers[GetCamera().buffer_entitytiles_opaque_index].Load(tileIndex * sizeof(uint));
#endif // TRANSPARENT
}
static const uint MAX_RTSHADOWS = 16;
RWTEXTURE2D(output, uint4, 0);
@@ -56,7 +63,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
const float2 bluenoise = blue_noise(DTid.xy).xy;
const uint2 tileIndex = uint2(floor(DTid.xy * 2 / TILED_CULLING_BLOCKSIZE));
const uint flatTileIndex = flatten2D(tileIndex, g_xFrame.EntityCullingTileCount.xy) * SHADER_ENTITY_TILE_BUCKET_COUNT;
const uint flatTileIndex = flatten2D(tileIndex, GetCamera().EntityCullingTileCount.xy) * SHADER_ENTITY_TILE_BUCKET_COUNT;
uint shadow_mask[4] = {0,0,0,0}; // FXC issue: can't dynamically index into uint4, unless unrolling all loops
uint shadow_index = 0;
@@ -66,7 +73,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
ray.Origin = P;
#ifndef RTSHADOW
ray.Origin = mul(g_xCamera.View, float4(ray.Origin, 1)).xyz;
ray.Origin = mul(GetCamera().View, float4(ray.Origin, 1)).xyz;
const float range = postprocess.params0.x;
const uint samplecount = postprocess.params0.y;
@@ -86,7 +93,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
[loop]
for (uint bucket = first_bucket; bucket <= last_bucket && shadow_index < MAX_RTSHADOWS; ++bucket)
{
uint bucket_bits = EntityTiles[flatTileIndex + bucket];
uint bucket_bits = load_entitytile(flatTileIndex + bucket);
// Bucket scalarizer - Siggraph 2017 - Improved Culling [Michal Drobot]:
bucket_bits = WaveReadLaneFirst(WaveActiveBitOr(bucket_bits));
@@ -243,7 +250,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
#else
// screen space raymarch shadow:
ray.Direction = normalize(mul((float3x3)g_xCamera.View, L));
ray.Direction = normalize(mul((float3x3)GetCamera().View, L));
float3 rayPos = ray.Origin + ray.Direction * stepsize * offset;
float occlusion = 0;
@@ -252,7 +259,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
{
rayPos += ray.Direction * stepsize;
float4 proj = mul(g_xCamera.Proj, float4(rayPos, 1));
float4 proj = mul(GetCamera().Proj, float4(rayPos, 1));
proj.xyz /= proj.w;
proj.xy = proj.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
@@ -260,7 +267,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
if (is_saturated(proj.xy))
{
const float ray_depth_real = proj.w;
const float ray_depth_sample = texture_lineardepth.SampleLevel(sampler_point_clamp, proj.xy, 1) * g_xCamera.ZFarP;
const float ray_depth_sample = texture_lineardepth.SampleLevel(sampler_point_clamp, proj.xy, 1) * GetCamera().ZFarP;
const float ray_depth_delta = ray_depth_real - ray_depth_sample;
if (ray_depth_delta > 0 && ray_depth_delta < thickness)
{
@@ -19,7 +19,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
uv = float2(FromSubUvsToUnit(uv.x, multiScatteringLUTRes.x), FromSubUvsToUnit(uv.y, multiScatteringLUTRes.y));
AtmosphereParameters atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters atmosphere = GetWeather().atmosphere;
float cosSunZenithAngle = uv.x * 2.0 - 1.0;
float3 sunDirection = float3(0.0, sqrt(saturate(1.0 - cosSunZenithAngle * cosSunZenithAngle)), cosSunZenithAngle);
@@ -16,7 +16,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
float2 uv = pixelPosition * rcp(multiScatteringLUTRes);
AtmosphereParameters atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters atmosphere = GetWeather().atmosphere;
float viewHeight = atmosphere.bottomRadius + skyLuminanceSampleHeight;
@@ -8,12 +8,12 @@ RWTEXTURE2D(output, float4, 0);
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
AtmosphereParameters atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters atmosphere = GetWeather().atmosphere;
float2 pixelPosition = float2(DTid.xy) + 0.5;
float2 uv = pixelPosition * rcp(skyViewLUTRes);
float3 skyRelativePosition = g_xCamera.CamPos;
float3 skyRelativePosition = GetCamera().CamPos;
float3 worldPosition = GetCameraPlanetPos(atmosphere, skyRelativePosition);
float viewHeight = length(worldPosition);
@@ -9,7 +9,7 @@ RWTEXTURE2D(output, float4, 0);
void main(uint3 DTid : SV_DispatchThreadID)
{
float2 pixelPosition = float2(DTid.xy) + 0.5;
AtmosphereParameters atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters atmosphere = GetWeather().atmosphere;
// Compute camera position from LUT coords
const float2 uv = pixelPosition * rcp(transmittanceLUTRes);
+11 -11
View File
@@ -8,7 +8,7 @@
float3 AccurateAtmosphericScattering(Texture2D<float4> skyViewLutTexture, Texture2D<float4> transmittanceLUT, Texture2D<float4> multiScatteringLUT, float3 rayOrigin, float3 rayDirection, float3 sunDirection, float sunEnergy, float3 sunColor, bool enableSun, bool darkMode, bool stationary)
{
AtmosphereParameters atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters atmosphere = GetWeather().atmosphere;
float3 worldDirection = rayDirection;
@@ -119,7 +119,7 @@ float3 CustomAtmosphericScattering(float3 V, float3 sunDirection, float3 sunColo
const float zenith = V.y; // how much is above (0: horizon, 1: directly above)
const float sunScatter = saturate(sunDirection.y + 0.1f); // how much the sun is directly above. Even if sunis at horizon, we add a constant scattering amount so that light still scatters at horizon
const float atmosphereDensity = 0.5 + g_xFrame.FogHeightSky; // constant of air density, or "fog height" as interpreted here (bigger is more obstruction of sun)
const float atmosphereDensity = 0.5 + GetWeather().fog.height_sky; // constant of air density, or "fog height" as interpreted here (bigger is more obstruction of sun)
const float zenithDensity = atmosphereDensity / pow(max(0.000001f, zenith), 0.75f);
const float sunScatterDensity = atmosphereDensity / pow(max(0.000001f, sunScatter), 0.75f);
@@ -153,13 +153,13 @@ float3 CustomAtmosphericScattering(float3 V, float3 sunDirection, float3 sunColo
void CalculateClouds(inout float3 sky, float3 V, bool dark_enabled)
{
if (g_xFrame.Cloudiness <= 0)
if (GetWeather().cloudiness <= 0)
{
return;
}
// Trace a cloud layer plane:
const float3 o = g_xCamera.CamPos;
const float3 o = GetCamera().CamPos;
const float3 d = V;
const float3 planeOrigin = float3(0, 1000, 0);
const float3 planeNormal = float3(0, -1, 0);
@@ -171,8 +171,8 @@ void CalculateClouds(inout float3 sky, float3 V, bool dark_enabled)
}
const float3 cloudPos = o + d * t;
const float2 cloudUV = cloudPos.xz * g_xFrame.CloudScale;
const float cloudTime = g_xFrame.Time * g_xFrame.CloudSpeed;
const float2 cloudUV = cloudPos.xz * GetWeather().cloud_scale;
const float cloudTime = g_xFrame.Time * GetWeather().cloud_speed;
const float2x2 m = float2x2(1.6, 1.2, -1.2, 1.6);
const uint quality = 8;
@@ -224,8 +224,8 @@ void CalculateClouds(inout float3 sky, float3 V, bool dark_enabled)
// lerp between "choppy clouds" and "uniform clouds". Lower cloudiness will produce choppy clouds, but very high cloudiness will switch to overcast unfiform clouds:
clouds = lerp(clouds * 9.0f * g_xFrame.Cloudiness + 0.3f, clouds * 0.5f + 0.5f, pow(saturate(g_xFrame.Cloudiness), 8));
clouds = saturate(clouds - (1 - g_xFrame.Cloudiness)); // modulate constant cloudiness
clouds = lerp(clouds * 9.0f * GetWeather().cloudiness + 0.3f, clouds * 0.5f + 0.5f, pow(saturate(GetWeather().cloudiness), 8));
clouds = saturate(clouds - (1 - GetWeather().cloudiness)); // modulate constant cloudiness
clouds *= pow(1 - saturate(length(abs(cloudPos.xz * 0.00001f))), 16); //fade close to horizon
if (dark_enabled)
@@ -244,7 +244,7 @@ float3 GetDynamicSkyColor(in float3 V, bool sun_enabled = true, bool clouds_enab
{
if (g_xFrame.Options & OPTION_BIT_SIMPLE_SKY)
{
return lerp(GetHorizonColor(), GetZenithColor(), saturate(V.y * 0.5f + 0.5f)) * g_xFrame.SkyExposure;
return lerp(GetHorizonColor(), GetZenithColor(), saturate(V.y * 0.5f + 0.5f)) * GetWeather().sky_exposure;
}
const float3 sunDirection = GetSunDirection();
@@ -260,7 +260,7 @@ float3 GetDynamicSkyColor(in float3 V, bool sun_enabled = true, bool clouds_enab
texture_skyviewlut, // Sky View Lut (combination of precomputed atmospheric LUTs)
texture_transmittancelut,
texture_multiscatteringlut,
g_xCamera.CamPos, // Ray origin
GetCamera().CamPos, // Ray origin
V, // Ray direction
sunDirection, // Position of the sun
sunEnergy, // Sun energy
@@ -282,7 +282,7 @@ float3 GetDynamicSkyColor(in float3 V, bool sun_enabled = true, bool clouds_enab
);
}
sky *= g_xFrame.SkyExposure;
sky *= GetWeather().sky_exposure;
if (clouds_enabled)
{
+2 -2
View File
@@ -3,10 +3,10 @@
float4 main(float4 pos : SV_POSITION, float2 clipspace : TEXCOORD) : SV_TARGET
{
float4 unprojected = mul(g_xCamera.InvVP, float4(clipspace, 0.0f, 1.0f));
float4 unprojected = mul(GetCamera().InvVP, float4(clipspace, 0.0f, 1.0f));
unprojected.xyz /= unprojected.w;
const float3 V = normalize(unprojected.xyz - g_xCamera.CamPos);
const float3 V = normalize(unprojected.xyz - GetCamera().CamPos);
float4 color = float4(GetDynamicSkyColor(V), 1);
+4 -4
View File
@@ -3,16 +3,16 @@
float4 main(float4 pos : SV_POSITION, float2 clipspace : TEXCOORD) : SV_TARGET
{
float4 unprojected = mul(g_xCamera.InvVP, float4(clipspace, 0.0f, 1.0f));
float4 unprojected = mul(GetCamera().InvVP, float4(clipspace, 0.0f, 1.0f));
unprojected.xyz /= unprojected.w;
const float3 V = normalize(unprojected.xyz - g_xCamera.CamPos);
const float3 V = normalize(unprojected.xyz - GetCamera().CamPos);
float4 color = float4(DEGAMMA_SKY(texture_globalenvmap.SampleLevel(sampler_linear_clamp, V, 0).rgb), 1);
CalculateClouds(color.rgb, V, false);
float4 pos2DPrev = mul(g_xCamera.PrevVP, float4(unprojected.xyz, 1));
float2 velocity = ((pos2DPrev.xy / pos2DPrev.w - g_xCamera.TemporalAAJitterPrev) - (clipspace - g_xCamera.TemporalAAJitter)) * float2(0.5f, -0.5f);
float4 pos2DPrev = mul(GetCamera().PrevVP, float4(unprojected.xyz, 1));
float2 velocity = ((pos2DPrev.xy / pos2DPrev.w - GetCamera().TemporalAAJitterPrev) - (clipspace - GetCamera().TemporalAAJitter)) * float2(0.5f, -0.5f);
return color;
}
+1 -1
View File
@@ -15,6 +15,6 @@ VSOut_Sphere main( uint vID : SV_VERTEXID )
o.nor = o.pos.xyz;
o.pos = mul(g_xTransform, o.pos);
o.pos3D = o.pos.xyz;
o.pos = mul(g_xCamera.VP, o.pos);
o.pos = mul(GetCamera().VP, o.pos);
return o;
}
+4 -4
View File
@@ -22,7 +22,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
const uint2 pixel = tile_upperleft + unflatten2D(t, TILE_SIZE);
const float2 uv = (pixel + 0.5f) * postprocess.resolution_rcp;
const float depth = texture_depth.SampleLevel(sampler_linear_clamp, uv, 1);
const float3 position = reconstructPosition(uv, depth, g_xCamera.InvP); // specify matrix to get view-space position!
const float3 position = reconstructPosition(uv, depth, GetCamera().InvP); // specify matrix to get view-space position!
tile_XY[t] = position.xy;
tile_Z[t] = position.z;
}
@@ -46,7 +46,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
const float center_Z = tile_Z[cross_idx[0]];
[branch]
if (center_Z >= g_xCamera.ZFarP)
if (center_Z >= GetCamera().ZFarP)
return;
const uint best_Z_horizontal = abs(tile_Z[cross_idx[1]] - center_Z) < abs(tile_Z[cross_idx[2]] - center_Z) ? 1 : 2;
@@ -95,7 +95,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
const float ray_range = ssao_range * lerp(0.2f, 1.0f, rand(seed, uv)); // modulate ray-length a bit to avoid uniform look
const float3 sam = P + cone * ray_range;
float4 vProjectedCoord = mul(g_xCamera.Proj, float4(sam, 1.0f));
float4 vProjectedCoord = mul(GetCamera().Proj, float4(sam, 1.0f));
vProjectedCoord.xyz /= vProjectedCoord.w;
vProjectedCoord.xy = vProjectedCoord.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
@@ -104,7 +104,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
{
#ifdef USE_LINEARDEPTH
const float ray_depth_real = vProjectedCoord.w; // .w is also linear depth, could be also written as getLinearDepth(vProjectedCoord.z)
const float ray_depth_sample = texture_lineardepth.SampleLevel(sampler_point_clamp, vProjectedCoord.xy, 0) * g_xCamera.ZFarP;
const float ray_depth_sample = texture_lineardepth.SampleLevel(sampler_point_clamp, vProjectedCoord.xy, 0) * GetCamera().ZFarP;
const float depth_fix = 1 - saturate(abs(ray_depth_real - ray_depth_sample) * 0.2f); // too much depth difference cancels the effect
ao += (ray_depth_sample < ray_depth_real) * depth_fix;
#else
+8 -8
View File
@@ -51,14 +51,14 @@ bool IntersectsDepthBuffer(float sceneZMax, float rayZMin, float rayZMax)
bool ScreenSpaceRayTrace(float3 csOrig, float3 csDir, float jitter, float roughness, out float2 hitPixel, out float3 hitPoint, out float iterations)
{
csOrig += csDir * 0.001; // precision issues in DX12
float rayLength = ((csOrig.z + csDir.z * rayTraceMaxDistance) < g_xCamera.ZNearP) ?
(g_xCamera.ZNearP - csOrig.z) / csDir.z : rayTraceMaxDistance;
float rayLength = ((csOrig.z + csDir.z * rayTraceMaxDistance) < GetCamera().ZNearP) ?
(GetCamera().ZNearP - csOrig.z) / csDir.z : rayTraceMaxDistance;
float3 csRayEnd = csOrig + csDir * rayLength;
// Project into homogeneous clip space
float4 clipRayOrigin = mul(g_xCamera.Proj, float4(csOrig, 1.0f));
float4 clipRayEnd = mul(g_xCamera.Proj, float4(csRayEnd, 1.0f));
float4 clipRayOrigin = mul(GetCamera().Proj, float4(csOrig, 1.0f));
float4 clipRayEnd = mul(GetCamera().Proj, float4(csRayEnd, 1.0f));
float k0 = 1.0f / clipRayOrigin.w;
float k1 = 1.0f / clipRayEnd.w;
@@ -203,7 +203,7 @@ bool ScreenSpaceRayTrace(float3 csOrig, float3 csDir, float jitter, float roughn
hitPixel = permute ? PQk.yx : PQk.xy;
hitPixel *= postprocess.resolution_rcp;
sceneZMax = texture_lineardepth.SampleLevel(sampler_linear_clamp, hitPixel, level) * g_xCamera.ZFarP;
sceneZMax = texture_lineardepth.SampleLevel(sampler_linear_clamp, hitPixel, level) * GetCamera().ZFarP;
}
// Undo the last increment, which ran after the test variables were set up
@@ -241,8 +241,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
}
// Everything in view space:
float3 N = normalize(mul((float3x3)g_xCamera.View, surface.N));
float3 P = reconstructPosition(uv, depth, g_xCamera.InvP);
float3 N = normalize(mul((float3x3)GetCamera().View, surface.N));
float3 P = reconstructPosition(uv, depth, GetCamera().InvP);
float3 V = normalize(-P);
const float roughness = GetRoughness(surface.roughness);
@@ -347,7 +347,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
if (hit)
{
const float3 Phit = reconstructPosition(uv, hitDepth, g_xCamera.InvP);
const float3 Phit = reconstructPosition(uv, hitDepth, GetCamera().InvP);
texture_rayLengths[DTid.xy] = distance(P, Phit);
}
else
+3 -3
View File
@@ -65,7 +65,7 @@ void GetSampleInfo(float2 velocity, float2 neighborUV, float2 uv, float3 P, floa
// BRDF Weight
float3 hitViewPosition = reconstructPosition(hitPixel, hitDepth, g_xCamera.InvP);
float3 hitViewPosition = reconstructPosition(hitPixel, hitDepth, GetCamera().InvP);
float3 L = normalize(hitViewPosition - P);
float3 H = normalize(L + V);
@@ -98,7 +98,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
return;
// Everthing in view space:
const float3 P = reconstructPosition(uv, depth, g_xCamera.InvP);
const float3 P = reconstructPosition(uv, depth, GetCamera().InvP);
const float3 V = normalize(-P);
PrimitiveID prim;
@@ -107,7 +107,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
Surface surface;
surface.load(prim, P);
const float3 N = normalize(mul((float3x3)g_xCamera.View, surface.N));
const float3 N = normalize(mul((float3x3)GetCamera().View, surface.N));
const float roughness = GetRoughness(surface.roughness);
const float NdotV = saturate(dot(N, V));
+3 -4
View File
@@ -6,7 +6,6 @@ PUSHCONSTANT(postprocess, PostProcess);
TEXTURE2D(resolve_current, float4, TEXSLOT_ONDEMAND0);
TEXTURE2D(resolve_history, float4, TEXSLOT_ONDEMAND1);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND2);
TEXTURE2D(rayLengths, float, TEXSLOT_ONDEMAND3);
RWTEXTURE2D(output, float4, 0);
@@ -110,7 +109,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3
return;
}
const float3 P = reconstructPosition(uv, depth, g_xCamera.InvP);
const float3 P = reconstructPosition(uv, depth, GetCamera().InvP);
PrimitiveID prim;
prim.unpack(texture_gbuffer0[DTid.xy * 2]);
@@ -134,9 +133,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3
if (rayLength > 0)
{
const float3 P = reconstructPosition(uv, depth);
const float3 V = normalize(g_xCamera.CamPos - P);
const float3 V = normalize(GetCamera().CamPos - P);
const float3 rayEnd = P - V * rayLength;
float4 rayEndPrev = mul(g_xCamera.PrevVP, float4(rayEnd, 1));
float4 rayEndPrev = mul(GetCamera().PrevVP, float4(rayEnd, 1));
rayEndPrev.xy /= rayEndPrev.w;
prevUV = rayEndPrev.xy * float2(0.5, -0.5) + 0.5;
}
+2 -2
View File
@@ -4,10 +4,10 @@
float4 main(float4 pos : SV_POSITION, float2 clipspace : TEXCOORD) : SV_TARGET
{
float4 unprojected = mul(g_xCamera.InvVP, float4(clipspace, 0.0f, 1.0f));
float4 unprojected = mul(GetCamera().InvVP, float4(clipspace, 0.0f, 1.0f));
unprojected.xyz /= unprojected.w;
const float3 origin = g_xCamera.CamPos;
const float3 origin = GetCamera().CamPos;
const float3 direction = normalize(unprojected.xyz - origin);
return float4(GetDynamicSkyColor(direction, true, true, true), 1);
+2 -2
View File
@@ -92,7 +92,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uin
float4 color = 0;
float seed = g_xFrame.Time;
const float2 uv = ((float2)pixel + 0.5) * g_xFrame.InternalResolution_rcp;
const float2 uv = ((float2)pixel + 0.5) * GetCamera().InternalResolution_rcp;
const float3 P = reconstructPosition(uv, depth);
uint2 primitiveID = texture_gbuffer0[pixel];
@@ -251,7 +251,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uin
{
// Slow down the propagation by chance
// Closer surfaces have less chance to avoid excessive clumping of surfels
const float lineardepth = getLinearDepth(depth) * g_xCamera.ZFarP_rcp;
const float lineardepth = getLinearDepth(depth) * GetCamera().ZFarP_rcp;
#ifdef SURFEL_COVERAGE_HALFRES
const float chance = pow(1 - lineardepth, 8);
#else
+9 -9
View File
@@ -159,7 +159,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
float3 atmosphereTransmittance = 1.0;
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
{
atmosphereTransmittance = GetAtmosphericLightTransmittance(g_xFrame.Atmosphere, surface.P, L, texture_transmittancelut);
atmosphereTransmittance = GetAtmosphericLightTransmittance(GetWeather().atmosphere, surface.P, L, texture_transmittancelut);
}
float3 lightColor = light.GetColor().rgb * light.GetEnergy() * atmosphereTransmittance;
@@ -383,19 +383,19 @@ void main(uint3 DTid : SV_DispatchThreadID)
life++;
float3 cam_to_surfel = surfel.position - g_xCamera.CamPos;
float3 cam_to_surfel = surfel.position - GetCamera().CamPos;
if (length(cam_to_surfel) > SURFEL_RECYCLE_DISTANCE)
{
#if 1
uint infrustum = 1;
float3 center = surfel.position;
float radius = -surfel.GetRadius();
infrustum &= dot(g_xCamera.FrustumPlanes[0], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[1], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[2], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[3], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[4], float4(center, 1)) > radius;
infrustum &= dot(g_xCamera.FrustumPlanes[5], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[0], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[1], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[2], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[3], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[4], float4(center, 1)) > radius;
infrustum &= dot(GetCamera().FrustumPlanes[5], float4(center, 1)) > radius;
if (infrustum)
{
recycle = 0;
@@ -405,7 +405,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
recycle++;
}
#else
if (dot(cam_to_surfel, g_xCamera.At) < 0)
if (dot(cam_to_surfel, GetCamera().At) < 0)
{
recycle++;
}
+2 -3
View File
@@ -5,7 +5,6 @@ PUSHCONSTANT(postprocess, PostProcess);
TEXTURE2D(input_current, float3, TEXSLOT_ONDEMAND0);
TEXTURE2D(input_history, float3, TEXSLOT_ONDEMAND1);
TEXTURE2D(texture_depth_history, float, TEXSLOT_ONDEMAND2);
RWTEXTURE2D(output, float3, 0);
@@ -102,7 +101,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3
#if 0
// Disocclusion fallback:
float depth_current = texture_lineardepth[DTid.xy] * g_xCamera.ZFarP;
float depth_current = texture_lineardepth[DTid.xy] * GetCamera().ZFarP;
float depth_history = getLinearDepth(texture_depth_history.SampleLevel(sampler_point_clamp, prevUV, 0));
if (length(velocity) > 0.01 && abs(depth_current - depth_history) > 1)
{
@@ -119,7 +118,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3
history.rgb = clamp(history.rgb, neighborhoodMin, neighborhoodMax);
// the linear filtering can cause blurry image, try to account for that:
float subpixelCorrection = frac(max(abs(velocity.x)*g_xFrame.InternalResolution.x, abs(velocity.y)*g_xFrame.InternalResolution.y)) * 0.5f;
float subpixelCorrection = frac(max(abs(velocity.x) * GetCamera().InternalResolution.x, abs(velocity.y) * GetCamera().InternalResolution.y)) * 0.5f;
// compute a nice blend factor:
float blendfactor = saturate(lerp(0.05f, 0.8f, subpixelCorrection));
+2 -2
View File
@@ -46,8 +46,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
frustum.planes[3] = ComputePlane(viewSpace[3], eyePos, viewSpace[2]);
// Store the computed frustum in global memory (if our thread ID is in bounds of the grid).
if (DTid.x < g_xFrame.EntityCullingTileCount.x && DTid.y < g_xFrame.EntityCullingTileCount.y)
if (DTid.x < GetCamera().EntityCullingTileCount.x && DTid.y < GetCamera().EntityCullingTileCount.y)
{
out_Frustums[flatten2D(DTid.xy, g_xFrame.EntityCullingTileCount.xy)] = frustum;
out_Frustums[flatten2D(DTid.xy, GetCamera().EntityCullingTileCount.xy)] = frustum;
}
}
@@ -45,7 +45,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
texture_lineardepth.SampleLevel(sampler_point_clamp, uv11, lowres_depthchain_mip)
);
const float4 depth_diff = abs(lineardepth_highres - lineardepth_lowres) * g_xCamera.ZFarP;
const float4 depth_diff = abs(lineardepth_highres - lineardepth_lowres) * GetCamera().ZFarP;
const float accum_diff = dot(depth_diff, float4(1, 1, 1, 1));
UPSAMPLE_FORMAT color;
+1 -1
View File
@@ -7,7 +7,7 @@ VertexToPixel main(uint vID : SV_VertexID)
float4 pos = CIRCLE[vID];
pos = mul(lightWorld, pos);
Out.pos = mul(g_xCamera.VP, pos);
Out.pos = mul(GetCamera().VP, pos);
Out.col = lerp(
float4(lightColor.rgb, 1), float4(0, 0, 0, 0),
distance(pos.xyz, float3(lightWorld._14, lightWorld._24, lightWorld._34)) / (lightEnerdis.w)
+1 -1
View File
@@ -7,7 +7,7 @@ VertexToPixel main(uint vID : SV_VertexID)
float4 pos = CONE[vID];
pos = mul(lightWorld, pos);
Out.pos = mul(g_xCamera.VP, pos);
Out.pos = mul(GetCamera().VP, pos);
Out.col = lerp(
float4(lightColor.rgb, 1), float4(0, 0, 0, 0),
distance(pos.xyz, float3(lightWorld._14, lightWorld._24, lightWorld._34)) / (lightEnerdis.w)
@@ -30,7 +30,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uin
{
uint2 pixel = DTid.xy;
const float2 uv = ((float2)pixel + 0.5) * g_xFrame.InternalResolution_rcp;
const float2 uv = ((float2)pixel + 0.5) * GetCamera().InternalResolution_rcp;
const float depth = texture_depthbuffer[pixel];
const float3 P = reconstructPosition(uv, depth);
@@ -55,11 +55,11 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uin
}
float4 pos2DPrev = mul(g_xCamera.PrevVP, float4(pre, 1));
float4 pos2DPrev = mul(GetCamera().PrevVP, float4(pre, 1));
pos2DPrev.xy /= pos2DPrev.w;
float2 pos2D = uv * 2 - 1;
pos2D.y *= -1;
float2 velocity = ((pos2DPrev.xy - g_xCamera.TemporalAAJitterPrev) - (pos2D.xy - g_xCamera.TemporalAAJitter)) * float2(0.5, -0.5);
float2 velocity = ((pos2DPrev.xy - GetCamera().TemporalAAJitterPrev) - (pos2D.xy - GetCamera().TemporalAAJitter)) * float2(0.5, -0.5);
output_velocity[pixel] = velocity;
@@ -67,7 +67,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uin
// Downsample depths:
output_depth_mip0[pixel] = depth;
float lineardepth = getLinearDepth(depth) * g_xCamera.ZFarP_rcp;
float lineardepth = getLinearDepth(depth) * GetCamera().ZFarP_rcp;
output_lineardepth_mip0[pixel] = lineardepth;
if (GTid.x % 2 == 0 && GTid.y % 2 == 0)
@@ -46,7 +46,7 @@ float GetHeightFractionForPoint(AtmosphereParameters atmosphere, float3 pos)
float planetRadius = atmosphere.bottomRadius * SKY_UNIT_TO_M;
float3 planetCenterWorld = atmosphere.planetCenter * SKY_UNIT_TO_M;
return saturate((distance(pos, planetCenterWorld) - (planetRadius + g_xFrame.VolumetricClouds.CloudStartHeight)) / g_xFrame.VolumetricClouds.CloudThickness);
return saturate((distance(pos, planetCenterWorld) - (planetRadius + GetWeather().volumetric_clouds.CloudStartHeight)) / GetWeather().volumetric_clouds.CloudThickness);
}
float SampleGradient(float4 gradient, float heightFraction)
@@ -62,21 +62,21 @@ float GetDensityHeightGradient(float heightFraction, float3 weatherData)
float mediumType = 1.0f - abs(cloudType - 0.5f) * 2.0f;
float largeType = saturate(cloudType - 0.5f) * 2.0f;
float4 cloudGradient = (g_xFrame.VolumetricClouds.CloudGradientSmall * smallType) + (g_xFrame.VolumetricClouds.CloudGradientMedium * mediumType) + (g_xFrame.VolumetricClouds.CloudGradientLarge * largeType);
float4 cloudGradient = (GetWeather().volumetric_clouds.CloudGradientSmall * smallType) + (GetWeather().volumetric_clouds.CloudGradientMedium * mediumType) + (GetWeather().volumetric_clouds.CloudGradientLarge * largeType);
return SampleGradient(cloudGradient, heightFraction);
}
float3 SampleWeather(float3 pos, float heightFraction, float2 coverageWindOffset)
{
float4 weatherData = texture_weatherMap.SampleLevel(sampler_linear_wrap, (pos.xz + coverageWindOffset) * g_xFrame.VolumetricClouds.WeatherScale * 0.0004, 0);
float4 weatherData = texture_weatherMap.SampleLevel(sampler_linear_wrap, (pos.xz + coverageWindOffset) * GetWeather().volumetric_clouds.WeatherScale * 0.0004, 0);
// Anvil clouds
weatherData.r = pow(abs(weatherData.r), RemapClamped(heightFraction * g_xFrame.VolumetricClouds.AnvilOverhangHeight, 0.7, 0.8, 1.0, lerp(1.0, 0.5, g_xFrame.VolumetricClouds.AnvilAmount)));
weatherData.r = pow(abs(weatherData.r), RemapClamped(heightFraction * GetWeather().volumetric_clouds.AnvilOverhangHeight, 0.7, 0.8, 1.0, lerp(1.0, 0.5, GetWeather().volumetric_clouds.AnvilAmount)));
//weatherData.r *= lerp(1, RemapClamped(pow(heightFraction * xPPDebugParams.y, 0.5), 0.4, 0.95, 1.0, 0.2), xPPDebugParams.x);
// Apply effects for coverage
weatherData.r = RemapClamped(weatherData.r * g_xFrame.VolumetricClouds.CoverageAmount, 0.0, 1.0, saturate(g_xFrame.VolumetricClouds.CoverageMinimum - 1.0), 1.0);
weatherData.g = RemapClamped(weatherData.g * g_xFrame.VolumetricClouds.TypeAmount, 0.0, 1.0, g_xFrame.VolumetricClouds.TypeOverall, 1.0);
weatherData.r = RemapClamped(weatherData.r * GetWeather().volumetric_clouds.CoverageAmount, 0.0, 1.0, saturate(GetWeather().volumetric_clouds.CoverageMinimum - 1.0), 1.0);
weatherData.g = RemapClamped(weatherData.g * GetWeather().volumetric_clouds.TypeAmount, 0.0, 1.0, GetWeather().volumetric_clouds.TypeOverall, 1.0);
return weatherData.rgb;
}
@@ -84,7 +84,7 @@ float3 SampleWeather(float3 pos, float heightFraction, float2 coverageWindOffset
float WeatherDensity(float3 weatherData)
{
const float wetness = saturate(weatherData.b);
return lerp(1.0, 1.0 - g_xFrame.VolumetricClouds.WeatherDensityAmount, wetness);
return lerp(1.0, 1.0 - GetWeather().volumetric_clouds.WeatherDensityAmount, wetness);
}
float SampleCloudDensity(float3 p, float heightFraction, float3 weatherData, float3 windOffset, float3 windDirection, float lod, bool sampleDetail)
@@ -92,10 +92,10 @@ float SampleCloudDensity(float3 p, float heightFraction, float3 weatherData, flo
#ifdef CLOUD_MODE_SIMPLE_FBM
float3 pos = p + windOffset;
pos += heightFraction * windDirection * g_xFrame.VolumetricClouds.SkewAlongWindDirection;
pos += heightFraction * windDirection * GetWeather().volumetric_clouds.SkewAlongWindDirection;
// Since the clouds have a massive size, we have to adjust scale accordingly
float noiseScale = max(g_xFrame.VolumetricClouds.TotalNoiseScale * 0.0004, 0.00001);
float noiseScale = max(GetWeather().volumetric_clouds.TotalNoiseScale * 0.0004, 0.00001);
float4 lowFrequencyNoises = texture_shapeNoise.SampleLevel(sampler_linear_wrap, pos * noiseScale, lod);
@@ -106,7 +106,7 @@ float SampleCloudDensity(float3 p, float heightFraction, float3 weatherData, flo
lowFrequencyFBM = saturate(lowFrequencyFBM);
float cloudSample = Remap(lowFrequencyNoises.r * pow(1.2 - heightFraction, 0.1), lowFrequencyFBM * g_xFrame.VolumetricClouds.ShapeNoiseMinMax.x, g_xFrame.VolumetricClouds.ShapeNoiseMinMax.y, 0.0, 1.0);
float cloudSample = Remap(lowFrequencyNoises.r * pow(1.2 - heightFraction, 0.1), lowFrequencyFBM * GetWeather().volumetric_clouds.ShapeNoiseMinMax.x, GetWeather().volumetric_clouds.ShapeNoiseMinMax.y, 0.0, 1.0);
cloudSample *= GetDensityHeightGradient(heightFraction, weatherData);
float cloudCoverage = weatherData.r;
@@ -116,25 +116,25 @@ float SampleCloudDensity(float3 p, float heightFraction, float3 weatherData, flo
#else
float3 pos = p + windOffset;
pos += heightFraction * windDirection * g_xFrame.VolumetricClouds.SkewAlongWindDirection;
pos += heightFraction * windDirection * GetWeather().volumetric_clouds.SkewAlongWindDirection;
float noiseScale = max(g_xFrame.VolumetricClouds.TotalNoiseScale * 0.0004, 0.00001);
float noiseScale = max(GetWeather().volumetric_clouds.TotalNoiseScale * 0.0004, 0.00001);
float4 lowFrequencyNoises = texture_shapeNoise.SampleLevel(sampler_linear_wrap, pos * noiseScale, lod);
float3 heightGradient = float3(SampleGradient(g_xFrame.VolumetricClouds.CloudGradientSmall, heightFraction),
SampleGradient(g_xFrame.VolumetricClouds.CloudGradientMedium, heightFraction),
SampleGradient(g_xFrame.VolumetricClouds.CloudGradientLarge, heightFraction));
float3 heightGradient = float3(SampleGradient(GetWeather().volumetric_clouds.CloudGradientSmall, heightFraction),
SampleGradient(GetWeather().volumetric_clouds.CloudGradientMedium, heightFraction),
SampleGradient(GetWeather().volumetric_clouds.CloudGradientLarge, heightFraction));
// Depending on the type, clouds with higher altitudes may recieve smaller noises
lowFrequencyNoises.gba *= heightGradient * g_xFrame.VolumetricClouds.ShapeNoiseHeightGradientAmount;
lowFrequencyNoises.gba *= heightGradient * GetWeather().volumetric_clouds.ShapeNoiseHeightGradientAmount;
float densityHeightGradient = GetDensityHeightGradient(heightFraction, weatherData);
float cloudSample = (lowFrequencyNoises.r + lowFrequencyNoises.g + lowFrequencyNoises.b + lowFrequencyNoises.a) * g_xFrame.VolumetricClouds.ShapeNoiseMultiplier * densityHeightGradient;
cloudSample = pow(abs(cloudSample), min(1.0, g_xFrame.VolumetricClouds.ShapeNoisePower * heightFraction));
float cloudSample = (lowFrequencyNoises.r + lowFrequencyNoises.g + lowFrequencyNoises.b + lowFrequencyNoises.a) * GetWeather().volumetric_clouds.ShapeNoiseMultiplier * densityHeightGradient;
cloudSample = pow(abs(cloudSample), min(1.0, GetWeather().volumetric_clouds.ShapeNoisePower * heightFraction));
cloudSample = smoothstep(g_xFrame.VolumetricClouds.ShapeNoiseMinMax.x, g_xFrame.VolumetricClouds.ShapeNoiseMinMax.y, cloudSample);
cloudSample = smoothstep(GetWeather().volumetric_clouds.ShapeNoiseMinMax.x, GetWeather().volumetric_clouds.ShapeNoiseMinMax.y, cloudSample);
// Remap function for noise against coverage, see GPU Pro 7
float cloudCoverage = weatherData.r;
@@ -146,10 +146,10 @@ float SampleCloudDensity(float3 p, float heightFraction, float3 weatherData, flo
if (cloudSample > 0.0 && sampleDetail)
{
// Apply our curl noise to erode with tiny details.
float3 curlNoise = DecodeCurlNoise(texture_curlNoise.SampleLevel(sampler_linear_wrap, p.xz * g_xFrame.VolumetricClouds.CurlScale * noiseScale, 0).rgb);
pos += float3(curlNoise.r, curlNoise.b, curlNoise.g) * heightFraction * g_xFrame.VolumetricClouds.CurlNoiseModifier;
float3 curlNoise = DecodeCurlNoise(texture_curlNoise.SampleLevel(sampler_linear_wrap, p.xz * GetWeather().volumetric_clouds.CurlScale * noiseScale, 0).rgb);
pos += float3(curlNoise.r, curlNoise.b, curlNoise.g) * heightFraction * GetWeather().volumetric_clouds.CurlNoiseModifier;
float3 highFrequencyNoises = texture_detailNoise.SampleLevel(sampler_linear_wrap, pos * g_xFrame.VolumetricClouds.DetailScale * noiseScale, lod).rgb;
float3 highFrequencyNoises = texture_detailNoise.SampleLevel(sampler_linear_wrap, pos * GetWeather().volumetric_clouds.DetailScale * noiseScale, lod).rgb;
// Create an FBM out of the high-frequency Worley Noises
float highFrequencyFBM = (highFrequencyNoises.r * 0.625) +
@@ -159,10 +159,10 @@ float SampleCloudDensity(float3 p, float heightFraction, float3 weatherData, flo
highFrequencyFBM = saturate(highFrequencyFBM);
// Dilate detail noise based on height
float highFrequenceNoiseModifier = lerp(1.0 - highFrequencyFBM, highFrequencyFBM, saturate(heightFraction * g_xFrame.VolumetricClouds.DetailNoiseHeightFraction));
float highFrequenceNoiseModifier = lerp(1.0 - highFrequencyFBM, highFrequencyFBM, saturate(heightFraction * GetWeather().volumetric_clouds.DetailNoiseHeightFraction));
// Erode with base of clouds
cloudSample = Remap(cloudSample, highFrequenceNoiseModifier * g_xFrame.VolumetricClouds.DetailNoiseModifier, 1.0, 0.0, 1.0);
cloudSample = Remap(cloudSample, highFrequenceNoiseModifier * GetWeather().volumetric_clouds.DetailNoiseModifier, 1.0, 0.0, 1.0);
}
return max(cloudSample, 0.0);
@@ -214,7 +214,7 @@ void VolumetricShadow(inout ParticipatingMedia participatingMedia, in Atmosphere
extinctionAccumulation[ms] = 0.0f;
}
const float sampleCount = g_xFrame.VolumetricClouds.ShadowSampleCount;
const float sampleCount = GetWeather().volumetric_clouds.ShadowSampleCount;
const float sampleSegmentT = 0.5f;
float lodOffset = 0.5;
@@ -230,7 +230,7 @@ void VolumetricShadow(inout ParticipatingMedia participatingMedia, in Atmosphere
float delta = t1 - t0; // 5 samples: 0.04, 0.12, 0.2, 0.28, 0.36
float t = t0 + delta * sampleSegmentT; // 5 samples: 0.02, 0.1, 0.26, 0.5, 0.82
float shadowSampleT = g_xFrame.VolumetricClouds.ShadowStepLength * t;
float shadowSampleT = GetWeather().volumetric_clouds.ShadowStepLength * t;
float3 samplePoint = worldPosition + sunDirection * shadowSampleT; // Step futher towards the light
float heightFraction = GetHeightFractionForPoint(atmosphere, samplePoint);
@@ -247,8 +247,8 @@ void VolumetricShadow(inout ParticipatingMedia participatingMedia, in Atmosphere
float shadowCloudDensity = SampleCloudDensity(samplePoint, heightFraction, weatherData, windOffset, windDirection, lod + lodOffset, true);
float3 shadowExtinction = g_xFrame.VolumetricClouds.ExtinctionCoefficient * shadowCloudDensity;
ParticipatingMedia shadowParticipatingMedia = SampleParticipatingMedia(0.0f, shadowExtinction, g_xFrame.VolumetricClouds.MultiScatteringScattering, g_xFrame.VolumetricClouds.MultiScatteringExtinction, 0.0f);
float3 shadowExtinction = GetWeather().volumetric_clouds.ExtinctionCoefficient * shadowCloudDensity;
ParticipatingMedia shadowParticipatingMedia = SampleParticipatingMedia(0.0f, shadowExtinction, GetWeather().volumetric_clouds.MultiScatteringScattering, GetWeather().volumetric_clouds.MultiScatteringExtinction, 0.0f);
[unroll]
for (ms = 0; ms < MS_COUNT; ms++)
@@ -262,7 +262,7 @@ void VolumetricShadow(inout ParticipatingMedia participatingMedia, in Atmosphere
[unroll]
for (ms = 0; ms < MS_COUNT; ms++)
{
participatingMedia.transmittanceToLight[ms] *= exp(-extinctionAccumulation[ms] * g_xFrame.VolumetricClouds.ShadowStepLength);
participatingMedia.transmittanceToLight[ms] *= exp(-extinctionAccumulation[ms] * GetWeather().volumetric_clouds.ShadowStepLength);
}
}
@@ -271,7 +271,7 @@ void VolumetricGroundContribution(inout float3 environmentLuminance, in Atmosphe
float planetRadius = atmosphere.bottomRadius * SKY_UNIT_TO_M;
float3 planetCenterWorld = atmosphere.planetCenter * SKY_UNIT_TO_M;
float cloudBottomRadius = planetRadius + g_xFrame.VolumetricClouds.CloudStartHeight;
float cloudBottomRadius = planetRadius + GetWeather().volumetric_clouds.CloudStartHeight;
float cloudSampleAltitudde = length(worldPosition - planetCenterWorld); // Distance from planet center to tracing sample
float cloudSampleHeightToBottom = cloudSampleAltitudde - cloudBottomRadius; // Distance from altitude to bottom of clouds
@@ -281,7 +281,7 @@ void VolumetricGroundContribution(inout float3 environmentLuminance, in Atmosphe
const float contributionStepLength = min(4000.0, cloudSampleHeightToBottom);
const float3 groundScatterDirection = float3(0.0, -1.0, 0.0);
const float sampleCount = g_xFrame.VolumetricClouds.GroundContributionSampleCount;
const float sampleCount = GetWeather().volumetric_clouds.GroundContributionSampleCount;
const float sampleSegmentT = 0.5f;
// Ground Contribution tracing loop, same idea as volumetric shadow
@@ -315,7 +315,7 @@ void VolumetricGroundContribution(inout float3 environmentLuminance, in Atmosphe
float contributionCloudDensity = SampleCloudDensity(samplePoint, heightFraction, weatherData, windOffset, windDirection, lod + lodOffset, true);
float3 contributionExtinction = g_xFrame.VolumetricClouds.ExtinctionCoefficient * contributionCloudDensity;
float3 contributionExtinction = GetWeather().volumetric_clouds.ExtinctionCoefficient * contributionCloudDensity;
opticalDepth += contributionExtinction * contributionStepLength * delta;
@@ -368,10 +368,10 @@ ParticipatingMediaPhase SampleParticipatingMediaPhase(float basePhase, float bas
float3 SampleAmbientLight(float heightFraction)
{
// Early experiment by adding directionality to ambient, based on: http://patapom.com/topics/Revision2013/Revision%202013%20-%20Real-time%20Volumetric%20Rendering%20Course%20Notes.pdf
//float ambientTerm = -cloudDensity * (1.0 - saturate(g_xFrame.VolumetricClouds.CloudAmbientGroundMultiplier + heightFraction));
//float ambientTerm = -cloudDensity * (1.0 - saturate(GetWeather().volumetric_clouds.CloudAmbientGroundMultiplier + heightFraction));
//float isotropicScatteringTopContribution = max(0.0, exp(ambientTerm) - ambientTerm * ExponentialIntegral(ambientTerm));
float isotropicScatteringTopContribution = saturate(g_xFrame.VolumetricClouds.CloudAmbientGroundMultiplier + heightFraction);
float isotropicScatteringTopContribution = saturate(GetWeather().volumetric_clouds.CloudAmbientGroundMultiplier + heightFraction);
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
{
@@ -390,9 +390,9 @@ void VolumetricCloudLighting(AtmosphereParameters atmosphere, float3 startPositi
inout float3 luminance, inout float3 transmittanceToView, inout float depthWeightedSum, inout float depthWeightsSum)
{
// Setup base parameters
//float3 albedo = g_xFrame.VolumetricClouds.Albedo * cloudDensity;
float3 albedo = pow(saturate(g_xFrame.VolumetricClouds.Albedo * cloudDensity * g_xFrame.VolumetricClouds.BeerPowder), g_xFrame.VolumetricClouds.BeerPowderPower); // Artistic approach
float3 extinction = g_xFrame.VolumetricClouds.ExtinctionCoefficient * cloudDensity;
//float3 albedo = GetWeather().volumetric_clouds.Albedo * cloudDensity;
float3 albedo = pow(saturate(GetWeather().volumetric_clouds.Albedo * cloudDensity * GetWeather().volumetric_clouds.BeerPowder), GetWeather().volumetric_clouds.BeerPowderPower); // Artistic approach
float3 extinction = GetWeather().volumetric_clouds.ExtinctionCoefficient * cloudDensity;
float3 atmosphereTransmittanceToLight = 1.0;
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
@@ -401,7 +401,7 @@ void VolumetricCloudLighting(AtmosphereParameters atmosphere, float3 startPositi
}
// Sample participating media with multiple scattering
ParticipatingMedia participatingMedia = SampleParticipatingMedia(albedo, extinction, g_xFrame.VolumetricClouds.MultiScatteringScattering, g_xFrame.VolumetricClouds.MultiScatteringExtinction, atmosphereTransmittanceToLight);
ParticipatingMedia participatingMedia = SampleParticipatingMedia(albedo, extinction, GetWeather().volumetric_clouds.MultiScatteringScattering, GetWeather().volumetric_clouds.MultiScatteringExtinction, atmosphereTransmittanceToLight);
// Sample environment lighting
@@ -425,8 +425,8 @@ void VolumetricCloudLighting(AtmosphereParameters atmosphere, float3 startPositi
// Sample dual lob phase with multiple scattering
float phaseFunction = DualLobPhase(g_xFrame.VolumetricClouds.PhaseG, g_xFrame.VolumetricClouds.PhaseG2, g_xFrame.VolumetricClouds.PhaseBlend, -cosTheta);
ParticipatingMediaPhase participatingMediaPhase = SampleParticipatingMediaPhase(phaseFunction, g_xFrame.VolumetricClouds.MultiScatteringEccentricity);
float phaseFunction = DualLobPhase(GetWeather().volumetric_clouds.PhaseG, GetWeather().volumetric_clouds.PhaseG2, GetWeather().volumetric_clouds.PhaseBlend, -cosTheta);
ParticipatingMediaPhase participatingMediaPhase = SampleParticipatingMediaPhase(phaseFunction, GetWeather().volumetric_clouds.MultiScatteringEccentricity);
// Update depth sampling
@@ -468,14 +468,14 @@ void RenderClouds(float3 rayOrigin, float3 rayDirection, float t, float steps, f
inout float3 luminance, inout float3 transmittanceToView, inout float depthWeightedSum, inout float depthWeightsSum)
{
// Wind animation offsets
float3 windDirection = float3(cos(g_xFrame.VolumetricClouds.WindAngle), -g_xFrame.VolumetricClouds.WindUpAmount, sin(g_xFrame.VolumetricClouds.WindAngle));
float3 windOffset = g_xFrame.VolumetricClouds.WindSpeed * g_xFrame.VolumetricClouds.AnimationMultiplier * windDirection * g_xFrame.Time;
float3 windDirection = float3(cos(GetWeather().volumetric_clouds.WindAngle), -GetWeather().volumetric_clouds.WindUpAmount, sin(GetWeather().volumetric_clouds.WindAngle));
float3 windOffset = GetWeather().volumetric_clouds.WindSpeed * GetWeather().volumetric_clouds.AnimationMultiplier * windDirection * g_xFrame.Time;
float2 coverageWindDirection = float2(cos(g_xFrame.VolumetricClouds.CoverageWindAngle), sin(g_xFrame.VolumetricClouds.CoverageWindAngle));
float2 coverageWindOffset = g_xFrame.VolumetricClouds.CoverageWindSpeed * g_xFrame.VolumetricClouds.AnimationMultiplier * coverageWindDirection * g_xFrame.Time;
float2 coverageWindDirection = float2(cos(GetWeather().volumetric_clouds.CoverageWindAngle), sin(GetWeather().volumetric_clouds.CoverageWindAngle));
float2 coverageWindOffset = GetWeather().volumetric_clouds.CoverageWindSpeed * GetWeather().volumetric_clouds.AnimationMultiplier * coverageWindDirection * g_xFrame.Time;
AtmosphereParameters atmosphere = g_xFrame.Atmosphere;
AtmosphereParameters atmosphere = GetWeather().atmosphere;
float3 sunIlluminance = GetSunColor() * GetSunEnergy();
float3 sunDirection = GetSunDirection();
@@ -485,7 +485,7 @@ void RenderClouds(float3 rayOrigin, float3 rayDirection, float t, float steps, f
// Init
float zeroDensitySampleCount = 0.0;
float stepLength = g_xFrame.VolumetricClouds.BigStepMarch;
float stepLength = GetWeather().volumetric_clouds.BigStepMarch;
float3 sampleWorldPosition = rayOrigin + rayDirection * t;
@@ -504,13 +504,13 @@ void RenderClouds(float3 rayOrigin, float3 rayDirection, float t, float steps, f
// If value is low, continue marching until we quit or hit something.
sampleWorldPosition += rayDirection * stepSize * stepLength;
zeroDensitySampleCount += 1.0;
stepLength = zeroDensitySampleCount > 10.0 ? g_xFrame.VolumetricClouds.BigStepMarch : 1.0; // If zero count has reached a high number, switch to big steps
stepLength = zeroDensitySampleCount > 10.0 ? GetWeather().volumetric_clouds.BigStepMarch : 1.0; // If zero count has reached a high number, switch to big steps
continue;
}
float rayDepth = distance(g_xCamera.CamPos, sampleWorldPosition);
float lod = step(g_xFrame.VolumetricClouds.LODDistance, rayDepth) + g_xFrame.VolumetricClouds.LODMin;
float rayDepth = distance(GetCamera().CamPos, sampleWorldPosition);
float lod = step(GetWeather().volumetric_clouds.LODDistance, rayDepth) + GetWeather().volumetric_clouds.LODMin;
float cloudDensity = saturate(SampleCloudDensity(sampleWorldPosition, heightFraction, weatherData, windOffset, windDirection, lod, true));
if (cloudDensity > 0.0)
@@ -531,7 +531,7 @@ void RenderClouds(float3 rayOrigin, float3 rayDirection, float t, float steps, f
stepSize, heightFraction, cloudDensity, weatherData, windOffset, windDirection, coverageWindOffset, lod,
luminance, transmittanceToView, depthWeightedSum, depthWeightsSum);
if (all(transmittanceToView < g_xFrame.VolumetricClouds.TransmittanceThreshold))
if (all(transmittanceToView < GetWeather().volumetric_clouds.TransmittanceThreshold))
{
break;
}
@@ -541,7 +541,7 @@ void RenderClouds(float3 rayOrigin, float3 rayDirection, float t, float steps, f
zeroDensitySampleCount += 1.0;
}
stepLength = zeroDensitySampleCount > 10.0 ? g_xFrame.VolumetricClouds.BigStepMarch : 1.0;
stepLength = zeroDensitySampleCount > 10.0 ? GetWeather().volumetric_clouds.BigStepMarch : 1.0;
sampleWorldPosition += rayDirection * stepSize * stepLength;
}
@@ -550,9 +550,9 @@ void RenderClouds(float3 rayOrigin, float3 rayDirection, float t, float steps, f
float CalculateAtmosphereBlend(float tDepth)
{
// Progressively increase alpha as clouds reaches the desired distance.
float fogDistance = saturate(tDepth * g_xFrame.VolumetricClouds.HorizonBlendAmount * 0.00001);
float fogDistance = saturate(tDepth * GetWeather().volumetric_clouds.HorizonBlendAmount * 0.00001);
float fade = pow(fogDistance, g_xFrame.VolumetricClouds.HorizonBlendPower);
float fade = pow(fogDistance, GetWeather().volumetric_clouds.HorizonBlendPower);
fade = smoothstep(0.0, 1.0, fade);
const float maxHorizonFade = 0.0;
@@ -584,10 +584,10 @@ void main(uint3 DTid : SV_DispatchThreadID)
float y = (1 - uv.y) * 2 - 1;
float2 screenPosition = float2(x, y);
float4 unprojected = mul(g_xCamera.InvVP, float4(screenPosition, 0, 1));
float4 unprojected = mul(GetCamera().InvVP, float4(screenPosition, 0, 1));
unprojected.xyz /= unprojected.w;
float3 rayOrigin = g_xCamera.CamPos;
float3 rayOrigin = GetCamera().CamPos;
float3 rayDirection = normalize(unprojected.xyz - rayOrigin);
@@ -598,13 +598,13 @@ void main(uint3 DTid : SV_DispatchThreadID)
float steps;
float stepSize;
{
AtmosphereParameters parameters = g_xFrame.Atmosphere;
AtmosphereParameters parameters = GetWeather().atmosphere;
float planetRadius = parameters.bottomRadius * SKY_UNIT_TO_M;
float3 planetCenterWorld = parameters.planetCenter * SKY_UNIT_TO_M;
const float cloudBottomRadius = planetRadius + g_xFrame.VolumetricClouds.CloudStartHeight;
const float cloudTopRadius = planetRadius + g_xFrame.VolumetricClouds.CloudStartHeight + g_xFrame.VolumetricClouds.CloudThickness;
const float cloudBottomRadius = planetRadius + GetWeather().volumetric_clouds.CloudStartHeight;
const float cloudTopRadius = planetRadius + GetWeather().volumetric_clouds.CloudStartHeight + GetWeather().volumetric_clouds.CloudThickness;
float2 tTopSolutions = RaySphereIntersect(rayOrigin, rayDirection, planetCenterWorld, cloudTopRadius);
if (tTopSolutions.x > 0.0 || tTopSolutions.y > 0.0)
@@ -641,7 +641,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
return;
}
if (tMax <= tMin || tMin > g_xFrame.VolumetricClouds.RenderDistance)
if (tMax <= tMin || tMin > GetWeather().volumetric_clouds.RenderDistance)
{
texture_render[DTid.xy] = float4(0.0, 0.0, 0.0, 0.0); // Inverted alpha
texture_cloudDepth[DTid.xy] = FLT_MAX;
@@ -655,10 +655,10 @@ void main(uint3 DTid : SV_DispatchThreadID)
tToDepthBuffer = length(depthWorldPosition - rayOrigin);
tMax = depth == 0.0 ? tMax : min(tMax, tToDepthBuffer); // Exclude skybox
const float marchingDistance = min(g_xFrame.VolumetricClouds.MaxMarchingDistance, tMax - tMin);
const float marchingDistance = min(GetWeather().volumetric_clouds.MaxMarchingDistance, tMax - tMin);
tMax = tMin + marchingDistance;
steps = g_xFrame.VolumetricClouds.MaxStepCount * saturate((tMax - tMin) * (1.0 / g_xFrame.VolumetricClouds.InverseDistanceStepCount));
steps = GetWeather().volumetric_clouds.MaxStepCount * saturate((tMax - tMin) * (1.0 / GetWeather().volumetric_clouds.InverseDistanceStepCount));
stepSize = (tMax - tMin) / steps;
//float offset = dither(DTid.xy + GetTemporalAASampleRotation());
@@ -666,7 +666,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
//float offset = InterleavedGradientNoise(DTid.xy, g_xFrame.FrameCount % 16);
//t = tMin + 0.5 * stepSize;
t = tMin + offset * stepSize * g_xFrame.VolumetricClouds.BigStepMarch; // offset avg = 0.5
t = tMin + offset * stepSize * GetWeather().volumetric_clouds.BigStepMarch; // offset avg = 0.5
}
@@ -683,7 +683,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
//float3 absoluteWorldPosition = rayOrigin + rayDirection * tDepth; // Could be used for other effects later that require worldPosition
float approxTransmittance = dot(transmittanceToView.rgb, 1.0 / 3.0);
float grayScaleTransmittance = approxTransmittance < g_xFrame.VolumetricClouds.TransmittanceThreshold ? 0.0 : approxTransmittance;
float grayScaleTransmittance = approxTransmittance < GetWeather().volumetric_clouds.TransmittanceThreshold ? 0.0 : approxTransmittance;
float4 color = float4(luminance, grayScaleTransmittance);
@@ -37,13 +37,13 @@ void main(uint3 DTid : SV_DispatchThreadID)
// Calculate screen dependant motion vector
float4 prevPos = float4(uv * 2.0 - 1.0, 1.0, 1.0);
prevPos = mul(g_xCamera.InvP, prevPos);
prevPos = mul(GetCamera().InvP, prevPos);
prevPos = prevPos / prevPos.w;
prevPos.xyz = mul((float3x3)g_xCamera.InvV, prevPos.xyz);
prevPos.xyz = mul((float3x3)g_xCamera.PrevV, prevPos.xyz);
prevPos.xyz = mul((float3x3)GetCamera().InvV, prevPos.xyz);
prevPos.xyz = mul((float3x3)GetCamera().PrevV, prevPos.xyz);
float4 reproj = mul(g_xCamera.Proj, prevPos);
float4 reproj = mul(GetCamera().Proj, prevPos);
reproj /= reproj.w;
float2 prevUV = reproj.xy * 0.5 + 0.5;
@@ -55,14 +55,14 @@ void main(uint3 DTid : SV_DispatchThreadID)
float2 screenPosition = float2(x, y);
float currentCloudLinearDepth = cloud_depth_current.SampleLevel(sampler_point_clamp, uv, 0).x;
float currentCloudDepth = getInverseLinearDepth(currentCloudLinearDepth, g_xCamera.ZNearP, g_xCamera.ZFarP);
float currentCloudDepth = getInverseLinearDepth(currentCloudLinearDepth, GetCamera().ZNearP, GetCamera().ZFarP);
float4 thisClip = float4(screenPosition, currentCloudDepth, 1.0);
float4 prevClip = mul(g_xCamera.InvVP, thisClip);
prevClip = mul(g_xCamera.PrevVP, prevClip);
float4 prevClip = mul(GetCamera().InvVP, thisClip);
prevClip = mul(GetCamera().PrevVP, prevClip);
//float4 prevClip = mul(g_xCamera.PrevVP, worldPosition);
//float4 prevClip = mul(GetCamera().PrevVP, worldPosition);
float2 prevScreen = prevClip.xy / prevClip.w;
float2 screenVelocity = screenPosition - prevScreen;
@@ -122,7 +122,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
float depth = texture_depth.SampleLevel(sampler_point_clamp, uv, 1).r; // Half res
float3 depthWorldPosition = reconstructPosition(uv, depth);
float tToDepthBuffer = length(depthWorldPosition - g_xCamera.CamPos);
float tToDepthBuffer = length(depthWorldPosition - GetCamera().CamPos);
if (abs(tToDepthBuffer - previousDepthResult.y) > tToDepthBuffer * 0.1)
{
@@ -86,7 +86,7 @@ inline void ResolverAABB(Texture2D<float4> currentColor, SamplerState currentSam
float depth = texture_depth.SampleLevel(sampler_point_clamp, uv, 1).r; // Half res
float3 depthWorldPosition = reconstructPosition(uv, depth);
float tToDepthBuffer = length(depthWorldPosition - g_xCamera.CamPos);
float tToDepthBuffer = length(depthWorldPosition - GetCamera().CamPos);
float validSampleCount = 1.0;
@@ -143,13 +143,13 @@ void main(uint3 DTid : SV_DispatchThreadID)
// Calculate screen dependant motion vector
float4 prevPos = float4(uv * 2.0 - 1.0, 1.0, 1.0);
prevPos = mul(g_xCamera.InvP, prevPos);
prevPos = mul(GetCamera().InvP, prevPos);
prevPos = prevPos / prevPos.w;
prevPos.xyz = mul((float3x3)g_xCamera.InvV, prevPos.xyz);
prevPos.xyz = mul((float3x3)g_xCamera.PrevV, prevPos.xyz);
prevPos.xyz = mul((float3x3)GetCamera().InvV, prevPos.xyz);
prevPos.xyz = mul((float3x3)GetCamera().PrevV, prevPos.xyz);
float4 reproj = mul(g_xCamera.Proj, prevPos);
float4 reproj = mul(GetCamera().Proj, prevPos);
reproj /= reproj.w;
float2 prevUV = reproj.xy * 0.5 + 0.5;
@@ -163,14 +163,14 @@ void main(uint3 DTid : SV_DispatchThreadID)
float2 screenPosition = float2(x, y);
float currentCloudLinearDepth = cloud_reproject_depth[DTid.xy].x;
float currentCloudDepth = getInverseLinearDepth(currentCloudLinearDepth, g_xCamera.ZNearP, g_xCamera.ZFarP);
float currentCloudDepth = getInverseLinearDepth(currentCloudLinearDepth, GetCamera().ZNearP, GetCamera().ZFarP);
float4 thisClip = float4(screenPosition, currentCloudDepth, 1.0);
float4 prevClip = mul(g_xCamera.InvVP, thisClip);
prevClip = mul(g_xCamera.PrevVP, prevClip);
float4 prevClip = mul(GetCamera().InvVP, thisClip);
prevClip = mul(GetCamera().PrevVP, prevClip);
//float4 prevClip = mul(g_xCamera.PrevVP, worldPosition);
//float4 prevClip = mul(GetCamera().PrevVP, worldPosition);
float2 prevScreen = prevClip.xy / prevClip.w;
float2 screenVelocity = screenPosition - prevScreen;
@@ -15,7 +15,7 @@ float4 main(VertexToPixel input) : SV_TARGET
float2 ScreenCoord = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
float depth = max(input.pos.z, texture_depth.SampleLevel(sampler_point_clamp, ScreenCoord, 2));
float3 P = reconstructPosition(ScreenCoord, depth);
float3 V = g_xCamera.CamPos - P;
float3 V = GetCamera().CamPos - P;
float cameraDistance = length(V);
V /= cameraDistance;
@@ -25,7 +25,7 @@ float4 main(VertexToPixel input) : SV_TARGET
const float3 L = light.GetDirection();
const float scattering = ComputeScattering(saturate(dot(L, -V)));
float3 rayEnd = g_xCamera.CamPos;
float3 rayEnd = GetCamera().CamPos;
const uint sampleCount = 16;
const float stepSize = length(P - rayEnd) / sampleCount;
@@ -71,7 +71,7 @@ float4 main(VertexToPixel input) : SV_TARGET
float3 atmosphereTransmittance = 1;
if (g_xFrame.Options & OPTION_BIT_REALISTIC_SKY)
{
atmosphereTransmittance = GetAtmosphericLightTransmittance(g_xFrame.Atmosphere, P, L, texture_transmittancelut);
atmosphereTransmittance = GetAtmosphericLightTransmittance(GetWeather().atmosphere, P, L, texture_transmittancelut);
}
return max(0, float4(accumulation * light.GetColor().rgb * light.GetEnergy() * atmosphereTransmittance, 1));
@@ -9,14 +9,14 @@ float4 main(VertexToPixel input) : SV_TARGET
float2 ScreenCoord = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
float depth = max(input.pos.z, texture_depth.SampleLevel(sampler_point_clamp, ScreenCoord, 2));
float3 P = reconstructPosition(ScreenCoord, depth);
float3 V = g_xCamera.CamPos - P;
float3 V = GetCamera().CamPos - P;
float cameraDistance = length(V);
V /= cameraDistance;
float marchedDistance = 0;
float3 accumulation = 0;
float3 rayEnd = g_xCamera.CamPos;
float3 rayEnd = GetCamera().CamPos;
if (length(rayEnd - light.position) > light.GetRange())
{
// if we are outside the light volume, then rayEnd will be the traced sphere frontface:
@@ -9,14 +9,14 @@ float4 main(VertexToPixel input) : SV_TARGET
float2 ScreenCoord = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
float depth = max(input.pos.z, texture_depth.SampleLevel(sampler_point_clamp, ScreenCoord, 2));
float3 P = reconstructPosition(ScreenCoord, depth);
float3 V = g_xCamera.CamPos - P;
float3 V = GetCamera().CamPos - P;
float cameraDistance = length(V);
V /= cameraDistance;
float marchedDistance = 0;
float3 accumulation = 0;
float3 rayEnd = g_xCamera.CamPos;
float3 rayEnd = GetCamera().CamPos;
// todo: rayEnd should be clamped to the closest cone intersection point when camera is outside volume
const uint sampleCount = 16;
+20 -26
View File
@@ -32,19 +32,6 @@ void wiGPUBVH::Update(const wiScene::Scene& scene)
{
GraphicsDevice* device = wiRenderer::GetDevice();
if (!primitiveCounterBuffer.IsValid())
{
GPUBufferDesc desc;
desc.BindFlags = BIND_SHADER_RESOURCE;
desc.Stride = sizeof(uint);
desc.Size = desc.Stride;
desc.Format = FORMAT_UNKNOWN;
desc.MiscFlags = RESOURCE_MISC_BUFFER_RAW;
desc.Usage = USAGE_DEFAULT;
device->CreateBuffer(&desc, nullptr, &primitiveCounterBuffer);
device->SetName(&primitiveCounterBuffer, "primitiveCounterBuffer");
}
// Pre-gather scene properties:
uint totalTriangles = 0;
for (size_t i = 0; i < scene.objects.GetCount(); ++i)
@@ -68,6 +55,24 @@ void wiGPUBVH::Update(const wiScene::Scene& scene)
}
}
if (totalTriangles > 0 && !primitiveCounterBuffer.IsValid())
{
GPUBufferDesc desc;
desc.BindFlags = BIND_SHADER_RESOURCE;
desc.Stride = sizeof(uint);
desc.Size = desc.Stride;
desc.Format = FORMAT_UNKNOWN;
desc.MiscFlags = RESOURCE_MISC_BUFFER_RAW;
desc.Usage = USAGE_DEFAULT;
device->CreateBuffer(&desc, nullptr, &primitiveCounterBuffer);
device->SetName(&primitiveCounterBuffer, "primitiveCounterBuffer");
}
if (totalTriangles == 0)
{
primitiveCounterBuffer = {};
}
if (totalTriangles > primitiveCapacity)
{
primitiveCapacity = std::max(2u, totalTriangles);
@@ -78,7 +83,7 @@ void wiGPUBVH::Update(const wiScene::Scene& scene)
desc.Stride = sizeof(BVHNode);
desc.Size = desc.Stride * primitiveCapacity * 2;
desc.Format = FORMAT_UNKNOWN;
desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
desc.MiscFlags = RESOURCE_MISC_BUFFER_RAW;
desc.Usage = USAGE_DEFAULT;
device->CreateBuffer(&desc, nullptr, &bvhNodeBuffer);
device->SetName(&bvhNodeBuffer, "BVHNodeBuffer");
@@ -114,7 +119,7 @@ void wiGPUBVH::Update(const wiScene::Scene& scene)
desc.Stride = sizeof(BVHPrimitive);
desc.Size = desc.Stride * primitiveCapacity;
desc.Format = FORMAT_UNKNOWN;
desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
desc.MiscFlags = RESOURCE_MISC_BUFFER_RAW;
desc.Usage = USAGE_DEFAULT;
device->CreateBuffer(&desc, nullptr, &primitiveBuffer);
device->SetName(&primitiveBuffer, "primitiveBuffer");
@@ -371,17 +376,6 @@ void wiGPUBVH::Build(const Scene& scene, CommandList cmd) const
#endif // BVH_VALIDATE
}
void wiGPUBVH::Bind(CommandList cmd) const
{
GraphicsDevice* device = wiRenderer::GetDevice();
const GPUResource* res[] = {
&primitiveCounterBuffer,
&primitiveBuffer,
&bvhNodeBuffer,
};
device->BindResources(res, TEXSLOT_BVH_COUNTER, arraysize(res), cmd);
}
void wiGPUBVH::Clear()
{
+2 -5
View File
@@ -10,9 +10,8 @@
#include <unordered_map>
#include <unordered_set>
class wiGPUBVH
struct wiGPUBVH
{
private:
// Scene BVH intersection resources:
wiGraphics::GPUBuffer bvhNodeBuffer;
wiGraphics::GPUBuffer bvhParentBuffer;
@@ -22,14 +21,12 @@ private:
wiGraphics::GPUBuffer primitiveBuffer;
wiGraphics::GPUBuffer primitiveMortonBuffer;
uint32_t primitiveCapacity = 0;
bool IsValid() const { return primitiveCounterBuffer.IsValid(); }
public:
void Update(const wiScene::Scene& scene);
void Build(const wiScene::Scene& scene, wiGraphics::CommandList cmd) const;
void Bind(wiGraphics::CommandList cmd) const;
void Clear();
static void Initialize();
};
+1
View File
@@ -2081,6 +2081,7 @@ using namespace DX12_Internal;
assert(pipeline != nullptr);
GetCommandList(cmd)->SetPipelineState(pipeline);
dirty_pso[cmd] = false;
if (prev_pt[cmd] != internal_state->primitiveTopology)
{
+4 -3
View File
@@ -1816,6 +1816,7 @@ using namespace Vulkan_Internal;
assert(pipeline != VK_NULL_HANDLE);
vkCmdBindPipeline(GetCommandList(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
dirty_pso[cmd] = false;
}
void GraphicsDevice_Vulkan::predraw(CommandList cmd)
@@ -4960,8 +4961,8 @@ using namespace Vulkan_Internal;
if (pDesc->type == RaytracingAccelerationStructureDesc::TOPLEVEL)
{
int index = allocationhandler->bindlessAccelerationStructures.allocate();
if (index >= 0)
internal_state->index = allocationhandler->bindlessAccelerationStructures.allocate();
if (internal_state->index >= 0)
{
VkWriteDescriptorSetAccelerationStructureKHR acc = {};
acc.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
@@ -4972,7 +4973,7 @@ using namespace Vulkan_Internal;
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
write.dstBinding = 0;
write.dstArrayElement = index;
write.dstArrayElement = internal_state->index;
write.descriptorCount = 1;
write.dstSet = allocationhandler->bindlessAccelerationStructures.descriptorSet;
write.pNext = &acc;
File diff suppressed because it is too large Load Diff
+4 -39
View File
@@ -158,8 +158,6 @@ namespace wiRenderer
wiScene::Scene& scene,
const Visibility& vis,
FrameCB& frameCB,
XMUINT2 internalResolution,
const wiCanvas& canvas,
float dt
);
// Updates the GPU state according to the previously called UpdatePerFrameData()
@@ -172,7 +170,6 @@ namespace wiRenderer
// Updates those GPU states that can be async
void UpdateRenderDataAsync(
const Visibility& vis,
const FrameCB& frameCB,
wiGraphics::CommandList cmd
);
@@ -183,7 +180,7 @@ namespace wiRenderer
// 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 UpdateCameraCB(
void BindCameraCB(
const wiScene::CameraComponent& camera,
const wiScene::CameraComponent& camera_previous,
const wiScene::CameraComponent& camera_reflection,
@@ -200,7 +197,7 @@ namespace wiRenderer
DRAWSCENE_HAIRPARTICLE = 1 << 4,
};
// Draw the world from a camera. You must call UpdateCameraCB() at least once in this frame prior to this
// Draw the world from a camera. You must call BindCameraCB() at least once in this frame prior to this
void DrawScene(
const Visibility& vis,
RENDERPASS renderPass,
@@ -246,13 +243,11 @@ namespace wiRenderer
// Draw volumetric light scattering effects
void DrawVolumeLights(
const Visibility& vis,
const wiGraphics::Texture& depthbuffer,
wiGraphics::CommandList cmd
);
// Draw Lens Flares for lights that have them enabled
void DrawLensFlares(
const Visibility& vis,
const wiGraphics::Texture& depthbuffer,
wiGraphics::CommandList cmd,
const wiGraphics::Texture* texture_directional_occlusion = nullptr
);
@@ -270,6 +265,7 @@ namespace wiRenderer
struct TiledLightResources
{
XMUINT3 tileCount = {};
wiGraphics::GPUBuffer tileFrustums; // entity culling frustums
wiGraphics::GPUBuffer entityTiles_Opaque; // culled entity indices (for opaque pass)
wiGraphics::GPUBuffer entityTiles_Transparent; // culled entity indices (for transparent pass)
@@ -278,7 +274,6 @@ namespace wiRenderer
// Compute light grid tiles
void ComputeTiledLightCulling(
const TiledLightResources& res,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& debugUAV,
wiGraphics::CommandList cmd
);
@@ -313,8 +308,6 @@ namespace wiRenderer
);
void ComputeShadingRateClassification(
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& output,
const wiGraphics::Texture& debugUAV,
wiGraphics::CommandList cmd
@@ -337,8 +330,6 @@ namespace wiRenderer
void SurfelGI_Coverage(
const SurfelGIResources& res,
const wiScene::Scene& scene,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& debugUAV,
wiGraphics::CommandList cmd
);
@@ -375,9 +366,8 @@ namespace wiRenderer
void CreateSSAOResources(SSAOResources& res, XMUINT2 resolution);
void Postprocess_SSAO(
const SSAOResources& res,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& output,
const wiGraphics::Texture& lineardepth,
wiGraphics::CommandList cmd,
float range = 1.0f,
uint32_t samplecount = 16,
@@ -436,10 +426,6 @@ namespace wiRenderer
void Postprocess_RTAO(
const RTAOResources& res,
const wiScene::Scene& scene,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& depth_history,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd,
float range = 1.0f,
@@ -454,9 +440,6 @@ namespace wiRenderer
void Postprocess_RTReflection(
const RTReflectionResources& res,
const wiScene::Scene& scene,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& depth_history,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd,
float range = 1000.0f
@@ -471,10 +454,6 @@ namespace wiRenderer
void Postprocess_SSR(
const SSRResources& res,
const wiGraphics::Texture& input,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& depth_history,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd
);
@@ -495,11 +474,7 @@ namespace wiRenderer
void Postprocess_RTShadow(
const RTShadowResources& res,
const wiScene::Scene& scene,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& depth_history,
const wiGraphics::GPUBuffer& entityTiles_Opaque,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd
);
@@ -510,10 +485,7 @@ namespace wiRenderer
void CreateScreenSpaceShadowResources(ScreenSpaceShadowResources& res, XMUINT2 resolution);
void Postprocess_ScreenSpaceShadow(
const ScreenSpaceShadowResources& res,
const wiGraphics::Texture& depthbuffer,
const wiGraphics::Texture& lineardepth,
const wiGraphics::GPUBuffer& entityTiles_Opaque,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd,
float range = 1,
@@ -548,7 +520,6 @@ namespace wiRenderer
const DepthOfFieldResources& res,
const wiGraphics::Texture& input,
const wiGraphics::Texture& output,
const wiGraphics::Texture& lineardepth,
wiGraphics::CommandList cmd,
float coc_scale = 10,
float max_coc = 18
@@ -576,8 +547,6 @@ namespace wiRenderer
void Postprocess_MotionBlur(
const MotionBlurResources& res,
const wiGraphics::Texture& input,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd,
float strength = 100.0f
@@ -594,7 +563,6 @@ namespace wiRenderer
void CreateVolumetricCloudResources(VolumetricCloudResources& res, XMUINT2 resolution);
void Postprocess_VolumetricClouds(
const VolumetricCloudResources& res,
const wiGraphics::Texture& depthbuffer,
wiGraphics::CommandList cmd
);
void Postprocess_FXAA(
@@ -605,9 +573,6 @@ namespace wiRenderer
void Postprocess_TemporalAA(
const wiGraphics::Texture& input_current,
const wiGraphics::Texture& input_history,
const wiGraphics::Texture& lineardepth,
const wiGraphics::Texture& depth_history,
const wiGraphics::Texture gbuffer[GBUFFER_COUNT],
const wiGraphics::Texture& output,
wiGraphics::CommandList cmd
);
+42 -3
View File
@@ -1660,6 +1660,11 @@ namespace wiScene
}
}
if (!device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING) && IsAccelerationStructureUpdateRequested())
{
BVH.Update(*this);
}
// Update water ripples:
for (size_t i = 0; i < waterRipples.size(); ++i)
{
@@ -1742,13 +1747,12 @@ namespace wiScene
std::swap(surfelMomentsTexture[0], surfelMomentsTexture[1]);
}
// Bindless scene resources:
// Shader scene resources:
shaderscene.instancebuffer = device->GetDescriptorIndex(&instanceBuffer, SRV);
shaderscene.meshbuffer = device->GetDescriptorIndex(&meshBuffer, SRV);
shaderscene.materialbuffer = device->GetDescriptorIndex(&materialBuffer, SRV);
shaderscene.TLAS = device->GetDescriptorIndex(&TLAS, SRV);
shaderscene.envmaparray = device->GetDescriptorIndex(&envmapArray, SRV);
if (weather.skyMap == nullptr)
{
shaderscene.globalenvmap = -1;
@@ -1757,6 +1761,41 @@ namespace wiScene
{
shaderscene.globalenvmap = device->GetDescriptorIndex(&weather.skyMap->texture, SRV);
}
shaderscene.TLAS = device->GetDescriptorIndex(&TLAS, SRV);
shaderscene.BVH_counter = device->GetDescriptorIndex(&BVH.primitiveCounterBuffer, SRV);
shaderscene.BVH_nodes = device->GetDescriptorIndex(&BVH.bvhNodeBuffer, SRV);
shaderscene.BVH_primitives = device->GetDescriptorIndex(&BVH.primitiveBuffer, SRV);
shaderscene.aabb_min = bounds.getMin();
shaderscene.aabb_max = bounds.getMax();
shaderscene.aabb_extents.x = abs(shaderscene.aabb_max.x - shaderscene.aabb_min.x);
shaderscene.aabb_extents.y = abs(shaderscene.aabb_max.y - shaderscene.aabb_min.y);
shaderscene.aabb_extents.z = abs(shaderscene.aabb_max.z - shaderscene.aabb_min.z);
shaderscene.aabb_extents_rcp.x = 1.0f / shaderscene.aabb_extents.x;
shaderscene.aabb_extents_rcp.y = 1.0f / shaderscene.aabb_extents.y;
shaderscene.aabb_extents_rcp.z = 1.0f / shaderscene.aabb_extents.z;
shaderscene.weather.sun_color = weather.sunColor;
shaderscene.weather.sun_direction = weather.sunDirection;
shaderscene.weather.sun_energy = weather.sunEnergy;
shaderscene.weather.ambient = weather.ambient;
shaderscene.weather.cloudiness = weather.cloudiness;
shaderscene.weather.cloud_scale = weather.cloudScale;
shaderscene.weather.cloud_speed = weather.cloudSpeed;
shaderscene.weather.fog.start = weather.fogStart;
shaderscene.weather.fog.end = weather.fogEnd;
shaderscene.weather.fog.height_start = weather.fogHeightStart;
shaderscene.weather.fog.height_end = weather.fogHeightEnd;
shaderscene.weather.fog.height_sky = weather.fogHeightSky;
shaderscene.weather.horizon = weather.horizon;
shaderscene.weather.zenith = weather.zenith;
shaderscene.weather.sky_exposure = weather.skyExposure;
shaderscene.weather.wind.speed = weather.windSpeed;
shaderscene.weather.wind.randomness = weather.windRandomness;
shaderscene.weather.wind.wavesize = weather.windWaveSize;
shaderscene.weather.wind.direction = weather.windDirection;
shaderscene.weather.atmosphere = weather.atmosphereParameters;
shaderscene.weather.volumetric_clouds = weather.volumetricCloudParameters;
}
void Scene::Clear()
{
+14
View File
@@ -889,6 +889,20 @@ namespace wiScene
XMFLOAT4X4 InvView, InvProjection, InvVP;
XMFLOAT2 jitter;
XMFLOAT4 clipPlane = XMFLOAT4(0, 0, 0, 0); // default: no clip plane
wiCanvas canvas;
int texture_depth_index = -1;
int texture_lineardepth_index = -1;
int texture_gbuffer0_index = -1;
int texture_gbuffer1_index = -1;
int texture_reflection_index = -1;
int texture_refraction_index = -1;
int texture_waterriples_index = -1;
int texture_ao_index = -1;
int texture_ssr_index = -1;
int texture_rtshadow_index = -1;
int texture_surfelgi_index = -1;
int buffer_entitytiles_opaque_index = -1;
int buffer_entitytiles_transparent_index = -1;
void CreatePerspective(float newWidth, float newHeight, float newNear, float newFar, float newFOV = XM_PI / 3.0f);
void UpdateCamera();
+2 -2
View File
@@ -7,9 +7,9 @@ namespace wiVersion
// main engine core
const int major = 0;
// minor features, major updates, breaking compatibility changes
const int minor = 57;
const int minor = 58;
// minor bug fixes, alterations, refactors, updates
const int revision = 43;
const int revision = 0;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);