Freestyle: Add option for rendering Freestyle to a separate pass

This allows for more flexibility in Compositing compared to the
hardcoded alpha-over that is currently used.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D6829
This commit is contained in:
Lukas Stockner 2020-02-13 01:29:30 +01:00
parent b6572c5430
commit 4af74f453d
Notes: blender-bot 2023-02-14 04:31:04 +01:00
Referenced by issue #73793, Walk navigation crosshair gets hidden behind objects
10 changed files with 55 additions and 18 deletions

View File

@ -126,6 +126,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel):
row = layout.row()
layout.prop(freestyle, "mode", text="Control Mode")
layout.prop(freestyle, "use_view_map_cache", text="View Map Cache")
layout.prop(freestyle, "as_render_pass", text="As Render Pass")
layout.label(text="Edge Detection Options:")
split = layout.split()

View File

@ -549,7 +549,15 @@ void FRS_composite_result(Render *re, ViewLayer *view_layer, Render *freestyle_r
}
return;
}
dest = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
if (view_layer->freestyle_config.flags & FREESTYLE_AS_RENDER_PASS) {
RE_create_render_pass(
re->result, RE_PASSNAME_FREESTYLE, 4, "RGBA", view_layer->name, re->viewname);
dest = RE_RenderLayerGetPass(rl, RE_PASSNAME_FREESTYLE, re->viewname);
}
else {
dest = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
}
if (!dest) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "No destination result image to composite to" << endl;

View File

@ -44,6 +44,7 @@ enum {
FREESTYLE_ADVANCED_OPTIONS_FLAG = 1 << 4,
FREESTYLE_CULLING = 1 << 5,
FREESTYLE_VIEW_MAP_CACHE = 1 << 6,
FREESTYLE_AS_RENDER_PASS = 1 << 7,
};
/* FreestyleConfig::mode */

View File

@ -317,6 +317,8 @@ typedef enum eScenePassType {
#define RE_PASSNAME_SUBSURFACE_INDIRECT "SubsurfaceInd"
#define RE_PASSNAME_SUBSURFACE_COLOR "SubsurfaceCol"
#define RE_PASSNAME_FREESTYLE "Freestyle"
/* View - MultiView */
typedef struct SceneRenderView {
struct SceneRenderView *next, *prev;

View File

@ -1661,6 +1661,17 @@ void rna_Scene_freestyle_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
DEG_id_tag_update(&scene->id, 0);
}
void rna_Scene_use_freestyle_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->owner_id;
DEG_id_tag_update(&scene->id, 0);
if (scene->nodetree) {
ntreeCompositUpdateRLayers(scene->nodetree);
}
}
void rna_Scene_use_view_map_cache_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *UNUSED(ptr))
@ -4626,6 +4637,14 @@ void rna_def_freestyle_settings(BlenderRNA *brna)
RNA_def_property_update(
prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_use_view_map_cache_update");
prop = RNA_def_property(srna, "as_render_pass", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_AS_RENDER_PASS);
RNA_def_property_ui_text(
prop,
"As Render Pass",
"Renders Freestyle output to a separate pass instead of overlaying it on the Combined pass");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
prop = RNA_def_property(srna, "sphere_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sphere_radius");
RNA_def_property_range(prop, 0.0, 1000.0);
@ -5691,7 +5710,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS);
RNA_def_property_ui_text(prop, "Edge", "Draw stylized strokes using Freestyle");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_freestyle_update");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_use_freestyle_update");
/* threads */
prop = RNA_def_property(srna, "threads", PROP_INT, PROP_NONE);

View File

@ -315,6 +315,12 @@ static void cmp_node_rlayer_create_outputs(bNodeTree *ntree,
engine, scene, view_layer, cmp_node_rlayer_create_outputs_cb, NULL);
RE_engine_free(engine);
if ((scene->r.mode & R_EDGE_FRS) &&
(view_layer->freestyle_config.flags & FREESTYLE_AS_RENDER_PASS)) {
ntreeCompositRegisterPass(
scene->nodetree, scene, view_layer, RE_PASSNAME_FREESTYLE, SOCK_RGBA);
}
MEM_freeN(data);
node->storage = NULL;

View File

@ -228,6 +228,13 @@ struct RenderPass *RE_create_gp_pass(struct RenderResult *rr,
const char *layername,
const char *viewname);
void RE_create_render_pass(struct RenderResult *rr,
const char *name,
int channels,
const char *chan_id,
const char *layername,
const char *viewname);
/* obligatory initialize call, disprect is optional */
void RE_InitState(struct Render *re,
struct Render *source,

View File

@ -66,12 +66,6 @@ void render_result_merge(struct RenderResult *rr, struct RenderResult *rrpart);
/* Add Passes */
void render_result_clone_passes(struct Render *re, struct RenderResult *rr, const char *viewname);
void render_result_add_pass(struct RenderResult *rr,
const char *name,
int channels,
const char *chan_id,
const char *layername,
const char *viewname);
/* Free */

View File

@ -258,7 +258,7 @@ void RE_engine_add_pass(RenderEngine *engine,
return;
}
render_result_add_pass(re->result, name, channels, chan_id, layername, NULL);
RE_create_render_pass(re->result, name, channels, chan_id, layername, NULL);
}
void RE_engine_end_result(

View File

@ -520,12 +520,12 @@ void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewna
}
}
void render_result_add_pass(RenderResult *rr,
const char *name,
int channels,
const char *chan_id,
const char *layername,
const char *viewname)
void RE_create_render_pass(RenderResult *rr,
const char *name,
int channels,
const char *chan_id,
const char *layername,
const char *viewname)
{
RenderLayer *rl;
RenderPass *rp;
@ -1234,7 +1234,7 @@ void render_result_exr_file_begin(Render *re, RenderEngine *engine)
* mutex locked to avoid deadlock with Python GIL. */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
for (RenderPass *pass = templates.first; pass; pass = pass->next) {
render_result_add_pass(
RE_create_render_pass(
re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@ -1277,8 +1277,7 @@ void render_result_exr_file_end(Render *re, RenderEngine *engine)
* mutex locked to avoid deadlock with Python GIL. */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
for (RenderPass *pass = templates.first; pass; pass = pass->next) {
render_result_add_pass(
re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
RE_create_render_pass(re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
}
BLI_freelistN(&templates);