summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-06-22 13:25:50 -0500
committerDave Parks <davep@lindenlab.com>2022-06-22 13:25:50 -0500
commitd0d1b832d4983f35ab29947eb6fda54a8aa48f8a (patch)
treea07f61179a59d315d842dc08aa9d7fd52dc35e79 /indra/newview/app_settings/shaders
parent4273b262072553aaa1a805ff08008de95da47aac (diff)
SL-17600 Proper irradiance probes.
Diffstat (limited to 'indra/newview/app_settings/shaders')
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl99
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl120
4 files changed, 238 insertions, 24 deletions
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
new file mode 100644
index 0000000000..2028509775
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
@@ -0,0 +1,99 @@
+/**
+ * @file irradianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+VARYING vec3 vary_dir;
+
+// =============================================================================================================
+// Parts of this file are (c) 2018 Sascha Willems
+// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/irradiancecube.frag
+/*
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+// =============================================================================================================
+
+
+
+#define PI 3.1415926535897932384626433832795
+
+float deltaPhi = PI/16.0;
+float deltaTheta = deltaPhi*0.25;
+
+void main()
+{
+ vec3 N = normalize(vary_dir);
+ vec3 up = vec3(0.0, 1.0, 0.0);
+ vec3 right = normalize(cross(up, N));
+ up = cross(N, right);
+
+ const float TWO_PI = PI * 2.0;
+ const float HALF_PI = PI * 0.5;
+
+ vec3 color = vec3(0.0);
+ uint sampleCount = 0u;
+ for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) {
+ for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) {
+ vec3 tempVec = cos(phi) * right + sin(phi) * up;
+ vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
+ color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), 3).rgb * cos(theta) * sin(theta);
+ sampleCount++;
+ }
+ }
+ frag_color = vec4(PI * color / float(sampleCount), 1.0);
+}
+// =============================================================================================================
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
new file mode 100644
index 0000000000..5190abf17c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file irradianceGenV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 vary_dir;
+
+void main()
+{
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
index 27008b8a1c..3fc227eae7 100644
--- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -26,8 +26,6 @@
/*[EXTRA_CODE_HERE]*/
-#define REFMAP_COUNT 256
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -35,6 +33,7 @@ out vec4 frag_color;
#endif
uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
VARYING vec3 vary_dir;
@@ -150,7 +149,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
// Biased (+1.0) mip level for better result
float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
- color += textureLod(reflectionProbes, vec4(L,REFMAP_COUNT), mipLevel).rgb * dotNL;
+ color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL;
totalWeight += dotNL;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 40378b49ea..83348077d7 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -31,6 +31,7 @@
#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
uniform samplerCubeArray reflectionProbes;
+uniform samplerCubeArray irradianceProbes;
layout (std140, binding = 1) uniform ReflectionProbes
{
@@ -308,7 +309,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i)
-// Tap a sphere based reflection probe
+// Tap a reflection probe
// pos - position of pixel
// dir - pixel normal
// lod - which mip to bias towards (lower is higher res, sharper reflections)
@@ -334,10 +335,36 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
v -= c;
v = env_mat * v;
{
- //float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res
- //return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb;
return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod).rgb;
- //return texture(reflectionProbes, vec4(v.xyz, refIndex[i].x)).rgb;
+ }
+}
+
+// Tap an irradiance map
+// pos - position of pixel
+// dir - pixel normal
+// c - center of probe
+// r2 - radius of probe squared
+// i - index of probe
+// vi - point at which reflection vector struck the influence volume, in clip space
+vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i)
+{
+ //lod = max(lod, 1);
+ // parallax adjustment
+
+ vec3 v;
+ if (refIndex[i].w < 0)
+ {
+ v = boxIntersect(pos, dir, i);
+ }
+ else
+ {
+ v = sphereIntersect(pos, dir, c, r2);
+ }
+
+ v -= c;
+ v = env_mat * v;
+ {
+ return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x;
}
}
@@ -371,7 +398,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);
w *= atten;
//w *= p; // boost weight based on priority
- col += refcol*w*max(minweight, refParams[i].x);
+ col += refcol*w;
wsum += w;
}
@@ -394,7 +421,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
float w = 1.0/d2;
w *= w;
- col += refcol*w*max(minweight, refParams[i].x);
+ col += refcol*w;
wsum += w;
}
}
@@ -408,24 +435,75 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
return col;
}
-vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod)
+vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
{
- vec3 col = sampleProbes(pos, dir, lod, 0.f);
+ // modified copy/paste of sampleProbes follows, will likely diverge from sampleProbes further
+ // as irradiance map mixing is tuned independently of radiance map mixing
+ float wsum = 0.0;
+ vec3 col = vec3(0,0,0);
+ float vd2 = dot(pos,pos); // view distance squared
- //desaturate
- vec3 hcol = col *0.5;
-
- col *= 2.0;
- col = vec3(
- col.r + hcol.g + hcol.b,
- col.g + hcol.r + hcol.b,
- col.b + hcol.r + hcol.g
- );
-
- col *= 0.333333;
+ float minweight = 1.0;
- return col;
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ if (abs(refIndex[i].w) < max_priority)
+ {
+ continue;
+ }
+ float r = refSphere[i].w; // radius of sphere volume
+ float p = float(abs(refIndex[i].w)); // priority
+
+ float rr = r*r; // radius squred
+ float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz-refSphere[i].xyz;
+ float d2 = dot(delta,delta);
+ float r2 = r1*r1;
+
+ {
+ vec3 refcol = tapIrradianceMap(pos, dir, refSphere[i].xyz, rr, i);
+
+ float w = 1.0/d2;
+
+ float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);
+ w *= atten;
+ //w *= p; // boost weight based on priority
+ col += refcol*w;
+
+ wsum += w;
+ }
+ }
+ if (probeInfluences <= 1)
+ { //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera
+ for (int idx = 0; idx < 8; ++idx)
+ {
+ if (refIndex[idx].w < 0)
+ { // don't fallback to box probes, they are *very* specific
+ continue;
+ }
+ int i = idx;
+ vec3 delta = pos.xyz-refSphere[i].xyz;
+ float d2 = dot(delta,delta);
+
+ {
+ vec3 refcol = tapIrradianceMap(pos, dir, refSphere[i].xyz, d2, i);
+
+ float w = 1.0/d2;
+ w *= w;
+ col += refcol*w;
+ wsum += w;
+ }
+ }
+ }
+
+ if (wsum > 0.0)
+ {
+ col *= 1.0/wsum;
+ }
+
+ return col;
}
// brighten a color so that at least one component is 1
@@ -451,7 +529,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- ambenv = sampleProbeAmbient(pos, norm, reflection_lods-2);
+ ambenv = sampleProbeAmbient(pos, norm);
if (glossiness > 0.0)
{