Rename any instance of scene layer or render layer in code with view layer
[blender.git] / source / blender / nodes / shader / node_shader_tree.c
index 35a8c712905539502d38331736e8332552337a31..dc48aa324b250ece6cc26177de7f96988a012c5a 100644 (file)
@@ -39,6 +39,7 @@
 #include "DNA_space_types.h"
 #include "DNA_world_types.h"
 #include "DNA_linestyle_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BLI_listbase.h"
 #include "BLI_threads.h"
 static int shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
 {
        Scene *scene = CTX_data_scene(C);
+       WorkSpace *workspace = CTX_wm_workspace(C);
+       ViewRender *view_render = BKE_viewrender_get(scene, workspace);
+       const char *engine_id = view_render->engine_id;
+
        /* allow empty engine string too, this is from older versions that didn't have registerable engines yet */
-       return (scene->r.engine[0] == '\0' ||
-               STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER) ||
-               STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME) ||
-               STREQ(scene->r.engine, RE_engine_id_CYCLES) ||
-               !BKE_scene_use_shading_nodes_custom(scene));
+       return (engine_id[0] == '\0' ||
+               STREQ(engine_id, RE_engine_id_BLENDER_RENDER) ||
+               STREQ(engine_id, RE_engine_id_BLENDER_GAME) ||
+               STREQ(engine_id, RE_engine_id_CYCLES) ||
+               !BKE_viewrender_use_shading_nodes_custom(view_render));
 }
 
 static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
 {
        SpaceNode *snode = CTX_wm_space_node(C);
        Scene *scene = CTX_data_scene(C);
-       SceneLayer *sl = CTX_data_scene_layer(C);
-       Object *ob = OBACT_NEW(sl);
+       WorkSpace *workspace = CTX_wm_workspace(C);
+       ViewLayer *view_layer = CTX_data_view_layer(C);
+       Object *ob = OBACT(view_layer);
+       ViewRender *view_render = BKE_viewrender_get(scene, workspace);
        
        if ((snode->shaderfrom == SNODE_SHADER_OBJECT) ||
-           (BKE_scene_use_new_shading_nodes(scene) == false))
+           (BKE_viewrender_use_new_shading_nodes(view_render) == false))
        {
                if (ob) {
                        *r_from = &ob->id;
@@ -119,12 +126,12 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre
        }
 }
 
-static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func)
+static void foreach_nodeclass(ViewRender *view_render, void *calldata, bNodeClassCallback func)
 {
        func(calldata, NODE_CLASS_INPUT, N_("Input"));
        func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
 
-       if (BKE_scene_use_new_shading_nodes(scene)) {
+       if (BKE_viewrender_use_new_shading_nodes(view_render)) {
                func(calldata, NODE_CLASS_SHADER, N_("Shader"));
                func(calldata, NODE_CLASS_TEXTURE, N_("Texture"));
        }
@@ -432,7 +439,7 @@ static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
 static void ntree_shader_relink_displacement(bNodeTree *ntree,
                                              short compatibility)
 {
-       if (compatibility != NODE_NEW_SHADING) {
+       if ((compatibility & NODE_NEW_SHADING) == 0) {
                /* We can only deal with new shading system here. */
                return;
        }
@@ -504,7 +511,7 @@ static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *
  */
 static void ntree_shader_tag_ssr_node(bNodeTree *ntree, short compatibility)
 {
-       if (compatibility != NODE_NEWER_SHADING) {
+       if ((compatibility & NODE_NEWER_SHADING) == 0) {
                /* We can only deal with new shading system here. */
                return;
        }
@@ -516,8 +523,72 @@ static void ntree_shader_tag_ssr_node(bNodeTree *ntree, short compatibility)
        /* Make sure sockets links pointers are correct. */
        ntreeUpdateTree(G.main, ntree);
 
-       int lobe_count = 0;
-       nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_count, true);
+       float lobe_id = 1;
+       nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_id, true);
+}
+
+static bool ntree_tag_sss_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
+{
+       switch (fromnode->type) {
+               case SH_NODE_BSDF_PRINCIPLED:
+               case SH_NODE_SUBSURFACE_SCATTERING:
+                       fromnode->sss_id = (*(float *)userdata);
+                       (*(float *)userdata) += 1;
+                       break;
+               default:
+                       break;
+       }
+
+       return true;
+}
+
+/* EEVEE: Scan the ntree to set the Subsurface Scattering id of every SSS node.
+ */
+static void ntree_shader_tag_sss_node(bNodeTree *ntree, short compatibility)
+{
+       if ((compatibility & NODE_NEWER_SHADING) == 0) {
+               /* We can only deal with new shading system here. */
+               return;
+       }
+
+       bNode *output_node = ntree_shader_output_node(ntree);
+       if (output_node == NULL) {
+               return;
+       }
+       /* Make sure sockets links pointers are correct. */
+       ntreeUpdateTree(G.main, ntree);
+
+       float sss_id = 1;
+       nodeChainIter(ntree, output_node, ntree_tag_sss_bsdf_cb, &sss_id, true);
+}
+
+/* EEVEE: Find which material domain are used (volume, surface ...).
+ */
+void ntreeGPUMaterialDomain(bNodeTree *ntree, bool *has_surface_output, bool *has_volume_output)
+{
+       /* localize tree to create links for reroute and mute */
+       bNodeTree *localtree = ntreeLocalize(ntree);
+
+       struct bNode *output = ntree_shader_output_node(localtree);
+
+       *has_surface_output = false;
+       *has_volume_output = false;
+
+       if (output != NULL) {
+               bNodeSocket *surface_sock = ntree_shader_node_find_input(output, "Surface");
+               bNodeSocket *volume_sock = ntree_shader_node_find_input(output, "Volume");
+
+               if (surface_sock != NULL) {
+                       *has_surface_output = (nodeCountSocketLinks(localtree, surface_sock) > 0);
+               }
+
+               if (volume_sock != NULL) {
+                       *has_volume_output = (nodeCountSocketLinks(localtree, volume_sock) > 0);
+               }
+       }
+
+       ntreeFreeTree(localtree);
+       MEM_freeN(localtree);
 }
 
 void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibility)
@@ -532,6 +603,7 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibili
        ntree_shader_relink_displacement(localtree, compatibility);
 
        ntree_shader_tag_ssr_node(localtree, compatibility);
+       ntree_shader_tag_sss_node(localtree, compatibility);
 
        exec = ntreeShaderBeginExecTree(localtree);
        ntreeExecGPUNodes(exec, mat, 1, compatibility);