From 55f597e2ec363b5cb22fa8f7f5694f7ef6a17772 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:28 -0700 Subject: DRTVWR-592: Allow using RGBA textures for terrain, as the texture uploader does not consolidate opaque textures --- indra/llimage/llimage.cpp | 2 +- indra/newview/llfloaterregioninfo.cpp | 2 +- indra/newview/skins/default/xui/en/notifications.xml | 4 ++-- indra/newview/skins/default/xui/en/panel_region_terrain.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 031471d1fe..a96b6601bd 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1110,7 +1110,7 @@ void LLImageRaw::composite( LLImageRaw* src ) return; } - llassert(3 == src->getComponents()); + llassert((3 == src->getComponents()) || (4 == src->getComponents())); llassert(3 == dst->getComponents()); if( 3 == dst->getComponents() ) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index da7a4733c7..49ed58e766 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1338,7 +1338,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL; - if (components != 3) + if (components != 3 && components != 4) { LLSD args; args["TEXTURE_NUM"] = i+1; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f77b235408..5404ece6b4 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3980,7 +3980,7 @@ Are you sure you want to return objects owned by [USER_NAME]? Couldn't set region textures: Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. -Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. fail @@ -3991,7 +3991,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller ima Couldn't set region textures: Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. -Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. - Terrain Textures (requires 1024x1024, 24 bit .tga files) + Terrain Textures (maximum size: 1024x1024) Date: Fri, 13 Oct 2023 09:56:34 -0700 Subject: DRTVWR-592: (WIP) Add material terrain selection to GUI --- indra/newview/llfloaterregioninfo.cpp | 83 ++++++++++++++++++++++ indra/newview/llfloaterregioninfo.h | 3 + indra/newview/llpanelface.cpp | 2 +- indra/newview/lltexturectrl.cpp | 60 +++++++++------- indra/newview/lltexturectrl.h | 32 ++++++--- .../skins/default/xui/en/panel_region_terrain.xml | 76 ++++++++++++++++++-- 6 files changed, 212 insertions(+), 44 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 49ed58e766..8c795432ea 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1394,12 +1394,20 @@ BOOL LLPanelRegionTerrainInfo::postBuild() initCtrl("terrain_raise_spin"); initCtrl("terrain_lower_spin"); + getChild("terrain_material_type")->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); initCtrl(buffer); } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + initCtrl(buffer); + } for(S32 i = 0; i < CORNER_COUNT; ++i) { @@ -1419,6 +1427,81 @@ BOOL LLPanelRegionTerrainInfo::postBuild() return LLPanelRegionInfo::postBuild(); } +enum class TerrainMaterialType +{ + TEXTURE, + PBR_MATERIAL, + COUNT +}; + +TerrainMaterialType material_type_from_index(S32 index) +{ + if (index == 0) + { + return TerrainMaterialType::TEXTURE; + } + if (index == 1) + { + return TerrainMaterialType::PBR_MATERIAL; + } + return TerrainMaterialType::COUNT; +} + +// virtual +void LLPanelRegionTerrainInfo::refresh() +{ + std::string buffer; + + bool has_material_assets = false; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + LLTextureCtrl* material_ctrl = getChild(buffer); + if (material_ctrl && material_ctrl->getImageAssetID().notNull()) + { + has_material_assets = true; + break; + } + } + + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) + { + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + material_type_ctrl->setEnabled(!(is_material_selected && has_material_assets)); + } +} + +void LLPanelRegionTerrainInfo::onSelectMaterialType() +{ + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (!material_type_ctrl) { return; } + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool show_texture_controls = material_type == TerrainMaterialType::TEXTURE; + const bool show_material_controls = material_type == TerrainMaterialType::PBR_MATERIAL; + std::string buffer; + LLTextureCtrl* texture_ctrl; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + texture_ctrl = getChild(buffer); + if (texture_ctrl) + { + texture_ctrl->setVisible(show_texture_controls); + } + } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + texture_ctrl = getChild(buffer); + if (texture_ctrl) + { + texture_ctrl->setVisible(show_material_controls); + } + } +} + // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index c34dbb62e8..7b22002806 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -258,6 +258,9 @@ public: //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button + void refresh() override; + void onSelectMaterialType(); + virtual BOOL sendUpdate(); static void onClickDownloadRaw(void*); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7d6015f557..ba379f77d8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -328,7 +328,7 @@ BOOL LLPanelFace::postBuild() pbr_ctrl->setImmediateFilterPermMask(PERM_NONE); pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); pbr_ctrl->setBakeTextureEnabled(false); - pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL); + pbr_ctrl->setInventoryPickType(EPickInventoryType::MATERIAL); } mTextureCtrl = getChild("texture control"); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 0dd1ff5483..ef58bba71e 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -176,7 +176,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mSetImageAssetIDCallback(NULL), mOnUpdateImageStatsCallback(NULL), mBakeTextureEnabled(FALSE), - mInventoryPickType(LLTextureCtrl::PICK_TEXTURE) + mInventoryPickType(EPickInventoryType::TEXTURE) { mCanApplyImmediately = can_apply_immediately; buildFromFile("floater_texture_ctrl.xml"); @@ -356,11 +356,11 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( bool is_material = cargo_type == DAD_MATERIAL; bool allow_dnd = false; - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { allow_dnd = is_material; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { allow_dnd = is_texture || is_mesh; } @@ -570,7 +570,7 @@ void LLFloaterTexturePicker::draw() mGLTFMaterial = NULL; if (mImageAssetID.notNull()) { - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID); llassert(mGLTFMaterial == nullptr || dynamic_cast(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr); @@ -901,7 +901,7 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) self->getChild("l_bake_use_texture_combo_box")->setVisible(index == 2 ? TRUE : FALSE); bool pipette_visible = (index == 0) - && (self->mInventoryPickType != LLTextureCtrl::PICK_MATERIAL); + && (self->mInventoryPickType != EPickInventoryType::MATERIAL); self->getChild("Pipette")->setVisible(pipette_visible); if (index == 2) @@ -966,15 +966,15 @@ void LLFloaterTexturePicker::onBtnAdd(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata; - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (self->mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL_TEXTURE, true); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (self->mInventoryPickType == EPickInventoryType::TEXTURE) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_IMAGE, true); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (self->mInventoryPickType == EPickInventoryType::MATERIAL) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL, true); } @@ -1229,16 +1229,16 @@ void LLFloaterTexturePicker::refreshLocalList() { mLocalScrollCtrl->clearRows(); - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == EPickInventoryType::MATERIAL) { LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } @@ -1248,18 +1248,18 @@ void LLFloaterTexturePicker::refreshInventoryFilter() { U32 filter_types = 0x0; - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == EPickInventoryType::MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } @@ -1294,13 +1294,13 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) onModeSelect(0, this); } -void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type) +void LLFloaterTexturePicker::setInventoryPickType(EPickInventoryType type) { mInventoryPickType = type; refreshLocalList(); refreshInventoryFilter(); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { getChild("Pipette")->setVisible(false); } @@ -1316,7 +1316,7 @@ void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryT setTitle(pick + mLabel); } - else if(mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if(mInventoryPickType == EPickInventoryType::MATERIAL) { setTitle(getString("pick_material")); } @@ -1352,16 +1352,16 @@ void LLFloaterTexturePicker::onPickerCallback(const std::vector& fi LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)handle.get(); self->mLocalScrollCtrl->clearRows(); - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (self->mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (self->mInventoryPickType == EPickInventoryType::TEXTURE) { LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (self->mInventoryPickType == EPickInventoryType::MATERIAL) { LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } @@ -1374,7 +1374,7 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) if (inventory_item_id.notNull()) { LLToolPipette::getInstance()->setResult(TRUE, ""); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { // tes have no data about material ids // Plus gltf materials are layered with overrides, @@ -1425,7 +1425,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mShowLoadingPlaceholder( TRUE ), mOpenTexPreview(false), mBakeTextureEnabled(true), - mInventoryPickType(PICK_TEXTURE), + mInventoryPickType(p.pick_type), mImageAssetID(p.image_id), mDefaultImageAssetID(p.default_image_id), mDefaultImageName(p.default_image_name), @@ -1680,7 +1680,7 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) if (!mOpenTexPreview) { showPicker(FALSE); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { //grab materials first... LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL)); @@ -1860,11 +1860,11 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, bool is_material = cargo_type == DAD_MATERIAL; bool allow_dnd = false; - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { allow_dnd = is_material; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { allow_dnd = is_texture || is_mesh; } @@ -2097,6 +2097,16 @@ LLSD LLTextureCtrl::getValue() const return LLSD(getImageAssetID()); } +namespace LLInitParam +{ + void TypeValues::declareValues() + { + declare("texture_material", EPickInventoryType::TEXTURE_MATERIAL); + declare("texture", EPickInventoryType::TEXTURE); + declare("material", EPickInventoryType::MATERIAL); + } +} + diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index c66e618782..28630d4ac4 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -64,10 +64,25 @@ bool get_is_predefined_texture(LLUUID asset_id); LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false); bool get_can_copy_texture(LLUUID image_id); +enum class EPickInventoryType +{ + TEXTURE_MATERIAL = 0, + TEXTURE = 1, + MATERIAL = 2, +}; + +namespace LLInitParam +{ + template<> + struct TypeValues : public TypeValuesHelper + { + static void declareValues(); + }; +} + ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl - class LLTextureCtrl : public LLUICtrl { @@ -79,19 +94,13 @@ public: TEXTURE_CANCEL } ETexturePickOp; - typedef enum e_pick_inventory_type - { - PICK_TEXTURE_MATERIAL = 0, - PICK_TEXTURE = 1, - PICK_MATERIAL = 2, - } EPickInventoryType; - public: struct Params : public LLInitParam::Block { Optional image_id; Optional default_image_id; Optional default_image_name; + Optional pick_type; Optional allow_no_texture; Optional can_apply_immediately; Optional no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty @@ -109,6 +118,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), + pick_type("pick_type", EPickInventoryType::TEXTURE), allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), @@ -260,7 +270,7 @@ private: S32 mLabelWidth; bool mOpenTexPreview; bool mBakeTextureEnabled; - LLTextureCtrl::EPickInventoryType mInventoryPickType; + EPickInventoryType mInventoryPickType; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -350,7 +360,7 @@ public: void setLocalTextureEnabled(BOOL enabled); void setBakeTextureEnabled(BOOL enabled); - void setInventoryPickType(LLTextureCtrl::EPickInventoryType type); + void setInventoryPickType(EPickInventoryType type); static void onPickerCallback(const std::vector& filenames, LLHandle handle); @@ -396,7 +406,7 @@ private: bool mCanApply; bool mCanPreview; bool mPreviewSettingChanged; - LLTextureCtrl::EPickInventoryType mInventoryPickType; + EPickInventoryType mInventoryPickType; texture_selected_callback mTextureSelectedCallback; diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 5e0dad445f..e36fb05647 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -76,29 +76,47 @@ left="8" top="30" width="460" /> + + + + - Terrain Textures (maximum size: 1024x1024) + width="200"> + Maximum size: 1024x1024 + + + + Date: Fri, 13 Oct 2023 09:56:39 -0700 Subject: DRTVWR-592: Use overrides, make mac build happy --- indra/newview/llfloaterregioninfo.h | 61 +++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 7b22002806..43a69e5804 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -75,9 +75,9 @@ class LLFloaterRegionInfo : public LLFloater public: - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; static void processEstateOwnerRequest(LLMessageSystem* msg, void**); @@ -98,7 +98,7 @@ public: static LLPanelRegionEnvironment* getPanelEnvironment(); // from LLPanel - virtual void refresh(); + void refresh() override; void onRegionChanged(); void requestRegionInfo(); @@ -145,7 +145,7 @@ public: virtual bool refreshFromRegion(LLViewerRegion* region); virtual bool estateUpdate(LLMessageSystem* msg) { return true; } - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); void enableButton(const std::string& btn_name, BOOL enable = TRUE); @@ -185,16 +185,15 @@ public: : LLPanelRegionInfo() {} ~LLPanelRegionGeneralInfo() {} - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; - // LLPanel - virtual BOOL postBuild(); + BOOL postBuild() override; void onBtnSet(); void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;} protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; void onClickKick(); void onKickCommit(const uuid_vec_t& ids); static void onClickKickAll(void* userdata); @@ -215,13 +214,13 @@ public: LLPanelRegionDebugInfo() : LLPanelRegionInfo(), mTargetAvatar() {} ~LLPanelRegionDebugInfo() {} - // LLPanel - virtual BOOL postBuild(); + + BOOL postBuild() override; - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; void onClickChooseAvatar(); void callbackAvatarID(const uuid_vec_t& ids, const std::vector names); @@ -248,9 +247,9 @@ public: LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {} ~LLPanelRegionTerrainInfo() {} - virtual BOOL postBuild(); // LLPanel + BOOL postBuild() override; - virtual bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator + bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region BOOL validateTextureSizes(); @@ -261,14 +260,15 @@ public: void refresh() override; void onSelectMaterialType(); - virtual BOOL sendUpdate(); - static void onClickDownloadRaw(void*); static void onClickUploadRaw(void*); static void onClickBakeTerrain(void*); bool callbackBakeTerrain(const LLSD& notification, const LLSD& response); bool callbackTextureHeights(const LLSD& notification, const LLSD& response); +protected: + BOOL sendUpdate() override; + private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; @@ -307,13 +307,12 @@ public: static void updateEstateName(const std::string& name); static void updateEstateOwnerName(const std::string& name); - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; virtual bool estateUpdate(LLMessageSystem* msg); - // LLPanel - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); - virtual void refresh(); + void refresh() override; void refreshFromEstate(); @@ -323,7 +322,7 @@ public: void setOwnerName(const std::string& name); protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; // confirmation dialog callback bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response); @@ -343,10 +342,9 @@ public: LLPanelEstateCovenant(); ~LLPanelEstateCovenant() {} - // LLPanel - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; virtual bool estateUpdate(LLMessageSystem* msg); // LLView overrides @@ -386,7 +384,7 @@ public: } EAssetStatus; protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; LLTextBox* mEstateNameText; LLTextBox* mEstateOwnerText; LLTextBox* mLastModifiedText; @@ -405,16 +403,19 @@ class LLPanelRegionExperiences : public LLPanelRegionInfo public: LLPanelRegionExperiences(){} - /*virtual*/ BOOL postBuild(); - virtual BOOL sendUpdate(); + BOOL postBuild() override; static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response); static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id); static void infoCallback(LLHandle handle, const LLSD& content); - bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; void sendPurchaseRequest()const; void processResponse( const LLSD& content ); + +protected: + BOOL sendUpdate() override; + private: void refreshRegionExperiences(); @@ -439,7 +440,7 @@ class LLPanelEstateAccess : public LLPanelRegionInfo public: LLPanelEstateAccess(); - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); void updateControls(LLViewerRegion* region); @@ -448,7 +449,7 @@ public: void setPendingUpdate(bool pending) { mPendingUpdate = pending; } bool getPendingUpdate() { return mPendingUpdate; } - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; private: void onClickAddAllowedAgent(); -- cgit v1.2.3 From 410ab689919cd2915afc4d881b58b749d477fffc Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:44 -0700 Subject: DRTVWR-592: (WIP) Save PBR material terrain (does not yet render) --- indra/newview/llfloaterregioninfo.cpp | 101 ++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8c795432ea..e87064bc63 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -606,6 +606,26 @@ LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment() return panel; } +enum class TerrainMaterialType +{ + TEXTURE, + PBR_MATERIAL, + COUNT +}; + +TerrainMaterialType material_type_from_index(S32 index) +{ + if (index == 0) + { + return TerrainMaterialType::TEXTURE; + } + if (index == 1) + { + return TerrainMaterialType::PBR_MATERIAL; + } + return TerrainMaterialType::COUNT; +} + // static LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain() { @@ -1321,6 +1341,17 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { + // *TODO: Don't early-exit in PBR material terrain editing mode, and + // instead do some reasonable checks that the PBR material is compatible + // with the terrain rendering pipeline. Err on the side of permissive. + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) + { + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + if (is_material_selected) { return TRUE; } + } + static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { @@ -1427,26 +1458,6 @@ BOOL LLPanelRegionTerrainInfo::postBuild() return LLPanelRegionInfo::postBuild(); } -enum class TerrainMaterialType -{ - TEXTURE, - PBR_MATERIAL, - COUNT -}; - -TerrainMaterialType material_type_from_index(S32 index) -{ - if (index == 0) - { - return TerrainMaterialType::TEXTURE; - } - if (index == 1) - { - return TerrainMaterialType::PBR_MATERIAL; - } - return TerrainMaterialType::COUNT; -} - // virtual void LLPanelRegionTerrainInfo::refresh() { @@ -1518,18 +1529,31 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) getChild("region_text")->setValue(LLSD(region->getName())); LLVLComposition* compp = region->getComposition(); - LLTextureCtrl* texture_ctrl; + + // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set the IDs on both pickers for now. + // *TODO: Determine the asset type of IDs, to determine which editing mode to display. + LLTextureCtrl* asset_ctrl; std::string buffer; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); - if(texture_ctrl) + asset_ctrl = getChild(buffer); + if(asset_ctrl) { LL_DEBUGS() << "Detail Texture " << i << ": " << compp->getDetailTextureID(i) << LL_ENDL; LLUUID tmp_id(compp->getDetailTextureID(i)); - texture_ctrl->setImageAssetID(tmp_id); + asset_ctrl->setImageAssetID(tmp_id); + } + } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl) + { + LLUUID tmp_id(compp->getDetailTextureID(i)); + asset_ctrl->setImageAssetID(tmp_id); } } @@ -1596,17 +1620,36 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() } } - LLTextureCtrl* texture_ctrl; + LLTextureCtrl* asset_ctrl; std::string id_str; LLMessageSystem* msg = gMessageSystem; + // Use material IDs instead of texture IDs if all material IDs are set + S32 materials_used = 0; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); - if(texture_ctrl) + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) + { + ++materials_used; + } + } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + if (materials_used == TERRAIN_TEXTURE_COUNT) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + } + else + { + buffer = llformat("texture_detail_%d", i); + asset_ctrl = getChild(buffer); + } + if(asset_ctrl) { - LLUUID tmp_id(texture_ctrl->getImageAssetID()); + LLUUID tmp_id(asset_ctrl->getImageAssetID()); tmp_id.toString(id_str); buffer = llformat("%d %s", i, id_str.c_str()); strings.push_back(buffer); -- cgit v1.2.3 From 2d10941459cf66d34073925c136d70bd6dbece3f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:49 -0700 Subject: DRTVWR-592: (WIP) More work on terrain texture editing GUI --- indra/newview/llfloaterregioninfo.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index e87064bc63..ff7012efb5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1624,15 +1624,24 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() std::string id_str; LLMessageSystem* msg = gMessageSystem; - // Use material IDs instead of texture IDs if all material IDs are set + // Use material IDs instead of texture IDs if all material IDs are set, AND the mode is set to PBR materials. S32 materials_used = 0; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); - if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) - { - ++materials_used; + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) + { + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + if (is_material_selected) + { + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) + { + ++materials_used; + } + } } } for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) -- cgit v1.2.3 From 76bf3390eb119a7dfd879bbbc31b4d5e687aac8f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:55 -0700 Subject: DRTVWR-592: (WIP) Detect when terrain materials are loaded, use as fallback when terrain textures do not load --- indra/newview/lldrawpoolterrain.cpp | 32 +++++++- indra/newview/llfetchedgltfmaterial.h | 1 + indra/newview/llfloaterregioninfo.cpp | 6 +- indra/newview/llviewerregion.cpp | 16 ++-- indra/newview/llvlcomposition.cpp | 135 +++++++++++++++++++++++----------- indra/newview/llvlcomposition.h | 21 ++++-- 6 files changed, 150 insertions(+), 61 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 77189dceae..687ff5f462 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -121,8 +121,36 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures() 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); + constexpr LLGLTexture::EBoostLevel level = LLGLTexture::BOOST_TERRAIN; + constexpr float stats = 1024.f * 1024.f; + + LLPointer& tex = compp->mDetailTextures[i]; + llassert(tex.notNull()); + tex->setBoostLevel(level); + tex->addTextureStats(stats); + + LLPointer& mat = compp->mDetailMaterials[i]; + llassert(mat.notNull()); + if (mat->mBaseColorTexture) + { + mat->mBaseColorTexture->setBoostLevel(level); + mat->mBaseColorTexture->addTextureStats(stats); + } + if (mat->mNormalTexture) + { + mat->mNormalTexture->setBoostLevel(level); + mat->mNormalTexture->addTextureStats(stats); + } + if (mat->mMetallicRoughnessTexture) + { + mat->mMetallicRoughnessTexture->setBoostLevel(level); + mat->mMetallicRoughnessTexture->addTextureStats(stats); + } + if (mat->mEmissiveTexture) + { + mat->mEmissiveTexture->setBoostLevel(level); + mat->mEmissiveTexture->addTextureStats(stats); + } } } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 1668657281..ce4d33a213 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -49,6 +49,7 @@ public: void bind(LLViewerTexture* media_tex = nullptr); bool isFetching() const { return mFetching; } + bool isLoaded() const { return !mFetching; } // Textures used for fetching/rendering LLPointer mBaseColorTexture; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ff7012efb5..b5698c1d65 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1541,8 +1541,8 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) if(asset_ctrl) { LL_DEBUGS() << "Detail Texture " << i << ": " - << compp->getDetailTextureID(i) << LL_ENDL; - LLUUID tmp_id(compp->getDetailTextureID(i)); + << compp->getDetailAssetID(i) << LL_ENDL; + LLUUID tmp_id(compp->getDetailAssetID(i)); asset_ctrl->setImageAssetID(tmp_id); } } @@ -1552,7 +1552,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) asset_ctrl = getChild(buffer); if(asset_ctrl) { - LLUUID tmp_id(compp->getDetailTextureID(i)); + LLUUID tmp_id(compp->getDetailAssetID(i)); asset_ctrl->setImageAssetID(tmp_id); } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6b92b16ef4..9d3e63333e 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2962,20 +2962,20 @@ void LLViewerRegion::unpackRegionHandshake() // Get the 4 textures for land msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(0)); - compp->setDetailTextureID(0, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(0)); + compp->setDetailAssetID(0, tmp_id); msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(1)); - compp->setDetailTextureID(1, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(1)); + compp->setDetailAssetID(1, tmp_id); msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(2)); - compp->setDetailTextureID(2, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(2)); + compp->setDetailAssetID(2, tmp_id); msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(3)); - compp->setDetailTextureID(3, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(3)); + compp->setDetailAssetID(3, tmp_id); // Get the start altitude and range values for land textures F32 tmp_f32; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 001fab7755..8480c9ce3d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -65,10 +65,10 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 mSurfacep = surfacep; // Load Terrain Textures - Original ones - setDetailTextureID(0, TERRAIN_DIRT_DETAIL); - setDetailTextureID(1, TERRAIN_GRASS_DETAIL); - setDetailTextureID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailTextureID(3, TERRAIN_ROCK_DETAIL); + setDetailAssetID(0, TERRAIN_DIRT_DETAIL); + setDetailAssetID(1, TERRAIN_GRASS_DETAIL); + setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); + setDetailAssetID(3, TERRAIN_ROCK_DETAIL); // Initialize the texture matrix to defaults. for (S32 i = 0; i < CORNER_COUNT; ++i) @@ -93,7 +93,7 @@ void LLVLComposition::setSurface(LLSurface *surfacep) } -void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) +void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) { if(id.isNull()) { @@ -104,6 +104,25 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; + // *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type. + // *TODO: As the material textures are loaded, prevent deletion + mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id); +} + +void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id) +{ + if(id.isNull()) + { + mDetailMaterials[corner] = nullptr; + } + else + { + // This is terrain material, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. + mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); + mDetailTextures[corner]->setNoDelete() ; + mRawImages[corner] = NULL; + } } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, @@ -149,10 +168,6 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus // simple height) - // Heights map into textures as 0-1 = first, 1-2 = second, etc. - // So we need to compress heights into this range. - const S32 NUM_TEXTURES = 4; - const F32 xyScaleInv = (1.f / xyScale); const F32 zScaleInv = (1.f / zScale); @@ -199,7 +214,7 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component twiddle *= noise_magnitude; - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range; + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; scaled_noisy_height = llmax(0.f, scaled_noisy_height); scaled_noisy_height = llmin(3.f, scaled_noisy_height); @@ -211,6 +226,37 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, static const U32 BASE_SIZE = 128; +// Boost the texture loading priority +// Return true when ready to use (i.e. texture is sufficiently loaded) +bool boost_texture_until_ready(LLPointer& tex) +{ + if (tex->getDiscardLevel() < 0) + { + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->addTextureStats(BASE_SIZE*BASE_SIZE); + return false; + } + if ((tex->getDiscardLevel() != 0 && + (tex->getWidth() < BASE_SIZE || + tex->getHeight() < BASE_SIZE))) + { + S32 width = tex->getFullWidth(); + S32 height = tex->getFullHeight(); + S32 min_dim = llmin(width, height); + S32 ddiscard = 0; + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->setMinDiscardLevel(ddiscard); + tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority + return false; + } + return true; +} + BOOL LLVLComposition::generateComposition() { @@ -220,35 +266,44 @@ BOOL LLVLComposition::generateComposition() return FALSE; } - for (S32 i = 0; i < 4; i++) + bool textures_ready = true; + for (S32 i = 0; i < ASSET_COUNT; i++) { - if (mDetailTextures[i]->getDiscardLevel() < 0) - { - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); - return FALSE; - } - if ((mDetailTextures[i]->getDiscardLevel() != 0 && - (mDetailTextures[i]->getWidth() < BASE_SIZE || - mDetailTextures[i]->getHeight() < BASE_SIZE))) - { - S32 width = mDetailTextures[i]->getFullWidth(); - S32 height = mDetailTextures[i]->getFullHeight(); - S32 min_dim = llmin(width, height); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; - } - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - mDetailTextures[i]->setMinDiscardLevel(ddiscard); - mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority - return FALSE; - } + if (!boost_texture_until_ready(mDetailTextures[i])) + { + textures_ready = false; + break; + } } + + if (textures_ready) + { + return TRUE; + } - return TRUE; + bool materials_ready = true; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const LLPointer& mat = mDetailMaterials[i]; + if (!mat.isLoaded() || + (mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) || + (mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) || + (mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) || + (mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture))) + { + materials_ready = false; + break; + } + } + + if (materials_ready) + { + return TRUE; + } + else + { + return FALSE; + } } BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, @@ -469,16 +524,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, return TRUE; } -LLUUID LLVLComposition::getDetailTextureID(S32 corner) +LLUUID LLVLComposition::getDetailAssetID(S32 corner) { + llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID()); return mDetailTextures[corner]->getID(); } -LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner) -{ - return mDetailTextures[corner]; -} - F32 LLVLComposition::getStartHeight(S32 corner) { return mStartHeight[corner]; diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 2dd04ac5a5..3e465efc95 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -28,10 +28,13 @@ #define LL_LLVLCOMPOSITION_H #include "llviewerlayer.h" -#include "llviewertexture.h" +#include "llpointer.h" class LLSurface; +class LLViewerFetchedTexture; +class LLFetchedGLTFMaterial; + class LLVLComposition : public LLViewerLayer { public: @@ -46,6 +49,10 @@ public: // Generate texture from composition values. BOOL generateTexture(const F32 x, const F32 y, const F32 width, const F32 height); + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. + static const S32 ASSET_COUNT = 4; + // Use these as indeces ito the get/setters below that use 'corner' enum ECorner { @@ -55,12 +62,12 @@ public: NORTHEAST = 3, CORNER_COUNT = 4 }; - LLUUID getDetailTextureID(S32 corner); - LLViewerFetchedTexture* getDetailTexture(S32 corner); + + LLUUID getDetailAssetID(S32 asset); F32 getStartHeight(S32 corner); F32 getHeightRange(S32 corner); - void setDetailTextureID(S32 corner, const LLUUID& id); + void setDetailAssetID(S32 asset, const LLUUID& id); void setStartHeight(S32 corner, F32 start_height); void setHeightRange(S32 corner, F32 range); @@ -73,8 +80,10 @@ protected: LLSurface *mSurfacep; BOOL mTexturesLoaded; - LLPointer mDetailTextures[CORNER_COUNT]; - LLPointer mRawImages[CORNER_COUNT]; + // TODO: Set flag to indicate whether the textures or materials loaded first + LLPointer mDetailTextures[ASSET_COUNT]; + LLPointer mRawImages[ASSET_COUNT]; + LLPointer mDetailMaterials[ASSET_COUNT]; F32 mStartHeight[CORNER_COUNT]; F32 mHeightRange[CORNER_COUNT]; -- cgit v1.2.3 From 94e824739b5e8408b52a03e5af8e3fb4e124c616 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:02 -0700 Subject: DRTVWR-592: Render PBR material terrain like legacy, using baseColor texture --- indra/newview/lldrawpoolterrain.cpp | 29 ++++- indra/newview/llvlcomposition.cpp | 239 ++++++++++++++++++++++-------------- indra/newview/llvlcomposition.h | 17 ++- 3 files changed, 187 insertions(+), 98 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 687ff5f462..9f0f9fd1b2 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -256,10 +256,31 @@ void LLDrawPoolTerrain::renderFullShader() // 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]; - LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLViewerTexture *detail_texture0p; + LLViewerTexture *detail_texture1p; + LLViewerTexture *detail_texture2p; + LLViewerTexture *detail_texture3p; + BOOL use_textures = compp->texturesReady() || !compp->materialsReady(); + if (use_textures) + { + detail_texture0p = compp->mDetailTextures[0]; + detail_texture1p = compp->mDetailTextures[1]; + detail_texture2p = compp->mDetailTextures[2]; + detail_texture3p = compp->mDetailTextures[3]; + } + else // use materials + { + detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture; + detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture; + detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture; + 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; } + } LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8480c9ce3d..9ad1a3dd17 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -34,6 +34,8 @@ #include "lltextureview.h" #include "llviewertexture.h" #include "llviewertexturelist.h" +#include "llfetchedgltfmaterial.h" +#include "llgltfmateriallist.h" #include "llviewerregion.h" #include "noise.h" #include "llregionhandle.h" // for from_region_handle @@ -59,8 +61,7 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : - LLViewerLayer(width, scale), - mParamsReady(FALSE) + LLViewerLayer(width, scale) { mSurfacep = surfacep; @@ -76,9 +77,11 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); } - mTexScaleX = 16.f; - mTexScaleY = 16.f; - mTexturesLoaded = FALSE; + + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + mMaterialTexturesSet[i] = false; + } } @@ -92,8 +95,19 @@ void LLVLComposition::setSurface(LLSurface *surfacep) mSurfacep = surfacep; } +LLPointer fetch_terrain_texture(const LLUUID& id) +{ + if (id.isNull()) + { + return nullptr; + } + + LLPointer tex = LLViewerTextureManager::getFetchedTexture(id); + tex->setNoDelete(); + return tex; +} -void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) +void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { if(id.isNull()) { @@ -101,28 +115,11 @@ void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) } // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. - mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); - mDetailTextures[corner]->setNoDelete() ; - mRawImages[corner] = NULL; - // *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type. - // *TODO: As the material textures are loaded, prevent deletion - mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id); -} - -void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id) -{ - if(id.isNull()) - { - mDetailMaterials[corner] = nullptr; - } - else - { - // This is terrain material, but we are not setting it as BOOST_TERRAIN - // since we will be manipulating it later as needed. - mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); - mDetailTextures[corner]->setNoDelete() ; - mRawImages[corner] = NULL; - } + mDetailTextures[asset] = fetch_terrain_texture(id); + mRawImages[asset] = NULL; + LLPointer& mat = mDetailMaterials[asset]; + mat = gGLTFMaterialList.getMaterial(id); + mMaterialTexturesSet[asset] = false; } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, @@ -228,82 +225,130 @@ static const U32 BASE_SIZE = 128; // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) -bool boost_texture_until_ready(LLPointer& tex) +// static +BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) { if (tex->getDiscardLevel() < 0) { - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->addTextureStats(BASE_SIZE*BASE_SIZE); - return false; + if (boost) + { + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->addTextureStats(BASE_SIZE*BASE_SIZE); + } + return FALSE; } if ((tex->getDiscardLevel() != 0 && (tex->getWidth() < BASE_SIZE || tex->getHeight() < BASE_SIZE))) { - S32 width = tex->getFullWidth(); - S32 height = tex->getFullHeight(); - S32 min_dim = llmin(width, height); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + if (boost) { - ddiscard++; - min_dim /= 2; + S32 width = tex->getFullWidth(); + S32 height = tex->getFullHeight(); + S32 min_dim = llmin(width, height); + S32 ddiscard = 0; + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->setMinDiscardLevel(ddiscard); + tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority } - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->setMinDiscardLevel(ddiscard); - tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority - return false; + return FALSE; } - return true; + return TRUE; } -BOOL LLVLComposition::generateComposition() +// Boost the loading priority of every known texture in the material +// Return true when ready to use (i.e. material and all textures within are sufficiently loaded) +// static +BOOL LLVLComposition::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) { + if (!mat->isLoaded()) + { + return FALSE; + } - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } + // Material is loaded, but textures may not be + if (!textures_set) + { + // *NOTE: These can sometimes be set to to nullptr due to + // updateTEMaterialTextures. For the sake of robustness, we emulate + // that fetching behavior by setting textures of null IDs to nullptr. + mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); + mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); + mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); + textures_set = true; - bool textures_ready = true; + return FALSE; + } + + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost)) + { + return FALSE; + } + + return TRUE; +} + +BOOL LLVLComposition::texturesReady(BOOL boost) +{ for (S32 i = 0; i < ASSET_COUNT; i++) { - if (!boost_texture_until_ready(mDetailTextures[i])) + if (!textureReady(mDetailTextures[i], boost)) { - textures_ready = false; - break; + return FALSE; } } + return TRUE; +} - if (textures_ready) - { - return TRUE; - } - - bool materials_ready = true; +BOOL LLVLComposition::materialsReady(BOOL boost) +{ for (S32 i = 0; i < ASSET_COUNT; i++) { - const LLPointer& mat = mDetailMaterials[i]; - if (!mat.isLoaded() || - (mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) || - (mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) || - (mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) || - (mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture))) + if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) { - materials_ready = false; - break; + return FALSE; } } + return TRUE; +} - if (materials_ready) +BOOL LLVLComposition::generateComposition() +{ + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } + + if (texturesReady(TRUE)) { return TRUE; } - else + + if (materialsReady(TRUE)) { - return FALSE; + return TRUE; } + + return FALSE; } BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, @@ -323,15 +368,28 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, // // These have already been validated by generateComposition. - U8* st_data[4]; - S32 st_data_size[4]; // for debugging + U8* st_data[ASSET_COUNT]; + S32 st_data_size[ASSET_COUNT]; // for debugging + + const bool use_textures = texturesReady(); - for (S32 i = 0; i < 4; i++) + for (S32 i = 0; i < ASSET_COUNT; i++) { if (mRawImages[i].isNull()) { // Read back a raw image for this discard level, if it exists - S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight()); + LLViewerFetchedTexture* tex; + if (use_textures) + { + tex = mDetailTextures[i]; + } + else + { + tex = mDetailMaterials[i]->mBaseColorTexture; + if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } + } + + S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) { @@ -339,31 +397,31 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, min_dim /= 2; } - BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ; - if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. + BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; + if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. { - if (mDetailTextures[i]->getFetchPriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage()) + if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP); - mDetailTextures[i]->forceToRefetchTexture(ddiscard); + tex->setBoostLevel(LLGLTexture::BOOST_MAP); + tex->forceToRefetchTexture(ddiscard); } if(delete_raw) { - mDetailTextures[i]->destroyRawImage() ; + tex->destroyRawImage() ; } - LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL; + LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } - mRawImages[i] = mDetailTextures[i]->getRawImage() ; + mRawImages[i] = tex->getRawImage() ; if(delete_raw) { - mDetailTextures[i]->destroyRawImage() ; + tex->destroyRawImage() ; } - if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE || - mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE || - mDetailTextures[i]->getComponents() != 3) + if (tex->getWidth(ddiscard) != BASE_SIZE || + tex->getHeight(ddiscard) != BASE_SIZE || + tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); @@ -514,7 +572,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - for (S32 i = 0; i < 4; i++) + for (S32 i = 0; i < ASSET_COUNT; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE); @@ -526,7 +584,10 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, LLUUID LLVLComposition::getDetailAssetID(S32 corner) { - llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID()); + llassert(mDetailTextures[corner] && mDetailMaterials[corner]); + // *HACK: Assume both the the material and texture were fetched in the same + // way using the same UUID. However, we may not know at this point which + // one will load. return mDetailTextures[corner]->getID(); } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 3e465efc95..af0cf9323c 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -30,6 +30,8 @@ #include "llviewerlayer.h" #include "llpointer.h" +#include "llimage.h" + class LLSurface; class LLViewerFetchedTexture; @@ -75,21 +77,26 @@ public: friend class LLDrawPoolTerrain; void setParamsReady() { mParamsReady = TRUE; } BOOL getParamsReady() const { return mParamsReady; } + BOOL texturesReady(BOOL boost = FALSE); + BOOL materialsReady(BOOL boost = FALSE); + protected: - BOOL mParamsReady; + static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); + static BOOL materialReady(LLPointer& mat, bool& textures_set, BOOL boost = FALSE); + + BOOL mParamsReady = FALSE; LLSurface *mSurfacep; - BOOL mTexturesLoaded; - // TODO: Set flag to indicate whether the textures or materials loaded first LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mRawImages[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; + bool mMaterialTexturesSet[ASSET_COUNT]; F32 mStartHeight[CORNER_COUNT]; F32 mHeightRange[CORNER_COUNT]; - F32 mTexScaleX; - F32 mTexScaleY; + F32 mTexScaleX = 16.f; + F32 mTexScaleY = 16.f; }; #endif //LL_LLVLCOMPOSITION_H -- cgit v1.2.3 From 3553fec2084b8be3f3de86cec293c1e363c1388e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:10 -0700 Subject: DRTVWR-592: (WIP) Separate code path for terrain rendering and shaders. Just copy/paste for now. Use same draw pool --- .../shaders/class1/deferred/pbrterrainF.glsl | 61 +++++++++ .../shaders/class1/deferred/pbrterrainV.glsl | 77 +++++++++++ indra/newview/lldrawpoolterrain.cpp | 152 +++++++++++++++++---- indra/newview/lldrawpoolterrain.h | 2 + indra/newview/llviewershadermgr.cpp | 53 ++++--- indra/newview/llviewershadermgr.h | 2 +- indra/newview/llvlcomposition.cpp | 11 +- indra/newview/llvlcomposition.h | 1 + 8 files changed, 303 insertions(+), 56 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl new file mode 100644 index 0000000000..96903aeba8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -0,0 +1,61 @@ +/** + * @file class1\deferred\terrainF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +out vec4 frag_data[4]; + +uniform sampler2D detail_0; +uniform sampler2D detail_1; +uniform sampler2D detail_2; +uniform sampler2D detail_3; +uniform sampler2D alpha_ramp; + +in vec3 pos; +in vec3 vary_normal; +in vec4 vary_texcoord0; +in vec4 vary_texcoord1; + +vec2 encode_normal(vec3 n); + +void main() +{ + vec4 color0 = texture2D(detail_0, vary_texcoord0.xy); + vec4 color1 = texture2D(detail_1, vary_texcoord0.xy); + vec4 color2 = texture2D(detail_2, vary_texcoord0.xy); + vec4 color3 = texture2D(detail_3, vary_texcoord0.xy); + + float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; + float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; + float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; + vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); + + outColor.a = 0.0; // yes, downstream atmospherics + + frag_data[0] = outColor; + frag_data[1] = vec4(0.0,0.0,0.0,-1.0); + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); + frag_data[3] = vec4(0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl new file mode 100644 index 0000000000..e8747a1f6b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -0,0 +1,77 @@ +/** + * @file class1\environment\pbrterrainV.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +uniform mat3 normal_matrix; +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; + +in vec3 position; +in vec3 normal; +in vec4 diffuse_color; +in vec2 texcoord0; +in vec2 texcoord1; + +out vec3 pos; +out vec3 vary_normal; +out vec4 vary_texcoord0; +out vec4 vary_texcoord1; + +uniform vec4 object_plane_s; +uniform vec4 object_plane_t; + +vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +{ + vec4 tcoord; + + tcoord.x = dot(vpos, tp0); + tcoord.y = dot(vpos, tp1); + tcoord.z = tc.z; + tcoord.w = tc.w; + + tcoord = mat * tcoord; + + return tcoord; +} + +void main() +{ + //transform vertex + vec4 pre_pos = vec4(position.xyz, 1.0); + vec4 t_pos = modelview_projection_matrix * pre_pos; + + gl_Position = t_pos; + pos = t_pos.xyz; + + vary_normal = normalize(normal_matrix * normal); + + // Transform and pass tex coords + 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); + + 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); +} diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 9f0f9fd1b2..16d982ea90 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -158,10 +158,6 @@ 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) @@ -256,31 +252,139 @@ void LLDrawPoolTerrain::renderFullShader() // 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; - LLViewerTexture *detail_texture1p; - LLViewerTexture *detail_texture2p; - LLViewerTexture *detail_texture3p; - BOOL use_textures = compp->texturesReady() || !compp->materialsReady(); + const BOOL use_textures = compp->useTextures(); + if (use_textures) { - detail_texture0p = compp->mDetailTextures[0]; - detail_texture1p = compp->mDetailTextures[1]; - detail_texture2p = compp->mDetailTextures[2]; - detail_texture3p = compp->mDetailTextures[3]; + // Use textures + sShader = &gDeferredTerrainProgram; + sShader->bind(); + renderFullShaderTextures(); } - else // use materials + else { - detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture; - detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture; - detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture; - 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; } + // Use materials + sShader = &gDeferredPBRTerrainProgram; + sShader->bind(); + renderFullShaderPBR(); } +} + +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]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + + LLVector4 tp0, tp1; + + 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(); + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); + + 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); + + // 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(); +} + +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; } LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 03bef31541..fbf6a8d917 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -79,6 +79,8 @@ protected: void renderFull2TU(); void renderFull4TU(); void renderFullShader(); + void renderFullShaderTextures(); + void renderFullShaderPBR(); void drawLoop(); private: diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4559d71d6d..19b3c59cae 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -138,7 +138,6 @@ LLGLSLShader gDeferredSkinnedDiffuseProgram; LLGLSLShader gDeferredSkinnedBumpProgram; LLGLSLShader gDeferredBumpProgram; LLGLSLShader gDeferredTerrainProgram; -LLGLSLShader gDeferredTerrainWaterProgram; LLGLSLShader gDeferredTreeProgram; LLGLSLShader gDeferredTreeShadowProgram; LLGLSLShader gDeferredSkinnedTreeShadowProgram; @@ -226,6 +225,7 @@ LLGLSLShader gDeferredPBRAlphaProgram; LLGLSLShader gDeferredSkinnedPBRAlphaProgram; LLGLSLShader gDeferredPBRAlphaWaterProgram; LLGLSLShader gDeferredSkinnedPBRAlphaWaterProgram; +LLGLSLShader gDeferredPBRTerrainProgram; //helper for making a rigged variant of a given shader bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -291,7 +291,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredEmissiveProgram); mShaderList.push_back(&gDeferredSkinnedEmissiveProgram); mShaderList.push_back(&gDeferredAvatarEyesProgram); - mShaderList.push_back(&gDeferredTerrainWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); @@ -939,7 +938,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedBumpProgram.unload(); gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); - gDeferredTerrainWaterProgram.unload(); gDeferredLightProgram.unload(); for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) { @@ -1026,6 +1024,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedPBRAlphaProgram.unload(); gDeferredPBRAlphaWaterProgram.unload(); gDeferredSkinnedPBRAlphaWaterProgram.unload(); + gDeferredPBRTerrainProgram.unload(); return TRUE; } @@ -1492,6 +1491,27 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = shader->createShader(NULL, NULL); llassert(success); } + + if (success) + { + gDeferredPBRTerrainProgram.mName = "Deferred PBR Terrain Shader"; + gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; + gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; + gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; + gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; + gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; + gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; + + gDeferredPBRTerrainProgram.mShaderFiles.clear(); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); + gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -2430,8 +2450,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTerrainProgram.mName = "Deferred Terrain Shader"; gDeferredTerrainProgram.mFeatures.encodesNormal = true; gDeferredTerrainProgram.mFeatures.hasSrgb = true; - gDeferredTerrainProgram.mFeatures.calculatesLighting = false; - gDeferredTerrainProgram.mFeatures.hasLighting = false; gDeferredTerrainProgram.mFeatures.isAlphaLighting = true; gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels gDeferredTerrainProgram.mFeatures.hasWaterFog = true; @@ -2447,31 +2465,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader"; - gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true; - gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true; - gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false; - gDeferredTerrainWaterProgram.mFeatures.hasLighting = false; - gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true; - gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredTerrainWaterProgram.mFeatures.hasGamma = true; - - gDeferredTerrainWaterProgram.mShaderFiles.clear(); - gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER)); - gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER)); - gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredTerrainWaterProgram.clearPermutations(); - gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1"); - success = gDeferredTerrainWaterProgram.createShader(NULL, NULL); - llassert(success); - } - if (success) { gDeferredAvatarProgram.mName = "Deferred Avatar Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index b0b9719d76..6765703ab8 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -211,7 +211,6 @@ extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; extern LLGLSLShader gDeferredBumpProgram; extern LLGLSLShader gDeferredTerrainProgram; -extern LLGLSLShader gDeferredTerrainWaterProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredTreeShadowProgram; extern LLGLSLShader gDeferredLightProgram; @@ -279,4 +278,5 @@ extern LLGLSLShader gDeferredPBROpaqueProgram; extern LLGLSLShader gDeferredPBRAlphaProgram; extern LLGLSLShader gDeferredPBRAlphaWaterProgram; extern LLGLSLShader gHUDPBRAlphaProgram; +extern LLGLSLShader gDeferredPBRTerrainProgram; #endif diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 9ad1a3dd17..5d711f4e5d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -228,6 +228,8 @@ static const U32 BASE_SIZE = 128; // static BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) { + llassert(tex.notNull()); + if (tex->getDiscardLevel() < 0) { if (boost) @@ -306,6 +308,13 @@ BOOL LLVLComposition::materialReady(LLPointer& mat, bool& return TRUE; } +BOOL LLVLComposition::useTextures() +{ + LL_PROFILE_ZONE_SCOPED; + + return texturesReady() || !materialsReady(); +} + BOOL LLVLComposition::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -371,7 +380,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = texturesReady(); + const bool use_textures = useTextures(); for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index af0cf9323c..504441d0f2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -77,6 +77,7 @@ public: friend class LLDrawPoolTerrain; void setParamsReady() { mParamsReady = TRUE; } BOOL getParamsReady() const { return mParamsReady; } + BOOL useTextures(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); -- cgit v1.2.3 From 474923e3cb29df35e8807006ad16861eb1dc24d0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:17 -0700 Subject: DRTVWR-592: (WIP) Add code for generating terrain tangents (not yet used) --- indra/newview/llvosurfacepatch.cpp | 169 +++++++++++++++++++++++++++++-------- indra/newview/llvosurfacepatch.h | 16 ++-- 2 files changed, 147 insertions(+), 38 deletions(-) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 3f5f56d378..bfa622b6c1 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -43,6 +43,9 @@ #include "pipeline.h" #include "llspatialpartition.h" +#include "mikktspace/mikktspace.h" +// mikktspace implementation already included in llvovolume object file + F32 LLVOSurfacePatch::sLODFactor = 1.f; LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -241,39 +244,53 @@ BOOL LLVOSurfacePatch::updateLOD() return TRUE; } -void LLVOSurfacePatch::getGeometry(LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp) +void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); - if (facep) - { - U32 index_offset = facep->getGeomIndex(); - - updateMainGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - updateNorthGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - updateEastGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - } + if (!facep) + { + return; + } + + U32 index_offset = facep->getGeomIndex(); + + updateMainGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateNorthGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateEastGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + + const bool has_tangents = tangentsp.get() != nullptr; + if (has_tangents) + { + // Last but not least, calculate tangents for the updated terrain vertices + genTerrainTangents(facep, + verticesp, + normalsp, + tangentsp, + texCoords0p); + } } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -759,6 +776,88 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } +struct MikktData +{ + MikktData(S32 vert_offet, + S32 vert_size, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p) : + vert_offset(vert_offset), + vert_size(vert_size), + verticesp(verticesp), + normalsp(normalsp), + texCoords0p(texCoords0p) + { + } + S32 vert_offset; + U32 vert_size; + LLStrider verticesp; + LLStrider normalsp; + LLStrider tangentsp; + LLStrider texCoords0p; +}; + + +void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p) +{ + SMikkTSpaceInterface ms; + + ms.m_getNumFaces = [](const SMikkTSpaceContext *pContext) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + return S32(data->vert_size / 3); + }; + + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *pContext, const int iFace) { return 3; }; + + ms.m_getPosition = [](const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + fvPosOut[0] = data->verticesp[data->vert_offset + iVert].mV[0]; + fvPosOut[1] = data->verticesp[data->vert_offset + iVert].mV[1]; + fvPosOut[2] = data->verticesp[data->vert_offset + iVert].mV[2]; + }; + + ms.m_getNormal = [](const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + fvNormOut[0] = data->normalsp[data->vert_offset + iVert].mV[0]; + fvNormOut[1] = data->normalsp[data->vert_offset + iVert].mV[1]; + fvNormOut[2] = data->normalsp[data->vert_offset + iVert].mV[2]; + }; + + ms.m_getTexCoord = [](const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + fvTexcOut[0] = data->texCoords0p[data->vert_offset + iVert].mV[0]; + fvTexcOut[1] = data->texCoords0p[data->vert_offset + iVert].mV[1]; + }; + + ms.m_setTSpaceBasic = + [](const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + data->tangentsp[data->vert_offset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); + }; + + ms.m_setTSpace = nullptr; + + MikktData data(facep->getGeomIndex(), + facep->getGeomCount(), + verticesp, + normalsp, + tangentsp, + texCoords0p); + SMikkTSpaceContext ctx = { &ms, &data }; + genTangSpaceDefault(&ctx); +} + void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) { mPatchp = patchp; @@ -998,12 +1097,16 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) //get vertex buffer striders LLStrider vertices; LLStrider normals; - LLStrider texcoords2; + LLStrider tangents; LLStrider texcoords; + LLStrider texcoords2; LLStrider indices; + const bool has_tangents = buffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); + llassert_always(buffer->getVertexStrider(vertices)); llassert_always(buffer->getNormalStrider(normals)); + llassert_always(has_tangents ? buffer->getTangentStrider(tangents) : true); llassert_always(buffer->getTexCoord0Strider(texcoords)); llassert_always(buffer->getTexCoord1Strider(texcoords2)); llassert_always(buffer->getIndexStrider(indices)); @@ -1020,7 +1123,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getGeometry(vertices, normals, texcoords, texcoords2, indices); + patchp->getTerrainGeometry(vertices, normals, tangents, texcoords, texcoords2, indices); indices_index += facep->getIndicesCount(); index_offset += facep->getGeomCount(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index aed67162d1..7d0f649dea 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -63,11 +63,12 @@ public: /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); /*virtual*/ void updateFaceSize(S32 idx); - void getGeometry(LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp); + void getTerrainGeometry(LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -136,6 +137,11 @@ protected: LLStrider &texCoords1p, LLStrider &indicesp, U32 &index_offset); + void genTerrainTangents(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 49a5b79c2b1ba5f4b909d1bfab89bb7ad9c1e888 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:24 -0700 Subject: DRTVWR-592: (WIP) Debugging, rethinking --- .../shaders/class1/deferred/pbrterrainF.glsl | 3 + .../shaders/class1/deferred/pbrterrainV.glsl | 7 ++ indra/newview/lldrawpoolterrain.h | 1 + indra/newview/llvosurfacepatch.cpp | 83 +++++++++++----------- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 96903aeba8..2426199056 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -33,6 +33,8 @@ uniform sampler2D alpha_ramp; in vec3 pos; in vec3 vary_normal; +in vec3 vary_tangent; // TODO: Decide if we want to keep this +flat in float vary_sign; // TODO: Decide if we want to keep this in vec4 vary_texcoord0; in vec4 vary_texcoord1; @@ -53,6 +55,7 @@ void main() outColor.a = 0.0; // yes, downstream atmospherics frag_data[0] = outColor; + frag_data[0] = vec4((0.5 * (1.0 + vary_sign)) * vary_tangent.xyz, 1.0); // TODO: Remove frag_data[1] = vec4(0.0,0.0,0.0,-1.0); vec3 nvn = normalize(vary_normal); frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index e8747a1f6b..fcc4448a80 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -29,15 +29,20 @@ uniform mat4 modelview_projection_matrix; in vec3 position; in vec3 normal; +in vec4 tangent; in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; out vec3 pos; out vec3 vary_normal; +out vec3 vary_tangent; // TODO: Decide if we want to keep this +flat out float vary_sign; // TODO: Decide if we want to keep this out vec4 vary_texcoord0; out vec4 vary_texcoord1; +out vec4 debug_tangent; // TODO: Remove + uniform vec4 object_plane_s; uniform vec4 object_plane_t; @@ -65,6 +70,8 @@ void main() pos = t_pos.xyz; vary_normal = normalize(normal_matrix * normal); + vary_tangent = normalize(normal_matrix * tangent.xyz); // TODO: Decide if we want to keep this + vary_sign = tangent.w; // TODO: Decide if we want to keep this // Transform and pass tex coords vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index fbf6a8d917..2a487228ed 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -37,6 +37,7 @@ public: { VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TANGENT | // Only PBR terrain uses this currently LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 }; diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index bfa622b6c1..edb07ffd9b 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -776,29 +776,33 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } -struct MikktData +struct MikktTerrainData { - MikktData(S32 vert_offet, - S32 vert_size, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p) : - vert_offset(vert_offset), - vert_size(vert_size), - verticesp(verticesp), - normalsp(normalsp), - texCoords0p(texCoords0p) + MikktTerrainData(U32 vert_offset, + U32 vert_size, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p) : + mVertOffset(vert_offset), + mVertSize(vert_size), + mVerticesp(verticesp), + mNormalsp(normalsp), + mTangentsp(tangentsp), + mTexCoords0p(texCoords0p) { } - S32 vert_offset; - U32 vert_size; - LLStrider verticesp; - LLStrider normalsp; - LLStrider tangentsp; - LLStrider texCoords0p; + U32 mVertOffset; + U32 mVertSize; + LLStrider mVerticesp; + LLStrider mNormalsp; + LLStrider mTangentsp; + LLStrider mTexCoords0p; }; +// TODO: mikktspace? lol no, use this instead +// void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +// const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, LLStrider &verticesp, @@ -810,51 +814,46 @@ void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, ms.m_getNumFaces = [](const SMikkTSpaceContext *pContext) { - MikktData *data = (MikktData *) pContext->m_pUserData; - return S32(data->vert_size / 3); + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + return S32(data->mVertSize / 3); }; ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *pContext, const int iFace) { return 3; }; ms.m_getPosition = [](const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - fvPosOut[0] = data->verticesp[data->vert_offset + iVert].mV[0]; - fvPosOut[1] = data->verticesp[data->vert_offset + iVert].mV[1]; - fvPosOut[2] = data->verticesp[data->vert_offset + iVert].mV[2]; + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + fvPosOut[0] = data->mVerticesp[data->mVertOffset + iVert].mV[0]; + fvPosOut[1] = data->mVerticesp[data->mVertOffset + iVert].mV[1]; + fvPosOut[2] = data->mVerticesp[data->mVertOffset + iVert].mV[2]; }; ms.m_getNormal = [](const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - fvNormOut[0] = data->normalsp[data->vert_offset + iVert].mV[0]; - fvNormOut[1] = data->normalsp[data->vert_offset + iVert].mV[1]; - fvNormOut[2] = data->normalsp[data->vert_offset + iVert].mV[2]; + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + fvNormOut[0] = data->mNormalsp[data->mVertOffset + iVert].mV[0]; + fvNormOut[1] = data->mNormalsp[data->mVertOffset + iVert].mV[1]; + fvNormOut[2] = data->mNormalsp[data->mVertOffset + iVert].mV[2]; }; ms.m_getTexCoord = [](const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - fvTexcOut[0] = data->texCoords0p[data->vert_offset + iVert].mV[0]; - fvTexcOut[1] = data->texCoords0p[data->vert_offset + iVert].mV[1]; + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + fvTexcOut[0] = data->mTexCoords0p[data->mVertOffset + iVert].mV[0]; + fvTexcOut[1] = data->mTexCoords0p[data->mVertOffset + iVert].mV[1]; }; ms.m_setTSpaceBasic = [](const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - data->tangentsp[data->vert_offset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + data->mTangentsp[data->mVertOffset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); }; ms.m_setTSpace = nullptr; - MikktData data(facep->getGeomIndex(), - facep->getGeomCount(), - verticesp, - normalsp, - tangentsp, - texCoords0p); - SMikkTSpaceContext ctx = { &ms, &data }; + MikktTerrainData data((U32) (facep->getGeomIndex()), (U32) (facep->getGeomCount()), verticesp, normalsp, tangentsp, texCoords0p); + SMikkTSpaceContext ctx = {&ms, &data}; genTangSpaceDefault(&ctx); } @@ -1102,11 +1101,9 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) LLStrider texcoords2; LLStrider indices; - const bool has_tangents = buffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); - llassert_always(buffer->getVertexStrider(vertices)); llassert_always(buffer->getNormalStrider(normals)); - llassert_always(has_tangents ? buffer->getTangentStrider(tangents) : true); + llassert_always(buffer->getTangentStrider(tangents)); llassert_always(buffer->getTexCoord0Strider(texcoords)); llassert_always(buffer->getTexCoord1Strider(texcoords2)); llassert_always(buffer->getIndexStrider(indices)); -- cgit v1.2.3 From 763a9b5249640ef71d532ff3c9c28418bd90fb68 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:32 -0700 Subject: DRTVWR-592: Working tangent calculation, not yet used --- indra/llmath/llvolume.cpp | 7 +- indra/llmath/llvolume.h | 2 + indra/newview/llvosurfacepatch.cpp | 214 ++++++++++++++++--------------------- indra/newview/llvosurfacepatch.h | 6 -- 4 files changed, 94 insertions(+), 135 deletions(-) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0e3792fda3..667108320a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6465,9 +6465,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) return TRUE; } -void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, - const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); - void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -6485,7 +6482,7 @@ void LLVolumeFace::createTangents() (*ptr++).clear(); } - CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); + LLCalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); //normalize normals for (U32 i = 0; i < mNumVertices; i++) @@ -7195,7 +7192,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } //adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html -void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index afed98ff36..c2586601ae 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1142,6 +1142,8 @@ public: std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); +void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); + BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index edb07ffd9b..839eb2b737 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -39,13 +39,11 @@ #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llvlcomposition.h" +#include "llvolume.h" #include "llvovolume.h" #include "pipeline.h" #include "llspatialpartition.h" -#include "mikktspace/mikktspace.h" -// mikktspace implementation already included in llvovolume object file - F32 LLVOSurfacePatch::sLODFactor = 1.f; LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -246,7 +244,6 @@ BOOL LLVOSurfacePatch::updateLOD() void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, - LLStrider &tangentsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp) @@ -280,17 +277,6 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords1p, indicesp, index_offset); - - const bool has_tangents = tangentsp.get() != nullptr; - if (has_tangents) - { - // Last but not least, calculate tangents for the updated terrain vertices - genTerrainTangents(facep, - verticesp, - normalsp, - tangentsp, - texCoords0p); - } } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -776,87 +762,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } -struct MikktTerrainData -{ - MikktTerrainData(U32 vert_offset, - U32 vert_size, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p) : - mVertOffset(vert_offset), - mVertSize(vert_size), - mVerticesp(verticesp), - mNormalsp(normalsp), - mTangentsp(tangentsp), - mTexCoords0p(texCoords0p) - { - } - U32 mVertOffset; - U32 mVertSize; - LLStrider mVerticesp; - LLStrider mNormalsp; - LLStrider mTangentsp; - LLStrider mTexCoords0p; -}; - -// TODO: mikktspace? lol no, use this instead -// void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, -// const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) - -void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p) -{ - SMikkTSpaceInterface ms; - - ms.m_getNumFaces = [](const SMikkTSpaceContext *pContext) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - return S32(data->mVertSize / 3); - }; - - ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *pContext, const int iFace) { return 3; }; - - ms.m_getPosition = [](const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - fvPosOut[0] = data->mVerticesp[data->mVertOffset + iVert].mV[0]; - fvPosOut[1] = data->mVerticesp[data->mVertOffset + iVert].mV[1]; - fvPosOut[2] = data->mVerticesp[data->mVertOffset + iVert].mV[2]; - }; - - ms.m_getNormal = [](const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - fvNormOut[0] = data->mNormalsp[data->mVertOffset + iVert].mV[0]; - fvNormOut[1] = data->mNormalsp[data->mVertOffset + iVert].mV[1]; - fvNormOut[2] = data->mNormalsp[data->mVertOffset + iVert].mV[2]; - }; - - ms.m_getTexCoord = [](const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - fvTexcOut[0] = data->mTexCoords0p[data->mVertOffset + iVert].mV[0]; - fvTexcOut[1] = data->mTexCoords0p[data->mVertOffset + iVert].mV[1]; - }; - - ms.m_setTSpaceBasic = - [](const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - data->mTangentsp[data->mVertOffset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); - }; - - ms.m_setTSpace = nullptr; - - MikktTerrainData data((U32) (facep->getGeomIndex()), (U32) (facep->getGeomCount()), verticesp, normalsp, tangentsp, texCoords0p); - SMikkTSpaceContext ctx = {&ms, &data}; - genTangSpaceDefault(&ctx); -} - void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) { mPatchp = patchp; @@ -1087,6 +992,47 @@ LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } +// Do not add vertices; honor strict vertex count specified by strider_vertex_count +void gen_terrain_tangents(U16 strider_vertex_count, + U32 strider_index_count, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p, + LLStrider &indicesp) +{ + LLVector4a *vertices = new LLVector4a[strider_vertex_count]; + LLVector4a *normals = new LLVector4a[strider_vertex_count]; + LLVector4a *tangents = new LLVector4a[strider_vertex_count]; + std::vector texcoords(strider_vertex_count); + std::vector indices(strider_index_count); + + for (U16 v = 0; v < strider_vertex_count; ++v) + { + F32 *vert = verticesp[v].mV; + vertices[v] = LLVector4a(vert[0], vert[1], vert[2], 1.f); + F32 *n = normalsp[v].mV; + normals[v] = LLVector4a(n[0], n[1], n[2], 1.f); + tangents[v] = tangentsp[v]; + texcoords[v] = texCoords0p[v]; + } + for (U32 i = 0; i < strider_index_count; ++i) + { + indices[i] = indicesp[i]; + } + + LLCalculateTangentArray(strider_vertex_count, vertices, normals, texcoords.data(), strider_index_count / 3, indices.data(), tangents); + + for (U16 v = 0; v < strider_vertex_count; ++v) + { + tangentsp[v] = tangents[v]; + } + + delete[] vertices; + delete[] normals; + delete[] tangents; +} + void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; @@ -1094,37 +1040,57 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders - LLStrider vertices; - LLStrider normals; - LLStrider tangents; - LLStrider texcoords; - LLStrider texcoords2; - LLStrider indices; - - llassert_always(buffer->getVertexStrider(vertices)); - llassert_always(buffer->getNormalStrider(normals)); - llassert_always(buffer->getTangentStrider(tangents)); - llassert_always(buffer->getTexCoord0Strider(texcoords)); - llassert_always(buffer->getTexCoord1Strider(texcoords2)); - llassert_always(buffer->getIndexStrider(indices)); - - U32 indices_index = 0; - U32 index_offset = 0; - - for (std::vector::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) - { - LLFace* facep = *i; + LLStrider vertices_start; + LLStrider normals_start; + LLStrider tangents_start; + LLStrider texcoords_start; + LLStrider texcoords2_start; + LLStrider indices_start; + + llassert_always(buffer->getVertexStrider(vertices_start)); + llassert_always(buffer->getNormalStrider(normals_start)); + llassert_always(buffer->getTangentStrider(tangents_start)); + llassert_always(buffer->getTexCoord0Strider(texcoords_start)); + llassert_always(buffer->getTexCoord1Strider(texcoords2_start)); + llassert_always(buffer->getIndexStrider(indices_start)); + + U32 indices_index = 0; + U32 index_offset = 0; - facep->setIndicesIndex(indices_index); - facep->setGeomIndex(index_offset); - facep->setVertexBuffer(buffer); + { + LLStrider vertices = vertices_start; + LLStrider normals = normals_start; + LLStrider texcoords = texcoords_start; + LLStrider texcoords2 = texcoords2_start; + LLStrider indices = indices_start; + + for (std::vector::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) + { + LLFace* facep = *i; + + facep->setIndicesIndex(indices_index); + facep->setGeomIndex(index_offset); + facep->setVertexBuffer(buffer); + + LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); + patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices); + + indices_index += facep->getIndicesCount(); + index_offset += facep->getGeomCount(); + } + } - LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getTerrainGeometry(vertices, normals, tangents, texcoords, texcoords2, indices); + const bool has_tangents = tangents_start.get() != nullptr; + if (has_tangents) + { + LLStrider vertices = vertices_start; + LLStrider normals = normals_start; + LLStrider tangents = tangents_start; + LLStrider texcoords = texcoords_start; + LLStrider indices = indices_start; - indices_index += facep->getIndicesCount(); - index_offset += facep->getGeomCount(); - } + gen_terrain_tangents(index_offset, indices_index, vertices, normals, tangents, texcoords, indices); + } buffer->unmapBuffer(); mFaceList.clear(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 7d0f649dea..a3dcb945d1 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -65,7 +65,6 @@ public: /*virtual*/ void updateFaceSize(S32 idx); void getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, - LLStrider &tangentsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp); @@ -137,11 +136,6 @@ protected: LLStrider &texCoords1p, LLStrider &indicesp, U32 &index_offset); - void genTerrainTangents(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 7376b3e4b9c03f3ff3aa0c431c66916ac655a692 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:40 -0700 Subject: DRTVWR-592: (WIP) (does not run) PBR terrain rendering - begin work on shaders, uniforms --- indra/llrender/llshadermgr.cpp | 18 +++ indra/llrender/llshadermgr.h | 18 +++ .../shaders/class1/deferred/pbrterrainF.glsl | 142 ++++++++++++++++++--- .../shaders/class1/deferred/pbrterrainV.glsl | 21 ++- 4 files changed, 166 insertions(+), 33 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 75d6ef6c46..89f39d7011 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1427,8 +1427,26 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("detail_1"); mReservedUniforms.push_back("detail_2"); mReservedUniforms.push_back("detail_3"); + mReservedUniforms.push_back("alpha_ramp"); + mReservedUniforms.push_back("detail_0_base_color"); + mReservedUniforms.push_back("detail_1_base_color"); + mReservedUniforms.push_back("detail_2_base_color"); + mReservedUniforms.push_back("detail_3_base_color"); + mReservedUniforms.push_back("detail_0_normal"); + mReservedUniforms.push_back("detail_1_normal"); + mReservedUniforms.push_back("detail_2_normal"); + mReservedUniforms.push_back("detail_3_normal"); + mReservedUniforms.push_back("detail_0_metallic_roughness"); + mReservedUniforms.push_back("detail_1_metallic_roughness"); + mReservedUniforms.push_back("detail_2_metallic_roughness"); + mReservedUniforms.push_back("detail_3_metallic_roughness"); + mReservedUniforms.push_back("detail_0_emissive"); + mReservedUniforms.push_back("detail_1_emissive"); + mReservedUniforms.push_back("detail_2_emissive"); + mReservedUniforms.push_back("detail_3_emissive"); + mReservedUniforms.push_back("origin"); mReservedUniforms.push_back("display_gamma"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 46f352aa58..b43ccf2ec2 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -248,8 +248,26 @@ public: TERRAIN_DETAIL1, // "detail_1" TERRAIN_DETAIL2, // "detail_2" TERRAIN_DETAIL3, // "detail_3" + TERRAIN_ALPHARAMP, // "alpha_ramp" + TERRAIN_DETAIL0_BASE_COLOR, // "detail_0_base_color" (GLTF) + TERRAIN_DETAIL1_BASE_COLOR, // "detail_1_base_color" (GLTF) + TERRAIN_DETAIL2_BASE_COLOR, // "detail_2_base_color" (GLTF) + TERRAIN_DETAIL3_BASE_COLOR, // "detail_3_base_color" (GLTF) + TERRAIN_DETAIL0_NORMAL, // "detail_0_normal" (GLTF) + TERRAIN_DETAIL1_NORMAL, // "detail_1_normal" (GLTF) + TERRAIN_DETAIL2_NORMAL, // "detail_2_normal" (GLTF) + TERRAIN_DETAIL3_NORMAL, // "detail_3_normal" (GLTF) + TERRAIN_DETAIL0_METALLIC_ROUGHNESS, // "detail_0_metallic_roughness" (GLTF) + TERRAIN_DETAIL1_METALLIC_ROUGHNESS, // "detail_1_metallic_roughness" (GLTF) + TERRAIN_DETAIL2_METALLIC_ROUGHNESS, // "detail_2_metallic_roughness" (GLTF) + TERRAIN_DETAIL3_METALLIC_ROUGHNESS, // "detail_3_metallic_roughness" (GLTF) + TERRAIN_DETAIL0_EMISSIVE, // "detail_0_emissive" (GLTF) + TERRAIN_DETAIL1_EMISSIVE, // "detail_1_emissive" (GLTF) + TERRAIN_DETAIL2_EMISSIVE, // "detail_2_emissive" (GLTF) + TERRAIN_DETAIL3_EMISSIVE, // "detail_3_emissive" (GLTF) + SHINY_ORIGIN, // "origin" DISPLAY_GAMMA, // "display_gamma" diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 2426199056..f355b8ef98 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -25,40 +25,140 @@ out vec4 frag_data[4]; -uniform sampler2D detail_0; -uniform sampler2D detail_1; -uniform sampler2D detail_2; -uniform sampler2D detail_3; uniform sampler2D alpha_ramp; -in vec3 pos; +// 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 +uniform sampler2D detail_0_base_color; +uniform sampler2D detail_1_base_color; +uniform sampler2D detail_2_base_color; +uniform sampler2D detail_3_base_color; +uniform sampler2D detail_0_normal; +uniform sampler2D detail_1_normal; +uniform sampler2D detail_2_normal; +uniform sampler2D detail_3_normal; +uniform sampler2D detail_0_metallic_roughness; +uniform sampler2D detail_1_metallic_roughness; +uniform sampler2D detail_2_metallic_roughness; +uniform sampler2D detail_3_metallic_roughness; +uniform sampler2D detail_0_emissive; +uniform sampler2D detail_1_emissive; +uniform sampler2D detail_2_emissive; +uniform sampler2D detail_3_emissive; + +// TODO: Needs new uniforms +// *TODO: More efficient packing? +uniform vec4 metallicFactors; +uniform vec4 roughnessFactors; +uniform vec3[4] emissiveColors; +uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() + in vec3 vary_normal; -in vec3 vary_tangent; // TODO: Decide if we want to keep this -flat in float vary_sign; // TODO: Decide if we want to keep this +in vec3 vary_tangent; +flat in float vary_sign; in vec4 vary_texcoord0; in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); +vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); -void main() +// 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 ); +} + +vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); +} + +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) +{ + 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)); + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec4 color0 = texture2D(detail_0, vary_texcoord0.xy); - vec4 color1 = texture2D(detail_1, vary_texcoord0.xy); - vec4 color2 = texture2D(detail_2, vary_texcoord0.xy); - vec4 color3 = texture2D(detail_3, vary_texcoord0.xy); + vec4[4] samples; + samples[0] = texture2D(tex0, texcoord); + samples[1] = texture2D(tex1, texcoord); + samples[2] = texture2D(tex2, texcoord); + samples[3] = texture2D(tex3, texcoord); + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} +// TODO: Implement +// TODO: Don't forget calls to srgb_to_linear during texture sampling +// TODO: Wherever base color alpha is not 1.0, blend with black +void main() +{ float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; - vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - - outColor.a = 0.0; // yes, downstream atmospherics + + 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 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); + + float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal); + float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal); + vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal); + float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + + // TODO: OOh, we need blending for every GLTF uniform too + // TODO: Unfork + if (base_color.a < minimum_alpha) + { + base_color.rgb *= vec3(0.0); + } + + vec3 col = base_color.rgb; + + // from mikktspace.com + vec3 vNt = normal_texture.xyz*2.0-1.0; + float sign = vary_sign; + vec3 vN = vary_normal; + vec3 vT = vary_tangent.xyz; + + vec3 vB = sign * cross(vN, vT); + vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); + + // RGB = Occlusion, Roughness, Metal + // default values, see LLViewerTexture::sDefaultPBRORMImagep + // occlusion 1.0 + // roughness 0.0 + // metal 0.0 + vec3 spec = metallic_roughness.rgb; - frag_data[0] = outColor; - frag_data[0] = vec4((0.5 * (1.0 + vary_sign)) * vary_tangent.xyz, 1.0); // TODO: Remove - frag_data[1] = vec4(0.0,0.0,0.0,-1.0); - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); - frag_data[3] = vec4(0); + spec.g *= roughness_factor; + spec.b *= metallic_factor; + + vec3 emissive = emssive_color; + emissive *= emissive_texture.rgb; + + tnorm *= gl_FrontFacing ? 1.0 : -1.0; + + + frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse + // TODO: What is packed into vertex_color.a? + frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + // TODO: What is environment intensity and do we want it? + frag_data[2] = max(vec4(encode_normal(tnorm), 0.0, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), 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 fcc4448a80..cbfe9f3ea5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -34,15 +34,12 @@ in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; -out vec3 pos; out vec3 vary_normal; -out vec3 vary_tangent; // TODO: Decide if we want to keep this -flat out float vary_sign; // TODO: Decide if we want to keep this +out vec3 vary_tangent; +flat out float vary_sign; out vec4 vary_texcoord0; out vec4 vary_texcoord1; -out vec4 debug_tangent; // TODO: Remove - uniform vec4 object_plane_s; uniform vec4 object_plane_t; @@ -63,17 +60,17 @@ vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) void main() { //transform vertex - vec4 pre_pos = vec4(position.xyz, 1.0); - vec4 t_pos = modelview_projection_matrix * pre_pos; + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - gl_Position = t_pos; - pos = t_pos.xyz; + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; - vary_normal = normalize(normal_matrix * normal); - vary_tangent = normalize(normal_matrix * tangent.xyz); // TODO: Decide if we want to keep this - vary_sign = tangent.w; // TODO: Decide if we want to keep this + vary_tangent = normalize(t); + vary_sign = tangent.w; + vary_normal = normalize(n); // Transform and pass tex coords + // *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); -- cgit v1.2.3 From a7cd5f6ef9d80e77eaf87cfc605d32605f0916f1 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:48 -0700 Subject: DRTVWR-592: (WIP) (does not run) PBR terrain rendering - more work on shaders, uniforms --- indra/llrender/llshadermgr.cpp | 6 +++++ indra/llrender/llshadermgr.h | 6 +++++ .../shaders/class1/deferred/pbrterrainF.glsl | 28 +++++++++------------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 89f39d7011..b2c8255d2a 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1447,6 +1447,12 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("detail_2_emissive"); mReservedUniforms.push_back("detail_3_emissive"); + mReservedUniforms.push_back("baseColorFactors"); + mReservedUniforms.push_back("metallicFactors"); + mReservedUniforms.push_back("roughnessFactors"); + mReservedUniforms.push_back("emissiveColors"); + mReservedUniforms.push_back("minimum_alphas"); + mReservedUniforms.push_back("origin"); mReservedUniforms.push_back("display_gamma"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index b43ccf2ec2..151e94093d 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -268,6 +268,12 @@ public: TERRAIN_DETAIL2_EMISSIVE, // "detail_2_emissive" (GLTF) TERRAIN_DETAIL3_EMISSIVE, // "detail_3_emissive" (GLTF) + TERRAIN_BASE_COLOR_FACTORS, // "baseColorFactors" (GLTF) + TERRAIN_METALLIC_FACTORS, // "metallicFactors" (GLTF) + TERRAIN_ROUGHNESS_FACTORS, // "roughnessFactors" (GLTF) + TERRAIN_EMISSIVE_COLORS, // "emissiveColors" (GLTF) + TERRAIN_MINIMUM_ALPHAS, // "minimum_alphas" (GLTF) + SHINY_ORIGIN, // "origin" DISPLAY_GAMMA, // "display_gamma" diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index f355b8ef98..4a0b324558 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -48,8 +48,8 @@ uniform sampler2D detail_1_emissive; uniform sampler2D detail_2_emissive; uniform sampler2D detail_3_emissive; -// TODO: Needs new uniforms // *TODO: More efficient packing? +uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl uniform vec4 metallicFactors; uniform vec4 roughnessFactors; uniform vec3[4] emissiveColors; @@ -101,9 +101,6 @@ vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 te return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -// TODO: Implement -// TODO: Don't forget calls to srgb_to_linear during texture sampling -// TODO: Wherever base color alpha is not 1.0, blend with black void main() { float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; @@ -111,23 +108,22 @@ void main() 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); + float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + if (base_color.a < minimum_alpha) + { + discard; + } + 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); + 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); - float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); - - // TODO: OOh, we need blending for every GLTF uniform too - // TODO: Unfork - if (base_color.a < minimum_alpha) - { - base_color.rgb *= vec3(0.0); - } - vec3 col = base_color.rgb; + vec3 col = baseColorFactor.rgb * srgb_to_linear(basecolor.rgb); // from mikktspace.com vec3 vNt = normal_texture.xyz*2.0-1.0; @@ -155,10 +151,8 @@ void main() frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse - // TODO: What is packed into vertex_color.a? - frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. - // TODO: What is environment intensity and do we want it? - frag_data[2] = max(vec4(encode_normal(tnorm), 0.0, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), vec4(0)); // normal, environment intensity, flags + 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[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } -- cgit v1.2.3 From 5d046d8835563fcad9e8dcf948d889d9ccec41d7 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:57 -0700 Subject: DRTVWR-592: (WIP) (does not work) PBR terrain rendering - compiles, but doesn't render properly just yet --- .../shaders/class1/deferred/pbrterrainF.glsl | 41 ++++-- .../shaders/class1/deferred/pbrterrainV.glsl | 8 +- indra/newview/lldrawpoolterrain.cpp | 154 ++++++++++++--------- 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(& 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); @@ -411,29 +428,6 @@ 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 // @@ -441,38 +435,74 @@ void LLDrawPoolTerrain::renderFullShaderPBR() 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() -- cgit v1.2.3 From 039116abd4166903005b8de6fa5d64f0fdf75422 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:05 -0700 Subject: DRTVWR-592: (WIP) Roughly working draft of PBR terrain --- .../shaders/class1/deferred/pbrterrainF.glsl | 20 ++++++++++++-------- indra/newview/lldrawpoolterrain.cpp | 11 +++++++---- indra/newview/llfloaterregioninfo.cpp | 1 - indra/newview/llvlcomposition.cpp | 1 + 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 60e5776bc6..4de6b9609c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -97,10 +97,11 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 te 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); + // TODO: Why is this needed for pbropaqueF but not here? (and is there different behavior with base color vs emissive color, that also needs to be corrected?) + //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); } @@ -116,20 +117,23 @@ vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 te void main() { + // Adjust the texture repeats for a more sensible default. + float texture_density_factor = 2.0; + vec2 terrain_texcoord = texture_density_factor * vary_texcoord0.xy; float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; - 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); + vec4 base_color = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, 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) { discard; } - 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); - 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 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); + vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); + vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, 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); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 2a0a7bad1c..204fbc56fd 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -370,6 +370,7 @@ void LLDrawPoolTerrain::renderFullShaderTextures() gGL.getTexUnit(detail0)->activate(); } +// TODO: Investigate use of bindFast for PBR terrain textures void LLDrawPoolTerrain::renderFullShaderPBR() { // Hack! Get the region that this draw pool is rendering from! @@ -386,7 +387,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR() tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - constexpr U32 terrain_material_count = LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; + constexpr U32 terrain_material_count = 1 + 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]; @@ -456,12 +457,14 @@ void LLDrawPoolTerrain::renderFullShaderPBR() // 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; + F32 min_alpha = -0.0f; if (material->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) { - min_alpha = material->mAlphaCutoff; + // 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); shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index b5698c1d65..2635ac3a71 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1531,7 +1531,6 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LLVLComposition* compp = region->getComposition(); // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set the IDs on both pickers for now. - // *TODO: Determine the asset type of IDs, to determine which editing mode to display. LLTextureCtrl* asset_ctrl; std::string buffer; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 5d711f4e5d..815489f753 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -360,6 +360,7 @@ BOOL LLVLComposition::generateComposition() return FALSE; } +// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { -- cgit v1.2.3 From 94d8f669acc57d670000498edf22589f7b178af0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:13 -0700 Subject: DRTVWR-592: Add debug options LocalTerrainAssetN. Fix PBR terrain texture flickering --- indra/newview/app_settings/settings.xml | 44 ++++ indra/newview/llappviewer.cpp | 1 + indra/newview/lldrawpoolterrain.cpp | 63 ++++-- indra/newview/lldrawpoolterrain.h | 2 +- indra/newview/llviewercontrol.cpp | 15 ++ indra/newview/llvlcomposition.cpp | 345 +++++++++++++++++--------------- indra/newview/llvlcomposition.h | 44 +++- 7 files changed, 328 insertions(+), 186 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 09eda2534c..013f0ca8ff 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16442,6 +16442,50 @@ Boolean Value 0 + + LocalTerrainAsset1 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + + LocalTerrainAsset2 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + + LocalTerrainAsset3 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + + LocalTerrainAsset4 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 PathfindingRetrieveNeighboringRegion diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cf84094aa4..edbae465f7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -227,6 +227,7 @@ #include "pipeline.h" #include "llgesturemgr.h" #include "llsky.h" +#include "llvlcomposition.h" #include "llvlmanager.h" #include "llviewercamera.h" #include "lldrawpoolbump.h" diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 204fbc56fd..8755e53763 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -249,10 +249,11 @@ void LLDrawPoolTerrain::drawLoop() void LLDrawPoolTerrain::renderFullShader() { + const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE); // 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 = compp->useTextures(); + const BOOL use_textures = !use_local_materials && compp->useTextures(); if (use_textures) { @@ -266,7 +267,7 @@ void LLDrawPoolTerrain::renderFullShader() // Use materials sShader = &gDeferredPBRTerrainProgram; sShader->bind(); - renderFullShaderPBR(); + renderFullShaderPBR(use_local_materials); } } @@ -371,12 +372,18 @@ void LLDrawPoolTerrain::renderFullShaderTextures() } // TODO: Investigate use of bindFast for PBR terrain textures -void LLDrawPoolTerrain::renderFullShaderPBR() +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(& materials)[LLVLComposition::ASSET_COUNT] = compp->mDetailMaterials; + LLPointer (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; + + if (local_materials) + { + // Override region terrain with the global local override terrain + materials = &gLocalTerrainMaterials.mDetailMaterials; + } LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -395,28 +402,58 @@ void LLDrawPoolTerrain::renderFullShaderPBR() 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; + const LLFetchedGLTFMaterial* material = (*materials)[i].get(); + + LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture; + LLViewerTexture *detail_normal_texturep = material->mNormalTexture; + LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture; + LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture; detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); - gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep); + 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(); detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); - gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep); + 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(); detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); - gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep); + 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(); detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); - gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); + 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(); } @@ -447,7 +484,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR() F32 minimum_alphas[terrain_material_count]; for (U32 i = 0; i < terrain_material_count; ++i) { - const LLFetchedGLTFMaterial* material = materials[i].get(); + const LLFetchedGLTFMaterial* material = (*materials)[i].get(); base_color_factors[i] = material->mBaseColor; metallic_factors[i] = material->mMetallicFactor; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 2a487228ed..1a27cc8be0 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -81,7 +81,7 @@ protected: void renderFull4TU(); void renderFullShader(); void renderFullShaderTextures(); - void renderFullShaderPBR(); + void renderFullShaderPBR(BOOL local_materials = false); void drawLoop(); private: diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index aae4409167..4e0ad11597 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -54,6 +54,7 @@ #include "llvotree.h" #include "llvovolume.h" #include "llworld.h" +#include "llvlcomposition.h" #include "pipeline.h" #include "llviewerjoystick.h" #include "llviewerobjectlist.h" @@ -656,6 +657,16 @@ void handleFPSTuningStrategyChanged(const LLSD& newValue) const auto newval = gSavedSettings.getU32("TuningFPSStrategy"); LLPerfStats::tunables.userFPSTuningStrategy = newval; } + +void handleLocalTerrainChanged(const LLSD& newValue) +{ + for (U32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + const auto setting = gSavedSettings.getString(std::string("LocalTerrainAsset") + std::to_string(i + 1)); + const LLUUID materialID(setting); + gLocalTerrainMaterials.setDetailAssetID(i, materialID); + } +} //////////////////////////////////////////////////////////////////////////// LLPointer setting_get_control(LLControlGroup& group, const std::string& setting) @@ -834,6 +845,10 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged); setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged); setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset1", handleLocalTerrainChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset2", handleLocalTerrainChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset3", handleLocalTerrainChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset4", handleLocalTerrainChanged); setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged); } diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 815489f753..c4bed85be7 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -42,6 +42,8 @@ #include "llviewercontrol.h" +static const U32 BASE_SIZE = 128; + F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) { @@ -59,40 +61,40 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F return result; } - -LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : - LLViewerLayer(width, scale) +LLTerrainMaterials::LLTerrainMaterials() { - mSurfacep = surfacep; - - // Load Terrain Textures - Original ones - setDetailAssetID(0, TERRAIN_DIRT_DETAIL); - setDetailAssetID(1, TERRAIN_GRASS_DETAIL); - setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailAssetID(3, TERRAIN_ROCK_DETAIL); - - // Initialize the texture matrix to defaults. - for (S32 i = 0; i < CORNER_COUNT; ++i) - { - mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); - mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); - } - for (S32 i = 0; i < ASSET_COUNT; ++i) { mMaterialTexturesSet[i] = false; } } - -LLVLComposition::~LLVLComposition() +LLTerrainMaterials::~LLTerrainMaterials() { } +BOOL LLTerrainMaterials::generateMaterials() +{ + if (texturesReady(TRUE)) + { + return TRUE; + } -void LLVLComposition::setSurface(LLSurface *surfacep) + if (materialsReady(TRUE)) + { + return TRUE; + } + + return FALSE; +} + +LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) { - mSurfacep = surfacep; + llassert(mDetailTextures[asset] && mDetailMaterials[asset]); + // *HACK: Assume both the the material and texture were fetched in the same + // way using the same UUID. However, we may not know at this point which + // one will load. + return mDetailTextures[asset]->getID(); } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -107,126 +109,51 @@ LLPointer fetch_terrain_texture(const LLUUID& id) return tex; } -void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) +void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) { - if(id.isNull()) - { - return; - } // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); - mRawImages[asset] = NULL; LLPointer& mat = mDetailMaterials[asset]; mat = gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; } -BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, - const F32 width, const F32 height) +BOOL LLTerrainMaterials::useTextures() { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } - - llassert(mSurfacep); - - if (!mSurfacep || !mSurfacep->getRegion()) - { - // We don't always have the region yet here.... - return FALSE; - } - - S32 x_begin, y_begin, x_end, y_end; + LL_PROFILE_ZONE_SCOPED; - x_begin = ll_round( x * mScaleInv ); - y_begin = ll_round( y * mScaleInv ); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); + return texturesReady() || !materialsReady(); +} - if (x_end > mWidth) - { - x_end = mWidth; - } - if (y_end > mWidth) +BOOL LLTerrainMaterials::texturesReady(BOOL boost) +{ + for (S32 i = 0; i < ASSET_COUNT; i++) { - y_end = mWidth; + if (!textureReady(mDetailTextures[i], boost)) + { + return FALSE; + } } + return TRUE; +} - LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); - - // For perlin noise generation... - const F32 slope_squared = 1.5f*1.5f; - const F32 xyScale = 4.9215f; //0.93284f; - const F32 zScale = 4; //0.92165f; - const F32 z_offset = 0.f; - const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus - // simple height) - - const F32 xyScaleInv = (1.f / xyScale); - const F32 zScaleInv = (1.f / zScale); - - const F32 inv_width = 1.f/mWidth; - - // OK, for now, just have the composition value equal the height at the point. - for (S32 j = y_begin; j < y_end; j++) +BOOL LLTerrainMaterials::materialsReady(BOOL boost) +{ + for (S32 i = 0; i < ASSET_COUNT; i++) { - for (S32 i = x_begin; i < x_end; i++) - { - - F32 vec[3]; - F32 vec1[3]; - F32 twiddle; - - // Bilinearly interpolate the start height and height range of the textures - F32 start_height = bilinear(mStartHeight[SOUTHWEST], - mStartHeight[SOUTHEAST], - mStartHeight[NORTHWEST], - mStartHeight[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - F32 height_range = bilinear(mHeightRange[SOUTHWEST], - mHeightRange[SOUTHEAST], - mHeightRange[NORTHWEST], - mHeightRange[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - - LLVector3 location(i*mScale, j*mScale, 0.f); - - F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; - - // Step 0: Measure the exact height at this texel - vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice - vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; - vec[2] = height*zScaleInv; - // - // Choose material value by adding to the exact height a random value - // - vec1[0] = vec[0]*(0.2222222222f); - vec1[1] = vec[1]*(0.2222222222f); - vec1[2] = vec[2]*(0.2222222222f); - twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions - - twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component - twiddle *= noise_magnitude; - - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; - - scaled_noisy_height = llmax(0.f, scaled_noisy_height); - scaled_noisy_height = llmin(3.f, scaled_noisy_height); - *(mDatap + i + j*mWidth) = scaled_noisy_height; - } - } - return TRUE; + if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) + { + return FALSE; + } + } + return TRUE; } -static const U32 BASE_SIZE = 128; - // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) // static -BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) +BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BOOL boost) { llassert(tex.notNull()); @@ -266,9 +193,9 @@ BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL // Boost the loading priority of every known texture in the material // Return true when ready to use (i.e. material and all textures within are sufficiently loaded) // static -BOOL LLVLComposition::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) +BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) { - if (!mat->isLoaded()) + if (!mat || !mat->isLoaded()) { return FALSE; } @@ -308,37 +235,140 @@ BOOL LLVLComposition::materialReady(LLPointer& mat, bool& return TRUE; } -BOOL LLVLComposition::useTextures() + +LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : + LLTerrainMaterials(), + LLViewerLayer(width, scale) +{ + // Load Terrain Textures - Original ones + setDetailAssetID(0, TERRAIN_DIRT_DETAIL); + setDetailAssetID(1, TERRAIN_GRASS_DETAIL); + setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); + setDetailAssetID(3, TERRAIN_ROCK_DETAIL); + + mSurfacep = surfacep; + + // Initialize the texture matrix to defaults. + for (S32 i = 0; i < CORNER_COUNT; ++i) + { + mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); + mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); + } +} + + +LLVLComposition::~LLVLComposition() { - LL_PROFILE_ZONE_SCOPED; + LLTerrainMaterials::~LLTerrainMaterials(); +} - return texturesReady() || !materialsReady(); + +void LLVLComposition::setSurface(LLSurface *surfacep) +{ + mSurfacep = surfacep; } -BOOL LLVLComposition::texturesReady(BOOL boost) +BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, + const F32 width, const F32 height) { - for (S32 i = 0; i < ASSET_COUNT; i++) + if (!mParamsReady) { - if (!textureReady(mDetailTextures[i], boost)) - { - return FALSE; - } + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; } - return TRUE; -} -BOOL LLVLComposition::materialsReady(BOOL boost) -{ - for (S32 i = 0; i < ASSET_COUNT; i++) + llassert(mSurfacep); + + if (!mSurfacep || !mSurfacep->getRegion()) { - if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) - { - return FALSE; - } - } - return TRUE; + // We don't always have the region yet here.... + return FALSE; + } + + S32 x_begin, y_begin, x_end, y_end; + + x_begin = ll_round( x * mScaleInv ); + y_begin = ll_round( y * mScaleInv ); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { + x_end = mWidth; + } + if (y_end > mWidth) + { + y_end = mWidth; + } + + LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); + + // For perlin noise generation... + const F32 slope_squared = 1.5f*1.5f; + const F32 xyScale = 4.9215f; //0.93284f; + const F32 zScale = 4; //0.92165f; + const F32 z_offset = 0.f; + const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus + // simple height) + + const F32 xyScaleInv = (1.f / xyScale); + const F32 zScaleInv = (1.f / zScale); + + const F32 inv_width = 1.f/mWidth; + + // OK, for now, just have the composition value equal the height at the point. + for (S32 j = y_begin; j < y_end; j++) + { + for (S32 i = x_begin; i < x_end; i++) + { + + F32 vec[3]; + F32 vec1[3]; + F32 twiddle; + + // Bilinearly interpolate the start height and height range of the textures + F32 start_height = bilinear(mStartHeight[SOUTHWEST], + mStartHeight[SOUTHEAST], + mStartHeight[NORTHWEST], + mStartHeight[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + F32 height_range = bilinear(mHeightRange[SOUTHWEST], + mHeightRange[SOUTHEAST], + mHeightRange[NORTHWEST], + mHeightRange[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + + LLVector3 location(i*mScale, j*mScale, 0.f); + + F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; + + // Step 0: Measure the exact height at this texel + vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice + vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; + vec[2] = height*zScaleInv; + // + // Choose material value by adding to the exact height a random value + // + vec1[0] = vec[0]*(0.2222222222f); + vec1[1] = vec[1]*(0.2222222222f); + vec1[2] = vec[2]*(0.2222222222f); + twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions + + twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component + twiddle *= noise_magnitude; + + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; + + scaled_noisy_height = llmax(0.f, scaled_noisy_height); + scaled_noisy_height = llmin(3.f, scaled_noisy_height); + *(mDatap + i + j*mWidth) = scaled_noisy_height; + } + } + return TRUE; } +LLTerrainMaterials gLocalTerrainMaterials; + BOOL LLVLComposition::generateComposition() { if (!mParamsReady) @@ -347,17 +377,7 @@ BOOL LLVLComposition::generateComposition() return FALSE; } - if (texturesReady(TRUE)) - { - return TRUE; - } - - if (materialsReady(TRUE)) - { - return TRUE; - } - - return FALSE; + return LLTerrainMaterials::generateMaterials(); } // TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. @@ -592,18 +612,19 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, return TRUE; } -LLUUID LLVLComposition::getDetailAssetID(S32 corner) +F32 LLVLComposition::getStartHeight(S32 corner) { - llassert(mDetailTextures[corner] && mDetailMaterials[corner]); - // *HACK: Assume both the the material and texture were fetched in the same - // way using the same UUID. However, we may not know at this point which - // one will load. - return mDetailTextures[corner]->getID(); + return mStartHeight[corner]; } -F32 LLVLComposition::getStartHeight(S32 corner) +void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { - return mStartHeight[corner]; + if (id.isNull()) + { + return; + } + LLTerrainMaterials::setDetailAssetID(asset, id); + mRawImages[asset] = NULL; } void LLVLComposition::setStartHeight(S32 corner, const F32 start_height) diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 504441d0f2..9dc0b7221e 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -37,7 +37,38 @@ class LLSurface; class LLViewerFetchedTexture; class LLFetchedGLTFMaterial; -class LLVLComposition : public LLViewerLayer +class LLTerrainMaterials +{ +public: + friend class LLDrawPoolTerrain; + + LLTerrainMaterials(); + virtual ~LLTerrainMaterials(); + + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. + static const S32 ASSET_COUNT = 4; + + BOOL generateMaterials(); + + LLUUID getDetailAssetID(S32 asset); + virtual void setDetailAssetID(S32 asset, const LLUUID& id); + BOOL useTextures(); + BOOL texturesReady(BOOL boost = FALSE); + BOOL materialsReady(BOOL boost = FALSE); + +protected: + static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); + static BOOL materialReady(LLPointer& mat, bool& textures_set, BOOL boost = FALSE); + LLPointer mDetailTextures[ASSET_COUNT]; + LLPointer mDetailMaterials[ASSET_COUNT]; + bool mMaterialTexturesSet[ASSET_COUNT]; +}; + +// Local materials to override all regions +extern LLTerrainMaterials gLocalTerrainMaterials; + +class LLVLComposition : public LLTerrainMaterials, public LLViewerLayer { public: LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale); @@ -65,11 +96,10 @@ public: CORNER_COUNT = 4 }; - LLUUID getDetailAssetID(S32 asset); + void setDetailAssetID(S32 asset, const LLUUID& id) override; F32 getStartHeight(S32 corner); F32 getHeightRange(S32 corner); - void setDetailAssetID(S32 asset, const LLUUID& id); void setStartHeight(S32 corner, F32 start_height); void setHeightRange(S32 corner, F32 range); @@ -77,9 +107,6 @@ public: friend class LLDrawPoolTerrain; void setParamsReady() { mParamsReady = TRUE; } BOOL getParamsReady() const { return mParamsReady; } - BOOL useTextures(); - BOOL texturesReady(BOOL boost = FALSE); - BOOL materialsReady(BOOL boost = FALSE); protected: static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); @@ -88,10 +115,7 @@ protected: BOOL mParamsReady = FALSE; LLSurface *mSurfacep; - LLPointer mDetailTextures[ASSET_COUNT]; - LLPointer mRawImages[ASSET_COUNT]; - LLPointer mDetailMaterials[ASSET_COUNT]; - bool mMaterialTexturesSet[ASSET_COUNT]; + LLPointer mRawImages[LLTerrainMaterials::ASSET_COUNT]; F32 mStartHeight[CORNER_COUNT]; F32 mHeightRange[CORNER_COUNT]; -- cgit v1.2.3 From 14c3730bf128a6f01825954ee67a06188e134526 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:20 -0700 Subject: DRTVWR-592: Fix unable to undo effect of local terrain debug setting without restarting viewer --- indra/newview/llvlcomposition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c4bed85be7..8d55c80be8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -115,7 +115,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); LLPointer& mat = mDetailMaterials[asset]; - mat = gGLTFMaterialList.getMaterial(id); + mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; } -- cgit v1.2.3 From d2da77698005579f9fdaecad5a5d80189ad03f23 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:27 -0700 Subject: DRTVWR-592: Fix some virtual functions not being marked override --- indra/newview/llfloaterregioninfo.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 43a69e5804..bfdeb9440d 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -76,7 +76,7 @@ public: void onOpen(const LLSD& key) override; - /*virtual*/ void onClose(bool app_quitting); + void onClose(bool app_quitting) override; BOOL postBuild() override; static void processEstateOwnerRequest(LLMessageSystem* msg, void**); @@ -249,7 +249,7 @@ public: BOOL postBuild() override; - bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator + bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region BOOL validateTextureSizes(); @@ -308,10 +308,10 @@ public: static void updateEstateOwnerName(const std::string& name); bool refreshFromRegion(LLViewerRegion* region) override; - virtual bool estateUpdate(LLMessageSystem* msg); + bool estateUpdate(LLMessageSystem* msg) override; BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); + void updateChild(LLUICtrl* child_ctrl) override; void refresh() override; void refreshFromEstate(); @@ -343,15 +343,15 @@ public: ~LLPanelEstateCovenant() {} BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); + void updateChild(LLUICtrl* child_ctrl) override; bool refreshFromRegion(LLViewerRegion* region) override; - virtual bool estateUpdate(LLMessageSystem* msg); + bool estateUpdate(LLMessageSystem* msg) override; // LLView overrides BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg); + std::string& tooltip_msg) override; static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response); static void resetCovenantID(void* userdata); static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response); @@ -441,7 +441,7 @@ public: LLPanelEstateAccess(); BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); + void updateChild(LLUICtrl* child_ctrl) override; void updateControls(LLViewerRegion* region); void updateLists(); -- cgit v1.2.3 From 1820f23b96a50962a3a6a3d48de1aff8e1acb2c0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:35 -0700 Subject: DRTVWR-592: Fix issues with blending of materials, for example when fading out an emissive texture. Also affects base color and ORM --- .../shaders/class1/deferred/pbrterrainF.glsl | 105 ++++++++++++--------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 4de6b9609c..85691ae9b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -80,38 +80,63 @@ 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 ); } -vec3 sample_and_mix_color3(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, vec3[4] factors, 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); + samples[0] = texture2D(tex0, texcoord).xyz; + samples[1] = texture2D(tex1, texcoord).xyz; + samples[2] = texture2D(tex2, texcoord).xyz; + samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = srgb_to_linear(samples[0]); + samples[1] = srgb_to_linear(samples[1]); + samples[2] = srgb_to_linear(samples[2]); + samples[3] = srgb_to_linear(samples[3]); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; 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 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; samples[0] = texture2D(tex0, texcoord); samples[1] = texture2D(tex1, texcoord); samples[2] = texture2D(tex2, texcoord); samples[3] = texture2D(tex3, texcoord); - // TODO: Why is this needed for pbropaqueF but not here? (and is there different behavior with base color vs emissive color, that also needs to be corrected?) - //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); + 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); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec4[4] samples; - samples[0] = texture2D(tex0, texcoord); - samples[1] = texture2D(tex1, texcoord); - samples[2] = texture2D(tex2, texcoord); - samples[3] = texture2D(tex3, texcoord); + vec3[4] samples; + samples[0] = texture2D(tex0, texcoord).xyz; + samples[1] = texture2D(tex1, texcoord).xyz; + samples[2] = texture2D(tex2, texcoord).xyz; + samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = texture2D(tex0, texcoord).xyz; + samples[1] = texture2D(tex1, texcoord).xyz; + samples[2] = texture2D(tex2, texcoord).xyz; + samples[3] = texture2D(tex3, texcoord).xyz; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } @@ -124,23 +149,30 @@ 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_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); + vec4 col = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, baseColorFactors, 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) + if (col.a < minimum_alpha) { discard; } - vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); - vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - 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[4] orm_factors; + orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); + orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); + orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); + orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); + // RGB = Occlusion, Roughness, Metal + // default values, see LLViewerTexture::sDefaultPBRORMImagep + // occlusion 1.0 + // roughness 0.0 + // metal 0.0 + vec3 spec = sample_and_mix_vector3(alpha1, alpha2, alphaFinal, terrain_texcoord, orm_factors, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); - vec3 col = baseColorFactor.rgb * srgb_to_linear(base_color.rgb); + vec3 emissive = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, emissiveColors, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + + float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); // from mikktspace.com vec3 vNt = normal_texture.xyz*2.0-1.0; @@ -151,25 +183,12 @@ void main() vec3 vB = sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); - // RGB = Occlusion, Roughness, Metal - // default values, see LLViewerTexture::sDefaultPBRORMImagep - // occlusion 1.0 - // roughness 0.0 - // metal 0.0 - vec3 spec = metallic_roughness.rgb; - - spec.g *= roughnessFactor; - spec.b *= metallicFactor; - - vec3 emissive = emissiveColor; - emissive *= emissive_texture.rgb; - tnorm *= gl_FrontFacing ? 1.0 : -1.0; - 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), vec4(0)); // normal, environment intensity, flags + frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse + frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } -- cgit v1.2.3 From 3b3ba3623ac816633b1bd67f5d3b4dea65a83b17 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:43 -0700 Subject: DRTVWR-592: Overdraw is not free. Render terrain after Opaque Blinn-Phong/PBR have populated the foreground --- indra/newview/lldrawpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index d5ef734c4b..c0bcb2b48d 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -56,9 +56,9 @@ public: POOL_SIMPLE = 1, POOL_FULLBRIGHT, POOL_BUMP, - POOL_TERRAIN, POOL_MATERIALS, POOL_GLTF_PBR, + POOL_TERRAIN, POOL_GRASS, POOL_GLTF_PBR_ALPHA_MASK, POOL_TREE, -- cgit v1.2.3 From de9184479cfc179ba6e9d6ff388aff7da7f0b4ab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:50 -0700 Subject: DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing --- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llsurfacepatch.cpp | 1 + indra/newview/llvlcomposition.cpp | 13 ++++-- indra/newview/llvlcomposition.h | 9 +++- indra/newview/llvosurfacepatch.cpp | 84 +++++++++++++++++++++---------------- indra/newview/llvosurfacepatch.h | 12 ++++-- 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8755e53763..e072e1def2 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // 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->useTextures(); + const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::MaterialType::TEXTURE); if (use_textures) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 449d3d95c8..81fb4cf0cd 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,6 +209,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); + // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? U32 surface_stride = mSurfacep->getGridsPerEdge(); U32 point_offset = x + y*surface_stride; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d55c80be8..8cd22e3bdb 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,13 +119,20 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::useTextures() +BOOL LLTerrainMaterials::getMaterialType() +{ + return mMaterialType; +} + +void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; - return texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady() || !materialsReady(); + mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } + BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -401,7 +408,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = useTextures(); + const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 9dc0b7221e..882c3d89b2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -49,11 +49,18 @@ public: // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; + enum class Type + { + TEXTURE, + PBR, + COUNT + }; + BOOL generateMaterials(); LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - BOOL useTextures(); + Type getMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 839eb2b737..69b721c899 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,7 +246,8 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp) + LLStrider &indicesp, + bool pbr) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -262,30 +263,34 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, j, x, y; @@ -321,7 +326,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -384,12 +389,13 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 vertex_count = 0; S32 i, x, y; @@ -421,7 +427,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -434,7 +440,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -471,7 +477,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -485,7 +491,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -529,7 +535,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -543,7 +549,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -581,12 +587,13 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, x, y; @@ -612,7 +619,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -624,7 +631,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -660,7 +667,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -672,7 +679,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -714,7 +721,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -726,7 +733,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -1037,6 +1044,13 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; + const LLFace* region_facep = *mFaceList.begin(); + const LLViewerObject* region_patchp = region_facep->getViewerObject(); + LLVLComposition* composition = region_patchp->mRegionp->getComposition(); + // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. + composition->updateMaterialType(); + const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; + LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a3dcb945d1..06bb373578 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,7 +67,8 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp); + LLStrider &indicesp, + bool pbr); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -121,21 +122,24 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 2318d657660320b921e1566b54d3833c0401a34c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 22 May 2023 10:10:14 -0700 Subject: Revert "DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing" This reverts commit de9184479cfc179ba6e9d6ff388aff7da7f0b4ab. --- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llsurfacepatch.cpp | 1 - indra/newview/llvlcomposition.cpp | 13 ++---- indra/newview/llvlcomposition.h | 9 +--- indra/newview/llvosurfacepatch.cpp | 84 ++++++++++++++++--------------------- indra/newview/llvosurfacepatch.h | 12 ++---- 6 files changed, 44 insertions(+), 77 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index e072e1def2..8755e53763 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // 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::MaterialType::TEXTURE); + const BOOL use_textures = !use_local_materials && compp->useTextures(); if (use_textures) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 81fb4cf0cd..449d3d95c8 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,7 +209,6 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); - // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? U32 surface_stride = mSurfacep->getGridsPerEdge(); U32 point_offset = x + y*surface_stride; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8cd22e3bdb..8d55c80be8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,20 +119,13 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::getMaterialType() -{ - return mMaterialType; -} - -void LLTerrainMaterials::updateMaterialType() +BOOL LLTerrainMaterials::useTextures() { LL_PROFILE_ZONE_SCOPED; - const BOOL use_textures = texturesReady() || !materialsReady(); - mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; + return texturesReady() || !materialsReady(); } - BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -408,7 +401,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; + const bool use_textures = useTextures(); for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 882c3d89b2..9dc0b7221e 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -49,18 +49,11 @@ public: // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; - enum class Type - { - TEXTURE, - PBR, - COUNT - }; - BOOL generateMaterials(); LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - Type getMaterialType(); + BOOL useTextures(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 69b721c899..839eb2b737 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,8 +246,7 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr) + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -263,34 +262,30 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset, - bool pbr) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset) { S32 i, j, x, y; @@ -326,7 +321,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -389,13 +384,12 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset, - bool pbr) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset) { S32 vertex_count = 0; S32 i, x, y; @@ -427,7 +421,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -440,7 +434,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -477,7 +471,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -491,7 +485,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -535,7 +529,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -549,7 +543,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -587,13 +581,12 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset, - bool pbr) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset) { S32 i, x, y; @@ -619,7 +612,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -631,7 +624,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -667,7 +660,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -679,7 +672,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -721,7 +714,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -733,7 +726,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -1044,13 +1037,6 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; - const LLFace* region_facep = *mFaceList.begin(); - const LLViewerObject* region_patchp = region_facep->getViewerObject(); - LLVLComposition* composition = region_patchp->mRegionp->getComposition(); - // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. - composition->updateMaterialType(); - const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; - LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 06bb373578..a3dcb945d1 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,8 +67,7 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr); + LLStrider &indicesp); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -122,24 +121,21 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From dfa19c5e436edb102d8bd121c853153303631b4d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:33:16 -0700 Subject: DRTVWR-592: PBR terrain fallback for Mac/Intel: Drop emissive texture. Bump featuretable. --- indra/newview/app_settings/settings.xml | 11 +++++ .../shaders/class1/deferred/pbrterrainF.glsl | 10 ++++ indra/newview/featuretable.txt | 2 + indra/newview/featuretable_mac.txt | 1 + indra/newview/lldrawpoolterrain.cpp | 54 +++++++++++++--------- indra/newview/lldrawpoolterrain.h | 3 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 35 +++++++------- indra/newview/llviewershadermgr.h | 11 +++++ 9 files changed, 89 insertions(+), 39 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 013f0ca8ff..94cc5a14a4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10711,6 +10711,17 @@ Value 12.0 + RenderTerrainPBRDetail + + Comment + Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features in accordance with the GLTF specification, which reduces the number of texture binds. Some Intel and Mac graphics drivers do not support more than 16 texture binds. Because PBR terrain exceeds this limit at the highest detail level, reducing texture binds is necessary for compatibility. + Persist + 1 + Type + S32 + Value + 0 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 85691ae9b6..344c342189 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 + out vec4 frag_data[4]; uniform sampler2D alpha_ramp; @@ -42,16 +44,20 @@ uniform sampler2D detail_0_metallic_roughness; uniform sampler2D detail_1_metallic_roughness; uniform sampler2D detail_2_metallic_roughness; uniform sampler2D detail_3_metallic_roughness; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) uniform sampler2D detail_0_emissive; uniform sampler2D detail_1_emissive; uniform sampler2D detail_2_emissive; uniform sampler2D detail_3_emissive; +#endif // *TODO: More efficient packing? uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl uniform vec4 metallicFactors; uniform vec4 roughnessFactors; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) uniform vec3[4] emissiveColors; +#endif uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() in vec3 vary_normal; @@ -170,7 +176,11 @@ void main() // metal 0.0 vec3 spec = sample_and_mix_vector3(alpha1, alpha2, alphaFinal, terrain_texcoord, orm_factors, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) vec3 emissive = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, emissiveColors, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); +#else + vec3 emissive = vec3(0); +#endif float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 39f7996c7c..b8e8cffed8 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -48,6 +48,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 2 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 @@ -312,6 +313,7 @@ RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 RenderGLMultiThreadedMedia 1 0 +RenderTerrainPBRDetail 1 -1 list AMD RenderGLMultiThreadedTextures 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index cce403c7aa..d775f04810 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -45,6 +45,7 @@ RenderObjectBump 1 1 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 -1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8755e53763..8442e61bb9 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -54,7 +54,10 @@ const F32 DETAIL_SCALE = 1.f/16.f; int DebugDetailMap = 0; +const S32 PBR_DETAIL_EMISSIVE = 0; + S32 LLDrawPoolTerrain::sDetailMode = 1; +S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow"); @@ -66,7 +69,9 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : { // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); + // TODO: This is unused. Remove? sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); + sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD); //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); @@ -106,12 +111,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask() void LLDrawPoolTerrain::prerender() { sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); -} - -//static -S32 LLDrawPoolTerrain::getDetailMode() -{ - return sDetailMode; + sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); } void LLDrawPoolTerrain::boostTerrainDetailTextures() @@ -371,7 +371,7 @@ void LLDrawPoolTerrain::renderFullShaderTextures() gGL.getTexUnit(detail0)->activate(); } -// TODO: Investigate use of bindFast for PBR terrain textures +// *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! @@ -445,17 +445,20 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) 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); - if (detail_emissive_texturep) - { - gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); - } - else + if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) { - gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + 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(); } - gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail_emissive[i])->activate(); } LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; @@ -506,7 +509,10 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) 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); + if (sPBRDetailMode >= 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 @@ -525,7 +531,10 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) 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); + if (sPBRDetailMode >= 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(); @@ -539,9 +548,12 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) 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(); + if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + { + gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_emissive[i])->disable(); + gGL.getTexUnit(detail_emissive[i])->activate(); + } } } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 1a27cc8be0..060354458d 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -43,8 +43,6 @@ public: }; virtual U32 getVertexDataMask(); - static S32 getDetailMode(); - LLDrawPoolTerrain(LLViewerTexture *texturep); virtual ~LLDrawPoolTerrain(); @@ -69,6 +67,7 @@ public: LLPointer mAlphaNoiseImagep; static S32 sDetailMode; + static S32 sPBRDetailMode; static F32 sDetailScale; // meters per texture protected: diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4e0ad11597..41b13cacbb 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -702,6 +702,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 19b3c59cae..2235b6d9a4 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1494,23 +1494,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredPBRTerrainProgram.mName = "Deferred PBR Terrain Shader"; - gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; - gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; - gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; - gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; - gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; - gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; - gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; - gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; - - gDeferredPBRTerrainProgram.mShaderFiles.clear(); - gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); - gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); - gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); + detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); + gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d", detail); + gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; + gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; + gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; + gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; + gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; + gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; + + gDeferredPBRTerrainProgram.mShaderFiles.clear(); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); + gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PBR_DETAIL", llformat("%d", detail)); success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); - llassert(success); + llassert(success); } if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 6765703ab8..8b4a19f8c3 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -278,5 +278,16 @@ extern LLGLSLShader gDeferredPBROpaqueProgram; extern LLGLSLShader gDeferredPBRAlphaProgram; extern LLGLSLShader gDeferredPBRAlphaWaterProgram; extern LLGLSLShader gHUDPBRAlphaProgram; + +// Encodes detail level for dropping textures, in accordance with the GLTF spec +// 0 is highest detail, -1 drops emissive, etc +// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures +enum TerrainPBRDetail : S32 +{ + TERRAIN_PBR_DETAIL_MAX = 0, + TERRAIN_PBR_DETAIL_EMISSIVE = 0, + TERRAIN_PBR_DETAIL_OCCLUSION = -1, + TERRAIN_PBR_DETAIL_MIN = -1, +}; extern LLGLSLShader gDeferredPBRTerrainProgram; #endif -- cgit v1.2.3 From cbf202d6324dfe67218e3a0d20ec1589f2906517 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 22 May 2023 18:19:14 -0700 Subject: SL-19750: Only disable PBR terrain emissive for machines that have a limit of 16 texture binds. Bump featuretable --- indra/newview/featuretable.txt | 5 +++-- indra/newview/featuretable_mac.txt | 6 ++++-- indra/newview/llfeaturemanager.cpp | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index b8e8cffed8..cb941b424b 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 58 +version 59 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -313,7 +313,6 @@ RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 RenderGLMultiThreadedMedia 1 0 -RenderTerrainPBRDetail 1 -1 list AMD RenderGLMultiThreadedTextures 1 1 @@ -323,3 +322,5 @@ RenderFSAASamples 0 0 RenderReflectionsEnabled 0 0 RenderReflectionProbeDetail 0 0 +list TexUnit16orLess +RenderTerrainPBRDetail 1 -1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index d775f04810..c04c1c9a4f 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 53 +version 54 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -45,7 +45,6 @@ RenderObjectBump 1 1 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 -RenderTerrainPBRDetail 1 -1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 @@ -309,6 +308,9 @@ RenderShadowDetail 0 0 list TexUnit8orLess RenderDeferredSSAO 0 0 +list TexUnit16orLess +RenderTerrainPBRDetail 1 -1 + list AMD RenderDeferredSSAO 1 0 diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index f482d5a37d..9fff505c2a 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -664,6 +664,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("TexUnit8orLess"); } + if (gGLManager.mNumTextureImageUnits <= 16) + { + maskFeatures("TexUnit16orLess"); + } if (gGLManager.mVRAM > 512) { maskFeatures("VRAMGT512"); -- cgit v1.2.3 From a65c9dad5521d8e8d375003220e362533a142250 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:33:21 -0700 Subject: DRTVWR-592: Another attempt to fix Mac build: remove deprecated use of texture2D --- .../shaders/class1/deferred/pbrterrainF.glsl | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 344c342189..73d4d9e3bc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -89,10 +89,10 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = texture2D(tex0, texcoord).xyz; - samples[1] = texture2D(tex1, texcoord).xyz; - samples[2] = texture2D(tex2, texcoord).xyz; - samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = texture(tex0, texcoord).xyz; + samples[1] = texture(tex1, texcoord).xyz; + samples[2] = texture(tex2, texcoord).xyz; + samples[3] = texture(tex3, texcoord).xyz; samples[0] = srgb_to_linear(samples[0]); samples[1] = srgb_to_linear(samples[1]); samples[2] = srgb_to_linear(samples[2]); @@ -107,10 +107,10 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 te vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; - samples[0] = texture2D(tex0, texcoord); - samples[1] = texture2D(tex1, texcoord); - samples[2] = texture2D(tex2, texcoord); - samples[3] = texture2D(tex3, texcoord); + samples[0] = texture(tex0, texcoord); + samples[1] = texture(tex1, texcoord); + samples[2] = texture(tex2, texcoord); + samples[3] = texture(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); @@ -125,10 +125,10 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 te vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = texture2D(tex0, texcoord).xyz; - samples[1] = texture2D(tex1, texcoord).xyz; - samples[2] = texture2D(tex2, texcoord).xyz; - samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = texture(tex0, texcoord).xyz; + samples[1] = texture(tex1, texcoord).xyz; + samples[2] = texture(tex2, texcoord).xyz; + samples[3] = texture(tex3, texcoord).xyz; samples[0] *= factors[0]; samples[1] *= factors[1]; samples[2] *= factors[2]; @@ -139,10 +139,10 @@ vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 t vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = texture2D(tex0, texcoord).xyz; - samples[1] = texture2D(tex1, texcoord).xyz; - samples[2] = texture2D(tex2, texcoord).xyz; - samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = texture(tex0, texcoord).xyz; + samples[1] = texture(tex1, texcoord).xyz; + samples[2] = texture(tex2, texcoord).xyz; + samples[3] = texture(tex3, texcoord).xyz; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } @@ -151,9 +151,9 @@ void main() // Adjust the texture repeats for a more sensible default. float texture_density_factor = 2.0; vec2 terrain_texcoord = texture_density_factor * vary_texcoord0.xy; - float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; - float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; - float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; + float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; + float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; + float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; vec4 col = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, baseColorFactors, 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); -- cgit v1.2.3 From 57433341abffba9382e6899b164af40200f5d6d3 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:35:02 -0700 Subject: Revert "Revert "DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing"" This reverts commit 2318d657660320b921e1566b54d3833c0401a34c. --- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llsurfacepatch.cpp | 1 + indra/newview/llvlcomposition.cpp | 13 ++++-- indra/newview/llvlcomposition.h | 9 +++- indra/newview/llvosurfacepatch.cpp | 84 +++++++++++++++++++++---------------- indra/newview/llvosurfacepatch.h | 12 ++++-- 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8442e61bb9..926d5e78d0 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // 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->useTextures(); + const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::MaterialType::TEXTURE); if (use_textures) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 449d3d95c8..81fb4cf0cd 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,6 +209,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); + // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? U32 surface_stride = mSurfacep->getGridsPerEdge(); U32 point_offset = x + y*surface_stride; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d55c80be8..8cd22e3bdb 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,13 +119,20 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::useTextures() +BOOL LLTerrainMaterials::getMaterialType() +{ + return mMaterialType; +} + +void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; - return texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady() || !materialsReady(); + mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } + BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -401,7 +408,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = useTextures(); + const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 9dc0b7221e..882c3d89b2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -49,11 +49,18 @@ public: // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; + enum class Type + { + TEXTURE, + PBR, + COUNT + }; + BOOL generateMaterials(); LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - BOOL useTextures(); + Type getMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 839eb2b737..69b721c899 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,7 +246,8 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp) + LLStrider &indicesp, + bool pbr) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -262,30 +263,34 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, j, x, y; @@ -321,7 +326,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -384,12 +389,13 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 vertex_count = 0; S32 i, x, y; @@ -421,7 +427,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -434,7 +440,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -471,7 +477,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -485,7 +491,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -529,7 +535,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -543,7 +549,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -581,12 +587,13 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, x, y; @@ -612,7 +619,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -624,7 +631,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -660,7 +667,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -672,7 +679,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -714,7 +721,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -726,7 +733,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -1037,6 +1044,13 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; + const LLFace* region_facep = *mFaceList.begin(); + const LLViewerObject* region_patchp = region_facep->getViewerObject(); + LLVLComposition* composition = region_patchp->mRegionp->getComposition(); + // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. + composition->updateMaterialType(); + const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; + LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a3dcb945d1..06bb373578 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,7 +67,8 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp); + LLStrider &indicesp, + bool pbr); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -121,21 +122,24 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From b9ba57fd0004751dfbcbea90264a6e16c5849e5e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:42 -0700 Subject: DRTVWR-592: (WIP) Fix terrain PBR texture repeat seam. Legacy terrain texture repeats currently broken --- .../shaders/class1/deferred/pbrterrainF.glsl | 25 +++++++++++++++++++--- .../shaders/class1/deferred/pbrterrainV.glsl | 22 +++++++++++++------ indra/newview/lldrawpoolterrain.cpp | 4 +++- indra/newview/llsurfacepatch.cpp | 14 +++++++++--- indra/newview/llsurfacepatch.h | 2 +- indra/newview/llviewercontrol.cpp | 10 +++++++++ indra/newview/llvlcomposition.cpp | 8 +++---- indra/newview/llvlcomposition.h | 2 ++ indra/newview/llvosurfacepatch.cpp | 6 +++--- 9 files changed, 71 insertions(+), 22 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 73d4d9e3bc..5f94855963 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -70,6 +70,7 @@ vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); +in vec4 debug_pos; // TODO: Remove // *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) { @@ -148,9 +149,8 @@ vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFina void main() { - // Adjust the texture repeats for a more sensible default. - float texture_density_factor = 2.0; - vec2 terrain_texcoord = texture_density_factor * vary_texcoord0.xy; + vec2 terrain_texcoord = vary_texcoord0.xy; + terrain_texcoord -= vec2(21.0);// TODO: Remove float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; @@ -162,6 +162,25 @@ void main() discard; } + // TODO: Remove all of this + float debug_pos_x = debug_pos.x; + //float debug_pos_x = terrain_texcoord.y; + float debug_metric = debug_pos_x; + debug_metric = debug_metric - floor(debug_metric); + debug_metric *= debug_metric; + float debug_metric2 = debug_pos_x / 4.0; + debug_metric2 = debug_metric2 - floor(debug_metric2); + debug_metric2 *= debug_metric2; + debug_metric2 *= debug_metric2; + debug_metric2 *= 16.0; + float debug_metric3 = debug_pos_x / 16.0; + debug_metric3 = debug_metric3 - floor(debug_metric3); + debug_metric3 *= debug_metric3; + debug_metric3 *= debug_metric3; + debug_metric3 *= debug_metric3; + debug_metric3 *= 16.0; + //col.xyz = vec3(debug_metric3, debug_metric2, debug_metric);// TODO: Remove + vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec3[4] orm_factors; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 6037a58c0d..fd80d1bb2c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -43,24 +43,27 @@ out vec4 vary_texcoord1; uniform vec4 object_plane_s; uniform vec4 object_plane_t; -vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +vec4 texgen_object_pbr(vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { vec4 tcoord; - tcoord.x = dot(vpos, tp0); - tcoord.y = dot(vpos, tp1); - tcoord.z = tc.z; - tcoord.w = tc.w; + tcoord.x = dot(tc, tp0); + tcoord.y = dot(tc, tp1); + tcoord.z = tcoord.z; + tcoord.w = tcoord.w; tcoord = mat * tcoord; - return tcoord; + return tcoord; } +out vec4 debug_pos; // TODO: Remove + void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + debug_pos = vec4(texcoord0, 0.0, 1.0); vec3 n = normal_matrix * normal; vec3 t = normal_matrix * tangent.xyz; @@ -71,7 +74,12 @@ void main() // Transform and pass tex coords // *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; + vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + // Adjust the texture repeats for a more sensible default. + // *TODO: Remove this extra factor when KHR texture transform is added + float texture_density_factor = 3.0; + //texture_density_factor /= 256.0; // TODO: Remove + vary_texcoord0.xy *= texture_density_factor; vec4 tc = vec4(texcoord1,0,1); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 926d5e78d0..b4671963e1 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // 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::MaterialType::TEXTURE); + const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::Type::TEXTURE); if (use_textures) { @@ -385,6 +385,8 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) materials = &gLocalTerrainMaterials.mDetailMaterials; } + // *TODO: I'm seeing terrain still jump when switching regions. Might have something to do with the extra repeat factor in the shader. Or is it a numerical precision issue?... + // *TODO: If we want to change the tiling, we should change this offset modulo to prevent seams LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 81fb4cf0cd..4f9911a11c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -201,7 +201,7 @@ LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, - LLVector2 *tex0, LLVector2 *tex1) + LLVector2 *tex0, LLVector2 *tex1, bool pbr) { if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp) { @@ -209,8 +209,15 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); - // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? + // TODO: I think this operation is being applied too early because it also affects the geometry - we only want to affect the UVs + // TODO: Figure out what correct scaling is needed to prevent seams at region borders - getPatchesPerEdge seems to not be the solution, nor is getGridsPerEdge on its own U32 surface_stride = mSurfacep->getGridsPerEdge(); + U32 texture_stride = mSurfacep->getGridsPerEdge() - 1; + if (!pbr) + { + // TODO: Re-enable legacy repeats + //texture_stride = mSurfacep->getGridsPerEdge(); + } U32 point_offset = x + y*surface_stride; *normal = getNormal(x, y); @@ -222,7 +229,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); - LLVector3 tex_pos = rel_pos * (1.f/surface_stride); + // TODO: Revert for non-PBR only here, and/or add note that non-PBR doesn't actually use it. + LLVector3 tex_pos = rel_pos * (1.f/(texture_stride * mSurfacep->getMetersPerGrid())); tex0->mV[0] = tex_pos.mV[0]; tex0->mV[1] = tex_pos.mV[1]; tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y); diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 8c8f501dce..0e6c045145 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -106,7 +106,7 @@ public: const LLVector3 &getNormal(const U32 x, const U32 y) const; void eval(const U32 x, const U32 y, const U32 stride, - LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); + LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1, bool pbr); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 41b13cacbb..baf5480c6a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -124,6 +124,15 @@ static bool handleTerrainDetailChanged(const LLSD& newvalue) return true; } +static bool handleTerrainScaleChanged(const LLSD& newvalue) +{ + F64 scale = newvalue.asReal(); + if (scale != 0.0) + { + LLDrawPoolTerrain::sDetailScale = F32(1.0 / scale); + } + return true; +} static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) { @@ -702,6 +711,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8cd22e3bdb..130d74b286 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,7 +119,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::getMaterialType() +LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { return mMaterialType; } @@ -132,7 +132,6 @@ void LLTerrainMaterials::updateMaterialType() mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } - BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -408,7 +407,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; + const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { @@ -423,8 +422,9 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, else { tex = mDetailMaterials[i]->mBaseColorTexture; - if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } } + // TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) + if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 882c3d89b2..a62302292f 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -61,6 +61,7 @@ public: LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); + void updateMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); @@ -70,6 +71,7 @@ protected: LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; bool mMaterialTexturesSet[ASSET_COUNT]; + Type mMaterialType = Type::TEXTURE; }; // Local materials to override all regions diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 69b721c899..a672777914 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1046,10 +1046,10 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) const LLFace* region_facep = *mFaceList.begin(); const LLViewerObject* region_patchp = region_facep->getViewerObject(); - LLVLComposition* composition = region_patchp->mRegionp->getComposition(); + LLVLComposition* composition = region_patchp->getRegion()->getComposition(); // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. composition->updateMaterialType(); - const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; + const bool pbr = composition->getMaterialType() == LLTerrainMaterials::Type::PBR; LLVertexBuffer* buffer = group->mVertexBuffer; @@ -1087,7 +1087,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices); + patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices, pbr); indices_index += facep->getIndicesCount(); index_offset += facep->getGeomCount(); -- cgit v1.2.3 From 35d889f7af9686b79fe0e5255121a444a044beab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:48 -0700 Subject: DRTVWR-592: Create separate config option for terrain repeats. Clean up debug --- indra/newview/app_settings/settings.xml | 13 ++++++++++++- .../shaders/class1/deferred/pbrterrainF.glsl | 21 --------------------- .../shaders/class1/deferred/pbrterrainV.glsl | 12 ++---------- indra/newview/lldrawpoolterrain.cpp | 13 +++++++------ indra/newview/lldrawpoolterrain.h | 3 ++- indra/newview/llsurfacepatch.cpp | 13 +++---------- indra/newview/llviewercontrol.cpp | 11 +++++++++++ 7 files changed, 37 insertions(+), 49 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94cc5a14a4..2dac0b5d70 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10703,7 +10703,7 @@ RenderTerrainScale Comment - Terrain detail texture scale + Terrain detail texture scale (meters) Persist 1 Type @@ -10722,6 +10722,17 @@ Value 0 + RenderTerrainPBRScale + + Comment + PBR terrain detail texture scale (meters) + Persist + 1 + Type + F32 + Value + 4.0 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 5f94855963..e6261ca85e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -70,7 +70,6 @@ vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); -in vec4 debug_pos; // TODO: Remove // *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) { @@ -150,7 +149,6 @@ vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFina void main() { vec2 terrain_texcoord = vary_texcoord0.xy; - terrain_texcoord -= vec2(21.0);// TODO: Remove float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; @@ -162,25 +160,6 @@ void main() discard; } - // TODO: Remove all of this - float debug_pos_x = debug_pos.x; - //float debug_pos_x = terrain_texcoord.y; - float debug_metric = debug_pos_x; - debug_metric = debug_metric - floor(debug_metric); - debug_metric *= debug_metric; - float debug_metric2 = debug_pos_x / 4.0; - debug_metric2 = debug_metric2 - floor(debug_metric2); - debug_metric2 *= debug_metric2; - debug_metric2 *= debug_metric2; - debug_metric2 *= 16.0; - float debug_metric3 = debug_pos_x / 16.0; - debug_metric3 = debug_metric3 - floor(debug_metric3); - debug_metric3 *= debug_metric3; - debug_metric3 *= debug_metric3; - debug_metric3 *= debug_metric3; - debug_metric3 *= 16.0; - //col.xyz = vec3(debug_metric3, debug_metric2, debug_metric);// TODO: Remove - vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec3[4] orm_factors; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index fd80d1bb2c..1653cc1a90 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -52,18 +52,15 @@ vec4 texgen_object_pbr(vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) tcoord.z = tcoord.z; tcoord.w = tcoord.w; - tcoord = mat * tcoord; + tcoord = mat * tcoord; return tcoord; } -out vec4 debug_pos; // TODO: Remove - void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - debug_pos = vec4(texcoord0, 0.0, 1.0); vec3 n = normal_matrix * normal; vec3 t = normal_matrix * tangent.xyz; @@ -71,15 +68,10 @@ void main() vary_tangent = normalize(t); vary_sign = tangent.w; vary_normal = normalize(n); - + // Transform and pass tex coords // *NOTE: KHR texture transform is ignored for now vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - // Adjust the texture repeats for a more sensible default. - // *TODO: Remove this extra factor when KHR texture transform is added - float texture_density_factor = 3.0; - //texture_density_factor /= 256.0; // TODO: Remove - vary_texcoord0.xy *= texture_density_factor; vec4 tc = vec4(texcoord1,0,1); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b4671963e1..85b4bb3dca 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -59,6 +59,7 @@ const S32 PBR_DETAIL_EMISSIVE = 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"); @@ -69,6 +70,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : { // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); + sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale"); // TODO: This is unused. Remove? sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); @@ -385,16 +387,15 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) materials = &gLocalTerrainMaterials.mDetailMaterials; } - // *TODO: I'm seeing terrain still jump when switching regions. Might have something to do with the extra repeat factor in the shader. Or is it a numerical precision issue?... - // *TODO: If we want to change the tiling, we should change this offset modulo to prevent seams + // *TODO: Figure out why this offset is *sometimes* producing seams at the region edge, and repeat jumps when crossing regions, when RenderTerrainPBRScale is not a factor of the region scale. LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; LLVector4 tp0, tp1; - tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); + tp0.setVec(sPBRDetailScale, 0.0f, 0.0f, offset_x); + tp1.setVec(0.0f, sPBRDetailScale, 0.0f, offset_y); constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; S32 detail_basecolor[terrain_material_count]; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 060354458d..99d192da86 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -68,7 +68,8 @@ public: static S32 sDetailMode; static S32 sPBRDetailMode; - static F32 sDetailScale; // meters per texture + static F32 sDetailScale; // textures per meter + static F32 sPBRDetailScale; // textures per meter protected: void boostTerrainDetailTextures(); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 4f9911a11c..5bc220fcbd 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,15 +209,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); - // TODO: I think this operation is being applied too early because it also affects the geometry - we only want to affect the UVs - // TODO: Figure out what correct scaling is needed to prevent seams at region borders - getPatchesPerEdge seems to not be the solution, nor is getGridsPerEdge on its own U32 surface_stride = mSurfacep->getGridsPerEdge(); - U32 texture_stride = mSurfacep->getGridsPerEdge() - 1; - if (!pbr) - { - // TODO: Re-enable legacy repeats - //texture_stride = mSurfacep->getGridsPerEdge(); - } U32 point_offset = x + y*surface_stride; *normal = getNormal(x, y); @@ -229,8 +221,9 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); - // TODO: Revert for non-PBR only here, and/or add note that non-PBR doesn't actually use it. - LLVector3 tex_pos = rel_pos * (1.f/(texture_stride * mSurfacep->getMetersPerGrid())); + // *NOTE: Only PBR terrain uses the UVs right now. Texture terrain just ignores it. + // *NOTE: In the future, UVs and horizontal position will no longer have a 1:1 relationship for PBR terrain + LLVector3 tex_pos = rel_pos; tex0->mV[0] = tex_pos.mV[0]; tex0->mV[1] = tex_pos.mV[1]; tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index baf5480c6a..8ee675820c 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -134,6 +134,16 @@ static bool handleTerrainScaleChanged(const LLSD& newvalue) return true; } +static bool handlePBRTerrainScaleChanged(const LLSD& newvalue) +{ + F64 scale = newvalue.asReal(); + if (scale != 0.0) + { + LLDrawPoolTerrain::sPBRDetailScale = F32(1.0 / scale); + } + return true; +} + static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) { std::string new_string = newvalue.asString(); @@ -712,6 +722,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); -- cgit v1.2.3 From d6aced7abf0c54ec94033534124025c87fb9aeb2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:54 -0700 Subject: DRTVWR-592: Remove WIP separate code path for terrain geometry rebuilds for PBR as that is not needed at the moment --- indra/newview/lldrawpoolterrain.cpp | 4 --- indra/newview/lldrawpoolterrain.h | 1 - indra/newview/llsurfacepatch.cpp | 2 +- indra/newview/llsurfacepatch.h | 2 +- indra/newview/llviewercontrol.cpp | 7 ----- indra/newview/llvlcomposition.cpp | 11 ++------ indra/newview/llvlcomposition.h | 2 -- indra/newview/llvosurfacepatch.cpp | 56 ++++++++++++++----------------------- indra/newview/llvosurfacepatch.h | 12 +++----- 9 files changed, 30 insertions(+), 67 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 85b4bb3dca..fb27729b57 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -56,7 +56,6 @@ int DebugDetailMap = 0; const S32 PBR_DETAIL_EMISSIVE = 0; -S32 LLDrawPoolTerrain::sDetailMode = 1; S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE; @@ -71,8 +70,6 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale"); - // TODO: This is unused. Remove? - sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD); @@ -112,7 +109,6 @@ U32 LLDrawPoolTerrain::getVertexDataMask() void LLDrawPoolTerrain::prerender() { - sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 99d192da86..13f031c8e7 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -66,7 +66,6 @@ public: LLPointer m2DAlphaRampImagep; LLPointer mAlphaNoiseImagep; - static S32 sDetailMode; static S32 sPBRDetailMode; static F32 sDetailScale; // textures per meter static F32 sPBRDetailScale; // textures per meter diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5bc220fcbd..b4daf71ce2 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -201,7 +201,7 @@ LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, - LLVector2 *tex0, LLVector2 *tex1, bool pbr) + LLVector2 *tex0, LLVector2 *tex1) { if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp) { diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 0e6c045145..8c8f501dce 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -106,7 +106,7 @@ public: const LLVector3 &getNormal(const U32 x, const U32 y) const; void eval(const U32 x, const U32 y, const U32 stride, - LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1, bool pbr); + LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 8ee675820c..ea821004a3 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -118,12 +118,6 @@ static bool handleRenderFarClipChanged(const LLSD& newvalue) return false; } -static bool handleTerrainDetailChanged(const LLSD& newvalue) -{ - LLDrawPoolTerrain::sDetailMode = newvalue.asInteger(); - return true; -} - static bool handleTerrainScaleChanged(const LLSD& newvalue) { F64 scale = newvalue.asReal(); @@ -720,7 +714,6 @@ void settings_setup_listeners() { setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); - setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 130d74b286..fa19bcae87 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -120,16 +120,11 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) } LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() -{ - return mMaterialType; -} - -void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; const BOOL use_textures = texturesReady() || !materialsReady(); - mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; + return use_textures ? Type::TEXTURE : Type::PBR; } BOOL LLTerrainMaterials::texturesReady(BOOL boost) @@ -386,7 +381,7 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. +// *TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { @@ -423,7 +418,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { tex = mDetailMaterials[i]->mBaseColorTexture; } - // TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) + // *TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index a62302292f..882c3d89b2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -61,7 +61,6 @@ public: LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); - void updateMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); @@ -71,7 +70,6 @@ protected: LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; bool mMaterialTexturesSet[ASSET_COUNT]; - Type mMaterialType = Type::TEXTURE; }; // Local materials to override all regions diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index a672777914..6318361d8d 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,8 +246,7 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr) + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -263,24 +262,21 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -289,8 +285,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr) + U32 &index_offset) { S32 i, j, x, y; @@ -326,7 +321,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -394,8 +389,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr) + U32 &index_offset) { S32 vertex_count = 0; S32 i, x, y; @@ -427,7 +421,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -440,7 +434,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -477,7 +471,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -491,7 +485,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -535,7 +529,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -549,7 +543,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -592,8 +586,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr) + U32 &index_offset) { S32 i, x, y; @@ -619,7 +612,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -631,7 +624,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -667,7 +660,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -679,7 +672,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -721,7 +714,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -733,7 +726,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -1044,13 +1037,6 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; - const LLFace* region_facep = *mFaceList.begin(); - const LLViewerObject* region_patchp = region_facep->getViewerObject(); - LLVLComposition* composition = region_patchp->getRegion()->getComposition(); - // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. - composition->updateMaterialType(); - const bool pbr = composition->getMaterialType() == LLTerrainMaterials::Type::PBR; - LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders @@ -1087,7 +1073,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices, pbr); + patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices); indices_index += facep->getIndicesCount(); index_offset += facep->getGeomCount(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 06bb373578..a3dcb945d1 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,8 +67,7 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr); + LLStrider &indicesp); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -122,24 +121,21 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 7f7431891661668b898e03345c8023b4bbd0d9d9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:59 -0700 Subject: DRTVWR-592: Add tracy block to gen_terrain_tangents (not profiled) --- indra/newview/llvosurfacepatch.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 6318361d8d..feb1e26d57 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1001,6 +1001,8 @@ void gen_terrain_tangents(U16 strider_vertex_count, LLStrider &texCoords0p, LLStrider &indicesp) { + LL_PROFILE_ZONE_SCOPED + LLVector4a *vertices = new LLVector4a[strider_vertex_count]; LLVector4a *normals = new LLVector4a[strider_vertex_count]; LLVector4a *tangents = new LLVector4a[strider_vertex_count]; -- cgit v1.2.3 From ab3b4edac7809008cfed6d1b77e5a4debb22c88e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:03 -0700 Subject: DRTVWR-592: Fix broken minimap loading, improve minimap view of PBR materials (still not accurate, but better...) --- indra/llimage/llimage.cpp | 53 ++++++++++++++ indra/llimage/llimage.h | 6 ++ indra/newview/llfetchedgltfmaterial.cpp | 5 +- indra/newview/llfetchedgltfmaterial.h | 9 ++- indra/newview/llgltfmateriallist.cpp | 4 +- indra/newview/llsurfacepatch.cpp | 2 +- indra/newview/llvlcomposition.cpp | 125 ++++++++++++++++++++++++++++---- indra/newview/llvlcomposition.h | 2 +- 8 files changed, 179 insertions(+), 27 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index a96b6601bd..acfc254b65 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -31,6 +31,7 @@ #include "llmath.h" #include "v4coloru.h" +#include "v3color.h" #include "llimagebmp.h" #include "llimagetga.h" @@ -1026,6 +1027,34 @@ bool LLImageRaw::optimizeAwayAlpha() return false; } +bool LLImageRaw::makeAlpha() +{ + if (getComponents() == 3) + { + U8* data = getData(); + U32 pixels = getWidth() * getHeight(); + + // alpha channel doesn't exist, make a new copy of data with alpha channel + U8* new_data = (U8*) ll_aligned_malloc_16(getWidth() * getHeight() * 4); + + for (U32 i = 0; i < pixels; ++i) + { + U32 di = i * 4; + U32 si = i * 3; + for (U32 j = 0; j < 3; ++j) + { + new_data[di+j] = data[si+j]; + } + } + + setDataAndSize(new_data, getWidth(), getHeight(), 3); + + return true; + } + + return false; +} + void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image) { // Find new sizes @@ -1268,6 +1297,30 @@ void LLImageRaw::fill( const LLColor4U& color ) } } +void LLImageRaw::tint( const LLColor3& color ) +{ + llassert( (3 == getComponents()) || (4 == getComponents()) ); + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + + S32 pixels = getWidth() * getHeight(); + const S32 components = getComponents(); + U8* data = getData(); + for( S32 i = 0; i < pixels; i++ ) + { + const float c0 = data[0] * color.mV[0]; + const float c1 = data[1] * color.mV[1]; + const float c2 = data[2] * color.mV[2]; + data[0] = llclamp((U8)c0, 0, 255); + data[1] = llclamp((U8)c1, 0, 255); + data[2] = llclamp((U8)c2, 0, 255); + data += components; + } +} + LLPointer LLImageRaw::duplicate() { if(getNumRefs() < 2) diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8f9e1b3c54..77b5f0b7bc 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -71,6 +71,7 @@ const S32 HTTP_PACKET_SIZE = 1496; class LLImageFormatted; class LLImageRaw; class LLColor4U; +class LLColor3; typedef enum e_image_codec { @@ -212,6 +213,8 @@ public: // if the alpha channel is all 100% opaque, delete it // returns true if alpha channel was deleted bool optimizeAwayAlpha(); + // Create an alpha channel if this image doesn't have one + bool makeAlpha(); static S32 biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE); static S32 expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE); @@ -225,6 +228,9 @@ public: // Fill the buffer with a constant color void fill( const LLColor4U& color ); + // Multiply this raw image by the given color + void tint( const LLColor3& color ); + // Copy operations //duplicate this raw image if refCount > 1. diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 1fb3577dd7..c870d4778c 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -35,8 +35,6 @@ LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() : LLGLTFMaterial() , mExpectedFlusTime(0.f) - , mActive(true) - , mFetching(false) { } @@ -163,10 +161,11 @@ void LLFetchedGLTFMaterial::onMaterialComplete(std::function material_co materialCompleteCallbacks.push_back(material_complete); } -void LLFetchedGLTFMaterial::materialComplete() +void LLFetchedGLTFMaterial::materialComplete(bool success) { llassert(mFetching); mFetching = false; + mFetchSuccess = success; for (std::function material_complete : materialCompleteCallbacks) { diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index ce4d33a213..c5f6f6ca94 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -49,7 +49,7 @@ public: void bind(LLViewerTexture* media_tex = nullptr); bool isFetching() const { return mFetching; } - bool isLoaded() const { return !mFetching; } + bool isLoaded() const { return !mFetching && mFetchSuccess; } // Textures used for fetching/rendering LLPointer mBaseColorTexture; @@ -61,11 +61,12 @@ protected: // Lifetime management void materialBegin(); - void materialComplete(); + void materialComplete(bool success); F64 mExpectedFlusTime; // since epoch in seconds - bool mActive; - bool mFetching; + bool mActive = true; + bool mFetching = false; + bool mFetchSuccess = false; std::vector> materialCompleteCallbacks; }; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 99a052f719..7994515b61 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -549,7 +549,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp if (status != LL_ERR_NOERR) { LL_WARNS("GLTF") << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; - asset_data->mMaterial->materialComplete(); + asset_data->mMaterial->materialComplete(false); delete asset_data; } else @@ -634,7 +634,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp LL_DEBUGS("GLTF") << "Failed to get material " << id << LL_ENDL; } - asset_data->mMaterial->materialComplete(); + asset_data->mMaterial->materialComplete(true); delete asset_data; }); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index b4daf71ce2..a6370e9ec2 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -741,7 +741,7 @@ void LLSurfacePatch::updateGL() updateCompositionStats(); F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], + if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY], tex_patch_size, tex_patch_size)) { mSTexUpdate = FALSE; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index fa19bcae87..f645023217 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -129,26 +129,28 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() BOOL LLTerrainMaterials::texturesReady(BOOL boost) { + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { if (!textureReady(mDetailTextures[i], boost)) { - return FALSE; + ready = FALSE; } } - return TRUE; + return ready; } BOOL LLTerrainMaterials::materialsReady(BOOL boost) { + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) { - return FALSE; + ready = FALSE; } } - return TRUE; + return ready; } // Boost the texture loading priority @@ -188,6 +190,10 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO } return FALSE; } + if (tex->getComponents() == 0) + { + return FALSE; + } return TRUE; } @@ -381,8 +387,7 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -// *TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. -BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, +BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height) { LL_PROFILE_ZONE_SCOPED @@ -390,8 +395,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, llassert(x >= 0.f); llassert(y >= 0.f); - LLTimer gen_timer; - /////////////////////////// // // Generate raw data arrays for surface textures @@ -403,6 +406,17 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; + // *TODO: Remove this as it is reduandant computation (first and foremost + // because getMaterialType() does something similar, but also... shouldn't + // the textures/materials already be loaded by now?) + if (use_textures) + { + if (!texturesReady()) { return FALSE; } + } + else + { + if (!materialsReady()) { return FALSE; } + } for (S32 i = 0; i < ASSET_COUNT; i++) { @@ -410,16 +424,37 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { // Read back a raw image for this discard level, if it exists LLViewerFetchedTexture* tex; + LLViewerFetchedTexture* tex_emissive; // Can be null + bool has_base_color_factor; + bool has_emissive_factor; + LLColor3 base_color_factor; + LLColor3 emissive_factor; if (use_textures) { tex = mDetailTextures[i]; + tex_emissive = nullptr; + has_base_color_factor = false; + has_emissive_factor = false; + llassert(tex); } else { tex = mDetailMaterials[i]->mBaseColorTexture; + tex_emissive = mDetailMaterials[i]->mEmissiveTexture; + base_color_factor = LLColor3(mDetailMaterials[i]->mBaseColor); + // *HACK: Treat alpha as black + base_color_factor *= (mDetailMaterials[i]->mBaseColor.mV[VW]); + emissive_factor = mDetailMaterials[i]->mEmissiveColor; + has_base_color_factor = (base_color_factor.mV[VX] != 1.f || + base_color_factor.mV[VY] != 1.f || + base_color_factor.mV[VZ] != 1.f); + has_emissive_factor = (emissive_factor.mV[VX] != 1.f || + emissive_factor.mV[VY] != 1.f || + emissive_factor.mV[VZ] != 1.f); } - // *TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) - if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } + + if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } + // tex_emissive can be null, and then will be ignored S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; @@ -430,8 +465,9 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; - if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. + if(tex->getRawImageLevel() != ddiscard) { + // Raw image is not ready, will enter here again later. if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { tex->setBoostLevel(LLGLTexture::BOOST_MAP); @@ -442,21 +478,78 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { tex->destroyRawImage() ; } - LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } + if (tex_emissive) + { + if(tex_emissive->getRawImageLevel() != ddiscard) + { + // Raw image is not ready, will enter here again later. + if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) + { + tex_emissive->setBoostLevel(LLGLTexture::BOOST_MAP); + tex_emissive->forceToRefetchTexture(ddiscard); + } + + if(delete_raw) + { + tex_emissive->destroyRawImage() ; + } + return FALSE; + } + } mRawImages[i] = tex->getRawImage() ; if(delete_raw) { tex->destroyRawImage() ; } - if (tex->getWidth(ddiscard) != BASE_SIZE || + + // *TODO: This isn't quite right for PBR: + // 1) It does not convert the color images from SRGB to linear + // before mixing (which will always require copying the image). + // 2) It mixes emissive and base color before mixing terrain + // materials, but it should be the other way around + // 3) The composite function used to put emissive into base color + // is not an alpha blend. + // Long-term, we should consider a method that is more + // maintainable. Shaders, perhaps? Bake shaders to textures? + LLPointer raw_emissive; + if (tex_emissive) + { + raw_emissive = tex_emissive->getRawImage(); + if (has_emissive_factor || + tex_emissive->getWidth(ddiscard) != BASE_SIZE || + tex_emissive->getHeight(ddiscard) != BASE_SIZE || + tex_emissive->getComponents() != 4) + { + LLPointer newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); + // Copy RGB, leave alpha alone (set to opaque by default) + newraw_emissive->copy(mRawImages[i]); + if (has_emissive_factor) + { + newraw_emissive->tint(emissive_factor); + } + raw_emissive = newraw_emissive; // deletes old + } + } + if (has_base_color_factor || + raw_emissive || + tex->getWidth(ddiscard) != BASE_SIZE || tex->getHeight(ddiscard) != BASE_SIZE || tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); + if (has_base_color_factor) + { + newraw->tint(base_color_factor); + } + // Apply emissive texture + if (raw_emissive) + { + newraw->composite(raw_emissive); + } mRawImages[i] = newraw; // deletes old } } @@ -478,12 +571,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (x_end > mWidth) { - LL_WARNS("Terrain") << "x end > width" << LL_ENDL; + llassert(false); x_end = mWidth; } if (y_end > mWidth) { - LL_WARNS("Terrain") << "y end > width" << LL_ENDL; + llassert(false); y_end = mWidth; } @@ -513,7 +606,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (tex_comps != st_comps) { - LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL; + llassert(false); return FALSE; } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 882c3d89b2..d59c0f95bb 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -87,7 +87,7 @@ public: BOOL generateHeights(const F32 x, const F32 y, const F32 width, const F32 height); BOOL generateComposition(); // Generate texture from composition values. - BOOL generateTexture(const F32 x, const F32 y, const F32 width, const F32 height); + BOOL generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. // So we need to compress heights into this range. -- cgit v1.2.3 From 754fe9d4b72c3a22fb18e32bd48daaa2ae7b02f7 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:09 -0700 Subject: DRTVWR-592: (WIP) Triplanar mapping --- indra/llrender/llglslshader.h | 1 + indra/llrender/llshadermgr.cpp | 8 ++ .../shaders/class1/deferred/pbrterrainF.glsl | 98 +++----------- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 148 +++++++++++++++++++++ .../shaders/class1/deferred/pbrterrainV.glsl | 9 +- indra/newview/llviewershadermgr.cpp | 2 + 6 files changed, 188 insertions(+), 78 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index b8071248e2..0de97da4db 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -57,6 +57,7 @@ public: bool hasAlphaMask = false; bool hasReflectionProbes = false; bool attachNothing = false; + bool isPBRTerrain = false; // include: shaders\class1\deferred\pbrterrainUtilF.glsl }; // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b2c8255d2a..91412add44 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -291,6 +291,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } + if (features->isPBRTerrain) + { + if (!shader->attachFragmentObject("deferred/pbrterrainUtilF.glsl")) + { + return FALSE; + } + } + // NOTE order of shader object attaching is VERY IMPORTANT!!! if (features->hasWaterFog) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index e6261ca85e..5bf20a3020 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -25,6 +25,15 @@ #define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config + +// TODO: Should be able to define this in another file and have it included in this one... +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +#define TerrainCoord vec4[2] +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +#define TerrainCoord vec2 +#endif + out vec4 frag_data[4]; uniform sampler2D alpha_ramp; @@ -60,6 +69,7 @@ uniform vec3[4] emissiveColors; #endif uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() +in vec4[2] vary_coords; in vec3 vary_normal; in vec3 vary_tangent; flat in float vary_sign; @@ -67,88 +77,22 @@ in vec4 vary_texcoord0; in vec4 vary_texcoord1; 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 -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 ); -} - -vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); -} - -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 ); -} -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - vec3[4] samples; - samples[0] = texture(tex0, texcoord).xyz; - samples[1] = texture(tex1, texcoord).xyz; - samples[2] = texture(tex2, texcoord).xyz; - samples[3] = texture(tex3, texcoord).xyz; - samples[0] = srgb_to_linear(samples[0]); - samples[1] = srgb_to_linear(samples[1]); - samples[2] = srgb_to_linear(samples[2]); - samples[3] = srgb_to_linear(samples[3]); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} - -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - vec4[4] samples; - samples[0] = texture(tex0, texcoord); - samples[1] = texture(tex1, texcoord); - samples[2] = texture(tex2, texcoord); - samples[3] = texture(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); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} +float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); +vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +void main() { - vec3[4] samples; - samples[0] = texture(tex0, texcoord).xyz; - samples[1] = texture(tex1, texcoord).xyz; - samples[2] = texture(tex2, texcoord).xyz; - samples[3] = texture(tex3, texcoord).xyz; - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} -vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - vec3[4] samples; - samples[0] = texture(tex0, texcoord).xyz; - samples[1] = texture(tex1, texcoord).xyz; - samples[2] = texture(tex2, texcoord).xyz; - samples[3] = texture(tex3, texcoord).xyz; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 + TerrainCoord terrain_texcoord = vary_coords; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 + TerrainCoord terrain_texcoord = vary_texcoord0.xy; +#endif -void main() -{ - vec2 terrain_texcoord = vary_texcoord0.xy; float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl new file mode 100644 index 0000000000..4f337b5ce1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -0,0 +1,148 @@ +/** + * @file class1\deferred\pbrterrainUtilF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +/** + * Triplanar mapping implementation adapted from Inigo Quilez' example shader, + * MIT license. + * https://www.shadertoy.com/view/MtsGWH + * Copyright © 2015 Inigo Quilez + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: The above copyright + * notice and this permission notice shall be included in all copies or + * substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", + * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +in vec3 vary_vertex_normal; + +vec3 srgb_to_linear(vec3 c); + +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 ); +} + +vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); +} + +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 ); +} + +#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, zx, unused) +#define TerrainCoord vec4[2] +// Triplanar mapping +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ + vec4 x = texture(tex, terrain_coord[0].zw); + vec4 y = texture(tex, terrain_coord[1].xy); + vec4 z = texture(tex, terrain_coord[0].xy); + float sharpness = 8.0; + vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); +} +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +#define TerrainCoord vec2 +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ + return texture(tex, terrain_coord); +} +#endif + +vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = terrain_texture(tex0, texcoord).xyz; + samples[1] = terrain_texture(tex1, texcoord).xyz; + samples[2] = terrain_texture(tex2, texcoord).xyz; + samples[3] = terrain_texture(tex3, texcoord).xyz; + samples[0] = srgb_to_linear(samples[0]); + samples[1] = srgb_to_linear(samples[1]); + samples[2] = srgb_to_linear(samples[2]); + samples[3] = srgb_to_linear(samples[3]); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec4[4] samples; + samples[0] = terrain_texture(tex0, texcoord); + samples[1] = terrain_texture(tex1, texcoord); + samples[2] = terrain_texture(tex2, texcoord); + samples[3] = terrain_texture(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); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = terrain_texture(tex0, texcoord).xyz; + samples[1] = terrain_texture(tex1, texcoord).xyz; + samples[2] = terrain_texture(tex2, texcoord).xyz; + samples[3] = terrain_texture(tex3, texcoord).xyz; + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = terrain_texture(tex0, texcoord).xyz; + samples[1] = terrain_texture(tex1, texcoord).xyz; + samples[2] = terrain_texture(tex2, texcoord).xyz; + samples[3] = terrain_texture(tex3, texcoord).xyz; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 1653cc1a90..991783d242 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -34,6 +34,8 @@ in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; +out vec4[2] vary_coords; +out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl out vec3 vary_normal; out vec3 vary_tangent; flat out float vary_sign; @@ -63,6 +65,8 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vec3 n = normal_matrix * normal; + // *TODO: Looks like terrain normals are per-vertex when they should be per-triangle instead, causing incorrect values on triangles touching steep edges of terrain + vary_vertex_normal = normal; vec3 t = normal_matrix * tangent.xyz; vary_tangent = normalize(t); @@ -73,7 +77,10 @@ void main() // *NOTE: KHR texture transform is ignored for now vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - vec4 tc = vec4(texcoord1,0,1); + vec4 tc = vec4(texcoord1,0,1); // TODO: This is redundant. Better to just use position and ignore texcoord? (We still need to decide how to handle alpha ramp, though...) + vary_coords[0].xy = texgen_object_pbr(vec4(position.xy, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_coords[0].zw = texgen_object_pbr(vec4(position.yz, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_coords[1].xy = texgen_object_pbr(vec4(position.zx, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; vary_texcoord0.zw = tc.xy; vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 2235b6d9a4..320801861c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -720,6 +720,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back(make_pair("deferred/pbrterrainUtilF.glsl", 1)); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); @@ -1506,6 +1507,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; + gDeferredPBRTerrainProgram.mFeatures.isPBRTerrain = true; gDeferredPBRTerrainProgram.mShaderFiles.clear(); gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); -- cgit v1.2.3 From 2dc3f3ade165d7d15d8579a0f04b72f6aa56c7fe Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:16 -0700 Subject: DRTVWR-592: Add triplanar mapping setting, gate to High graphics setting or higher, bump feature table --- indra/newview/app_settings/settings.xml | 11 +++++++++++ .../app_settings/shaders/class1/deferred/pbrterrainF.glsl | 3 --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 2 -- indra/newview/featuretable.txt | 8 ++++++++ indra/newview/featuretable_mac.txt | 8 ++++++++ indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 15 ++++++++++++++- 7 files changed, 42 insertions(+), 6 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2dac0b5d70..28ee1b3a70 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10733,6 +10733,17 @@ Value 4.0 + RenderTerrainPBRPlanarSampleCount + + Comment + How many UV planes to sample PBR terrain textures from. 1 is "flat", 3 is triplanar mapping (aka box mapping) + Persist + 1 + Type + S32 + Value + 3 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 5bf20a3020..b9073a9361 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -25,9 +25,6 @@ #define TERRAIN_PBR_DETAIL_EMISSIVE 0 -#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config - -// TODO: Should be able to define this in another file and have it included in this one... #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 #define TerrainCoord vec4[2] #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 4f337b5ce1..b0b77398df 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -64,8 +64,6 @@ 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 ); } -#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config - #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, zx, unused) #define TerrainCoord vec4[2] diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index cb941b424b..4bc83b099f 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -49,6 +49,7 @@ RenderReflectionProbeDetail 1 2 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 @@ -95,6 +96,7 @@ RenderReflectionsEnabled 1 0 RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0 RenderVolumeLODFactor 1 1.125 RenderDeferredSSAO 1 0 @@ -124,6 +126,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 RenderDeferredSSAO 1 0 @@ -151,6 +154,7 @@ RenderLocalLights 1 1 RenderTransparentWater 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.25 RenderDeferredSSAO 1 0 @@ -180,6 +184,7 @@ RenderLocalLights 1 1 RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.375 RenderDeferredSSAO 1 0 @@ -209,6 +214,7 @@ RenderLocalLights 1 1 RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 RenderDeferredSSAO 1 1 @@ -237,6 +243,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.75 @@ -265,6 +272,7 @@ RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVolumeLODFactor 1 2.0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c04c1c9a4f..97dad655a2 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -45,6 +45,7 @@ RenderObjectBump 1 1 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 @@ -89,6 +90,7 @@ RenderLocalLights 1 0 RenderMaxPartCount 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 0 RenderTreeLODFactor 1 0 RenderVolumeLODFactor 1 1.125 @@ -118,6 +120,7 @@ RenderMaxPartCount 1 2048 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 @@ -147,6 +150,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.25 @@ -176,6 +180,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.375 @@ -205,6 +210,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 @@ -234,6 +240,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.75 @@ -262,6 +269,7 @@ RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVolumeLODFactor 1 2.0 diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index ea821004a3..19999545b6 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -717,6 +717,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRPlanarSampleCount", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 320801861c..c23ef1c314 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -69,6 +69,14 @@ bool LLViewerShaderMgr::sSkipReload = false; LLVector4 gShinyOrigin; +S32 clamp_terrain_mapping(S32 mapping) +{ + // 1 = "flat", 2 not implemented, 3 = triplanar mapping + mapping = llclamp(mapping, 1, 3); + if (mapping == 2) { mapping = 1; } + return mapping; +} + //utility shaders LLGLSLShader gOcclusionProgram; LLGLSLShader gSkinnedOcclusionProgram; @@ -682,6 +690,9 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["REF_SAMPLE_COUNT"] = "32"; } + const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); + attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); + LLGLSLShader::sGlobalDefines = attribs; // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. @@ -720,7 +731,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back(make_pair("deferred/pbrterrainUtilF.glsl", 1)); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); @@ -1497,6 +1508,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); + const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d", detail); gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; @@ -1514,6 +1526,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PBR_DETAIL", llformat("%d", detail)); + gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT", llformat("%d", mapping)); success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); llassert(success); } -- cgit v1.2.3 From ed973f4cbc58b5460513be709a0a23f0caa1120c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:22 -0700 Subject: DRTVWR-592: Add test config for triplanar mapping blend strength --- indra/newview/app_settings/settings.xml | 11 +++++++++++ .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 8 ++++++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 28ee1b3a70..85dfe688a7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10744,6 +10744,17 @@ Value 3 + RenderTerrainPBRTriplanarBlendFactor + + Comment + Higher values create sharper transitions, but are more likely to produce artifacts. + Persist + 1 + Type + F32 + Value + 8.0 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index b0b77398df..ef2d030320 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -73,7 +73,7 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) vec4 x = texture(tex, terrain_coord[0].zw); vec4 y = texture(tex, terrain_coord[1].xy); vec4 z = texture(tex, terrain_coord[0].xy); - float sharpness = 8.0; + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 19999545b6..b6f01f2843 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -718,6 +718,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRPlanarSampleCount", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRTriplanarBlendFactor", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index c23ef1c314..f1f92132ec 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -690,8 +690,12 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["REF_SAMPLE_COUNT"] = "32"; } - const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); - attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); + { // PBR terrain + const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); + attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); + const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor"); + attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor); + } LLGLSLShader::sGlobalDefines = attribs; -- cgit v1.2.3 From 23ca385f3dd0304a92e8da54236bc60f4f52e359 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:28 -0700 Subject: DRTVWR-592: Give PBR terrain shader more descriptive name for debugging/profiling --- indra/newview/llviewershadermgr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f1f92132ec..5849f97e0e 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1513,7 +1513,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); - gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d", detail); + gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d %s", + detail, + (mapping == 1 ? "flat" : "triplanar")); gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; -- cgit v1.2.3 From db4bc52829ec041ca0366069d07e942f0d32aacd Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:34 -0700 Subject: DRTVWR-592: (WIP) PBR Terrain: Improve orientation of textures and normal maps for triplanar mapping, minor cleanup --- .../shaders/class1/deferred/pbrterrainF.glsl | 10 ++-- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 68 ++++++++++++++++++---- .../shaders/class1/deferred/pbrterrainV.glsl | 52 +++++++++-------- .../shaders/class1/deferred/textureUtilV.glsl | 2 +- indra/newview/lldrawpoolterrain.cpp | 28 +++++---- 5 files changed, 109 insertions(+), 51 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index b9073a9361..7febbe280e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -35,7 +35,7 @@ out vec4 frag_data[4]; uniform sampler2D alpha_ramp; -// *TODO: Configurable quality level which disables PBR features on machines +// *TODO: More 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 uniform sampler2D detail_0_base_color; @@ -57,7 +57,6 @@ uniform sampler2D detail_2_emissive; uniform sampler2D detail_3_emissive; #endif -// *TODO: More efficient packing? uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl uniform vec4 metallicFactors; uniform vec4 roughnessFactors; @@ -66,7 +65,9 @@ uniform vec3[4] emissiveColors; #endif uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 in vec4[2] vary_coords; +#endif in vec3 vary_normal; in vec3 vary_tangent; flat in float vary_sign; @@ -79,7 +80,7 @@ float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); void main() { @@ -101,7 +102,6 @@ void main() discard; } - vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec3[4] orm_factors; orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); @@ -124,7 +124,7 @@ void main() float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); // from mikktspace.com - vec3 vNt = normal_texture.xyz*2.0-1.0; + vec3 vNt = sample_and_mix_normal(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index ef2d030320..a9155cc629 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -65,14 +65,56 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) } #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 -// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, zx, unused) -#define TerrainCoord vec4[2] // Triplanar mapping + +// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) +#define TerrainCoord vec4[2] + +vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) +{ + // If the vertex normal is negative, flip the texture back + // right-side up. + vec2 uv = uv_unflipped * vec2(sign, 1); + return texture(tex, uv); +} + +vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) +{ + // Unpack normal from pixel to vector + vec3 n = _t_texture(tex, uv_unflipped, sign).xyz*2.0-1.0; + // If the sign is negative, rotate normal by 180 degrees + n.xy = (min(0, sign) * n.xy) + (min(0, -sign) * -n.xy); + return n; +} + vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { - vec4 x = texture(tex, terrain_coord[0].zw); - vec4 y = texture(tex, terrain_coord[1].xy); - vec4 z = texture(tex, terrain_coord[0].xy); + // Multiplying the UVs by the sign of the normal flips the texture upright. + vec4 x = _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); + vec4 y = _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); + vec4 z = _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; + vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); +} + +// Specialized triplanar normal texture sampling implementation, taking into +// account how the rotation of the texture affects the lighting and trying to +// negate that. +// *TODO: Decide if we want this. It may be better to just calculate the +// tangents on-the-fly here rather than messing with the normals, due to the +// subtleties of the effects of triplanar mapping on UVs. These sampled normals +// are only valid on the faces of a cube, and the pregenerated tangents are +// only valid for uv = xy. +// *NOTE: Bottom face has not been tested +vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) +{ + vec3 x = _t_texture_n(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); + x.xy = vec2(-x.y, x.x); + vec3 y = _t_texture_n(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); + y.xy = -y.xy; + vec3 z = _t_texture_n(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); @@ -83,6 +125,11 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { return texture(tex, terrain_coord); } + +vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) +{ + return texture(tex, terrain_coord).xyz; +} #endif vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) @@ -135,12 +182,13 @@ vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, Terrai return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +// Returns the unpacked normal texture in range [-1, 1] +vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = terrain_texture(tex0, texcoord).xyz; - samples[1] = terrain_texture(tex1, texcoord).xyz; - samples[2] = terrain_texture(tex2, texcoord).xyz; - samples[3] = terrain_texture(tex3, texcoord).xyz; + samples[0] = terrain_texture_normal(tex0, texcoord).xyz; + samples[1] = terrain_texture_normal(tex1, texcoord).xyz; + samples[2] = terrain_texture_normal(tex2, texcoord).xyz; + samples[3] = terrain_texture_normal(tex3, texcoord).xyz; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 991783d242..2df5faf037 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -34,7 +34,9 @@ in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 out vec4[2] vary_coords; +#endif out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl out vec3 vary_normal; out vec3 vary_tangent; @@ -42,22 +44,13 @@ flat out float vary_sign; out vec4 vary_texcoord0; out vec4 vary_texcoord1; -uniform vec4 object_plane_s; -uniform vec4 object_plane_t; +// *HACK: tangent_space_transform should use texture_normal_transform, or maybe +// we shouldn't use tangent_space_transform at all. See the call to +// tangent_space_transform below. +uniform vec4[2] texture_base_color_transform; -vec4 texgen_object_pbr(vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) -{ - vec4 tcoord; - - tcoord.x = dot(tc, tp0); - tcoord.y = dot(tc, tp1); - tcoord.z = tcoord.z; - tcoord.w = tcoord.w; - - tcoord = mat * tcoord; - - return tcoord; -} +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); +vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() { @@ -65,23 +58,36 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vec3 n = normal_matrix * normal; - // *TODO: Looks like terrain normals are per-vertex when they should be per-triangle instead, causing incorrect values on triangles touching steep edges of terrain vary_vertex_normal = normal; vec3 t = normal_matrix * tangent.xyz; vary_tangent = normalize(t); + // *TODO: Decide if we want this. It may be better to just calculate the + // tangents on-the-fly in the fragment shader, due to the subtleties of the + // effect of triplanar mapping on UVs. + // *HACK: Should be using texture_normal_transform here. The KHR texture + // transform spec requires handling texture transforms separately for each + // individual texture. + vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_base_color_transform, texture_matrix0)); vary_sign = tangent.w; vary_normal = normalize(n); // Transform and pass tex coords - // *NOTE: KHR texture transform is ignored for now - vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - - vec4 tc = vec4(texcoord1,0,1); // TODO: This is redundant. Better to just use position and ignore texcoord? (We still need to decide how to handle alpha ramp, though...) - vary_coords[0].xy = texgen_object_pbr(vec4(position.xy, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - vary_coords[0].zw = texgen_object_pbr(vec4(position.yz, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - vary_coords[1].xy = texgen_object_pbr(vec4(position.zx, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + // *HACK: texture_base_color_transform is used for all of these here, but + // the KHR texture transform spec requires handling texture transforms + // separately for each individual texture. +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 + // xy + vary_coords[0].xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0); + // yz + vary_coords[0].zw = texture_transform(position.yz, texture_base_color_transform, texture_matrix0); + // (-x)z + vary_coords[1].xy = texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform, texture_matrix0); +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 + vary_texcoord0.xy = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); +#endif + vec4 tc = vec4(texcoord1,0,1); 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/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl index 636dfed4ba..732333311c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl @@ -65,7 +65,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl // Apply texture animation first to avoid shearing and other artifacts texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy; // Convert to left-handed coordinate system. The offset of 1 is necessary - // for rotations to be applied correctly. + // for rotation and scale to be applied correctly. texcoord.y = 1.0 - texcoord.y; texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy); // Convert back to right-handed coordinate system diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index fb27729b57..6f48971ca0 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -383,16 +383,6 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) materials = &gLocalTerrainMaterials.mDetailMaterials; } - // *TODO: Figure out why this offset is *sometimes* producing seams at the region edge, and repeat jumps when crossing regions, when RenderTerrainPBRScale is not a factor of the region scale. - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; - - LLVector4 tp0, tp1; - - tp0.setVec(sPBRDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sPBRDetailScale, 0.0f, offset_y); - constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; S32 detail_basecolor[terrain_material_count]; S32 detail_normal[terrain_material_count]; @@ -463,8 +453,22 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; llassert(shader); - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); + + // *TODO: Figure out why this offset is *sometimes* producing seams at the + // region edge, and repeat jumps when crossing regions, when + // RenderTerrainPBRScale is not a factor of the region scale. + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + + LLGLTFMaterial::TextureTransform base_color_transform; + base_color_transform.mScale = LLVector2(sPBRDetailScale, sPBRDetailScale); + base_color_transform.mOffset = LLVector2(offset_x, offset_y); + F32 base_color_packed[8]; + base_color_transform.getPacked(base_color_packed); + // *HACK: Use the same texture repeats for all PBR terrain textures for now + // (not compliant with KHR texture transform spec) + shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed); LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -- cgit v1.2.3 From 3e3a3c1c5262e65df3edf27c4e27a6bbc8d49a01 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:40 -0700 Subject: DRTVWR-592: Fix terrain normal sampling in non-triplanar case --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a9155cc629..a89bc6f211 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -128,7 +128,7 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - return texture(tex, terrain_coord).xyz; + return texture(tex, terrain_coord).xyz*2.0-1.0; } #endif -- cgit v1.2.3 From 2895b7bf81c3d076a8ceaa4ce77037e870069365 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:45 -0700 Subject: DRTVWR-592: Triplanar performance pass --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 63 ++++++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a89bc6f211..1b13bc8836 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -109,14 +109,67 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) // *NOTE: Bottom face has not been tested vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - vec3 x = _t_texture_n(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; + vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + float threshold = 0.01; + vec3 significant = max(vec3(0), sign(weight - threshold)); + int sample_type = (int(significant.x) << 2) | + (int(significant.y) << 1) | + (int(significant.z) << 0); + + #define SAMPLE_X 1 << 2 + #define SAMPLE_Y 1 << 1 + #define SAMPLE_Z 1 << 0 + #define terrain_coord_x terrain_coord[0].zw + #define terrain_coord_y terrain_coord[1].xy + #define terrain_coord_z terrain_coord[0].xy + vec3 x; + vec3 y; + vec3 z; + switch (sample_type) + { + case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X | SAMPLE_Y: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec3(0); + break; + case SAMPLE_X | SAMPLE_Z: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec3(0); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_Y | SAMPLE_Z: + x = vec3(0); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec3(0); + z = vec3(0); + break; + case SAMPLE_Y: + x = vec3(0); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec3(0); + break; + case SAMPLE_Z: + default: + x = vec3(0); + y = vec3(0); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + } + + // *HACK: Transform normals according to orientation of the UVs x.xy = vec2(-x.y, x.x); - vec3 y = _t_texture_n(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); y.xy = -y.xy; - vec3 z = _t_texture_n(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); - float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -- cgit v1.2.3 From a8d69a4baecfae81b4adb68992f02e3ebc47b876 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:50 -0700 Subject: DRTVWR-592: Fix weights --- .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 1b13bc8836..e69ee54a8c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -112,10 +112,10 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); float threshold = 0.01; - vec3 significant = max(vec3(0), sign(weight - threshold)); - int sample_type = (int(significant.x) << 2) | - (int(significant.y) << 1) | - (int(significant.z) << 0); + weight = max(vec3(0), sign(weight - threshold)); + int sample_type = (int(weight.x) << 2) | + (int(weight.y) << 1) | + (int(weight.z) << 0); #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 -- cgit v1.2.3 From bb0ae367d705e6d45f21526b26caa962824d6375 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:56 -0700 Subject: DRTVWR-592: (WIP) Test impact of higher threshold on performance and visuals --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index e69ee54a8c..4f2619f811 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -111,7 +111,7 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); - float threshold = 0.01; + float threshold = 0.1; weight = max(vec3(0), sign(weight - threshold)); int sample_type = (int(weight.x) << 2) | (int(weight.y) << 1) | -- cgit v1.2.3 From e6777d566fddc79d1194a2090e5df5b609285d89 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:02 -0700 Subject: DRTVWR-592: Fix not thresholding texture lookups for non-normal textures. Also decrease threshold to (hopefully) reasonable level --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 72 +++++++++++++++++++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 4f2619f811..b89edc9731 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,6 +69,7 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) { @@ -89,12 +90,63 @@ vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { - // Multiplying the UVs by the sign of the normal flips the texture upright. - vec4 x = _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); - vec4 y = _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); - vec4 z = _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; + weight = max(vec3(0), sign(weight - threshold)); + + #define SAMPLE_X 1 << 2 + #define SAMPLE_Y 1 << 1 + #define SAMPLE_Z 1 << 0 + int sample_type = (int(weight.x) * SAMPLE_X) | + (int(weight.y) * SAMPLE_Y) | + (int(weight.z) * SAMPLE_Z); + #define terrain_coord_x terrain_coord[0].zw + #define terrain_coord_y terrain_coord[1].xy + #define terrain_coord_z terrain_coord[0].xy + vec4 x; + vec4 y; + vec4 z; + switch (sample_type) + { + case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X | SAMPLE_Y: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec4(0); + break; + case SAMPLE_X | SAMPLE_Z: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec4(0); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_Y | SAMPLE_Z: + x = vec4(0); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec4(0); + z = vec4(0); + break; + case SAMPLE_Y: + x = vec4(0); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec4(0); + break; + case SAMPLE_Z: + default: + x = vec4(0); + y = vec4(0); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + } + return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); } @@ -110,16 +162,16 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); - float threshold = 0.1; + vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; weight = max(vec3(0), sign(weight - threshold)); - int sample_type = (int(weight.x) << 2) | - (int(weight.y) << 1) | - (int(weight.z) << 0); #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 #define SAMPLE_Z 1 << 0 + int sample_type = (int(weight.x) * SAMPLE_X) | + (int(weight.y) * SAMPLE_Y) | + (int(weight.z) * SAMPLE_Z); #define terrain_coord_x terrain_coord[0].zw #define terrain_coord_y terrain_coord[1].xy #define terrain_coord_z terrain_coord[0].xy -- cgit v1.2.3 From 53a5055ab72c3fb77892a3e43c769c3b19c1e97d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:07 -0700 Subject: DRTVWR-592: (WIP) (has debug) Convert colors to linear before triplanar blending. General refactor. --- .../shaders/class1/deferred/pbrterrainF.glsl | 11 + .../shaders/class1/deferred/pbrterrainUtilF.glsl | 249 ++++++++++++--------- 2 files changed, 160 insertions(+), 100 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7febbe280e..ba917416ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,6 +135,17 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if 0 // TODO: Remove debug + //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove + //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove + //col.xyz = spec; // TODO: Remove + //col.xyz = vec3(1); // TODO: Remove + //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove + tnorm = vary_normal; // TODO: Remove + spec.r = 1.0; // TODO: Remove + spec.gb = vec2(1.0, 0.0); // TODO: Remove + emissive.rgb = vec3(0); // TODO: Remove +#endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index b89edc9731..c72bc65cca 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,7 +69,15 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] +#if 0 // TODO: Revert #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 +#else +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 +#endif + +// Positive value prevents artifacts when weights are close to zero +// TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) +#define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0 vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) { @@ -79,35 +87,60 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) return texture(tex, uv); } -vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) +vec4 _t_texture_c(sampler2D tex, vec2 uv_unflipped, float sign) { - // Unpack normal from pixel to vector - vec3 n = _t_texture(tex, uv_unflipped, sign).xyz*2.0-1.0; - // If the sign is negative, rotate normal by 180 degrees - n.xy = (min(0, sign) * n.xy) + (min(0, -sign) * -n.xy); - return n; + vec4 c = _t_texture(tex, uv_unflipped, sign); + c.xyz = srgb_to_linear(c.xyz); + return c; } -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +#define SAMPLE_X 1 << 2 +#define SAMPLE_Y 1 << 1 +#define SAMPLE_Z 1 << 0 +#define terrain_coord_x terrain_coord[0].zw +#define terrain_coord_y terrain_coord[1].xy +#define terrain_coord_z terrain_coord[0].xy +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainWeight +{ + vec3 weight; +#if TERRAIN_DEBUG + vec3 usage; +#endif + int type; +}; + +TerrainWeight _t_weight(TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - weight = max(vec3(0), sign(weight - threshold)); - - #define SAMPLE_X 1 << 2 - #define SAMPLE_Y 1 << 1 - #define SAMPLE_Z 1 << 0 - int sample_type = (int(weight.x) * SAMPLE_X) | - (int(weight.y) * SAMPLE_Y) | - (int(weight.z) * SAMPLE_Z); - #define terrain_coord_x terrain_coord[0].zw - #define terrain_coord_y terrain_coord[1].xy - #define terrain_coord_z terrain_coord[0].xy + vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + weight_signed -= vec3(threshold); + TerrainWeight tw; + tw.weight = max(vec3(0), weight_signed); + vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); +#if TERRAIN_DEBUG + tw.usage = usage; +#endif + tw.type = (int(usage.x) * SAMPLE_X) | + (int(usage.y) * SAMPLE_Y) | + (int(usage.z) * SAMPLE_Z); + return tw; +} + +struct TerrainSample +{ vec4 x; vec4 y; vec4 z; - switch (sample_type) +}; + +TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ + vec4 x; + vec4 y; + vec4 z; + switch (tw.type) { case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); @@ -117,37 +150,98 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) case SAMPLE_X | SAMPLE_Y: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec4(0); + z = x; break; case SAMPLE_X | SAMPLE_Z: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec4(0); z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + y = x; break; case SAMPLE_Y | SAMPLE_Z: - x = vec4(0); y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + x = y; break; case SAMPLE_X: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec4(0); - z = vec4(0); + y = x; + z = x; break; case SAMPLE_Y: - x = vec4(0); y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec4(0); + x = y; + z = y; break; case SAMPLE_Z: + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + x = z; + y = z; + break; default: x = vec4(0); - y = vec4(0); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + y = x; + z = x; break; } - return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); + TerrainSample ts; + ts.x = x; + ts.y = y; + ts.z = z; + return ts; +} + +struct TerrainSampleNormal +{ + vec3 x; + vec3 y; + vec3 z; +}; + +TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ + TerrainSample ts = _t_sample(tex, terrain_coord, tw); + TerrainSampleNormal tsn; + tsn.x = ts.x.xyz; + tsn.y = ts.y.xyz; + tsn.z = ts.z.xyz; + vec3 ns = sign(vary_vertex_normal); + // If the sign is negative, rotate normal by 180 degrees + tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); + tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); + tsn.z.xy = (min(0, ns.z) * tsn.z.xy) + (min(0, -ns.z) * -tsn.z.xy); + // *HACK: Transform normals according to orientation of the UVs + tsn.x.xy = vec2(-tsn.x.y, tsn.x.x); + tsn.y.xy = -tsn.y.xy; + return tsn; +} + +TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ + TerrainSample ts = _t_sample(tex, terrain_coord, tw); + ts.x.xyz = srgb_to_linear(ts.x.xyz); + ts.y.xyz = srgb_to_linear(ts.y.xyz); + ts.z.xyz = srgb_to_linear(ts.z.xyz); + return ts; +} + +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ + TerrainWeight tw = _t_weight(terrain_coord); + + TerrainSample ts = _t_sample(tex, terrain_coord, tw); + +#if 1 + return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +#else // TODO: Remove debug + //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); +#if 1 + return vec4(tw.usage, 1.0); +#else + //return vec4(tw.usage, 1.0); + return vec4((tw.usage + weight) / 2.0, 1.0); +#endif +#endif } // Specialized triplanar normal texture sampling implementation, taking into @@ -156,74 +250,26 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) // *TODO: Decide if we want this. It may be better to just calculate the // tangents on-the-fly here rather than messing with the normals, due to the // subtleties of the effects of triplanar mapping on UVs. These sampled normals -// are only valid on the faces of a cube, and the pregenerated tangents are -// only valid for uv = xy. +// are only valid on the faces of a cube. // *NOTE: Bottom face has not been tested vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); - float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - weight = max(vec3(0), sign(weight - threshold)); - - #define SAMPLE_X 1 << 2 - #define SAMPLE_Y 1 << 1 - #define SAMPLE_Z 1 << 0 - int sample_type = (int(weight.x) * SAMPLE_X) | - (int(weight.y) * SAMPLE_Y) | - (int(weight.z) * SAMPLE_Z); - #define terrain_coord_x terrain_coord[0].zw - #define terrain_coord_y terrain_coord[1].xy - #define terrain_coord_z terrain_coord[0].xy - vec3 x; - vec3 y; - vec3 z; - switch (sample_type) - { - case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - case SAMPLE_X | SAMPLE_Y: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec3(0); - break; - case SAMPLE_X | SAMPLE_Z: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec3(0); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - case SAMPLE_Y | SAMPLE_Z: - x = vec3(0); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - case SAMPLE_X: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec3(0); - z = vec3(0); - break; - case SAMPLE_Y: - x = vec3(0); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec3(0); - break; - case SAMPLE_Z: - default: - x = vec3(0); - y = vec3(0); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - } + TerrainWeight tw = _t_weight(terrain_coord); - // *HACK: Transform normals according to orientation of the UVs - x.xy = vec2(-x.y, x.x); - y.xy = -y.xy; + TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); - return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); + return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); } + +vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) +{ + TerrainWeight tw = _t_weight(terrain_coord); + + TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); + + return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +} + #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 #define TerrainCoord vec2 vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) @@ -235,6 +281,13 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { return texture(tex, terrain_coord).xyz*2.0-1.0; } + +vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) +{ + vec4 col = texture(tex, terrain_coord); + col.xyz = srgb_to_linear(col.xyz); + return col; +} #endif vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) @@ -258,14 +311,10 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, Terrain vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; - samples[0] = terrain_texture(tex0, texcoord); - samples[1] = terrain_texture(tex1, texcoord); - samples[2] = terrain_texture(tex2, texcoord); - samples[3] = terrain_texture(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); + samples[0] = terrain_texture_color(tex0, texcoord); + samples[1] = terrain_texture_color(tex1, texcoord); + samples[2] = terrain_texture_color(tex2, texcoord); + samples[3] = terrain_texture_color(tex3, texcoord); samples[0] *= factors[0]; samples[1] *= factors[1]; samples[2] *= factors[2]; -- cgit v1.2.3 From a9a08f72be2c30a40f7c6565bb82e7356245e8ec Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:13 -0700 Subject: DRTVWR-592: (WIP) Cleanup --- .../shaders/class1/deferred/pbrterrainF.glsl | 8 +-- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 77 ++++++++++------------ 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index ba917416ce..10a147a039 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -141,10 +141,10 @@ void main() //col.xyz = spec; // TODO: Remove //col.xyz = vec3(1); // TODO: Remove //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove - tnorm = vary_normal; // TODO: Remove - spec.r = 1.0; // TODO: Remove - spec.gb = vec2(1.0, 0.0); // TODO: Remove - emissive.rgb = vec3(0); // TODO: Remove + //tnorm = vary_normal; // TODO: Remove + //spec.r = 1.0; // TODO: Remove + //spec.gb = vec2(1.0, 0.0); // TODO: Remove + //emissive.rgb = vec3(0); // TODO: Remove #endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index c72bc65cca..1f8b0b97c7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -87,19 +87,9 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) return texture(tex, uv); } -vec4 _t_texture_c(sampler2D tex, vec2 uv_unflipped, float sign) -{ - vec4 c = _t_texture(tex, uv_unflipped, sign); - c.xyz = srgb_to_linear(c.xyz); - return c; -} - #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 #define SAMPLE_Z 1 << 0 -#define terrain_coord_x terrain_coord[0].zw -#define terrain_coord_y terrain_coord[1].xy -#define terrain_coord_z terrain_coord[0].xy #define TERRAIN_DEBUG 1 // TODO: Remove debug struct TerrainWeight { @@ -137,57 +127,55 @@ struct TerrainSample TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) { - vec4 x; - vec4 y; - vec4 z; + TerrainSample ts; + +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); switch (tw.type) { case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + ts.x = do_sample_x(); + ts.y = do_sample_y(); + ts.z = do_sample_z(); break; case SAMPLE_X | SAMPLE_Y: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = x; + ts.x = do_sample_x(); + ts.y = do_sample_y(); + ts.z = ts.x; break; case SAMPLE_X | SAMPLE_Z: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - y = x; + ts.x = do_sample_x(); + ts.z = do_sample_z(); + ts.y = ts.x; break; case SAMPLE_Y | SAMPLE_Z: - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - x = y; + ts.y = do_sample_y(); + ts.z = do_sample_z(); + ts.x = ts.y; break; case SAMPLE_X: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = x; - z = x; + ts.x = do_sample_x(); + ts.y = ts.x; + ts.z = ts.x; break; case SAMPLE_Y: - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - x = y; - z = y; + ts.y = do_sample_y(); + ts.x = ts.y; + ts.z = ts.y; break; case SAMPLE_Z: - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - x = z; - y = z; + ts.z = do_sample_z(); + ts.x = ts.z; + ts.y = ts.z; break; default: - x = vec4(0); - y = x; - z = x; + ts.x = vec4(0); + ts.y = ts.x; + ts.z = ts.x; break; } - TerrainSample ts; - ts.x = x; - ts.y = y; - ts.z = z; return ts; } @@ -202,9 +190,9 @@ TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, Terra { TerrainSample ts = _t_sample(tex, terrain_coord, tw); TerrainSampleNormal tsn; - tsn.x = ts.x.xyz; - tsn.y = ts.y.xyz; - tsn.z = ts.z.xyz; + tsn.x = ts.x.xyz*2.0-1.0; + tsn.y = ts.y.xyz*2.0-1.0; + tsn.z = ts.z.xyz*2.0-1.0; vec3 ns = sign(vary_vertex_normal); // If the sign is negative, rotate normal by 180 degrees tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); @@ -261,6 +249,7 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); } +// Triplanar sampling of colors. Colors are converted to linear space before blending. vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) { TerrainWeight tw = _t_weight(terrain_coord); -- cgit v1.2.3 From d745b6321306a44ae9bbd5afc6fff376ebaf12e9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:19 -0700 Subject: DRTVWR-592: (DEBUG) (broken) Strange sampling behavior survives weight bypass --- .../shaders/class1/deferred/pbrterrainF.glsl | 10 +++++----- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 10a147a039..19de8568b8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,16 +135,16 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; -#if 0 // TODO: Remove debug +#if 1 // TODO: Remove debug //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove //col.xyz = spec; // TODO: Remove //col.xyz = vec3(1); // TODO: Remove //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove - //tnorm = vary_normal; // TODO: Remove - //spec.r = 1.0; // TODO: Remove - //spec.gb = vec2(1.0, 0.0); // TODO: Remove - //emissive.rgb = vec3(0); // TODO: Remove + tnorm = vary_normal; // TODO: Remove + spec.r = 1.0; // TODO: Remove + spec.gb = vec2(1.0, 0.0); // TODO: Remove + emissive.rgb = vec3(0); // TODO: Remove #endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 1f8b0b97c7..327d23d2e7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -129,8 +129,13 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); +#if 0 +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#else // TODO: Remove debug +#define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#endif #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); switch (tw.type) { @@ -219,15 +224,15 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample(tex, terrain_coord, tw); -#if 1 +#if 0 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); #else // TODO: Remove debug //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); -#if 1 +#if 0 return vec4(tw.usage, 1.0); #else //return vec4(tw.usage, 1.0); - return vec4((tw.usage + weight) / 2.0, 1.0); + return vec4((tw.usage + tw.weight) / 2.0, 1.0); #endif #endif } @@ -256,7 +261,11 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); +#if 0 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +#else // TODO: Remove debug + return ts.x; +#endif } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -- cgit v1.2.3 From aba9185f3a27221f71aa53001b45db0337a0b904 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:24 -0700 Subject: DRTVWR-592: (DEBUG) (broken) Strange sampling behavior isolated to switch..case blocks --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 179 ++++++++++++++++++--- 1 file changed, 155 insertions(+), 24 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 327d23d2e7..5067e94efe 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -79,12 +79,29 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) #define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0 -vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) +vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { + // Handle case where sign is 0 + // TODO: Why didn't this fix the seams? +#if 0 + float sign = (2.0*sign_or_zero) + 1.0; + sign /= sign; // If the vertex normal is negative, flip the texture back // right-side up. vec2 uv = uv_unflipped * vec2(sign, 1); return texture(tex, uv); +#else // TODO: Remove debug +#if 0 + // Name mangling test + float l_sign = (2.0*sign_or_zero) + 1.0; + l_sign /= l_sign; + vec2 l_uv = uv_unflipped * vec2(l_sign, 1); + return texture(tex, l_uv); +#else + // Simplified uv test + return texture(tex, uv_unflipped); +#endif +#endif } #define SAMPLE_X 1 << 2 @@ -94,10 +111,11 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) struct TerrainWeight { vec3 weight; + int type; #if TERRAIN_DEBUG + vec3 weight_signed; vec3 usage; #endif - int type; }; TerrainWeight _t_weight(TerrainCoord terrain_coord) @@ -109,12 +127,13 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) TerrainWeight tw; tw.weight = max(vec3(0), weight_signed); vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); -#if TERRAIN_DEBUG - tw.usage = usage; -#endif tw.type = (int(usage.x) * SAMPLE_X) | (int(usage.y) * SAMPLE_Y) | (int(usage.z) * SAMPLE_Z); +#if TERRAIN_DEBUG + tw.weight_signed = weight_signed; + tw.usage = usage; +#endif return tw; } @@ -129,32 +148,44 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#if 0 +#if 1 +#if 1 +#if 1 #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) #else // TODO: Remove debug +// Still an error despite sampling the same texture three times from the same location #define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #endif -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#else // TODO: Remove? + vec2 coord_z = terrain_coord[0].xy; + vec2 coord_z_2 = terrain_coord[0].xy; + vec2 coord_z_3 = terrain_coord[0].xy; +#define do_sample_x() texture(tex, coord_z) +#define do_sample_y() texture(tex, coord_z_2) +#define do_sample_z() texture(tex, coord_z_3) +#endif +#if 0 switch (tw.type) { - case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: + case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): ts.x = do_sample_x(); ts.y = do_sample_y(); ts.z = do_sample_z(); break; - case SAMPLE_X | SAMPLE_Y: + case (SAMPLE_X | SAMPLE_Y): ts.x = do_sample_x(); ts.y = do_sample_y(); ts.z = ts.x; break; - case SAMPLE_X | SAMPLE_Z: + case (SAMPLE_X | SAMPLE_Z): ts.x = do_sample_x(); ts.z = do_sample_z(); ts.y = ts.x; break; - case SAMPLE_Y | SAMPLE_Z: + case (SAMPLE_Y | SAMPLE_Z): ts.y = do_sample_y(); ts.z = do_sample_z(); ts.x = ts.y; @@ -175,11 +206,114 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.y = ts.z; break; default: - ts.x = vec4(0); + ts.x = vec4(1.0, 0.0, 1.0, 1.0); + ts.y = ts.x; + ts.z = ts.x; + break; + } +#else // TODO: Remove debug +#if 0 + // This case works - no ant trails despite using a switch...case statement + switch (tw.type) + { + case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + break; + case (SAMPLE_X | SAMPLE_Y): + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.z = ts.x; + break; + case (SAMPLE_X | SAMPLE_Z): + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + ts.y = ts.x; + break; + case (SAMPLE_Y | SAMPLE_Z): + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + ts.x = ts.y; + break; + case SAMPLE_X: + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.y = ts.x; + ts.z = ts.x; + break; + case SAMPLE_Y: + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.x = ts.y; + ts.z = ts.y; + break; + case SAMPLE_Z: + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + ts.x = ts.z; + ts.y = ts.z; + break; + default: + ts.x = vec4(1.0, 0.0, 1.0, 1.0); + ts.y = ts.x; + ts.z = ts.x; + break; + } +#else +// This shows the bug: case of sampling beforehand, assigning in switch..case + vec4 x = do_sample_x(); + vec4 y = do_sample_y(); + vec4 z = do_sample_z(); + switch (tw.type) + { + case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): + ts.x = x; + ts.y = y; + ts.z = z; + break; + case (SAMPLE_X | SAMPLE_Y): + ts.x = x; + ts.y = y; + ts.z = ts.x; + break; + case (SAMPLE_X | SAMPLE_Z): + ts.x = x; + ts.z = z; + ts.y = ts.x; + break; + case (SAMPLE_Y | SAMPLE_Z): + ts.y = y; + ts.z = z; + ts.x = ts.y; + break; + case SAMPLE_X: + ts.x = x; + ts.y = ts.x; + ts.z = ts.x; + break; + case SAMPLE_Y: + ts.y = y; + ts.x = ts.y; + ts.z = ts.y; + break; + case SAMPLE_Z: + ts.z = z; + ts.x = ts.z; + ts.y = ts.z; + break; + default: + ts.x = vec4(1.0, 0.0, 1.0, 1.0); ts.y = ts.x; ts.z = ts.x; break; } +#endif +#endif +#else // TODO: Remove debug +// No error +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); +ts.z = do_sample_z(); +ts.x = ts.z; +ts.y = ts.z; +#endif return ts; } @@ -218,23 +352,14 @@ TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeig return ts; } +// Triplanar sampling of things that are neither colors nor normals (i.e. orm) vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { TerrainWeight tw = _t_weight(terrain_coord); TerrainSample ts = _t_sample(tex, terrain_coord, tw); -#if 0 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -#else // TODO: Remove debug - //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); -#if 0 - return vec4(tw.usage, 1.0); -#else - //return vec4(tw.usage, 1.0); - return vec4((tw.usage + tw.weight) / 2.0, 1.0); -#endif -#endif } // Specialized triplanar normal texture sampling implementation, taking into @@ -261,10 +386,16 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); -#if 0 +#if 1 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); #else // TODO: Remove debug - return ts.x; + //return vec4(vec3(isnan(ts.x)), 1.0); + //return ts.x; +#if 0 + return vec4(1.0+sign(vary_vertex_normal)/2.0, 1.0); +#else + return vec4(isnan(tw.weight_signed), 1.0); +#endif #endif } -- cgit v1.2.3 From fb12fb4bf7bbbf457b4f81356b0d0fadf2b42664 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:29 -0700 Subject: DRTVWR-592: (DEBUG) (broken) Clean up a few debug cases not used for reproducing the bug --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 100 +++------------------ 1 file changed, 12 insertions(+), 88 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 5067e94efe..a40f70a9e2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,39 +69,22 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -#if 0 // TODO: Revert +// TODO: Decide if we want this threshold +#if 0 #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 -#else +#else // TODO: Remove debug #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 #endif -// Positive value prevents artifacts when weights are close to zero -// TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) -#define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0 - vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 - // TODO: Why didn't this fix the seams? -#if 0 float sign = (2.0*sign_or_zero) + 1.0; sign /= sign; // If the vertex normal is negative, flip the texture back // right-side up. vec2 uv = uv_unflipped * vec2(sign, 1); return texture(tex, uv); -#else // TODO: Remove debug -#if 0 - // Name mangling test - float l_sign = (2.0*sign_or_zero) + 1.0; - l_sign /= l_sign; - vec2 l_uv = uv_unflipped * vec2(l_sign, 1); - return texture(tex, l_uv); -#else - // Simplified uv test - return texture(tex, uv_unflipped); -#endif -#endif } #define SAMPLE_X 1 << 2 @@ -126,7 +109,7 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) weight_signed -= vec3(threshold); TerrainWeight tw; tw.weight = max(vec3(0), weight_signed); - vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); + vec3 usage = max(vec3(0), sign(weight_signed)); tw.type = (int(usage.x) * SAMPLE_X) | (int(usage.y) * SAMPLE_Y) | (int(usage.z) * SAMPLE_Z); @@ -149,25 +132,16 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight TerrainSample ts; #if 1 -#if 1 -#if 1 +// This demonstrates the case when the bug occurs: Sampling in switch..case +#if 0 #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) #else // TODO: Remove debug -// Still an error despite sampling the same texture three times from the same location +// Bug still occurs despite sampling the same texture three times from the same location #define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #endif #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#else // TODO: Remove? - vec2 coord_z = terrain_coord[0].xy; - vec2 coord_z_2 = terrain_coord[0].xy; - vec2 coord_z_3 = terrain_coord[0].xy; -#define do_sample_x() texture(tex, coord_z) -#define do_sample_y() texture(tex, coord_z_2) -#define do_sample_z() texture(tex, coord_z_3) -#endif -#if 0 switch (tw.type) { case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): @@ -212,53 +186,11 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight break; } #else // TODO: Remove debug -#if 0 - // This case works - no ant trails despite using a switch...case statement - switch (tw.type) - { - case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - break; - case (SAMPLE_X | SAMPLE_Y): - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.z = ts.x; - break; - case (SAMPLE_X | SAMPLE_Z): - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - break; - case (SAMPLE_Y | SAMPLE_Z): - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - ts.x = ts.y; - break; - case SAMPLE_X: - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; - case SAMPLE_Y: - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.x = ts.y; - ts.z = ts.y; - break; - case SAMPLE_Z: - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - ts.x = ts.z; - ts.y = ts.z; - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; - } -#else -// This shows the bug: case of sampling beforehand, assigning in switch..case +// This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case +// This otherwise uses the same logic as in the case that reproduces the bug. +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) vec4 x = do_sample_x(); vec4 y = do_sample_y(); vec4 z = do_sample_z(); @@ -305,14 +237,6 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.z = ts.x; break; } -#endif -#endif -#else // TODO: Remove debug -// No error -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); -ts.z = do_sample_z(); -ts.x = ts.z; -ts.y = ts.z; #endif return ts; -- cgit v1.2.3 From be39e92f7d3c6df80eeb1f183723978ce1bf1b52 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:41:19 -0700 Subject: DRTVWR-592: (WIP) (has debug) Fix "ant trail" seams in terrain caused by multiple texture lookups in a switch..case block --- .../shaders/class1/deferred/pbrterrainF.glsl | 2 +- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 44 +++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 19de8568b8..ba917416ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,7 +135,7 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; -#if 1 // TODO: Remove debug +#if 0 // TODO: Remove debug //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove //col.xyz = spec; // TODO: Remove diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a40f70a9e2..fc04afe513 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -131,7 +131,7 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#if 1 +#if 0 // This demonstrates the case when the bug occurs: Sampling in switch..case #if 0 #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) @@ -142,7 +142,12 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight #define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #endif #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#if 0 switch (tw.type) +#else // TODO: Remove debug +// Bug still occurs when the type is masked + switch (tw.type & (SAMPLE_X | SAMPLE_Y | SAMPLE_Z)) +#endif { case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): ts.x = do_sample_x(); @@ -186,6 +191,7 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight break; } #else // TODO: Remove debug +#if 0 // This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case // This otherwise uses the same logic as in the case that reproduces the bug. #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) @@ -237,6 +243,42 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.z = ts.x; break; } +#else // TODO: Keep? +// Test case where the switch..case is broken up into three parts +// This fixes unexplained, "ant trail" seams in terrain. (as seen on Nvidia/Windows 10) +// The extra two branches are not free, but it's still a performance win +// compared to sampling along all three axes for every terrain fragment. +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +switch (tw.type & SAMPLE_X) +{ + case SAMPLE_X: + ts.x = do_sample_x(); + break; + default: + ts.x = vec4(1.0, 0.0, 1.0, 1.0); + break; +} +switch (tw.type & SAMPLE_Y) +{ + case SAMPLE_Y: + ts.y = do_sample_y(); + break; + default: + ts.y = vec4(1.0, 0.0, 1.0, 1.0); + break; +} +switch (tw.type & SAMPLE_Z) +{ + case SAMPLE_Z: + ts.z = do_sample_z(); + break; + default: + ts.z = vec4(1.0, 0.0, 1.0, 1.0); + break; +} +#endif #endif return ts; -- cgit v1.2.3 From 823fcddcb508fac6d1f819633f6a91230f06b114 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:02 -0700 Subject: DRTVWR-592: (WIP) (has debug) Fix removing axial sign flip of normal texture during zero check, add another zero check --- .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index fc04afe513..c5de74604f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -80,7 +80,7 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 float sign = (2.0*sign_or_zero) + 1.0; - sign /= sign; + sign /= abs(sign); // If the vertex normal is negative, flip the texture back // right-side up. vec2 uv = uv_unflipped * vec2(sign, 1); @@ -190,8 +190,8 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.z = ts.x; break; } -#else // TODO: Remove debug -#if 0 +#else +#if 0 // TODO: Remove debug // This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case // This otherwise uses the same logic as in the case that reproduces the bug. #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) @@ -295,10 +295,15 @@ TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, Terra { TerrainSample ts = _t_sample(tex, terrain_coord, tw); TerrainSampleNormal tsn; + // Unpack normals tsn.x = ts.x.xyz*2.0-1.0; tsn.y = ts.y.xyz*2.0-1.0; tsn.z = ts.z.xyz*2.0-1.0; + // Get sign vec3 ns = sign(vary_vertex_normal); + // Handle case where sign is 0 + ns = (2.0*ns) + 1.0; + ns /= abs(ns); // If the sign is negative, rotate normal by 180 degrees tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); -- cgit v1.2.3 From c48837ef9b7cd016577b2f54f3f6b52764c32e17 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:07 -0700 Subject: DRTVWR-592: (WIP) (has debug) More rigorous definition of usage vector for triplanar that avoids possible case where 1 = 0.9999, which gets rounded down to 0 on int cast --- .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index c5de74604f..1ea1ced45b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -97,7 +97,7 @@ struct TerrainWeight int type; #if TERRAIN_DEBUG vec3 weight_signed; - vec3 usage; + ivec3 usage; #endif }; @@ -109,10 +109,10 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) weight_signed -= vec3(threshold); TerrainWeight tw; tw.weight = max(vec3(0), weight_signed); - vec3 usage = max(vec3(0), sign(weight_signed)); - tw.type = (int(usage.x) * SAMPLE_X) | - (int(usage.y) * SAMPLE_Y) | - (int(usage.z) * SAMPLE_Z); + ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); + tw.type = ((usage.x) * SAMPLE_X) | + ((usage.y) * SAMPLE_Y) | + ((usage.z) * SAMPLE_Z); #if TERRAIN_DEBUG tw.weight_signed = weight_signed; tw.usage = usage; -- cgit v1.2.3 From fa11e94c3cf4fad439dc10db630c747c8da42dd8 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:12 -0700 Subject: DRTVWR-592: Clean up debug and test cases for ant trails artifact. Fix whitespace --- .../shaders/class1/deferred/pbrterrainF.glsl | 11 -- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 182 +++------------------ 2 files changed, 24 insertions(+), 169 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index ba917416ce..7febbe280e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,17 +135,6 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; -#if 0 // TODO: Remove debug - //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove - //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove - //col.xyz = spec; // TODO: Remove - //col.xyz = vec3(1); // TODO: Remove - //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove - tnorm = vary_normal; // TODO: Remove - spec.r = 1.0; // TODO: Remove - spec.gb = vec2(1.0, 0.0); // TODO: Remove - emissive.rgb = vec3(0); // TODO: Remove -#endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 1ea1ced45b..e2d6cdb2d6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,12 +69,7 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -// TODO: Decide if we want this threshold -#if 0 #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 -#else // TODO: Remove debug -#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 -#endif vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { @@ -90,15 +85,10 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 #define SAMPLE_Z 1 << 0 -#define TERRAIN_DEBUG 1 // TODO: Remove debug struct TerrainWeight { vec3 weight; int type; -#if TERRAIN_DEBUG - vec3 weight_signed; - ivec3 usage; -#endif }; TerrainWeight _t_weight(TerrainCoord terrain_coord) @@ -131,155 +121,41 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#if 0 -// This demonstrates the case when the bug occurs: Sampling in switch..case -#if 0 -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) -#else // TODO: Remove debug -// Bug still occurs despite sampling the same texture three times from the same location -#define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#endif -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#if 0 - switch (tw.type) -#else // TODO: Remove debug -// Bug still occurs when the type is masked - switch (tw.type & (SAMPLE_X | SAMPLE_Y | SAMPLE_Z)) -#endif + // The switch..case is broken up into three parts deliberately. A single + // switch..case caused unexplained, "ant trail" seams in terrain. (as seen + // on Nvidia/Windows 10). The extra two branches are not free, but it's + // still a performance win compared to sampling along all three axes for + // every terrain fragment. + #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) + #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) + #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) + switch (tw.type & SAMPLE_X) { - case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): - ts.x = do_sample_x(); - ts.y = do_sample_y(); - ts.z = do_sample_z(); - break; - case (SAMPLE_X | SAMPLE_Y): - ts.x = do_sample_x(); - ts.y = do_sample_y(); - ts.z = ts.x; - break; - case (SAMPLE_X | SAMPLE_Z): - ts.x = do_sample_x(); - ts.z = do_sample_z(); - ts.y = ts.x; - break; - case (SAMPLE_Y | SAMPLE_Z): - ts.y = do_sample_y(); - ts.z = do_sample_z(); - ts.x = ts.y; - break; case SAMPLE_X: ts.x = do_sample_x(); - ts.y = ts.x; - ts.z = ts.x; - break; - case SAMPLE_Y: - ts.y = do_sample_y(); - ts.x = ts.y; - ts.z = ts.y; - break; - case SAMPLE_Z: - ts.z = do_sample_z(); - ts.x = ts.z; - ts.y = ts.z; - break; + break; default: ts.x = vec4(1.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; + break; } -#else -#if 0 // TODO: Remove debug -// This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case -// This otherwise uses the same logic as in the case that reproduces the bug. -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) - vec4 x = do_sample_x(); - vec4 y = do_sample_y(); - vec4 z = do_sample_z(); - switch (tw.type) + switch (tw.type & SAMPLE_Y) { - case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): - ts.x = x; - ts.y = y; - ts.z = z; - break; - case (SAMPLE_X | SAMPLE_Y): - ts.x = x; - ts.y = y; - ts.z = ts.x; - break; - case (SAMPLE_X | SAMPLE_Z): - ts.x = x; - ts.z = z; - ts.y = ts.x; - break; - case (SAMPLE_Y | SAMPLE_Z): - ts.y = y; - ts.z = z; - ts.x = ts.y; - break; - case SAMPLE_X: - ts.x = x; - ts.y = ts.x; - ts.z = ts.x; - break; case SAMPLE_Y: - ts.y = y; - ts.x = ts.y; - ts.z = ts.y; - break; + ts.y = do_sample_y(); + break; + default: + ts.y = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tw.type & SAMPLE_Z) + { case SAMPLE_Z: - ts.z = z; - ts.x = ts.z; - ts.y = ts.z; - break; + ts.z = do_sample_z(); + break; default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; + ts.z = vec4(1.0, 0.0, 1.0, 1.0); + break; } -#else // TODO: Keep? -// Test case where the switch..case is broken up into three parts -// This fixes unexplained, "ant trail" seams in terrain. (as seen on Nvidia/Windows 10) -// The extra two branches are not free, but it's still a performance win -// compared to sampling along all three axes for every terrain fragment. -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -switch (tw.type & SAMPLE_X) -{ - case SAMPLE_X: - ts.x = do_sample_x(); - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - break; -} -switch (tw.type & SAMPLE_Y) -{ - case SAMPLE_Y: - ts.y = do_sample_y(); - break; - default: - ts.y = vec4(1.0, 0.0, 1.0, 1.0); - break; -} -switch (tw.type & SAMPLE_Z) -{ - case SAMPLE_Z: - ts.z = do_sample_z(); - break; - default: - ts.z = vec4(1.0, 0.0, 1.0, 1.0); - break; -} -#endif -#endif return ts; } @@ -357,17 +233,7 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); -#if 1 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -#else // TODO: Remove debug - //return vec4(vec3(isnan(ts.x)), 1.0); - //return ts.x; -#if 0 - return vec4(1.0+sign(vary_vertex_normal)/2.0, 1.0); -#else - return vec4(isnan(tw.weight_signed), 1.0); -#endif -#endif } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -- cgit v1.2.3 From b1a3a274ffe539ea61d9fd7aa6f95f44049964e2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:18 -0700 Subject: DRTVWR-592: Don't read UVs for PBR terrain in single-plane case - works out to be more expensive than triplanar in some cases, and UVs are already trivial --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 2df5faf037..64ab3bbb13 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -84,7 +84,7 @@ void main() // (-x)z vary_coords[1].xy = texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform, texture_matrix0); #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 - vary_texcoord0.xy = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + vary_texcoord0.xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0); #endif vec4 tc = vec4(texcoord1,0,1); -- cgit v1.2.3 From 6e949e5d63c56a899b6a7745fcca04e0cd2f9639 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:24 -0700 Subject: DRTVWR-592: Remove shader cruft --- .../app_settings/shaders/class1/deferred/pbrterrainV.glsl | 1 - indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 64ab3bbb13..dbb9404219 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -31,7 +31,6 @@ in vec3 position; in vec3 normal; in vec4 tangent; in vec4 diffuse_color; -in vec2 texcoord0; in vec2 texcoord1; #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index f6d3b59e85..33a78fd26d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -30,7 +30,6 @@ uniform mat4 modelview_projection_matrix; in vec3 position; in vec3 normal; in vec4 diffuse_color; -in vec2 texcoord0; in vec2 texcoord1; out vec3 pos; @@ -41,18 +40,16 @@ out vec4 vary_texcoord1; uniform vec4 object_plane_s; uniform vec4 object_plane_t; -vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +vec2 texgen_object(vec4 vpos, mat4 mat, vec4 tp0, vec4 tp1) { vec4 tcoord; tcoord.x = dot(vpos, tp0); tcoord.y = dot(vpos, tp1); - tcoord.z = tc.z; - tcoord.w = tc.w; tcoord = mat * tcoord; - return tcoord; + return tcoord.xy; } void main() @@ -67,7 +64,7 @@ void main() vary_normal = normalize(normal_matrix * normal); // Transform and pass tex coords - vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_texcoord0.xy = texgen_object(vec4(position, 1.0), texture_matrix0, object_plane_s, object_plane_t); vec4 t = vec4(texcoord1,0,1); -- cgit v1.2.3 From 1d885181d850388feb89c92a018cb591b5cc7f18 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:29 -0700 Subject: DRTVWR-592: (WIP) (has debug) Apply triplanar optimization technique to PBR material sampling. Use slightly different alpha ramp to hide unused materials --- .../shaders/class1/deferred/pbrterrainF.glsl | 61 ++++- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 288 +++++++++++++++++---- 2 files changed, 301 insertions(+), 48 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7febbe280e..7b5eba14b7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -82,6 +82,19 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +#if 1 // TODO: Remove +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainMix +{ + vec4 weight; + int type; +#if TERRAIN_DEBUG + ivec4 usage; +#endif +}; +TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal); +#endif + void main() { @@ -125,16 +138,60 @@ void main() // from mikktspace.com vec3 vNt = sample_and_mix_normal(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; - vec3 vB = sign * cross(vN, vT); + vec3 vB = vary_sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if 0 // TODO: Remove (terrain weights visualization) + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); +#if 1 + // Show full usage and weights + float uw = 0.3; +#if 1 +#if 0 + vec4 mix_usage = vec4(tm.usage); +#else + vec4 mix_usage = vec4(tm.weight); +#endif +#else + // Version with easier-to-see boundaries of weights vs usage + vec4 mix_usage = mix(vec4(tm.usage), + mix(max(vec4(0.0), sign(tm.weight - 0.01)), + max(vec4(0.0), sign(tm.weight - 0.005)), + 0.5), + uw); +#endif + col.xyz = mix_usage.xyz; + col.x = max(col.x, mix_usage.w); + //col.y = 0.0; + //col.z = 0.0; +#else + // Show places where weight > usage + tolerance + float tolerance = 0.005; + vec4 weight_gt_usage = sign( + max( + vec4(0.0), + (tm.weight - (vec4(tm.usage) + vec4(tolerance))) + ) + ); + col.xyz = weight_gt_usage.xyz; + col.x = max(col.x, weight_gt_usage.w); +#endif +#endif +#if 0 // TODO: Remove (material channel discriminator) + //col.rgb = vec3(0.0, 1.0, 0.0); + //col.rgb = spec.rgb; + //col.rgb = (vNt + 1.0) / 2.0; + col.rgb = (tnorm + 1.0) / 2.0; + spec.rgb = vec3(1.0, 1.0, 0.0); + tnorm = vary_normal; + emissive = vec3(0); +#endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index e2d6cdb2d6..59b273afc3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -49,11 +49,62 @@ in vec3 vary_vertex_normal; vec3 srgb_to_linear(vec3 c); +// A relatively agressive threshold ensures that only one or two materials are used in most places +#define TERRAIN_RAMP_MIX_THRESHOLD 0.1 + +#define MIX_X 1 << 3 +#define MIX_Y 1 << 2 +#define MIX_Z 1 << 1 +#define MIX_W 1 << 0 + +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainMix +{ + vec4 weight; + int type; +#if TERRAIN_DEBUG + ivec4 usage; +#endif +}; + +#define TerrainMixSample vec4[4] +#define TerrainMixSample3 vec3[4] + +TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) +{ + TerrainMix tm; + vec4 sample_x = vec4(1,0,0,0); + vec4 sample_y = vec4(0,1,0,0); + vec4 sample_z = vec4(0,0,1,0); + vec4 sample_w = vec4(0,0,0,1); + + tm.weight = mix( mix(sample_w, sample_z, alpha2), mix(sample_y, sample_x, alpha1), alphaFinal ); + tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD; + ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight))); + // Prevent negative weights and keep weights balanced + tm.weight = normalize(tm.weight*vec4(usage)); + + tm.type = (usage.x * MIX_X) | + (usage.y * MIX_Y) | + (usage.z * MIX_Z) | + (usage.w * MIX_W); +#if TERRAIN_DEBUG // TODO: Remove debug + tm.usage = usage; +#endif + return tm; +} + 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 ); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + // Assume weights are normalized + return tm.weight.x * samples.x + + tm.weight.y * samples.y + + tm.weight.z * samples.z + + tm.weight.w * samples.w; } +#if 0 // TODO: Decide if still needed, and if so, use _t_mix internally for weights vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) { return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); @@ -63,6 +114,25 @@ 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 ); } +#endif + +vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) +{ + // Assume weights are normalized + return tm.weight.x * tms[0] + + tm.weight.y * tms[1] + + tm.weight.z * tms[2] + + tm.weight.w * tms[3]; +} + +vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) +{ + // Assume weights are normalized + return tm.weight.x * tms3[0] + + tm.weight.y * tms3[1] + + tm.weight.z * tms3[2] + + tm.weight.w * tms3[3]; +} #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 // Triplanar mapping @@ -98,15 +168,12 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); weight_signed -= vec3(threshold); TerrainWeight tw; - tw.weight = max(vec3(0), weight_signed); + // *NOTE: Make sure the threshold doesn't affect the materials + tw.weight = normalize(max(vec3(0), weight_signed)); ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); tw.type = ((usage.x) * SAMPLE_X) | ((usage.y) * SAMPLE_Y) | ((usage.z) * SAMPLE_Z); -#if TERRAIN_DEBUG - tw.weight_signed = weight_signed; - tw.usage = usage; -#endif return tw; } @@ -256,59 +323,188 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) } #endif +// The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. +// *TODO: Currently, there is much more switch..case branching than needed. This could be simplified by branching per-material rather than per-texture. + +TerrainMixSample _tmix_sample(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + TerrainMixSample tms; + + switch (tm.type & MIX_X) + { + case MIX_X: + tms[0] = terrain_texture(tex0, texcoord); + break; + default: + tms[0] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + tms[1] = terrain_texture(tex1, texcoord); + break; + default: + tms[1] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + tms[2] = terrain_texture(tex2, texcoord); + break; + default: + tms[2] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + tms[3] = terrain_texture(tex3, texcoord); + break; + default: + tms[3] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + + return tms; +} + +TerrainMixSample _tmix_sample_color(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + TerrainMixSample tmix; + + switch (tm.type & MIX_X) + { + case MIX_X: + tmix[0] = terrain_texture_color(tex0, texcoord); + break; + default: + tmix[0] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + tmix[1] = terrain_texture_color(tex1, texcoord); + break; + default: + tmix[1] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + tmix[2] = terrain_texture_color(tex2, texcoord); + break; + default: + tmix[2] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + tmix[3] = terrain_texture_color(tex3, texcoord); + break; + default: + tmix[3] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + + return tmix; +} + +TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + TerrainMixSample3 tmix3; + + switch (tm.type & MIX_X) + { + case MIX_X: + tmix3[0] = terrain_texture_normal(tex0, texcoord); + break; + default: + tmix3[0] = vec3(1.0, 0.0, 1.0); + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + tmix3[1] = terrain_texture_normal(tex1, texcoord); + break; + default: + tmix3[1] = vec3(1.0, 0.0, 1.0); + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + tmix3[2] = terrain_texture_normal(tex2, texcoord); + break; + default: + tmix3[2] = vec3(1.0, 0.0, 1.0); + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + tmix3[3] = terrain_texture_normal(tex3, texcoord); + break; + default: + tmix3[3] = vec3(1.0, 0.0, 1.0); + break; + } + + return tmix3; +} + vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec3[4] samples; - samples[0] = terrain_texture(tex0, texcoord).xyz; - samples[1] = terrain_texture(tex1, texcoord).xyz; - samples[2] = terrain_texture(tex2, texcoord).xyz; - samples[3] = terrain_texture(tex3, texcoord).xyz; - samples[0] = srgb_to_linear(samples[0]); - samples[1] = srgb_to_linear(samples[1]); - samples[2] = srgb_to_linear(samples[2]); - samples[3] = srgb_to_linear(samples[3]); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); + vec3[4] tms3; + tms3[0] = tms[0].xyz; + tms3[1] = tms[1].xyz; + tms3[2] = tms[2].xyz; + tms3[3] = tms[3].xyz; + tms3[0] *= factors[0]; + tms3[1] *= factors[1]; + tms3[2] *= factors[2]; + tms3[3] *= factors[3]; + return terrain_mix(tm, tms3); } vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec4[4] samples; - samples[0] = terrain_texture_color(tex0, texcoord); - samples[1] = terrain_texture_color(tex1, texcoord); - samples[2] = terrain_texture_color(tex2, texcoord); - samples[3] = terrain_texture_color(tex3, texcoord); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); + tms[0] *= factors[0]; + tms[1] *= factors[1]; + tms[2] *= factors[2]; + tms[3] *= factors[3]; + return terrain_mix(tm, tms); } vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec3[4] samples; - samples[0] = terrain_texture(tex0, texcoord).xyz; - samples[1] = terrain_texture(tex1, texcoord).xyz; - samples[2] = terrain_texture(tex2, texcoord).xyz; - samples[3] = terrain_texture(tex3, texcoord).xyz; - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); + vec3[4] tms3; + tms3[0] = tms[0].xyz; + tms3[1] = tms[1].xyz; + tms3[2] = tms[2].xyz; + tms3[3] = tms[3].xyz; + tms3[0] *= factors[0]; + tms3[1] *= factors[1]; + tms3[2] *= factors[2]; + tms3[3] *= factors[3]; + return terrain_mix(tm, tms3); } // Returns the unpacked normal texture in range [-1, 1] vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec3[4] samples; - samples[0] = terrain_texture_normal(tex0, texcoord).xyz; - samples[1] = terrain_texture_normal(tex1, texcoord).xyz; - samples[2] = terrain_texture_normal(tex2, texcoord).xyz; - samples[3] = terrain_texture_normal(tex3, texcoord).xyz; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); + return terrain_mix(tm, tms3); } -- cgit v1.2.3 From 86f0c9faa83ce4917ce7820a3295b39369d994ee Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:35 -0700 Subject: DRTVWR-592: (WIP) (has debug) Fix PBR terrain material mixing and triplanar mapping using wrong mix, causing bright spots --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 59b273afc3..13f3934689 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -82,7 +82,8 @@ TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD; ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight))); // Prevent negative weights and keep weights balanced - tm.weight = normalize(tm.weight*vec4(usage)); + tm.weight = tm.weight*vec4(usage); + tm.weight /= (tm.weight.x + tm.weight.y + tm.weight.z + tm.weight.w); tm.type = (usage.x * MIX_X) | (usage.y * MIX_Y) | @@ -97,7 +98,7 @@ TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); - // Assume weights are normalized + // Assume weights add to 1 return tm.weight.x * samples.x + tm.weight.y * samples.y + tm.weight.z * samples.z + @@ -118,7 +119,7 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) { - // Assume weights are normalized + // Assume weights add to 1 return tm.weight.x * tms[0] + tm.weight.y * tms[1] + tm.weight.z * tms[2] + @@ -127,7 +128,7 @@ vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) { - // Assume weights are normalized + // Assume weights add to 1 return tm.weight.x * tms3[0] + tm.weight.y * tms3[1] + tm.weight.z * tms3[2] + @@ -165,11 +166,13 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); + weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); weight_signed -= vec3(threshold); TerrainWeight tw; // *NOTE: Make sure the threshold doesn't affect the materials - tw.weight = normalize(max(vec3(0), weight_signed)); + tw.weight = max(vec3(0), weight_signed); + tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); tw.type = ((usage.x) * SAMPLE_X) | ((usage.y) * SAMPLE_Y) | -- cgit v1.2.3 From 00d56e2607a671b9478bf06b7df808b2f4141395 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:39 -0700 Subject: DRTVWR-592: Disable (but do not remove) shader debug --- .../shaders/class1/deferred/pbrterrainF.glsl | 9 ++++++--- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 16 +++------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7b5eba14b7..f788b46aa7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -82,7 +82,7 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -#if 1 // TODO: Remove +#if 0 // TODO: Remove #define TERRAIN_DEBUG 1 // TODO: Remove debug struct TerrainMix { @@ -147,6 +147,7 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if TERRAIN_DEBUG // TODO: Remove #if 0 // TODO: Remove (terrain weights visualization) TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); #if 1 @@ -187,10 +188,12 @@ void main() //col.rgb = vec3(0.0, 1.0, 0.0); //col.rgb = spec.rgb; //col.rgb = (vNt + 1.0) / 2.0; - col.rgb = (tnorm + 1.0) / 2.0; - spec.rgb = vec3(1.0, 1.0, 0.0); + //col.rgb = (tnorm + 1.0) / 2.0; + //spec.rgb = vec3(1.0, 1.0, 0.0); + col.rgb = spec.rgb; tnorm = vary_normal; emissive = vec3(0); +#endif #endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 13f3934689..9d1990bd4a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -57,7 +57,9 @@ vec3 srgb_to_linear(vec3 c); #define MIX_Z 1 << 1 #define MIX_W 1 << 0 -#define TERRAIN_DEBUG 1 // TODO: Remove debug +#if 0 // TODO: Remove debug +#define TERRAIN_DEBUG 1 +#endif struct TerrainMix { vec4 weight; @@ -105,18 +107,6 @@ float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) tm.weight.w * samples.w; } -#if 0 // TODO: Decide if still needed, and if so, use _t_mix internally for weights -vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); -} - -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 ); -} -#endif - vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) { // Assume weights add to 1 -- cgit v1.2.3 From b163f72ecc2ebdb553b312e5e399d103f00eaf34 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:44 -0700 Subject: DRTVWR-592: (WIP) (has debug) Add new functions for mixing PBR materials. Not yet used. --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 286 ++++++++++++++++++--- 1 file changed, 252 insertions(+), 34 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 9d1990bd4a..a8d8b1a91d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -44,18 +44,99 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 in vec3 vary_vertex_normal; vec3 srgb_to_linear(vec3 c); -// A relatively agressive threshold ensures that only one or two materials are used in most places +// A relatively agressive threshold for terrain material mixing sampling +// cutoff. This ensures that only one or two materials are used in most places, +// making PBR terrain blending more performant. Should be greater than 0 to work. #define TERRAIN_RAMP_MIX_THRESHOLD 0.1 +// A small threshold for triplanar mapping sampling cutoff. This and +// TERRAIN_TRIPLANAR_BLEND_FACTOR together ensures that only one or two samples +// per texture are used in most places, making triplanar mapping more +// performant. Should be greater than 0 to work. +// There's also an artistic design choice in the use of these factors, and the +// use of triplanar generally. Don't take these triplanar constants for granted. +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 + +#define SAMPLE_X 1 << 0 +#define SAMPLE_Y 1 << 1 +#define SAMPLE_Z 1 << 2 +#define MIX_X 1 << 3 +#define MIX_Y 1 << 4 +#define MIX_Z 1 << 5 +#define MIX_W 1 << 6 + +struct PBRMix +{ + vec4 col; // RGB color with alpha, linear space + vec3 orm; // Occlusion, roughness, metallic + vec3 vNt; // Unpacked normal texture sample, vector +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + vec3 emissive; // RGB emissive color, linear space +#endif +}; -#define MIX_X 1 << 3 -#define MIX_Y 1 << 2 -#define MIX_Z 1 << 1 -#define MIX_W 1 << 0 +PBRMix init_pbr_mix() +{ + PBRMix mix; + mix.col = vec4(0); + mix.orm = vec3(0); + mix.vNt = vec3(0); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive = vec3(0); +#endif + return mix; +} + +// Usage example, for two weights: +// vec2 weights = ... // Weights must add up to 1 +// PBRMix mix = init_pbr_mix(); +// PBRMix mix1 = ... +// mix = mix_pbr(mix, mix1, weights.x); +// PBRMix mix2 = ... +// mix = mix_pbr(mix, mix2, weights.y); +PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight) +{ + PBRMix mix; + mix.col = mix1.col + (mix2.col * mix2_weight); + mix.orm = mix1.orm + (mix2.orm * mix2_weight); + mix.vNt = mix1.vNt + (mix2.vNt * mix2_weight); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight); +#endif + return mix; +} + +PBRMix sample_pbr( + vec2 uv + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + ) +{ + PBRMix mix; + mix.col = texture(tex_col, uv); + mix.col.rgb = srgb_to_linear(mix.col.rgb); + mix.orm = texture(tex_orm, uv).xyz; + mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz); +#endif + return mix; +} + +struct TerrainTriplanar +{ + vec3 weight; + int type; +}; #if 0 // TODO: Remove debug #define TERRAIN_DEBUG 1 @@ -97,6 +178,24 @@ TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) return tm; } +TerrainTriplanar _t_triplanar() +{ + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; + float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; + vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); + weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); + weight_signed -= vec3(threshold); + TerrainTriplanar tw; + // *NOTE: Make sure the threshold doesn't affect the materials + tw.weight = max(vec3(0), weight_signed); + tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); + ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); + tw.type = ((usage.x) * SAMPLE_X) | + ((usage.y) * SAMPLE_Y) | + ((usage.z) * SAMPLE_Z); + return tw; +} + float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); @@ -130,7 +229,6 @@ vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { @@ -143,31 +241,50 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) return texture(tex, uv); } -#define SAMPLE_X 1 << 2 -#define SAMPLE_Y 1 << 1 -#define SAMPLE_Z 1 << 0 -struct TerrainWeight +vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero) { - vec3 weight; - int type; -}; + // Handle case where sign is 0 + float sign = (2.0*sign_or_zero) + 1.0; + sign /= abs(sign); + // If the vertex normal is negative, flip the texture back + // right-side up. + vec2 uv = uv_unflipped * vec2(sign, 1); + return uv; +} -TerrainWeight _t_weight(TerrainCoord terrain_coord) +vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero) { - float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); - weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); - weight_signed -= vec3(threshold); - TerrainWeight tw; - // *NOTE: Make sure the threshold doesn't affect the materials - tw.weight = max(vec3(0), weight_signed); - tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); - ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); - tw.type = ((usage.x) * SAMPLE_X) | - ((usage.y) * SAMPLE_Y) | - ((usage.z) * SAMPLE_Z); - return tw; + // Assume normal is unpacked + vec3 vNt1 = vNt0; + // Get sign + float sign = sign_or_zero; + // Handle case where sign is 0 + sign = (2.0*sign) + 1.0; + sign /= abs(sign); + // If the sign is negative, rotate normal by 180 degrees + vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy); + return vNt1; +} + +// Triplanar-specific normal texture fixes +vec3 _t_normal_post_x(vec3 vNt0) +{ + vec3 vNt_x = _t_normal_post_1(vNt0, sign(vary_vertex_normal.x)); + // *HACK: Transform normals according to orientation of the UVs + vNt_x.xy = vec2(-vNt_x.y, vNt_x.x); + return vNt_x; +} +vec3 _t_normal_post_y(vec3 vNt0) +{ + vec3 vNt_y = _t_normal_post_1(vNt0, sign(vary_vertex_normal.y)); + // *HACK: Transform normals according to orientation of the UVs + vNt_y.xy = -vNt_y.xy; + return vNt_y; +} +vec3 _t_normal_post_z(vec3 vNt0) +{ + vec3 vNt_z = _t_normal_post_1(vNt0, sign(vary_vertex_normal.z)); + return vNt_z; } struct TerrainSample @@ -177,7 +294,7 @@ struct TerrainSample vec4 z; }; -TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) { TerrainSample ts; @@ -227,7 +344,7 @@ struct TerrainSampleNormal vec3 z; }; -TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) { TerrainSample ts = _t_sample(tex, terrain_coord, tw); TerrainSampleNormal tsn; @@ -250,7 +367,7 @@ TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, Terra return tsn; } -TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) { TerrainSample ts = _t_sample(tex, terrain_coord, tw); ts.x.xyz = srgb_to_linear(ts.x.xyz); @@ -262,7 +379,7 @@ TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeig // Triplanar sampling of things that are neither colors nor normals (i.e. orm) vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { - TerrainWeight tw = _t_weight(terrain_coord); + TerrainTriplanar tw = _t_triplanar(); TerrainSample ts = _t_sample(tex, terrain_coord, tw); @@ -279,7 +396,7 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) // *NOTE: Bottom face has not been tested vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - TerrainWeight tw = _t_weight(terrain_coord); + TerrainTriplanar tw = _t_triplanar(); TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); @@ -289,13 +406,92 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) // Triplanar sampling of colors. Colors are converted to linear space before blending. vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) { - TerrainWeight tw = _t_weight(terrain_coord); + TerrainTriplanar tw = _t_triplanar(); TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); } +PBRMix terrain_sample_pbr( + TerrainCoord terrain_coord + , TerrainTriplanar tw + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + ) +{ + PBRMix mix = init_pbr_mix(); + + #define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) + #define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) + #define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) + switch (tw.type & SAMPLE_X) + { + case SAMPLE_X: + PBRMix mix_x = sample_pbr( + get_uv_x() + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + // Triplanar-specific normal texture fix + mix_x.vNt = _t_normal_post_x(mix_x.vNt); + mix = mix_pbr(mix, mix_x, tw.weight.x); + break; + default: + break; + } + + switch (tw.type & SAMPLE_Y) + { + case SAMPLE_Y: + PBRMix mix_y = sample_pbr( + get_uv_y() + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + // Triplanar-specific normal texture fix + mix_y.vNt = _t_normal_post_y(mix_y.vNt); + mix = mix_pbr(mix, mix_y, tw.weight.y); + break; + default: + break; + } + + switch (tw.type & SAMPLE_Z) + { + case SAMPLE_Z: + PBRMix mix_z = sample_pbr( + get_uv_z() + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + // Triplanar-specific normal texture fix + mix_z.vNt = _t_normal_post_z(mix_z.vNt); + mix = mix_pbr(mix, mix_z, tw.weight.z); + break; + default: + break; + } + + return mix; +} + #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 #define TerrainCoord vec2 vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) @@ -314,6 +510,28 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) col.xyz = srgb_to_linear(col.xyz); return col; } + +// TODO: Implement this for the more complex triplanar case +PBRMix terrain_sample_pbr( + TerrainCoord terrain_coord + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + ) +{ + return sample_pbr( + terrain_coord + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); +} #endif // The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -- cgit v1.2.3 From b162ff3cae482a443f93d818125f6e22d647451f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:50 -0700 Subject: DRTVWR-592: Implement reduced branching terrain shader --- .../shaders/class1/deferred/pbrterrainF.glsl | 207 ++++++++++++--------- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 70 ++++++- 2 files changed, 186 insertions(+), 91 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index f788b46aa7..22071421de 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -31,6 +31,52 @@ #define TerrainCoord vec2 #endif +#if 0 // TODO: Remove debug +#define TERRAIN_DEBUG 1 +#endif + +// TODO: Decide if this struct needs to be declared +struct TerrainMix +{ + vec4 weight; + int type; +#if TERRAIN_DEBUG + ivec4 usage; +#endif +}; + +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); + +// TODO: Decide if this struct needs to be declared +struct PBRMix +{ + vec4 col; // RGB color with alpha, linear space + vec3 orm; // Occlusion, roughness, metallic + vec3 vNt; // Unpacked normal texture sample, vector +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + vec3 emissive; // RGB emissive color, linear space +#endif +}; + +PBRMix init_pbr_mix(); + +PBRMix terrain_sample_and_multiply_pbr( + TerrainCoord terrain_coord + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + , vec4 factor_col + , vec3 factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , vec3 factor_emissive +#endif + ); + +PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight); + out vec4 frag_data[4]; uniform sampler2D alpha_ramp; @@ -82,19 +128,6 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -#if 0 // TODO: Remove -#define TERRAIN_DEBUG 1 // TODO: Remove debug -struct TerrainMix -{ - vec4 weight; - int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif -}; -TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal); -#endif - void main() { @@ -108,36 +141,91 @@ void main() float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; - vec4 col = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, baseColorFactors, 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 (col.a < minimum_alpha) - { - discard; - } + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - - vec3[4] orm_factors; - orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); - orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); - orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); - orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); // RGB = Occlusion, Roughness, Metal // default values, see LLViewerTexture::sDefaultPBRORMImagep // occlusion 1.0 // roughness 0.0 // metal 0.0 - vec3 spec = sample_and_mix_vector3(alpha1, alpha2, alphaFinal, terrain_texcoord, orm_factors, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); + vec3[4] orm_factors; + orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); + orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); + orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); + orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); -#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - vec3 emissive = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, emissiveColors, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); -#else - vec3 emissive = vec3(0); -#endif + PBRMix mix = init_pbr_mix(); + PBRMix mix2; + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_0_base_color + , detail_0_metallic_roughness + , detail_0_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_0_emissive + #endif + , baseColorFactors[0] + , orm_factors[0] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[0] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[0]); + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_1_base_color + , detail_1_metallic_roughness + , detail_1_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_1_emissive + #endif + , baseColorFactors[1] + , orm_factors[1] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[1] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[1]); + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_2_base_color + , detail_2_metallic_roughness + , detail_2_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_2_emissive + #endif + , baseColorFactors[2] + , orm_factors[2] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[2] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[2]); + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_3_base_color + , detail_3_metallic_roughness + , detail_3_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_3_emissive + #endif + , baseColorFactors[3] + , orm_factors[3] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[3] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[3]); + float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + if (mix.col.a < minimum_alpha) + { + discard; + } float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); // from mikktspace.com - vec3 vNt = sample_and_mix_normal(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); + vec3 vNt = mix.vNt; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; @@ -145,59 +233,10 @@ void main() vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); tnorm *= gl_FrontFacing ? 1.0 : -1.0; - -#if TERRAIN_DEBUG // TODO: Remove -#if 0 // TODO: Remove (terrain weights visualization) - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); -#if 1 - // Show full usage and weights - float uw = 0.3; -#if 1 -#if 0 - vec4 mix_usage = vec4(tm.usage); -#else - vec4 mix_usage = vec4(tm.weight); -#endif -#else - // Version with easier-to-see boundaries of weights vs usage - vec4 mix_usage = mix(vec4(tm.usage), - mix(max(vec4(0.0), sign(tm.weight - 0.01)), - max(vec4(0.0), sign(tm.weight - 0.005)), - 0.5), - uw); -#endif - col.xyz = mix_usage.xyz; - col.x = max(col.x, mix_usage.w); - //col.y = 0.0; - //col.z = 0.0; -#else - // Show places where weight > usage + tolerance - float tolerance = 0.005; - vec4 weight_gt_usage = sign( - max( - vec4(0.0), - (tm.weight - (vec4(tm.usage) + vec4(tolerance))) - ) - ); - col.xyz = weight_gt_usage.xyz; - col.x = max(col.x, weight_gt_usage.w); -#endif -#endif -#if 0 // TODO: Remove (material channel discriminator) - //col.rgb = vec3(0.0, 1.0, 0.0); - //col.rgb = spec.rgb; - //col.rgb = (vNt + 1.0) / 2.0; - //col.rgb = (tnorm + 1.0) / 2.0; - //spec.rgb = vec3(1.0, 1.0, 0.0); - col.rgb = spec.rgb; - tnorm = vary_normal; - emissive = vec3(0); -#endif -#endif - frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse - frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse + frag_data[1] = max(vec4(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags - frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive + frag_data[3] = max(vec4(mix.emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a8d8b1a91d..a87927786c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -153,7 +153,7 @@ struct TerrainMix #define TerrainMixSample vec4[4] #define TerrainMixSample3 vec3[4] -TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) { TerrainMix tm; vec4 sample_x = vec4(1,0,0,0); @@ -198,7 +198,7 @@ TerrainTriplanar _t_triplanar() float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); // Assume weights add to 1 return tm.weight.x * samples.x + tm.weight.y * samples.y + @@ -511,7 +511,6 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) return col; } -// TODO: Implement this for the more complex triplanar case PBRMix terrain_sample_pbr( TerrainCoord terrain_coord , sampler2D tex_col @@ -671,7 +670,7 @@ TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, samp vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); vec3[4] tms3; tms3[0] = tms[0].xyz; @@ -687,7 +686,7 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, Terrain vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); tms[0] *= factors[0]; tms[1] *= factors[1]; @@ -698,7 +697,7 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); vec3[4] tms3; tms3[0] = tms[0].xyz; @@ -715,7 +714,64 @@ vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, Terrai // Returns the unpacked normal texture in range [-1, 1] vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); return terrain_mix(tm, tms3); } + +PBRMix multiply_factors_pbr( + PBRMix mix_in + , vec4 factor_col + , vec3 factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , vec3 factor_emissive +#endif + ) +{ + PBRMix mix = mix_in; + mix.col *= factor_col; + mix.orm *= factor_orm; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive *= factor_emissive; +#endif + return mix; +} + +PBRMix terrain_sample_and_multiply_pbr( + TerrainCoord terrain_coord + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + , vec4 factor_col + , vec3 factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , vec3 factor_emissive +#endif + ) +{ + PBRMix mix = terrain_sample_pbr( + terrain_coord +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 + , _t_triplanar() +#endif + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + + mix = multiply_factors_pbr(mix + , factor_col + , factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , factor_emissive +#endif + ); + + return mix; +} -- cgit v1.2.3 From be38adebbe46d62bc07d504a70556062f4e55101 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:56 -0700 Subject: DRTVWR-592: Add missing branching for terrain sampling. Jury is still out on which version is faster --- .../shaders/class1/deferred/pbrterrainF.glsl | 154 +++++++++++++-------- 1 file changed, 94 insertions(+), 60 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 22071421de..0a7c58451d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -31,6 +31,11 @@ #define TerrainCoord vec2 #endif +#define MIX_X 1 << 3 +#define MIX_Y 1 << 4 +#define MIX_Z 1 << 5 +#define MIX_W 1 << 6 + #if 0 // TODO: Remove debug #define TERRAIN_DEBUG 1 #endif @@ -123,6 +128,7 @@ in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); +// TODO: Clean these up vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); @@ -156,66 +162,94 @@ void main() PBRMix mix = init_pbr_mix(); PBRMix mix2; - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_0_base_color - , detail_0_metallic_roughness - , detail_0_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_0_emissive - #endif - , baseColorFactors[0] - , orm_factors[0] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[0] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[0]); - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_1_base_color - , detail_1_metallic_roughness - , detail_1_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_1_emissive - #endif - , baseColorFactors[1] - , orm_factors[1] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[1] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[1]); - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_2_base_color - , detail_2_metallic_roughness - , detail_2_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_2_emissive - #endif - , baseColorFactors[2] - , orm_factors[2] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[2] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[2]); - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_3_base_color - , detail_3_metallic_roughness - , detail_3_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_3_emissive - #endif - , baseColorFactors[3] - , orm_factors[3] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[3] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[3]); + switch (tm.type & MIX_X) + { + case MIX_X: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_0_base_color + , detail_0_metallic_roughness + , detail_0_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_0_emissive + #endif + , baseColorFactors[0] + , orm_factors[0] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[0] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.x); + break; + default: + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_1_base_color + , detail_1_metallic_roughness + , detail_1_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_1_emissive + #endif + , baseColorFactors[1] + , orm_factors[1] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[1] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.y); + break; + default: + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_2_base_color + , detail_2_metallic_roughness + , detail_2_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_2_emissive + #endif + , baseColorFactors[2] + , orm_factors[2] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[2] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.z); + break; + default: + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_3_base_color + , detail_3_metallic_roughness + , detail_3_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_3_emissive + #endif + , baseColorFactors[3] + , orm_factors[3] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[3] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.w); + break; + default: + break; + } float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); if (mix.col.a < minimum_alpha) -- cgit v1.2.3 From f9bd70efc9ab25dfc1ab0b9aa10d16aec271410b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:02 -0700 Subject: DRTVWR-592: Fix non-triplanar being slower somehow in some cases. --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a87927786c..078c753a35 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -511,26 +511,8 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) return col; } -PBRMix terrain_sample_pbr( - TerrainCoord terrain_coord - , sampler2D tex_col - , sampler2D tex_orm - , sampler2D tex_vNt -#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , sampler2D tex_emissive -#endif - ) -{ - return sample_pbr( - terrain_coord - , tex_col - , tex_orm - , tex_vNt -#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , tex_emissive -#endif - ); -} +#define terrain_sample_pbr sample_pbr + #endif // The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -- cgit v1.2.3 From f3c98a548a688199114763cfc4eb90bb3d2fbd5c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:08 -0700 Subject: DRTVWR-592: Clean up --- .../shaders/class1/deferred/pbrterrainF.glsl | 50 +-- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 387 +-------------------- 2 files changed, 30 insertions(+), 407 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 0a7c58451d..18f8c4aa73 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -36,18 +36,11 @@ #define MIX_Z 1 << 5 #define MIX_W 1 << 6 -#if 0 // TODO: Remove debug -#define TERRAIN_DEBUG 1 -#endif - // TODO: Decide if this struct needs to be declared struct TerrainMix { vec4 weight; int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif }; TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); @@ -127,12 +120,7 @@ in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); -// TODO: Clean these up -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +float terrain_mix(TerrainMix tm, vec4 tms4); void main() { @@ -170,14 +158,14 @@ void main() , detail_0_base_color , detail_0_metallic_roughness , detail_0_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_0_emissive - #endif +#endif , baseColorFactors[0] , orm_factors[0] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[0] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.x); break; @@ -192,14 +180,14 @@ void main() , detail_1_base_color , detail_1_metallic_roughness , detail_1_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_1_emissive - #endif +#endif , baseColorFactors[1] , orm_factors[1] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[1] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.y); break; @@ -214,14 +202,14 @@ void main() , detail_2_base_color , detail_2_metallic_roughness , detail_2_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_2_emissive - #endif +#endif , baseColorFactors[2] , orm_factors[2] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[2] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.z); break; @@ -236,14 +224,14 @@ void main() , detail_3_base_color , detail_3_metallic_roughness , detail_3_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_3_emissive - #endif +#endif , baseColorFactors[3] , orm_factors[3] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[3] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.w); break; @@ -251,12 +239,12 @@ void main() break; } - float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + float minimum_alpha = terrain_mix(tm, minimum_alphas); if (mix.col.a < minimum_alpha) { discard; } - float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); + float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z)); // from mikktspace.com vec3 vNt = mix.vNt; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 078c753a35..c18cf832f8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -138,16 +138,10 @@ struct TerrainTriplanar int type; }; -#if 0 // TODO: Remove debug -#define TERRAIN_DEBUG 1 -#endif struct TerrainMix { vec4 weight; int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif }; #define TerrainMixSample vec4[4] @@ -172,9 +166,6 @@ TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) (usage.y * MIX_Y) | (usage.z * MIX_Z) | (usage.w * MIX_W); -#if TERRAIN_DEBUG // TODO: Remove debug - tm.usage = usage; -#endif return tm; } @@ -196,32 +187,13 @@ TerrainTriplanar _t_triplanar() return tw; } -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - // Assume weights add to 1 - return tm.weight.x * samples.x + - tm.weight.y * samples.y + - tm.weight.z * samples.z + - tm.weight.w * samples.w; -} - -vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) -{ - // Assume weights add to 1 - return tm.weight.x * tms[0] + - tm.weight.y * tms[1] + - tm.weight.z * tms[2] + - tm.weight.w * tms[3]; -} - -vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) +// Assume weights add to 1 +float terrain_mix(TerrainMix tm, vec4 tms4) { - // Assume weights add to 1 - return tm.weight.x * tms3[0] + - tm.weight.y * tms3[1] + - tm.weight.z * tms3[2] + - tm.weight.w * tms3[3]; + return (tm.weight.x * tms4[0]) + + (tm.weight.y * tms4[1]) + + (tm.weight.z * tms4[2]) + + (tm.weight.w * tms4[3]); } #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 @@ -230,17 +202,6 @@ vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) -{ - // Handle case where sign is 0 - float sign = (2.0*sign_or_zero) + 1.0; - sign /= abs(sign); - // If the vertex normal is negative, flip the texture back - // right-side up. - vec2 uv = uv_unflipped * vec2(sign, 1); - return texture(tex, uv); -} - vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 @@ -287,132 +248,6 @@ vec3 _t_normal_post_z(vec3 vNt0) return vNt_z; } -struct TerrainSample -{ - vec4 x; - vec4 y; - vec4 z; -}; - -TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts; - - // The switch..case is broken up into three parts deliberately. A single - // switch..case caused unexplained, "ant trail" seams in terrain. (as seen - // on Nvidia/Windows 10). The extra two branches are not free, but it's - // still a performance win compared to sampling along all three axes for - // every terrain fragment. - #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) - #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) - #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) - switch (tw.type & SAMPLE_X) - { - case SAMPLE_X: - ts.x = do_sample_x(); - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tw.type & SAMPLE_Y) - { - case SAMPLE_Y: - ts.y = do_sample_y(); - break; - default: - ts.y = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tw.type & SAMPLE_Z) - { - case SAMPLE_Z: - ts.z = do_sample_z(); - break; - default: - ts.z = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return ts; -} - -struct TerrainSampleNormal -{ - vec3 x; - vec3 y; - vec3 z; -}; - -TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - TerrainSampleNormal tsn; - // Unpack normals - tsn.x = ts.x.xyz*2.0-1.0; - tsn.y = ts.y.xyz*2.0-1.0; - tsn.z = ts.z.xyz*2.0-1.0; - // Get sign - vec3 ns = sign(vary_vertex_normal); - // Handle case where sign is 0 - ns = (2.0*ns) + 1.0; - ns /= abs(ns); - // If the sign is negative, rotate normal by 180 degrees - tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); - tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); - tsn.z.xy = (min(0, ns.z) * tsn.z.xy) + (min(0, -ns.z) * -tsn.z.xy); - // *HACK: Transform normals according to orientation of the UVs - tsn.x.xy = vec2(-tsn.x.y, tsn.x.x); - tsn.y.xy = -tsn.y.xy; - return tsn; -} - -TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - ts.x.xyz = srgb_to_linear(ts.x.xyz); - ts.y.xyz = srgb_to_linear(ts.y.xyz); - ts.z.xyz = srgb_to_linear(ts.z.xyz); - return ts; -} - -// Triplanar sampling of things that are neither colors nor normals (i.e. orm) -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - - return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -} - -// Specialized triplanar normal texture sampling implementation, taking into -// account how the rotation of the texture affects the lighting and trying to -// negate that. -// *TODO: Decide if we want this. It may be better to just calculate the -// tangents on-the-fly here rather than messing with the normals, due to the -// subtleties of the effects of triplanar mapping on UVs. These sampled normals -// are only valid on the faces of a cube. -// *NOTE: Bottom face has not been tested -vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); - - return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -} - -// Triplanar sampling of colors. Colors are converted to linear space before blending. -vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); - - return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -} - PBRMix terrain_sample_pbr( TerrainCoord terrain_coord , TerrainTriplanar tw @@ -426,9 +261,9 @@ PBRMix terrain_sample_pbr( { PBRMix mix = init_pbr_mix(); - #define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) - #define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) - #define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) switch (tw.type & SAMPLE_X) { case SAMPLE_X: @@ -482,6 +317,7 @@ PBRMix terrain_sample_pbr( #endif ); // Triplanar-specific normal texture fix + // *NOTE: Bottom face has not been tested mix_z.vNt = _t_normal_post_z(mix_z.vNt); mix = mix_pbr(mix, mix_z, tw.weight.z); break; @@ -493,214 +329,13 @@ PBRMix terrain_sample_pbr( } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -#define TerrainCoord vec2 -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) -{ - return texture(tex, terrain_coord); -} - -vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) -{ - return texture(tex, terrain_coord).xyz*2.0-1.0; -} -vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) -{ - vec4 col = texture(tex, terrain_coord); - col.xyz = srgb_to_linear(col.xyz); - return col; -} +#define TerrainCoord vec2 #define terrain_sample_pbr sample_pbr #endif -// The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -// *TODO: Currently, there is much more switch..case branching than needed. This could be simplified by branching per-material rather than per-texture. - -TerrainMixSample _tmix_sample(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample tms; - - switch (tm.type & MIX_X) - { - case MIX_X: - tms[0] = terrain_texture(tex0, texcoord); - break; - default: - tms[0] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tms[1] = terrain_texture(tex1, texcoord); - break; - default: - tms[1] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tms[2] = terrain_texture(tex2, texcoord); - break; - default: - tms[2] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tms[3] = terrain_texture(tex3, texcoord); - break; - default: - tms[3] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return tms; -} - -TerrainMixSample _tmix_sample_color(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample tmix; - - switch (tm.type & MIX_X) - { - case MIX_X: - tmix[0] = terrain_texture_color(tex0, texcoord); - break; - default: - tmix[0] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tmix[1] = terrain_texture_color(tex1, texcoord); - break; - default: - tmix[1] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tmix[2] = terrain_texture_color(tex2, texcoord); - break; - default: - tmix[2] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tmix[3] = terrain_texture_color(tex3, texcoord); - break; - default: - tmix[3] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return tmix; -} - -TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample3 tmix3; - - switch (tm.type & MIX_X) - { - case MIX_X: - tmix3[0] = terrain_texture_normal(tex0, texcoord); - break; - default: - tmix3[0] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tmix3[1] = terrain_texture_normal(tex1, texcoord); - break; - default: - tmix3[1] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tmix3[2] = terrain_texture_normal(tex2, texcoord); - break; - default: - tmix3[2] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tmix3[3] = terrain_texture_normal(tex3, texcoord); - break; - default: - tmix3[3] = vec3(1.0, 0.0, 1.0); - break; - } - - return tmix3; -} - -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); - vec3[4] tms3; - tms3[0] = tms[0].xyz; - tms3[1] = tms[1].xyz; - tms3[2] = tms[2].xyz; - tms3[3] = tms[3].xyz; - tms3[0] *= factors[0]; - tms3[1] *= factors[1]; - tms3[2] *= factors[2]; - tms3[3] *= factors[3]; - return terrain_mix(tm, tms3); -} - -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); - tms[0] *= factors[0]; - tms[1] *= factors[1]; - tms[2] *= factors[2]; - tms[3] *= factors[3]; - return terrain_mix(tm, tms); -} - -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); - vec3[4] tms3; - tms3[0] = tms[0].xyz; - tms3[1] = tms[1].xyz; - tms3[2] = tms[2].xyz; - tms3[3] = tms[3].xyz; - tms3[0] *= factors[0]; - tms3[1] *= factors[1]; - tms3[2] *= factors[2]; - tms3[3] *= factors[3]; - return terrain_mix(tm, tms3); -} - -// Returns the unpacked normal texture in range [-1, 1] -vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); - return terrain_mix(tm, tms3); -} - PBRMix multiply_factors_pbr( PBRMix mix_in , vec4 factor_col -- cgit v1.2.3 From 8d9933b37057a67652512d949cedb24b9b087810 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:13 -0700 Subject: DRTVWR-592: EXTRA_CODE_HERE is actually important - bring that back --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 2 ++ indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 18f8c4aa73..4bb9758224 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #define TERRAIN_PBR_DETAIL_EMISSIVE 0 #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index c18cf832f8..316b751590 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + /** * Triplanar mapping implementation adapted from Inigo Quilez' example shader, * MIT license. -- cgit v1.2.3 From cc0f831aaa960552b218da436da57b44cb2dfe0f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:18 -0700 Subject: DRTVWR-592: Fix PBR terrain shader compile crash when emissive textures are disabled --- .../newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 8 +++++++- indra/newview/llviewershadermgr.cpp | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 4bb9758224..db03e0885c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -258,9 +258,15 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#define emissive mix.emissive +#else +#define emissive vec3(0) +#endif frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags - frag_data[3] = max(vec4(mix.emissive,0), vec4(0)); // PBR sRGB Emissive + frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5849f97e0e..d545ef97fd 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -695,6 +695,8 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor"); attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor); + S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); + attribs["TERRAIN_PBR_DETAIL"] = llformat("%d", detail); } LLGLSLShader::sGlobalDefines = attribs; -- cgit v1.2.3 From 45547c7bbadf15804f54bb28fd1c94eb5f080bf5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 16:19:20 -0700 Subject: DRTVWR-592: Attempt to fix Mac build --- indra/newview/lltexturectrl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 08c530314e..ee7095dd50 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -133,7 +133,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), - pick_type("pick_type", PICK_TEXTURE), + pick_type("pick_type", LLTexPickInventoryType::TEXTURE), allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), -- cgit v1.2.3 From 0625516e3838b940d3ed4be1167b7def147f5d22 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 22 Jan 2024 11:58:48 -0600 Subject: https://github.com/secondlife/viewer-issues/issues/22 partial build fix --- indra/newview/llviewershadermgr.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f9c2906170..6495692e9a 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1275,7 +1275,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; -- cgit v1.2.3 From 210d9204813318f55fb39505fda88d4a3544ae0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 22 Jan 2024 20:43:53 +0200 Subject: Build fix for issues/22 --- indra/newview/lltexturectrl.cpp | 12 ++++++------ indra/newview/lltexturectrl.h | 28 ++++++++-------------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index c330696fb2..368222f7a0 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -2367,12 +2367,12 @@ LLSD LLTextureCtrl::getValue() const namespace LLInitParam { - void TypeValues::declareValues() - { - declare("texture_material", LLTextureCtrl::PICK_TEXTURE_MATERIAL); - declare("texture", LLTextureCtrl::PICK_TEXTURE); - declare("material", LLTextureCtrl::PICK_MATERIAL); - } + void TypeValues::declareValues() + { + declare("texture_material", PICK_TEXTURE_MATERIAL); + declare("texture", PICK_TEXTURE); + declare("material", PICK_MATERIAL); + } } diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index d71566c526..5c7091a9b5 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -64,17 +64,18 @@ bool get_is_predefined_texture(LLUUID asset_id); LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false); bool get_can_copy_texture(LLUUID image_id); -enum class LLTexPickInventoryType : U32 + +typedef enum e_pick_inventory_type { - TEXTURE_MATERIAL = 0, - TEXTURE = 1, - MATERIAL = 2, -}; + PICK_TEXTURE_MATERIAL = 0, + PICK_TEXTURE = 1, + PICK_MATERIAL = 2, +} EPickInventoryType; namespace LLInitParam { template<> - struct TypeValues : public TypeValuesHelper + struct TypeValues : public TypeValuesHelper { static void declareValues(); }; @@ -88,13 +89,6 @@ enum LLPickerSource PICKER_UNKNOWN, // on cancel, default ids }; -typedef enum e_pick_inventory_type -{ - PICK_TEXTURE_MATERIAL = 0, - PICK_TEXTURE = 1, - PICK_MATERIAL = 2, -} EPickInventoryType; - ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl @@ -110,12 +104,6 @@ public: TEXTURE_CANCEL } ETexturePickOp; - // *HACK: Can't forward-declare an enum scoped inside a class. Maybe there's a better way to initialize LLInitParam::TypeValues that doesn't run into this limitation. - typedef LLTexPickInventoryType EPickInventoryType; - static const EPickInventoryType PICK_TEXTURE_MATERIAL = LLTexPickInventoryType::TEXTURE_MATERIAL; - static const EPickInventoryType PICK_TEXTURE = LLTexPickInventoryType::TEXTURE; - static const EPickInventoryType PICK_MATERIAL = LLTexPickInventoryType::MATERIAL; - public: struct Params : public LLInitParam::Block { @@ -140,7 +128,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), - pick_type("pick_type", LLTexPickInventoryType::TEXTURE), + pick_type("pick_type", PICK_TEXTURE), allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), -- cgit v1.2.3 From 7b0372ac1f6191ef9216296cef2f476caadee40c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 23 Jan 2024 13:12:54 -0800 Subject: Put PBR terrain behind feature flag --- indra/newview/app_settings/settings.xml | 11 ++++++ indra/newview/llfloaterregioninfo.cpp | 41 ++++++++++++++-------- .../skins/default/xui/en/panel_region_terrain.xml | 16 ++++++++- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 578bb02387..df30b8d298 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10833,6 +10833,17 @@ Value 12.0 + RenderTerrainPBREnabled + + Comment + EXPERIMENTAL: Enable PBR Terrain features. Requires restart. + Persist + 1 + Type + Boolean + Value + 0 + RenderTerrainPBRDetail Comment diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 15ac46dc21..2c743d596e 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1441,32 +1441,45 @@ BOOL LLPanelRegionTerrainInfo::postBuild() mAskedTextureHeights = false; mConfirmedTextureHeights = false; + refresh(); + return LLPanelRegionInfo::postBuild(); } // virtual void LLPanelRegionTerrainInfo::refresh() { - std::string buffer; + // For simplicity, require restart + static BOOL feature_pbr_terrain_enabled = gSavedSettings.getBOOL("RenderTerrainPBREnabled"); - bool has_material_assets = false; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - LLTextureCtrl* material_ctrl = getChild(buffer); - if (material_ctrl && material_ctrl->getImageAssetID().notNull()) - { - has_material_assets = true; - break; - } - } + LLTextBox* texture_text = getChild("detail_texture_text"); + if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); } LLComboBox* material_type_ctrl = getChild("terrain_material_type"); if (material_type_ctrl) { - const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + material_type_ctrl->setVisible(feature_pbr_terrain_enabled); + + bool has_material_assets = false; + + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + LLTextureCtrl* material_ctrl = getChild(buffer); + if (material_ctrl && material_ctrl->getImageAssetID().notNull()) + { + has_material_assets = true; + break; + } + } + + TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + + if (!feature_pbr_terrain_enabled) { material_type = TerrainMaterialType::TEXTURE; } + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; - material_type_ctrl->setEnabled(!(is_material_selected && has_material_assets)); + material_type_ctrl->setEnabled(feature_pbr_terrain_enabled && !(is_material_selected && has_material_assets)); } } diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index e36fb05647..88855ab739 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -92,6 +92,20 @@ name="PBRMaterials" value="PBRMaterials" /> + + Terrain Textures + Maximum size: 1024x1024 -- cgit v1.2.3