Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-06-09 21:48:19 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-06-09 22:11:03 +0300
commit147eef974114a032d9122f6d3ae3305868619877 (patch)
tree84efe2449cfa48fc19d201c0689fd49c87b46b27 /source/blender/draw/engines
parent45a5ddb57b2a94fde25d9ffab6dfd1bdd312152c (diff)
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.
Diffstat (limited to 'source/blender/draw/engines')
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c2
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl186
-rw-r--r--source/blender/draw/engines/eevee/shaders/lamps_lib.glsl85
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl25
5 files changed, 73 insertions, 228 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 52c8ec985b8..3ce60e0ed75 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -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);
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 2d074eea522..560f898b275 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -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,
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
deleted file mode 100644
index aad71b3e48e..00000000000
--- a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
+++ /dev/null
@@ -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
diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
index 0e6f976187a..ec5f6f4472f 100644
--- a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
@@ -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);
- }
- else {
- return direct_diffuse_sphere(ld, N, l_vector);
- }
-#else
- if (ld.l_type == SUN) {
- return direct_diffuse_sun(ld, N);
+ 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_point(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));
}
-#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);
- }
- else {
- return direct_ggx_sphere(ld, N, V, l_vector, roughness, f0);
- }
-#else
- if (ld.l_type == SUN) {
- return direct_ggx_sun(ld, N, V, 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_point(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);
}
-#endif
}
+#endif
#define MAX_SSS_SAMPLES 65
#define SSS_LUT_SIZE 64.0
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 4e65834e528..ac1dd071a29 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -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 ----------------- */