Merge branch 'DRTVWR-559' of https://bitbucket.org/lindenlab/viewer
# Conflicts: # autobuild.xml # indra/newview/CMakeLists.txt # indra/newview/llface.cpp # indra/newview/llfilepicker.h # indra/newview/llinventoryicon.cpp # indra/newview/lltexturectrl.cpp # indra/newview/llviewerobject.cpp # indra/newview/llvovolume.cpp # indra/newview/llvovolume.h # indra/newview/pipeline.cpp # indra/newview/skins/default/textures/textures.xml # indra/newview/skins/default/xui/en/floater_inventory_view_finder.xmlmaster
commit
536e958018
112
autobuild.xml
112
autobuild.xml
|
|
@ -1381,65 +1381,17 @@
|
|||
<string>glext</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c5e9a59c7cf03c88a5cb4ab0a9c21091</string>
|
||||
<string>4f8dc85863fec36e8d872c31f4abcd05</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/99835/880141/glext-68-darwin64-571812.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101480/892402/glext-68-common-572829.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>da432b959ccd920adca1030ad7f1b6cf</string>
|
||||
<key>url</key>
|
||||
<string>http://3p.firestormviewer.org/glext-68-linux-180871251.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>12b2d643a013be8297bbbe37743abe94</string>
|
||||
<key>url</key>
|
||||
<string>http://3p.firestormviewer.org/glext-68-linux64-180841554.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>6a311615bce59b01cf73ee65012a9b38</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54951/511711/glext-68-windows-538965.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>daf619dab1cf7518af6532b18800c4b0</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54924/511490/glext-68-windows64-538965.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
|
|
@ -3773,6 +3725,62 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>version</key>
|
||||
<string>3.0.16.565299</string>
|
||||
</map>
|
||||
<key>vulkan_gltf</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2018 Sascha Willems</string>
|
||||
<key>description</key>
|
||||
<string>Vulkan GLTF Sample Implementation</string>
|
||||
<key>license</key>
|
||||
<string>Copyright (c) 2018 Sascha Willems</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/vulkan_gltf.txt</string>
|
||||
<key>name</key>
|
||||
<string>vulkan_gltf</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>8cff2060843db3db788511ee34a8e8cc</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>58eea384be49ba756ce9c5e66669540b</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>79b6a11622c2f83cfc2b7cd1fafb867b</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1</string>
|
||||
</map>
|
||||
<key>xmlrpc-epi</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
include(Prebuilt)
|
||||
|
||||
if (NOT USESYSTEMLIBS)
|
||||
if (WINDOWS OR LINUX)
|
||||
use_prebuilt_binary(glext)
|
||||
endif (WINDOWS OR LINUX)
|
||||
use_prebuilt_binary(glext)
|
||||
use_prebuilt_binary(glh_linear)
|
||||
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (NOT USESYSTEMLIBS)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
include(Variables)
|
||||
include(FreeType)
|
||||
include(GLH)
|
||||
include(GLEXT)
|
||||
|
||||
set(LLRENDER_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llrender
|
||||
${GLH_INCLUDE_DIR}
|
||||
${GLEXT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (BUILD_HEADLESS)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
use_prebuilt_binary(vulkan_gltf)
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ LLAssetDictionary::LLAssetDictionary()
|
|||
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
|
||||
addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
|
||||
addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true));
|
||||
addEntry(LLAssetType::AT_MATERIAL, new AssetEntry("MATERIAL", "material", "render material", true, true, true));
|
||||
addEntry(LLAssetType::AT_MATERIAL, new AssetEntry("MATERIAL", "material", "render material", true, true, true));
|
||||
addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
|
||||
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
|
||||
|
||||
|
|
|
|||
|
|
@ -834,6 +834,15 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
|
|||
++sRawImageCount;
|
||||
}
|
||||
|
||||
LLImageRaw::LLImageRaw(const U8* data, U16 width, U16 height, S8 components)
|
||||
: LLImageBase()
|
||||
{
|
||||
if (allocateDataSize(width, height, components))
|
||||
{
|
||||
memcpy(getData(), data, width * height * components);
|
||||
}
|
||||
}
|
||||
|
||||
LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
|
||||
: LLImageBase()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ protected:
|
|||
public:
|
||||
LLImageRaw();
|
||||
LLImageRaw(U16 width, U16 height, S8 components);
|
||||
LLImageRaw(const U8* data, U16 width, U16 height, S8 components);
|
||||
LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
|
||||
// Construct using createFromFile (used by tools)
|
||||
//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ LLInventoryDictionary::LLInventoryDictionary()
|
|||
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
|
||||
addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
|
||||
addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS));
|
||||
addEntry(LLInventoryType::IT_MATERIAL, new InventoryEntry("material", "render material", 1, LLAssetType::AT_MATERIAL));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,8 @@ const std::string LLSettingsSky::SETTING_SKY_MOISTURE_LEVEL("moisture_level");
|
|||
const std::string LLSettingsSky::SETTING_SKY_DROPLET_RADIUS("droplet_radius");
|
||||
const std::string LLSettingsSky::SETTING_SKY_ICE_LEVEL("ice_level");
|
||||
|
||||
const std::string LLSettingsSky::SETTING_REFLECTION_PROBE_AMBIANCE("reflection_probe_ambiance");
|
||||
|
||||
const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("3ae23978-ac82-bcf3-a9cb-ba6e52dcb9ad");
|
||||
|
||||
static const LLUUID DEFAULT_SUN_ID("32bfbcea-24b1-fb9d-1ef9-48a28a63730f"); // dataserver
|
||||
|
|
@ -634,6 +636,9 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
|
|||
validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
|
||||
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
|
||||
|
||||
validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal,
|
||||
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
|
||||
|
||||
validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
|
||||
validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
|
||||
validation.push_back(Validator(SETTING_MIE_CONFIG, true, LLSD::TypeArray, &validateMieLayers));
|
||||
|
|
@ -759,6 +764,8 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
|
|||
dfltsetting[SETTING_SKY_DROPLET_RADIUS] = 800.0f;
|
||||
dfltsetting[SETTING_SKY_ICE_LEVEL] = 0.0f;
|
||||
|
||||
dfltsetting[SETTING_REFLECTION_PROBE_AMBIANCE] = 0.0f;
|
||||
|
||||
dfltsetting[SETTING_RAYLEIGH_CONFIG] = rayleighConfigDefault();
|
||||
dfltsetting[SETTING_MIE_CONFIG] = mieConfigDefault();
|
||||
dfltsetting[SETTING_ABSORPTION_CONFIG] = absorptionConfigDefault();
|
||||
|
|
@ -1136,6 +1143,11 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level)
|
|||
setValue(SETTING_SKY_ICE_LEVEL, ice_level);
|
||||
}
|
||||
|
||||
void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance)
|
||||
{
|
||||
setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance);
|
||||
}
|
||||
|
||||
void LLSettingsSky::setAmbientColor(const LLColor3 &val)
|
||||
{
|
||||
mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = val.getValue();
|
||||
|
|
@ -1424,6 +1436,11 @@ F32 LLSettingsSky::getSkyIceLevel() const
|
|||
return mSettings[SETTING_SKY_ICE_LEVEL].asReal();
|
||||
}
|
||||
|
||||
F32 LLSettingsSky::getReflectionProbeAmbiance() const
|
||||
{
|
||||
return mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal();
|
||||
}
|
||||
|
||||
F32 LLSettingsSky::getSkyBottomRadius() const
|
||||
{
|
||||
return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ public:
|
|||
static const std::string SETTING_SKY_DROPLET_RADIUS;
|
||||
static const std::string SETTING_SKY_ICE_LEVEL;
|
||||
|
||||
static const std::string SETTING_REFLECTION_PROBE_AMBIANCE;
|
||||
|
||||
static const std::string SETTING_LEGACY_HAZE;
|
||||
|
||||
static const LLUUID DEFAULT_ASSET_ID;
|
||||
|
|
@ -131,6 +133,8 @@ public:
|
|||
F32 getSkyDropletRadius() const;
|
||||
F32 getSkyIceLevel() const;
|
||||
|
||||
F32 getReflectionProbeAmbiance() const;
|
||||
|
||||
// Return first (only) profile layer represented in LLSD
|
||||
LLSD getRayleighConfig() const;
|
||||
LLSD getMieConfig() const;
|
||||
|
|
@ -159,6 +163,8 @@ public:
|
|||
void setSkyDropletRadius(F32 radius);
|
||||
void setSkyIceLevel(F32 ice_level);
|
||||
|
||||
void setReflectionProbeAmbiance(F32 ambiance);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
LLColor3 getAmbientColor() const;
|
||||
void setAmbientColor(const LLColor3 &val);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ set(llprimitive_HEADER_FILES
|
|||
CMakeLists.txt
|
||||
lldaeloader.h
|
||||
llgltfloader.h
|
||||
llgltfmaterial.h
|
||||
legacy_object_types.h
|
||||
llmaterial.h
|
||||
llmaterialid.h
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "LLGLTFLoader.h"
|
||||
#include "llgltfloader.h"
|
||||
|
||||
// Import & define single-header gltf import/export lib
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
// Additionally, disable inclusion of STB header files entirely with
|
||||
// TINYGLTF_NO_INCLUDE_STB_IMAGE
|
||||
// TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE
|
||||
#include "tinygltf\tiny_gltf.h"
|
||||
#include "tinygltf/tiny_gltf.h"
|
||||
|
||||
|
||||
// TODO: includes inherited from dae loader. Validate / prune
|
||||
|
|
@ -68,7 +68,6 @@ static const std::string lod_suffix[LLModel::NUM_LODS] =
|
|||
"_PHYS",
|
||||
};
|
||||
|
||||
const U32 LIMIT_MATERIALS_OUTPUT = 12;
|
||||
|
||||
LLGLTFLoader::LLGLTFLoader(std::string filename,
|
||||
S32 lod,
|
||||
|
|
@ -94,7 +93,6 @@ LLGLTFLoader::LLGLTFLoader(std::string filename,
|
|||
jointsFromNodes,
|
||||
jointAliasMap,
|
||||
maxJointsPerMesh ),
|
||||
mGeneratedModelLimit(modelLimit),
|
||||
//mPreprocessGLTF(preprocess),
|
||||
mMeshesLoaded(false),
|
||||
mMaterialsLoaded(false)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,6 @@ private:
|
|||
bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh);
|
||||
LLUUID imageBufferToTextureUUID(const gltf_texture& tex);
|
||||
|
||||
U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels
|
||||
// bool mPreprocessGLTF;
|
||||
|
||||
/* Below inherited from dae loader - unknown if/how useful here
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* @file llgltfmaterial.h
|
||||
* @brief Material definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llrefcount.h"
|
||||
#include "v4color.h"
|
||||
#include "v3color.h"
|
||||
#include "lluuid.h"
|
||||
#include "llmd5.h"
|
||||
|
||||
class LLGLTFMaterial : public LLRefCount
|
||||
{
|
||||
public:
|
||||
|
||||
enum AlphaMode
|
||||
{
|
||||
ALPHA_MODE_OPAQUE = 0,
|
||||
ALPHA_MODE_BLEND,
|
||||
ALPHA_MODE_MASK
|
||||
};
|
||||
|
||||
LLUUID mAlbedoId;
|
||||
LLUUID mNormalId;
|
||||
LLUUID mMetallicRoughnessId;
|
||||
LLUUID mEmissiveId;
|
||||
|
||||
LLColor4 mAlbedoColor = LLColor4(1,1,1,1);
|
||||
LLColor3 mEmissiveColor = LLColor3(0,0,0);
|
||||
|
||||
F32 mMetallicFactor = 0.f;
|
||||
F32 mRoughnessFactor = 0.f;
|
||||
bool mDoubleSided = false;
|
||||
AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE;
|
||||
|
||||
// get a UUID based on a hash of this LLGLTFMaterial
|
||||
LLUUID getHash() const
|
||||
{
|
||||
LLMD5 md5;
|
||||
md5.update((unsigned char*) this, sizeof(this));
|
||||
LLUUID id;
|
||||
md5.raw_digest(id.mData);
|
||||
return id;
|
||||
}
|
||||
|
||||
// set mAlphaMode from string.
|
||||
// Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE
|
||||
void setAlphaMode(const std::string& mode)
|
||||
{
|
||||
if (mode == "MASK")
|
||||
{
|
||||
mAlphaMode = ALPHA_MODE_MASK;
|
||||
}
|
||||
else if (mode == "BLEND")
|
||||
{
|
||||
mAlphaMode = ALPHA_MODE_BLEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAlphaMode = ALPHA_MODE_OPAQUE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -155,6 +155,13 @@ std::string LLMaterialID::asString() const
|
|||
return materialIDString;
|
||||
}
|
||||
|
||||
LLUUID LLMaterialID::asUUID() const
|
||||
{
|
||||
LLUUID ret;
|
||||
memcpy(ret.mData, mID, MATERIAL_ID_SIZE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
|
||||
{
|
||||
s << material_id.asString();
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public:
|
|||
|
||||
LLSD asLLSD() const;
|
||||
std::string asString() const;
|
||||
LLUUID asUUID() const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "llsd.h"
|
||||
#include "llmaterialid.h"
|
||||
#include "llmaterial.h"
|
||||
#include "llgltfmaterial.h"
|
||||
|
||||
// These bits are used while unpacking TEM messages to tell which aspects of
|
||||
// the texture entry changed.
|
||||
|
|
@ -134,6 +135,10 @@ public:
|
|||
S32 setMaterialID(const LLMaterialID& pMaterialID);
|
||||
S32 setMaterialParams(const LLMaterialPtr pMaterialParams);
|
||||
|
||||
void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; }
|
||||
LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; }
|
||||
|
||||
|
||||
virtual const LLUUID &getID() const { return mID; }
|
||||
const LLColor4 &getColor() const { return mColor; }
|
||||
const F32 getAlpha() const { return mColor.mV[VALPHA]; }
|
||||
|
|
@ -162,6 +167,8 @@ public:
|
|||
const LLMaterialID& getMaterialID() const { return mMaterialID; };
|
||||
const LLMaterialPtr getMaterialParams() const { return mMaterial; };
|
||||
|
||||
LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; }
|
||||
|
||||
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
|
||||
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
|
||||
// to NOT return NULL.
|
||||
|
|
@ -219,6 +226,7 @@ protected:
|
|||
bool mMaterialUpdatePending;
|
||||
LLMaterialID mMaterialID;
|
||||
LLMaterialPtr mMaterial;
|
||||
LLPointer<LLGLTFMaterial> mGLTFMaterial; // if present, ignore mMaterial
|
||||
|
||||
// Note the media data is not sent via the same message structure as the rest of the TE
|
||||
LLMediaEntry* mMediaEntry; // The media data for the face
|
||||
|
|
|
|||
|
|
@ -53,6 +53,50 @@ GLenum LLCubeMapArray::sTargets[6] =
|
|||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
|
||||
};
|
||||
|
||||
LLVector3 LLCubeMapArray::sLookVecs[6] =
|
||||
{
|
||||
LLVector3(1, 0, 0),
|
||||
LLVector3(-1, 0, 0),
|
||||
LLVector3(0, 1, 0),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, 0, 1),
|
||||
LLVector3(0, 0, -1)
|
||||
};
|
||||
|
||||
LLVector3 LLCubeMapArray::sUpVecs[6] =
|
||||
{
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, 0, 1),
|
||||
LLVector3(0, 0, -1),
|
||||
LLVector3(0, -1, 0),
|
||||
LLVector3(0, -1, 0)
|
||||
};
|
||||
|
||||
LLVector3 LLCubeMapArray::sClipToCubeLookVecs[6] =
|
||||
{
|
||||
LLVector3(0, 0, -1), //GOOD
|
||||
LLVector3(0, 0, 1), //GOOD
|
||||
|
||||
LLVector3(1, 0, 0), // GOOD
|
||||
LLVector3(1, 0, 0), // GOOD
|
||||
|
||||
LLVector3(1, 0, 0),
|
||||
LLVector3(-1, 0, 0),
|
||||
};
|
||||
|
||||
LLVector3 LLCubeMapArray::sClipToCubeUpVecs[6] =
|
||||
{
|
||||
LLVector3(-1, 0, 0), //GOOD
|
||||
LLVector3(1, 0, 0), //GOOD
|
||||
|
||||
LLVector3(0, 1, 0), // GOOD
|
||||
LLVector3(0, -1, 0), // GOOD
|
||||
|
||||
LLVector3(0, 0, -1),
|
||||
LLVector3(0, 0, 1)
|
||||
};
|
||||
|
||||
LLCubeMapArray::LLCubeMapArray()
|
||||
: mTextureStage(0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,13 +32,20 @@
|
|||
|
||||
class LLVector3;
|
||||
|
||||
// Environment map hack!
|
||||
class LLCubeMapArray : public LLRefCount
|
||||
{
|
||||
public:
|
||||
LLCubeMapArray();
|
||||
|
||||
static GLenum sTargets[6];
|
||||
|
||||
// look and up vectors for each cube face (agent space)
|
||||
static LLVector3 sLookVecs[6];
|
||||
static LLVector3 sUpVecs[6];
|
||||
|
||||
// look and up vectors for each cube face (clip space)
|
||||
static LLVector3 sClipToCubeLookVecs[6];
|
||||
static LLVector3 sClipToCubeUpVecs[6];
|
||||
|
||||
// allocate a cube map array
|
||||
// res - resolution of each cube face
|
||||
|
|
|
|||
|
|
@ -455,6 +455,7 @@ LLGLManager::LLGLManager() :
|
|||
mHasAnisotropic(FALSE),
|
||||
mHasARBEnvCombine(FALSE),
|
||||
mHasCubeMap(FALSE),
|
||||
mHasCubeMapArray(FALSE),
|
||||
mHasDebugOutput(FALSE),
|
||||
|
||||
mIsAMD(FALSE),
|
||||
|
|
@ -1074,6 +1075,7 @@ void LLGLManager::initExtensions()
|
|||
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
|
||||
mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
|
||||
mHasUniformBufferObject = ExtensionExists("GL_ARB_uniform_buffer_object", gGLHExts.mSysExts);
|
||||
mHasCubeMapArray = ExtensionExists("GL_ARB_texture_cube_map_array", gGLHExts.mSysExts);
|
||||
#if !LL_DARWIN
|
||||
mHasPointParameters = ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
|
||||
#endif
|
||||
|
|
@ -1186,6 +1188,10 @@ void LLGLManager::initExtensions()
|
|||
{
|
||||
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL;
|
||||
}
|
||||
if (!mHasCubeMapArray)
|
||||
{
|
||||
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_cube_map_array" << LL_ENDL;
|
||||
}
|
||||
|
||||
// Disable certain things due to known bugs
|
||||
if (mIsIntel && mHasMipMapGeneration)
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ public:
|
|||
BOOL mHasAnisotropic;
|
||||
BOOL mHasARBEnvCombine;
|
||||
BOOL mHasCubeMap;
|
||||
BOOL mHasCubeMapArray;
|
||||
BOOL mHasDebugOutput;
|
||||
BOOL mHassRGBTexture;
|
||||
BOOL mHassRGBFramebuffer;
|
||||
|
|
|
|||
|
|
@ -577,11 +577,13 @@ extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
|||
//----------------------------------------------------------------------------
|
||||
// LL_DARWIN
|
||||
|
||||
#define GL_GLEXT_LEGACY
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
|
||||
#define GL_EXT_separate_specular_color 1
|
||||
#include <OpenGL/glext.h>
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include "GL/glext.h"
|
||||
|
||||
#include "GL/glh_extensions.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
|
|||
#ifdef GL_INTERLEAVED_ATTRIBS
|
||||
if (varying_count > 0 && varyings)
|
||||
{
|
||||
glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||
glTransformFeedbackVaryings((GLuint64) mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -793,7 +793,14 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
extra_code_text[extra_code_count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use alpha float to store bit flags
|
||||
// See: C++: addDeferredAttachment(), shader: frag_data[2]
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS 0.25\n"); // bit 0
|
||||
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR 0.50\n"); // bit 1
|
||||
extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (mod(floor(norm.w/flag),2.0)>0.5)\n");
|
||||
|
||||
if (defines)
|
||||
{
|
||||
for (std::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
|
||||
|
|
@ -1169,14 +1176,19 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
|
||||
|
||||
mReservedUniforms.push_back("color");
|
||||
|
||||
mReservedUniforms.push_back("emissiveColor");
|
||||
mReservedUniforms.push_back("metallicFactor");
|
||||
mReservedUniforms.push_back("roughnessFactor");
|
||||
|
||||
mReservedUniforms.push_back("diffuseMap");
|
||||
mReservedUniforms.push_back("altDiffuseMap");
|
||||
mReservedUniforms.push_back("specularMap");
|
||||
mReservedUniforms.push_back("emissiveMap");
|
||||
mReservedUniforms.push_back("bumpMap");
|
||||
mReservedUniforms.push_back("bumpMap2");
|
||||
mReservedUniforms.push_back("environmentMap");
|
||||
mReservedUniforms.push_back("reflectionProbes");
|
||||
mReservedUniforms.push_back("irradianceProbes");
|
||||
mReservedUniforms.push_back("cloud_noise_texture");
|
||||
mReservedUniforms.push_back("cloud_noise_texture_next");
|
||||
mReservedUniforms.push_back("fullbright");
|
||||
|
|
@ -1223,6 +1235,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("minimum_alpha");
|
||||
mReservedUniforms.push_back("emissive_brightness");
|
||||
|
||||
// Deferred
|
||||
mReservedUniforms.push_back("shadow_matrix");
|
||||
mReservedUniforms.push_back("env_mat");
|
||||
mReservedUniforms.push_back("shadow_clip");
|
||||
|
|
@ -1247,8 +1260,9 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("depth_cutoff");
|
||||
mReservedUniforms.push_back("norm_cutoff");
|
||||
mReservedUniforms.push_back("shadow_target_width");
|
||||
mReservedUniforms.push_back("view_dir"); // DEFERRED_VIEW_DIR
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH+1);
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_VIEW_DIR+1);
|
||||
|
||||
mReservedUniforms.push_back("tc_scale");
|
||||
mReservedUniforms.push_back("rcp_screen_res");
|
||||
|
|
@ -1361,6 +1375,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("halo_map");
|
||||
mReservedUniforms.push_back("moon_brightness");
|
||||
mReservedUniforms.push_back("cloud_variance");
|
||||
mReservedUniforms.push_back("reflection_probe_ambiance");
|
||||
|
||||
mReservedUniforms.push_back("sh_input_r");
|
||||
mReservedUniforms.push_back("sh_input_g");
|
||||
|
|
|
|||
|
|
@ -74,13 +74,18 @@ public:
|
|||
PROJECTOR_LOD, // "proj_lod"
|
||||
PROJECTOR_AMBIENT_LOD, // "proj_ambient_lod"
|
||||
DIFFUSE_COLOR, // "color"
|
||||
EMISSIVE_COLOR, // "emissiveColor"
|
||||
METALLIC_FACTOR, // "metallicFactor"
|
||||
ROUGHNESS_FACTOR, // "roughnessFactor"
|
||||
DIFFUSE_MAP, // "diffuseMap"
|
||||
ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
|
||||
SPECULAR_MAP, // "specularMap"
|
||||
EMISSIVE_MAP, // "emissiveMap"
|
||||
BUMP_MAP, // "bumpMap"
|
||||
BUMP_MAP2, // "bumpMap2"
|
||||
ENVIRONMENT_MAP, // "environmentMap"
|
||||
REFLECTION_PROBES, // "reflectionProbes"
|
||||
IRRADIANCE_PROBES, // "irradianceProbes"
|
||||
CLOUD_NOISE_MAP, // "cloud_noise_texture"
|
||||
CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
|
||||
FULLBRIGHT, // "fullbright"
|
||||
|
|
@ -143,6 +148,7 @@ public:
|
|||
DEFERRED_DEPTH_CUTOFF, // "depth_cutoff"
|
||||
DEFERRED_NORM_CUTOFF, // "norm_cutoff"
|
||||
DEFERRED_SHADOW_TARGET_WIDTH, // "shadow_target_width"
|
||||
DEFERRED_VIEW_DIR, // "view_dir"
|
||||
|
||||
FXAA_TC_SCALE, // "tc_scale"
|
||||
FXAA_RCP_SCREEN_RES, // "rcp_screen_res"
|
||||
|
|
@ -257,6 +263,7 @@ public:
|
|||
|
||||
CLOUD_VARIANCE, // "cloud_variance"
|
||||
|
||||
REFLECTION_PROBE_AMBIANCE, // "reflection_probe_ambiance"
|
||||
SH_INPUT_L1R, // "sh_input_r"
|
||||
SH_INPUT_L1G, // "sh_input_g"
|
||||
SH_INPUT_L1B, // "sh_input_b"
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ include(UnixInstall)
|
|||
include(ViewerMiscLibs)
|
||||
#include(ViewerManager) # <FS:Ansariel> Remove VMP
|
||||
include(VisualLeakDetector)
|
||||
include(VulkanGltf)
|
||||
include(URIPARSER)
|
||||
include(Growl)
|
||||
include(ColladaDom)
|
||||
|
|
@ -519,6 +520,7 @@ set(viewer_SOURCE_FILES
|
|||
llmaniptranslate.cpp
|
||||
llmarketplacefunctions.cpp
|
||||
llmarketplacenotifications.cpp
|
||||
llmaterialeditor.cpp
|
||||
llmaterialmgr.cpp
|
||||
llmediactrl.cpp
|
||||
llmediadataclient.cpp
|
||||
|
|
@ -1300,6 +1302,7 @@ set(viewer_HEADER_FILES
|
|||
llmaniptranslate.h
|
||||
llmarketplacefunctions.h
|
||||
llmarketplacenotifications.h
|
||||
llmaterialeditor.h
|
||||
llmaterialmgr.h
|
||||
llmediactrl.h
|
||||
llmediadataclient.h
|
||||
|
|
|
|||
|
|
@ -52,6 +52,6 @@ void main()
|
|||
frag_data[0] = vec4(diff.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,5 +64,5 @@ void main()
|
|||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ void main()
|
|||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, alpha1);
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
frag_data[2] = vec4(0,0,0,1);
|
||||
frag_data[2] = vec4(0,0,0,GBUFFER_FLAG_SKIP_ATMOS);
|
||||
|
||||
gl_FragDepth = 0.99995f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,6 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,5 +52,5 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,6 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,6 @@ void main()
|
|||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,5 +48,5 @@ void main()
|
|||
frag_data[0] = vec4(col, 0.0);
|
||||
frag_data[1] = vec4(spec, vertex_color.a); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,5 +38,5 @@ void main()
|
|||
{
|
||||
frag_data[0] = color*texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
frag_data[1] = vec4(0.0);
|
||||
frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,5 +56,5 @@ void main()
|
|||
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = spec;
|
||||
frag_data[2] = norm;
|
||||
frag_data[2] = norm; // TODO: Should .w be set?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,10 +277,10 @@ void main()
|
|||
vec4 final_specular = spec;
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
|
||||
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, GBUFFER_FLAG_HAS_ATMOS);
|
||||
final_specular.a = specular_color.a * norm.a;
|
||||
#else
|
||||
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
|
||||
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, GBUFFER_FLAG_HAS_ATMOS);
|
||||
final_specular.a = specular_color.a;
|
||||
#endif
|
||||
|
||||
|
|
@ -444,10 +444,10 @@ void main()
|
|||
|
||||
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
|
||||
|
||||
// deferred path
|
||||
frag_data[0] = final_color; //gbuffer is sRGB
|
||||
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
|
||||
frag_data[0] = final_color; // gbuffer is sRGB
|
||||
frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
|
||||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void main()
|
|||
|
||||
frag_data[0] = vec4(c.rgb, c.a);
|
||||
frag_data[1] = vec4(0.0);
|
||||
frag_data[2] = vec4(0.0f);
|
||||
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
|
||||
gl_FragDepth = 0.999985f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,85 +25,120 @@
|
|||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
#define DEBUG_BASIC 1
|
||||
#define DEBUG_COLOR 0
|
||||
#define DEBUG_NORMAL 0
|
||||
#define DEBUG_BASIC 0
|
||||
#define DEBUG_VERTEX 0
|
||||
#define DEBUG_NORMAL_RAW 0 // Output packed normal map "as is" to diffuse
|
||||
#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse
|
||||
#define DEBUG_POSITION 0
|
||||
#define DEBUG_REFLECT_VEC 0
|
||||
#define DEBUG_REFLECT_COLOR 0
|
||||
|
||||
uniform sampler2D diffuseMap; //always in sRGB space
|
||||
|
||||
uniform float metallicFactor;
|
||||
uniform float roughnessFactor;
|
||||
uniform vec3 emissiveColor;
|
||||
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
uniform sampler2D bumpMap;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_EMISSIVE_MAP
|
||||
uniform sampler2D emissiveMap;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
uniform sampler2D specularMap;
|
||||
uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness
|
||||
#endif
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
uniform mat3 env_mat;
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_data[3];
|
||||
out vec4 frag_data[4];
|
||||
#else
|
||||
#define frag_data gl_FragData
|
||||
#endif
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
VARYING vec3 vary_mat2;
|
||||
VARYING vec2 vary_texcoord1;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
VARYING vec2 vary_texcoord2;
|
||||
VARYING vec2 vary_texcoord2;
|
||||
#endif
|
||||
|
||||
vec2 encode_normal(vec3 n);
|
||||
vec3 linear_to_srgb(vec3 c);
|
||||
|
||||
struct PBR
|
||||
{
|
||||
float LdotH; // Light and Half
|
||||
float NdotL; // Normal and Light
|
||||
float NdotH; // Normal and Half
|
||||
float VdotH; // View and Half
|
||||
};
|
||||
|
||||
const float M_PI = 3.141592653589793;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
|
||||
// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
|
||||
// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
|
||||
// else
|
||||
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
|
||||
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
|
||||
norm.xyz = norm.xyz * 2 - 1;
|
||||
|
||||
vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
|
||||
dot(norm.xyz,vary_mat1),
|
||||
dot(norm.xyz,vary_mat2));
|
||||
#else
|
||||
vec4 norm = vec4(0,0,0,1.0);
|
||||
// vec3 tnorm = vary_normal;
|
||||
vec3 tnorm = vec3(0,0,1);
|
||||
#endif
|
||||
|
||||
tnorm = normalize(tnorm.xyz);
|
||||
|
||||
//#ifdef HAS_SPECULAR_MAP
|
||||
//#else
|
||||
vec4 norm = vec4(0,0,0,1.0);
|
||||
vec3 tnorm = vary_normal;
|
||||
//#endif
|
||||
norm.xyz = normalize(tnorm.xyz);
|
||||
// RGB = Occlusion, Roughness, Metal
|
||||
// default values
|
||||
// occlusion ?
|
||||
// roughness 1.0
|
||||
// metal 1.0
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb;
|
||||
#else
|
||||
vec3 spec = vec3(1,1,1);
|
||||
#endif
|
||||
|
||||
spec.g *= roughnessFactor;
|
||||
spec.b *= metallicFactor;
|
||||
|
||||
vec3 spec;
|
||||
spec.rgb = vec3(vertex_color.a);
|
||||
vec3 emissive = emissiveColor;
|
||||
#ifdef HAS_EMISSIVE_MAP
|
||||
emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb;
|
||||
#endif
|
||||
|
||||
vec3 pos = vary_position;
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
|
||||
|
||||
#if DEBUG_BASIC
|
||||
col.rgb = vec3( 1, 0, 1 ); // DEBUG
|
||||
col.rgb = vec3( 1, 0, 1 );
|
||||
#endif
|
||||
#if DEBUG_COLOR
|
||||
#if DEBUG_VERTEX
|
||||
col.rgb = vertex_color.rgb;
|
||||
#endif
|
||||
#if DEBUG_NORMAL
|
||||
#if DEBUG_NORMAL_RAW
|
||||
col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb;
|
||||
#endif
|
||||
#if DEBUG_NORMAL_OUT
|
||||
col.rgb = vary_normal;
|
||||
#endif
|
||||
#if DEBUG_POSITION
|
||||
col.rgb = vary_position.xyz;
|
||||
#endif
|
||||
#if DEBUG_REFLECT_VEC
|
||||
col.rgb = refnormpersp;
|
||||
#endif
|
||||
#if DEBUG_REFLECT_COLOR
|
||||
col.rgb = reflected_color;
|
||||
#endif
|
||||
|
||||
frag_data[0] = vec4(col, 0.0);
|
||||
frag_data[1] = vec4(spec, vertex_color.a); // spec
|
||||
frag_data[2] = vec4(encode_normal(norm.xyz), vertex_color.a, 0.0);
|
||||
frag_data[0] = vec4(col, 0.0); // Diffuse
|
||||
frag_data[1] = vec4(spec.rgb, vertex_color.a); // Occlusion, Roughness, Metal
|
||||
frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags
|
||||
frag_data[3] = vec4(emissive,0); // Emissive
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,32 +23,122 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
#define DIFFUSE_ALPHA_MODE_IGNORE 0
|
||||
#define DIFFUSE_ALPHA_MODE_BLEND 1
|
||||
#define DIFFUSE_ALPHA_MODE_MASK 2
|
||||
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
#endif
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
||||
#if !defined(HAS_SKIN)
|
||||
uniform mat4 modelview_matrix;
|
||||
#endif
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
|
||||
#endif
|
||||
|
||||
uniform mat4 texture_matrix0;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
ATTRIBUTE vec4 tangent;
|
||||
ATTRIBUTE vec2 texcoord1;
|
||||
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
VARYING vec3 vary_mat2;
|
||||
|
||||
VARYING vec2 vary_texcoord1;
|
||||
#else
|
||||
VARYING vec3 vary_normal;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
ATTRIBUTE vec2 texcoord2;
|
||||
VARYING vec2 vary_texcoord2;
|
||||
#endif
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
void passTextureIndex();
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_position = (modelview_matrix * vec4(position.xyz,1.0)).xyz;
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
#ifdef HAS_SKIN
|
||||
mat4 mat = getObjectSkinnedTransform();
|
||||
|
||||
passTextureIndex();
|
||||
vary_normal = normalize(normal_matrix * normal);
|
||||
mat = modelview_matrix * mat;
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
vary_position = pos;
|
||||
#endif
|
||||
|
||||
gl_Position = projection_matrix*vec4(pos,1.0);
|
||||
|
||||
#else
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
|
||||
#endif
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
|
||||
vec3 b = cross(n, t)*tangent.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
#else //HAS_NORMAL_MAP
|
||||
vary_normal = n;
|
||||
#endif //HAS_NORMAL_MAP
|
||||
#else //HAS_SKIN
|
||||
vec3 n = normalize(normal_matrix * normal);
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vec3 t = normalize(normal_matrix * tangent.xyz);
|
||||
vec3 b = cross(n,t)*tangent.w;
|
||||
//vec3 t = cross(b,n) * binormal.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
#else //HAS_NORMAL_MAP
|
||||
vary_normal = n;
|
||||
#endif //HAS_NORMAL_MAP
|
||||
#endif //HAS_SKIN
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
#if !defined(HAS_SKIN)
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void main()
|
|||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, 0.0);
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog
|
||||
frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
|
||||
|
||||
gl_FragDepth = 0.99999f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ void main()
|
|||
color = mix(color.rgb, reflected_color, envIntensity);
|
||||
}
|
||||
|
||||
if (norm.w < 0.5)
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
|
||||
{
|
||||
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
|
||||
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ void main()
|
|||
|
||||
frag_data[0] = col;
|
||||
frag_data[1] = vec4(0.0f);
|
||||
frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
|
||||
|
||||
gl_FragDepth = 0.99995f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void main()
|
|||
|
||||
frag_data[0] = c;
|
||||
frag_data[1] = vec4(0.0f);
|
||||
frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
|
||||
|
||||
gl_FragDepth = 0.999988f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,6 @@ void main()
|
|||
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, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,5 +52,5 @@ void main()
|
|||
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,5 +78,5 @@ void main()
|
|||
|
||||
frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, env intens, atmo kill
|
||||
frag_data[2] = vec4(encode_normal(wavef), 0.0, GBUFFER_FLAG_HAS_ATMOS); // normalxyz, env intens, flags (atmo kill)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,5 +180,5 @@ void main()
|
|||
|
||||
|
||||
frag_data[1] = vec4(0); // speccolor, spec
|
||||
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0
|
||||
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, GBUFFER_FLAG_HAS_ATMOS);// normalxy, env intens, flags (atmo kill)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file irradianceGenF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform samplerCubeArray reflectionProbes;
|
||||
uniform int sourceIdx;
|
||||
|
||||
VARYING vec3 vary_dir;
|
||||
|
||||
// =============================================================================================================
|
||||
// Parts of this file are (c) 2018 Sascha Willems
|
||||
// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/irradiancecube.frag
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Sascha Willems
|
||||
|
||||
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.
|
||||
*/
|
||||
// =============================================================================================================
|
||||
|
||||
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
void main()
|
||||
{
|
||||
float deltaPhi = (2.0 * PI) / 11.25;
|
||||
float deltaTheta = (0.5 * PI) / 4.0;
|
||||
float mipLevel = 2;
|
||||
|
||||
vec3 N = normalize(vary_dir);
|
||||
vec3 up = vec3(0.0, 1.0, 0.0);
|
||||
vec3 right = normalize(cross(up, N));
|
||||
up = cross(N, right);
|
||||
|
||||
const float TWO_PI = PI * 2.0;
|
||||
const float HALF_PI = PI * 0.5;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
uint sampleCount = 0u;
|
||||
for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) {
|
||||
for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) {
|
||||
vec3 tempVec = cos(phi) * right + sin(phi) * up;
|
||||
vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
|
||||
color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), mipLevel).rgb * cos(theta) * sin(theta);
|
||||
sampleCount++;
|
||||
}
|
||||
}
|
||||
frag_color = vec4(PI * color / float(sampleCount), 1.0);
|
||||
}
|
||||
// =============================================================================================================
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @file irradianceGenV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, 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 mat4 modelview_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
VARYING vec3 vary_dir;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 1.0);
|
||||
|
||||
vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* @file radianceGenF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, 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$
|
||||
*/
|
||||
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform samplerCubeArray reflectionProbes;
|
||||
uniform int sourceIdx;
|
||||
|
||||
VARYING vec3 vary_dir;
|
||||
|
||||
// =============================================================================================================
|
||||
// Parts of this file are (c) 2018 Sascha Willems
|
||||
// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/prefilterenvmap.frag
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Sascha Willems
|
||||
|
||||
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.
|
||||
*/
|
||||
// =============================================================================================================
|
||||
|
||||
|
||||
uniform float roughness;
|
||||
|
||||
uniform float mipLevel;
|
||||
|
||||
const float PI = 3.1415926536;
|
||||
|
||||
// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
float random(vec2 co)
|
||||
{
|
||||
float a = 12.9898;
|
||||
float b = 78.233;
|
||||
float c = 43758.5453;
|
||||
float dt= dot(co.xy ,vec2(a,b));
|
||||
float sn= mod(dt,3.14);
|
||||
return fract(sin(sn) * c);
|
||||
}
|
||||
|
||||
vec2 hammersley2d(uint i, uint N)
|
||||
{
|
||||
// Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
uint bits = (i << 16u) | (i >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
float rdi = float(bits) * 2.3283064365386963e-10;
|
||||
return vec2(float(i) /float(N), rdi);
|
||||
}
|
||||
|
||||
// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
|
||||
vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
|
||||
{
|
||||
// Maps a 2D point to a hemisphere with spread based on roughness
|
||||
float alpha = roughness * roughness;
|
||||
float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
|
||||
vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
|
||||
|
||||
// Tangent space
|
||||
vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangentX = normalize(cross(up, normal));
|
||||
vec3 tangentY = normalize(cross(normal, tangentX));
|
||||
|
||||
// Convert to world Space
|
||||
return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
|
||||
}
|
||||
|
||||
// Normal Distribution function
|
||||
float D_GGX(float dotNH, float roughness)
|
||||
{
|
||||
float alpha = roughness * roughness;
|
||||
float alpha2 = alpha * alpha;
|
||||
float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
|
||||
return (alpha2)/(PI * denom*denom);
|
||||
}
|
||||
|
||||
vec3 prefilterEnvMap(vec3 R, float roughness)
|
||||
{
|
||||
vec3 N = R;
|
||||
vec3 V = R;
|
||||
vec3 color = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
float envMapDim = 256.0;
|
||||
int numSamples = 32/max(int(mipLevel), 1);
|
||||
|
||||
for(uint i = 0u; i < numSamples; i++) {
|
||||
vec2 Xi = hammersley2d(i, numSamples);
|
||||
vec3 H = importanceSample_GGX(Xi, roughness, N);
|
||||
vec3 L = 2.0 * dot(V, H) * H - V;
|
||||
float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
if(dotNL > 0.0) {
|
||||
// Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
|
||||
|
||||
float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
float dotVH = clamp(dot(V, H), 0.0, 1.0);
|
||||
|
||||
// Probability Distribution Function
|
||||
float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
|
||||
// Slid angle of current smple
|
||||
float omegaS = 1.0 / (float(numSamples) * pdf);
|
||||
// Solid angle of 1 pixel across all cube faces
|
||||
float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
|
||||
// Biased (+1.0) mip level for better result
|
||||
//float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
|
||||
color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL;
|
||||
totalWeight += dotNL;
|
||||
|
||||
}
|
||||
}
|
||||
return (color / totalWeight);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize(vary_dir);
|
||||
frag_color = vec4(prefilterEnvMap(N, roughness), 1.0);
|
||||
}
|
||||
// =============================================================================================================
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* @file radianceGenV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, 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 mat4 modelview_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
VARYING vec3 vary_dir;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 1.0);
|
||||
|
||||
vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
|
||||
}
|
||||
|
||||
|
|
@ -473,4 +473,5 @@ void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 no
|
|||
fresnel = min(fresnel+envIntensity, 1.0);
|
||||
reflected_color *= (envIntensity*fresnel)*brighten(spec.rgb);
|
||||
color = mix(color.rgb, reflected_color, envIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,5 +195,5 @@ void main()
|
|||
// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, 1.0);
|
||||
frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog
|
||||
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS); // 1.0 in norm.w masks off fog
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ void main()
|
|||
color = mix(color.rgb, reflected_color, envIntensity);
|
||||
}
|
||||
|
||||
if (norm.w < 0.5)
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
|
||||
{
|
||||
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
|
||||
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
|
||||
|
|
|
|||
|
|
@ -446,10 +446,10 @@ void main()
|
|||
|
||||
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
|
||||
|
||||
// deferred path
|
||||
frag_data[0] = final_color; //gbuffer is sRGB
|
||||
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
|
||||
frag_data[0] = final_color; // gbuffer is sRGB
|
||||
frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
|
||||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
|
||||
|
||||
uniform samplerCubeArray reflectionProbes;
|
||||
uniform samplerCubeArray irradianceProbes;
|
||||
|
||||
layout (std140, binding = 1) uniform ReflectionProbes
|
||||
{
|
||||
|
|
@ -308,7 +309,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i)
|
|||
|
||||
|
||||
|
||||
// Tap a sphere based reflection probe
|
||||
// Tap a reflection probe
|
||||
// pos - position of pixel
|
||||
// dir - pixel normal
|
||||
// lod - which mip to bias towards (lower is higher res, sharper reflections)
|
||||
|
|
@ -334,9 +335,36 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i)
|
|||
v -= c;
|
||||
v = env_mat * v;
|
||||
{
|
||||
float min_lod = textureQueryLod(reflectionProbes,v).y; // lower is higher res
|
||||
return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), max(min_lod, lod)).rgb;
|
||||
//return texture(reflectionProbes, vec4(v.xyz, refIndex[i].x)).rgb;
|
||||
return textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod).rgb;
|
||||
}
|
||||
}
|
||||
|
||||
// Tap an irradiance map
|
||||
// pos - position of pixel
|
||||
// dir - pixel normal
|
||||
// c - center of probe
|
||||
// r2 - radius of probe squared
|
||||
// i - index of probe
|
||||
// vi - point at which reflection vector struck the influence volume, in clip space
|
||||
vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i)
|
||||
{
|
||||
//lod = max(lod, 1);
|
||||
// parallax adjustment
|
||||
|
||||
vec3 v;
|
||||
if (refIndex[i].w < 0)
|
||||
{
|
||||
v = boxIntersect(pos, dir, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
v = sphereIntersect(pos, dir, c, r2);
|
||||
}
|
||||
|
||||
v -= c;
|
||||
v = env_mat * v;
|
||||
{
|
||||
return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +377,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
|
|||
for (int idx = 0; idx < probeInfluences; ++idx)
|
||||
{
|
||||
int i = probeIndex[idx];
|
||||
if (refIndex[i].w < max_priority)
|
||||
if (abs(refIndex[i].w) < max_priority)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -370,7 +398,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
|
|||
float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);
|
||||
w *= atten;
|
||||
//w *= p; // boost weight based on priority
|
||||
col += refcol*w*max(minweight, refParams[i].x);
|
||||
col += refcol*w;
|
||||
|
||||
wsum += w;
|
||||
}
|
||||
|
|
@ -393,7 +421,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
|
|||
|
||||
float w = 1.0/d2;
|
||||
w *= w;
|
||||
col += refcol*w*max(minweight, refParams[i].x);
|
||||
col += refcol*w;
|
||||
wsum += w;
|
||||
}
|
||||
}
|
||||
|
|
@ -407,24 +435,75 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
|
|||
return col;
|
||||
}
|
||||
|
||||
vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod)
|
||||
vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
|
||||
{
|
||||
vec3 col = sampleProbes(pos, dir, lod, 0.f);
|
||||
// modified copy/paste of sampleProbes follows, will likely diverge from sampleProbes further
|
||||
// as irradiance map mixing is tuned independently of radiance map mixing
|
||||
float wsum = 0.0;
|
||||
vec3 col = vec3(0,0,0);
|
||||
float vd2 = dot(pos,pos); // view distance squared
|
||||
|
||||
//desaturate
|
||||
vec3 hcol = col *0.5;
|
||||
|
||||
col *= 2.0;
|
||||
col = vec3(
|
||||
col.r + hcol.g + hcol.b,
|
||||
col.g + hcol.r + hcol.b,
|
||||
col.b + hcol.r + hcol.g
|
||||
);
|
||||
|
||||
col *= 0.333333;
|
||||
float minweight = 1.0;
|
||||
|
||||
for (int idx = 0; idx < probeInfluences; ++idx)
|
||||
{
|
||||
int i = probeIndex[idx];
|
||||
if (abs(refIndex[i].w) < max_priority)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float r = refSphere[i].w; // radius of sphere volume
|
||||
float p = float(abs(refIndex[i].w)); // priority
|
||||
|
||||
float rr = r*r; // radius squred
|
||||
float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
|
||||
vec3 delta = pos.xyz-refSphere[i].xyz;
|
||||
float d2 = dot(delta,delta);
|
||||
float r2 = r1*r1;
|
||||
|
||||
{
|
||||
vec3 refcol = tapIrradianceMap(pos, dir, refSphere[i].xyz, rr, i);
|
||||
|
||||
float w = 1.0/d2;
|
||||
|
||||
float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);
|
||||
w *= atten;
|
||||
//w *= p; // boost weight based on priority
|
||||
col += refcol*w;
|
||||
|
||||
wsum += w;
|
||||
}
|
||||
}
|
||||
|
||||
if (probeInfluences <= 1)
|
||||
{ //edge-of-scene probe or no probe influence, mix in with embiggened version of probes closest to camera
|
||||
for (int idx = 0; idx < 8; ++idx)
|
||||
{
|
||||
if (refIndex[idx].w < 0)
|
||||
{ // don't fallback to box probes, they are *very* specific
|
||||
continue;
|
||||
}
|
||||
int i = idx;
|
||||
vec3 delta = pos.xyz-refSphere[i].xyz;
|
||||
float d2 = dot(delta,delta);
|
||||
|
||||
{
|
||||
vec3 refcol = tapIrradianceMap(pos, dir, refSphere[i].xyz, d2, i);
|
||||
|
||||
float w = 1.0/d2;
|
||||
w *= w;
|
||||
col += refcol*w;
|
||||
wsum += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wsum > 0.0)
|
||||
{
|
||||
col *= 1.0/wsum;
|
||||
}
|
||||
|
||||
return col;
|
||||
|
||||
}
|
||||
|
||||
// brighten a color so that at least one component is 1
|
||||
|
|
@ -450,7 +529,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l
|
|||
|
||||
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
|
||||
|
||||
ambenv = sampleProbeAmbient(pos, norm, reflection_lods-1);
|
||||
ambenv = sampleProbeAmbient(pos, norm);
|
||||
|
||||
if (glossiness > 0.0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file class2/deferred/softenLightF.glsl
|
||||
* @file class3/deferred/softenLightF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
@ -23,6 +23,31 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#define DEBUG_PBR_PACKORM0 0 // Rough=0, Metal=0
|
||||
#define DEBUG_PBR_PACKORM1 0 // Rough=1, Metal=1
|
||||
#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0
|
||||
|
||||
#define DEBUG_PBR_RAW_DIFF 0 // Output: use diffuse in G-Buffer
|
||||
#define DEBUG_PBR_RAW_SPEC 0 // Output: use spec in G-Buffer
|
||||
#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance
|
||||
#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian
|
||||
#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal
|
||||
#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughenss
|
||||
#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness
|
||||
#define DEBUG_PBR_METAL 0 // Output: grayscale metal
|
||||
#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance
|
||||
#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input)
|
||||
#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output)
|
||||
#define DEBUG_PBR_SPEC 0 // Output: Final spec
|
||||
#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: reflection
|
||||
#define DEBUG_PBR_NORMAL 0 // Output: passed in normal. To see raw normal map: set DEBUG_PBR_RAW_DIFF 1, and in pbropaqueF set DEBUG_NORMAL_RAW
|
||||
#define DEBUG_PBR_VIEW 0 // Output: view_dir
|
||||
#define DEBUG_PBR_BRDF 0 // Output: Environment BRDF
|
||||
#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal,ViewDir)
|
||||
#define DEBUG_PBR_DOT_TV 0 // Output:
|
||||
#define DEBUG_PBR_DOT_BV 0 // Output:
|
||||
#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
|
|
@ -85,6 +110,34 @@ vec3 srgb_to_linear(vec3 c);
|
|||
vec4 applyWaterFogView(vec3 pos, vec4 color);
|
||||
#endif
|
||||
|
||||
uniform vec3 view_dir; // PBR
|
||||
|
||||
#define getDiffuseLightPBR(n) ambenv
|
||||
#define getSpecularPBR(reflection) glossenv
|
||||
|
||||
// Approximate Environment BRDF
|
||||
vec2 getGGXApprox( vec2 uv )
|
||||
{
|
||||
vec2 st = vec2(1.) - uv;
|
||||
float d = (st.x * st.x * 0.5) * (st.y * st.y);
|
||||
float scale = 1.0 - d;
|
||||
float bias = d;
|
||||
return vec2( scale, bias );
|
||||
}
|
||||
|
||||
vec2 getGGX( vec2 brdfPoint )
|
||||
{
|
||||
// TODO: use GGXLUT
|
||||
// texture2D(GGXLUT, brdfPoint).rg;
|
||||
return getGGXApprox( brdfPoint);
|
||||
}
|
||||
|
||||
vec3 calcBaseReflect0(float ior)
|
||||
{
|
||||
vec3 reflect0 = vec3(pow((ior - 1.0) / (ior + 1.0), 2.0));
|
||||
return reflect0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
|
|
@ -131,6 +184,142 @@ void main()
|
|||
vec3 legacyenv;
|
||||
sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
|
||||
|
||||
bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR);
|
||||
if (hasPBR)
|
||||
{
|
||||
vec3 colorDiffuse = vec3(0);
|
||||
vec3 colorEmissive = vec3(0);
|
||||
vec3 colorSpec = vec3(0);
|
||||
// vec3 colorClearCoat = vec3(0);
|
||||
// vec3 colorSheen = vec3(0);
|
||||
// vec3 colorTransmission = vec3(0);
|
||||
|
||||
vec3 packedORM = spec.rgb; // Packed: Occlusion Roughness Metal
|
||||
#if DEBUG_PBR_PACK_ORM0
|
||||
packedORM = vec3(0,0,0);
|
||||
#endif
|
||||
#if DEBUG_PBR_PACK_ORM1
|
||||
packedORM = vec3(1,1,1);
|
||||
#endif
|
||||
float IOR = 1.5; // default Index Of Reflection 1.5
|
||||
vec3 reflect0 = vec3(0.04); // -> incidence reflectance 0.04
|
||||
|
||||
IOR = 0.0; // TODO: Set from glb
|
||||
reflect0 = calcBaseReflect0(IOR);
|
||||
|
||||
float metal = packedORM.b;
|
||||
vec3 reflect90 = vec3(0);
|
||||
vec3 v = view_dir;
|
||||
vec3 n = norm.xyz;
|
||||
// vec3 t = texture2DRect(tangentMap, tc).rgb;
|
||||
#if DEBUG_PBR_TANGENT1
|
||||
vec3 t = vec3(1,0,0);
|
||||
#endif
|
||||
vec3 b = cross( n,t);
|
||||
vec3 reflectVN = normalize(reflect(-v,n));
|
||||
|
||||
float dotNV = clamp(dot(n,v),0,1);
|
||||
float dotTV = clamp(dot(n,t),0,1);
|
||||
float dotBV = clamp(dot(n,b),0,1);
|
||||
|
||||
// Reference: getMetallicRoughnessInfo
|
||||
float perceptualRough = packedORM.g;
|
||||
float alphaRough = perceptualRough * perceptualRough;
|
||||
vec3 colorDiff = mix( diffuse.rgb, vec3(0) , metal);
|
||||
reflect0 = mix( reflect0 , diffuse.rgb, metal); // reflect at 0 degrees
|
||||
reflect90 = vec3(1); // reflect at 90 degrees
|
||||
float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b );
|
||||
|
||||
// Common to RadianceGGX and RadianceLambertian
|
||||
float specWeight = 1.0;
|
||||
vec2 brdfPoint = clamp(vec2(dotNV, perceptualRough), vec2(0,0), vec2(1,1));
|
||||
vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0
|
||||
vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel
|
||||
vec3 kSpec = reflect0 + fresnelR*pow(1.0 - dotNV, 5.0);
|
||||
|
||||
// Reference: getIBLRadianceGGX
|
||||
vec3 specLight = getSpecularPBR(reflection);
|
||||
#if HAS_IBL
|
||||
kSpec = mix( kSpec, iridescenceFresnel, iridescenceFactor);
|
||||
#endif
|
||||
vec3 FssEssRadiance = kSpec*vScaleBias.x + vScaleBias.y;
|
||||
colorSpec += specWeight * specLight * FssEssRadiance;
|
||||
|
||||
// Reference: getIBLRadianceLambertian
|
||||
vec3 irradiance = getDiffuseLightPBR(n);
|
||||
vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term
|
||||
float Ems = (1.0 - vScaleBias.x + vScaleBias.y);
|
||||
vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0);
|
||||
vec3 AvgEms = avg * Ems;
|
||||
vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms);
|
||||
vec3 kDiffuse = colorDiffuse * (1.0 - FssEssLambert + FmsEms);
|
||||
colorDiffuse += (FmsEms + kDiffuse) * irradiance;
|
||||
|
||||
color.rgb = colorDiffuse + colorEmissive + colorSpec;
|
||||
|
||||
#if DEBUG_PBR_BRDF_UV
|
||||
color.rgb = vec3(brdfPoint,0.0);
|
||||
#endif
|
||||
#if DEBUG_PBR_BRDF_SCALE_BIAS
|
||||
color.rgb = vec3(vScaleBias,0.0);
|
||||
#endif
|
||||
#if DEBUG_PBR_FRESNEL
|
||||
color.rgb = fresnelR;
|
||||
#endif
|
||||
#if DEBUG_PBR_RAW_DIFF
|
||||
color.rgb = diffuse.rgb;
|
||||
#endif
|
||||
#if DEBUG_PBR_RAW_SPEC
|
||||
color.rgb = spec.rgb;
|
||||
#endif
|
||||
#if DEBUG_PBR_REFLECTANCE
|
||||
color.rgb = vec3(reflectance);
|
||||
#endif
|
||||
#if DEBUG_PBR_IRRADIANCE
|
||||
color.rgb = irradiance;
|
||||
#endif
|
||||
#if DEBUG_PBR_DIFFUSE
|
||||
color.rgb = colorDiffuse;
|
||||
#endif
|
||||
#if DEBUG_PBR_EMISSIVE
|
||||
color.rgb = colorEmissive;
|
||||
#endif
|
||||
#if DEBUG_PBR_METAL
|
||||
color.rgb = vec3(metal);
|
||||
#endif
|
||||
#if DEBUG_PBR_ROUGH_PERCEPTUAL
|
||||
color.rgb = vec3(perceptualRough);
|
||||
#endif
|
||||
#if DEBUG_PBR_ROUGH_ALPHA
|
||||
color.rgb = vec3(alphaRough);
|
||||
#endif
|
||||
#if DEBUG_PBR_SPEC
|
||||
color.rgb = colorSpec;
|
||||
#endif
|
||||
#if DEBUG_PBR_SPEC_REFLECTION
|
||||
color.rgb = specLight;
|
||||
#endif
|
||||
#if DEBUG_PBR_ORM
|
||||
color.rgb = packedORM;
|
||||
#endif
|
||||
#if DEBUG_PBR_NORMAL
|
||||
color.rgb = norm.xyz;
|
||||
#endif
|
||||
#if DEBUG_PBR_VIEW
|
||||
color.rgb = view_dir;
|
||||
#endif
|
||||
#if DEBUG_PBR_DOT_NV
|
||||
color.rgb = vec3(dotNV);
|
||||
#endif
|
||||
#if DEBUG_PBR_DOT_TV
|
||||
color.rgb = vec3(dotTV);
|
||||
#endif
|
||||
#if DEBUG_PBR_DOT_BV
|
||||
color.rgb = vec3(dotBV);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
amblit = max(ambenv, amblit);
|
||||
color.rgb = amblit*ambocc;
|
||||
|
||||
|
|
@ -170,7 +359,7 @@ void main()
|
|||
applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
|
||||
}
|
||||
|
||||
if (norm.w < 0.5)
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
|
||||
{
|
||||
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
|
||||
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
|
||||
|
|
@ -181,7 +370,7 @@ void main()
|
|||
color = fogged.rgb;
|
||||
bloom = fogged.a;
|
||||
#endif
|
||||
|
||||
}
|
||||
// convert to linear as fullscreen lights need to sum in linear colorspace
|
||||
// and will be gamma (re)corrected downstream...
|
||||
//color = vec3(ambocc);
|
||||
|
|
|
|||
|
|
@ -719,3 +719,55 @@ 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.
|
||||
|
||||
|
||||
============
|
||||
tinygltf
|
||||
============
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
|
||||
|
||||
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.
|
||||
|
||||
==============
|
||||
Vulkan GLTF
|
||||
==============
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Sascha Willems
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -796,3 +796,52 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||
SOFTWARE.
|
||||
|
||||
|
||||
============
|
||||
tinygltf
|
||||
============
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
|
||||
|
||||
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.
|
||||
|
||||
==============
|
||||
Vulkan GLTF
|
||||
==============
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Sascha Willems
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public:
|
|||
enum
|
||||
{
|
||||
// Correspond to LLPipeline render type
|
||||
// NOTE: Keep in sync with gPoolNames
|
||||
POOL_SIMPLE = 1,
|
||||
POOL_GROUND,
|
||||
POOL_FULLBRIGHT,
|
||||
|
|
@ -130,6 +131,7 @@ class LLRenderPass : public LLDrawPool
|
|||
public:
|
||||
// list of possible LLRenderPass types to assign a render batch to
|
||||
// NOTE: "rigged" variant MUST be non-rigged variant + 1
|
||||
// see LLVolumeGeometryManager::registerFace()
|
||||
enum
|
||||
{
|
||||
PASS_SIMPLE = NUM_POOL_TYPES,
|
||||
|
|
@ -191,6 +193,8 @@ public:
|
|||
PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
|
||||
PASS_ALPHA_INVISIBLE,
|
||||
PASS_ALPHA_INVISIBLE_RIGGED,
|
||||
PASS_PBR_OPAQUE,
|
||||
PASS_PBR_OPAQUE_RIGGED,
|
||||
NUM_RENDER_TYPES,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,12 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass)
|
|||
return;
|
||||
}
|
||||
|
||||
const U32 type = LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE;
|
||||
if (!gPipeline.hasRenderType(type))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gGL.flush();
|
||||
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
|
|
@ -86,7 +92,55 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass)
|
|||
|
||||
// TODO: handle under water?
|
||||
// if (LLPipeline::sUnderWaterRender)
|
||||
// PASS_SIMPLE or PASS_MATERIAL
|
||||
//pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
}
|
||||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
//gGL.getTexUnit(0)->activate();
|
||||
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(0)->bindFast(params.mTexture); // diffuse
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep);
|
||||
}
|
||||
|
||||
if (params.mNormalMap)
|
||||
{
|
||||
gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: bind default normal map (???? WTF is it ???)
|
||||
}
|
||||
|
||||
if (params.mSpecularMap)
|
||||
{
|
||||
gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); // Packed Occlusion Roughness Metal
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
|
||||
}
|
||||
|
||||
if (params.mEmissiveMap)
|
||||
{
|
||||
gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::EMISSIVE_MAP, params.mEmissiveMap); // Packed Occlusion Roughness Metal
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredPBROpaqueProgram.bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep);
|
||||
}
|
||||
|
||||
gDeferredPBROpaqueProgram.uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor);
|
||||
gDeferredPBROpaqueProgram.uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor);
|
||||
gDeferredPBROpaqueProgram.uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV);
|
||||
|
||||
LLRenderPass::pushBatch(params, getVertexDataMask(), FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,11 +34,15 @@ class LLDrawPoolPBROpaque : public LLRenderPass
|
|||
public:
|
||||
enum
|
||||
{
|
||||
VERTEX_DATA_MASK = 0
|
||||
| LLVertexBuffer::MAP_VERTEX
|
||||
| LLVertexBuffer::MAP_NORMAL
|
||||
| LLVertexBuffer::MAP_TEXCOORD0
|
||||
| LLVertexBuffer::MAP_COLOR
|
||||
// See: DEFERRED_VB_MASK
|
||||
VERTEX_DATA_MASK = 0
|
||||
| LLVertexBuffer::MAP_VERTEX
|
||||
| LLVertexBuffer::MAP_NORMAL
|
||||
| LLVertexBuffer::MAP_TEXCOORD0 // Diffuse
|
||||
| LLVertexBuffer::MAP_TEXCOORD1 // Normal
|
||||
| LLVertexBuffer::MAP_TEXCOORD2 // Spec <-- ORM Occlusion Roughness Metal
|
||||
| LLVertexBuffer::MAP_TANGENT
|
||||
| LLVertexBuffer::MAP_COLOR
|
||||
};
|
||||
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1476,6 +1476,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
LLColor4U color = (tep ? tep->getColor() : LLColor4());
|
||||
// </FS:ND>
|
||||
|
||||
if (tep->getGLTFMaterial())
|
||||
{
|
||||
color = tep->getGLTFMaterial()->mAlbedoColor;
|
||||
}
|
||||
|
||||
if (rebuild_color)
|
||||
{ //decide if shiny goes in alpha channel of color
|
||||
if (tep &&
|
||||
|
|
@ -1893,10 +1898,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
// LLMaterial* mat = tep->getMaterialParams().get();
|
||||
LLMaterial* mat = tep ? tep->getMaterialParams().get() : 0;
|
||||
// </FS:ND>
|
||||
LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial();
|
||||
|
||||
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
|
||||
|
||||
if (mat && !do_bump)
|
||||
if ((mat || gltf_mat) && !do_bump)
|
||||
{
|
||||
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|
||||
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
|
||||
|
|
@ -2129,10 +2135,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
mVertexBuffer->flush();
|
||||
}
|
||||
|
||||
if (!mat && do_bump)
|
||||
if ((!mat && !gltf_mat) && do_bump)
|
||||
{
|
||||
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
|
||||
|
||||
mVObjp->getVolume()->genTangents(f);
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector4a tangent = vf.mTangents[i];
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ LLFilePicker LLFilePicker::sInstance;
|
|||
#define XML_FILTER L"XML files (*.xml)\0*.xml\0"
|
||||
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
|
||||
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
|
||||
#define MODEL_FILTER L"Model files (*.dae; *.gltf; *.glb)\0*.dae;*.gltf;*.glb\0"
|
||||
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
|
||||
#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0"
|
||||
#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
|
||||
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
|
||||
// <FS:CR> Import filter
|
||||
|
|
@ -235,6 +236,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
|
|||
mOFN.lpstrFilter = MODEL_FILTER \
|
||||
L"\0";
|
||||
break;
|
||||
case FFLOAD_MATERIAL:
|
||||
mOFN.lpstrFilter = MATERIAL_FILTER \
|
||||
L"\0";
|
||||
break;
|
||||
case FFLOAD_SCRIPT:
|
||||
mOFN.lpstrFilter = SCRIPT_FILTER \
|
||||
L"\0";
|
||||
|
|
|
|||
|
|
@ -92,9 +92,9 @@ public:
|
|||
FFLOAD_COLLADA = 10,
|
||||
FFLOAD_SCRIPT = 11,
|
||||
FFLOAD_DICTIONARY = 12,
|
||||
FFLOAD_DIRECTORY = 13, //To call from lldirpicker.
|
||||
FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
|
||||
|
||||
FFLOAD_DIRECTORY = 13, // To call from lldirpicker.
|
||||
FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
|
||||
FFLOAD_MATERIAL = 15,
|
||||
// Firestorm additions
|
||||
FFLOAD_IMPORT = 50
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4420,6 +4420,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
disabled_items.push_back(std::string("New Note"));
|
||||
disabled_items.push_back(std::string("New Settings"));
|
||||
disabled_items.push_back(std::string("New Gesture"));
|
||||
disabled_items.push_back(std::string("New Material"));
|
||||
disabled_items.push_back(std::string("New Clothes"));
|
||||
disabled_items.push_back(std::string("New Body Parts"));
|
||||
disabled_items.push_back(std::string("upload_def"));
|
||||
|
|
@ -4447,6 +4448,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
disabled_items.push_back(std::string("New Script"));
|
||||
disabled_items.push_back(std::string("New Note"));
|
||||
disabled_items.push_back(std::string("New Gesture"));
|
||||
disabled_items.push_back(std::string("New Material"));
|
||||
disabled_items.push_back(std::string("New Clothes"));
|
||||
disabled_items.push_back(std::string("New Body Parts"));
|
||||
disabled_items.push_back(std::string("upload_def"));
|
||||
|
|
@ -4518,6 +4520,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
items.push_back(std::string("New Script"));
|
||||
items.push_back(std::string("New Note"));
|
||||
items.push_back(std::string("New Gesture"));
|
||||
items.push_back(std::string("New Material"));
|
||||
items.push_back(std::string("New Clothes"));
|
||||
items.push_back(std::string("New Body Parts"));
|
||||
items.push_back(std::string("New Settings"));
|
||||
|
|
|
|||
|
|
@ -1389,6 +1389,18 @@ const std::string& LLInventoryFilter::getFilterText()
|
|||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_MATERIAL))
|
||||
{
|
||||
filtered_types += LLTrans::getString("Materials");
|
||||
filtered_by_type = TRUE;
|
||||
num_filter_types++;
|
||||
}
|
||||
else
|
||||
{
|
||||
not_filtered_types += LLTrans::getString("Materials");
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
|
||||
{
|
||||
filtered_types += LLTrans::getString("Notecards");
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ LLIconDictionary::LLIconDictionary()
|
|||
addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay"));
|
||||
addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings"));
|
||||
|
||||
addEntry(LLInventoryType::ICONNAME_MATERIAL, new IconEntry("Inv_Material"));
|
||||
|
||||
addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
|
||||
addEntry(LLInventoryType::ICONNAME_UNKNOWN, new IconEntry("Inv_Unknown"));
|
||||
|
||||
|
|
@ -178,9 +180,12 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
|
|||
case LLAssetType::AT_MESH:
|
||||
idx = LLInventoryType::ICONNAME_MESH;
|
||||
break;
|
||||
case LLAssetType::AT_SETTINGS:
|
||||
idx = assignSettingsIcon(misc_flag);
|
||||
break;
|
||||
case LLAssetType::AT_SETTINGS:
|
||||
idx = assignSettingsIcon(misc_flag);
|
||||
break;
|
||||
case LLAssetType::AT_MATERIAL:
|
||||
idx = LLInventoryType::ICONNAME_MATERIAL;
|
||||
break;
|
||||
case LLAssetType::AT_UNKNOWN:
|
||||
idx = LLInventoryType::ICONNAME_UNKNOWN;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,810 @@
|
|||
/**
|
||||
* @file llmaterialeditor.cpp
|
||||
* @brief Implementation of the notecard editor
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llmaterialeditor.h"
|
||||
|
||||
#include "llappviewer.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewermenufile.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llvovolume.h"
|
||||
|
||||
#include "tinygltf/tiny_gltf.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLPreviewNotecard
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// Default constructor
|
||||
LLMaterialEditor::LLMaterialEditor(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
, mHasUnsavedChanges(false)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLMaterialEditor::postBuild()
|
||||
{
|
||||
mAlbedoTextureCtrl = getChild<LLTextureCtrl>("albedo_texture");
|
||||
mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture");
|
||||
mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture");
|
||||
mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture");
|
||||
|
||||
mAlbedoTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitAlbedoTexture, this, _1, _2));
|
||||
mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2));
|
||||
mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2));
|
||||
mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2));
|
||||
|
||||
childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this));
|
||||
childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this));
|
||||
childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this));
|
||||
|
||||
boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void*) { setHasUnsavedChanges(true); };
|
||||
|
||||
childSetCommitCallback("double sided", changes_callback, NULL);
|
||||
|
||||
// Albedo
|
||||
childSetCommitCallback("albedo color", changes_callback, NULL);
|
||||
childSetCommitCallback("transparency", changes_callback, NULL);
|
||||
childSetCommitCallback("alpha mode", changes_callback, NULL);
|
||||
childSetCommitCallback("alpha cutoff", changes_callback, NULL);
|
||||
|
||||
// Metallic-Roughness
|
||||
childSetCommitCallback("metalness factor", changes_callback, NULL);
|
||||
childSetCommitCallback("roughness factor", changes_callback, NULL);
|
||||
|
||||
// Metallic-Roughness
|
||||
childSetCommitCallback("metalness factor", changes_callback, NULL);
|
||||
childSetCommitCallback("roughness factor", changes_callback, NULL);
|
||||
|
||||
// Emissive
|
||||
childSetCommitCallback("emissive color", changes_callback, NULL);
|
||||
|
||||
childSetVisible("unsaved_changes", mHasUnsavedChanges);
|
||||
|
||||
return LLFloater::postBuild();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onClickCloseBtn(bool app_quitting)
|
||||
{
|
||||
if (app_quitting)
|
||||
{
|
||||
closeFloater(app_quitting);
|
||||
}
|
||||
else
|
||||
{
|
||||
onClickCancel();
|
||||
}
|
||||
}
|
||||
|
||||
LLUUID LLMaterialEditor::getAlbedoId()
|
||||
{
|
||||
return mAlbedoTextureCtrl->getValue().asUUID();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setAlbedoId(const LLUUID& id)
|
||||
{
|
||||
mAlbedoTextureCtrl->setValue(id);
|
||||
mAlbedoTextureCtrl->setDefaultImageAssetID(id);
|
||||
|
||||
if (id.notNull())
|
||||
{
|
||||
// todo: this does not account for posibility of texture
|
||||
// being from inventory, need to check that
|
||||
childSetValue("albedo_upload_fee", getString("upload_fee_string"));
|
||||
// Only set if we will need to upload this texture
|
||||
mAlbedoTextureUploadId = id;
|
||||
}
|
||||
}
|
||||
|
||||
LLColor4 LLMaterialEditor::getAlbedoColor()
|
||||
{
|
||||
LLColor4 ret = LLColor4(childGetValue("albedo color"));
|
||||
ret.mV[3] = getTransparency();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setAlbedoColor(const LLColor4& color)
|
||||
{
|
||||
childSetValue("albedo color", color.getValue());
|
||||
childSetValue("transparency", color.mV[3]);
|
||||
}
|
||||
|
||||
F32 LLMaterialEditor::getTransparency()
|
||||
{
|
||||
return childGetValue("transparency").asReal();
|
||||
}
|
||||
|
||||
std::string LLMaterialEditor::getAlphaMode()
|
||||
{
|
||||
return childGetValue("alpha mode").asString();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setAlphaMode(const std::string& alpha_mode)
|
||||
{
|
||||
childSetValue("alpha mode", alpha_mode);
|
||||
}
|
||||
|
||||
F32 LLMaterialEditor::getAlphaCutoff()
|
||||
{
|
||||
return childGetValue("alpha cutoff").asReal();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff)
|
||||
{
|
||||
childSetValue("alpha cutoff", alpha_cutoff);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setMaterialName(const std::string &name)
|
||||
{
|
||||
setTitle(name);
|
||||
mMaterialName = name;
|
||||
}
|
||||
|
||||
LLUUID LLMaterialEditor::getMetallicRoughnessId()
|
||||
{
|
||||
return mMetallicTextureCtrl->getValue().asUUID();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id)
|
||||
{
|
||||
mMetallicTextureCtrl->setValue(id);
|
||||
mMetallicTextureCtrl->setDefaultImageAssetID(id);
|
||||
|
||||
if (id.notNull())
|
||||
{
|
||||
// todo: this does not account for posibility of texture
|
||||
// being from inventory, need to check that
|
||||
childSetValue("metallic_upload_fee", getString("upload_fee_string"));
|
||||
mMetallicTextureUploadId = id;
|
||||
}
|
||||
}
|
||||
|
||||
F32 LLMaterialEditor::getMetalnessFactor()
|
||||
{
|
||||
return childGetValue("metalness factor").asReal();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setMetalnessFactor(F32 factor)
|
||||
{
|
||||
childSetValue("metalness factor", factor);
|
||||
}
|
||||
|
||||
F32 LLMaterialEditor::getRoughnessFactor()
|
||||
{
|
||||
return childGetValue("roughness factor").asReal();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setRoughnessFactor(F32 factor)
|
||||
{
|
||||
childSetValue("roughness factor", factor);
|
||||
}
|
||||
|
||||
LLUUID LLMaterialEditor::getEmissiveId()
|
||||
{
|
||||
return mEmissiveTextureCtrl->getValue().asUUID();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setEmissiveId(const LLUUID& id)
|
||||
{
|
||||
mEmissiveTextureCtrl->setValue(id);
|
||||
mEmissiveTextureCtrl->setDefaultImageAssetID(id);
|
||||
|
||||
if (id.notNull())
|
||||
{
|
||||
// todo: this does not account for posibility of texture
|
||||
// being from inventory, need to check that
|
||||
childSetValue("emissive_upload_fee", getString("upload_fee_string"));
|
||||
mEmissiveTextureUploadId = id;
|
||||
}
|
||||
}
|
||||
|
||||
LLColor4 LLMaterialEditor::getEmissiveColor()
|
||||
{
|
||||
return LLColor4(childGetValue("emissive color"));
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setEmissiveColor(const LLColor4& color)
|
||||
{
|
||||
childSetValue("emissive color", color.getValue());
|
||||
}
|
||||
|
||||
LLUUID LLMaterialEditor::getNormalId()
|
||||
{
|
||||
return mNormalTextureCtrl->getValue().asUUID();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setNormalId(const LLUUID& id)
|
||||
{
|
||||
mNormalTextureCtrl->setValue(id);
|
||||
mNormalTextureCtrl->setDefaultImageAssetID(id);
|
||||
|
||||
if (id.notNull())
|
||||
{
|
||||
// todo: this does not account for posibility of texture
|
||||
// being from inventory, need to check that
|
||||
childSetValue("normal_upload_fee", getString("upload_fee_string"));
|
||||
mNormalTextureUploadId = id;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLMaterialEditor::getDoubleSided()
|
||||
{
|
||||
return childGetValue("double sided").asBoolean();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setDoubleSided(bool double_sided)
|
||||
{
|
||||
childSetValue("double sided", double_sided);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::setHasUnsavedChanges(bool value)
|
||||
{
|
||||
if (value != mHasUnsavedChanges)
|
||||
{
|
||||
mHasUnsavedChanges = value;
|
||||
childSetVisible("unsaved_changes", value);
|
||||
}
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data)
|
||||
{
|
||||
// might be better to use arrays, to have a single callback
|
||||
// and not to repeat the same thing for each tecture control
|
||||
LLUUID new_val = mAlbedoTextureCtrl->getValue().asUUID();
|
||||
if (new_val == mAlbedoTextureUploadId && mAlbedoTextureUploadId.notNull())
|
||||
{
|
||||
childSetValue("albedo_upload_fee", getString("upload_fee_string"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("albedo_upload_fee", getString("no_upload_fee_string"));
|
||||
}
|
||||
setHasUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data)
|
||||
{
|
||||
LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID();
|
||||
if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull())
|
||||
{
|
||||
childSetValue("metallic_upload_fee", getString("upload_fee_string"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("metallic_upload_fee", getString("no_upload_fee_string"));
|
||||
}
|
||||
setHasUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data)
|
||||
{
|
||||
LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID();
|
||||
if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull())
|
||||
{
|
||||
childSetValue("emissive_upload_fee", getString("upload_fee_string"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("emissive_upload_fee", getString("no_upload_fee_string"));
|
||||
}
|
||||
setHasUnsavedChanges(true);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data)
|
||||
{
|
||||
LLUUID new_val = mNormalTextureCtrl->getValue().asUUID();
|
||||
if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull())
|
||||
{
|
||||
childSetValue("normal_upload_fee", getString("upload_fee_string"));
|
||||
}
|
||||
else
|
||||
{
|
||||
childSetValue("normal_upload_fee", getString("no_upload_fee_string"));
|
||||
}
|
||||
setHasUnsavedChanges(true);
|
||||
}
|
||||
|
||||
|
||||
static void write_color(const LLColor4& color, std::vector<double>& c)
|
||||
{
|
||||
for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component
|
||||
{
|
||||
c[i] = color.mV[i];
|
||||
}
|
||||
}
|
||||
|
||||
static U32 write_texture(const LLUUID& id, tinygltf::Model& model)
|
||||
{
|
||||
tinygltf::Image image;
|
||||
image.uri = id.asString();
|
||||
model.images.push_back(image);
|
||||
U32 image_idx = model.images.size() - 1;
|
||||
|
||||
tinygltf::Texture texture;
|
||||
texture.source = image_idx;
|
||||
model.textures.push_back(texture);
|
||||
U32 texture_idx = model.textures.size() - 1;
|
||||
|
||||
return texture_idx;
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onClickSave()
|
||||
{
|
||||
applyToSelection();
|
||||
|
||||
tinygltf::Model model;
|
||||
model.materials.resize(1);
|
||||
tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness;
|
||||
|
||||
// write albedo
|
||||
LLColor4 albedo_color = getAlbedoColor();
|
||||
albedo_color.mV[3] = getTransparency();
|
||||
write_color(albedo_color, pbrMaterial.baseColorFactor);
|
||||
|
||||
model.materials[0].alphaCutoff = getAlphaCutoff();
|
||||
model.materials[0].alphaMode = getAlphaMode();
|
||||
|
||||
LLUUID albedo_id = getAlbedoId();
|
||||
|
||||
if (albedo_id.notNull())
|
||||
{
|
||||
U32 texture_idx = write_texture(albedo_id, model);
|
||||
|
||||
pbrMaterial.baseColorTexture.index = texture_idx;
|
||||
}
|
||||
|
||||
// write metallic/roughness
|
||||
F32 metalness = getMetalnessFactor();
|
||||
F32 roughness = getRoughnessFactor();
|
||||
|
||||
pbrMaterial.metallicFactor = metalness;
|
||||
pbrMaterial.roughnessFactor = roughness;
|
||||
|
||||
LLUUID mr_id = getMetallicRoughnessId();
|
||||
if (mr_id.notNull())
|
||||
{
|
||||
U32 texture_idx = write_texture(mr_id, model);
|
||||
pbrMaterial.metallicRoughnessTexture.index = texture_idx;
|
||||
}
|
||||
|
||||
//write emissive
|
||||
LLColor4 emissive_color = getEmissiveColor();
|
||||
model.materials[0].emissiveFactor.resize(3);
|
||||
write_color(emissive_color, model.materials[0].emissiveFactor);
|
||||
|
||||
LLUUID emissive_id = getEmissiveId();
|
||||
if (emissive_id.notNull())
|
||||
{
|
||||
U32 idx = write_texture(emissive_id, model);
|
||||
model.materials[0].emissiveTexture.index = idx;
|
||||
}
|
||||
|
||||
//write normal
|
||||
LLUUID normal_id = getNormalId();
|
||||
if (normal_id.notNull())
|
||||
{
|
||||
U32 idx = write_texture(normal_id, model);
|
||||
model.materials[0].normalTexture.index = idx;
|
||||
}
|
||||
|
||||
//write doublesided
|
||||
model.materials[0].doubleSided = getDoubleSided();
|
||||
|
||||
std::ostringstream str;
|
||||
|
||||
tinygltf::TinyGLTF gltf;
|
||||
model.asset.version = "2.0";
|
||||
gltf.WriteGltfSceneToStream(&model, str, true, false);
|
||||
|
||||
std::string dump = str.str();
|
||||
|
||||
LL_INFOS() << mMaterialName << ": " << dump << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onClickSaveAs()
|
||||
{
|
||||
LLSD args;
|
||||
args["DESC"] = mMaterialName;
|
||||
|
||||
LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2));
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (0 == option)
|
||||
{
|
||||
std::string new_name = response["message"].asString();
|
||||
LLStringUtil::trim(new_name);
|
||||
if (!new_name.empty())
|
||||
{
|
||||
setMaterialName(new_name);
|
||||
onClickSave();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("InvalidMaterialName");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onClickCancel()
|
||||
{
|
||||
if (mHasUnsavedChanges)
|
||||
{
|
||||
LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (0 == option)
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
class LLMaterialFilePicker : public LLFilePickerThread
|
||||
{
|
||||
public:
|
||||
LLMaterialFilePicker(LLMaterialEditor* me);
|
||||
virtual void notify(const std::vector<std::string>& filenames);
|
||||
void loadMaterial(const std::string& filename);
|
||||
static void textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata);
|
||||
private:
|
||||
LLMaterialEditor* mME;
|
||||
};
|
||||
|
||||
LLMaterialFilePicker::LLMaterialFilePicker(LLMaterialEditor* me)
|
||||
: LLFilePickerThread(LLFilePicker::FFLOAD_MATERIAL)
|
||||
{
|
||||
mME = me;
|
||||
}
|
||||
|
||||
void LLMaterialFilePicker::notify(const std::vector<std::string>& filenames)
|
||||
{
|
||||
if (LLAppViewer::instance()->quitRequested())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (filenames.size() > 0)
|
||||
{
|
||||
loadMaterial(filenames[0]);
|
||||
}
|
||||
}
|
||||
|
||||
const tinygltf::Image* get_image_from_texture_index(const tinygltf::Model& model, S32 texture_index)
|
||||
{
|
||||
if (texture_index >= 0)
|
||||
{
|
||||
S32 source_idx = model.textures[texture_index].source;
|
||||
if (source_idx >= 0)
|
||||
{
|
||||
return &(model.images[source_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static LLImageRaw* get_texture(const std::string& folder, const tinygltf::Model& model, S32 texture_index)
|
||||
{
|
||||
const tinygltf::Image* image = get_image_from_texture_index(model, texture_index);
|
||||
|
||||
LLImageRaw* rawImage = nullptr;
|
||||
|
||||
if (image != nullptr &&
|
||||
image->bits == 8 &&
|
||||
!image->image.empty() &&
|
||||
image->component <= 4)
|
||||
{
|
||||
rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
|
||||
rawImage->verticalFlip();
|
||||
}
|
||||
|
||||
return rawImage;
|
||||
}
|
||||
|
||||
static void strip_alpha_channel(LLPointer<LLImageRaw>& img)
|
||||
{
|
||||
if (img->getComponents() == 4)
|
||||
{
|
||||
LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3);
|
||||
tmp->copyUnscaled4onto3(img);
|
||||
img = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// copy red channel from src_img to dst_img
|
||||
// PRECONDITIONS:
|
||||
// dst_img must be 3 component
|
||||
// src_img and dst_image must have the same dimensions
|
||||
static void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
|
||||
{
|
||||
llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight());
|
||||
llassert(dst_img->getComponents() == 3);
|
||||
|
||||
U32 pixel_count = dst_img->getWidth() * dst_img->getHeight();
|
||||
U8* src = src_img->getData();
|
||||
U8* dst = dst_img->getData();
|
||||
S8 src_components = src_img->getComponents();
|
||||
|
||||
for (U32 i = 0; i < pixel_count; ++i)
|
||||
{
|
||||
dst[i * 3] = src[i * src_components];
|
||||
}
|
||||
}
|
||||
|
||||
static void pack_textures(tinygltf::Model& model, tinygltf::Material& material,
|
||||
LLPointer<LLImageRaw>& albedo_img,
|
||||
LLPointer<LLImageRaw>& normal_img,
|
||||
LLPointer<LLImageRaw>& mr_img,
|
||||
LLPointer<LLImageRaw>& emissive_img,
|
||||
LLPointer<LLImageRaw>& occlusion_img,
|
||||
LLPointer<LLViewerFetchedTexture>& albedo_tex,
|
||||
LLPointer<LLViewerFetchedTexture>& normal_tex,
|
||||
LLPointer<LLViewerFetchedTexture>& mr_tex,
|
||||
LLPointer<LLViewerFetchedTexture>& emissive_tex)
|
||||
{
|
||||
// TODO: downscale if needed
|
||||
if (albedo_img)
|
||||
{
|
||||
albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true);
|
||||
}
|
||||
|
||||
if (normal_img)
|
||||
{
|
||||
strip_alpha_channel(normal_img);
|
||||
normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true);
|
||||
}
|
||||
|
||||
if (mr_img)
|
||||
{
|
||||
strip_alpha_channel(mr_img);
|
||||
|
||||
if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index)
|
||||
{
|
||||
// occlusion is a distinct texture from pbrMetallicRoughness
|
||||
// pack into mr red channel
|
||||
int occlusion_idx = material.occlusionTexture.index;
|
||||
int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
|
||||
if (occlusion_idx != mr_idx)
|
||||
{
|
||||
//scale occlusion image to match resolution of mr image
|
||||
occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
|
||||
|
||||
copy_red_channel(occlusion_img, mr_img);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (occlusion_img)
|
||||
{
|
||||
//no mr but occlusion exists, make a white mr_img and copy occlusion red channel over
|
||||
mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3);
|
||||
mr_img->clear(255, 255, 255);
|
||||
copy_red_channel(occlusion_img, mr_img);
|
||||
|
||||
}
|
||||
|
||||
if (mr_img)
|
||||
{
|
||||
mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true);
|
||||
}
|
||||
|
||||
if (emissive_img)
|
||||
{
|
||||
strip_alpha_channel(emissive_img);
|
||||
emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true);
|
||||
}
|
||||
}
|
||||
|
||||
static LLColor4 get_color(const std::vector<double>& in)
|
||||
{
|
||||
LLColor4 out;
|
||||
for (S32 i = 0; i < llmin((S32) in.size(), 4); ++i)
|
||||
{
|
||||
out.mV[i] = in[i];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void LLMaterialFilePicker::textureLoadedCallback(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LLMaterialFilePicker::loadMaterial(const std::string& filename)
|
||||
{
|
||||
tinygltf::TinyGLTF loader;
|
||||
std::string error_msg;
|
||||
std::string warn_msg;
|
||||
|
||||
bool loaded = false;
|
||||
tinygltf::Model model_in;
|
||||
|
||||
std::string filename_lc = filename;
|
||||
LLStringUtil::toLower(filename_lc);
|
||||
|
||||
// Load a tinygltf model fom a file. Assumes that the input filename has already been
|
||||
// been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
|
||||
if (std::string::npos == filename_lc.rfind(".gltf"))
|
||||
{ // file is binary
|
||||
loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename);
|
||||
}
|
||||
else
|
||||
{ // file is ascii
|
||||
loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename);
|
||||
}
|
||||
|
||||
if (!loaded)
|
||||
{
|
||||
LLNotificationsUtil::add("CannotUploadMaterial");
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_in.materials.empty())
|
||||
{
|
||||
// materials are missing
|
||||
LLNotificationsUtil::add("CannotUploadMaterial");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string folder = gDirUtilp->getDirName(filename);
|
||||
|
||||
|
||||
tinygltf::Material material_in = model_in.materials[0];
|
||||
|
||||
tinygltf::Model model_out;
|
||||
model_out.asset.version = "2.0";
|
||||
model_out.materials.resize(1);
|
||||
|
||||
// get albedo texture
|
||||
LLPointer<LLImageRaw> albedo_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index);
|
||||
// get normal map
|
||||
LLPointer<LLImageRaw> normal_img = get_texture(folder, model_in, material_in.normalTexture.index);
|
||||
// get metallic-roughness texture
|
||||
LLPointer<LLImageRaw> mr_img = get_texture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index);
|
||||
// get emissive texture
|
||||
LLPointer<LLImageRaw> emissive_img = get_texture(folder, model_in, material_in.emissiveTexture.index);
|
||||
// get occlusion map if needed
|
||||
LLPointer<LLImageRaw> occlusion_img;
|
||||
if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
|
||||
{
|
||||
occlusion_img = get_texture(folder, model_in, material_in.occlusionTexture.index);
|
||||
}
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> albedo_tex;
|
||||
LLPointer<LLViewerFetchedTexture> normal_tex;
|
||||
LLPointer<LLViewerFetchedTexture> mr_tex;
|
||||
LLPointer<LLViewerFetchedTexture> emissive_tex;
|
||||
|
||||
pack_textures(model_in, material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img,
|
||||
albedo_tex, normal_tex, mr_tex, emissive_tex);
|
||||
|
||||
LLUUID albedo_id;
|
||||
if (albedo_tex != nullptr)
|
||||
{
|
||||
albedo_tex->forceToSaveRawImage(0, F32_MAX);
|
||||
albedo_id = albedo_tex->getID();
|
||||
}
|
||||
|
||||
LLUUID normal_id;
|
||||
if (normal_tex != nullptr)
|
||||
{
|
||||
normal_tex->forceToSaveRawImage(0, F32_MAX);
|
||||
normal_id = normal_tex->getID();
|
||||
}
|
||||
|
||||
LLUUID mr_id;
|
||||
if (mr_tex != nullptr)
|
||||
{
|
||||
mr_tex->forceToSaveRawImage(0, F32_MAX);
|
||||
mr_id = mr_tex->getID();
|
||||
}
|
||||
|
||||
LLUUID emissive_id;
|
||||
if (emissive_tex != nullptr)
|
||||
{
|
||||
emissive_tex->forceToSaveRawImage(0, F32_MAX);
|
||||
emissive_id = emissive_tex->getID();
|
||||
}
|
||||
|
||||
mME->setAlbedoId(albedo_id);
|
||||
mME->setMetallicRoughnessId(mr_id);
|
||||
mME->setEmissiveId(emissive_id);
|
||||
mME->setNormalId(normal_id);
|
||||
|
||||
mME->setAlphaMode(material_in.alphaMode);
|
||||
mME->setAlphaCutoff(material_in.alphaCutoff);
|
||||
|
||||
mME->setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor));
|
||||
mME->setEmissiveColor(get_color(material_in.emissiveFactor));
|
||||
|
||||
mME->setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor);
|
||||
mME->setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor);
|
||||
|
||||
mME->setDoubleSided(material_in.doubleSided);
|
||||
|
||||
std::string new_material = LLTrans::getString("New Material");
|
||||
mME->setMaterialName(new_material);
|
||||
|
||||
mME->setHasUnsavedChanges(true);
|
||||
mME->openFloater();
|
||||
|
||||
mME->applyToSelection();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::importMaterial()
|
||||
{
|
||||
(new LLMaterialFilePicker(this))->getFile();
|
||||
}
|
||||
|
||||
void LLMaterialEditor::applyToSelection()
|
||||
{
|
||||
LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject();
|
||||
if (objectp && objectp->getVolume())
|
||||
{
|
||||
LLGLTFMaterial* mat = new LLGLTFMaterial();
|
||||
mat->mAlbedoColor = getAlbedoColor();
|
||||
mat->mAlbedoColor.mV[3] = getTransparency();
|
||||
mat->mAlbedoId = getAlbedoId();
|
||||
|
||||
mat->mNormalId = getNormalId();
|
||||
|
||||
mat->mMetallicRoughnessId = getMetallicRoughnessId();
|
||||
mat->mMetallicFactor = getMetalnessFactor();
|
||||
mat->mRoughnessFactor = getRoughnessFactor();
|
||||
|
||||
mat->mEmissiveColor = getEmissiveColor();
|
||||
mat->mEmissiveId = getEmissiveId();
|
||||
|
||||
mat->mDoubleSided = getDoubleSided();
|
||||
mat->setAlphaMode(getAlphaMode());
|
||||
|
||||
LLVOVolume* vobjp = (LLVOVolume*)objectp;
|
||||
for (int i = 0; i < vobjp->getNumTEs(); ++i)
|
||||
{
|
||||
vobjp->getTE(i)->setGLTFMaterial(mat);
|
||||
vobjp->updateTEMaterialTextures(i);
|
||||
}
|
||||
|
||||
vobjp->markForUpdate(TRUE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* @file llmaterialeditor.h
|
||||
* @brief LLMaterialEditor class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLTextureCtrl;
|
||||
|
||||
class LLMaterialEditor : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLMaterialEditor(const LLSD& key);
|
||||
|
||||
// open a file dialog and select a gltf/glb file for import
|
||||
void importMaterial();
|
||||
|
||||
// for live preview, apply current material to currently selected object
|
||||
void applyToSelection();
|
||||
|
||||
void onClickSave();
|
||||
void onClickSaveAs();
|
||||
void onSaveAsMsgCallback(const LLSD& notification, const LLSD& response);
|
||||
void onClickCancel();
|
||||
void onCancelMsgCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
// llpanel
|
||||
BOOL postBuild() override;
|
||||
void onClickCloseBtn(bool app_quitting = false) override;
|
||||
|
||||
LLUUID getAlbedoId();
|
||||
void setAlbedoId(const LLUUID& id);
|
||||
|
||||
LLColor4 getAlbedoColor();
|
||||
|
||||
// sets both albedo color and transparency
|
||||
void setAlbedoColor(const LLColor4& color);
|
||||
|
||||
F32 getTransparency();
|
||||
|
||||
std::string getAlphaMode();
|
||||
void setAlphaMode(const std::string& alpha_mode);
|
||||
|
||||
F32 getAlphaCutoff();
|
||||
void setAlphaCutoff(F32 alpha_cutoff);
|
||||
|
||||
void setMaterialName(const std::string &name);
|
||||
|
||||
LLUUID getMetallicRoughnessId();
|
||||
void setMetallicRoughnessId(const LLUUID& id);
|
||||
|
||||
F32 getMetalnessFactor();
|
||||
void setMetalnessFactor(F32 factor);
|
||||
|
||||
F32 getRoughnessFactor();
|
||||
void setRoughnessFactor(F32 factor);
|
||||
|
||||
LLUUID getEmissiveId();
|
||||
void setEmissiveId(const LLUUID& id);
|
||||
|
||||
LLColor4 getEmissiveColor();
|
||||
void setEmissiveColor(const LLColor4& color);
|
||||
|
||||
LLUUID getNormalId();
|
||||
void setNormalId(const LLUUID& id);
|
||||
|
||||
bool getDoubleSided();
|
||||
void setDoubleSided(bool double_sided);
|
||||
|
||||
void setHasUnsavedChanges(bool value);
|
||||
|
||||
void onCommitAlbedoTexture(LLUICtrl* ctrl, const LLSD& data);
|
||||
void onCommitMetallicTexture(LLUICtrl* ctrl, const LLSD& data);
|
||||
void onCommitEmissiveTexture(LLUICtrl* ctrl, const LLSD& data);
|
||||
void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data);
|
||||
|
||||
private:
|
||||
LLTextureCtrl* mAlbedoTextureCtrl;
|
||||
LLTextureCtrl* mMetallicTextureCtrl;
|
||||
LLTextureCtrl* mEmissiveTextureCtrl;
|
||||
LLTextureCtrl* mNormalTextureCtrl;
|
||||
|
||||
// 'Default' texture, unless it's null or from inventory is the one with the fee
|
||||
LLUUID mAlbedoTextureUploadId;
|
||||
LLUUID mMetallicTextureUploadId;
|
||||
LLUUID mEmissiveTextureUploadId;
|
||||
LLUUID mNormalTextureUploadId;
|
||||
|
||||
bool mHasUnsavedChanges;
|
||||
std::string mMaterialName;
|
||||
};
|
||||
|
||||
|
|
@ -108,6 +108,8 @@ namespace
|
|||
const std::string FIELD_SKY_DENSITY_DROPLET_RADIUS("droplet_radius");
|
||||
const std::string FIELD_SKY_DENSITY_ICE_LEVEL("ice_level");
|
||||
|
||||
const std::string FIELD_REFLECTION_PROBE_AMBIANCE("probe_ambiance");
|
||||
|
||||
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
|
||||
const F32 SLIDER_SCALE_BLUE_HORIZON_DENSITY(2.0f);
|
||||
const F32 SLIDER_SCALE_GLOW_R(20.0f);
|
||||
|
|
@ -150,6 +152,7 @@ BOOL LLPanelSettingsSkyAtmosTab::postBuild()
|
|||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoistureLevelChanged(); });
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDropletRadiusChanged(); });
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onIceLevelChanged(); });
|
||||
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
|
||||
refresh();
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -172,6 +175,7 @@ void LLPanelSettingsSkyAtmosTab::setEnabled(BOOL enabled)
|
|||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setEnabled(enabled);
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setEnabled(enabled);
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setEnabled(enabled);
|
||||
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,10 +207,12 @@ void LLPanelSettingsSkyAtmosTab::refresh()
|
|||
F32 moisture_level = mSkySettings->getSkyMoistureLevel();
|
||||
F32 droplet_radius = mSkySettings->getSkyDropletRadius();
|
||||
F32 ice_level = mSkySettings->getSkyIceLevel();
|
||||
F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance();
|
||||
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level);
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius);
|
||||
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setValue(ice_level);
|
||||
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(rp_ambiance);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
@ -311,6 +317,15 @@ void LLPanelSettingsSkyAtmosTab::onIceLevelChanged()
|
|||
setIsDirty();
|
||||
}
|
||||
|
||||
void LLPanelSettingsSkyAtmosTab::onReflectionProbeAmbianceChanged()
|
||||
{
|
||||
if (!mSkySettings) return;
|
||||
F32 ambiance = getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->getValue().asReal();
|
||||
mSkySettings->setReflectionProbeAmbiance(ambiance);
|
||||
mSkySettings->update();
|
||||
setIsDirty();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
LLPanelSettingsSkyCloudTab::LLPanelSettingsSkyCloudTab() :
|
||||
LLPanelSettingsSky()
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ private:
|
|||
void onMoistureLevelChanged();
|
||||
void onDropletRadiusChanged();
|
||||
void onIceLevelChanged();
|
||||
void onReflectionProbeAmbianceChanged();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1315,6 +1315,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
|
|||
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
|
||||
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
|
||||
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
|
||||
getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL));
|
||||
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
|
||||
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
|
||||
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
|
||||
|
|
@ -1377,6 +1378,12 @@ void LLFloaterInventoryFinder::draw()
|
|||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (!getChild<LLUICtrl>("check_material")->getValue())
|
||||
{
|
||||
filter &= ~(0x1 << LLInventoryType::IT_MATERIAL);
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (!getChild<LLUICtrl>("check_notecard")->getValue())
|
||||
{
|
||||
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
|
||||
|
|
@ -1555,6 +1562,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
|
|||
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
|
||||
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
|
||||
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
|
||||
self->getChild<LLUICtrl>("check_material")->setValue(TRUE);
|
||||
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
|
||||
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
|
||||
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
|
||||
|
|
@ -1575,6 +1583,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
|
|||
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
|
||||
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
|
||||
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
|
||||
self->getChild<LLUICtrl>("check_material")->setValue(FALSE);
|
||||
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
|
||||
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
|
||||
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
|
||||
|
|
|
|||
|
|
@ -74,10 +74,11 @@ void LLReflectionMap::autoAdjustOrigin()
|
|||
d.setAdd(bounds[0], bounds[1]);
|
||||
d.sub(mOrigin);
|
||||
mRadius = d.getLength3().getF32();
|
||||
mPriority = 1;
|
||||
}
|
||||
else if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
|
||||
{
|
||||
mPriority = 8;
|
||||
mPriority = 1;
|
||||
// cast a ray towards 8 corners of bounding box
|
||||
// nudge origin towards center of empty space
|
||||
|
||||
|
|
@ -155,7 +156,7 @@ void LLReflectionMap::autoAdjustOrigin()
|
|||
else
|
||||
{
|
||||
// user placed probe
|
||||
mPriority = 64;
|
||||
mPriority = 2;
|
||||
|
||||
// use center of octree node volume for nodes that are just branches without data
|
||||
mOrigin = node->getCenter();
|
||||
|
|
@ -196,15 +197,13 @@ extern LLControlGroup gSavedSettings;
|
|||
|
||||
F32 LLReflectionMap::getAmbiance()
|
||||
{
|
||||
static LLCachedControl<F32> minimum_ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f);
|
||||
|
||||
F32 ret = 0.f;
|
||||
if (mViewerObject && mViewerObject->getVolume())
|
||||
{
|
||||
ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
|
||||
}
|
||||
|
||||
return llmax(ret, minimum_ambiance());
|
||||
return ret;
|
||||
}
|
||||
|
||||
F32 LLReflectionMap::getNearClip()
|
||||
|
|
|
|||
|
|
@ -33,15 +33,11 @@
|
|||
#include "pipeline.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llenvironment.h"
|
||||
|
||||
extern BOOL gCubeSnapshot;
|
||||
extern BOOL gTeleportDisplay;
|
||||
|
||||
//#pragma optimize("", off)
|
||||
|
||||
// experimental pipeline render target override, if this works, do something less hacky
|
||||
LLPipeline::RenderTargetPack gProbeRT;
|
||||
|
||||
LLReflectionMapManager::LLReflectionMapManager()
|
||||
{
|
||||
for (int i = 0; i < LL_REFLECTION_PROBE_COUNT; ++i)
|
||||
|
|
@ -84,7 +80,11 @@ void LLReflectionMapManager::update()
|
|||
if (mTexture.isNull())
|
||||
{
|
||||
mTexture = new LLCubeMapArray();
|
||||
mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT);
|
||||
// store LL_REFLECTION_PROBE_COUNT+2 cube maps, final two cube maps are used for render target and radiance map generation source)
|
||||
mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT+2);
|
||||
|
||||
mIrradianceMaps = new LLCubeMapArray();
|
||||
mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, LL_REFLECTION_PROBE_COUNT);
|
||||
}
|
||||
|
||||
if (!mRenderTarget.isComplete())
|
||||
|
|
@ -94,15 +94,6 @@ void LLReflectionMapManager::update()
|
|||
const bool use_stencil_buffer = true;
|
||||
U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample
|
||||
mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE);
|
||||
|
||||
// hack to allocate render targets using gPipeline code
|
||||
gCubeSnapshot = TRUE;
|
||||
auto* old_rt = gPipeline.mRT;
|
||||
gPipeline.mRT = &gProbeRT;
|
||||
gPipeline.allocateScreenBuffer(targetRes, targetRes);
|
||||
gPipeline.allocateShadowBuffer(targetRes, targetRes);
|
||||
gPipeline.mRT = old_rt;
|
||||
gCubeSnapshot = FALSE;
|
||||
}
|
||||
|
||||
if (mMipChain.empty())
|
||||
|
|
@ -118,12 +109,6 @@ void LLReflectionMapManager::update()
|
|||
}
|
||||
}
|
||||
|
||||
// =============== TODO -- move to an init function =================
|
||||
|
||||
// naively drop probes every 16m as we move the camera around for now
|
||||
// later, use LLSpatialPartition to manage probes
|
||||
const F32 PROBE_SPACING = 16.f;
|
||||
const U32 MAX_PROBES = 8;
|
||||
|
||||
LLVector4a camera_pos;
|
||||
camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
|
||||
|
|
@ -131,7 +116,7 @@ void LLReflectionMapManager::update()
|
|||
// process kill list
|
||||
for (auto& probe : mKillList)
|
||||
{
|
||||
auto& iter = std::find(mProbes.begin(), mProbes.end(), probe);
|
||||
auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe);
|
||||
if (iter != mProbes.end())
|
||||
{
|
||||
deleteProbe(iter - mProbes.begin());
|
||||
|
|
@ -152,7 +137,6 @@ void LLReflectionMapManager::update()
|
|||
{
|
||||
return;
|
||||
}
|
||||
const F32 UPDATE_INTERVAL = 5.f; //update no more than once every 5 seconds
|
||||
|
||||
bool did_update = false;
|
||||
|
||||
|
|
@ -375,7 +359,7 @@ void LLReflectionMapManager::deleteProbe(U32 i)
|
|||
// remove from any Neighbors lists
|
||||
for (auto& other : probe->mNeighbors)
|
||||
{
|
||||
auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
|
||||
auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
|
||||
llassert(iter != other->mNeighbors.end());
|
||||
other->mNeighbors.erase(iter);
|
||||
}
|
||||
|
|
@ -403,13 +387,19 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
{
|
||||
mRenderTarget.bindTarget();
|
||||
// hacky hot-swap of camera specific render targets
|
||||
auto* old_rt = gPipeline.mRT;
|
||||
gPipeline.mRT = &gProbeRT;
|
||||
gPipeline.mRT = &gPipeline.mAuxillaryRT;
|
||||
probe->update(mRenderTarget.getWidth(), face);
|
||||
gPipeline.mRT = old_rt;
|
||||
gPipeline.mRT = &gPipeline.mMainRT;
|
||||
mRenderTarget.flush();
|
||||
|
||||
// generate mipmaps
|
||||
S32 targetIdx = LL_REFLECTION_PROBE_COUNT;
|
||||
|
||||
if (probe != mUpdatingProbe)
|
||||
{ // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel
|
||||
targetIdx += 1;
|
||||
}
|
||||
|
||||
// downsample to placeholder map
|
||||
{
|
||||
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
|
|
@ -428,7 +418,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
|
||||
|
||||
for (int i = 0; i < mMipChain.size(); ++i)
|
||||
//for (int i = 0; i < mMipChain.size(); ++i)
|
||||
for (int i = 0; i < 1; ++i)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("probe mip");
|
||||
mMipChain[i].bindTarget();
|
||||
|
|
@ -483,6 +474,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
if (mip >= 0)
|
||||
{
|
||||
mTexture->bind(0);
|
||||
//glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
|
||||
mTexture->unbind();
|
||||
}
|
||||
|
|
@ -495,6 +488,120 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
gReflectionMipProgram.unbind();
|
||||
}
|
||||
|
||||
if (face == 5)
|
||||
{
|
||||
//generate radiance map
|
||||
gRadianceGenProgram.bind();
|
||||
S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
|
||||
mTexture->bind(channel);
|
||||
static LLStaticHashedString sSourceIdx("sourceIdx");
|
||||
gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx);
|
||||
|
||||
static LLStaticHashedString sMipLevel("mipLevel");
|
||||
|
||||
for (int i = 1; i < mMipChain.size(); ++i)
|
||||
{
|
||||
for (int cf = 0; cf < 6; ++cf)
|
||||
{ // for each cube face
|
||||
LLCoordFrame frame;
|
||||
frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
|
||||
|
||||
F32 mat[16];
|
||||
frame.getOpenGLRotation(mat);
|
||||
gGL.loadMatrix(mat);
|
||||
|
||||
mMipChain[i].bindTarget();
|
||||
static LLStaticHashedString sRoughness("roughness");
|
||||
|
||||
gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
|
||||
gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f));
|
||||
if (i > 0)
|
||||
{
|
||||
gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex);
|
||||
}
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(gGL.QUADS);
|
||||
//gGL.vertex3f(-1, -1, -1);
|
||||
//gGL.vertex3f(1, -1, -1);
|
||||
//gGL.vertex3f(1, 1, -1);
|
||||
//gGL.vertex3f(-1, 1, -1);
|
||||
//gGL.end();
|
||||
gGL.begin(gGL.TRIANGLES);
|
||||
gGL.vertex3f(-1, -1, -1);
|
||||
gGL.vertex3f(1, -1, -1);
|
||||
gGL.vertex3f(1, 1, -1);
|
||||
gGL.vertex3f(-1, -1, -1);
|
||||
gGL.vertex3f(1, 1, -1);
|
||||
gGL.vertex3f(-1, 1, -1);
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
gGL.flush();
|
||||
|
||||
S32 res = mMipChain[i].getWidth();
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
|
||||
mMipChain[i].flush();
|
||||
}
|
||||
}
|
||||
gRadianceGenProgram.unbind();
|
||||
|
||||
//generate irradiance map
|
||||
gIrradianceGenProgram.bind();
|
||||
channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
|
||||
mTexture->bind(channel);
|
||||
|
||||
gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex);
|
||||
|
||||
int start_mip = 0;
|
||||
// find the mip target to start with based on irradiance map resolution
|
||||
for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip)
|
||||
{
|
||||
if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = start_mip; i < mMipChain.size(); ++i)
|
||||
{
|
||||
for (int cf = 0; cf < 6; ++cf)
|
||||
{ // for each cube face
|
||||
LLCoordFrame frame;
|
||||
frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
|
||||
|
||||
F32 mat[16];
|
||||
frame.getOpenGLRotation(mat);
|
||||
gGL.loadMatrix(mat);
|
||||
|
||||
mMipChain[i].bindTarget();
|
||||
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(gGL.QUADS);
|
||||
//gGL.vertex3f(-1, -1, -1);
|
||||
//gGL.vertex3f(1, -1, -1);
|
||||
//gGL.vertex3f(1, 1, -1);
|
||||
//gGL.vertex3f(-1, 1, -1);
|
||||
//gGL.end();
|
||||
gGL.begin(gGL.TRIANGLES);
|
||||
gGL.vertex3f(-1, -1, -1);
|
||||
gGL.vertex3f(1, -1, -1);
|
||||
gGL.vertex3f(1, 1, -1);
|
||||
gGL.vertex3f(-1, -1, -1);
|
||||
gGL.vertex3f(1, 1, -1);
|
||||
gGL.vertex3f(-1, 1, -1);
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
gGL.flush();
|
||||
|
||||
S32 res = mMipChain[i].getWidth();
|
||||
mIrradianceMaps->bind(channel);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
|
||||
mTexture->bind(channel);
|
||||
mMipChain[i].flush();
|
||||
}
|
||||
}
|
||||
gIrradianceGenProgram.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
void LLReflectionMapManager::rebuild()
|
||||
|
|
@ -523,7 +630,7 @@ void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)
|
|||
|
||||
for (auto& other : probe->mNeighbors)
|
||||
{
|
||||
auto& iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
|
||||
auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
|
||||
llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly
|
||||
other->mNeighbors.erase(iter);
|
||||
}
|
||||
|
|
@ -577,6 +684,11 @@ void LLReflectionMapManager::updateUniforms()
|
|||
S32 count = 0;
|
||||
U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors
|
||||
|
||||
LLEnvironment& environment = LLEnvironment::instance();
|
||||
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
|
||||
|
||||
F32 minimum_ambiance = psky->getReflectionProbeAmbiance();
|
||||
|
||||
for (auto* refmap : mReflectionMaps)
|
||||
{
|
||||
if (refmap == nullptr)
|
||||
|
|
@ -609,7 +721,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
rpd.refIndex[count][3] = -rpd.refIndex[count][3];
|
||||
}
|
||||
|
||||
rpd.refParams[count].set(refmap->getAmbiance(), 0.f, 0.f, 0.f);
|
||||
rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance()), 0.f, 0.f, 0.f);
|
||||
|
||||
S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llreflectionmap.h"
|
||||
#include "llrendertarget.h"
|
||||
#include "llcubemaparray.h"
|
||||
#include "llcubemap.h"
|
||||
|
||||
class LLSpatialGroup;
|
||||
class LLViewerObject;
|
||||
|
|
@ -38,6 +39,7 @@ class LLViewerObject;
|
|||
|
||||
// reflection probe resolution
|
||||
#define LL_REFLECTION_PROBE_RESOLUTION 256
|
||||
#define LL_IRRADIANCE_MAP_RESOLUTION 64
|
||||
|
||||
// reflection probe mininum scale
|
||||
#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f;
|
||||
|
|
@ -111,9 +113,12 @@ private:
|
|||
|
||||
std::vector<LLRenderTarget> mMipChain;
|
||||
|
||||
// storage for reflection probes
|
||||
// storage for reflection probe radiance maps (plus two scratch space cubemaps)
|
||||
LLPointer<LLCubeMapArray> mTexture;
|
||||
|
||||
// storage for reflection probe irradiance maps
|
||||
LLPointer<LLCubeMapArray> mIrradianceMaps;
|
||||
|
||||
// array indicating if a particular cubemap is free
|
||||
bool mCubeFree[LL_REFLECTION_PROBE_COUNT];
|
||||
|
||||
|
|
|
|||
|
|
@ -758,6 +758,7 @@ LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
|
|||
param_map[SETTING_SKY_DROPLET_RADIUS] = DefaultParam(LLShaderMgr::DROPLET_RADIUS, sky_defaults[SETTING_SKY_DROPLET_RADIUS]);
|
||||
param_map[SETTING_SKY_ICE_LEVEL] = DefaultParam(LLShaderMgr::ICE_LEVEL, sky_defaults[SETTING_SKY_ICE_LEVEL]);
|
||||
|
||||
param_map[SETTING_REFLECTION_PROBE_AMBIANCE] = DefaultParam(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, sky_defaults[SETTING_REFLECTION_PROBE_AMBIANCE]);
|
||||
// AdvancedAtmospherics TODO
|
||||
// Provide mappings for new shader params here
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,9 +124,14 @@ public:
|
|||
LL_ALIGN_16(LLFace* mFace); //associated face
|
||||
F32 mDistance;
|
||||
U32 mDrawMode;
|
||||
LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
|
||||
LLMaterialID mMaterialID;
|
||||
U32 mShaderMask;
|
||||
|
||||
// Material points here are likely for debugging only and are immaterial (zing!)
|
||||
LLMaterialPtr mMaterial;
|
||||
LLPointer<LLGLTFMaterial> mGLTFMaterial;
|
||||
|
||||
LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info
|
||||
|
||||
U32 mShaderMask;
|
||||
U32 mBlendFuncSrc;
|
||||
U32 mBlendFuncDst;
|
||||
BOOL mHasGlow;
|
||||
|
|
@ -134,6 +139,8 @@ public:
|
|||
const LLMatrix4* mSpecularMapMatrix;
|
||||
LLPointer<LLViewerTexture> mNormalMap;
|
||||
const LLMatrix4* mNormalMapMatrix;
|
||||
LLPointer<LLViewerTexture> mEmissiveMap;
|
||||
|
||||
LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
|
||||
F32 mEnvIntensity;
|
||||
F32 mAlphaMaskCutoff;
|
||||
|
|
|
|||
|
|
@ -241,10 +241,8 @@ void LLFloaterTexturePicker::setActive( BOOL active )
|
|||
void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
|
||||
{
|
||||
mCanApplyImmediately = b;
|
||||
if (!mCanApplyImmediately)
|
||||
{
|
||||
getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
|
||||
}
|
||||
|
||||
getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately);
|
||||
updateFilterPermMask();
|
||||
}
|
||||
|
||||
|
|
@ -480,11 +478,7 @@ BOOL LLFloaterTexturePicker::postBuild()
|
|||
|
||||
getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
|
||||
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
|
||||
|
||||
if (!mCanApplyImmediately)
|
||||
{
|
||||
getChildView("show_folders_check")->setEnabled(FALSE);
|
||||
}
|
||||
getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately);
|
||||
|
||||
getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
|
||||
//<FS:Chaser> UUID picker
|
||||
|
|
@ -553,7 +547,7 @@ void LLFloaterTexturePicker::draw()
|
|||
}
|
||||
|
||||
getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
|
||||
getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
|
||||
getChildView("Blank")->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID != mDefaultImageAssetID) || mTentative);
|
||||
getChildView("Transparent")->setEnabled(mImageAssetID != mTransparentImageAssetID || mTentative); // <FS:PP> FIRE-5082: "Transparent" button in Texture Panel
|
||||
getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
|
||||
|
||||
|
|
@ -1311,7 +1305,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
|
|||
mOnCloseCallback(NULL),
|
||||
mOnSelectCallback(NULL),
|
||||
mBorderColor( p.border_color() ),
|
||||
mAllowNoTexture( FALSE ),
|
||||
mAllowNoTexture( p.allow_no_texture ),
|
||||
mAllowLocalTexture( TRUE ),
|
||||
mImmediateFilterPermMask( PERM_NONE ),
|
||||
mNonImmediateFilterPermMask( PERM_NONE ),
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public:
|
|||
: image_id("image"),
|
||||
default_image_id("default_image_id"),
|
||||
default_image_name("default_image_name"),
|
||||
allow_no_texture("allow_no_texture"),
|
||||
allow_no_texture("allow_no_texture", false),
|
||||
can_apply_immediately("can_apply_immediately"),
|
||||
no_commit_on_selection("no_commit_on_selection", false),
|
||||
label_width("label_width", -1),
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@
|
|||
#include "llinspectobject.h"
|
||||
#include "llinspectremoteobject.h"
|
||||
#include "llinspecttoast.h"
|
||||
#include "llmaterialeditor.h"
|
||||
#include "llmoveview.h"
|
||||
// <FS:Ansariel> [FS communication UI]
|
||||
//#include "llfloaterimnearbychat.h
|
||||
|
|
@ -416,6 +417,8 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
|
||||
LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
|
||||
|
||||
LLFloaterReg::add("material_editor", "floater_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);
|
||||
|
||||
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
|
||||
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
|
||||
//LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary()
|
|||
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
|
||||
|
||||
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
|
||||
mInventoryItemsDict["New Material"] = LLTrans::getString("New Material");
|
||||
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
|
||||
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
|
||||
mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
|
||||
|
|
@ -2042,6 +2043,7 @@ void remove_folder_contents(const LLUUID& category, bool keep_outfit_links,
|
|||
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
|
||||
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
|
||||
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
|
||||
const std::string NEW_MATERIAL_NAME = "New Material"; // *TODO:Translate? (probably not)
|
||||
|
||||
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
|
||||
void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
|
||||
|
|
@ -2097,6 +2099,15 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
|
|||
LLInventoryType::IT_GESTURE,
|
||||
PERM_ALL); // overridden in create_new_item
|
||||
}
|
||||
else if ("material" == type_name)
|
||||
{
|
||||
const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
|
||||
create_new_item(NEW_GESTURE_NAME,
|
||||
parent_id,
|
||||
LLAssetType::AT_MATERIAL,
|
||||
LLInventoryType::IT_MATERIAL,
|
||||
PERM_ALL); // overridden in create_new_item
|
||||
}
|
||||
else if (("sky" == type_name) || ("water" == type_name) || ("daycycle" == type_name))
|
||||
{
|
||||
LLSettingsType::type_e stype(LLSettingsType::ST_NONE);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llbuycurrencyhtml.h"
|
||||
#include "llfloatermap.h"
|
||||
#include "llfloatermodelpreview.h"
|
||||
#include "llmaterialeditor.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llfloateroutfitsnapshot.h"
|
||||
#include "llimage.h"
|
||||
|
|
@ -109,6 +110,20 @@ class LLFileEnableUploadModel : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLFileEnableUploadMaterial : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::findInstance("material_editor");
|
||||
if (me && me->isShown())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLMeshEnabled : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -290,6 +305,7 @@ static std::string SLOBJECT_EXTENSIONS = "slobject";
|
|||
#endif
|
||||
static std::string ALL_FILE_EXTENSIONS = "*.*";
|
||||
static std::string MODEL_EXTENSIONS = "dae";
|
||||
static std::string MATERIAL_EXTENSIONS = "gltf glb";
|
||||
|
||||
std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
|
||||
{
|
||||
|
|
@ -306,6 +322,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
|
|||
return SLOBJECT_EXTENSIONS;
|
||||
case LLFilePicker::FFLOAD_MODEL:
|
||||
return MODEL_EXTENSIONS;
|
||||
case LLFilePicker::FFLOAD_MATERIAL:
|
||||
return MATERIAL_EXTENSIONS;
|
||||
case LLFilePicker::FFLOAD_XML:
|
||||
return XML_EXTENSIONS;
|
||||
case LLFilePicker::FFLOAD_ALL:
|
||||
|
|
@ -590,7 +608,20 @@ class LLFileUploadModel : public view_listener_t
|
|||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class LLFileUploadMaterial : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
|
||||
if (me)
|
||||
{
|
||||
me->importMaterial();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
class LLFileUploadSound : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -1271,6 +1302,7 @@ void init_menu_file()
|
|||
view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
|
||||
view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
|
||||
view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
|
||||
view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial");
|
||||
view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
|
||||
view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
|
||||
view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
|
||||
|
|
|
|||
|
|
@ -424,6 +424,11 @@ void LLViewerObject::deleteTEImages()
|
|||
delete[] mTESpecularMaps;
|
||||
mTESpecularMaps = NULL;
|
||||
}
|
||||
|
||||
mGLTFAlbedoMaps.clear();
|
||||
mGLTFNormalMaps.clear();
|
||||
mGLTFMetallicRoughnessMaps.clear();
|
||||
mGLTFEmissiveMaps.clear();
|
||||
}
|
||||
|
||||
void LLViewerObject::markDead()
|
||||
|
|
@ -4890,6 +4895,11 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
|
|||
mTEImages = new_images;
|
||||
mTENormalMaps = new_normmaps;
|
||||
mTESpecularMaps = new_specmaps;
|
||||
|
||||
mGLTFAlbedoMaps.resize(num_tes);
|
||||
mGLTFNormalMaps.resize(num_tes);
|
||||
mGLTFMetallicRoughnessMaps.resize(num_tes);
|
||||
mGLTFEmissiveMaps.resize(num_tes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5028,23 +5038,28 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID&
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
|
||||
|
||||
void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry)
|
||||
{
|
||||
LLUUID old_image_id;
|
||||
if (getTE(te))
|
||||
{
|
||||
old_image_id = getTE(te)->getID();
|
||||
}
|
||||
|
||||
LLPrimitive::setTE(te, texture_entry);
|
||||
LLUUID old_image_id;
|
||||
if (getTE(te))
|
||||
{
|
||||
old_image_id = getTE(te)->getID();
|
||||
}
|
||||
|
||||
const LLUUID& image_id = getTEref(te).getID();
|
||||
LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
|
||||
mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
LLPrimitive::setTE(te, texture_entry);
|
||||
|
||||
|
||||
updateAvatarMeshVisibility(image_id,old_image_id);
|
||||
|
||||
const LLUUID& image_id = getTEref(te).getID();
|
||||
LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
|
||||
mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
|
||||
updateAvatarMeshVisibility(image_id, old_image_id);
|
||||
|
||||
updateTEMaterialTextures(te);
|
||||
}
|
||||
|
||||
void LLViewerObject::updateTEMaterialTextures(U8 te)
|
||||
{
|
||||
if (getTEref(te).getMaterialParams().notNull())
|
||||
{
|
||||
const LLUUID& norm_id = getTEref(te).getMaterialParams()->getNormalID();
|
||||
|
|
@ -5053,6 +5068,20 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
|
|||
const LLUUID& spec_id = getTEref(te).getMaterialParams()->getSpecularID();
|
||||
mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
|
||||
}
|
||||
|
||||
auto fetch_texture = [](const LLUUID& id)
|
||||
{
|
||||
return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
|
||||
};
|
||||
|
||||
LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial();
|
||||
if (mat != nullptr)
|
||||
{
|
||||
mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId);
|
||||
mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId);
|
||||
mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId);
|
||||
mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId);
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::refreshBakeTexture()
|
||||
|
|
@ -5593,7 +5622,6 @@ void LLViewerObject::fitFaceTexture(const U8 face)
|
|||
LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL;
|
||||
}
|
||||
|
||||
|
||||
LLBBox LLViewerObject::getBoundingBoxAgent() const
|
||||
{
|
||||
LLVector3 position_agent;
|
||||
|
|
|
|||
|
|
@ -327,6 +327,7 @@ public:
|
|||
|
||||
/*virtual*/ void setNumTEs(const U8 num_tes);
|
||||
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
|
||||
void updateTEMaterialTextures(U8 te);
|
||||
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
|
||||
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
|
||||
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
|
||||
|
|
@ -366,6 +367,12 @@ public:
|
|||
LLViewerTexture *getTEImage(const U8 te) const;
|
||||
LLViewerTexture *getTENormalMap(const U8 te) const;
|
||||
LLViewerTexture *getTESpecularMap(const U8 te) const;
|
||||
|
||||
LLViewerTexture* getGLTFAlbedoMap(U8 te) const { return mGLTFAlbedoMaps[te]; }
|
||||
LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; }
|
||||
LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; }
|
||||
LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; }
|
||||
|
||||
|
||||
bool isImageAlphaBlended(const U8 te) const;
|
||||
|
||||
|
|
@ -692,6 +699,13 @@ public:
|
|||
LLPointer<LLViewerTexture> *mTEImages;
|
||||
LLPointer<LLViewerTexture> *mTENormalMaps;
|
||||
LLPointer<LLViewerTexture> *mTESpecularMaps;
|
||||
|
||||
std::vector<LLPointer<LLViewerTexture> > mGLTFAlbedoMaps;
|
||||
std::vector<LLPointer<LLViewerTexture> > mGLTFNormalMaps;
|
||||
std::vector<LLPointer<LLViewerTexture> > mGLTFMetallicRoughnessMaps;
|
||||
std::vector<LLPointer<LLViewerTexture> > mGLTFEmissiveMaps;
|
||||
|
||||
|
||||
|
||||
// true if user can select this object by clicking under any circumstances (even if pick_unselectable is true)
|
||||
// can likely be factored out
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ LLGLSLShader gCustomAlphaProgram;
|
|||
LLGLSLShader gGlowCombineProgram;
|
||||
LLGLSLShader gSplatTextureRectProgram;
|
||||
LLGLSLShader gReflectionMipProgram;
|
||||
LLGLSLShader gRadianceGenProgram;
|
||||
LLGLSLShader gIrradianceGenProgram;
|
||||
LLGLSLShader gGlowCombineFXAAProgram;
|
||||
LLGLSLShader gTwoTextureAddProgram;
|
||||
LLGLSLShader gTwoTextureCompareProgram;
|
||||
|
|
@ -266,6 +268,7 @@ LLGLSLShader gRlvSphereProgram;
|
|||
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
|
||||
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
|
||||
LLGLSLShader gDeferredPBROpaqueProgram;
|
||||
LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
|
||||
|
||||
//helper for making a rigged variant of a given shader
|
||||
bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
|
||||
|
|
@ -769,6 +772,8 @@ void LLViewerShaderMgr::unloadShaders()
|
|||
gGlowCombineProgram.unload();
|
||||
gSplatTextureRectProgram.unload();
|
||||
gReflectionMipProgram.unload();
|
||||
gRadianceGenProgram.unload();
|
||||
gIrradianceGenProgram.unload();
|
||||
gGlowCombineFXAAProgram.unload();
|
||||
gTwoTextureAddProgram.unload();
|
||||
gTwoTextureCompareProgram.unload();
|
||||
|
|
@ -1342,6 +1347,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
}
|
||||
|
||||
gDeferredPBROpaqueProgram.unload();
|
||||
gDeferredSkinnedPBROpaqueProgram.unload();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1633,22 +1639,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
|
||||
llassert(success);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
|
||||
gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
|
||||
gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
|
||||
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.clear();
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gDeferredPBROpaqueProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
|
||||
gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
//gDeferredPBROpaqueProgram.addPermutation("HAS_NORMAL_MAP", "1");
|
||||
success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
|
||||
llassert(success);
|
||||
}
|
||||
}
|
||||
|
||||
gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
|
||||
|
|
@ -1669,6 +1659,28 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
|
||||
gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
|
||||
|
||||
if (success)
|
||||
{
|
||||
gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
|
||||
gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
|
||||
gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
|
||||
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.clear();
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
gDeferredPBROpaqueProgram.addPermutation("HAS_NORMAL_MAP", "1");
|
||||
gDeferredPBROpaqueProgram.addPermutation("HAS_SPECULAR_MAP", "1");
|
||||
gDeferredPBROpaqueProgram.addPermutation("HAS_EMISSIVE_MAP", "1");
|
||||
gDeferredPBROpaqueProgram.addPermutation("DIFFUSE_ALPHA_MODE", "0");
|
||||
|
||||
success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
|
||||
if (success)
|
||||
{
|
||||
success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
|
||||
}
|
||||
llassert(success);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
|
@ -3843,6 +3855,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
|
|||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gRadianceGenProgram.mName = "Radiance Gen Shader";
|
||||
gRadianceGenProgram.mShaderFiles.clear();
|
||||
gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
|
||||
success = gRadianceGenProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gIrradianceGenProgram.mName = "Irradiance Gen Shader";
|
||||
gIrradianceGenProgram.mShaderFiles.clear();
|
||||
gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
|
||||
success = gIrradianceGenProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
mShaderLevel[SHADER_INTERFACE] = 0;
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ extern LLGLSLShader gCustomAlphaProgram;
|
|||
extern LLGLSLShader gGlowCombineProgram;
|
||||
extern LLGLSLShader gSplatTextureRectProgram;
|
||||
extern LLGLSLShader gReflectionMipProgram;
|
||||
extern LLGLSLShader gRadianceGenProgram;
|
||||
extern LLGLSLShader gIrradianceGenProgram;
|
||||
extern LLGLSLShader gGlowCombineFXAAProgram;
|
||||
extern LLGLSLShader gDebugProgram;
|
||||
extern LLGLSLShader gClipProgram;
|
||||
|
|
|
|||
|
|
@ -308,6 +308,13 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
|
|||
return tex;
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps)
|
||||
{
|
||||
LLViewerFetchedTexture* ret = new LLViewerFetchedTexture(raw, type, usemipmaps);
|
||||
gTextureList.addImage(ret, TEX_LIST_STANDARD);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
|
||||
const LLUUID &image_id,
|
||||
FTType f_type,
|
||||
|
|
|
|||
|
|
@ -714,6 +714,8 @@ public:
|
|||
static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
|
||||
static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
|
||||
|
||||
static LLViewerFetchedTexture* getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps);
|
||||
|
||||
static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
|
||||
FTType f_type = FTT_DEFAULT,
|
||||
BOOL usemipmap = TRUE,
|
||||
|
|
|
|||
|
|
@ -5665,10 +5665,26 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
|||
|
||||
LLViewerTexture* tex = facep->getTexture();
|
||||
|
||||
|
||||
U8 index = facep->getTextureIndex();
|
||||
|
||||
LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
|
||||
LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
|
||||
LLMaterial* mat = nullptr;
|
||||
|
||||
LLUUID mat_id;
|
||||
|
||||
LLGLTFMaterial* gltf_mat = facep->getTextureEntry()->getGLTFMaterial();
|
||||
if (gltf_mat != nullptr)
|
||||
{
|
||||
mat_id = gltf_mat->getHash(); // TODO: cache this hash
|
||||
}
|
||||
else
|
||||
{
|
||||
mat = facep->getTextureEntry()->getMaterialParams().get();
|
||||
if (mat)
|
||||
{
|
||||
mat_id = facep->getTextureEntry()->getMaterialID().asUUID();
|
||||
}
|
||||
}
|
||||
|
||||
bool batchable = false;
|
||||
|
||||
|
|
@ -5690,7 +5706,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
|||
|
||||
if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
|
||||
{
|
||||
if (mat || draw_vec[idx]->mMaterial)
|
||||
if (mat || gltf_mat || draw_vec[idx]->mMaterial)
|
||||
{ //can't batch textures when materials are present (yet)
|
||||
batchable = false;
|
||||
}
|
||||
|
|
@ -5722,7 +5738,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
|||
draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
|
||||
draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
|
||||
#endif
|
||||
//draw_vec[idx]->mMaterial == mat &&
|
||||
draw_vec[idx]->mMaterialID == mat_id &&
|
||||
draw_vec[idx]->mFullbright == fullbright &&
|
||||
draw_vec[idx]->mBump == bump &&
|
||||
|
|
@ -5779,11 +5794,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
|||
draw_info->mEnvIntensity = spec;
|
||||
draw_info->mSpecularMap = NULL;
|
||||
draw_info->mMaterial = mat;
|
||||
draw_info->mGLTFMaterial = gltf_mat;
|
||||
draw_info->mShaderMask = shader_mask;
|
||||
draw_info->mAvatar = facep->mAvatar;
|
||||
draw_info->mSkinInfo = facep->mSkinInfo;
|
||||
|
||||
if (mat)
|
||||
if (gltf_mat)
|
||||
{
|
||||
LLViewerObject* vobj = facep->getViewerObject();
|
||||
U8 te = facep->getTEOffset();
|
||||
|
||||
draw_info->mTexture = vobj->getGLTFAlbedoMap(te);
|
||||
draw_info->mNormalMap = vobj->getGLTFNormalMap(te);
|
||||
draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te);
|
||||
draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te);
|
||||
}
|
||||
else if (mat)
|
||||
{
|
||||
draw_info->mMaterialID = mat_id;
|
||||
|
||||
|
|
@ -6170,6 +6196,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if LL_RELEASE_WITH_DEBUG_INFO
|
||||
const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
|
||||
const LLUUID obj_id( vobj->getID() );
|
||||
|
|
@ -6177,6 +6204,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
#else
|
||||
bool is_pbr = false;
|
||||
#endif
|
||||
#else
|
||||
bool is_pbr = facep->getTextureEntry()->getGLTFMaterial() != nullptr;
|
||||
#endif
|
||||
|
||||
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
|
||||
// batch, it will recover its vertex buffer reference from the spatial group
|
||||
|
|
@ -6319,31 +6349,43 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
if (gPipeline.canUseWindLightShadersOnObjects()
|
||||
&& LLPipeline::sRenderBump)
|
||||
{
|
||||
// <FS:ND> We just skip all of this is there is no te entry. This might get some funny results (which would be a face without te anyway).
|
||||
// if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
|
||||
if (LLPipeline::sRenderDeferred && te && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
|
||||
// </FS:ND>
|
||||
// <FS> Skip if no te entry
|
||||
if (!te)
|
||||
continue;
|
||||
|
||||
LLGLTFMaterial* gltf_mat = te->getGLTFMaterial();
|
||||
|
||||
if (LLPipeline::sRenderDeferred &&
|
||||
(gltf_mat != nullptr || (te->getMaterialParams().notNull() && !te->getMaterialID().isNull())))
|
||||
{
|
||||
LLMaterial* mat = te->getMaterialParams().get();
|
||||
if (mat->getNormalID().notNull())
|
||||
{
|
||||
if (mat->getSpecularID().notNull())
|
||||
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
|
||||
add_face(sNormSpecFaces, normspec_count, facep);
|
||||
}
|
||||
else
|
||||
{ //has normal map (needs texcoord1 and tangent)
|
||||
add_face(sNormFaces, norm_count, facep);
|
||||
}
|
||||
}
|
||||
else if (mat->getSpecularID().notNull())
|
||||
{ //has specular map but no normal map, needs texcoord2
|
||||
add_face(sSpecFaces, spec_count, facep);
|
||||
}
|
||||
else
|
||||
{ //has neither specular map nor normal map, only needs texcoord0
|
||||
add_face(sSimpleFaces, simple_count, facep);
|
||||
}
|
||||
if (gltf_mat != nullptr)
|
||||
{
|
||||
// all gltf materials have all vertex attributes for now
|
||||
add_face(sNormSpecFaces, normspec_count, facep);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLMaterial* mat = te->getMaterialParams().get();
|
||||
if (mat->getNormalID().notNull())
|
||||
{
|
||||
if (mat->getSpecularID().notNull())
|
||||
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
|
||||
add_face(sNormSpecFaces, normspec_count, facep);
|
||||
}
|
||||
else
|
||||
{ //has normal map (needs texcoord1 and tangent)
|
||||
add_face(sNormFaces, norm_count, facep);
|
||||
}
|
||||
}
|
||||
else if (mat->getSpecularID().notNull())
|
||||
{ //has specular map but no normal map, needs texcoord2
|
||||
add_face(sSpecFaces, spec_count, facep);
|
||||
}
|
||||
else
|
||||
{ //has neither specular map nor normal map, only needs texcoord0
|
||||
add_face(sSimpleFaces, simple_count, facep);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (te->getBumpmap())
|
||||
{ //needs normal + tangent
|
||||
|
|
@ -7058,15 +7100,24 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
|
||||
BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
|
||||
|
||||
LLMaterial* mat = te->getMaterialParams().get();
|
||||
LLGLTFMaterial* gltf_mat = te->getGLTFMaterial();
|
||||
|
||||
bool can_be_shiny = true;
|
||||
if (mat)
|
||||
{
|
||||
U8 mode = mat->getDiffuseAlphaMode();
|
||||
can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
|
||||
mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
|
||||
}
|
||||
LLMaterial* mat = nullptr;
|
||||
bool can_be_shiny = false;
|
||||
|
||||
// ignore traditional material if GLTF material is present
|
||||
if (gltf_mat == nullptr)
|
||||
{
|
||||
mat = te->getMaterialParams().get();
|
||||
|
||||
can_be_shiny = true;
|
||||
if (mat)
|
||||
{
|
||||
U8 mode = mat->getDiffuseAlphaMode();
|
||||
can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
|
||||
mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
|
||||
}
|
||||
}
|
||||
|
||||
F32 te_alpha = te->getColor().mV[3];
|
||||
bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
|
||||
|
|
@ -7075,10 +7126,15 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
|
||||
is_alpha = (is_alpha || transparent) ? TRUE : FALSE;
|
||||
|
||||
if (mat && LLPipeline::sRenderDeferred && !hud_group)
|
||||
if ((gltf_mat || mat) && LLPipeline::sRenderDeferred && !hud_group)
|
||||
{
|
||||
bool material_pass = false;
|
||||
|
||||
if (gltf_mat)
|
||||
{ // all other parameters ignored if gltf material is present
|
||||
registerFace(group, facep, LLRenderPass::PASS_PBR_OPAQUE);
|
||||
}
|
||||
else
|
||||
// do NOT use 'fullbright' for this logic or you risk sending
|
||||
// things without normals down the materials pipeline and will
|
||||
// render poorly if not crash NORSPEC-240,314
|
||||
|
|
|
|||
|
|
@ -116,39 +116,39 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
|
||||
/*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references
|
||||
LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
|
||||
void markDead() override; // Override (and call through to parent) to clean up media references
|
||||
|
||||
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
LLDrawable* createDrawable(LLPipeline *pipeline) override;
|
||||
|
||||
void deleteFaces();
|
||||
|
||||
void animateTextures();
|
||||
|
||||
BOOL isVisible() const ;
|
||||
/*virtual*/ BOOL isActive() const;
|
||||
/*virtual*/ BOOL isAttachment() const;
|
||||
/*virtual*/ BOOL isRootEdit() const; // overridden for sake of attachments treating themselves as a root object
|
||||
/*virtual*/ BOOL isHUDAttachment() const;
|
||||
BOOL isActive() const override;
|
||||
BOOL isAttachment() const override;
|
||||
BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object
|
||||
BOOL isHUDAttachment() const override;
|
||||
|
||||
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
|
||||
/*virtual*/ BOOL setParent(LLViewerObject* parent);
|
||||
S32 getLOD() const { return mLOD; }
|
||||
/*virtual*/ BOOL setParent(LLViewerObject* parent) override;
|
||||
S32 getLOD() const override { return mLOD; }
|
||||
void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
|
||||
bool isNoLOD() const { return NO_LOD == mLOD; }
|
||||
const LLVector3 getPivotPositionAgent() const;
|
||||
const LLVector3 getPivotPositionAgent() const override;
|
||||
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
|
||||
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
|
||||
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
|
||||
/*virtual*/ const LLMatrix4 getRenderMatrix() const override;
|
||||
typedef std::map<LLUUID, S32> texture_cost_t;
|
||||
U32 getRenderCost(texture_cost_t &textures) const;
|
||||
/*virtual*/ F32 getEstTrianglesMax() const;
|
||||
/*virtual*/ F32 getEstTrianglesStreamingCost() const;
|
||||
/* virtual*/ F32 getStreamingCost() const;
|
||||
/*virtual*/ bool getCostData(LLMeshCostData& costs) const;
|
||||
/*virtual*/ F32 getEstTrianglesMax() const override;
|
||||
/*virtual*/ F32 getEstTrianglesStreamingCost() const override;
|
||||
/* virtual*/ F32 getStreamingCost() const override;
|
||||
/*virtual*/ bool getCostData(LLMeshCostData& costs) const override;
|
||||
|
||||
/*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
|
||||
/*virtual*/ U32 getHighLODTriangleCount();
|
||||
/*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
|
||||
/*virtual*/ U32 getHighLODTriangleCount() override;
|
||||
//<FS:Beq> Mesh Info in object panel
|
||||
/*virtual*/ U32 getLODTriangleCount(S32 lod);
|
||||
//</FS:Beq>
|
||||
|
|
@ -162,7 +162,7 @@ public:
|
|||
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
|
||||
LLVector4a* normal = NULL, // return the surface normal at the intersection point
|
||||
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
|
||||
);
|
||||
) override;
|
||||
|
||||
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
|
||||
LLVector3 agentDirectionToVolume(const LLVector3& dir) const;
|
||||
|
|
@ -172,17 +172,17 @@ public:
|
|||
|
||||
BOOL getVolumeChanged() const { return mVolumeChanged; }
|
||||
|
||||
/*virtual*/ F32 getRadius() const { return mVObjRadius; };
|
||||
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
|
||||
F32 getVObjRadius() const override { return mVObjRadius; };
|
||||
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override;
|
||||
|
||||
void markForUpdate(BOOL priority);
|
||||
void markForUpdate(BOOL priority) override;
|
||||
void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }
|
||||
void faceMappingChanged() { mFaceMappingChanged=TRUE; };
|
||||
|
||||
/*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
|
||||
/*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts
|
||||
|
||||
/*virtual*/ void parameterChanged(U16 param_type, bool local_origin);
|
||||
/*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
|
||||
/*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override;
|
||||
/*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override;
|
||||
|
||||
// update mReflectionProbe based on isReflectionProbe()
|
||||
void updateReflectionProbePtr();
|
||||
|
|
@ -190,40 +190,40 @@ public:
|
|||
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
U32 block_num, const EObjectUpdateType update_type,
|
||||
LLDataPacker *dp);
|
||||
LLDataPacker *dp) override;
|
||||
|
||||
/*virtual*/ void setSelected(BOOL sel);
|
||||
/*virtual*/ BOOL setDrawableParent(LLDrawable* parentp);
|
||||
/*virtual*/ void setSelected(BOOL sel) override;
|
||||
/*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override;
|
||||
|
||||
/*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
|
||||
/*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override;
|
||||
|
||||
/*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) ;
|
||||
/*virtual*/ void setNumTEs(const U8 num_tes);
|
||||
/*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
|
||||
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
|
||||
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
|
||||
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
|
||||
/*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump);
|
||||
/*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny);
|
||||
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright);
|
||||
/*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
|
||||
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
|
||||
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
|
||||
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
|
||||
/*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override;
|
||||
/*virtual*/ void setNumTEs(const U8 num_tes) override;
|
||||
/*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override;
|
||||
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override;
|
||||
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override;
|
||||
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override;
|
||||
/*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override;
|
||||
/*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override;
|
||||
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override;
|
||||
/*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override;
|
||||
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override;
|
||||
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override;
|
||||
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override;
|
||||
|
||||
static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
|
||||
|
||||
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
|
||||
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
|
||||
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
|
||||
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
|
||||
/*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen);
|
||||
/*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media);
|
||||
/*virtual*/ BOOL setMaterial(const U8 material);
|
||||
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override;
|
||||
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override;
|
||||
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override;
|
||||
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override;
|
||||
/*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override;
|
||||
/*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override;
|
||||
/*virtual*/ BOOL setMaterial(const U8 material) override;
|
||||
|
||||
void setTexture(const S32 face);
|
||||
S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
|
||||
/*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
|
||||
/*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
|
||||
void updateSculptTexture();
|
||||
void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
|
||||
void sculpt();
|
||||
|
|
@ -232,21 +232,21 @@ public:
|
|||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
void updateRelativeXform(bool force_identity = false);
|
||||
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
|
||||
/*virtual*/ void updateFaceSize(S32 idx);
|
||||
/*virtual*/ BOOL updateLOD();
|
||||
void updateRadius();
|
||||
/*virtual*/ void updateTextures();
|
||||
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override;
|
||||
/*virtual*/ void updateFaceSize(S32 idx) override;
|
||||
/*virtual*/ BOOL updateLOD() override;
|
||||
void updateRadius() override;
|
||||
/*virtual*/ void updateTextures() override;
|
||||
void updateTextureVirtualSize(bool forced = false);
|
||||
|
||||
void updateFaceFlags();
|
||||
void regenFaces();
|
||||
BOOL genBBoxes(BOOL force_global);
|
||||
void preRebuild();
|
||||
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
|
||||
virtual F32 getBinRadius();
|
||||
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override;
|
||||
virtual F32 getBinRadius() override;
|
||||
|
||||
virtual U32 getPartitionType() const;
|
||||
virtual U32 getPartitionType() const override;
|
||||
|
||||
// For Lights
|
||||
void setIsLight(BOOL is_light);
|
||||
|
|
@ -305,11 +305,11 @@ public:
|
|||
|
||||
// Flexible Objects
|
||||
U32 getVolumeInterfaceID() const;
|
||||
virtual BOOL isFlexible() const;
|
||||
virtual BOOL isSculpted() const;
|
||||
virtual BOOL isMesh() const;
|
||||
virtual BOOL isRiggedMesh() const;
|
||||
virtual BOOL hasLightTexture() const;
|
||||
virtual BOOL isFlexible() const override;
|
||||
virtual BOOL isSculpted() const override;
|
||||
virtual BOOL isMesh() const override;
|
||||
virtual BOOL isRiggedMesh() const override;
|
||||
virtual BOOL hasLightTexture() const override;
|
||||
|
||||
|
||||
BOOL isVolumeGlobal() const;
|
||||
|
|
@ -326,12 +326,12 @@ public:
|
|||
void onSetExtendedMeshFlags(U32 flags);
|
||||
void setExtendedMeshFlags(U32 flags);
|
||||
bool canBeAnimatedObject() const;
|
||||
bool isAnimatedObject() const;
|
||||
virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
|
||||
virtual void afterReparent();
|
||||
bool isAnimatedObject() const override;
|
||||
virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent) override;
|
||||
virtual void afterReparent() override;
|
||||
|
||||
//virtual
|
||||
void updateRiggingInfo();
|
||||
void updateRiggingInfo() override;
|
||||
S32 mLastRiggingInfoLOD;
|
||||
|
||||
// Functions that deal with media, or media navigation
|
||||
|
|
|
|||
|
|
@ -299,29 +299,33 @@ static LLStaticHashedString sKern("kern");
|
|||
static LLStaticHashedString sKernScale("kern_scale");
|
||||
|
||||
//----------------------------------------
|
||||
std::string gPoolNames[] =
|
||||
#if 0
|
||||
std::string gPoolNames[LLDrawPool::NUM_POOL_TYPES] =
|
||||
{
|
||||
// Correspond to LLDrawpool enum render type
|
||||
"NONE",
|
||||
"POOL_SIMPLE",
|
||||
"POOL_GROUND",
|
||||
"POOL_FULLBRIGHT",
|
||||
"POOL_BUMP",
|
||||
"POOL_MATERIALS",
|
||||
"POOL_TERRAIN",
|
||||
"POOL_SKY",
|
||||
"POOL_WL_SKY",
|
||||
"POOL_TREE",
|
||||
"POOL_ALPHA_MASK",
|
||||
"POOL_FULLBRIGHT_ALPHA_MASK",
|
||||
"POOL_GRASS",
|
||||
"POOL_INVISIBLE",
|
||||
"POOL_AVATAR",
|
||||
"POOL_VOIDWATER",
|
||||
"POOL_WATER",
|
||||
"POOL_GLOW",
|
||||
"POOL_ALPHA"
|
||||
"NONE"
|
||||
, "POOL_SIMPLE"
|
||||
, "POOL_GROUND"
|
||||
, "POOL_FULLBRIGHT"
|
||||
, "POOL_BUMP"
|
||||
, "POOL_MATERIALS"
|
||||
, "POOL_TERRAIN"
|
||||
, "POOL_SKY"
|
||||
, "POOL_WL_SKY"
|
||||
, "POOL_TREE"
|
||||
, "POOL_ALPHA_MASK"
|
||||
, "POOL_FULLBRIGHT_ALPHA_MASK"
|
||||
, "POOL_GRASS"
|
||||
, "POOL_INVISIBLE"
|
||||
, "POOL_AVATAR"
|
||||
, "POOL_CONTROL_AV" // Animesh
|
||||
, "POOL_VOIDWATER"
|
||||
, "POOL_WATER"
|
||||
, "POOL_GLOW"
|
||||
, "POOL_ALPHA"
|
||||
, "POOL_PBR_OPAQUE"
|
||||
};
|
||||
#endif
|
||||
|
||||
void drawBox(const LLVector4a& c, const LLVector4a& r);
|
||||
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
|
||||
|
|
@ -396,8 +400,12 @@ void validate_framebuffer_object();
|
|||
// for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions)
|
||||
bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
|
||||
{
|
||||
return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular
|
||||
target.addColorAttachment(GL_RGB10_A2); //normal+z
|
||||
bool pbr = gSavedSettings.getBOOL("RenderPBR");
|
||||
bool valid = true
|
||||
&& target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) // frag-data[1] specular or PBR packed OcclusionRoughnessMetal
|
||||
&& target.addColorAttachment(GL_RGB10_A2) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
|
||||
&& (pbr ? target.addColorAttachment(GL_RGBA) : true); // frag_data[3] emissive
|
||||
return valid;
|
||||
}
|
||||
|
||||
LLPipeline::LLPipeline() :
|
||||
|
|
@ -464,7 +472,7 @@ void LLPipeline::init()
|
|||
{
|
||||
refreshCachedSettings();
|
||||
|
||||
mRT = new RenderTargetPack();
|
||||
mRT = &mMainRT;
|
||||
|
||||
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
|
||||
gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
|
||||
|
|
@ -763,9 +771,6 @@ void LLPipeline::cleanup()
|
|||
mDeferredVB = NULL;
|
||||
|
||||
mCubeVB = NULL;
|
||||
|
||||
delete mRT;
|
||||
mRT = nullptr;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -925,6 +930,16 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
|
|||
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
if (mRT == &mMainRT)
|
||||
{ // hacky -- allocate auxillary buffer
|
||||
gCubeSnapshot = TRUE;
|
||||
mRT = &mAuxillaryRT;
|
||||
U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2;
|
||||
allocateScreenBuffer(res, res, 0);
|
||||
mRT = &mMainRT;
|
||||
gCubeSnapshot = FALSE;
|
||||
}
|
||||
|
||||
// remember these dimensions
|
||||
mRT->width = resX;
|
||||
mRT->height = resY;
|
||||
|
|
@ -1791,6 +1806,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
|
|||
}
|
||||
|
||||
LLMaterial* mat = te->getMaterialParams().get();
|
||||
LLGLTFMaterial* gltf_mat = te->getGLTFMaterial();
|
||||
|
||||
bool color_alpha = te->getColor().mV[3] < 0.999f;
|
||||
bool alpha = color_alpha;
|
||||
|
|
@ -1824,6 +1840,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
|
|||
{
|
||||
return LLDrawPool::POOL_BUMP;
|
||||
}
|
||||
else if (gltf_mat && !alpha)
|
||||
{
|
||||
return LLDrawPool::POOL_PBR_OPAQUE;
|
||||
}
|
||||
else if (mat && !alpha)
|
||||
{
|
||||
return LLDrawPool::POOL_MATERIALS;
|
||||
|
|
@ -8930,6 +8950,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
|
|||
soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
|
||||
soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
|
||||
|
||||
if(LLPipeline::sRenderPBR)
|
||||
{
|
||||
LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis();
|
||||
soften_shader.uniform3fv(LLShaderMgr::DEFERRED_VIEW_DIR, 1, cameraAtAxis.mV);
|
||||
}
|
||||
|
||||
{
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
|
|
@ -9543,10 +9569,22 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
|
|||
void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
|
||||
{
|
||||
S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
|
||||
bool bound = false;
|
||||
if (channel > -1 && mReflectionMapManager.mTexture.notNull())
|
||||
{
|
||||
// see comments in class2/deferred/softenLightF.glsl for what these uniforms mean
|
||||
mReflectionMapManager.mTexture->bind(channel);
|
||||
bound = true;
|
||||
}
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
|
||||
if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull())
|
||||
{
|
||||
mReflectionMapManager.mIrradianceMaps->bind(channel);
|
||||
bound = true;
|
||||
}
|
||||
|
||||
if (bound)
|
||||
{
|
||||
mReflectionMapManager.setUniforms();
|
||||
|
||||
F32* m = gGLModelView;
|
||||
|
|
|
|||
|
|
@ -538,6 +538,8 @@ public:
|
|||
RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,
|
||||
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
|
||||
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
|
||||
RENDER_TYPE_PASS_PBR_OPAQUE = LLRenderPass::PASS_PBR_OPAQUE,
|
||||
RENDER_TYPE_PASS_PBR_OPAQUE_RIGGED = LLRenderPass::PASS_PBR_OPAQUE_RIGGED,
|
||||
// Following are object types (only used in drawable mRenderType)
|
||||
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
|
||||
RENDER_TYPE_VOLUME,
|
||||
|
|
@ -687,6 +689,13 @@ public:
|
|||
LLRenderTarget shadowOcclusion[4];
|
||||
};
|
||||
|
||||
// main full resoltuion render target
|
||||
RenderTargetPack mMainRT;
|
||||
|
||||
// auxillary 512x512 render target pack
|
||||
RenderTargetPack mAuxillaryRT;
|
||||
|
||||
// currently used render target pack
|
||||
RenderTargetPack* mRT;
|
||||
|
||||
LLRenderTarget mSpotShadow[2];
|
||||
|
|
|
|||
|
|
@ -157,6 +157,13 @@
|
|||
function="Inventory.DoCreate"
|
||||
parameter="gesture" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
name="inventory_new_material"
|
||||
label="New Material">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="material" />
|
||||
</menu_item_call>
|
||||
<menu
|
||||
name="inventory_new_clothes"
|
||||
label="New Clothes">
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 684 B |
|
|
@ -329,6 +329,7 @@ with the same filename but different name
|
|||
<texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" />
|
||||
<texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" />
|
||||
<texture name="Inv_LandmarkVisited" file_name="icons/Inv_Landmark.png" preload="false" />
|
||||
<texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" />
|
||||
<texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" />
|
||||
<texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" />
|
||||
<texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" />
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<floater
|
||||
legacy_header_height="18"
|
||||
can_minimize="false"
|
||||
height="528"
|
||||
height="548"
|
||||
layout="topleft"
|
||||
name="Inventory Finder"
|
||||
help_topic="inventory_finder"
|
||||
|
|
@ -94,6 +94,23 @@
|
|||
name="check_landmark"
|
||||
top_delta="0"
|
||||
width="126" />
|
||||
<icon
|
||||
height="16"
|
||||
image_name="Inv_Material"
|
||||
layout="topleft"
|
||||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_material"
|
||||
top="122"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
label="Materials"
|
||||
layout="topleft"
|
||||
left_pad="2"
|
||||
name="check_material"
|
||||
top_delta="0"
|
||||
width="126" />
|
||||
<icon
|
||||
height="16"
|
||||
image_name="Inv_Notecard"
|
||||
|
|
@ -101,7 +118,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_notecard"
|
||||
top="122"
|
||||
top="142"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -118,7 +135,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_object"
|
||||
top="142"
|
||||
top="162"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -135,7 +152,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_script"
|
||||
top="162"
|
||||
top="182"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -152,7 +169,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_sound"
|
||||
top="182"
|
||||
top="202"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -169,7 +186,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_texture"
|
||||
top="202"
|
||||
top="222"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -186,7 +203,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_snapshot"
|
||||
top="222"
|
||||
top="242"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -203,7 +220,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_settings"
|
||||
top="242"
|
||||
top="262"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -221,7 +238,7 @@
|
|||
layout="topleft"
|
||||
left="8"
|
||||
name="All"
|
||||
top="262"
|
||||
top="282"
|
||||
width="100" />
|
||||
<button
|
||||
height="20"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,499 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
can_resize="false"
|
||||
default_tab_group="1"
|
||||
height="887"
|
||||
layout="topleft"
|
||||
name="material editor"
|
||||
help_topic="material_editor"
|
||||
title="[MATERIAL_NAME]"
|
||||
width="256">
|
||||
<string name="no_upload_fee_string">no upload fee</string>
|
||||
<string name="upload_fee_string">L$10 upload fee</string>
|
||||
<check_box
|
||||
follows="left|top"
|
||||
label="Double Sided"
|
||||
left="14"
|
||||
top="14"
|
||||
name="double sided"
|
||||
height="25"
|
||||
width="120" />
|
||||
<panel
|
||||
border="true"
|
||||
follows="left|top"
|
||||
width="246"
|
||||
height="196"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
mouse_opaque="false"
|
||||
name="albedo_texture_pnl"
|
||||
top_pad="5"
|
||||
>
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="5"
|
||||
width="64">
|
||||
Albedo:
|
||||
</text>
|
||||
<texture_picker
|
||||
can_apply_immediately="false"
|
||||
default_image_name="Default"
|
||||
fallback_image="materials_ui_x_24.png"
|
||||
allow_no_texture="true"
|
||||
follows="left|top"
|
||||
top_pad="8"
|
||||
height="151"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="albedo_texture"
|
||||
tool_tip="Albedo map. Alpha channel is optional and used for transparency."
|
||||
width="128" />
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="128"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="-17"
|
||||
name="albedo_upload_fee"
|
||||
>
|
||||
No upload fee
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
top="8"
|
||||
>
|
||||
Tint
|
||||
</text>
|
||||
<color_swatch
|
||||
can_apply_immediately="false"
|
||||
follows="left|top"
|
||||
height="40"
|
||||
label_height="0"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
name="albedo color"
|
||||
width="40" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
width="96"
|
||||
>
|
||||
Transparency
|
||||
</text>
|
||||
<spinner
|
||||
decimal_digits="3"
|
||||
follows="left|top"
|
||||
height="19"
|
||||
increment="0.01"
|
||||
initial_value="1"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
max_val="1"
|
||||
name="transparency"
|
||||
width="64"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="label alphamode"
|
||||
text_readonly_color="LabelDisabledColor"
|
||||
top_pad="5"
|
||||
width="90">
|
||||
Alpha mode
|
||||
</text>
|
||||
<combo_box
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="alpha mode"
|
||||
top_pad="4"
|
||||
width="96">
|
||||
<combo_box.item
|
||||
label="None"
|
||||
name="None"
|
||||
value="OPAQUE" />
|
||||
<combo_box.item
|
||||
label="Alpha blending"
|
||||
name="Alpha blending"
|
||||
value="BLEND" />
|
||||
<combo_box.item
|
||||
label="Alpha masking"
|
||||
name="Alpha masking"
|
||||
value="MASK" />
|
||||
</combo_box>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
width="96"
|
||||
>
|
||||
Alpha Cutoff
|
||||
</text>
|
||||
<spinner
|
||||
decimal_digits="3"
|
||||
follows="left|top"
|
||||
height="19"
|
||||
increment="0.01"
|
||||
initial_value="1"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
max_val="1"
|
||||
name="alpha cutoff"
|
||||
width="64"
|
||||
/>
|
||||
</panel>
|
||||
<panel
|
||||
border="true"
|
||||
follows="left|top"
|
||||
width="246"
|
||||
height="175"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
mouse_opaque="false"
|
||||
name="metallic_texture_pnl"
|
||||
top_pad="5"
|
||||
>
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="5"
|
||||
>
|
||||
Metallic-Roughness:
|
||||
</text>
|
||||
<texture_picker
|
||||
can_apply_immediately="false"
|
||||
default_image_name="Default"
|
||||
fallback_image="materials_ui_x_24.png"
|
||||
allow_no_texture="true"
|
||||
follows="left|top"
|
||||
width="128"
|
||||
height="151"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="metallic_roughness_texture"
|
||||
tool_tip="GLTF metallic-roughness map with optional occlusion. Red channel is occlusion, green channel is roughness, blue channel is metalness."
|
||||
top_pad="8"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="128"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="-17"
|
||||
name="metallic_upload_fee"
|
||||
>
|
||||
No upload fee
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
top="8"
|
||||
>
|
||||
Metallic Factor
|
||||
</text>
|
||||
<spinner
|
||||
decimal_digits="3"
|
||||
follows="left|top"
|
||||
height="19"
|
||||
increment="0.01"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
max_val="100"
|
||||
name="metalness factor"
|
||||
width="64"
|
||||
/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
width="96"
|
||||
>
|
||||
Roughness Factor
|
||||
</text>
|
||||
<spinner
|
||||
decimal_digits="3"
|
||||
follows="left|top"
|
||||
height="19"
|
||||
increment="0.01"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
max_val="100"
|
||||
name="roughness factor"
|
||||
width="64"
|
||||
/>
|
||||
</panel>
|
||||
<panel
|
||||
border="true"
|
||||
follows="left|top"
|
||||
width="246"
|
||||
height="175"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
mouse_opaque="false"
|
||||
name="emissive_texture_pnl"
|
||||
top_pad="5"
|
||||
>
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="5"
|
||||
width="64">
|
||||
Emissive:
|
||||
</text>
|
||||
<texture_picker
|
||||
can_apply_immediately="false"
|
||||
default_image_name="Default"
|
||||
fallback_image="materials_ui_x_24.png"
|
||||
allow_no_texture="true"
|
||||
follows="left|top"
|
||||
top_pad="8"
|
||||
height="151"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="emissive_texture"
|
||||
width="128" />
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="128"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="-17"
|
||||
name="emissive_upload_fee"
|
||||
>
|
||||
No upload fee
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
top="8"
|
||||
>
|
||||
Tint
|
||||
</text>
|
||||
<color_swatch
|
||||
can_apply_immediately="false"
|
||||
follows="left|top"
|
||||
height="40"
|
||||
label_height="0"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
name="emissive color"
|
||||
width="40" />
|
||||
<!--<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="64"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
>
|
||||
Intensity
|
||||
</text>
|
||||
<spinner
|
||||
decimal_digits="3"
|
||||
follows="left|top"
|
||||
height="19"
|
||||
increment="0.01"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_pad="5"
|
||||
max_val="100"
|
||||
width="64"
|
||||
/>-->
|
||||
</panel>
|
||||
<panel
|
||||
border="true"
|
||||
follows="left|top"
|
||||
width="246"
|
||||
height="175"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
mouse_opaque="false"
|
||||
top_pad="5"
|
||||
name="normal_texture_pnl"
|
||||
>
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="5"
|
||||
width="64">
|
||||
Normal:
|
||||
</text>
|
||||
<texture_picker
|
||||
can_apply_immediately="false"
|
||||
default_image_name="Default"
|
||||
fallback_image="materials_ui_x_24.png"
|
||||
allow_no_texture="true"
|
||||
follows="left|top"
|
||||
top_pad="8"
|
||||
height="151"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="normal_texture"
|
||||
width="128" />
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="128"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="-17"
|
||||
name="normal_upload_fee"
|
||||
>
|
||||
No upload fee
|
||||
</text>
|
||||
</panel>
|
||||
|
||||
<panel
|
||||
follows="right|bottom"
|
||||
width="246"
|
||||
height="97"
|
||||
layout="bottomright"
|
||||
top_delta="-2"
|
||||
left="5"
|
||||
name="button_panel"
|
||||
>
|
||||
<text
|
||||
type="string"
|
||||
name="unsaved_changes"
|
||||
font.style="BOLD"
|
||||
text_color="DrYellow"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="200"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="0"
|
||||
>
|
||||
Usaved changes
|
||||
</text>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="25"
|
||||
label="Save"
|
||||
layout="topleft"
|
||||
name="save"
|
||||
top_pad="7"
|
||||
left="0"
|
||||
width="120" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="25"
|
||||
label="Save As..."
|
||||
layout="topleft"
|
||||
name="save_as"
|
||||
top_delta="0"
|
||||
left_pad="6"
|
||||
width="120" />
|
||||
<text
|
||||
type="string"
|
||||
font.style="BOLD"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
width="220"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="5"
|
||||
>
|
||||
Total upload fee: L$ [FEE]
|
||||
</text>
|
||||
|
||||
<view_border
|
||||
bevel_style="none"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="button_border"
|
||||
top_pad="7"
|
||||
width="246"/>
|
||||
|
||||
<button
|
||||
follows="left|top"
|
||||
height="25"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
name="cancel"
|
||||
top_pad="7"
|
||||
left="61"
|
||||
width="121" />
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -183,6 +183,14 @@
|
|||
function="Inventory.DoCreate"
|
||||
parameter="gesture" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Material"
|
||||
layout="topleft"
|
||||
name="New Material">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="material" />
|
||||
</menu_item_call>
|
||||
<menu
|
||||
label="New Clothes"
|
||||
layout="topleft"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue