95 lines
2.2 KiB
C
95 lines
2.2 KiB
C
#include "Algorithm/Sobol.h"
|
|
|
|
static inline int sobol_get_bit(uint32_t index, uint32_t bit)
|
|
{
|
|
return (index >> bit) & 1;
|
|
}
|
|
|
|
//NOTE: Maybe precompute the vector table?
|
|
void sobol_init()
|
|
{
|
|
// First, set dimension 0 manually (Van der Corput)
|
|
for (int i = 0; i < SOBOL_BITS; i++)
|
|
{
|
|
sobol_direction_vectors[0][i] = 1U << (31 - i);
|
|
}
|
|
|
|
for (int d = 1; d < SOBOL_DIMENSIONS; d++)
|
|
{
|
|
int s = s_vals[d - 1];
|
|
int a = a_vals[d - 1];
|
|
|
|
// Set initial direction numbers
|
|
for (int i = 0; i < s; i++)
|
|
{
|
|
sobol_direction_vectors[d][i] = m_vals[d - 1][i] << (31 - i);
|
|
}
|
|
|
|
// Compute remaining direction numbers
|
|
for (int i = s; i < SOBOL_BITS; i++)
|
|
{
|
|
uint32_t v = sobol_direction_vectors[d][i - s];
|
|
v ^= v >> s;
|
|
|
|
for (int k = 1; k < s; k++)
|
|
{
|
|
if ((a >> (s - 1 - k)) & 1)
|
|
v ^= sobol_direction_vectors[d][i - k];
|
|
}
|
|
|
|
sobol_direction_vectors[d][i] = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint16_t sobol_get_dimension(uint16_t bounce, sampling_dimension_t operation_type)
|
|
{
|
|
return PRNG_BASE_NUM + bounce * PRNG_BOUNCE_NUM + operation_type;
|
|
}
|
|
|
|
static inline float sobol_uint_to_float(uint32_t x)
|
|
{
|
|
return x * 2.3283064365386963e-10f; // 1/2^32
|
|
}
|
|
|
|
float sobol_sample(uint32_t index, uint16_t dimension)
|
|
{
|
|
// return random_float();
|
|
if (dimension >= SOBOL_DIMENSIONS)
|
|
{
|
|
return 0.0f; // Invalid dimension
|
|
}
|
|
|
|
uint32_t result = 0;
|
|
for (int i = 0; i < SOBOL_BITS; i++)
|
|
{
|
|
if (sobol_get_bit(index, i))
|
|
{
|
|
result ^= sobol_direction_vectors[dimension][i];
|
|
}
|
|
}
|
|
|
|
return sobol_uint_to_float(result);
|
|
}
|
|
|
|
float sobol_sample_scrambled(uint32_t index, uint16_t dimension, uint32_t scramble)
|
|
{
|
|
if (dimension >= SOBOL_DIMENSIONS)
|
|
{
|
|
return 0.0f;
|
|
}
|
|
|
|
uint32_t result = 0;
|
|
for (int i = 0; i < SOBOL_BITS; i++)
|
|
{
|
|
if (sobol_get_bit(index, i))
|
|
{
|
|
result ^= sobol_direction_vectors[dimension][i];
|
|
}
|
|
}
|
|
|
|
// Apply XOR scrambling to decorrelate pixels
|
|
result ^= scramble;
|
|
|
|
return sobol_uint_to_float(result);
|
|
} |