summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2023-10-13 09:57:57 -0700
committerCosmic Linden <cosmic@lindenlab.com>2023-10-13 09:57:57 -0700
commit5d046d8835563fcad9e8dcf948d889d9ccec41d7 (patch)
treead223ccf798181611d23e470a8c186d1fd2e0cab /indra
parenta7cd5f6ef9d80e77eaf87cfc605d32605f0916f1 (diff)
DRTVWR-592: (WIP) (does not work) PBR terrain rendering - compiles, but doesn't render properly just yet
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl8
-rw-r--r--indra/newview/lldrawpoolterrain.cpp154
3 files changed, 123 insertions, 80 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
index 4a0b324558..60e5776bc6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
@@ -27,7 +27,6 @@ out vec4 frag_data[4];
uniform sampler2D alpha_ramp;
-// TODO: Bind the right textures and uniforms during shader setup
// *TODO: Configurable quality level which disables PBR features on machines
// with limited texture availability
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
@@ -65,7 +64,7 @@ vec2 encode_normal(vec3 n);
vec3 linear_to_srgb(vec3 c);
vec3 srgb_to_linear(vec3 c);
-// TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly
+// *TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly
float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal)
{
return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal );
@@ -81,13 +80,27 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal)
return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal );
}
-vec4 sample_and_mix_color(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
+vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
+{
+ vec3[4] samples;
+ samples[0] = srgb_to_linear(texture2D(tex0, texcoord).xyz);
+ samples[1] = srgb_to_linear(texture2D(tex1, texcoord).xyz);
+ samples[2] = srgb_to_linear(texture2D(tex2, texcoord).xyz);
+ samples[3] = srgb_to_linear(texture2D(tex3, texcoord).xyz);
+ return terrain_mix(samples, alpha1, alpha2, alphaFinal);
+}
+
+vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
{
vec4[4] samples;
- samples[0] = srgb_to_linear(texture2D(tex0, texcoord));
- samples[1] = srgb_to_linear(texture2D(tex1, texcoord));
- samples[2] = srgb_to_linear(texture2D(tex2, texcoord));
- samples[3] = srgb_to_linear(texture2D(tex3, texcoord));
+ samples[0] = texture2D(tex0, texcoord);
+ samples[1] = texture2D(tex1, texcoord);
+ samples[2] = texture2D(tex2, texcoord);
+ samples[3] = texture2D(tex3, texcoord);
+ samples[0].xyz = srgb_to_linear(samples[0].xyz);
+ samples[1].xyz = srgb_to_linear(samples[1].xyz);
+ samples[2].xyz = srgb_to_linear(samples[2].xyz);
+ samples[3].xyz = srgb_to_linear(samples[3].xyz);
return terrain_mix(samples, alpha1, alpha2, alphaFinal);
}
@@ -107,7 +120,7 @@ void main()
float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
- vec4 base_color = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_basecolor, detail_1_basecolor, detail_2_basecolor, detail_3_basecolor);
+ vec4 base_color = sample_and_mix_color4(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color);
float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal);
if (base_color.a < minimum_alpha)
{
@@ -116,14 +129,14 @@ void main()
vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal);
vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness);
- vec4 emissive_texture = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive);
+ vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive);
vec4 baseColorFactor = terrain_mix(baseColorFactors, alpha1, alpha2, alphaFinal);
float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal);
float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal);
vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal);
- vec3 col = baseColorFactor.rgb * srgb_to_linear(basecolor.rgb);
+ vec3 col = baseColorFactor.rgb * srgb_to_linear(base_color.rgb);
// from mikktspace.com
vec3 vNt = normal_texture.xyz*2.0-1.0;
@@ -141,10 +154,10 @@ void main()
// metal 0.0
vec3 spec = metallic_roughness.rgb;
- spec.g *= roughness_factor;
- spec.b *= metallic_factor;
+ spec.g *= roughnessFactor;
+ spec.b *= metallicFactor;
- vec3 emissive = emssive_color;
+ vec3 emissive = emissiveColor;
emissive *= emissive_texture.rgb;
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
@@ -152,7 +165,7 @@ void main()
frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse
frag_data[1] = max(vec4(spec.rgb,baseColorFactor.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
- frag_data[2] = max(vec4(encode_normal(tnorm), baseColorFactor.a, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), vec4(0)); // normal, environment intensity, flags
+ frag_data[2] = max(vec4(encode_normal(tnorm), baseColorFactor.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags
frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
index cbfe9f3ea5..6037a58c0d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
@@ -73,9 +73,9 @@ void main()
// *NOTE: KHR texture transform is ignored for now
vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
- vec4 t = vec4(texcoord1,0,1);
+ vec4 tc = vec4(texcoord1,0,1);
- vary_texcoord0.zw = t.xy;
- vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
- vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
+ vary_texcoord0.zw = tc.xy;
+ vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0);
+ vary_texcoord1.zw = tc.xy-vec2(1.0, 0.0);
}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 16d982ea90..2a0a7bad1c 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -375,16 +375,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
-
- LLViewerTexture *detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture;
- LLViewerTexture *detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture;
- LLViewerTexture *detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture;
- LLViewerTexture *detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture;
- LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep;
- if (!detail_texture0p) { detail_texture0p = blank; }
- if (!detail_texture1p) { detail_texture1p = blank; }
- if (!detail_texture2p) { detail_texture2p = blank; }
- if (!detail_texture3p) { detail_texture3p = blank; }
+ LLPointer<LLFetchedGLTFMaterial>(& materials)[LLVLComposition::ASSET_COUNT] = compp->mDetailMaterials;
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
@@ -395,13 +386,39 @@ void LLDrawPoolTerrain::renderFullShaderPBR()
tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x);
tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y);
- //
- // detail texture 0
- //
- S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
- gGL.getTexUnit(detail0)->bind(detail_texture0p);
- gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail0)->activate();
+ constexpr U32 terrain_material_count = LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
+ S32 detail_basecolor[terrain_material_count];
+ S32 detail_normal[terrain_material_count];
+ S32 detail_metalrough[terrain_material_count];
+ S32 detail_emissive[terrain_material_count];
+
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ LLViewerTexture *detail_basecolor_texturep = materials[i]->mBaseColorTexture;
+ LLViewerTexture *detail_normal_texturep = materials[i]->mNormalTexture;
+ LLViewerTexture *detail_metalrough_texturep = materials[i]->mMetallicRoughnessTexture;
+ LLViewerTexture *detail_emissive_texturep = materials[i]->mEmissiveTexture;
+
+ detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
+ gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep);
+ gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_basecolor[i])->activate();
+
+ detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
+ gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_normal[i])->activate();
+
+ detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
+ gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+
+ detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
+ gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep);
+ gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_emissive[i])->activate();
+ }
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
llassert(shader);
@@ -412,67 +429,80 @@ void LLDrawPoolTerrain::renderFullShaderPBR()
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
//
- // detail texture 1
- //
- S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
- gGL.getTexUnit(detail1)->bind(detail_texture1p);
- gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail1)->activate();
-
- // detail texture 2
- //
- S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
- gGL.getTexUnit(detail2)->bind(detail_texture2p);
- gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail2)->activate();
-
-
- // detail texture 3
- //
- S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
- gGL.getTexUnit(detail3)->bind(detail_texture3p);
- gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail3)->activate();
-
- //
// Alpha Ramp
//
S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ //
+ // GLTF uniforms
+ //
+
+ LLColor4 base_color_factors[terrain_material_count];
+ F32 metallic_factors[terrain_material_count];
+ F32 roughness_factors[terrain_material_count];
+ LLColor3 emissive_colors[terrain_material_count];
+ F32 minimum_alphas[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ const LLFetchedGLTFMaterial* material = materials[i].get();
+
+ base_color_factors[i] = material->mBaseColor;
+ metallic_factors[i] = material->mMetallicFactor;
+ roughness_factors[i] = material->mRoughnessFactor;
+ emissive_colors[i] = material->mEmissiveColor;
+ // glTF 2.0 Specification 3.9.4. Alpha Coverage
+ // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK
+ // Use 0 here due to GLTF terrain blending (LLGLTFMaterial::bind uses
+ // -1 for easier debugging)
+ F32 min_alpha = 0.f;
+ if (material->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ min_alpha = material->mAlphaCutoff;
+ }
+
+ }
+ shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors);
+ shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]);
+ shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]);
+ shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors);
+ shader->uniform4f(LLShaderMgr::TERRAIN_MINIMUM_ALPHAS, minimum_alphas[0], minimum_alphas[1], minimum_alphas[2], minimum_alphas[3]);
+
// GL_BLEND disabled by default
drawLoop();
// Disable multitexture
+
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(alpha_ramp)->disable();
gGL.getTexUnit(alpha_ramp)->activate();
-
- gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail3)->disable();
- gGL.getTexUnit(detail3)->activate();
- gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail2)->disable();
- gGL.getTexUnit(detail2)->activate();
-
- gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail1)->disable();
- gGL.getTexUnit(detail1)->activate();
-
- //----------------------------------------------------------------------------
- // Restore Texture Unit 0 defaults
-
- gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail0)->activate();
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
+
+ gGL.getTexUnit(detail_basecolor[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_basecolor[i])->disable();
+ gGL.getTexUnit(detail_basecolor[i])->activate();
+
+ gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_normal[i])->disable();
+ gGL.getTexUnit(detail_normal[i])->activate();
+
+ gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_metalrough[i])->disable();
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+
+ gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_emissive[i])->disable();
+ gGL.getTexUnit(detail_emissive[i])->activate();
+ }
}
void LLDrawPoolTerrain::hilightParcelOwners()