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:
authorDalai Felinto <dfelinto@gmail.com>2016-01-15 18:00:56 +0300
committerDalai Felinto <dfelinto@gmail.com>2016-01-15 18:00:56 +0300
commit9a76354585e2cd2011267e79bd99ca59a06588f8 (patch)
treee775e7c44dc210ef9978b483930ade6a9b4d6fc5 /intern/cycles
parent9137a4401440d3f3206e989f49f3539079d685b8 (diff)
Cycles-Bake: Custom Baking passes
The combined pass is built with the contributions the user finds fit. It is useful for lightmap baking, as well as non-view dependent effects baking. The manual will be updated once we get closer to the 2.77 release. Meanwhile the new page can be found here: http://dalaifelinto.com/blender-manual/render/cycles/baking.html Reviewers: sergey, brecht Differential Revision: https://developer.blender.org/D1674
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/addon/__init__.py4
-rw-r--r--intern/cycles/blender/addon/engine.py4
-rw-r--r--intern/cycles/blender/addon/properties.py16
-rw-r--r--intern/cycles/blender/addon/ui.py41
-rw-r--r--intern/cycles/blender/addon/version_update.py63
-rw-r--r--intern/cycles/blender/blender_python.cpp6
-rw-r--r--intern/cycles/blender/blender_session.cpp66
-rw-r--r--intern/cycles/blender/blender_session.h9
-rw-r--r--intern/cycles/device/device_cpu.cpp3
-rw-r--r--intern/cycles/device/device_task.cpp2
-rw-r--r--intern/cycles/device/device_task.h1
-rw-r--r--intern/cycles/kernel/kernel_bake.h202
-rw-r--r--intern/cycles/kernel/kernel_types.h45
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu.h1
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h2
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel.cu4
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel.cl6
-rw-r--r--intern/cycles/render/bake.cpp30
-rw-r--r--intern/cycles/render/bake.h4
19 files changed, 349 insertions, 160 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 0783c1c4cba..e883413d935 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -67,8 +67,8 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, scene):
engine.render(self)
- def bake(self, scene, obj, pass_type, object_id, pixel_array, num_pixels, depth, result):
- engine.bake(self, obj, pass_type, object_id, pixel_array, num_pixels, depth, result)
+ def bake(self, scene, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
+ engine.bake(self, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
# viewport render
def view_update(self, context):
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 19fa23bd74a..42ec253613f 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -110,11 +110,11 @@ def render(engine):
_cycles.render(engine.session)
-def bake(engine, obj, pass_type, object_id, pixel_array, num_pixels, depth, result):
+def bake(engine, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
import _cycles
session = getattr(engine, "session", None)
if session is not None:
- _cycles.bake(engine.session, obj.as_pointer(), pass_type, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
+ _cycles.bake(engine.session, obj.as_pointer(), pass_type, pass_filter, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
def reset(engine, data, scene):
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index ed6cea2bcb2..c83da3d5b54 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -493,18 +493,10 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
('UV', "UV", ""),
('EMIT', "Emit", ""),
('ENVIRONMENT', "Environment", ""),
- ('DIFFUSE_DIRECT', "Diffuse Direct", ""),
- ('DIFFUSE_INDIRECT', "Diffuse Indirect", ""),
- ('DIFFUSE_COLOR', "Diffuse Color", ""),
- ('GLOSSY_DIRECT', "Glossy Direct", ""),
- ('GLOSSY_INDIRECT', "Glossy Indirect", ""),
- ('GLOSSY_COLOR', "Glossy Color", ""),
- ('TRANSMISSION_DIRECT', "Transmission Direct", ""),
- ('TRANSMISSION_INDIRECT', "Transmission Indirect", ""),
- ('TRANSMISSION_COLOR', "Transmission Color", ""),
- ('SUBSURFACE_DIRECT', "Subsurface Direct", ""),
- ('SUBSURFACE_INDIRECT', "Subsurface Indirect", ""),
- ('SUBSURFACE_COLOR', "Subsurface Color", ""),
+ ('DIFFUSE', "Diffuse", ""),
+ ('GLOSSY', "Glossy", ""),
+ ('TRANSMISSION', "Transmission", ""),
+ ('SUBSURFACE', "Subsurface", ""),
),
)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 8d00e4850d7..22df14201e8 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1448,16 +1448,49 @@ class CyclesRender_PT_bake(CyclesButtonsPanel, Panel):
if cscene.bake_type == 'NORMAL':
layout.separator()
- box = layout.box()
- box.label(text="Normal Settings:")
- box.prop(cbk, "normal_space", text="Space")
+ col = layout.column()
+ col.label(text="Normal Settings:")
+ col.prop(cbk, "normal_space", text="Space")
- row = box.row(align=True)
+ row = col.row(align=True)
row.label(text="Swizzle:")
row.prop(cbk, "normal_r", text="")
row.prop(cbk, "normal_g", text="")
row.prop(cbk, "normal_b", text="")
+ elif cscene.bake_type == 'COMBINED':
+ col = layout.column()
+ col.label(text="Combined Settings:")
+
+ row = col.row()
+ row.prop(cbk, "use_pass_ambient_occlusion")
+ row.prop(cbk, "use_pass_emit")
+
+ row = col.row(align=True)
+ row.prop(cbk, "use_pass_direct", toggle=True)
+ row.prop(cbk, "use_pass_indirect", toggle=True)
+
+ split = col.split()
+ split.active = cbk.use_pass_direct or cbk.use_pass_indirect
+
+ col = split.column()
+ col.prop(cbk, "use_pass_diffuse")
+ col.prop(cbk, "use_pass_glossy")
+
+ col = split.column()
+ col.prop(cbk, "use_pass_transmission")
+ col.prop(cbk, "use_pass_subsurface")
+
+ elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
+ layout.separator()
+ col = layout.column()
+ col.label(text="{0} Settings:".format(cscene.bake_type.title()))
+
+ row = col.row(align=True)
+ row.prop(cbk, "use_pass_direct", toggle=True)
+ row.prop(cbk, "use_pass_indirect", toggle=True)
+ row.prop(cbk, "use_pass_color", toggle=True)
+
class CyclesRender_PT_debug(CyclesButtonsPanel, Panel):
bl_label = "Debug"
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index eb6d5d957ad..d8b3f5bc672 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -113,6 +113,64 @@ def vector_curve_node_remap(node):
point.location.y = (point.location.y - 0.5) * 2.0
node.mapping.update()
+
+def custom_bake_remap(scene):
+ """
+ Remap bake types into the new types and set the flags accordingly
+ """
+ bake_lookup = (
+ 'COMBINED',
+ 'AO',
+ 'SHADOW',
+ 'NORMAL',
+ 'UV',
+ 'EMIT',
+ 'ENVIRONMENT',
+ 'DIFFUSE_DIRECT',
+ 'DIFFUSE_INDIRECT',
+ 'DIFFUSE_COLOR',
+ 'GLOSSY_DIRECT',
+ 'GLOSSY_INDIRECT',
+ 'GLOSSY_COLOR',
+ 'TRANSMISSION_DIRECT',
+ 'TRANSMISSION_INDIRECT',
+ 'TRANSMISSION_COLOR',
+ 'SUBSURFACE_DIRECT',
+ 'SUBSURFACE_INDIRECT',
+ 'SUBSURFACE_COLOR')
+
+ diffuse_direct_idx = bake_lookup.index('DIFFUSE_DIRECT')
+
+ cscene = scene.cycles
+
+ # Old bake type
+ bake_type_idx = cscene.get("bake_type")
+
+ if bake_type_idx is None:
+ cscene.bake_type = 'COMBINED'
+ return
+
+ # File doesn't need versioning
+ if bake_type_idx < diffuse_direct_idx:
+ return
+
+ # File needs versioning
+ bake_type = bake_lookup[bake_type_idx]
+ cscene.bake_type, end = bake_type.split('_')
+
+ if end == 'DIRECT':
+ scene.render.bake.use_pass_indirect = False
+ scene.render.bake.use_pass_color = False
+
+ elif end == 'INDIRECT':
+ scene.render.bake.use_pass_direct = False
+ scene.render.bake.use_pass_color = False
+
+ elif end == 'COLOR':
+ scene.render.bake.use_pass_direct = False
+ scene.render.bake.use_pass_indirect = False
+
+
@persistent
def do_versions(self):
# We don't modify startup file because it assumes to
@@ -156,3 +214,8 @@ def do_versions(self):
if bpy.data.version <= (2, 76, 5):
foreach_cycles_node(vector_curve_node_remap)
+
+ # Baking types changed
+ if bpy.data.version <= (2, 76, 6):
+ for scene in bpy.data.scenes:
+ custom_bake_remap(scene)
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index acc6f4cde95..006301eead7 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -269,9 +269,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
PyObject *pysession, *pyobject;
PyObject *pypixel_array, *pyresult;
const char *pass_type;
- int num_pixels, depth, object_id;
+ int num_pixels, depth, object_id, pass_filter;
- if(!PyArg_ParseTuple(args, "OOsiOiiO", &pysession, &pyobject, &pass_type, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult))
+ if(!PyArg_ParseTuple(args, "OOsiiOiiO", &pysession, &pyobject, &pass_type, &pass_filter, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
@@ -288,7 +288,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state);
- session->bake(b_object, pass_type, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
+ session->bake(b_object, pass_type, pass_filter, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
python_thread_state_restore(&session->python_thread_state);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 088748cc0ae..a2a399e6152 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -316,22 +316,14 @@ static ShaderEvalType get_shader_type(const string& pass_type)
return SHADER_EVAL_COMBINED;
else if(strcmp(shader_type, "SHADOW")==0)
return SHADER_EVAL_SHADOW;
- else if(strcmp(shader_type, "DIFFUSE_DIRECT")==0)
- return SHADER_EVAL_DIFFUSE_DIRECT;
- else if(strcmp(shader_type, "GLOSSY_DIRECT")==0)
- return SHADER_EVAL_GLOSSY_DIRECT;
- else if(strcmp(shader_type, "TRANSMISSION_DIRECT")==0)
- return SHADER_EVAL_TRANSMISSION_DIRECT;
- else if(strcmp(shader_type, "SUBSURFACE_DIRECT")==0)
- return SHADER_EVAL_SUBSURFACE_DIRECT;
- else if(strcmp(shader_type, "DIFFUSE_INDIRECT")==0)
- return SHADER_EVAL_DIFFUSE_INDIRECT;
- else if(strcmp(shader_type, "GLOSSY_INDIRECT")==0)
- return SHADER_EVAL_GLOSSY_INDIRECT;
- else if(strcmp(shader_type, "TRANSMISSION_INDIRECT")==0)
- return SHADER_EVAL_TRANSMISSION_INDIRECT;
- else if(strcmp(shader_type, "SUBSURFACE_INDIRECT")==0)
- return SHADER_EVAL_SUBSURFACE_INDIRECT;
+ else if(strcmp(shader_type, "DIFFUSE")==0)
+ return SHADER_EVAL_DIFFUSE;
+ else if(strcmp(shader_type, "GLOSSY")==0)
+ return SHADER_EVAL_GLOSSY;
+ else if(strcmp(shader_type, "TRANSMISSION")==0)
+ return SHADER_EVAL_TRANSMISSION;
+ else if(strcmp(shader_type, "SUBSURFACE")==0)
+ return SHADER_EVAL_SUBSURFACE;
/* extra */
else if(strcmp(shader_type, "ENVIRONMENT")==0)
@@ -543,11 +535,47 @@ static void populate_bake_data(BakeData *data, const int object_id, BL::BakePixe
}
}
-void BlenderSession::bake(BL::Object b_object, const string& pass_type, const int object_id, BL::BakePixel pixel_array, const size_t num_pixels, const int /*depth*/, float result[])
+static int bake_pass_filter_get(const int pass_filter)
+{
+ int flag = BAKE_FILTER_NONE;
+
+ if((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0)
+ flag |= BAKE_FILTER_DIRECT;
+ if((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0)
+ flag |= BAKE_FILTER_INDIRECT;
+ if((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0)
+ flag |= BAKE_FILTER_COLOR;
+
+ if((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0)
+ flag |= BAKE_FILTER_DIFFUSE;
+ if((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0)
+ flag |= BAKE_FILTER_GLOSSY;
+ if((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
+ flag |= BAKE_FILTER_TRANSMISSION;
+ if((pass_filter & BL::BakeSettings::pass_filter_SUBSURFACE) != 0)
+ flag |= BAKE_FILTER_SUBSURFACE;
+
+ if((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
+ flag |= BAKE_FILTER_EMISSION;
+ if((pass_filter & BL::BakeSettings::pass_filter_AO) != 0)
+ flag |= BAKE_FILTER_AO;
+
+ return flag;
+}
+
+void BlenderSession::bake(BL::Object b_object,
+ const string& pass_type,
+ const int pass_filter,
+ const int object_id,
+ BL::BakePixel pixel_array,
+ const size_t num_pixels,
+ const int /*depth*/,
+ float result[])
{
ShaderEvalType shader_type = get_shader_type(pass_type);
size_t object_index = OBJECT_NONE;
int tri_offset = 0;
+ int bake_pass_filter = bake_pass_filter_get(pass_filter);
/* Set baking flag in advance, so kernel loading can check if we need
* any baking capabilities.
@@ -565,7 +593,7 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, const in
Pass::add(PASS_UV, scene->film->passes);
}
- if(BakeManager::is_light_pass(shader_type)) {
+ if(BakeManager::is_light_pass(shader_type, bake_pass_filter)) {
/* force use_light_pass to be true */
Pass::add(PASS_LIGHT, scene->film->passes);
}
@@ -617,7 +645,7 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, const in
session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this));
- scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result);
+ scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_pass_filter, bake_data, result);
/* free all memory used (host and device), so we wouldn't leave render
* engine with extra memory allocated
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 708776dc8ca..0d391cadc98 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -52,7 +52,14 @@ public:
/* offline render */
void render();
- void bake(BL::Object b_object, const string& pass_type, const int object_id, BL::BakePixel pixel_array, const size_t num_pixels, const int depth, float pixels[]);
+ void bake(BL::Object b_object,
+ const string& pass_type,
+ const int custom_flag,
+ const int object_id,
+ BL::BakePixel pixel_array,
+ const size_t num_pixels,
+ const int depth,
+ float pixels[]);
void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile);
void write_render_tile(RenderTile& rtile);
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 3241f32e006..83447b7a5f3 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -397,7 +397,7 @@ public:
#ifdef WITH_OSL
OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
#endif
- void(*shader_kernel)(KernelGlobals*, uint4*, float4*, float*, int, int, int, int);
+ void(*shader_kernel)(KernelGlobals*, uint4*, float4*, float*, int, int, int, int, int);
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
if(system_cpu_support_avx2()) {
@@ -440,6 +440,7 @@ public:
(float4*)task.shader_output,
(float*)task.shader_output_luma,
task.shader_eval_type,
+ task.shader_filter,
x,
task.offset,
sample);
diff --git a/intern/cycles/device/device_task.cpp b/intern/cycles/device/device_task.cpp
index 0cae118a692..1f1128a28f8 100644
--- a/intern/cycles/device/device_task.cpp
+++ b/intern/cycles/device/device_task.cpp
@@ -30,7 +30,7 @@ DeviceTask::DeviceTask(Type type_)
: type(type_), x(0), y(0), w(0), h(0), rgba_byte(0), rgba_half(0), buffer(0),
sample(0), num_samples(1),
shader_input(0), shader_output(0), shader_output_luma(0),
- shader_eval_type(0), shader_x(0), shader_w(0)
+ shader_eval_type(0), shader_filter(0), shader_x(0), shader_w(0)
{
last_update_time = time_dt();
}
diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h
index 7654508d4a5..d7912f386f5 100644
--- a/intern/cycles/device/device_task.h
+++ b/intern/cycles/device/device_task.h
@@ -48,6 +48,7 @@ public:
device_ptr shader_input;
device_ptr shader_output, shader_output_luma;
int shader_eval_type;
+ int shader_filter;
int shader_x, shader_w;
DeviceTask(Type type = PATH_TRACE);
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 2a2220ceb99..31e58de0b48 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN
#undef USE_BAKE_JITTER
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)
+ const bool is_ao, const bool is_sss, int sample)
{
/* initialize master radiance accumulator */
kernel_assert(kernel_data.film.use_light_pass);
@@ -56,13 +56,13 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
#endif
/* sample ambient occlusion */
- if(is_combined || is_ao) {
+ if(is_ao) {
kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
}
#ifdef __SUBSURFACE__
/* sample subsurface scattering */
- if((is_combined || is_sss_sample) && (sd->flag & SD_BSSRDF)) {
+ if(is_sss_sample && (sd->flag & SD_BSSRDF)) {
/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
SubsurfaceIndirectRays ss_indirect;
kernel_path_subsurface_init_indirect(&ss_indirect);
@@ -124,13 +124,13 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
/* branched path tracer */
/* sample ambient occlusion */
- if(is_combined || is_ao) {
+ if(is_ao) {
kernel_branched_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
}
#ifdef __SUBSURFACE__
/* sample subsurface scattering */
- if((is_combined || is_sss_sample) && (sd->flag & SD_BSSRDF)) {
+ if(is_sss_sample && (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);
}
@@ -175,21 +175,27 @@ ccl_device bool is_aa_pass(ShaderEvalType type)
}
}
-ccl_device bool is_light_pass(ShaderEvalType type)
+/* Keep it synced with BakeManager::is_light_pass. */
+ccl_device bool is_light_pass(ShaderEvalType type, const int pass_filter)
{
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;
+ case SHADER_EVAL_DIFFUSE:
+ case SHADER_EVAL_GLOSSY:
+ case SHADER_EVAL_TRANSMISSION:
+ return ((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
+ ((pass_filter & BAKE_FILTER_INDIRECT) != 0);
+ case SHADER_EVAL_COMBINED:
+ return ((pass_filter & BAKE_FILTER_AO) != 0) ||
+ ((pass_filter & BAKE_FILTER_EMISSION) != 0) ||
+ ((((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
+ ((pass_filter & BAKE_FILTER_INDIRECT) != 0)) &&
+ (((pass_filter & BAKE_FILTER_DIFFUSE) != 0) ||
+ ((pass_filter & BAKE_FILTER_GLOSSY) != 0) ||
+ ((pass_filter & BAKE_FILTER_TRANSMISSION) != 0) ||
+ ((pass_filter & BAKE_FILTER_SUBSURFACE) != 0)));
default:
return false;
}
@@ -208,15 +214,52 @@ ccl_device_inline float bake_clamp_mirror_repeat(float u)
return (((int)fu) & 1)? 1.0f - u: u;
}
+ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg, ShaderData *sd, PathState *state,
+ float3 (*shader_bsdf)(KernelGlobals *kg, ShaderData *sd),
+ float3 direct, float3 indirect, 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 shader_bsdf(kg, sd);
+ }
+ }
+ else {
+ shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN);
+ color = shader_bsdf(kg, sd);
+ }
+
+ 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;
@@ -279,13 +322,23 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
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);
+ if(is_light_pass(type, pass_filter)) {
+ bool is_ao, is_sss;
+
+ if (type == SHADER_EVAL_COMBINED) {
+ is_ao = (pass_filter & BAKE_FILTER_AO) != 0;
+ is_sss = ((pass_filter & BAKE_FILTER_SUBSURFACE) != 0) &&
+ (((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
+ ((pass_filter & BAKE_FILTER_INDIRECT) != 0));
+ }
+ else {
+ is_ao = (type == SHADER_EVAL_AO);
+ is_sss = (type == SHADER_EVAL_SUBSURFACE) &&
+ (((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
+ ((pass_filter & BAKE_FILTER_INDIRECT) != 0));
+ }
+
+ compute_light_pass(kg, &sd, &L, rng, is_ao, is_sss, sample);
}
switch(type) {
@@ -305,32 +358,6 @@ 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, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_diffuse(kg, &sd);
- break;
- }
- case SHADER_EVAL_GLOSSY_COLOR:
- {
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_glossy(kg, &sd);
- break;
- }
- case SHADER_EVAL_TRANSMISSION_COLOR:
- {
- shader_eval_surface(kg, &sd, &state, 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, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = shader_bsdf_subsurface(kg, &sd);
-#endif
- break;
- }
case SHADER_EVAL_EMISSION:
{
shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_EMISSION);
@@ -347,7 +374,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:
@@ -355,55 +409,25 @@ 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:
- {
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_diffuse, shader_bsdf_diffuse(kg, &sd));
- break;
- }
- case SHADER_EVAL_GLOSSY_DIRECT:
- {
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_glossy, shader_bsdf_glossy(kg, &sd));
- break;
- }
- case SHADER_EVAL_TRANSMISSION_DIRECT:
- {
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.direct_transmission, shader_bsdf_transmission(kg, &sd));
- break;
- }
- case SHADER_EVAL_SUBSURFACE_DIRECT:
- {
-#ifdef __SUBSURFACE__
- shader_eval_surface(kg, &sd, &state, 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:
+ case SHADER_EVAL_DIFFUSE:
{
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_diffuse, shader_bsdf_diffuse(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg, &sd, &state, &shader_bsdf_diffuse, L.direct_diffuse, L.indirect_diffuse, pass_filter);
break;
}
- case SHADER_EVAL_GLOSSY_INDIRECT:
+ case SHADER_EVAL_GLOSSY:
{
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_glossy, shader_bsdf_glossy(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg, &sd, &state, &shader_bsdf_glossy, L.direct_glossy, L.indirect_glossy, pass_filter);
break;
}
- case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ case SHADER_EVAL_TRANSMISSION:
{
- shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
- out = safe_divide_color(L.indirect_transmission, shader_bsdf_transmission(kg, &sd));
+ out = kernel_bake_evaluate_direct_indirect(kg, &sd, &state, &shader_bsdf_transmission, L.direct_transmission, L.indirect_transmission, pass_filter);
break;
}
- case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ case SHADER_EVAL_SUBSURFACE:
{
#ifdef __SUBSURFACE__
- shader_eval_surface(kg, &sd, &state, 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, &shader_bsdf_subsurface, L.direct_subsurface, L.indirect_subsurface, pass_filter);
#endif
break;
}
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 77fc16e3d35..da2416bc09b 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -218,14 +218,10 @@ typedef enum ShaderEvalType {
SHADER_EVAL_AO,
SHADER_EVAL_COMBINED,
SHADER_EVAL_SHADOW,
- SHADER_EVAL_DIFFUSE_DIRECT,
- SHADER_EVAL_GLOSSY_DIRECT,
- SHADER_EVAL_TRANSMISSION_DIRECT,
- SHADER_EVAL_SUBSURFACE_DIRECT,
- SHADER_EVAL_DIFFUSE_INDIRECT,
- SHADER_EVAL_GLOSSY_INDIRECT,
- SHADER_EVAL_TRANSMISSION_INDIRECT,
- SHADER_EVAL_SUBSURFACE_INDIRECT,
+ SHADER_EVAL_DIFFUSE,
+ SHADER_EVAL_GLOSSY,
+ SHADER_EVAL_TRANSMISSION,
+ SHADER_EVAL_SUBSURFACE,
/* extra */
SHADER_EVAL_ENVIRONMENT,
@@ -355,6 +351,39 @@ typedef enum PassType {
#define PASS_ALL (~0)
+typedef enum BakePassFilter {
+ BAKE_FILTER_NONE = 0,
+ BAKE_FILTER_DIRECT = (1 << 0),
+ BAKE_FILTER_INDIRECT = (1 << 1),
+ BAKE_FILTER_COLOR = (1 << 2),
+ BAKE_FILTER_DIFFUSE = (1 << 3),
+ BAKE_FILTER_GLOSSY = (1 << 4),
+ BAKE_FILTER_TRANSMISSION = (1 << 5),
+ BAKE_FILTER_SUBSURFACE = (1 << 6),
+ BAKE_FILTER_EMISSION = (1 << 7),
+ BAKE_FILTER_AO = (1 << 8),
+} BakePassFilter;
+
+typedef enum BakePassFilterCombos {
+ BAKE_FILTER_COMBINED = (
+ BAKE_FILTER_DIRECT |
+ BAKE_FILTER_INDIRECT |
+ BAKE_FILTER_DIFFUSE |
+ BAKE_FILTER_GLOSSY |
+ BAKE_FILTER_TRANSMISSION |
+ BAKE_FILTER_SUBSURFACE |
+ BAKE_FILTER_EMISSION |
+ BAKE_FILTER_AO),
+ BAKE_FILTER_DIFFUSE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_DIFFUSE),
+ BAKE_FILTER_GLOSSY_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_GLOSSY),
+ BAKE_FILTER_TRANSMISSION_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_TRANSMISSION),
+ BAKE_FILTER_SUBSURFACE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_SUBSURFACE),
+ BAKE_FILTER_DIFFUSE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_DIFFUSE),
+ BAKE_FILTER_GLOSSY_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_GLOSSY),
+ BAKE_FILTER_TRANSMISSION_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_TRANSMISSION),
+ BAKE_FILTER_SUBSURFACE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_SUBSURFACE),
+} BakePassFilterCombos;
+
#ifdef __PASSES__
typedef ccl_addr_space struct PathRadiance {
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
index 1ce1e41272b..1a07c705f1c 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
@@ -44,6 +44,7 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
float4 *output,
float *output_luma,
int type,
+ int filter,
int i,
int offset,
int sample);
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
index 0249610b381..1454f925ab9 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
@@ -101,6 +101,7 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
float4 *output,
float *output_luma,
int type,
+ int filter,
int i,
int offset,
int sample)
@@ -111,6 +112,7 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
input,
output,
(ShaderEvalType)type,
+ filter,
i,
offset,
sample);
diff --git a/intern/cycles/kernel/kernels/cuda/kernel.cu b/intern/cycles/kernel/kernels/cuda/kernel.cu
index e094612de01..c8940b981bb 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel.cu
+++ b/intern/cycles/kernel/kernels/cuda/kernel.cu
@@ -183,12 +183,12 @@ kernel_cuda_shader(uint4 *input,
extern "C" __global__ void
CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
-kernel_cuda_bake(uint4 *input, float4 *output, int type, int sx, int sw, int offset, int sample)
+kernel_cuda_bake(uint4 *input, float4 *output, int type, int filter, int sx, int sw, int offset, int sample)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
if(x < sx + sw)
- kernel_bake_evaluate(NULL, input, output, (ShaderEvalType)type, x, offset, sample);
+ kernel_bake_evaluate(NULL, input, output, (ShaderEvalType)type, filter, x, offset, sample);
}
#endif
diff --git a/intern/cycles/kernel/kernels/opencl/kernel.cl b/intern/cycles/kernel/kernels/opencl/kernel.cl
index 4c9f7ba1d7c..0a44a4d0301 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel.cl
+++ b/intern/cycles/kernel/kernels/opencl/kernel.cl
@@ -99,7 +99,7 @@ __kernel void kernel_ocl_bake(
ccl_global type *name,
#include "../../kernel_textures.h"
- int type, int sx, int sw, int offset, int sample)
+ int type, int filter, int sx, int sw, int offset, int sample)
{
KernelGlobals kglobals, *kg = &kglobals;
@@ -115,7 +115,7 @@ __kernel void kernel_ocl_bake(
#ifdef __NO_BAKING__
output[x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#else
- kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, x, offset, sample);
+ kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, filter, x, offset, sample);
#endif
}
}
@@ -174,4 +174,4 @@ __kernel void kernel_ocl_convert_to_half_float(
kernel_film_convert_to_half_float(kg, rgba, buffer, sample_scale, x, y, offset, stride);
}
-#endif // __COMPILE_ONLY_MEGAKERNEL__ \ No newline at end of file
+#endif // __COMPILE_ONLY_MEGAKERNEL__
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 4bbac0f91d1..6a3adcabeb1 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -131,7 +131,7 @@ void BakeManager::set_shader_limit(const size_t x, const size_t y)
m_shader_limit = (size_t)pow(2, ceil(log(m_shader_limit)/log(2)));
}
-bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[])
+bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, const int pass_filter, BakeData *bake_data, float result[])
{
size_t num_pixels = bake_data->size();
@@ -183,6 +183,7 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre
task.shader_input = d_input.device_pointer;
task.shader_output = d_output.device_pointer;
task.shader_eval_type = shader_type;
+ task.shader_filter = pass_filter;
task.shader_x = 0;
task.offset = shader_offset;
task.shader_w = d_output.size();
@@ -254,21 +255,28 @@ bool BakeManager::is_aa_pass(ShaderEvalType type)
}
}
-bool BakeManager::is_light_pass(ShaderEvalType type)
+/* Keep it synced with kernel_bake.h::is_light_pass. */
+bool BakeManager::is_light_pass(ShaderEvalType type, const int pass_filter)
{
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;
+ case SHADER_EVAL_DIFFUSE:
+ case SHADER_EVAL_GLOSSY:
+ case SHADER_EVAL_TRANSMISSION:
+ case SHADER_EVAL_SUBSURFACE:
+ return ((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
+ ((pass_filter & BAKE_FILTER_INDIRECT) != 0);
+ case SHADER_EVAL_COMBINED:
+ return ((pass_filter & BAKE_FILTER_AO) != 0) ||
+ ((pass_filter & BAKE_FILTER_EMISSION) != 0) ||
+ ((((pass_filter & BAKE_FILTER_DIRECT) != 0) ||
+ ((pass_filter & BAKE_FILTER_INDIRECT) != 0)) &&
+ (((pass_filter & BAKE_FILTER_DIFFUSE) != 0) ||
+ ((pass_filter & BAKE_FILTER_GLOSSY) != 0) ||
+ ((pass_filter & BAKE_FILTER_TRANSMISSION) != 0) ||
+ ((pass_filter & BAKE_FILTER_SUBSURFACE) != 0)));
default:
return false;
}
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index 14d975a4b4e..b731b213065 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -63,12 +63,12 @@ public:
void set_shader_limit(const size_t x, const size_t y);
- bool bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[]);
+ bool bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, const int pass_filter, BakeData *bake_data, float result[]);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
- static bool is_light_pass(ShaderEvalType type);
+ static bool is_light_pass(ShaderEvalType type, const int pass_filter);
static bool is_aa_pass(ShaderEvalType type);
bool need_update;