2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2002-10-12 11:37:38 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2008-04-16 22:40:48 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup bli
|
2011-02-27 20:37:56 +00:00
|
|
|
*/
|
|
|
|
|
2005-07-20 03:33:44 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2014-03-30 13:03:57 +11:00
|
|
|
#include <math.h>
|
2015-02-03 23:24:13 +11:00
|
|
|
#include <time.h>
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2005-07-25 20:33:10 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2006-11-29 17:01:09 +00:00
|
|
|
#include "BLI_threads.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BLI_rand.h"
|
2014-03-30 15:36:09 +02:00
|
|
|
#include "BLI_math.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2017-11-14 16:10:48 +11:00
|
|
|
/* defines BLI_INLINE */
|
2018-11-07 12:17:58 +11:00
|
|
|
#include "BLI_compiler_compat.h"
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2014-04-02 09:57:48 +11:00
|
|
|
#include "BLI_sys_types.h"
|
2014-03-30 13:12:33 +11:00
|
|
|
#include "BLI_strict_flags.h"
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
#define MULTIPLIER 0x5DEECE66Dll
|
|
|
|
#define MASK 0x0000FFFFFFFFFFFFll
|
|
|
|
#define MASK_BYTES 2
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
#define ADDEND 0xB
|
|
|
|
#define LOWSEED 0x330E
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
extern unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
|
2019-02-23 17:47:33 +11:00
|
|
|
#define hash BLI_noise_hash_uchar_512
|
2011-05-10 14:48:06 +00:00
|
|
|
|
2014-04-02 09:57:48 +11:00
|
|
|
/**
|
|
|
|
* Random Number Generator.
|
|
|
|
*/
|
2005-07-25 20:56:48 +00:00
|
|
|
struct RNG {
|
2019-04-17 06:17:24 +02:00
|
|
|
uint64_t X;
|
2005-07-25 20:56:48 +00:00
|
|
|
};
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
RNG *BLI_rng_new(unsigned int seed)
|
2005-07-25 20:33:10 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_seed(rng, seed);
|
2005-07-25 20:33:10 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return rng;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2015-04-16 16:07:46 +10:00
|
|
|
/**
|
|
|
|
* A version of #BLI_rng_new that hashes the seed.
|
|
|
|
*/
|
2013-04-15 23:12:40 +00:00
|
|
|
RNG *BLI_rng_new_srandom(unsigned int seed)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
|
2013-04-15 23:12:40 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_srandom(rng, seed);
|
2013-04-15 23:12:40 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return rng;
|
2013-04-15 23:12:40 +00:00
|
|
|
}
|
|
|
|
|
2019-02-18 16:59:31 +01:00
|
|
|
RNG *BLI_rng_copy(RNG *rng)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return MEM_dupallocN(rng);
|
2019-02-18 16:59:31 +01:00
|
|
|
}
|
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
void BLI_rng_free(RNG *rng)
|
2005-07-25 20:33:10 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(rng);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
void BLI_rng_seed(RNG *rng, unsigned int seed)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
rng->X = (((uint64_t)seed) << 16) | LOWSEED;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2015-04-16 16:07:46 +10:00
|
|
|
/**
|
|
|
|
* Use a hash table to create better seed.
|
|
|
|
*/
|
2012-10-23 13:50:44 +00:00
|
|
|
void BLI_rng_srandom(RNG *rng, unsigned int seed)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_seed(rng, seed + hash[seed & 255]);
|
|
|
|
seed = BLI_rng_get_uint(rng);
|
|
|
|
BLI_rng_seed(rng, seed + hash[seed & 255]);
|
|
|
|
seed = BLI_rng_get_uint(rng);
|
|
|
|
BLI_rng_seed(rng, seed + hash[seed & 255]);
|
2008-08-18 11:09:27 +00:00
|
|
|
}
|
|
|
|
|
2014-07-20 00:38:52 +10:00
|
|
|
BLI_INLINE void rng_step(RNG *rng)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
|
2014-07-20 00:38:52 +10:00
|
|
|
}
|
|
|
|
|
2016-06-12 00:38:49 +10:00
|
|
|
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
size_t last_len = 0;
|
|
|
|
size_t trim_len = bytes_len;
|
2016-06-12 00:38:49 +10:00
|
|
|
|
|
|
|
#define RAND_STRIDE (sizeof(rng->X) - MASK_BYTES)
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (trim_len > RAND_STRIDE) {
|
|
|
|
last_len = trim_len % RAND_STRIDE;
|
|
|
|
trim_len = trim_len - last_len;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
trim_len = 0;
|
|
|
|
last_len = bytes_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *data_src = (void *)&(rng->X);
|
|
|
|
size_t i = 0;
|
|
|
|
while (i != trim_len) {
|
|
|
|
BLI_assert(i < trim_len);
|
2016-06-12 00:38:49 +10:00
|
|
|
#ifdef __BIG_ENDIAN__
|
2019-04-17 06:17:24 +02:00
|
|
|
for (size_t j = (RAND_STRIDE + MASK_BYTES) - 1; j != MASK_BYTES - 1; j--)
|
2016-06-12 00:38:49 +10:00
|
|
|
#else
|
2019-04-17 06:17:24 +02:00
|
|
|
for (size_t j = 0; j != RAND_STRIDE; j++)
|
2016-06-12 00:38:49 +10:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
|
|
|
bytes[i++] = data_src[j];
|
|
|
|
}
|
|
|
|
rng_step(rng);
|
|
|
|
}
|
|
|
|
if (last_len) {
|
|
|
|
for (size_t j = 0; j != last_len; j++) {
|
|
|
|
bytes[i++] = data_src[j];
|
|
|
|
}
|
|
|
|
}
|
2016-06-12 00:38:49 +10:00
|
|
|
|
|
|
|
#undef RAND_STRIDE
|
|
|
|
}
|
|
|
|
|
2014-07-20 00:38:52 +10:00
|
|
|
int BLI_rng_get_int(RNG *rng)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
rng_step(rng);
|
|
|
|
return (int)(rng->X >> 17);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2014-03-30 13:12:33 +11:00
|
|
|
unsigned int BLI_rng_get_uint(RNG *rng)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
rng_step(rng);
|
|
|
|
return (unsigned int)(rng->X >> 17);
|
2014-03-30 13:12:33 +11:00
|
|
|
}
|
|
|
|
|
2015-04-16 16:07:46 +10:00
|
|
|
/**
|
|
|
|
* \return Random value (0..1), but never 1.0.
|
|
|
|
*/
|
2012-10-23 13:50:44 +00:00
|
|
|
double BLI_rng_get_double(RNG *rng)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return (double)BLI_rng_get_int(rng) / 0x80000000;
|
2005-07-25 20:33:10 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2015-04-16 16:07:46 +10:00
|
|
|
/**
|
|
|
|
* \return Random value (0..1), but never 1.0.
|
|
|
|
*/
|
2012-10-23 13:50:44 +00:00
|
|
|
float BLI_rng_get_float(RNG *rng)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return (float)BLI_rng_get_int(rng) / 0x80000000;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2014-06-14 18:12:19 +10:00
|
|
|
void BLI_rng_get_float_unit_v2(RNG *rng, float v[2])
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
|
|
|
|
v[0] = cosf(a);
|
|
|
|
v[1] = sinf(a);
|
2014-06-14 18:12:19 +10:00
|
|
|
}
|
|
|
|
|
2014-03-30 13:03:57 +11:00
|
|
|
void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
float r;
|
|
|
|
v[2] = (2.0f * BLI_rng_get_float(rng)) - 1.0f;
|
|
|
|
if ((r = 1.0f - (v[2] * v[2])) > 0.0f) {
|
|
|
|
float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
|
|
|
|
r = sqrtf(r);
|
|
|
|
v[0] = r * cosf(a);
|
|
|
|
v[1] = r * sinf(a);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
v[2] = 1.0f;
|
|
|
|
}
|
2014-03-30 13:03:57 +11:00
|
|
|
}
|
|
|
|
|
2015-01-09 11:54:51 +01:00
|
|
|
/**
|
|
|
|
* Generate a random point inside given tri.
|
|
|
|
*/
|
|
|
|
void BLI_rng_get_tri_sample_float_v2(
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG *rng, const float v1[2], const float v2[2], const float v3[2], float r_pt[2])
|
2015-01-09 11:54:51 +01:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
float u = BLI_rng_get_float(rng);
|
|
|
|
float v = BLI_rng_get_float(rng);
|
2015-01-09 11:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
float side_u[2], side_v[2];
|
2015-01-09 11:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if ((u + v) > 1.0f) {
|
|
|
|
u = 1.0f - u;
|
|
|
|
v = 1.0f - v;
|
|
|
|
}
|
2015-01-09 11:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
sub_v2_v2v2(side_u, v2, v1);
|
|
|
|
sub_v2_v2v2(side_v, v3, v1);
|
2015-01-09 11:54:51 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
copy_v2_v2(r_pt, v1);
|
|
|
|
madd_v2_v2fl(r_pt, side_u, u);
|
|
|
|
madd_v2_v2fl(r_pt, side_v, v);
|
2015-01-09 11:54:51 +01:00
|
|
|
}
|
|
|
|
|
2014-03-30 20:35:59 +11:00
|
|
|
void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot)
|
2005-07-20 03:33:44 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const size_t elem_size = (size_t)elem_size_i;
|
|
|
|
unsigned int i = elem_tot;
|
|
|
|
void *temp;
|
2012-03-19 19:27:39 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (elem_tot <= 1) {
|
|
|
|
return;
|
|
|
|
}
|
2012-03-19 19:27:39 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
temp = malloc(elem_size);
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
while (i--) {
|
|
|
|
unsigned int j = BLI_rng_get_uint(rng) % elem_tot;
|
|
|
|
if (i != j) {
|
|
|
|
void *iElem = (unsigned char *)data + i * elem_size_i;
|
|
|
|
void *jElem = (unsigned char *)data + j * elem_size_i;
|
|
|
|
memcpy(temp, iElem, elem_size);
|
|
|
|
memcpy(iElem, jElem, elem_size);
|
|
|
|
memcpy(jElem, temp, elem_size);
|
|
|
|
}
|
|
|
|
}
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
free(temp);
|
2005-07-20 03:33:44 +00:00
|
|
|
}
|
|
|
|
|
2015-04-16 16:07:46 +10:00
|
|
|
/**
|
|
|
|
* Simulate getting \a n random values.
|
|
|
|
*
|
|
|
|
* \note Useful when threaded code needs consistent values, independent of task division.
|
|
|
|
*/
|
2012-10-23 13:50:44 +00:00
|
|
|
void BLI_rng_skip(RNG *rng, int n)
|
2007-12-04 13:57:28 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
while (n--) {
|
|
|
|
rng_step(rng);
|
|
|
|
}
|
2007-12-04 13:57:28 +00:00
|
|
|
}
|
|
|
|
|
2005-07-25 20:33:10 +00:00
|
|
|
/***/
|
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
/* fill an array with random numbers */
|
|
|
|
void BLI_array_frand(float *ar, int count, unsigned int seed)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG rng;
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_srandom(&rng, seed);
|
2018-07-31 10:22:19 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
ar[i] = BLI_rng_get_float(&rng);
|
|
|
|
}
|
2018-07-31 10:22:19 +02:00
|
|
|
}
|
|
|
|
|
2013-04-15 23:12:40 +00:00
|
|
|
float BLI_hash_frand(unsigned int seed)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG rng;
|
2005-07-25 20:33:10 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_srandom(&rng, seed);
|
|
|
|
return BLI_rng_get_float(&rng);
|
2005-07-25 20:33:10 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
void BLI_array_randomize(void *data,
|
|
|
|
unsigned int elem_size,
|
|
|
|
unsigned int elem_tot,
|
|
|
|
unsigned int seed)
|
2005-07-25 20:33:10 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG rng;
|
2005-07-25 20:33:10 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_seed(&rng, seed);
|
|
|
|
BLI_rng_shuffle_array(&rng, data, elem_size, elem_tot);
|
2005-07-25 20:33:10 +00:00
|
|
|
}
|
|
|
|
|
2005-08-25 13:11:04 +00:00
|
|
|
/* ********* for threaded random ************** */
|
|
|
|
|
2006-11-29 17:01:09 +00:00
|
|
|
static RNG rng_tab[BLENDER_MAX_THREADS];
|
2005-08-25 13:11:04 +00:00
|
|
|
|
|
|
|
void BLI_thread_srandom(int thread, unsigned int seed)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (thread >= BLENDER_MAX_THREADS) {
|
|
|
|
thread = 0;
|
|
|
|
}
|
2018-06-17 16:32:54 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
|
|
|
|
seed = BLI_rng_get_uint(&rng_tab[thread]);
|
|
|
|
BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
|
|
|
|
seed = BLI_rng_get_uint(&rng_tab[thread]);
|
|
|
|
BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
|
2005-08-25 13:11:04 +00:00
|
|
|
}
|
|
|
|
|
2011-12-17 00:52:36 +00:00
|
|
|
int BLI_thread_rand(int thread)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return BLI_rng_get_int(&rng_tab[thread]);
|
2005-08-25 13:11:04 +00:00
|
|
|
}
|
|
|
|
|
2011-12-17 00:52:36 +00:00
|
|
|
float BLI_thread_frand(int thread)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return BLI_rng_get_float(&rng_tab[thread]);
|
2005-08-25 13:11:04 +00:00
|
|
|
}
|
|
|
|
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
struct RNG_THREAD_ARRAY {
|
2019-04-17 06:17:24 +02:00
|
|
|
RNG rng_tab[BLENDER_MAX_THREADS];
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
RNG_THREAD_ARRAY *BLI_rng_threaded_new(void)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
unsigned int i;
|
|
|
|
RNG_THREAD_ARRAY *rngarr = MEM_mallocN(sizeof(RNG_THREAD_ARRAY), "random_array");
|
2018-06-17 16:32:54 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (i = 0; i < BLENDER_MAX_THREADS; i++) {
|
|
|
|
BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
|
|
|
|
}
|
2018-06-17 16:32:54 +02:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return rngarr;
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(rngarr);
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return BLI_rng_get_int(&rngarr->rng_tab[thread]);
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
}
|
|
|
|
|
2017-11-14 16:10:48 +11:00
|
|
|
/* ********* Low-discrepancy sequences ************** */
|
|
|
|
|
|
|
|
/* incremental halton sequence generator, from:
|
|
|
|
* "Instant Radiosity", Keller A. */
|
|
|
|
BLI_INLINE double halton_ex(double invprimes, double *offset)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
double e = fabs((1.0 - *offset) - 1e-10);
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (invprimes >= e) {
|
|
|
|
double lasth;
|
|
|
|
double h = invprimes;
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
do {
|
|
|
|
lasth = h;
|
|
|
|
h *= invprimes;
|
|
|
|
} while (h >= e);
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
*offset += ((lasth + h) - 1.0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*offset += invprimes;
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return *offset;
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
2019-03-20 18:17:16 +11:00
|
|
|
void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const double invprime = 1.0 / (double)prime;
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
*r = 0.0;
|
2018-03-07 01:36:09 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
*r = halton_ex(invprime, &offset);
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
2019-03-20 18:17:16 +11:00
|
|
|
void BLI_halton_2d(unsigned int prime[2], double offset[2], int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
r[0] = r[1] = 0.0;
|
2018-03-07 01:36:09 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
r[i] = halton_ex(invprimes[i], &offset[i]);
|
|
|
|
}
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
2019-03-20 18:17:16 +11:00
|
|
|
void BLI_halton_3d(unsigned int prime[3], double offset[3], int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const double invprimes[3] = {
|
|
|
|
1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
r[0] = r[1] = r[2] = 0.0;
|
2018-03-07 01:36:09 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
r[i] = halton_ex(invprimes[i], &offset[i]);
|
|
|
|
}
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
2019-03-20 18:17:16 +11:00
|
|
|
void BLI_halton_2d_sequence(unsigned int prime[2], double offset[2], int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
r[s * 2 + i] = halton_ex(invprimes[i], &offset[i]);
|
|
|
|
}
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/* From "Sampling with Hammersley and Halton Points" TT Wong
|
|
|
|
* Appendix: Source Code 1 */
|
|
|
|
BLI_INLINE double radical_inverse(unsigned int n)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
double u = 0;
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* This reverse the bitwise representation
|
|
|
|
* around the decimal point. */
|
|
|
|
for (double p = 0.5; n; p *= 0.5, n >>= 1) {
|
|
|
|
if (n & 1) {
|
|
|
|
u += p;
|
|
|
|
}
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return u;
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
2019-03-20 18:17:16 +11:00
|
|
|
void BLI_hammersley_1d(unsigned int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
*r = radical_inverse(n);
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|
|
|
|
|
2019-03-20 18:17:16 +11:00
|
|
|
void BLI_hammersley_2d_sequence(unsigned int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (unsigned int s = 0; s < n; s++) {
|
|
|
|
r[s * 2 + 0] = (double)(s + 0.5) / (double)n;
|
|
|
|
r[s * 2 + 1] = radical_inverse(s);
|
|
|
|
}
|
2017-11-14 16:10:48 +11:00
|
|
|
}
|