Skip to content

Commit ce06e17

Browse files
committed
Fix the alpha gamma value when rendering legacy diffuse textures and materials
With the new PBR renderer, the faces using alpha blend with a simple diffuse texture or a Blinn-Phong material are badly rendered (way too opaque), which breaks rendering for an enormous amount of "legacy" (pre-PBR) objects. It has been proposed (1) to introduce a new "alpha gamma" parameter for faces, that would need to be set on legacy contents in order to fix the latter, which would also force to introduce a no-mod permission exception for this parameter alone, so that people owning a legacy no-mod object could still manually edit it to fix its rendering. This proposal is ill-conceived: how can anyone, in their right mind, hope that *every* owner of *every* "legacy" object using alpha blending in SL will bother to edit the said object (supposing they even know they can do it and how to do it) ??? The *proper* solution is to fix the renderer itself, and automatically apply a gamma correction factor to faces *not bearing* a glTF material. This commit implements this fix (which is now part of the Cool VL Viewer and proves that it works very nicely). It implements the same kind of rendering fix (at the shader level) as (2), but instead automatically detects faces rendering with a PBR material, and applies the correction to all faces *not* using such a material. In the event you want to let contents creators use linear alpha channels in objects mixing legacy BP materials and PBR materials (even though I fail to see how a creator would want to do that at all), I suggest you implement an additional flag for faces, that could be set to antagonize this auto-fix (this would let full leeway about the alpha channel scale for newly created contents while not requiring to implement some weird no-mod permission exception since this flag would be set by the creator themselves). In the mean time, this fix solves one of the remaining major issues seen with the PBR renderer. (1) https://feedback.secondlife.com/bug-reports/p/pbr-client-opacity-issue-on-textures-with-alpha-channel-windows (2) secondlife#2668
1 parent cefee59 commit ce06e17

File tree

8 files changed

+31
-5
lines changed

8 files changed

+31
-5
lines changed

indra/llrender/llshadermgr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,7 @@ void LLShaderMgr::initAttribsAndUniforms()
13131313

13141314
mReservedUniforms.push_back("minimum_alpha");
13151315
mReservedUniforms.push_back("emissive_brightness");
1316+
mReservedUniforms.push_back("alpha_gamma");
13161317

13171318
// Deferred
13181319
mReservedUniforms.push_back("shadow_matrix");

indra/llrender/llshadermgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class LLShaderMgr
156156

157157
MINIMUM_ALPHA, // "minimum_alpha"
158158
EMISSIVE_BRIGHTNESS, // "emissive_brightness"
159+
ALPHA_GAMMA, // "alpha_gamma"
159160

160161
DEFERRED_SHADOW_MATRIX, // "shadow_matrix"
161162
DEFERRED_ENV_MAT, // "env_mat"

indra/newview/app_settings/settings.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7478,6 +7478,17 @@
74787478
<key>Value</key>
74797479
<integer>0</integer>
74807480
</map>
7481+
<key>RenderLegacyAlphaGamma</key>
7482+
<map>
7483+
<key>Comment</key>
7484+
<string>Gamma correction factor (clamped between 1.0 and 2.2) used to render non-PBR faces with alpha blend. 1.0 to disable.</string>
7485+
<key>Persist</key>
7486+
<integer>1</integer>
7487+
<key>Type</key>
7488+
<string>F32</string>
7489+
<key>Value</key>
7490+
<real>1.8</real>
7491+
</map>
74817492
<key>RenderLocalLightCount</key>
74827493
<map>
74837494
<key>Comment</key>

indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ uniform mat3 env_mat;
3737
uniform vec3 sun_dir;
3838
uniform vec3 moon_dir;
3939
uniform int classic_mode;
40+
uniform float alpha_gamma;
4041

4142
#ifdef USE_DIFFUSE_TEX
4243
uniform sampler2D diffuseMap;
@@ -215,7 +216,7 @@ void main()
215216
}
216217

