1+ #ifndef _NBL_HLSL_RWMC_CASCADE_ACCUMULATOR_INCLUDED_
2+ #define _NBL_HLSL_RWMC_CASCADE_ACCUMULATOR_INCLUDED_
3+ #include <nbl/builtin/hlsl/cpp_compat.hlsl>
4+ #include <nbl/builtin/hlsl/cpp_compat/promote.hlsl>
5+ #include <nbl/builtin/hlsl/vector_utils/vector_traits.hlsl>
6+ #include <nbl/builtin/hlsl/colorspace/encodeCIEXYZ.hlsl>
7+ #include <nbl/builtin/hlsl/rwmc/SplattingParameters.hlsl>
8+
9+ namespace nbl
10+ {
11+ namespace hlsl
12+ {
13+ namespace rwmc
14+ {
15+
16+ template<typename CascadeLayerType, uint32_t CascadeCount NBL_PRIMARY_REQUIRES (concepts::Vector<CascadeLayerType>)
17+ struct CascadeAccumulator
18+ {
19+ struct CascadeEntry
20+ {
21+ uint32_t cascadeSampleCounter[CascadeCount];
22+ CascadeLayerType data[CascadeCount];
23+
24+ void addSampleIntoCascadeEntry (CascadeLayerType _sample, uint32_t lowerCascadeIndex, float lowerCascadeLevelWeight, float higherCascadeLevelWeight, uint32_t sampleCount)
25+ {
26+ const float reciprocalSampleCount = 1.0f / float (sampleCount);
27+
28+ uint32_t lowerCascadeSampleCount = cascadeSampleCounter[lowerCascadeIndex];
29+ data[lowerCascadeIndex] += (_sample * lowerCascadeLevelWeight - (sampleCount - lowerCascadeSampleCount) * data[lowerCascadeIndex]) * reciprocalSampleCount;
30+ cascadeSampleCounter[lowerCascadeIndex] = sampleCount;
31+
32+ uint32_t higherCascadeIndex = lowerCascadeIndex + 1u;
33+ if (higherCascadeIndex < CascadeCount)
34+ {
35+ uint32_t higherCascadeSampleCount = cascadeSampleCounter[higherCascadeIndex];
36+ data[higherCascadeIndex] += (_sample * higherCascadeLevelWeight - (sampleCount - higherCascadeSampleCount) * data[higherCascadeIndex]) * reciprocalSampleCount;
37+ cascadeSampleCounter[higherCascadeIndex] = sampleCount;
38+ }
39+ }
40+ };
41+
42+ using cascade_layer_scalar_type = typename vector_traits<CascadeLayerType>::scalar_type;
43+ using this_t = CascadeAccumulator<CascadeLayerType, CascadeCount>;
44+ using output_storage_type = CascadeEntry;
45+ using initialization_data = SplattingParameters;
46+ output_storage_type accumulation;
47+
48+ SplattingParameters splattingParameters;
49+
50+ static this_t create (NBL_CONST_REF_ARG (SplattingParameters) settings)
51+ {
52+ this_t retval;
53+ for (int i = 0 ; i < CascadeCount; ++i)
54+ {
55+ retval.accumulation.data[i] = promote<CascadeLayerType, float32_t>(0.0f );
56+ retval.accumulation.cascadeSampleCounter[i] = 0u;
57+ }
58+ retval.splattingParameters = settings;
59+
60+ return retval;
61+ }
62+
63+ cascade_layer_scalar_type getLuma (NBL_CONST_REF_ARG (CascadeLayerType) col)
64+ {
65+ return hlsl::dot<CascadeLayerType>(hlsl::transpose (colorspace::scRGBtoXYZ)[1 ], col);
66+ }
67+
68+ // most of this code is stolen from https://cg.ivd.kit.edu/publications/2018/rwmc/tool/split.cpp
69+ void addSample (uint32_t sampleCount, CascadeLayerType _sample)
70+ {
71+ const cascade_layer_scalar_type log2Start = splattingParameters.log2Start;
72+ const cascade_layer_scalar_type log2Base = splattingParameters.log2Base;
73+ const cascade_layer_scalar_type luma = getLuma (_sample);
74+ const cascade_layer_scalar_type log2Luma = log2<cascade_layer_scalar_type>(luma);
75+ const cascade_layer_scalar_type cascade = log2Luma * 1.f / log2Base - log2Start / log2Base;
76+ const cascade_layer_scalar_type clampedCascade = clamp (cascade, 0 , CascadeCount - 1 );
77+ // c<=0 -> 0, c>=Count-1 -> Count-1
78+ uint32_t lowerCascadeIndex = floor<cascade_layer_scalar_type>(cascade);
79+ // 0 whenever clamped or `cascade` is integer (when `clampedCascade` is integer)
80+ cascade_layer_scalar_type higherCascadeWeight = clampedCascade - floor<cascade_layer_scalar_type>(clampedCascade);
81+ // never 0 thanks to magic of `1-fract(x)`
82+ cascade_layer_scalar_type lowerCascadeWeight = cascade_layer_scalar_type (1 ) - higherCascadeWeight;
83+
84+ // handle super bright sample case
85+ if (cascade > CascadeCount - 1 )
86+ lowerCascadeWeight = exp2 (log2Start + log2Base * (CascadeCount - 1 ) - log2Luma);
87+
88+ accumulation.addSampleIntoCascadeEntry (_sample, lowerCascadeIndex, lowerCascadeWeight, higherCascadeWeight, sampleCount);
89+ }
90+
91+
92+ };
93+
94+ }
95+ }
96+ }
97+
98+ #endif
0 commit comments