diff options
author | Stuart Broadfoot <gbroadfoot@hotmail.com> | 2012-12-28 18:21:30 +0400 |
---|---|---|
committer | Stuart Broadfoot <gbroadfoot@hotmail.com> | 2012-12-28 18:21:30 +0400 |
commit | e9ba345c46c93a193193f01d4bfac714a666d384 (patch) | |
tree | 49df9d78dc9327de642779e300e1592e5d7b3a42 /intern/cycles/kernel/kernel_light.h | |
parent | 857df8065face58eff5556953cdf2dd72e09f2b6 (diff) |
New feature
Patch [#33445] - Experimental Cycles Hair Rendering (CPU only)
This patch allows hair data to be exported to cycles and introduces a new line segment primitive to render with.
The UI appears under the particle tab and there is a new hair info node available.
It is only available under the experimental feature set and for cpu rendering.
Diffstat (limited to 'intern/cycles/kernel/kernel_light.h')
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 97ae2d3db87..0f74ab75dd4 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -326,6 +326,59 @@ __device float triangle_light_pdf(KernelGlobals *kg, return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi; } +#ifdef __HAIR__ +/* Strand Light */ + +__device void curve_seg_light_sample(KernelGlobals *kg, int prim, int object, + float randu, float randv, float time, LightSample *ls) +{ + /* this strand code needs completion */ + float4 v00 = kernel_tex_fetch(__cur_segs, prim); + + int v1 = __float_as_int(v00.x); + int v2 = __float_as_int(v00.y); + float l = v00.w; + + float4 P1 = kernel_tex_fetch(__cur_keys, v1); + float4 P2 = kernel_tex_fetch(__cur_keys, v2); + float r1 = P1.w; + float r2 = P2.w; + float3 tg = float4_to_float3(P2 - P1) / l; + float3 xc = make_float3(tg.x * tg.z, tg.y * tg.z, -(tg.x * tg.x + tg.y * tg.y)); + if (dot(xc, xc) == 0.0f) + xc = make_float3(tg.x * tg.y, -(tg.x * tg.x + tg.z * tg.z), tg.z * tg.y); + xc = normalize(xc); + float3 yc = cross(tg, xc); + float gd = ((r2 - r1)/l); + + /* normal currently ignores gradient */ + ls->Ng = sinf(2 * M_PI_F * randv) * xc + cosf(2 * M_PI_F * randv) * yc; + ls->P = randu * l * tg + (gd * l + r1) * ls->Ng; + ls->object = object; + ls->prim = prim; + ls->t = 0.0f; + ls->type = LIGHT_STRAND; + ls->eval_fac = 1.0f; + ls->shader = __float_as_int(v00.z); + +#ifdef __INSTANCING__ + /* instance transform */ + if(ls->object >= 0) { +#ifdef __OBJECT_MOTION__ + Transform itfm; + Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); +#else + Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); + Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); +#endif + + ls->P = transform_point(&tfm, ls->P); + ls->Ng = normalize(transform_direction(&tfm, ls->Ng)); + } +#endif +} +#endif + /* Light Distribution */ __device int light_distribution_sample(KernelGlobals *kg, float randt) @@ -365,10 +418,19 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra /* fetch light data */ float4 l = kernel_tex_fetch(__light_distribution, index); int prim = __float_as_int(l.y); +#ifdef __HAIR__ +/* currently use l.z to indicate is strand sample which isn't ideal */ + bool is_curve = __float_as_int(l.z) == 0.0f; +#endif if(prim >= 0) { int object = __float_as_int(l.w); - triangle_light_sample(kg, prim, object, randu, randv, time, ls); +#ifdef __HAIR__ + if (is_curve) + curve_seg_light_sample(kg, prim, object, randu, randv, time, ls); + else +#endif + triangle_light_sample(kg, prim, object, randu, randv, time, ls); } else { int point = -prim-1; |