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.
This commit is contained in:
parent
23f51a4e43
commit
18ba7e26ad
|
@ -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);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue