2011-04-27 11:58:34 +00:00
|
|
|
/*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Copyright 2011-2013 Blender Foundation
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License
|
2011-04-27 11:58:34 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
/* Direction Emission */
|
|
|
|
|
2014-04-21 13:53:20 +00:00
|
|
|
ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
|
2014-04-21 12:20:29 +00:00
|
|
|
LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* setup shading at emitter */
|
|
|
|
ShaderData sd;
|
|
|
|
float3 eval;
|
|
|
|
|
2012-01-26 19:45:59 +00:00
|
|
|
#ifdef __BACKGROUND_MIS__
|
2012-01-20 17:49:17 +00:00
|
|
|
if(ls->type == LIGHT_BACKGROUND) {
|
|
|
|
Ray ray;
|
|
|
|
ray.D = ls->D;
|
|
|
|
ray.P = ls->P;
|
2012-10-18 12:45:27 +00:00
|
|
|
ray.t = 1.0f;
|
|
|
|
#ifdef __OBJECT_MOTION__
|
|
|
|
ray.time = time;
|
|
|
|
#endif
|
2013-05-03 21:34:51 +00:00
|
|
|
ray.dP = differential3_zero();
|
2013-05-03 05:24:05 +00:00
|
|
|
ray.dD = dI;
|
2014-03-15 13:22:41 +00:00
|
|
|
|
2014-04-21 12:20:29 +00:00
|
|
|
shader_setup_from_background(kg, &sd, &ray, bounce+1, transparent_bounce);
|
2012-12-15 10:18:42 +00:00
|
|
|
eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
|
2012-01-20 17:49:17 +00:00
|
|
|
}
|
2012-01-26 19:45:59 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
2014-04-21 12:20:29 +00:00
|
|
|
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);
|
2012-12-28 14:21:30 +00:00
|
|
|
|
2012-01-20 17:49:17 +00:00
|
|
|
ls->Ng = sd.Ng;
|
|
|
|
|
|
|
|
/* no path flag, we're evaluating this for all closures. that's weak but
|
2012-06-09 17:22:52 +00:00
|
|
|
* we'd have to do multiple evaluations otherwise */
|
2014-04-21 13:53:20 +00:00
|
|
|
shader_eval_surface(kg, &sd, 0.0f, 0, SHADER_CONTEXT_EMISSION);
|
2012-01-20 17:49:17 +00:00
|
|
|
|
|
|
|
/* evaluate emissive closure */
|
|
|
|
if(sd.flag & SD_EMISSION)
|
|
|
|
eval = shader_emissive_eval(kg, &sd);
|
|
|
|
else
|
|
|
|
eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
2013-01-09 21:09:20 +00:00
|
|
|
|
|
|
|
eval *= ls->eval_fac;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
return eval;
|
|
|
|
}
|
|
|
|
|
2014-04-03 20:43:56 +00:00
|
|
|
ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd,
|
|
|
|
LightSample *ls, Ray *ray, BsdfEval *eval, bool *is_lamp,
|
|
|
|
int bounce, int transparent_bounce)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->pdf == 0.0f)
|
2012-01-20 17:49:17 +00:00
|
|
|
return false;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2013-05-03 05:24:05 +00:00
|
|
|
/* todo: implement */
|
2013-05-03 21:34:51 +00:00
|
|
|
differential3 dD = differential3_zero();
|
2013-05-03 05:24:05 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* evaluate closure */
|
2014-04-03 20:43:56 +00:00
|
|
|
float3 light_eval = direct_emissive_eval(kg, ls, -ls->D, dD, ls->t, sd->time, bounce, transparent_bounce);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
if(is_zero(light_eval))
|
2011-04-27 11:58:34 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/* evaluate BSDF at shading point */
|
|
|
|
float bsdf_pdf;
|
|
|
|
|
2013-12-29 14:40:43 +00:00
|
|
|
#ifdef __VOLUME__
|
2014-03-29 12:03:47 +00:00
|
|
|
if(sd->prim != PRIM_NONE)
|
2014-04-03 20:43:56 +00:00
|
|
|
shader_bsdf_eval(kg, sd, ls->D, eval, &bsdf_pdf);
|
2013-12-29 14:40:43 +00:00
|
|
|
else
|
2014-04-03 20:43:56 +00:00
|
|
|
shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf);
|
2013-12-29 14:40:43 +00:00
|
|
|
#else
|
2014-04-03 20:43:56 +00:00
|
|
|
shader_bsdf_eval(kg, sd, ls->D, eval, &bsdf_pdf);
|
2013-12-29 14:40:43 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->shader & SHADER_USE_MIS) {
|
2011-04-27 11:58:34 +00:00
|
|
|
/* multiple importance sampling */
|
2014-04-03 20:43:56 +00:00
|
|
|
float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
light_eval *= mis_weight;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
|
2014-04-03 20:43:56 +00:00
|
|
|
bsdf_eval_mul(eval, light_eval/ls->pdf);
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
|
2013-06-07 18:59:23 +00:00
|
|
|
#ifdef __PASSES__
|
|
|
|
/* use visibility flag to skip lights */
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->shader & SHADER_EXCLUDE_ANY) {
|
|
|
|
if(ls->shader & SHADER_EXCLUDE_DIFFUSE)
|
2013-06-07 18:59:23 +00:00
|
|
|
eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->shader & SHADER_EXCLUDE_GLOSSY)
|
2013-06-07 18:59:23 +00:00
|
|
|
eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->shader & SHADER_EXCLUDE_TRANSMIT)
|
2013-06-07 18:59:23 +00:00
|
|
|
eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
if(bsdf_eval_is_zero(eval))
|
|
|
|
return false;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->shader & SHADER_CAST_SHADOW) {
|
2011-09-27 20:37:24 +00:00
|
|
|
/* setup ray */
|
2014-04-03 20:43:56 +00:00
|
|
|
bool transmit = (dot(sd->Ng, ls->D) < 0.0f);
|
2012-01-30 18:34:01 +00:00
|
|
|
ray->P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng);
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2014-04-03 20:43:56 +00:00
|
|
|
if(ls->t == FLT_MAX) {
|
2011-09-27 20:37:24 +00:00
|
|
|
/* distant light */
|
2014-04-03 20:43:56 +00:00
|
|
|
ray->D = ls->D;
|
|
|
|
ray->t = ls->t;
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* other lights, avoid self-intersection */
|
2014-04-03 20:43:56 +00:00
|
|
|
ray->D = ray_offset(ls->P, ls->Ng) - ray->P;
|
2013-06-04 17:20:00 +00:00
|
|
|
ray->D = normalize_len(ray->D, &ray->t);
|
2011-09-27 20:37:24 +00:00
|
|
|
}
|
2013-05-03 21:34:51 +00:00
|
|
|
|
|
|
|
ray->dP = sd->dP;
|
|
|
|
ray->dD = differential3_zero();
|
2011-09-12 13:13:56 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-09-27 20:37:24 +00:00
|
|
|
/* signal to not cast shadow ray */
|
|
|
|
ray->t = 0.0f;
|
2011-09-12 13:13:56 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2013-01-30 17:04:51 +00:00
|
|
|
/* return if it's a lamp for shadow pass */
|
2014-04-03 20:43:56 +00:00
|
|
|
*is_lamp = (ls->prim == PRIM_NONE && ls->type != LIGHT_BACKGROUND);
|
2013-01-30 17:04:51 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-01-09 21:09:20 +00:00
|
|
|
/* Indirect Primitive Emission */
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2013-11-15 23:17:10 +00:00
|
|
|
ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* evaluate emissive closure */
|
|
|
|
float3 L = shader_emissive_eval(kg, sd);
|
|
|
|
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
2014-05-04 16:19:08 +00:00
|
|
|
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE))
|
2012-12-28 14:21:30 +00:00
|
|
|
#else
|
2014-05-04 16:19:08 +00:00
|
|
|
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
|
2012-12-28 14:21:30 +00:00
|
|
|
#endif
|
2014-05-04 16:19:08 +00:00
|
|
|
{
|
2012-01-20 17:49:17 +00:00
|
|
|
/* multiple importance sampling, get triangle light pdf,
|
2012-06-09 17:22:52 +00:00
|
|
|
* and compute weight with respect to BSDF pdf */
|
2011-04-27 11:58:34 +00:00
|
|
|
float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
|
|
|
|
float mis_weight = power_heuristic(bsdf_pdf, pdf);
|
|
|
|
|
|
|
|
return L*mis_weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
return L;
|
|
|
|
}
|
|
|
|
|
2013-01-09 21:09:20 +00:00
|
|
|
/* Indirect Lamp Emission */
|
|
|
|
|
2014-05-01 17:18:42 +00:00
|
|
|
ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float3 *emission)
|
2013-01-09 21:09:20 +00:00
|
|
|
{
|
2014-05-01 17:18:42 +00:00
|
|
|
bool hit_lamp = false;
|
2013-01-09 21:09:20 +00:00
|
|
|
|
2014-05-01 17:18:42 +00:00
|
|
|
*emission = make_float3(0.0f, 0.0f, 0.0f);
|
2013-01-09 21:09:20 +00:00
|
|
|
|
2014-05-01 17:18:42 +00:00
|
|
|
for(int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
|
|
|
|
LightSample ls;
|
|
|
|
|
|
|
|
if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
|
|
|
|
continue;
|
2013-06-07 18:59:23 +00:00
|
|
|
|
|
|
|
#ifdef __PASSES__
|
2014-05-01 17:18:42 +00:00
|
|
|
/* 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_GLOSSY)) ||
|
|
|
|
((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)))
|
|
|
|
continue;
|
|
|
|
}
|
2013-06-07 18:59:23 +00:00
|
|
|
#endif
|
|
|
|
|
2014-05-01 17:18:42 +00:00
|
|
|
float3 L = direct_emissive_eval(kg, &ls, -ray->D, ray->dD, ls.t, ray->time, state->bounce, state->transparent_bounce);
|
2013-01-09 21:09:20 +00:00
|
|
|
|
2014-04-04 14:45:49 +00:00
|
|
|
#ifdef __VOLUME__
|
|
|
|
if(state->volume_stack[0].shader != SHADER_NONE) {
|
|
|
|
/* shadow attenuation */
|
|
|
|
Ray volume_ray = *ray;
|
|
|
|
volume_ray.t = ls.t;
|
|
|
|
float3 volume_tp = make_float3(1.0f, 1.0f, 1.0f);
|
|
|
|
kernel_volume_shadow(kg, state, &volume_ray, &volume_tp);
|
|
|
|
L *= volume_tp;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-05-01 17:18:42 +00:00
|
|
|
if(!(state->flag & PATH_RAY_MIS_SKIP)) {
|
|
|
|
/* multiple importance sampling, get regular light pdf,
|
|
|
|
* and compute weight with respect to BSDF pdf */
|
|
|
|
float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
|
|
|
|
L *= mis_weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
*emission += L;
|
|
|
|
hit_lamp = true;
|
2013-01-09 21:09:20 +00:00
|
|
|
}
|
|
|
|
|
2014-05-01 17:18:42 +00:00
|
|
|
return hit_lamp;
|
2013-01-09 21:09:20 +00:00
|
|
|
}
|
|
|
|
|
2012-01-20 17:49:17 +00:00
|
|
|
/* Indirect Background */
|
|
|
|
|
2014-04-21 15:51:51 +00:00
|
|
|
ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *state, Ray *ray)
|
2012-01-20 17:49:17 +00:00
|
|
|
{
|
|
|
|
#ifdef __BACKGROUND__
|
2013-12-28 01:27:48 +00:00
|
|
|
int shader = kernel_data.background.surface_shader;
|
2013-06-10 20:34:34 +00:00
|
|
|
|
|
|
|
/* use visibility flag to skip lights */
|
|
|
|
if(shader & SHADER_EXCLUDE_ANY) {
|
2014-04-21 15:51:51 +00:00
|
|
|
if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
|
|
|
|
((shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
|
|
|
|
((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
|
|
|
|
((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)))
|
2013-06-10 20:34:34 +00:00
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
|
|
|
|
2012-01-20 17:49:17 +00:00
|
|
|
/* evaluate background closure */
|
|
|
|
ShaderData sd;
|
2014-04-21 15:51:51 +00:00
|
|
|
shader_setup_from_background(kg, &sd, ray, state->bounce+1, state->transparent_bounce);
|
2013-06-10 20:34:34 +00:00
|
|
|
|
2014-04-21 15:51:51 +00:00
|
|
|
float3 L = shader_eval_background(kg, &sd, state->flag, SHADER_CONTEXT_EMISSION);
|
2012-01-20 17:49:17 +00:00
|
|
|
|
2012-01-26 19:45:59 +00:00
|
|
|
#ifdef __BACKGROUND_MIS__
|
2012-01-20 17:49:17 +00:00
|
|
|
/* check if background light exists or if we should skip pdf */
|
|
|
|
int res = kernel_data.integrator.pdf_background_res;
|
|
|
|
|
2014-04-21 15:51:51 +00:00
|
|
|
if(!(state->flag & PATH_RAY_MIS_SKIP) && res) {
|
2012-01-20 17:49:17 +00:00
|
|
|
/* multiple importance sampling, get background light pdf for ray
|
2012-06-09 17:22:52 +00:00
|
|
|
* direction, and compute weight with respect to BSDF pdf */
|
2012-01-20 17:49:17 +00:00
|
|
|
float pdf = background_light_pdf(kg, ray->D);
|
2014-04-21 15:51:51 +00:00
|
|
|
float mis_weight = power_heuristic(state->ray_pdf, pdf);
|
2012-01-20 17:49:17 +00:00
|
|
|
|
|
|
|
return L*mis_weight;
|
|
|
|
}
|
2012-01-26 19:45:59 +00:00
|
|
|
#endif
|
2012-01-20 17:49:17 +00:00
|
|
|
|
|
|
|
return L;
|
|
|
|
#else
|
|
|
|
return make_float3(0.8f, 0.8f, 0.8f);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|
|
|
|
|