Eevee: Remove Additive & Multiply Blend mode
This commit also provide a compatibility code that will convert old materials using Additive or Multiply Blend mode to their node equivalent. This conversion is only done on outputs that are enabled for eevee.
This commit is contained in:
parent
d5002f007e
commit
13d469e6f0
Notes:
blender-bot
2023-02-14 00:13:36 +01:00
Referenced by issue #71584, Nodes changed after import in blender 2.81 (due to versioning code of blend mode refactor)
|
@ -27,7 +27,7 @@
|
|||
* \note Use #STRINGIFY() rather than defining with quotes.
|
||||
*/
|
||||
#define BLENDER_VERSION 281
|
||||
#define BLENDER_SUBVERSION 1
|
||||
#define BLENDER_SUBVERSION 2
|
||||
/** Several breakages with 280, e.g. collections vs layers. */
|
||||
#define BLENDER_MINVERSION 280
|
||||
#define BLENDER_MINSUBVERSION 0
|
||||
|
|
|
@ -9487,7 +9487,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
/* don't forget to set version number in BKE_blender_version.h! */
|
||||
}
|
||||
|
||||
static void do_versions_after_linking(Main *main)
|
||||
static void do_versions_after_linking(Main *main, ReportList *reports)
|
||||
{
|
||||
// printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->name : main->name,
|
||||
// main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile);
|
||||
|
@ -9495,7 +9495,7 @@ static void do_versions_after_linking(Main *main)
|
|||
do_versions_after_linking_250(main);
|
||||
do_versions_after_linking_260(main);
|
||||
do_versions_after_linking_270(main);
|
||||
do_versions_after_linking_280(main);
|
||||
do_versions_after_linking_280(main, reports);
|
||||
do_versions_after_linking_cycles(main);
|
||||
}
|
||||
|
||||
|
@ -9798,7 +9798,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
blo_split_main(&mainlist, bfd->main);
|
||||
for (Main *mainvar = mainlist.first; mainvar; mainvar = mainvar->next) {
|
||||
BLI_assert(mainvar->versionfile != 0);
|
||||
do_versions_after_linking(mainvar);
|
||||
do_versions_after_linking(mainvar, fd->reports);
|
||||
}
|
||||
blo_join_main(&mainlist);
|
||||
|
||||
|
@ -11569,7 +11569,7 @@ static void library_link_end(Main *mainl,
|
|||
* or they will go again through do_versions - bad, very bad! */
|
||||
split_main_newid(mainvar, main_newid);
|
||||
|
||||
do_versions_after_linking(main_newid);
|
||||
do_versions_after_linking(main_newid, (*fd)->reports);
|
||||
|
||||
add_main_to_main(mainvar, main_newid);
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ void blo_do_versions_cycles(struct FileData *fd, struct Library *lib, struct Mai
|
|||
void do_versions_after_linking_250(struct Main *bmain);
|
||||
void do_versions_after_linking_260(struct Main *bmain);
|
||||
void do_versions_after_linking_270(struct Main *bmain);
|
||||
void do_versions_after_linking_280(struct Main *bmain);
|
||||
void do_versions_after_linking_280(struct Main *bmain, ReportList *reports);
|
||||
void do_versions_after_linking_cycles(struct Main *bmain);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -734,7 +734,128 @@ static void do_versions_seq_alloc_transform_and_crop(ListBase *seqbase)
|
|||
}
|
||||
}
|
||||
|
||||
void do_versions_after_linking_280(Main *bmain)
|
||||
/* Return true if there is something to convert. */
|
||||
static bool do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree,
|
||||
char blend_method,
|
||||
GSet *nodegrp_tree_set)
|
||||
{
|
||||
bool need_update = false;
|
||||
bool do_conversion = false;
|
||||
|
||||
/* Iterate backwards from end so we don't encounter newly added links. */
|
||||
bNodeLink *prevlink;
|
||||
for (bNodeLink *link = ntree->links.last; link; link = prevlink) {
|
||||
prevlink = link->prev;
|
||||
|
||||
/* Detect link to replace. */
|
||||
bNode *fromnode = link->fromnode;
|
||||
bNodeSocket *fromsock = link->fromsock;
|
||||
bNode *tonode = link->tonode;
|
||||
bNodeSocket *tosock = link->tosock;
|
||||
|
||||
if (nodegrp_tree_set) {
|
||||
if (fromnode->type == NODE_GROUP && fromnode->id != NULL) {
|
||||
bNodeTree *group_ntree = (bNodeTree *)fromnode->id;
|
||||
if (BLI_gset_add(nodegrp_tree_set, group_ntree)) {
|
||||
/* Recursive but not convert (blend_method = -1). Conversion happens after. */
|
||||
if (!do_versions_material_convert_legacy_blend_mode(group_ntree, -1, nodegrp_tree_set)) {
|
||||
/* There is no output to convert in the tree, remove it. */
|
||||
BLI_gset_remove(nodegrp_tree_set, group_ntree, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tonode->type == NODE_GROUP && tonode->id != NULL) {
|
||||
bNodeTree *group_ntree = (bNodeTree *)tonode->id;
|
||||
if (BLI_gset_add(nodegrp_tree_set, group_ntree)) {
|
||||
/* Recursive but not convert (blend_method = -1). Conversion happens after. */
|
||||
if (!do_versions_material_convert_legacy_blend_mode(group_ntree, -1, nodegrp_tree_set)) {
|
||||
/* There is no output to convert in the tree, remove it. */
|
||||
BLI_gset_remove(nodegrp_tree_set, group_ntree, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(tonode->type == SH_NODE_OUTPUT_MATERIAL && STREQ(tosock->identifier, "Surface"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only do outputs that are enabled for EEVEE */
|
||||
if (!ELEM(tonode->custom1, SHD_OUTPUT_ALL, SHD_OUTPUT_EEVEE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do_conversion = true;
|
||||
|
||||
if (blend_method == 1 /* MA_BM_ADD */) {
|
||||
nodeRemLink(ntree, link);
|
||||
|
||||
bNode *add_node = nodeAddStaticNode(NULL, ntree, SH_NODE_ADD_SHADER);
|
||||
add_node->locx = 0.5f * (fromnode->locx + tonode->locx);
|
||||
add_node->locy = 0.5f * (fromnode->locy + tonode->locy);
|
||||
|
||||
bNodeSocket *shader1_socket = add_node->inputs.first;
|
||||
bNodeSocket *shader2_socket = add_node->inputs.last;
|
||||
bNodeSocket *add_socket = nodeFindSocket(add_node, SOCK_OUT, "Shader");
|
||||
|
||||
bNode *transp_node = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_TRANSPARENT);
|
||||
transp_node->locx = add_node->locx;
|
||||
transp_node->locy = add_node->locy - 110.0f;
|
||||
|
||||
bNodeSocket *transp_socket = nodeFindSocket(transp_node, SOCK_OUT, "BSDF");
|
||||
|
||||
/* Link to input and material output node. */
|
||||
nodeAddLink(ntree, fromnode, fromsock, add_node, shader1_socket);
|
||||
nodeAddLink(ntree, transp_node, transp_socket, add_node, shader2_socket);
|
||||
nodeAddLink(ntree, add_node, add_socket, tonode, tosock);
|
||||
|
||||
need_update = true;
|
||||
}
|
||||
else if (blend_method == 2 /* MA_BM_MULTIPLY */) {
|
||||
nodeRemLink(ntree, link);
|
||||
|
||||
bNode *transp_node = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_TRANSPARENT);
|
||||
|
||||
bNodeSocket *color_socket = nodeFindSocket(transp_node, SOCK_IN, "Color");
|
||||
bNodeSocket *transp_socket = nodeFindSocket(transp_node, SOCK_OUT, "BSDF");
|
||||
|
||||
/* If incomming link is from a closure socket, we need to convert it. */
|
||||
if (fromsock->type == SOCK_SHADER) {
|
||||
transp_node->locx = 0.33f * fromnode->locx + 0.66f * tonode->locx;
|
||||
transp_node->locy = 0.33f * fromnode->locy + 0.66f * tonode->locy;
|
||||
|
||||
bNode *shtorgb_node = nodeAddStaticNode(NULL, ntree, SH_NODE_SHADERTORGB);
|
||||
shtorgb_node->locx = 0.66f * fromnode->locx + 0.33f * tonode->locx;
|
||||
shtorgb_node->locy = 0.66f * fromnode->locy + 0.33f * tonode->locy;
|
||||
|
||||
bNodeSocket *shader_socket = nodeFindSocket(shtorgb_node, SOCK_IN, "Shader");
|
||||
bNodeSocket *rgba_socket = nodeFindSocket(shtorgb_node, SOCK_OUT, "Color");
|
||||
|
||||
nodeAddLink(ntree, fromnode, fromsock, shtorgb_node, shader_socket);
|
||||
nodeAddLink(ntree, shtorgb_node, rgba_socket, transp_node, color_socket);
|
||||
}
|
||||
else {
|
||||
transp_node->locx = 0.5f * (fromnode->locx + tonode->locx);
|
||||
transp_node->locy = 0.5f * (fromnode->locy + tonode->locy);
|
||||
|
||||
nodeAddLink(ntree, fromnode, fromsock, transp_node, color_socket);
|
||||
}
|
||||
|
||||
/* Link to input and material output node. */
|
||||
nodeAddLink(ntree, transp_node, transp_socket, tonode, tosock);
|
||||
|
||||
need_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
}
|
||||
|
||||
return do_conversion;
|
||||
}
|
||||
|
||||
void do_versions_after_linking_280(Main *bmain, ReportList *reports)
|
||||
{
|
||||
bool use_collection_compat_28 = true;
|
||||
|
||||
|
@ -1129,6 +1250,69 @@ void do_versions_after_linking_280(Main *bmain)
|
|||
camera->dof_ob = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 281, 2)) {
|
||||
/* Replace Multiply and Additive blend mode by Alpha Blend
|
||||
* now that we use dualsource blending. */
|
||||
/* We take care of doing only nodetrees that are always part of materials
|
||||
* with old blending modes. */
|
||||
GSet *ntrees_additive = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
|
||||
GSet *ntrees_multiply = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
|
||||
GSet *ntrees_nolegacy = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
|
||||
for (Material *ma = bmain->materials.first; ma; ma = ma->id.next) {
|
||||
bNodeTree *ntree = ma->nodetree;
|
||||
if (ma->blend_method == 1 /* MA_BM_ADD */) {
|
||||
if (ma->use_nodes) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, ma->blend_method, ntrees_additive);
|
||||
}
|
||||
ma->blend_method = MA_BM_BLEND;
|
||||
}
|
||||
else if (ma->blend_method == 2 /* MA_BM_MULTIPLY */) {
|
||||
if (ma->use_nodes) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, ma->blend_method, ntrees_multiply);
|
||||
}
|
||||
ma->blend_method = MA_BM_BLEND;
|
||||
}
|
||||
else {
|
||||
/* Still tag the group nodes as not using legacy blend modes. */
|
||||
if (ma->use_nodes) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, -1, ntrees_nolegacy);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Remove group nodetree that are used by material using non-legacy blend mode. */
|
||||
GHashIterState iter = {0};
|
||||
bNodeTree *ntree;
|
||||
bool error = false;
|
||||
while (BLI_gset_pop(ntrees_nolegacy, (GSetIterState *)&iter, (void **)&ntree)) {
|
||||
if (BLI_gset_remove(ntrees_additive, ntree, NULL)) {
|
||||
error = true;
|
||||
}
|
||||
if (BLI_gset_remove(ntrees_multiply, ntree, NULL)) {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
BLI_gset_free(ntrees_nolegacy, NULL);
|
||||
/* Convert remaining group nodetree. */
|
||||
GHashIterState iter_add = {0};
|
||||
GHashIterState iter_mul = {0};
|
||||
while (BLI_gset_pop(ntrees_additive, (GSetIterState *)&iter_add, (void **)&ntree)) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, 1 /* MA_BM_ADD */, NULL);
|
||||
}
|
||||
while (BLI_gset_pop(ntrees_multiply, (GSetIterState *)&iter_mul, (void **)&ntree)) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, 2 /* MA_BM_MULTIPLY */, NULL);
|
||||
}
|
||||
BLI_gset_free(ntrees_additive, NULL);
|
||||
BLI_gset_free(ntrees_multiply, NULL);
|
||||
|
||||
if (error) {
|
||||
BKE_report(reports, RPT_ERROR, "Eevee material conversion problem. Error in console");
|
||||
printf(
|
||||
"One or more group nodetrees containing a material output were found"
|
||||
" in both a material using deprecated blend mode and a normal one.\n"
|
||||
"Nothing in these nodetrees was changed and manual update is required.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: This version patch is intended for versions < 2.52.2,
|
||||
|
|
|
@ -1474,21 +1474,10 @@ static void material_transparent(Material *ma,
|
|||
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
|
||||
DRW_STATE_BLEND_CUSTOM);
|
||||
|
||||
DRWState cur_state = DRW_STATE_WRITE_COLOR;
|
||||
DRWState cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
|
||||
cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
|
||||
|
||||
switch (ma->blend_method) {
|
||||
case MA_BM_ADD:
|
||||
case MA_BM_MULTIPLY:
|
||||
case MA_BM_BLEND:
|
||||
cur_state |= DRW_STATE_BLEND_CUSTOM;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable other blend modes and use the one we want. */
|
||||
DRW_shgroup_state_disable(*shgrp, all_state);
|
||||
DRW_shgroup_state_enable(*shgrp, cur_state);
|
||||
|
@ -1564,8 +1553,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
|
|||
&shgrp_depth_array[i],
|
||||
&shgrp_depth_clip_array[i]);
|
||||
break;
|
||||
case MA_BM_ADD:
|
||||
case MA_BM_MULTIPLY:
|
||||
case MA_BM_BLEND:
|
||||
material_transparent(ma_array[i],
|
||||
sldata,
|
||||
|
|
|
@ -306,12 +306,12 @@ typedef struct Material {
|
|||
|
||||
/* blend_method */
|
||||
enum {
|
||||
MA_BM_SOLID,
|
||||
MA_BM_ADD,
|
||||
MA_BM_MULTIPLY,
|
||||
MA_BM_CLIP,
|
||||
MA_BM_HASHED,
|
||||
MA_BM_BLEND,
|
||||
MA_BM_SOLID = 0,
|
||||
// MA_BM_ADD = 1, /* deprecated */
|
||||
// MA_BM_MULTIPLY = 2, /* deprecated */
|
||||
MA_BM_CLIP = 3,
|
||||
MA_BM_HASHED = 4,
|
||||
MA_BM_BLEND = 5,
|
||||
};
|
||||
|
||||
/* blend_flag */
|
||||
|
|
|
@ -719,16 +719,6 @@ void RNA_def_material(BlenderRNA *brna)
|
|||
|
||||
static EnumPropertyItem prop_eevee_blend_items[] = {
|
||||
{MA_BM_SOLID, "OPAQUE", 0, "Opaque", "Render surface without transparency"},
|
||||
{MA_BM_ADD,
|
||||
"ADD",
|
||||
0,
|
||||
"Additive",
|
||||
"Render surface and blend the result with additive blending"},
|
||||
{MA_BM_MULTIPLY,
|
||||
"MULTIPLY",
|
||||
0,
|
||||
"Multiply",
|
||||
"Render surface and blend the result with multiplicative blending"},
|
||||
{MA_BM_CLIP,
|
||||
"CLIP",
|
||||
0,
|
||||
|
|
Loading…
Reference in New Issue