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:
authorClément Foucault <foucault.clem@gmail.com>2019-08-13 01:11:36 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-08-14 14:36:56 +0300
commit13d469e6f0c554399629febeb1fd8d680b873a90 (patch)
tree16d8812da3b9cc1295a4693e1ec3e6687e1ae36f /source/blender/blenloader
parentd5002f007e8d770dea15f0881cd9d0a4f3aaf824 (diff)
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.
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c8
-rw-r--r--source/blender/blenloader/intern/readfile.h2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c186
3 files changed, 190 insertions, 6 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 65120fc4c10..bcee606ea7b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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);
}
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 7cd5bb7ac93..10ee3d52a74 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -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
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 15b4f513050..254259b1542 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -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,