Merge branch 'DRTVWR-559' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/app_settings/settings.xml # indra/newview/llreflectionmapmanager.cpp # indra/newview/llspatialpartition.cpp # indra/newview/llviewercontrol.cpp # indra/newview/llviewerdisplay.cpp # indra/newview/llviewermenu.cpp # indra/newview/llviewershadermgr.cpp # indra/newview/llworldmapview.cpp # indra/newview/pipeline.cpp # indra/newview/skins/default/xui/en/panel_tools_texture.xmlmaster
commit
f4182ddc7f
|
|
@ -3078,7 +3078,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-tracy</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2017-2021, Bartosz Taudul (wolf@nereid.pl)</string>
|
||||
<string>Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl)</string>
|
||||
<key>description</key>
|
||||
<string>Tracy Profiler Library</string>
|
||||
<key>license</key>
|
||||
|
|
@ -3094,9 +3094,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>da7317e4a81609f624f84780f28b07de</string>
|
||||
<string>9b6e1a1f4b0969d38a1ca8ee00aeb548</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86972/801630/tracy-v0.7.8.563351-darwin64-563351.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110584/960613/tracy-v0.8.1.578241-darwin64-578241.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3106,11 +3106,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>47c696cd2966c5cc3c8ba6115dd1f886</string>
|
||||
<string>9e6975565d7337442259324e68bcf59c</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/86973/801641/tracy-v0.7.8.563351-windows-563351.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110585/960636/tracy-v0.8.1.578241-windows-578241.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3120,11 +3120,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>dff3dd1db6a4cb0b73f60a5db3ee0de2</string>
|
||||
<string>05b72ae5d733aed7d3bf142287601cc6</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/100101/882119/tracy-v0.8.1.571983-windows64-571983.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110586/960637/tracy-v0.8.1.578241-windows64-578241.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
@ -3135,7 +3135,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>git</string>
|
||||
<key>version</key>
|
||||
<string>v0.7.8.563351</string>
|
||||
<string>v0.8.1.578241</string>
|
||||
</map>
|
||||
<key>tut</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ else (LINUX)
|
|||
${BOOST_CONTEXT_LIBRARY}
|
||||
${BOOST_THREAD_LIBRARY}
|
||||
${BOOST_SYSTEM_LIBRARY}
|
||||
${TRACY_LIBRARY}
|
||||
)
|
||||
endif (LINUX)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@ if (USE_TRACY)
|
|||
|
||||
if (DARWIN)
|
||||
MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'")
|
||||
set(TRACY_LIBRARY "TracyClient")
|
||||
endif (DARWIN)
|
||||
|
||||
if (LINUX)
|
||||
MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'")
|
||||
set(TRACY_LIBRARY "TracyClient")
|
||||
endif (LINUX)
|
||||
else (USE_TRACY)
|
||||
# Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "lltimer.h"
|
||||
#include "llthread.h"
|
||||
#include "llmutex.h"
|
||||
#include "llmd5.h"
|
||||
#include "hbxxh.h"
|
||||
|
||||
#include "llprofiler.h"
|
||||
|
|
@ -404,11 +405,16 @@ LLUUID LLUUID::operator^(const LLUUID& rhs) const
|
|||
return id;
|
||||
}
|
||||
|
||||
// WARNING: this algorithm SHALL NOT be changed. It is also used by the server
|
||||
// and plays a role in some assets validation (e.g. clothing items). Changing
|
||||
// it would cause invalid assets.
|
||||
void LLUUID::combine(const LLUUID& other, LLUUID& result) const
|
||||
{
|
||||
HBXXH128 hash((const void*)mData, 16, false); // false = do not finalize
|
||||
hash.update((const void*)other.mData, 16);
|
||||
hash.digest(result);
|
||||
LLMD5 md5_uuid;
|
||||
md5_uuid.update((unsigned char*)mData, 16);
|
||||
md5_uuid.update((unsigned char*)other.mData, 16);
|
||||
md5_uuid.finalize();
|
||||
md5_uuid.raw_digest(result.mData);
|
||||
}
|
||||
|
||||
LLUUID LLUUID::combine(const LLUUID &other) const
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ if (LL_TESTS)
|
|||
SET(llprimitive_TEST_SOURCE_FILES
|
||||
llmediaentry.cpp
|
||||
llprimitive.cpp
|
||||
llgltfmaterial.cpp
|
||||
)
|
||||
|
||||
LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
|
||||
endif (LL_TESTS)
|
||||
|
|
|
|||
|
|
@ -31,34 +31,28 @@
|
|||
// NOTE -- this should be the one and only place tiny_gltf.h is included
|
||||
#include "tinygltf/tiny_gltf.h"
|
||||
|
||||
const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
|
||||
const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
|
||||
const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
|
||||
const char* GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
|
||||
const char* const LLGLTFMaterial::ASSET_VERSION = "1.1";
|
||||
const char* const LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0";
|
||||
const std::array<std::string, 2> LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" };
|
||||
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform";
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale";
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset";
|
||||
const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
|
||||
|
||||
// special UUID that indicates a null UUID in override data
|
||||
static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
|
||||
|
||||
// https://github.com/KhronosGroup/glTF/tree/main/extensions/3.0/Khronos/KHR_texture_transform
|
||||
LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix()
|
||||
void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8])
|
||||
{
|
||||
LLMatrix3 scale;
|
||||
scale.mMatrix[0][0] = mScale[0];
|
||||
scale.mMatrix[1][1] = mScale[1];
|
||||
|
||||
LLMatrix3 rotation;
|
||||
const F32 cos_r = cos(mRotation);
|
||||
const F32 sin_r = sin(mRotation);
|
||||
rotation.mMatrix[0][0] = cos_r;
|
||||
rotation.mMatrix[0][1] = sin_r;
|
||||
rotation.mMatrix[1][0] = -sin_r;
|
||||
rotation.mMatrix[1][1] = cos_r;
|
||||
|
||||
LLMatrix3 offset;
|
||||
offset.mMatrix[2][0] = mOffset[0];
|
||||
offset.mMatrix[2][1] = mOffset[1];
|
||||
|
||||
return offset * rotation * scale;
|
||||
packed[0] = mScale.mV[VX];
|
||||
packed[1] = mScale.mV[VY];
|
||||
packed[2] = mRotation;
|
||||
// packed[3] = unused
|
||||
packed[4] = mOffset.mV[VX];
|
||||
packed[5] = mOffset.mV[VY];
|
||||
// packed[6] = unused
|
||||
// packed[7] = unused
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::TextureTransform::operator==(const TextureTransform& other) const
|
||||
|
|
@ -73,16 +67,14 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs)
|
|||
|
||||
LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
//have to do a manual operator= because of LLRefCount
|
||||
mBaseColorId = rhs.mBaseColorId;
|
||||
mNormalId = rhs.mNormalId;
|
||||
mMetallicRoughnessId = rhs.mMetallicRoughnessId;
|
||||
mEmissiveId = rhs.mEmissiveId;
|
||||
//have to do a manual operator= because of LLRefCount
|
||||
mTextureId = rhs.mTextureId;
|
||||
|
||||
mTextureTransform = rhs.mTextureTransform;
|
||||
|
||||
mBaseColor = rhs.mBaseColor;
|
||||
mEmissiveColor = rhs.mEmissiveColor;
|
||||
|
||||
|
||||
mMetallicFactor = rhs.mMetallicFactor;
|
||||
mRoughnessFactor = rhs.mRoughnessFactor;
|
||||
mAlphaCutoff = rhs.mAlphaCutoff;
|
||||
|
|
@ -90,8 +82,6 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
|
|||
mDoubleSided = rhs.mDoubleSided;
|
||||
mAlphaMode = rhs.mAlphaMode;
|
||||
|
||||
mTextureTransform = rhs.mTextureTransform;
|
||||
|
||||
mOverrideDoubleSided = rhs.mOverrideDoubleSided;
|
||||
mOverrideAlphaMode = rhs.mOverrideAlphaMode;
|
||||
|
||||
|
|
@ -100,10 +90,9 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
|
|||
|
||||
bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
|
||||
{
|
||||
return mBaseColorId == rhs.mBaseColorId &&
|
||||
mNormalId == rhs.mNormalId &&
|
||||
mMetallicRoughnessId == rhs.mMetallicRoughnessId &&
|
||||
mEmissiveId == rhs.mEmissiveId &&
|
||||
return mTextureId == rhs.mTextureId &&
|
||||
|
||||
mTextureTransform == rhs.mTextureTransform &&
|
||||
|
||||
mBaseColor == rhs.mBaseColor &&
|
||||
mEmissiveColor == rhs.mEmissiveColor &&
|
||||
|
|
@ -115,8 +104,6 @@ bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
|
|||
mDoubleSided == rhs.mDoubleSided &&
|
||||
mAlphaMode == rhs.mAlphaMode &&
|
||||
|
||||
mTextureTransform == rhs.mTextureTransform &&
|
||||
|
||||
mOverrideDoubleSided == rhs.mOverrideDoubleSided &&
|
||||
mOverrideAlphaMode == rhs.mOverrideAlphaMode;
|
||||
}
|
||||
|
|
@ -148,6 +135,8 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const
|
|||
|
||||
writeToModel(model_out, 0);
|
||||
|
||||
// To ensure consistency in asset upload, this should be the only reference
|
||||
// to WriteGltfSceneToStream in the viewer.
|
||||
gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false);
|
||||
|
||||
return str.str();
|
||||
|
|
@ -164,13 +153,13 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index)
|
|||
const tinygltf::Material& material_in = model.materials[mat_index];
|
||||
|
||||
// Apply base color texture
|
||||
setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId);
|
||||
setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR);
|
||||
// Apply normal map
|
||||
setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId);
|
||||
setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL);
|
||||
// Apply metallic-roughness texture
|
||||
setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId);
|
||||
setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS);
|
||||
// Apply emissive texture
|
||||
setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId);
|
||||
setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE);
|
||||
|
||||
setAlphaMode(material_in.alphaMode);
|
||||
mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f);
|
||||
|
|
@ -264,11 +253,11 @@ std::string gltf_get_texture_image(const tinygltf::Model& model, const T& textur
|
|||
|
||||
// *NOTE: Use template here as workaround for the different similar texture info classes
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out)
|
||||
void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
const std::string uri = gltf_get_texture_image(model, texture_info);
|
||||
texture_id_out.set(uri);
|
||||
mTextureId[texture_info_id].set(uri);
|
||||
|
||||
const tinygltf::Value::Object& extensions_object = texture_info.extensions;
|
||||
const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM);
|
||||
|
|
@ -297,21 +286,24 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
|
|||
tinygltf::Material& material_out = model.materials[mat_index];
|
||||
|
||||
// set base color texture
|
||||
writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId);
|
||||
writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR);
|
||||
// set normal texture
|
||||
writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId);
|
||||
writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL);
|
||||
// set metallic-roughness texture
|
||||
writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId);
|
||||
writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS);
|
||||
// set emissive texture
|
||||
writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId);
|
||||
writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE);
|
||||
// set occlusion texture
|
||||
// *NOTE: This is required for ORM materials for GLTF compliance.
|
||||
// See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_material_occlusiontexture
|
||||
writeToTexture(model, material_out.occlusionTexture, GLTF_TEXTURE_INFO_OCCLUSION);
|
||||
|
||||
|
||||
material_out.alphaMode = getAlphaMode();
|
||||
material_out.alphaCutoff = mAlphaCutoff;
|
||||
|
||||
|
||||
mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor);
|
||||
|
||||
material_out.emissiveFactor.resize(3); // 0 size by default
|
||||
|
||||
if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor())
|
||||
{
|
||||
material_out.emissiveFactor.resize(3);
|
||||
|
|
@ -323,7 +315,6 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const
|
|||
|
||||
material_out.doubleSided = mDoubleSided;
|
||||
|
||||
|
||||
// generate "extras" string
|
||||
tinygltf::Value::Object extras;
|
||||
bool write_extras = false;
|
||||
|
|
@ -364,28 +355,43 @@ void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const
|
||||
void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
const LLUUID& texture_id = mTextureId[texture_info_id];
|
||||
const TextureTransform& transform = mTextureTransform[texture_info_id];
|
||||
if (texture_id.isNull() && transform == sDefault.mTextureTransform[0])
|
||||
const bool is_blank_transform = transform == sDefault.mTextureTransform[0];
|
||||
// Check if this material matches all the fallback values, and if so, then
|
||||
// skip including it to reduce material size
|
||||
if (!force_write && texture_id.isNull() && is_blank_transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// tinygltf will discard this texture info if there is no valid texture,
|
||||
// causing potential loss of information for overrides, so ensure one is
|
||||
// defined. -Cosmic,2023-01-30
|
||||
gltf_allocate_texture_image(model, texture_info, texture_id.asString());
|
||||
|
||||
tinygltf::Value::Object transform_map;
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mOffset.mV[VX]),
|
||||
tinygltf::Value(transform.mOffset.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mScale.mV[VX]),
|
||||
tinygltf::Value(transform.mScale.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
|
||||
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
|
||||
if (!is_blank_transform)
|
||||
{
|
||||
tinygltf::Value::Object transform_map;
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mOffset.mV[VX]),
|
||||
tinygltf::Value(transform.mOffset.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({
|
||||
tinygltf::Value(transform.mScale.mV[VX]),
|
||||
tinygltf::Value(transform.mScale.mV[VY])
|
||||
}));
|
||||
transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation);
|
||||
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::sanitizeAssetMaterial()
|
||||
{
|
||||
mTextureTransform = sDefault.mTextureTransform;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::setBaseMaterial()
|
||||
|
|
@ -419,40 +425,33 @@ void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override)
|
||||
void LLGLTFMaterial::setTextureId(TextureInfo texture_info, const LLUUID& id, bool for_override)
|
||||
{
|
||||
mBaseColorId = id;
|
||||
mTextureId[texture_info] = id;
|
||||
if (for_override)
|
||||
{
|
||||
hackOverrideUUID(mBaseColorId);
|
||||
hackOverrideUUID(mTextureId[texture_info]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override)
|
||||
{
|
||||
setTextureId(GLTF_TEXTURE_INFO_BASE_COLOR, id, for_override);
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setNormalId(const LLUUID& id, bool for_override)
|
||||
{
|
||||
mNormalId = id;
|
||||
if (for_override)
|
||||
{
|
||||
hackOverrideUUID(mNormalId);
|
||||
}
|
||||
setTextureId(GLTF_TEXTURE_INFO_NORMAL, id, for_override);
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id, bool for_override)
|
||||
void LLGLTFMaterial::setOcclusionRoughnessMetallicId(const LLUUID& id, bool for_override)
|
||||
{
|
||||
mMetallicRoughnessId = id;
|
||||
if (for_override)
|
||||
{
|
||||
hackOverrideUUID(mMetallicRoughnessId);
|
||||
}
|
||||
setTextureId(GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, id, for_override);
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setEmissiveId(const LLUUID& id, bool for_override)
|
||||
{
|
||||
mEmissiveId = id;
|
||||
if (for_override)
|
||||
{
|
||||
hackOverrideUUID(mEmissiveId);
|
||||
}
|
||||
setTextureId(GLTF_TEXTURE_INFO_EMISSIVE, id, for_override);
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setBaseColorFactor(const LLColor4& baseColor, bool for_override)
|
||||
|
|
@ -533,10 +532,7 @@ const char* LLGLTFMaterial::getAlphaMode() const
|
|||
void LLGLTFMaterial::setAlphaMode(S32 mode, bool for_override)
|
||||
{
|
||||
mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK);
|
||||
if (for_override)
|
||||
{
|
||||
mOverrideAlphaMode = true;
|
||||
}
|
||||
mOverrideAlphaMode = for_override && mAlphaMode == getDefaultAlphaMode();
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override)
|
||||
|
|
@ -544,10 +540,7 @@ void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override)
|
|||
// sure, no clamping will ever be needed for a bool, but include the
|
||||
// setter for consistency with the clamping API
|
||||
mDoubleSided = double_sided;
|
||||
if (for_override)
|
||||
{
|
||||
mOverrideDoubleSided = true;
|
||||
}
|
||||
mOverrideDoubleSided = for_override && mDoubleSided == getDefaultDoubleSided();
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset)
|
||||
|
|
@ -640,10 +633,12 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
applyOverrideUUID(mBaseColorId, override_mat.mBaseColorId);
|
||||
applyOverrideUUID(mNormalId, override_mat.mNormalId);
|
||||
applyOverrideUUID(mMetallicRoughnessId, override_mat.mMetallicRoughnessId);
|
||||
applyOverrideUUID(mEmissiveId, override_mat.mEmissiveId);
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLUUID& texture_id = mTextureId[i];
|
||||
const LLUUID& override_texture_id = override_mat.mTextureId[i];
|
||||
applyOverrideUUID(texture_id, override_texture_id);
|
||||
}
|
||||
|
||||
if (override_mat.mBaseColor != getDefaultBaseColor())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "llrefcount.h"
|
||||
#include "llmemory.h"
|
||||
#include "m3math.h"
|
||||
#include "v4color.h"
|
||||
#include "v3color.h"
|
||||
#include "v2math.h"
|
||||
|
|
@ -49,13 +48,18 @@ public:
|
|||
// default material for reference
|
||||
static const LLGLTFMaterial sDefault;
|
||||
|
||||
static const char* const ASSET_VERSION;
|
||||
static const char* const ASSET_TYPE;
|
||||
static const std::array<std::string, 2> ACCEPTED_ASSET_VERSIONS;
|
||||
static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); }
|
||||
|
||||
struct TextureTransform
|
||||
{
|
||||
LLVector2 mOffset = { 0.f, 0.f };
|
||||
LLVector2 mScale = { 1.f, 1.f };
|
||||
F32 mRotation = 0.f;
|
||||
|
||||
LLMatrix3 asMatrix();
|
||||
void getPacked(F32 (&packed)[8]);
|
||||
|
||||
bool operator==(const TextureTransform& other) const;
|
||||
};
|
||||
|
|
@ -74,12 +78,28 @@ public:
|
|||
bool operator==(const LLGLTFMaterial& rhs) const;
|
||||
bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); }
|
||||
|
||||
LLUUID mBaseColorId;
|
||||
LLUUID mNormalId;
|
||||
LLUUID mMetallicRoughnessId;
|
||||
LLUUID mEmissiveId;
|
||||
enum TextureInfo : U32
|
||||
{
|
||||
GLTF_TEXTURE_INFO_BASE_COLOR,
|
||||
GLTF_TEXTURE_INFO_NORMAL,
|
||||
GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
|
||||
// *NOTE: GLTF_TEXTURE_INFO_OCCLUSION is currently ignored, in favor of
|
||||
// the values specified with GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS.
|
||||
// Currently, only ORM materials are supported (materials which define
|
||||
// occlusion, roughness, and metallic in the same texture).
|
||||
// -Cosmic,2023-01-26
|
||||
GLTF_TEXTURE_INFO_OCCLUSION = GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
|
||||
GLTF_TEXTURE_INFO_EMISSIVE,
|
||||
|
||||
// NOTE : initialize values to defaults according to the GLTF spec
|
||||
GLTF_TEXTURE_INFO_COUNT
|
||||
};
|
||||
|
||||
std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
|
||||
|
||||
std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
|
||||
|
||||
// NOTE: initialize values to defaults according to the GLTF spec
|
||||
// NOTE: these values should be in linear color space
|
||||
LLColor4 mBaseColor = LLColor4(1, 1, 1, 1);
|
||||
LLColor3 mEmissiveColor = LLColor3(0, 0, 0);
|
||||
|
||||
|
|
@ -104,24 +124,14 @@ public:
|
|||
return hash;
|
||||
}
|
||||
|
||||
enum TextureInfo : U32
|
||||
{
|
||||
GLTF_TEXTURE_INFO_BASE_COLOR,
|
||||
GLTF_TEXTURE_INFO_NORMAL,
|
||||
GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS,
|
||||
GLTF_TEXTURE_INFO_EMISSIVE,
|
||||
|
||||
GLTF_TEXTURE_INFO_COUNT
|
||||
};
|
||||
|
||||
std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
|
||||
|
||||
//setters for various members (will clamp to acceptable ranges)
|
||||
// for_override - set to true if this value is being set as part of an override (important for handling override to default value)
|
||||
|
||||
void setTextureId(TextureInfo texture_info, const LLUUID& id, bool for_override = false);
|
||||
|
||||
void setBaseColorId(const LLUUID& id, bool for_override = false);
|
||||
void setNormalId(const LLUUID& id, bool for_override = false);
|
||||
void setMetallicRoughnessId(const LLUUID& id, bool for_override = false);
|
||||
void setOcclusionRoughnessMetallicId(const LLUUID& id, bool for_override = false);
|
||||
void setEmissiveId(const LLUUID& id, bool for_override = false);
|
||||
|
||||
void setBaseColorFactor(const LLColor4& baseColor, bool for_override = false);
|
||||
|
|
@ -180,6 +190,10 @@ public:
|
|||
|
||||
void applyOverride(const LLGLTFMaterial& override_mat);
|
||||
|
||||
// For base materials only (i.e. assets). Clears transforms to
|
||||
// default since they're not supported in assets yet.
|
||||
void sanitizeAssetMaterial();
|
||||
|
||||
// For material overrides only. Clears most properties to
|
||||
// default/fallthrough, but preserves the transforms.
|
||||
bool setBaseMaterial();
|
||||
|
|
@ -187,12 +201,11 @@ public:
|
|||
bool isClearedForBaseMaterial();
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);
|
||||
|
||||
template<typename T>
|
||||
void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out);
|
||||
|
||||
template<typename T>
|
||||
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const;
|
||||
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const;
|
||||
|
||||
void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,369 @@
|
|||
/**
|
||||
* @file llgltfmaterial_test.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "lltut.h"
|
||||
|
||||
#include "../llgltfmaterial.h"
|
||||
#include "lluuid.cpp"
|
||||
|
||||
// Import & define single-header gltf import/export lib
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#define TINYGLTF_USE_CPP14 // default is C++ 11
|
||||
|
||||
// tinygltf by default loads image files using STB
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
// to use our own image loading:
|
||||
// 1. replace this definition with TINYGLTF_NO_STB_IMAGE
|
||||
// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)
|
||||
|
||||
// tinygltf saves image files using STB
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data)
|
||||
|
||||
// Disable reading external images to prevent warnings and speed up the tests.
|
||||
// We don't need this for the tests, but still need the filesystem
|
||||
// implementation to be defined in order for llprimitive to link correctly.
|
||||
#define TINYGLTF_NO_EXTERNAL_IMAGE 1
|
||||
|
||||
#include "tinygltf/tiny_gltf.h"
|
||||
|
||||
namespace tut
|
||||
{
|
||||
struct llgltfmaterial
|
||||
{
|
||||
};
|
||||
typedef test_group<llgltfmaterial> llgltfmaterial_t;
|
||||
typedef llgltfmaterial_t::object llgltfmaterial_object_t;
|
||||
tut::llgltfmaterial_t tut_llgltfmaterial("llgltfmaterial");
|
||||
|
||||
// A positive 32-bit float with a long string representation
|
||||
constexpr F32 test_fraction = 1.09045365e-32;
|
||||
// A larger positive 32-bit float for values that get zeroed if below a threshold
|
||||
constexpr F32 test_fraction_big = 0.109045;
|
||||
|
||||
void apply_test_material_texture_ids(LLGLTFMaterial& material)
|
||||
{
|
||||
material.setBaseColorId(LLUUID::generateNewID());
|
||||
material.setNormalId(LLUUID::generateNewID());
|
||||
material.setOcclusionRoughnessMetallicId(LLUUID::generateNewID());
|
||||
material.setEmissiveId(LLUUID::generateNewID());
|
||||
}
|
||||
|
||||
void apply_test_material_texture_transforms(LLGLTFMaterial& material)
|
||||
{
|
||||
LLGLTFMaterial::TextureTransform test_transform;
|
||||
test_transform.mOffset.mV[VX] = test_fraction;
|
||||
test_transform.mOffset.mV[VY] = test_fraction;
|
||||
test_transform.mScale.mV[VX] = test_fraction;
|
||||
test_transform.mScale.mV[VY] = test_fraction;
|
||||
test_transform.mRotation = test_fraction;
|
||||
for (LLGLTFMaterial::TextureInfo i = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; i = LLGLTFMaterial::TextureInfo((U32)i + 1))
|
||||
{
|
||||
material.setTextureOffset(i, test_transform.mOffset);
|
||||
material.setTextureScale(i, test_transform.mScale);
|
||||
material.setTextureRotation(i, test_transform.mRotation);
|
||||
}
|
||||
}
|
||||
|
||||
void apply_test_material_factors(LLGLTFMaterial& material)
|
||||
{
|
||||
material.setBaseColorFactor(LLColor4(test_fraction_big, test_fraction_big, test_fraction_big, test_fraction_big));
|
||||
material.setEmissiveColorFactor(LLColor3(test_fraction_big, test_fraction_big, test_fraction_big));
|
||||
material.setMetallicFactor(test_fraction);
|
||||
material.setRoughnessFactor(test_fraction);
|
||||
}
|
||||
|
||||
LLGLTFMaterial create_test_material()
|
||||
{
|
||||
LLGLTFMaterial material;
|
||||
|
||||
apply_test_material_texture_ids(material);
|
||||
|
||||
apply_test_material_texture_transforms(material);
|
||||
|
||||
apply_test_material_factors(material);
|
||||
|
||||
material.setAlphaCutoff(test_fraction);
|
||||
// Because this is the default value, it should append to the extras field to mark it as an override
|
||||
material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE);
|
||||
// Because this is the default value, it should append to the extras field to mark it as an override
|
||||
material.setDoubleSided(false);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
void ensure_gltf_material_serialize(const std::string& ensure_suffix, const LLGLTFMaterial& material_in)
|
||||
{
|
||||
const std::string json_in = material_in.asJSON();
|
||||
LLGLTFMaterial material_out;
|
||||
std::string warn_msg;
|
||||
std::string error_msg;
|
||||
bool serialize_success = material_out.fromJSON(json_in, warn_msg, error_msg);
|
||||
ensure_equals("LLGLTFMaterial serialization has no warnings: " + ensure_suffix, "", warn_msg);
|
||||
ensure_equals("LLGLTFMaterial serialization has no errors: " + ensure_suffix, "", error_msg);
|
||||
ensure("LLGLTFMaterial serializes successfully: " + ensure_suffix, serialize_success);
|
||||
ensure("LLGLTFMaterial is preserved when deserialized: " + ensure_suffix, material_in == material_out);
|
||||
const std::string json_out = material_out.asJSON();
|
||||
ensure_equals("LLGLTFMaterial is preserved when serialized: " + ensure_suffix, json_in, json_out);
|
||||
}
|
||||
|
||||
void ensure_gltf_material_trimmed(const std::string& material_json, const std::string& must_not_contain)
|
||||
{
|
||||
ensure("LLGLTFMaterial serialization trims property '" + must_not_contain + "'", material_json.find(must_not_contain) == std::string::npos);
|
||||
}
|
||||
|
||||
// Test that GLTF material fields have not changed since these tests were written
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<1>()
|
||||
{
|
||||
#if ADDRESS_SIZE != 32
|
||||
#if LL_WINDOWS
|
||||
// If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial)
|
||||
// This test result will vary between compilers, so only test a single platform
|
||||
ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216);
|
||||
#endif
|
||||
#endif
|
||||
ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4);
|
||||
}
|
||||
|
||||
// Test that occlusion and metallicRoughness are the same (They are different for asset validation. See lluploadmaterial.cpp)
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<2>()
|
||||
{
|
||||
ensure_equals("LLGLTFMaterial occlusion does not differ from metallic roughness", LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, LLGLTFMaterial::GLTF_TEXTURE_INFO_OCCLUSION);
|
||||
}
|
||||
|
||||
// Ensure double sided and alpha mode overrides serialize as expected
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<3>()
|
||||
{
|
||||
const bool doubleSideds[] { false, true };
|
||||
const LLGLTFMaterial::AlphaMode alphaModes[] { LLGLTFMaterial::ALPHA_MODE_OPAQUE, LLGLTFMaterial::ALPHA_MODE_BLEND, LLGLTFMaterial::ALPHA_MODE_MASK };
|
||||
const bool forOverrides[] { false, true };
|
||||
|
||||
for (bool doubleSided : doubleSideds)
|
||||
{
|
||||
for (bool forOverride : forOverrides)
|
||||
{
|
||||
LLGLTFMaterial material;
|
||||
material.setDoubleSided(doubleSided, forOverride);
|
||||
const bool overrideBit = (doubleSided == false) && forOverride;
|
||||
ensure_equals("LLGLTFMaterial: double sided = " + std::to_string(doubleSided) + " override bit when forOverride = " + std::to_string(forOverride), material.mOverrideDoubleSided, overrideBit);
|
||||
ensure_gltf_material_serialize("double sided = " + std::to_string(doubleSided), material);
|
||||
}
|
||||
}
|
||||
|
||||
for (LLGLTFMaterial::AlphaMode alphaMode : alphaModes)
|
||||
{
|
||||
for (bool forOverride : forOverrides)
|
||||
{
|
||||
LLGLTFMaterial material;
|
||||
material.setAlphaMode(alphaMode, forOverride);
|
||||
const bool overrideBit = (alphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE) && forOverride;
|
||||
ensure_equals("LLGLTFMaterial: alpha mode = " + std::to_string(alphaMode) + " override bit when forOverride = " + std::to_string(forOverride), material.mOverrideAlphaMode, overrideBit);
|
||||
ensure_gltf_material_serialize("alpha mode = " + std::to_string(alphaMode), material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a GLTF material's transform components serialize as expected
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<4>()
|
||||
{
|
||||
LLGLTFMaterial material;
|
||||
LLGLTFMaterial::TextureTransform& transform = material.mTextureTransform[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR];
|
||||
transform.mOffset[VX] = 1.f;
|
||||
transform.mOffset[VY] = 2.f;
|
||||
transform.mScale[VX] = 0.05f;
|
||||
transform.mScale[VY] = 100.f;
|
||||
transform.mRotation = 1.571f;
|
||||
ensure_gltf_material_serialize("material with transform", material);
|
||||
}
|
||||
|
||||
// Test that a GLTF material avoids serializing a material unnecessarily
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<5>()
|
||||
{
|
||||
{
|
||||
const LLGLTFMaterial material;
|
||||
const std::string material_json = material.asJSON();
|
||||
ensure_gltf_material_trimmed(material_json, "pbrMetallicRoughness");
|
||||
ensure_gltf_material_trimmed(material_json, "normalTexture");
|
||||
ensure_gltf_material_trimmed(material_json, "emissiveTexture");
|
||||
ensure_gltf_material_trimmed(material_json, "occlusionTexture");
|
||||
}
|
||||
|
||||
{
|
||||
LLGLTFMaterial metallic_factor_material;
|
||||
metallic_factor_material.setMetallicFactor(0.5);
|
||||
const std::string metallic_factor_material_json = metallic_factor_material.asJSON();
|
||||
ensure_gltf_material_trimmed(metallic_factor_material_json, "baseColorTexture");
|
||||
ensure_gltf_material_trimmed(metallic_factor_material_json, "metallicRoughnessTexture");
|
||||
}
|
||||
}
|
||||
|
||||
// Test that a GLTF material preserves values on serialization
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<6>()
|
||||
{
|
||||
{
|
||||
const LLGLTFMaterial full_material = create_test_material();
|
||||
ensure_gltf_material_serialize("full material", full_material);
|
||||
}
|
||||
|
||||
{
|
||||
LLGLTFMaterial texture_ids_only_material;
|
||||
apply_test_material_texture_ids(texture_ids_only_material);
|
||||
ensure_gltf_material_serialize("material with texture IDs only", texture_ids_only_material);
|
||||
}
|
||||
|
||||
{
|
||||
LLGLTFMaterial texture_transforms_only_material;
|
||||
apply_test_material_texture_ids(texture_transforms_only_material);
|
||||
ensure_gltf_material_serialize("material with texture transforms only", texture_transforms_only_material);
|
||||
}
|
||||
|
||||
{
|
||||
LLGLTFMaterial factors_only_material;
|
||||
apply_test_material_factors(factors_only_material);
|
||||
ensure_gltf_material_serialize("material with scaling/tint factors only", factors_only_material);
|
||||
}
|
||||
}
|
||||
|
||||
// Test that sDefault is a no-op override
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<7>()
|
||||
{
|
||||
const LLGLTFMaterial material_asset = create_test_material();
|
||||
LLGLTFMaterial render_material = material_asset;
|
||||
render_material.applyOverride(LLGLTFMaterial::sDefault);
|
||||
ensure("LLGLTFMaterial: sDefault is a no-op override", material_asset == render_material);
|
||||
}
|
||||
|
||||
// Test application of transform overrides
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<8>()
|
||||
{
|
||||
LLGLTFMaterial override_material;
|
||||
apply_test_material_texture_transforms(override_material);
|
||||
LLGLTFMaterial render_material;
|
||||
render_material.applyOverride(override_material);
|
||||
ensure("LLGLTFMaterial: transform overrides", render_material == override_material);
|
||||
}
|
||||
|
||||
// Test application of flag-based overrides
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<9>()
|
||||
{
|
||||
{
|
||||
LLGLTFMaterial override_material;
|
||||
override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_BLEND, true);
|
||||
override_material.setDoubleSided(true, true);
|
||||
|
||||
LLGLTFMaterial render_material;
|
||||
|
||||
render_material.applyOverride(override_material);
|
||||
|
||||
ensure("LLGLTFMaterial: extra overrides with non-default values applied over default", render_material == override_material);
|
||||
}
|
||||
{
|
||||
LLGLTFMaterial override_material;
|
||||
override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true);
|
||||
override_material.setDoubleSided(false, true);
|
||||
|
||||
LLGLTFMaterial render_material;
|
||||
override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_BLEND, false);
|
||||
override_material.setDoubleSided(true, false);
|
||||
|
||||
render_material.applyOverride(override_material);
|
||||
// Not interested in these flags for equality comparison
|
||||
override_material.mOverrideDoubleSided = false;
|
||||
override_material.mOverrideAlphaMode = false;
|
||||
|
||||
ensure("LLGLTFMaterial: extra overrides with default values applied over non-default", render_material == override_material);
|
||||
}
|
||||
}
|
||||
|
||||
// Test application of texture overrides
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<10>()
|
||||
{
|
||||
const U32 texture_count = 2;
|
||||
const LLUUID override_textures[texture_count] = { LLUUID::null, LLUUID::generateNewID() };
|
||||
const LLUUID asset_textures[texture_count] = { LLUUID::generateNewID(), LLUUID::null };
|
||||
for (U32 i = 0; i < texture_count; ++i)
|
||||
{
|
||||
LLGLTFMaterial override_material;
|
||||
const LLUUID& override_texture = override_textures[i];
|
||||
for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1))
|
||||
{
|
||||
override_material.setTextureId(j, override_texture, true);
|
||||
}
|
||||
|
||||
LLGLTFMaterial render_material;
|
||||
const LLUUID& asset_texture = asset_textures[i];
|
||||
for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1))
|
||||
{
|
||||
render_material.setTextureId(j, asset_texture, false);
|
||||
}
|
||||
|
||||
render_material.applyOverride(override_material);
|
||||
|
||||
for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1))
|
||||
{
|
||||
const LLUUID& render_texture = render_material.mTextureId[j];
|
||||
ensure_equals("LLGLTFMaterial: Override texture ID " + override_texture.asString() + " replaces underlying texture ID " + asset_texture.asString(), render_texture, override_texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test non-persistence of default value flags in overrides
|
||||
template<> template<>
|
||||
void llgltfmaterial_object_t::test<11>()
|
||||
{
|
||||
const S32 non_default_alpha_modes[] = { LLGLTFMaterial::ALPHA_MODE_BLEND, LLGLTFMaterial::ALPHA_MODE_MASK };
|
||||
for (S32 non_default_alpha_mode : non_default_alpha_modes)
|
||||
{
|
||||
LLGLTFMaterial material;
|
||||
// Set default alpha mode
|
||||
material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true);
|
||||
ensure_equals("LLGLTFMaterial: alpha mode override flag set", material.mOverrideAlphaMode, true);
|
||||
// Set non-default alpha mode
|
||||
material.setAlphaMode(non_default_alpha_mode, true);
|
||||
ensure_equals("LLGLTFMaterial: alpha mode override flag unset", material.mOverrideAlphaMode, false);
|
||||
}
|
||||
|
||||
{
|
||||
// Set default double sided
|
||||
LLGLTFMaterial material;
|
||||
material.setDoubleSided(false, true);
|
||||
ensure_equals("LLGLTFMaterial: double sided override flag set", material.mOverrideDoubleSided, true);
|
||||
// Set non-default double sided
|
||||
material.setDoubleSided(true, true);
|
||||
ensure_equals("LLGLTFMaterial: double sided override flag unset", material.mOverrideDoubleSided, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL us
|
|||
|
||||
bind(0);
|
||||
|
||||
U32 format = components == 4 ? GL_RGBA12 : GL_RGB10;
|
||||
U32 format = components == 4 ? GL_RGBA12 : GL_RGB16F;
|
||||
|
||||
U32 mip = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1408,8 +1408,11 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
LL_PROFILE_ZONE_NUM(height);
|
||||
|
||||
free_cur_tex_image();
|
||||
#if 0
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
|
||||
#if LL_DARWIN
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
|
||||
}
|
||||
#else
|
||||
// break up calls to a manageable size for the GL command buffer
|
||||
{
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
|
|||
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
|
||||
{
|
||||
stop_glerror();
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// Counterclockwise quad will face the viewer
|
||||
|
|
@ -155,7 +154,6 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
|
|||
gGL.vertex2i(left, top);
|
||||
gGL.end();
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
|
||||
|
|
|
|||
|
|
@ -177,6 +177,11 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!shader->attachVertexObject("deferred/textureUtilV.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Attach Fragment Shader Features Next
|
||||
|
|
@ -685,7 +690,6 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
|||
extra_code_text[extra_code_count++] = strdup("#define texture2D texture\n");
|
||||
extra_code_text[extra_code_count++] = strdup("#define textureCube texture\n");
|
||||
extra_code_text[extra_code_count++] = strdup("#define texture2DLod textureLod\n");
|
||||
extra_code_text[extra_code_count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
|
||||
|
||||
if (major_version > 1 || minor_version >= 40)
|
||||
{ //GLSL 1.40 replaces texture2DRect et al with texture
|
||||
|
|
@ -1075,11 +1079,13 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("texture_matrix3");
|
||||
mReservedUniforms.push_back("object_plane_s");
|
||||
mReservedUniforms.push_back("object_plane_t");
|
||||
mReservedUniforms.push_back("texture_basecolor_matrix"); // GLTF
|
||||
mReservedUniforms.push_back("texture_normal_matrix"); // GLTF
|
||||
mReservedUniforms.push_back("texture_metallic_roughness_matrix"); // GLTF
|
||||
mReservedUniforms.push_back("texture_emissive_matrix"); // GLTF
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_MATRIX+1);
|
||||
|
||||
mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF)
|
||||
mReservedUniforms.push_back("texture_normal_transform"); // (GLTF)
|
||||
mReservedUniforms.push_back("texture_metallic_roughness_transform"); // (GLTF)
|
||||
mReservedUniforms.push_back("texture_emissive_transform"); // (GLTF)
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1);
|
||||
|
||||
mReservedUniforms.push_back("viewport");
|
||||
|
||||
|
|
|
|||
|
|
@ -52,10 +52,12 @@ public:
|
|||
TEXTURE_MATRIX3, // "texture_matrix3"
|
||||
OBJECT_PLANE_S, // "object_plane_s"
|
||||
OBJECT_PLANE_T, // "object_plane_t"
|
||||
TEXTURE_BASECOLOR_MATRIX, // "texture_basecolor_matrix" (GLTF)
|
||||
TEXTURE_NORMAL_MATRIX, // "texture_normal_matrix" (GLTF)
|
||||
TEXTURE_METALLIC_ROUGHNESS_MATRIX, // "texture_metallic_roughness_matrix" (GLTF)
|
||||
TEXTURE_EMISSIVE_MATRIX, // "texture_emissive_matrix" (GLTF)
|
||||
|
||||
TEXTURE_BASE_COLOR_TRANSFORM, // "texture_base_color_transform" (GLTF)
|
||||
TEXTURE_NORMAL_TRANSFORM, // "texture_normal_transform" (GLTF)
|
||||
TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, // "texture_metallic_roughness_transform" (GLTF)
|
||||
TEXTURE_EMISSIVE_TRANSFORM, // "texture_emissive_transform" (GLTF)
|
||||
|
||||
VIEWPORT, // "viewport"
|
||||
LIGHT_POSITION, // "light_position"
|
||||
LIGHT_DIRECTION, // "light_direction"
|
||||
|
|
|
|||
|
|
@ -1390,7 +1390,7 @@ void LLVertexBuffer::setBuffer()
|
|||
U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
|
||||
|
||||
// this Vertex Buffer must provide all necessary attributes for currently bound shader
|
||||
llassert(((~data_mask & mTypeMask) > 0) || (mTypeMask == data_mask));
|
||||
llassert((data_mask & mTypeMask) == data_mask);
|
||||
|
||||
if (sGLRenderBuffer != mGLBuffer)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
<string>RenderDeferredSSAO</string>
|
||||
<string>RenderDepthOfField</string>
|
||||
<string>RenderDepthOfFieldInEditMode</string>
|
||||
<string>RenderExposure</string>
|
||||
<string>RenderFarClip</string>
|
||||
<string>RenderFlexTimeFactor</string>
|
||||
<string>RenderFSAASamples</string>
|
||||
|
|
@ -41,6 +42,7 @@
|
|||
<string>RenderTerrainDetail</string>
|
||||
<string>RenderTerrainLODFactor</string>
|
||||
<string>RenderTerrainScale</string>
|
||||
<string>RenderTonemapper</string>
|
||||
<string>RenderTreeLODFactor</string>
|
||||
<string>RenderTransparentWater</string>
|
||||
<string>RenderUnloadedAvatar</string>
|
||||
|
|
|
|||
|
|
@ -13462,7 +13462,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>256</integer>
|
||||
<integer>128</integer>
|
||||
</map>
|
||||
<key>RenderReflectionProbeAmbianceScale</key>
|
||||
<map>
|
||||
|
|
@ -13473,9 +13473,31 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<integer>8</integer>
|
||||
<real>8</real>
|
||||
</map>
|
||||
|
||||
<key>RenderTonemapper</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Which tone mapping function to use (0 - Linear, 1 - ACES Narkowicz, 2 - ACES Hill)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>1</real>
|
||||
</map>
|
||||
<key>RenderExposure</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Exposure value to send to tonemapper.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1</real>
|
||||
</map>
|
||||
|
||||
<key>RenderReflectionProbeDrawDistance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -13485,7 +13507,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>64</real>
|
||||
<integer>64</integer>
|
||||
</map>
|
||||
<key>RenderReflectionProbeAmbiance</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -52,9 +52,6 @@ VARYING vec2 vary_texcoord2;
|
|||
VARYING vec2 vary_texcoord3;
|
||||
VARYING float altitude_blend_factor;
|
||||
|
||||
/// Soft clips the light with a gamma correction
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
vec4 cloudNoise(vec2 uv)
|
||||
{
|
||||
vec4 a = texture2D(cloud_noise_texture, uv);
|
||||
|
|
@ -119,7 +116,6 @@ void main()
|
|||
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
|
||||
color.rgb= max(vec3(0), color.rgb);
|
||||
color.rgb *= 2.0;
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, alpha1);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ const float ONE_OVER_PI = 0.3183098861;
|
|||
|
||||
vec3 srgb_to_linear(vec3 cs);
|
||||
vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
|
||||
vec3 scaleSoftClipFragLinear(vec3 light);
|
||||
|
||||
float calcLegacyDistanceAttenuation(float distance, float falloff)
|
||||
{
|
||||
|
|
@ -383,7 +382,8 @@ vec3 pbrIbl(vec3 diffuseColor,
|
|||
vec3 irradiance, // irradiance map sample
|
||||
float ao, // ambient occlusion factor
|
||||
float nv, // normal dot view vector
|
||||
float perceptualRough)
|
||||
float perceptualRough,
|
||||
out vec3 specContrib)
|
||||
{
|
||||
// retrieve a scale and bias to F0. See [1], Figure 3
|
||||
vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
|
||||
|
|
@ -393,9 +393,24 @@ vec3 pbrIbl(vec3 diffuseColor,
|
|||
vec3 diffuse = diffuseLight * diffuseColor;
|
||||
vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
|
||||
|
||||
return (diffuse + specular*0.5) * ao; //reduce by half to place in appropriate color space for atmospherics
|
||||
specContrib = specular * ao;
|
||||
|
||||
return (diffuse + specular) * ao;
|
||||
}
|
||||
|
||||
vec3 pbrIbl(vec3 diffuseColor,
|
||||
vec3 specularColor,
|
||||
vec3 radiance, // radiance map sample
|
||||
vec3 irradiance, // irradiance map sample
|
||||
float ao, // ambient occlusion factor
|
||||
float nv, // normal dot view vector
|
||||
float perceptualRough)
|
||||
{
|
||||
vec3 specContrib;
|
||||
return pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, nv, perceptualRough, specContrib);
|
||||
}
|
||||
|
||||
|
||||
// Encapsulate the various inputs used by the various functions in the shading equation
|
||||
// We store values in this struct to simplify the integration of alternative implementations
|
||||
// of the shading terms, outlined in the Readme.MD Appendix.
|
||||
|
|
@ -460,7 +475,8 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
|||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 v, // surface point to camera
|
||||
vec3 l) //surface point to light
|
||||
vec3 l, //surface point to light
|
||||
out vec3 specContrib) //specular contribution (exposed to alpha shaders to calculate "glare")
|
||||
{
|
||||
// make sure specular highlights from punctual lights don't fall off of polished surfaces
|
||||
perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
|
||||
|
|
@ -506,17 +522,30 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
|||
float G = geometricOcclusion(pbrInputs);
|
||||
float D = microfacetDistribution(pbrInputs);
|
||||
|
||||
const vec3 u_LightColor = vec3(1.0);
|
||||
|
||||
// Calculation of analytical lighting contribution
|
||||
vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
|
||||
vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
|
||||
specContrib = F * G * D / (4.0 * NdotL * NdotV);
|
||||
// Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
|
||||
vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
|
||||
vec3 color = NdotL * (diffuseContrib + specContrib);
|
||||
|
||||
specContrib *= NdotL;
|
||||
specContrib = max(specContrib, vec3(0));
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 v, // surface point to camera
|
||||
vec3 l) //surface point to light
|
||||
{
|
||||
vec3 specContrib;
|
||||
|
||||
return pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n, v, l, specContrib);
|
||||
}
|
||||
|
||||
void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor)
|
||||
{
|
||||
vec3 f0 = vec3(0.04);
|
||||
|
|
@ -525,23 +554,30 @@ void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor
|
|||
specularColor = mix(f0, baseColor, metallic);
|
||||
}
|
||||
|
||||
vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
|
||||
vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten, out vec3 specContrib)
|
||||
{
|
||||
vec3 color = vec3(0);
|
||||
|
||||
float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
|
||||
|
||||
color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, 0.2);
|
||||
vec3 ibl_spec;
|
||||
color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness, ibl_spec);
|
||||
|
||||
color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 2.75 * scol;
|
||||
color += colorEmissive*0.5;
|
||||
color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir), specContrib) * sunlit * 2.75 * scol;
|
||||
specContrib *= sunlit * 2.75 * scol;
|
||||
specContrib += ibl_spec;
|
||||
|
||||
color = atmosFragLightingLinear(color, additive, atten);
|
||||
color = scaleSoftClipFragLinear(color);
|
||||
color += colorEmissive;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
|
||||
{
|
||||
vec3 specContrib;
|
||||
return pbrBaseLight(diffuseColor, specularColor, metallic, v, norm, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten, specContrib);
|
||||
}
|
||||
|
||||
uniform vec4 waterPlane;
|
||||
uniform float waterSign;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,14 +27,9 @@
|
|||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
|
@ -46,8 +41,6 @@ void main()
|
|||
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,8 +100,10 @@ void main()
|
|||
#endif
|
||||
|
||||
#ifndef IS_HUD
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
#endif
|
||||
|
||||
frag_color.rgb = color.rgb;
|
||||
frag_color.a = color.a;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* @file materialF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
// debug stub
|
||||
|
||||
#define DIFFUSE_ALPHA_MODE_BLEND 1
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
out vec4 frag_data[3];
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
frag_color = vec4(0.5, 0, 1, 0.5);
|
||||
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
|
||||
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
|
||||
frag_data[0] = vec4(0.5, 0, 1, 0); // gbuffer is sRGB for legacy materials
|
||||
frag_data[1] = vec4(0); // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = vec4(0); // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -27,10 +27,10 @@ uniform mat4 texture_matrix0;
|
|||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
in vec3 position;
|
||||
in vec2 texcoord0;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
out vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @file pbralphaF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// debug stub
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
frag_color = vec4(1.0, 0, 0.5, 0.5);
|
||||
}
|
||||
|
|
@ -44,15 +44,14 @@ uniform mat4 modelview_matrix;
|
|||
|
||||
out vec3 vary_position;
|
||||
|
||||
uniform mat3 texture_basecolor_matrix;
|
||||
uniform mat3 texture_normal_matrix;
|
||||
uniform mat3 texture_metallic_roughness_matrix;
|
||||
uniform mat3 texture_emissive_matrix;
|
||||
uniform vec4[2] texture_base_color_transform;
|
||||
uniform vec4[2] texture_normal_transform;
|
||||
uniform vec4[2] texture_metallic_roughness_transform;
|
||||
uniform vec4[2] texture_emissive_transform;
|
||||
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
out vec3 vary_fragcoord;
|
||||
|
||||
uniform float near_clip;
|
||||
#endif
|
||||
|
||||
in vec3 position;
|
||||
in vec4 diffuse_color;
|
||||
|
|
@ -60,7 +59,7 @@ in vec3 normal;
|
|||
in vec4 tangent;
|
||||
in vec2 texcoord0;
|
||||
|
||||
out vec2 basecolor_texcoord;
|
||||
out vec2 base_color_texcoord;
|
||||
out vec2 normal_texcoord;
|
||||
out vec2 metallic_roughness_texcoord;
|
||||
out vec2 emissive_texcoord;
|
||||
|
|
@ -71,6 +70,8 @@ out vec3 vary_tangent;
|
|||
flat out float vary_sign;
|
||||
out vec3 vary_normal;
|
||||
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -86,14 +87,12 @@ void main()
|
|||
#endif
|
||||
gl_Position = vert;
|
||||
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip);
|
||||
#endif
|
||||
|
||||
basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
normal_texcoord = (texture_matrix0 * vec4(texture_normal_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
metallic_roughness_texcoord = (texture_matrix0 * vec4(texture_metallic_roughness_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
|
||||
normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0);
|
||||
metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0);
|
||||
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
|
||||
|
|
@ -126,18 +125,21 @@ uniform mat4 modelview_matrix;
|
|||
|
||||
out vec3 vary_position;
|
||||
|
||||
uniform mat3 texture_basecolor_matrix;
|
||||
uniform mat3 texture_emissive_matrix;
|
||||
uniform vec4[2] texture_base_color_transform;
|
||||
uniform vec4[2] texture_emissive_transform;
|
||||
|
||||
in vec3 position;
|
||||
in vec4 diffuse_color;
|
||||
in vec2 texcoord0;
|
||||
|
||||
out vec2 basecolor_texcoord;
|
||||
out vec2 base_color_texcoord;
|
||||
out vec2 emissive_texcoord;
|
||||
|
||||
out vec4 vertex_color;
|
||||
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
|
|
@ -145,8 +147,8 @@ void main()
|
|||
gl_Position = vert;
|
||||
vary_position = vert.xyz;
|
||||
|
||||
basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
|
||||
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ out vec4 frag_color;
|
|||
in vec3 vary_position;
|
||||
in vec4 vertex_emissive;
|
||||
|
||||
in vec2 basecolor_texcoord;
|
||||
in vec2 base_color_texcoord;
|
||||
in vec2 emissive_texcoord;
|
||||
|
||||
uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
|
||||
|
|
@ -47,7 +47,7 @@ vec3 srgb_to_linear(vec3 c);
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 basecolor = texture2D(diffuseMap, basecolor_texcoord.xy).rgba;
|
||||
vec4 basecolor = texture2D(diffuseMap, base_color_texcoord.xy).rgba;
|
||||
|
||||
if (basecolor.a < minimum_alpha)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,19 +34,21 @@ uniform mat4 modelview_projection_matrix;
|
|||
|
||||
uniform mat4 texture_matrix0;
|
||||
|
||||
uniform mat3 texture_basecolor_matrix;
|
||||
uniform mat3 texture_emissive_matrix;
|
||||
uniform vec4[2] texture_base_color_transform;
|
||||
uniform vec4[2] texture_emissive_transform;
|
||||
|
||||
in vec3 position;
|
||||
in vec4 emissive;
|
||||
|
||||
in vec2 texcoord0;
|
||||
|
||||
out vec2 basecolor_texcoord;
|
||||
out vec2 base_color_texcoord;
|
||||
out vec2 emissive_texcoord;
|
||||
|
||||
out vec4 vertex_emissive;
|
||||
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef HAS_SKIN
|
||||
|
|
@ -62,8 +64,8 @@ void main()
|
|||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
#endif
|
||||
|
||||
basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
|
||||
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
|
||||
|
||||
vertex_emissive = emissive;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ in vec3 vary_normal;
|
|||
in vec3 vary_tangent;
|
||||
flat in float vary_sign;
|
||||
|
||||
in vec2 basecolor_texcoord;
|
||||
in vec2 base_color_texcoord;
|
||||
in vec2 normal_texcoord;
|
||||
in vec2 metallic_roughness_texcoord;
|
||||
in vec2 emissive_texcoord;
|
||||
|
|
@ -62,7 +62,7 @@ uniform mat3 normal_matrix;
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 basecolor = texture2D(diffuseMap, basecolor_texcoord.xy).rgba;
|
||||
vec4 basecolor = texture2D(diffuseMap, base_color_texcoord.xy).rgba;
|
||||
if (basecolor.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
|
|
@ -121,7 +121,7 @@ out vec4 frag_color;
|
|||
in vec3 vary_position;
|
||||
in vec4 vertex_color;
|
||||
|
||||
in vec2 basecolor_texcoord;
|
||||
in vec2 base_color_texcoord;
|
||||
in vec2 emissive_texcoord;
|
||||
|
||||
uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
|
||||
|
|
@ -131,7 +131,7 @@ vec3 srgb_to_linear(vec3 c);
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 basecolor = texture2D(diffuseMap, basecolor_texcoord.xy).rgba;
|
||||
vec4 basecolor = texture2D(diffuseMap, base_color_texcoord.xy).rgba;
|
||||
if (basecolor.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ uniform mat4 modelview_projection_matrix;
|
|||
#endif
|
||||
uniform mat4 texture_matrix0;
|
||||
|
||||
uniform mat3 texture_basecolor_matrix;
|
||||
uniform mat3 texture_normal_matrix;
|
||||
uniform mat3 texture_metallic_roughness_matrix;
|
||||
uniform mat3 texture_emissive_matrix;
|
||||
uniform vec4[2] texture_base_color_transform;
|
||||
uniform vec4[2] texture_normal_transform;
|
||||
uniform vec4[2] texture_metallic_roughness_transform;
|
||||
uniform vec4[2] texture_emissive_transform;
|
||||
|
||||
in vec3 position;
|
||||
in vec4 diffuse_color;
|
||||
|
|
@ -49,7 +49,7 @@ in vec3 normal;
|
|||
in vec4 tangent;
|
||||
in vec2 texcoord0;
|
||||
|
||||
out vec2 basecolor_texcoord;
|
||||
out vec2 base_color_texcoord;
|
||||
out vec2 normal_texcoord;
|
||||
out vec2 metallic_roughness_texcoord;
|
||||
out vec2 emissive_texcoord;
|
||||
|
|
@ -60,6 +60,8 @@ out vec3 vary_tangent;
|
|||
flat out float vary_sign;
|
||||
out vec3 vary_normal;
|
||||
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef HAS_SKIN
|
||||
|
|
@ -75,11 +77,11 @@ void main()
|
|||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
#endif
|
||||
|
||||
basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
normal_texcoord = (texture_matrix0 * vec4(texture_normal_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
metallic_roughness_texcoord = (texture_matrix0 * vec4(texture_metallic_roughness_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
|
||||
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
|
||||
normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0);
|
||||
metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0);
|
||||
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
|
||||
|
|
@ -104,27 +106,29 @@ uniform mat4 modelview_projection_matrix;
|
|||
|
||||
uniform mat4 texture_matrix0;
|
||||
|
||||
uniform mat3 texture_basecolor_matrix;
|
||||
uniform mat3 texture_normal_matrix;
|
||||
uniform mat3 texture_metallic_roughness_matrix;
|
||||
uniform mat3 texture_emissive_matrix;
|
||||
uniform vec4[2] texture_base_color_transform;
|
||||
uniform vec4[2] texture_normal_transform;
|
||||
uniform vec4[2] texture_metallic_roughness_transform;
|
||||
uniform vec4[2] texture_emissive_transform;
|
||||
|
||||
in vec3 position;
|
||||
in vec4 diffuse_color;
|
||||
in vec2 texcoord0;
|
||||
|
||||
out vec2 basecolor_texcoord;
|
||||
out vec2 base_color_texcoord;
|
||||
out vec2 emissive_texcoord;
|
||||
|
||||
out vec4 vertex_color;
|
||||
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
|
||||
basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy;
|
||||
base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
|
||||
emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,95 @@ uniform float display_gamma;
|
|||
|
||||
vec3 linear_to_srgb(vec3 cl);
|
||||
|
||||
//===============================================================
|
||||
// tone mapping taken from Khronos sample implementation
|
||||
//===============================================================
|
||||
|
||||
// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
|
||||
const mat3 ACESInputMat = mat3
|
||||
(
|
||||
0.59719, 0.07600, 0.02840,
|
||||
0.35458, 0.90834, 0.13383,
|
||||
0.04823, 0.01566, 0.83777
|
||||
);
|
||||
|
||||
|
||||
// ODT_SAT => XYZ => D60_2_D65 => sRGB
|
||||
const mat3 ACESOutputMat = mat3
|
||||
(
|
||||
1.60475, -0.10208, -0.00327,
|
||||
-0.53108, 1.10813, -0.07276,
|
||||
-0.07367, -0.00605, 1.07602
|
||||
);
|
||||
|
||||
// ACES tone map (faster approximation)
|
||||
// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
|
||||
vec3 toneMapACES_Narkowicz(vec3 color)
|
||||
{
|
||||
const float A = 2.51;
|
||||
const float B = 0.03;
|
||||
const float C = 2.43;
|
||||
const float D = 0.59;
|
||||
const float E = 0.14;
|
||||
return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
// ACES filmic tone map approximation
|
||||
// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
|
||||
vec3 RRTAndODTFit(vec3 color)
|
||||
{
|
||||
vec3 a = color * (color + 0.0245786) - 0.000090537;
|
||||
vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
|
||||
return a / b;
|
||||
}
|
||||
|
||||
|
||||
// tone mapping
|
||||
vec3 toneMapACES_Hill(vec3 color)
|
||||
{
|
||||
color = ACESInputMat * color;
|
||||
|
||||
// Apply RRT and ODT
|
||||
color = RRTAndODTFit(color);
|
||||
|
||||
color = ACESOutputMat * color;
|
||||
|
||||
// Clamp to [0, 1]
|
||||
color = clamp(color, 0.0, 1.0);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
uniform float exposure;
|
||||
uniform float gamma;
|
||||
|
||||
vec3 toneMap(vec3 color)
|
||||
{
|
||||
color *= exposure;
|
||||
|
||||
#ifdef TONEMAP_ACES_NARKOWICZ
|
||||
color = toneMapACES_Narkowicz(color);
|
||||
#endif
|
||||
|
||||
#ifdef TONEMAP_ACES_HILL
|
||||
color = toneMapACES_Hill(color);
|
||||
#endif
|
||||
|
||||
#ifdef TONEMAP_ACES_HILL_EXPOSURE_BOOST
|
||||
// boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621
|
||||
// this factor is based on the exposure correction of Krzysztof Narkowicz in his
|
||||
// implemetation of ACES tone mapping
|
||||
color *= 1.0/0.6;
|
||||
//color /= 0.6;
|
||||
color = toneMapACES_Hill(color);
|
||||
#endif
|
||||
|
||||
return linear_to_srgb(color);
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
|
||||
//=================================
|
||||
// borrowed noise from:
|
||||
// <https://www.shadertoy.com/view/4dS3Wd>
|
||||
|
|
@ -79,16 +168,26 @@ float noise(vec2 x) {
|
|||
|
||||
//=============================
|
||||
|
||||
|
||||
vec3 legacyGamma(vec3 color)
|
||||
{
|
||||
color = 1. - clamp(color, vec3(0.), vec3(1.));
|
||||
color = 1. - pow(color, vec3(gamma)); // s/b inverted already CPU-side
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
|
||||
vec4 diff = texture2D(diffuseRect, vary_fragcoord);
|
||||
diff.rgb = linear_to_srgb(diff.rgb);
|
||||
vec2 tc = vary_fragcoord.xy*screen_res;
|
||||
|
||||
diff.rgb = toneMap(diff.rgb);
|
||||
diff.rgb = legacyGamma(diff.rgb);
|
||||
|
||||
vec2 tc = vary_fragcoord.xy*screen_res*4.0;
|
||||
vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y);
|
||||
vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
|
||||
diff.rgb += nz*0.008;
|
||||
diff.rgb += nz*0.003;
|
||||
//diff.rgb = nz;
|
||||
frag_color = diff;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,12 +59,12 @@ float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul,
|
|||
stc.xyz /= stc.w;
|
||||
stc.z += offset * 2.0;
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float cs = texture(shadowMap, stc.xyz);
|
||||
float shadow = cs * 4.0;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += texture(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0));
|
||||
shadow += texture(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0));
|
||||
shadow += texture(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0));
|
||||
shadow += texture(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0));
|
||||
return clamp(shadow * 0.125, 0.0, 1.0);
|
||||
#else
|
||||
return 1.0;
|
||||
|
|
@ -78,16 +78,16 @@ float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2
|
|||
stc.z += spot_shadow_bias * bias_scale;
|
||||
stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
|
||||
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float cs = texture(shadowMap, stc.xyz);
|
||||
float shadow = cs;
|
||||
|
||||
vec2 off = 1.0/proj_shadow_res;
|
||||
off.y *= 1.5;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
|
||||
shadow += texture(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0));
|
||||
shadow += texture(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0));
|
||||
shadow += texture(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0));
|
||||
shadow += texture(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0));
|
||||
return shadow*0.2;
|
||||
#else
|
||||
return 1.0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* @file class1/deferred/textureUtilV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// This shader code is taken from the sample code on the KHR_texture_transform
|
||||
// spec page page, plus or minus some sign error corrections (I think because the GLSL
|
||||
// matrix constructor is backwards?):
|
||||
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform
|
||||
// Previously (6494eed242b1), we passed in a single, precalculated matrix
|
||||
// uniform per transform into the shaders. However, that was found to produce
|
||||
// small-but-noticeable discrepancies with the GLTF sample model
|
||||
// "TextureTransformTest", likely due to numerical precision differences. In
|
||||
// the interest of parity with other renderers, calculate the transform
|
||||
// directly in the shader. -Cosmic,2023-02-24
|
||||
vec2 khr_texture_transform(vec2 texcoord, vec2 scale, float rotation, vec2 offset)
|
||||
{
|
||||
mat3 scale_mat = mat3(scale.x,0,0, 0,scale.y,0, 0,0,1);
|
||||
mat3 offset_mat = mat3(1,0,0, 0,1,0, offset.x, offset.y, 1);
|
||||
mat3 rotation_mat = mat3(
|
||||
cos(rotation),-sin(rotation), 0,
|
||||
sin(rotation), cos(rotation), 0,
|
||||
0, 0, 1
|
||||
);
|
||||
|
||||
mat3 transform = offset_mat * rotation_mat * scale_mat;
|
||||
|
||||
return (transform * vec3(texcoord, 1)).xy;
|
||||
}
|
||||
|
||||
// vertex_texcoord - The UV texture coordinates sampled from the vertex at
|
||||
// runtime. Per SL convention, this is in a right-handed UV coordinate
|
||||
// system. Collada models also have right-handed UVs.
|
||||
// khr_gltf_transform - The texture transform matrix as defined in the
|
||||
// KHR_texture_transform GLTF extension spec. It assumes a left-handed UV
|
||||
// coordinate system. GLTF models also have left-handed UVs.
|
||||
// sl_animation_transform - The texture transform matrix for texture
|
||||
// animations, available through LSL script functions such as
|
||||
// LlSetTextureAnim. It assumes a right-handed UV coordinate system.
|
||||
// texcoord - The final texcoord to use for image sampling
|
||||
vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform)
|
||||
{
|
||||
vec2 texcoord = vertex_texcoord;
|
||||
|
||||
// Apply texture animation first to avoid shearing and other artifacts
|
||||
texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy;
|
||||
// Convert to left-handed coordinate system. The offset of 1 is necessary
|
||||
// for rotations to be applied correctly.
|
||||
texcoord.y = 1.0 - texcoord.y;
|
||||
texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);
|
||||
// Convert back to right-handed coordinate system
|
||||
texcoord.y = 1.0 - texcoord.y;
|
||||
|
||||
// To make things more confusing, all SL image assets are upside-down
|
||||
// We may need an additional sign flip here when we implement a Vulkan backend
|
||||
|
||||
return texcoord;
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ uniform float waterFogKS;
|
|||
vec3 getPositionEye();
|
||||
|
||||
vec3 srgb_to_linear(vec3 col);
|
||||
vec3 linear_to_srgb(vec3 col);
|
||||
|
||||
vec4 applyWaterFogView(vec3 pos, vec4 color)
|
||||
{
|
||||
|
|
@ -68,48 +69,16 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
|
|||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit)
|
||||
{
|
||||
vec3 view = normalize(pos);
|
||||
//normalize view vector
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w / es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
kc.rgb = srgb_to_linear(kc.rgb); // TODO -- pass in waterFogColor linear
|
||||
kc.rgb *= sunlit;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2 * l) - 1.0;
|
||||
|
||||
float L = min(t1 / t2 * t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l * kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
color = applyWaterFogView(pos, color);
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
return color;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file gaussianF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
uniform sampler2D diffuseRect;
|
||||
|
||||
uniform float resScale;
|
||||
|
||||
// texture direction, will be <1, 0> or <0, 1>
|
||||
uniform vec2 direction;
|
||||
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
// get linear depth value given a depth buffer sample d and znear and zfar values
|
||||
float linearDepth(float d, float znear, float zfar);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vec3(0,0,0);
|
||||
|
||||
float w[9] = float[9]( 0.0002, 0.0060, 0.0606, 0.2417, 0.3829, 0.2417, 0.0606, 0.0060, 0.0002 );
|
||||
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
vec2 tc = vary_texcoord0 + (i-4)*direction*resScale;
|
||||
col += texture(diffuseRect, tc).rgb * w[i];
|
||||
}
|
||||
|
||||
frag_color = vec4(col, 0.0);
|
||||
}
|
||||
|
|
@ -127,14 +127,11 @@ vec4 prefilterEnvMap(vec3 R)
|
|||
vec3 V = R;
|
||||
vec4 color = vec4(0.0);
|
||||
float totalWeight = 0.0;
|
||||
float envMapDim = u_width;
|
||||
int numSamples = 4;
|
||||
|
||||
float numMips = max_probe_lod;
|
||||
float envMapDim = float(textureSize(reflectionProbes, 0).s);
|
||||
float roughness = mipLevel/max_probe_lod;
|
||||
int numSamples = max(int(32*roughness), 1);
|
||||
|
||||
float roughness = mipLevel/numMips;
|
||||
|
||||
numSamples = max(int(numSamples*roughness), 1);
|
||||
float numMips = max_probe_lod+1;
|
||||
|
||||
for(uint i = 0u; i < numSamples; i++) {
|
||||
vec2 Xi = hammersley2d(i, numSamples);
|
||||
|
|
@ -154,11 +151,9 @@ vec4 prefilterEnvMap(vec3 R)
|
|||
// 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 mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, numMips);
|
||||
//float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
|
||||
color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip) * dotNL;
|
||||
float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
|
||||
color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL;
|
||||
totalWeight += dotNL;
|
||||
|
||||
}
|
||||
}
|
||||
return (color / totalWeight);
|
||||
|
|
|
|||
|
|
@ -23,78 +23,14 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
// NOTE screenMap should always be texture channel 0 and
|
||||
// depthmap should always be channel 1
|
||||
uniform sampler2D diffuseRect;
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float resScale;
|
||||
uniform float znear;
|
||||
uniform float zfar;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
// get linear depth value given a depth buffer sample d and znear and zfar values
|
||||
float linearDepth(float d, float znear, float zfar);
|
||||
in vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
#if 0
|
||||
float w[9];
|
||||
|
||||
float c = 1.0/16.0; //corner weight
|
||||
float e = 1.0/8.0; //edge weight
|
||||
float m = 1.0/4.0; //middle weight
|
||||
|
||||
//float wsum = c*4+e*4+m;
|
||||
|
||||
w[0] = c; w[1] = e; w[2] = c;
|
||||
w[3] = e; w[4] = m; w[5] = e;
|
||||
w[6] = c; w[7] = e; w[8] = c;
|
||||
|
||||
vec2 tc[9];
|
||||
|
||||
float ed = 1;
|
||||
float cd = 1;
|
||||
|
||||
|
||||
tc[0] = vec2(-cd, cd); tc[1] = vec2(0, ed); tc[2] = vec2(cd, cd);
|
||||
tc[3] = vec2(-ed, 0); tc[4] = vec2(0, 0); tc[5] = vec2(ed, 0);
|
||||
tc[6] = vec2(-cd, -cd); tc[7] = vec2(0, -ed); tc[8] = vec2(cd, -1);
|
||||
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
color += texture2D(screenMap, vary_texcoord0.xy+tc[i]).rgb * w[i];
|
||||
//color += texture2D(screenMap, vary_texcoord0.xy+tc[i]*2.0).rgb * w[i]*0.5;
|
||||
}
|
||||
|
||||
//color /= wsum;
|
||||
|
||||
frag_color = vec4(color, 1.0);
|
||||
#else
|
||||
float depth = texture(depthMap, vary_texcoord0.xy).r;
|
||||
float dist = linearDepth(depth, znear, zfar);
|
||||
|
||||
// convert linear depth to distance
|
||||
vec3 v;
|
||||
v.xy = vary_texcoord0.xy / 512.0 * 2.0 - 1.0;
|
||||
v.z = 1.0;
|
||||
v = normalize(v);
|
||||
dist /= v.z;
|
||||
|
||||
vec3 col = texture2D(diffuseRect, vary_texcoord0.xy).rgb;
|
||||
frag_color = vec4(col, dist/256.0);
|
||||
#endif
|
||||
vec3 col = texture(diffuseRect, vary_texcoord0.xy).rgb;
|
||||
frag_color = vec4(col, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,17 +25,13 @@
|
|||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
in vec3 position;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
out vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
vary_texcoord0 = texcoord0;
|
||||
vertex_color = diffuse_color;
|
||||
vary_texcoord0 = position.xy*0.5+0.5;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,9 @@ void main()
|
|||
|
||||
calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
|
||||
|
||||
vec3 sunlit_linear = srgb_to_linear(sunlit);
|
||||
vec3 amblit_linear = amblit;
|
||||
|
||||
vec3 irradiance;
|
||||
vec3 glossenv;
|
||||
vec3 legacyenv;
|
||||
|
|
@ -266,7 +269,7 @@ void main()
|
|||
|
||||
color.a = final_alpha;
|
||||
|
||||
vec3 sun_contrib = min(final_da, shadow) * sunlit;
|
||||
vec3 sun_contrib = min(final_da, shadow) * sunlit_linear;
|
||||
|
||||
color.rgb = max(amblit, irradiance);
|
||||
|
||||
|
|
@ -274,8 +277,10 @@ void main()
|
|||
|
||||
color.rgb *= diffuse_linear.rgb;
|
||||
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
|
||||
color.rgb = scaleSoftClipFragLinear(color.rgb);
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
vec4 light = vec4(0,0,0,0);
|
||||
|
||||
|
|
@ -294,8 +299,9 @@ void main()
|
|||
color.rgb += light.rgb;
|
||||
#endif // !defined(LOCAL_LIGHT_KILL)
|
||||
|
||||
|
||||
#ifdef WATER_FOG
|
||||
color = applyWaterFogViewLinear(pos.xyz, color, sunlit);
|
||||
color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear);
|
||||
#endif // WATER_FOG
|
||||
|
||||
#endif // #else // FOR_IMPOSTOR
|
||||
|
|
@ -303,6 +309,7 @@ void main()
|
|||
#ifdef IS_HUD
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
#endif
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,14 +46,15 @@ uniform vec3 moon_dir;
|
|||
|
||||
out vec4 frag_color;
|
||||
|
||||
in vec3 vary_fragcoord;
|
||||
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
in vec3 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
#endif
|
||||
|
||||
in vec3 vary_position;
|
||||
|
||||
in vec2 basecolor_texcoord;
|
||||
in vec2 base_color_texcoord;
|
||||
in vec2 normal_texcoord;
|
||||
in vec2 metallic_roughness_texcoord;
|
||||
in vec2 emissive_texcoord;
|
||||
|
|
@ -81,6 +82,8 @@ vec3 srgb_to_linear(vec3 c);
|
|||
vec3 linear_to_srgb(vec3 c);
|
||||
|
||||
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
|
||||
vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten);
|
||||
vec3 scaleSoftClipFragLinear(vec3 color);
|
||||
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
float calcLegacyDistanceAttenuation(float distance, float falloff);
|
||||
|
|
@ -106,16 +109,16 @@ vec3 pbrBaseLight(vec3 diffuseColor,
|
|||
vec3 colorEmissive,
|
||||
float ao,
|
||||
vec3 additive,
|
||||
vec3 atten);
|
||||
vec3 atten,
|
||||
out vec3 specContrib);
|
||||
|
||||
vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
float metallic,
|
||||
vec3 n, // normal
|
||||
vec3 v, // surface point to camera
|
||||
vec3 l); //surface point to light
|
||||
|
||||
vec2 BRDF(float NoV, float roughness);
|
||||
vec3 l, //surface point to light
|
||||
out vec3 specContrib);
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
||||
float perceptualRoughness,
|
||||
|
|
@ -126,7 +129,7 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
|||
vec3 lp, // light position
|
||||
vec3 ld, // light direction (for spotlights)
|
||||
vec3 lightColor,
|
||||
float lightSize, float falloff, float is_pointlight, float ambiance)
|
||||
float lightSize, float falloff, float is_pointlight, inout float glare, float ambiance)
|
||||
{
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
|
|
@ -148,7 +151,10 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
|||
|
||||
vec3 intensity = spot_atten * dist_atten * lightColor * 3.0;
|
||||
|
||||
color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
|
||||
vec3 speccol;
|
||||
color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv, speccol);
|
||||
speccol *= intensity;
|
||||
glare += max(max(speccol.r, speccol.g), speccol.b);
|
||||
}
|
||||
|
||||
return color;
|
||||
|
|
@ -157,13 +163,14 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
|
|||
void main()
|
||||
{
|
||||
vec3 color = vec3(0,0,0);
|
||||
float glare = 0.0;
|
||||
|
||||
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
|
||||
vec3 pos = vary_position;
|
||||
|
||||
waterClip(pos);
|
||||
|
||||
vec4 basecolor = texture(diffuseMap, basecolor_texcoord.xy).rgba;
|
||||
vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
|
||||
basecolor.rgb = srgb_to_linear(basecolor.rgb);
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
if (basecolor.a < minimum_alpha)
|
||||
|
|
@ -191,8 +198,11 @@ void main()
|
|||
vec3 atten;
|
||||
calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
|
||||
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
vec3 sunlit_linear = srgb_to_linear(sunlit);
|
||||
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
|
||||
#endif
|
||||
|
||||
|
|
@ -211,7 +221,7 @@ void main()
|
|||
float gloss = 1.0 - perceptualRoughness;
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
sampleReflectionProbes(irradiance, radiance, vec2(0), pos.xyz, norm.xyz, gloss);
|
||||
sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, pos.xyz, norm.xyz, gloss);
|
||||
// Take maximium of legacy ambient vs irradiance sample as irradiance
|
||||
// NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
|
||||
irradiance = max(amblit,irradiance);
|
||||
|
|
@ -222,15 +232,19 @@ void main()
|
|||
|
||||
vec3 v = -normalize(pos.xyz);
|
||||
|
||||
color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
|
||||
vec3 spec;
|
||||
color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec);
|
||||
glare += max(max(spec.r, spec.g), spec.b);
|
||||
|
||||
float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
|
||||
vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRoughness);
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
|
||||
color.rgb = scaleSoftClipFragLinear(color.rgb);
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
vec3 light = vec3(0);
|
||||
|
||||
// Punctual lights
|
||||
#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
|
||||
#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w);
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
|
|
@ -244,11 +258,10 @@ void main()
|
|||
|
||||
|
||||
float a = basecolor.a*vertex_color.a;
|
||||
vec3 spec = radiance; // *specularColor;
|
||||
float lum = max(max(spec.r, spec.g), spec.b);
|
||||
|
||||
float f = brdf.y;
|
||||
a += f;
|
||||
glare = min(glare, 1.0);
|
||||
a = max(a, glare);
|
||||
|
||||
frag_color = vec4(color.rgb,a);
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +276,7 @@ out vec4 frag_color;
|
|||
|
||||
in vec3 vary_position;
|
||||
|
||||
in vec2 basecolor_texcoord;
|
||||
in vec2 base_color_texcoord;
|
||||
in vec2 emissive_texcoord;
|
||||
|
||||
in vec4 vertex_color;
|
||||
|
|
@ -282,7 +295,7 @@ void main()
|
|||
|
||||
vec3 pos = vary_position;
|
||||
|
||||
vec4 basecolor = texture(diffuseMap, basecolor_texcoord.xy).rgba;
|
||||
vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
|
||||
basecolor.rgb = srgb_to_linear(basecolor.rgb);
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
if (basecolor.a < minimum_alpha)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ uniform mat3 env_mat;
|
|||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
ambenv = vec3(reflection_probe_ambiance * 0.25);
|
||||
|
||||
|
|
@ -43,11 +43,10 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
|||
glossenv = srgb_to_linear(textureCube(environmentMap, env_vec).rgb);
|
||||
}
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness)
|
||||
void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
sampleReflectionProbes(ambenv, glossenv,
|
||||
tc, pos, norm, glossiness, false);
|
||||
sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness);
|
||||
}
|
||||
|
||||
vec4 sampleReflectionProbesDebug(vec3 pos)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,6 @@ float computeLod(float pdf)
|
|||
|
||||
vec4 filterColor(vec3 N)
|
||||
{
|
||||
//return textureLod(uCubeMap, N, 3.0).rgb;
|
||||
vec4 color = vec4(0.f);
|
||||
|
||||
for(int i = 0; i < u_sampleCount; ++i)
|
||||
|
|
@ -192,7 +191,7 @@ vec4 filterColor(vec3 N)
|
|||
// apply the bias to the lod
|
||||
lod += u_lodBias;
|
||||
|
||||
lod = clamp(lod, 0, 7);
|
||||
lod = clamp(lod, 0, max_probe_lod);
|
||||
// sample lambertian at a lower resolution to avoid fireflies
|
||||
vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ vec3 linear_to_srgb(vec3 col);
|
|||
vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
|
||||
{
|
||||
light *= atten.r;
|
||||
light += additive;
|
||||
return light * 2.0;
|
||||
light += additive * 2.0;
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten)
|
||||
|
|
|
|||
|
|
@ -137,12 +137,15 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
|
||||
|
||||
// brightness of surface both sunlight and ambient
|
||||
sunlit = sunlight.rgb;
|
||||
amblit = tmpAmbient.rgb;
|
||||
|
||||
// fudge sunlit and amblit to get consistent lighting compared to legacy
|
||||
// midday before PBR was a thing
|
||||
sunlit = sunlight.rgb * 0.7;
|
||||
amblit = tmpAmbient.rgb * 0.25;
|
||||
|
||||
additive *= vec3(1.0 - combined_haze);
|
||||
}
|
||||
|
||||
|
||||
vec3 srgb_to_linear(vec3 col);
|
||||
|
||||
// provide a touch of lighting in the opposite direction of the sun light
|
||||
|
|
@ -150,21 +153,24 @@ vec3 srgb_to_linear(vec3 col);
|
|||
float ambientLighting(vec3 norm, vec3 light_dir)
|
||||
{
|
||||
float ambient = min(abs(dot(norm.xyz, light_dir.xyz)), 1.0);
|
||||
ambient *= 0.56;
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0 - ambient);
|
||||
return ambient;
|
||||
}
|
||||
|
||||
|
||||
// return colors in linear space
|
||||
// return lit amblit in linear space, leave sunlit and additive in sRGB space
|
||||
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,
|
||||
out vec3 atten)
|
||||
{
|
||||
calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten, false);
|
||||
sunlit = srgb_to_linear(sunlit);
|
||||
additive = srgb_to_linear(additive);
|
||||
amblit = ambient_linear;
|
||||
|
||||
// multiply by 2 to get same colors as when the "scaleSoftClip" implementation was doubling color values
|
||||
// (allows for mixing of light sources other than sunlight e.g. reflection probes)
|
||||
sunlit *= 2.0;
|
||||
amblit *= 2.0;
|
||||
|
||||
amblit *= ambientLighting(norm, light_dir);
|
||||
amblit = srgb_to_linear(amblit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,43 +22,34 @@
|
|||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
uniform float gamma;
|
||||
|
||||
vec3 getAtmosAttenuation();
|
||||
vec3 getAdditiveColor();
|
||||
// DEPRECATED
|
||||
|
||||
vec3 srgb_to_linear(vec3 col);
|
||||
vec3 linear_to_srgb(vec3 col);
|
||||
|
||||
vec3 scaleSoftClipFragLinear(vec3 light)
|
||||
{ // identical to non-linear version and that's probably close enough
|
||||
//soft clip effect:
|
||||
light = 1. - clamp(light, vec3(0.), vec3(1.));
|
||||
light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side
|
||||
return light;
|
||||
}
|
||||
//soft clip effect has been moved to postDeferredGammaCorrect legacyGamma, this file is effectively dead
|
||||
// but these functions need to be removed from all existing shaders before removing this file
|
||||
|
||||
vec3 scaleSoftClipFrag(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
light = 1. - clamp(light, vec3(0.), vec3(1.));
|
||||
light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 scaleSoftClipFragLinear(vec3 light)
|
||||
{ // identical to non-linear version and that's probably close enough
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 scaleSoftClip(vec3 light)
|
||||
{
|
||||
return scaleSoftClipFrag(light);
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten)
|
||||
{
|
||||
//return mix(scaleSoftClipFrag(light.rgb), add, atten);
|
||||
return scaleSoftClipFrag(light.rgb);
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClip(vec3 light)
|
||||
{
|
||||
return fullbrightScaleSoftClipFrag(light, getAdditiveColor(), getAtmosAttenuation());
|
||||
return light;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,23 +48,27 @@ vec3 atmosTransport(vec3 light)
|
|||
vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten)
|
||||
{
|
||||
// same as non-linear version, probably fine
|
||||
float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
|
||||
return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
|
||||
//float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
|
||||
//return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
|
||||
return atmosTransportFrag(light, additive, atten);
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
|
||||
{
|
||||
float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
|
||||
return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
|
||||
//float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
|
||||
//return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
|
||||
return atmosTransportFrag(light, additive, atten);
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light)
|
||||
{
|
||||
return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
|
||||
//return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
|
||||
return atmosTransport(light);
|
||||
}
|
||||
|
||||
vec3 fullbrightShinyAtmosTransport(vec3 light)
|
||||
{
|
||||
float brightness = dot(light.rgb, vec3(0.33333));
|
||||
return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
|
||||
//float brightness = dot(light.rgb, vec3(0.33333));
|
||||
//return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
|
||||
return atmosTransport(light);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ uniform vec3 light_diffuse[8];
|
|||
float getAmbientClamp();
|
||||
void waterClip(vec3 pos);
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
|
||||
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
|
||||
{
|
||||
// SL-14895 inverted attenuation work-around
|
||||
// This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
|
||||
|
|
@ -170,6 +170,11 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
|
|||
vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
|
||||
speccol = clamp(speccol, vec3(0), vec3(1));
|
||||
col += speccol;
|
||||
|
||||
float cur_glare = max(speccol.r, speccol.g);
|
||||
cur_glare = max(cur_glare, speccol.b);
|
||||
glare = max(glare, speccol.r);
|
||||
glare += max(cur_glare, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -218,83 +223,105 @@ VARYING vec2 vary_texcoord0;
|
|||
|
||||
vec2 encode_normal(vec3 n);
|
||||
|
||||
void main()
|
||||
// get the transformed normal and apply glossiness component from normal map
|
||||
vec3 getNormal(inout float glossiness)
|
||||
{
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
waterClip(vary_position.xyz);
|
||||
#endif
|
||||
|
||||
vec2 pos_screen = vary_texcoord0.xy;
|
||||
|
||||
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
diffcol.rgb *= vertex_color.rgb;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
|
||||
|
||||
// Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
|
||||
float bias = 0.001953125; // 1/512, or half an 8-bit quantization
|
||||
if (diffcol.a < minimum_alpha-bias)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
|
||||
glossiness *= norm.a;
|
||||
|
||||
norm.xyz = norm.xyz * 2 - 1;
|
||||
|
||||
return normalize(vec3(dot(norm.xyz,vary_mat0),
|
||||
dot(norm.xyz,vary_mat1),
|
||||
dot(norm.xyz,vary_mat2)));
|
||||
#else
|
||||
return normalize(vary_normal);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 getSpecular()
|
||||
{
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
|
||||
spec.rgb *= specular_color.rgb;
|
||||
#else
|
||||
vec4 spec = vec4(specular_color.rgb, 1.0);
|
||||
#endif
|
||||
return spec;
|
||||
}
|
||||
|
||||
#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;
|
||||
void alphaMask(float alpha)
|
||||
{
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
|
||||
// Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
|
||||
float bias = 0.001953125; // 1/512, or half an 8-bit quantization
|
||||
if (alpha < minimum_alpha-bias)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
norm.xyz = normalize(tnorm.xyz);
|
||||
void waterClip()
|
||||
{
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
waterClip(vary_position.xyz);
|
||||
#endif
|
||||
}
|
||||
|
||||
float getEmissive(vec4 diffcol)
|
||||
{
|
||||
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
|
||||
return emissive_brightness;
|
||||
#else
|
||||
return max(diffcol.a, emissive_brightness);
|
||||
#endif
|
||||
}
|
||||
|
||||
float getShadow(vec3 pos, vec3 norm)
|
||||
{
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
return sampleDirectionalShadow(pos, norm, vary_texcoord0.xy);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
waterClip();
|
||||
|
||||
// diffcol == diffuse map combined with vertex color
|
||||
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
diffcol.rgb *= vertex_color.rgb;
|
||||
|
||||
alphaMask(diffcol.a);
|
||||
|
||||
// spec == specular map combined with specular color
|
||||
vec4 spec = getSpecular();
|
||||
float env = env_intensity * spec.a;
|
||||
float glossiness = specular_color.a;
|
||||
vec3 norm = getNormal(glossiness);
|
||||
|
||||
vec2 abnormal = encode_normal(norm.xyz);
|
||||
|
||||
vec4 final_color = diffcol;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
|
||||
final_color.a = emissive_brightness;
|
||||
#else
|
||||
final_color.a = max(final_color.a, emissive_brightness);
|
||||
#endif
|
||||
|
||||
vec4 final_specular = spec;
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
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, GBUFFER_FLAG_HAS_ATMOS);
|
||||
final_specular.a = specular_color.a;
|
||||
#endif
|
||||
float emissive = getEmissive(diffcol);
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
//forward rendering, output lit linear color
|
||||
diffcol.rgb = srgb_to_linear(diffcol.rgb);
|
||||
final_specular.rgb = srgb_to_linear(final_specular.rgb);
|
||||
spec.rgb = srgb_to_linear(spec.rgb);
|
||||
|
||||
vec3 pos = vary_position;
|
||||
|
||||
float shadow = 1.0f;
|
||||
float shadow = getShadow(pos, norm);
|
||||
|
||||
#ifdef HAS_SUN_SHADOW
|
||||
shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
|
||||
#endif
|
||||
|
||||
vec4 diffuse = final_color;
|
||||
vec4 diffuse = diffcol;
|
||||
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
|
|
@ -307,54 +334,63 @@ void main()
|
|||
vec3 atten;
|
||||
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
|
||||
|
||||
vec3 sunlit_linear = srgb_to_linear(sunlit);
|
||||
vec3 amblit_linear = amblit;
|
||||
|
||||
vec3 ambenv;
|
||||
vec3 glossenv;
|
||||
vec3 legacyenv;
|
||||
sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos_screen, pos.xyz, norm.xyz, final_specular.a, env_intensity);
|
||||
sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env);
|
||||
|
||||
// use sky settings ambient or irradiance map sample, whichever is brighter
|
||||
color = max(amblit, ambenv);
|
||||
color = max(amblit_linear, ambenv);
|
||||
|
||||
float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
|
||||
vec3 sun_contrib = min(da, shadow) * sunlit;
|
||||
vec3 sun_contrib = min(da, shadow) * sunlit_linear;
|
||||
color.rgb += sun_contrib;
|
||||
color *= diffcol.rgb;
|
||||
|
||||
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
|
||||
|
||||
if (final_specular.a > 0.0) // specular reflection
|
||||
float glare = 0.0;
|
||||
|
||||
if (glossiness > 0.0) // specular reflection
|
||||
{
|
||||
float sa = dot(normalize(refnormpersp), light_dir.xyz);
|
||||
vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, final_specular.a)).r);
|
||||
vec3 dumbshiny = sunlit_linear * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r);
|
||||
|
||||
// add the two types of shiny together
|
||||
vec3 spec_contrib = dumbshiny * final_specular.rgb;
|
||||
vec3 spec_contrib = dumbshiny * spec.rgb;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 6;
|
||||
|
||||
glare = max(spec_contrib.r, spec_contrib.g);
|
||||
glare = max(glare, spec_contrib.b);
|
||||
|
||||
color += spec_contrib;
|
||||
|
||||
applyGlossEnv(color, glossenv, final_specular, pos.xyz, norm.xyz);
|
||||
applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
|
||||
}
|
||||
|
||||
color = mix(color.rgb, diffcol.rgb, diffuse.a);
|
||||
color = mix(color.rgb, diffcol.rgb, emissive);
|
||||
|
||||
if (env_intensity > 0.0)
|
||||
if (env > 0.0)
|
||||
{ // add environmentmap
|
||||
applyLegacyEnv(color, legacyenv, final_specular, pos.xyz, norm.xyz, env_intensity);
|
||||
applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, env);
|
||||
|
||||
float cur_glare = max(max(legacyenv.r, legacyenv.g), legacyenv.b);
|
||||
cur_glare *= env*4.0;
|
||||
glare += cur_glare;
|
||||
}
|
||||
|
||||
color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), diffuse.a);
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
|
||||
color.rgb = scaleSoftClipFragLinear(color.rgb);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 temp = applyWaterFogView(pos, vec4(color, 0.0));
|
||||
color = temp.rgb;
|
||||
#endif
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
vec3 npos = normalize(-pos.xyz);
|
||||
vec3 light = vec3(0, 0, 0);
|
||||
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w );
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, spec, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
|
|
@ -364,17 +400,25 @@ void main()
|
|||
LIGHT_LOOP(6)
|
||||
LIGHT_LOOP(7)
|
||||
|
||||
light *= 1.0-emissive;
|
||||
color += light;
|
||||
|
||||
float al = diffcol.a*vertex_color.a;
|
||||
glare *= 1.0-emissive;
|
||||
glare = min(glare, 1.0);
|
||||
float al = max(diffcol.a, glare) * vertex_color.a;
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 temp = applyWaterFogView(pos, vec4(color, 0.0));
|
||||
color = temp.rgb;
|
||||
#endif
|
||||
|
||||
frag_color = vec4(color, al);
|
||||
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
|
||||
|
||||
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
|
||||
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
|
||||
frag_data[0] = final_color; // gbuffer is sRGB for legacy materials
|
||||
frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
frag_data[0] = vec4(diffcol.rgb, emissive); // gbuffer is sRGB for legacy materials
|
||||
frag_data[1] = vec4(spec.rgb, glossiness); // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = vec4(encode_normal(norm), env, GBUFFER_FLAG_HAS_ATMOS);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ uniform sampler2D diffuseRect;
|
|||
uniform sampler2D specularRect;
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D lightFunc;
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
|
|
@ -126,8 +125,7 @@ void main()
|
|||
diffuse = srgb_to_linear(diffuse);
|
||||
spec.rgb = srgb_to_linear(spec.rgb);
|
||||
|
||||
float noise = texture2D(noiseMap, tc).b;
|
||||
float lit = nl * dist_atten * noise;
|
||||
float lit = nl * dist_atten;
|
||||
|
||||
final_color = color.rgb*lit*diffuse;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ bool isAbove(vec3 pos, vec4 plane)
|
|||
return (dot(plane.xyz, pos) + plane.w) > 0;
|
||||
}
|
||||
|
||||
int max_priority = 0;
|
||||
bool sample_automatic = true;
|
||||
|
||||
// return true if probe at index i influences position pos
|
||||
bool shouldSampleProbe(int i, vec3 pos)
|
||||
|
|
@ -95,24 +95,24 @@ bool shouldSampleProbe(int i, vec3 pos)
|
|||
return false;
|
||||
}
|
||||
|
||||
max_priority = max(max_priority, -refIndex[i].w);
|
||||
sample_automatic = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (refSphere[i].w > 0.0) // zero is special indicator to always sample this probe
|
||||
if (refIndex[i].w == 0 && !sample_automatic)
|
||||
{
|
||||
vec3 delta = pos.xyz - refSphere[i].xyz;
|
||||
float d = dot(delta, delta);
|
||||
float r2 = refSphere[i].w;
|
||||
r2 *= r2;
|
||||
|
||||
if (d > r2)
|
||||
{ //outside bounding sphere
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
max_priority = max(max_priority, refIndex[i].w);
|
||||
vec3 delta = pos.xyz - refSphere[i].xyz;
|
||||
float d = dot(delta, delta);
|
||||
float r2 = refSphere[i].w;
|
||||
r2 *= r2;
|
||||
|
||||
if (d > r2)
|
||||
{ // outside bounding sphere
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -120,7 +120,6 @@ bool shouldSampleProbe(int i, vec3 pos)
|
|||
|
||||
// call before sampleRef
|
||||
// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT
|
||||
// overall algorithm --
|
||||
void preProbeSample(vec3 pos)
|
||||
{
|
||||
// TODO: make some sort of structure that reduces the number of distance checks
|
||||
|
|
@ -210,7 +209,7 @@ void preProbeSample(vec3 pos)
|
|||
}
|
||||
}
|
||||
|
||||
if (max_priority <= 1)
|
||||
if (sample_automatic)
|
||||
{ // probe at index 0 is a special probe for smoothing out automatic probes
|
||||
probeIndex[probeInfluences++] = 0;
|
||||
}
|
||||
|
|
@ -342,7 +341,7 @@ return texCUBE(envMap, ReflDirectionWS);
|
|||
// d - distance to nearest wall in clip space
|
||||
vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
|
||||
{
|
||||
// Intersection with OBB convertto unit box space
|
||||
// Intersection with OBB convert to unit box space
|
||||
// Transform in local unit parallax cube space (scaled and rotated)
|
||||
mat4 clipToLocal = refBox[i];
|
||||
|
||||
|
|
@ -431,18 +430,24 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
|
|||
// origin - center of sphere probe
|
||||
// r - radius of probe influence volume
|
||||
// min_da - minimum angular attenuation coefficient
|
||||
float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da)
|
||||
// i - index of probe in refSphere
|
||||
// dw - distance weight
|
||||
float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da, int i, out float dw)
|
||||
{
|
||||
float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
|
||||
vec3 delta = pos.xyz - origin;
|
||||
float d2 = max(length(delta), 0.001);
|
||||
|
||||
float r2 = r1; //r1 * r1;
|
||||
|
||||
//float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);
|
||||
float atten = 1.0 - max(d2 - r2, 0.0) / max((r - r2), 0.001);
|
||||
float w = 1.0 / d2;
|
||||
|
||||
dw = w * atten * max(r, 1.0)*4;
|
||||
|
||||
atten *= max(dot(normalize(-delta), dir), min_da);
|
||||
float w = 1.0 / d2;
|
||||
|
||||
w *= atten;
|
||||
|
||||
return w;
|
||||
|
|
@ -451,48 +456,43 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da)
|
|||
// Tap a reflection probe
|
||||
// pos - position of pixel
|
||||
// dir - pixel normal
|
||||
// vi - return value of intersection point with influence volume
|
||||
// wi - return value of approximate world space position of sampled pixel
|
||||
// lod - which mip to bias towards (lower is higher res, sharper reflections)
|
||||
// w - weight of sample (distance and angular attenuation)
|
||||
// dw - weight of sample (distance only)
|
||||
// lod - which mip to sample (lower is higher res, sharper reflections)
|
||||
// c - center of probe
|
||||
// r2 - radius of probe squared
|
||||
// i - index of probe
|
||||
vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float lod, vec3 c, int i)
|
||||
vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i)
|
||||
{
|
||||
//lod = max(lod, 1);
|
||||
// parallax adjustment
|
||||
|
||||
vec3 v;
|
||||
|
||||
if (refIndex[i].w < 0)
|
||||
{
|
||||
{ // box probe
|
||||
float d = 0;
|
||||
v = boxIntersect(pos, dir, i, d);
|
||||
|
||||
w = max(d, 0.001);
|
||||
}
|
||||
else
|
||||
{
|
||||
float r = refSphere[i].w; // radius of sphere volume
|
||||
float rr = r * r; // radius squared
|
||||
{ // sphere probe
|
||||
float r = refSphere[i].w;
|
||||
|
||||
float rr = r * r;
|
||||
|
||||
v = sphereIntersect(pos, dir, c,
|
||||
refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
|
||||
refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
|
||||
rr);
|
||||
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25);
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25, i, dw);
|
||||
}
|
||||
|
||||
vi = v;
|
||||
|
||||
v -= c;
|
||||
vec3 d = normalize(v);
|
||||
|
||||
v = env_mat * v;
|
||||
|
||||
vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod);
|
||||
|
||||
wi = d * ret.a * 256.0+c;
|
||||
vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y;
|
||||
|
||||
return ret.rgb;
|
||||
}
|
||||
|
|
@ -500,10 +500,10 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float
|
|||
// Tap an irradiance map
|
||||
// pos - position of pixel
|
||||
// dir - pixel normal
|
||||
// c - center of probe
|
||||
// r2 - radius of probe squared
|
||||
// w - weight of sample (distance and angular attenuation)
|
||||
// dw - weight of sample (distance only)
|
||||
// i - index of probe
|
||||
vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
|
||||
vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int i)
|
||||
{
|
||||
// parallax adjustment
|
||||
vec3 v;
|
||||
|
|
@ -516,14 +516,15 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
|
|||
else
|
||||
{
|
||||
float r = refSphere[i].w; // radius of sphere volume
|
||||
float p = float(abs(refIndex[i].w)); // priority
|
||||
float rr = r * r; // radius squred
|
||||
|
||||
// pad sphere for manual probe extending into automatic probe space
|
||||
float rr = r * r;
|
||||
|
||||
v = sphereIntersect(pos, dir, c,
|
||||
refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
|
||||
refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
|
||||
rr);
|
||||
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001);
|
||||
w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001, i, dw);
|
||||
}
|
||||
|
||||
v -= c;
|
||||
|
|
@ -533,106 +534,129 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
|
|||
}
|
||||
}
|
||||
|
||||
vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)
|
||||
vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
|
||||
{
|
||||
float wsum = 0.0;
|
||||
vec3 col = vec3(0,0,0);
|
||||
float vd2 = dot(pos,pos); // view distance squared
|
||||
float wsum[2];
|
||||
wsum[0] = 0;
|
||||
wsum[1] = 0;
|
||||
|
||||
float dwsum[2];
|
||||
dwsum[0] = 0;
|
||||
dwsum[1] = 0;
|
||||
|
||||
vec3 col[2];
|
||||
col[0] = vec3(0);
|
||||
col[1] = vec3(0);
|
||||
|
||||
for (int idx = 0; idx < probeInfluences; ++idx)
|
||||
{
|
||||
int i = probeIndex[idx];
|
||||
if (abs(refIndex[i].w) < max_priority)
|
||||
int p = clamp(abs(refIndex[i].w), 0, 1);
|
||||
|
||||
if (p == 0 && !sample_automatic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float w;
|
||||
vec3 vi, wi;
|
||||
float w = 0;
|
||||
float dw = 0;
|
||||
vec3 refcol;
|
||||
|
||||
|
||||
{
|
||||
if (errorCorrect && refIndex[i].w >= 0)
|
||||
{ // error correction is on and this probe is a sphere
|
||||
//take a sample to get depth value, then error correct
|
||||
refcol = tapRefMap(pos, dir, w, vi, wi, abs(lod + 2), refSphere[i].xyz, i);
|
||||
refcol = tapRefMap(pos, dir, w, dw, lod, refSphere[i].xyz, i);
|
||||
|
||||
//adjust lookup by distance result
|
||||
float d = length(vi - wi);
|
||||
vi += dir * d;
|
||||
|
||||
vi -= refSphere[i].xyz;
|
||||
|
||||
vi = env_mat * vi;
|
||||
|
||||
refcol = textureLod(reflectionProbes, vec4(vi, refIndex[i].x), lod).rgb;
|
||||
|
||||
// weight by vector correctness
|
||||
vec3 pi = normalize(wi - pos);
|
||||
w *= max(dot(pi, dir), 0.1);
|
||||
//w = pow(w, 32.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
refcol = tapRefMap(pos, dir, w, vi, wi, lod, refSphere[i].xyz, i);
|
||||
}
|
||||
|
||||
col += refcol.rgb*w;
|
||||
|
||||
wsum += w;
|
||||
col[p] += refcol.rgb*w;
|
||||
wsum[p] += w;
|
||||
dwsum[p] += dw;
|
||||
}
|
||||
}
|
||||
|
||||
if (wsum > 0.0)
|
||||
// mix automatic and manual probes
|
||||
if (sample_automatic && wsum[0] > 0.0)
|
||||
{ // some automatic probes were sampled
|
||||
col[0] *= 1.0/wsum[0];
|
||||
if (wsum[1] > 0.0)
|
||||
{ //some manual probes were sampled, mix between the two
|
||||
col[1] *= 1.0/wsum[1];
|
||||
col[1] = mix(col[0], col[1], min(dwsum[1], 1.0));
|
||||
col[0] = vec3(0);
|
||||
}
|
||||
}
|
||||
else if (wsum[1] > 0.0)
|
||||
{
|
||||
col *= 1.0/wsum;
|
||||
// manual probes were sampled but no automatic probes were
|
||||
col[1] *= 1.0/wsum[1];
|
||||
col[0] = vec3(0);
|
||||
}
|
||||
|
||||
return col;
|
||||
return col[1]+col[0];
|
||||
}
|
||||
|
||||
vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
|
||||
{
|
||||
// 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
|
||||
float wsum[2];
|
||||
wsum[0] = 0;
|
||||
wsum[1] = 0;
|
||||
|
||||
float minweight = 1.0;
|
||||
float dwsum[2];
|
||||
dwsum[0] = 0;
|
||||
dwsum[1] = 0;
|
||||
|
||||
vec3 col[2];
|
||||
col[0] = vec3(0);
|
||||
col[1] = vec3(0);
|
||||
|
||||
for (int idx = 0; idx < probeInfluences; ++idx)
|
||||
{
|
||||
int i = probeIndex[idx];
|
||||
if (abs(refIndex[i].w) < max_priority)
|
||||
int p = clamp(abs(refIndex[i].w), 0, 1);
|
||||
|
||||
if (p == 0 && !sample_automatic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
float w;
|
||||
vec3 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i);
|
||||
float w = 0;
|
||||
float dw = 0;
|
||||
|
||||
col += refcol*w;
|
||||
|
||||
wsum += w;
|
||||
vec3 refcol = tapIrradianceMap(pos, dir, w, dw, refSphere[i].xyz, i);
|
||||
|
||||
col[p] += refcol*w;
|
||||
wsum[p] += w;
|
||||
dwsum[p] += dw;
|
||||
}
|
||||
}
|
||||
|
||||
if (wsum > 0.0)
|
||||
{
|
||||
col *= 1.0/wsum;
|
||||
// mix automatic and manual probes
|
||||
if (sample_automatic && wsum[0] > 0.0)
|
||||
{ // some automatic probes were sampled
|
||||
col[0] *= 1.0/wsum[0];
|
||||
if (wsum[1] > 0.0)
|
||||
{ //some manual probes were sampled, mix between the two
|
||||
col[1] *= 1.0/wsum[1];
|
||||
col[1] = mix(col[0], col[1], min(dwsum[1], 1.0));
|
||||
col[0] = vec3(0);
|
||||
}
|
||||
}
|
||||
|
||||
return col;
|
||||
else if (wsum[1] > 0.0)
|
||||
{
|
||||
// manual probes were sampled but no automatic probes were
|
||||
col[1] *= 1.0/wsum[1];
|
||||
col[0] = vec3(0);
|
||||
}
|
||||
|
||||
return col[1]+col[0];
|
||||
}
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
// TODO - don't hard code lods
|
||||
float reflection_lods = max_probe_lod;
|
||||
float reflection_lods = max_probe_lod-1;
|
||||
preProbeSample(pos);
|
||||
|
||||
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
|
||||
|
|
@ -640,13 +664,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
|||
ambenv = sampleProbeAmbient(pos, norm);
|
||||
|
||||
float lod = (1.0-glossiness)*reflection_lods;
|
||||
glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
|
||||
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
|
||||
|
||||
#if defined(SSR)
|
||||
if (cube_snapshot != 1 && glossiness >= 0.9)
|
||||
{
|
||||
vec4 ssr = vec4(0);
|
||||
//float w = tapScreenSpaceReflection(errorCorrect ? 1 : 4, tc, pos, norm, ssr, sceneMap);
|
||||
float w = tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap);
|
||||
|
||||
glossenv = mix(glossenv, ssr.rgb, w);
|
||||
|
|
@ -654,11 +677,20 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
|||
#endif
|
||||
}
|
||||
|
||||
void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness);
|
||||
|
||||
// fudge factor to get PBR water at a similar luminance ot legacy water
|
||||
glossenv *= 0.25;
|
||||
}
|
||||
|
||||
void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
|
||||
{
|
||||
vec3 origin = vec3(0,0,0);
|
||||
|
||||
bool manual_probe = abs(refIndex[i].w) > 2;
|
||||
bool manual_probe = abs(refIndex[i].w) > 0;
|
||||
|
||||
if (manual_probe)
|
||||
{
|
||||
|
|
@ -694,18 +726,9 @@ vec4 sampleReflectionProbesDebug(vec3 pos)
|
|||
return col;
|
||||
}
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness)
|
||||
{
|
||||
sampleReflectionProbes(ambenv, glossenv,
|
||||
tc, pos, norm, glossiness, false);
|
||||
}
|
||||
|
||||
|
||||
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity)
|
||||
{
|
||||
// TODO - don't hard code lods
|
||||
float reflection_lods = max_probe_lod;
|
||||
preProbeSample(pos);
|
||||
|
||||
|
|
@ -716,12 +739,12 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
|
|||
if (glossiness > 0.0)
|
||||
{
|
||||
float lod = (1.0-glossiness)*reflection_lods;
|
||||
glossenv = sampleProbes(pos, normalize(refnormpersp), lod, false);
|
||||
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
|
||||
}
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false);
|
||||
legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
|
||||
}
|
||||
|
||||
#if defined(SSR)
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ float getDepth(vec2 pos_screen);
|
|||
vec3 linear_to_srgb(vec3 c);
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
uniform vec4 waterPlane;
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
|
||||
#endif
|
||||
|
|
@ -153,6 +155,24 @@ void main()
|
|||
|
||||
calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
|
||||
|
||||
vec3 sunlit_linear = srgb_to_linear(sunlit);
|
||||
vec3 amblit_linear = amblit;
|
||||
|
||||
bool do_atmospherics = false;
|
||||
|
||||
#ifndef WATER_FOG
|
||||
// when above water, mask off atmospherics below water
|
||||
if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
|
||||
{
|
||||
do_atmospherics = true;
|
||||
}
|
||||
#else
|
||||
do_atmospherics = true;
|
||||
#endif
|
||||
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
vec3 orm = texture2D(specularRect, tc).rgb;
|
||||
|
|
@ -161,23 +181,32 @@ void main()
|
|||
float ao = orm.r * ambocc;
|
||||
|
||||
vec3 colorEmissive = texture2D(emissiveRect, tc).rgb;
|
||||
|
||||
// PBR IBL
|
||||
float gloss = 1.0 - perceptualRoughness;
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
|
||||
sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss);
|
||||
|
||||
// Take maximium of legacy ambient vs irradiance sample as irradiance
|
||||
// NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
|
||||
irradiance = max(amblit,irradiance);
|
||||
irradiance = max(amblit_linear,irradiance);
|
||||
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
|
||||
|
||||
vec3 v = -normalize(pos.xyz);
|
||||
color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
|
||||
color = vec3(1,0,1);
|
||||
color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
|
||||
|
||||
|
||||
if (do_atmospherics)
|
||||
{
|
||||
color = linear_to_srgb(color);
|
||||
color = atmosFragLightingLinear(color, additive, atten);
|
||||
color = srgb_to_linear(color);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
|
||||
{
|
||||
|
|
@ -199,12 +228,12 @@ void main()
|
|||
sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity);
|
||||
|
||||
// use sky settings ambient or irradiance map sample, whichever is brighter
|
||||
irradiance = max(amblit, irradiance);
|
||||
irradiance = max(amblit_linear, irradiance);
|
||||
|
||||
// apply lambertian IBL only (see pbrIbl)
|
||||
color.rgb = irradiance * ambocc;
|
||||
|
||||
vec3 sun_contrib = min(da, scol) * sunlit;
|
||||
vec3 sun_contrib = min(da, scol) * sunlit_linear;
|
||||
color.rgb += sun_contrib;
|
||||
color.rgb *= baseColor.rgb;
|
||||
|
||||
|
|
@ -230,9 +259,16 @@ void main()
|
|||
applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
|
||||
}
|
||||
|
||||
color = mix(atmosFragLightingLinear(color, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), baseColor.a);
|
||||
color = scaleSoftClipFragLinear(color);
|
||||
}
|
||||
|
||||
if (do_atmospherics)
|
||||
{
|
||||
color = linear_to_srgb(color);
|
||||
color = atmosFragLightingLinear(color, additive, atten);
|
||||
color = srgb_to_linear(color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
|
|||
}
|
||||
|
||||
vec3 srgb_to_linear(vec3 col);
|
||||
vec3 linear_to_srgb(vec3 col);
|
||||
|
||||
vec3 vN, vT, vB;
|
||||
|
||||
|
|
@ -122,11 +123,8 @@ vec3 transform_normal(vec3 vNt)
|
|||
return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
|
||||
}
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness);
|
||||
|
||||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
|
||||
void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec2 tc, vec3 pos, vec3 norm, float glossiness);
|
||||
|
||||
vec3 getPositionWithNDC(vec3 ndc);
|
||||
|
||||
|
|
@ -203,6 +201,8 @@ void main()
|
|||
|
||||
calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
|
||||
|
||||
vec3 sunlit_linear = srgb_to_linear(sunlit);
|
||||
|
||||
#ifdef TRANSPARENT_WATER
|
||||
vec4 fb = texture2D(screenTex, distort2);
|
||||
float depth = texture2D(screenDepth, distort2).r;
|
||||
|
|
@ -219,21 +219,24 @@ void main()
|
|||
|
||||
fb = applyWaterFogViewLinear(refPos, fb, sunlit);
|
||||
#else
|
||||
vec4 fb = applyWaterFogViewLinear(viewVec*1024.0, vec4(0.5), sunlit);
|
||||
vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);
|
||||
#endif
|
||||
|
||||
// fudge sample on other side of water to be a tad darker
|
||||
fb.rgb *= 0.75;
|
||||
|
||||
float metallic = 0.0;
|
||||
float perceptualRoughness = 0.1;
|
||||
float perceptualRoughness = 0.05;
|
||||
float gloss = 1.0 - perceptualRoughness;
|
||||
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss);
|
||||
sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss);
|
||||
|
||||
irradiance = vec3(0);
|
||||
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
vec3 diffuseColor = vec3(0);
|
||||
vec3 specularColor = vec3(0);
|
||||
calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);
|
||||
|
||||
vec3 v = -normalize(pos.xyz);
|
||||
|
|
@ -250,10 +253,7 @@ void main()
|
|||
|
||||
vec3 punctual = pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir));
|
||||
|
||||
vec3 color = punctual * sunlit * 2.75 * scol;
|
||||
|
||||
color = atmosFragLightingLinear(color, additive, atten);
|
||||
color = scaleSoftClipFragLinear(color);
|
||||
vec3 color = punctual * sunlit_linear * 2.75 * scol;
|
||||
|
||||
vec3 ibl = pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0);
|
||||
|
||||
|
|
@ -265,10 +265,24 @@ void main()
|
|||
f *= 0.9;
|
||||
f *= f;
|
||||
|
||||
// incoming scale is [0, 1] with 0.5 being default
|
||||
// shift to 0.5 to 1.5
|
||||
f *= (fresnelScale - 0.5)+1.0;
|
||||
|
||||
// incoming offset is [0, 1] with 0.5 being default
|
||||
// shift from -1 to 1
|
||||
f += (fresnelOffset - 0.5) * 2.0;
|
||||
|
||||
f = clamp(f, 0, 1);
|
||||
//fb.rgb *= 1.;
|
||||
|
||||
|
||||
color = mix(color, fb.rgb, f);
|
||||
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
color = atmosFragLightingLinear(color, additive, atten);
|
||||
color = scaleSoftClipFragLinear(color);
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
|
||||
float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
|
||||
|
||||
frag_color = vec4(color, spec); //*sunAngle2);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version 48
|
||||
version 50
|
||||
// The version number above should be incremented IF AND ONLY IF some
|
||||
// change has been made that is sufficiently important to justify
|
||||
// resetting the graphics preferences of all users to the recommended
|
||||
|
|
@ -71,7 +71,7 @@ RenderFSAASamples 1 16
|
|||
RenderMaxTextureIndex 1 16
|
||||
RenderGLContextCoreProfile 1 1
|
||||
RenderGLMultiThreaded 1 0
|
||||
RenderReflectionProbeResolution 1 256
|
||||
RenderReflectionProbeResolution 1 128
|
||||
RenderScreenSpaceReflections 1 1
|
||||
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ RenderGlowResolutionPow 1 8
|
|||
RenderMaxPartCount 1 2048
|
||||
RenderLocalLights 1 1
|
||||
RenderTransparentWater 1 0
|
||||
RenderReflectionsEnabled 1 0
|
||||
RenderReflectionsEnabled 1 1
|
||||
RenderReflectionProbeDetail 1 0
|
||||
RenderTerrainDetail 1 1
|
||||
RenderTerrainLODFactor 1 1.0
|
||||
|
|
@ -279,12 +279,6 @@ RenderUseAdvancedAtmospherics 1 0
|
|||
list VRAMGT512
|
||||
RenderCompressTextures 1 0
|
||||
|
||||
//
|
||||
// VRAM < 2GB
|
||||
//
|
||||
list VRAMLT2GB
|
||||
RenderReflectionProbeResolution 1 128
|
||||
|
||||
//
|
||||
// "Default" setups for safe, low, medium, high
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version 37
|
||||
version 38
|
||||
// The version number above should be incremented IF AND ONLY IF some
|
||||
// change has been made that is sufficiently important to justify
|
||||
// resetting the graphics preferences of all users to the recommended
|
||||
|
|
@ -71,7 +71,7 @@ RenderFSAASamples 1 16
|
|||
RenderMaxTextureIndex 1 16
|
||||
RenderGLContextCoreProfile 1 1
|
||||
RenderGLMultiThreaded 1 0
|
||||
RenderReflectionProbeResolution 1 256
|
||||
RenderReflectionProbeResolution 1 128
|
||||
RenderScreenSpaceReflections 1 1
|
||||
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ RenderGlowResolutionPow 1 8
|
|||
RenderMaxPartCount 1 2048
|
||||
RenderLocalLights 1 1
|
||||
RenderTransparentWater 1 0
|
||||
RenderReflectionsEnabled 1 0
|
||||
RenderReflectionsEnabled 1 1
|
||||
RenderReflectionProbeDetail 1 0
|
||||
RenderTerrainDetail 1 1
|
||||
RenderTerrainLODFactor 1 1.0
|
||||
|
|
@ -279,12 +279,6 @@ RenderUseAdvancedAtmospherics 1 0
|
|||
list VRAMGT512
|
||||
RenderCompressTextures 1 0
|
||||
|
||||
//
|
||||
// VRAM < 2GB
|
||||
//
|
||||
list VRAMLT2GB
|
||||
RenderReflectionProbeResolution 1 128
|
||||
|
||||
//
|
||||
// "Default" setups for safe, low, medium, high
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version 44
|
||||
version 45
|
||||
// The version number above should be incremented IF AND ONLY IF some
|
||||
// change has been made that is sufficiently important to justify
|
||||
// resetting the graphics preferences of all users to the recommended
|
||||
|
|
@ -71,6 +71,7 @@ RenderGLMultiThreaded 1 0
|
|||
RenderReflectionsEnabled 1 1
|
||||
RenderReflectionProbeDetail 1 2
|
||||
RenderScreenSpaceReflections 1 1
|
||||
RenderReflectionProbeCount 1 8
|
||||
|
||||
//
|
||||
// Low Graphics Settings
|
||||
|
|
@ -123,7 +124,7 @@ RenderUseAdvancedAtmospherics 1 0
|
|||
RenderShadowDetail 1 0
|
||||
WLSkyDetail 1 48
|
||||
RenderFSAASamples 1 0
|
||||
RenderReflectionsEnabled 1 0
|
||||
RenderReflectionsEnabled 1 1
|
||||
RenderReflectionProbeDetail 1 0
|
||||
RenderScreenSpaceReflections 1 0
|
||||
|
||||
|
|
|
|||
|
|
@ -4727,8 +4727,6 @@ bool LLAgent::teleportCore(bool is_local)
|
|||
LL_INFOS("Teleport") << "Non-local, setting teleport state to TELEPORT_START" << LL_ENDL;
|
||||
gAgent.setTeleportState( LLAgent::TELEPORT_START );
|
||||
|
||||
//release geometry from old location
|
||||
gPipeline.resetVertexBuffers();
|
||||
LLSpatialPartition::sTeleportRequested = TRUE;
|
||||
|
||||
// <FS:Ansariel> Draw Distance stepping; originally based on SpeedRez by Henri Beauchamp, licensed under LGPL
|
||||
|
|
@ -5122,7 +5120,6 @@ void LLAgent::teleportCancel()
|
|||
}
|
||||
clearTeleportRequest();
|
||||
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
|
||||
gPipeline.resetVertexBuffers();
|
||||
}
|
||||
|
||||
void LLAgent::restoreCanceledTeleportRequest()
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
|
|||
break;
|
||||
case POOL_GLTF_PBR:
|
||||
poolp = new LLDrawPoolGLTFPBR();
|
||||
break;
|
||||
case POOL_GLTF_PBR_ALPHA_MASK:
|
||||
poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
|
||||
break;
|
||||
default:
|
||||
LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
|
||||
|
|
@ -717,11 +720,6 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textur
|
|||
}
|
||||
}
|
||||
|
||||
//if (params.mGroup) // TOO LATE!
|
||||
//{
|
||||
// params.mGroup->rebuildMesh();
|
||||
//}
|
||||
|
||||
params.mVertexBuffer->setBuffer();
|
||||
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,9 @@ public:
|
|||
POOL_BUMP,
|
||||
POOL_TERRAIN,
|
||||
POOL_MATERIALS,
|
||||
POOL_GRASS,
|
||||
POOL_GLTF_PBR,
|
||||
POOL_GRASS,
|
||||
POOL_GLTF_PBR_ALPHA_MASK,
|
||||
POOL_TREE,
|
||||
POOL_ALPHA_MASK,
|
||||
POOL_FULLBRIGHT_ALPHA_MASK,
|
||||
|
|
@ -109,7 +110,7 @@ public:
|
|||
|
||||
virtual void render(S32 pass = 0) {};
|
||||
virtual void prerender() {};
|
||||
virtual U32 getVertexDataMask() = 0;
|
||||
virtual U32 getVertexDataMask() { return 0; } // DEPRECATED -- draw pool doesn't actually determine vertex data mask any more
|
||||
virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
|
||||
virtual S32 getShaderLevel() const { return mShaderLevel; }
|
||||
|
||||
|
|
|
|||
|
|
@ -31,11 +31,17 @@
|
|||
#include "llviewershadermgr.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
static const U32 gltf_render_types[] = { LLPipeline::RENDER_TYPE_PASS_GLTF_PBR, LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK };
|
||||
|
||||
LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR() :
|
||||
LLRenderPass(POOL_GLTF_PBR)
|
||||
LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR(U32 type) :
|
||||
LLRenderPass(type)
|
||||
{
|
||||
if (type == LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK)
|
||||
{
|
||||
mRenderType = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRenderType = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLDrawPoolGLTFPBR::getNumDeferredPasses()
|
||||
|
|
@ -47,14 +53,11 @@ void LLDrawPoolGLTFPBR::renderDeferred(S32 pass)
|
|||
{
|
||||
llassert(!LLPipeline::sRenderingHUDs);
|
||||
|
||||
for (U32 type : gltf_render_types)
|
||||
{
|
||||
gDeferredPBROpaqueProgram.bind();
|
||||
pushGLTFBatches(type);
|
||||
gDeferredPBROpaqueProgram.bind();
|
||||
pushGLTFBatches(mRenderType);
|
||||
|
||||
gDeferredPBROpaqueProgram.bind(true);
|
||||
pushRiggedGLTFBatches(type + 1);
|
||||
}
|
||||
gDeferredPBROpaqueProgram.bind(true);
|
||||
pushRiggedGLTFBatches(mRenderType + 1);
|
||||
}
|
||||
|
||||
S32 LLDrawPoolGLTFPBR::getNumPostDeferredPasses()
|
||||
|
|
@ -67,12 +70,9 @@ void LLDrawPoolGLTFPBR::renderPostDeferred(S32 pass)
|
|||
if (LLPipeline::sRenderingHUDs)
|
||||
{
|
||||
gHUDPBROpaqueProgram.bind();
|
||||
for (U32 type : gltf_render_types)
|
||||
{
|
||||
pushGLTFBatches(type);
|
||||
}
|
||||
pushGLTFBatches(mRenderType);
|
||||
}
|
||||
else
|
||||
else if (mRenderType == LLPipeline::RENDER_TYPE_PASS_GLTF_PBR) // HACK -- don't render glow except for the non-alpha masked implementation
|
||||
{
|
||||
gGL.setColorMask(false, true);
|
||||
gPBRGlowProgram.bind();
|
||||
|
|
@ -85,4 +85,3 @@ void LLDrawPoolGLTFPBR::renderPostDeferred(S32 pass)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,21 +32,9 @@
|
|||
class LLDrawPoolGLTFPBR final : public LLRenderPass
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
// 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
|
||||
};
|
||||
U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
|
||||
LLDrawPoolGLTFPBR(U32 type = LLDrawPool::POOL_GLTF_PBR);
|
||||
|
||||
LLDrawPoolGLTFPBR();
|
||||
U32 mRenderType = 0;
|
||||
|
||||
S32 getNumDeferredPasses() override;
|
||||
void renderDeferred(S32 pass) override;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@
|
|||
#include "llvowlsky.h"
|
||||
#include "llsettingsvo.h"
|
||||
|
||||
extern BOOL gCubeSnapshot;
|
||||
|
||||
static LLStaticHashedString sCamPosLocal("camPosLocal");
|
||||
static LLStaticHashedString sCustomAlpha("custom_alpha");
|
||||
|
||||
|
|
@ -416,11 +418,14 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
|
|||
void LLDrawPoolWLSky::renderDeferred(S32 pass)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
|
||||
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
|
||||
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY) || gSky.mVOSkyp.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: remove gSky.mVOSkyp and fold sun/moon into LLVOWLSky
|
||||
gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
|
||||
|
||||
const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
|
||||
|
||||
gGL.setColorMask(true, false);
|
||||
|
|
@ -431,7 +436,10 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
|
|||
{
|
||||
renderSkyHazeDeferred(origin, camHeightLocal);
|
||||
renderHeavenlyBodies();
|
||||
renderStarsDeferred(origin);
|
||||
if (!gCubeSnapshot)
|
||||
{
|
||||
renderStarsDeferred(origin);
|
||||
}
|
||||
renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
|
||||
}
|
||||
gGL.setColorMask(true, true);
|
||||
|
|
|
|||
|
|
@ -1603,7 +1603,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
|
||||
}
|
||||
|
||||
bool do_tex_mat = tex_mode && mTextureMatrix;
|
||||
// For GLTF materials: Transforms will be applied later
|
||||
bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat;
|
||||
|
||||
if (!do_bump)
|
||||
{ //not bump mapped, might be able to do a cheap update
|
||||
|
|
@ -1700,7 +1701,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
*tex_coords0++ = tc;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (do_xform)
|
||||
{
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
|
|
@ -1713,6 +1714,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
|
||||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
|
||||
*tex_coords0++ = tc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
LLVector4a& norm = vf.mNormals[i];
|
||||
LLVector4a& center = *(vf.mCenter);
|
||||
LLVector4a vec = vf.mPositions[i];
|
||||
vec.mul(scalea);
|
||||
planarProjection(tc, norm, center, vec);
|
||||
|
||||
*tex_coords0++ = tc;
|
||||
}
|
||||
}
|
||||
|
|
@ -1780,44 +1795,44 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
}
|
||||
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
|
||||
LLVector4a& norm = vf.mNormals[i];
|
||||
|
||||
LLVector4a& center = *(vf.mCenter);
|
||||
|
||||
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{
|
||||
LLVector4a vec = vf.mPositions[i];
|
||||
|
||||
vec.mul(scalea);
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
|
||||
LLVector4a& norm = vf.mNormals[i];
|
||||
|
||||
LLVector4a& center = *(vf.mCenter);
|
||||
|
||||
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{
|
||||
LLVector4a vec = vf.mPositions[i];
|
||||
|
||||
vec.mul(scalea);
|
||||
|
||||
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
|
||||
{
|
||||
planarProjection(tc, norm, center, vec);
|
||||
}
|
||||
}
|
||||
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
|
||||
{
|
||||
planarProjection(tc, norm, center, vec);
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_mode && mTextureMatrix)
|
||||
{
|
||||
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
|
||||
tmp = tmp * *mTextureMatrix;
|
||||
tc.mV[0] = tmp.mV[0];
|
||||
tc.mV[1] = tmp.mV[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
}
|
||||
if (tex_mode && mTextureMatrix)
|
||||
{
|
||||
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
|
||||
tmp = tmp * *mTextureMatrix;
|
||||
tc.mV[0] = tmp.mV[0];
|
||||
tc.mV[1] = tmp.mV[1];
|
||||
}
|
||||
else if (do_xform)
|
||||
{
|
||||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
}
|
||||
|
||||
*dst++ = tc;
|
||||
if (do_bump)
|
||||
{
|
||||
bump_tc.push_back(tc);
|
||||
}
|
||||
}
|
||||
*dst++ = tc;
|
||||
if (do_bump)
|
||||
{
|
||||
bump_tc.push_back(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!mat && !gltf_mat) && do_bump)
|
||||
|
|
|
|||
|
|
@ -435,18 +435,14 @@ bool LLFeatureManager::loadGPUClass()
|
|||
}
|
||||
|
||||
if (gbps < 0.f)
|
||||
{ //couldn't bench, use GLVersion
|
||||
{ //couldn't bench, default to Low
|
||||
#if LL_DARWIN
|
||||
//GLVersion is misleading on OSX, just default to class 3 if we can't bench
|
||||
LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
|
||||
mGPUClass = GPU_CLASS_3;
|
||||
#else
|
||||
mGPUClass = GPU_CLASS_2;
|
||||
#endif
|
||||
}
|
||||
else if (gbps <= 5.f)
|
||||
{
|
||||
mGPUClass = GPU_CLASS_0;
|
||||
#endif
|
||||
}
|
||||
else if (gbps <= 8.f)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -110,14 +110,21 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
|
|||
shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
|
||||
shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
|
||||
|
||||
const LLMatrix3 base_color_matrix = mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].asMatrix();
|
||||
shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_BASECOLOR_MATRIX, 1, false, (F32*)base_color_matrix.mMatrix);
|
||||
const LLMatrix3 normal_matrix = mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].asMatrix();
|
||||
shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_NORMAL_MATRIX, 1, false, (F32*)normal_matrix.mMatrix);
|
||||
const LLMatrix3 metallic_roughness_matrix = mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].asMatrix();
|
||||
shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_MATRIX, 1, false, (F32*)metallic_roughness_matrix.mMatrix);
|
||||
const LLMatrix3 emissive_matrix = mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].asMatrix();
|
||||
shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_EMISSIVE_MATRIX, 1, false, (F32*)emissive_matrix.mMatrix);
|
||||
F32 base_color_packed[8];
|
||||
mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(base_color_packed);
|
||||
shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed);
|
||||
|
||||
F32 normal_packed[8];
|
||||
mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed);
|
||||
shader->uniform4fv(LLShaderMgr::TEXTURE_NORMAL_TRANSFORM, 2, (F32*)normal_packed);
|
||||
|
||||
F32 metallic_roughness_packed[8];
|
||||
mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].getPacked(metallic_roughness_packed);
|
||||
shader->uniform4fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, 2, (F32*)metallic_roughness_packed);
|
||||
|
||||
F32 emissive_packed[8];
|
||||
mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].getPacked(emissive_packed);
|
||||
shader->uniform4fv(LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM, 2, (F32*)emissive_packed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -693,6 +693,7 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
|
|||
allowedv->push_back("anim");
|
||||
break;
|
||||
case FFLOAD_GLTF:
|
||||
case FFLOAD_MATERIAL:
|
||||
allowedv->push_back("gltf");
|
||||
allowedv->push_back("glb");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -564,9 +564,9 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
|
|||
|
||||
if (LLSDSerialize::deserialize(asset, str, buffer.size()))
|
||||
{
|
||||
if (asset.has("version") && asset["version"] == "1.0")
|
||||
if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString()))
|
||||
{
|
||||
if (asset.has("type") && asset["type"].asString() == "GLTF 2.0")
|
||||
if (asset.has("type") && asset["type"].asString() == LLGLTFMaterial::ASSET_TYPE)
|
||||
{
|
||||
if (asset.has("data") && asset["data"].isString())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -277,10 +277,10 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index)
|
|||
llassert(mat.notNull()); // by this point shouldn't be null
|
||||
if (mat.notNull())
|
||||
{
|
||||
tex_color_id = mat->mBaseColorId;
|
||||
tex_metal_id = mat->mMetallicRoughnessId;
|
||||
tex_emissive_id = mat->mEmissiveId;
|
||||
tex_normal_id = mat->mNormalId;
|
||||
tex_color_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR];
|
||||
tex_metal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS];
|
||||
tex_emissive_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE];
|
||||
tex_normal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL];
|
||||
}
|
||||
if (mFirst)
|
||||
{
|
||||
|
|
@ -420,6 +420,13 @@ BOOL LLMaterialEditor::postBuild()
|
|||
mEmissiveTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY));
|
||||
mNormalTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY));
|
||||
}
|
||||
else
|
||||
{
|
||||
mBaseColorTextureCtrl->setCanApplyImmediately(false);
|
||||
mMetallicTextureCtrl->setCanApplyImmediately(false);
|
||||
mEmissiveTextureCtrl->setCanApplyImmediately(false);
|
||||
mNormalTextureCtrl->setCanApplyImmediately(false);
|
||||
}
|
||||
|
||||
if (!mIsOverride)
|
||||
{
|
||||
|
|
@ -461,6 +468,10 @@ BOOL LLMaterialEditor::postBuild()
|
|||
mBaseColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY));
|
||||
mBaseColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY));
|
||||
}
|
||||
else
|
||||
{
|
||||
mBaseColorCtrl->setCanApplyImmediately(false);
|
||||
}
|
||||
// transparency is a part of base color
|
||||
childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
|
||||
childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY);
|
||||
|
|
@ -477,6 +488,10 @@ BOOL LLMaterialEditor::postBuild()
|
|||
mEmissiveColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY));
|
||||
mEmissiveColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY));
|
||||
}
|
||||
else
|
||||
{
|
||||
mEmissiveColorCtrl->setCanApplyImmediately(false);
|
||||
}
|
||||
|
||||
if (!mIsOverride)
|
||||
{
|
||||
|
|
@ -949,7 +964,7 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_
|
|||
}
|
||||
case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:
|
||||
{
|
||||
nodep->mSavedGLTFOverrideMaterials[te]->setMetallicRoughnessId(mCtrl->getValue().asUUID(), true);
|
||||
nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true);
|
||||
break;
|
||||
}
|
||||
case MATERIAL_EMISIVE_TEX_DIRTY:
|
||||
|
|
@ -991,30 +1006,6 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_
|
|||
LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (!capabilitiesAvailable())
|
||||
|
|
@ -1034,109 +1025,14 @@ void LLMaterialEditor::onClickSave()
|
|||
saveIfNeeded();
|
||||
}
|
||||
|
||||
|
||||
std::string LLMaterialEditor::getGLTFJson(bool prettyprint)
|
||||
{
|
||||
tinygltf::Model model;
|
||||
getGLTFModel(model);
|
||||
|
||||
std::ostringstream str;
|
||||
|
||||
tinygltf::TinyGLTF gltf;
|
||||
|
||||
gltf.WriteGltfSceneToStream(&model, str, prettyprint, false);
|
||||
|
||||
std::string dump = str.str();
|
||||
|
||||
return dump;
|
||||
}
|
||||
|
||||
void LLMaterialEditor::getGLBData(std::vector<U8>& data)
|
||||
{
|
||||
tinygltf::Model model;
|
||||
getGLTFModel(model);
|
||||
|
||||
std::ostringstream str;
|
||||
|
||||
tinygltf::TinyGLTF gltf;
|
||||
|
||||
gltf.WriteGltfSceneToStream(&model, str, false, true);
|
||||
|
||||
std::string dump = str.str();
|
||||
|
||||
data.resize(dump.length());
|
||||
|
||||
memcpy(&data[0], dump.c_str(), dump.length());
|
||||
}
|
||||
|
||||
void LLMaterialEditor::getGLTFModel(tinygltf::Model& model)
|
||||
{
|
||||
model.materials.resize(1);
|
||||
tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness;
|
||||
|
||||
// write base color
|
||||
LLColor4 base_color = getBaseColor();
|
||||
base_color.mV[3] = getTransparency();
|
||||
write_color(base_color, pbrMaterial.baseColorFactor);
|
||||
|
||||
model.materials[0].alphaCutoff = getAlphaCutoff();
|
||||
model.materials[0].alphaMode = getAlphaMode();
|
||||
|
||||
LLUUID base_color_id = getBaseColorId();
|
||||
|
||||
if (base_color_id.notNull())
|
||||
{
|
||||
U32 texture_idx = write_texture(base_color_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();
|
||||
|
||||
model.asset.version = "2.0";
|
||||
}
|
||||
|
||||
std::string LLMaterialEditor::getEncodedAsset()
|
||||
{
|
||||
LLSD asset;
|
||||
asset["version"] = "1.0";
|
||||
asset["type"] = "GLTF 2.0";
|
||||
asset["data"] = getGLTFJson(false);
|
||||
asset["version"] = LLGLTFMaterial::ASSET_VERSION;
|
||||
asset["type"] = LLGLTFMaterial::ASSET_TYPE;
|
||||
LLGLTFMaterial mat;
|
||||
getGLTFMaterial(&mat);
|
||||
asset["data"] = mat.asJSON();
|
||||
|
||||
std::ostringstream str;
|
||||
LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
|
||||
|
|
@ -1151,9 +1047,9 @@ bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
|
|||
std::istrstream str(&buffer[0], buffer.size());
|
||||
if (LLSDSerialize::deserialize(asset, str, buffer.size()))
|
||||
{
|
||||
if (asset.has("version") && asset["version"] == "1.0")
|
||||
if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString()))
|
||||
{
|
||||
if (asset.has("type") && asset["type"] == "GLTF 2.0")
|
||||
if (asset.has("type") && asset["type"] == LLGLTFMaterial::ASSET_TYPE)
|
||||
{
|
||||
if (asset.has("data") && asset["data"].isString())
|
||||
{
|
||||
|
|
@ -1169,6 +1065,12 @@ bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
|
|||
if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
|
||||
{
|
||||
// assets are only supposed to have one item
|
||||
// *NOTE: This duplicates some functionality from
|
||||
// LLGLTFMaterial::fromJSON, but currently does the job
|
||||
// better for the material editor use case.
|
||||
// However, LLGLTFMaterial::asJSON should always be
|
||||
// used when uploading materials, to ensure the
|
||||
// asset is valid.
|
||||
return setFromGltfModel(model_in, 0, true);
|
||||
}
|
||||
else
|
||||
|
|
@ -1975,7 +1877,9 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con
|
|||
{
|
||||
// don't use override material here, it has 'hacked ids'
|
||||
// and values, use end result, apply it on top of local.
|
||||
me->setBaseColor(render_material->mBaseColor);
|
||||
const LLColor4& base_color = render_material->mBaseColor;
|
||||
me->setBaseColor(LLColor3(base_color));
|
||||
me->setTransparency(base_color[VW]);
|
||||
me->setMetalnessFactor(render_material->mMetallicFactor);
|
||||
me->setRoughnessFactor(render_material->mRoughnessFactor);
|
||||
me->setEmissiveColor(render_material->mEmissiveColor);
|
||||
|
|
@ -1986,24 +1890,24 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con
|
|||
// most things like colors we can apply without verifying
|
||||
// but texture ids are going to be different from both, base and override
|
||||
// so only apply override id if there is actually a difference
|
||||
if (local_material->mBaseColorId != render_material->mBaseColorId)
|
||||
if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
|
||||
{
|
||||
me->setBaseColorId(render_material->mBaseColorId);
|
||||
me->setBaseColorId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
|
||||
me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string"));
|
||||
}
|
||||
if (local_material->mNormalId != render_material->mNormalId)
|
||||
if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
|
||||
{
|
||||
me->setNormalId(render_material->mNormalId);
|
||||
me->setNormalId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
|
||||
me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string"));
|
||||
}
|
||||
if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId)
|
||||
if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
|
||||
{
|
||||
me->setMetallicRoughnessId(render_material->mMetallicRoughnessId);
|
||||
me->setMetallicRoughnessId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
|
||||
me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string"));
|
||||
}
|
||||
if (local_material->mEmissiveId != render_material->mEmissiveId)
|
||||
if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
|
||||
{
|
||||
me->setEmissiveId(render_material->mEmissiveId);
|
||||
me->setEmissiveId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
|
||||
me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string"));
|
||||
}
|
||||
|
||||
|
|
@ -2017,7 +1921,11 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con
|
|||
LLSD payload;
|
||||
if (render_material)
|
||||
{
|
||||
payload["data"] = render_material->asJSON();
|
||||
// Make a copy of the render material with unsupported transforms removed
|
||||
LLGLTFMaterial asset_material = *render_material;
|
||||
asset_material.sanitizeAssetMaterial();
|
||||
// Serialize the sanitized render material
|
||||
payload["data"] = asset_material.asJSON();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2040,8 +1948,9 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati
|
|||
if (0 == option)
|
||||
{
|
||||
LLSD asset;
|
||||
asset["version"] = "1.0";
|
||||
asset["type"] = "GLTF 2.0";
|
||||
asset["version"] = LLGLTFMaterial::ASSET_VERSION;
|
||||
asset["type"] = LLGLTFMaterial::ASSET_TYPE;
|
||||
// This is the string serialized from LLGLTFMaterial::asJSON
|
||||
asset["data"] = notification["payload"]["data"];
|
||||
|
||||
std::ostringstream str;
|
||||
|
|
@ -2584,7 +2493,7 @@ public:
|
|||
}
|
||||
else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull())
|
||||
{
|
||||
material->setBaseColorId(revert_mat->mBaseColorId, false);
|
||||
material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false);
|
||||
}
|
||||
|
||||
if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY)
|
||||
|
|
@ -2593,16 +2502,16 @@ public:
|
|||
}
|
||||
else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull())
|
||||
{
|
||||
material->setNormalId(revert_mat->mNormalId, false);
|
||||
material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false);
|
||||
}
|
||||
|
||||
if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
|
||||
{
|
||||
material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true);
|
||||
material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true);
|
||||
}
|
||||
else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull())
|
||||
{
|
||||
material->setMetallicRoughnessId(revert_mat->mMetallicRoughnessId, false);
|
||||
material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false);
|
||||
}
|
||||
|
||||
if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
|
||||
|
|
@ -2638,7 +2547,7 @@ public:
|
|||
}
|
||||
else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull())
|
||||
{
|
||||
material->setEmissiveId(revert_mat->mEmissiveId, false);
|
||||
material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false);
|
||||
}
|
||||
|
||||
if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY)
|
||||
|
|
@ -2751,20 +2660,23 @@ void LLMaterialEditor::applyToSelection()
|
|||
}
|
||||
}
|
||||
|
||||
// Get a dump of the json representation of the current state of the editor UI
|
||||
// in GLTF format, excluding transforms as they are not supported in material
|
||||
// assets. (See also LLGLTFMaterial::sanitizeAssetMaterial())
|
||||
void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
|
||||
{
|
||||
mat->mBaseColor = getBaseColor();
|
||||
mat->mBaseColor.mV[3] = getTransparency();
|
||||
mat->mBaseColorId = getBaseColorId();
|
||||
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = getBaseColorId();
|
||||
|
||||
mat->mNormalId = getNormalId();
|
||||
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = getNormalId();
|
||||
|
||||
mat->mMetallicRoughnessId = getMetallicRoughnessId();
|
||||
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = getMetallicRoughnessId();
|
||||
mat->mMetallicFactor = getMetalnessFactor();
|
||||
mat->mRoughnessFactor = getRoughnessFactor();
|
||||
|
||||
mat->mEmissiveColor = getEmissiveColor();
|
||||
mat->mEmissiveId = getEmissiveId();
|
||||
mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = getEmissiveId();
|
||||
|
||||
mat->mDoubleSided = getDoubleSided();
|
||||
mat->setAlphaMode(getAlphaMode());
|
||||
|
|
@ -2774,15 +2686,15 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
|
|||
void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)
|
||||
{
|
||||
setBaseColor(mat->mBaseColor);
|
||||
setBaseColorId(mat->mBaseColorId);
|
||||
setNormalId(mat->mNormalId);
|
||||
setBaseColorId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
|
||||
setNormalId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
|
||||
|
||||
setMetallicRoughnessId(mat->mMetallicRoughnessId);
|
||||
setMetallicRoughnessId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
|
||||
setMetalnessFactor(mat->mMetallicFactor);
|
||||
setRoughnessFactor(mat->mRoughnessFactor);
|
||||
|
||||
setEmissiveColor(mat->mEmissiveColor);
|
||||
setEmissiveId(mat->mEmissiveId);
|
||||
setEmissiveId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
|
||||
|
||||
setDoubleSided(mat->mDoubleSided);
|
||||
setAlphaMode(mat->getAlphaMode());
|
||||
|
|
|
|||
|
|
@ -84,8 +84,7 @@ protected:
|
|||
};
|
||||
|
||||
class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
|
||||
{
|
||||
public:
|
||||
{ public:
|
||||
LLMaterialEditor(const LLSD& key);
|
||||
|
||||
bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false);
|
||||
|
|
@ -98,6 +97,7 @@ public:
|
|||
// for live preview, apply current material to currently selected object
|
||||
void applyToSelection();
|
||||
|
||||
// get a dump of the json representation of the current state of the editor UI as a material object
|
||||
void getGLTFMaterial(LLGLTFMaterial* mat);
|
||||
|
||||
void loadAsset() override;
|
||||
|
|
@ -131,11 +131,6 @@ public:
|
|||
|
||||
void onClickSave();
|
||||
|
||||
// get a dump of the json representation of the current state of the editor UI in GLTF format
|
||||
std::string getGLTFJson(bool prettyprint = true);
|
||||
|
||||
void getGLBData(std::vector<U8>& data);
|
||||
|
||||
void getGLTFModel(tinygltf::Model& model);
|
||||
|
||||
std::string getEncodedAsset();
|
||||
|
|
|
|||
|
|
@ -1975,6 +1975,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
|
|||
const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
|
||||
const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
|
||||
const bool show_texture_info = texture_info != LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT;
|
||||
const bool new_state = show_texture_info && has_pbr_capabilities && has_pbr_material;
|
||||
|
||||
LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU");
|
||||
LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
|
||||
|
|
@ -1982,13 +1983,15 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
|
|||
LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU");
|
||||
LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV");
|
||||
|
||||
gltfCtrlTextureScaleU->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material);
|
||||
gltfCtrlTextureScaleV->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material);
|
||||
gltfCtrlTextureRotation->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material);
|
||||
gltfCtrlTextureOffsetU->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material);
|
||||
gltfCtrlTextureOffsetV->setEnabled(show_texture_info && has_pbr_capabilities && has_pbr_material);
|
||||
gltfCtrlTextureScaleU->setEnabled(new_state);
|
||||
gltfCtrlTextureScaleV->setEnabled(new_state);
|
||||
gltfCtrlTextureRotation->setEnabled(new_state);
|
||||
gltfCtrlTextureOffsetU->setEnabled(new_state);
|
||||
gltfCtrlTextureOffsetV->setEnabled(new_state);
|
||||
|
||||
// Control values are set in setMaterialOverridesFromSelection
|
||||
// Control values will be set once per frame in
|
||||
// setMaterialOverridesFromSelection
|
||||
sMaterialOverrideSelection.setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2979,7 +2982,6 @@ void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata)
|
|||
// and generally reflecting old state when switching tabs or objects
|
||||
//
|
||||
self->updateUI();
|
||||
self->setMaterialOverridesFromSelection();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -3981,34 +3983,12 @@ private:
|
|||
|
||||
struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
|
||||
{
|
||||
LLPanelFaceUpdateFunctor(bool update_media, bool update_pbr)
|
||||
LLPanelFaceUpdateFunctor(bool update_media)
|
||||
: mUpdateMedia(update_media)
|
||||
, mUpdatePbr(update_pbr)
|
||||
{}
|
||||
|
||||
virtual bool apply(LLViewerObject* object)
|
||||
{
|
||||
if (mUpdatePbr)
|
||||
{
|
||||
// setRenderMaterialId is supposed to create it
|
||||
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
|
||||
if (param_block)
|
||||
{
|
||||
if (param_block->isEmpty())
|
||||
{
|
||||
object->setHasRenderMaterialParams(false);
|
||||
}
|
||||
else if (object->hasRenderMaterialParams())
|
||||
{
|
||||
object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
object->setHasRenderMaterialParams(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object->sendTEUpdate();
|
||||
|
||||
if (mUpdateMedia)
|
||||
|
|
@ -4023,7 +4003,6 @@ struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
|
|||
}
|
||||
private:
|
||||
bool mUpdateMedia;
|
||||
bool mUpdatePbr;
|
||||
};
|
||||
|
||||
struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor
|
||||
|
|
@ -4159,7 +4138,7 @@ void LLPanelFace::onPasteColor()
|
|||
LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR);
|
||||
selected_objects->applyToTEs(&paste_func);
|
||||
|
||||
LLPanelFaceUpdateFunctor sendfunc(false, false);
|
||||
LLPanelFaceUpdateFunctor sendfunc(false);
|
||||
selected_objects->applyToObjects(&sendfunc);
|
||||
}
|
||||
|
||||
|
|
@ -4520,7 +4499,7 @@ void LLPanelFace::onPasteTexture()
|
|||
LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE);
|
||||
selected_objects->applyToTEs(&paste_func);
|
||||
|
||||
LLPanelFaceUpdateFunctor sendfunc(true, true);
|
||||
LLPanelFaceUpdateFunctor sendfunc(true);
|
||||
selected_objects->applyToObjects(&sendfunc);
|
||||
|
||||
LLGLTFMaterialList::flushUpdates();
|
||||
|
|
@ -4837,7 +4816,7 @@ void LLPanelFace::onPasteFaces()
|
|||
LLPanelFacePasteTexFunctor paste_color_func(this, PASTE_COLOR);
|
||||
selected_objects->applyToTEs(&paste_color_func);
|
||||
|
||||
LLPanelFaceUpdateFunctor sendfunc(true, true);
|
||||
LLPanelFaceUpdateFunctor sendfunc(true);
|
||||
selected_objects->applyToObjects(&sendfunc);
|
||||
|
||||
LLPanelFaceNavigateHomeFunctor navigate_home_func;
|
||||
|
|
@ -4950,17 +4929,7 @@ void LLPanelFace::Selection::connect()
|
|||
|
||||
bool LLPanelFace::Selection::update()
|
||||
{
|
||||
const bool selection_changed = compareSelection();
|
||||
if (selection_changed)
|
||||
{
|
||||
clearObjectUpdatePending();
|
||||
}
|
||||
else if (isObjectUpdatePending())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool changed = mChanged;
|
||||
const bool changed = mChanged || compareSelection();
|
||||
mChanged = false;
|
||||
return changed;
|
||||
}
|
||||
|
|
@ -4976,16 +4945,9 @@ void LLPanelFace::Selection::onSelectedObjectUpdated(const LLUUID& object_id, S3
|
|||
if (object_id == mSelectedObjectID && side == mSelectedSide)
|
||||
{
|
||||
mChanged = true;
|
||||
clearObjectUpdatePending();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelFace::Selection::clearObjectUpdatePending()
|
||||
{
|
||||
mPendingObjectID = LLUUID::null;
|
||||
mPendingSide = -1;
|
||||
}
|
||||
|
||||
bool LLPanelFace::Selection::compareSelection()
|
||||
{
|
||||
if (!mNeedsSelectionCheck)
|
||||
|
|
|
|||
|
|
@ -547,15 +547,13 @@ private:
|
|||
// updated. Necessary to prevent controls updating when the mouse is
|
||||
// held down.
|
||||
void setObjectUpdatePending(const LLUUID &object_id, S32 side);
|
||||
void setDirty() { mChanged = true; };
|
||||
|
||||
// Callbacks
|
||||
void onSelectionChanged() { mNeedsSelectionCheck = true; }
|
||||
void onSelectedObjectUpdated(const LLUUID &object_id, S32 side);
|
||||
|
||||
protected:
|
||||
void clearObjectUpdatePending();
|
||||
bool isObjectUpdatePending() { return mPendingSide != -1; }
|
||||
|
||||
bool compareSelection();
|
||||
|
||||
bool mChanged = false;
|
||||
|
|
|
|||
|
|
@ -767,27 +767,49 @@ void LLPanelVolume::sendIsReflectionProbe()
|
|||
BOOL value = getChild<LLUICtrl>("Reflection Probe")->getValue();
|
||||
BOOL old_value = volobjp->isReflectionProbe();
|
||||
|
||||
volobjp->setIsReflectionProbe(value);
|
||||
LL_INFOS() << "update reflection probe sent" << LL_ENDL;
|
||||
if (value && value != old_value)
|
||||
{ // defer to notification util as to whether or not we *really* make this object a reflection probe
|
||||
LLNotificationsUtil::add("ReflectionProbeApplied", LLSD(), LLSD(), boost::bind(&LLPanelVolume::doSendIsReflectionProbe, this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
volobjp->setIsReflectionProbe(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (value && !old_value)
|
||||
{ // has become a reflection probe, slam to a 10m sphere and pop up a message
|
||||
// warning people about the pitfalls of reflection probes
|
||||
auto* select_mgr = LLSelectMgr::getInstance();
|
||||
void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLSD & response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0) // YES
|
||||
{
|
||||
LLViewerObject* objectp = mObject;
|
||||
if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLVOVolume* volobjp = (LLVOVolume*)objectp;
|
||||
|
||||
mObject->setScale(LLVector3(10.f, 10.f, 10.f));
|
||||
select_mgr->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION | UPD_SCALE);
|
||||
volobjp->setIsReflectionProbe(true);
|
||||
|
||||
select_mgr->selectionUpdatePhantom(true);
|
||||
select_mgr->selectionSetGLTFMaterial(LLUUID::null);
|
||||
select_mgr->selectionSetAlphaOnly(0.f);
|
||||
|
||||
LLVolumeParams params;
|
||||
params.getPathParams().setCurveType(LL_PCODE_PATH_CIRCLE);
|
||||
params.getProfileParams().setCurveType(LL_PCODE_PROFILE_CIRCLE_HALF);
|
||||
mObject->updateVolume(params);
|
||||
{ // has become a reflection probe, slam to a 10m sphere and pop up a message
|
||||
// warning people about the pitfalls of reflection probes
|
||||
|
||||
LLNotificationsUtil::add("ReflectionProbeApplied");
|
||||
auto* select_mgr = LLSelectMgr::getInstance();
|
||||
|
||||
select_mgr->selectionUpdatePhantom(true);
|
||||
select_mgr->selectionSetGLTFMaterial(LLUUID::null);
|
||||
select_mgr->selectionSetAlphaOnly(0.f);
|
||||
|
||||
LLVolumeParams params;
|
||||
params.getPathParams().setCurveType(LL_PCODE_PATH_CIRCLE);
|
||||
params.getProfileParams().setCurveType(LL_PCODE_PROFILE_CIRCLE_HALF);
|
||||
mObject->updateVolume(params);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cancelled, touch up UI state
|
||||
getChild<LLUICtrl>("Reflection Probe")->setValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1375,6 +1397,12 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
|
|||
if (volobjp->setReflectionProbeIsBox(is_box))
|
||||
{
|
||||
// make the volume match the probe
|
||||
auto* select_mgr = LLSelectMgr::getInstance();
|
||||
|
||||
select_mgr->selectionUpdatePhantom(true);
|
||||
select_mgr->selectionSetGLTFMaterial(LLUUID::null);
|
||||
select_mgr->selectionSetAlphaOnly(0.f);
|
||||
|
||||
U8 profile, path;
|
||||
|
||||
if (!is_box)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,14 @@ public:
|
|||
void refresh();
|
||||
|
||||
void sendIsLight();
|
||||
|
||||
// when an object is becoming a refleciton probe, present a dialog asking for confirmation
|
||||
// otherwise, send the reflection probe update immediately
|
||||
void sendIsReflectionProbe();
|
||||
|
||||
// callback for handling response of the ok/cancel/ignore dialog for making an object a reflection probe
|
||||
void doSendIsReflectionProbe(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void sendIsFlexible();
|
||||
|
||||
static bool precommitValidate(const LLSD& data);
|
||||
|
|
|
|||
|
|
@ -31,13 +31,24 @@
|
|||
#include "llviewerwindow.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llworld.h"
|
||||
#include "llshadermgr.h"
|
||||
|
||||
extern F32SecondsImplicit gFrameTimeSeconds;
|
||||
|
||||
extern U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
|
||||
|
||||
LLReflectionMap::LLReflectionMap()
|
||||
{
|
||||
}
|
||||
|
||||
LLReflectionMap::~LLReflectionMap()
|
||||
{
|
||||
if (mOcclusionQuery)
|
||||
{
|
||||
glDeleteQueries(1, &mOcclusionQuery);
|
||||
}
|
||||
}
|
||||
|
||||
void LLReflectionMap::update(U32 resolution, U32 face)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
|
|
@ -66,7 +77,7 @@ void LLReflectionMap::autoAdjustOrigin()
|
|||
|
||||
if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
|
||||
{
|
||||
mPriority = 1;
|
||||
mPriority = 0;
|
||||
// cast a ray towards 8 corners of bounding box
|
||||
// nudge origin towards center of empty space
|
||||
|
||||
|
|
@ -150,7 +161,7 @@ void LLReflectionMap::autoAdjustOrigin()
|
|||
}
|
||||
else if (mViewerObject)
|
||||
{
|
||||
mPriority = 64;
|
||||
mPriority = 1;
|
||||
mOrigin.load3(mViewerObject->getPositionAgent().mV);
|
||||
mRadius = mViewerObject->getScale().mV[0]*0.5f;
|
||||
}
|
||||
|
|
@ -245,3 +256,71 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLReflectionMap::isActive()
|
||||
{
|
||||
return mCubeIndex != -1;
|
||||
}
|
||||
|
||||
void LLReflectionMap::doOcclusion(const LLVector4a& eye)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
|
||||
#if 1
|
||||
// super sloppy, but we're doing an occlusion cull against a bounding cube of
|
||||
// a bounding sphere, pad radius so we assume if the eye is within
|
||||
// the bounding sphere of the bounding cube, the node is not culled
|
||||
F32 dist = mRadius * F_SQRT3 + 1.f;
|
||||
|
||||
LLVector4a o;
|
||||
o.setSub(mOrigin, eye);
|
||||
|
||||
bool do_query = false;
|
||||
|
||||
if (o.getLength3().getF32() < dist)
|
||||
{ // eye is inside radius, don't attempt to occlude
|
||||
mOccluded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOcclusionQuery == 0)
|
||||
{ // no query was previously issued, allocate one and issue
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - glGenQueries");
|
||||
glGenQueries(1, &mOcclusionQuery);
|
||||
do_query = true;
|
||||
}
|
||||
else
|
||||
{ // query was previously issued, check it and only issue a new query
|
||||
// if previous query is available
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - glGetQueryObject");
|
||||
GLuint result = 0;
|
||||
glGetQueryObjectuiv(mOcclusionQuery, GL_QUERY_RESULT_AVAILABLE, &result);
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
do_query = true;
|
||||
glGetQueryObjectuiv(mOcclusionQuery, GL_QUERY_RESULT, &result);
|
||||
mOccluded = result == 0;
|
||||
mOcclusionPendingFrames = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mOcclusionPendingFrames++;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_query)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - push query");
|
||||
glBeginQuery(GL_ANY_SAMPLES_PASSED, mOcclusionQuery);
|
||||
|
||||
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
|
||||
shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mOrigin.getF32ptr());
|
||||
shader->uniform3f(LLShaderMgr::BOX_SIZE, mRadius, mRadius, mRadius);
|
||||
|
||||
gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(LLViewerCamera::getInstance(), mOrigin));
|
||||
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ public:
|
|||
// allocate an environment map of the given resolution
|
||||
LLReflectionMap();
|
||||
|
||||
~LLReflectionMap();
|
||||
|
||||
// update this environment map
|
||||
// resolution - size of cube map to generate
|
||||
void update(U32 resolution, U32 face);
|
||||
|
|
@ -64,6 +66,12 @@ public:
|
|||
// return false if no bounding box (treat as sphere influence volume)
|
||||
bool getBox(LLMatrix4& box);
|
||||
|
||||
// return true if this probe is active for rendering
|
||||
bool isActive();
|
||||
|
||||
// perform occlusion query/readback
|
||||
void doOcclusion(const LLVector4a& eye);
|
||||
|
||||
// point at which environment map was last generated from (in agent space)
|
||||
LLVector4a mOrigin;
|
||||
|
||||
|
|
@ -97,6 +105,14 @@ public:
|
|||
LLViewerObject* mViewerObject = nullptr;
|
||||
|
||||
// what priority should this probe have (higher is higher priority)
|
||||
U32 mPriority = 1;
|
||||
// currently only 0 or 1
|
||||
// 0 - automatic probe
|
||||
// 1 - manual probe
|
||||
U32 mPriority = 0;
|
||||
|
||||
// occlusion culling state
|
||||
GLuint mOcclusionQuery = 0;
|
||||
bool mOccluded = false;
|
||||
U32 mOcclusionPendingFrames = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ void LLReflectionMapManager::update()
|
|||
|
||||
if (!mRenderTarget.isComplete())
|
||||
{
|
||||
U32 color_fmt = GL_RGB16F;
|
||||
U32 targetRes = mProbeResolution * 2; // super sample
|
||||
U32 color_fmt = GL_RGB16;
|
||||
U32 targetRes = mProbeResolution * 4; // super sample
|
||||
mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ void LLReflectionMapManager::update()
|
|||
mMipChain.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
mMipChain[i].allocate(res, res, GL_RGBA16F);
|
||||
mMipChain[i].allocate(res, res, GL_RGB16);
|
||||
res /= 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -157,6 +157,7 @@ void LLReflectionMapManager::update()
|
|||
LLReflectionMap* closestDynamic = nullptr;
|
||||
|
||||
LLReflectionMap* oldestProbe = nullptr;
|
||||
LLReflectionMap* oldestOccluded = nullptr;
|
||||
|
||||
if (mUpdatingProbe != nullptr)
|
||||
{
|
||||
|
|
@ -179,12 +180,27 @@ void LLReflectionMapManager::update()
|
|||
probe->mProbeIndex = i;
|
||||
|
||||
LLVector4a d;
|
||||
|
||||
if (!did_update &&
|
||||
i < mReflectionProbeCount &&
|
||||
(oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime))
|
||||
|
||||
if (probe->mOccluded)
|
||||
{
|
||||
oldestProbe = probe;
|
||||
if (oldestOccluded == nullptr)
|
||||
{
|
||||
oldestOccluded = probe;
|
||||
}
|
||||
else if (probe->mLastUpdateTime < oldestOccluded->mLastUpdateTime)
|
||||
{
|
||||
oldestOccluded = probe;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!did_update &&
|
||||
i < mReflectionProbeCount &&
|
||||
(oldestProbe == nullptr ||
|
||||
probe->mLastUpdateTime < oldestProbe->mLastUpdateTime))
|
||||
{
|
||||
oldestProbe = probe;
|
||||
}
|
||||
}
|
||||
|
||||
if (realtime &&
|
||||
|
|
@ -240,6 +256,13 @@ void LLReflectionMapManager::update()
|
|||
doProbeUpdate();
|
||||
}
|
||||
|
||||
if (oldestOccluded)
|
||||
{
|
||||
// as far as this occluded probe is concerned, an origin/radius update is as good as a full update
|
||||
oldestOccluded->autoAdjustOrigin();
|
||||
oldestOccluded->mLastUpdateTime = gFrameTimeSeconds;
|
||||
}
|
||||
|
||||
// update distance to camera for all probes
|
||||
std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());
|
||||
}
|
||||
|
|
@ -277,8 +300,11 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma
|
|||
mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested
|
||||
if (mProbes[i]->mCubeIndex != -1)
|
||||
{
|
||||
mProbes[i]->mProbeIndex = count;
|
||||
maps[count++] = mProbes[i];
|
||||
if (!mProbes[i]->mOccluded)
|
||||
{
|
||||
mProbes[i]->mProbeIndex = count;
|
||||
maps[count++] = mProbes[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -449,7 +475,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
//only render sky, water, terrain, and clouds
|
||||
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
|
||||
LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
|
||||
|
||||
probe->update(mRenderTarget.getWidth(), face);
|
||||
|
||||
|
|
@ -476,8 +502,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
|
||||
// downsample to placeholder map
|
||||
{
|
||||
gReflectionMipProgram.bind();
|
||||
|
||||
gGL.matrixMode(gGL.MM_MODELVIEW);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
|
|
@ -489,13 +513,41 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
gGL.flush();
|
||||
U32 res = mProbeResolution * 2;
|
||||
|
||||
S32 mips = log2((F32)mProbeResolution) + 0.5f;
|
||||
|
||||
S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
|
||||
S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE);
|
||||
static LLStaticHashedString resScale("resScale");
|
||||
static LLStaticHashedString direction("direction");
|
||||
static LLStaticHashedString znear("znear");
|
||||
static LLStaticHashedString zfar("zfar");
|
||||
|
||||
LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
|
||||
LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
|
||||
|
||||
// perform a gaussian blur on the super sampled render before downsampling
|
||||
{
|
||||
gGaussianProgram.bind();
|
||||
gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2));
|
||||
S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// horizontal
|
||||
gGaussianProgram.uniform2f(direction, 1.f, 0.f);
|
||||
gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
|
||||
mRenderTarget.bindTarget();
|
||||
gPipeline.mScreenTriangleVB->setBuffer();
|
||||
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
mRenderTarget.flush();
|
||||
|
||||
// vertical
|
||||
gGaussianProgram.uniform2f(direction, 0.f, 1.f);
|
||||
gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget);
|
||||
screen_rt->bindTarget();
|
||||
gPipeline.mScreenTriangleVB->setBuffer();
|
||||
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
screen_rt->flush();
|
||||
}
|
||||
|
||||
|
||||
S32 mips = log2((F32)mProbeResolution) + 0.5f;
|
||||
|
||||
gReflectionMipProgram.bind();
|
||||
S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
|
||||
|
||||
for (int i = 0; i < mMipChain.size(); ++i)
|
||||
{
|
||||
|
|
@ -503,7 +555,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
mMipChain[i].bindTarget();
|
||||
if (i == 0)
|
||||
{
|
||||
|
||||
gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
|
||||
}
|
||||
else
|
||||
|
|
@ -511,50 +562,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
|
||||
}
|
||||
|
||||
gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
|
||||
|
||||
static LLStaticHashedString resScale("resScale");
|
||||
static LLStaticHashedString znear("znear");
|
||||
static LLStaticHashedString zfar("zfar");
|
||||
|
||||
gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i));
|
||||
gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
|
||||
gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
|
||||
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
//gGL.begin(gGL.QUADS);
|
||||
|
||||
//gGL.texCoord2f(0, 0);
|
||||
//gGL.vertex2f(-1, -1);
|
||||
|
||||
//gGL.texCoord2f(1.f, 0);
|
||||
//gGL.vertex2f(1, -1);
|
||||
|
||||
//gGL.texCoord2f(1.f, 1.f);
|
||||
//gGL.vertex2f(1, 1);
|
||||
|
||||
//gGL.texCoord2f(0, 1.f);
|
||||
//gGL.vertex2f(-1, 1);
|
||||
//gGL.end();
|
||||
|
||||
gGL.begin(gGL.TRIANGLES);
|
||||
gGL.texCoord2f(0, 0);
|
||||
gGL.vertex2f(-1, -1);
|
||||
gGL.texCoord2f(1.f, 0);
|
||||
gGL.vertex2f(1, -1);
|
||||
gGL.texCoord2f(1.f, 1.f);
|
||||
gGL.vertex2f(1, 1);
|
||||
|
||||
gGL.texCoord2f(0, 0);
|
||||
gGL.vertex2f(-1, -1);
|
||||
gGL.texCoord2f(1.f, 1.f);
|
||||
gGL.vertex2f(1, 1);
|
||||
gGL.texCoord2f(0, 1.f);
|
||||
gGL.vertex2f(-1, 1);
|
||||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
gGL.flush();
|
||||
|
||||
gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2));
|
||||
|
||||
gPipeline.mScreenTriangleVB->setBuffer();
|
||||
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
|
||||
res /= 2;
|
||||
|
||||
S32 mip = i - (mMipChain.size() - mips);
|
||||
|
|
@ -579,7 +592,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
|||
gGL.popMatrix();
|
||||
|
||||
gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gReflectionMipProgram.unbind();
|
||||
}
|
||||
|
||||
|
|
@ -802,7 +814,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale);
|
||||
|
||||
F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f;
|
||||
|
||||
F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f;
|
||||
|
||||
for (auto* refmap : mReflectionMaps)
|
||||
{
|
||||
|
|
@ -817,8 +829,12 @@ void LLReflectionMapManager::updateUniforms()
|
|||
llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged
|
||||
|
||||
{
|
||||
//LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere");
|
||||
if (refmap->mViewerObject)
|
||||
{ // have active manual probes live-track the object they're associated with
|
||||
refmap->mOrigin.load3(refmap->mViewerObject->getPositionAgent().mV);
|
||||
refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
|
||||
|
||||
}
|
||||
modelview.affineTransform(refmap->mOrigin, oa);
|
||||
rpd.refSphere[count].set(oa.getF32ptr());
|
||||
rpd.refSphere[count].mV[3] = refmap->mRadius;
|
||||
|
|
@ -836,7 +852,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
rpd.refIndex[count][3] = -rpd.refIndex[count][3];
|
||||
}
|
||||
|
||||
rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, 0.f, 0.f, 0.f);
|
||||
rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, 0.f, 0.f);
|
||||
|
||||
S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
|
||||
{
|
||||
|
|
@ -850,7 +866,7 @@ void LLReflectionMapManager::updateUniforms()
|
|||
}
|
||||
|
||||
GLint idx = neighbor->mProbeIndex;
|
||||
if (idx == -1)
|
||||
if (idx == -1 || neighbor->mOccluded)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -999,7 +1015,7 @@ void LLReflectionMapManager::initReflectionMaps()
|
|||
mTexture = new LLCubeMapArray();
|
||||
|
||||
// store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
|
||||
mTexture->allocate(mProbeResolution, 4, mReflectionProbeCount + 2);
|
||||
mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
|
||||
|
||||
mIrradianceMaps = new LLCubeMapArray();
|
||||
mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE);
|
||||
|
|
@ -1052,3 +1068,17 @@ void LLReflectionMapManager::cleanup()
|
|||
// note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state
|
||||
initCubeFree();
|
||||
}
|
||||
|
||||
void LLReflectionMapManager::doOcclusion()
|
||||
{
|
||||
LLVector4a eye;
|
||||
eye.load3(LLViewerCamera::instance().getOrigin().mV);
|
||||
|
||||
for (auto& probe : mProbes)
|
||||
{
|
||||
if (probe != nullptr && probe != mDefaultProbe)
|
||||
{
|
||||
probe->doOcclusion(eye);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,9 @@ public:
|
|||
// True if currently updating a radiance map, false if currently updating an irradiance map
|
||||
bool isRadiancePass() { return mRadiancePass; }
|
||||
|
||||
// perform occlusion culling on all active reflection probes
|
||||
void doOcclusion();
|
||||
|
||||
private:
|
||||
friend class LLPipeline;
|
||||
|
||||
|
|
|
|||
|
|
@ -2027,12 +2027,6 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
|
|||
asset_id = mItem->getAssetUUID();
|
||||
}
|
||||
|
||||
if (asset_id.notNull() && !objectp->hasRenderMaterialParams())
|
||||
{
|
||||
// make sure param section exists
|
||||
objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
|
||||
}
|
||||
|
||||
// Blank out most override data on the object and send to server
|
||||
objectp->setRenderMaterialID(te, asset_id);
|
||||
|
||||
|
|
@ -2061,25 +2055,6 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
|
||||
if (param_block)
|
||||
{
|
||||
// To not cause multiple competing request that modify
|
||||
// same param field send update only once per object
|
||||
if (param_block->isEmpty())
|
||||
{
|
||||
object->setHasRenderMaterialParams(false);
|
||||
}
|
||||
else if (object->hasRenderMaterialParams())
|
||||
{
|
||||
object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
object->setHasRenderMaterialParams(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mItem)
|
||||
{
|
||||
// 1 particle effect per object
|
||||
|
|
@ -2295,14 +2270,13 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
|
|||
{
|
||||
// Restore base material
|
||||
LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te];
|
||||
objectp->setRenderMaterialID(te, asset_id, false /*wait for bulk update*/);
|
||||
|
||||
// Update material locally
|
||||
objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/);
|
||||
objectp->setTEGLTFMaterialOverride(te, nodep->mSavedGLTFOverrideMaterials[te]);
|
||||
|
||||
// todo: make sure this does not cause race condition with setRenderMaterialID
|
||||
// when we are reverting from null id to non null plus override
|
||||
if (te < (S32)nodep->mSavedGLTFOverrideMaterials.size()
|
||||
&& nodep->mSavedGLTFOverrideMaterials[te].notNull()
|
||||
&& asset_id.notNull())
|
||||
// Enqueue update to server
|
||||
if (asset_id.notNull())
|
||||
{
|
||||
// Restore overrides
|
||||
LLGLTFMaterialList::queueModify(objectp, te, nodep->mSavedGLTFOverrideMaterials[te]);
|
||||
|
|
@ -2318,38 +2292,6 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
|
|||
}
|
||||
} setfunc(mSelectedObjects);
|
||||
getSelection()->applyToTEs(&setfunc);
|
||||
|
||||
struct g : public LLSelectedObjectFunctor
|
||||
{
|
||||
virtual bool apply(LLViewerObject* object)
|
||||
{
|
||||
if (object && !object->permModify())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
|
||||
if (param_block)
|
||||
{
|
||||
if (param_block->isEmpty())
|
||||
{
|
||||
object->setHasRenderMaterialParams(false);
|
||||
}
|
||||
else if (object->hasRenderMaterialParams())
|
||||
{
|
||||
object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
object->setHasRenderMaterialParams(true);
|
||||
}
|
||||
}
|
||||
|
||||
object->sendTEUpdate();
|
||||
return true;
|
||||
}
|
||||
} sendfunc;
|
||||
getSelection()->applyToObjects(&sendfunc);
|
||||
}
|
||||
|
||||
void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
|
||||
|
|
|
|||
|
|
@ -716,15 +716,15 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
|
|||
|
||||
LLColor3 ambient(getTotalAmbient());
|
||||
|
||||
shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
|
||||
|
||||
if (radiance_pass)
|
||||
{ // during an irradiance map update, disable ambient lighting (direct lighting only) and desaturate sky color (avoid tinting the world blue)
|
||||
shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, LLVector3::zero.mV);
|
||||
shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3::zero.mV);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, linearColor3v(getAmbientColor() / 3.f)); // note magic number 3.f comes from SLIDER_SCALE_SUN_AMBIENT
|
||||
shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
|
||||
}
|
||||
|
||||
shader->uniform3fv(LLShaderMgr::BLUE_HORIZON_LINEAR, linearColor3v(getBlueHorizon() / 2.f)); // note magic number of 2.f comes from SLIDER_SCALE_BLUE_HORIZON_DENSITY
|
||||
|
|
|
|||
|
|
@ -1722,8 +1722,6 @@ void renderOctree(LLSpatialGroup* group)
|
|||
}
|
||||
|
||||
face->getVertexBuffer()->setBuffer();
|
||||
//drawBox((face->mExtents[0] + face->mExtents[1])*0.5f,
|
||||
// (face->mExtents[1]-face->mExtents[0])*0.5f);
|
||||
face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
|
||||
}
|
||||
}
|
||||
|
|
@ -1748,145 +1746,20 @@ void renderOctree(LLSpatialGroup* group)
|
|||
LLVector4a fudge;
|
||||
fudge.splat(0.001f);
|
||||
|
||||
//LLVector4a size = group->mObjectBounds[1];
|
||||
//size.mul(1.01f);
|
||||
//size.add(fudge);
|
||||
|
||||
//{
|
||||
// LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
// drawBox(group->mObjectBounds[0], fudge);
|
||||
//}
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
//if (group->mBuilt <= 0.f)
|
||||
{
|
||||
//draw opaque outline
|
||||
//gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f);
|
||||
//drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
|
||||
|
||||
gGL.diffuseColor4f(0,1,1,1);
|
||||
|
||||
const LLVector4a* bounds = group->getBounds();
|
||||
drawBoxOutline(bounds[0], bounds[1]);
|
||||
|
||||
//draw bounding box for draw info
|
||||
/*if (group->getSpatialPartition()->mRenderByGroup)
|
||||
{
|
||||
gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f);
|
||||
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
|
||||
{
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
|
||||
{
|
||||
LLDrawInfo* draw_info = *j;
|
||||
LLVector4a center;
|
||||
center.setAdd(draw_info->mExtents[1], draw_info->mExtents[0]);
|
||||
center.mul(0.5f);
|
||||
LLVector4a size;
|
||||
size.setSub(draw_info->mExtents[1], draw_info->mExtents[0]);
|
||||
size.mul(0.5f);
|
||||
drawBoxOutline(center, size);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
|
||||
// gGL.diffuseColor4f(0,1,0,1);
|
||||
// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
|
||||
}
|
||||
|
||||
std::set<LLSpatialGroup*> visible_selected_groups;
|
||||
|
||||
void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
|
||||
{
|
||||
/*LLGLEnable blend(GL_BLEND);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
LLGLEnable cull(GL_CULL_FACE);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/
|
||||
|
||||
/*BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
|
||||
!group->isEmpty();
|
||||
|
||||
|
||||
if (render_objects)
|
||||
{
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
gGL.setLineWidth(4.f); // <FS> Line width OGL core profile fix by Rye Mutt
|
||||
gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
|
||||
gGL.setLineWidth(1.f); // <FS> Line width OGL core profile fix by Rye Mutt
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
bool selected = false;
|
||||
|
||||
for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
|
||||
{
|
||||
LLDrawable* drawable = *iter;
|
||||
if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
|
||||
{
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{ //store for rendering occlusion volume as overlay
|
||||
visible_selected_groups.insert(group);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*if (render_objects)
|
||||
{
|
||||
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
|
||||
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
|
||||
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
|
||||
}
|
||||
|
||||
{
|
||||
LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL);
|
||||
|
||||
if (render_objects)
|
||||
{
|
||||
gGL.diffuseColor4f(0.f, 0.5f, 0.f,1.f);
|
||||
gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
if (render_objects)
|
||||
{
|
||||
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
|
||||
gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
|
||||
|
||||
bool selected = false;
|
||||
|
||||
for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
|
||||
{
|
||||
LLDrawable* drawable = *iter;
|
||||
if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
|
||||
{
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{ //store for rendering occlusion volume as overlay
|
||||
visible_selected_groups.insert(group);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void renderXRay(LLSpatialGroup* group, LLCamera* camera)
|
||||
{
|
||||
|
|
@ -3309,23 +3182,6 @@ public:
|
|||
renderOctree(group);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
//render visibility wireframe
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
|
||||
{
|
||||
group->rebuildGeom();
|
||||
group->rebuildMesh();
|
||||
|
||||
gGL.flush();
|
||||
gGL.pushMatrix();
|
||||
gGLLastMatrix = NULL;
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
renderVisibility(group, mCamera);
|
||||
stop_glerror();
|
||||
gGLLastMatrix = NULL;
|
||||
gGL.popMatrix();
|
||||
gGL.diffuseColor4f(1,1,1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3434,6 +3290,7 @@ public:
|
|||
renderAgentTarget(avatar);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (gDebugGL)
|
||||
{
|
||||
for (U32 i = 0; i < drawable->getNumFaces(); ++i)
|
||||
|
|
@ -3459,6 +3316,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
|
||||
|
|
|
|||
|
|
@ -697,6 +697,7 @@ private:
|
|||
static LLFace** sNormFaces[2];
|
||||
static LLFace** sSpecFaces[2];
|
||||
static LLFace** sNormSpecFaces[2];
|
||||
static LLFace** sPbrFaces[2];
|
||||
static LLFace** sAlphaFaces[2];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,9 @@ void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
|
|||
{
|
||||
mCanApplyImmediately = b;
|
||||
|
||||
getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately);
|
||||
LLUICtrl *apply_checkbox = getChild<LLUICtrl>("apply_immediate_check");
|
||||
apply_checkbox->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
|
||||
apply_checkbox->setEnabled(mCanApplyImmediately);
|
||||
}
|
||||
|
||||
void LLFloaterTexturePicker::stopUsingPipette()
|
||||
|
|
@ -585,7 +587,7 @@ BOOL LLFloaterTexturePicker::postBuild()
|
|||
|
||||
mNoCopyTextureSelected = FALSE;
|
||||
|
||||
getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
|
||||
getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
|
||||
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
|
||||
getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately);
|
||||
|
||||
|
|
@ -973,7 +975,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
|
|||
|
||||
if(!mPreviewSettingChanged)
|
||||
{
|
||||
mCanPreview = gSavedSettings.getBOOL("TextureLivePreview");
|
||||
mCanPreview = mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1288,7 +1290,7 @@ void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data
|
|||
|
||||
if (!self->mPreviewSettingChanged)
|
||||
{
|
||||
self->mCanPreview = gSavedSettings.getBOOL("TextureLivePreview");
|
||||
self->mCanPreview = self->mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1309,7 +1311,7 @@ void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)
|
|||
getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
|
||||
|
||||
mCanApply = can_apply;
|
||||
mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false;
|
||||
mCanPreview = can_preview ? (mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")) : false;
|
||||
mPreviewSettingChanged = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -309,48 +309,48 @@ bool LLTinyGLTFHelper::getMaterialFromFile(
|
|||
if (base_color_tex)
|
||||
{
|
||||
base_color_tex->addTextureStats(64.f * 64.f, TRUE);
|
||||
material->mBaseColorId = base_color_tex->getID();
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = base_color_tex->getID();
|
||||
material->mBaseColorTexture = base_color_tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
material->mBaseColorId = LLUUID::null;
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = LLUUID::null;
|
||||
material->mBaseColorTexture = nullptr;
|
||||
}
|
||||
|
||||
if (normal_tex)
|
||||
{
|
||||
normal_tex->addTextureStats(64.f * 64.f, TRUE);
|
||||
material->mNormalId = normal_tex->getID();
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = normal_tex->getID();
|
||||
material->mNormalTexture = normal_tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
material->mNormalId = LLUUID::null;
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = LLUUID::null;
|
||||
material->mNormalTexture = nullptr;
|
||||
}
|
||||
|
||||
if (mr_tex)
|
||||
{
|
||||
mr_tex->addTextureStats(64.f * 64.f, TRUE);
|
||||
material->mMetallicRoughnessId = mr_tex->getID();
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = mr_tex->getID();
|
||||
material->mMetallicRoughnessTexture = mr_tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
material->mMetallicRoughnessId = LLUUID::null;
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = LLUUID::null;
|
||||
material->mMetallicRoughnessTexture = nullptr;
|
||||
}
|
||||
|
||||
if (emissive_tex)
|
||||
{
|
||||
emissive_tex->addTextureStats(64.f * 64.f, TRUE);
|
||||
material->mEmissiveId = emissive_tex->getID();
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = emissive_tex->getID();
|
||||
material->mEmissiveTexture = emissive_tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
material->mEmissiveId = LLUUID::null;
|
||||
material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = LLUUID::null;
|
||||
material->mEmissiveTexture = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2129,11 +2129,6 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
|
|||
{
|
||||
return ACCEPT_NO_LOCKED;
|
||||
}
|
||||
//If texture !copyable don't texture or you'll never get it back.
|
||||
if(!item->getPermissions().allowCopyBy(gAgent.getID()))
|
||||
{
|
||||
return ACCEPT_NO;
|
||||
}
|
||||
|
||||
if (cargo_type == DAD_TEXTURE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -233,14 +233,7 @@ bool handleSetShaderChanged(const LLSD& newvalue)
|
|||
if (gPipeline.isInit())
|
||||
{
|
||||
// ALM depends onto atmospheric shaders, state might have changed
|
||||
bool old_state = LLPipeline::sRenderDeferred;
|
||||
LLPipeline::refreshCachedSettings();
|
||||
if (old_state != LLPipeline::sRenderDeferred)
|
||||
{
|
||||
gPipeline.releaseGLBuffers();
|
||||
gPipeline.createGLBuffers();
|
||||
gPipeline.resetVertexBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
// else, leave terrain detail as is
|
||||
|
|
@ -290,7 +283,6 @@ bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
|
|||
gPipeline.updateRenderTransparentWater();
|
||||
gPipeline.releaseGLBuffers();
|
||||
gPipeline.createGLBuffers();
|
||||
gPipeline.resetVertexBuffers();
|
||||
LLViewerShaderMgr::instance()->setShaders();
|
||||
}
|
||||
LLWorld::getInstance()->updateWaterObjects();
|
||||
|
|
@ -489,15 +481,6 @@ static bool handleWLSkyDetailChanged(const LLSD&)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handleResetVertexBuffersChanged(const LLSD&)
|
||||
{
|
||||
if (gPipeline.isInit())
|
||||
{
|
||||
gPipeline.resetVertexBuffers();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleRepartition(const LLSD&)
|
||||
{
|
||||
if (gPipeline.isInit())
|
||||
|
|
@ -528,7 +511,6 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
|
|||
LLPipeline::refreshCachedSettings();
|
||||
gPipeline.releaseGLBuffers();
|
||||
gPipeline.createGLBuffers();
|
||||
gPipeline.resetVertexBuffers();
|
||||
LLViewerShaderMgr::instance()->setShaders();
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1146,7 +1128,6 @@ void settings_setup_listeners()
|
|||
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
|
||||
// DEPRECATED -- setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
|
||||
|
|
@ -1159,23 +1140,18 @@ void settings_setup_listeners()
|
|||
setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
|
||||
// DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
|
||||
// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderResolutionMultiplier", handleRenderResolutionDivisorChanged);
|
||||
// [/SL:KB]
|
||||
// DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderReflectionsEnabled", handleReflectionProbeDetailChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderTonemapper", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "ChatConsoleFontSize", handleChatFontSizeChanged);
|
||||
|
|
@ -1199,11 +1175,6 @@ void settings_setup_listeners()
|
|||
setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
|
||||
|
|
|
|||
|
|
@ -103,9 +103,6 @@ F32 gSavedDrawDistance = 0.0f;
|
|||
F32 gLastDrawDistanceStep = 0.0f;
|
||||
// <FS:Ansariel> FIRE-12004: Attachments getting lost on TP
|
||||
LLFrameTimer gPostTeleportFinishKillObjectDelayTimer;
|
||||
// <FS:Ansariel> FIRE-15917 / FIRE-31906: Mesh attachments sometimes vanish after teleports
|
||||
bool postTeleportResetVB = false;
|
||||
LLFrameTimer postTeleportResetVBTimer;
|
||||
|
||||
BOOL gForceRenderLandFence = FALSE;
|
||||
BOOL gDisplaySwapBuffers = FALSE;
|
||||
|
|
@ -313,26 +310,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
LLGLState::checkStates();
|
||||
|
||||
stop_glerror();
|
||||
|
||||
gPipeline.disableLights();
|
||||
|
||||
// <FS:Ansariel> FIRE-15917 / FIRE-31906: Mesh attachments sometimes vanish after teleports
|
||||
static LLCachedControl<F32> teleportArrivalDelay(gSavedSettings, "TeleportArrivalDelay");
|
||||
if (postTeleportResetVB && postTeleportResetVBTimer.getElapsedTimeF32() > teleportArrivalDelay())
|
||||
{
|
||||
LL_INFOS("Teleport") << "Resetting Vertex Buffers after TP finished" << LL_ENDL;
|
||||
postTeleportResetVB = false;
|
||||
postTeleportResetVBTimer.stop();
|
||||
gPipeline.resetVertexBuffers();
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
//reset vertex buffers if needed
|
||||
gPipeline.doResetVertexBuffers();
|
||||
|
||||
stop_glerror();
|
||||
|
||||
// Don't draw if the window is hidden or minimized.
|
||||
// In fact, must explicitly check the minimized state before drawing.
|
||||
// Attempting to draw into a minimized window causes a GL error. JC
|
||||
|
|
@ -549,11 +528,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
// <FS:Ansariel> FIRE-12004: Attachments getting lost on TP
|
||||
gPostTeleportFinishKillObjectDelayTimer.reset();
|
||||
|
||||
// <FS:Ansariel> FIRE-15917 / FIRE-31906: Mesh attachments sometimes vanish after teleports
|
||||
postTeleportResetVB = true;
|
||||
postTeleportResetVBTimer.start();
|
||||
// </FS:Ansariel>
|
||||
break;
|
||||
|
||||
case LLAgent::TELEPORT_ARRIVING:
|
||||
|
|
|
|||
|
|
@ -10951,7 +10951,6 @@ BOOL get_visibility(void* user_data)
|
|||
return viewp->getVisible();
|
||||
}
|
||||
|
||||
// TomY TODO: Get rid of these?
|
||||
class LLViewShowHoverTips : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -10970,7 +10969,6 @@ class LLViewCheckShowHoverTips : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
// TomY TODO: Get rid of these?
|
||||
class LLViewHighlightTransparent : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -10979,7 +10977,6 @@ class LLViewHighlightTransparent : public view_listener_t
|
|||
// [RLVa:KB] - @edit and @viewtransparent
|
||||
LLDrawPoolAlpha::sShowDebugAlpha = (!LLDrawPoolAlpha::sShowDebugAlpha) && (RlvActions::canHighlightTransparent());
|
||||
// [/RLVa:KB]
|
||||
gPipeline.resetVertexBuffers();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -10998,7 +10995,6 @@ class LLViewHighlightTransparentRigged : public view_listener_t
|
|||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLDrawPoolAlpha::sShowDebugAlphaRigged = !LLDrawPoolAlpha::sShowDebugAlphaRigged;
|
||||
gPipeline.resetVertexBuffers();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -558,19 +558,19 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
|
|||
// Todo: make it account for possibility of same texture in different
|
||||
// materials and even in scope of same material
|
||||
S32 texture_count = 0;
|
||||
if (material->mBaseColorId.notNull())
|
||||
if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull())
|
||||
{
|
||||
texture_count++;
|
||||
}
|
||||
if (material->mMetallicRoughnessId.notNull())
|
||||
if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull())
|
||||
{
|
||||
texture_count++;
|
||||
}
|
||||
if (material->mNormalId.notNull())
|
||||
if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull())
|
||||
{
|
||||
texture_count++;
|
||||
}
|
||||
if (material->mEmissiveId.notNull())
|
||||
if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull())
|
||||
{
|
||||
texture_count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3705,8 +3705,6 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
|
|||
// Teleport is finished; it can't be cancelled now.
|
||||
gViewerWindow->setProgressCancelButtonVisible(FALSE);
|
||||
|
||||
gPipeline.doResetVertexBuffers(true);
|
||||
|
||||
// Do teleport effect for where you're leaving
|
||||
// VEFFECT: TeleportStart
|
||||
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
|
||||
|
|
|
|||
|
|
@ -5165,10 +5165,10 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
|
|||
|
||||
if (mat != nullptr)
|
||||
{
|
||||
mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId);
|
||||
mat->mNormalTexture = fetch_texture(mat->mNormalId);
|
||||
mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId);
|
||||
mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId);
|
||||
mat->mBaseColorTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
|
||||
mat->mNormalTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
|
||||
mat->mMetallicRoughnessTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
|
||||
mat->mEmissiveTexture= fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6470,6 +6470,11 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
|
|||
{
|
||||
if (local_origin)
|
||||
{
|
||||
// *NOTE: Do not send the render material ID in this way as it will get
|
||||
// out-of-sync with other sent client data.
|
||||
// See LLViewerObject::setRenderMaterialID and LLGLTFMaterialList
|
||||
llassert(param_type != LLNetworkData::PARAMS_RENDER_MATERIAL);
|
||||
|
||||
LLViewerRegion* regionp = getRegion();
|
||||
if(!regionp) return;
|
||||
|
||||
|
|
@ -7432,6 +7437,15 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
|
|||
});
|
||||
}
|
||||
|
||||
// predictively update LLRenderMaterialParams (don't wait for server)
|
||||
if (param_block)
|
||||
{ // update existing parameter block
|
||||
for (S32 te = start_idx; te < end_idx; ++te)
|
||||
{
|
||||
param_block->setMaterial(te, id);
|
||||
}
|
||||
}
|
||||
|
||||
if (update_server)
|
||||
{
|
||||
// update via ModifyMaterialParams cap (server will echo back changes)
|
||||
|
|
@ -7443,27 +7457,6 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
|
|||
LLGLTFMaterialList::queueApply(this, te, id);
|
||||
}
|
||||
}
|
||||
|
||||
// predictively update LLRenderMaterialParams (don't wait for server)
|
||||
if (param_block)
|
||||
{ // update existing parameter block
|
||||
for (S32 te = start_idx; te < end_idx; ++te)
|
||||
{
|
||||
param_block->setMaterial(te, id);
|
||||
}
|
||||
|
||||
if (update_server)
|
||||
{
|
||||
// If 'in use' changes, it will send an update itself.
|
||||
bool in_use_changed = setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, !param_block->isEmpty(), true);
|
||||
|
||||
if (!in_use_changed)
|
||||
{
|
||||
// In use didn't change, but the parameter did, send an update
|
||||
parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, param_block, !param_block->isEmpty(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::setRenderMaterialIDs(const LLUUID& id)
|
||||
|
|
|
|||
|
|
@ -870,6 +870,7 @@ LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctre
|
|||
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
|
||||
{
|
||||
mOcclusionQuery[i] = 0;
|
||||
mOcclusionCheckCount[i] = 0;
|
||||
mOcclusionIssued[i] = 0;
|
||||
mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
|
||||
mVisible[i] = 0;
|
||||
|
|
@ -1127,10 +1128,12 @@ void LLOcclusionCullingGroup::checkOcclusion()
|
|||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available");
|
||||
glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
mOcclusionCheckCount[LLViewerCamera::sCurCameraID]++;
|
||||
}
|
||||
|
||||
if (available)
|
||||
if (available || mOcclusionCheckCount[LLViewerCamera::sCurCameraID] > 4)
|
||||
{
|
||||
mOcclusionCheckCount[LLViewerCamera::sCurCameraID] = 0;
|
||||
GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result");
|
||||
|
|
@ -1140,20 +1143,6 @@ void LLOcclusionCullingGroup::checkOcclusion()
|
|||
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
#endif
|
||||
|
||||
#if 0 // (12/2021) occasional false-negative occlusion tests produce water reflection errors, SL-16461
|
||||
// If/when water occlusion queries become 100% reliable, re-enable this optimization
|
||||
|
||||
if (LLPipeline::RENDER_TYPE_WATER == mSpatialPartition->mDrawableType)
|
||||
{
|
||||
// Note any unoccluded water, for deciding on reflection/distortion passes
|
||||
// (If occlusion is disabled, these are set within LLDrawPoolWater::render)
|
||||
if (query_result > 0)
|
||||
{
|
||||
LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
|
||||
LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (query_result > 0)
|
||||
{
|
||||
clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ protected:
|
|||
|
||||
LLViewerOctreePartition* mSpatialPartition;
|
||||
U32 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
|
||||
U32 mOcclusionCheckCount[LLViewerCamera::NUM_CAMERAS];
|
||||
|
||||
public:
|
||||
static std::set<U32> sPendingQueries;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ LLGLSLShader gSkinnedOcclusionProgram;
|
|||
LLGLSLShader gOcclusionCubeProgram;
|
||||
LLGLSLShader gGlowCombineProgram;
|
||||
LLGLSLShader gReflectionMipProgram;
|
||||
LLGLSLShader gGaussianProgram;
|
||||
LLGLSLShader gRadianceGenProgram;
|
||||
LLGLSLShader gIrradianceGenProgram;
|
||||
LLGLSLShader gGlowCombineFXAAProgram;
|
||||
|
|
@ -235,7 +236,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
|
|||
mShaderLevel(SHADER_COUNT, 0),
|
||||
mMaxAvatarShaderLevel(0)
|
||||
{
|
||||
/// Make sure WL Sky is the first program
|
||||
//ONLY shaders that need WL Param management should be added here
|
||||
mShaderList.push_back(&gAvatarProgram);
|
||||
mShaderList.push_back(&gWaterProgram);
|
||||
|
|
@ -291,6 +291,8 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
|
|||
mShaderList.push_back(&gDeferredPBRAlphaProgram);
|
||||
mShaderList.push_back(&gHUDPBRAlphaProgram);
|
||||
mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
|
||||
mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
|
||||
|
||||
}
|
||||
|
||||
LLViewerShaderMgr::~LLViewerShaderMgr()
|
||||
|
|
@ -377,9 +379,6 @@ void LLViewerShaderMgr::setShaders()
|
|||
|
||||
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
|
||||
|
||||
//hack to reset buffers that change behavior with shaders
|
||||
gPipeline.resetVertexBuffers();
|
||||
|
||||
if (gViewerWindow)
|
||||
{
|
||||
gViewerWindow->setCursor(UI_CURSOR_WAIT);
|
||||
|
|
@ -655,6 +654,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
|
|||
shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
|
||||
shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
|
||||
shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
|
||||
shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) );
|
||||
if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
|
||||
{
|
||||
shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
|
||||
|
|
@ -1334,6 +1334,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
|
||||
gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
|
||||
gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
gDeferredPBROpaqueProgram.clearPermutations();
|
||||
|
||||
success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
|
||||
if (success)
|
||||
|
|
@ -1648,8 +1649,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredSunProgram.mFeatures.hasShadows = true;
|
||||
gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao;
|
||||
|
||||
gDeferredSunProgram.mName = "Deferred Sun Shader";
|
||||
gDeferredSunProgram.mShaderFiles.clear();
|
||||
gDeferredSunProgram.mShaderFiles.clear();
|
||||
gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
|
||||
gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
|
||||
gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
|
|
@ -2532,6 +2532,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
|
|||
gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
|
||||
gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
|
||||
gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
|
||||
gDeferredPostGammaCorrectProgram.clearPermutations();
|
||||
U32 tonemapper = gSavedSettings.getU32("RenderTonemapper");
|
||||
if (tonemapper == 1)
|
||||
{
|
||||
gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_ACES_NARKOWICZ", "1");
|
||||
}
|
||||
else if (tonemapper == 2)
|
||||
{
|
||||
gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_ACES_HILL_EXPOSURE_BOOST", "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_LINEAR", "1");
|
||||
}
|
||||
gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
|
||||
gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
|
||||
gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
|
|
@ -3202,12 +3216,20 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
|
|||
gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
|
||||
gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
|
||||
success = gReflectionMipProgram.createShader(NULL, NULL);
|
||||
if (success)
|
||||
{
|
||||
gReflectionMipProgram.bind();
|
||||
gReflectionMipProgram.uniform1i(sScreenMap, 0);
|
||||
gReflectionMipProgram.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gGaussianProgram.mName = "Reflection Mip Shader";
|
||||
gGaussianProgram.mFeatures.isDeferred = true;
|
||||
gGaussianProgram.mFeatures.hasGamma = true;
|
||||
gGaussianProgram.mFeatures.hasAtmospherics = true;
|
||||
gGaussianProgram.mFeatures.calculatesAtmospherics = true;
|
||||
gGaussianProgram.mShaderFiles.clear();
|
||||
gGaussianProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
|
||||
gGaussianProgram.mShaderFiles.push_back(make_pair("interface/gaussianF.glsl", GL_FRAGMENT_SHADER));
|
||||
gGaussianProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
|
||||
success = gGaussianProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success && gGLManager.mHasCubeMapArray)
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ extern LLGLSLShader gOcclusionProgram;
|
|||
extern LLGLSLShader gOcclusionCubeProgram;
|
||||
extern LLGLSLShader gGlowCombineProgram;
|
||||
extern LLGLSLShader gReflectionMipProgram;
|
||||
extern LLGLSLShader gGaussianProgram;
|
||||
extern LLGLSLShader gRadianceGenProgram;
|
||||
extern LLGLSLShader gIrradianceGenProgram;
|
||||
extern LLGLSLShader gGlowCombineFXAAProgram;
|
||||
|
|
|
|||
|
|
@ -1993,18 +1993,12 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
{
|
||||
mIsFetching = FALSE;
|
||||
mLastFetchState = -1;
|
||||
setDebugText("");
|
||||
mLastPacketTimer.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
|
||||
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
|
||||
/*if (mFetchState != mLastFetchState)
|
||||
{
|
||||
setDebugText(LLTextureFetch::getStateString(mFetchState));
|
||||
mLastFetchState = mFetchState;
|
||||
}*/
|
||||
}
|
||||
|
||||
// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
|
||||
|
|
|
|||
|
|
@ -755,18 +755,8 @@ void LLVOVolume::animateTextures()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(result & LLViewerTextureAnim::ROTATE))
|
||||
{
|
||||
te->getRotation(&rot);
|
||||
}
|
||||
if (!(result & LLViewerTextureAnim::TRANSLATE))
|
||||
{
|
||||
te->getOffset(&off_s,&off_t);
|
||||
}
|
||||
if (!(result & LLViewerTextureAnim::SCALE))
|
||||
{
|
||||
te->getScale(&scale_s, &scale_t);
|
||||
}
|
||||
LLGLTFMaterial *gltf_mat = te->getGLTFRenderMaterial();
|
||||
const bool is_pbr = gltf_mat != nullptr;
|
||||
|
||||
if (!facep->mTextureMatrix)
|
||||
{
|
||||
|
|
@ -775,22 +765,65 @@ void LLVOVolume::animateTextures()
|
|||
|
||||
LLMatrix4& tex_mat = *facep->mTextureMatrix;
|
||||
tex_mat.setIdentity();
|
||||
LLVector3 trans ;
|
||||
|
||||
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
|
||||
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
|
||||
if (!is_pbr)
|
||||
{
|
||||
if (!(result & LLViewerTextureAnim::ROTATE))
|
||||
{
|
||||
te->getRotation(&rot);
|
||||
}
|
||||
if (!(result & LLViewerTextureAnim::TRANSLATE))
|
||||
{
|
||||
te->getOffset(&off_s,&off_t);
|
||||
}
|
||||
if (!(result & LLViewerTextureAnim::SCALE))
|
||||
{
|
||||
te->getScale(&scale_s, &scale_t);
|
||||
}
|
||||
|
||||
LLVector3 scale(scale_s, scale_t, 1.f);
|
||||
LLQuaternion quat;
|
||||
quat.setQuat(rot, 0, 0, -1.f);
|
||||
|
||||
tex_mat.rotate(quat);
|
||||
LLVector3 trans ;
|
||||
|
||||
LLMatrix4 mat;
|
||||
mat.initAll(scale, LLQuaternion(), LLVector3());
|
||||
tex_mat *= mat;
|
||||
|
||||
tex_mat.translate(trans);
|
||||
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
|
||||
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
|
||||
|
||||
LLVector3 scale(scale_s, scale_t, 1.f);
|
||||
LLQuaternion quat;
|
||||
quat.setQuat(rot, 0, 0, -1.f);
|
||||
|
||||
tex_mat.rotate(quat);
|
||||
|
||||
LLMatrix4 mat;
|
||||
mat.initAll(scale, LLQuaternion(), LLVector3());
|
||||
tex_mat *= mat;
|
||||
|
||||
tex_mat.translate(trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For PBR materials, use Blinn-Phong rotation as hint for
|
||||
// translation direction. In a Blinn-Phong material, the
|
||||
// translation direction would be a byproduct the texture
|
||||
// transform.
|
||||
F32 rot_frame;
|
||||
te->getRotation(&rot_frame);
|
||||
|
||||
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
|
||||
|
||||
LLQuaternion quat;
|
||||
quat.setQuat(rot, 0, 0, -1.f);
|
||||
tex_mat.rotate(quat);
|
||||
|
||||
LLMatrix4 mat;
|
||||
LLVector3 scale(scale_s, scale_t, 1.f);
|
||||
mat.initAll(scale, LLQuaternion(), LLVector3());
|
||||
tex_mat *= mat;
|
||||
|
||||
LLVector3 off(off_s, off_t, 0.f);
|
||||
off.rotVec(rot_frame, 0, 0, 1.f);
|
||||
tex_mat.translate(off);
|
||||
|
||||
tex_mat.translate(LLVector3(0.5f, 0.5f, 0.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -5374,6 +5407,7 @@ LLFace** LLVolumeGeometryManager::sSimpleFaces[2] = { NULL };
|
|||
LLFace** LLVolumeGeometryManager::sNormFaces[2] = { NULL };
|
||||
LLFace** LLVolumeGeometryManager::sSpecFaces[2] = { NULL };
|
||||
LLFace** LLVolumeGeometryManager::sNormSpecFaces[2] = { NULL };
|
||||
LLFace** LLVolumeGeometryManager::sPbrFaces[2] = { NULL };
|
||||
LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL };
|
||||
|
||||
LLVolumeGeometryManager::LLVolumeGeometryManager()
|
||||
|
|
@ -5410,6 +5444,7 @@ void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)
|
|||
sNormFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
|
||||
sSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
|
||||
sNormSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
|
||||
sPbrFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
|
||||
sAlphaFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
|
||||
}
|
||||
}
|
||||
|
|
@ -5424,6 +5459,7 @@ void LLVolumeGeometryManager::freeFaces()
|
|||
ll_aligned_free<64>(sNormFaces[i]);
|
||||
ll_aligned_free<64>(sSpecFaces[i]);
|
||||
ll_aligned_free<64>(sNormSpecFaces[i]);
|
||||
ll_aligned_free<64>(sPbrFaces[i]);
|
||||
ll_aligned_free<64>(sAlphaFaces[i]);
|
||||
|
||||
sFullbrightFaces[i] = NULL;
|
||||
|
|
@ -5432,6 +5468,7 @@ void LLVolumeGeometryManager::freeFaces()
|
|||
sNormFaces[i] = NULL;
|
||||
sSpecFaces[i] = NULL;
|
||||
sNormSpecFaces[i] = NULL;
|
||||
sPbrFaces[i] = NULL;
|
||||
sAlphaFaces[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -5883,6 +5920,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
U32 norm_count[2] = { 0 };
|
||||
U32 spec_count[2] = { 0 };
|
||||
U32 normspec_count[2] = { 0 };
|
||||
U32 pbr_count[2] = { 0 };
|
||||
|
||||
static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
|
||||
static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
|
||||
|
|
@ -6215,8 +6253,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
{
|
||||
if (gltf_mat != nullptr)
|
||||
{
|
||||
// all gltf materials have all vertex attributes for now
|
||||
add_face(sNormSpecFaces, normspec_count, facep);
|
||||
add_face(sPbrFaces, pbr_count, facep);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -6315,6 +6352,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;
|
||||
U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2;
|
||||
|
||||
U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT;
|
||||
|
||||
if (emissive)
|
||||
{ //emissive faces are present, include emissive byte to preserve batching
|
||||
simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
|
||||
|
|
@ -6324,6 +6363,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;
|
||||
normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;
|
||||
spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
|
||||
pbr_mask = pbr_mask | LLVertexBuffer::MAP_EMISSIVE;
|
||||
}
|
||||
|
||||
BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
|
||||
|
|
@ -6354,6 +6394,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[i], norm_count[i], FALSE, FALSE, rigged);
|
||||
geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[i], spec_count[i], FALSE, FALSE, rigged);
|
||||
geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[i], normspec_count[i], FALSE, FALSE, rigged);
|
||||
geometryBytes += genDrawInfo(group, pbr_mask | extra_mask, sPbrFaces[i], pbr_count[i], FALSE, FALSE, rigged);
|
||||
|
||||
// for rigged set, add weights and disable alpha sorting (rigged items use depth buffer)
|
||||
extra_mask |= LLVertexBuffer::MAP_WEIGHT4;
|
||||
|
|
@ -7051,7 +7092,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("facep->alpha -> invisible");
|
||||
registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
|
||||
}
|
||||
else if (facep->canRenderAsMask())
|
||||
else if (facep->canRenderAsMask() && !hud_group)
|
||||
{
|
||||
if (te->getFullbright() || LLPipeline::sNoAlpha)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -424,22 +424,14 @@ void LLWorldMapView::draw()
|
|||
S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
|
||||
|
||||
LLLocalClipRect clip(getLocalRect());
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
||||
// Clear the background alpha to 0
|
||||
gGL.flush();
|
||||
gGL.setColorMask(false, true);
|
||||
gGL.flush();
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
gGL.color4f(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
gl_rect_2d(0, height, width, 0);
|
||||
}
|
||||
|
||||
gGL.flush();
|
||||
gGL.setColorMask(true, true);
|
||||
// Draw background rectangle
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.color4fv(mBackgroundColor.mV);
|
||||
gl_rect_2d(0, height, width, 0);
|
||||
|
||||
// Draw the image tiles
|
||||
// <FS:CR> Aurora Sim
|
||||
|
|
@ -452,10 +444,6 @@ void LLWorldMapView::draw()
|
|||
#endif //OPENSIM
|
||||
// </FS:CR> Aurora Sim
|
||||
|
||||
gGL.flush();
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
// Draw per sim overlayed information (names, mature, offline...)
|
||||
// <FS:Ansariel> Performance tweak
|
||||
//for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin();
|
||||
|
|
@ -508,7 +496,6 @@ void LLWorldMapView::draw()
|
|||
if (info->isDown())
|
||||
{
|
||||
// Draw a transparent red square over down sims
|
||||
gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA);
|
||||
gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
|
@ -532,31 +519,13 @@ void LLWorldMapView::draw()
|
|||
gGL.end();
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
// As part of the AO project, we no longer want to draw access indicators;
|
||||
// it's too complicated to get all the rules straight and will only
|
||||
// cause confusion.
|
||||
/**********************
|
||||
else if (!info->isPG() && gAgent.isTeen())
|
||||
{
|
||||
// If this is a mature region, and you are not, draw a line across it
|
||||
gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.color3f(1.f, 0.f, 0.f);
|
||||
gGL.begin(LLRender::LINES);
|
||||
gGL.vertex2f(left, top);
|
||||
gGL.vertex2f(right, bottom);
|
||||
gGL.vertex2f(left, bottom);
|
||||
gGL.vertex2f(right, top);
|
||||
gGL.end();
|
||||
}
|
||||
**********************/
|
||||
// <FS:CR> Aurora Sim
|
||||
#ifdef OPENSIM
|
||||
else if ((mapShowLandForSale && (level <= DRAW_LANDFORSALE_THRESHOLD)) || LLGridManager::getInstance()->isInAuroraSim())
|
||||
#else
|
||||
else if (mapShowLandForSale && (level <= DRAW_LANDFORSALE_THRESHOLD))
|
||||
#endif //OPENSIM
|
||||
|
||||
{
|
||||
// Draw the overlay image "Land for Sale / Land for Auction"
|
||||
LLViewerFetchedTexture* overlayimage = info->getLandForSaleImage();
|
||||
|
|
@ -576,7 +545,6 @@ void LLWorldMapView::draw()
|
|||
// Draw something whenever we have enough info
|
||||
if (overlayimage->hasGLTexture())
|
||||
{
|
||||
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
|
||||
gGL.getTexUnit(0)->bind(overlayimage);
|
||||
gGL.color4f(1.f, 1.f, 1.f, 1.f);
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
|
|
@ -686,21 +654,6 @@ void LLWorldMapView::draw()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Draw background rectangle
|
||||
LLGLSUIDefault gls_ui;
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.flush();
|
||||
gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA);
|
||||
gGL.color4fv( mBackgroundColor.mV );
|
||||
gl_rect_2d(0, height, width, 0);
|
||||
}
|
||||
|
||||
gGL.flush();
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
// Draw item infos if we're not zoomed out too much and there's something to draw
|
||||
if ((level <= DRAW_SIMINFO_THRESHOLD) && (mapShowInfohubs ||
|
||||
mapShowTelehubs ||
|
||||
|
|
@ -905,7 +858,6 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load
|
|||
gGL.getTexUnit(0)->bind(simimage.get());
|
||||
simimage->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
gGL.color4f(1.f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
// <FS:Ansariel> Remove QUADS rendering mode
|
||||
|
|
@ -963,8 +915,6 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load
|
|||
// Used for debug only
|
||||
void LLWorldMapView::drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right)
|
||||
{
|
||||
gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
if (level == 1)
|
||||
gGL.color3f(1.f, 0.f, 0.f); // red
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
|
|||
bool valid = true
|
||||
&& target.addColorAttachment(GL_RGBA) // frag-data[1] specular OR PBR ORM
|
||||
&& target.addColorAttachment(GL_RGBA16F) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
|
||||
&& target.addColorAttachment(GL_RGBA); // frag_data[3] PBR emissive
|
||||
&& target.addColorAttachment(GL_RGB16); // frag_data[3] PBR emissive
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
|
@ -463,6 +463,7 @@ void LLPipeline::init()
|
|||
getPool(LLDrawPool::POOL_MATERIALS);
|
||||
getPool(LLDrawPool::POOL_GLOW);
|
||||
getPool(LLDrawPool::POOL_GLTF_PBR);
|
||||
getPool(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
|
||||
|
||||
resetFrameStats();
|
||||
|
||||
|
|
@ -731,8 +732,6 @@ void LLPipeline::destroyGL()
|
|||
|
||||
resetDrawOrders();
|
||||
|
||||
resetVertexBuffers();
|
||||
|
||||
releaseGLBuffers();
|
||||
|
||||
if (mMeshDirtyQueryObject)
|
||||
|
|
@ -870,7 +869,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
gCubeSnapshot = TRUE;
|
||||
mReflectionMapManager.initReflectionMaps();
|
||||
mRT = &mAuxillaryRT;
|
||||
U32 res = mReflectionMapManager.mProbeResolution * 2; //multiply by 2 because probes will be super sampled
|
||||
U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled
|
||||
allocateScreenBuffer(res, res, samples);
|
||||
mRT = &mMainRT;
|
||||
gCubeSnapshot = FALSE;
|
||||
|
|
@ -1653,6 +1652,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
|
|||
case LLDrawPool::POOL_GLTF_PBR:
|
||||
poolp = mPBROpaquePool;
|
||||
break;
|
||||
case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
|
||||
poolp = mPBRAlphaMaskPool;
|
||||
break;
|
||||
|
||||
default:
|
||||
llassert(0);
|
||||
|
|
@ -2389,7 +2391,6 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
|
|||
}
|
||||
|
||||
LLViewerCamera::sCurCameraID = saved_camera_id;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -2400,7 +2401,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, bool hud_att
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
|
||||
LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out
|
||||
|
||||
bool water_clip = !sRenderTransparentWater;
|
||||
bool water_clip = !sRenderTransparentWater && !sRenderingHUDs;
|
||||
|
||||
if (water_clip)
|
||||
{
|
||||
|
|
@ -2550,19 +2551,33 @@ void LLPipeline::doOcclusion(LLCamera& camera)
|
|||
LL_PROFILE_GPU_ZONE("doOcclusion");
|
||||
llassert(!gCubeSnapshot);
|
||||
|
||||
if (sReflectionProbesEnabled && sUseOcclusion > 1 && !LLPipeline::sShadowRender && !gCubeSnapshot)
|
||||
{
|
||||
gGL.setColorMask(false, false);
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
|
||||
gOcclusionCubeProgram.bind();
|
||||
|
||||
if (mCubeVB.isNull())
|
||||
{ //cube VB will be used for issuing occlusion queries
|
||||
mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
|
||||
}
|
||||
mCubeVB->setBuffer();
|
||||
|
||||
mReflectionMapManager.doOcclusion();
|
||||
gOcclusionCubeProgram.unbind();
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
}
|
||||
|
||||
if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
|
||||
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
|
||||
{
|
||||
gGL.setColorMask(true, false, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.setColorMask(false, false);
|
||||
}
|
||||
gGL.setColorMask(false, false);
|
||||
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
LLGLDisable test(GL_ALPHA_TEST);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
|
@ -4118,7 +4133,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
|
|||
|
||||
bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
|
||||
|
||||
setupHWLights(nullptr);
|
||||
setupHWLights();
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools");
|
||||
|
|
@ -4245,7 +4260,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
|
|||
LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
|
||||
|
||||
calcNearbyLights(camera);
|
||||
setupHWLights(NULL);
|
||||
setupHWLights();
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
gGL.setColorMask(true, false);
|
||||
|
|
@ -4850,7 +4865,7 @@ void LLPipeline::renderDebug()
|
|||
mReflectionMapManager.renderDebug();
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("RenderReflectionProbeVolumes"))
|
||||
if (gSavedSettings.getBOOL("RenderReflectionProbeVolumes") && !hud_only)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("probe debug display");
|
||||
|
||||
|
|
@ -4903,7 +4918,7 @@ void LLPipeline::renderDebug()
|
|||
}
|
||||
}
|
||||
|
||||
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
|
|
@ -5355,6 +5370,19 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
|
|||
}
|
||||
break;
|
||||
|
||||
case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
|
||||
if (mPBRAlphaMaskPool)
|
||||
{
|
||||
llassert(0);
|
||||
LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Alpha Mask Pool" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPBRAlphaMaskPool = new_poolp;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
llassert(0);
|
||||
LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
|
||||
|
|
@ -5471,6 +5499,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
|
|||
mPBROpaquePool = NULL;
|
||||
break;
|
||||
|
||||
case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
|
||||
llassert(poolp == mPBRAlphaMaskPool);
|
||||
mPBRAlphaMaskPool = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
llassert(0);
|
||||
LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
|
||||
|
|
@ -5614,7 +5647,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
assertInitialized();
|
||||
|
||||
if (LLPipeline::sReflectionRender || gCubeSnapshot)
|
||||
if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -5795,11 +5828,16 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::setupHWLights(LLDrawPool* pool)
|
||||
void LLPipeline::setupHWLights()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
assertInitialized();
|
||||
|
||||
if (LLPipeline::sRenderingHUDs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLEnvironment& environment = LLEnvironment::instance();
|
||||
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
|
||||
|
||||
|
|
@ -6869,94 +6907,6 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::resetVertexBuffers()
|
||||
{
|
||||
mResetVertexBuffers = true;
|
||||
}
|
||||
|
||||
void LLPipeline::doResetVertexBuffers(bool forced)
|
||||
{
|
||||
if (!mResetVertexBuffers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!forced && LLSpatialPartition::sTeleportRequested)
|
||||
{
|
||||
if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
|
||||
{
|
||||
return; //wait for teleporting to finish
|
||||
}
|
||||
else
|
||||
{
|
||||
//teleporting aborted
|
||||
LLSpatialPartition::sTeleportRequested = FALSE;
|
||||
mResetVertexBuffers = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
|
||||
mResetVertexBuffers = false;
|
||||
|
||||
mCubeVB = NULL;
|
||||
mDeferredVB = NULL;
|
||||
exoPostProcess::instance().destroyVB(); // Will be re-created via updateRenderDeferred()
|
||||
|
||||
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
||||
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
|
||||
{
|
||||
LLViewerRegion* region = *iter;
|
||||
for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
|
||||
{
|
||||
LLSpatialPartition* part = region->getSpatialPartition(i);
|
||||
if (part)
|
||||
{
|
||||
part->resetVertexBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(LLSpatialPartition::sTeleportRequested)
|
||||
{
|
||||
LLSpatialPartition::sTeleportRequested = FALSE;
|
||||
|
||||
LLWorld::getInstance()->clearAllVisibleObjects();
|
||||
clearRebuildDrawables();
|
||||
}
|
||||
|
||||
resetDrawOrders();
|
||||
|
||||
gSky.resetVertexBuffers();
|
||||
|
||||
LLVOPartGroup::destroyGL();
|
||||
|
||||
if ( LLPathingLib::getInstance() )
|
||||
{
|
||||
LLPathingLib::getInstance()->cleanupVBOManager();
|
||||
}
|
||||
LLVOPartGroup::destroyGL();
|
||||
gGL.resetVertexBuffer();
|
||||
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
updateRenderBump();
|
||||
|
||||
sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");
|
||||
sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
|
||||
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
|
||||
|
||||
gGL.initVertexBuffer();
|
||||
|
||||
// <FS:Ansariel> Reset VB during TP
|
||||
//mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK);
|
||||
//mDeferredVB->allocateBuffer(8, 0);
|
||||
initDeferredVB();
|
||||
// </FS:Ansariel>
|
||||
|
||||
LLVOPartGroup::restoreGL();
|
||||
|
||||
exoPostProcess::instance().ExodusRenderPostUpdate(); // <FS:CR> Import Vignette from Exodus
|
||||
}
|
||||
|
||||
void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool rigged)
|
||||
{
|
||||
assertInitialized();
|
||||
|
|
@ -7711,9 +7661,13 @@ void LLPipeline::renderFinalize()
|
|||
|
||||
gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
|
||||
|
||||
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
|
||||
|
||||
gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
|
||||
F32 e = llclamp(exposure(), 0.5f, 4.f);
|
||||
|
||||
static LLStaticHashedString s_exposure("exposure");
|
||||
|
||||
gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
|
||||
|
||||
mScreenTriangleVB->setBuffer();
|
||||
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
|
|
@ -7957,18 +7911,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::SCENE_MAP);
|
||||
if (channel > -1)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(&mSceneMap);
|
||||
}
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::SCENE_DEPTH);
|
||||
if (channel > -1)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(&mSceneMap, true);
|
||||
}
|
||||
|
||||
if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1)
|
||||
{
|
||||
shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
|
||||
|
|
@ -8211,7 +8153,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
|
||||
glh::matrix4f mat = copy_matrix(gGLModelView);
|
||||
|
||||
setupHWLights(NULL); // to set mSun/MoonDir;
|
||||
setupHWLights(); // to set mSun/MoonDir;
|
||||
|
||||
glh::vec4f tc(mSunDir.mV);
|
||||
mat.mult_matrix_vec(tc);
|
||||
|
|
@ -8347,6 +8289,8 @@ void LLPipeline::renderDeferredLighting()
|
|||
soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
|
||||
soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
|
||||
|
||||
soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
|
||||
|
||||
{
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
|
|
@ -8750,10 +8694,13 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
|
|||
shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
|
||||
}
|
||||
|
||||
//if (!gCubeSnapshot)
|
||||
// make sure we're not already targeting the same spot light with both shadow maps
|
||||
llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
|
||||
|
||||
if (!gCubeSnapshot)
|
||||
{
|
||||
LLDrawable* potential = drawablep;
|
||||
//determine if this is a good light for casting shadows
|
||||
//determine if this light is higher priority than one of the existing spot shadows
|
||||
F32 m_pri = volume->getSpotLightPriority();
|
||||
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
|
|
@ -8762,7 +8709,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
|
|||
|
||||
if (mTargetShadowSpotLight[i].notNull())
|
||||
{
|
||||
pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
|
||||
pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
|
||||
}
|
||||
|
||||
if (m_pri > pri)
|
||||
|
|
@ -8775,6 +8722,9 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
|
|||
}
|
||||
}
|
||||
|
||||
// make sure we didn't end up targeting the same spot light with both shadow maps
|
||||
llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
|
||||
|
||||
LLViewerTexture* img = volume->getLightTexture();
|
||||
|
||||
if (img == NULL)
|
||||
|
|
@ -8895,6 +8845,21 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
|
|||
|
||||
setEnvMat(shader);
|
||||
}
|
||||
|
||||
// reflection probe shaders generally sample the scene map as well for SSR
|
||||
channel = shader.enableTexture(LLShaderMgr::SCENE_MAP);
|
||||
if (channel > -1)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(&mSceneMap);
|
||||
}
|
||||
|
||||
channel = shader.enableTexture(LLShaderMgr::SCENE_DEPTH);
|
||||
if (channel > -1)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(&mSceneMap, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader)
|
||||
|
|
@ -9418,6 +9383,24 @@ LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i)
|
|||
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
|
||||
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render");
|
||||
|
||||
// helper class for disabling occlusion culling for the current stack frame
|
||||
class LLDisableOcclusionCulling
|
||||
{
|
||||
public:
|
||||
S32 mUseOcclusion;
|
||||
|
||||
LLDisableOcclusionCulling()
|
||||
{
|
||||
mUseOcclusion = LLPipeline::sUseOcclusion;
|
||||
LLPipeline::sUseOcclusion = 0;
|
||||
}
|
||||
|
||||
~LLDisableOcclusionCulling()
|
||||
{
|
||||
LLPipeline::sUseOcclusion = mUseOcclusion;
|
||||
}
|
||||
};
|
||||
|
||||
void LLPipeline::generateSunShadow(LLCamera& camera)
|
||||
{
|
||||
if (!sRenderDeferred || RenderShadowDetail <= 0)
|
||||
|
|
@ -9428,6 +9411,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
|
||||
LL_PROFILE_GPU_ZONE("generateSunShadow");
|
||||
|
||||
LLDisableOcclusionCulling no_occlusion;
|
||||
|
||||
bool skip_avatar_update = false;
|
||||
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
|
||||
{
|
||||
|
|
@ -9593,7 +9578,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
|
||||
if (fp.empty())
|
||||
{
|
||||
if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowCamera[0] = main_camera;
|
||||
mShadowExtents[0][0] = min;
|
||||
|
|
@ -9661,7 +9646,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
|
||||
|
||||
if (mSunDiffuse == LLColor4::black)
|
||||
{ //sun diffuse is totally shadows don't matter
|
||||
{ //sun diffuse is totally black shadows don't matter
|
||||
LLGLDepthTest depth(GL_TRUE);
|
||||
|
||||
for (S32 j = 0; j < 4; j++)
|
||||
|
|
@ -9673,23 +9658,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
}
|
||||
else
|
||||
{
|
||||
/*if (gCubeSnapshot)
|
||||
{
|
||||
// do one shadow split for cube snapshots, clear the rest
|
||||
mSunClipPlanes.set(64.f, 64.f, 64.f);
|
||||
dist[1] = dist[2] = dist[3] = dist[4] = 64.f;
|
||||
for (S32 j = 1; j < 4; j++)
|
||||
{
|
||||
mRT->shadow[j].bindTarget();
|
||||
mRT->shadow[j].clear();
|
||||
mRT->shadow[j].flush();
|
||||
}
|
||||
}*/
|
||||
|
||||
//for (S32 j = 0; j < (gCubeSnapshot ? 1 : 4); j++)
|
||||
for (S32 j = 0; j < 4; j++)
|
||||
{
|
||||
if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowFrustPoints[j].clear();
|
||||
}
|
||||
|
|
@ -9731,7 +9702,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
shadow_cam.calcAgentFrustumPlanes(frust);
|
||||
shadow_cam.mFrustumCornerDist = 0.f;
|
||||
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowCamera[j] = shadow_cam;
|
||||
}
|
||||
|
|
@ -9741,7 +9712,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
|
||||
{
|
||||
//no possible shadow receivers
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowExtents[j][0] = LLVector3();
|
||||
mShadowExtents[j][1] = LLVector3();
|
||||
|
|
@ -9761,7 +9732,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowExtents[j][0] = min;
|
||||
mShadowExtents[j][1] = max;
|
||||
|
|
@ -9988,7 +9959,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
|
||||
eye = LLVector3(origin_agent.v);
|
||||
|
||||
if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowFrustOrigin[j] = eye;
|
||||
}
|
||||
|
|
@ -10051,14 +10022,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
|
||||
mRT->shadow[j].flush();
|
||||
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
|
||||
{
|
||||
mShadowCamera[j+4] = shadow_cam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//hack to disable projector shadows
|
||||
bool gen_shadow = RenderShadowDetail > 1;
|
||||
|
||||
|
|
@ -10070,6 +10040,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
F32 fade_amt = gFrameIntervalSeconds.value()
|
||||
* llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
|
||||
|
||||
// should never happen
|
||||
llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
|
||||
|
||||
//update shadow targets
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
{ //for each current shadow
|
||||
|
|
@ -10100,6 +10073,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
}
|
||||
}
|
||||
|
||||
// this should never happen
|
||||
llassert(mShadowSpotLight[0] != mShadowSpotLight[1] || mShadowSpotLight[0].isNull());
|
||||
|
||||
for (S32 i = 0; i < 2; i++)
|
||||
{
|
||||
set_current_modelview(saved_view);
|
||||
|
|
@ -10185,8 +10161,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
|
||||
LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
//
|
||||
|
||||
mSpotShadow[i].bindTarget();
|
||||
|
|
|
|||
|
|
@ -97,9 +97,7 @@ public:
|
|||
|
||||
void destroyGL();
|
||||
void restoreGL();
|
||||
void resetVertexBuffers();
|
||||
void doResetVertexBuffers(bool forced = false);
|
||||
void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
|
||||
void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
|
||||
void requestResizeShadowTexture(); // set flag only, no work, safer for callbacks...
|
||||
|
||||
void resizeScreenTexture();
|
||||
|
|
@ -327,7 +325,7 @@ public:
|
|||
S32 getLightCount() const { return mLights.size(); }
|
||||
|
||||
void calcNearbyLights(LLCamera& camera);
|
||||
void setupHWLights(LLDrawPool* pool);
|
||||
void setupHWLights();
|
||||
void setupAvatarLights(bool for_edit = false);
|
||||
void enableLights(U32 mask);
|
||||
void enableLightsStatic();
|
||||
|
|
@ -913,6 +911,8 @@ protected:
|
|||
LLDrawPool* mMaterialsPool = nullptr;
|
||||
LLDrawPool* mWLSkyPool = nullptr;
|
||||
LLDrawPool* mPBROpaquePool = nullptr;
|
||||
LLDrawPool* mPBRAlphaMaskPool = nullptr;
|
||||
|
||||
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -712,6 +712,61 @@
|
|||
value="2"/>
|
||||
</combo_box>
|
||||
|
||||
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="420"
|
||||
name="RenderTonemapperText"
|
||||
text_readonly_color="LabelDisabledColor"
|
||||
top_delta="24"
|
||||
width="128">
|
||||
Tonemapper:
|
||||
</text>
|
||||
<combo_box
|
||||
control_name="RenderTonemapper"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left_delta="130"
|
||||
top_delta="0"
|
||||
name="ToneMapper"
|
||||
width="150">
|
||||
<combo_box.item
|
||||
label="Linear"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="ACES Narkowicz"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="ACES Hill"
|
||||
name="2"
|
||||
value="2"/>
|
||||
</combo_box>
|
||||
|
||||
<slider
|
||||
control_name="RenderExposure"
|
||||
decimal_digits="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="0.1"
|
||||
initial_value="160"
|
||||
label="Exposure:"
|
||||
label_width="145"
|
||||
layout="topleft"
|
||||
left="420"
|
||||
min_val="0.5"
|
||||
max_val="4.0"
|
||||
name="RenderExposure"
|
||||
show_text="true"
|
||||
top_delta="20"
|
||||
width="260">
|
||||
</slider>
|
||||
|
||||
<!-- End of Advanced Settings block -->
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
|
|
|
|||
|
|
@ -13979,10 +13979,12 @@ Material successfully created. Asset ID: [ASSET_ID]
|
|||
name="ReflectionProbeApplied"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Your object has been set to the default Reflection Probe state, which is an invisible, phantom, 5m sphere. To learn more about Reflection Probes and how to use them, see the Knowledge Base.
|
||||
<usetemplate ignoretext="Reflection Probe tips"
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
WARNING: You have made your object a Reflection Probe. This will implicitly change the object to mimic its influence volume and will make irreversible changes to the object. Do you want to continue?
|
||||
<usetemplate
|
||||
ignoretext="Reflection Probe tips"
|
||||
name="okcancelignore"
|
||||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
|
|
|
|||
|
|
@ -376,6 +376,40 @@
|
|||
name="2"
|
||||
value="2"/>
|
||||
</combo_box>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_delta="-5"
|
||||
name="RenderTonemapperText"
|
||||
text_readonly_color="LabelDisabledColor"
|
||||
top_pad="4"
|
||||
width="170">
|
||||
Tonemapper:
|
||||
</text>
|
||||
<combo_box
|
||||
control_name="RenderTonemapper"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="5"
|
||||
top_pad="3"
|
||||
name="ToneMapper"
|
||||
width="150">
|
||||
<combo_box.item
|
||||
label="Linear"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="ACES Narkowicz"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="ACES Hill"
|
||||
name="2"
|
||||
value="2"/>
|
||||
</combo_box>
|
||||
<!-- FS:TM Avatar Physics was moved down to LOD section-->
|
||||
<!-- FS:TM Point Lighting added instead of above-->
|
||||
<text
|
||||
|
|
@ -576,6 +610,24 @@
|
|||
top_pad="5"
|
||||
width="297"/>
|
||||
|
||||
<slider
|
||||
control_name="RenderExposure"
|
||||
decimal_digits="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="0.1"
|
||||
initial_value="1"
|
||||
label="Exposure"
|
||||
label_width="185"
|
||||
layout="topleft"
|
||||
left="200"
|
||||
min_val="0.5"
|
||||
max_val="4.0"
|
||||
name="RenderExposure"
|
||||
show_text="true"
|
||||
top_pad="2"
|
||||
width="297"/>
|
||||
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
|
|
|
|||
|
|
@ -144,11 +144,11 @@
|
|||
top="65"
|
||||
width="90">
|
||||
<combo_box.item
|
||||
label="Materials"
|
||||
label="Blinn-Phong"
|
||||
name="Materials"
|
||||
value="Materials" />
|
||||
<combo_box.item
|
||||
label="PBR"
|
||||
label="PBR Metallic Roughness"
|
||||
name="PBR"
|
||||
value="PBR" />
|
||||
<combo_box.item
|
||||
|
|
@ -249,7 +249,7 @@
|
|||
allow_no_texture="true"
|
||||
follows="left|top"
|
||||
height="80"
|
||||
label="PBR"
|
||||
label="Material"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="pbr_control"
|
||||
|
|
|
|||
Loading…
Reference in New Issue