EEVEE: Optimize Principled BSDF compilation time
This removes unused closure branches in the principled BSDF code using the Material flags. On top of this, use constants for weights to use compiler dead code eliminitation for unused branches when there is different variants of the principled BSDF node used. Finally, remove Gbuffer packing cases that are not present inside the nodetree. Testing with the same setup as #145347: | | main (ms) | PR (ms) | Delta (ms) | | -------- | ----------- | ------------ |------------ | | Nvidia | 174 | 132 (1.31x) | 42 | | Mesa AMD | 191 | 170 (1.12x) | 21 | Barbershop compilation time is almost equal because it is not using the principled BSDF. Rel #145347 Pull Request: https://projects.blender.org/blender/blender/pulls/146324
This commit is contained in:
committed by
Clément Foucault
parent
3995359236
commit
ecc495ac39
@@ -24,6 +24,21 @@
|
||||
|
||||
#include "eevee_gbuffer_lib.glsl"
|
||||
|
||||
/* Allows to reduce shader complexity and compilation time.
|
||||
* Prefer removing the defines to let the loading lib have all cases by default. */
|
||||
#ifndef MAT_REFLECTION
|
||||
# undef GBUFFER_HAS_REFLECTION
|
||||
#endif
|
||||
#ifndef MAT_REFRACTION
|
||||
# undef GBUFFER_HAS_REFRACTION
|
||||
#endif
|
||||
#ifndef MAT_SUBSURFACE
|
||||
# undef GBUFFER_HAS_SUBSURFACE
|
||||
#endif
|
||||
#ifndef MAT_TRANSLUCENT
|
||||
# undef GBUFFER_HAS_TRANSLUCENT
|
||||
#endif
|
||||
|
||||
namespace gbuffer {
|
||||
|
||||
using ClosurePacking = gbuffer::ClosurePacking;
|
||||
|
||||
@@ -164,6 +164,10 @@ GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_tests_data)
|
||||
TYPEDEF_SOURCE("eevee_defines.hh")
|
||||
DEFINE("MAT_REFLECTION")
|
||||
DEFINE("MAT_REFRACTION")
|
||||
DEFINE("MAT_SUBSURFACE")
|
||||
DEFINE("MAT_TRANSLUCENT")
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -114,6 +114,7 @@ void node_bsdf_principled(float4 base_color,
|
||||
weight *= max((1.0f - math_reduce_max(sheen_color)), 0.0f);
|
||||
}
|
||||
|
||||
#ifdef MAT_CLEARCOAT
|
||||
/* Second layer: Coat */
|
||||
if (coat_weight > 0.0f) {
|
||||
float coat_NV = dot(CN, V);
|
||||
@@ -140,6 +141,9 @@ void node_bsdf_principled(float4 base_color,
|
||||
else {
|
||||
coat_tint.rgb = float3(1.0f);
|
||||
}
|
||||
#else
|
||||
coat_tint.rgb = float3(1.0f);
|
||||
#endif
|
||||
|
||||
/* Emission component.
|
||||
* Attenuated by sheen and coat.
|
||||
@@ -164,6 +168,7 @@ void node_bsdf_principled(float4 base_color,
|
||||
weight *= max((1.0f - metallic), 0.0f);
|
||||
}
|
||||
|
||||
#ifdef MAT_REFRACTION
|
||||
/* Transmission component */
|
||||
if (transmission_weight > 0.0f) {
|
||||
float3 F0 = float3(F0_from_ior(ior)) * reflection_tint;
|
||||
@@ -192,6 +197,7 @@ void node_bsdf_principled(float4 base_color,
|
||||
/* Attenuate lower layers */
|
||||
weight *= max((1.0f - transmission_weight), 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Specular component */
|
||||
if (true) {
|
||||
@@ -224,6 +230,7 @@ void node_bsdf_principled(float4 base_color,
|
||||
weight *= max((1.0f - math_reduce_max(reflectance)), 0.0f);
|
||||
}
|
||||
|
||||
#ifdef MAT_SUBSURFACE
|
||||
/* Subsurface component */
|
||||
if (subsurface_weight > 0.0f) {
|
||||
ClosureSubsurface sss_data;
|
||||
@@ -241,7 +248,9 @@ void node_bsdf_principled(float4 base_color,
|
||||
/* Attenuate lower layers */
|
||||
weight *= max((1.0f - subsurface_weight), 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAT_DIFFUSE
|
||||
/* Diffuse component */
|
||||
if (true) {
|
||||
ClosureDiffuse diffuse_data;
|
||||
@@ -253,6 +262,7 @@ void node_bsdf_principled(float4 base_color,
|
||||
diffuse_data.weight = 1.0f;
|
||||
closure_eval(diffuse_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
result = Closure(0);
|
||||
}
|
||||
|
||||
@@ -351,6 +351,22 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
|
||||
flag |= GPU_MATFLAG_COAT;
|
||||
}
|
||||
|
||||
/* Make constant link for the cases we optimize. This allows the driver to constant fold.
|
||||
* Note that doing so specialize the final tree topology, and thus the shader becomes less
|
||||
* reusable. So to be used with care.
|
||||
* Also note that we do note override existing links. This is because it would leak the current
|
||||
* nodes otherwise. */
|
||||
const float zero = 0.0f;
|
||||
if (!use_coat && in[SOCK_COAT_WEIGHT_ID].link == nullptr) {
|
||||
in[SOCK_COAT_WEIGHT_ID].link = GPU_constant(&zero);
|
||||
}
|
||||
if (!use_subsurf && in[SOCK_SUBSURFACE_WEIGHT_ID].link == nullptr) {
|
||||
in[SOCK_SUBSURFACE_WEIGHT_ID].link = GPU_constant(&zero);
|
||||
}
|
||||
if (!use_refract && in[SOCK_TRANSMISSION_WEIGHT_ID].link == nullptr) {
|
||||
in[SOCK_TRANSMISSION_WEIGHT_ID].link = GPU_constant(&zero);
|
||||
}
|
||||
|
||||
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
|
||||
|
||||
GPU_material_flag_set(mat, flag);
|
||||
|
||||
Reference in New Issue
Block a user