From c341dd0585b73a0526573c085e6d265b0daf6738 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 14 Feb 2018 10:20:26 +0100 Subject: [PATCH 1/7] CMake: Fix cimpilation error when CUDA dynload is disabled but toolkit is not installed --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0a0b4bd27f..f5b80efef85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -744,6 +744,15 @@ if(WITH_AUDASPACE) endif() endif() +# Auto-enable CUDA dynload if toolkit is not found. +if(NOT WITH_CUDA_DYNLOAD) + find_package(CUDA) + if (NOT CUDA_FOUND) + message("CUDA toolkit not found, using dynamic runtime loading of libraries instead") + set(WITH_CUDA_DYNLOAD ON) + endif() +endif() + #----------------------------------------------------------------------------- # Check for valid directories # ... a partial checkout may cause this. From a966852362bbeffab9e8b297da2d75bf53e69051 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 14 Feb 2018 10:31:04 +0100 Subject: [PATCH 2/7] CMake: Expose Cycles devices support as CMake option Handy to disable GPU based devices when it's needed to run Valgrind. --- CMakeLists.txt | 7 +++++++ intern/cycles/CMakeLists.txt | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5b80efef85..5b2bd2fd460 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -420,6 +420,13 @@ mark_as_advanced(WITH_CYCLES_LOGGING) mark_as_advanced(WITH_CYCLES_DEBUG) mark_as_advanced(WITH_CYCLES_NATIVE_ONLY) +option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles CUDA compute support" ON) +option(WITH_CYCLES_DEVICE_OPENCL "Enable Cycles OpenCL compute support" ON) +option(WITH_CYCLES_NETWORK "Enable Cycles compute over network support (EXPERIMENTAL and unfinished)" OFF) +mark_as_advanced(WITH_CYCLES_DEVICE_CUDA) +mark_as_advanced(WITH_CYCLES_DEVICE_OPENCL) +mark_as_advanced(WITH_CYCLES_NETWORK) + option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON) mark_as_advanced(WITH_CUDA_DYNLOAD) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index e7b934ec74f..9df1e91e239 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -167,8 +167,13 @@ if(WITH_CYCLES_OPENSUBDIV) ) endif() -set(WITH_CYCLES_DEVICE_OPENCL TRUE) -set(WITH_CYCLES_DEVICE_CUDA TRUE) +if(WITH_CYCLES_STANDALONE) + set(WITH_CYCLES_DEVICE_OPENCL TRUE) + set(WITH_CYCLES_DEVICE_CUDA TRUE) + # Experimental and unfinished. + set(WITH_CYCLES_NETWORK FALSE) +endif() +# TODO(sergey): Consider removing it, only causes confusion in interface. set(WITH_CYCLES_DEVICE_MULTI TRUE) if(CYCLES_STANDALONE_REPOSITORY) From c09e4ae08a4d97beaf919e6434eca4956a47d401 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 14 Feb 2018 11:21:27 +0100 Subject: [PATCH 3/7] Math utils: Add clamping functions --- source/blender/blenlib/BLI_math_base.h | 4 ++++ .../blender/blenlib/intern/math_base_inline.c | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 377b9325717..3b24cae018d 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -132,6 +132,10 @@ MINLINE int max_iiii(int a, int b, int c, int d); MINLINE size_t min_zz(size_t a, size_t b); MINLINE size_t max_zz(size_t a, size_t b); +MINLINE int clamp_i(int value, int min, int max); +MINLINE float clamp_f(float value, float min, float max); +MINLINE size_t clamp_z(size_t value, size_t min, size_t max); + MINLINE int compare_ff(float a, float b, const float max_diff); MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps); diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 2f5b0f420b1..144198f2c06 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -324,6 +324,26 @@ MINLINE size_t max_zz(size_t a, size_t b) return (b < a) ? a : b; } +MINLINE int clamp_i(int value, int min, int max) +{ + return min_ii(max_ii(value, min), max); +} + +MINLINE float clamp_f(float value, float min, float max) +{ + if (value > max) { + return max; + } else if (value < min) { + return min; + } + return value; +} + +MINLINE size_t clamp_z(size_t value, size_t min, size_t max) +{ + return min_zz(max_zz(value, min), max); +} + /** * Almost-equal for IEEE floats, using absolute difference method. * From 1c34825b4f1b8dbc658c60120dacb2600936bdd9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 14 Feb 2018 11:36:46 +0100 Subject: [PATCH 4/7] Hair child: Use clamp function to clamp curve evaluation Avoids redundant calls to the curve evaluation. --- source/blender/blenkernel/intern/particle_child.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index bfcda89a635..667d51b3536 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -565,7 +565,7 @@ static float do_clump_level(float result[3], const float co[3], const float par_ float clump = 0.0f; if (clumpcurve) { - clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f)); + clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f)); interp_v3_v3v3(result, co, par_co, clump); } @@ -655,7 +655,7 @@ static void do_rough_curve(const float loc[3], float mat[4][4], float time, floa if (!roughcurve) return; - fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f); + fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f); copy_v3_v3(rco, loc); mul_v3_fl(rco, time); From 800305964613691d5def1c5e02ff3f5101db573b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 14 Feb 2018 11:46:33 +0100 Subject: [PATCH 5/7] Particles: Cleanup, remove trailign whitespace --- .../blenkernel/intern/particle_child.c | 140 +++++++++--------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index 667d51b3536..d002c6a6108 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -67,7 +67,7 @@ static void get_strand_normal(Material *ma, const float surfnor[3], float surfdi else { copy_v3_v3(vnor, nor); } - + if (ma->strand_surfnor > 0.0f) { if (ma->strand_surfnor > surfdist) { blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor; @@ -85,7 +85,7 @@ typedef struct ParticlePathIterator { ParticleCacheKey *key; int index; float time; - + ParticleCacheKey *parent_key; float parent_rotation[4]; } ParticlePathIterator; @@ -94,11 +94,11 @@ static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *key ParticleCacheKey *parent, int index) { BLI_assert(index >= 0 && index < totkeys); - + iter->key = keys + index; iter->index = index; iter->time = (float)index / (float)(totkeys - 1); - + if (parent) { iter->parent_key = parent + index; if (index > 0) @@ -114,7 +114,7 @@ static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *key typedef struct ParticlePathModifier { struct ParticlePathModifier *next, *prev; - + void (*apply)(ParticleCacheKey *keys, int totkeys, ParticleCacheKey *parent_keys); } ParticlePathModifier; @@ -133,7 +133,7 @@ static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const { /* Creates a logarithmic spiral: * r(theta) = a * exp(b * theta) - * + * * The "density" parameter b is defined by the shape parameter * and goes up to the Golden Spiral for 1.0 * https://en.wikipedia.org/wiki/Golden_spiral @@ -142,33 +142,33 @@ static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const /* angle of the spiral against the curve (rotated opposite to make a smooth transition) */ const float start_angle = ((b != 0.0f) ? atanf(1.0f / b) : (float)-M_PI_2) + (b > 0.0f ? -(float)M_PI_2 : (float)M_PI_2); - + float spiral_axis[3], rot[3][3]; float vec[3]; - + float theta = freq * time * 2.0f * (float)M_PI; float radius = amplitude * expf(b * theta); - + /* a bit more intuitive than using negative frequency for this */ if (amplitude < 0.0f) theta = -theta; - + cross_v3_v3v3(spiral_axis, dir, kink); normalize_v3(spiral_axis); - + mul_v3_v3fl(vec, kink, -radius); - + axis_angle_normalized_to_mat3(rot, spiral_axis, theta); mul_m3_v3(rot, vec); - + madd_v3_v3fl(vec, kink, amplitude); - + axis_angle_normalized_to_mat3(rot, spiral_axis, -start_angle); mul_m3_v3(rot, vec); - + add_v3_v3v3(result, spiral_start, vec); } - + copy_v3_v3(state->co, result); } @@ -180,7 +180,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co const int seed = ctx->sim.psys->child_seed + (int)(cpa - ctx->sim.psys->child); const int totkeys = ctx->segments + 1; const int extrakeys = ctx->extra_segments; - + float kink_amp_random = part->kink_amp_random; float kink_amp = part->kink_amp * (1.0f - kink_amp_random * psys_frand(ctx->sim.psys, 93541 + seed)); float kink_freq = part->kink_freq; @@ -189,11 +189,11 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co float rough1 = part->rough1; float rough2 = part->rough2; float rough_end = part->rough_end; - + ParticlePathIterator iter; ParticleCacheKey *key; int k; - + float dir[3]; float spiral_start[3] = {0.0f, 0.0f, 0.0f}; float spiral_start_time = 0.0f; @@ -204,7 +204,7 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co float cut_time; int start_index = 0, end_index = 0; float kink_base[3]; - + if (ptex) { kink_amp *= ptex->kink_amp; kink_freq *= ptex->kink_freq; @@ -212,44 +212,44 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co rough2 *= ptex->rough2; rough_end *= ptex->roughe; } - + cut_time = (totkeys - 1) * ptex->length; zero_v3(spiral_start); - + for (k = 0, key = keys; k < totkeys-1; k++, key++) { if ((float)(k + 1) >= cut_time) { float fac = cut_time - (float)k; ParticleCacheKey *par = parent_keys + k; - + start_index = k + 1; end_index = start_index + extrakeys; - + spiral_start_time = ((float)k + fac) / (float)(totkeys - 1); interp_v3_v3v3(spiral_start, key->co, (key+1)->co, fac); - + interp_v3_v3v3(spiral_par_co, par->co, (par+1)->co, fac); interp_v3_v3v3(spiral_par_vel, par->vel, (par+1)->vel, fac); interp_qt_qtqt(spiral_par_rot, par->rot, (par+1)->rot, fac); - + break; } } - + zero_v3(dir); - + zero_v3(kink_base); kink_base[part->kink_axis] = 1.0f; mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base); - + for (k = 0, key = keys; k < end_index; k++, key++) { float par_time; float *par_co, *par_vel, *par_rot; - + psys_path_iter_get(&iter, keys, end_index, NULL, k); if (k < start_index) { sub_v3_v3v3(dir, (key+1)->co, key->co); normalize_v3(dir); - + par_time = (float)k / (float)(totkeys - 1); par_co = parent_keys[k].co; par_vel = parent_keys[k].vel; @@ -258,36 +258,36 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co else { float spiral_time = (float)(k - start_index) / (float)(extrakeys-1); float kink[3], tmp[3]; - + /* use same time value for every point on the spiral */ par_time = spiral_start_time; par_co = spiral_par_co; par_vel = spiral_par_vel; par_rot = spiral_par_rot; - + project_v3_v3v3(tmp, kink_base, dir); sub_v3_v3v3(kink, kink_base, tmp); normalize_v3(kink); - + if (kink_axis_random > 0.0f) { float a = kink_axis_random * (psys_frand(ctx->sim.psys, 7112 + seed) * 2.0f - 1.0f) * (float)M_PI; float rot[3][3]; - + axis_angle_normalized_to_mat3(rot, dir, a); mul_m3_v3(rot, kink); } - + do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start); } - + /* apply different deformations to the child path */ do_child_modifiers(ctx, &ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time); } - + totlen = 0.0f; for (k = 0, key = keys; k < end_index-1; k++, key++) totlen += len_v3v3((key+1)->co, key->co); - + *r_totkeys = end_index; *r_max_length = totlen; } @@ -318,12 +318,12 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod struct Material *ma = ctx->ma; const bool draw_col_ma = (part->draw_col == PART_DRAW_COL_MAT); const bool use_length_check = !ELEM(part->kink, PART_KINK_SPIRAL); - + ParticlePathModifier *mod; ParticleCacheKey *key; int totkeys, k; float max_length; - + #if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */ for (mod = modifiers->first; mod; mod = mod->next) { mod->apply(keys, totkeys, parent_keys); @@ -331,23 +331,23 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod #else (void)modifiers; (void)mod; - + if (part->kink == PART_KINK_SPIRAL) { do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length); keys->segments = totkeys - 1; } else { ParticlePathIterator iter; - + totkeys = ctx->segments + 1; max_length = ptex->length; - + for (k = 0, key = keys; k < totkeys; k++, key++) { ParticleKey *par; - + psys_path_iter_get(&iter, keys, totkeys, parent_keys, k); par = (ParticleKey *)iter.parent_key; - + /* apply different deformations to the child path */ do_child_modifiers(ctx, &ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time); } @@ -367,11 +367,11 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod if (k >= 2) { sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co); mul_v3_fl((key-1)->vel, 0.5); - + if (ma && draw_col_ma) get_strand_normal(ma, ornor, cur_length, (key-1)->vel); } - + if (use_length_check && k > 1) { float dvec[3]; /* check if path needs to be cut before actual end of data points */ @@ -388,7 +388,7 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod /* last key */ sub_v3_v3v3(key->vel, key->co, (key-1)->co); } - + if (ma && draw_col_ma) { copy_v3_v3(key->col, &ma->r); get_strand_normal(ma, ornor, cur_length, key->vel); @@ -419,7 +419,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], } t = time * freq * (float)M_PI; - + if (smooth_start) { dt = fabsf(t); /* smooth the beginning of kink */ @@ -434,7 +434,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], if (obmat) mul_mat3_m4_v3(obmat, kink); - + mul_qt_v3(par_rot, kink); /* make sure kink is normal to strand */ @@ -450,12 +450,12 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], case PART_KINK_CURL: { float curl_offset[3]; - + /* rotate kink vector around strand tangent */ mul_v3_v3fl(curl_offset, kink, amplitude); axis_angle_to_quat(q1, par_vel, t); mul_qt_v3(q1, curl_offset); - + interp_v3_v3v3(par_vec, state->co, par_co, flat); add_v3_v3v3(result, par_vec, curl_offset); break; @@ -494,7 +494,7 @@ void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], float z_vec[3] = {0.f, 0.f, 1.f}; float vec_one[3], state_co[3]; float inp_y, inp_z, length; - + if (par_rot) { mul_qt_v3(par_rot, y_vec); mul_qt_v3(par_rot, z_vec); @@ -563,10 +563,10 @@ static float do_clump_level(float result[3], const float co[3], const float par_ float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve) { float clump = 0.0f; - + if (clumpcurve) { clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f)); - + interp_v3_v3v3(result, co, par_co, clump); } else if (clumpfac != 0.0f) { @@ -584,7 +584,7 @@ static float do_clump_level(float result[3], const float co[3], const float par_ interp_v3_v3v3(result, co, par_co, clump); } - + return clump; } @@ -592,21 +592,21 @@ float do_clump(ParticleKey *state, const float par_co[3], float time, const floa bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve) { float clump; - + if (use_clump_noise && clump_noise_size != 0.0f) { float center[3], noisevec[3]; float da[4], pa[12]; - + mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size); voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0); mul_v3_fl(&pa[0], clump_noise_size); add_v3_v3v3(center, par_co, &pa[0]); - + do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve); } - + clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve); - + return clump; } @@ -651,18 +651,18 @@ static void do_rough_curve(const float loc[3], float mat[4][4], float time, floa { float rough[3]; float rco[3]; - + if (!roughcurve) return; - + fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f); - + copy_v3_v3(rco, loc); mul_v3_fl(rco, time); rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); - + madd_v3_v3fl(state->co, mat[0], fac * rough[0]); madd_v3_v3fl(state->co, mat[1], fac * rough[1]); madd_v3_v3fl(state->co, mat[2], fac * rough[2]); @@ -707,14 +707,14 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, if (guided == 0) { float orco_offset[3]; float clump; - + sub_v3_v3v3(orco_offset, orco, par_orco); clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f, part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve); if (kink_freq != 0.f) { kink_amp *= (1.f - kink_amp_clump * clump); - + do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape, kink_amp, part->kink_flat, part->kink, part->kink_axis, sim->ob->obmat, smooth_start); @@ -727,13 +727,13 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, else { if (rough1 > 0.f) do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state); - + if (rough2 > 0.f) { float vec[3]; psys_frand_vec(sim->psys, i + 27, vec); do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state); } - + if (rough_end > 0.f) { float vec[3]; psys_frand_vec(sim->psys, i + 27, vec); From c8e661706fcdd88f1cf371f2e5e4eb76bf09fda3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 14 Feb 2018 11:52:58 +0100 Subject: [PATCH 6/7] Particles: Avoid multiple function declarations in multiple places This makes it really hard to spot errors when function signature changes. --- source/blender/blenkernel/CMakeLists.txt | 1 + source/blender/blenkernel/intern/particle.c | 10 +---- .../blenkernel/intern/particle_child.c | 10 +---- source/blender/blenkernel/particle_private.h | 42 +++++++++++++++++++ 4 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 source/blender/blenkernel/particle_private.h diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 3fc2c3f8eb0..6ddc12e435b 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -301,6 +301,7 @@ set(SRC depsgraph_private.h nla_private.h tracking_private.h + particle_private.h intern/CCGSubSurf.h intern/CCGSubSurf_inline.h intern/CCGSubSurf_intern.h diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 26e7562590d..2b5c293932a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -88,6 +88,8 @@ #include "RE_render_ext.h" +#include "particle_private.h" + unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT]; unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT]; float PSYS_FRAND_BASE[PSYS_FRAND_COUNT]; @@ -107,9 +109,6 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex); static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra); -extern void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, - ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3], - ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t); /* few helpers for countall etc. */ int count_particles(ParticleSystem *psys) @@ -1797,11 +1796,6 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in /* Path Cache */ /************************************************/ -extern void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat, - short type, short axis, float obmat[4][4], int smooth_start); -extern float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump, - bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve); - void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) { EffectedPoint point; diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index d002c6a6108..d420f331707 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -37,15 +37,9 @@ #include "BKE_colortools.h" #include "BKE_particle.h" -struct Material; +#include "particle_private.h" -void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat, - short type, short axis, float obmat[4][4], int smooth_start); -float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump, - bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve); -void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, - ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3], - ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t); +struct Material; static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3]) { diff --git a/source/blender/blenkernel/particle_private.h b/source/blender/blenkernel/particle_private.h new file mode 100644 index 00000000000..b4878807df7 --- /dev/null +++ b/source/blender/blenkernel/particle_private.h @@ -0,0 +1,42 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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 + * of the License, or (at your option) any later version. + * + * 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, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/particle_private.h + * \ingroup bke + */ + +#ifndef __PARTICLE_PRIVATE_H__ +#define __PARTICLE_PRIVATE_H__ + +void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat, + short type, short axis, float obmat[4][4], int smooth_start); +float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump, + bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve); +void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, + ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3], + ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t); + +#endif /* __PARTICLE_PRIVATE_H__ */ From f6107af4cf4d907495e2e9c18e5866fd1d420650 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Feb 2018 14:32:38 +0100 Subject: [PATCH 7/7] Cycles: change Index output of Hair and Particle Info to Random, in 0..1 range. These are used for randomization, so it's convenient if the index is already hashed and consistent with the Object Info node. --- intern/cycles/blender/blender_curves.cpp | 20 ++++++------------- intern/cycles/kernel/geom/geom_object.h | 2 +- intern/cycles/kernel/kernel_types.h | 2 +- intern/cycles/kernel/osl/osl_services.cpp | 15 ++++---------- intern/cycles/kernel/osl/osl_services.h | 3 ++- .../cycles/kernel/shaders/node_hair_info.osl | 4 ++-- .../kernel/shaders/node_particle_info.osl | 4 ++-- intern/cycles/kernel/svm/svm_geometry.h | 6 +++--- intern/cycles/kernel/svm/svm_types.h | 4 ++-- intern/cycles/render/attribute.cpp | 6 +++--- intern/cycles/render/nodes.cpp | 18 ++++++++--------- intern/cycles/render/particles.cpp | 4 +++- intern/cycles/util/util_hash.h | 5 +++++ source/blender/blenlib/BLI_hash.h | 5 +++++ source/blender/gpu/intern/gpu_draw.c | 4 ++-- .../gpu/shaders/gpu_shader_material.glsl | 4 ++-- .../shader/nodes/node_shader_hair_info.c | 2 +- .../shader/nodes/node_shader_particle_info.c | 2 +- 18 files changed, 54 insertions(+), 56 deletions(-) diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index c8eb879e5cb..f7cb0b66d29 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -25,6 +25,7 @@ #include "blender/blender_util.h" #include "util/util_foreach.h" +#include "util/util_hash.h" #include "util/util_logging.h" CCL_NAMESPACE_BEGIN @@ -565,12 +566,12 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa return; Attribute *attr_intercept = NULL; - Attribute *attr_index = NULL; + Attribute *attr_random = NULL; if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT); - if(mesh->need_attribute(scene, ATTR_STD_CURVE_INDEX)) - attr_index = mesh->curve_attributes.add(ATTR_STD_CURVE_INDEX); + if(mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) + attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM); /* compute and reserve size of arrays */ for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { @@ -615,8 +616,8 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa num_curve_keys++; } - if(attr_index != NULL) { - attr_index->add(num_curves); + if(attr_random != NULL) { + attr_random->add(hash_int_01(num_curves)); } mesh->add_curve(num_keys, CData->psys_shader[sys]); @@ -625,15 +626,6 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa } } - if(attr_index != NULL) { - /* Normalize index to 0..1 range. */ - float *curve_index = attr_index->data_float(); - const float norm_factor = 1.0f / (float)num_curves; - for(int i = 0; i < num_curves; ++i) { - curve_index[i] *= norm_factor; - } - } - /* check allocation */ if((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) { VLOG(1) << "Allocation failed, clearing data"; diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index fa0dff4bd57..a63d180d450 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -352,7 +352,7 @@ ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd) /* Particle data from which object was instanced */ -ccl_device_inline float particle_index(KernelGlobals *kg, int particle) +ccl_device_inline float particle_random(KernelGlobals *kg, int particle) { int offset = particle*PARTICLE_SIZE; float4 f = kernel_tex_fetch(__particles, offset + 0); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 0bb5873e75c..aeb63b4a65e 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -772,7 +772,7 @@ typedef enum AttributeStandard { ATTR_STD_MOTION_VERTEX_NORMAL, ATTR_STD_PARTICLE, ATTR_STD_CURVE_INTERCEPT, - ATTR_STD_CURVE_INDEX, + ATTR_STD_CURVE_RANDOM, ATTR_STD_PTEX_FACE_ID, ATTR_STD_PTEX_UV, ATTR_STD_VOLUME_DENSITY, diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 3789073f344..c4128e84f5c 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -82,7 +82,7 @@ ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated"); ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv"); ustring OSLRenderServices::u_material_index("material:index"); ustring OSLRenderServices::u_object_random("object:random"); -ustring OSLRenderServices::u_particle_index("particle:index"); +ustring OSLRenderServices::u_particle_random("particle:random"); ustring OSLRenderServices::u_particle_age("particle:age"); ustring OSLRenderServices::u_particle_lifetime("particle:lifetime"); ustring OSLRenderServices::u_particle_location("particle:location"); @@ -96,11 +96,10 @@ ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices"); ustring OSLRenderServices::u_geom_name("geom:name"); ustring OSLRenderServices::u_geom_undisplaced("geom:undisplaced"); ustring OSLRenderServices::u_is_smooth("geom:is_smooth"); -#ifdef __HAIR__ ustring OSLRenderServices::u_is_curve("geom:is_curve"); ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness"); ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal"); -#endif +ustring OSLRenderServices::u_curve_random("geom:curve_random"); ustring OSLRenderServices::u_path_ray_length("path:ray_length"); ustring OSLRenderServices::u_path_ray_depth("path:ray_depth"); ustring OSLRenderServices::u_path_diffuse_depth("path:diffuse_depth"); @@ -653,9 +652,9 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD } /* Particle Attributes */ - else if(name == u_particle_index) { + else if(name == u_particle_random) { int particle_id = object_particle_id(kg, sd->object); - float f = particle_index(kg, particle_id); + float f = particle_random(kg, particle_id); return set_attribute_float(f, type, derivatives, val); } else if(name == u_particle_age) { @@ -701,11 +700,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD return set_attribute_int(3, type, derivatives, val); } else if((name == u_geom_trianglevertices || name == u_geom_polyvertices) -#ifdef __HAIR__ && sd->type & PRIMITIVE_ALL_TRIANGLE) -#else - ) -#endif { float3 P[3]; @@ -730,7 +725,6 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0); return set_attribute_float(f, type, derivatives, val); } -#ifdef __HAIR__ /* Hair Attributes */ else if(name == u_is_curve) { float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0; @@ -744,7 +738,6 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD float3 f = curve_tangent_normal(kg, sd); return set_attribute_float3(f, type, derivatives, val); } -#endif else return false; } diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 642529655bf..2f2dc124a98 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -146,7 +146,7 @@ public: static ustring u_geom_dupli_uv; static ustring u_material_index; static ustring u_object_random; - static ustring u_particle_index; + static ustring u_particle_random; static ustring u_particle_age; static ustring u_particle_lifetime; static ustring u_particle_location; @@ -163,6 +163,7 @@ public: static ustring u_is_curve; static ustring u_curve_thickness; static ustring u_curve_tangent_normal; + static ustring u_curve_random; static ustring u_path_ray_length; static ustring u_path_ray_depth; static ustring u_path_diffuse_depth; diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl index 79995bdbfc3..19216f67579 100644 --- a/intern/cycles/kernel/shaders/node_hair_info.osl +++ b/intern/cycles/kernel/shaders/node_hair_info.osl @@ -21,12 +21,12 @@ shader node_hair_info( output float Intercept = 0.0, output float Thickness = 0.0, output normal TangentNormal = N, - output float Index = 0) + output float Random = 0) { getattribute("geom:is_curve", IsStrand); getattribute("geom:curve_intercept", Intercept); getattribute("geom:curve_thickness", Thickness); getattribute("geom:curve_tangent_normal", TangentNormal); - getattribute("geom:curve_index", Index); + getattribute("geom:curve_random", Random); } diff --git a/intern/cycles/kernel/shaders/node_particle_info.osl b/intern/cycles/kernel/shaders/node_particle_info.osl index 768b7753d02..05358400bf8 100644 --- a/intern/cycles/kernel/shaders/node_particle_info.osl +++ b/intern/cycles/kernel/shaders/node_particle_info.osl @@ -17,7 +17,7 @@ #include "stdosl.h" shader node_particle_info( - output float Index = 0.0, + output float Random = 0.0, output float Age = 0.0, output float Lifetime = 0.0, output point Location = point(0.0, 0.0, 0.0), @@ -25,7 +25,7 @@ shader node_particle_info( output vector Velocity = point(0.0, 0.0, 0.0), output vector AngularVelocity = point(0.0, 0.0, 0.0)) { - getattribute("particle:index", Index); + getattribute("particle:random", Random); getattribute("particle:age", Age); getattribute("particle:lifetime", Lifetime); getattribute("particle:location", Location); diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 6c88d150b60..2f85a801112 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -114,9 +114,9 @@ ccl_device void svm_node_particle_info(KernelGlobals *kg, uint out_offset) { switch(type) { - case NODE_INFO_PAR_INDEX: { + case NODE_INFO_PAR_RANDOM: { int particle_id = object_particle_id(kg, sd->object); - stack_store_float(stack, out_offset, particle_index(kg, particle_id)); + stack_store_float(stack, out_offset, particle_random(kg, particle_id)); break; } case NODE_INFO_PAR_AGE: { @@ -180,7 +180,7 @@ ccl_device void svm_node_hair_info(KernelGlobals *kg, } case NODE_INFO_CURVE_INTERCEPT: break; /* handled as attribute */ - case NODE_INFO_CURVE_INDEX: + case NODE_INFO_CURVE_RANDOM: break; /* handled as attribute */ case NODE_INFO_CURVE_THICKNESS: { data = curve_thickness(kg, sd); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index b3a2cf6e9ae..9e19ab4444d 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -160,7 +160,7 @@ typedef enum NodeObjectInfo { } NodeObjectInfo; typedef enum NodeParticleInfo { - NODE_INFO_PAR_INDEX, + NODE_INFO_PAR_RANDOM, NODE_INFO_PAR_AGE, NODE_INFO_PAR_LIFETIME, NODE_INFO_PAR_LOCATION, @@ -177,7 +177,7 @@ typedef enum NodeHairInfo { /*fade for minimum hair width transpency*/ /*NODE_INFO_CURVE_FADE,*/ NODE_INFO_CURVE_TANGENT_NORMAL, - NODE_INFO_CURVE_INDEX, + NODE_INFO_CURVE_RANDOM, } NodeHairInfo; typedef enum NodeLightPath { diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 2d1100c9d88..2c22db8189d 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -267,8 +267,8 @@ const char *Attribute::standard_name(AttributeStandard std) return "particle"; case ATTR_STD_CURVE_INTERCEPT: return "curve_intercept"; - case ATTR_STD_CURVE_INDEX: - return "curve_index"; + case ATTR_STD_CURVE_RANDOM: + return "curve_random"; case ATTR_STD_PTEX_FACE_ID: return "ptex_face_id"; case ATTR_STD_PTEX_UV: @@ -453,7 +453,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) case ATTR_STD_CURVE_INTERCEPT: attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY); break; - case ATTR_STD_CURVE_INDEX: + case ATTR_STD_CURVE_RANDOM: attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE); break; case ATTR_STD_GENERATED_TRANSFORM: diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index d2a03ceb76a..44c807065e4 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3463,7 +3463,7 @@ NODE_DEFINE(ParticleInfoNode) { NodeType* type = NodeType::add("particle_info", create, NodeType::SHADER); - SOCKET_OUT_FLOAT(index, "Index"); + SOCKET_OUT_FLOAT(random, "Random"); SOCKET_OUT_FLOAT(age, "Age"); SOCKET_OUT_FLOAT(lifetime, "Lifetime"); SOCKET_OUT_POINT(location, "Location"); @@ -3484,7 +3484,7 @@ ParticleInfoNode::ParticleInfoNode() void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(!output("Index")->links.empty()) + if(!output("Random")->links.empty()) attributes->add(ATTR_STD_PARTICLE); if(!output("Age")->links.empty()) attributes->add(ATTR_STD_PARTICLE); @@ -3510,9 +3510,9 @@ void ParticleInfoNode::compile(SVMCompiler& compiler) { ShaderOutput *out; - out = output("Index"); + out = output("Random"); if(!out->links.empty()) { - compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out)); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out)); } out = output("Age"); @@ -3572,7 +3572,7 @@ NODE_DEFINE(HairInfoNode) #if 0 /*output for minimum hair width transparency - deactivated */ SOCKET_OUT_FLOAT(fade, "Fade"); #endif - SOCKET_OUT_FLOAT(index, "Index"); + SOCKET_OUT_FLOAT(index, "Random"); return type; } @@ -3590,8 +3590,8 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) if(!intercept_out->links.empty()) attributes->add(ATTR_STD_CURVE_INTERCEPT); - if(!output("Index")->links.empty()) - attributes->add(ATTR_STD_CURVE_INDEX); + if(!output("Random")->links.empty()) + attributes->add(ATTR_STD_CURVE_RANDOM); } ShaderNode::attributes(shader, attributes); @@ -3627,9 +3627,9 @@ void HairInfoNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out)); }*/ - out = output("Index"); + out = output("Random"); if(!out->links.empty()) { - int attr = compiler.attribute(ATTR_STD_CURVE_INDEX); + int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM); compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT); } } diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp index 06ff45b09bd..07e246a092a 100644 --- a/intern/cycles/render/particles.cpp +++ b/intern/cycles/render/particles.cpp @@ -19,6 +19,7 @@ #include "render/scene.h" #include "util/util_foreach.h" +#include "util/util_hash.h" #include "util/util_logging.h" #include "util/util_map.h" #include "util/util_progress.h" @@ -79,7 +80,8 @@ void ParticleSystemManager::device_update_particles(Device *, DeviceScene *dscen Particle& pa = psys->particles[k]; int offset = i*PARTICLE_SIZE; - particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size); + float random = hash_int_01(pa.index); + particles[offset] = make_float4(random, pa.age, pa.lifetime, pa.size); particles[offset+1] = pa.rotation; particles[offset+2] = make_float4(pa.location.x, pa.location.y, pa.location.z, pa.velocity.x); particles[offset+3] = make_float4(pa.velocity.y, pa.velocity.z, pa.angular_velocity.x, pa.angular_velocity.y); diff --git a/intern/cycles/util/util_hash.h b/intern/cycles/util/util_hash.h index a30b7fe288e..2307ca158f0 100644 --- a/intern/cycles/util/util_hash.h +++ b/intern/cycles/util/util_hash.h @@ -61,6 +61,11 @@ static inline uint hash_string(const char *str) } #endif +ccl_device_inline float hash_int_01(uint k) +{ + return (float)hash_int(k) * (1.0f/(float)0xFFFFFFFF); +} + CCL_NAMESPACE_END #endif /* __UTIL_HASH_H__ */ diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h index e849e5f8f61..8b797820722 100644 --- a/source/blender/blenlib/BLI_hash.h +++ b/source/blender/blenlib/BLI_hash.h @@ -63,4 +63,9 @@ BLI_INLINE unsigned int BLI_hash_int(unsigned int k) return BLI_hash_int_2d(k, 0); } +BLI_INLINE float BLI_hash_int_01(unsigned int k) +{ + return (float)BLI_hash_int(k) * (1.0f/(float)0xFFFFFFFF); +} + #endif // __BLI_HASH_H__ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 427e179f29a..d7e744951c4 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -41,11 +41,11 @@ #include "GPU_glew.h" #include "BLI_blenlib.h" +#include "BLI_hash.h" #include "BLI_linklist.h" #include "BLI_math.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLI_hash.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -1884,7 +1884,7 @@ static int gpu_get_particle_info(GPUParticleInfo *pi) if (ind >= 0) { ParticleData *p = &dob->particle_system->particles[ind]; - pi->scalprops[0] = ind; + pi->scalprops[0] = BLI_hash_int_01(ind); pi->scalprops[1] = GMS.gscene->r.cfra - p->time; pi->scalprops[2] = p->lifetime; pi->scalprops[3] = p->size; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index d589c8765e6..5fe14e76a90 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -190,10 +190,10 @@ void geom( void particle_info( vec4 sprops, vec3 loc, vec3 vel, vec3 avel, - out float index, out float age, out float life_time, out vec3 location, + out float random, out float age, out float life_time, out vec3 location, out float size, out vec3 velocity, out vec3 angular_velocity) { - index = sprops.x; + random = sprops.x; age = sprops.y; life_time = sprops.z; size = sprops.w; diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.c index 5fe74976c08..6a15c59aa5b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_hair_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.c @@ -33,7 +33,7 @@ static bNodeSocketTemplate outputs[] = { { SOCK_FLOAT, 0, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 0, N_("Tangent Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, /*{ SOCK_FLOAT, 0, N_("Fade"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},*/ - { SOCK_FLOAT, 0, "Index" }, + { SOCK_FLOAT, 0, N_("Random") }, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c index 5f0d81e98c9..721d470b467 100644 --- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c @@ -29,7 +29,7 @@ #include "RE_shader_ext.h" static bNodeSocketTemplate outputs[] = { - { SOCK_FLOAT, 0, "Index" }, + { SOCK_FLOAT, 0, "Random" }, { SOCK_FLOAT, 0, "Age" }, { SOCK_FLOAT, 0, "Lifetime" }, { SOCK_VECTOR, 0, "Location" },