diff options
author | Lukas Stockner <lukasstockner97> | 2019-12-04 21:57:28 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-12-10 22:44:46 +0300 |
commit | e760972221e68d3c81f2ee3687cc71836dde8ae9 (patch) | |
tree | b1a2efbb17c05a429e4509d336a1eb14c73cfb8c /intern/cycles/kernel | |
parent | 35b5888b157d05d378df3acc899d28856a9eb9a4 (diff) |
Cycles: support for custom shader AOVs
Custom render passes are added in the Shader AOVs panel in the view layer
settings, with a name and data type. In shader nodes, an AOV Output node
is then used to output either a value or color to the pass.
Arbitrary names can be used for these passes, as long as they don't conflict
with built-in passes that are enabled. The AOV Output node can be used in both
material and world shader nodes.
Implemented by Lukas, with tweaks by Brecht.
Differential Revision: https://developer.blender.org/D4837
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_bake.h | 12 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_passes.h | 74 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 14 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path_branched.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shadow.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_subsurface.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_write_passes.h | 95 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/split/kernel_indirect_background.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/split/kernel_shader_eval.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_aov.h | 49 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 3 |
17 files changed, 203 insertions, 97 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 4077a1ad516..99172f30b8b 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -129,6 +129,7 @@ set(SRC_HEADERS kernel_types.h kernel_volume.h kernel_work_stealing.h + kernel_write_passes.h ) set(SRC_KERNELS_CPU_HEADERS @@ -182,6 +183,7 @@ set(SRC_CLOSURE_HEADERS set(SRC_SVM_HEADERS svm/svm.h svm/svm_ao.h + svm/svm_aov.h svm/svm_attribute.h svm/svm_bevel.h svm/svm_blackbody.h diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index cd1ca5ea7ec..8e5a279e6cd 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -45,7 +45,7 @@ ccl_device_inline void compute_light_pass( path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL); /* evaluate surface shader */ - shader_eval_surface(kg, sd, &state, state.flag); + shader_eval_surface(kg, sd, &state, NULL, state.flag); /* TODO, disable more closures we don't need besides transparent */ shader_bsdf_disable_transparency(kg, sd); @@ -209,12 +209,12 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg, } else { /* surface color of the pass only */ - shader_eval_surface(kg, sd, state, 0); + shader_eval_surface(kg, sd, state, NULL, 0); return kernel_bake_shader_bsdf(kg, sd, type); } } else { - shader_eval_surface(kg, sd, state, 0); + shader_eval_surface(kg, sd, state, NULL, 0); color = kernel_bake_shader_bsdf(kg, sd, type); } @@ -332,7 +332,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, case SHADER_EVAL_EMISSION: { if (type != SHADER_EVAL_NORMAL || (sd.flag & SD_HAS_BUMP)) { int path_flag = (type == SHADER_EVAL_EMISSION) ? PATH_RAY_EMISSION : 0; - shader_eval_surface(kg, &sd, &state, path_flag); + shader_eval_surface(kg, &sd, &state, NULL, path_flag); } if (type == SHADER_EVAL_NORMAL) { @@ -445,7 +445,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, /* evaluate */ int path_flag = 0; /* we can't know which type of BSDF this is for */ - shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION); + shader_eval_surface(kg, &sd, &state, NULL, path_flag | PATH_RAY_EMISSION); out = shader_background_eval(&sd); break; } @@ -524,7 +524,7 @@ ccl_device void kernel_background_evaluate(KernelGlobals *kg, /* evaluate */ int path_flag = 0; /* we can't know which type of BSDF this is for */ - shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION); + shader_eval_surface(kg, &sd, &state, NULL, path_flag | PATH_RAY_EMISSION); float3 color = shader_background_eval(&sd); /* write output */ diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 459280cf433..e70958c2b06 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -73,7 +73,7 @@ ccl_device_noinline_cpu float3 direct_emissive_eval(KernelGlobals *kg, /* No proper path flag, we're evaluating this for all closures. that's * weak but we'd have to do multiple evaluations otherwise. */ path_state_modify_bounce(state, true); - shader_eval_surface(kg, emission_sd, state, PATH_RAY_EMISSION); + shader_eval_surface(kg, emission_sd, state, NULL, PATH_RAY_EMISSION); path_state_modify_bounce(state, false); /* Evaluate closures. */ @@ -294,6 +294,7 @@ ccl_device_noinline_cpu bool indirect_lamp_emission(KernelGlobals *kg, ccl_device_noinline_cpu float3 indirect_background(KernelGlobals *kg, ShaderData *emission_sd, ccl_addr_space PathState *state, + ccl_global float *buffer, ccl_addr_space Ray *ray) { #ifdef __BACKGROUND__ @@ -322,7 +323,7 @@ ccl_device_noinline_cpu float3 indirect_background(KernelGlobals *kg, # endif path_state_modify_bounce(state, true); - shader_eval_surface(kg, emission_sd, state, state->flag | PATH_RAY_EMISSION); + shader_eval_surface(kg, emission_sd, state, buffer, state->flag | PATH_RAY_EMISSION); path_state_modify_bounce(state, false); L = shader_background_eval(emission_sd); diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index 3e423e42573..828add9dc13 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -14,85 +14,11 @@ * limitations under the License. */ -#if defined(__SPLIT_KERNEL__) || defined(__KERNEL_CUDA__) -# define __ATOMIC_PASS_WRITE__ -#endif - #include "kernel/kernel_id_passes.h" CCL_NAMESPACE_BEGIN -ccl_device_inline void kernel_write_pass_float(ccl_global float *buffer, float value) -{ - ccl_global float *buf = buffer; -#ifdef __ATOMIC_PASS_WRITE__ - atomic_add_and_fetch_float(buf, value); -#else - *buf += value; -#endif -} - -ccl_device_inline void kernel_write_pass_float3(ccl_global float *buffer, float3 value) -{ -#ifdef __ATOMIC_PASS_WRITE__ - ccl_global float *buf_x = buffer + 0; - ccl_global float *buf_y = buffer + 1; - ccl_global float *buf_z = buffer + 2; - - atomic_add_and_fetch_float(buf_x, value.x); - atomic_add_and_fetch_float(buf_y, value.y); - atomic_add_and_fetch_float(buf_z, value.z); -#else - ccl_global float3 *buf = (ccl_global float3 *)buffer; - *buf += value; -#endif -} - -ccl_device_inline void kernel_write_pass_float4(ccl_global float *buffer, float4 value) -{ -#ifdef __ATOMIC_PASS_WRITE__ - ccl_global float *buf_x = buffer + 0; - ccl_global float *buf_y = buffer + 1; - ccl_global float *buf_z = buffer + 2; - ccl_global float *buf_w = buffer + 3; - - atomic_add_and_fetch_float(buf_x, value.x); - atomic_add_and_fetch_float(buf_y, value.y); - atomic_add_and_fetch_float(buf_z, value.z); - atomic_add_and_fetch_float(buf_w, value.w); -#else - ccl_global float4 *buf = (ccl_global float4 *)buffer; - *buf += value; -#endif -} - #ifdef __DENOISING_FEATURES__ -ccl_device_inline void kernel_write_pass_float_variance(ccl_global float *buffer, float value) -{ - kernel_write_pass_float(buffer, value); - - /* The online one-pass variance update that's used for the mega-kernel can't easily be - * implemented with atomics, - * so for the split kernel the E[x^2] - 1/N * (E[x])^2 fallback is used. */ - kernel_write_pass_float(buffer + 1, value * value); -} - -# ifdef __ATOMIC_PASS_WRITE__ -# define kernel_write_pass_float3_unaligned kernel_write_pass_float3 -# else -ccl_device_inline void kernel_write_pass_float3_unaligned(ccl_global float *buffer, float3 value) -{ - buffer[0] += value.x; - buffer[1] += value.y; - buffer[2] += value.z; -} -# endif - -ccl_device_inline void kernel_write_pass_float3_variance(ccl_global float *buffer, float3 value) -{ - kernel_write_pass_float3_unaligned(buffer, value); - kernel_write_pass_float3_unaligned(buffer + 3, value * value); -} ccl_device_inline void kernel_write_denoising_shadow(KernelGlobals *kg, ccl_global float *buffer, diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 55abe39c465..693efad8c50 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -27,6 +27,7 @@ #include "kernel/geom/geom.h" #include "kernel/bvh/bvh.h" +#include "kernel/kernel_write_passes.h" #include "kernel/kernel_accumulate.h" #include "kernel/kernel_shader.h" #include "kernel/kernel_light.h" @@ -116,6 +117,7 @@ ccl_device_forceinline void kernel_path_background(KernelGlobals *kg, ccl_addr_space Ray *ray, float3 throughput, ShaderData *sd, + ccl_global float *buffer, PathRadiance *L) { /* eval background shader if nothing hit */ @@ -136,7 +138,7 @@ ccl_device_forceinline void kernel_path_background(KernelGlobals *kg, #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, sd, state, ray); + float3 L_background = indirect_background(kg, sd, state, buffer, ray); path_radiance_accum_background(L, state, throughput, L_background); #endif /* __BACKGROUND__ */ } @@ -267,7 +269,7 @@ ccl_device_forceinline bool kernel_path_shader_apply(KernelGlobals *kg, float3 bg = make_float3(0.0f, 0.0f, 0.0f); if (!kernel_data.background.transparent) { - bg = indirect_background(kg, emission_sd, state, ray); + bg = indirect_background(kg, emission_sd, state, NULL, ray); } path_radiance_accum_shadowcatcher(L, throughput, bg); } @@ -418,7 +420,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* Shade background. */ if (!hit) { - kernel_path_background(kg, state, ray, throughput, sd, L); + kernel_path_background(kg, state, ray, throughput, sd, NULL, L); break; } else if (path_state_ao_bounce(kg, state)) { @@ -434,7 +436,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, # endif /* Evaluate shader. */ - shader_eval_surface(kg, sd, state, state->flag); + shader_eval_surface(kg, sd, state, NULL, state->flag); shader_prepare_closures(sd, state); /* Apply shadow catcher, holdout, emission. */ @@ -556,7 +558,7 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg, /* Shade background. */ if (!hit) { - kernel_path_background(kg, state, ray, throughput, &sd, L); + kernel_path_background(kg, state, ray, throughput, &sd, buffer, L); break; } else if (path_state_ao_bounce(kg, state)) { @@ -572,7 +574,7 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg, # endif /* Evaluate shader. */ - shader_eval_surface(kg, &sd, state, state->flag); + shader_eval_surface(kg, &sd, state, buffer, state->flag); shader_prepare_closures(&sd, state); /* Apply shadow catcher, holdout, emission. */ diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index ea6b23e7eb4..39309379f0c 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -405,7 +405,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, /* Shade background. */ if (!hit) { - kernel_path_background(kg, &state, &ray, throughput, &sd, L); + kernel_path_background(kg, &state, &ray, throughput, &sd, buffer, L); break; } @@ -417,7 +417,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, if (!(sd.flag & SD_HAS_ONLY_VOLUME)) { # endif - shader_eval_surface(kg, &sd, &state, state.flag); + shader_eval_surface(kg, &sd, &state, buffer, state.flag); shader_merge_closures(&sd); /* Apply shadow catcher, holdout, emission. */ diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 7ccb99cad2a..d03faff4242 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -1076,6 +1076,7 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd) ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, + ccl_global float *buffer, int path_flag) { PROFILING_INIT(kg, PROFILING_SHADER_EVAL); @@ -1107,7 +1108,7 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, #endif { #ifdef __SVM__ - svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag); + svm_eval_nodes(kg, sd, state, buffer, SHADER_TYPE_SURFACE, path_flag); #else if (sd->object == OBJECT_NONE) { sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f); @@ -1319,7 +1320,7 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg, else # endif { - svm_eval_nodes(kg, sd, state, SHADER_TYPE_VOLUME, path_flag); + svm_eval_nodes(kg, sd, state, NULL, SHADER_TYPE_VOLUME, path_flag); } # endif @@ -1348,7 +1349,7 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, else # endif { - svm_eval_nodes(kg, sd, state, SHADER_TYPE_DISPLACEMENT, 0); + svm_eval_nodes(kg, sd, state, NULL, SHADER_TYPE_DISPLACEMENT, 0); } #endif } diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h index 61fcc61264a..b3ae29932da 100644 --- a/intern/cycles/kernel/kernel_shadow.h +++ b/intern/cycles/kernel/kernel_shadow.h @@ -71,7 +71,7 @@ ccl_device_forceinline bool shadow_handle_transparent_isect(KernelGlobals *kg, /* Attenuation from transparent surface. */ if (!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) { path_state_modify_bounce(state, true); - shader_eval_surface(kg, shadow_sd, state, PATH_RAY_SHADOW); + shader_eval_surface(kg, shadow_sd, state, NULL, PATH_RAY_SHADOW); path_state_modify_bounce(state, false); *throughput *= shader_bsdf_transparency(kg, shadow_sd); } diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h index dbe2c12ce81..23e30db1b08 100644 --- a/intern/cycles/kernel/kernel_subsurface.h +++ b/intern/cycles/kernel/kernel_subsurface.h @@ -138,7 +138,7 @@ ccl_device void subsurface_color_bump_blur( if (bump || texture_blur > 0.0f) { /* average color and normal at incoming point */ - shader_eval_surface(kg, sd, state, state->flag); + shader_eval_surface(kg, sd, state, NULL, state->flag); float3 in_color = shader_bssrdf_sum(sd, (bump) ? N : NULL, NULL); /* we simply divide out the average color and multiply with the average diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 7306c32d7c8..c35e345763a 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -222,6 +222,8 @@ typedef enum ShaderEvalType { SHADER_EVAL_TRANSMISSION_COLOR, SHADER_EVAL_SUBSURFACE_COLOR, SHADER_EVAL_EMISSION, + SHADER_EVAL_AOV_COLOR, + SHADER_EVAL_AOV_VALUE, /* light passes */ SHADER_EVAL_AO, @@ -371,6 +373,8 @@ typedef enum PassType { #endif PASS_RENDER_TIME, PASS_CRYPTOMATTE, + PASS_AOV_COLOR, + PASS_AOV_VALUE, PASS_CATEGORY_MAIN_END = 31, PASS_MIST = 32, @@ -1244,6 +1248,11 @@ typedef struct KernelFilm { int pass_denoising_clean; int denoising_flags; + int pass_aov_color; + int pass_aov_value; + int pad1; + int pad2; + /* XYZ to rendering color space transform. float4 instead of float3 to * ensure consistent padding/alignment across devices. */ float4 xyz_to_r; diff --git a/intern/cycles/kernel/kernel_write_passes.h b/intern/cycles/kernel/kernel_write_passes.h new file mode 100644 index 00000000000..410218d91d4 --- /dev/null +++ b/intern/cycles/kernel/kernel_write_passes.h @@ -0,0 +1,95 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#if defined(__SPLIT_KERNEL__) || defined(__KERNEL_CUDA__) +# define __ATOMIC_PASS_WRITE__ +#endif + +CCL_NAMESPACE_BEGIN + +ccl_device_inline void kernel_write_pass_float(ccl_global float *buffer, float value) +{ + ccl_global float *buf = buffer; +#ifdef __ATOMIC_PASS_WRITE__ + atomic_add_and_fetch_float(buf, value); +#else + *buf += value; +#endif +} + +ccl_device_inline void kernel_write_pass_float3(ccl_global float *buffer, float3 value) +{ +#ifdef __ATOMIC_PASS_WRITE__ + ccl_global float *buf_x = buffer + 0; + ccl_global float *buf_y = buffer + 1; + ccl_global float *buf_z = buffer + 2; + + atomic_add_and_fetch_float(buf_x, value.x); + atomic_add_and_fetch_float(buf_y, value.y); + atomic_add_and_fetch_float(buf_z, value.z); +#else + ccl_global float3 *buf = (ccl_global float3 *)buffer; + *buf += value; +#endif +} + +ccl_device_inline void kernel_write_pass_float4(ccl_global float *buffer, float4 value) +{ +#ifdef __ATOMIC_PASS_WRITE__ + ccl_global float *buf_x = buffer + 0; + ccl_global float *buf_y = buffer + 1; + ccl_global float *buf_z = buffer + 2; + ccl_global float *buf_w = buffer + 3; + + atomic_add_and_fetch_float(buf_x, value.x); + atomic_add_and_fetch_float(buf_y, value.y); + atomic_add_and_fetch_float(buf_z, value.z); + atomic_add_and_fetch_float(buf_w, value.w); +#else + ccl_global float4 *buf = (ccl_global float4 *)buffer; + *buf += value; +#endif +} + +#ifdef __DENOISING_FEATURES__ +ccl_device_inline void kernel_write_pass_float_variance(ccl_global float *buffer, float value) +{ + kernel_write_pass_float(buffer, value); + + /* The online one-pass variance update that's used for the megakernel can't easily be implemented + * with atomics, so for the split kernel the E[x^2] - 1/N * (E[x])^2 fallback is used. */ + kernel_write_pass_float(buffer + 1, value * value); +} + +# ifdef __ATOMIC_PASS_WRITE__ +# define kernel_write_pass_float3_unaligned kernel_write_pass_float3 +# else +ccl_device_inline void kernel_write_pass_float3_unaligned(ccl_global float *buffer, float3 value) +{ + buffer[0] += value.x; + buffer[1] += value.y; + buffer[2] += value.z; +} +# endif + +ccl_device_inline void kernel_write_pass_float3_variance(ccl_global float *buffer, float3 value) +{ + kernel_write_pass_float3_unaligned(buffer, value); + kernel_write_pass_float3_unaligned(buffer + 3, value * value); +} +#endif /* __DENOISING_FEATURES__ */ + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 1b161fbc8ee..767bd7702ae 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -44,6 +44,7 @@ #include "kernel/kernel_globals.h" #include "kernel/kernel_color.h" #include "kernel/kernel_random.h" +#include "kernel/kernel_write_passes.h" #include "kernel/kernel_projection.h" #include "kernel/kernel_differential.h" #include "kernel/kernel_montecarlo.h" diff --git a/intern/cycles/kernel/split/kernel_indirect_background.h b/intern/cycles/kernel/split/kernel_indirect_background.h index b1c65f61e2c..6d500650cc0 100644 --- a/intern/cycles/kernel/split/kernel_indirect_background.h +++ b/intern/cycles/kernel/split/kernel_indirect_background.h @@ -58,8 +58,10 @@ ccl_device void kernel_indirect_background(KernelGlobals *kg) ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; float3 throughput = kernel_split_state.throughput[ray_index]; ShaderData *sd = kernel_split_sd(sd, ray_index); + uint buffer_offset = kernel_split_state.buffer_offset[ray_index]; + ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset; - kernel_path_background(kg, state, ray, throughput, sd, L); + kernel_path_background(kg, state, ray, throughput, sd, buffer, L); kernel_split_path_end(kg, ray_index); } } diff --git a/intern/cycles/kernel/split/kernel_shader_eval.h b/intern/cycles/kernel/split/kernel_shader_eval.h index 8e39c9797e5..c760a2b2049 100644 --- a/intern/cycles/kernel/split/kernel_shader_eval.h +++ b/intern/cycles/kernel/split/kernel_shader_eval.h @@ -50,8 +50,10 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg) ccl_global char *ray_state = kernel_split_state.ray_state; if (IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; + uint buffer_offset = kernel_split_state.buffer_offset[ray_index]; + ccl_global float *buffer = kernel_split_params.tile.buffer + buffer_offset; - shader_eval_surface(kg, kernel_split_sd(sd, ray_index), state, state->flag); + shader_eval_surface(kg, kernel_split_sd(sd, ray_index), state, buffer, state->flag); #ifdef __BRANCHED_PATH__ if (kernel_data.integrator.branched) { shader_merge_closures(kernel_split_sd(sd, ray_index)); diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 18f086d6726..c4d7164a4d8 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -164,6 +164,7 @@ CCL_NAMESPACE_END #include "kernel/svm/svm_math_util.h" #include "kernel/svm/svm_mapping_util.h" +#include "kernel/svm/svm_aov.h" #include "kernel/svm/svm_attribute.h" #include "kernel/svm/svm_gradient.h" #include "kernel/svm/svm_blackbody.h" @@ -218,6 +219,7 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, + ccl_global float *buffer, ShaderType type, int path_flag) { @@ -467,6 +469,17 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, case NODE_IES: svm_node_ies(kg, sd, stack, node, &offset); break; + case NODE_AOV_START: + if (!svm_node_aov_check(state, buffer)) { + return; + } + break; + case NODE_AOV_COLOR: + svm_node_aov_color(kg, sd, stack, node, buffer); + break; + case NODE_AOV_VALUE: + svm_node_aov_value(kg, sd, stack, node, buffer); + break; # endif /* __EXTRA_NODES__ */ #endif /* NODES_GROUP(NODE_GROUP_LEVEL_2) */ diff --git a/intern/cycles/kernel/svm/svm_aov.h b/intern/cycles/kernel/svm/svm_aov.h new file mode 100644 index 00000000000..899e466d099 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_aov.h @@ -0,0 +1,49 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +CCL_NAMESPACE_BEGIN + +ccl_device_inline bool svm_node_aov_check(ccl_addr_space PathState *state, + ccl_global float *buffer) +{ + int path_flag = state->flag; + + bool is_primary = (path_flag & PATH_RAY_CAMERA) && (!(path_flag & PATH_RAY_SINGLE_PASS_DONE)); + + return ((buffer != NULL) && is_primary); +} + +ccl_device void svm_node_aov_color( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ccl_global float *buffer) +{ + float3 val = stack_load_float3(stack, node.y); + + if (buffer) { + kernel_write_pass_float4(buffer + kernel_data.film.pass_aov_color + 4 * node.z, + make_float4(val.x, val.y, val.z, 1.0f)); + } +} + +ccl_device void svm_node_aov_value( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ccl_global float *buffer) +{ + float val = stack_load_float(stack, node.y); + + if (buffer) { + kernel_write_pass_float(buffer + kernel_data.film.pass_aov_value + node.z, val); + } +} +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 040e7c6a0f8..8dbb147e76a 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -150,6 +150,9 @@ typedef enum ShaderNodeType { NODE_VERTEX_COLOR, NODE_VERTEX_COLOR_BUMP_DX, NODE_VERTEX_COLOR_BUMP_DY, + NODE_AOV_START, + NODE_AOV_VALUE, + NODE_AOV_COLOR, } ShaderNodeType; typedef enum NodeAttributeType { |