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
This commit is contained in:
parent
9137a44014
commit
9a76354585
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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", ""),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
case SHADER_EVAL_DIFFUSE:
|
||||
{
|
||||
shader_eval_surface(kg, &sd, &state, 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, &shader_bsdf_diffuse, L.direct_diffuse, L.indirect_diffuse, pass_filter);
|
||||
break;
|
||||
}
|
||||
case SHADER_EVAL_GLOSSY_DIRECT:
|
||||
case SHADER_EVAL_GLOSSY:
|
||||
{
|
||||
shader_eval_surface(kg, &sd, &state, 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, &shader_bsdf_glossy, L.direct_glossy, L.indirect_glossy, pass_filter);
|
||||
break;
|
||||
}
|
||||
case SHADER_EVAL_TRANSMISSION_DIRECT:
|
||||
case SHADER_EVAL_TRANSMISSION:
|
||||
{
|
||||
shader_eval_surface(kg, &sd, &state, 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, &shader_bsdf_transmission, L.direct_transmission, L.indirect_transmission, pass_filter);
|
||||
break;
|
||||
}
|
||||
case SHADER_EVAL_SUBSURFACE_DIRECT:
|
||||
case SHADER_EVAL_SUBSURFACE:
|
||||
{
|
||||
#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:
|
||||
{
|
||||
shader_eval_surface(kg, &sd, &state, 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, &state, 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, &state, 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, &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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
#endif // __COMPILE_ONLY_MEGAKERNEL__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
* and keep comment above the defines.
|
||||
* Use STRINGIFY() rather than defining with quotes */
|
||||
#define BLENDER_VERSION 276
|
||||
#define BLENDER_SUBVERSION 5
|
||||
#define BLENDER_SUBVERSION 7
|
||||
/* Several breakages with 270, e.g. constraint deg vs rad */
|
||||
#define BLENDER_MINVERSION 270
|
||||
#define BLENDER_MINSUBVERSION 6
|
||||
|
|
|
@ -528,6 +528,7 @@ void BKE_scene_init(Scene *sce)
|
|||
sce->r.bake_biasdist = 0.001;
|
||||
|
||||
sce->r.bake.flag = R_BAKE_CLEAR;
|
||||
sce->r.bake.pass_filter = R_BAKE_PASS_FILTER_ALL;
|
||||
sce->r.bake.width = 512;
|
||||
sce->r.bake.height = 512;
|
||||
sce->r.bake.margin = 16;
|
||||
|
|
|
@ -1050,4 +1050,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(main, 276, 7)) {
|
||||
Scene *scene;
|
||||
for (scene = main->scene.first; scene != NULL; scene = scene->id.next) {
|
||||
scene->r.bake.pass_filter = R_BAKE_PASS_FILTER_ALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ typedef struct BakeAPIRender {
|
|||
ListBase selected_objects;
|
||||
|
||||
ScenePassType pass_type;
|
||||
int pass_filter;
|
||||
int margin;
|
||||
|
||||
int save_mode;
|
||||
|
@ -428,6 +429,66 @@ static bool bake_object_check(Object *ob, ReportList *reports)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool bake_pass_filter_check(ScenePassType pass_type, const int pass_filter, ReportList *reports)
|
||||
{
|
||||
switch (pass_type) {
|
||||
case SCE_PASS_COMBINED:
|
||||
if ((pass_filter & R_BAKE_PASS_FILTER_EMIT) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
|
||||
((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0))
|
||||
{
|
||||
if (((pass_filter & R_BAKE_PASS_FILTER_DIFFUSE) != 0) ||
|
||||
((pass_filter & R_BAKE_PASS_FILTER_GLOSSY) != 0) ||
|
||||
((pass_filter & R_BAKE_PASS_FILTER_TRANSM) != 0) ||
|
||||
((pass_filter & R_BAKE_PASS_FILTER_SUBSURFACE) != 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((pass_filter & R_BAKE_PASS_FILTER_AO) != 0) {
|
||||
BKE_report(reports, RPT_ERROR,
|
||||
"Combined bake pass Ambient Occlusion contribution requires an enabled light pass. "
|
||||
"Bake the Ambient Occlusion pass type instead.");
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, "Combined bake pass requires Emit, or a light pass with "
|
||||
"Direct or Indirect contributions enabled");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR,
|
||||
"Combined bake pass requires Emit, or a light pass with "
|
||||
"Direct or Indirect contributions enabled");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SCE_PASS_DIFFUSE_COLOR:
|
||||
case SCE_PASS_GLOSSY_COLOR:
|
||||
case SCE_PASS_TRANSM_COLOR:
|
||||
case SCE_PASS_SUBSURFACE_COLOR:
|
||||
if (((pass_filter & R_BAKE_PASS_FILTER_COLOR) != 0) ||
|
||||
((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
|
||||
((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR,
|
||||
"Bake pass requires Direct, Indirect, or Color contributions to be enabled");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* before even getting in the bake function we check for some basic errors */
|
||||
static bool bake_objects_check(Main *bmain, Object *ob, ListBase *selected_objects,
|
||||
ReportList *reports, const bool is_selected_to_active)
|
||||
|
@ -552,7 +613,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re
|
|||
|
||||
static int bake(
|
||||
Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
|
||||
const ScenePassType pass_type, const int margin,
|
||||
const ScenePassType pass_type, const int pass_filter, const int margin,
|
||||
const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
|
||||
const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage,
|
||||
const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[],
|
||||
|
@ -794,7 +855,7 @@ static int bake(
|
|||
/* the baking itself */
|
||||
for (i = 0; i < tot_highpoly; i++) {
|
||||
ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high,
|
||||
num_pixels, depth, pass_type, result);
|
||||
num_pixels, depth, pass_type, pass_filter, result);
|
||||
if (!ok) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
|
||||
goto cage_cleanup;
|
||||
|
@ -820,7 +881,7 @@ cage_cleanup:
|
|||
ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
|
||||
|
||||
if (RE_bake_has_engine(re)) {
|
||||
ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, result);
|
||||
ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, pass_filter, result);
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
|
||||
|
@ -1032,6 +1093,7 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
|
|||
bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL;
|
||||
|
||||
bkr->pass_type = RNA_enum_get(op->ptr, "type");
|
||||
bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter");
|
||||
bkr->margin = RNA_int_get(op->ptr, "margin");
|
||||
|
||||
bkr->save_mode = RNA_enum_get(op->ptr, "save_mode");
|
||||
|
@ -1090,6 +1152,10 @@ static int bake_exec(bContext *C, wmOperator *op)
|
|||
/* setup new render */
|
||||
RE_test_break_cb(re, NULL, bake_break);
|
||||
|
||||
if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) {
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if (!bake_objects_check(bkr.main, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
|
||||
goto finally;
|
||||
}
|
||||
|
@ -1104,7 +1170,7 @@ static int bake_exec(bContext *C, wmOperator *op)
|
|||
if (bkr.is_selected_to_active) {
|
||||
result = bake(
|
||||
bkr.render, bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports,
|
||||
bkr.pass_type, bkr.margin, bkr.save_mode,
|
||||
bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
|
||||
bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage,
|
||||
bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
|
||||
bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa,
|
||||
|
@ -1117,7 +1183,7 @@ static int bake_exec(bContext *C, wmOperator *op)
|
|||
Object *ob_iter = link->ptr.data;
|
||||
result = bake(
|
||||
bkr.render, bkr.main, bkr.scene, ob_iter, NULL, bkr.reports,
|
||||
bkr.pass_type, bkr.margin, bkr.save_mode,
|
||||
bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
|
||||
is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage,
|
||||
bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
|
||||
bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa,
|
||||
|
@ -1143,6 +1209,11 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
|
|||
|
||||
RE_SetReports(bkr->render, bkr->reports);
|
||||
|
||||
if (!bake_pass_filter_check(bkr->pass_type, bkr->pass_filter, bkr->reports)) {
|
||||
bkr->result = OPERATOR_CANCELLED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bake_objects_check(bkr->main, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
|
||||
bkr->result = OPERATOR_CANCELLED;
|
||||
return;
|
||||
|
@ -1156,7 +1227,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
|
|||
if (bkr->is_selected_to_active) {
|
||||
bkr->result = bake(
|
||||
bkr->render, bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports,
|
||||
bkr->pass_type, bkr->margin, bkr->save_mode,
|
||||
bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
|
||||
bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage,
|
||||
bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
|
||||
bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa,
|
||||
|
@ -1169,7 +1240,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
|
|||
Object *ob_iter = link->ptr.data;
|
||||
bkr->result = bake(
|
||||
bkr->render, bkr->main, bkr->scene, ob_iter, NULL, bkr->reports,
|
||||
bkr->pass_type, bkr->margin, bkr->save_mode,
|
||||
bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
|
||||
is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage,
|
||||
bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
|
||||
bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa,
|
||||
|
@ -1277,6 +1348,11 @@ static void bake_set_props(wmOperator *op, Scene *scene)
|
|||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
|
||||
}
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "pass_filter");
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_enum_set(op->ptr, prop, bake->pass_filter);
|
||||
}
|
||||
}
|
||||
|
||||
static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
|
@ -1325,6 +1401,8 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
|
|||
|
||||
void OBJECT_OT_bake(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Bake";
|
||||
ot->description = "Bake image textures of selected objects";
|
||||
|
@ -1336,8 +1414,11 @@ void OBJECT_OT_bake(wmOperatorType *ot)
|
|||
ot->invoke = bake_invoke;
|
||||
ot->poll = ED_operator_object_active_editable_mesh;
|
||||
|
||||
RNA_def_enum(ot->srna, "type", rna_enum_render_pass_type_items, SCE_PASS_COMBINED, "Type",
|
||||
RNA_def_enum(ot->srna, "type", rna_enum_bake_pass_type_items, SCE_PASS_COMBINED, "Type",
|
||||
"Type of pass to bake, some of them may not be supported by the current render engine");
|
||||
prop = RNA_def_enum(ot->srna, "pass_filter", rna_enum_bake_pass_filter_type_items, R_BAKE_PASS_FILTER_NONE, "Pass Filter",
|
||||
"Filter to combined, diffuse, glossy, transmission and subsurface passes");
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path",
|
||||
"Image filepath to use when saving externally");
|
||||
RNA_def_int(ot->srna, "width", 512, 1, INT_MAX, "Width",
|
||||
|
|
|
@ -462,7 +462,7 @@ typedef struct BakeData {
|
|||
short margin, flag;
|
||||
|
||||
float cage_extrusion;
|
||||
float pad2;
|
||||
int pass_filter;
|
||||
|
||||
char normal_swizzle[3];
|
||||
char normal_space;
|
||||
|
@ -489,6 +489,22 @@ typedef enum BakeSaveMode {
|
|||
R_BAKE_SAVE_EXTERNAL = 1,
|
||||
} BakeSaveMode;
|
||||
|
||||
/* bake->pass_filter */
|
||||
typedef enum BakePassFilter{
|
||||
R_BAKE_PASS_FILTER_NONE = 0,
|
||||
R_BAKE_PASS_FILTER_AO = (1 << 0),
|
||||
R_BAKE_PASS_FILTER_EMIT = (1 << 1),
|
||||
R_BAKE_PASS_FILTER_DIFFUSE = (1 << 2),
|
||||
R_BAKE_PASS_FILTER_GLOSSY = (1 << 3),
|
||||
R_BAKE_PASS_FILTER_TRANSM = (1 << 4),
|
||||
R_BAKE_PASS_FILTER_SUBSURFACE = (1 << 5),
|
||||
R_BAKE_PASS_FILTER_DIRECT = (1 << 6),
|
||||
R_BAKE_PASS_FILTER_INDIRECT = (1 << 7),
|
||||
R_BAKE_PASS_FILTER_COLOR = (1 << 8),
|
||||
} BakePassFilter;
|
||||
|
||||
#define R_BAKE_PASS_FILTER_ALL (~0)
|
||||
|
||||
/* *************************************************************** */
|
||||
/* Render Data */
|
||||
|
||||
|
|
|
@ -141,6 +141,9 @@ extern EnumPropertyItem rna_enum_controller_type_items[];
|
|||
extern EnumPropertyItem rna_enum_render_pass_type_items[];
|
||||
extern EnumPropertyItem rna_enum_render_pass_debug_type_items[];
|
||||
|
||||
extern EnumPropertyItem rna_enum_bake_pass_type_items[];
|
||||
extern EnumPropertyItem rna_enum_bake_pass_filter_type_items[];
|
||||
|
||||
extern EnumPropertyItem rna_enum_keymap_propvalue_items[];
|
||||
|
||||
extern EnumPropertyItem rna_enum_operator_context_items[];
|
||||
|
|
|
@ -84,6 +84,21 @@ EnumPropertyItem rna_enum_render_pass_debug_type_items[] = {
|
|||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
EnumPropertyItem rna_enum_bake_pass_type_items[] = {
|
||||
{SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
|
||||
{SCE_PASS_AO, "AO", 0, "AO", ""},
|
||||
{SCE_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
|
||||
{SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
|
||||
{SCE_PASS_UV, "UV", 0, "UV", ""},
|
||||
{SCE_PASS_EMIT, "EMIT", 0, "Emit", ""},
|
||||
{SCE_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
|
||||
{SCE_PASS_DIFFUSE_COLOR, "DIFFUSE", 0, "Diffuse", ""},
|
||||
{SCE_PASS_GLOSSY_COLOR, "GLOSSY", 0, "Glossy", ""},
|
||||
{SCE_PASS_TRANSM_COLOR, "TRANSMISSION", 0, "Transmission", ""},
|
||||
{SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE", 0, "Subsurface", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -162,7 +177,7 @@ static void engine_render(RenderEngine *engine, struct Scene *scene)
|
|||
}
|
||||
|
||||
static void engine_bake(RenderEngine *engine, struct Scene *scene,
|
||||
struct Object *object, const int pass_type,
|
||||
struct Object *object, const int pass_type, const int pass_filter,
|
||||
const int object_id, const struct BakePixel *pixel_array,
|
||||
const int num_pixels, const int depth, void *result)
|
||||
{
|
||||
|
@ -178,6 +193,7 @@ static void engine_bake(RenderEngine *engine, struct Scene *scene,
|
|||
RNA_parameter_set_lookup(&list, "scene", &scene);
|
||||
RNA_parameter_set_lookup(&list, "object", &object);
|
||||
RNA_parameter_set_lookup(&list, "pass_type", &pass_type);
|
||||
RNA_parameter_set_lookup(&list, "pass_filter", &pass_filter);
|
||||
RNA_parameter_set_lookup(&list, "object_id", &object_id);
|
||||
RNA_parameter_set_lookup(&list, "pixel_array", &pixel_array);
|
||||
RNA_parameter_set_lookup(&list, "num_pixels", &num_pixels);
|
||||
|
@ -432,7 +448,9 @@ static void rna_def_render_engine(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||
prop = RNA_def_pointer(func, "object", "Object", "", "");
|
||||
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||
prop = RNA_def_enum(func, "pass_type", rna_enum_render_pass_type_items, 0, "Pass", "Pass to bake");
|
||||
prop = RNA_def_enum(func, "pass_type", rna_enum_bake_pass_type_items, 0, "Pass", "Pass to bake");
|
||||
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||
prop = RNA_def_int(func, "pass_filter", 0, 0, INT_MAX, "Pass Filter", "Filter to combined, diffuse, glossy, transmission and subsurface passes", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||
prop = RNA_def_int(func, "object_id", 0, 0, INT_MAX, "Object Id", "Id of the current object being baked in relation to the others", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||
|
|
|
@ -391,6 +391,20 @@ EnumPropertyItem rna_enum_stereo3d_interlace_type_items[] = {
|
|||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = {
|
||||
{R_BAKE_PASS_FILTER_NONE, "NONE", 0, "None", ""},
|
||||
{R_BAKE_PASS_FILTER_AO, "AO", 0, "AO", ""},
|
||||
{R_BAKE_PASS_FILTER_EMIT, "EMIT", 0, "Emit", ""},
|
||||
{R_BAKE_PASS_FILTER_DIRECT, "DIRECT", 0, "Direct", ""},
|
||||
{R_BAKE_PASS_FILTER_INDIRECT, "INDIRECT", 0, "Indirect", ""},
|
||||
{R_BAKE_PASS_FILTER_COLOR, "COLOR", 0, "Color", ""},
|
||||
{R_BAKE_PASS_FILTER_DIFFUSE, "DIFFUSE", 0, "Diffuse", ""},
|
||||
{R_BAKE_PASS_FILTER_GLOSSY, "GLOSSY", 0, "Glossy", ""},
|
||||
{R_BAKE_PASS_FILTER_TRANSM, "TRANSMISSION", 0, "Transmission", ""},
|
||||
{R_BAKE_PASS_FILTER_SUBSURFACE, "SUBSURFACE", 0, "Subsurface", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
|
@ -3747,6 +3761,57 @@ static void rna_def_bake_data(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Cage",
|
||||
"Cast rays to active object from a cage");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
/* custom passes flags */
|
||||
prop = RNA_def_property(srna, "use_pass_ambient_occlusion", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_AO);
|
||||
RNA_def_property_ui_text(prop, "AO", "Add ambient occlusion contribution");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_emit", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_EMIT);
|
||||
RNA_def_property_ui_text(prop, "Emit", "Add emission contribution");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_direct", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_DIRECT);
|
||||
RNA_def_property_ui_text(prop, "Direct", "Add direct lighting contribution");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_indirect", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_INDIRECT);
|
||||
RNA_def_property_ui_text(prop, "Indirect", "Add indirect lighting contribution");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_color", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_COLOR);
|
||||
RNA_def_property_ui_text(prop, "Color", "Color the pass");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_diffuse", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_DIFFUSE);
|
||||
RNA_def_property_ui_text(prop, "Diffuse", "Add diffuse contribution");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_glossy", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_GLOSSY);
|
||||
RNA_def_property_ui_text(prop, "Glossy", "Add glossy contribution");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_transmission", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_TRANSM);
|
||||
RNA_def_property_ui_text(prop, "Transmission", "Add transmission contribution");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_pass_subsurface", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_SUBSURFACE);
|
||||
RNA_def_property_ui_text(prop, "Subsurface", "Add subsurface contribution");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "pass_filter", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "pass_filter");
|
||||
RNA_def_property_enum_items(prop, rna_enum_bake_pass_filter_type_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_ui_text(prop, "Pass Filter", "Passes to include in the active baking pass");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
}
|
||||
|
||||
static void rna_def_scene_game_data(BlenderRNA *brna)
|
||||
|
|
|
@ -72,7 +72,7 @@ bool RE_bake_has_engine(struct Render *re);
|
|||
|
||||
bool RE_bake_engine(
|
||||
struct Render *re, struct Object *object, const int object_id, const BakePixel pixel_array[],
|
||||
const size_t num_pixels, const int depth, const ScenePassType pass_type, float result[]);
|
||||
const size_t num_pixels, const int depth, const ScenePassType pass_type, const int pass_filter, float result[]);
|
||||
|
||||
/* bake.c */
|
||||
int RE_pass_depth(const ScenePassType pass_type);
|
||||
|
|
|
@ -89,7 +89,7 @@ typedef struct RenderEngineType {
|
|||
|
||||
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
|
||||
void (*render)(struct RenderEngine *engine, struct Scene *scene);
|
||||
void (*bake)(struct RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type, const int object_id, const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result);
|
||||
void (*bake)(struct RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type, const int pass_filter, const int object_id, const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result);
|
||||
|
||||
void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
|
||||
void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
|
||||
|
|
|
@ -471,7 +471,8 @@ bool RE_bake_engine(
|
|||
Render *re, Object *object,
|
||||
const int object_id, const BakePixel pixel_array[],
|
||||
const size_t num_pixels, const int depth,
|
||||
const ScenePassType pass_type, float result[])
|
||||
const ScenePassType pass_type, const int pass_filter,
|
||||
float result[])
|
||||
{
|
||||
RenderEngineType *type = RE_engines_find(re->r.engine);
|
||||
RenderEngine *engine;
|
||||
|
@ -507,7 +508,7 @@ bool RE_bake_engine(
|
|||
type->update(engine, re->main, re->scene);
|
||||
|
||||
if (type->bake)
|
||||
type->bake(engine, re->scene, object, pass_type, object_id, pixel_array, num_pixels, depth, result);
|
||||
type->bake(engine, re->scene, object, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result);
|
||||
|
||||
engine->tile_x = 0;
|
||||
engine->tile_y = 0;
|
||||
|
|
Loading…
Reference in New Issue