[Bf-blender-cvs] [dbed33479a9] blender2.8: Eevee: Remove non-ltc area light code + optimisation.

Clément Foucault noreply at git.blender.org
Mon May 29 15:52:58 CEST 2017


Commit: dbed33479a9f55e42b70ea03fe796b10337a21c7
Author: Clément Foucault
Date:   Mon May 29 12:32:05 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBdbed33479a9f55e42b70ea03fe796b10337a21c7

Eevee: Remove non-ltc area light code + optimisation.

Reduce size ShadingData struct leads to some improvement even with more computation.

===================================================================

M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M	source/blender/draw/engines/eevee/shaders/ltc_lib.glsl

===================================================================

diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index feaddd3c0e3..a9be6ca5478 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -66,21 +66,11 @@ struct ShadowCascadeData {
 	vec4 bias;
 };
 
-struct AreaData {
-	vec3 corner[4];
-	float solid_angle;
-};
-
 struct ShadingData {
 	vec3 V; /* View vector */
 	vec3 N; /* World Normal of the fragment */
 	vec3 W; /* World Position of the fragment */
-	vec3 R; /* Reflection vector */
-	vec3 L; /* Current Light vector (normalized) */
-	vec3 spec_dominant_dir; /* dominant direction of the specular rays */
 	vec3 l_vector; /* Current Light vector */
-	float l_distance; /* distance(l_position, W) */
-	AreaData area_data; /* If current light is an area light */
 };
 
 /* ------- Convenience functions --------- */
@@ -213,21 +203,6 @@ vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9])
 	return sh;
 }
 
-float rectangle_solid_angle(AreaData ad)
-{
-	vec3 n0 = normalize(cross(ad.corner[0], ad.corner[1]));
-	vec3 n1 = normalize(cross(ad.corner[1], ad.corner[2]));
-	vec3 n2 = normalize(cross(ad.corner[2], ad.corner[3]));
-	vec3 n3 = normalize(cross(ad.corner[3], ad.corner[0]));
-
-	float g0 = acos(dot(-n0, n1));
-	float g1 = acos(dot(-n1, n2));
-	float g2 = acos(dot(-n2, n3));
-	float g3 = acos(dot(-n3, n0));
-
-	return max(0.0, (g0 + g1 + g2 + g3 - 2.0 * M_PI));
-}
-
 vec3 get_specular_dominant_dir(vec3 N, vec3 R, float roughness)
 {
 	float smoothness = 1.0 - roughness;
@@ -235,52 +210,6 @@ vec3 get_specular_dominant_dir(vec3 N, vec3 R, float roughness)
 	return normalize(mix(N, R, fac));
 }
 
