diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 951b768678..7b6612b90a 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -28,12 +28,41 @@ #include "llgltfmaterial.h" -#include "tiny_gltf.h" +#include "tinygltf/tiny_gltf.h" + +LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) +{ + *this = rhs; +} + +LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) +{ + //have to do a manual operator= because of LLRefCount + mBaseColorId = rhs.mBaseColorId; + mNormalId = rhs.mNormalId; + mMetallicRoughnessId = rhs.mMetallicRoughnessId; + mEmissiveId = rhs.mEmissiveId; + + mBaseColor = rhs.mBaseColor; + mEmissiveColor = rhs.mEmissiveColor; + + mMetallicFactor = rhs.mMetallicFactor; + mRoughnessFactor = rhs.mRoughnessFactor; + mAlphaCutoff = rhs.mAlphaCutoff; + + mDoubleSided = rhs.mDoubleSided; + mAlphaMode = rhs.mAlphaMode; + + mTextureTransform = rhs.mTextureTransform; + + return *this; +} bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) { +#if 1 tinygltf::TinyGLTF gltf; - + tinygltf::Model model_in; if (gltf.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, json.c_str(), json.length(), "")) @@ -45,12 +74,13 @@ bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, st return true; } - +#endif return false; } std::string LLGLTFMaterial::asJSON(bool prettyprint) const { +#if 1 tinygltf::TinyGLTF gltf; tinygltf::Model model_out; @@ -61,6 +91,9 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); return str.str(); +#else + return ""; +#endif } void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) @@ -130,7 +163,7 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const { - if (model.materials.size() < mat_index+1) + if (model.materials.size() < mat_index + 1) { model.materials.resize(mat_index + 1); } @@ -143,7 +176,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const U32 idx = model.images.size(); model.images.resize(idx + 1); model.textures.resize(idx + 1); - + material_out.pbrMetallicRoughness.baseColorTexture.index = idx; model.textures[idx].source = idx; model.images[idx].uri = mBaseColorId.asString(); @@ -160,7 +193,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const model.textures[idx].source = idx; model.images[idx].uri = mNormalId.asString(); } - + // set metallic-roughness texture if (mMetallicRoughnessId.notNull()) { @@ -187,7 +220,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.alphaMode = getAlphaMode(); material_out.alphaCutoff = mAlphaCutoff; - + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); mEmissiveColor.write(material_out.emissiveFactor); @@ -195,11 +228,160 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; material_out.doubleSided = mDoubleSided; + + model.asset.version = "2.0"; } -void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model & model, S32 mat_index, LLGLTFMaterial const * base_material) const + +void LLGLTFMaterial::setBaseColorId(const LLUUID& id) { - if (model.materials.size() < mat_index+1) + mBaseColorId = id; +} + +void LLGLTFMaterial::setNormalId(const LLUUID& id) +{ + mNormalId = id; +} + +void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id) +{ + mMetallicRoughnessId = id; +} + +void LLGLTFMaterial::setEmissiveId(const LLUUID& id) +{ + mEmissiveId = id; +} + +void LLGLTFMaterial::setBaseColorFactor(const LLColor3& baseColor, F32 transparency) +{ + mBaseColor.set(baseColor, transparency); + mBaseColor.clamp(); +} + +void LLGLTFMaterial::setAlphaCutoff(F32 cutoff) +{ + mAlphaCutoff = llclamp(cutoff, 0.f, 1.f); +} + +void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor) +{ + mEmissiveColor = emissiveColor; + mEmissiveColor.clamp(); +} + +void LLGLTFMaterial::setMetallicFactor(F32 metallic) +{ + mMetallicFactor = llclamp(metallic, 0.f, 1.f); +} + +void LLGLTFMaterial::setRoughnessFactor(F32 roughness) +{ + mRoughnessFactor = llclamp(roughness, 0.f, 1.f); +} + +void LLGLTFMaterial::setAlphaMode(S32 mode) +{ + mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK); +} + +void LLGLTFMaterial::setDoubleSided(bool double_sided) +{ + // sure, no clamping will ever be needed for a bool, but include the + // setter for consistency with the clamping API + mDoubleSided = double_sided; +} + +void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset) +{ + mTextureTransform[texture_info].mOffset = offset; +} + +void LLGLTFMaterial::setTextureScale(TextureInfo texture_info, const LLVector2& scale) +{ + mTextureTransform[texture_info].mScale = scale; +} + +void LLGLTFMaterial::setTextureRotation(TextureInfo texture_info, float rotation) +{ + mTextureTransform[texture_info].mRotation = rotation; +} + +// Default value accessors + +LLUUID LLGLTFMaterial::getDefaultBaseColorId() +{ + return LLUUID::null; +} + +LLUUID LLGLTFMaterial::getDefaultNormalId() +{ + return LLUUID::null; +} + +LLUUID LLGLTFMaterial::getDefaultEmissiveId() +{ + return LLUUID::null; +} + +LLUUID LLGLTFMaterial::getDefaultMetallicRoughnessId() +{ + return LLUUID::null; +} + +F32 LLGLTFMaterial::getDefaultAlphaCutoff() +{ + return 0.f; +} + +S32 LLGLTFMaterial::getDefaultAlphaMode() +{ + return (S32) ALPHA_MODE_OPAQUE; +} + +F32 LLGLTFMaterial::getDefaultMetallicFactor() +{ + return 0.f; +} + +F32 LLGLTFMaterial::getDefaultRoughnessFactor() +{ + return 0.f; +} + +LLColor4 LLGLTFMaterial::getDefaultBaseColor() +{ + return LLColor4::white; +} + +LLColor3 LLGLTFMaterial::getDefaultEmissiveColor() +{ + return LLColor3::black; +} + +bool LLGLTFMaterial::getDefaultDoubleSided() +{ + return false; +} + +LLVector2 LLGLTFMaterial::getDefaultTextureOffset() +{ + return LLVector2(0.f, 0.f); +} + +LLVector2 LLGLTFMaterial::getDefaultTextureScale() +{ + return LLVector2(1.f, 1.f); +} + +F32 LLGLTFMaterial::getDefaultTextureRotation() +{ + return 0.f; +} + +void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const +{ + if (model.materials.size() < mat_index + 1) { model.materials.resize(mat_index + 1); } @@ -256,38 +438,120 @@ void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model & model, S32 mat_inde model.images[idx].uri = mEmissiveId.asString(); } - if(mAlphaMode != base_material->mAlphaMode) + if (mAlphaMode != base_material->mAlphaMode) { material_out.alphaMode = getAlphaMode(); } - if(mAlphaCutoff != base_material->mAlphaCutoff) + if (mAlphaCutoff != base_material->mAlphaCutoff) { material_out.alphaCutoff = mAlphaCutoff; } - if(mBaseColor != base_material->mBaseColor) + if (mBaseColor != base_material->mBaseColor) { mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); } - if(mEmissiveColor != base_material->mEmissiveColor) + if (mEmissiveColor != base_material->mEmissiveColor) { mEmissiveColor.write(material_out.emissiveFactor); } - if(mMetallicFactor != base_material->mMetallicFactor) + if (mMetallicFactor != base_material->mMetallicFactor) { material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; } - if(mRoughnessFactor != base_material->mRoughnessFactor) + if (mRoughnessFactor != base_material->mRoughnessFactor) { material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; } - if(mDoubleSided != base_material->mDoubleSided) + if (mDoubleSided != base_material->mDoubleSided) { material_out.doubleSided = mDoubleSided; } } + +void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) +{ + // TODO: potentially reimplement this with a more general purpose JSON merge + + if (override_mat.mBaseColorId != getDefaultBaseColorId()) + { + mBaseColorId = override_mat.mBaseColorId; + } + + if (override_mat.mNormalId != getDefaultNormalId()) + { + mNormalId = override_mat.mNormalId; + } + + if (override_mat.mMetallicRoughnessId != getDefaultMetallicRoughnessId()) + { + mMetallicRoughnessId = override_mat.mMetallicRoughnessId; + } + + if (override_mat.mEmissiveId != getDefaultEmissiveId()) + { + mEmissiveId = override_mat.mEmissiveId; + } + + if (override_mat.mBaseColor != getDefaultBaseColor()) + { + mBaseColor = override_mat.mBaseColor; + } + + if (override_mat.mEmissiveColor != getDefaultEmissiveColor()) + { + mEmissiveColor = override_mat.mEmissiveColor; + } + + if (override_mat.mMetallicFactor != getDefaultMetallicFactor()) + { + mMetallicFactor = override_mat.mMetallicFactor; + } + + if (override_mat.mRoughnessFactor != getDefaultRoughnessFactor()) + { + mRoughnessFactor = override_mat.mRoughnessFactor; + } + + if (override_mat.mAlphaMode != getDefaultAlphaMode()) + { + mAlphaMode = override_mat.mAlphaMode; + } + if (override_mat.mAlphaCutoff != getDefaultAlphaCutoff()) + { + mAlphaCutoff = override_mat.mAlphaCutoff; + } + + if (override_mat.mDoubleSided != getDefaultDoubleSided()) + { + mDoubleSided = override_mat.mDoubleSided; + } + + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (override_mat.mTextureTransform[i].mOffset != getDefaultTextureOffset()) + { + mTextureTransform[i].mOffset = override_mat.mTextureTransform[i].mOffset; + } + + if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale()) + { + mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale; + } + + if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale()) + { + mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale; + } + + if (override_mat.mTextureTransform[i].mRotation != getDefaultTextureRotation()) + { + mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation; + } + } +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index e8d1d67f1b..ea7e402805 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -27,8 +27,10 @@ #pragma once #include "llrefcount.h" +#include "llmemory.h" #include "v4color.h" #include "v3color.h" +#include "v2math.h" #include "lluuid.h" #include "llmd5.h" @@ -43,6 +45,13 @@ class LLGLTFMaterial : public LLRefCount { public: + struct TextureTransform + { + LLVector2 mOffset = { 0.f, 0.f }; + LLVector2 mScale = { 1.f, 1.f }; + F32 mRotation = 0.f; + }; + enum AlphaMode { ALPHA_MODE_OPAQUE = 0, @@ -50,6 +59,11 @@ public: ALPHA_MODE_MASK }; + LLGLTFMaterial() {} + LLGLTFMaterial(const LLGLTFMaterial& rhs); + + LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs); + LLUUID mBaseColorId; LLUUID mNormalId; LLUUID mMetallicRoughnessId; @@ -74,9 +88,56 @@ public: md5.finalize(); LLUUID id; md5.raw_digest(id.mData); + // *TODO: Hash the overrides return id; } + 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 mTextureTransform; + + //setters for various members (will clamp to acceptable ranges) + + void setBaseColorId(const LLUUID& id); + void setNormalId(const LLUUID& id); + void setMetallicRoughnessId(const LLUUID& id); + void setEmissiveId(const LLUUID& id); + + void setBaseColorFactor(const LLColor3& baseColor, F32 transparency); + void setAlphaCutoff(F32 cutoff); + void setEmissiveColorFactor(const LLColor3& emissiveColor); + void setMetallicFactor(F32 metallic); + void setRoughnessFactor(F32 roughness); + void setAlphaMode(S32 mode); + void setDoubleSided(bool double_sided); + void setTextureOffset(TextureInfo texture_info, const LLVector2& offset); + void setTextureScale(TextureInfo texture_info, const LLVector2& scale); + void setTextureRotation(TextureInfo texture_info, float rotation); + + // Default value accessors + static LLUUID getDefaultBaseColorId(); + static LLUUID getDefaultNormalId(); + static LLUUID getDefaultEmissiveId(); + static LLUUID getDefaultMetallicRoughnessId(); + static F32 getDefaultAlphaCutoff(); + static S32 getDefaultAlphaMode(); + static F32 getDefaultMetallicFactor(); + static F32 getDefaultRoughnessFactor(); + static LLColor4 getDefaultBaseColor(); + static LLColor3 getDefaultEmissiveColor(); + static bool getDefaultDoubleSided(); + static LLVector2 getDefaultTextureOffset(); + static LLVector2 getDefaultTextureScale(); + static F32 getDefaultTextureRotation(); + // set mAlphaMode from string. // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE void setAlphaMode(const std::string& mode) @@ -124,6 +185,9 @@ public: void writeToModel(tinygltf::Model& model, S32 mat_index) const; // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model - void writeOverridesToModel(tinygltf::Model & model, S32 mat_index, LLGLTFMaterial const * base_material) const; + void writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const; + + void applyOverride(const LLGLTFMaterial& override_mat); + }; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 284dfc15f4..e185404ada 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -491,6 +491,25 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) return TEM_CHANGE_NONE; } +void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) +{ + mGLTFMaterial = material; + if (mGLTFMaterial == nullptr) + { + setGLTFRenderMaterial(nullptr); + } +} + +S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat) +{ + if (mGLTFRenderMaterial != mat) + { + mGLTFRenderMaterial = mat; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; +} + S32 LLTextureEntry::setMediaFlags(U8 media_flags) { media_flags &= TEM_MEDIA_MASK; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 1549b2ce87..8dc3434a01 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -135,10 +135,6 @@ public: S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); - void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } - LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } - - virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -167,8 +163,6 @@ public: const LLMaterialID& getMaterialID() const { return mMaterialID; }; const LLMaterialPtr getMaterialParams() const { return mMaterial; }; - LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } - // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() // to NOT return NULL. @@ -200,6 +194,19 @@ public: // Media flags enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; + // GLTF asset + void setGLTFMaterial(LLGLTFMaterial* material); + LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } + + // GLTF override + LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; } + void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } + + // GLTF render material + // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter + LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial.get() : getGLTFMaterial(); } + S32 setGLTFRenderMaterial(LLGLTFMaterial* mat); + public: F32 mScaleS; // S, T offset F32 mScaleT; // S, T offset @@ -226,7 +233,17 @@ protected: bool mMaterialUpdatePending; LLMaterialID mMaterialID; LLMaterialPtr mMaterial; - LLPointer mGLTFMaterial; // if present, ignore mMaterial + + // Reference to GLTF material asset state + // On the viewer, this should be the same LLGLTFMaterial instance that exists in LLGLTFMaterialList + LLPointer mGLTFMaterial; + + // GLTF material parameter overrides -- the viewer will use this data to override material parameters + // set by the asset and store the results in mRenderGLTFMaterial + LLPointer mGLTFMaterialOverrides; + + // GLTF material to use for rendering -- will always be an LLFetchedGLTFMaterial + LLPointer mGLTFRenderMaterial; // Note the media data is not sent via the same message structure as the rest of the TE LLMediaEntry* mMediaEntry; // The media data for the face diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 3f63cf24f8..8a1ee35573 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -74,6 +74,7 @@ Voice Avatar --> + Capabilities import export Outfit diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl index b633813819..feaf562686 100644 --- a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl @@ -196,7 +196,7 @@ vec4 filterColor(vec3 N) // apply the bias to the lod lod += u_lodBias; - lod = clamp(lod, 0, 7); + lod = clamp(lod, 0, 6); // sample lambertian at a lower resolution to avoid fireflies vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod); diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index f4879b52de..32f157e9d2 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -127,7 +127,7 @@ vec4 prefilterEnvMap(vec3 R) float envMapDim = 256.0; int numSamples = 4; - float numMips = 7.0; + float numMips = 6.0; float roughness = mipLevel/numMips; @@ -151,7 +151,7 @@ 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, 7.f); + 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; totalWeight += dotNL; diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 211e1f5d8d..ca436033f1 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -507,7 +507,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness, bool errorCorrect) { // TODO - don't hard code lods - float reflection_lods = 7; + float reflection_lods = 6; preProbeSample(pos); vec3 refnormpersp = reflect(pos.xyz, norm.xyz); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 198cf22f12..af5e7da2bc 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -285,9 +285,9 @@ RenderFSAASamples 1 0 RenderGLMultiThreaded 1 0 RenderGLContextCoreProfile 1 0 -// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 16 +// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 32 list AMD -RenderReflectionProbeCount 1 16 +RenderReflectionProbeCount 1 32 list GL3 RenderFSAASamples 0 0 diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 0920194629..d008fc2261 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -723,45 +723,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) gPipeline.bindDeferredShader(*target_shader); } - if (params.mTexture.notNull()) - { - gGL.getTexUnit(0)->bindFast(params.mTexture); // diffuse - } - else - { - gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); - } - - if (params.mNormalMap) - { - target_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); - } - else - { - target_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - } - - if (params.mSpecularMap) - { - target_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); // PBR linear packed Occlusion, Roughness, Metal. - } - else - { - target_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - if (params.mEmissiveMap) - { - target_shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, params.mEmissiveMap); // PBR sRGB Emissive - } - else - { - target_shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - target_shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor); - target_shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor); - target_shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV); + params.mGLTFMaterial->bind(target_shader); } else { diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index 71f648a714..2f710e570b 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -95,57 +95,10 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass) for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo* pparams = *i; - LLGLTFMaterial *mat = pparams->mGLTFMaterial; - - // glTF 2.0 Specification 3.9.4. Alpha Coverage - // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK - F32 min_alpha = -1.0; - if (mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) - { - min_alpha = mat->mAlphaCutoff; - } - shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha); - - if (pparams->mTexture.notNull()) - { - gGL.getTexUnit(0)->bindFast(pparams->mTexture); // diffuse - } - else - { - gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); - } - - if (pparams->mNormalMap) - { - shader->bindTexture(LLShaderMgr::BUMP_MAP, pparams->mNormalMap); - } - else - { - shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - } - - if (pparams->mSpecularMap) - { - shader->bindTexture(LLShaderMgr::SPECULAR_MAP, pparams->mSpecularMap); // PBR linear packed Occlusion, Roughness, Metal. - } - else - { - shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - if (pparams->mEmissiveMap) - { - shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, pparams->mEmissiveMap); // PBR sRGB Emissive - } - else - { - shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, pparams->mGLTFMaterial->mRoughnessFactor); - shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, pparams->mGLTFMaterial->mMetallicFactor); - shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, pparams->mGLTFMaterial->mEmissiveColor.mV); - + auto& mat = pparams->mGLTFMaterial; + + mat->bind(shader); + LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0); bool tex_setup = false; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index a63d036e74..f7cf63e99b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1407,9 +1407,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLColor4U color = (tep ? tep->getColor() : LLColor4()); // - if (tep->getGLTFMaterial()) + if (tep->getGLTFRenderMaterial()) { - color = tep->getGLTFMaterial()->mBaseColor; + color = tep->getGLTFRenderMaterial()->mBaseColor; } if (rebuild_color) @@ -1679,7 +1679,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, // LLMaterial* mat = tep->getMaterialParams().get(); LLMaterial* mat = tep ? tep->getMaterialParams().get() : 0; // - LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial(); bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index a06dd276cd..2d3015635c 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -27,6 +27,10 @@ #include "llfetchedgltfmaterial.h" +#include "llviewertexturelist.h" +#include "llavatarappearancedefines.h" +#include "llshadermgr.h" + LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() : LLGLTFMaterial() , mExpectedFlusTime(0.f) @@ -38,5 +42,62 @@ LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() { + +} + +void LLFetchedGLTFMaterial::bind(LLGLSLShader* shader) +{ + // glTF 2.0 Specification 3.9.4. Alpha Coverage + // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK + F32 min_alpha = -1.0; + + if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) + { + min_alpha = mAlphaCutoff; + } + shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha); + + if (mBaseColorTexture.notNull()) + { + gGL.getTexUnit(0)->bindFast(mBaseColorTexture); + } + else + { + gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); + } + + + if (mNormalTexture.notNull()) + { + shader->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture); + } + else + { + shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + } + + if (mMetallicRoughnessTexture.notNull()) + { + shader->bindTexture(LLShaderMgr::SPECULAR_MAP, mMetallicRoughnessTexture); // PBR linear packed Occlusion, Roughness, Metal. + } + else + { + shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + if (mEmissiveTexture.notNull()) + { + shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, mEmissiveTexture); // PBR sRGB Emissive + } + else + { + shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + // NOTE: base color factor is baked into vertex stream + + shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor); + shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); + shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 4cbe6651c4..3b2801bf77 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -28,14 +28,26 @@ #include "llgltfmaterial.h" #include "llpointer.h" +#include "llviewertexture.h" -class LLFetchedGLTFMaterial : public LLGLTFMaterial +class LLGLSLShader; + +class LLFetchedGLTFMaterial: public LLGLTFMaterial { friend class LLGLTFMaterialList; // for lifetime management public: LLFetchedGLTFMaterial(); virtual ~LLFetchedGLTFMaterial(); + // bind this material for rendering + void bind(LLGLSLShader* shader); + + // Textures used for fetching/rendering + LLPointer mBaseColorTexture; + LLPointer mNormalTexture; + LLPointer mMetallicRoughnessTexture; + LLPointer mEmissiveTexture; + protected: //Lifetime management F64 mExpectedFlusTime; // since epoch in seconds diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 0fd5f37b51..0a104d1db5 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -35,36 +35,65 @@ #include "lltinygltfhelper.h" #include "llviewercontrol.h" #include "llviewergenericmessage.h" +#include "llviewerobjectlist.h" #include "tinygltf/tiny_gltf.h" #include +#include "json/reader.h" +#include "json/value.h" + namespace { class LLGLTFOverrideDispatchHandler : public LLDispatchHandler { + LOG_CLASS(LLGLTFOverrideDispatchHandler); public: LLGLTFOverrideDispatchHandler() = default; ~LLGLTFOverrideDispatchHandler() override = default; bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override { - for (std::string const & s : strings) { - LL_DEBUGS() << "received override: " << s << LL_ENDL; + // iterate over pairs of parameters + int i; + for (i = 0; i+1 < strings.size(); i += 2) + { + std::string params_json = strings[i]; + std::string override_json = strings[i+1]; + + LL_DEBUGS() << "received override: " << params_json << " | " << override_json << LL_ENDL; + + Json::Value params; + Json::Reader reader; + bool success = reader.parse(params_json, params); + if (!success) + { + LL_WARNS() << "failed to parse override parameters. errors: " << reader.getFormatedErrorMessages() << LL_ENDL; + break; + } + + LLViewerObject * obj = gObjectList.findObject(LLUUID(params["object_id"].asString())); + S32 side = params["side"].asInt(); -#if 0 - // for now messages are coming in llsd - LLSD override_data; - std::istringstream input(s); - LLSDSerialize::deserialize(override_data, input, s.length()); - LL_DEBUGS() << "deserialized override: " << override_data << LL_ENDL; -#else std::string warn_msg, error_msg; - LLGLTFMaterial override_data; - override_data.fromJSON(s, warn_msg, error_msg); -#endif + LLPointer override_data = new LLGLTFMaterial(); + success = override_data->fromJSON(override_json, warn_msg, error_msg); +// if (!success) +// { +// LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; +// break; +// } + + if(obj) + { + obj->setTEGLTFMaterialOverride(side, override_data); + } + + LL_DEBUGS() << "successfully parsed override: " << override_data->asJSON() << LL_ENDL; } + LL_WARNS_IF(i != strings.size()) << "parse error or unhandled mismatched odd number of parameters for material override" << LL_ENDL; + return true; } }; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index f292844313..f194226fa5 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -152,18 +152,7 @@ bool LLLocalGLTFMaterial::updateSelf() if (mLastModified.asString() != new_last_modified.asString()) { - LLPointer raw_material; - if (mWorldID.notNull()) - { - // update existing material - // will create a new one if material doesn't exist yet - raw_material = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID); - } - else - { - raw_material = new LLFetchedGLTFMaterial(); - } - if (loadMaterial(raw_material, mMaterialIndex)) + if (loadMaterial()) { // decode is successful, we can safely proceed. if (mWorldID.isNull()) @@ -172,8 +161,10 @@ bool LLLocalGLTFMaterial::updateSelf() } mLastModified = new_last_modified; - // will replace material if it already exists - gGLTFMaterialList.addMaterial(mWorldID, raw_material); + // addMaterial will replace material witha a new + // pointer if value already exists but we are + // reusing existing pointer, so it should add only. + gGLTFMaterialList.addMaterial(mWorldID, mGLTFMaterial); mUpdateRetries = LL_LOCAL_UPDATE_RETRIES; updated = true; @@ -223,10 +214,21 @@ bool LLLocalGLTFMaterial::updateSelf() return updated; } -bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat, S32 index) +bool LLLocalGLTFMaterial::loadMaterial() { bool decode_successful = false; + if (mWorldID.notNull()) + { + // We should already have it, but update mGLTFMaterial just in case + // will create a new one if material doesn't exist yet + mGLTFMaterial = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID); + } + else + { + mGLTFMaterial = new LLFetchedGLTFMaterial(); + } + switch (mExtension) { case ET_MATERIAL_GLTF: @@ -261,19 +263,19 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat, S32 index) break; } - if (model_in.materials.size() <= index) + if (model_in.materials.size() <= mMaterialIndex) { // materials are missing - LL_WARNS() << "Cannot load Material, Material " << index << " is missing, " << mFilename << LL_ENDL; + LL_WARNS() << "Cannot load Material, Material " << mMaterialIndex << " is missing, " << mFilename << LL_ENDL; decode_successful = false; break; } // sets everything, but textures will have inaccurate ids - mat->setFromModel(model_in, index); + mGLTFMaterial->setFromModel(model_in, mMaterialIndex); std::string folder = gDirUtilp->getDirName(filename_lc); - tinygltf::Material material_in = model_in.materials[index]; + tinygltf::Material material_in = model_in.materials[mMaterialIndex]; if (!material_in.name.empty()) { @@ -302,19 +304,50 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat, S32 index) if (mBaseColorFetched) { - mat->mBaseColorId= mBaseColorFetched->getID(); + mBaseColorFetched->addTextureStats(64.f * 64.f, TRUE); + mGLTFMaterial->mBaseColorId = mBaseColorFetched->getID(); + mGLTFMaterial->mBaseColorTexture = mBaseColorFetched; } + else + { + mGLTFMaterial->mBaseColorId = LLUUID::null; + mGLTFMaterial->mBaseColorTexture = nullptr; + } + if (mNormalFetched) { - mat->mNormalId = mNormalFetched->getID(); + mNormalFetched->addTextureStats(64.f * 64.f, TRUE); + mGLTFMaterial->mNormalId = mNormalFetched->getID(); + mGLTFMaterial->mNormalTexture = mBaseColorFetched; } + else + { + mGLTFMaterial->mNormalId = LLUUID::null; + mGLTFMaterial->mNormalTexture = nullptr; + } + if (mMRFetched) { - mat->mMetallicRoughnessId = mMRFetched->getID(); + mMRFetched->addTextureStats(64.f * 64.f, TRUE); + mGLTFMaterial->mMetallicRoughnessId = mMRFetched->getID(); + mGLTFMaterial->mMetallicRoughnessTexture = mBaseColorFetched; } + else + { + mGLTFMaterial->mMetallicRoughnessId = LLUUID::null; + mGLTFMaterial->mMetallicRoughnessTexture = nullptr; + } + if (mEmissiveFetched) { - mat->mEmissiveId = mEmissiveFetched->getID(); + mEmissiveFetched->addTextureStats(64.f * 64.f, TRUE); + mGLTFMaterial->mEmissiveId = mEmissiveFetched->getID(); + mGLTFMaterial->mEmissiveTexture = mBaseColorFetched; + } + else + { + mGLTFMaterial->mEmissiveId = LLUUID::null; + mGLTFMaterial->mEmissiveTexture = nullptr; } break; diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index f762dcc2ce..097f2ea30a 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -34,6 +34,7 @@ class LLScrollListCtrl; class LLGLTFMaterial; class LLViewerObject; class LLViewerFetchedTexture; +class LLFetchedGLTFMaterial; class LLLocalGLTFMaterial { @@ -53,7 +54,7 @@ public: bool updateSelf(); private: - bool loadMaterial(LLPointer raw, S32 index); + bool loadMaterial(); private: /* private enums */ enum ELinkStatus @@ -80,7 +81,9 @@ private: /* members */ S32 mUpdateRetries; S32 mMaterialIndex; // Single file can have more than one - // material needs to maintain textures + // Maintain textures and material pointers to + // make sure they won't be deleted in any way + LLPointer mGLTFMaterial; LLPointer mBaseColorFetched; LLPointer mNormalFetched; LLPointer mMRFetched; diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 14b762998a..e0a2c00db3 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -38,7 +38,7 @@ class LLViewerObject; #define LL_MAX_REFLECTION_PROBE_COUNT 256 // reflection probe resolution -#define LL_REFLECTION_PROBE_RESOLUTION 256 +#define LL_REFLECTION_PROBE_RESOLUTION 128 #define LL_IRRADIANCE_MAP_RESOLUTION 64 // reflection probe mininum scale diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b305460ae6..4784c7fcd0 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -41,6 +41,7 @@ #include "llviewercamera.h" #include "llvector4a.h" #include "llvoavatar.h" +#include "llfetchedgltfmaterial.h" // needed to resolve render_hull dep #include "llmodel.h" @@ -125,9 +126,11 @@ public: F32 mDistance; U32 mDrawMode; - // Material points here are likely for debugging only and are immaterial (zing!) + // Material pointer here is likely for debugging only and are immaterial (zing!) LLMaterialPtr mMaterial; - LLPointer mGLTFMaterial; + + // PBR material parameters + LLPointer mGLTFMaterial; LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info @@ -139,7 +142,6 @@ public: const LLMatrix4* mSpecularMapMatrix; LLPointer mNormalMap; const LLMatrix4* mNormalMapMatrix; - LLPointer mEmissiveMap; LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent F32 mEnvIntensity; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cda9371201..6c0beee0d5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -432,11 +432,6 @@ void LLViewerObject::deleteTEImages() delete[] mTESpecularMaps; mTESpecularMaps = NULL; } - - mGLTFBaseColorMaps.clear(); - mGLTFNormalMaps.clear(); - mGLTFMetallicRoughnessMaps.clear(); - mGLTFEmissiveMaps.clear(); } void LLViewerObject::markDead() @@ -4929,11 +4924,6 @@ void LLViewerObject::setNumTEs(const U8 num_tes) mTEImages = new_images; mTENormalMaps = new_normmaps; mTESpecularMaps = new_specmaps; - - mGLTFBaseColorMaps.resize(num_tes); - mGLTFNormalMaps.resize(num_tes); - mGLTFMetallicRoughnessMaps.resize(num_tes); - mGLTFEmissiveMaps.resize(num_tes); } else { @@ -5103,14 +5093,28 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); } - auto fetch_texture = [](const LLUUID& id, LLViewerObject *obj) + LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial(); + LLUUID mat_id = getRenderMaterialID(te); + if (mat == nullptr && mat_id.notNull()) + { + mat = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mat_id); + getTE(te)->setGLTFMaterial(mat); + } + else if (mat_id.isNull() && mat != nullptr) + { + mat = nullptr; + getTE(te)->setGLTFMaterial(nullptr); + } + + auto fetch_texture = [this](const LLUUID& id) { LLViewerFetchedTexture* img = nullptr; if (id.notNull()) { if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) { - LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id); + // TODO -- fall back to LLTextureEntry::mGLTFRenderMaterial when overriding with baked texture + LLViewerTexture* viewerTexture = getBakedTextureForMagicId(id); img = viewerTexture ? dynamic_cast(viewerTexture) : nullptr; } else @@ -5123,34 +5127,13 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) return img; }; - LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); - LLUUID mat_id = getRenderMaterialID(te); - if (mat == nullptr && mat_id.notNull()) - { - mat = gGLTFMaterialList.getMaterial(mat_id); - getTE(te)->setGLTFMaterial(mat); - } - else if (mat_id.isNull() && mat != nullptr) - { - mat = nullptr; - getTE(te)->setGLTFMaterial(nullptr); - } - if (mat != nullptr) { - mGLTFBaseColorMaps[te] = fetch_texture(mat->mBaseColorId, this); - mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId, this); - mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId, this); - mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId, this); + mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId); + mat->mNormalTexture = fetch_texture(mat->mNormalId); + mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId); + mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId); } - else - { - mGLTFBaseColorMaps[te] = nullptr; - mGLTFNormalMaps[te] = nullptr; - mGLTFMetallicRoughnessMaps[te] = nullptr; - mGLTFEmissiveMaps[te] = nullptr; - } - } void LLViewerObject::refreshBakeTexture() @@ -5505,10 +5488,39 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null); - refreshMaterials(); return retval; } +S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat) +{ + S32 retval = TEM_CHANGE_NONE; + + LLTextureEntry* tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + return retval; + } + + LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial(); + + tep->setGLTFMaterialOverride(override_mat); + + if (override_mat && src_mat) + { + LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); + render_mat->applyOverride(*override_mat); + tep->setGLTFRenderMaterial(render_mat); + retval = TEM_CHANGE_TEXTURE; + } + else if (tep->setGLTFRenderMaterial(nullptr)) + { + retval = TEM_CHANGE_TEXTURE; + } + + return retval; +} + void LLViewerObject::refreshMaterials() { setChanged(TEXTURE); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index eb4637f6e8..4882478ed7 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -363,6 +363,7 @@ public: /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); + virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat); // Used by Materials update functions to properly kick off rebuilds // of VBs etc when materials updates require changes. @@ -378,12 +379,6 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; - LLViewerTexture* getGLTFBaseColorMap(U8 te) const { return mGLTFBaseColorMaps[te]; } - LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; } - LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; } - LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; } - - bool isImageAlphaBlended(const U8 te) const; void fitFaceTexture(const U8 face); @@ -710,13 +705,6 @@ public: LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; - std::vector > mGLTFBaseColorMaps; - std::vector > mGLTFNormalMaps; - std::vector > mGLTFMetallicRoughnessMaps; - std::vector > mGLTFEmissiveMaps; - - - // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true) // can likely be factored out BOOL mbCanSelect; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 949f374506..9017fccffc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2811,6 +2811,24 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa return TEM_CHANGE_TEXTURE; } +S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) +{ + S32 retval = LLViewerObject::setTEGLTFMaterialOverride(te, mat); + + if (retval == TEM_CHANGE_TEXTURE) + { + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + } + + return retval; +} + + S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) { S32 res = LLViewerObject::setTEScale(te, s, t); @@ -2844,6 +2862,7 @@ S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t) return res; } + void LLVOVolume::updateTEData() { /*if (mDrawable.notNull()) @@ -5502,7 +5521,7 @@ bool can_batch_texture(LLFace* facep) return false; } - if (facep->getTextureEntry()->getGLTFMaterial() != nullptr) + if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr) { // PBR materials break indexed texture batching return false; } @@ -5679,7 +5698,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLUUID mat_id; - LLGLTFMaterial* gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial(); if (gltf_mat != nullptr) { mat_id = gltf_mat->getHash(); // TODO: cache this hash @@ -5808,21 +5827,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (gltf_mat) { - LLViewerObject* vobj = facep->getViewerObject(); - U8 te = facep->getTEOffset(); - - draw_info->mTexture = vobj->getGLTFBaseColorMap(te); - draw_info->mNormalMap = vobj->getGLTFNormalMap(te); - draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); - draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); - if (draw_info->mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) - { - draw_info->mAlphaMaskCutoff = gltf_mat->mAlphaCutoff * gltf_mat->mBaseColor.mV[3]; - } - else - { - draw_info->mAlphaMaskCutoff = 1.f; - } + // nothing to do, render pools will reference the GLTF material } else if (mat) { @@ -6222,7 +6227,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_pbr = false; #endif #else - LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFRenderMaterial(); bool is_pbr = gltf_mat != nullptr; #endif @@ -6370,7 +6375,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (!te) continue; - LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); if (LLPipeline::sRenderDeferred && (gltf_mat != nullptr || (te->getMaterialParams().notNull() && !te->getMaterialID().isNull()))) @@ -7095,7 +7100,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; - LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); LLMaterial* mat = nullptr; bool can_be_shiny = false; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 1551cfe411..f0a6bc20b9 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -214,6 +214,7 @@ public: static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override; + S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) override; /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override; /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override; /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ff3dd0f5bb..04b6cc9061 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1770,7 +1770,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima } LLMaterial* mat = te->getMaterialParams().get(); - LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); bool color_alpha = te->getColor().mV[3] < 0.999f; bool alpha = color_alpha; @@ -3920,15 +3920,26 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) void LLPipeline::touchTextures(LLDrawInfo* info) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - for (int i = 0; i < info->mTextureList.size(); ++i) - { - touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); - } - touchTexture(info->mTexture, info->mVSize); - touchTexture(info->mSpecularMap, info->mVSize); - touchTexture(info->mNormalMap, info->mVSize); - touchTexture(info->mEmissiveMap, info->mVSize); + auto& mat = info->mGLTFMaterial; + if (mat.notNull()) + { + touchTexture(mat->mBaseColorTexture, info->mVSize); + touchTexture(mat->mNormalTexture, info->mVSize); + touchTexture(mat->mMetallicRoughnessTexture, info->mVSize); + touchTexture(mat->mEmissiveTexture, info->mVSize); + } + else + { + for (int i = 0; i < info->mTextureList.size(); ++i) + { + touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); + } + + touchTexture(info->mTexture, info->mVSize); + touchTexture(info->mSpecularMap, info->mVSize); + touchTexture(info->mNormalMap, info->mVSize); + } } void LLPipeline::postSort(LLCamera& camera)