Files
Misaki f1d3dddb9a Change project structure;
Added new c# binding;
2025-12-30 20:54:05 +09:00

94 lines
2.1 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)
{
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);
}