-/* From UE4 paper */
-vec3 mrp_sphere(LightData ld, ShadingData sd, vec3 dir, inout float roughness, out float energy_conservation)
-{
-	roughness = max(3e-3, roughness); /* Artifacts appear with roughness below this threshold */
-
-	/* energy preservation */
-	float sphere_angle = saturate(ld.l_radius / sd.l_distance);
-	energy_conservation = pow(roughness / saturate(roughness + 0.5 * sphere_angle), 2.0);
-
-	/* sphere light */
-	float inter_dist = dot(sd.l_vector, dir);
-	vec3 closest_point_on_ray = inter_dist * dir;
-	vec3 center_to_ray = closest_point_on_ray - sd.l_vector;
-
-	/* closest point on sphere */
-	vec3 closest_point_on_sphere = sd.l_vector + center_to_ray * saturate(ld.l_radius * inverse_distance(center_to_ray));
-
-	return normalize(closest_point_on_sphere);
-}
-
-vec3 mrp_area(LightData ld, ShadingData sd, vec3 dir, inout float roughness, out float energy_conservation)
-{
-	roughness = max(3e-3, roughness); /* Artifacts appear with roughness below this threshold */
-
-	/* FIXME : This needs to be fixed */
-	energy_conservation = pow(roughness / saturate(roughness + 0.5 * sd.area_data.solid_angle), 2.0);
-
-	vec3 refproj = line_plane_intersect(sd.W, dir, ld.l_position, ld.l_forward);
-
-	/* Project the point onto the light plane */
-	vec3 refdir = refproj - ld.l_position;
-	vec2 mrp = vec2(dot(refdir, ld.l_right), dot(refdir, ld.l_up));
-
-	/* clamp to light shape bounds */
-	vec2 area_half_size = vec2(ld.l_sizex, ld.l_sizey);
-	mrp = clamp(mrp, -area_half_size, area_half_size);
-
-	/* go back in world space */
-	vec3 closest_point_on_rectangle = sd.l_vector + mrp.x * ld.l_right + mrp.y * ld.l_up;
-
-	float len = length(closest_point_on_rectangle);
-	energy_conservation /= len * len;
-
-	return closest_point_on_rectangle / len;
-}
-
 /* Fresnel */
 vec3 F_schlick(vec3 f0, float cos_theta)
 {
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
index 9097f4aca5a..07fff8ac2d2 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
@@ -13,8 +13,10 @@
 
 float direct_diffuse_point(LightData ld, ShadingData sd)
 {
-	float bsdf = max(0.0, dot(sd.N, sd.L));
-	bsdf /= sd.l_distance * sd.l_distance;
+	float dist = length(sd.l_vector);
+	vec3 L = sd.l_vector / dist;
+	float bsdf = max(0.0, dot(sd.N, L));
+	bsdf /= dist * dist;
 	return bsdf;
 }
 
@@ -23,9 +25,11 @@ float direct_diffuse_point(LightData ld, ShadingData sd)
  * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
 float direct_diffuse_sphere(LightData ld, ShadingData sd)
 {
+	float dist = length(sd.l_vector);
+	vec3 L = sd.l_vector / dist;
 	float radius = max(ld.l_sizex, 0.0001);
-	float costheta = clamp(dot(sd.N, sd.L), -0.999, 0.999);
-	float h = min(ld.l_radius / sd.l_distance , 0.9999);
+	float costheta = clamp(dot(sd.N, L), -0.999, 0.999);
+	float h = min(ld.l_radius / dist , 0.9999);
 	float h2 = h*h;
 	float costheta2 = costheta * costheta;
 	float bsdf;
@@ -51,26 +55,21 @@ float direct_diffuse_sphere(LightData ld, ShadingData sd)
  * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
 float direct_diffuse_rectangle(LightData ld, ShadingData sd)
 {
-#ifdef USE_LTC
-	float bsdf = ltc_evaluate(sd.N, sd.V, mat3(1.0), sd.area_data.corner);
+	vec3 corners[4];
+	corners[0] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up *  ld.l_sizey;
+	corners[1] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
+	corners[2] = sd.l_vector + ld.l_right *  ld.l_sizex + ld.l_up * -ld.l_sizey;
+	corners[3] = sd.l_vector + ld.l_right *  ld.l_sizex + ld.l_up *  ld.l_sizey;
+
+	float bsdf = ltc_evaluate(sd.N, sd.V, mat3(1.0), corners);
 	bsdf *= M_1_2PI;
-#else
-	float bsdf = sd.area_data.solid_angle * 0.2 * (
-		max(0.0, dot(normalize(sd.area_data.corner[0]), sd.N)) +
-		max(0.0, dot(normalize(sd.area_data.corner[1]), sd.N)) +
-		max(0.0, dot(normalize(sd.area_data.corner[2]), sd.N)) +
-		max(0.0, dot(normalize(sd.area_data.corner[3]), sd.N)) +
-		max(0.0, dot(sd.L, sd.N))
-	);
-	bsdf *= M_1_PI;
-#endif
 	return bsdf;
 }
 
 /* infinitly far away point source, no decay */
 float direct_diffuse_sun(LightData ld, ShadingData sd)
 {
-	float bsdf = max(0.0, dot(sd.N, sd.L));
+	float bsdf = max(0.0, dot(sd.N, -ld.l_forward));
 	bsdf *= M_1_PI; /* Normalize */
 	return bsdf;
 }
@@ -85,25 +84,29 @@ float direct_diffuse_unit_disc(vec3 N, vec3 L)
 /* ----------- GGx ------------ */
 vec3 direct_ggx_point(ShadingData sd, float roughness, vec3 f0)
 {
-	float bsdf = bsdf_ggx(sd.N, sd.L, sd.V, roughness);
-	bsdf /= sd.l_distance * sd.l_distance;
+	float dist = length(sd.l_vector);
+	vec3 L = sd.l_vector / dist;
+	float bsdf = bsdf_ggx(sd.N, L, sd.V, roughness);
+	bsdf /= dist * dist;
 
 	/* Fresnel */
-	float VH = max(dot(sd.V, normalize(sd.V + sd.L)), 0.0);
+	float VH = max(dot(sd.V, normalize(sd.V + L)), 0.0);
 	return F_schlick(f0, VH) * bsdf;
 }
 
 vec3 direct_ggx_sphere(LightData ld, ShadingData sd, float roughness, vec3 f0)
 {
-#ifdef USE_LTC
-	float NV = max(dot(sd.N, sd.V), 1e-8);
-	vec3 P = line_aligned_plane_intersect(vec3(0.0), sd.spec_dominant_dir, sd.l_vector);
+	vec3 L = normalize(sd.l_vector);
+	vec3 spec_dir = get_specular_dominant_dir(sd.N, reflect(-sd.V, sd.N), roughness);
+	vec3 P = line_aligned_plane_intersect(vec3(0.0), spec_dir, sd.l_vector);
 
 	vec3 Px = normalize(P - sd.l_vector) * ld.l_radius;
-	vec3 Py = cross(Px, sd.L);
+	vec3 Py = cross(Px, L);
 
-	vec2 uv = lut_coords(NV, sqrt(roughness));
-	mat3 ltcmat = ltc_matrix(uv);
+	vec2 uv = lut_coords(dot(sd.N, sd.V), sqrt(roughness));
+	vec3 brdf_lut = texture(brdfLut, uv).rgb;
+	vec4 ltc_lut = texture(ltcMat, uv).rgba;
+	mat3 ltc_mat = ltc_matrix(ltc_lut);
 
 // #define HIGHEST_QUALITY
 #ifdef HIGHEST_QUALITY
@@ -120,64 +123,44 @@ vec3 direct_ggx_sphere(LightData ld, ShadingData sd, float roughness, vec3 f0)
 	points[5] = sd.l_vector + Pxy2;
 	points[6] = sd.l_vector + Py;
 	points[7] = sd.l_vector + Pxy1;
-	float bsdf = ltc_evaluate_circle(sd.N, sd.V, ltcmat, points);
+	float bsdf = ltc_evaluate_circle(sd.N, sd.V, ltc_mat, points);
 #else
 	vec3 points[4];
 	points[0] = sd.l_vector + Px;
 	points[1] = sd.l_vector - Py;
 	points[2] = sd.l_vector - Px;
 	points[3] = sd.l_vector + Py;
-	float bsdf = ltc_evaluate(sd.N, sd.V, ltcmat, points);
+	float bsdf = ltc_evaluate(sd.N, sd.V, ltc_mat, points);
 	/* sqrt(pi/2) difference between square and disk area */
 	bsdf *= 1.25331413731;
 #endif
-	vec3 lut = texture(brdfLut, uv).rgb;
-	bsdf *= lut.b; /* Bsdf intensity */
-	bsdf *= M_1_2PI * M_1_PI;
 
-	vec3 spec = F_area(f0, lut.xy) * bsdf;
-#else
-	float energy_conservation;
-	vec3 L = mrp_sphere(ld, sd, sd.spec_dominant_dir, roughness, energy_conservation);
-	float bsdf = bsdf_ggx(sd.N, L, sd.V, roughness);
+	bsdf *= brdf_lut.b; /* Bsdf intensity */
+	bsdf *= M_1_2PI * M_1_PI;
 
-	bsdf *= energy_conservation / (sd.l_distance * sd.l_distance);
-	bsdf *= max(ld.l_radius * ld.l_radius, 1e-16); /* radius is already inside energy_conservation */
+	vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
 
-	/* Fresnel */
-	float VH = max(dot(sd.V, normalize(sd.V + sd.L)), 0.0);
-	vec3 spec = F_schlick(f0, VH) * bsdf;
-#endif
 	return spec;
 }
 
 vec3 direct_ggx_rectangle(LightData ld, ShadingData sd, float roughness, vec3 f0)
 {
-#ifdef USE_LTC
-	float NV = max(dot(sd.N, sd.V), 1e-8);
-	vec2 uv = lut_coords(NV, sqrt(roughness));
-	mat3 ltcmat = ltc_matrix(uv);
-
-	float bsdf = ltc_evaluate(sd.N, sd.V, ltcmat, sd.area_data.corner);
-	vec3 lut = texture(brdfLut, uv).rgb;
-	bsdf *= lut.b; /* Bsdf intensity */
+	vec3 corners[4];
+	corners[0] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up *  ld.l_sizey;
+	corners[1] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
+	corners[2] = sd.l_vector + ld.l_right *  ld.l_sizex + ld.l_up * -ld.l_sizey;
+	corners[3] = sd.l_vector + ld.l_right *  ld.l_sizex + ld.l_up *  ld.l_sizey;
+
+	vec2 uv = lut_coords(dot(sd.N, sd.V), sqrt(roughness));
+	vec3 brdf_lut = texture(brdfLut, uv).rgb;
+	vec4 ltc_lut = texture(ltcMat, uv).rgba;
+	mat3 ltc_mat = ltc_matrix(ltc_lut);
+	float bsdf = ltc_evaluate(sd.N, sd.V, ltc_mat, corners);
+	bsdf *= brdf_lut.b; /* Bsdf intensity */
 	bsdf *= M_1_2PI;
 
-	vec3 spec = F_area(f0, lut.xy) * bsdf;
-#else
-	float energy_conservation;
-	vec3 L = mrp_area(ld, sd, sd.spec_dominant_dir, roug

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list