217218
color.rgb = diffuse_srgb.rgb;
218-
color.a = final_alpha;
219+
color.a = pow(final_alpha, alpha_gamma);
219220

220221
#else // FOR_IMPOSTOR
221222

@@ -263,7 +264,7 @@ void main()
263264

264265
vec4 color = vec4(0.0);
265266

266-
color.a = final_alpha;
267+
color.a = pow(final_alpha, alpha_gamma);
267268

268269
color.rgb = irradiance;
269270
if (classic_mode > 0)

indra/newview/app_settings/shaders/class3/deferred/materialF.glsl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
3838
uniform int sun_up_factor;
3939
uniform int classic_mode;
40+
uniform float alpha_gamma;
4041

4142
vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);
4243
vec3 scaleSoftClipFragLinear(vec3 l);
@@ -420,7 +421,7 @@ void main()
420421

421422
glare *= 1.0-emissive;
422423
glare = min(glare, 1.0);
423-
float al = max(diffcol.a, glare) * vertex_color.a;
424+
float al = pow(max(diffcol.a, glare) * vertex_color.a, alpha_gamma);
424425
float final_scale = 1;
425426
if (classic_mode > 0)
426427
final_scale = 1.1;

indra/newview/lldrawpoolalpha.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
595595
above_water = !above_water;
596596
}
597597

598+
// Gamma correction factor for alpha faces without PBR material, in PBR
599+
// rendering mode. HB
600+
static LLCachedControl<F32> legacy_gamma(gSavedSettings,
601+
"RenderLegacyAlphaGamma");
602+
F32 alpha_gamma = llclamp((F32)legacy_gamma, 1.f, 2.2f);
598603

599604
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
600605
{
@@ -760,6 +765,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
760765
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[VRED], spec_color.mV[VGREEN], spec_color.mV[VBLUE], spec_color.mV[VALPHA]);
761766
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
762767
current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
768+
// Fix for alpha gamma on non-PBR (legacy) faces. HB
769+
current_shader->uniform1f(LLShaderMgr::ALPHA_GAMMA, params.mHasPBR ? 1.f : alpha_gamma);
763770
}
764771
}
765772

indra/newview/llspatialpartition.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ class LLDrawInfo final : public LLRefCount
136136
U8 mShiny = 0;
137137
bool mFullbright = false;
138138
bool mHasGlow = false;
139+
// Set to 'true' when a PBR material is actually used to render this face. HB
140+
bool mHasPBR = false;
139141

140142
struct CompareTexture
141143
{

indra/newview/llvovolume.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5372,10 +5372,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
53725372

53735373
U8 index = facep->getTextureIndex();
53745374

5375+
bool has_pbr = false;
53755376
LLMaterial* mat = nullptr;
5376-
53775377
LLUUID mat_id;
5378-
53795378
auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial();
53805379
llassert(gltf_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr);
53815380
if (gltf_mat != nullptr)
@@ -5384,6 +5383,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
53845383
if (!facep->hasMedia() || (tex && tex->getType() != LLViewerTexture::MEDIA_TEXTURE))
53855384
{ // no media texture, face texture will be unused
53865385
tex = nullptr;
5386+
has_pbr = true;
53875387
}
53885388
}
53895389
else
@@ -5447,6 +5447,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
54475447
info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
54485448
#endif
54495449
info->mMaterialID == mat_id &&
5450+
info->mHasPBR == has_pbr &&
54505451
info->mFullbright == fullbright &&
54515452
info->mBump == bump &&
54525453
(!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
@@ -5501,6 +5502,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
55015502
draw_info->mShaderMask = shader_mask;
55025503
draw_info->mAvatar = facep->mAvatar;
55035504
draw_info->mSkinInfo = facep->mSkinInfo;
5505+
draw_info->mHasPBR = has_pbr;
55045506

55055507
if (gltf_mat)
55065508
{

0 commit comments

Comments
 (0)