diff options
Diffstat (limited to 'indra/newview/llfetchedgltfmaterial.cpp')
-rw-r--r-- | indra/newview/llfetchedgltfmaterial.cpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp new file mode 100644 index 0000000000..1fb3577dd7 --- /dev/null +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -0,0 +1,177 @@ +/** + * @file llfetchedgltfmaterial.cpp + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfetchedgltfmaterial.h" + +#include "llviewertexturelist.h" +#include "llavatarappearancedefines.h" +#include "llshadermgr.h" +#include "pipeline.h" + +LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() + : LLGLTFMaterial() + , mExpectedFlusTime(0.f) + , mActive(true) + , mFetching(false) +{ + +} + +LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() +{ + +} + +LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs) +{ + LLGLTFMaterial::operator =(rhs); + + mBaseColorTexture = rhs.mBaseColorTexture; + mNormalTexture = rhs.mNormalTexture; + mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture; + mEmissiveTexture = rhs.mEmissiveTexture; + + return *this; +} + +void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) +{ + // glTF 2.0 Specification 3.9.4. Alpha Coverage + // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK + F32 min_alpha = -1.0; + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + // override emissive and base color textures with media tex if present + LLViewerTexture* baseColorTex = media_tex ? media_tex : mBaseColorTexture; + LLViewerTexture* emissiveTex = media_tex ? media_tex : mEmissiveTexture; + + if (!LLPipeline::sShadowRender || (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)) + { + if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) + { + // dividing the alpha cutoff by transparency here allows the shader to compare against + // the alpha value of the texture without needing the transparency value + min_alpha = mAlphaCutoff/mBaseColor.mV[3]; + } + shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha); + } + + if (baseColorTex != nullptr) + { + gGL.getTexUnit(0)->bindFast(baseColorTex); + } + else + { + gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); + } + + 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); + + if (!LLPipeline::sShadowRender) + { + if (mNormalTexture.notNull() && mNormalTexture->getDiscardLevel() <= 4) + { + 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 (emissiveTex != nullptr) + { + shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, emissiveTex); // 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); + + 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); + } + +} + +void LLFetchedGLTFMaterial::materialBegin() +{ + llassert(!mFetching); + mFetching = true; +} + +void LLFetchedGLTFMaterial::onMaterialComplete(std::function<void()> material_complete) +{ + if (!material_complete) { return; } + + if (!mFetching) + { + material_complete(); + return; + } + + materialCompleteCallbacks.push_back(material_complete); +} + +void LLFetchedGLTFMaterial::materialComplete() +{ + llassert(mFetching); + mFetching = false; + + for (std::function<void()> material_complete : materialCompleteCallbacks) + { + material_complete(); + } + materialCompleteCallbacks.clear(); + materialCompleteCallbacks.shrink_to_fit(); +} |