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:
authorBrecht Van Lommel <brecht@blender.org>2019-05-10 22:39:58 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2020-05-15 21:25:24 +0300
commitd9773edaa394f61393f9c8b80275e62f74306097 (patch)
tree232b771b341e98a5403af16791bdcca133cb1edd /source/blender/render
parent3ff8ca60e94db2584ca76e323a54c738e677d5f8 (diff)
Cycles: code refactor to bake using regular render session and tiles
There should be no user visible change from this, except that tile size now affects performance. The goal here is to simplify bake denoising in D3099, letting it reuse more denoising tiles and pass code. A lot of code is now shared with regular rendering, with the two main differences being that we read some render result passes from the bake API when starting to render a tile, and call the bake kernel instead of the path trace kernel. With this kind of design where Cycles asks for tiles from the bake API, it should eventually be easier to reduce memory usage, show tiles as they are baked, or bake multiple passes at once, though there's still quite some work needed for that. Reviewers: #cycles Subscribers: monio, wmatyjewicz, lukasstockner97, michaelknubben Differential Revision: https://developer.blender.org/D3108
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/extern/include/RE_bake.h2
-rw-r--r--source/blender/render/extern/include/RE_engine.h14
-rw-r--r--source/blender/render/intern/include/render_result.h11
-rw-r--r--source/blender/render/intern/source/external_engine.c129
-rw-r--r--source/blender/render/intern/source/pipeline.c2
-rw-r--r--source/blender/render/intern/source/render_result.c18
6 files changed, 141 insertions, 35 deletions
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index 372defbe8db..59e34404074 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -67,7 +67,7 @@ bool RE_bake_engine(struct Render *re,
struct Object *object,
const int object_id,
const BakePixel pixel_array[],
- const size_t num_pixels,
+ const BakeImages *bake_images,
const int depth,
const eScenePassType pass_type,
const int pass_filter,
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index fd55a2a01df..82b45ba9d4a 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -87,11 +87,8 @@ typedef struct RenderEngineType {
struct Object *object,
const int pass_type,
const int pass_filter,
- const int object_id,
- const struct BakePixel *pixel_array,
- const int num_pixels,
- const int depth,
- void *result);
+ const int width,
+ const int height);
void (*view_update)(struct RenderEngine *engine,
const struct bContext *context,
@@ -140,6 +137,13 @@ typedef struct RenderEngine {
struct ReportList *reports;
+ struct {
+ const struct BakePixel *pixels;
+ float *result;
+ int width, height, depth;
+ int object_id;
+ } bake;
+
/* Depsgraph */
struct Depsgraph *depsgraph;
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index fabbd5fb096..0ed8871b224 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -84,11 +84,12 @@ void render_result_exr_file_begin(struct Render *re, struct RenderEngine *engine
void render_result_exr_file_end(struct Render *re, struct RenderEngine *engine);
/* render pass wrapper for gpencil */
-struct RenderPass *gp_add_pass(struct RenderResult *rr,
- struct RenderLayer *rl,
- int channels,
- const char *name,
- const char *viewname);
+struct RenderPass *render_layer_add_pass(struct RenderResult *rr,
+ struct RenderLayer *rl,
+ int channels,
+ const char *name,
+ const char *viewname,
+ const char *chanid);
void render_result_exr_file_merge(struct RenderResult *rr,
struct RenderResult *rrpart,
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 4770e98bd20..4d88bb82dd9 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -31,6 +31,7 @@
#include "BLI_ghash.h"
#include "BLI_listbase.h"
+#include "BLI_math_bits.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -167,6 +168,89 @@ void RE_engine_free(RenderEngine *engine)
MEM_freeN(engine);
}
+/* Bake Render Results */
+
+static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h)
+{
+ /* Create render result with specified size. */
+ RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
+
+ rr->rectx = w;
+ rr->recty = h;
+ rr->tilerect.xmin = x;
+ rr->tilerect.ymin = y;
+ rr->tilerect.xmax = x + w;
+ rr->tilerect.ymax = y + h;
+
+ /* Add single baking render layer. */
+ RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer");
+ 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");
+ RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA");
+ RenderPass *differential_pass = render_layer_add_pass(rr, rl, 4, "BakeDifferential", "", "RGBA");
+
+ /* Fill render passes from bake pixel array, to be read by the render engine. */
+ for (int ty = 0; ty < h; ty++) {
+ size_t offset = ty * w * 4;
+ 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;
+
+ for (int tx = 0; tx < w; tx++) {
+ if (bake_pixel->object_id != engine->bake.object_id) {
+ primitive[0] = int_as_float(-1);
+ primitive[1] = int_as_float(-1);
+ }
+ else {
+ primitive[0] = int_as_float(bake_pixel->object_id);
+ primitive[1] = int_as_float(bake_pixel->primitive_id);
+ primitive[2] = bake_pixel->uv[0];
+ primitive[3] = bake_pixel->uv[1];
+
+ differential[0] = bake_pixel->du_dx;
+ differential[1] = bake_pixel->du_dy;
+ differential[2] = bake_pixel->dv_dx;
+ differential[3] = bake_pixel->dv_dy;
+ }
+
+ primitive += 4;
+ differential += 4;
+ bake_pixel++;
+ }
+ }
+
+ return rr;
+}
+
+static void render_result_to_bake(RenderEngine *engine, RenderResult *rr)
+{
+ RenderPass *rpass = RE_pass_find_by_name(rr->layers.first, RE_PASSNAME_COMBINED, "");
+
+ if (!rpass) {
+ return;
+ }
+
+ /* Copy from tile render result to full image bake result. */
+ int x = rr->tilerect.xmin;
+ int y = rr->tilerect.ymin;
+ int w = rr->tilerect.xmax - rr->tilerect.xmin;
+ int h = rr->tilerect.ymax - rr->tilerect.ymin;
+
+ for (int ty = 0; ty < h; ty++) {
+ size_t offset = ty * w * engine->bake.depth;
+ size_t bake_offset = ((y + ty) * engine->bake.width + x) * engine->bake.depth;
+ size_t size = w * engine->bake.depth * sizeof(float);
+
+ memcpy(engine->bake.result + bake_offset, rpass->rect + offset, size);
+ }
+}
+
/* Render Results */
static RenderPart *get_part_from_result(Render *re, RenderResult *result)
@@ -180,6 +264,12 @@ static RenderPart *get_part_from_result(Render *re, RenderResult *result)
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);
+ BLI_addtail(&engine->fullresult, result);
+ return result;
+ }
+
Render *re = engine->re;
RenderResult *result;
rcti disprect;
@@ -237,6 +327,11 @@ RenderResult *RE_engine_begin_result(
void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
{
+ if (engine->bake.pixels) {
+ /* No interactive baking updates for now. */
+ return;
+ }
+
Render *re = engine->re;
if (result) {
@@ -270,6 +365,13 @@ void RE_engine_end_result(
return;
}
+ if (engine->bake.pixels) {
+ render_result_to_bake(engine, result);
+ BLI_remlink(&engine->fullresult, result);
+ render_result_free(result);
+ return;
+ }
+
/* merge. on break, don't merge in result for preview renders, looks nicer */
if (!highlight) {
/* for exr tile render, detect tiles that are done */
@@ -574,7 +676,7 @@ bool RE_bake_engine(Render *re,
Object *object,
const int object_id,
const BakePixel pixel_array[],
- const size_t num_pixels,
+ const BakeImages *bake_images,
const int depth,
const eScenePassType pass_type,
const int pass_filter,
@@ -619,16 +721,21 @@ bool RE_bake_engine(Render *re,
type->update(engine, re->main, engine->depsgraph);
}
- type->bake(engine,
- engine->depsgraph,
- object,
- pass_type,
- pass_filter,
- object_id,
- pixel_array,
- num_pixels,
- depth,
- result);
+ for (int i = 0; i < bake_images->size; i++) {
+ const BakeImage *image = bake_images->data + i;
+
+ engine->bake.pixels = pixel_array + image->offset;
+ engine->bake.result = result + image->offset * depth;
+ engine->bake.width = image->width;
+ engine->bake.height = image->height;
+ engine->bake.depth = depth;
+ engine->bake.object_id = object_id;
+
+ type->bake(
+ engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height);
+
+ memset(&engine->bake, 0, sizeof(engine->bake));
+ }
engine->depsgraph = NULL;
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 4a910d9e12c..d68f74751ec 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2955,5 +2955,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
BLI_freelinkN(&rl->passes, rp);
}
/* create a totally new pass */
- return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname);
+ return render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname, "RGBA");
}
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index b38c1b573f3..d829033656a 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -213,12 +213,12 @@ static void set_pass_full_name(
/********************************** New **************************************/
-static RenderPass *render_layer_add_pass(RenderResult *rr,
- RenderLayer *rl,
- int channels,
- const char *name,
- const char *viewname,
- const char *chan_id)
+RenderPass *render_layer_add_pass(RenderResult *rr,
+ RenderLayer *rl,
+ int channels,
+ const char *name,
+ const char *viewname,
+ const char *chan_id)
{
const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
@@ -280,12 +280,6 @@ static RenderPass *render_layer_add_pass(RenderResult *rr,
return rpass;
}
-/* wrapper called from render_opengl */
-RenderPass *gp_add_pass(
- RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname)
-{
- return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA");
-}
/* called by main render as well for parts */
/* will read info from Render *re to define layers */