diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-10-27 17:07:44 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-10-27 23:49:15 +0300 |
commit | 18ba7e26ad445981fb2750ec4bef1273f11d1554 (patch) | |
tree | ea935b8cb35d025ab86442bbcff5dc126f485a8b | |
parent | 23f51a4e43b75514b1219efcde9767bab0c166c2 (diff) |
GPUMaterial: Add a domain property.
This let us know efficiently if a material has a dedicated nodetree for each of it's output node input.
Only works for Eevee at this moment.
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 30 | ||||
-rw-r--r-- | source/blender/nodes/shader/node_shader_tree.c | 29 |
4 files changed, 62 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index fe9fb2598d0..20516d3dd5e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -816,6 +816,7 @@ extern void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *); void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *)); void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat, short compatibility); +void ntreeGPUMaterialDomain(struct bNodeTree *ntree, bool *has_surface_output, bool *has_volume_output); /** \} */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 7bc256a70fa..1508941f706 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -267,6 +267,8 @@ void GPU_material_vertex_attributes(GPUMaterial *material, bool GPU_material_do_color_management(GPUMaterial *mat); bool GPU_material_use_new_shading_nodes(GPUMaterial *mat); bool GPU_material_use_world_space_shading(GPUMaterial *mat); +bool GPU_material_use_domain_surface(GPUMaterial *mat); +bool GPU_material_use_domain_volume(GPUMaterial *mat); /* Exported shading */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 55157246c19..312cd7bc20a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -135,9 +135,20 @@ struct GPUMaterial { bool bound; bool is_opensubdiv; + + /* XXX: Should be in Material. But it depends on the output node + * used and since the output selection is difference for GPUMaterial... + */ + int domain; + GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ }; +enum { + GPU_DOMAIN_SURFACE = (1 << 0), + GPU_DOMAIN_VOLUME = (1 << 1) +}; + /* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */ static void texture_rgb_blend( GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, @@ -509,6 +520,16 @@ bool GPU_material_use_world_space_shading(GPUMaterial *mat) return BKE_scene_use_world_space_shading(mat->scene); } +bool GPU_material_use_domain_surface(GPUMaterial *mat) +{ + return (mat->domain & GPU_DOMAIN_SURFACE); +} + +bool GPU_material_use_domain_volume(GPUMaterial *mat) +{ + return (mat->domain & GPU_DOMAIN_VOLUME); +} + static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist) { GPUNodeLink *visifac; @@ -2145,6 +2166,7 @@ GPUMaterial *GPU_material_from_nodetree( GPUMaterial *mat; GPUNodeLink *outlink; LinkData *link; + bool has_volume_output, has_surface_output; /* Caller must re-use materials. */ BLI_assert(GPU_material_from_nodetree_find(gpumaterials, engine_type, options) == NULL); @@ -2156,6 +2178,14 @@ GPUMaterial *GPU_material_from_nodetree( mat->options = options; ntreeGPUMaterialNodes(ntree, mat, NODE_NEW_SHADING | NODE_NEWER_SHADING); + ntreeGPUMaterialDomain(ntree, &has_surface_output, &has_volume_output); + + if (has_surface_output) { + mat->domain |= GPU_DOMAIN_SURFACE; + } + if (has_volume_output) { + mat->domain |= GPU_DOMAIN_VOLUME; + } /* Let Draw manager finish the construction. */ if (mat->outlink) { diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index b014da90145..67086d1f97d 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -527,6 +527,35 @@ static void ntree_shader_tag_ssr_node(bNodeTree *ntree, short compatibility) nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_count, 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) { /* localize tree to create links for reroute and mute */ |