Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/engine.c
| Show First 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | #endif | ||||
| BLI_mutex_end(&engine->update_render_passes_mutex); | BLI_mutex_end(&engine->update_render_passes_mutex); | ||||
| MEM_freeN(engine); | MEM_freeN(engine); | ||||
| } | } | ||||
| /* Bake Render Results */ | /* 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. */ | /* Create render result with specified size. */ | ||||
| RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__); | RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__); | ||||
| rr->rectx = w; | rr->rectx = w; | ||||
| rr->recty = h; | rr->recty = h; | ||||
| rr->tilerect.xmin = x; | rr->tilerect.xmin = x; | ||||
| rr->tilerect.ymin = y; | rr->tilerect.ymin = y; | ||||
| rr->tilerect.xmax = x + w; | rr->tilerect.xmax = x + w; | ||||
| rr->tilerect.ymax = y + h; | rr->tilerect.ymax = y + h; | ||||
| /* Add single baking render layer. */ | /* Add single baking render layer. */ | ||||
| RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer"); | RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer"); | ||||
| STRNCPY(rl->name, layername); | |||||
| rl->rectx = w; | rl->rectx = w; | ||||
| rl->recty = h; | rl->recty = h; | ||||
| BLI_addtail(&rr->layers, rl); | BLI_addtail(&rr->layers, rl); | ||||
| /* Add render passes. */ | /* 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 *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA", true); | ||||
| RenderPass *differential_pass = render_layer_add_pass( | RenderPass *differential_pass = render_layer_add_pass( | ||||
| rr, rl, 4, "BakeDifferential", "", "RGBA", true); | rr, rl, 4, "BakeDifferential", "", "RGBA", true); | ||||
| /* Fill render passes from bake pixel array, to be read by the render engine. */ | /* Fill render passes from bake pixel array, to be read by the render engine. */ | ||||
| for (int ty = 0; ty < h; ty++) { | for (int ty = 0; ty < h; ty++) { | ||||
| size_t offset = ty * w * 4; | size_t offset = ty * w * 4; | ||||
| float *primitive = primitive_pass->rect + offset; | float *primitive = primitive_pass->rect + offset; | ||||
| float *differential = differential_pass->rect + offset; | float *differential = differential_pass->rect + offset; | ||||
| size_t bake_offset = (y + ty) * engine->bake.width + x; | size_t bake_offset = (y + ty) * image->width + x; | ||||
| const BakePixel *bake_pixel = engine->bake.pixels + bake_offset; | const BakePixel *bake_pixel = pixels + bake_offset; | ||||
| for (int tx = 0; tx < w; tx++) { | for (int tx = 0; tx < w; tx++) { | ||||
| if (bake_pixel->object_id != engine->bake.object_id) { | if (bake_pixel->object_id != engine->bake.object_id) { | ||||
| primitive[0] = int_as_float(-1); | primitive[0] = int_as_float(-1); | ||||
| primitive[1] = int_as_float(-1); | primitive[1] = int_as_float(-1); | ||||
| } | } | ||||
| else { | else { | ||||
| primitive[0] = int_as_float(bake_pixel->seed); | primitive[0] = int_as_float(bake_pixel->seed); | ||||
| Show All 13 Lines | for (int ty = 0; ty < h; ty++) { | ||||
| } | } | ||||
| } | } | ||||
| return rr; | return rr; | ||||
| } | } | ||||
| static void render_result_to_bake(RenderEngine *engine, RenderResult *rr) | static void render_result_to_bake(RenderEngine *engine, RenderResult *rr) | ||||
| { | { | ||||
| RenderPass *rpass = RE_pass_find_by_name(rr->layers.first, RE_PASSNAME_COMBINED, ""); | RenderLayer *rl = rr->layers.first; | ||||
| RenderPass *rpass = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, ""); | |||||
| if (!rpass) { | if (!rpass) { | ||||
| return; | 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 | /* 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. */ | * object currently being baked, to preserve other objects when baking multiple. */ | ||||
| const int x = rr->tilerect.xmin; | const int x = rr->tilerect.xmin; | ||||
| const int y = rr->tilerect.ymin; | const int y = rr->tilerect.ymin; | ||||
| const int w = rr->tilerect.xmax - rr->tilerect.xmin; | const int w = rr->tilerect.xmax - rr->tilerect.xmin; | ||||
| const int h = rr->tilerect.ymax - rr->tilerect.ymin; | 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++) { | for (int ty = 0; ty < h; ty++) { | ||||
| const size_t offset = ty * w; | 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 float *pass_rect = rpass->rect + offset * channels_num; | ||||
| const BakePixel *bake_pixel = engine->bake.pixels + bake_offset; | const BakePixel *bake_pixel = pixels + bake_offset; | ||||
| float *bake_result = engine->bake.result + bake_offset * pixel_depth; | float *bake_result = result + bake_offset * channels_num; | ||||
| for (int tx = 0; tx < w; tx++) { | for (int tx = 0; tx < w; tx++) { | ||||
| if (bake_pixel->object_id == engine->bake.object_id) { | 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; | pass_rect += channels_num; | ||||
| bake_result += pixel_depth; | bake_result += channels_num; | ||||
| bake_pixel++; | bake_pixel++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Render Results */ | /* Render Results */ | ||||
| static HighlightedTile highlighted_tile_from_result_get(Render *UNUSED(re), RenderResult *result) | static HighlightedTile highlighted_tile_from_result_get(Render *UNUSED(re), RenderResult *result) | ||||
| Show All 33 Lines | static void engine_tile_highlight_set(RenderEngine *engine, | ||||
| } | } | ||||
| BLI_mutex_unlock(&re->highlighted_tiles_mutex); | BLI_mutex_unlock(&re->highlighted_tiles_mutex); | ||||
| } | } | ||||
| RenderResult *RE_engine_begin_result( | RenderResult *RE_engine_begin_result( | ||||
| RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) | RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) | ||||
| { | { | ||||
| if (engine->bake.pixels) { | if (engine->bake.targets) { | ||||
| RenderResult *result = render_result_from_bake(engine, x, y, w, h); | RenderResult *result = render_result_from_bake(engine, x, y, w, h, layername); | ||||
| BLI_addtail(&engine->fullresult, result); | BLI_addtail(&engine->fullresult, result); | ||||
| return result; | return result; | ||||
| } | } | ||||
| Render *re = engine->re; | Render *re = engine->re; | ||||
| RenderResult *result; | RenderResult *result; | ||||
| rcti disprect; | rcti disprect; | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | if (!re->result->passes_allocated) { | ||||
| render_result_passes_allocated_ensure(re->result); | render_result_passes_allocated_ensure(re->result); | ||||
| } | } | ||||
| BLI_rw_mutex_unlock(&re->resultmutex); | BLI_rw_mutex_unlock(&re->resultmutex); | ||||
| } | } | ||||
| } | } | ||||
| void RE_engine_update_result(RenderEngine *engine, RenderResult *result) | void RE_engine_update_result(RenderEngine *engine, RenderResult *result) | ||||
| { | { | ||||
| if (engine->bake.pixels) { | if (engine->bake.targets) { | ||||
| /* No interactive baking updates for now. */ | /* No interactive baking updates for now. */ | ||||
| return; | return; | ||||
| } | } | ||||
| Render *re = engine->re; | Render *re = engine->re; | ||||
| if (result) { | if (result) { | ||||
| re_ensure_passes_allocated_thread_safe(re); | re_ensure_passes_allocated_thread_safe(re); | ||||
| Show All 22 Lines | void RE_engine_end_result( | ||||
| RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results) | RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results) | ||||
| { | { | ||||
| Render *re = engine->re; | Render *re = engine->re; | ||||
| if (!result) { | if (!result) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (engine->bake.pixels) { | if (engine->bake.targets) { | ||||
| if (!cancel || merge_results) { | |||||
| render_result_to_bake(engine, result); | render_result_to_bake(engine, result); | ||||
| } | |||||
| BLI_remlink(&engine->fullresult, result); | BLI_remlink(&engine->fullresult, result); | ||||
| render_result_free(result); | render_result_free(result); | ||||
| return; | return; | ||||
| } | } | ||||
| if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES)) { | if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES)) { | ||||
| const HighlightedTile tile = highlighted_tile_from_result_get(re, result); | const HighlightedTile tile = highlighted_tile_from_result_get(re, result); | ||||
| ▲ Show 20 Lines • Show All 392 Lines • ▼ Show 20 Lines | bool RE_bake_engine(Render *re, | ||||
| if (type->bake) { | if (type->bake) { | ||||
| engine->depsgraph = depsgraph; | engine->depsgraph = depsgraph; | ||||
| /* update is only called so we create the engine.session */ | /* update is only called so we create the engine.session */ | ||||
| if (type->update) { | if (type->update) { | ||||
| type->update(engine, re->main, engine->depsgraph); | type->update(engine, re->main, engine->depsgraph); | ||||
| } | } | ||||
| for (int i = 0; i < targets->images_num; i++) { | /* Bake all images. */ | ||||
| const BakeImage *image = targets->images + i; | engine->bake.targets = targets; | ||||
| engine->bake.pixels = pixel_array; | |||||
| engine->bake.pixels = pixel_array + image->offset; | engine->bake.result = result; | ||||
| 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; | 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( | type->bake( | ||||
| engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height); | 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 = NULL; | engine->depsgraph = NULL; | ||||
| } | } | ||||
| engine->flag &= ~RE_ENGINE_RENDERING; | engine->flag &= ~RE_ENGINE_RENDERING; | ||||
| engine_depsgraph_free(engine); | engine_depsgraph_free(engine); | ||||
| RE_engine_free(engine); | RE_engine_free(engine); | ||||
| ▲ Show 20 Lines • Show All 364 Lines • Show Last 20 Lines | |||||