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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/addon/__init__.py3
-rw-r--r--intern/cycles/blender/addon/engine.py6
-rw-r--r--intern/cycles/blender/addon/properties.py27
-rw-r--r--intern/cycles/blender/addon/ui.py48
-rw-r--r--intern/cycles/blender/blender_python.cpp33
-rw-r--r--intern/cycles/blender/blender_session.cpp155
-rw-r--r--intern/cycles/blender/blender_session.h3
-rw-r--r--intern/cycles/device/device_cpu.cpp10
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h21
-rw-r--r--intern/cycles/kernel/kernel_displace.h267
-rw-r--r--intern/cycles/kernel/kernel_path.h80
-rw-r--r--intern/cycles/kernel/kernel_types.h33
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/bake.cpp183
-rw-r--r--intern/cycles/render/bake.h72
-rw-r--r--intern/cycles/render/film.cpp7
-rw-r--r--intern/cycles/render/light.cpp5
-rw-r--r--intern/cycles/render/mesh_displace.cpp10
-rw-r--r--intern/cycles/render/scene.cpp13
-rw-r--r--intern/cycles/render/scene.h3
-rw-r--r--intern/cycles/render/session.cpp9
-rw-r--r--intern/cycles/render/session.h2
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);