Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/kernel_bake.h')
-rw-r--r--intern/cycles/kernel/kernel_bake.h364
1 files changed, 221 insertions, 143 deletions
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 2b305e5488d..8e7a2c1b62b 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -16,10 +16,10 @@
CCL_NAMESPACE_BEGIN
-#undef USE_BAKE_JITTER
+#ifndef __NO_BAKING__
ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng,
- const bool is_combined, const bool is_ao, const bool is_sss, int sample)
+ int pass_filter, int sample)
{
/* initialize master radiance accumulator */
kernel_assert(kernel_data.film.use_light_pass);
@@ -29,7 +29,6 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
PathState state;
Ray ray;
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- bool is_sss_sample = is_sss;
ray.P = sd->P + sd->Ng;
ray.D = -sd->Ng;
@@ -46,7 +45,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
/* evaluate surface shader */
float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF);
- shader_eval_surface(kg, sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
+ shader_eval_surface(kg, sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
/* TODO, disable the closures we won't need */
@@ -56,27 +55,56 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
#endif
/* sample ambient occlusion */
- if(is_combined || is_ao) {
+ if(pass_filter & BAKE_FILTER_AO) {
kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
}
+ /* sample emission */
+ if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+ float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+ path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
+ }
+
+ bool is_sss_sample = false;
+
#ifdef __SUBSURFACE__
/* sample subsurface scattering */
- if((is_combined || is_sss_sample) && (sd->flag & SD_BSSRDF)) {
+ if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
- if(kernel_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, &throughput))
+ SubsurfaceIndirectRays ss_indirect;
+ kernel_path_subsurface_init_indirect(&ss_indirect);
+ if(kernel_path_subsurface_scatter(kg,
+ sd,
+ &L_sample,
+ &state,
+ &rng,
+ &ray,
+ &throughput,
+ &ss_indirect))
+ {
+ while(ss_indirect.num_rays) {
+ kernel_path_subsurface_setup_indirect(kg,
+ &ss_indirect,
+ &state,
+ &ray,
+ &L_sample,
+ &throughput);
+ kernel_path_indirect(kg,
+ &rng,
+ &ray,
+ throughput,
+ state.num_samples,
+ &state,
+ &L_sample);
+ kernel_path_subsurface_accum_indirect(&ss_indirect, &L_sample);
+ }
is_sss_sample = true;
+ }
}
#endif
/* sample light and BSDF */
- if((!is_sss_sample) && (!is_ao)) {
-
- if(sd->flag & SD_EMISSION) {
- float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
- }
-
+ if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
kernel_path_surface_connect_light(kg, &rng, sd, throughput, &state, &L_sample);
if(kernel_path_surface_bounce(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
@@ -84,7 +112,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
state.ray_t = 0.0f;
#endif
/* compute indirect light */
- kernel_path_indirect(kg, &rng, ray, throughput, 1, state, &L_sample);
+ kernel_path_indirect(kg, &rng, &ray, throughput, 1, &state, &L_sample);
/* sum and reset indirect light pass variables for the next samples */
path_radiance_sum_indirect(&L_sample);
@@ -97,30 +125,30 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
/* branched path tracer */
/* sample ambient occlusion */
- if(is_combined || is_ao) {
+ if(pass_filter & BAKE_FILTER_AO) {
kernel_branched_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
}
+ /* sample emission */
+ if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+ float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+ path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
+ }
+
#ifdef __SUBSURFACE__
/* sample subsurface scattering */
- if((is_combined || is_sss_sample) && (sd->flag & SD_BSSRDF)) {
+ if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
kernel_branched_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, throughput);
}
#endif
/* sample light and BSDF */
- if((!is_sss_sample) && (!is_ao)) {
-
- if(sd->flag & SD_EMISSION) {
- float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
- }
-
+ if(pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT)) {
#if defined(__EMISSION__)
/* direct light */
if(kernel_data.integrator.use_direct_light) {
- bool all = kernel_data.integrator.sample_all_lights_direct;
+ int all = kernel_data.integrator.sample_all_lights_direct;
kernel_branched_path_surface_connect_light(kg, &rng,
sd, &state, throughput, 1.0f, &L_sample, all);
}
@@ -148,47 +176,91 @@ ccl_device bool is_aa_pass(ShaderEvalType type)
}
}
-ccl_device bool is_light_pass(ShaderEvalType type)
-{
- switch (type) {
- case SHADER_EVAL_AO:
- case SHADER_EVAL_COMBINED:
- case SHADER_EVAL_SHADOW:
- case SHADER_EVAL_DIFFUSE_DIRECT:
- case SHADER_EVAL_GLOSSY_DIRECT:
- case SHADER_EVAL_TRANSMISSION_DIRECT:
- case SHADER_EVAL_SUBSURFACE_DIRECT:
- case SHADER_EVAL_DIFFUSE_INDIRECT:
- case SHADER_EVAL_GLOSSY_INDIRECT:
- case SHADER_EVAL_TRANSMISSION_INDIRECT:
- case SHADER_EVAL_SUBSURFACE_INDIRECT:
- return true;
- default:
- return false;
- }
-}
-
/* this helps with AA but it's not the real solution as it does not AA the geometry
* but it's better than nothing, thus committed */
-ccl_device_inline float bake_clamp_mirror_repeat(float u)
+ccl_device_inline float bake_clamp_mirror_repeat(float u, float max)
{
/* use mirror repeat (like opengl texture) so that if the barycentric
* coordinate goes past the end of the triangle it is not always clamped
* to the same value, gives ugly patterns */
+ u /= max;
float fu = floorf(u);
u = u - fu;
- return (((int)fu) & 1)? 1.0f - u: u;
+ return ((((int)fu) & 1)? 1.0f - u: u) * max;
+}
+
+ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg,
+ ShaderData *sd,
+ const ShaderEvalType type)
+{
+ switch(type) {
+ case SHADER_EVAL_DIFFUSE:
+ return shader_bsdf_diffuse(kg, sd);
+ case SHADER_EVAL_GLOSSY:
+ return shader_bsdf_glossy(kg, sd);
+ case SHADER_EVAL_TRANSMISSION:
+ return shader_bsdf_transmission(kg, sd);
+#ifdef __SUBSURFACE__
+ case SHADER_EVAL_SUBSURFACE:
+ return shader_bsdf_subsurface(kg, sd);
+#endif
+ default:
+ kernel_assert(!"Unknown bake type passed to BSDF evaluate");
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
+ ShaderData *sd,
+ PathState *state,
+ float3 direct,
+ float3 indirect,
+ const ShaderEvalType type,
+ const int pass_filter)
+{
+ float3 color;
+ const bool is_color = (pass_filter & BAKE_FILTER_COLOR) != 0;
+ const bool is_direct = (pass_filter & BAKE_FILTER_DIRECT) != 0;
+ const bool is_indirect = (pass_filter & BAKE_FILTER_INDIRECT) != 0;
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
+
+ if(is_color) {
+ if(is_direct || is_indirect) {
+ /* Leave direct and diffuse channel colored. */
+ color = make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ /* surface color of the pass only */
+ shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN);
+ return kernel_bake_shader_bsdf(kg, sd, type);
+ }
+ }
+ else {
+ shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN);
+ color = kernel_bake_shader_bsdf(kg, sd, type);
+ }
+
+ if(is_direct) {
+ out += safe_divide_color(direct, color);
+ }
+
+ if(is_indirect) {
+ out += safe_divide_color(indirect, color);
+ }
+
+ return out;
}
ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output,
- ShaderEvalType type, int i, int offset, int sample)
+ ShaderEvalType type, int pass_filter, int i, int offset, int sample)
{
ShaderData sd;
+ PathState state = {0};
uint4 in = input[i * 2];
uint4 diff = input[i * 2 + 1];
- float3 out;
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
int object = in.x;
int prim = in.y;
@@ -209,7 +281,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
/* random number generator */
RNG rng = cmj_hash(offset + i, kernel_data.integrator.seed);
-#ifdef USE_BAKE_JITTER
float filter_x, filter_y;
if(sample == 0) {
filter_x = filter_y = 0.5f;
@@ -220,10 +291,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
/* subpixel u/v offset */
if(sample > 0) {
- u = bake_clamp_mirror_repeat(u + dudx*(filter_x - 0.5f) + dudy*(filter_y - 0.5f));
- v = bake_clamp_mirror_repeat(v + dvdx*(filter_x - 0.5f) + dvdy*(filter_y - 0.5f));
+ u = bake_clamp_mirror_repeat(u + dudx*(filter_x - 0.5f) + dudy*(filter_y - 0.5f), 1.0f);
+ v = bake_clamp_mirror_repeat(v + dvdx*(filter_x - 0.5f) + dvdy*(filter_y - 0.5f), 1.0f - u);
}
-#endif
/* triangle */
int shader;
@@ -235,13 +305,11 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
float3 I = Ng;
float t = 0.0f;
float time = TIME_INVALID;
- int bounce = 0;
- int transparent_bounce = 0;
/* light passes */
PathRadiance L;
- shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time, bounce, transparent_bounce);
+ shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time);
sd.I = sd.N;
/* update differentials */
@@ -252,22 +320,16 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
sd.dv.dx = dvdx;
sd.dv.dy = dvdy;
- /* light passes */
- if(is_light_pass(type)) {
- compute_light_pass(kg, &sd, &L, rng,
- (type == SHADER_EVAL_COMBINED),
- (type == SHADER_EVAL_AO),
- (type == SHADER_EVAL_SUBSURFACE_DIRECT ||
- type == SHADER_EVAL_SUBSURFACE_INDIRECT),
- sample);
- }
+ /* light passes if we need more than color */
+ if(pass_filter & ~BAKE_FILTER_COLOR)
+ compute_light_pass(kg, &sd, &L, rng, pass_filter, sample);
- switch (type) {
+ switch(type) {
/* data passes */
case SHADER_EVAL_NORMAL:
{
if((sd.flag & SD_HAS_BUMP)) {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
}
/* compression: normal = (2 * color) - 1 */
@@ -279,35 +341,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
out = primitive_uv(kg, &sd);
break;
}
- case SHADER_EVAL_DIFFUSE_COLOR:
- {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_diffuse(kg, &sd);
- break;
- }
- case SHADER_EVAL_GLOSSY_COLOR:
- {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_glossy(kg, &sd);
- break;
- }
- case SHADER_EVAL_TRANSMISSION_COLOR:
- {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_transmission(kg, &sd);
- break;
- }
- case SHADER_EVAL_SUBSURFACE_COLOR:
- {
-#ifdef __SUBSURFACE__
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_subsurface(kg, &sd);
-#endif
- break;
- }
case SHADER_EVAL_EMISSION:
{
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_EMISSION);
+ shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_EMISSION);
out = shader_emissive_eval(kg, &sd);
break;
}
@@ -321,7 +357,34 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
}
case SHADER_EVAL_COMBINED:
{
- out = path_radiance_clamp_and_sum(kg, &L);
+ if((pass_filter & BAKE_FILTER_COMBINED) == BAKE_FILTER_COMBINED) {
+ out = path_radiance_clamp_and_sum(kg, &L);
+ break;
+ }
+
+ if((pass_filter & BAKE_FILTER_DIFFUSE_DIRECT) == BAKE_FILTER_DIFFUSE_DIRECT)
+ out += L.direct_diffuse;
+ if((pass_filter & BAKE_FILTER_DIFFUSE_INDIRECT) == BAKE_FILTER_DIFFUSE_INDIRECT)
+ out += L.indirect_diffuse;
+
+ if((pass_filter & BAKE_FILTER_GLOSSY_DIRECT) == BAKE_FILTER_GLOSSY_DIRECT)
+ out += L.direct_glossy;
+ if((pass_filter & BAKE_FILTER_GLOSSY_INDIRECT) == BAKE_FILTER_GLOSSY_INDIRECT)
+ out += L.indirect_glossy;
+
+ if((pass_filter & BAKE_FILTER_TRANSMISSION_DIRECT) == BAKE_FILTER_TRANSMISSION_DIRECT)
+ out += L.direct_transmission;
+ if((pass_filter & BAKE_FILTER_TRANSMISSION_INDIRECT) == BAKE_FILTER_TRANSMISSION_INDIRECT)
+ out += L.indirect_transmission;
+
+ if((pass_filter & BAKE_FILTER_SUBSURFACE_DIRECT) == BAKE_FILTER_SUBSURFACE_DIRECT)
+ out += L.direct_subsurface;
+ if((pass_filter & BAKE_FILTER_SUBSURFACE_INDIRECT) == BAKE_FILTER_SUBSURFACE_INDIRECT)
+ out += L.indirect_subsurface;
+
+ if((pass_filter & BAKE_FILTER_EMISSION) != 0)
+ out += L.emission;
+
break;
}
case SHADER_EVAL_SHADOW:
@@ -329,55 +392,49 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
break;
}
- case SHADER_EVAL_DIFFUSE_DIRECT:
+ case SHADER_EVAL_DIFFUSE:
{
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_diffuse, shader_bsdf_diffuse(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg,
+ &sd,
+ &state,
+ L.direct_diffuse,
+ L.indirect_diffuse,
+ type,
+ pass_filter);
break;
}
- case SHADER_EVAL_GLOSSY_DIRECT:
+ case SHADER_EVAL_GLOSSY:
{
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_glossy, shader_bsdf_glossy(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg,
+ &sd,
+ &state,
+ L.direct_glossy,
+ L.indirect_glossy,
+ type,
+ pass_filter);
break;
}
- case SHADER_EVAL_TRANSMISSION_DIRECT:
+ case SHADER_EVAL_TRANSMISSION:
{
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_transmission, shader_bsdf_transmission(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg,
+ &sd,
+ &state,
+ L.direct_transmission,
+ L.indirect_transmission,
+ type,
+ pass_filter);
break;
}
- case SHADER_EVAL_SUBSURFACE_DIRECT:
+ case SHADER_EVAL_SUBSURFACE:
{
#ifdef __SUBSURFACE__
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_subsurface, shader_bsdf_subsurface(kg, &sd));
-#endif
- break;
- }
- case SHADER_EVAL_DIFFUSE_INDIRECT:
- {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_diffuse, shader_bsdf_diffuse(kg, &sd));
- break;
- }
- case SHADER_EVAL_GLOSSY_INDIRECT:
- {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_glossy, shader_bsdf_glossy(kg, &sd));
- break;
- }
- case SHADER_EVAL_TRANSMISSION_INDIRECT:
- {
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_transmission, shader_bsdf_transmission(kg, &sd));
- break;
- }
- case SHADER_EVAL_SUBSURFACE_INDIRECT:
- {
-#ifdef __SUBSURFACE__
- shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_subsurface, shader_bsdf_subsurface(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg,
+ &sd,
+ &state,
+ L.direct_subsurface,
+ L.indirect_subsurface,
+ type,
+ pass_filter);
#endif
break;
}
@@ -402,11 +459,11 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
#endif
/* setup shader data */
- shader_setup_from_background(kg, &sd, &ray, 0, 0);
+ shader_setup_from_background(kg, &sd, &ray);
/* evaluate */
int flag = 0; /* we can't know which type of BSDF this is for */
- out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
+ out = shader_eval_background(kg, &sd, &state, flag, SHADER_CONTEXT_MAIN);
break;
}
default:
@@ -426,9 +483,18 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
output[i] += make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
}
-ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i, int sample)
+#endif /* __NO_BAKING__ */
+
+ccl_device void kernel_shader_evaluate(KernelGlobals *kg,
+ ccl_global uint4 *input,
+ ccl_global float4 *output,
+ ccl_global float *output_luma,
+ ShaderEvalType type,
+ int i,
+ int sample)
{
ShaderData sd;
+ PathState state = {0};
uint4 in = input[i];
float3 out;
@@ -443,7 +509,7 @@ ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *inpu
/* evaluate */
float3 P = sd.P;
- shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN);
+ shader_eval_displacement(kg, &sd, &state, SHADER_CONTEXT_MAIN);
out = sd.P - P;
}
else { // SHADER_EVAL_BACKGROUND
@@ -465,18 +531,30 @@ ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *inpu
#endif
/* setup shader data */
- shader_setup_from_background(kg, &sd, &ray, 0, 0);
+ shader_setup_from_background(kg, &sd, &ray);
/* evaluate */
int flag = 0; /* we can't know which type of BSDF this is for */
- out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
+ out = shader_eval_background(kg, &sd, &state, flag, SHADER_CONTEXT_MAIN);
}
/* write output */
- if(sample == 0)
- output[i] = make_float4(out.x, out.y, out.z, 0.0f);
- else
- output[i] += make_float4(out.x, out.y, out.z, 0.0f);
+ if(sample == 0) {
+ if(output != NULL) {
+ output[i] = make_float4(out.x, out.y, out.z, 0.0f);
+ }
+ if(output_luma != NULL) {
+ output_luma[i] = average(out);
+ }
+ }
+ else {
+ if(output != NULL) {
+ output[i] += make_float4(out.x, out.y, out.z, 0.0f);
+ }
+ if(output_luma != NULL) {
+ output_luma[i] += average(out);
+ }
+ }
}
CCL_NAMESPACE_END