summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolterrain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolterrain.cpp')
-rw-r--r--indra/newview/lldrawpoolterrain.cpp322
1 files changed, 291 insertions, 31 deletions
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index c86c4b3472..2897f3d749 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -54,8 +54,9 @@
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
-S32 LLDrawPoolTerrain::sDetailMode = 1;
+S32 LLDrawPoolTerrain::sPBRDetailMode = 0;
F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE;
+F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE;
static LLGLSLShader* sShader = NULL;
static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow");
@@ -66,7 +67,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
{
// Hack!
sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
- sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
+ sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale");
+ sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail");
mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD);
//gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
@@ -105,13 +107,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask()
void LLDrawPoolTerrain::prerender()
{
- sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
-}
-
-//static
-S32 LLDrawPoolTerrain::getDetailMode()
-{
- return sDetailMode;
+ sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail");
}
void LLDrawPoolTerrain::boostTerrainDetailTextures()
@@ -119,21 +115,13 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- for (S32 i = 0; i < 4; i++)
- {
- compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- compp->mDetailTextures[i]->addTextureStats(1024.f * 1024.f);
- }
+ compp->boost();
}
void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
-
- sShader = &gDeferredTerrainProgram;
-
- sShader->bind();
}
void LLDrawPoolTerrain::endDeferredPass(S32 pass)
@@ -204,19 +192,8 @@ void LLDrawPoolTerrain::drawLoop()
{
LLFace *facep = *iter;
- LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix);
-
- if (model_matrix != gGLLastMatrix)
- {
- llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
- gGLLastMatrix = model_matrix;
- gGL.loadMatrix(gGLModelView);
- if (model_matrix)
- {
- gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
- }
- gPipeline.mMatrixOpCount++;
- }
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
+ LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix);
facep->renderIndexed();
}
@@ -225,9 +202,34 @@ void LLDrawPoolTerrain::drawLoop()
void LLDrawPoolTerrain::renderFullShader()
{
+ const bool use_local_materials = gLocalTerrainMaterials.materialsReady(true, false);
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
+ const bool use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::Type::TEXTURE);
+
+ if (use_textures)
+ {
+ // Use textures
+ sShader = &gDeferredTerrainProgram;
+ sShader->bind();
+ renderFullShaderTextures();
+ }
+ else
+ {
+ // Use materials
+ sShader = &gDeferredPBRTerrainProgram;
+ sShader->bind();
+ renderFullShaderPBR(use_local_materials);
+ }
+}
+
+void LLDrawPoolTerrain::renderFullShaderTextures()
+{
+ // 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->mDetailTextures[0];
LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
@@ -322,6 +324,264 @@ void LLDrawPoolTerrain::renderFullShader()
gGL.getTexUnit(detail0)->activate();
}
+// *TODO: Investigate use of bindFast for PBR terrain textures
+void LLDrawPoolTerrain::renderFullShaderPBR(bool local_materials)
+{
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ LLPointer<LLFetchedGLTFMaterial> (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailRenderMaterials;
+
+ constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT;
+#ifdef SHOW_ASSERT
+ constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
+ llassert(shader_material_count == terrain_material_count);
+#endif
+
+ if (local_materials)
+ {
+ // Override region terrain with the global local override terrain
+ fetched_materials = &gLocalTerrainMaterials.mDetailRenderMaterials;
+ }
+ const LLGLTFMaterial* materials[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ materials[i] = (*fetched_materials)[i].get();
+ if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; }
+ }
+
+ 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 = nullptr;
+ LLViewerTexture* detail_normal_texturep = nullptr;
+ LLViewerTexture* detail_metalrough_texturep = nullptr;
+ LLViewerTexture* detail_emissive_texturep = nullptr;
+
+ const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get();
+ if (fetched_material)
+ {
+ detail_basecolor_texturep = fetched_material->mBaseColorTexture;
+ detail_normal_texturep = fetched_material->mNormalTexture;
+ detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture;
+ detail_emissive_texturep = fetched_material->mEmissiveTexture;
+ }
+
+ detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
+ if (detail_basecolor_texturep)
+ {
+ gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_basecolor[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_basecolor[i])->activate();
+
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ if (detail_normal_texturep)
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
+ }
+ gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_normal[i])->activate();
+ }
+
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ if (detail_metalrough_texturep)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+ }
+
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
+ if (detail_emissive_texturep)
+ {
+ gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_emissive[i])->activate();
+ }
+ }
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader);
+
+ // Like for PBR materials, PBR terrain texture transforms are defined by
+ // the KHR_texture_transform spec, but with the following notable
+ // differences:
+ // 1) The PBR UV origin is defined as the Southwest corner of the region,
+ // with positive U facing East and positive V facing South.
+ // 2) There is an additional scaling factor RenderTerrainPBRScale. If
+ // we've done our math right, RenderTerrainPBRScale should not affect the
+ // overall behavior of KHR_texture_transform
+ // 3) There is only one texture transform per material, whereas
+ // KHR_texture_transform supports one texture transform per texture info.
+ // i.e. this isn't fully compliant with KHR_texture_transform, but is
+ // compliant when all texture infos used by a material have the same
+ // texture transform.
+ LLGLTFMaterial::TextureTransform::PackTight transforms_packed[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get();
+ LLGLTFMaterial::TextureTransform transform;
+ if (fetched_material)
+ {
+ transform = fetched_material->mTextureTransform[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR];
+#ifdef SHOW_ASSERT
+ // Assert condition where the contents of the texture transforms
+ // differ per texture info - we currently don't support this case.
+ for (U32 ti = 1; ti < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++ti)
+ {
+ llassert(fetched_material->mTextureTransform[0] == fetched_material->mTextureTransform[ti]);
+ }
+#endif
+ }
+ // *NOTE: Notice here we are combining the scale from
+ // RenderTerrainPBRScale into the KHR_texture_transform. This only
+ // works if the scale is uniform and no other transforms are
+ // applied to the terrain UVs.
+ transform.mScale.mV[VX] *= sPBRDetailScale;
+ transform.mScale.mV[VY] *= sPBRDetailScale;
+
+ transform.getPackedTight(transforms_packed[i]);
+ }
+ const U32 transform_param_count = LLGLTFMaterial::TextureTransform::PACK_TIGHT_SIZE * terrain_material_count;
+ constexpr U32 vec4_size = 4;
+ const U32 transform_vec4_count = (transform_param_count + (vec4_size - 1)) / vec4_size;
+ llassert(transform_vec4_count == 5); // If false, need to update shader
+ shader->uniform4fv(LLShaderMgr::TERRAIN_TEXTURE_TRANSFORMS, transform_vec4_count, (F32*)transforms_packed);
+
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+
+ //
+ // 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 LLGLTFMaterial* material = materials[i];
+
+ 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.0f;
+ if (material->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ // dividing the alpha cutoff by transparency here allows the shader to compare against
+ // the alpha value of the texture without needing the transparency value
+ min_alpha = material->mAlphaCutoff/material->mBaseColor.mV[3];
+ }
+ minimum_alphas[i] = min_alpha;
+ }
+ shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ 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]);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ 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);
+
+ gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(alpha_ramp)->disable();
+ gGL.getTexUnit(alpha_ramp)->activate();
+
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ 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();
+
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_normal[i])->disable();
+ gGL.getTexUnit(detail_normal[i])->activate();
+ }
+
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_metalrough[i])->disable();
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+ }
+
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
+ {
+ gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_emissive[i])->disable();
+ gGL.getTexUnit(detail_emissive[i])->activate();
+ }
+ }
+}
+
void LLDrawPoolTerrain::hilightParcelOwners()
{
{ //use fullbright shader for highlighting