diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl')
-rw-r--r-- | indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 4f6e01764a..4f2475b101 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -48,6 +48,7 @@ layout (std140) uniform ReflectionProbes /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation // box[3][0..2] - plane thickness mat4 refBox[MAX_REFMAP_COUNT]; + mat4 heroBox; // list of bounding spheres for reflection probes sorted by distance to camera (closest first) vec4 refSphere[MAX_REFMAP_COUNT]; // extra parameters @@ -56,6 +57,7 @@ layout (std140) uniform ReflectionProbes // z - fade in // w - znear vec4 refParams[MAX_REFMAP_COUNT]; + vec4 heroSphere; // index of cube map in reflectionProbes for a corresponding reflection probe // e.g. cube map channel of refSphere[2] is stored in refIndex[2] // refIndex.x - cubemap channel in reflectionProbes @@ -71,6 +73,10 @@ layout (std140) uniform ReflectionProbes // number of reflection probes present in refSphere int refmapCount; + + int heroShape; + int heroMipCount; + int heroProbeCount; }; // Inputs @@ -366,11 +372,11 @@ return texCUBE(envMap, ReflDirectionWS); // i - probe index in refBox/refSphere // d - distance to nearest wall in clip space // scale - scale of box, default 1.0 -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d, float scale) { // Intersection with OBB convert to unit box space // Transform in local unit parallax cube space (scaled and rotated) - mat4 clipToLocal = refBox[i]; + mat4 clipToLocal = i; vec3 RayLS = mat3(clipToLocal) * dir; vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -389,7 +395,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) return IntersectPositionCS; } -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d) { return boxIntersect(origin, dir, i, d, 1.0); } @@ -444,9 +450,9 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col) } -void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col) +void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col) { - mat4 clipToLocal = refBox[i]; + mat4 clipToLocal = i; // transform into unit cube space origin = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -463,7 +469,7 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col) // r - radius of probe influence volume // i - index of probe in refSphere // dw - distance weight -float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw) +float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, vec4 i, out float dw) { float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down) vec3 delta = pos.xyz - origin; @@ -472,7 +478,7 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001); float w = 1.0 / d2; - w *= refParams[i].z; + w *= i.z; dw = w * atten * max(r, 1.0)*4; @@ -498,7 +504,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, if (refIndex[i].w < 0) { // box probe float d = 0; - v = boxIntersect(pos, dir, i, d); + v = boxIntersect(pos, dir, refBox[i], d); w = max(d, 0.001); } @@ -512,7 +518,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 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 rr); - w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw); + w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw); } v -= c; @@ -538,7 +544,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int if (refIndex[i].w < 0) { float d = 0.0; - v = boxIntersect(pos, dir, i, d, 3.0); + v = boxIntersect(pos, dir, refBox[i], d, 3.0); w = max(d, 0.001); } else @@ -552,7 +558,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int 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, i, dw); + w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw); } v -= c; @@ -682,23 +688,37 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit) return col[1]+col[0]; } - #if defined(HERO_PROBES) uniform vec4 clipPlane; -uniform samplerCubeArray heroProbes; +uniform samplerCubeArray heroProbes; void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) { float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; - if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8) + float w = 0; + float dw = 0; + float falloffMult = 10; + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + if (heroShape < 1) { - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) - { - glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz; - } + float d = 0; + boxIntersect(pos, norm, heroBox, d, 1.0); + + w = max(d, 0); } + else + { + float r = heroSphere.w; + + w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw); + } + + clipDist = clipDist * 0.95 + 0.05; + clipDist = clamp(clipDist * falloffMult, 0, 1); + w = clamp(w * falloffMult * clipDist, 0, 1); + + glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w); } #else @@ -779,7 +799,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col) { if (refIndex[i].w < 0) { - boxIntersectDebug(origin, pos, i, col); + boxIntersectDebug(origin, pos, refBox[i], col); } else { |