BLI_rand : Make use of BLI_halton and BLI_hammersley

This commit is contained in:
Clément Foucault
2017-09-26 21:38:23 +02:00
parent 47e6d53c8a
commit b96c70f9b2
7 changed files with 31 additions and 91 deletions

View File

@@ -312,19 +312,16 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
static void hammersley_create(float *out, int n, int seed, float amount)
{
RNG *rng;
double p, t, offs[2];
int k, kk;
double offs[2], t;
rng = BLI_rng_new(31415926 + n + seed);
offs[0] = BLI_rng_get_double(rng) + (double)amount;
offs[1] = BLI_rng_get_double(rng) + (double)amount;
BLI_rng_free(rng);
for (k = 0; k < n; k++) {
t = 0;
for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
if (kk & 1) /* kk mod 2 = 1 */
t += p;
for (int k = 0; k < n; k++) {
BLI_hammersley_1D(k, &t);
out[2*k + 0] = fmod((double)k/(double)n + offs[0], 1.0);
out[2*k + 1] = fmod(t + offs[1], 1.0);

View File

@@ -277,19 +277,6 @@ static int matcap_to_index(int matcap)
return 0;
}
/* Van der Corput sequence */
/* TODO this is duplicated code from eevee_lightprobes.c */
/* From http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */
static float radical_inverse(int i) {
unsigned int bits = (unsigned int)i;
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return (float)bits * 2.3283064365386963e-10f;
}
/* Using Hammersley distribution */
static float *create_disk_samples(int num_samples)
{
@@ -299,7 +286,10 @@ static float *create_disk_samples(int num_samples)
for (int i = 0; i < num_samples; i++) {
float r = (i + 0.5f) * num_samples_inv;
float phi = radical_inverse(i) * 2.0f * M_PI;
double dphi;
BLI_hammersley_1D(i, &dphi);
float phi = (float)dphi * 2.0f * M_PI;
texels[i][0] = cosf(phi);
texels[i][1] = sinf(phi);
/* This deliberatly distribute more samples

View File

@@ -43,7 +43,7 @@
#include "DEG_depsgraph.h"
#include "BLI_dynstr.h"
#include "BLI_jitter.h"
#include "BLI_rand.h"
#include "eevee_private.h"
#include "GPU_texture.h"
@@ -764,7 +764,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
if (effects->taa_total_sample != taa_pref_samples) {
effects->taa_total_sample = taa_pref_samples;
BLI_jitter_init(effects->taa_jit_ofs, effects->taa_total_sample);
}
DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
@@ -779,10 +778,16 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
effects->taa_alpha = 1.0f - (1.0f / (float)(effects->taa_current_sample));
double ht_point[2];
double ht_offset[2] = {0.0, 0.0};
unsigned int ht_primes[2] = {2, 3};
BLI_halton_2D(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point);
window_translate_m4(
effects->overide_winmat, persmat,
(effects->taa_jit_ofs[effects->taa_current_sample][0] * 2.0f) / viewport_size[0],
(effects->taa_jit_ofs[effects->taa_current_sample][1] * 2.0f) / viewport_size[1]);
((float)(ht_point[0]) * 2.0f - 1.0f) / viewport_size[0],
((float)(ht_point[1]) * 2.0f - 1.0f) / viewport_size[1]);
mul_m4_m4m4(effects->overide_persmat, effects->overide_winmat, viewmat);
invert_m4_m4(effects->overide_persinv, effects->overide_persmat);

View File

@@ -43,22 +43,6 @@ extern GlobalsUboStorage ts;
/* *********** FUNCTIONS *********** */
/* TODO : put this somewhere in BLI */
static float halton_1D(int prime, int n)
{
float inv_prime = 1.0f / (float)prime;
float f = 1.0f;
float r = 0.0f;
while (n > 0) {
f = f * inv_prime;
r += f * (n % prime);
n = (int)(n * inv_prime);
}
return r;
}
static void EEVEE_engine_init(void *ved)
{
EEVEE_Data *vedata = (EEVEE_Data *)ved;
@@ -192,11 +176,12 @@ static void EEVEE_draw_scene(void *vedata)
EEVEE_update_util_texture(rand);
}
else if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) && (stl->effects->taa_current_sample > 1)) {
rand = halton_1D(2, stl->effects->taa_current_sample - 1);
double r;
BLI_halton_1D(2, 0.0, stl->effects->taa_current_sample - 1, &r);
/* Set jitter offset */
/* PERF This is killing perf ! */
EEVEE_update_util_texture(rand);
EEVEE_update_util_texture((float)r);
}
while (loop_ct--) {

View File

@@ -32,6 +32,7 @@
#include "BKE_object.h"
#include "BLI_dynstr.h"
#include "BLI_rand.h"
#include "ED_screen.h"
@@ -97,18 +98,6 @@ extern GlobalsUboStorage ts;
/* *********** FUNCTIONS *********** */
/* Van der Corput sequence */
/* From http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */
static float radical_inverse(int i) {
unsigned int bits = (unsigned int)i;
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return (float)bits * 2.3283064365386963e-10f;
}
static struct GPUTexture *create_hammersley_sample_texture(int samples)
{
struct GPUTexture *tex;
@@ -116,7 +105,9 @@ static struct GPUTexture *create_hammersley_sample_texture(int samples)
int i;
for (i = 0; i < samples; i++) {
float phi = radical_inverse(i) * 2.0f * M_PI;
double dphi;
BLI_hammersley_1D(i, &dphi);
float phi = (float)dphi * 2.0f * M_PI;
texels[i][0] = cosf(phi);
texels[i][1] = sinf(phi);
}

View File

@@ -370,7 +370,6 @@ typedef struct EEVEE_EffectsInfo {
/* Temporal Anti Aliasing */
int taa_current_sample;
int taa_total_sample;
float taa_jit_ofs[32][2];
float taa_alpha;
float prev_drw_persmat[4][4];
float overide_persmat[4][4];

View File

@@ -995,7 +995,7 @@ static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)
/* **************** QMC sampling *************** */
static void halton_sample(double *ht_invprimes, double *ht_nums, double *v)
static void UNUSED_FUNCTION(halton_sample)(double *ht_invprimes, double *ht_nums, double *v)
{
/* incremental halton sequence generator, from:
* "Instant Radiosity", Keller A. */
@@ -1022,26 +1022,6 @@ static void halton_sample(double *ht_invprimes, double *ht_nums, double *v)
}
}
/* Generate Hammersley points in [0,1)^2
* From Lucille renderer */
static void hammersley_create(double *out, int n)
{
double p, t;
int k, kk;
for (k = 0; k < n; k++) {
t = 0;
for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1) {
if (kk & 1) { /* kk mod 2 = 1 */
t += p;
}
}
out[2 * k + 0] = (double)k / (double)n;
out[2 * k + 1] = t;
}
}
static struct QMCSampler *QMC_initSampler(int type, int tot)
{
QMCSampler *qsa = MEM_callocN(sizeof(QMCSampler), "qmc sampler");
@@ -1051,7 +1031,7 @@ static struct QMCSampler *QMC_initSampler(int type, int tot)
qsa->type = type;
if (qsa->type==SAMP_TYPE_HAMMERSLEY)
hammersley_create(qsa->samp2d, qsa->tot);
BLI_hammersley_2D_sequence(qsa->tot, qsa->samp2d);
return qsa;
}
@@ -1069,20 +1049,13 @@ static void QMC_initPixel(QMCSampler *qsa, int thread)
/* generate a new randomized halton sequence per pixel
* to alleviate qmc artifacts and make it reproducible
* between threads/frames */
double ht_invprimes[2], ht_nums[2];
double r[2];
int i;
double ht_offset[2];
unsigned int ht_primes[2] = {2, 3};
ht_nums[0] = BLI_thread_frand(thread);
ht_nums[1] = BLI_thread_frand(thread);
ht_invprimes[0] = 0.5;
ht_invprimes[1] = 1.0/3.0;
ht_offset[0] = BLI_thread_frand(thread);
ht_offset[1] = BLI_thread_frand(thread);
for (i=0; i< qsa->tot; i++) {
halton_sample(ht_invprimes, ht_nums, r);
qsa->samp2d[2*i+0] = r[0];
qsa->samp2d[2*i+1] = r[1];
}
BLI_halton_2D_sequence(ht_primes, ht_offset, qsa->tot, qsa->samp2d);
}
}