diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-02-07 18:08:50 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2014-02-07 18:09:34 +0400 |
commit | 9c83ed774bbc7b74242df0628f1de07df8f04df7 (patch) | |
tree | f78b5a057fe169d6fa70aa400cb3885091ccf451 /intern | |
parent | 52bae9691b08d24c63e5fa43af644bc5654afb11 (diff) |
Fix T36979: wrong render of textured mesh lights with multiple importance sampling.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 20 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_triangle.h | 12 |
3 files changed, 24 insertions, 21 deletions
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 1ec116b7635..58bdc2b70ca 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN /* Direction Emission */ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando, - LightSample *ls, float u, float v, float3 I, differential3 dI, float t, float time, int bounce) + LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce) { /* setup shading at emitter */ ShaderData sd; @@ -47,10 +47,10 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando, { #ifdef __HAIR__ if(ls->type == LIGHT_STRAND) - shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, bounce+1, ls->prim); + shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ls->prim); else #endif - shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, bounce+1, ~0); + shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ~0); ls->Ng = sd.Ng; @@ -95,7 +95,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int differential3 dD = differential3_zero(); /* evaluate closure */ - float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, dD, ls.t, sd->time, bounce); + float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce); if(is_zero(light_eval)) return false; @@ -211,10 +211,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int } #endif - /* todo: missing texture coordinates */ - float u = 0.0f; - float v = 0.0f; - float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ray->dD, ls.t, ray->time, bounce); + float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce); if(!(path_flag & PATH_RAY_MIS_SKIP)) { /* multiple importance sampling, get regular light pdf, diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 9915cd2495f..c32f0395744 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -23,6 +23,7 @@ typedef struct LightSample { float3 Ng; /* normal on light */ float3 D; /* direction from shading point to light */ float t; /* distance to light (FLT_MAX for distant light) */ + float u, v; /* parametric coordinate on primitive */ float pdf; /* light sampling probability density function */ float eval_fac; /* intensity multiplier */ int object; /* object id for triangle/curve lights */ @@ -219,6 +220,8 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp, ls->object = ~0; ls->prim = ~0; ls->lamp = lamp; + ls->u = randu; + ls->v = randv; if(type == LIGHT_DISTANT) { /* distant light */ @@ -309,6 +312,9 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, ls->object = ~0; ls->prim = ~0; ls->lamp = lamp; + /* todo: missing texture coordinates */ + ls->u = 0.0f; + ls->v = 0.0f; if(!(ls->shader & SHADER_USE_MIS)) return false; @@ -443,14 +449,24 @@ ccl_device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls ccl_device void triangle_light_sample(KernelGlobals *kg, int prim, int object, float randu, float randv, float time, LightSample *ls) { + float u, v; + + /* compute random point in triangle */ + randu = sqrtf(randu); + + u = 1.0f - randu; + v = randv*randu; + /* triangle, so get position, normal, shader */ - ls->P = triangle_sample_MT(kg, prim, randu, randv); + ls->P = triangle_point_MT(kg, prim, u, v); ls->Ng = triangle_normal_MT(kg, prim, &ls->shader); ls->object = object; ls->prim = prim; ls->lamp = ~0; ls->shader |= SHADER_USE_MIS; ls->t = 0.0f; + ls->u = u; + ls->v = v; ls->type = LIGHT_TRIANGLE; ls->eval_fac = 1.0f; @@ -504,6 +520,8 @@ ccl_device void curve_segment_light_sample(KernelGlobals *kg, int prim, int obje ls->prim = prim; ls->lamp = ~0; ls->t = 0.0f; + ls->u = randu; + ls->v = randv; ls->type = LIGHT_STRAND; ls->eval_fac = 1.0f; ls->shader = __float_as_int(v00.z) | SHADER_USE_MIS; diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h index d457b67e77e..0455df85961 100644 --- a/intern/cycles/kernel/kernel_triangle.h +++ b/intern/cycles/kernel/kernel_triangle.h @@ -31,18 +31,6 @@ ccl_device_inline float3 triangle_point_MT(KernelGlobals *kg, int tri_index, flo return (u*v0 + v*v1 + t*v2); } -/* Sample point on triangle */ -ccl_device_inline float3 triangle_sample_MT(KernelGlobals *kg, int tri_index, float randu, float randv) -{ - /* compute point */ - randu = sqrtf(randu); - - float u = 1.0f - randu; - float v = randv*randu; - - return triangle_point_MT(kg, tri_index, u, v); -} - /* Normal for Moller-Trumbore triangles */ ccl_device_inline float3 triangle_normal_MT(KernelGlobals *kg, int tri_index, int *shader) { |