# 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.xml
master
Ansariel 2022-06-27 17:58:22 +02:00
commit 536e958018
106 changed files with 3536 additions and 418 deletions

View File

@ -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>

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1,5 @@
# -*- cmake -*-
include(Prebuilt)
use_prebuilt_binary(vulkan_gltf)

View File

@ -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));

View File

@ -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()
{

View File

@ -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);

View File

@ -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));
}

View File

@ -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();

View File

@ -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);

View File

@ -58,6 +58,7 @@ set(llprimitive_HEADER_FILES
CMakeLists.txt
lldaeloader.h
llgltfloader.h
llgltfmaterial.h
legacy_object_types.h
llmaterial.h
llmaterialid.h

View File

@ -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)

View File

@ -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

View File

@ -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;
}
}
};

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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)

View File

@ -124,6 +124,7 @@ public:
BOOL mHasAnisotropic;
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasCubeMapArray;
BOOL mHasDebugOutput;
BOOL mHassRGBTexture;
BOOL mHassRGBFramebuffer;

View File

@ -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"

View File

@ -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

View File

@ -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");

View File

@ -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"

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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?
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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);
}
// =============================================================================================================

View File

@ -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;
}

View File

@ -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);
}
// =============================================================================================================

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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);

View File

@ -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
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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.

View File

@ -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.

View File

@ -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,
};

View File

@ -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);
}
}

View File

@ -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; }

View File

@ -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];

View File

@ -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";

View File

@ -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
};

View File

@ -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"));

View File

@ -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");

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
};

View File

@ -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()

View File

@ -79,6 +79,7 @@ private:
void onMoistureLevelChanged();
void onDropletRadiusChanged();
void onIceLevelChanged();
void onReflectionProbeAmbianceChanged();
};

View File

@ -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);

View File

@ -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()

View File

@ -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
{

View File

@ -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];

View File

@ -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
}

View File

@ -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;

View File

@ -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 ),

View File

@ -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),

View File

@ -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>);

View File

@ -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);

View File

@ -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");

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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];

View File

@ -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

View File

@ -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" />

View File

@ -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"

View File

@ -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>

View File

@ -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