diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2014-01-03 01:05:07 +0400 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2014-05-03 04:19:09 +0400 |
commit | eec3eaba084725a978f4aefb773a16ae9c0420db (patch) | |
tree | 68e34c3e8ff42af5263c010895b6649961f82eb6 /intern/cycles/render | |
parent | 97641a0ec946005d9a042f075697109c6590a28d (diff) |
Cycles Bake
Expand Cycles to use the new baking API in Blender.
It works on the selected object, and the panel can be accessed in the Render panel (similar to where it is for the Blender Internal).
It bakes for the active texture of each material of the object. The active texture is currently defined as the active Image Texture node present in the material nodetree. If you don't want the baking to override an existent material, make sure the active Image Texture node is not connected to the nodetree. The active texture is also the texture shown in the viewport in the rendered mode.
Remember to save your images after the baking is complete.
Note: Bake currently only works in the CPU
Note: This is not supported by Cycles standalone because a lot of the work is done in Blender as part of the operator only, not the engine (Cycles).
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Bake
Supported Passes:
-----------------
Data Passes
* Normal
* UV
* Diffuse/Glossy/Transmission/Subsurface/Emit Color
Light Passes
* AO
* Combined
* Shadow
* Diffuse/Glossy/Transmission/Subsurface/Emit Direct/Indirect
* Environment
Review: D421
Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge
Original design by Brecht van Lommel.
The entire commit history can be found on the branch: bake-cycles
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/CMakeLists.txt | 2 | ||||
-rw-r--r-- | intern/cycles/render/bake.cpp | 183 | ||||
-rw-r--r-- | intern/cycles/render/bake.h | 72 | ||||
-rw-r--r-- | intern/cycles/render/film.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/render/mesh_displace.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/session.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/session.h | 2 |
10 files changed, 297 insertions, 9 deletions
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); |