ddgi probe offsets
This commit is contained in:
@@ -14,6 +14,7 @@ static const uint DDGI_COLOR_TEXTURE_WIDTH = DDGI_COLOR_TEXELS * DDGI_GRID_DIMEN
|
||||
static const uint DDGI_COLOR_TEXTURE_HEIGHT = DDGI_COLOR_TEXELS * DDGI_GRID_DIMENSIONS.z;
|
||||
static const uint DDGI_DEPTH_TEXTURE_WIDTH = DDGI_DEPTH_TEXELS * DDGI_GRID_DIMENSIONS.x * DDGI_GRID_DIMENSIONS.y;
|
||||
static const uint DDGI_DEPTH_TEXTURE_HEIGHT = DDGI_DEPTH_TEXELS * DDGI_GRID_DIMENSIONS.z;
|
||||
static const float DDGI_KEEP_DISTANCE = 0.1f; // how much distance should probes keep from surfaces
|
||||
|
||||
#define DDGI_LINEAR_BLENDING
|
||||
|
||||
@@ -52,12 +53,32 @@ struct DDGIRayDataPacked
|
||||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
struct DDGIProbeOffset
|
||||
{
|
||||
uint2 data;
|
||||
|
||||
#ifndef __cplusplus
|
||||
inline void store(float3 offset)
|
||||
{
|
||||
data = pack_half3(offset);
|
||||
}
|
||||
inline float3 load()
|
||||
{
|
||||
return unpack_half3(data);
|
||||
}
|
||||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
inline float3 ddgi_cellsize()
|
||||
{
|
||||
return GetScene().ddgi.cell_size;
|
||||
}
|
||||
inline float3 ddgi_cellsize_rcp()
|
||||
{
|
||||
return GetScene().ddgi.cell_size_rcp;
|
||||
}
|
||||
inline float ddgi_max_distance()
|
||||
{
|
||||
return GetScene().ddgi.max_distance;
|
||||
@@ -77,7 +98,13 @@ inline uint ddgi_probe_index(uint3 probeCoord)
|
||||
}
|
||||
inline float3 ddgi_probe_position(uint3 probeCoord)
|
||||
{
|
||||
return GetScene().ddgi.grid_min + probeCoord * ddgi_cellsize();
|
||||
float3 pos = GetScene().ddgi.grid_min + probeCoord * ddgi_cellsize();
|
||||
[branch]
|
||||
if (GetScene().ddgi.offset_buffer >= 0)
|
||||
{
|
||||
pos += bindless_buffers[GetScene().ddgi.offset_buffer].Load<DDGIProbeOffset>(ddgi_probe_index(probeCoord) * sizeof(DDGIProbeOffset)).load();
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
inline uint2 ddgi_probe_color_pixel(uint3 probeCoord)
|
||||
{
|
||||
@@ -111,7 +138,7 @@ float3 ddgi_sample_irradiance(float3 P, float3 N)
|
||||
float sum_weight = 0;
|
||||
|
||||
// alpha is how far from the floor(currentVertex) position. on [0, 1] for each axis.
|
||||
float3 alpha = clamp((P - base_probe_pos) / ddgi_cellsize(), 0, 1);
|
||||
float3 alpha = saturate((P - base_probe_pos) * ddgi_cellsize_rcp());
|
||||
|
||||
// Iterate over adjacent probe cage
|
||||
for (uint i = 0; i < 8; ++i)
|
||||
|
||||
@@ -43,6 +43,9 @@ struct ShaderScene
|
||||
float max_distance;
|
||||
|
||||
float3 grid_extents_rcp;
|
||||
int offset_buffer;
|
||||
|
||||
float3 cell_size_rcp;
|
||||
float padding0;
|
||||
};
|
||||
DDGI ddgi;
|
||||
|
||||
@@ -39,7 +39,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
|
||||
{
|
||||
RayDesc ray;
|
||||
ray.Origin = probePos;
|
||||
ray.TMin = 0.0001;
|
||||
ray.TMin = 0; // don't need TMin because we are not tracing from a surface
|
||||
ray.TMax = FLT_MAX;
|
||||
ray.Direction = normalize(mul(random_orientation, spherical_fibonacci(rayIndex, push.rayCount)));
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ static const float WEIGHT_EPSILON = 0.0001;
|
||||
#ifdef DDGI_UPDATE_DEPTH
|
||||
static const uint THREADCOUNT = DDGI_DEPTH_RESOLUTION;
|
||||
RWTexture2D<float2> output : register(u0);
|
||||
RWByteAddressBuffer ddgiOffsetBuffer:register(u1);
|
||||
#else
|
||||
static const uint THREADCOUNT = DDGI_COLOR_RESOLUTION;
|
||||
RWTexture2D<float3> output : register(u0);
|
||||
@@ -32,6 +33,19 @@ void main(uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint groupIndex
|
||||
const uint3 probeCoord = ddgi_probe_coord(probeIndex);
|
||||
const float maxDistance = ddgi_max_distance();
|
||||
|
||||
#ifdef DDGI_UPDATE_DEPTH
|
||||
[branch]
|
||||
if (groupIndex == 0 && push.frameIndex == 0)
|
||||
{
|
||||
DDGIProbeOffset ofs;
|
||||
ofs.store(float3(0, 0, 0));
|
||||
ddgiOffsetBuffer.Store<DDGIProbeOffset>(probeIndex * sizeof(DDGIProbeOffset), ofs);
|
||||
}
|
||||
float3 probeOffset = ddgiOffsetBuffer.Load<DDGIProbeOffset>(probeIndex * sizeof(DDGIProbeOffset)).load();
|
||||
float3 probeOffsetNew = 0;
|
||||
const float probeOffsetDistance = maxDistance * DDGI_KEEP_DISTANCE;
|
||||
#endif // DDGI_UPDATE_DEPTH
|
||||
|
||||
#ifdef DDGI_UPDATE_DEPTH
|
||||
float2 result = 0;
|
||||
const uint2 pixel_topleft = ddgi_probe_depth_pixel(probeCoord);
|
||||
@@ -65,14 +79,19 @@ void main(uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint groupIndex
|
||||
DDGIRayData ray = ray_cache[r];
|
||||
|
||||
#ifdef DDGI_UPDATE_DEPTH
|
||||
float ray_probe_distance;
|
||||
float depth;
|
||||
if (ray.depth > 0)
|
||||
{
|
||||
ray_probe_distance = clamp(ray.depth - 0.01, 0, maxDistance);
|
||||
depth = clamp(ray.depth - 0.01, 0, maxDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
ray_probe_distance = maxDistance;
|
||||
depth = maxDistance;
|
||||
}
|
||||
|
||||
if (depth < probeOffsetDistance)
|
||||
{
|
||||
probeOffsetNew -= ray.direction * (probeOffsetDistance - depth);
|
||||
}
|
||||
#else
|
||||
const float3 radiance = ray.radiance.rgb;
|
||||
@@ -86,7 +105,7 @@ void main(uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint groupIndex
|
||||
if (weight > WEIGHT_EPSILON)
|
||||
{
|
||||
#ifdef DDGI_UPDATE_DEPTH
|
||||
result += float2(ray_probe_distance * weight, sqr(ray_probe_distance) * weight);
|
||||
result += float2(depth, sqr(depth)) * weight;
|
||||
#else
|
||||
result += ray.radiance.rgb * weight;
|
||||
#endif // DDGI_UPDATE_DEPTH
|
||||
@@ -129,6 +148,17 @@ void main(uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint groupIndex
|
||||
uint2 dst_coord = copy_coord + DDGI_DEPTH_BORDER_OFFSETS[index].zw;
|
||||
output[dst_coord] = output[src_coord];
|
||||
}
|
||||
|
||||
[branch]
|
||||
if (groupIndex == 0)
|
||||
{
|
||||
probeOffset = lerp(probeOffset, probeOffsetNew, 0.01);
|
||||
const float3 limit = ddgi_cellsize() * 0.5;
|
||||
probeOffset = clamp(probeOffset, -limit, limit);
|
||||
DDGIProbeOffset ofs;
|
||||
ofs.store(probeOffset);
|
||||
ddgiOffsetBuffer.Store<DDGIProbeOffset>(probeIndex * sizeof(DDGIProbeOffset), ofs);
|
||||
}
|
||||
#else
|
||||
// Copy color borders:
|
||||
for (uint index = groupIndex; index < 36; index += THREADCOUNT * THREADCOUNT)
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "wiECS.h"
|
||||
#include "wiScene_Decl.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace wi
|
||||
{
|
||||
class Archive;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "wiVector.h"
|
||||
#include "wiScene_Decl.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace wi
|
||||
{
|
||||
class Archive;
|
||||
|
||||
@@ -5681,12 +5681,12 @@ void DrawDebugWorld(
|
||||
}
|
||||
|
||||
|
||||
if (GetDDGIDebugEnabled())
|
||||
if (GetDDGIDebugEnabled() && GetDDGIEnabled())
|
||||
{
|
||||
device->EventBegin("Debug DDGI", cmd);
|
||||
|
||||
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_DDGI], cmd);
|
||||
device->DrawInstanced(2880, DDGI_GRID_DIMENSIONS.x* DDGI_GRID_DIMENSIONS.y* DDGI_GRID_DIMENSIONS.z, 0, 0, cmd); // uv-sphere
|
||||
device->DrawInstanced(2880, DDGI_GRID_DIMENSIONS.x * DDGI_GRID_DIMENSIONS.y * DDGI_GRID_DIMENSIONS.z, 0, 0, cmd); // uv-sphere
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
@@ -8077,6 +8077,7 @@ void DDGI(
|
||||
GPUBarrier::Buffer(&scene.ddgiRayBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE_COMPUTE),
|
||||
GPUBarrier::Image(&scene.ddgiColorTexture[1], ResourceState::SHADER_RESOURCE_COMPUTE, ResourceState::UNORDERED_ACCESS),
|
||||
GPUBarrier::Image(&scene.ddgiDepthTexture[1], ResourceState::SHADER_RESOURCE_COMPUTE, ResourceState::UNORDERED_ACCESS),
|
||||
GPUBarrier::Buffer(&scene.ddgiOffsetBuffer, ResourceState::SHADER_RESOURCE_COMPUTE, ResourceState::UNORDERED_ACCESS),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
@@ -8117,6 +8118,7 @@ void DDGI(
|
||||
|
||||
const GPUResource* uavs[] = {
|
||||
&scene.ddgiDepthTexture[1],
|
||||
&scene.ddgiOffsetBuffer,
|
||||
};
|
||||
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
|
||||
|
||||
@@ -8129,6 +8131,7 @@ void DDGI(
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&scene.ddgiColorTexture[1], ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE_COMPUTE),
|
||||
GPUBarrier::Image(&scene.ddgiDepthTexture[1], ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE_COMPUTE),
|
||||
GPUBarrier::Buffer(&scene.ddgiOffsetBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE_COMPUTE),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
@@ -1790,6 +1790,13 @@ namespace wi::scene
|
||||
device->CreateBuffer(&buf, nullptr, &ddgiRayBuffer);
|
||||
device->SetName(&ddgiRayBuffer, "ddgiRayBuffer");
|
||||
|
||||
buf.stride = sizeof(DDGIProbeOffset);
|
||||
buf.size = buf.stride * DDGI_PROBE_COUNT;
|
||||
buf.bind_flags = BindFlag::UNORDERED_ACCESS | BindFlag::SHADER_RESOURCE;
|
||||
buf.misc_flags = ResourceMiscFlag::BUFFER_RAW;
|
||||
device->CreateBuffer(&buf, nullptr, &ddgiOffsetBuffer);
|
||||
device->SetName(&ddgiOffsetBuffer, "ddgiOffsetBuffer");
|
||||
|
||||
TextureDesc tex;
|
||||
tex.width = DDGI_COLOR_TEXTURE_WIDTH;
|
||||
tex.height = DDGI_COLOR_TEXTURE_HEIGHT;
|
||||
@@ -1815,6 +1822,8 @@ namespace wi::scene
|
||||
}
|
||||
else if (ddgiColorTexture[0].IsValid())
|
||||
{
|
||||
ddgiRayBuffer = {};
|
||||
ddgiOffsetBuffer = {};
|
||||
ddgiColorTexture[0] = {};
|
||||
ddgiColorTexture[1] = {};
|
||||
ddgiDepthTexture[0] = {};
|
||||
@@ -1872,6 +1881,7 @@ namespace wi::scene
|
||||
|
||||
shaderscene.ddgi.color_texture = device->GetDescriptorIndex(&ddgiColorTexture[0], SubresourceType::SRV);
|
||||
shaderscene.ddgi.depth_texture = device->GetDescriptorIndex(&ddgiDepthTexture[0], SubresourceType::SRV);
|
||||
shaderscene.ddgi.offset_buffer = device->GetDescriptorIndex(&ddgiOffsetBuffer, SubresourceType::SRV);
|
||||
shaderscene.ddgi.grid_min.x = shaderscene.aabb_min.x - 1;
|
||||
shaderscene.ddgi.grid_min.y = shaderscene.aabb_min.y - 1;
|
||||
shaderscene.ddgi.grid_min.z = shaderscene.aabb_min.z - 1;
|
||||
@@ -1888,6 +1898,9 @@ namespace wi::scene
|
||||
shaderscene.ddgi.cell_size.x = shaderscene.ddgi.grid_extents.x / (DDGI_GRID_DIMENSIONS.x - 1);
|
||||
shaderscene.ddgi.cell_size.y = shaderscene.ddgi.grid_extents.y / (DDGI_GRID_DIMENSIONS.y - 1);
|
||||
shaderscene.ddgi.cell_size.z = shaderscene.ddgi.grid_extents.z / (DDGI_GRID_DIMENSIONS.z - 1);
|
||||
shaderscene.ddgi.cell_size_rcp.x = 1.0f / shaderscene.ddgi.cell_size.x;
|
||||
shaderscene.ddgi.cell_size_rcp.y = 1.0f / shaderscene.ddgi.cell_size.y;
|
||||
shaderscene.ddgi.cell_size_rcp.z = 1.0f / shaderscene.ddgi.cell_size.z;
|
||||
shaderscene.ddgi.max_distance = std::max(shaderscene.ddgi.cell_size.x, std::max(shaderscene.ddgi.cell_size.y, shaderscene.ddgi.cell_size.z)) * 1.5f;
|
||||
}
|
||||
void Scene::Clear()
|
||||
|
||||
@@ -1338,6 +1338,7 @@ namespace wi::scene
|
||||
// DDGI resources:
|
||||
uint ddgi_frameIndex = 0;
|
||||
wi::graphics::GPUBuffer ddgiRayBuffer;
|
||||
wi::graphics::GPUBuffer ddgiOffsetBuffer;
|
||||
wi::graphics::Texture ddgiColorTexture[2];
|
||||
wi::graphics::Texture ddgiDepthTexture[2];
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wi::version
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 60;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 22;
|
||||
const int revision = 23;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user