diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_emission.h')
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 7523105607f..de9e8d77ec8 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -17,12 +17,20 @@ CCL_NAMESPACE_BEGIN /* Direction Emission */ - ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, - LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce) + LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce +#ifdef __SPLIT_KERNEL__ + ,ShaderData *sd_input +#endif +) { /* setup shading at emitter */ - ShaderData sd; +#ifdef __SPLIT_KERNEL__ + ShaderData *sd = sd_input; +#else + ShaderData sd_object; + ShaderData *sd = &sd_object; +#endif float3 eval; #ifdef __BACKGROUND_MIS__ @@ -37,23 +45,23 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, ray.dP = differential3_zero(); ray.dD = dI; - shader_setup_from_background(kg, &sd, &ray, bounce+1, transparent_bounce); - eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION); + shader_setup_from_background(kg, sd, &ray, bounce+1, transparent_bounce); + eval = shader_eval_background(kg, sd, 0, SHADER_CONTEXT_EMISSION); } else #endif { - 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, transparent_bounce); + 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, transparent_bounce); - ls->Ng = sd.Ng; + ls->Ng = ccl_fetch(sd, Ng); /* no path flag, we're evaluating this for all closures. that's weak but * we'd have to do multiple evaluations otherwise */ - shader_eval_surface(kg, &sd, 0.0f, 0, SHADER_CONTEXT_EMISSION); + shader_eval_surface(kg, sd, 0.0f, 0, SHADER_CONTEXT_EMISSION); /* evaluate emissive closure */ - if(sd.flag & SD_EMISSION) - eval = shader_emissive_eval(kg, &sd); + if(ccl_fetch(sd, flag) & SD_EMISSION) + eval = shader_emissive_eval(kg, sd); else eval = make_float3(0.0f, 0.0f, 0.0f); } @@ -65,7 +73,11 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, LightSample *ls, Ray *ray, BsdfEval *eval, bool *is_lamp, - int bounce, int transparent_bounce) + int bounce, int transparent_bounce +#ifdef __SPLIT_KERNEL__ + , ShaderData *sd_DL +#endif + ) { if(ls->pdf == 0.0f) return false; @@ -74,7 +86,14 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, differential3 dD = differential3_zero(); /* evaluate closure */ - float3 light_eval = direct_emissive_eval(kg, ls, -ls->D, dD, ls->t, sd->time, bounce, transparent_bounce); + + float3 light_eval = direct_emissive_eval(kg, ls, -ls->D, dD, ls->t, ccl_fetch(sd, time), + bounce, + transparent_bounce +#ifdef __SPLIT_KERNEL__ + ,sd_DL +#endif + ); if(is_zero(light_eval)) return false; @@ -83,7 +102,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, float bsdf_pdf; #ifdef __VOLUME__ - if(sd->prim != PRIM_NONE) + if(ccl_fetch(sd, prim) != PRIM_NONE) shader_bsdf_eval(kg, sd, ls->D, eval, &bsdf_pdf); else shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf); @@ -118,8 +137,8 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, if(ls->shader & SHADER_CAST_SHADOW) { /* setup ray */ - bool transmit = (dot(sd->Ng, ls->D) < 0.0f); - ray->P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng); + bool transmit = (dot(ccl_fetch(sd, Ng), ls->D) < 0.0f); + ray->P = ray_offset(ccl_fetch(sd, P), (transmit)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); if(ls->t == FLT_MAX) { /* distant light */ @@ -132,7 +151,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, ray->D = normalize_len(ray->D, &ray->t); } - ray->dP = sd->dP; + ray->dP = ccl_fetch(sd, dP); ray->dD = differential3_zero(); } else { @@ -154,14 +173,14 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader float3 L = shader_emissive_eval(kg, sd); #ifdef __HAIR__ - if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE)) + if(!(path_flag & PATH_RAY_MIS_SKIP) && (ccl_fetch(sd, flag) & SD_USE_MIS) && (ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE)) #else - if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) + if(!(path_flag & PATH_RAY_MIS_SKIP) && (ccl_fetch(sd, flag) & SD_USE_MIS)) #endif { /* multiple importance sampling, get triangle light pdf, * and compute weight with respect to BSDF pdf */ - float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t); + float pdf = triangle_light_pdf(kg, ccl_fetch(sd, Ng), ccl_fetch(sd, I), t); float mis_weight = power_heuristic(bsdf_pdf, pdf); return L*mis_weight; @@ -172,7 +191,11 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader /* Indirect Lamp Emission */ -ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float3 *emission) +ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float3 *emission +#ifdef __SPLIT_KERNEL__ + ,ShaderData *sd +#endif + ) { bool hit_lamp = false; @@ -188,14 +211,21 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *st /* use visibility flag to skip lights */ if(ls.shader & SHADER_EXCLUDE_ANY) { if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) || - ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_REFLECT)) || + ((ls.shader & SHADER_EXCLUDE_GLOSSY) && + ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) || ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) || ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER))) continue; } #endif - float3 L = direct_emissive_eval(kg, &ls, -ray->D, ray->dD, ls.t, ray->time, state->bounce, state->transparent_bounce); + float3 L = direct_emissive_eval(kg, &ls, -ray->D, ray->dD, ls.t, ray->time, + state->bounce, + state->transparent_bounce +#ifdef __SPLIT_KERNEL__ + ,sd +#endif + ); #ifdef __VOLUME__ if(state->volume_stack[0].shader != SHADER_NONE) { @@ -224,7 +254,11 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *st /* Indirect Background */ -ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *state, Ray *ray) +ccl_device_noinline float3 indirect_background(KernelGlobals *kg, ccl_addr_space PathState *state, ccl_addr_space Ray *ray +#ifdef __SPLIT_KERNEL__ + ,ShaderData *sd_global +#endif + ) { #ifdef __BACKGROUND__ int shader = kernel_data.background.surface_shader; @@ -232,18 +266,25 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *sta /* use visibility flag to skip lights */ if(shader & SHADER_EXCLUDE_ANY) { if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) || - ((shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_REFLECT)) || + ((shader & SHADER_EXCLUDE_GLOSSY) && + ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) || ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) || ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) || ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER))) return make_float3(0.0f, 0.0f, 0.0f); } +#ifdef __SPLIT_KERNEL__ /* evaluate background closure */ + Ray priv_ray = *ray; + shader_setup_from_background(kg, sd_global, &priv_ray, state->bounce+1, state->transparent_bounce); + float3 L = shader_eval_background(kg, sd_global, state->flag, SHADER_CONTEXT_EMISSION); +#else ShaderData sd; shader_setup_from_background(kg, &sd, ray, state->bounce+1, state->transparent_bounce); float3 L = shader_eval_background(kg, &sd, state->flag, SHADER_CONTEXT_EMISSION); +#endif #ifdef __BACKGROUND_MIS__ /* check if background light exists or if we should skip pdf */ @@ -252,7 +293,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *sta if(!(state->flag & PATH_RAY_MIS_SKIP) && res) { /* multiple importance sampling, get background light pdf for ray * direction, and compute weight with respect to BSDF pdf */ - float pdf = background_light_pdf(kg, ray->D); + float pdf = background_light_pdf(kg, ray->P, ray->D); float mis_weight = power_heuristic(state->ray_pdf, pdf); return L*mis_weight; |