Eevee: Improve compilation time (reduce branching).
This patch reduce the branching in the lamp loop, improving compilation time noticeably (2372ms to 1785ms for the default shader). This should not change the appearance of the shader. Performance impact is negligeable.
This commit is contained in:
parent
45a5ddb57b
commit
147eef9741
|
@ -201,7 +201,6 @@ data_to_c_simple(engines/eevee/shaders/shadow_store_frag.glsl SRC)
|
|||
data_to_c_simple(engines/eevee/shaders/shadow_copy_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/btdf_lut_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
|
||||
|
|
|
@ -83,7 +83,6 @@ extern char datatoc_ltc_lib_glsl[];
|
|||
extern char datatoc_bsdf_lut_frag_glsl[];
|
||||
extern char datatoc_btdf_lut_frag_glsl[];
|
||||
extern char datatoc_bsdf_common_lib_glsl[];
|
||||
extern char datatoc_bsdf_direct_lib_glsl[];
|
||||
extern char datatoc_bsdf_sampling_lib_glsl[];
|
||||
extern char datatoc_common_uniforms_lib_glsl[];
|
||||
extern char datatoc_common_hair_lib_glsl[];
|
||||
|
@ -552,7 +551,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E
|
|||
datatoc_irradiance_lib_glsl,
|
||||
datatoc_lightprobe_lib_glsl,
|
||||
datatoc_ltc_lib_glsl,
|
||||
datatoc_bsdf_direct_lib_glsl,
|
||||
datatoc_lamps_lib_glsl,
|
||||
/* Add one for each Closure */
|
||||
datatoc_lit_surface_frag_glsl,
|
||||
|
@ -574,7 +572,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E
|
|||
datatoc_irradiance_lib_glsl,
|
||||
datatoc_lightprobe_lib_glsl,
|
||||
datatoc_ltc_lib_glsl,
|
||||
datatoc_bsdf_direct_lib_glsl,
|
||||
datatoc_lamps_lib_glsl,
|
||||
datatoc_volumetric_lib_glsl,
|
||||
datatoc_volumetric_frag_glsl);
|
||||
|
|
|
@ -65,7 +65,6 @@ static struct {
|
|||
} e_data = {NULL}; /* Engine data */
|
||||
|
||||
extern char datatoc_bsdf_common_lib_glsl[];
|
||||
extern char datatoc_bsdf_direct_lib_glsl[];
|
||||
extern char datatoc_common_uniforms_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
extern char datatoc_octahedron_lib_glsl[];
|
||||
|
@ -92,7 +91,6 @@ static void eevee_create_shader_volumes(void)
|
|||
datatoc_common_view_lib_glsl,
|
||||
datatoc_common_uniforms_lib_glsl,
|
||||
datatoc_bsdf_common_lib_glsl,
|
||||
datatoc_bsdf_direct_lib_glsl,
|
||||
datatoc_octahedron_lib_glsl,
|
||||
datatoc_irradiance_lib_glsl,
|
||||
datatoc_lamps_lib_glsl,
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/* Bsdf direct light function */
|
||||
/* in other word, how materials react to scene lamps */
|
||||
|
||||
/* Naming convention
|
||||
* V View vector (normalized)
|
||||
* N World Normal (normalized)
|
||||
* L Outgoing Light Vector (Surface to Light in World Space) (normalized)
|
||||
* Ldist Distance from surface to the light
|
||||
* W World Pos
|
||||
*/
|
||||
|
||||
/* ------------ Diffuse ------------- */
|
||||
|
||||
float direct_diffuse_point(vec3 N, vec4 l_vector)
|
||||
{
|
||||
float dist = l_vector.w;
|
||||
vec3 L = l_vector.xyz / dist;
|
||||
float bsdf = max(0.0, dot(N, L));
|
||||
bsdf /= dist * dist;
|
||||
return bsdf;
|
||||
}
|
||||
|
||||
/* infinitly far away point source, no decay */
|
||||
float direct_diffuse_sun(LightData ld, vec3 N)
|
||||
{
|
||||
float bsdf = max(0.0, dot(N, -ld.l_forward));
|
||||
bsdf *= M_1_PI; /* Normalize */
|
||||
return bsdf;
|
||||
}
|
||||
|
||||
#ifdef USE_LTC
|
||||
float direct_diffuse_sphere(LightData ld, vec3 N, vec4 l_vector)
|
||||
{
|
||||
float NL = dot(N, l_vector.xyz / l_vector.w);
|
||||
|
||||
return ltc_evaluate_disk_simple(ld.l_radius / l_vector.w, NL);
|
||||
}
|
||||
|
||||
float direct_diffuse_rectangle(LightData ld, vec3 N, vec3 V, vec4 l_vector)
|
||||
{
|
||||
vec3 corners[4];
|
||||
corners[0] = normalize(l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey);
|
||||
corners[1] = normalize(l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey);
|
||||
corners[2] = normalize(l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey);
|
||||
corners[3] = normalize(l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey);
|
||||
|
||||
return ltc_evaluate_quad(corners, N);
|
||||
}
|
||||
|
||||
float direct_diffuse_ellipse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
|
||||
{
|
||||
vec3 points[3];
|
||||
points[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
|
||||
points[1] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
|
||||
points[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
|
||||
|
||||
return ltc_evaluate_disk(N, V, mat3(1), points);
|
||||
}
|
||||
|
||||
float direct_diffuse_unit_disc(LightData ld, vec3 N, vec3 V)
|
||||
{
|
||||
float NL = dot(N, -ld.l_forward);
|
||||
|
||||
return ltc_evaluate_disk_simple(ld.l_radius, NL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ----------- GGx ------------ */
|
||||
vec3 direct_ggx_point(vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
|
||||
{
|
||||
roughness = max(1e-3, roughness);
|
||||
float dist = l_vector.w;
|
||||
vec3 L = l_vector.xyz / dist;
|
||||
float bsdf = bsdf_ggx(N, L, V, roughness);
|
||||
bsdf /= dist * dist;
|
||||
|
||||
/* Fresnel */
|
||||
float VH = max(dot(V, normalize(V + L)), 0.0);
|
||||
return F_schlick(f0, VH) * bsdf;
|
||||
}
|
||||
|
||||
vec3 direct_ggx_sun(LightData ld, vec3 N, vec3 V, float roughness, vec3 f0)
|
||||
{
|
||||
roughness = max(1e-3, roughness);
|
||||
float bsdf = bsdf_ggx(N, -ld.l_forward, V, roughness);
|
||||
float VH = dot(V, -ld.l_forward) * 0.5 + 0.5;
|
||||
return F_schlick(f0, VH) * bsdf;
|
||||
}
|
||||
|
||||
#ifdef USE_LTC
|
||||
vec3 direct_ggx_sphere(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
|
||||
{
|
||||
roughness = clamp(roughness, 0.0008, 0.999); /* Fix low roughness artifacts. */
|
||||
|
||||
vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
|
||||
vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
|
||||
vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
|
||||
mat3 ltc_mat = ltc_matrix(ltc_lut);
|
||||
|
||||
/* Make orthonormal basis. */
|
||||
vec3 L = l_vector.xyz / l_vector.w;
|
||||
vec3 Px, Py;
|
||||
make_orthonormal_basis(L, Px, Py);
|
||||
Px *= ld.l_radius;
|
||||
Py *= ld.l_radius;
|
||||
|
||||
vec3 points[3];
|
||||
points[0] = l_vector.xyz - Px - Py;
|
||||
points[1] = l_vector.xyz + Px - Py;
|
||||
points[2] = l_vector.xyz + Px + Py;
|
||||
|
||||
float bsdf = ltc_evaluate_disk(N, V, ltc_mat, points);
|
||||
bsdf *= brdf_lut.b; /* Bsdf intensity */
|
||||
|
||||
vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
vec3 direct_ggx_ellipse(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
|
||||
{
|
||||
vec3 points[3];
|
||||
points[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
|
||||
points[1] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
|
||||
points[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
|
||||
|
||||
vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
|
||||
vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
|
||||
vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
|
||||
mat3 ltc_mat = ltc_matrix(ltc_lut);
|
||||
|
||||
float bsdf = ltc_evaluate_disk(N, V, ltc_mat, points);
|
||||
bsdf *= brdf_lut.b; /* Bsdf intensity */
|
||||
|
||||
vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
vec3 direct_ggx_rectangle(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
|
||||
{
|
||||
vec3 corners[4];
|
||||
corners[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey;
|
||||
corners[1] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
|
||||
corners[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
|
||||
corners[3] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
|
||||
|
||||
vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
|
||||
vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
|
||||
vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
|
||||
mat3 ltc_mat = ltc_matrix(ltc_lut);
|
||||
|
||||
ltc_transform_quad(N, V, ltc_mat, corners);
|
||||
float bsdf = ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0));
|
||||
bsdf *= brdf_lut.b; /* Bsdf intensity */
|
||||
|
||||
vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
vec3 direct_ggx_unit_disc(LightData ld, vec3 N, vec3 V, float roughness, vec3 f0)
|
||||
{
|
||||
roughness = clamp(roughness, 0.0004, 0.999); /* Fix low roughness artifacts. */
|
||||
|
||||
vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
|
||||
vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
|
||||
vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
|
||||
mat3 ltc_mat = ltc_matrix(ltc_lut);
|
||||
|
||||
vec3 Px = ld.l_right * ld.l_radius;
|
||||
vec3 Py = ld.l_up * ld.l_radius;
|
||||
|
||||
vec3 points[3];
|
||||
points[0] = -ld.l_forward - Px - Py;
|
||||
points[1] = -ld.l_forward + Px - Py;
|
||||
points[2] = -ld.l_forward + Px + Py;
|
||||
|
||||
float bsdf = ltc_evaluate_disk(N, V, ltc_mat, points);
|
||||
bsdf *= brdf_lut.b; /* Bsdf intensity */
|
||||
|
||||
vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
|
||||
|
||||
return spec;
|
||||
}
|
||||
#endif
|
|
@ -249,55 +249,70 @@ float light_visibility(LightData ld, vec3 W,
|
|||
return vis;
|
||||
}
|
||||
|
||||
#ifdef USE_LTC
|
||||
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
|
||||
{
|
||||
#ifdef USE_LTC
|
||||
if (ld.l_type == SUN) {
|
||||
return direct_diffuse_unit_disc(ld, N, V);
|
||||
}
|
||||
else if (ld.l_type == AREA_RECT) {
|
||||
return direct_diffuse_rectangle(ld, N, V, l_vector);
|
||||
if (ld.l_type == AREA_RECT) {
|
||||
vec3 corners[4];
|
||||
corners[0] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey);
|
||||
corners[1] = normalize((l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey);
|
||||
corners[2] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey);
|
||||
corners[3] = normalize((l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey);
|
||||
|
||||
return ltc_evaluate_quad(corners, N);
|
||||
}
|
||||
else if (ld.l_type == AREA_ELLIPSE) {
|
||||
return direct_diffuse_ellipse(ld, N, V, l_vector);
|
||||
vec3 points[3];
|
||||
points[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey;
|
||||
points[1] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey;
|
||||
points[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey;
|
||||
|
||||
return ltc_evaluate_disk(N, V, mat3(1.0), points);
|
||||
}
|
||||
else {
|
||||
return direct_diffuse_sphere(ld, N, l_vector);
|
||||
float radius = ld.l_radius;
|
||||
radius /= (ld.l_type == SUN) ? 1.0 : l_vector.w;
|
||||
vec3 L = (ld.l_type == SUN) ? -ld.l_forward : (l_vector.xyz / l_vector.w);
|
||||
|
||||
return ltc_evaluate_disk_simple(radius, dot(N, L));
|
||||
}
|
||||
#else
|
||||
if (ld.l_type == SUN) {
|
||||
return direct_diffuse_sun(ld, N);
|
||||
}
|
||||
else {
|
||||
return direct_diffuse_point(N, l_vector);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 light_specular(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
|
||||
float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
|
||||
{
|
||||
#ifdef USE_LTC
|
||||
if (ld.l_type == SUN) {
|
||||
return direct_ggx_unit_disc(ld, N, V, roughness, f0);
|
||||
}
|
||||
else if (ld.l_type == AREA_RECT) {
|
||||
return direct_ggx_rectangle(ld, N, V, l_vector, roughness, f0);
|
||||
}
|
||||
else if (ld.l_type == AREA_ELLIPSE) {
|
||||
return direct_ggx_ellipse(ld, N, V, l_vector, roughness, f0);
|
||||
if (ld.l_type == AREA_RECT) {
|
||||
vec3 corners[4];
|
||||
corners[0] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * ld.l_sizey;
|
||||
corners[1] = (l_vector.xyz + ld.l_right * -ld.l_sizex) + ld.l_up * -ld.l_sizey;
|
||||
corners[2] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * -ld.l_sizey;
|
||||
corners[3] = (l_vector.xyz + ld.l_right * ld.l_sizex) + ld.l_up * ld.l_sizey;
|
||||
|
||||
ltc_transform_quad(N, V, ltc_matrix(ltc_mat), corners);
|
||||
|
||||
return ltc_evaluate_quad(corners, vec3(0.0, 0.0, 1.0));
|
||||
}
|
||||
else {
|
||||
return direct_ggx_sphere(ld, N, V, l_vector, roughness, f0);
|
||||
bool is_ellipse = (ld.l_type == AREA_ELLIPSE);
|
||||
float radius_x = is_ellipse ? ld.l_sizex : ld.l_radius;
|
||||
float radius_y = is_ellipse ? ld.l_sizey : ld.l_radius;
|
||||
|
||||
vec3 L = (ld.l_type == SUN) ? -ld.l_forward : l_vector.xyz;
|
||||
vec3 Px = ld.l_right;
|
||||
vec3 Py = ld.l_up;
|
||||
|
||||
if (ld.l_type == SPOT || ld.l_type == POINT) {
|
||||
make_orthonormal_basis(l_vector.xyz / l_vector.w, Px, Py);
|
||||
}
|
||||
|
||||
vec3 points[3];
|
||||
points[0] = (L + Px * -radius_x) + Py * -radius_y;
|
||||
points[1] = (L + Px * radius_x) + Py * -radius_y;
|
||||
points[2] = (L + Px * radius_x) + Py * radius_y;
|
||||
|
||||
return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points);
|
||||
}
|
||||
#else
|
||||
if (ld.l_type == SUN) {
|
||||
return direct_ggx_sun(ld, N, V, roughness, f0);
|
||||
}
|
||||
else {
|
||||
return direct_ggx_point(N, V, l_vector, roughness, f0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_SSS_SAMPLES 65
|
||||
#define SSS_LUT_SIZE 64.0
|
||||
|
|
|
@ -182,6 +182,17 @@ void CLOSURE_NAME(
|
|||
/* -------------------- SCENE LAMPS LIGHTING ---------------------- */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#ifdef CLOSURE_GLOSSY
|
||||
vec2 lut_uv = lut_coords(dot(N, V), roughness);
|
||||
vec4 ltc_mat = texture(utilTex, vec3(lut_uv, 0.0)).rgba;
|
||||
#endif
|
||||
|
||||
#ifdef CLOSURE_CLEARCOAT
|
||||
vec2 lut_uv_clear = lut_coords(dot(C_N, V), C_roughness);
|
||||
vec4 ltc_mat_clear = texture(utilTex, vec3(lut_uv_clear, 0.0)).rgba;
|
||||
vec3 out_spec_clear = vec3(0.0);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
|
||||
LightData ld = lights_data[i];
|
||||
|
||||
|
@ -200,14 +211,24 @@ void CLOSURE_NAME(
|
|||
#endif
|
||||
|
||||
#ifdef CLOSURE_GLOSSY
|
||||
out_spec += l_color_vis * light_specular(ld, N, V, l_vector, roughnessSquared, f0) * ld.l_spec;
|
||||
out_spec += l_color_vis * light_specular(ld, ltc_mat, N, V, l_vector) * ld.l_spec;
|
||||
#endif
|
||||
|
||||
#ifdef CLOSURE_CLEARCOAT
|
||||
out_spec += l_color_vis * light_specular(ld, C_N, V, l_vector, C_roughnessSquared, f0) * C_intensity * ld.l_spec;
|
||||
out_spec_clear += l_color_vis * light_specular(ld, ltc_mat_clear, C_N, V, l_vector) * C_intensity * ld.l_spec;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CLOSURE_GLOSSY
|
||||
vec3 brdf_lut_lamps = texture(utilTex, vec3(lut_uv, 1.0)).rgb;
|
||||
out_spec *= F_area(f0, brdf_lut_lamps.xy) * brdf_lut_lamps.z;
|
||||
#endif
|
||||
|
||||
#ifdef CLOSURE_CLEARCOAT
|
||||
vec3 brdf_lut_lamps_clear = texture(utilTex, vec3(lut_uv_clear, 1.0)).rgb;
|
||||
out_spec_clear *= F_area(f0, brdf_lut_lamps_clear.xy) * brdf_lut_lamps_clear.z;
|
||||
out_spec += out_spec_clear;
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
|
||||
|
|
Loading…
Reference in New Issue