From cbd17fce86cc30434d6d665338a7d771bddcad8b Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Thu, 25 May 2023 16:09:22 -0400 Subject: Fix underwater fog mismatch between opaque and alpha blend when local lights are nearby (#227) * Fix water fog mismatch between alpha blend and opaque when local light is nearby * Add PBR underwater alpha blend shader --- .../shaders/class2/deferred/alphaF.glsl | 9 ++-- .../shaders/class2/deferred/pbralphaF.glsl | 9 ++++ .../shaders/class3/deferred/materialF.glsl | 12 ++--- indra/newview/lldrawpoolalpha.cpp | 5 +- indra/newview/llviewershadermgr.cpp | 62 ++++++++++++++++++++++ indra/newview/llviewershadermgr.h | 1 + 6 files changed, 86 insertions(+), 12 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index ae8cd97b18..cd57b47eae 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -274,6 +274,10 @@ void main() color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); +#ifdef WATER_FOG + color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear); +#endif // WATER_FOG + vec4 light = vec4(0,0,0,0); #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w); @@ -291,11 +295,6 @@ void main() color.rgb += light.rgb; #endif // !defined(LOCAL_LIGHT_KILL) - -#ifdef WATER_FOG - color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear); -#endif // WATER_FOG - #endif // #else // FOR_IMPOSTOR #ifdef IS_HUD diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index e6aef7abdc..9ac106149e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -84,6 +84,10 @@ vec3 linear_to_srgb(vec3 c); void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten); +#ifdef WATER_FOG +vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit); +#endif + void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); @@ -237,6 +241,11 @@ void main() color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); +#ifdef WATER_FOG + vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear); + color = temp.rgb; +#endif + vec3 light = vec3(0); // Punctual lights diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index ba19fe0f19..5fb5647d35 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -38,7 +38,7 @@ uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 o uniform int sun_up_factor; #ifdef WATER_FOG -vec4 applyWaterFogView(vec3 pos, vec4 color); +vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit); #endif vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten); @@ -411,6 +411,11 @@ void main() color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); +#ifdef WATER_FOG + vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear); + color = temp.rgb; +#endif + vec3 npos = normalize(-pos.xyz); vec3 light = vec3(0, 0, 0); @@ -431,11 +436,6 @@ void main() 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 = max(vec4(color, al), vec4(0)); #else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 67bc0463c8..6aa2316589 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -197,7 +197,10 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) prepare_alpha_shader(&materialShader[i], false, true, water_sign); } - pbr_shader = LLPipeline::sRenderingHUDs ? &gHUDPBRAlphaProgram : &gDeferredPBRAlphaProgram; + pbr_shader = + (LLPipeline::sUnderWaterRender) ? &gDeferredPBRAlphaWaterProgram : + (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram : + &gDeferredPBRAlphaProgram; prepare_alpha_shader(pbr_shader, false, true, water_sign); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 8e5f5ef866..44147184ef 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -222,6 +222,8 @@ LLGLSLShader gDeferredSkinnedPBROpaqueProgram; LLGLSLShader gHUDPBRAlphaProgram; LLGLSLShader gDeferredPBRAlphaProgram; LLGLSLShader gDeferredSkinnedPBRAlphaProgram; +LLGLSLShader gDeferredPBRAlphaWaterProgram; +LLGLSLShader gDeferredSkinnedPBRAlphaWaterProgram; //helper for making a rigged variant of a given shader bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -296,8 +298,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredWLMoonProgram); mShaderList.push_back(&gDeferredWLSunProgram); mShaderList.push_back(&gDeferredPBRAlphaProgram); + mShaderList.push_back(&gDeferredPBRAlphaWaterProgram); mShaderList.push_back(&gHUDPBRAlphaProgram); mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); + mShaderList.push_back(&gDeferredSkinnedPBRAlphaWaterProgram); mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma mShaderList.push_back(&gNoPostGammaCorrectProgram); mShaderList.push_back(&gLegacyPostGammaCorrectProgram); @@ -1020,6 +1024,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedPBROpaqueProgram.unload(); gDeferredPBRAlphaProgram.unload(); gDeferredSkinnedPBRAlphaProgram.unload(); + gDeferredPBRAlphaWaterProgram.unload(); + gDeferredSkinnedPBRAlphaWaterProgram.unload(); return TRUE; } @@ -1411,6 +1417,62 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() shader->mRiggedVariant->mFeatures.hasLighting = true; } + if (success) + { + LLGLSLShader* shader = &gDeferredPBRAlphaWaterProgram; + shader->mName = "Deferred PBR Alpha Underwater Shader"; + + shader->mFeatures.calculatesLighting = false; + shader->mFeatures.hasLighting = false; + shader->mFeatures.isAlphaLighting = true; + shader->mFeatures.hasWaterFog = true; + shader->mFeatures.hasSrgb = true; + shader->mFeatures.encodesNormal = true; + shader->mFeatures.calculatesAtmospherics = true; + shader->mFeatures.hasAtmospherics = true; + shader->mFeatures.hasGamma = true; + shader->mFeatures.hasShadows = use_sun_shadow; + shader->mFeatures.isDeferred = true; // include deferredUtils + shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; + + shader->mShaderGroup = LLGLSLShader::SG_WATER; + + shader->mShaderFiles.clear(); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); + + shader->clearPermutations(); + + U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + shader->addPermutation("HAS_NORMAL_MAP", "1"); + shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness + shader->addPermutation("HAS_EMISSIVE_MAP", "1"); + shader->addPermutation("USE_VERTEX_COLOR", "1"); + shader->addPermutation("WATER_FOG", "1"); + + if (use_sun_shadow) + { + shader->addPermutation("HAS_SUN_SHADOW", "1"); + } + + shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaWaterProgram); + if (success) + { + success = shader->createShader(NULL, NULL); + } + llassert(success); + + // Alpha Shader Hack + // See: LLRender::syncMatrices() + shader->mFeatures.calculatesLighting = true; + shader->mFeatures.hasLighting = true; + + shader->mRiggedVariant->mFeatures.calculatesLighting = true; + shader->mRiggedVariant->mFeatures.hasLighting = true; + } + if (success) { LLGLSLShader* shader = &gHUDPBRAlphaProgram; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 492e60b840..f4d5df701d 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -277,5 +277,6 @@ extern LLGLSLShader gHUDPBROpaqueProgram; extern LLGLSLShader gPBRGlowProgram; extern LLGLSLShader gDeferredPBROpaqueProgram; extern LLGLSLShader gDeferredPBRAlphaProgram; +extern LLGLSLShader gDeferredPBRAlphaWaterProgram; extern LLGLSLShader gHUDPBRAlphaProgram; #endif -- cgit v1.2.3