Skip to content

Commit

Permalink
Spatial radiance caching
Browse files Browse the repository at this point in the history
  • Loading branch information
sergcpp committed Apr 16, 2024
1 parent 5941d5b commit f95f9c2
Show file tree
Hide file tree
Showing 171 changed files with 6,593 additions and 3,650 deletions.
14 changes: 11 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,14 @@ set(INTERNAL_SOURCE_FILES internal/Atmosphere.h
internal/CoreRef.h
internal/CoreRef.cpp
internal/CoreSIMD.h
internal/DenoiseRef.h
internal/DenoiseRef.cpp
internal/Fixed.h
internal/FreelistAlloc.h
internal/FreelistAlloc.cpp
internal/HashMap32.h
internal/RadCacheRef.h
internal/RadCacheRef.cpp
internal/RastState.h
internal/RendererCPU.h
internal/RendererGPU.h
Expand All @@ -89,6 +93,8 @@ set(INTERNAL_SOURCE_FILES internal/Atmosphere.h
internal/SceneCPU.cpp
internal/SceneGPU.h
internal/ScopeExit.h
internal/ShadeRef.h
internal/ShadeRef.cpp
internal/SmallVector.h
internal/SparseStorageCPU.h
internal/SparseStorageGPU.h
Expand All @@ -100,13 +106,15 @@ set(INTERNAL_SOURCE_FILES internal/Atmosphere.h
internal/TextureStorageCPU.cpp
internal/TextureUtils.h
internal/TextureUtils.cpp
internal/TextureUtilsNEON.cpp
internal/TextureUtilsSSE2.cpp
internal/Time_.h
internal/Time.cpp
internal/VectorGPU.h
internal/TonemapRef.h
internal/TonemapRef.cpp
internal/UNetFilter.h
internal/UNetFilter.cpp
internal/TextureUtilsNEON.cpp
internal/TextureUtilsSSE2.cpp)
internal/VectorGPU.h)

if (ENABLE_REF_IMPL)
set(INTERNAL_SOURCE_FILES ${INTERNAL_SOURCE_FILES}
Expand Down
22 changes: 18 additions & 4 deletions RendererBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct settings_t {
bool use_tex_compression = true;
bool use_hwrt = true;
bool use_bindless = true;
bool use_spatial_cache = false;
int validation_level = 0;
};

Expand All @@ -60,16 +61,14 @@ class RegionContext {
rect_t rect_;

public:
int iteration = 0; ///< Number of rendered samples per pixel
int iteration = 0; ///< Number of rendered samples per pixel

explicit RegionContext(const rect_t &rect) : rect_(rect) {}

const rect_t &rect() const { return rect_; }

/// Clear region context (used to start again)
void Clear() {
iteration = 0;
}
void Clear() { iteration = 0; }
};

class ILog;
Expand Down Expand Up @@ -140,6 +139,19 @@ class RendererBase {
*/
virtual void DenoiseImage(int pass, const RegionContext &region) = 0;

/** @brief Update spatial radiance cache
@param scene reference to a scene
@param region image region to render
*/
virtual void UpdateSpatialCache(const SceneBase &scene, RegionContext &region) = 0;

/** @brief Resolve spatial radiance cache
@param scene reference to a scene
*/
virtual void ResolveSpatialCache(
const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for = parallel_for_serial) = 0;

/// Structure that holds render timings (in microseconds)
struct stats_t {
unsigned long long time_primary_ray_gen_us;
Expand All @@ -151,6 +163,8 @@ class RendererBase {
unsigned long long time_secondary_shade_us;
unsigned long long time_secondary_shadow_us;
unsigned long long time_denoise_us;
unsigned long long time_cache_update_us;
unsigned long long time_cache_resolve_us;
};
virtual void GetStats(stats_t &st) = 0;
virtual void ResetStats() = 0;
Expand Down
222 changes: 100 additions & 122 deletions internal/Atmosphere.cpp

Large diffs are not rendered by default.

41 changes: 39 additions & 2 deletions internal/Constants.inl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ const int RAND_DIM_BSDF = 1;
const int RAND_DIM_LIGHT_PICK = 2;
const int RAND_DIM_LIGHT = 3;
const int RAND_DIM_TEX = 4;
const int RAND_DIM_BOUNCE_COUNT = 5; // separate for each bounce
const int RAND_DIM_CACHE = 5;
// 6 and 7 reserved for the future use
const int RAND_DIM_BOUNCE_COUNT = 8; // separate for each bounce

//
// Light constants
Expand Down Expand Up @@ -89,4 +91,39 @@ const int ATLAS_TEX_RECONSTRUCT_Z_BIT = 16384; // 0b0100000000000000
const int ATLAS_TEX_WIDTH_BITS = 16383; // 0b0011111111111111
const int ATLAS_TEX_MIPS_BIT = 32768; // 0b1000000000000000
const int ATLAS_TEX_YCOCG_BIT = 16384; // 0b0100000000000000
const int ATLAS_TEX_HEIGHT_BITS = 16383; // 0b0011111111111111
const int ATLAS_TEX_HEIGHT_BITS = 16383; // 0b0011111111111111

//
// Spatial hashing
//
const uint HASH_GRID_POSITION_BIT_NUM = 17u;
const uint HASH_GRID_POSITION_BIT_MASK = (1u << HASH_GRID_POSITION_BIT_NUM) - 1;
const uint HASH_GRID_LEVEL_BIT_NUM = 10u;
const uint HASH_GRID_LEVEL_BIT_MASK = (1u << HASH_GRID_LEVEL_BIT_NUM) - 1;
const uint HASH_GRID_NORMAL_BIT_NUM = 3u;
const uint HASH_GRID_NORMAL_BIT_MASK = (1u << HASH_GRID_NORMAL_BIT_NUM) - 1;
const uint HASH_GRID_HASH_MAP_BUCKET_SIZE = 32u;
const uint HASH_GRID_INVALID_CACHE_ENTRY = 0xFFFFFFFFu;
const uint HASH_GRID_LEVEL_BIAS = 2u; // positive bias adds extra levels with content magnification
const uint HASH_GRID_INVALID_HASH_KEY = 0u;
const bool HASH_GRID_USE_NORMALS = true;
const bool HASH_GRID_ALLOW_COMPACTION = (HASH_GRID_HASH_MAP_BUCKET_SIZE == 32u);

//
// Radiance caching
//
const int RAD_CACHE_SAMPLE_COUNT_MAX = 128;
const int RAD_CACHE_SAMPLE_COUNT_MIN = 8;
const float RAD_CACHE_RADIANCE_SCALE = 1e4f;
const int RAD_CACHE_SAMPLE_COUNTER_BIT_NUM = 20;
const uint RAD_CACHE_SAMPLE_COUNTER_BIT_MASK = ((1u << RAD_CACHE_SAMPLE_COUNTER_BIT_NUM) - 1);
const uint RAD_CACHE_FRAME_COUNTER_BIT_NUM = (32 - RAD_CACHE_SAMPLE_COUNTER_BIT_NUM);
const uint RAD_CACHE_FRAME_COUNTER_BIT_MASK = ((1u << RAD_CACHE_FRAME_COUNTER_BIT_NUM) - 1);
const float RAD_CACHE_GRID_LOGARITHM_BASE = 2.0f;
const int RAD_CACHE_STALE_FRAME_NUM_MAX = 128;
const int RAD_CACHE_DOWNSAMPLING_FACTOR = 4;
const bool RAD_CACHE_ENABLE_COMPACTION = true;
const bool RAD_CACHE_FILTER_ADJACENT_LEVELS = true;
const int RAD_CACHE_PROPAGATION_DEPTH = 4;
const float RAD_CACHE_GRID_SCALE = 50.0f;
const float RAD_CACHE_MIN_ROUGHNESS = 0.4f;
73 changes: 72 additions & 1 deletion internal/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
#pragma intrinsic(_BitScanForward)
#pragma intrinsic(_BitScanReverse)
#pragma intrinsic(_bittestandcomplement)
#pragma intrinsic(_InterlockedExchangeAdd)
#pragma intrinsic(_InterlockedCompareExchange)
#pragma intrinsic(_InterlockedCompareExchange64)

#define InterlockedExchangeAdd _InterlockedExchangeAdd
#define InterlockedCompareExchange _InterlockedCompareExchange
#define InterlockedCompareExchange64 _InterlockedCompareExchange64

#ifdef _M_IX86
// Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls
Expand All @@ -40,6 +47,11 @@ force_inline unsigned char _BitScanForward64(unsigned long *Index, unsigned __in
return 0;
}
#endif
#else

#define InterlockedExchangeAdd __sync_fetch_and_add
#define InterlockedCompareExchange(dst, exch, comp) __sync_val_compare_and_swap(dst, comp, exch)
#define InterlockedCompareExchange64(dst, exch, comp) __sync_val_compare_and_swap(dst, comp, exch)

#endif

Expand Down Expand Up @@ -430,6 +442,45 @@ enum class ePreOp { None, Upscale, HDRTransfer, PositiveNormalize };
};
static_assert(sizeof(pass_info_t) == 20, "!");*/

struct cache_voxel_t {
float radiance[3] = {};
uint32_t sample_count = 0;
uint32_t frame_count = 0;
};

struct packed_cache_voxel_t {
uint32_t v[4] = {};
};

inline cache_voxel_t unpack_voxel_data(const packed_cache_voxel_t &v) {
cache_voxel_t ret;
ret.radiance[0] = float(v.v[0]) / RAD_CACHE_RADIANCE_SCALE;
ret.radiance[1] = float(v.v[1]) / RAD_CACHE_RADIANCE_SCALE;
ret.radiance[2] = float(v.v[2]) / RAD_CACHE_RADIANCE_SCALE;
ret.sample_count = (v.v[3] >> 0) & RAD_CACHE_SAMPLE_COUNTER_BIT_MASK;
ret.frame_count = (v.v[3] >> RAD_CACHE_SAMPLE_COUNTER_BIT_NUM) & RAD_CACHE_FRAME_COUNTER_BIT_MASK;
return ret;
}

struct cache_grid_params_t {
float cam_pos_curr[3] = {0.0f, 0.0f, 0.0f}, cam_pos_prev[3] = {0.0f, 0.0f, 0.0f};
float log_base = RAD_CACHE_GRID_LOGARITHM_BASE;
float scale = RAD_CACHE_GRID_SCALE;
float exposure = 1.0f;
};

struct cache_data_t {
uint32_t cache_entries[RAD_CACHE_PROPAGATION_DEPTH];
float sample_weight[RAD_CACHE_PROPAGATION_DEPTH][3];
int path_len;
};

enum eSpatialCacheMode {
None,
Update,
Query
};

struct scene_data_t {
const environment_t &env;
const mesh_instance_t *mesh_instances;
Expand All @@ -450,14 +501,34 @@ struct scene_data_t {
uint32_t blocker_lights_count;
Span<const light_bvh_node_t> light_nodes;
Span<const light_wbvh_node_t> light_wnodes;
const cache_grid_params_t &spatial_cache_grid;
Span<const uint64_t> spatial_cache_entries;
Span<const packed_cache_voxel_t> spatial_cache_voxels;
};

force_inline float clamp(const float val, const float min, const float max) {
return val < min ? min : (val > max ? max : val);
}

force_inline float saturate(const float val) { return clamp(val, 0.0f, 1.0f); }

force_inline float sqr(const float x) { return x * x; }

force_inline float mix(float x, float y, float a) { return x * (1.0f - a) + y * a; }

force_inline float log_base(const float x, const float base) { return logf(x) / logf(base); }

force_inline float calc_voxel_size(const uint32_t grid_level, const cache_grid_params_t &params) {
return powf(params.log_base, grid_level) / (params.scale * powf(params.log_base, HASH_GRID_LEVEL_BIAS));
}

template <typename T> void rect_fill(Span<T> data, const int stride, const rect_t &rect, T &&val) {
for (int y = 0; y < rect.h; ++y) {
const int yy = rect.y + y;
for (int x = 0; x < rect.w; ++x) {
const int xx = rect.x + x;
data[yy * stride + xx] = val;
}
}
}

} // namespace Ray
Loading

0 comments on commit f95f9c2

Please sign in to comment.