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:
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c6
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl10
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl74
-rw-r--r--source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl48
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/ssr_lib.glsl11
8 files changed, 104 insertions, 60 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 0ce94b8f1b1..3e1d4a8aaa6 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -245,7 +245,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1);
DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1);
- DRW_shgroup_uniform_float(grp, "roughnessSquared", &pinfo->roughness, 1);
+ DRW_shgroup_uniform_float(grp, "roughness", &pinfo->roughness, 1);
DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1);
DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1);
DRW_shgroup_uniform_float(grp, "texelSize", &pinfo->texel_size, 1);
@@ -1045,8 +1045,8 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata,
/* Disney Roughness */
pinfo->roughness = square_f(pinfo->roughness);
/* Distribute Roughness across lod more evenly */
- pinfo->roughness = square_f(square_f(pinfo->roughness));
- CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */
+ pinfo->roughness = square_f(pinfo->roughness);
+ CLAMP(pinfo->roughness, 1e-4f, 0.9999f); /* Avoid artifacts */
#if 1 /* Variable Sample count and bias (fast) */
switch (i) {
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 5f0fde134d1..c8eaa06094e 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -102,7 +102,7 @@ float D_ggx_opti(float NH, float a2)
return M_PI * tmp * tmp; /* Doing RCP and mul a2 at the end */
}
-float G1_Smith_GGX(float NX, float a2)
+float G1_Smith_GGX_opti(float NX, float a2)
{
/* Using Brian Karis approach and refactoring by NX/NX
* this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV
@@ -122,7 +122,7 @@ float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness)
float NL = max(dot(N, L), 1e-8);
float NV = max(dot(N, V), 1e-8);
- float G = G1_Smith_GGX(NV, a2) * G1_Smith_GGX(NL, a2); /* Doing RCP at the end */
+ float G = G1_Smith_GGX_opti(NV, a2) * G1_Smith_GGX_opti(NL, a2); /* Doing RCP at the end */
float D = D_ggx_opti(NH, a2);
/* Denominator is canceled by G1_Smith */
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
index 46ea8b747c8..4c1544654c1 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
@@ -25,7 +25,8 @@ void main()
vec3 Xi = (vec3(i, j, 0.0) + 0.5) / sampleCount;
Xi.yz = vec2(cos(Xi.y * M_2PI), sin(Xi.y * M_2PI));
- vec3 H = sample_ggx(Xi, a2); /* Microfacet normal */
+ /* Microfacet normal */
+ vec3 H = sample_ggx(Xi, a, V);
vec3 L = -reflect(V, H);
float NL = L.z;
@@ -33,9 +34,10 @@ void main()
float NH = max(H.z, 0.0);
float VH = max(dot(V, H), 0.0);
- float G1_v = G1_Smith_GGX(NV, a2);
- float G1_l = G1_Smith_GGX(NL, a2);
- float G_smith = 4.0 * NV * NL / (G1_v * G1_l); /* See G1_Smith_GGX for explanations. */
+ float G1_v = G1_Smith_GGX_opti(NV, a2);
+ float G1_l = G1_Smith_GGX_opti(NL, a2);
+ /* See G1_Smith_GGX_opti for explanations. */
+ float G_smith = 4.0 * NV * NL / (G1_v * G1_l);
float brdf = (G_smith * VH) / (NH * NV);
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
index bbc79a2d05b..004d884dc75 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
@@ -1,4 +1,5 @@
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
uniform sampler1D texHammersley;
@@ -8,6 +9,11 @@ vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
return T * vector.x + B * vector.y + N * vector.z;
}
+vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return vec3(dot(T, vector), dot(B, vector), dot(N, vector));
+}
+
#ifdef HAMMERSLEY_SIZE
vec3 hammersley_3d(float i, float invsamplenbr)
{
@@ -22,9 +28,18 @@ vec3 hammersley_3d(float i, float invsamplenbr)
/* -------------- BSDFS -------------- */
-float pdf_ggx_reflect(float NH, float a2)
+#define USE_VISIBLE_NORMAL 1
+
+float pdf_ggx_reflect(float NH, float NV, float VH, float alpha)
{
+ float a2 = sqr(alpha);
+#if USE_VISIBLE_NORMAL
+ float D = a2 / D_ggx_opti(NH, a2);
+ float G1 = NV * 2.0 / G1_Smith_GGX_opti(NV, a2);
+ return G1 * VH * D / NV;
+#else
return NH * a2 / D_ggx_opti(NH, a2);
+#endif
}
float pdf_hemisphere()
@@ -32,22 +47,50 @@ float pdf_hemisphere()
return 0.5 * M_1_PI;
}
-vec3 sample_ggx(vec3 rand, float a2)
+vec3 sample_ggx(vec3 rand, float alpha, vec3 Vt)
{
+#if USE_VISIBLE_NORMAL
+ /* From:
+ * "A Simpler and Exact Sampling Routine for the GGXDistribution of Visible Normals"
+ * by Eric Heitz.
+ * http://jcgt.org/published/0007/04/01/slides.pdf
+ * View vector is expected to be in tangent space. */
+
+ /* Stretch view. */
+ vec3 Th, Bh, Vh = normalize(vec3(alpha * Vt.xy, Vt.z));
+ make_orthonormal_basis(Vh, Th, Bh);
+ /* Sample point with polar coordinates (r, phi). */
+ float r = sqrt(rand.x);
+ float x = r * rand.y;
+ float y = r * rand.z;
+ float s = 0.5 * (1.0 + Vh.z);
+ y = (1.0 - s) * sqrt(1.0 - x * x) + s * y;
+ float z = sqrt(saturate(1.0 - x * x - y * y));
+ /* Compute normal. */
+ vec3 Hh = x * Th + y * Bh + z * Vh;
+ /* Unstretch. */
+ vec3 Ht = normalize(vec3(alpha * Hh.xy, saturate(Hh.z)));
+ /* Microfacet Normal. */
+ return Ht;
+#else
/* Theta is the cone angle. */
- float z = sqrt((1.0 - rand.x) / (1.0 + a2 * rand.x - rand.x)); /* cos theta */
- float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */
+ float z = sqrt((1.0 - rand.x) / (1.0 + sqr(alpha) * rand.x - rand.x)); /* cos theta */
+ float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */
float x = r * rand.y;
float y = r * rand.z;
-
/* Microfacet Normal */
return vec3(x, y, z);
+#endif
}
-vec3 sample_ggx(vec3 rand, float a2, vec3 N, vec3 T, vec3 B, out float NH)
+vec3 sample_ggx(vec3 rand, float alpha, vec3 V, vec3 N, vec3 T, vec3 B, out float pdf)
{
- vec3 Ht = sample_ggx(rand, a2);
- NH = Ht.z;
+ vec3 Vt = world_to_tangent(V, N, T, B);
+ vec3 Ht = sample_ggx(rand, alpha, Vt);
+ float NH = saturate(Ht.z);
+ float NV = saturate(Vt.z);
+ float VH = saturate(dot(Vt, Ht));
+ pdf = pdf_ggx_reflect(NH, NV, VH, alpha);
return tangent_to_world(Ht, N, T, B);
}
@@ -69,18 +112,23 @@ vec3 sample_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B)
}
#ifdef HAMMERSLEY_SIZE
-vec3 sample_ggx(float nsample, float inv_sample_count, float a2, vec3 N, vec3 T, vec3 B)
+vec3 sample_ggx(float nsample,
+ float inv_sample_count,
+ float alpha,
+ vec3 V,
+ vec3 N,
+ vec3 T,
+ vec3 B,
+ out float pdf)
{
vec3 Xi = hammersley_3d(nsample, inv_sample_count);
- vec3 Ht = sample_ggx(Xi, a2);
- return tangent_to_world(Ht, N, T, B);
+ return sample_ggx(Xi, alpha, V, N, T, B, pdf);
}
vec3 sample_hemisphere(float nsample, float inv_sample_count, vec3 N, vec3 T, vec3 B)
{
vec3 Xi = hammersley_3d(nsample, inv_sample_count);
- vec3 Ht = sample_hemisphere(Xi);
- return tangent_to_world(Ht, N, T, B);
+ return sample_hemisphere(Xi, N, T, B);
}
vec3 sample_cone(float nsample, float inv_sample_count, float angle, vec3 N, vec3 T, vec3 B)
diff --git a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
index 2ffe23a9197..2f1298e2707 100644
--- a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
@@ -37,7 +37,7 @@ void main()
Xi.yz = vec2(cos(Xi.y * M_2PI), sin(Xi.y * M_2PI));
/* Microfacet normal. */
- vec3 H = sample_ggx(Xi, a2);
+ vec3 H = sample_ggx(Xi, a2, V);
float VH = dot(V, H);
@@ -59,7 +59,7 @@ void main()
float LH = dot(L, H);
/* Balancing the adjustments made in G1_Smith. */
- float G1_l = NL * 2.0 / G1_Smith_GGX(NL, a2);
+ float G1_l = NL * 2.0 / G1_Smith_GGX_opti(NL, a2);
/* btdf = abs(VH*LH) * (ior*ior) * D * G(V) * G(L) / (Ht2 * NV)
* pdf = (VH * abs(LH)) * (ior*ior) * D * G(V) / (Ht2 * NV) */
diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
index a9139b7a146..11aa85f2f2d 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -64,27 +64,22 @@ uniform sampler2D specroughBuffer;
layout(location = 0) out vec4 hitData;
-void do_planar_ssr(
- int index, vec3 V, vec3 N, vec3 T, vec3 B, vec3 viewPlaneNormal, vec3 vP, float a2, vec4 rand)
+void do_planar_ssr(int index,
+ vec3 V,
+ vec3 N,
+ vec3 T,
+ vec3 B,
+ vec3 viewPlaneNormal,
+ vec3 vP,
+ float alpha,
+ vec4 rand)
{
- float NH;
+ float pdf;
/* Microfacet normal */
- vec3 H = sample_ggx(rand.xzw, a2, N, T, B, NH);
- float pdf = pdf_ggx_reflect(NH, a2);
-
+ vec3 H = sample_ggx(rand.xzw, alpha, V, N, T, B, pdf);
vec3 R = reflect(-V, H);
R = reflect(R, viewPlaneNormal);
- /* If ray is bad (i.e. going below the plane) regenerate. */
- if (dot(R, viewPlaneNormal) > 0.0) {
- /* Microfacet normal */
- vec3 H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH);
- pdf = pdf_ggx_reflect(NH, a2);
-
- R = reflect(-V, H);
- R = reflect(R, viewPlaneNormal);
- }
-
Ray ray;
ray.origin = vP;
ray.direction = R * 1e16;
@@ -92,7 +87,7 @@ void do_planar_ssr(
RayTraceParameters params;
params.jitter = rand.y;
params.trace_quality = ssrQuality;
- params.roughness = a2;
+ params.roughness = alpha * alpha;
HitData data;
data.is_planar = true;
@@ -104,26 +99,26 @@ void do_planar_ssr(
hitData = encode_hit_data(data);
}
-void do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 vP, float a2, vec4 rand)
+void do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 vP, float alpha, vec4 rand)
{
- float NH;
+ float pdf;
/* Microfacet normal */
- vec3 H = sample_ggx(rand.xzw, a2, N, T, B, NH);
+ vec3 H = sample_ggx(rand.xzw, alpha, V, N, T, B, pdf);
vec3 R = reflect(-V, H);
Ray ray;
- ray.origin = vP;
+ ray.origin = vP + N * 1e-4;
ray.direction = R * 1e16;
RayTraceParameters params;
params.thickness = ssrThickness;
params.jitter = rand.y;
params.trace_quality = ssrQuality;
- params.roughness = a2;
+ params.roughness = alpha * alpha;
HitData data;
data.is_planar = true;
- data.ray_pdf_inv = safe_rcp(pdf_ggx_reflect(NH, a2));
+ data.ray_pdf_inv = safe_rcp(pdf);
data.is_hit = raytrace(ray, params, true, data.hit_dir);
data.hit_dir = get_view_space_from_depth(data.hit_dir.xy, data.hit_dir.z);
data.hit_dir -= ray.origin;
@@ -170,8 +165,7 @@ void main()
}
float roughness = speccol_roughness.a;
- float roughnessSquared = max(1e-3, roughness * roughness);
- float a2 = roughnessSquared * roughnessSquared;
+ float alpha = max(1e-3, roughness * roughness);
/* Early out */
if (roughness > ssrMaxRoughness + 0.2) {
@@ -204,12 +198,12 @@ void main()
tracePosition = transform_point(ViewMatrix, tracePosition);
vec3 viewPlaneNormal = transform_direction(ViewMatrix, pd.pl_normal);
- do_planar_ssr(i, vV, vN, vT, vB, viewPlaneNormal, tracePosition, a2, rand);
+ do_planar_ssr(i, vV, vN, vT, vB, viewPlaneNormal, tracePosition, alpha, rand);
return;
}
}
- do_ssr(vV, vN, vT, vB, vP, a2, rand);
+ do_ssr(vV, vN, vT, vB, vP, alpha, rand);
}
#else /* STEP_RESOLVE */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
index 35fdbcb715f..99cbf2839ad 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
@@ -3,7 +3,7 @@
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
uniform samplerCube probeHdr;
-uniform float roughnessSquared;
+uniform float roughness;
uniform float texelSize;
uniform float lodFactor;
uniform float lodMax;
@@ -52,7 +52,9 @@ void main()
float weight = 0.0;
vec3 out_radiance = vec3(0.0);
for (float i = 0; i < sampleCount; i++) {
- vec3 H = sample_ggx(i, invSampleCount, roughnessSquared, N, T, B); /* Microfacet normal */
+ float pdf;
+ /* Microfacet normal */
+ vec3 H = sample_ggx(i, invSampleCount, roughness, V, N, T, B, pdf);
vec3 L = -reflect(V, H);
float NL = dot(N, L);
@@ -62,7 +64,6 @@ void main()
/* Coarse Approximation of the mapping distortion
* Unit Sphere -> Cubemap Face */
const float dist = 4.0 * M_PI / 6.0;
- float pdf = pdf_ggx_reflect(NH, roughnessSquared);
/* http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html : Equation 13 */
float lod = clamp(lodFactor - 0.5 * log2(pdf * dist), 0.0, lodMax);
diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
index 37624fc31ea..612e95832e4 100644
--- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
@@ -15,21 +15,20 @@ uniform float refractionDepth;
vec4 screen_space_refraction(vec3 vP, vec3 N, vec3 V, float ior, float roughnessSquared, vec4 rand)
{
- float a2 = max(5e-6, roughnessSquared * roughnessSquared);
+ float alpha = max(0.002, roughnessSquared);
/* Importance sampling bias */
rand.x = mix(rand.x, 0.0, BTDF_BIAS);
vec3 T, B;
- float NH;
make_orthonormal_basis(N, T, B);
- vec3 H = sample_ggx(rand.xzw, a2, N, T, B, NH); /* Microfacet normal */
- float pdf = pdf_ggx_reflect(NH, a2);
+ float pdf;
+ /* Microfacet normal */
+ vec3 H = sample_ggx(rand.xzw, alpha, V, N, T, B, pdf);
/* If ray is bad (i.e. going below the plane) regenerate. */
if (F_eta(ior, dot(H, V)) < 1.0) {
- H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH); /* Microfacet normal */
- pdf = pdf_ggx_reflect(NH, a2);
+ H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), alpha, V, N, T, B, pdf);
}
vec3 vV = viewCameraVec(vP);