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:
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl111
1 files changed, 47 insertions, 64 deletions
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, roughness, energy_conservation);
- float bsdf = bsdf_ggx(sd.N, L, sd.V, roughness);
+ vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
- bsdf *= energy_conservation;
- /* fade mrp artifacts */
- bsdf *= max(0.0, dot(-sd.spec_dominant_dir, ld.l_forward));
- bsdf *= max(0.0, -dot(L, ld.l_forward));
-
- /* Fresnel */
- float VH = max(dot(sd.V, normalize(sd.V + sd.L)), 0.0);
- vec3 spec = F_schlick(f0, VH) * bsdf;
-#endif
return spec;
}