diff --git a/doc/contributions.txt b/doc/contributions.txt
index 90252f8490..f1451af57e 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -602,6 +602,7 @@ Henri Beauchamp
SL-15175
SL-19110
SL-19159
+ [NO JIRA] (fullbright HUD alpha fix)
herina Bode
Hikkoshi Sakai
VWR-429
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index 9e61b6b894..c95f791dbf 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -34,6 +34,6 @@ void main()
{
// NOTE: when this shader is used, only alpha is being written to
float a = diffuseLookup(vary_texcoord0.xy).a*vertex_color.a;
- frag_color = vec4(0, 0, 0, a);
+ frag_color = max(vec4(0, 0, 0, a), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 8b2a69b924..a6fab10791 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -76,9 +76,9 @@ void main()
vec3 pos = vary_position;
+ color.a = final_alpha;
#ifndef IS_HUD
color.rgb = srgb_to_linear(color.rgb);
- color.a = final_alpha;
#ifdef IS_ALPHA
vec3 sunlit;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
index e8f7d73f1f..0b154e82ad 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -78,13 +78,12 @@ void main()
do_atmospherics = true;
}
-
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
if (depth >= 1.0)
{
- //should only be true of WL sky, just port over base color value
+ //should only be true of sky, clouds, sun/moon, and stars
discard;
}
@@ -102,6 +101,6 @@ void main()
alpha = 1.0;
}
- frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
- frag_color.a = alpha;
+ frag_color = max(vec4(color.rgb, alpha), vec4(0)); //output linear since local lights will be added to this shader's results
+
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 025bcdaf3e..f6b8299f91 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -35,15 +35,31 @@ float getDepth(vec2 pos_screen);
vec4 getWaterFogView(vec3 pos);
+uniform int above_water;
+
void main()
{
vec2 tc = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
float depth = getDepth(tc.xy);
+
+ if (above_water > 0)
+ {
+ // we want to depth test when the camera is above water, but some GPUs have a hard time
+ // with depth testing against render targets that are bound for sampling in the same shader
+ // so we do it manually here
+
+ float cur_depth = vary_fragcoord.z/vary_fragcoord.w*0.5+0.5;
+ if (cur_depth > depth)
+ {
+ discard;
+ }
+ }
+
vec4 pos = getPositionWithDepth(tc, depth);
vec4 norm = texture(normalMap, tc);
vec4 fogged = getWaterFogView(pos.xyz);
- frag_color.rgb = max(fogged.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
- frag_color.a = fogged.a;
+ frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results
+
}
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index ddb1b79681..223e55eb69 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -30,7 +30,6 @@ uniform sampler2D bumpMap;
#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
#endif
uniform vec4 fogCol;
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index f53bc2e13e..b364e454e8 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -76,7 +76,7 @@ uniform sampler2D bumpMap2;
uniform float blend_factor;
#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D screenDepth;
+uniform sampler2D depthMap;
#endif
uniform sampler2D refTex;
@@ -210,7 +210,7 @@ void main()
#ifdef TRANSPARENT_WATER
vec4 fb = texture(screenTex, distort2);
- float depth = texture(screenDepth, distort2).r;
+ float depth = texture(depthMap, distort2).r;
vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
if (refPos.z > pos.z-0.05)
@@ -218,7 +218,7 @@ void main()
//we sampled an above water sample, don't distort
distort2 = distort;
fb = texture(screenTex, distort2);
- depth = texture(screenDepth, distort2).r;
+ depth = texture(depthMap, distort2).r;
refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
}
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 4300670445..0925a01439 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -53,7 +53,9 @@ public:
// before grass, so grass should be the first alpha masked pool. Other ordering should be done
// based on fill rate and likelihood to occlude future passes (faster, large occluders first).
//
- POOL_SIMPLE = 1,
+ POOL_SKY = 1,
+ POOL_WL_SKY,
+ POOL_SIMPLE,
POOL_FULLBRIGHT,
POOL_BUMP,
POOL_TERRAIN,
@@ -64,8 +66,6 @@ public:
POOL_TREE,
POOL_ALPHA_MASK,
POOL_FULLBRIGHT_ALPHA_MASK,
- POOL_SKY,
- POOL_WL_SKY,
POOL_AVATAR,
POOL_CONTROL_AV, // Animesh
POOL_GLOW,
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index ba0e0858b4..44160b306e 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -212,7 +212,7 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
}
}
- gPipeline.bindDeferredShader(*shader);
+ gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
//bind normal map
S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
@@ -244,7 +244,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
// bind reflection texture from RenderTarget
S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
- S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
@@ -261,11 +260,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
}
- if (screenDepth > -1)
- {
- gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
- }
-
if (mShaderLevel == 1)
{
fog_color.mV[VW] = log(fog_density) / log(2);
@@ -348,7 +342,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
shader->disableTexture(LLShaderMgr::BUMP_MAP);
shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader->disableTexture(LLShaderMgr::WATER_REFTEX);
- shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
// clean up
gPipeline.unbindDeferredShader(*shader);
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 05ee328e43..b14235f25c 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -87,6 +87,9 @@ void LLDrawPoolWLSky::endDeferredPass(S32 pass)
cloud_shader = nullptr;
sun_shader = nullptr;
moon_shader = nullptr;
+
+ // clear the depth buffer so haze shaders can use unwritten depth as a mask
+ glClear(GL_DEPTH_BUFFER_BIT);
}
void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index d54fb187f2..91595ac8c6 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -4474,6 +4474,7 @@ void LLPanelFace::onCopyTexture()
te_data["te"]["bumpmap"] = tep->getBumpmap();
te_data["te"]["bumpshiny"] = tep->getBumpShiny();
te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright();
+ te_data["te"]["texgen"] = tep->getTexGen();
te_data["te"]["pbr"] = objectp->getRenderMaterialID(te);
if (tep->getGLTFMaterialOverride() != nullptr)
{
@@ -4869,6 +4870,11 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
{
objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger());
}
+ if (te_data["te"].has("texgen"))
+ {
+ objectp->setTETexGen(te, (U8)te_data["te"]["texgen"].asInteger());
+ }
+
// PBR/GLTF
if (te_data["te"].has("pbr"))
{
@@ -4937,8 +4943,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
{
LLUUID object_id = objectp->getID();
- LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
-
// Normal
// Replace placeholders with target's
if (te_data["material"].has("NormMapNoCopy"))
@@ -4984,7 +4988,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te);
LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id);
- LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["DiffuseAlphaMode"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["AlphaMaskCutoff"].asInteger(), te, object_id);
if (te_data.has("te") && te_data["te"].has("shiny"))
{
objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger());
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 04c8a320bf..de701c4b73 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -951,6 +951,10 @@ U32 render_type_from_string(std::string render_type)
{
return LLPipeline::RENDER_TYPE_BUMP;
}
+ else if ("pbr" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_GLTF_PBR;
+ }
else
{
return 0;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3411502a60..1eb86679ee 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -872,10 +872,8 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
// [/SL:KB]
- if (LLPipeline::sRenderTransparentWater)
- { //water reflection texture
- mWaterDis.allocate(resX, resY, GL_RGBA16F, true);
- }
+ //water reflection texture (always needed as scratch space whether or not transparent water is enabled)
+ mWaterDis.allocate(resX, resY, GL_RGBA16F, true);
if (RenderUIBuffer)
{
@@ -7691,7 +7689,7 @@ void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
}
}
-void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
+void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target, LLRenderTarget* depth_target)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LLRenderTarget* deferred_target = &mRT->deferredScreen;
@@ -7730,7 +7728,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
if (channel > -1)
{
- gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ if (depth_target)
+ {
+ gGL.getTexUnit(channel)->bind(depth_target, TRUE);
+ }
+ else
+ {
+ gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ }
stop_glerror();
}
@@ -8445,18 +8450,48 @@ void LLPipeline::doAtmospherics()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ if (sImpostorRender)
+ { // do not attempt atmospherics on impostors
+ return;
+ }
+
if (RenderDeferredAtmospheric)
{
+ {
+ // copy depth buffer for use in haze shader (use water displacement map as temp storage)
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
+
+ mRT->screen.flush();
+ dst.bindTarget();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(&src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+ gGL.setColorMask(false, false);
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst.flush();
+ mRT->screen.bindTarget();
+ }
+
LLGLEnable blend(GL_BLEND);
gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
-
gGL.setColorMask(true, true);
// apply haze
LLGLSLShader& haze_shader = gHazeProgram;
LL_PROFILE_GPU_ZONE("haze");
- bindDeferredShader(haze_shader);
+ bindDeferredShader(haze_shader, nullptr, &mWaterDis);
LLEnvironment& environment = LLEnvironment::instance();
haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -8479,9 +8514,39 @@ void LLPipeline::doAtmospherics()
void LLPipeline::doWaterHaze()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ if (sImpostorRender)
+ { // do not attempt water haze on impostors
+ return;
+ }
if (RenderDeferredAtmospheric)
{
+ // copy depth buffer for use in haze shader (use water displacement map as temp storage)
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
+
+ mRT->screen.flush();
+ dst.bindTarget();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(&src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+ gGL.setColorMask(false, false);
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst.flush();
+ mRT->screen.bindTarget();
+ }
+
LLGLEnable blend(GL_BLEND);
gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA);
@@ -8491,7 +8556,7 @@ void LLPipeline::doWaterHaze()
LLGLSLShader& haze_shader = gHazeWaterProgram;
LL_PROFILE_GPU_ZONE("haze");
- bindDeferredShader(haze_shader);
+ bindDeferredShader(haze_shader, nullptr, &mWaterDis);
haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
@@ -8509,7 +8574,7 @@ void LLPipeline::doWaterHaze()
else
{
//render water patches like LLDrawPoolWater does
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+ LLGLDepthTest depth(GL_FALSE);
LLGLDisable cull(GL_CULL_FACE);
gGLLastMatrix = NULL;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index fe2dcdc141..2d58da8fb5 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -306,7 +306,7 @@ public:
// if setup is true, wil lset texture compare mode function and filtering options
void bindShadowMaps(LLGLSLShader& shader);
void bindDeferredShaderFast(LLGLSLShader& shader);
- void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
+ void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr, LLRenderTarget* depth_target = nullptr);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 081e135b3e..933b5c3fa6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -3282,6 +3282,16 @@
function="Advanced.ToggleRenderType"
parameter="bump" />
+