diff options
-rw-r--r-- | intern/cycles/blender/session.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/integrator/pass_accessor.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/film/read.h | 15 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/init_from_bake.h | 2 | ||||
-rw-r--r-- | intern/cycles/scene/volume.cpp | 24 | ||||
-rw-r--r-- | intern/cycles/session/session.cpp | 3 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_boundary.c | 2 | ||||
-rw-r--r-- | source/blender/freestyle/intern/application/Controller.h | 4 | ||||
-rw-r--r-- | source/blender/render/RE_bake.h | 5 | ||||
-rw-r--r-- | source/blender/render/RE_engine.h | 4 | ||||
-rw-r--r-- | source/blender/render/RE_pipeline.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/engine.cc | 93 | ||||
-rw-r--r-- | source/blender/render/intern/render_types.h | 3 |
13 files changed, 124 insertions, 46 deletions
diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp index 5954d5fb572..321771b67a5 100644 --- a/intern/cycles/blender/session.cpp +++ b/intern/cycles/blender/session.cpp @@ -659,6 +659,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, session->set_display_driver(nullptr); session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine)); + session->full_buffer_written_cb = [&](string_view filename) { full_buffer_written(filename); }; /* Sync scene. */ BL::Object b_camera_override(b_engine.camera_override()); @@ -700,6 +701,10 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, BufferParams buffer_params; buffer_params.width = bake_width; buffer_params.height = bake_height; + buffer_params.window_width = bake_width; + buffer_params.window_height = bake_height; + /* Unique layer name for multi-image baking. */ + buffer_params.layer = string_printf("bake_%d\n", (int)full_buffer_files_.size()); /* Update session. */ session->reset(session_params, buffer_params); @@ -713,8 +718,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, session->start(); session->wait(); } - - session->set_output_driver(nullptr); } void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) diff --git a/intern/cycles/integrator/pass_accessor.cpp b/intern/cycles/integrator/pass_accessor.cpp index 05318b7545b..ab056e953c2 100644 --- a/intern/cycles/integrator/pass_accessor.cpp +++ b/intern/cycles/integrator/pass_accessor.cpp @@ -191,6 +191,12 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers, * had the computation done. */ if (pass_info.num_components == 3) { get_pass_float3(render_buffers, buffer_params, destination); + + /* Use alpha for colors passes. */ + if (type == PASS_DIFFUSE_COLOR || type == PASS_GLOSSY_COLOR || + type == PASS_TRANSMISSION_COLOR) { + num_written_components = destination.num_components; + } } else if (pass_info.num_components == 4) { if (destination.num_components == 3) { diff --git a/intern/cycles/kernel/film/read.h b/intern/cycles/kernel/film/read.h index a0236909f4b..995c20a0053 100644 --- a/intern/cycles/kernel/film/read.h +++ b/intern/cycles/kernel/film/read.h @@ -235,6 +235,21 @@ ccl_device_inline void film_get_pass_pixel_float3(ccl_global const KernelFilmCon pixel[0] = f.x; pixel[1] = f.y; pixel[2] = f.z; + + /* Optional alpha channel. */ + if (kfilm_convert->num_components >= 4) { + if (kfilm_convert->pass_combined != PASS_UNUSED) { + float scale, scale_exposure; + film_get_scale_and_scale_exposure(kfilm_convert, buffer, &scale, &scale_exposure); + + ccl_global const float *in_combined = buffer + kfilm_convert->pass_combined; + const float alpha = in_combined[3] * scale; + pixel[3] = film_transparency_to_alpha(alpha); + } + else { + pixel[3] = 1.0f; + } + } } /* -------------------------------------------------------------------- diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h index dd26215bcd2..c77fc2540c1 100644 --- a/intern/cycles/kernel/integrator/init_from_bake.h +++ b/intern/cycles/kernel/integrator/init_from_bake.h @@ -113,7 +113,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg, if (prim == -1) { /* Accumulate transparency for empty pixels. */ kernel_accum_transparent(kg, state, 0, 1.0f, buffer); - return false; + return true; } prim += kernel_data.bake.tri_offset; diff --git a/intern/cycles/scene/volume.cpp b/intern/cycles/scene/volume.cpp index 77955350305..337e1833a42 100644 --- a/intern/cycles/scene/volume.cpp +++ b/intern/cycles/scene/volume.cpp @@ -183,7 +183,7 @@ class VolumeMeshBuilder { typename GridType::ValueOnIter iter = copy->beginValueOn(); for (; iter; ++iter) { - if (iter.getValue() < ValueType(volume_clipping)) { + if (openvdb::math::Abs(iter.getValue()) < ValueType(volume_clipping)) { iter.setValueOff(); } } @@ -294,6 +294,12 @@ void VolumeMeshBuilder::create_mesh(vector<float3> &vertices, #endif } +static bool is_non_empty_leaf(const openvdb::MaskGrid::TreeType &tree, const openvdb::Coord coord) +{ + auto *leaf_node = tree.probeLeaf(coord); + return (leaf_node && !leaf_node->isEmpty()); +} + void VolumeMeshBuilder::generate_vertices_and_quads(vector<ccl::int3> &vertices_is, vector<QuadData> &quads) { @@ -306,6 +312,10 @@ void VolumeMeshBuilder::generate_vertices_and_quads(vector<ccl::int3> &vertices_ unordered_map<size_t, int> used_verts; for (auto iter = tree.cbeginLeaf(); iter; ++iter) { + if (iter->isEmpty()) { + continue; + } + openvdb::CoordBBox leaf_bbox = iter->getNodeBoundingBox(); /* +1 to convert from exclusive to include bounds. */ leaf_bbox.max() = leaf_bbox.max().offsetBy(1); @@ -333,27 +343,27 @@ void VolumeMeshBuilder::generate_vertices_and_quads(vector<ccl::int3> &vertices_ static const int LEAF_DIM = openvdb::MaskGrid::TreeType::LeafNodeType::DIM; auto center = leaf_bbox.min() + openvdb::Coord(LEAF_DIM / 2); - if (!tree.probeLeaf(openvdb::Coord(center.x() - LEAF_DIM, center.y(), center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x() - LEAF_DIM, center.y(), center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_X_MIN); } - if (!tree.probeLeaf(openvdb::Coord(center.x() + LEAF_DIM, center.y(), center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x() + LEAF_DIM, center.y(), center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_X_MAX); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y() - LEAF_DIM, center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y() - LEAF_DIM, center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Y_MIN); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y() + LEAF_DIM, center.z()))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y() + LEAF_DIM, center.z()))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Y_MAX); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y(), center.z() - LEAF_DIM))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y(), center.z() - LEAF_DIM))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Z_MIN); } - if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y(), center.z() + LEAF_DIM))) { + if (!is_non_empty_leaf(tree, openvdb::Coord(center.x(), center.y(), center.z() + LEAF_DIM))) { create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Z_MAX); } } diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp index e5df22211e7..a2955da5480 100644 --- a/intern/cycles/session/session.cpp +++ b/intern/cycles/session/session.cpp @@ -436,8 +436,7 @@ int2 Session::get_effective_tile_size() const const int image_width = buffer_params_.width; const int image_height = buffer_params_.height; - /* No support yet for baking with tiles. */ - if (!params.use_auto_tile || scene->bake_manager->get_baking()) { + if (!params.use_auto_tile) { return make_int2(image_width, image_height); } diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 8d08c338b93..93da767e3c5 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -423,7 +423,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* Copy the new vertices to the queue to be processed in the next iteration. */ while (!BLI_gsqueue_is_empty(next_iteration)) { - int next_v; + PBVHVertRef next_v; BLI_gsqueue_pop(next_iteration, &next_v); BLI_gsqueue_push(current_iteration, &next_v); } diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h index b5ef0fba1f7..8e59b277ff3 100644 --- a/source/blender/freestyle/intern/application/Controller.h +++ b/source/blender/freestyle/intern/application/Controller.h @@ -20,6 +20,10 @@ # include "MEM_guardedalloc.h" #endif +struct Depsgraph; +struct Render; +struct ViewLayer; + namespace Freestyle { class AppCanvas; diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h index 56c66df5925..ebfc7509504 100644 --- a/source/blender/render/RE_bake.h +++ b/source/blender/render/RE_bake.h @@ -7,6 +7,8 @@ #pragma once +#include "RE_pipeline.h" + struct Depsgraph; struct ImBuf; struct MLoopUV; @@ -24,6 +26,9 @@ typedef struct BakeImage { int width; int height; size_t offset; + + /* For associating render result layer with image. */ + char render_layer_name[RE_MAXNAME]; } BakeImage; typedef struct BakeTargets { diff --git a/source/blender/render/RE_engine.h b/source/blender/render/RE_engine.h index 822f07c0dce..d5ad70e5a03 100644 --- a/source/blender/render/RE_engine.h +++ b/source/blender/render/RE_engine.h @@ -15,6 +15,7 @@ #include "BLI_threads.h" +struct BakeTargets; struct BakePixel; struct Depsgraph; struct Main; @@ -140,9 +141,10 @@ typedef struct RenderEngine { struct ReportList *reports; struct { + const struct BakeTargets *targets; const struct BakePixel *pixels; float *result; - int width, height, depth; + int image_id; int object_id; } bake; diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h index 548e38d3ef3..66057c06058 100644 --- a/source/blender/render/RE_pipeline.h +++ b/source/blender/render/RE_pipeline.h @@ -7,7 +7,7 @@ #pragma once -#include "DEG_depsgraph.h" +#include "DNA_ID.h" #include "DNA_listBase.h" #include "DNA_vec_types.h" diff --git a/source/blender/render/intern/engine.cc b/source/blender/render/intern/engine.cc index eac2a8931ea..97aad39d5db 100644 --- a/source/blender/render/intern/engine.cc +++ b/source/blender/render/intern/engine.cc @@ -182,8 +182,18 @@ void RE_engine_free(RenderEngine *engine) /* Bake Render Results */ -static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h) +static RenderResult *render_result_from_bake( + RenderEngine *engine, int x, int y, int w, int h, const char *layername) { + BakeImage *image = &engine->bake.targets->images[engine->bake.image_id]; + const BakePixel *pixels = engine->bake.pixels + image->offset; + const size_t channels_num = engine->bake.targets->channels_num; + + /* Remember layer name for to match images in render_frame_finish. */ + if (image->render_layer_name[0] == '\0') { + STRNCPY(image->render_layer_name, layername); + } + /* Create render result with specified size. */ RenderResult *rr = MEM_cnew<RenderResult>(__func__); @@ -196,12 +206,13 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, /* Add single baking render layer. */ RenderLayer *rl = MEM_cnew<RenderLayer>("bake render layer"); + STRNCPY(rl->name, layername); rl->rectx = w; rl->recty = h; BLI_addtail(&rr->layers, rl); /* Add render passes. */ - render_layer_add_pass(rr, rl, engine->bake.depth, RE_PASSNAME_COMBINED, "", "RGBA", true); + render_layer_add_pass(rr, rl, channels_num, RE_PASSNAME_COMBINED, "", "RGBA", true); RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA", true); RenderPass *differential_pass = render_layer_add_pass( @@ -213,8 +224,8 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, float *primitive = primitive_pass->rect + offset; float *differential = differential_pass->rect + offset; - size_t bake_offset = (y + ty) * engine->bake.width + x; - const BakePixel *bake_pixel = engine->bake.pixels + bake_offset; + size_t bake_offset = (y + ty) * image->width + x; + const BakePixel *bake_pixel = pixels + bake_offset; for (int tx = 0; tx < w; tx++) { if (bake_pixel->object_id != engine->bake.object_id) { @@ -244,36 +255,50 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, static void render_result_to_bake(RenderEngine *engine, RenderResult *rr) { - RenderPass *rpass = RE_pass_find_by_name( - static_cast<RenderLayer *>(rr->layers.first), RE_PASSNAME_COMBINED, ""); - + RenderLayer *rl = static_cast<RenderLayer *>(rr->layers.first); + RenderPass *rpass = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, ""); if (!rpass) { return; } + /* Find bake image corresponding to layer. */ + int image_id = 0; + for (; image_id < engine->bake.targets->images_num; image_id++) { + if (STREQ(engine->bake.targets->images[image_id].render_layer_name, rl->name)) { + break; + } + } + if (image_id == engine->bake.targets->images_num) { + return; + } + + const BakeImage *image = &engine->bake.targets->images[image_id]; + const BakePixel *pixels = engine->bake.pixels + image->offset; + const size_t channels_num = engine->bake.targets->channels_num; + const size_t channels_size = channels_num * sizeof(float); + float *result = engine->bake.result + image->offset * channels_num; + /* Copy from tile render result to full image bake result. Just the pixels for the * object currently being baked, to preserve other objects when baking multiple. */ const int x = rr->tilerect.xmin; const int y = rr->tilerect.ymin; const int w = rr->tilerect.xmax - rr->tilerect.xmin; const int h = rr->tilerect.ymax - rr->tilerect.ymin; - const size_t pixel_depth = engine->bake.depth; - const size_t pixel_size = pixel_depth * sizeof(float); for (int ty = 0; ty < h; ty++) { const size_t offset = ty * w; - const size_t bake_offset = (y + ty) * engine->bake.width + x; + const size_t bake_offset = (y + ty) * image->width + x; - const float *pass_rect = rpass->rect + offset * pixel_depth; - const BakePixel *bake_pixel = engine->bake.pixels + bake_offset; - float *bake_result = engine->bake.result + bake_offset * pixel_depth; + const float *pass_rect = rpass->rect + offset * channels_num; + const BakePixel *bake_pixel = pixels + bake_offset; + float *bake_result = result + bake_offset * channels_num; for (int tx = 0; tx < w; tx++) { if (bake_pixel->object_id == engine->bake.object_id) { - memcpy(bake_result, pass_rect, pixel_size); + memcpy(bake_result, pass_rect, channels_size); } - pass_rect += pixel_depth; - bake_result += pixel_depth; + pass_rect += channels_num; + bake_result += channels_num; bake_pixel++; } } @@ -323,8 +348,8 @@ static void engine_tile_highlight_set(RenderEngine *engine, RenderResult *RE_engine_begin_result( RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) { - if (engine->bake.pixels) { - RenderResult *result = render_result_from_bake(engine, x, y, w, h); + if (engine->bake.targets) { + RenderResult *result = render_result_from_bake(engine, x, y, w, h, layername); BLI_addtail(&engine->fullresult, result); return result; } @@ -385,7 +410,7 @@ static void re_ensure_passes_allocated_thread_safe(Render *re) void RE_engine_update_result(RenderEngine *engine, RenderResult *result) { - if (engine->bake.pixels) { + if (engine->bake.targets) { /* No interactive baking updates for now. */ return; } @@ -425,8 +450,10 @@ void RE_engine_end_result( return; } - if (engine->bake.pixels) { - render_result_to_bake(engine, result); + if (engine->bake.targets) { + if (!cancel || merge_results) { + render_result_to_bake(engine, result); + } BLI_remlink(&engine->fullresult, result); render_result_free(result); return; @@ -836,22 +863,28 @@ bool RE_bake_engine(Render *re, type->update(engine, re->main, engine->depsgraph); } - for (int i = 0; i < targets->images_num; i++) { - const BakeImage *image = targets->images + i; + /* Bake all images. */ + engine->bake.targets = targets; + engine->bake.pixels = pixel_array; + engine->bake.result = result; + engine->bake.object_id = object_id; - engine->bake.pixels = pixel_array + image->offset; - engine->bake.result = result + image->offset * targets->channels_num; - engine->bake.width = image->width; - engine->bake.height = image->height; - engine->bake.depth = targets->channels_num; - engine->bake.object_id = object_id; + for (int i = 0; i < targets->images_num; i++) { + const BakeImage *image = &targets->images[i]; + engine->bake.image_id = i; type->bake( engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height); + } - memset(&engine->bake, 0, sizeof(engine->bake)); + /* Optionally let render images read bake images from disk delayed. */ + if (type->render_frame_finish) { + engine->bake.image_id = 0; + type->render_frame_finish(engine); } + memset(&engine->bake, 0, sizeof(engine->bake)); + engine->depsgraph = nullptr; } diff --git a/source/blender/render/intern/render_types.h b/source/blender/render/intern/render_types.h index d1ffa1ba705..29bac6e2766 100644 --- a/source/blender/render/intern/render_types.h +++ b/source/blender/render/intern/render_types.h @@ -17,6 +17,7 @@ #include "RE_pipeline.h" +struct Depsgraph; struct GSet; struct Main; struct Object; @@ -87,7 +88,7 @@ struct Render { /* NOTE: This is a minimal dependency graph and evaluated scene which is enough to access view * layer visibility and use for postprocessing (compositor and sequencer). */ - Depsgraph *pipeline_depsgraph; + struct Depsgraph *pipeline_depsgraph; Scene *pipeline_scene_eval; /* callbacks */ |