diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-06-04 21:17:10 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-06-04 21:17:10 +0400 |
commit | 6548f7efefb2e9db25e8c6ca8b7d4ed6b9725543 (patch) | |
tree | 106465145a9e15e3e01ff6fbde850d880dbb7c2c /intern/cycles/kernel | |
parent | 0f1fd51c2169d45327eef4c40622551694c9dd9e (diff) |
Cycles: spot lamp support.
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 35 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/emissive.h | 15 |
4 files changed, 45 insertions, 15 deletions
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 0ef1425e68a..881d25ad7ba 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -104,13 +104,8 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, float mis_weight = power_heuristic(pdf, bsdf_pdf); light_eval *= mis_weight; } - /* todo: clean up these weights */ - else if(ls.shader & SHADER_AREA_LIGHT) - light_eval *= 0.25f; /* area lamp */ - else if(ls.t != FLT_MAX) - light_eval *= 0.25f*M_1_PI_F; /* point lamp */ - bsdf_eval_mul(eval, light_eval/pdf); + bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf)); if(bsdf_eval_is_zero(eval)) return false; diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index e9e7fbd4ca1..76552400f9c 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -23,6 +23,7 @@ typedef struct LightSample { float3 D; float3 Ng; float t; + float eval_fac; int object; int prim; int shader; @@ -189,6 +190,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->Ng = D; ls->D = -D; ls->t = FLT_MAX; + ls->eval_fac = 1.0f; } #ifdef __BACKGROUND_MIS__ else if(type == LIGHT_BACKGROUND) { @@ -199,6 +201,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->Ng = D; ls->D = -D; ls->t = FLT_MAX; + ls->eval_fac = 1.0f; } #endif else { @@ -212,6 +215,36 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->P += sphere_light_sample(P, ls->P, size, randu, randv); ls->Ng = normalize(P - ls->P); + ls->eval_fac = 0.25f*M_1_PI_F; + } + else if(type == LIGHT_SPOT) { + float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2); + float size = data1.y; + + /* spot light */ + if(size > 0.0f) + ls->P += sphere_light_sample(P, ls->P, size, randu, randv); + + float3 dir = make_float3(data1.z, data1.w, data2.x); + float3 I = normalize(P - ls->P); + + float spot_angle = data2.y; + float spot_smooth = data2.z; + + float eval_fac = fabsf(dot(dir, I)); + + if(eval_fac <= spot_angle) { + eval_fac = 0.0f; + } + else { + float t = eval_fac - spot_angle; + + if(t < spot_smooth && spot_smooth != 0.0f) + eval_fac *= smoothstepf(t/spot_smooth); + } + + ls->Ng = I; + ls->eval_fac = eval_fac*0.25f*M_1_PI_F; } else { /* area light */ @@ -224,6 +257,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point, ls->P += area_light_sample(axisu, axisv, randu, randv); ls->Ng = D; + ls->eval_fac = 0.25f; } ls->t = 0.0f; @@ -262,6 +296,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, ls->prim = prim; ls->t = 0.0f; ls->type = LIGHT_AREA; + ls->eval_fac = 1.0f; #ifdef __INSTANCING__ /* instance transform */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index a64c850d35a..d119057ac67 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -283,7 +283,8 @@ typedef enum LightType { LIGHT_DISTANT, LIGHT_BACKGROUND, LIGHT_AREA, - LIGHT_AO + LIGHT_AO, + LIGHT_SPOT } LightType; /* Camera Type */ diff --git a/intern/cycles/kernel/svm/emissive.h b/intern/cycles/kernel/svm/emissive.h index e3f99e9b729..0b0218674b8 100644 --- a/intern/cycles/kernel/svm/emissive.h +++ b/intern/cycles/kernel/svm/emissive.h @@ -34,14 +34,6 @@ CCL_NAMESPACE_BEGIN /* EMISSION CLOSURE */ -__device float3 emissive_eval(const float3 Ng, const float3 I) -{ - float cosNO = fabsf(dot(Ng, I)); - float res = (cosNO > 0.0f)? 1.0f: 0.0f; - - return make_float3(res, res, res); -} - /// Return the probability distribution function in the direction I, /// given the parameters and the light's surface normal. This MUST match /// the PDF computed by sample(). @@ -51,6 +43,13 @@ __device float emissive_pdf(const float3 Ng, const float3 I) return (cosNO > 0.0f)? 1.0f: 0.0f; } +__device float3 emissive_eval(const float3 Ng, const float3 I) +{ + float res = emissive_pdf(Ng, I); + + return make_float3(res, res, res); +} + __device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc) { return emissive_eval(sd->Ng, sd->I); |