diff options
Diffstat (limited to 'indra/newview/app_settings/shaders')
11 files changed, 317 insertions, 148 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl index ddb53ff852..24faf1763f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl @@ -49,10 +49,9 @@ uniform mat3 texture_normal_matrix; uniform mat3 texture_metallic_roughness_matrix; uniform mat3 texture_emissive_matrix; -#ifdef HAS_SUN_SHADOW out vec3 vary_fragcoord; + uniform float near_clip; -#endif in vec3 position; in vec4 diffuse_color; @@ -88,9 +87,7 @@ void main() #endif gl_Position = vert; -#ifdef HAS_SUN_SHADOW vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip); -#endif basecolor_texcoord = texture_transform(texcoord0, texture_basecolor_matrix, texture_matrix0); normal_texcoord = texture_transform(texcoord0, texture_normal_matrix, texture_matrix0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 987b2d1fe8..e0e975faf0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -41,6 +41,122 @@ uniform float display_gamma; vec3 linear_to_srgb(vec3 cl); +//=============================================================== +// tone mapping taken from Khronos sample implementation +//=============================================================== +const float GAMMA = 2.2; +const float INV_GAMMA = 1.0 / GAMMA; + + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +const mat3 ACESInputMat = mat3 +( + 0.59719, 0.07600, 0.02840, + 0.35458, 0.90834, 0.13383, + 0.04823, 0.01566, 0.83777 +); + + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +const mat3 ACESOutputMat = mat3 +( + 1.60475, -0.10208, -0.00327, + -0.53108, 1.10813, -0.07276, + -0.07367, -0.00605, 1.07602 +); + + +// linear to sRGB approximation +// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html +vec3 linearTosRGB(vec3 color) +{ + return pow(color, vec3(INV_GAMMA)); +} + + +// sRGB to linear approximation +// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html +vec3 sRGBToLinear(vec3 srgbIn) +{ + return vec3(pow(srgbIn.xyz, vec3(GAMMA))); +} + + +vec4 sRGBToLinear(vec4 srgbIn) +{ + return vec4(sRGBToLinear(srgbIn.xyz), srgbIn.w); +} + + +// ACES tone map (faster approximation) +// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +vec3 toneMapACES_Narkowicz(vec3 color) +{ + const float A = 2.51; + const float B = 0.03; + const float C = 2.43; + const float D = 0.59; + const float E = 0.14; + return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); +} + + +// ACES filmic tone map approximation +// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +vec3 RRTAndODTFit(vec3 color) +{ + vec3 a = color * (color + 0.0245786) - 0.000090537; + vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; + return a / b; +} + + +// tone mapping +vec3 toneMapACES_Hill(vec3 color) +{ + color = ACESInputMat * color; + + // Apply RRT and ODT + color = RRTAndODTFit(color); + + color = ACESOutputMat * color; + + // Clamp to [0, 1] + color = clamp(color, 0.0, 1.0); + + return color; +} + + +#define TONEMAP_ACES_NARKOWICZ +//#define TONEMAP_ACES_HILL_EXPOSURE_BOOST +float u_Exposure = 1; + +vec3 toneMap(vec3 color) +{ + color *= u_Exposure; + +#ifdef TONEMAP_ACES_NARKOWICZ + color = toneMapACES_Narkowicz(color); +#endif + +#ifdef TONEMAP_ACES_HILL + color = toneMapACES_Hill(color); +#endif + +#ifdef TONEMAP_ACES_HILL_EXPOSURE_BOOST + // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621 + // this factor is based on the exposure correction of Krzysztof Narkowicz in his + // implemetation of ACES tone mapping + color /= 0.6; + color = toneMapACES_Hill(color); +#endif + + return linearTosRGB(color); +} + +//=============================================================== + //================================= // borrowed noise from: // <https://www.shadertoy.com/view/4dS3Wd> @@ -83,7 +199,7 @@ void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) vec4 diff = texture2D(diffuseRect, vary_fragcoord); - diff.rgb = linear_to_srgb(diff.rgb); + diff.rgb = toneMap(diff.rgb); vec2 tc = vary_fragcoord.xy*screen_res; vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl index fffbdb913e..ee3a5f1f31 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl @@ -59,12 +59,12 @@ float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul, stc.xyz /= stc.w; stc.z += offset * 2.0; stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here - float cs = texture(shadowMap, stc.xyz).x; + float cs = texture(shadowMap, stc.xyz); float shadow = cs * 4.0; - shadow += texture(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0)).x; - shadow += texture(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; - shadow += texture(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0)).x; - shadow += texture(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += texture(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0)); + shadow += texture(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0)); + shadow += texture(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0)); + shadow += texture(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0)); return clamp(shadow * 0.125, 0.0, 1.0); #else return 1.0; @@ -78,16 +78,16 @@ float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 stc.z += spot_shadow_bias * bias_scale; stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap - float cs = texture(shadowMap, stc.xyz).x; + float cs = texture(shadowMap, stc.xyz); float shadow = cs; vec2 off = 1.0/proj_shadow_res; off.y *= 1.5; - shadow += texture(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x; - shadow += texture(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x; - shadow += texture(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x; - shadow += texture(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x; + shadow += texture(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)); + shadow += texture(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)); + shadow += texture(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)); + shadow += texture(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)); return shadow*0.2; #else return 1.0; diff --git a/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl new file mode 100644 index 0000000000..8e341503f5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl @@ -0,0 +1,53 @@ +/** + * @file gaussianF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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$ + */ + +out vec4 frag_color; + +uniform sampler2D diffuseRect; + +uniform float resScale; + +// texture direction, will be <1, 0> or <0, 1> +uniform vec2 direction; + +in vec2 vary_texcoord0; + +// get linear depth value given a depth buffer sample d and znear and zfar values +float linearDepth(float d, float znear, float zfar); + +void main() +{ + vec3 col = vec3(0,0,0); + + float w[] = { 0.0002, 0.0060, 0.0606, 0.2417, 0.3829, 0.2417, 0.0606, 0.0060, 0.0002 }; + + for (int i = 0; i < 9; ++i) + { + vec2 tc = vary_texcoord0 + (i-4)*direction*resScale; + col += texture(diffuseRect, tc).rgb * w[i]; + } + + frag_color = vec4(col, 0.0); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index e60ddcd569..b6f080739e 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -127,14 +127,11 @@ vec4 prefilterEnvMap(vec3 R) vec3 V = R; vec4 color = vec4(0.0); float totalWeight = 0.0; - float envMapDim = u_width; - int numSamples = 4; - - float numMips = max_probe_lod; + float envMapDim = float(textureSize(reflectionProbes, 0).s); + float roughness = mipLevel/max_probe_lod; + int numSamples = max(int(32*roughness), 1); - float roughness = mipLevel/numMips; - - numSamples = max(int(numSamples*roughness), 1); + float numMips = max_probe_lod+1; for(uint i = 0u; i < numSamples; i++) { vec2 Xi = hammersley2d(i, numSamples); @@ -154,11 +151,9 @@ vec4 prefilterEnvMap(vec3 R) // Solid angle of 1 pixel across all cube faces float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); // Biased (+1.0) mip level for better result - float mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, numMips); - //float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f); - color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip) * dotNL; + float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); + color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL; totalWeight += dotNL; - } } return (color / totalWeight); diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl index a9c28b2974..9f7706fe36 100644 --- a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl @@ -23,18 +23,8 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable - -/*[EXTRA_CODE_HERE]*/ - -#ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif -// NOTE screenMap should always be texture channel 0 and -// depthmap should always be channel 1 uniform sampler2D diffuseRect; uniform sampler2D depthMap; @@ -42,48 +32,13 @@ uniform float resScale; uniform float znear; uniform float zfar; -VARYING vec2 vary_texcoord0; +in vec2 vary_texcoord0; // get linear depth value given a depth buffer sample d and znear and zfar values float linearDepth(float d, float znear, float zfar); void main() { -#if 0 - float w[9]; - - float c = 1.0/16.0; //corner weight - float e = 1.0/8.0; //edge weight - float m = 1.0/4.0; //middle weight - - //float wsum = c*4+e*4+m; - - w[0] = c; w[1] = e; w[2] = c; - w[3] = e; w[4] = m; w[5] = e; - w[6] = c; w[7] = e; w[8] = c; - - vec2 tc[9]; - - float ed = 1; - float cd = 1; - - - tc[0] = vec2(-cd, cd); tc[1] = vec2(0, ed); tc[2] = vec2(cd, cd); - tc[3] = vec2(-ed, 0); tc[4] = vec2(0, 0); tc[5] = vec2(ed, 0); - tc[6] = vec2(-cd, -cd); tc[7] = vec2(0, -ed); tc[8] = vec2(cd, -1); - - vec3 color = vec3(0,0,0); - - for (int i = 0; i < 9; ++i) - { - color += texture2D(screenMap, vary_texcoord0.xy+tc[i]).rgb * w[i]; - //color += texture2D(screenMap, vary_texcoord0.xy+tc[i]*2.0).rgb * w[i]*0.5; - } - - //color /= wsum; - - frag_color = vec4(color, 1.0); -#else float depth = texture(depthMap, vary_texcoord0.xy).r; float dist = linearDepth(depth, znear, zfar); @@ -94,7 +49,6 @@ void main() v = normalize(v); dist /= v.z; - vec3 col = texture2D(diffuseRect, vary_texcoord0.xy).rgb; - frag_color = vec4(col, dist/256.0); -#endif + vec3 col = texture(diffuseRect, vary_texcoord0.xy).rgb; + frag_color = vec4(col, dist/256.0); } diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl index 641d670c26..edc0a9628b 100644 --- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl @@ -25,17 +25,16 @@ uniform mat4 modelview_projection_matrix; -ATTRIBUTE vec3 position; -ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec4 diffuse_color; +in vec3 position; +in vec4 diffuse_color; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +out vec4 vertex_color; +out vec2 vary_texcoord0; void main() { gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - vary_texcoord0 = texcoord0; + vary_texcoord0 = position.xy*0.5+0.5; vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 35ccc65a8e..a95feb8e2f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -46,8 +46,9 @@ uniform vec3 moon_dir; out vec4 frag_color; +in vec3 vary_fragcoord; + #ifdef HAS_SUN_SHADOW - in vec3 vary_fragcoord; uniform vec2 screen_res; #endif @@ -191,8 +192,9 @@ void main() vec3 atten; calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten); -#ifdef HAS_SUN_SHADOW vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + +#ifdef HAS_SUN_SHADOW scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag); #endif @@ -211,7 +213,7 @@ void main() float gloss = 1.0 - perceptualRoughness; vec3 irradiance = vec3(0); vec3 radiance = vec3(0); - sampleReflectionProbes(irradiance, radiance, vec2(0), pos.xyz, norm.xyz, gloss); + sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, 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); diff --git a/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl index c7da23fb00..baf68e11f4 100644 --- a/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl @@ -176,7 +176,6 @@ float computeLod(float pdf) vec4 filterColor(vec3 N) { - //return textureLod(uCubeMap, N, 3.0).rgb; vec4 color = vec4(0.f); for(int i = 0; i < u_sampleCount; ++i) @@ -192,7 +191,7 @@ vec4 filterColor(vec3 N) // apply the bias to the lod lod += u_lodBias; - lod = clamp(lod, 0, 7); + lod = clamp(lod, 0, max_probe_lod); // sample lambertian at a lower resolution to avoid fireflies vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod); diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 8b1d41776f..24539c3c3a 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,13 +456,15 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da) // Tap a reflection probe // pos - position of pixel // dir - pixel normal +// w - weight of sample (distance and angular attenuation) +// dw - weight of sample (distance only) // 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) // 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, out vec3 vi, out vec3 wi, float lod, vec3 c, int i) { //lod = max(lod, 1); // parallax adjustment @@ -473,14 +480,15 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float } else { - float r = refSphere[i].w; // radius of sphere volume - float rr = r * r; // radius squared + 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; @@ -500,10 +508,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 +524,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; @@ -535,19 +544,30 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i) vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect) { - 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; + float w = 0; + float dw = 0; vec3 vi, wi; vec3 refcol; @@ -556,7 +576,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect) 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); + refcol = tapRefMap(pos, dir, w, dw, vi, wi, abs(lod + 2), refSphere[i].xyz, i); //adjust lookup by distance result float d = length(vi - wi); @@ -571,61 +591,96 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect) // 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); + refcol = tapRefMap(pos, dir, w, dw, 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 minweight = 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 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i); + float w = 0; + float dw = 0; - col += refcol*w; - - wsum += w; + vec3 refcol = tapIrradianceMap(pos, dir, w, dw, refSphere[i].xyz, i); + + 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, @@ -658,7 +713,7 @@ 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) { @@ -705,7 +760,6 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, 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); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 3d721cd048..631d2c04d0 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -232,8 +232,8 @@ void main() 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); |