improvements for multiple renderpath usage

This commit is contained in:
Turánszki János
2024-02-13 09:05:24 +01:00
parent a4ac425433
commit a73f92be86
6 changed files with 118 additions and 114 deletions
+18 -15
View File
@@ -790,7 +790,7 @@ namespace wi
);
}
if (wi::renderer::GetDDGIEnabled())
if (wi::renderer::GetDDGIEnabled() && getSceneUpdateEnabled())
{
wi::renderer::DDGI(
*scene,
@@ -1032,7 +1032,7 @@ namespace wi
});
}
if (wi::renderer::GetVXGIEnabled())
if (wi::renderer::GetVXGIEnabled() && getSceneUpdateEnabled())
{
cmd = device->BeginCommandList();
wi::jobsystem::Execute(ctx, [cmd, this](wi::jobsystem::JobArgs args) {
@@ -1041,19 +1041,22 @@ namespace wi
}
// Updating textures:
cmd = device->BeginCommandList();
device->WaitCommandList(cmd, cmd_prepareframe_async);
wi::jobsystem::Execute(ctx, [cmd, this](wi::jobsystem::JobArgs args) {
wi::renderer::BindCommonResources(cmd);
wi::renderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
cmd
);
wi::renderer::RefreshLightmaps(*scene, cmd);
wi::renderer::RefreshEnvProbes(visibility_main, cmd);
});
if (getSceneUpdateEnabled())
{
cmd = device->BeginCommandList();
device->WaitCommandList(cmd, cmd_prepareframe_async);
wi::jobsystem::Execute(ctx, [cmd, this](wi::jobsystem::JobArgs args) {
wi::renderer::BindCommonResources(cmd);
wi::renderer::BindCameraCB(
*camera,
camera_previous,
camera_reflection,
cmd
);
wi::renderer::RefreshLightmaps(*scene, cmd);
wi::renderer::RefreshEnvProbes(visibility_main, cmd);
});
}
if (visibility_main.IsRequestedPlanarReflections())
{
+75 -96
View File
@@ -6,7 +6,6 @@
#include "wiHelper.h"
#include "wiTextureHelper.h"
#include "wiEnums.h"
#include "wiRectPacker.h"
#include "wiBacklog.h"
#include "wiProfiler.h"
#include "wiOcean.h"
@@ -2476,7 +2475,7 @@ inline void CreateSpotLightShadowCam(const LightComponent& light, SHCAM& shcam)
{
shcam.init(light.position, light.rotation, 0.1f, light.GetRange(), light.outerConeAngle * 2);
}
inline void CreateDirLightShadowCams(const LightComponent& light, CameraComponent camera, SHCAM* shcams, size_t shcam_count)
inline void CreateDirLightShadowCams(const LightComponent& light, CameraComponent camera, SHCAM* shcams, size_t shcam_count, const wi::rectpacker::Rect& shadow_rect)
{
// remove camera jittering
camera.jitter = XMFLOAT2(0, 0);
@@ -2542,7 +2541,7 @@ inline void CreateDirLightShadowCams(const LightComponent& light, CameraComponen
// Snap cascade to texel grid:
const XMVECTOR extent = XMVectorSubtract(vMax, vMin);
const XMVECTOR texelSize = extent / float(light.shadow_rect.w);
const XMVECTOR texelSize = extent / float(shadow_rect.w);
vMin = XMVectorFloor(vMin / texelSize) * texelSize;
vMax = XMVectorFloor(vMax / texelSize) * texelSize;
center = (vMin + vMax) * 0.5f;
@@ -3011,6 +3010,8 @@ void UpdateVisibility(Visibility& vis)
// Cull lights:
const uint32_t light_loop = (uint32_t)std::min(vis.scene->aabb_lights.size(), vis.scene->lights.GetCount());
vis.visibleLights.resize(light_loop);
vis.visibleLightShadowRects.clear();
vis.visibleLightShadowRects.resize(light_loop);
wi::jobsystem::Dispatch(ctx, light_loop, groupSize, [&](wi::jobsystem::JobArgs args) {
// Setup stream compaction:
@@ -3262,56 +3263,26 @@ void UpdateVisibility(Visibility& vis)
}
}
wi::profiler::EndRange(range); // Frustum Culling
}
void UpdatePerFrameData(
Scene& scene,
const Visibility& vis,
FrameCB& frameCB,
float dt
)
{
// Update Voxelization parameters:
if (scene.objects.GetCount() > 0)
{
Scene::VXGI::ClipMap& clipmap = scene.vxgi.clipmaps[scene.vxgi.clipmap_to_update];
clipmap.voxelsize = scene.vxgi.clipmaps[0].voxelsize * (1u << scene.vxgi.clipmap_to_update);
const float texelSize = clipmap.voxelsize * 2;
XMFLOAT3 center = XMFLOAT3(std::floor(vis.camera->Eye.x / texelSize) * texelSize, std::floor(vis.camera->Eye.y / texelSize) * texelSize, std::floor(vis.camera->Eye.z / texelSize) * texelSize);
clipmap.offsetfromPrevFrame.x = int((clipmap.center.x - center.x) / texelSize);
clipmap.offsetfromPrevFrame.y = -int((clipmap.center.y - center.y) / texelSize);
clipmap.offsetfromPrevFrame.z = int((clipmap.center.z - center.z) / texelSize);
clipmap.center = center;
XMFLOAT3 extents = XMFLOAT3(scene.vxgi.res * clipmap.voxelsize, scene.vxgi.res * clipmap.voxelsize, scene.vxgi.res * clipmap.voxelsize);
if (extents.x != clipmap.extents.x || extents.y != clipmap.extents.y || extents.z != clipmap.extents.z)
{
scene.vxgi.pre_clear = true;
}
clipmap.extents = extents;
}
// Shadow atlas packing:
if (!vis.visibleLights.empty() || vis.scene->weather.rain_amount > 0)
if ((vis.flags & Visibility::ALLOW_SHADOW_ATLAS_PACKING) && !vis.visibleLights.empty() || vis.scene->weather.rain_amount > 0)
{
auto range = wi::profiler::BeginRangeCPU("Shadowmap packing");
static thread_local wi::rectpacker::State packer;
float iterative_scaling = 1;
while (iterative_scaling > 0.03f)
{
packer.clear();
if(vis.scene->weather.rain_amount > 0)
vis.shadow_packer.clear();
if (vis.scene->weather.rain_amount > 0)
{
// Rain blocker:
wi::rectpacker::Rect rect = {};
rect.id = -1;
rect.w = rect.h = 128;
packer.add_rect(rect);
vis.shadow_packer.add_rect(rect);
}
for (uint32_t lightIndex : vis.visibleLights)
{
LightComponent& light = scene.lights[lightIndex];
light.shadow_rect = {};
const LightComponent& light = vis.scene->lights[lightIndex];
if (!light.IsCastingShadow() || light.IsStatic())
continue;
@@ -3362,56 +3333,53 @@ void UpdatePerFrameData(
}
if (rect.w > 8 && rect.h > 8)
{
packer.add_rect(rect);
vis.shadow_packer.add_rect(rect);
}
}
if (!packer.rects.empty())
if (!vis.shadow_packer.rects.empty())
{
if (packer.pack(8192))
if (vis.shadow_packer.pack(8192))
{
for (auto& rect : packer.rects)
for (auto& rect : vis.shadow_packer.rects)
{
if (rect.id == -1)
{
// Rain blocker:
if (rect.was_packed)
{
scene.rain_blocker_dummy_light.shadow_rect = rect;
vis.rain_blocker_shadow_rect = rect;
}
else
{
scene.rain_blocker_dummy_light.shadow_rect = {};
vis.rain_blocker_shadow_rect = {};
}
continue;
}
uint32_t lightIndex = uint32_t(rect.id);
LightComponent& light = scene.lights[lightIndex];
wi::rectpacker::Rect& lightrect = vis.visibleLightShadowRects[lightIndex];
const LightComponent& light = vis.scene->lights[lightIndex];
if (rect.was_packed)
{
light.shadow_rect = rect;
lightrect = rect;
// Remove slice multipliers from rect:
switch (light.GetType())
{
case LightComponent::DIRECTIONAL:
light.shadow_rect.w /= int(light.cascade_distances.size());
lightrect.w /= int(light.cascade_distances.size());
break;
case LightComponent::POINT:
light.shadow_rect.w /= 6;
lightrect.w /= 6;
break;
}
}
else
{
light.direction = {};
}
}
if ((int)shadowMapAtlas.desc.width < packer.width || (int)shadowMapAtlas.desc.height < packer.height)
if ((int)shadowMapAtlas.desc.width < vis.shadow_packer.width || (int)shadowMapAtlas.desc.height < vis.shadow_packer.height)
{
TextureDesc desc;
desc.width = uint32_t(packer.width);
desc.height = uint32_t(packer.height);
desc.width = uint32_t(vis.shadow_packer.width);
desc.height = uint32_t(vis.shadow_packer.height);
desc.format = format_depthbuffer_shadowmap;
desc.bind_flags = BindFlag::DEPTH_STENCIL | BindFlag::SHADER_RESOURCE;
desc.layout = ResourceState::SHADER_RESOURCE;
@@ -3430,7 +3398,7 @@ void UpdatePerFrameData(
device->SetName(&shadowMapAtlas_Transparent, "shadowMapAtlas_Transparent");
}
break;
}
else
@@ -3446,6 +3414,15 @@ void UpdatePerFrameData(
wi::profiler::EndRange(range);
}
wi::profiler::EndRange(range); // Frustum Culling
}
void UpdatePerFrameData(
Scene& scene,
const Visibility& vis,
FrameCB& frameCB,
float dt
)
{
// Calculate volumetric cloud shadow data:
if (vis.scene->weather.IsVolumetricClouds() && vis.scene->weather.IsVolumetricCloudsCastShadow())
{
@@ -3591,13 +3568,13 @@ void UpdatePerFrameData(
frameCB.rain_blocker_matrix_prev = frameCB.rain_blocker_matrix;
frameCB.rain_blocker_matrix_inverse_prev = frameCB.rain_blocker_matrix_inverse;
frameCB.rain_blocker_mad = XMFLOAT4(
float(scene.rain_blocker_dummy_light.shadow_rect.w) / float(shadowMapAtlas.desc.width),
float(scene.rain_blocker_dummy_light.shadow_rect.h) / float(shadowMapAtlas.desc.height),
float(scene.rain_blocker_dummy_light.shadow_rect.x) / float(shadowMapAtlas.desc.width),
float(scene.rain_blocker_dummy_light.shadow_rect.y) / float(shadowMapAtlas.desc.height)
float(vis.rain_blocker_shadow_rect.w) / float(shadowMapAtlas.desc.width),
float(vis.rain_blocker_shadow_rect.h) / float(shadowMapAtlas.desc.height),
float(vis.rain_blocker_shadow_rect.x) / float(shadowMapAtlas.desc.width),
float(vis.rain_blocker_shadow_rect.y) / float(shadowMapAtlas.desc.height)
);
SHCAM shcam;
CreateDirLightShadowCams(vis.scene->rain_blocker_dummy_light, *vis.camera, &shcam, 1);
CreateDirLightShadowCams(vis.scene->rain_blocker_dummy_light, *vis.camera, &shcam, 1, vis.rain_blocker_shadow_rect);
XMStoreFloat4x4(&frameCB.rain_blocker_matrix, shcam.view_projection);
XMStoreFloat4x4(&frameCB.rain_blocker_matrix_inverse, XMMatrixInverse(nullptr, shcam.view_projection));
}
@@ -4031,13 +4008,14 @@ void UpdateRenderData(
shaderentity.indices = ~0;
bool shadow = light.IsCastingShadow() && !light.IsStatic();
const wi::rectpacker::Rect& shadow_rect = vis.visibleLightShadowRects[lightIndex];
if (shadow)
{
shaderentity.shadowAtlasMulAdd.x = light.shadow_rect.w * atlas_dim_rcp.x;
shaderentity.shadowAtlasMulAdd.y = light.shadow_rect.h * atlas_dim_rcp.y;
shaderentity.shadowAtlasMulAdd.z = light.shadow_rect.x * atlas_dim_rcp.x;
shaderentity.shadowAtlasMulAdd.w = light.shadow_rect.y * atlas_dim_rcp.y;
shaderentity.shadowAtlasMulAdd.x = shadow_rect.w * atlas_dim_rcp.x;
shaderentity.shadowAtlasMulAdd.y = shadow_rect.h * atlas_dim_rcp.y;
shaderentity.shadowAtlasMulAdd.z = shadow_rect.x * atlas_dim_rcp.x;
shaderentity.shadowAtlasMulAdd.w = shadow_rect.y * atlas_dim_rcp.y;
shaderentity.SetIndices(matrixCounter, 0);
}
@@ -4050,7 +4028,7 @@ void UpdateRenderData(
if (shadow && !light.cascade_distances.empty())
{
SHCAM* shcams = (SHCAM*)alloca(sizeof(SHCAM) * light.cascade_distances.size());
CreateDirLightShadowCams(light, *vis.camera, shcams, light.cascade_distances.size());
CreateDirLightShadowCams(light, *vis.camera, shcams, light.cascade_distances.size(), shadow_rect);
for (size_t cascade = 0; cascade < light.cascade_distances.size(); ++cascade)
{
std::memcpy(&matrixArray[matrixCounter++], &shcams[cascade].view_projection, sizeof(XMMATRIX));
@@ -5618,6 +5596,7 @@ void DrawShadowmaps(
{
continue;
}
const wi::rectpacker::Rect& shadow_rect = vis.visibleLightShadowRects[lightIndex];
switch (light.GetType())
{
@@ -5631,7 +5610,7 @@ void DrawShadowmaps(
const uint32_t cascade_count = std::min((uint32_t)light.cascade_distances.size(), max_viewport_count);
Viewport* viewports = (Viewport*)alloca(sizeof(Viewport) * cascade_count);
SHCAM* shcams = (SHCAM*)alloca(sizeof(SHCAM) * cascade_count);
CreateDirLightShadowCams(light, *vis.camera, shcams, cascade_count);
CreateDirLightShadowCams(light, *vis.camera, shcams, cascade_count, shadow_rect);
renderQueue.init();
bool transparentShadowsRequested = false;
@@ -5674,10 +5653,10 @@ void DrawShadowmaps(
cb.cameras[cascade].output_index = cascade;
Viewport& vp = viewports[cascade];
vp.top_left_x = float(light.shadow_rect.x + cascade * light.shadow_rect.w);
vp.top_left_y = float(light.shadow_rect.y);
vp.width = float(light.shadow_rect.w);
vp.height = float(light.shadow_rect.h);
vp.top_left_x = float(shadow_rect.x + cascade * shadow_rect.w);
vp.top_left_y = float(shadow_rect.y);
vp.width = float(shadow_rect.w);
vp.height = float(shadow_rect.h);
vp.min_depth = 0.0f;
vp.max_depth = 1.0f;
}
@@ -5702,10 +5681,10 @@ void DrawShadowmaps(
device->BindDynamicConstantBuffer(cb, CBSLOT_RENDERER_CAMERA, cmd);
Viewport vp;
vp.top_left_x = float(light.shadow_rect.x + cascade * light.shadow_rect.w);
vp.top_left_y = float(light.shadow_rect.y);
vp.width = float(light.shadow_rect.w);
vp.height = float(light.shadow_rect.h);
vp.top_left_x = float(shadow_rect.x + cascade * shadow_rect.w);
vp.top_left_y = float(shadow_rect.y);
vp.width = float(shadow_rect.w);
vp.height = float(shadow_rect.h);
vp.min_depth = 0.0f;
vp.max_depth = 1.0f;
device->BindViewports(1, &vp, cmd);
@@ -5773,10 +5752,10 @@ void DrawShadowmaps(
device->BindDynamicConstantBuffer(cb, CBSLOT_RENDERER_CAMERA, cmd);
Viewport vp;
vp.top_left_x = float(light.shadow_rect.x);
vp.top_left_y = float(light.shadow_rect.y);
vp.width = float(light.shadow_rect.w);
vp.height = float(light.shadow_rect.h);
vp.top_left_x = float(shadow_rect.x);
vp.top_left_y = float(shadow_rect.y);
vp.width = float(shadow_rect.w);
vp.height = float(shadow_rect.h);
vp.min_depth = 0.0f;
vp.max_depth = 1.0f;
device->BindViewports(1, &vp, cmd);
@@ -5801,10 +5780,10 @@ void DrawShadowmaps(
device->BindDynamicConstantBuffer(cb, CBSLOT_RENDERER_CAMERA, cmd);
Viewport vp;
vp.top_left_x = float(light.shadow_rect.x);
vp.top_left_y = float(light.shadow_rect.y);
vp.width = float(light.shadow_rect.w);
vp.height = float(light.shadow_rect.h);
vp.top_left_x = float(shadow_rect.x);
vp.top_left_y = float(shadow_rect.y);
vp.width = float(shadow_rect.w);
vp.height = float(shadow_rect.h);
vp.min_depth = 0.0f;
vp.max_depth = 1.0f;
device->BindViewports(1, &vp, cmd);
@@ -5854,10 +5833,10 @@ void DrawShadowmaps(
frusta[camera_count] = cameras[shcam].frustum;
camera_count++;
}
vp[shcam].top_left_x = float(light.shadow_rect.x + shcam * light.shadow_rect.w);
vp[shcam].top_left_y = float(light.shadow_rect.y);
vp[shcam].width = float(light.shadow_rect.w);
vp[shcam].height = float(light.shadow_rect.h);
vp[shcam].top_left_x = float(shadow_rect.x + shcam * shadow_rect.w);
vp[shcam].top_left_y = float(shadow_rect.y);
vp[shcam].width = float(shadow_rect.w);
vp[shcam].height = float(shadow_rect.h);
vp[shcam].min_depth = 0.0f;
vp[shcam].max_depth = 1.0f;
}
@@ -5931,10 +5910,10 @@ void DrawShadowmaps(
device->BindDynamicConstantBuffer(cb, CBSLOT_RENDERER_CAMERA, cmd);
Viewport vp;
vp.top_left_x = float(light.shadow_rect.x + shcam * light.shadow_rect.w);
vp.top_left_y = float(light.shadow_rect.y);
vp.width = float(light.shadow_rect.w);
vp.height = float(light.shadow_rect.h);
vp.top_left_x = float(shadow_rect.x + shcam * shadow_rect.w);
vp.top_left_y = float(shadow_rect.y);
vp.width = float(shadow_rect.w);
vp.height = float(shadow_rect.h);
vp.min_depth = 0;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
@@ -5963,7 +5942,7 @@ void DrawShadowmaps(
if(vis.scene->weather.rain_amount > 0)
{
SHCAM shcam;
CreateDirLightShadowCams(vis.scene->rain_blocker_dummy_light, *vis.camera, &shcam, 1);
CreateDirLightShadowCams(vis.scene->rain_blocker_dummy_light, *vis.camera, &shcam, 1, vis.rain_blocker_shadow_rect);
renderQueue.init();
for (size_t i = 0; i < vis.scene->aabb_objects.size(); ++i)
@@ -5995,10 +5974,10 @@ void DrawShadowmaps(
cb.cameras[cascade].output_index = cascade;
Viewport vp;
vp.top_left_x = float(vis.scene->rain_blocker_dummy_light.shadow_rect.x + cascade * vis.scene->rain_blocker_dummy_light.shadow_rect.w);
vp.top_left_y = float(vis.scene->rain_blocker_dummy_light.shadow_rect.y);
vp.width = float(vis.scene->rain_blocker_dummy_light.shadow_rect.w);
vp.height = float(vis.scene->rain_blocker_dummy_light.shadow_rect.h);
vp.top_left_x = float(vis.rain_blocker_shadow_rect.x + cascade * vis.rain_blocker_shadow_rect.w);
vp.top_left_y = float(vis.rain_blocker_shadow_rect.y);
vp.width = float(vis.rain_blocker_shadow_rect.w);
vp.height = float(vis.rain_blocker_shadow_rect.h);
vp.min_depth = 0.0f;
vp.max_depth = 1.0f;
+5
View File
@@ -4,6 +4,7 @@
#include "wiGraphicsDevice.h"
#include "wiScene.h"
#include "wiECS.h"
#include "wiRectPacker.h"
#include "wiPrimitive.h"
#include "wiCanvas.h"
#include "wiMath.h"
@@ -109,6 +110,7 @@ namespace wi::renderer
ALLOW_HAIRS = 1 << 5,
ALLOW_REQUEST_REFLECTION = 1 << 6,
ALLOW_OCCLUSION_CULLING = 1 << 7,
ALLOW_SHADOW_ATLAS_PACKING = 1 << 8,
ALLOW_EVERYTHING = ~0u
};
@@ -122,6 +124,9 @@ namespace wi::renderer
wi::vector<uint32_t> visibleEmitters;
wi::vector<uint32_t> visibleHairs;
wi::vector<uint32_t> visibleLights;
wi::rectpacker::State shadow_packer;
wi::rectpacker::Rect rain_blocker_shadow_rect;
wi::vector<wi::rectpacker::Rect> visibleLightShadowRects;
std::atomic<uint32_t> object_counter;
std::atomic<uint32_t> light_counter;
+19 -1
View File
@@ -767,6 +767,25 @@ namespace wi::scene
}
}
// VXGI volume update:
// Note: this is using camera that the scene is associated with
{
VXGI::ClipMap& clipmap = vxgi.clipmaps[vxgi.clipmap_to_update];
clipmap.voxelsize = vxgi.clipmaps[0].voxelsize * (1u << vxgi.clipmap_to_update);
const float texelSize = clipmap.voxelsize * 2;
XMFLOAT3 center = XMFLOAT3(std::floor(camera.Eye.x / texelSize) * texelSize, std::floor(camera.Eye.y / texelSize) * texelSize, std::floor(camera.Eye.z / texelSize) * texelSize);
clipmap.offsetfromPrevFrame.x = int((clipmap.center.x - center.x) / texelSize);
clipmap.offsetfromPrevFrame.y = -int((clipmap.center.y - center.y) / texelSize);
clipmap.offsetfromPrevFrame.z = int((clipmap.center.z - center.z) / texelSize);
clipmap.center = center;
XMFLOAT3 extents = XMFLOAT3(vxgi.res * clipmap.voxelsize, vxgi.res * clipmap.voxelsize, vxgi.res * clipmap.voxelsize);
if (extents.x != clipmap.extents.x || extents.y != clipmap.extents.y || extents.z != clipmap.extents.z)
{
vxgi.pre_clear = true;
}
clipmap.extents = extents;
}
// Shader scene resources:
if (device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA))
{
@@ -4598,7 +4617,6 @@ namespace wi::scene
ocean.occlusionQueries[queryheap_idx] = -1; // invalidate query
}
rain_blocker_dummy_light.shadow_rect = {};
if (weather.rain_amount > 0)
{
GraphicsDevice* device = wi::graphics::GetDevice();
-1
View File
@@ -1045,7 +1045,6 @@ namespace wi::scene
XMFLOAT4 rotation = XMFLOAT4(0, 0, 0, 1);
XMFLOAT3 scale = XMFLOAT3(1, 1, 1);
mutable int occlusionquery = -1;
wi::rectpacker::Rect shadow_rect = {};
wi::vector<wi::Resource> lensFlareRimTextures;
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 375;
const int revision = 376;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);