summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl')
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl484
1 files changed, 373 insertions, 111 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 7ed9e7b4fc..bd6ba4bf15 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -1,31 +1,72 @@
-/**
+/**
* @file class3/deferred/softenLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, 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$
*/
-
+
+#define DEBUG_PBR_PACKORM0 0 // Rough=0, Metal=0
+#define DEBUG_PBR_PACKORM1 0 // Rough=1, Metal=1
+#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0
+#define DEBUG_PBR_VERT2CAM1 0 // vertex2camera = 0,0,1
+
+#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian
+#define DEBUG_PBR_EMISSIVE 0 // Output: Emissive
+#define DEBUG_PBR_METAL 0 // Output: grayscale Metal map
+#define DEBUG_PBR_OCCLUSION 0 // Output: grayscale Occlusion map
+#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal
+#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughenss map
+#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness
+
+#define DEBUG_PBR_NORMAL 0 // Output: passed in normal. To see raw normal map: set DEBUG_PBR_DIFFUSE_MAP 1, and in pbropaqueF set DEBUG_NORMAL_RAW
+#define DEBUG_PBR_TANGENT 0 // Output: Tangent
+#define DEBUG_PBR_BITANGENT 0 // Output: Bitangent
+#define DEBUG_PBR_DOT_BV 0 // Output: graysacle dot(Bitangent,Vertex2Camera)
+#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal ,Vertex2Camera)
+#define DEBUG_PBR_DOT_TV 0 // Output: grayscale dot(Tangent ,Vertex2Camera)
+
+#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output)
+#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input)
+#define DEBUG_PBR_DIFFUSE_K 0 // Output: diffuse FssEssLambert + FmsEms
+#define DEBUG_PBR_DIFFUSE_MAP 0 // Output: use diffuse in G-Buffer
+#define DEBUG_PBR_FE_GGX 0 // Output: FssEssGGX
+#define DEBUG_PBR_FE_LAMBERT 0 // Output: FssEssLambert
+#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel
+#define DEBUG_PBR_IOR 0 // Output: grayscale IOR
+#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance
+#define DEBUG_PBR_KSPEC 0 // Output: K spec
+#define DEBUG_PBR_REFLECT0_BASE 0 // Output: black reflect0 default from ior
+#define DEBUG_PBR_REFLECT0_MIX 0 // Output: diffuse reflect0 calculated from ior
+#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance -- NOT USED
+#define DEBUG_PBR_SPEC 0 // Output: Final spec
+#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: environment reflection
+#define DEBUG_PBR_V2C_RAW 0 // Output: vertex2camera
+#define DEBUG_PBR_V2C_REMAP 0 // Output: vertex2camera (remap [-1,1] -> [0,1])
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
+
+#define FLT_MAX 3.402823466e+38
-/*[EXTRA_CODE_HERE]*/
+#define REFMAP_COUNT 256
+#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -36,142 +77,363 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
uniform sampler2DRect lightMap;
+#endif
+
uniform sampler2DRect depthMap;
uniform sampler2D lightFunc;
-uniform samplerCube environmentMap;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform float cloud_shadow;
-uniform float max_y;
-uniform vec4 glow;
uniform mat3 env_mat;
-uniform vec4 shadow_clip;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
uniform vec2 screen_res;
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+float getAmbientClamp();
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFrag(vec3 l);
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClip(vec3 light);
-vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance);
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
+// reflection probe interface
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
-vec3 ColorFromRadiance(vec3 radiance);
-vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
#ifdef WATER_FOG
vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-void main()
+uniform vec3 view_dir; // PBR
+
+// Approximate Environment BRDF
+vec2 getGGXApprox( vec2 uv )
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPositionWithDepth(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
+ vec2 st = vec2(1.) - uv;
+ float d = (st.x * st.x * 0.5) * (st.y * st.y);
+ float scale = 1.0 - d;
+ float bias = d;
+ return vec2( scale, bias );
+}
+
+vec2 getGGX( vec2 brdfPoint )
+{
+ // TODO: use GGXLUT
+ // texture2D(GGXLUT, brdfPoint).rg;
+ return getGGXApprox( brdfPoint);
+}
+
+vec3 calcBaseReflect0(float ior)
+{
+ vec3 reflect0 = vec3(pow((ior - 1.0) / (ior + 1.0), 2.0));
+ return reflect0;
+}
+
+void main()
+{
+ vec2 tc = vary_fragcoord.xy;
+ float depth = texture2DRect(depthMap, tc.xy).r;
+ vec4 pos = getPositionWithDepth(tc, depth);
+ vec4 norm = texture2DRect(normalMap, tc);
float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
+ norm.xyz = getNorm(tc);
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ float light_gamma = 1.0 / 1.3;
+ da = pow(da, light_gamma);
- vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB
- diffuse.rgb = srgb_to_linear(diffuse.rgb);
+ vec4 diffuse = texture2DRect(diffuseRect, tc);
+ diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
- vec3 col;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+ float scol = max(scol_ambocc.r, diffuse.a);
+ float ambocc = scol_ambocc.g;
+#else
+ float scol = 1.0;
+ float ambocc = 1.0;
+#endif
+
+ vec3 color = vec3(0);
float bloom = 0.0;
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
+
+ //vec3 amb_vec = env_mat * norm.xyz;
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+
+ bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR);
+ if (hasPBR)
{
- vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f);
-
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
-
- float scol = max(scol_ambocc.r, diffuse.a);
-
- float ambocc = scol_ambocc.g;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
-
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
-
- indirect = clamp(indirect, vec3(0), vec3(1.0));
-
- vec3 transmittance;
- vec3 sky_irradiance;
- vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance);
- vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance);
-
- vec3 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter;
- vec3 atmo_color = ColorFromRadiance(radiance);
-
- col = atmo_color + indirect;
- col *= transmittance;
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color;
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb * 0.25;
- bloom = dot(spec_contrib, spec_contrib);
- col += spec_contrib;
- }
-
- col = mix(col, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 sun_direction = (inv_modelview * vec4(sun_dir, 1.0)).xyz;
- vec3 radiance_sun = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance);
- vec3 refcol = ColorFromRadiance(radiance_sun);
- col = mix(col.rgb, refcol, envIntensity);
- }
-
- /*if (norm.w < 0.5)
- {
- col = scaleSoftClipFrag(col);
- }*/
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
+ vec3 colorDiffuse = vec3(0);
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 colorSpec = vec3(0);
+// vec3 colorClearCoat = vec3(0);
+// vec3 colorSheen = vec3(0);
+// vec3 colorTransmission = vec3(0);
+
+ vec3 packedORM = spec.rgb; // Packed: Occlusion Roughness Metal
+#if DEBUG_PBR_PACK_ORM0
+ packedORM = vec3(0,0,0);
+#endif
+#if DEBUG_PBR_PACK_ORM1
+ packedORM = vec3(1,1,1);
+#endif
+ float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
+ vec3 reflect0 = vec3(0.04); // -> incidence reflectance 0.04
+#if HAS_IOR
+ reflect0 = calcBaseReflect0(IOR);
+#endif
+#if DEBUG_PBR_REFLECT0_BASE
+ vec3 debug_reflect0 = reflect0;
+#endif
+
+ float metal = packedORM.b;
+ vec3 reflect90 = vec3(0);
+ vec3 v = -normalize(pos.xyz);
+#if DEBUG_PBR_VERT2CAM1
+ v = vec3(0,0,1);
+#endif
+ vec3 n = norm.xyz;
+// vec3 t = texture2DRect(tangentMap, tc).rgb;
+#if DEBUG_PBR_TANGENT1
+ vec3 t = vec3(1,0,0);
+#endif
+ vec3 b = cross( n,t);
+ vec3 reflectVN = normalize(reflect(-v,n));
+
+ float dotNV = clamp(dot(n,v),0,1);
+ float dotTV = clamp(dot(t,v),0,1);
+ float dotBV = clamp(dot(b,v),0,1);
+
+ // Reference: getMetallicRoughnessInfo
+ float perceptualRough = packedORM.g;
+ float alphaRough = perceptualRough * perceptualRough;
+ vec3 colorDiff = mix( diffuse.rgb, vec3(0) , metal);
+ reflect0 = mix( reflect0 , diffuse.rgb, metal); // reflect at 0 degrees
+ reflect90 = vec3(1); // reflect at 90 degrees
+#if DEBUG_PBR_REFLECTANCE
+ float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b );
+#endif
+
+ // Common to RadianceGGX and RadianceLambertian
+ float specWeight = 1.0;
+ vec2 brdfPoint = clamp(vec2(dotNV, perceptualRough), vec2(0,0), vec2(1,1));
+ vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0
+ vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel
+ vec3 kSpec = reflect0 + fresnelR*pow(1.0 - dotNV, 5.0);
+
+ // Reference: getIBLRadianceGGX
+ // https://forum.substance3d.com/index.php?topic=3243.0
+ // Glossiness
+ // This map is the inverse of the roughness map.
+ vec3 irradiance = vec3(0);
+ vec3 specLight = vec3(0);
+ float gloss = 1.0 - perceptualRough;
+ sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
+#if HAS_IBL
+ kSpec = mix( kSpec, iridescenceFresnel, iridescenceFactor);
+#endif
+ vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y;
+ colorSpec += specWeight * specLight * FssEssGGX;
+
+ // Reference: getIBLRadianceLambertian
+ vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term
+ float Ems = (1.0 - vScaleBias.x + vScaleBias.y);
+ vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0);
+ vec3 AvgEms = avg * Ems;
+ vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms);
+ vec3 kDiffuse = colorDiffuse * (1.0 - FssEssLambert + FmsEms);
+ colorDiffuse += (FmsEms + kDiffuse) * irradiance;
+
+ colorDiffuse *= packedORM.r; // Occlusion -- NOTE: pbropaque will need occlusion_strength pre-multiplied into spec.r
+
+ color.rgb = colorDiffuse + colorEmissive + colorSpec;
+
+ #if DEBUG_PBR_DIFFUSE
+ color.rgb = colorDiffuse;
+ #endif
+ #if DEBUG_PBR_EMISSIVE
+ color.rgb = colorEmissive;
+ #endif
+ #if DEBUG_PBR_METAL
+ color.rgb = vec3(metal);
+ #endif
+ #if DEBUG_PBR_OCCLUSION
+ color.rgb = vec3(packedORM.r);
+ #endif
+ #if DEBUG_PBR_ORM
+ color.rgb = packedORM;
+ #endif
+ #if DEBUG_PBR_ROUGH_PERCEPTUAL
+ color.rgb = vec3(perceptualRough);
+ #endif
+ #if DEBUG_PBR_ROUGH_ALPHA
+ color.rgb = vec3(alphaRough);
+ #endif
+
+ #if DEBUG_PBR_NORMAL
+ color.rgb = norm.xyz;
+ #endif
+ #if DEBUG_PBR_TANGENT
+ color.rgb = t;
+ #endif
+ #if DEBUG_PBR_BITANGENT
+ color.rgb = b;
+ #endif
+ #if DEBUG_PBR_DOT_NV
+ color.rgb = vec3(dotNV);
+ #endif
+ #if DEBUG_PBR_DOT_TV
+ color.rgb = vec3(dotTV);
+ #endif
+ #if DEBUG_PBR_DOT_BV
+ color.rgb = vec3(dotBV);
+ #endif
+
+ #if DEBUG_PBR_BRDF_UV
+ color.rgb = vec3(brdfPoint,0.0);
+ #endif
+ #if DEBUG_PBR_BRDF_SCALE_BIAS
+ color.rgb = vec3(vScaleBias,0.0);
+ #endif
+ #if DEBUG_PBR_DIFFUSE_K
+ color.rgb = kDiffuse;
+ #endif
+ #if DEBUG_PBR_DIFFUSE_MAP
+ color.rgb = diffuse.rgb;
+ #endif
+ #if DEBUG_PBR_FE_GGX
+ color.rgb = FssEssGGX; // spec
+ #endif
+ #if DEBUG_PBR_FE_LAMBERT
+ color.rgb = FssEssLambert; // diffuse
+ #endif
+ #if DEBUG_PBR_FRESNEL
+ color.rgb = fresnelR;
+ #endif
+ #if DEBUG_PBR_IOR
+ color.rgb = vec3(IOR);
+ #endif
+ #if DEBUG_PBR_IRRADIANCE
+ color.rgb = irradiance;
+ #endif
+ #if DEBUG_PBR_KSPEC
+ color.rgb = kSpec;
+ #endif
+ #if DEBUG_PBR_REFLECT0_BASE
+ color.rgb = vec3(debug_reflect0);
+ #endif
+ #if DEBUG_PBR_REFLECT0_MIX
+ color.rgb = vec3(reflect0);
+ #endif
+ #if DEBUG_PBR_REFLECTANCE
+ color.rgb = vec3(reflectance);
+ #endif
+ #if DEBUG_PBR_SPEC
+ color.rgb = colorSpec;
+ #endif
+ #if DEBUG_PBR_SPEC_REFLECTION
+ color.rgb = specLight;
+ #endif
+ #if DEBUG_PBR_V2C_RAW
+ color.rgb = v;
+ #endif
+ #if DEBUG_PBR_V2C_REMAP
+ color.rgb = v*0.5 + vec3(0.5);
+ #endif
}
+else
+{
+ sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
+
+ amblit = max(ambenv, amblit);
+ color.rgb = amblit*ambocc;
+
+ //float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ //ambient *= 0.5;
+ //ambient *= ambient;
+ //ambient = (1.0 - ambient);
+ //color.rgb *= ambient;
+
+ vec3 sun_contrib = min(da, scol) * sunlit;
+ color.rgb += sun_contrib;
+ color.rgb = min(color.rgb, vec3(1,1,1));
+ color.rgb *= diffuse.rgb;
- //output linear since gamma correction happens down stream
- frag_color.rgb = col;
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
+ vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+ color.rgb += spec_contrib;
+
+ // add reflection map - EXPERIMENTAL WORK IN PROGRESS
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+ }
+
+ color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ { // add environmentmap
+ //fudge darker
+ legacyenv *= 0.5*diffuse.a+0.5;;
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
+ }
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+ {
+ color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
+ color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
+ }
+
+#ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
+ color = fogged.rgb;
+ bloom = fogged.a;
+#endif
+}
+ // convert to linear as fullscreen lights need to sum in linear colorspace
+ // and will be gamma (re)corrected downstream...
+ //color = vec3(ambocc);
+ //color = ambenv;
+ //color.b = diffuse.a;
+ frag_color.rgb = srgb_to_linear(color.rgb);
frag_color.a = bloom;
}