diff options
22 files changed, 937 insertions, 55 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index 9f42cc9bb00..27d986900c8 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -67,6 +67,9 @@ class CyclesRender(bpy.types.RenderEngine): def render(self, scene): engine.render(self) + def bake(self, scene, obj, pass_type, pixel_array, num_pixels, depth, result): + engine.bake(self, obj, pass_type, pixel_array, num_pixels, depth, result) + # viewport render def view_update(self, context): if not self.session: diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index b9ce65588df..25a9e97a99b 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -59,6 +59,12 @@ def render(engine): _cycles.render(engine.session) +def bake(engine, obj, pass_type, 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, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer()) + def reset(engine, data, scene): import _cycles data = data.as_pointer() diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 2b05c2148eb..7205a272395 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -471,6 +471,33 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=False, ) + cls.bake_type = EnumProperty( + name="Bake Type", + default='COMBINED', + description="Type of pass to bake", + items = ( + ('COMBINED', "Combined", ""), + ('AO', "Ambient Occlusion", ""), + ('SHADOW', "Shadow", ""), + ('NORMAL', "Normal", ""), + ('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", ""), + ), + ) + @classmethod def unregister(cls): del bpy.types.Scene.cycles diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index f35cb1abd2e..5c8115b6612 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1227,6 +1227,54 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel): row.prop(ccscene, "maximum_width", text="Max Ext.") +class CyclesRender_PT_bake(CyclesButtonsPanel, Panel): + bl_label = "Bake" + bl_context = "render" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'CYCLES'} + + def draw(self, context): + layout = self.layout + + scene = context.scene + cscene = scene.cycles + + cbk = scene.render.bake + + layout.operator("object.bake", icon='RENDER_STILL').type = \ + cscene.bake_type + + col = layout.column() + col.prop(cscene, "bake_type") + + col.separator() + split = layout.split() + + sub = split.column() + sub.prop(cbk, "use_clear") + sub.prop(cbk, "margin") + + sub = split.column() + sub.prop(cbk, "use_selected_to_active") + sub = sub.column() + + sub.active = cbk.use_selected_to_active + sub.prop(cbk, "cage_extrusion", text="Distance") + sub.prop_search(cbk, "cage", scene, "objects") + + if cscene.bake_type == 'NORMAL': + col.separator() + box = col.box() + box.label(text="Normal Settings:") + box.prop(cbk, "normal_space", text="Space") + + row = box.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="") + + class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel): bl_label = "Cycles Hair Settings" bl_context = "particle" diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 8b04a869a85..658fccaf12e 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -147,6 +147,38 @@ static PyObject *render_func(PyObject *self, PyObject *value) Py_RETURN_NONE; } +/* pixel_array and result passed as pointers */ +static PyObject *bake_func(PyObject *self, PyObject *args) +{ + PyObject *pysession, *pyobject; + PyObject *pypixel_array, *pyresult; + const char *pass_type; + int num_pixels, depth; + + if(!PyArg_ParseTuple(args, "OOsOiiO", &pysession, &pyobject, &pass_type, &pypixel_array, &num_pixels, &depth, &pyresult)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + + BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession); + + PointerRNA objectptr; + RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyobject), &objectptr); + BL::Object b_object(objectptr); + + void *b_result = PyLong_AsVoidPtr(pyresult); + + PointerRNA bakepixelptr; + RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pypixel_array), &bakepixelptr); + BL::BakePixel b_bake_pixel(bakepixelptr); + + session->bake(b_object, pass_type, b_bake_pixel, num_pixels, depth, (float *)b_result); + + Py_END_ALLOW_THREADS + + Py_RETURN_NONE; +} + static PyObject *draw_func(PyObject *self, PyObject *args) { PyObject *pysession, *pyv3d, *pyrv3d; @@ -418,6 +450,7 @@ static PyMethodDef methods[] = { {"create", create_func, METH_VARARGS, ""}, {"free", free_func, METH_O, ""}, {"render", render_func, METH_O, ""}, + {"bake", bake_func, METH_VARARGS, ""}, {"draw", draw_func, METH_VARARGS, ""}, {"sync", sync_func, METH_O, ""}, {"reset", reset_func, METH_VARARGS, ""}, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index f5e696bc582..6f959d42680 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -14,6 +14,8 @@ * limitations under the License */ +#include <stdlib.h> + #include "background.h" #include "buffers.h" #include "camera.h" @@ -21,6 +23,8 @@ #include "integrator.h" #include "film.h" #include "light.h" +#include "mesh.h" +#include "object.h" #include "scene.h" #include "session.h" #include "shader.h" @@ -259,6 +263,58 @@ static PassType get_pass_type(BL::RenderPass b_pass) return PASS_NONE; } +static ShaderEvalType get_shader_type(const string& pass_type) +{ + const char *shader_type = pass_type.c_str(); + + /* data passes */ + if(strcmp(shader_type, "NORMAL")==0) + return SHADER_EVAL_NORMAL; + else if(strcmp(shader_type, "UV")==0) + return SHADER_EVAL_UV; + else if(strcmp(shader_type, "DIFFUSE_COLOR")==0) + return SHADER_EVAL_DIFFUSE_COLOR; + else if(strcmp(shader_type, "GLOSSY_COLOR")==0) + return SHADER_EVAL_GLOSSY_COLOR; + else if(strcmp(shader_type, "TRANSMISSION_COLOR")==0) + return SHADER_EVAL_TRANSMISSION_COLOR; + else if(strcmp(shader_type, "SUBSURFACE_COLOR")==0) + return SHADER_EVAL_SUBSURFACE_COLOR; + else if(strcmp(shader_type, "EMIT")==0) + return SHADER_EVAL_EMISSION; + + /* light passes */ + else if(strcmp(shader_type, "AO")==0) + return SHADER_EVAL_AO; + else if(strcmp(shader_type, "COMBINED")==0) + 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; + + /* extra */ + else if(strcmp(shader_type, "ENVIRONMENT")==0) + return SHADER_EVAL_ENVIRONMENT; + + else + return SHADER_EVAL_BAKE; +} + static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername) { return b_engine.begin_result(x, y, w, h, layername); @@ -425,6 +481,105 @@ void BlenderSession::render() sync = NULL; } +static void populate_bake_data(BakeData *data, BL::BakePixel pixel_array, const int num_pixels) +{ + BL::BakePixel bp = pixel_array; + + int i; + for(i=0; i < num_pixels; i++) { + data->set(i, bp.primitive_id(), bp.uv()); + bp = bp.next(); + } +} + +static bool is_light_pass(ShaderEvalType type) +{ + switch (type) { + case SHADER_EVAL_AO: + case SHADER_EVAL_COMBINED: + case SHADER_EVAL_SHADOW: + case SHADER_EVAL_DIFFUSE_DIRECT: + case SHADER_EVAL_GLOSSY_DIRECT: + case SHADER_EVAL_TRANSMISSION_DIRECT: + case SHADER_EVAL_SUBSURFACE_DIRECT: + case SHADER_EVAL_DIFFUSE_INDIRECT: + case SHADER_EVAL_GLOSSY_INDIRECT: + case SHADER_EVAL_TRANSMISSION_INDIRECT: + case SHADER_EVAL_SUBSURFACE_INDIRECT: + return true; + default: + return false; + } +} + +void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, int depth, float result[]) +{ + ShaderEvalType shader_type = get_shader_type(pass_type); + size_t object_index = OBJECT_NONE; + int tri_offset = 0; + + if(shader_type == SHADER_EVAL_UV) { + /* force UV to be available */ + Pass::add(PASS_UV, scene->film->passes); + } + + if(is_light_pass(shader_type)) { + /* force use_light_pass to be true */ + Pass::add(PASS_LIGHT, scene->film->passes); + } + + /* create device and update scene */ + scene->film->tag_update(scene); + scene->integrator->tag_update(scene); + + /* update scene */ + sync->sync_camera(b_render, b_engine.camera_override(), width, height); + sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state); + + /* get buffer parameters */ + SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height); + + scene->bake_manager->set_baking(true); + + /* set number of samples */ + session->tile_manager.set_samples(session_params.samples); + session->reset(buffer_params, session_params.samples); + session->update_scene(); + + /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */ + for(size_t i = 0; i < scene->objects.size(); i++) { + if(strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) { + object_index = i; + tri_offset = scene->objects[i]->mesh->tri_offset; + break; + } + } + + /* when used, non-instanced convention: object = ~object */ + int object = ~object_index; + + BakeData *bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); + + populate_bake_data(bake_data, pixel_array, num_pixels); + + /* set number of samples */ + session->tile_manager.set_samples(session_params.samples); + session->reset(buffer_params, session_params.samples); + session->update_scene(); + + scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result); + + /* free all memory used (host and device), so we wouldn't leave render + * engine with extra memory allocated + */ + + session->device_free(); + + delete sync; + sync = NULL; +} + void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only) { RenderBuffers *buffers = rtile.buffers; diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index d30e3eda870..0e44493d674 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -20,6 +20,7 @@ #include "device.h" #include "scene.h" #include "session.h" +#include "bake.h" #include "util_vector.h" @@ -51,6 +52,8 @@ public: /* offline render */ void render(); + void bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, int num_pixels, 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 e14e403d82b..c9cc7592028 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -395,7 +395,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_avx_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(task_pool.canceled()) + if(task.get_cancel() || task_pool.canceled()) break; } } @@ -406,7 +406,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_sse41_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(task_pool.canceled()) + if(task.get_cancel() || task_pool.canceled()) break; } } @@ -417,7 +417,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(task_pool.canceled()) + if(task.get_cancel() || task_pool.canceled()) break; } } @@ -428,7 +428,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(task_pool.canceled()) + if(task.get_cancel() || task_pool.canceled()) break; } } @@ -438,7 +438,7 @@ public: for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { kernel_cpu_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); - if(task_pool.canceled()) + if(task.get_cancel() || task_pool.canceled()) break; } } diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 582a220ab3c..82450b73097 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -407,5 +407,26 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi return L_sum; } +ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples) +{ + float fac = 1.0f/num_samples; + + L->direct_diffuse += L_sample->direct_diffuse*fac; + L->direct_glossy += L_sample->direct_glossy*fac; + L->direct_transmission += L_sample->direct_transmission*fac; + L->direct_subsurface += L_sample->direct_subsurface*fac; + + L->indirect_diffuse += L_sample->indirect_diffuse*fac; + L->indirect_glossy += L_sample->indirect_glossy*fac; + L->indirect_transmission += L_sample->indirect_transmission*fac; + L->indirect_subsurface += L_sample->indirect_subsurface*fac; + + L->emission += L_sample->emission*fac; + L->background += L_sample->background*fac; + L->ao += L_sample->ao*fac; + L->shadow += L_sample->shadow*fac; + L->mist += L_sample->mist*fac; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h index 1935f72ce95..a2709e711d2 100644 --- a/intern/cycles/kernel/kernel_displace.h +++ b/intern/cycles/kernel/kernel_displace.h @@ -16,8 +16,275 @@ CCL_NAMESPACE_BEGIN +ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng, bool is_ao) +{ + int samples = kernel_data.integrator.aa_samples; + + /* initialize master radiance accumulator */ + kernel_assert(kernel_data.film.use_light_pass); + path_radiance_init(L, kernel_data.film.use_light_pass); + + /* take multiple samples */ + for(int sample = 0; sample < samples; sample++) { + PathRadiance L_sample; + PathState state; + Ray ray; + float3 throughput = make_float3(1.0f, 1.0f, 1.0f); + + /* init radiance */ + path_radiance_init(&L_sample, kernel_data.film.use_light_pass); + + /* init path state */ + path_state_init(kg, &state, &rng, sample); + state.num_samples = samples; + + /* evaluate surface shader */ + float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF); + shader_eval_surface(kg, sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN); + + /* sample ambient occlusion */ + if(is_ao) { + kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput); + } + + /* sample light and BSDF */ + else if(kernel_path_integrate_lighting(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) { +#ifdef __LAMP_MIS__ + state.ray_t = 0.0f; +#endif + + /* compute indirect light */ + kernel_path_indirect(kg, &rng, ray, throughput, state.num_samples, state, &L_sample); + + /* sum and reset indirect light pass variables for the next samples */ + path_radiance_sum_indirect(&L_sample); + path_radiance_reset_indirect(&L_sample); + } + + /* accumulate into master L */ + path_radiance_accum_sample(L, &L_sample, samples); + } +} + +ccl_device bool is_light_pass(ShaderEvalType type) +{ + switch (type) { + case SHADER_EVAL_AO: + case SHADER_EVAL_COMBINED: + case SHADER_EVAL_SHADOW: + case SHADER_EVAL_DIFFUSE_DIRECT: + case SHADER_EVAL_GLOSSY_DIRECT: + case SHADER_EVAL_TRANSMISSION_DIRECT: + case SHADER_EVAL_SUBSURFACE_DIRECT: + case SHADER_EVAL_DIFFUSE_INDIRECT: + case SHADER_EVAL_GLOSSY_INDIRECT: + case SHADER_EVAL_TRANSMISSION_INDIRECT: + case SHADER_EVAL_SUBSURFACE_INDIRECT: + return true; + default: + return false; + } +} + +ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i) +{ + ShaderData sd; + uint4 in = input[i]; + float3 out; + + int object = in.x; + int prim = in.y; + + if(prim == -1) + return; + + float u = __uint_as_float(in.z); + float v = __uint_as_float(in.w); + + int shader; + float3 P, Ng; + + triangle_point_normal(kg, prim, u, v, &P, &Ng, &shader); + + /* dummy initilizations copied from SHADER_EVAL_DISPLACE */ + float3 I = Ng; + float t = 0.0f; + float time = TIME_INVALID; + int bounce = 0; + int transparent_bounce = 0; + + /* light passes */ + PathRadiance L; + + /* TODO, disable the closures we won't need */ + shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time, bounce, transparent_bounce); + + if(is_light_pass(type)){ + RNG rng = cmj_hash(i, 0); + compute_light_pass(kg, &sd, &L, rng, (type == SHADER_EVAL_AO)); + } + + switch (type) { + /* data passes */ + case SHADER_EVAL_NORMAL: + { + /* compression: normal = (2 * color) - 1 */ + out = sd.N * 0.5f + make_float3(0.5f, 0.5f, 0.5f); + break; + } + case SHADER_EVAL_UV: + { + out = primitive_uv(kg, &sd); + break; + } + case SHADER_EVAL_DIFFUSE_COLOR: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = shader_bsdf_diffuse(kg, &sd); + break; + } + case SHADER_EVAL_GLOSSY_COLOR: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = shader_bsdf_glossy(kg, &sd); + break; + } + case SHADER_EVAL_TRANSMISSION_COLOR: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = shader_bsdf_transmission(kg, &sd); + break; + } + case SHADER_EVAL_SUBSURFACE_COLOR: + { +#ifdef __SUBSURFACE__ + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = shader_bsdf_subsurface(kg, &sd); +#endif + break; + } + case SHADER_EVAL_EMISSION: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_EMISSION); + out = shader_emissive_eval(kg, &sd); + break; + } + + /* light passes */ + case SHADER_EVAL_AO: + { + out = L.ao; + break; + } + case SHADER_EVAL_COMBINED: + { + out = path_radiance_clamp_and_sum(kg, &L); + break; + } + case SHADER_EVAL_SHADOW: + { + out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z); + break; + } + case SHADER_EVAL_DIFFUSE_DIRECT: + { + shader_eval_surface(kg, &sd, 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, 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, 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, 0.f, 0, SHADER_CONTEXT_MAIN); + out = safe_divide_color(L.direct_subsurface, shader_bsdf_subsurface(kg, &sd)); +#endif + break; + } + case SHADER_EVAL_DIFFUSE_INDIRECT: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = safe_divide_color(L.indirect_diffuse, shader_bsdf_diffuse(kg, &sd)); + break; + } + case SHADER_EVAL_GLOSSY_INDIRECT: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = safe_divide_color(L.indirect_glossy, shader_bsdf_glossy(kg, &sd)); + break; + } + case SHADER_EVAL_TRANSMISSION_INDIRECT: + { + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = safe_divide_color(L.indirect_transmission, shader_bsdf_transmission(kg, &sd)); + break; + } + case SHADER_EVAL_SUBSURFACE_INDIRECT: + { +#ifdef __SUBSURFACE__ + shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN); + out = safe_divide_color(L.indirect_subsurface, shader_bsdf_subsurface(kg, &sd)); +#endif + break; + } + + /* extra */ + case SHADER_EVAL_ENVIRONMENT: + { + /* setup ray */ + Ray ray; + + ray.P = make_float3(0.0f, 0.0f, 0.0f); + ray.D = normalize(P); + ray.t = 0.0f; +#ifdef __CAMERA_MOTION__ + ray.time = 0.5f; +#endif + +#ifdef __RAY_DIFFERENTIALS__ + ray.dD = differential3_zero(); + ray.dP = differential3_zero(); +#endif + + /* setup shader data */ + shader_setup_from_background(kg, &sd, &ray, 0, 0); + + /* evaluate */ + int flag = 0; /* we can't know which type of BSDF this is for */ + out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN); + break; + } + default: + { + /* no real shader, returning the position of the verts for debugging */ + out = normalize(P); + break; + } + } + + /* write output */ + output[i] = make_float4(out.x, out.y, out.z, 1.0f); + return; +} + ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i) { + if(type >= SHADER_EVAL_BAKE) { + kernel_bake_evaluate(kg, input, output, type, i); + return; + } + ShaderData sd; uint4 in = input[i]; float3 out; diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 1ca6bd38ba9..e71b58aa709 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -212,7 +212,9 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg } } -ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_global float *buffer, +#endif + +ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, float3 throughput, int num_samples, PathState state, PathRadiance *L) { /* path iteration */ @@ -378,7 +380,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g } #endif -#ifdef __EMISSION__ +#if defined(__EMISSION__) && defined(__BRANCHED_PATH__) if(kernel_data.integrator.use_direct_light) { bool all = kernel_data.integrator.sample_all_lights_indirect; kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L, all); @@ -456,10 +458,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g } } -#endif - -#ifdef __SUBSURFACE__ - ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rng, ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray) { @@ -569,7 +567,39 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn } } +ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, float3 throughput) +{ + /* todo: solve correlation */ + float bsdf_u, bsdf_v; + + path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); + + float ao_factor = kernel_data.background.ao_factor; + float3 ao_N; + float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N); + float3 ao_D; + float ao_pdf; + float3 ao_alpha = shader_bsdf_alpha(kg, sd); + + sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); + + if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { + Ray light_ray; + float3 ao_shadow; + + light_ray.P = ray_offset(sd->P, sd->Ng); + light_ray.D = ao_D; + light_ray.t = kernel_data.background.ao_distance; +#ifdef __OBJECT_MOTION__ + light_ray.time = sd->time; #endif + light_ray.dP = sd->dP; + light_ray.dD = differential3_zero(); + + if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) + path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state->bounce); + } +} ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer) { @@ -738,35 +768,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - /* todo: solve correlation */ - float bsdf_u, bsdf_v; - path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); - - float ao_factor = kernel_data.background.ao_factor; - float3 ao_N; - float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); - float3 ao_D; - float ao_pdf; - float3 ao_alpha = shader_bsdf_alpha(kg, &sd); - - sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); - - if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { - Ray light_ray; - float3 ao_shadow; - - light_ray.P = ray_offset(sd.P, sd.Ng); - light_ray.D = ao_D; - light_ray.t = kernel_data.background.ao_distance; -#ifdef __OBJECT_MOTION__ - light_ray.time = sd.time; -#endif - light_ray.dP = sd.dP; - light_ray.dD = differential3_zero(); - - if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) - path_radiance_accum_ao(&L, throughput, ao_alpha, ao_bsdf, ao_shadow, state.bounce); - } + kernel_path_ao(kg, &sd, &L, &state, rng, throughput); } #endif @@ -803,7 +805,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, hit_state.ray_t = 0.0f; #endif - kernel_path_indirect(kg, rng, hit_ray, buffer, tp, state.num_samples, hit_state, &L); + kernel_path_indirect(kg, rng, hit_ray, tp, state.num_samples, hit_state, &L); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -1022,7 +1024,7 @@ ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals * ps.ray_t = 0.0f; #endif - kernel_path_indirect(kg, rng, bsdf_ray, buffer, tp*num_samples_inv, num_samples, ps, L); + kernel_path_indirect(kg, rng, bsdf_ray, tp*num_samples_inv, num_samples, ps, L); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -1110,7 +1112,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in if(result == VOLUME_PATH_SCATTERED) { /* todo: use all-light sampling */ if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &tp, &ps, &L, &pray, num_samples_inv)) { - kernel_path_indirect(kg, rng, pray, buffer, tp*num_samples_inv, num_samples, ps, &L); + kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -1150,7 +1152,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in if(result == VOLUME_PATH_SCATTERED) { /* todo: use all-light sampling */ if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &tp, &ps, &L, &pray, num_samples_inv)) { - kernel_path_indirect(kg, rng, pray, buffer, tp*num_samples_inv, num_samples, ps, &L); + kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L); /* for render passes, sum and reset indirect light pass variables * for the next samples */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index f83345925ea..b3656c38cae 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -160,7 +160,35 @@ typedef uint RNG; typedef enum ShaderEvalType { SHADER_EVAL_DISPLACE, - SHADER_EVAL_BACKGROUND + SHADER_EVAL_BACKGROUND, + /* bake types */ + SHADER_EVAL_BAKE, /* no real shade, it's used in the code to + * differentiate the type of shader eval from the above + */ + /* data passes */ + SHADER_EVAL_NORMAL, + SHADER_EVAL_UV, + SHADER_EVAL_DIFFUSE_COLOR, + SHADER_EVAL_GLOSSY_COLOR, + SHADER_EVAL_TRANSMISSION_COLOR, + SHADER_EVAL_SUBSURFACE_COLOR, + SHADER_EVAL_EMISSION, + + /* light passes */ + 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, + + /* extra */ + SHADER_EVAL_ENVIRONMENT, } ShaderEvalType; /* Path Tracing @@ -281,7 +309,8 @@ typedef enum PassType { PASS_MIST = 2097152, PASS_SUBSURFACE_DIRECT = 4194304, PASS_SUBSURFACE_INDIRECT = 8388608, - PASS_SUBSURFACE_COLOR = 16777216 + PASS_SUBSURFACE_COLOR = 16777216, + PASS_LIGHT = 33554432, /* no real pass, used to force use_light_pass */ } PassType; #define PASS_ALL (~0) diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 7d00ed92164..449c1391980 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -16,6 +16,7 @@ set(INC_SYS set(SRC attribute.cpp background.cpp + bake.cpp blackbody.cpp buffers.cpp camera.cpp @@ -43,6 +44,7 @@ set(SRC set(SRC_HEADERS attribute.h + bake.h background.h blackbody.h buffers.h diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp new file mode 100644 index 00000000000..2e3022e2c02 --- /dev/null +++ b/intern/cycles/render/bake.cpp @@ -0,0 +1,183 @@ +/* + * Copyright 2011-2014 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 + */ + +#include "bake.h" + +CCL_NAMESPACE_BEGIN + +BakeData::BakeData(const int object, const int tri_offset, const int num_pixels): +m_object(object), +m_tri_offset(tri_offset), +m_num_pixels(num_pixels) +{ + m_primitive.resize(num_pixels); + m_u.resize(num_pixels); + m_v.resize(num_pixels); +} + +BakeData::~BakeData() +{ + m_primitive.clear(); + m_u.clear(); + m_v.clear(); +} + +void BakeData::set(int i, int prim, float uv[2]) +{ + m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim); + m_u[i] = uv[0]; + m_v[i] = uv[1]; +} + +int BakeData::object() +{ + return m_object; +} + +int BakeData::size() +{ + return m_num_pixels; +} + +bool BakeData::is_valid(int i) +{ + return m_primitive[i] != -1; +} + +uint4 BakeData::data(int i) +{ + return make_uint4( + m_object, + m_primitive[i], + __float_as_int(m_u[i]), + __float_as_int(m_v[i]) + ); +} + +BakeManager::BakeManager() +{ + m_bake_data = NULL; + m_is_baking = false; + need_update = true; +} + +BakeManager::~BakeManager() +{ + if(m_bake_data) + delete m_bake_data; +} + +bool BakeManager::get_baking() +{ + return m_is_baking; +} + +void BakeManager::set_baking(const bool value) +{ + m_is_baking = value; +} + +BakeData *BakeManager::init(const int object, const int tri_offset, const int num_pixels) +{ + m_bake_data = new BakeData(object, tri_offset, num_pixels); + return m_bake_data; +} + +bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[]) +{ + size_t limit = bake_data->size(); + + /* setup input for device task */ + device_vector<uint4> d_input; + uint4 *d_input_data = d_input.resize(limit); + size_t d_input_size = 0; + + for(size_t i = 0; i < limit; i++) { + d_input_data[d_input_size++] = bake_data->data(i); + } + + if(d_input_size == 0) + return false; + + /* run device task */ + device_vector<float4> d_output; + d_output.resize(d_input_size); + + /* needs to be up to data for attribute access */ + device->const_copy_to("__data", &dscene->data, sizeof(dscene->data)); + + device->mem_alloc(d_input, MEM_READ_ONLY); + device->mem_copy_to(d_input); + device->mem_alloc(d_output, MEM_WRITE_ONLY); + + DeviceTask task(DeviceTask::SHADER); + task.shader_input = d_input.device_pointer; + task.shader_output = d_output.device_pointer; + task.shader_eval_type = shader_type; + task.shader_x = 0; + task.shader_w = d_output.size(); + task.get_cancel = function_bind(&Progress::get_cancel, &progress); + + device->task_add(task); + device->task_wait(); + + if(progress.get_cancel()) { + device->mem_free(d_input); + device->mem_free(d_output); + m_is_baking = false; + return false; + } + + device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); + device->mem_free(d_input); + device->mem_free(d_output); + + /* read result */ + int k = 0; + + float4 *offset = (float4*)d_output.data_pointer; + + size_t depth = 4; + for(size_t i = 0; i < limit; i++) { + size_t index = i * depth; + float4 out = offset[k++]; + + if(bake_data->is_valid(i)) { + for(size_t j=0; j < 4; j++) { + result[index + j] = out[j]; + } + } + } + + m_is_baking = false; + return true; +} + +void BakeManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) +{ + if(!need_update) + return; + + if(progress.get_cancel()) return; + + need_update = false; +} + +void BakeManager::device_free(Device *device, DeviceScene *dscene) +{ +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h new file mode 100644 index 00000000000..830a9513065 --- /dev/null +++ b/intern/cycles/render/bake.h @@ -0,0 +1,72 @@ +/* + * Copyright 2011-2014 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 + */ + +#ifndef __BAKE_H__ +#define __BAKE_H__ + +#include "util_vector.h" +#include "device.h" +#include "scene.h" +#include "session.h" + +CCL_NAMESPACE_BEGIN + +class BakeData { +public: + BakeData(const int object, const int tri_offset, const int num_pixels); + ~BakeData(); + + void set(int i, int prim, float uv[2]); + int object(); + int size(); + uint4 data(int i); + bool is_valid(int i); + +private: + int m_object; + int m_tri_offset; + int m_num_pixels; + vector<int>m_primitive; + vector<float>m_u; + vector<float>m_v; +}; + +class BakeManager { +public: + BakeManager(); + ~BakeManager(); + + bool get_baking(); + void set_baking(const bool value); + + BakeData *init(const int object, const int tri_offset, const int num_pixels); + + bool bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[]); + + void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); + void device_free(Device *device, DeviceScene *dscene); + + bool need_update; + +private: + BakeData *m_bake_data; + bool m_is_baking; +}; + +CCL_NAMESPACE_END + +#endif /* __BAKE_H__ */ + diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 30ad86a8d4c..c1aefbcfbbc 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -155,6 +155,9 @@ void Pass::add(PassType type, vector<Pass>& passes) pass.components = 4; pass.exposure = false; break; + case PASS_LIGHT: + /* ignores */ + break; } passes.push_back(pass); @@ -393,6 +396,10 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) kfilm->pass_shadow = kfilm->pass_stride; kfilm->use_light_pass = 1; break; + + case PASS_LIGHT: + kfilm->use_light_pass = 1; + break; case PASS_NONE: break; } diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index dd5694582e6..a5e3fabb19d 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN -static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels) +static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels, Progress& progress) { /* create input */ int width = res; @@ -66,6 +66,7 @@ static void shade_background_pixels(Device *device, DeviceScene *dscene, int res main_task.shader_eval_type = SHADER_EVAL_BACKGROUND; main_task.shader_x = 0; main_task.shader_w = width*height; + main_task.get_cancel = function_bind(&Progress::get_cancel, &progress); /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */ list<DeviceTask> split_tasks; @@ -396,7 +397,7 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene, assert(res > 0); vector<float3> pixels; - shade_background_pixels(device, dscene, res, pixels); + shade_background_pixels(device, dscene, res, pixels, progress); if(progress.get_cancel()) return; diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index 09d3ce6a588..661fd9c66c1 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -119,17 +119,21 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me task.shader_eval_type = SHADER_EVAL_DISPLACE; task.shader_x = 0; task.shader_w = d_output.size(); + task.get_cancel = function_bind(&Progress::get_cancel, &progress); device->task_add(task); device->task_wait(); + if(progress.get_cancel()) { + device->mem_free(d_input); + device->mem_free(d_output); + return false; + } + device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); device->mem_free(d_input); device->mem_free(d_output); - if(progress.get_cancel()) - return false; - /* read result */ done.clear(); done.resize(mesh->verts.size(), false); diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 2ed4efe7f2b..4a42b2c9e35 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -17,6 +17,7 @@ #include <stdlib.h> #include "background.h" +#include "bake.h" #include "camera.h" #include "curves.h" #include "device.h" @@ -54,6 +55,7 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_) image_manager = new ImageManager(); particle_system_manager = new ParticleSystemManager(); curve_system_manager = new CurveSystemManager(); + bake_manager = new BakeManager(); /* OSL only works on the CPU */ if(device_info_.type == DEVICE_CPU) @@ -103,6 +105,8 @@ void Scene::free_memory(bool final) particle_system_manager->device_free(device, &dscene); curve_system_manager->device_free(device, &dscene); + bake_manager->device_free(device, &dscene); + if(!params.persistent_data || final) image_manager->device_free(device, &dscene); @@ -122,6 +126,7 @@ void Scene::free_memory(bool final) delete particle_system_manager; delete curve_system_manager; delete image_manager; + delete bake_manager; } } @@ -208,6 +213,11 @@ void Scene::device_update(Device *device_, Progress& progress) if(progress.get_cancel()) return; + progress.set_status("Updating Baking"); + bake_manager->device_update(device, &dscene, this, progress); + + if(progress.get_cancel()) return; + progress.set_status("Updating Device", "Writing constant memory"); device->const_copy_to("__data", &dscene.data, sizeof(dscene.data)); } @@ -258,7 +268,8 @@ bool Scene::need_reset() || integrator->need_update || shader_manager->need_update || particle_system_manager->need_update - || curve_system_manager->need_update); + || curve_system_manager->need_update + || bake_manager->need_update); } void Scene::reset() diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index b6a4d6c0436..c913b4c59da 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -51,6 +51,8 @@ class CurveSystemManager; class Shader; class ShaderManager; class Progress; +class BakeManager; +class BakeData; /* Scene Device Data */ @@ -174,6 +176,7 @@ public: ObjectManager *object_manager; ParticleSystemManager *particle_system_manager; CurveSystemManager *curve_system_manager; + BakeManager *bake_manager; /* default shaders */ int default_surface; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 9cf7f49754c..28b44df6b36 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -23,6 +23,7 @@ #include "integrator.h" #include "scene.h" #include "session.h" +#include "bake.h" #include "util_foreach.h" #include "util_function.h" @@ -733,10 +734,14 @@ void Session::update_scene() cam->tag_update(); } - /* number of samples is needed by multi jittered sampling pattern */ + /* number of samples is needed by multi jittered + * sampling pattern and by baking */ Integrator *integrator = scene->integrator; + BakeManager *bake_manager = scene->bake_manager; - if(integrator->sampling_pattern == SAMPLING_PATTERN_CMJ) { + if(integrator->sampling_pattern == SAMPLING_PATTERN_CMJ || + bake_manager->get_baking()) + { int aa_samples = tile_manager.num_samples; if(aa_samples != integrator->aa_samples) { diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 8c597c431bb..1e625158652 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -136,6 +136,7 @@ public: void set_samples(int samples); void set_pause(bool pause); + void update_scene(); void device_free(); protected: struct DelayedReset { @@ -147,7 +148,6 @@ protected: void run(); - void update_scene(); void update_status_time(bool show_pause = false, bool show_done = false); void tonemap(int sample); |