summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class3
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings/shaders/class3')
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl184
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl241
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl46
5 files changed, 323 insertions, 208 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index 8d2a65d4a9..add1cb2a37 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -92,7 +92,7 @@ uniform vec3 light_diffuse[8];
float getAmbientClamp();
void waterClip(vec3 pos);
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
{
// SL-14895 inverted attenuation work-around
// This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
@@ -170,6 +170,11 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
speccol = clamp(speccol, vec3(0), vec3(1));
col += speccol;
+
+ float cur_glare = max(speccol.r, speccol.g);
+ cur_glare = max(cur_glare, speccol.b);
+ glare = max(glare, speccol.r);
+ glare += max(cur_glare, 0.0);
}
}
}
@@ -218,83 +223,105 @@ VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
-void main()
+// get the transformed normal and apply glossiness component from normal map
+vec3 getNormal(inout float glossiness)
{
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- waterClip(vary_position.xyz);
-#endif
+#ifdef HAS_NORMAL_MAP
+ vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+ glossiness *= norm.a;
- vec2 pos_screen = vary_texcoord0.xy;
+ norm.xyz = norm.xyz * 2 - 1;
- vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
- diffcol.rgb *= vertex_color.rgb;
+ return normalize(vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2)));
+#else
+ return normalize(vary_normal);
+#endif
+}
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+vec4 getSpecular()
+{
+#ifdef HAS_SPECULAR_MAP
+ vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
+ spec.rgb *= specular_color.rgb;
+#else
+ vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+ return spec;
+}
+void alphaMask(float alpha)
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
// Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
float bias = 0.001953125; // 1/512, or half an 8-bit quantization
- if (diffcol.a < minimum_alpha-bias)
+ if (alpha < minimum_alpha-bias)
{
discard;
}
#endif
+}
-#ifdef HAS_SPECULAR_MAP
- vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
- spec.rgb *= specular_color.rgb;
-#else
- vec4 spec = vec4(specular_color.rgb, 1.0);
+void waterClip()
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ waterClip(vary_position.xyz);
#endif
+}
-#ifdef HAS_NORMAL_MAP
- vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
- norm.xyz = norm.xyz * 2 - 1;
+float getEmissive(vec4 diffcol)
+{
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+ return emissive_brightness;
+#else
+ return max(diffcol.a, emissive_brightness);
+#endif
+}
- vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
- dot(norm.xyz,vary_mat1),
- dot(norm.xyz,vary_mat2));
+float getShadow(vec3 pos, vec3 norm)
+{
+#ifdef HAS_SUN_SHADOW
+ #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ return sampleDirectionalShadow(pos, norm, vary_texcoord0.xy);
+ #else
+ return 1;
+ #endif
#else
- vec4 norm = vec4(0,0,0,1.0);
- vec3 tnorm = vary_normal;
+ return 1;
#endif
+}
- norm.xyz = normalize(tnorm.xyz);
+void main()
+{
+ waterClip();
- vec2 abnormal = encode_normal(norm.xyz);
+ // diffcol == diffuse map combined with vertex color
+ vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+ diffcol.rgb *= vertex_color.rgb;
- vec4 final_color = diffcol;
+ alphaMask(diffcol.a);
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
- final_color.a = emissive_brightness;
-#else
- final_color.a = max(final_color.a, emissive_brightness);
-#endif
+ // spec == specular map combined with specular color
+ vec4 spec = getSpecular();
+ float env = env_intensity * spec.a;
+ float glossiness = specular_color.a;
+ vec3 norm = getNormal(glossiness);
- vec4 final_specular = spec;
-
-#ifdef HAS_SPECULAR_MAP
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, GBUFFER_FLAG_HAS_ATMOS);
- final_specular.a = specular_color.a * norm.a;
-#else
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, GBUFFER_FLAG_HAS_ATMOS);
- final_specular.a = specular_color.a;
-#endif
+ vec2 abnormal = encode_normal(norm.xyz);
+
+ float emissive = getEmissive(diffcol);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
//forward rendering, output lit linear color
diffcol.rgb = srgb_to_linear(diffcol.rgb);
- final_specular.rgb = srgb_to_linear(final_specular.rgb);
+ spec.rgb = srgb_to_linear(spec.rgb);
vec3 pos = vary_position;
- float shadow = 1.0f;
+ float shadow = getShadow(pos, norm);
-#ifdef HAS_SUN_SHADOW
- shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
-#endif
-
- vec4 diffuse = final_color;
+ vec4 diffuse = diffcol;
vec3 color = vec3(0,0,0);
@@ -307,54 +334,63 @@ void main()
vec3 atten;
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+ vec3 amblit_linear = amblit;
+
vec3 ambenv;
vec3 glossenv;
vec3 legacyenv;
- sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos_screen, pos.xyz, norm.xyz, final_specular.a, env_intensity);
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env);
// use sky settings ambient or irradiance map sample, whichever is brighter
- color = max(amblit, ambenv);
+ color = max(amblit_linear, ambenv);
float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
- vec3 sun_contrib = min(da, shadow) * sunlit;
+ vec3 sun_contrib = min(da, shadow) * sunlit_linear;
color.rgb += sun_contrib;
color *= diffcol.rgb;
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- if (final_specular.a > 0.0) // specular reflection
+ float glare = 0.0;
+
+ if (glossiness > 0.0) // specular reflection
{
float sa = dot(normalize(refnormpersp), light_dir.xyz);
- vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, final_specular.a)).r);
+ vec3 dumbshiny = sunlit_linear * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r);
// add the two types of shiny together
- vec3 spec_contrib = dumbshiny * final_specular.rgb;
+ vec3 spec_contrib = dumbshiny * spec.rgb;
bloom = dot(spec_contrib, spec_contrib) / 6;
+ glare = max(spec_contrib.r, spec_contrib.g);
+ glare = max(glare, spec_contrib.b);
+
color += spec_contrib;
- applyGlossEnv(color, glossenv, final_specular, pos.xyz, norm.xyz);
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
}
- color = mix(color.rgb, diffcol.rgb, diffuse.a);
+ color = mix(color.rgb, diffcol.rgb, emissive);
- if (env_intensity > 0.0)
+ if (env > 0.0)
{ // add environmentmap
- applyLegacyEnv(color, legacyenv, final_specular, pos.xyz, norm.xyz, env_intensity);
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, env);
+
+ float cur_glare = max(max(legacyenv.r, legacyenv.g), legacyenv.b);
+ cur_glare *= env*4.0;
+ glare += cur_glare;
}
- color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), diffuse.a);
+ color.rgb = linear_to_srgb(color.rgb);
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
color.rgb = scaleSoftClipFragLinear(color.rgb);
-
-#ifdef WATER_FOG
- vec4 temp = applyWaterFogView(pos, vec4(color, 0.0));
- color = temp.rgb;
-#endif
+ color.rgb = srgb_to_linear(color.rgb);
vec3 npos = normalize(-pos.xyz);
vec3 light = vec3(0, 0, 0);
-#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w );
+#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, spec, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
LIGHT_LOOP(1)
LIGHT_LOOP(2)
@@ -364,17 +400,25 @@ void main()
LIGHT_LOOP(6)
LIGHT_LOOP(7)
+ light *= 1.0-emissive;
color += light;
- float al = diffcol.a*vertex_color.a;
+ glare *= 1.0-emissive;
+ glare = min(glare, 1.0);
+ float al = max(diffcol.a, glare) * vertex_color.a;
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogView(pos, vec4(color, 0.0));
+ color = temp.rgb;
+#endif
frag_color = vec4(color, al);
-#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
- frag_data[0] = final_color; // gbuffer is sRGB for legacy materials
- frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
+ frag_data[0] = vec4(diffcol.rgb, emissive); // gbuffer is sRGB for legacy materials
+ frag_data[1] = vec4(spec.rgb, glossiness); // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = vec4(encode_normal(norm), env, GBUFFER_FLAG_HAS_ATMOS);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
#endif
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index d9cbae45a6..8229ecbbb7 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -37,7 +37,6 @@ uniform sampler2D diffuseRect;
uniform sampler2D specularRect;
uniform sampler2D normalMap;
uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
-uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
uniform sampler2D depthMap;
@@ -126,8 +125,7 @@ void main()
diffuse = srgb_to_linear(diffuse);
spec.rgb = srgb_to_linear(spec.rgb);
- float noise = texture2D(noiseMap, tc).b;
- float lit = nl * dist_atten * noise;
+ float lit = nl * dist_atten;
final_color = color.rgb*lit*diffuse;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 8b1d41776f..a6a2543915 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -80,7 +80,7 @@ bool isAbove(vec3 pos, vec4 plane)
return (dot(plane.xyz, pos) + plane.w) > 0;
}
-int max_priority = 0;
+bool sample_automatic = true;
// return true if probe at index i influences position pos
bool shouldSampleProbe(int i, vec3 pos)
@@ -95,24 +95,24 @@ bool shouldSampleProbe(int i, vec3 pos)
return false;
}
- max_priority = max(max_priority, -refIndex[i].w);
+ sample_automatic = false;
}
else
{
- if (refSphere[i].w > 0.0) // zero is special indicator to always sample this probe
+ if (refIndex[i].w == 0 && !sample_automatic)
{
- vec3 delta = pos.xyz - refSphere[i].xyz;
- float d = dot(delta, delta);
- float r2 = refSphere[i].w;
- r2 *= r2;
-
- if (d > r2)
- { //outside bounding sphere
- return false;
- }
+ return false;
}
- max_priority = max(max_priority, refIndex[i].w);
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d = dot(delta, delta);
+ float r2 = refSphere[i].w;
+ r2 *= r2;
+
+ if (d > r2)
+ { // outside bounding sphere
+ return false;
+ }
}
return true;
@@ -120,7 +120,6 @@ bool shouldSampleProbe(int i, vec3 pos)
// call before sampleRef
// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT
-// overall algorithm --
void preProbeSample(vec3 pos)
{
// TODO: make some sort of structure that reduces the number of distance checks
@@ -210,7 +209,7 @@ void preProbeSample(vec3 pos)
}
}
- if (max_priority <= 1)
+ if (sample_automatic)
{ // probe at index 0 is a special probe for smoothing out automatic probes
probeIndex[probeInfluences++] = 0;
}
@@ -342,7 +341,7 @@ return texCUBE(envMap, ReflDirectionWS);
// d - distance to nearest wall in clip space
vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
{
- // Intersection with OBB convertto unit box space
+ // Intersection with OBB convert to unit box space
// Transform in local unit parallax cube space (scaled and rotated)
mat4 clipToLocal = refBox[i];
@@ -431,18 +430,24 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
// origin - center of sphere probe
// r - radius of probe influence volume
// min_da - minimum angular attenuation coefficient
-float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da)
+// i - index of probe in refSphere
+// dw - distance weight
+float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da, int i, out float dw)
{
float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
vec3 delta = pos.xyz - origin;
float d2 = max(length(delta), 0.001);
+
float r2 = r1; //r1 * r1;
//float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);
float atten = 1.0 - max(d2 - r2, 0.0) / max((r - r2), 0.001);
+ float w = 1.0 / d2;
+
+ dw = w * atten * max(r, 1.0)*4;
atten *= max(dot(normalize(-delta), dir), min_da);
- float w = 1.0 / d2;
+
w *= atten;
return w;
@@ -451,48 +456,43 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da)
// Tap a reflection probe
// pos - position of pixel
// dir - pixel normal
-// vi - return value of intersection point with influence volume
-// wi - return value of approximate world space position of sampled pixel
-// lod - which mip to bias towards (lower is higher res, sharper reflections)
+// w - weight of sample (distance and angular attenuation)
+// dw - weight of sample (distance only)
+// lod - which mip to sample (lower is higher res, sharper reflections)
// c - center of probe
// r2 - radius of probe squared
// i - index of probe
-vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float lod, vec3 c, int i)
+vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i)
{
- //lod = max(lod, 1);
// parallax adjustment
-
vec3 v;
if (refIndex[i].w < 0)
- {
+ { // box probe
float d = 0;
v = boxIntersect(pos, dir, i, d);
w = max(d, 0.001);
}
else
- {
- float r = refSphere[i].w; // radius of sphere volume
- float rr = r * r; // radius squared
+ { // sphere probe
+ float r = refSphere[i].w;
+
+ float rr = r * r;
v = sphereIntersect(pos, dir, c,
- refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
+ refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
rr);
- w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25);
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25, i, dw);
}
- vi = v;
-
v -= c;
vec3 d = normalize(v);
v = env_mat * v;
- vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod);
-
- wi = d * ret.a * 256.0+c;
+ vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y;
return ret.rgb;
}
@@ -500,10 +500,10 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float
// Tap an irradiance map
// pos - position of pixel
// dir - pixel normal
-// c - center of probe
-// r2 - radius of probe squared
+// w - weight of sample (distance and angular attenuation)
+// dw - weight of sample (distance only)
// i - index of probe
-vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
+vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int i)
{
// parallax adjustment
vec3 v;
@@ -516,14 +516,15 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
else
{
float r = refSphere[i].w; // radius of sphere volume
- float p = float(abs(refIndex[i].w)); // priority
- float rr = r * r; // radius squred
+
+ // pad sphere for manual probe extending into automatic probe space
+ float rr = r * r;
v = sphereIntersect(pos, dir, c,
- refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
+ refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
rr);
- w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001);
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001, i, dw);
}
v -= c;
@@ -533,106 +534,129 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
}
}
-vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)
+vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
{
- float wsum = 0.0;
- vec3 col = vec3(0,0,0);
- float vd2 = dot(pos,pos); // view distance squared
+ float wsum[2];
+ wsum[0] = 0;
+ wsum[1] = 0;
+
+ float dwsum[2];
+ dwsum[0] = 0;
+ dwsum[1] = 0;
+
+ vec3 col[2];
+ col[0] = vec3(0);
+ col[1] = vec3(0);
for (int idx = 0; idx < probeInfluences; ++idx)
{
int i = probeIndex[idx];
- if (abs(refIndex[i].w) < max_priority)
+ int p = clamp(abs(refIndex[i].w), 0, 1);
+
+ if (p == 0 && !sample_automatic)
{
continue;
}
- float w;
- vec3 vi, wi;
+ float w = 0;
+ float dw = 0;
vec3 refcol;
{
- if (errorCorrect && refIndex[i].w >= 0)
- { // error correction is on and this probe is a sphere
- //take a sample to get depth value, then error correct
- refcol = tapRefMap(pos, dir, w, vi, wi, abs(lod + 2), refSphere[i].xyz, i);
-
- //adjust lookup by distance result
- float d = length(vi - wi);
- vi += dir * d;
-
- vi -= refSphere[i].xyz;
+ refcol = tapRefMap(pos, dir, w, dw, lod, refSphere[i].xyz, i);
- vi = env_mat * vi;
-
- refcol = textureLod(reflectionProbes, vec4(vi, refIndex[i].x), lod).rgb;
-
- // weight by vector correctness
- vec3 pi = normalize(wi - pos);
- w *= max(dot(pi, dir), 0.1);
- //w = pow(w, 32.0);
- }
- else
- {
- refcol = tapRefMap(pos, dir, w, vi, wi, lod, refSphere[i].xyz, i);
- }
-
- col += refcol.rgb*w;
-
- wsum += w;
+ col[p] += refcol.rgb*w;
+ wsum[p] += w;
+ dwsum[p] += dw;
}
}
- if (wsum > 0.0)
+ // mix automatic and manual probes
+ if (sample_automatic && wsum[0] > 0.0)
+ { // some automatic probes were sampled
+ col[0] *= 1.0/wsum[0];
+ if (wsum[1] > 0.0)
+ { //some manual probes were sampled, mix between the two
+ col[1] *= 1.0/wsum[1];
+ col[1] = mix(col[0], col[1], min(dwsum[1], 1.0));
+ col[0] = vec3(0);
+ }
+ }
+ else if (wsum[1] > 0.0)
{
- col *= 1.0/wsum;
+ // manual probes were sampled but no automatic probes were
+ col[1] *= 1.0/wsum[1];
+ col[0] = vec3(0);
}
- return col;
+ return col[1]+col[0];
}
vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
{
// 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
+ float wsum[2];
+ wsum[0] = 0;
+ wsum[1] = 0;
+
+ float dwsum[2];
+ dwsum[0] = 0;
+ dwsum[1] = 0;
- float minweight = 1.0;
+ vec3 col[2];
+ col[0] = vec3(0);
+ col[1] = vec3(0);
for (int idx = 0; idx < probeInfluences; ++idx)
{
int i = probeIndex[idx];
- if (abs(refIndex[i].w) < max_priority)
+ int p = clamp(abs(refIndex[i].w), 0, 1);
+
+ if (p == 0 && !sample_automatic)
{
continue;
}
{
- float w;
- vec3 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i);
+ float w = 0;
+ float dw = 0;
+
+ vec3 refcol = tapIrradianceMap(pos, dir, w, dw, refSphere[i].xyz, i);
- col += refcol*w;
-
- wsum += w;
+ col[p] += refcol*w;
+ wsum[p] += w;
+ dwsum[p] += dw;
}
}
- if (wsum > 0.0)
+ // mix automatic and manual probes
+ if (sample_automatic && wsum[0] > 0.0)
+ { // some automatic probes were sampled
+ col[0] *= 1.0/wsum[0];
+ if (wsum[1] > 0.0)
+ { //some manual probes were sampled, mix between the two
+ col[1] *= 1.0/wsum[1];
+ col[1] = mix(col[0], col[1], min(dwsum[1], 1.0));
+ col[0] = vec3(0);
+ }
+ }
+ else if (wsum[1] > 0.0)
{
- col *= 1.0/wsum;
+ // manual probes were sampled but no automatic probes were
+ col[1] *= 1.0/wsum[1];
+ col[0] = vec3(0);
}
-
- return col;
+
+ return col[1]+col[0];
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
// TODO - don't hard code lods
- float reflection_lods = max_probe_lod;
+ float reflection_lods = max_probe_lod-1;
preProbeSample(pos);
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
@@ -640,13 +664,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
ambenv = sampleProbeAmbient(pos, norm);
float lod = (1.0-glossiness)*reflection_lods;
- glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
#if defined(SSR)
if (cube_snapshot != 1 && glossiness >= 0.9)
{
vec4 ssr = vec4(0);
- //float w = tapScreenSpaceReflection(errorCorrect ? 1 : 4, tc, pos, norm, ssr, sceneMap);
float w = tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap);
glossenv = mix(glossenv, ssr.rgb, w);
@@ -654,11 +677,20 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
#endif
}
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness);
+
+ // fudge factor to get PBR water at a similar luminance ot legacy water
+ glossenv *= 0.25;
+}
+
void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
{
vec3 origin = vec3(0,0,0);
- bool manual_probe = abs(refIndex[i].w) > 2;
+ bool manual_probe = abs(refIndex[i].w) > 0;
if (manual_probe)
{
@@ -694,18 +726,9 @@ vec4 sampleReflectionProbesDebug(vec3 pos)
return col;
}
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness)
-{
- sampleReflectionProbes(ambenv, glossenv,
- tc, pos, norm, glossiness, false);
-}
-
-
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity)
{
- // TODO - don't hard code lods
float reflection_lods = max_probe_lod;
preProbeSample(pos);
@@ -716,12 +739,12 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
if (glossiness > 0.0)
{
float lod = (1.0-glossiness)*reflection_lods;
- glossenv = sampleProbes(pos, normalize(refnormpersp), lod, false);
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
}
if (envIntensity > 0.0)
{
- legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false);
+ legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
}
#if defined(SSR)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 8d48e6f596..dfd1d47b3e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -85,6 +85,8 @@ float getDepth(vec2 pos_screen);
vec3 linear_to_srgb(vec3 c);
vec3 srgb_to_linear(vec3 c);
+uniform vec4 waterPlane;
+
#ifdef WATER_FOG
vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
#endif
@@ -153,6 +155,24 @@ void main()
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+ vec3 amblit_linear = amblit;
+
+ bool do_atmospherics = false;
+
+#ifndef WATER_FOG
+ // when above water, mask off atmospherics below water
+ if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
+ {
+ do_atmospherics = true;
+ }
+#else
+ do_atmospherics = true;
+#endif
+
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
vec3 orm = texture2D(specularRect, tc).rgb;
@@ -161,23 +181,32 @@ void main()
float ao = orm.r * ambocc;
vec3 colorEmissive = texture2D(emissiveRect, tc).rgb;
-
// PBR IBL
float gloss = 1.0 - perceptualRoughness;
- vec3 irradiance = vec3(0);
- vec3 radiance = vec3(0);
+
sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss);
// Take maximium of legacy ambient vs irradiance sample as irradiance
// NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
- irradiance = max(amblit,irradiance);
+ irradiance = max(amblit_linear,irradiance);
vec3 diffuseColor;
vec3 specularColor;
calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
vec3 v = -normalize(pos.xyz);
- color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+ color = vec3(1,0,1);
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+
+
+ if (do_atmospherics)
+ {
+ color = linear_to_srgb(color);
+ color = atmosFragLightingLinear(color, additive, atten);
+ color = srgb_to_linear(color);
+ }
+
+
}
else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
{
@@ -199,12 +228,12 @@ void main()
sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity);
// use sky settings ambient or irradiance map sample, whichever is brighter
- irradiance = max(amblit, irradiance);
+ irradiance = max(amblit_linear, irradiance);
// apply lambertian IBL only (see pbrIbl)
color.rgb = irradiance * ambocc;
- vec3 sun_contrib = min(da, scol) * sunlit;
+ vec3 sun_contrib = min(da, scol) * sunlit_linear;
color.rgb += sun_contrib;
color.rgb *= baseColor.rgb;
@@ -230,9 +259,16 @@ void main()
applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
}
- color = mix(atmosFragLightingLinear(color, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), baseColor.a);
- color = scaleSoftClipFragLinear(color);
- }
+
+ if (do_atmospherics)
+ {
+ color = linear_to_srgb(color);
+ color = atmosFragLightingLinear(color, additive, atten);
+ color = srgb_to_linear(color);
+ }
+ }
+
+
#ifdef WATER_FOG
vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 3d721cd048..7524567f6b 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -114,6 +114,7 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
}
vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
vec3 vN, vT, vB;
@@ -122,11 +123,8 @@ vec3 transform_normal(vec3 vNt)
return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
}
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness);
-
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness);
vec3 getPositionWithNDC(vec3 ndc);
@@ -203,6 +201,8 @@ void main()
calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+
#ifdef TRANSPARENT_WATER
vec4 fb = texture2D(screenTex, distort2);
float depth = texture2D(screenDepth, distort2).r;
@@ -219,21 +219,24 @@ void main()
fb = applyWaterFogViewLinear(refPos, fb, sunlit);
#else
- vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(0.5), sunlit);
+ vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);
#endif
+ // fudge sample on other side of water to be a tad darker
+ fb.rgb *= 0.75;
+
float metallic = 0.0;
- float perceptualRoughness = 0.1;
+ float perceptualRoughness = 0.05;
float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss);
+ sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss);
irradiance = vec3(0);
- vec3 diffuseColor;
- vec3 specularColor;
+ vec3 diffuseColor = vec3(0);
+ vec3 specularColor = vec3(0);
calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);
vec3 v = -normalize(pos.xyz);
@@ -250,10 +253,7 @@ void main()
vec3 punctual = pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir));
- vec3 color = punctual * sunlit * 2.75 * scol;
-
- color = atmosFragLightingLinear(color, additive, atten);
- color = scaleSoftClipFragLinear(color);
+ vec3 color = punctual * sunlit_linear * 2.75 * scol;
vec3 ibl = pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0);
@@ -265,10 +265,24 @@ void main()
f *= 0.9;
f *= f;
+ // incoming scale is [0, 1] with 0.5 being default
+ // shift to 0.5 to 1.5
+ f *= (fresnelScale - 0.5)+1.0;
+
+ // incoming offset is [0, 1] with 0.5 being default
+ // shift from -1 to 1
+ f += (fresnelOffset - 0.5) * 2.0;
+
f = clamp(f, 0, 1);
- //fb.rgb *= 1.;
-
+
color = mix(color, fb.rgb, f);
+
+ color.rgb = linear_to_srgb(color.rgb);
+ color = atmosFragLightingLinear(color, additive, atten);
+ color = scaleSoftClipFragLinear(color);
+ color.rgb = srgb_to_linear(color.rgb);
+
+
float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
frag_color = vec4(color, spec); //*sunAngle2);