From d8dd4d9c0cd4554704cbe15b5502f4d87a4674ad Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 27 Jun 2023 20:01:52 -0700 Subject: Just about got hero reflection maps working. DRTVWR-583 --- indra/llprimitive/llprimitive.cpp | 5 + indra/llprimitive/llprimitive.h | 1 + indra/llprimitive/llprimtexturelist.cpp | 10 ++ indra/llprimitive/llprimtexturelist.h | 1 + indra/llprimitive/lltextureentry.cpp | 19 +++ indra/llprimitive/lltextureentry.h | 12 +- indra/llrender/llglslshader.cpp | 4 +- indra/llrender/llglslshader.h | 1 + indra/llrender/llshadermgr.cpp | 9 ++ indra/llrender/llshadermgr.h | 1 + indra/newview/app_settings/settings.xml | 11 ++ .../shaders/class3/deferred/reflectionProbeF.glsl | 8 ++ .../shaders/class3/deferred/softenLightF.glsl | 12 +- indra/newview/llpanelface.cpp | 18 +++ indra/newview/llpanelface.h | 4 +- indra/newview/llreflectionmap.h | 11 ++ indra/newview/llreflectionmapmanager.cpp | 135 +++++++++++++++++---- indra/newview/llreflectionmapmanager.h | 15 ++- indra/newview/llselectmgr.cpp | 41 +++++++ indra/newview/llselectmgr.h | 1 + indra/newview/llviewerobject.cpp | 22 ++++ indra/newview/llviewerobject.h | 1 + indra/newview/llviewershadermgr.cpp | 2 + indra/newview/llvovolume.cpp | 10 ++ indra/newview/llvovolume.h | 1 + indra/newview/pipeline.cpp | 7 ++ 26 files changed, 331 insertions(+), 31 deletions(-) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 5dfce4ae16..b45ead92d3 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -404,6 +404,11 @@ S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) return mTextureList.setFullbright(index, fullbright); } +S32 LLPrimitive::setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target) +{ + return mTextureList.setRenderableTarget(te, target); +} + S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) { return mTextureList.setMediaFlags(index, media_flags); diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index d2adfa4a3d..520c7c7ac8 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -485,6 +485,7 @@ public: virtual S32 setTETexGen(const U8 te, const U8 texgen); virtual S32 setTEShiny(const U8 te, const U8 shiny); virtual S32 setTEFullbright(const U8 te, const U8 fullbright); + virtual S32 setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target); virtual S32 setTEMediaFlags(const U8 te, const U8 flags); virtual S32 setTEGlow(const U8 te, const F32 glow); virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index f4f08248b8..49b59e35cb 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -341,6 +341,16 @@ S32 LLPrimTextureList::setFullbright(const U8 index, const U8 fullbright) return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setRenderableTarget(const U8 index, const U8 target) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setRenderableTarget((LLTextureEntry::eRenderableTarget)target); + } + + return TEM_CHANGE_NONE; +} + S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) { if (index < mEntryList.size()) diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 49c636e40f..34b87d879f 100644 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -102,6 +102,7 @@ public: S32 setTexGen(const U8 index, const U8 texgen); S32 setShiny(const U8 index, const U8 shiny); S32 setFullbright(const U8 index, const U8 t); + S32 setRenderableTarget(const U8 index, const U8 target); S32 setMediaFlags(const U8 index, const U8 media_flags); S32 setGlow(const U8 index, const F32 glow); S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 71caff1686..d057e5ab29 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -504,6 +504,16 @@ S32 LLTextureEntry::setFullbright(U8 fullbright) return TEM_CHANGE_NONE; } +S32 LLTextureEntry::setRenderableTarget(eRenderableTarget target) +{ + if (getRenderableTarget() != target) { + mRenderableTarget = target; + return TEM_CHANGE_TEXTURE; + } + + return TEM_CHANGE_NONE; +} + S32 LLTextureEntry::setShiny(U8 shiny) { shiny &= TEM_SHINY_MASK; @@ -685,6 +695,15 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams) mMaterialUpdatePending = true; } mMaterial = pMaterialParams; + + // TODO: GZ: We should avoid magic UUIDs in the future, but for development we're using one for the time being. Remove this later. + if (mMaterial->getSpecularID().asString() == "da7ecda1-e780-423f-ce27-26df7dc69cb6") + { + setRenderableTarget(RT_MIRROR); + } else { + setRenderableTarget(RT_DISABLED); + } + return TEM_CHANGE_TEXTURE; } diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index f5f2c0172d..2c0832e1d4 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -80,6 +80,12 @@ public: TEX_GEN_SPHERICAL = 0x04, TEX_GEN_CYLINDRICAL = 0x06 } eTexGen; + + + typedef enum e_renderable_target { + RT_DISABLED = 0x00, + RT_MIRROR = 0x02 + } eRenderableTarget; LLTextureEntry(); LLTextureEntry(const LLUUID& tex_id); @@ -134,7 +140,9 @@ public: S32 setGlow(F32 glow); S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); - + + S32 setRenderableTarget(eRenderableTarget target); + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -152,6 +160,7 @@ public: U8 getBumpmap() const { return mBump & TEM_BUMP_MASK; } U8 getFullbright() const { return (mBump>>TEM_FULLBRIGHT_SHIFT) & TEM_FULLBRIGHT_MASK; } + eRenderableTarget getRenderableTarget() const { return mRenderableTarget; } U8 getShiny() const { return (mBump>>TEM_SHINY_SHIFT) & TEM_SHINY_MASK; } U8 getBumpShiny() const { return mBump & TEM_BUMP_SHINY_MASK; } U8 getBumpShinyFullbright() const { return mBump; } @@ -233,6 +242,7 @@ protected: LLColor4 mColor; U8 mBump; // Bump map, shiny, and fullbright U8 mMediaFlags; // replace with web page, movie, etc. + eRenderableTarget mRenderableTarget; F32 mGlow; bool mMaterialUpdatePending; LLMaterialID mMaterialID; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index ccfb8f69be..be5ad08fbe 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1184,12 +1184,14 @@ S32 LLGLSLShader::getTextureChannel(S32 uniform) const S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; - + if (uniform < 0 || uniform >= (S32)mTexture.size()) { LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL; return -1; } + + S32 index = mTexture[uniform]; if (index != -1) { diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index b8071248e2..71b9b0f4fb 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -57,6 +57,7 @@ public: bool hasAlphaMask = false; bool hasReflectionProbes = false; bool attachNothing = false; + bool hasHeroProbes = false; }; // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 75d6ef6c46..177cad2508 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -238,6 +238,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } + + if (features->hasHeroProbes) + { + if (!shader->attachFragmentObject("deferred/heroProbesUtil.glsl")) + { + return FALSE; + } + } if (features->hasShadows) { @@ -1260,6 +1268,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("sceneDepth"); mReservedUniforms.push_back("reflectionProbes"); mReservedUniforms.push_back("irradianceProbes"); + mReservedUniforms.push_back("heroProbes"); mReservedUniforms.push_back("cloud_noise_texture"); mReservedUniforms.push_back("cloud_noise_texture_next"); mReservedUniforms.push_back("fullbright"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 46f352aa58..cfa824c361 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -96,6 +96,7 @@ public: SCENE_DEPTH, // "sceneDepth" REFLECTION_PROBES, // "reflectionProbes" IRRADIANCE_PROBES, // "irradianceProbes" + HERO_PROBE, // "heroProbes" CLOUD_NOISE_MAP, // "cloud_noise_texture" CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next" FULLBRIGHT, // "fullbright" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2b2a2d9d1b..270d5e6869 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9175,6 +9175,17 @@ 0.00 + RenderMirrors + + Comment + Renders realtime mirrors. + Persist + 1 + Type + Boolean + Value + 1 + RenderScreenSpaceReflections Comment diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 1b2a34ef01..298ddf92a7 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -31,6 +31,7 @@ float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, uniform samplerCubeArray reflectionProbes; uniform samplerCubeArray irradianceProbes; + uniform sampler2D sceneMap; uniform int cube_snapshot; uniform float max_probe_lod; @@ -70,6 +71,9 @@ layout (std140) uniform ReflectionProbes // number of reflection probes present in refSphere int refmapCount; + + vec4 heroPosition[1]; + int heroProbeCount; }; // Inputs @@ -513,6 +517,10 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, v = env_mat * v; +#if defined(HERO_PROBES) + vec3 mirror = textureLod(heroProbes, vec4(v.xyz, 0), lod).rgb; +#endif + vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y; return ret.rgb; diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 4ef003e0cb..a63d445115 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -32,6 +32,14 @@ uniform sampler2D specularRect; uniform sampler2D normalMap; uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl +uniform samplerCubeArray heroProbes; + +layout (std140) uniform HeroProbeData +{ + vec4 heroPosition[1]; + int heroProbeCount; +}; + const float M_PI = 3.14159265; #if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) @@ -290,7 +298,7 @@ void main() vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); color = fogged.rgb; #endif - - frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results + frag_color.rgb = textureLod(heroProbes, vec4(norm.xyz, 0), 0).rgb; + //frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results frag_color.a = 0.0; } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7d6015f557..6b737b6895 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -592,6 +592,17 @@ void LLPanelFace::sendFullbright() LLSelectMgr::getInstance()->selectionSetFullbright( fullbright ); } +void LLPanelFace::sendMirror() +{ + LLCheckBoxCtrl* mCheckMirror = getChild("checkbox mirror"); + + if (!mCheckMirror) + return; + + LLTextureEntry::eRenderableTarget target = mCheckMirror->get() ? LLTextureEntry::RT_MIRROR : LLTextureEntry::RT_DISABLED; + LLSelectMgr::getInstance()->selectionSetRenderableTarget(target); +} + void LLPanelFace::sendColor() { @@ -1686,6 +1697,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild("shinyOffsetV")->setValue(offset_y); getChild("glossiness")->setValue(material->getSpecularLightExponent()); getChild("environment")->setValue(material->getEnvironmentIntensity()); + getChild("mirror")->setValue(material->getEnvironmentIntensity()); updateShinyControls(!material->getSpecularID().isNull(), true); } @@ -2994,6 +3006,12 @@ void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata) self->sendFullbright(); } +void LLPanelFace::onCommitMirror(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + self->sendMirror(); +} + // static void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata) { diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 106259b84a..f6d6d99d9f 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -138,6 +138,7 @@ protected: void sendTexGen(); // applies and sends bump map void sendShiny(U32 shininess); // applies and sends shininess void sendFullbright(); // applies and sends full bright + void sendMirror(); void sendGlow(); void alignTestureLayer(); @@ -227,7 +228,8 @@ protected: static void onCommitShiny( LLUICtrl* ctrl, void* userdata); static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitGlow( LLUICtrl* ctrl, void *userdata); + static void onCommitMirror(LLUICtrl* ctrl, void* userdata); + static void onCommitGlow( LLUICtrl* ctrl, void *userdata); static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 7ea0fe6187..831a6358ee 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -36,6 +36,15 @@ class alignas(16) LLReflectionMap : public LLRefCount { LL_ALIGN_NEW public: + + enum class ProbeType + { + ALL = 0, + RADIANCE, + IRRADIANCE, + REFLECTION + }; + // allocate an environment map of the given resolution LLReflectionMap(); @@ -127,5 +136,7 @@ public: GLuint mOcclusionQuery = 0; bool mOccluded = false; U32 mOcclusionPendingFrames = 0; + + ProbeType mType; }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e30aba3df7..8e7d073167 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -130,6 +130,13 @@ void LLReflectionMapManager::update() U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } + + if (!mHeroRenderTarget.isComplete()) + { + U32 color_fmt = GL_RGB16F; + U32 targetRes = mHeroProbeResolution * 2; + mHeroRenderTarget.allocate(targetRes, targetRes, color_fmt, true); + } if (mMipChain.empty()) { @@ -315,7 +322,7 @@ void LLReflectionMapManager::update() mRadiancePass = mRealtimeRadiancePass; for (U32 i = 0; i < 6; ++i) { - updateProbeFace(closestDynamic, i); + updateProbeFace(closestDynamic, i, mProbeResolution); } mRealtimeRadiancePass = !mRealtimeRadiancePass; @@ -354,6 +361,10 @@ void LLReflectionMapManager::update() oldestOccluded->autoAdjustOrigin(); oldestOccluded->mLastUpdateTime = gFrameTimeSeconds; } + + + doHeroProbeUpdate(); + } LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) @@ -528,7 +539,7 @@ void LLReflectionMapManager::doProbeUpdate() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(mUpdatingProbe != nullptr); - updateProbeFace(mUpdatingProbe, mUpdatingFace); + updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution); if (++mUpdatingFace == 6) { @@ -547,6 +558,21 @@ void LLReflectionMapManager::doProbeUpdate() } } +void LLReflectionMapManager::doHeroProbeUpdate() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(mHeroProbe != nullptr); + + touch_default_probe(mHeroProbe); + + for (int i = 0; i < 6; i++) + { + gPipeline.mRT = &gPipeline.mAuxillaryRT; + mHeroProbe->update(mHeroProbeResolution, i); + gPipeline.mRT = &gPipeline.mMainRT; + } +} + // Do the reflection map update render passes. // For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated // First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate @@ -555,10 +581,20 @@ void LLReflectionMapManager::doProbeUpdate() // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. // At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. // In effect this simulates single-bounce lighting. -void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) +void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; + + LLRenderTarget* target = &mRenderTarget; + + S32 sourceIdx = mReflectionProbeCount; + + if (probeResolution == mHeroProbeResolution) + { + sourceIdx = 0; + target = &mHeroRenderTarget; + } mLightScale = 1.f; static LLCachedControl max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f); @@ -577,20 +613,18 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, 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); + probe->update(target->getWidth(), face); gPipeline.popRenderTypeMask(); } else { - probe->update(mRenderTarget.getWidth(), face); + probe->update(target->getWidth(), face); } gPipeline.mRT = &gPipeline.mMainRT; - S32 sourceIdx = mReflectionProbeCount; - - if (probe != mUpdatingProbe) + if (probe != mUpdatingProbe && probe->mType != LLReflectionMap::ProbeType::REFLECTION) { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel sourceIdx += 1; } @@ -611,7 +645,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.loadIdentity(); gGL.flush(); - U32 res = mProbeResolution * 2; + U32 res = probeResolution * 2; static LLStaticHashedString resScale("resScale"); static LLStaticHashedString direction("direction"); @@ -623,20 +657,20 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) // perform a gaussian blur on the super sampled render before downsampling { gGaussianProgram.bind(); - gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2)); + gGaussianProgram.uniform1f(resScale, 1.f / (probeResolution * 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(); + target->bindTarget(); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - mRenderTarget.flush(); + target->flush(); // vertical gGaussianProgram.uniform2f(direction, 0.f, 1.f); - gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget); + gGL.getTexUnit(diffuseChannel)->bind(target); screen_rt->bindTarget(); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -644,7 +678,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } - S32 mips = log2((F32)mProbeResolution) + 0.5f; + S32 mips = log2((F32)probeResolution) + 0.5f; gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); @@ -663,7 +697,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } - gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); + gReflectionMipProgram.uniform1f(resScale, 1.f/(probeResolution*2)); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -675,14 +709,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (mip >= 0) { LL_PROFILE_GPU_ZONE("probe mip copy"); - mTexture->bind(0); + probe->mCubeArray->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); //if (i == 0) //{ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); //} - mTexture->unbind(); + probe->mCubeArray->unbind(); } mMipChain[i].flush(); } @@ -695,7 +729,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gReflectionMipProgram.unbind(); } - if (face == 5) + if (face == 5 && probe->mType != LLReflectionMap::ProbeType::REFLECTION) { mMipChain[0].bindTarget(); static LLStaticHashedString sSourceIdx("sourceIdx"); @@ -707,7 +741,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mVertexBuffer->setBuffer(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - mTexture->bind(channel); + probe->mCubeArray->bind(channel); gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -722,7 +756,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, i); - gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); + gRadianceGenProgram.uniform1i(sWidth, probeResolution); for (int cf = 0; cf < 6; ++cf) { // for each cube face @@ -752,7 +786,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) //generate irradiance map gIrradianceGenProgram.bind(); S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - mTexture->bind(channel); + probe->mCubeArray->bind(channel); gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -787,7 +821,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 res = mMipChain[i].getWidth(); mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - mTexture->bind(channel); + probe->mCubeArray->bind(channel); } } } @@ -890,7 +924,7 @@ void LLReflectionMapManager::updateUniforms() GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth // numbrer of active refmaps - GLint refmapCount; + GLint refmapCount; }; mReflectionMaps.resize(mReflectionProbeCount); @@ -1068,7 +1102,7 @@ void LLReflectionMapManager::updateUniforms() #endif rpd.refmapCount = count; - + //copy rpd into uniform buffer object if (mUBO == 0) { @@ -1081,7 +1115,35 @@ void LLReflectionMapManager::updateUniforms() glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } + + struct HeroProbeData + { + LLVector4 heroPosition[1]; + GLint heroProbeCount = 1; + }; + + HeroProbeData hpd; + + modelview.loadu(gGLModelView); + + oa.set(0, 0, 0, 0); + hpd.heroProbeCount = 1; + modelview.affineTransform(mHeroProbe->mOrigin, oa); + hpd.heroPosition[0].set(oa.getF32ptr()); + + //copy rpd into uniform buffer object + if (mUBO == 0) + { + glGenBuffers(1, &mHeroUBO); + } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); + glBindBuffer(GL_UNIFORM_BUFFER, mHeroUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } + #if 0 if (!gCubeSnapshot) { @@ -1214,7 +1276,7 @@ void LLReflectionMapManager::initReflectionMaps() { U32 count = LL_MAX_REFLECTION_PROBE_COUNT; - if (mTexture.isNull() || mReflectionProbeCount != count || mReset) + if (mTexture.isNull() || mReflectionProbeCount != count || mReset || mHeroArray.isNull()) { mReset = false; mReflectionProbeCount = count; @@ -1263,6 +1325,22 @@ void LLReflectionMapManager::initReflectionMaps() mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); + + mHeroProbeResolution = 512; + + mHeroArray = new LLCubeMapArray(); + mHeroArray->allocate(mHeroProbeResolution, 3, 1); + + if (mHeroProbe.isNull()) { + mHeroProbe = new LLReflectionMap(); + } + + mHeroProbe->mCubeIndex = 0; + mHeroProbe->mCubeArray = mHeroArray; + mHeroProbe->mDistance = 64.f; + mHeroProbe->mRadius = 4096.f; + mHeroProbe->mProbeIndex = 0; + touch_default_probe(mHeroProbe); } @@ -1291,11 +1369,13 @@ void LLReflectionMapManager::cleanup() { mVertexBuffer = nullptr; mRenderTarget.release(); + mHeroRenderTarget.release(); mMipChain.clear(); mTexture = nullptr; mIrradianceMaps = nullptr; + mHeroArray = nullptr; mProbes.clear(); mKillList.clear(); @@ -1306,9 +1386,14 @@ void LLReflectionMapManager::cleanup() mDefaultProbe = nullptr; mUpdatingProbe = nullptr; + + mHeroProbe = nullptr; glDeleteBuffers(1, &mUBO); mUBO = 0; + + glDeleteBuffers(1, &mHeroUBO); + mHeroUBO = 0; // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state initCubeFree(); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 5a3901cae9..2ca9a8d598 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -125,11 +125,15 @@ private: // render target for cube snapshots // used to generate mipmaps without doing a copy-to-texture LLRenderTarget mRenderTarget; + + LLRenderTarget mHeroRenderTarget; std::vector mMipChain; // storage for reflection probe radiance maps (plus two scratch space cubemaps) LLPointer mTexture; + + LLPointer mHeroArray; // vertex buffer for pushing verts to filter shaders LLPointer mVertexBuffer; @@ -142,9 +146,11 @@ private: // perform an update on the currently updating Probe void doProbeUpdate(); + + void doHeroProbeUpdate(); // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face); + void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution); // list of active reflection maps std::vector > mProbes; @@ -157,6 +163,9 @@ private: // handle to UBO U32 mUBO = 0; + + // Hero UBO + U32 mHeroUBO = 0; // list of maps being used for rendering std::vector mReflectionMaps; @@ -176,12 +185,16 @@ private: bool mRealtimeRadiancePass = false; LLPointer mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0) + + LLPointer mHeroProbe; // number of reflection probes to use for rendering U32 mReflectionProbeCount; // resolution of reflection probes U32 mProbeResolution = 128; + + U32 mHeroProbeResolution = 512; // maximum LoD of reflection probes (mip levels - 1) F32 mMaxProbeLOD = 6.f; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index dca341e5a2..19ce8f6a55 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2347,6 +2347,47 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright) getSelection()->applyToObjects(&sendfunc); } +void LLSelectMgr::selectionSetRenderableTarget(LLTextureEntry::eRenderableTarget target) +{ + struct f : public LLSelectedTEFunctor + { + LLTextureEntry::eRenderableTarget mRenderableTarget; + + f(const LLTextureEntry::eRenderableTarget& t) : mRenderableTarget(t) {} + + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + object->setTERenderableTarget(te, mRenderableTarget); + } + + return true; + } + } setfunc(target); + + getSelection()->applyToTEs(&setfunc); + + struct g : public LLSelectedObjectFunctor + { + LLTextureEntry::eRenderableTarget mRenderableTarget; + + g(const LLTextureEntry::eRenderableTarget& t) : mRenderableTarget(t) {} + + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + + return true; + } + } sendfunc(target); + + getSelection()->applyToObjects(&sendfunc); +} + // This function expects media_data to be a map containing relevant // media data name/value pairs (e.g. home_url, etc.) void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index ca9a32f0db..93d750215b 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -653,6 +653,7 @@ public: void selectionSetGlow(const F32 glow); void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1); void selectionRemoveMaterial(); + void selectionSetRenderableTarget(LLTextureEntry::eRenderableTarget target); void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); void selectionSetObjectName(const std::string& name); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e67750af7c..8930b2453b 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5284,6 +5284,28 @@ S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright) return retval; } +S32 LLViewerObject::setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target) +{ + S32 retval = 0; + + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (target != tep->getRenderableTarget()) + { + retval = LLPrimitive::setTERenderableTarget(te, target); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + //gPipeline.markMirror(mDrawable); + } + } + + return retval; +} + S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bf82c43cd3..f4f596bfd0 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -359,6 +359,7 @@ public: /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny ); /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright ); + /*virtual*/ S32 setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target); /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags ); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5eae1dfb18..f6f1cf6854 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -2228,6 +2228,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredSoftenProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); } + + gDeferredSoftenProgram.addPermutation("HERO_PROBES", "1"); if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { //if using SSAO, take screen space light map into account as if shadows are enabled diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8160785d75..8eacdd2162 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2344,6 +2344,16 @@ S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright) return res; } +S32 LLVOVolume::setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget mirror) +{ + S32 res = LLViewerObject::setTERenderableTarget(te, mirror); + if (res) + { + //gPipeline.markMirror(mDrawable); + } + return res; +} + S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) { S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index acba18383f..f2162ef244 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -209,6 +209,7 @@ public: /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override; /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override; /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override; + /*virtual*/ S32 setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target) override; /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override; /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override; /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38f27d4dfa..d6e0bf1b09 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8419,6 +8419,13 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) mReflectionMapManager.mIrradianceMaps->bind(channel); bound = true; } + + channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); + if (channel > -1 && mReflectionMapManager.mHeroArray.notNull()) + { + mReflectionMapManager.mHeroArray->bind(channel); + bound = true; + } if (bound) { -- cgit v1.2.3 From 5ade456ee796aeb779302016b9ee9d418c728a22 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 28 Jun 2023 13:27:15 -0400 Subject: Make sure we're passing the cube array as a parameter to updateProbeFace. DRTVWR-583 --- indra/newview/llreflectionmapmanager.cpp | 36 ++++++++++++++++++++++++-------- indra/newview/llreflectionmapmanager.h | 2 +- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8e7d073167..783ff69073 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -322,7 +322,7 @@ void LLReflectionMapManager::update() mRadiancePass = mRealtimeRadiancePass; for (U32 i = 0; i < 6; ++i) { - updateProbeFace(closestDynamic, i, mProbeResolution); + updateProbeFace(closestDynamic, i, mProbeResolution, mTexture); } mRealtimeRadiancePass = !mRealtimeRadiancePass; @@ -362,8 +362,26 @@ void LLReflectionMapManager::update() oldestOccluded->mLastUpdateTime = gFrameTimeSeconds; } - - doHeroProbeUpdate(); + if (mHeroProbe != nullptr) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); + // update the closest dynamic probe realtime + // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames + mHeroProbe->autoAdjustOrigin(); + + // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set + // lighting values etc + bool radiance_pass = isRadiancePass(); + mRadiancePass = mRealtimeRadiancePass; + for (U32 i = 0; i < 6; ++i) + { + updateProbeFace(mHeroProbe, i, mProbeResolution, mHeroArray); + } + mRealtimeRadiancePass = !mRealtimeRadiancePass; + + // restore "isRadiancePass" + mRadiancePass = radiance_pass; + } } @@ -539,7 +557,7 @@ void LLReflectionMapManager::doProbeUpdate() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(mUpdatingProbe != nullptr); - updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution); + updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution, mTexture); if (++mUpdatingFace == 6) { @@ -709,14 +727,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U if (mip >= 0) { LL_PROFILE_GPU_ZONE("probe mip copy"); - probe->mCubeArray->bind(0); + cubeArray->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); //if (i == 0) //{ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); //} - probe->mCubeArray->unbind(); + cubeArray->unbind(); } mMipChain[i].flush(); } @@ -741,7 +759,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U mVertexBuffer->setBuffer(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - probe->mCubeArray->bind(channel); + cubeArray->bind(channel); gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -786,7 +804,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U //generate irradiance map gIrradianceGenProgram.bind(); S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - probe->mCubeArray->bind(channel); + cubeArray->bind(channel); gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -821,7 +839,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U S32 res = mMipChain[i].getWidth(); mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - probe->mCubeArray->bind(channel); + cubeArray->bind(channel); } } } diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 2ca9a8d598..1275617e0a 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -150,7 +150,7 @@ private: void doHeroProbeUpdate(); // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution); + void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray); // list of active reflection maps std::vector > mProbes; -- cgit v1.2.3 From 53b2efd13143f85c447320fa35d192df466b16ca Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 29 Jun 2023 17:35:24 -0400 Subject: Remove doHeroProbeUpdate DRTVWR-583 --- indra/newview/llreflectionmapmanager.cpp | 60 ++++++++++++-------------------- indra/newview/llreflectionmapmanager.h | 2 -- 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 783ff69073..fe3ea15352 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -329,6 +329,28 @@ void LLReflectionMapManager::update() // restore "isRadiancePass" mRadiancePass = radiance_pass; } + + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); + // update the closest dynamic probe realtime + // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames + mHeroProbe->autoAdjustOrigin(); + + // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set + // lighting values etc + bool radiance_pass = isRadiancePass(); + mRadiancePass = mRealtimeRadiancePass; + for (U32 i = 0; i < 6; ++i) + { + updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray); + } + + mRealtimeRadiancePass = !mRealtimeRadiancePass; + + // restore "isRadiancePass" + mRadiancePass = radiance_pass; + } static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) @@ -361,28 +383,6 @@ void LLReflectionMapManager::update() oldestOccluded->autoAdjustOrigin(); oldestOccluded->mLastUpdateTime = gFrameTimeSeconds; } - - if (mHeroProbe != nullptr) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - // update the closest dynamic probe realtime - // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames - mHeroProbe->autoAdjustOrigin(); - - // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set - // lighting values etc - bool radiance_pass = isRadiancePass(); - mRadiancePass = mRealtimeRadiancePass; - for (U32 i = 0; i < 6; ++i) - { - updateProbeFace(mHeroProbe, i, mProbeResolution, mHeroArray); - } - mRealtimeRadiancePass = !mRealtimeRadiancePass; - - // restore "isRadiancePass" - mRadiancePass = radiance_pass; - } - } LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) @@ -576,21 +576,6 @@ void LLReflectionMapManager::doProbeUpdate() } } -void LLReflectionMapManager::doHeroProbeUpdate() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - llassert(mHeroProbe != nullptr); - - touch_default_probe(mHeroProbe); - - for (int i = 0; i < 6; i++) - { - gPipeline.mRT = &gPipeline.mAuxillaryRT; - mHeroProbe->update(mHeroProbeResolution, i); - gPipeline.mRT = &gPipeline.mMainRT; - } -} - // Do the reflection map update render passes. // For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated // First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate @@ -1190,6 +1175,7 @@ void LLReflectionMapManager::setUniforms() updateUniforms(); } glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); + glBindBufferBase(GL_UNIFORM_BUFFER, 1, mHeroUBO); } diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 1275617e0a..81b0ef8ed8 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -146,8 +146,6 @@ private: // perform an update on the currently updating Probe void doProbeUpdate(); - - void doHeroProbeUpdate(); // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray); -- cgit v1.2.3 From f7f9601567ce089f3335407f1d3c7d32dbb18c60 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 17 Jul 2023 15:05:47 -0700 Subject: Got hero probes rendering from the camera. DRTVWR-583 --- indra/llplugin/llpluginprocessparent.cpp | 2 +- .../shaders/class3/deferred/softenLightF.glsl | 9 ++++---- indra/newview/llreflectionmapmanager.cpp | 26 ++++++++-------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 756d0b5db8..f5966b71de 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -582,7 +582,7 @@ void LLPluginProcessParent::idle(void) params.args.add("-e"); params.args.add("tell application \"Terminal\""); params.args.add("-e"); - params.args.add(STRINGIZE("set win to do script \"gdb -pid " + params.args.add(STRINGIZE("set win to do script \"lldb -pid " << mProcess->getProcessID() << "\"")); params.args.add("-e"); params.args.add("do script \"continue\" in win"); diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index a63d445115..d8118fab82 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -117,8 +117,8 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 additive, vec3 atten); -vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, - float perceptualRoughness, +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, float metallic, vec3 n, // normal vec3 v, // surface point to camera @@ -193,7 +193,7 @@ void main() if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { - vec3 orm = texture(specularRect, tc).rgb; + vec3 orm = texture(specularRect, tc).rgb; float perceptualRoughness = orm.g; float metallic = orm.b; float ao = orm.r; @@ -298,7 +298,6 @@ void main() vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); color = fogged.rgb; #endif - frag_color.rgb = textureLod(heroProbes, vec4(norm.xyz, 0), 0).rgb; - //frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results + frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results frag_color.a = 0.0; } diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index fe3ea15352..45489fb35b 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -333,20 +333,14 @@ void LLReflectionMapManager::update() { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - // update the closest dynamic probe realtime - // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames - mHeroProbe->autoAdjustOrigin(); - - // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set - // lighting values etc + + mHeroProbe->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); bool radiance_pass = isRadiancePass(); - mRadiancePass = mRealtimeRadiancePass; + mRadiancePass = true; for (U32 i = 0; i < 6; ++i) { updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray); } - - mRealtimeRadiancePass = !mRealtimeRadiancePass; // restore "isRadiancePass" mRadiancePass = radiance_pass; @@ -713,12 +707,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U { LL_PROFILE_GPU_ZONE("probe mip copy"); cubeArray->bind(0); - //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); - //if (i == 0) - //{ - //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); - //} + cubeArray->unbind(); } mMipChain[i].flush(); @@ -732,7 +723,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U gReflectionMipProgram.unbind(); } - if (face == 5 && probe->mType != LLReflectionMap::ProbeType::REFLECTION) + if (face == 5) { mMipChain[0].bindTarget(); static LLStaticHashedString sSourceIdx("sourceIdx"); @@ -1330,10 +1321,11 @@ void LLReflectionMapManager::initReflectionMaps() mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); - mHeroProbeResolution = 512; + mHeroProbeResolution = 128; mHeroArray = new LLCubeMapArray(); - mHeroArray->allocate(mHeroProbeResolution, 3, 1); + // Revise when we have both water and mirrors in hero probes. + mHeroArray->allocate(mHeroProbeResolution, 3, 2, true); if (mHeroProbe.isNull()) { mHeroProbe = new LLReflectionMap(); -- cgit v1.2.3 From 3d73326516c73f880f46e28f14b6c515307ede91 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 18 Jul 2023 00:14:34 -0700 Subject: Fix for irradiance breaking. Still need to fix the problem with individual faces getting tossed around though. Will work on that tomorrow. DRTVWR-583 --- indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl | 3 +-- indra/newview/llpanelface.cpp | 2 +- indra/newview/llreflectionmapmanager.cpp | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index d8118fab82..0152c0612a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -217,6 +217,7 @@ void main() { color = atmosFragLightingLinear(color, additive, atten); } + color = texture(heroProbes, vec4(norm.xyz * env_mat, 0), 0).xyz; } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { @@ -291,9 +292,7 @@ void main() color = atmosFragLightingLinear(color, additive, atten); } } - - #ifdef WATER_FOG vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); color = fogged.rgb; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 721b1482d9..9140888cc1 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1035,7 +1035,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mComboMatMedia->setEnabled(editable); LLRadioGroup* radio_mat_type = getChild("radio_material_type"); - + if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE) { radio_mat_type->selectNthItem(MATTYPE_DIFFUSE); diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 6550686a32..99ebcf5231 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1171,7 +1171,6 @@ void LLReflectionMapManager::setUniforms() updateUniforms(); } glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); - glBindBufferBase(GL_UNIFORM_BUFFER, 1, mHeroUBO); } -- cgit v1.2.3 From b861832102abf469963bd3c56f7b009ba4432d6a Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sun, 6 Aug 2023 23:33:29 -0700 Subject: Making more progress, need to add the heroprobe manager. DRTVWR-583 --- indra/llprimitive/lltextureentry.cpp | 8 ------ .../shaders/class3/deferred/softenLightF.glsl | 4 ++- indra/newview/lldrawable.h | 1 + indra/newview/llreflectionmapmanager.cpp | 20 +++++++++------ indra/newview/llreflectionmapmanager.h | 4 ++- indra/newview/llviewerobject.h | 1 + indra/newview/llvovolume.cpp | 30 +++++++++++++++++++++- indra/newview/llvovolume.h | 2 ++ indra/newview/pipeline.cpp | 22 ++++++++++++++++ indra/newview/pipeline.h | 5 ++++ 10 files changed, 78 insertions(+), 19 deletions(-) diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index d057e5ab29..fdf3774bfa 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -696,14 +696,6 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams) } mMaterial = pMaterialParams; - // TODO: GZ: We should avoid magic UUIDs in the future, but for development we're using one for the time being. Remove this later. - if (mMaterial->getSpecularID().asString() == "da7ecda1-e780-423f-ce27-26df7dc69cb6") - { - setRenderableTarget(RT_MIRROR); - } else { - setRenderableTarget(RT_DISABLED); - } - return TEM_CHANGE_TEXTURE; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 0152c0612a..e485c26e9b 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -217,7 +217,9 @@ void main() { color = atmosFragLightingLinear(color, additive, atten); } - color = texture(heroProbes, vec4(norm.xyz * env_mat, 0), 0).xyz; + + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + color = texture(heroProbes, vec4(env_mat * refnormpersp, 0), 0).xyz; } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 970e8c8b2a..fc182fc2e2 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -286,6 +286,7 @@ public: ANIMATED_CHILD = 0x01000000, ACTIVE_CHILD = 0x02000000, FOR_UNLOAD = 0x04000000, //should be unload from memory + MIRROR = 0x08000000, // Used as a mirror, needs a hero probe position to be calculated. } EDrawableFlags; public: diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 99ebcf5231..ad4d3d94e2 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -140,7 +140,7 @@ void LLReflectionMapManager::update() if (mMipChain.empty()) { - U32 res = mProbeResolution; + U32 res = mHeroProbeResolution; U32 count = log2((F32)res) + 0.5f; mMipChain.resize(count); @@ -326,7 +326,7 @@ void LLReflectionMapManager::update() mRadiancePass = mRealtimeRadiancePass; for (U32 i = 0; i < 6; ++i) { - updateProbeFace(closestDynamic, i, mProbeResolution, mTexture); + updateProbeFace(closestDynamic, i, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); } mRealtimeRadiancePass = !mRealtimeRadiancePass; @@ -343,7 +343,7 @@ void LLReflectionMapManager::update() mRadiancePass = true; for (U32 i = 0; i < 6; ++i) { - updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray); + updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray, mMipChain, mHeroProbeCount); } // restore "isRadiancePass" @@ -555,7 +555,7 @@ void LLReflectionMapManager::doProbeUpdate() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(mUpdatingProbe != nullptr); - updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution, mTexture); + updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); if (++mUpdatingFace == 6) { @@ -582,14 +582,14 @@ void LLReflectionMapManager::doProbeUpdate() // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. // At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. // In effect this simulates single-bounce lighting. -void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray) +void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; LLRenderTarget* target = &mRenderTarget; - S32 sourceIdx = mReflectionProbeCount; + S32 sourceIdx = probeCount; if (probeResolution == mHeroProbeResolution) { @@ -1327,9 +1327,13 @@ void LLReflectionMapManager::initReflectionMaps() mHeroProbeResolution = 128; - mHeroArray = new LLCubeMapArray(); // Revise when we have both water and mirrors in hero probes. - mHeroArray->allocate(mHeroProbeResolution, 3, 2, true); + mHeroProbeCount = 1; + + mHeroArray = new LLCubeMapArray(); + + // We use an extra probe for scratch space on these. + mHeroArray->allocate(mHeroProbeResolution, 3, mHeroProbeCount + 1, true); if (mHeroProbe.isNull()) { mHeroProbe = new LLReflectionMap(); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 81b0ef8ed8..9f48ce3cfd 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -148,7 +148,7 @@ private: void doProbeUpdate(); // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray); + void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount); // list of active reflection maps std::vector > mProbes; @@ -188,6 +188,8 @@ private: // number of reflection probes to use for rendering U32 mReflectionProbeCount; + + U32 mHeroProbeCount; // resolution of reflection probes U32 mProbeResolution = 128; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 4d49c61b23..fe33047218 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -257,6 +257,7 @@ public: virtual BOOL isRiggedMesh() const { return FALSE; } virtual BOOL hasLightTexture() const { return FALSE; } virtual BOOL isReflectionProbe() const { return FALSE; } + virtual BOOL isMirror() const { return FALSE; } // This method returns true if the object is over land owned by // the agent, one of its groups, or it encroaches and diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 556ec083a7..254e945243 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1044,7 +1044,9 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) { updateReflectionProbePtr(); } - + + gPipeline.setMirror(mDrawable, isMirror()); + updateRadius(); bool force_update = true; // avoid non-alpha mDistance update being optimized away mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); @@ -3377,6 +3379,30 @@ F32 LLVOVolume::getLightCutoff() const } } +BOOL LLVOVolume::isMirror() const +{ + S32 faceCount = getNumFaces(); + + // Temporary hack to set the object to mirror. + for (int i = 0; i < faceCount; i++) + { + const LLTextureEntry* te = getTE(i); + + if (te->getMaterialParams().notNull()) + { + LLViewerTexture* specularp = getTESpecularMap(0); + + if (specularp && specularp->getID() == "da7ecda1-e780-423f-ce27-26df7dc69cb6") + { + LL_INFOS() << "BELLADONNA OF SADNESS" << LL_ENDL; + return TRUE; + } + } + } + + return FALSE; +} + BOOL LLVOVolume::isReflectionProbe() const { return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -4427,6 +4453,8 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u } updateReflectionProbePtr(); + + gPipeline.setMirror(mDrawable, isMirror()); } void LLVOVolume::updateReflectionProbePtr() diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 93aba9b8cb..cecf726763 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -308,6 +308,8 @@ public: F32 getReflectionProbeNearClip() const; bool getReflectionProbeIsBox() const; bool getReflectionProbeIsDynamic() const; + + BOOL isMirror() const override; // Flexible Objects U32 getVolumeInterfaceID() const; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d7188c0fe7..e742992c1d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2761,6 +2761,23 @@ void LLPipeline::markShift(LLDrawable *drawablep) } } +void LLPipeline::setMirror(LLDrawable *drawablep, bool is_mirror) +{ + if (drawablep && assertInitialized()) + { + if (is_mirror) + { + drawablep->setState(LLDrawable::MIRROR); + mMirrorList.insert(drawablep); + } + else + { + mMirrorList.erase(drawablep); + drawablep->clearState(LLDrawable::MIRROR); + } + } +} + void LLPipeline::shiftObjects(const LLVector3 &offset) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -5812,6 +5829,11 @@ void LLPipeline::findReferences(LLDrawable *drawablep) { LL_INFOS() << "In mRetexturedList" << LL_ENDL; } + + if (std::find(mMirrorList.begin(), mMirrorList.end(), drawablep) != mMirrorList.end()) + { + LL_INFOS() << "In mMirrorList" << LL_ENDL; + } if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c0559ce83b..f3b35e0325 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -357,6 +357,7 @@ public: void shiftObjects(const LLVector3 &offset); void setLight(LLDrawable *drawablep, bool is_light); + void setMirror(LLDrawable *drawablep, bool is_mirror); bool hasRenderBatches(const U32 type) const; LLCullResult::drawinfo_iterator beginRenderMap(U32 type); @@ -818,6 +819,10 @@ protected: LLDrawable::ordered_drawable_set_t mLights; light_set_t mNearbyLights; // lights near camera LLColor4 mHWLightColors[8]; + + + LLDrawable::ordered_drawable_set_t mMirrorList; + LLDrawable* mNearestMirror; ///////////////////////////////////////////// // -- cgit v1.2.3 From 423820475c7201c39d03c0622dedbf4b1e8b1879 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 7 Aug 2023 00:17:04 -0700 Subject: Revert LLReflectionMapManager DRTVWR-583 --- indra/newview/CMakeLists.txt | 2 + indra/newview/llheroprobemanager.cpp | 1333 ++++++++++++++++++++++++++++++ indra/newview/llheroprobemanager.h | 208 +++++ indra/newview/llreflectionmapmanager.cpp | 168 +--- indra/newview/llreflectionmapmanager.h | 25 +- indra/newview/pipeline.cpp | 3 +- 6 files changed, 1594 insertions(+), 145 deletions(-) create mode 100644 indra/newview/llheroprobemanager.cpp create mode 100644 indra/newview/llheroprobemanager.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c6d82ea260..7a57fe8fef 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -515,6 +515,7 @@ set(viewer_SOURCE_FILES llrecentpeople.cpp llreflectionmap.cpp llreflectionmapmanager.cpp + llheroprobemanager.cpp llregioninfomodel.cpp llregionposition.cpp llremoteparcelrequest.cpp @@ -1149,6 +1150,7 @@ set(viewer_HEADER_FILES llrecentpeople.h llreflectionmap.h llreflectionmapmanager.h + llheroprobemanager.h llregioninfomodel.h llregionposition.h llremoteparcelrequest.h diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp new file mode 100644 index 0000000000..54a61d000e --- /dev/null +++ b/indra/newview/llheroprobemanager.cpp @@ -0,0 +1,1333 @@ +/** + * @file LLHeroProbeManager.cpp + * @brief LLHeroProbeManager class implementation + * + * $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 "llheroprobemanager.h" +#include "llreflectionmapmanager.h" +#include "llviewercamera.h" +#include "llspatialpartition.h" +#include "llviewerregion.h" +#include "pipeline.h" +#include "llviewershadermgr.h" +#include "llviewercontrol.h" +#include "llenvironment.h" +#include "llstartup.h" + +extern BOOL gCubeSnapshot; +extern BOOL gTeleportDisplay; + +// get the next highest power of two of v (or v if v is already a power of two) +//defined in llvertexbuffer.cpp +extern U32 nhpo2(U32 v); + +static void touch_default_probe(LLReflectionMap* probe) +{ + if (LLViewerCamera::getInstance()) + { + LLVector3 origin = LLViewerCamera::getInstance()->getOrigin(); + origin.mV[2] += 64.f; + + probe->mOrigin.load3(origin.mV); + } +} + +LLHeroProbeManager::LLHeroProbeManager() +{ + initCubeFree(); +} + +void LLHeroProbeManager::initCubeFree() +{ + // start at 1 because index 0 is reserved for mDefaultProbe + for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) + { + mCubeFree.push_back(i); + } +} + +struct CompareProbeDistance +{ + LLReflectionMap* mDefaultProbe; + + bool operator()(const LLPointer& lhs, const LLPointer& rhs) + { + return lhs->mDistance < rhs->mDistance; + } +}; + +static F32 update_score(LLReflectionMap* p) +{ + return gFrameTimeSeconds - p->mLastUpdateTime - p->mDistance*0.1f; +} + +// return true if a is higher priority for an update than b +static bool check_priority(LLReflectionMap* a, LLReflectionMap* b) +{ + if (a->mCubeIndex == -1) + { // not a candidate for updating + return false; + } + else if (b->mCubeIndex == -1) + { // certainly higher priority than b + return true; + } + else if (!a->mComplete && !b->mComplete) + { //neither probe is complete, use distance + return a->mDistance < b->mDistance; + } + else if (a->mComplete && b->mComplete) + { //both probes are complete, use update_score metric + return update_score(a) > update_score(b); + } + + // one of these probes is not complete, if b is complete, a is higher priority + return b->mComplete; +} + +// helper class to seed octree with probes +void LLHeroProbeManager::update() +{ + if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE) + { + return; + } + + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(!gCubeSnapshot); // assert a snapshot is not in progress + if (LLAppViewer::instance()->logoutRequestSent()) + { + return; + } + + initReflectionMaps(); + + if (!mRenderTarget.isComplete()) + { + U32 color_fmt = GL_RGB16F; + U32 targetRes = mProbeResolution * 4; // super sample + mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); + } + + if (!mHeroRenderTarget.isComplete()) + { + U32 color_fmt = GL_RGB16F; + U32 targetRes = mHeroProbeResolution * 2; + mHeroRenderTarget.allocate(targetRes, targetRes, color_fmt, true); + } + + if (mMipChain.empty()) + { + U32 res = mHeroProbeResolution; + U32 count = log2((F32)res) + 0.5f; + + mMipChain.resize(count); + for (int i = 0; i < count; ++i) + { + mMipChain[i].allocate(res, res, GL_RGB16F); + res /= 2; + } + } + + llassert(mProbes[0] == mDefaultProbe); + + LLVector4a camera_pos; + camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); + + // process kill list + for (auto& probe : mKillList) + { + auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe); + if (iter != mProbes.end()) + { + deleteProbe(iter - mProbes.begin()); + } + } + + mKillList.clear(); + + // process create list + for (auto& probe : mCreateList) + { + mProbes.push_back(probe); + } + + mCreateList.clear(); + + if (mProbes.empty()) + { + return; + } + + + bool did_update = false; + + static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); + static LLCachedControl sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); + + bool realtime = sDetail >= (S32)LLHeroProbeManager::DetailLevel::REALTIME; + + LLReflectionMap* closestDynamic = nullptr; + + LLReflectionMap* oldestProbe = nullptr; + LLReflectionMap* oldestOccluded = nullptr; + + if (mUpdatingProbe != nullptr) + { + did_update = true; + doProbeUpdate(); + } + + // update distance to camera for all probes + std::sort(mProbes.begin()+1, mProbes.end(), CompareProbeDistance()); + llassert(mProbes[0] == mDefaultProbe); + llassert(mProbes[0]->mCubeArray == mTexture); + llassert(mProbes[0]->mCubeIndex == 0); + + // make sure we're assigning cube slots to the closest probes + + // first free any cube indices for distant probes + for (U32 i = mReflectionProbeCount; i < mProbes.size(); ++i) + { + LLReflectionMap* probe = mProbes[i]; + llassert(probe != nullptr); + + if (probe->mCubeIndex != -1 && mUpdatingProbe != probe) + { // free this index + mCubeFree.push_back(probe->mCubeIndex); + + probe->mCubeArray = nullptr; + probe->mCubeIndex = -1; + probe->mComplete = false; + } + } + + // next distribute the free indices + U32 count = llmin(mReflectionProbeCount, (U32)mProbes.size()); + + for (S32 i = 1; i < count && !mCubeFree.empty(); ++i) + { + // find the closest probe that needs a cube index + LLReflectionMap* probe = mProbes[i]; + + if (probe->mCubeIndex == -1) + { + S32 idx = allocateCubeIndex(); + llassert(idx > 0); //if we're still in this loop, mCubeFree should not be empty and allocateCubeIndex should be returning good indices + probe->mCubeArray = mTexture; + probe->mCubeIndex = idx; + } + } + + for (int i = 0; i < mProbes.size(); ++i) + { + LLReflectionMap* probe = mProbes[i]; + if (probe->getNumRefs() == 1) + { // no references held outside manager, delete this probe + deleteProbe(i); + --i; + continue; + } + + if (probe != mDefaultProbe && !probe->isRelevant()) + { + continue; + } + + LLVector4a d; + + if (probe != mDefaultProbe) + { + if (probe->mViewerObject) //make sure probes track the viewer objects they are attached to + { + probe->mOrigin.load3(probe->mViewerObject->getPositionAgent().mV); + } + d.setSub(camera_pos, probe->mOrigin); + probe->mDistance = d.getLength3().getF32() - probe->mRadius; + } + else if (probe->mComplete) + { + // make default probe have a distance of 64m for the purposes of prioritization (if it's already been generated once) + probe->mDistance = 64.f; + } + else + { + probe->mDistance = -4096.f; //boost priority of default probe when it's not complete + } + + if (probe->mComplete) + { + probe->autoAdjustOrigin(); + probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f); + } + if (probe->mOccluded && probe->mComplete) + { + if (oldestOccluded == nullptr) + { + oldestOccluded = probe; + } + else if (probe->mLastUpdateTime < oldestOccluded->mLastUpdateTime) + { + oldestOccluded = probe; + } + } + else + { + if (!did_update && + i < mReflectionProbeCount && + (oldestProbe == nullptr || + check_priority(probe, oldestProbe))) + { + oldestProbe = probe; + } + } + + if (realtime && + closestDynamic == nullptr && + probe->mCubeIndex != -1 && + probe->getIsDynamic()) + { + closestDynamic = probe; + } + } + + if (realtime && closestDynamic != nullptr) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); + // update the closest dynamic probe realtime + // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames + closestDynamic->autoAdjustOrigin(); + + // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set + // lighting values etc + bool radiance_pass = isRadiancePass(); + mRadiancePass = mRealtimeRadiancePass; + for (U32 i = 0; i < 6; ++i) + { + updateProbeFace(closestDynamic, i, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); + } + mRealtimeRadiancePass = !mRealtimeRadiancePass; + + // restore "isRadiancePass" + mRadiancePass = radiance_pass; + } + + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); + + mHeroProbe->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); + bool radiance_pass = isRadiancePass(); + mRadiancePass = true; + for (U32 i = 0; i < 6; ++i) + { + updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray, mMipChain, mHeroProbeCount); + } + + // restore "isRadiancePass" + mRadiancePass = radiance_pass; + } + + static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); + if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) + { + if (sLevel == 0) + { // when probes are disabled don't update the default probe more often than the prescribed update period + oldestProbe = nullptr; + } + } + else if (sLevel > 0) + { // when probes are enabled don't update the default probe less often than the prescribed update period + oldestProbe = mDefaultProbe; + } + + // switch to updating the next oldest probe + if (!did_update && oldestProbe != nullptr) + { + LLReflectionMap* probe = oldestProbe; + llassert(probe->mCubeIndex != -1); + + probe->autoAdjustOrigin(); + + mUpdatingProbe = probe; + 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; + } +} + +LLReflectionMap* LLHeroProbeManager::addProbe(LLSpatialGroup* group) +{ + LLReflectionMap* probe = new LLReflectionMap(); + probe->mGroup = group; + + if (mDefaultProbe.isNull()) + { //safety check to make sure default probe is always first probe added + mDefaultProbe = new LLReflectionMap(); + mProbes.push_back(mDefaultProbe); + } + + llassert(mProbes[0] == mDefaultProbe); + + if (group) + { + probe->mOrigin = group->getOctreeNode()->getCenter(); + } + + if (gCubeSnapshot) + { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update + mCreateList.push_back(probe); + } + else + { + mProbes.push_back(probe); + } + + return probe; +} + +struct CompareProbeDepth +{ + bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs) + { + return lhs->mMinDepth < rhs->mMinDepth; + } +}; + +void LLHeroProbeManager::getReflectionMaps(std::vector& maps) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + LLVector4a oa; // scratch space for transformed origin + + U32 count = 0; + U32 lastIdx = 0; + for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i) + { + mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested + if (mProbes[i]->mCubeIndex != -1) + { + if (!mProbes[i]->mOccluded && mProbes[i]->mComplete) + { + maps[count++] = mProbes[i]; + modelview.affineTransform(mProbes[i]->mOrigin, oa); + mProbes[i]->mMinDepth = -oa.getF32ptr()[2] - mProbes[i]->mRadius; + mProbes[i]->mMaxDepth = -oa.getF32ptr()[2] + mProbes[i]->mRadius; + } + } + else + { + mProbes[i]->mProbeIndex = -1; + } + lastIdx = i; + } + + // set remaining probe indices to -1 + for (U32 i = lastIdx+1; i < mProbes.size(); ++i) + { + mProbes[i]->mProbeIndex = -1; + } + + if (count > 1) + { + std::sort(maps.begin(), maps.begin() + count, CompareProbeDepth()); + } + + for (U32 i = 0; i < count; ++i) + { + maps[i]->mProbeIndex = i; + } + + // null terminate list + if (count < maps.size()) + { + maps[count] = nullptr; + } +} + +LLReflectionMap* LLHeroProbeManager::registerSpatialGroup(LLSpatialGroup* group) +{ + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) + { + OctreeNode* node = group->getOctreeNode(); + F32 size = node->getSize().getF32ptr()[0]; + if (size >= 15.f && size <= 17.f) + { + return addProbe(group); + } + } + + return nullptr; +} + +LLReflectionMap* LLHeroProbeManager::registerViewerObject(LLViewerObject* vobj) +{ + llassert(vobj != nullptr); + + LLReflectionMap* probe = new LLReflectionMap(); + probe->mViewerObject = vobj; + probe->mOrigin.load3(vobj->getPositionAgent().mV); + + if (gCubeSnapshot) + { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update + mCreateList.push_back(probe); + } + else + { + mProbes.push_back(probe); + } + + return probe; +} + +S32 LLHeroProbeManager::allocateCubeIndex() +{ + if (!mCubeFree.empty()) + { + S32 ret = mCubeFree.front(); + mCubeFree.pop_front(); + return ret; + } + + return -1; +} + +void LLHeroProbeManager::deleteProbe(U32 i) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LLReflectionMap* probe = mProbes[i]; + + llassert(probe != mDefaultProbe); + + if (probe->mCubeIndex != -1) + { // mark the cube index used by this probe as being free + mCubeFree.push_back(probe->mCubeIndex); + } + if (mUpdatingProbe == probe) + { + mUpdatingProbe = nullptr; + mUpdatingFace = 0; + } + + // remove from any Neighbors lists + for (auto& other : probe->mNeighbors) + { + auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); + llassert(iter != other->mNeighbors.end()); + other->mNeighbors.erase(iter); + } + + mProbes.erase(mProbes.begin() + i); +} + + +void LLHeroProbeManager::doProbeUpdate() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(mUpdatingProbe != nullptr); + + updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); + + if (++mUpdatingFace == 6) + { + updateNeighbors(mUpdatingProbe); + mUpdatingFace = 0; + if (isRadiancePass()) + { + mUpdatingProbe->mComplete = true; + mUpdatingProbe = nullptr; + mRadiancePass = false; + } + else + { + mRadiancePass = true; + } + } +} + +// Do the reflection map update render passes. +// For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated +// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate +// a simple mip chain (not convolution filter). +// At the end of these passes, an irradiance map is generated for this probe and placed into the irradiance cube map array at the index for this probe +// The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. +// At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. +// In effect this simulates single-bounce lighting. +void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount) +{ + // hacky hot-swap of camera specific render targets + gPipeline.mRT = &gPipeline.mAuxillaryRT; + + LLRenderTarget* target = &mRenderTarget; + + S32 sourceIdx = probeCount; + + if (probeResolution == mHeroProbeResolution) + { + sourceIdx = 0; + target = &mHeroRenderTarget; + } + + mLightScale = 1.f; + static LLCachedControl max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f); + if (!isRadiancePass() && probe->getAmbiance() > max_local_light_ambiance) + { + mLightScale = max_local_light_ambiance / probe->getAmbiance(); + } + + if (probe == mDefaultProbe) + { + touch_default_probe(probe); + + gPipeline.pushRenderTypeMask(); + + //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_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES); + + probe->update(target->getWidth(), face); + + gPipeline.popRenderTypeMask(); + } + else + { + probe->update(target->getWidth(), face); + } + + gPipeline.mRT = &gPipeline.mMainRT; + + if (probe != mUpdatingProbe && probe->mType != LLReflectionMap::ProbeType::REFLECTION) + { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel + sourceIdx += 1; + } + + gGL.setColorMask(true, true); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + + // downsample to placeholder map + { + gGL.matrixMode(gGL.MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); + + gGL.matrixMode(gGL.MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + gGL.flush(); + U32 res = probeResolution * 2; + + static LLStaticHashedString resScale("resScale"); + static LLStaticHashedString direction("direction"); + static LLStaticHashedString znear("znear"); + static LLStaticHashedString zfar("zfar"); + + LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; + + // perform a gaussian blur on the super sampled render before downsampling + { + gGaussianProgram.bind(); + gGaussianProgram.uniform1f(resScale, 1.f / (probeResolution * 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); + target->bindTarget(); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + target->flush(); + + // vertical + gGaussianProgram.uniform2f(direction, 0.f, 1.f); + gGL.getTexUnit(diffuseChannel)->bind(target); + screen_rt->bindTarget(); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + screen_rt->flush(); + } + + + S32 mips = log2((F32)probeResolution) + 0.5f; + + gReflectionMipProgram.bind(); + S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); + + for (int i = 0; i < mMipChain.size(); ++i) + { + LL_PROFILE_GPU_ZONE("probe mip"); + mMipChain[i].bindTarget(); + if (i == 0) + { + gGL.getTexUnit(diffuseChannel)->bind(screen_rt); + } + else + { + gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1])); + } + + + gReflectionMipProgram.uniform1f(resScale, 1.f/(probeResolution*2)); + + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + res /= 2; + + S32 mip = i - (mMipChain.size() - mips); + + if (mip >= 0) + { + LL_PROFILE_GPU_ZONE("probe mip copy"); + cubeArray->bind(0); + + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); + + cubeArray->unbind(); + } + mMipChain[i].flush(); + } + + gGL.popMatrix(); + gGL.matrixMode(gGL.MM_MODELVIEW); + gGL.popMatrix(); + + gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE); + gReflectionMipProgram.unbind(); + } + + if (face == 5) + { + mMipChain[0].bindTarget(); + static LLStaticHashedString sSourceIdx("sourceIdx"); + + if (isRadiancePass()) + { + //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) + gRadianceGenProgram.bind(); + mVertexBuffer->setBuffer(); + + S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + cubeArray->bind(channel); + gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); + gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); + + U32 res = mMipChain[0].getWidth(); + + for (int i = 0; i < mMipChain.size(); ++i) + { + LL_PROFILE_GPU_ZONE("probe radiance gen"); + static LLStaticHashedString sMipLevel("mipLevel"); + static LLStaticHashedString sRoughness("roughness"); + static LLStaticHashedString sWidth("u_width"); + + gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); + gRadianceGenProgram.uniform1f(sMipLevel, i); + gRadianceGenProgram.uniform1i(sWidth, probeResolution); + + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); + + mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); + + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + } + + if (i != mMipChain.size() - 1) + { + res /= 2; + glViewport(0, 0, res, res); + } + } + + gRadianceGenProgram.unbind(); + } + else + { + //generate irradiance map + gIrradianceGenProgram.bind(); + S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + cubeArray->bind(channel); + + gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); + gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); + + mVertexBuffer->setBuffer(); + int start_mip = 0; + // find the mip target to start with based on irradiance map resolution + for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) + { + if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) + { + break; + } + } + + //for (int i = start_mip; i < mMipChain.size(); ++i) + { + int i = start_mip; + LL_PROFILE_GPU_ZONE("probe irradiance gen"); + glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); + for (int cf = 0; cf < 6; ++cf) + { // for each cube face + LLCoordFrame frame; + frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + + F32 mat[16]; + frame.getOpenGLRotation(mat); + gGL.loadMatrix(mat); + + mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); + + S32 res = mMipChain[i].getWidth(); + mIrradianceMaps->bind(channel); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); + cubeArray->bind(channel); + } + } + } + + mMipChain[0].flush(); + + gIrradianceGenProgram.unbind(); + } +} + +void LLHeroProbeManager::reset() +{ + mReset = true; +} + +void LLHeroProbeManager::shift(const LLVector4a& offset) +{ + for (auto& probe : mProbes) + { + probe->mOrigin.add(offset); + } +} + +void LLHeroProbeManager::updateNeighbors(LLReflectionMap* probe) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + if (mDefaultProbe == probe) + { + return; + } + + //remove from existing neighbors + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear"); + + for (auto& other : probe->mNeighbors) + { + auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); + llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly + other->mNeighbors.erase(iter); + } + + probe->mNeighbors.clear(); + } + + // search for new neighbors + if (probe->isRelevant()) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search"); + for (auto& other : mProbes) + { + if (other != mDefaultProbe && other != probe) + { + if (other->isRelevant() && probe->intersects(other)) + { + probe->mNeighbors.push_back(other); + other->mNeighbors.push_back(probe); + } + } + } + } +} + +void LLHeroProbeManager::updateUniforms() +{ + if (!LLPipeline::sReflectionProbesEnabled) + { + return; + } + + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + + // structure for packing uniform buffer object + // see class3/deferred/reflectionProbeF.glsl + struct ReflectionProbeData + { + // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of + // the box probe + LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; + + // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space + LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; + + // extra parameters + // x - irradiance scale + // y - radiance scale + // z - fade in + // w - znear + LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; + + // indices used by probe: + // [i][0] - cubemap array index for this probe + // [i][1] - index into "refNeighbor" for probes that intersect this probe + // [i][2] - number of probes that intersect this probe, or -1 for no neighbors + // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) + GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; + + // list of neighbor indices + GLint refNeighbor[4096]; + + GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth + // numbrer of active refmaps + GLint refmapCount; + }; + + mReflectionMaps.resize(mReflectionProbeCount); + getReflectionMaps(mReflectionMaps); + + ReflectionProbeData rpd; + + F32 minDepth[256]; + + for (int i = 0; i < 256; ++i) + { + rpd.refBucket[i][0] = mReflectionProbeCount; + rpd.refBucket[i][1] = mReflectionProbeCount; + rpd.refBucket[i][2] = mReflectionProbeCount; + rpd.refBucket[i][3] = mReflectionProbeCount; + minDepth[i] = FLT_MAX; + } + + // load modelview matrix into matrix 4a + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + LLVector4a oa; // scratch space for transformed origin + + S32 count = 0; + U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors + + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsSky::ptr_t psky = environment.getCurrentSky(); + + static LLCachedControl cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust); + + bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); + F32 ambscale = is_ambiance_pass ? 0.f : 1.f; + F32 radscale = is_ambiance_pass ? 0.5f : 1.f; + + for (auto* refmap : mReflectionMaps) + { + if (refmap == nullptr) + { + break; + } + + if (refmap != mDefaultProbe) + { + // bucket search data + // theory of operation: + // 1. Determine minimum and maximum depth of each influence volume and store in mDepth (done in getReflectionMaps) + // 2. Sort by minimum depth + // 3. Prepare a bucket for each 1m of depth out to 256m + // 4. For each bucket, store the index of the nearest probe that might influence pixels in that bucket + // 5. In the shader, lookup the bucket for the pixel depth to get the index of the first probe that could possibly influence + // the current pixel. + int depth_min = llclamp(llfloor(refmap->mMinDepth), 0, 255); + int depth_max = llclamp(llfloor(refmap->mMaxDepth), 0, 255); + for (U32 i = depth_min; i <= depth_max; ++i) + { + if (refmap->mMinDepth < minDepth[i]) + { + minDepth[i] = refmap->mMinDepth; + rpd.refBucket[i][0] = refmap->mProbeIndex; + } + } + } + + llassert(refmap->mProbeIndex == count); + llassert(mReflectionMaps[refmap->mProbeIndex] == refmap); + + llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged + + { + 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; + } + + rpd.refIndex[count][0] = refmap->mCubeIndex; + llassert(nc % 4 == 0); + rpd.refIndex[count][1] = nc / 4; + rpd.refIndex[count][3] = refmap->mPriority; + + // for objects that are reflection probes, use the volume as the influence volume of the probe + // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres + if (refmap->getBox(rpd.refBox[count])) + { // negate priority to indicate this probe has a box influence volume + rpd.refIndex[count][3] = -rpd.refIndex[count][3]; + } + + rpd.refParams[count].set( + llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale + radscale, // radiance scale + refmap->mFadeIn, // fade in weight + oa.getF32ptr()[2] - refmap->mRadius); // z near + + S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors + { + //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); + //pack neghbor list + const U32 max_neighbors = 64; + U32 neighbor_count = 0; + + for (auto& neighbor : refmap->mNeighbors) + { + if (ni >= 4096) + { // out of space + break; + } + + GLint idx = neighbor->mProbeIndex; + if (idx == -1 || neighbor->mOccluded || neighbor->mCubeIndex == -1) + { + continue; + } + + // this neighbor may be sampled + rpd.refNeighbor[ni++] = idx; + + neighbor_count++; + if (neighbor_count >= max_neighbors) + { + break; + } + } + } + + if (nc == ni) + { + //no neighbors, tag as empty + rpd.refIndex[count][1] = -1; + } + else + { + rpd.refIndex[count][2] = ni - nc; + + // move the cursor forward + nc = ni; + if (nc % 4 != 0) + { // jump to next power of 4 for compatibility with ivec4 + nc += 4 - (nc % 4); + } + } + + + count++; + } + +#if 0 + { + // fill in gaps in refBucket + S32 probe_idx = mReflectionProbeCount; + + for (int i = 0; i < 256; ++i) + { + if (i < count) + { // for debugging, store depth of mReflectionsMaps[i] + rpd.refBucket[i][1] = (S32) (mReflectionMaps[i]->mDepth * 10); + } + + if (rpd.refBucket[i][0] == mReflectionProbeCount) + { + rpd.refBucket[i][0] = probe_idx; + } + else + { + probe_idx = rpd.refBucket[i][0]; + } + } + } +#endif + + rpd.refmapCount = count; + + //copy rpd into uniform buffer object + if (mUBO == 0) + { + glGenBuffers(1, &mUBO); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); + glBindBuffer(GL_UNIFORM_BUFFER, mUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } + + struct HeroProbeData + { + LLVector4 heroPosition[1]; + GLint heroProbeCount = 1; + }; + + HeroProbeData hpd; + + modelview.loadu(gGLModelView); + + oa.set(0, 0, 0, 0); + hpd.heroProbeCount = 1; + modelview.affineTransform(mHeroProbe->mOrigin, oa); + hpd.heroPosition[0].set(oa.getF32ptr()); + + //copy rpd into uniform buffer object + if (mUBO == 0) + { + glGenBuffers(1, &mHeroUBO); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); + glBindBuffer(GL_UNIFORM_BUFFER, mHeroUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } + +#if 0 + if (!gCubeSnapshot) + { + for (auto& probe : mProbes) + { + LLViewerObject* vobj = probe->mViewerObject; + if (vobj) + { + F32 time = (F32)gFrameTimeSeconds - probe->mLastUpdateTime; + vobj->setDebugText(llformat("%d/%d/%d/%.1f - %.1f/%.1f", probe->mCubeIndex, probe->mProbeIndex, (U32) probe->mNeighbors.size(), probe->mMinDepth, probe->mMaxDepth, time), time > 1.f ? LLColor4::white : LLColor4::green); + } + } + } +#endif +} + +void LLHeroProbeManager::setUniforms() +{ + if (!LLPipeline::sReflectionProbesEnabled) + { + return; + } + + if (mUBO == 0) + { + updateUniforms(); + } + glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); +} + +void LLHeroProbeManager::renderDebug() +{ + gDebugProgram.bind(); + + for (auto& probe : mProbes) + { + renderReflectionProbe(probe); + } + + gDebugProgram.unbind(); +} + +void LLHeroProbeManager::initReflectionMaps() +{ + U32 count = LL_MAX_REFLECTION_PROBE_COUNT; + + if (mTexture.isNull() || mReflectionProbeCount != count || mReset || mHeroArray.isNull()) + { + mReset = false; + mReflectionProbeCount = count; + mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); + mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 + + 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, 3, mReflectionProbeCount + 2); + + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); + + // reset probe state + mUpdatingFace = 0; + mUpdatingProbe = nullptr; + mRadiancePass = false; + mRealtimeRadiancePass = false; + + for (auto& probe : mProbes) + { + probe->mLastUpdateTime = 0.f; + probe->mComplete = false; + probe->mProbeIndex = -1; + probe->mCubeArray = nullptr; + probe->mCubeIndex = -1; + probe->mNeighbors.clear(); + } + + mCubeFree.clear(); + initCubeFree(); + + if (mDefaultProbe.isNull()) + { + llassert(mProbes.empty()); // default probe MUST be the first probe created + mDefaultProbe = new LLReflectionMap(); + mProbes.push_back(mDefaultProbe); + } + + llassert(mProbes[0] == mDefaultProbe); + + mDefaultProbe->mCubeIndex = 0; + mDefaultProbe->mCubeArray = mTexture; + mDefaultProbe->mDistance = 64.f; + mDefaultProbe->mRadius = 4096.f; + mDefaultProbe->mProbeIndex = 0; + touch_default_probe(mDefaultProbe); + + mHeroProbeResolution = 128; + + // Revise when we have both water and mirrors in hero probes. + mHeroProbeCount = 1; + + mHeroArray = new LLCubeMapArray(); + + // We use an extra probe for scratch space on these. + mHeroArray->allocate(mHeroProbeResolution, 3, mHeroProbeCount + 1, true); + + if (mHeroProbe.isNull()) { + mHeroProbe = new LLReflectionMap(); + } + + mHeroProbe->mCubeIndex = 0; + mHeroProbe->mCubeArray = mHeroArray; + mHeroProbe->mDistance = 64.f; + mHeroProbe->mRadius = 4096.f; + mHeroProbe->mProbeIndex = 0; + touch_default_probe(mHeroProbe); + + } + + if (mVertexBuffer.isNull()) + { + U32 mask = LLVertexBuffer::MAP_VERTEX; + LLPointer buff = new LLVertexBuffer(mask); + buff->allocateBuffer(4, 0); + + LLStrider v; + + buff->getVertexStrider(v); + + v[0] = LLVector3(-1, -1, -1); + v[1] = LLVector3(1, -1, -1); + v[2] = LLVector3(-1, 1, -1); + v[3] = LLVector3(1, 1, -1); + + buff->unmapBuffer(); + + mVertexBuffer = buff; + } +} + +void LLHeroProbeManager::cleanup() +{ + mVertexBuffer = nullptr; + mRenderTarget.release(); + mHeroRenderTarget.release(); + + mMipChain.clear(); + + mTexture = nullptr; + mIrradianceMaps = nullptr; + mHeroArray = nullptr; + + mProbes.clear(); + mKillList.clear(); + mCreateList.clear(); + + mReflectionMaps.clear(); + mUpdatingFace = 0; + + mDefaultProbe = nullptr; + mUpdatingProbe = nullptr; + + mHeroProbe = nullptr; + + glDeleteBuffers(1, &mUBO); + mUBO = 0; + + glDeleteBuffers(1, &mHeroUBO); + mHeroUBO = 0; + + // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state + initCubeFree(); +} + +void LLHeroProbeManager::doOcclusion() +{ + LLVector4a eye; + eye.load3(LLViewerCamera::instance().getOrigin().mV); + + for (auto& probe : mProbes) + { + if (probe != nullptr && probe != mDefaultProbe) + { + probe->doOcclusion(eye); + } + } +} diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h new file mode 100644 index 0000000000..be761a680e --- /dev/null +++ b/indra/newview/llheroprobemanager.h @@ -0,0 +1,208 @@ +/** + * @file llheroprobemanager.h + * @brief LLHeroProbeManager class declaration + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "llreflectionmap.h" +#include "llrendertarget.h" +#include "llcubemaparray.h" +#include "llcubemap.h" + +class LLSpatialGroup; +class LLViewerObject; + +// number of reflection probes to keep in vram +#define LL_MAX_REFLECTION_PROBE_COUNT 256 + +// reflection probe resolution +#define LL_IRRADIANCE_MAP_RESOLUTION 64 + +// reflection probe mininum scale +#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; + +class alignas(16) LLHeroProbeManager +{ + LL_ALIGN_NEW +public: + enum class DetailLevel + { + STATIC_ONLY = 0, + STATIC_AND_DYNAMIC, + REALTIME = 2 + }; + + // allocate an environment map of the given resolution + LLHeroProbeManager(); + + // release any GL state + void cleanup(); + + // maintain reflection probes + void update(); + + // add a probe for the given spatial group + LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr); + + // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size() + // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr. + // maps -- presized array of Reflection Map pointers + void getReflectionMaps(std::vector& maps); + + // called by LLSpatialGroup constructor + // If spatial group should receive a Reflection Probe, will create one for the specified spatial group + LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group); + + // presently hacked into LLViewerObject::setTE + // Used by LLViewerObjects that are Reflection Probes + // vobj must not be null + // Guaranteed to not return null + LLReflectionMap* registerViewerObject(LLViewerObject* vobj); + + // reset all state on the next update + void reset(); + + // called on region crossing to "shift" probes into new coordinate frame + void shift(const LLVector4a& offset); + + // debug display, called from llspatialpartition if reflection + // probe debug display is active + void renderDebug(); + + // call once at startup to allocate cubemap arrays + void initReflectionMaps(); + + // 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; + + // initialize mCubeFree array to default values + void initCubeFree(); + + // delete the probe with the given index in mProbes + void deleteProbe(U32 i); + + // get a free cube index + // returns -1 if allocation failed + S32 allocateCubeIndex(); + + // update the neighbors of the given probe + void updateNeighbors(LLReflectionMap* probe); + + // update UBO used for rendering (call only once per render pipe flush) + void updateUniforms(); + + // bind UBO used for rendering + void setUniforms(); + + // render target for cube snapshots + // used to generate mipmaps without doing a copy-to-texture + LLRenderTarget mRenderTarget; + + LLRenderTarget mHeroRenderTarget; + + std::vector mMipChain; + + // storage for reflection probe radiance maps (plus two scratch space cubemaps) + LLPointer mTexture; + + LLPointer mHeroArray; + + // vertex buffer for pushing verts to filter shaders + LLPointer mVertexBuffer; + + // storage for reflection probe irradiance maps + LLPointer mIrradianceMaps; + + // list of free cubemap indices + std::list mCubeFree; + + // perform an update on the currently updating Probe + void doProbeUpdate(); + + // update the specified face of the specified probe + void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount); + + // list of active reflection maps + std::vector > mProbes; + + // list of reflection maps to kill + std::vector > mKillList; + + // list of reflection maps to create + std::vector > mCreateList; + + // handle to UBO + U32 mUBO = 0; + + // Hero UBO + U32 mHeroUBO = 0; + + // list of maps being used for rendering + std::vector mReflectionMaps; + + LLReflectionMap* mUpdatingProbe = nullptr; + U32 mUpdatingFace = 0; + + // if true, we're generating the radiance map for the current probe, otherwise we're generating the irradiance map. + // Update sequence should be to generate the irradiance map from render of the world that has no irradiance, + // then generate the radiance map from a render of the world that includes irradiance. + // This should avoid feedback loops and ensure that the colors in the radiance maps match the colors in the environment. + bool mRadiancePass = false; + + // same as above, but for the realtime probe. + // Realtime probes should update all six sides of the irradiance map on "odd" frames and all six sides of the + // radiance map on "even" frames. + bool mRealtimeRadiancePass = false; + + LLPointer mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0) + + LLPointer mHeroProbe; + + // number of reflection probes to use for rendering + U32 mReflectionProbeCount; + + U32 mHeroProbeCount; + + // resolution of reflection probes + U32 mProbeResolution = 128; + + U32 mHeroProbeResolution = 512; + + // maximum LoD of reflection probes (mip levels - 1) + F32 mMaxProbeLOD = 6.f; + + // amount to scale local lights during an irradiance map update (set during updateProbeFace and used by LLPipeline) + F32 mLightScale = 1.f; + + // if true, reset all probe render state on the next update (for teleports and sky changes) + bool mReset = false; +}; + diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index ad4d3d94e2..e855be8fbd 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -130,17 +130,10 @@ void LLReflectionMapManager::update() U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } - - if (!mHeroRenderTarget.isComplete()) - { - U32 color_fmt = GL_RGB16F; - U32 targetRes = mHeroProbeResolution * 2; - mHeroRenderTarget.allocate(targetRes, targetRes, color_fmt, true); - } if (mMipChain.empty()) { - U32 res = mHeroProbeResolution; + U32 res = mProbeResolution; U32 count = log2((F32)res) + 0.5f; mMipChain.resize(count); @@ -304,8 +297,8 @@ void LLReflectionMapManager::update() } } - if (realtime && - closestDynamic == nullptr && + if (realtime && + closestDynamic == nullptr && probe->mCubeIndex != -1 && probe->getIsDynamic()) { @@ -320,35 +313,19 @@ void LLReflectionMapManager::update() // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames closestDynamic->autoAdjustOrigin(); - // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set + // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set // lighting values etc bool radiance_pass = isRadiancePass(); mRadiancePass = mRealtimeRadiancePass; for (U32 i = 0; i < 6; ++i) { - updateProbeFace(closestDynamic, i, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); + updateProbeFace(closestDynamic, i); } mRealtimeRadiancePass = !mRealtimeRadiancePass; // restore "isRadiancePass" mRadiancePass = radiance_pass; } - - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - - mHeroProbe->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); - bool radiance_pass = isRadiancePass(); - mRadiancePass = true; - for (U32 i = 0; i < 6; ++i) - { - updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray, mMipChain, mHeroProbeCount); - } - - // restore "isRadiancePass" - mRadiancePass = radiance_pass; - } static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) @@ -555,7 +532,7 @@ void LLReflectionMapManager::doProbeUpdate() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(mUpdatingProbe != nullptr); - updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); + updateProbeFace(mUpdatingProbe, mUpdatingFace); if (++mUpdatingFace == 6) { @@ -576,26 +553,16 @@ void LLReflectionMapManager::doProbeUpdate() // Do the reflection map update render passes. // For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated -// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate +// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate // a simple mip chain (not convolution filter). // At the end of these passes, an irradiance map is generated for this probe and placed into the irradiance cube map array at the index for this probe // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. // At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. // In effect this simulates single-bounce lighting. -void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount) +void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; - - LLRenderTarget* target = &mRenderTarget; - - S32 sourceIdx = probeCount; - - if (probeResolution == mHeroProbeResolution) - { - sourceIdx = 0; - target = &mHeroRenderTarget; - } mLightScale = 1.f; static LLCachedControl max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f); @@ -614,18 +581,20 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES); - probe->update(target->getWidth(), face); + probe->update(mRenderTarget.getWidth(), face); gPipeline.popRenderTypeMask(); } else { - probe->update(target->getWidth(), face); + probe->update(mRenderTarget.getWidth(), face); } gPipeline.mRT = &gPipeline.mMainRT; - if (probe != mUpdatingProbe && probe->mType != LLReflectionMap::ProbeType::REFLECTION) + S32 sourceIdx = mReflectionProbeCount; + + if (probe != mUpdatingProbe) { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel sourceIdx += 1; } @@ -646,7 +615,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U gGL.loadIdentity(); gGL.flush(); - U32 res = probeResolution * 2; + U32 res = mProbeResolution * 2; static LLStaticHashedString resScale("resScale"); static LLStaticHashedString direction("direction"); @@ -658,20 +627,20 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U // perform a gaussian blur on the super sampled render before downsampling { gGaussianProgram.bind(); - gGaussianProgram.uniform1f(resScale, 1.f / (probeResolution * 2)); + 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); - target->bindTarget(); + mRenderTarget.bindTarget(); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - target->flush(); + mRenderTarget.flush(); // vertical gGaussianProgram.uniform2f(direction, 0.f, 1.f); - gGL.getTexUnit(diffuseChannel)->bind(target); + gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget); screen_rt->bindTarget(); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -679,7 +648,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U } - S32 mips = log2((F32)probeResolution) + 0.5f; + S32 mips = log2((F32)mProbeResolution) + 0.5f; gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); @@ -698,7 +667,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U } - gReflectionMipProgram.uniform1f(resScale, 1.f/(probeResolution*2)); + gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -710,11 +679,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U if (mip >= 0) { LL_PROFILE_GPU_ZONE("probe mip copy"); - cubeArray->bind(0); - + mTexture->bind(0); + //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); - - cubeArray->unbind(); + //if (i == 0) + //{ + //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + //} + mTexture->unbind(); } mMipChain[i].flush(); } @@ -739,7 +711,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U mVertexBuffer->setBuffer(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - cubeArray->bind(channel); + mTexture->bind(channel); gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -754,7 +726,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, i); - gRadianceGenProgram.uniform1i(sWidth, probeResolution); + gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); for (int cf = 0; cf < 6; ++cf) { // for each cube face @@ -784,7 +756,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U //generate irradiance map gIrradianceGenProgram.bind(); S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - cubeArray->bind(channel); + mTexture->bind(channel); gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -819,7 +791,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face, U S32 res = mMipChain[i].getWidth(); mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - cubeArray->bind(channel); + mTexture->bind(channel); } } } @@ -896,14 +868,14 @@ void LLReflectionMapManager::updateUniforms() // see class3/deferred/reflectionProbeF.glsl struct ReflectionProbeData { - // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of + // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of // the box probe - LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; + LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space - LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; + LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; - // extra parameters + // extra parameters // x - irradiance scale // y - radiance scale // z - fade in @@ -915,10 +887,10 @@ void LLReflectionMapManager::updateUniforms() // [i][1] - index into "refNeighbor" for probes that intersect this probe // [i][2] - number of probes that intersect this probe, or -1 for no neighbors // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) - GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; + GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; // list of neighbor indices - GLint refNeighbor[4096]; + GLint refNeighbor[4096]; GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth // numbrer of active refmaps @@ -1101,7 +1073,7 @@ void LLReflectionMapManager::updateUniforms() #endif rpd.refmapCount = count; - + //copy rpd into uniform buffer object if (mUBO == 0) { @@ -1114,35 +1086,7 @@ void LLReflectionMapManager::updateUniforms() glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } - - struct HeroProbeData - { - LLVector4 heroPosition[1]; - GLint heroProbeCount = 1; - }; - - HeroProbeData hpd; - - modelview.loadu(gGLModelView); - - oa.set(0, 0, 0, 0); - hpd.heroProbeCount = 1; - modelview.affineTransform(mHeroProbe->mOrigin, oa); - hpd.heroPosition[0].set(oa.getF32ptr()); - //copy rpd into uniform buffer object - if (mUBO == 0) - { - glGenBuffers(1, &mHeroUBO); - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); - glBindBuffer(GL_UNIFORM_BUFFER, mHeroUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - } - #if 0 if (!gCubeSnapshot) { @@ -1167,7 +1111,7 @@ void LLReflectionMapManager::setUniforms() } if (mUBO == 0) - { + { updateUniforms(); } glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); @@ -1275,7 +1219,7 @@ void LLReflectionMapManager::initReflectionMaps() { U32 count = LL_MAX_REFLECTION_PROBE_COUNT; - if (mTexture.isNull() || mReflectionProbeCount != count || mReset || mHeroArray.isNull()) + if (mTexture.isNull() || mReflectionProbeCount != count || mReset) { mReset = false; mReflectionProbeCount = count; @@ -1324,27 +1268,6 @@ void LLReflectionMapManager::initReflectionMaps() mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); - - mHeroProbeResolution = 128; - - // Revise when we have both water and mirrors in hero probes. - mHeroProbeCount = 1; - - mHeroArray = new LLCubeMapArray(); - - // We use an extra probe for scratch space on these. - mHeroArray->allocate(mHeroProbeResolution, 3, mHeroProbeCount + 1, true); - - if (mHeroProbe.isNull()) { - mHeroProbe = new LLReflectionMap(); - } - - mHeroProbe->mCubeIndex = 0; - mHeroProbe->mCubeArray = mHeroArray; - mHeroProbe->mDistance = 64.f; - mHeroProbe->mRadius = 4096.f; - mHeroProbe->mProbeIndex = 0; - touch_default_probe(mHeroProbe); } @@ -1369,17 +1292,15 @@ void LLReflectionMapManager::initReflectionMaps() } } -void LLReflectionMapManager::cleanup() -{ +void LLReflectionMapManager::cleanup() +{ mVertexBuffer = nullptr; mRenderTarget.release(); - mHeroRenderTarget.release(); mMipChain.clear(); mTexture = nullptr; mIrradianceMaps = nullptr; - mHeroArray = nullptr; mProbes.clear(); mKillList.clear(); @@ -1390,14 +1311,9 @@ void LLReflectionMapManager::cleanup() mDefaultProbe = nullptr; mUpdatingProbe = nullptr; - - mHeroProbe = nullptr; glDeleteBuffers(1, &mUBO); mUBO = 0; - - glDeleteBuffers(1, &mHeroUBO); - mHeroUBO = 0; // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state initCubeFree(); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 9f48ce3cfd..7b17112814 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -43,21 +43,23 @@ class LLViewerObject; // reflection probe mininum scale #define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; +void renderReflectionProbe(LLReflectionMap* probe); + class alignas(16) LLReflectionMapManager { LL_ALIGN_NEW public: - enum class DetailLevel + enum class DetailLevel { STATIC_ONLY = 0, STATIC_AND_DYNAMIC, REALTIME = 2 }; - // allocate an environment map of the given resolution + // allocate an environment map of the given resolution LLReflectionMapManager(); - // release any GL state + // release any GL state void cleanup(); // maintain reflection probes @@ -113,7 +115,7 @@ private: // returns -1 if allocation failed S32 allocateCubeIndex(); - // update the neighbors of the given probe + // update the neighbors of the given probe void updateNeighbors(LLReflectionMap* probe); // update UBO used for rendering (call only once per render pipe flush) @@ -125,15 +127,11 @@ private: // render target for cube snapshots // used to generate mipmaps without doing a copy-to-texture LLRenderTarget mRenderTarget; - - LLRenderTarget mHeroRenderTarget; std::vector mMipChain; // storage for reflection probe radiance maps (plus two scratch space cubemaps) LLPointer mTexture; - - LLPointer mHeroArray; // vertex buffer for pushing verts to filter shaders LLPointer mVertexBuffer; @@ -148,7 +146,7 @@ private: void doProbeUpdate(); // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount); + void updateProbeFace(LLReflectionMap* probe, U32 face); // list of active reflection maps std::vector > mProbes; @@ -161,9 +159,6 @@ private: // handle to UBO U32 mUBO = 0; - - // Hero UBO - U32 mHeroUBO = 0; // list of maps being used for rendering std::vector mReflectionMaps; @@ -183,18 +178,12 @@ private: bool mRealtimeRadiancePass = false; LLPointer mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0) - - LLPointer mHeroProbe; // number of reflection probes to use for rendering U32 mReflectionProbeCount; - - U32 mHeroProbeCount; // resolution of reflection probes U32 mProbeResolution = 128; - - U32 mHeroProbeResolution = 512; // maximum LoD of reflection probes (mip levels - 1) F32 mMaxProbeLOD = 6.f; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e742992c1d..909c0f9aaa 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8461,13 +8461,14 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) mReflectionMapManager.mIrradianceMaps->bind(channel); bound = true; } - + /* channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); if (channel > -1 && mReflectionMapManager.mHeroArray.notNull()) { mReflectionMapManager.mHeroArray->bind(channel); bound = true; } + */ if (bound) { -- cgit v1.2.3 From d5845fe3e7f3a620453f00421608211d6353905f Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 18 Aug 2023 21:47:40 -0700 Subject: Latest updates to the hero probe manager. DRTVWR-583 --- indra/newview/llappviewer.cpp | 1 + indra/newview/llheroprobemanager.cpp | 923 ++--------------------------------- indra/newview/llheroprobemanager.h | 87 +--- indra/newview/pipeline.cpp | 31 +- indra/newview/pipeline.h | 2 + 5 files changed, 75 insertions(+), 969 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 343778fe03..3b0ba77ea2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1517,6 +1517,7 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot"); pingMainloopTimeout("Main:Snapshot"); gPipeline.mReflectionMapManager.update(); + gPipeline.mHeroProbeManager.update(); LLFloaterSnapshot::update(); // take snapshots LLFloaterSimpleOutfitSnapshot::update(); gGLActive = FALSE; diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 54a61d000e..5edf819fff 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -57,55 +57,6 @@ static void touch_default_probe(LLReflectionMap* probe) LLHeroProbeManager::LLHeroProbeManager() { - initCubeFree(); -} - -void LLHeroProbeManager::initCubeFree() -{ - // start at 1 because index 0 is reserved for mDefaultProbe - for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) - { - mCubeFree.push_back(i); - } -} - -struct CompareProbeDistance -{ - LLReflectionMap* mDefaultProbe; - - bool operator()(const LLPointer& lhs, const LLPointer& rhs) - { - return lhs->mDistance < rhs->mDistance; - } -}; - -static F32 update_score(LLReflectionMap* p) -{ - return gFrameTimeSeconds - p->mLastUpdateTime - p->mDistance*0.1f; -} - -// return true if a is higher priority for an update than b -static bool check_priority(LLReflectionMap* a, LLReflectionMap* b) -{ - if (a->mCubeIndex == -1) - { // not a candidate for updating - return false; - } - else if (b->mCubeIndex == -1) - { // certainly higher priority than b - return true; - } - else if (!a->mComplete && !b->mComplete) - { //neither probe is complete, use distance - return a->mDistance < b->mDistance; - } - else if (a->mComplete && b->mComplete) - { //both probes are complete, use update_score metric - return update_score(a) > update_score(b); - } - - // one of these probes is not complete, if b is complete, a is higher priority - return b->mComplete; } // helper class to seed octree with probes @@ -131,17 +82,10 @@ void LLHeroProbeManager::update() U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } - - if (!mHeroRenderTarget.isComplete()) - { - U32 color_fmt = GL_RGB16F; - U32 targetRes = mHeroProbeResolution * 2; - mHeroRenderTarget.allocate(targetRes, targetRes, color_fmt, true); - } if (mMipChain.empty()) { - U32 res = mHeroProbeResolution; + U32 res = mProbeResolution; U32 count = log2((F32)res) + 0.5f; mMipChain.resize(count); @@ -156,422 +100,22 @@ void LLHeroProbeManager::update() LLVector4a camera_pos; camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); - - // process kill list - for (auto& probe : mKillList) - { - auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe); - if (iter != mProbes.end()) - { - deleteProbe(iter - mProbes.begin()); - } - } - - mKillList.clear(); - // process create list - for (auto& probe : mCreateList) - { - mProbes.push_back(probe); - } - - mCreateList.clear(); - - if (mProbes.empty()) - { - return; - } - - - bool did_update = false; - - static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); - static LLCachedControl sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); - - bool realtime = sDetail >= (S32)LLHeroProbeManager::DetailLevel::REALTIME; - - LLReflectionMap* closestDynamic = nullptr; - - LLReflectionMap* oldestProbe = nullptr; - LLReflectionMap* oldestOccluded = nullptr; - - if (mUpdatingProbe != nullptr) - { - did_update = true; - doProbeUpdate(); - } - - // update distance to camera for all probes - std::sort(mProbes.begin()+1, mProbes.end(), CompareProbeDistance()); - llassert(mProbes[0] == mDefaultProbe); - llassert(mProbes[0]->mCubeArray == mTexture); - llassert(mProbes[0]->mCubeIndex == 0); - - // make sure we're assigning cube slots to the closest probes + static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); + static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); - // first free any cube indices for distant probes - for (U32 i = mReflectionProbeCount; i < mProbes.size(); ++i) - { - LLReflectionMap* probe = mProbes[i]; - llassert(probe != nullptr); - - if (probe->mCubeIndex != -1 && mUpdatingProbe != probe) - { // free this index - mCubeFree.push_back(probe->mCubeIndex); - - probe->mCubeArray = nullptr; - probe->mCubeIndex = -1; - probe->mComplete = false; - } - } - - // next distribute the free indices - U32 count = llmin(mReflectionProbeCount, (U32)mProbes.size()); - - for (S32 i = 1; i < count && !mCubeFree.empty(); ++i) - { - // find the closest probe that needs a cube index - LLReflectionMap* probe = mProbes[i]; - - if (probe->mCubeIndex == -1) - { - S32 idx = allocateCubeIndex(); - llassert(idx > 0); //if we're still in this loop, mCubeFree should not be empty and allocateCubeIndex should be returning good indices - probe->mCubeArray = mTexture; - probe->mCubeIndex = idx; - } - } - - for (int i = 0; i < mProbes.size(); ++i) - { - LLReflectionMap* probe = mProbes[i]; - if (probe->getNumRefs() == 1) - { // no references held outside manager, delete this probe - deleteProbe(i); - --i; - continue; - } - - if (probe != mDefaultProbe && !probe->isRelevant()) - { - continue; - } - - LLVector4a d; - - if (probe != mDefaultProbe) - { - if (probe->mViewerObject) //make sure probes track the viewer objects they are attached to - { - probe->mOrigin.load3(probe->mViewerObject->getPositionAgent().mV); - } - d.setSub(camera_pos, probe->mOrigin); - probe->mDistance = d.getLength3().getF32() - probe->mRadius; - } - else if (probe->mComplete) - { - // make default probe have a distance of 64m for the purposes of prioritization (if it's already been generated once) - probe->mDistance = 64.f; - } - else - { - probe->mDistance = -4096.f; //boost priority of default probe when it's not complete - } - - if (probe->mComplete) - { - probe->autoAdjustOrigin(); - probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f); - } - if (probe->mOccluded && probe->mComplete) - { - if (oldestOccluded == nullptr) - { - oldestOccluded = probe; - } - else if (probe->mLastUpdateTime < oldestOccluded->mLastUpdateTime) - { - oldestOccluded = probe; - } - } - else - { - if (!did_update && - i < mReflectionProbeCount && - (oldestProbe == nullptr || - check_priority(probe, oldestProbe))) - { - oldestProbe = probe; - } - } - - if (realtime && - closestDynamic == nullptr && - probe->mCubeIndex != -1 && - probe->getIsDynamic()) - { - closestDynamic = probe; - } - } - - if (realtime && closestDynamic != nullptr) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - // update the closest dynamic probe realtime - // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames - closestDynamic->autoAdjustOrigin(); - - // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set - // lighting values etc - bool radiance_pass = isRadiancePass(); - mRadiancePass = mRealtimeRadiancePass; - for (U32 i = 0; i < 6; ++i) - { - updateProbeFace(closestDynamic, i, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); - } - mRealtimeRadiancePass = !mRealtimeRadiancePass; - - // restore "isRadiancePass" - mRadiancePass = radiance_pass; - } - - { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - mHeroProbe->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); - bool radiance_pass = isRadiancePass(); - mRadiancePass = true; - for (U32 i = 0; i < 6; ++i) - { - updateProbeFace(mHeroProbe, i, mHeroProbeResolution, mHeroArray, mMipChain, mHeroProbeCount); - } - - // restore "isRadiancePass" - mRadiancePass = radiance_pass; - } - - static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); - if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) - { - if (sLevel == 0) - { // when probes are disabled don't update the default probe more often than the prescribed update period - oldestProbe = nullptr; - } - } - else if (sLevel > 0) - { // when probes are enabled don't update the default probe less often than the prescribed update period - oldestProbe = mDefaultProbe; - } - - // switch to updating the next oldest probe - if (!did_update && oldestProbe != nullptr) - { - LLReflectionMap* probe = oldestProbe; - llassert(probe->mCubeIndex != -1); - - probe->autoAdjustOrigin(); - - mUpdatingProbe = probe; - 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; - } -} - -LLReflectionMap* LLHeroProbeManager::addProbe(LLSpatialGroup* group) -{ - LLReflectionMap* probe = new LLReflectionMap(); - probe->mGroup = group; - - if (mDefaultProbe.isNull()) - { //safety check to make sure default probe is always first probe added - mDefaultProbe = new LLReflectionMap(); - mProbes.push_back(mDefaultProbe); - } - - llassert(mProbes[0] == mDefaultProbe); - - if (group) - { - probe->mOrigin = group->getOctreeNode()->getCenter(); - } - - if (gCubeSnapshot) - { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update - mCreateList.push_back(probe); - } - else - { - mProbes.push_back(probe); - } - - return probe; -} - -struct CompareProbeDepth -{ - bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs) - { - return lhs->mMinDepth < rhs->mMinDepth; - } -}; - -void LLHeroProbeManager::getReflectionMaps(std::vector& maps) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - - LLMatrix4a modelview; - modelview.loadu(gGLModelView); - LLVector4a oa; // scratch space for transformed origin - - U32 count = 0; - U32 lastIdx = 0; - for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i) - { - mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested - if (mProbes[i]->mCubeIndex != -1) + // Probe 0 is always our mirror probe. Probe N - 1 is our water probe. + mProbes[0]->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); + for (U32 j = 0; j < mProbes.size(); j++) { - if (!mProbes[i]->mOccluded && mProbes[i]->mComplete) + for (U32 i = 0; i < 6; ++i) { - maps[count++] = mProbes[i]; - modelview.affineTransform(mProbes[i]->mOrigin, oa); - mProbes[i]->mMinDepth = -oa.getF32ptr()[2] - mProbes[i]->mRadius; - mProbes[i]->mMaxDepth = -oa.getF32ptr()[2] + mProbes[i]->mRadius; + updateProbeFace(mProbes[j], i); } } - else - { - mProbes[i]->mProbeIndex = -1; - } - lastIdx = i; - } - - // set remaining probe indices to -1 - for (U32 i = lastIdx+1; i < mProbes.size(); ++i) - { - mProbes[i]->mProbeIndex = -1; - } - - if (count > 1) - { - std::sort(maps.begin(), maps.begin() + count, CompareProbeDepth()); - } - - for (U32 i = 0; i < count; ++i) - { - maps[i]->mProbeIndex = i; - } - - // null terminate list - if (count < maps.size()) - { - maps[count] = nullptr; - } -} - -LLReflectionMap* LLHeroProbeManager::registerSpatialGroup(LLSpatialGroup* group) -{ - if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) - { - OctreeNode* node = group->getOctreeNode(); - F32 size = node->getSize().getF32ptr()[0]; - if (size >= 15.f && size <= 17.f) - { - return addProbe(group); - } - } - - return nullptr; -} - -LLReflectionMap* LLHeroProbeManager::registerViewerObject(LLViewerObject* vobj) -{ - llassert(vobj != nullptr); - - LLReflectionMap* probe = new LLReflectionMap(); - probe->mViewerObject = vobj; - probe->mOrigin.load3(vobj->getPositionAgent().mV); - - if (gCubeSnapshot) - { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update - mCreateList.push_back(probe); - } - else - { - mProbes.push_back(probe); - } - - return probe; -} - -S32 LLHeroProbeManager::allocateCubeIndex() -{ - if (!mCubeFree.empty()) - { - S32 ret = mCubeFree.front(); - mCubeFree.pop_front(); - return ret; - } - - return -1; -} - -void LLHeroProbeManager::deleteProbe(U32 i) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - LLReflectionMap* probe = mProbes[i]; - - llassert(probe != mDefaultProbe); - - if (probe->mCubeIndex != -1) - { // mark the cube index used by this probe as being free - mCubeFree.push_back(probe->mCubeIndex); - } - if (mUpdatingProbe == probe) - { - mUpdatingProbe = nullptr; - mUpdatingFace = 0; - } - - // remove from any Neighbors lists - for (auto& other : probe->mNeighbors) - { - auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); - llassert(iter != other->mNeighbors.end()); - other->mNeighbors.erase(iter); - } - - mProbes.erase(mProbes.begin() + i); -} - - -void LLHeroProbeManager::doProbeUpdate() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - llassert(mUpdatingProbe != nullptr); - - updateProbeFace(mUpdatingProbe, mUpdatingFace, mProbeResolution, mTexture, mMipChain, mReflectionProbeCount); - - if (++mUpdatingFace == 6) - { - updateNeighbors(mUpdatingProbe); - mUpdatingFace = 0; - if (isRadiancePass()) - { - mUpdatingProbe->mComplete = true; - mUpdatingProbe = nullptr; - mRadiancePass = false; - } - else - { - mRadiancePass = true; - } } } @@ -583,53 +127,36 @@ void LLHeroProbeManager::doProbeUpdate() // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. // At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. // In effect this simulates single-bounce lighting. -void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount) +void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; - - LLRenderTarget* target = &mRenderTarget; - - S32 sourceIdx = probeCount; - - if (probeResolution == mHeroProbeResolution) - { - sourceIdx = 0; - target = &mHeroRenderTarget; - } mLightScale = 1.f; static LLCachedControl max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f); - if (!isRadiancePass() && probe->getAmbiance() > max_local_light_ambiance) + if (probe->getAmbiance() > max_local_light_ambiance) { mLightScale = max_local_light_ambiance / probe->getAmbiance(); } - if (probe == mDefaultProbe) { - touch_default_probe(probe); - gPipeline.pushRenderTypeMask(); //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_VOIDWATER, 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::RENDER_TYPE_AVATAR, LLPipeline::END_RENDER_TYPES); - probe->update(target->getWidth(), face); + probe->update(mRenderTarget.getWidth(), face); gPipeline.popRenderTypeMask(); } - else - { - probe->update(target->getWidth(), face); - } gPipeline.mRT = &gPipeline.mMainRT; - if (probe != mUpdatingProbe && probe->mType != LLReflectionMap::ProbeType::REFLECTION) - { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel - sourceIdx += 1; - } + S32 sourceIdx = mReflectionProbeCount; + + // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. + sourceIdx += 1; gGL.setColorMask(true, true); LLGLDepthTest depth(GL_FALSE, GL_FALSE); @@ -647,7 +174,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p gGL.loadIdentity(); gGL.flush(); - U32 res = probeResolution * 2; + U32 res = mProbeResolution * 2; static LLStaticHashedString resScale("resScale"); static LLStaticHashedString direction("direction"); @@ -659,20 +186,20 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p // perform a gaussian blur on the super sampled render before downsampling { gGaussianProgram.bind(); - gGaussianProgram.uniform1f(resScale, 1.f / (probeResolution * 2)); + 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); - target->bindTarget(); + mRenderTarget.bindTarget(); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - target->flush(); + mRenderTarget.flush(); // vertical gGaussianProgram.uniform2f(direction, 0.f, 1.f); - gGL.getTexUnit(diffuseChannel)->bind(target); + gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget); screen_rt->bindTarget(); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -680,7 +207,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p } - S32 mips = log2((F32)probeResolution) + 0.5f; + S32 mips = log2((F32)mProbeResolution) + 0.5f; gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); @@ -699,7 +226,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p } - gReflectionMipProgram.uniform1f(resScale, 1.f/(probeResolution*2)); + gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -711,11 +238,14 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p if (mip >= 0) { LL_PROFILE_GPU_ZONE("probe mip copy"); - cubeArray->bind(0); - + mTexture->bind(0); + //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); - - cubeArray->unbind(); + //if (i == 0) + //{ + //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + //} + mTexture->unbind(); } mMipChain[i].flush(); } @@ -733,14 +263,13 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p mMipChain[0].bindTarget(); static LLStaticHashedString sSourceIdx("sourceIdx"); - if (isRadiancePass()) { //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) gRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - cubeArray->bind(channel); + mTexture->bind(channel); gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -755,7 +284,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, i); - gRadianceGenProgram.uniform1i(sWidth, probeResolution); + gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); for (int cf = 0; cf < 6; ++cf) { // for each cube face @@ -780,50 +309,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p gRadianceGenProgram.unbind(); } - else - { - //generate irradiance map - gIrradianceGenProgram.bind(); - S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); - cubeArray->bind(channel); - - gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); - gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); - - mVertexBuffer->setBuffer(); - int start_mip = 0; - // find the mip target to start with based on irradiance map resolution - for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) - { - if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) - { - break; - } - } - - //for (int i = start_mip; i < mMipChain.size(); ++i) - { - int i = start_mip; - LL_PROFILE_GPU_ZONE("probe irradiance gen"); - glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); - for (int cf = 0; cf < 6; ++cf) - { // for each cube face - LLCoordFrame frame; - frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); - - F32 mat[16]; - frame.getOpenGLRotation(mat); - gGL.loadMatrix(mat); - - mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); - - S32 res = mMipChain[i].getWidth(); - mIrradianceMaps->bind(channel); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - cubeArray->bind(channel); - } - } - } mMipChain[0].flush(); @@ -831,59 +316,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, U32 p } } -void LLHeroProbeManager::reset() -{ - mReset = true; -} - -void LLHeroProbeManager::shift(const LLVector4a& offset) -{ - for (auto& probe : mProbes) - { - probe->mOrigin.add(offset); - } -} - -void LLHeroProbeManager::updateNeighbors(LLReflectionMap* probe) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - if (mDefaultProbe == probe) - { - return; - } - - //remove from existing neighbors - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear"); - - for (auto& other : probe->mNeighbors) - { - auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe); - llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly - other->mNeighbors.erase(iter); - } - - probe->mNeighbors.clear(); - } - - // search for new neighbors - if (probe->isRelevant()) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search"); - for (auto& other : mProbes) - { - if (other != mDefaultProbe && other != probe) - { - if (other->isRelevant() && probe->intersects(other)) - { - probe->mNeighbors.push_back(other); - other->mNeighbors.push_back(probe); - } - } - } - } -} - void LLHeroProbeManager::updateUniforms() { if (!LLPipeline::sReflectionProbesEnabled) @@ -892,229 +324,6 @@ void LLHeroProbeManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - - // structure for packing uniform buffer object - // see class3/deferred/reflectionProbeF.glsl - struct ReflectionProbeData - { - // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of - // the box probe - LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; - - // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space - LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; - - // extra parameters - // x - irradiance scale - // y - radiance scale - // z - fade in - // w - znear - LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; - - // indices used by probe: - // [i][0] - cubemap array index for this probe - // [i][1] - index into "refNeighbor" for probes that intersect this probe - // [i][2] - number of probes that intersect this probe, or -1 for no neighbors - // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) - GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; - - // list of neighbor indices - GLint refNeighbor[4096]; - - GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth - // numbrer of active refmaps - GLint refmapCount; - }; - - mReflectionMaps.resize(mReflectionProbeCount); - getReflectionMaps(mReflectionMaps); - - ReflectionProbeData rpd; - - F32 minDepth[256]; - - for (int i = 0; i < 256; ++i) - { - rpd.refBucket[i][0] = mReflectionProbeCount; - rpd.refBucket[i][1] = mReflectionProbeCount; - rpd.refBucket[i][2] = mReflectionProbeCount; - rpd.refBucket[i][3] = mReflectionProbeCount; - minDepth[i] = FLT_MAX; - } - - // load modelview matrix into matrix 4a - LLMatrix4a modelview; - modelview.loadu(gGLModelView); - LLVector4a oa; // scratch space for transformed origin - - S32 count = 0; - U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors - - LLEnvironment& environment = LLEnvironment::instance(); - LLSettingsSky::ptr_t psky = environment.getCurrentSky(); - - static LLCachedControl cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f); - static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust); - - bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); - F32 ambscale = is_ambiance_pass ? 0.f : 1.f; - F32 radscale = is_ambiance_pass ? 0.5f : 1.f; - - for (auto* refmap : mReflectionMaps) - { - if (refmap == nullptr) - { - break; - } - - if (refmap != mDefaultProbe) - { - // bucket search data - // theory of operation: - // 1. Determine minimum and maximum depth of each influence volume and store in mDepth (done in getReflectionMaps) - // 2. Sort by minimum depth - // 3. Prepare a bucket for each 1m of depth out to 256m - // 4. For each bucket, store the index of the nearest probe that might influence pixels in that bucket - // 5. In the shader, lookup the bucket for the pixel depth to get the index of the first probe that could possibly influence - // the current pixel. - int depth_min = llclamp(llfloor(refmap->mMinDepth), 0, 255); - int depth_max = llclamp(llfloor(refmap->mMaxDepth), 0, 255); - for (U32 i = depth_min; i <= depth_max; ++i) - { - if (refmap->mMinDepth < minDepth[i]) - { - minDepth[i] = refmap->mMinDepth; - rpd.refBucket[i][0] = refmap->mProbeIndex; - } - } - } - - llassert(refmap->mProbeIndex == count); - llassert(mReflectionMaps[refmap->mProbeIndex] == refmap); - - llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged - - { - 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; - } - - rpd.refIndex[count][0] = refmap->mCubeIndex; - llassert(nc % 4 == 0); - rpd.refIndex[count][1] = nc / 4; - rpd.refIndex[count][3] = refmap->mPriority; - - // for objects that are reflection probes, use the volume as the influence volume of the probe - // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres - if (refmap->getBox(rpd.refBox[count])) - { // negate priority to indicate this probe has a box influence volume - rpd.refIndex[count][3] = -rpd.refIndex[count][3]; - } - - rpd.refParams[count].set( - llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale - radscale, // radiance scale - refmap->mFadeIn, // fade in weight - oa.getF32ptr()[2] - refmap->mRadius); // z near - - S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors - { - //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); - //pack neghbor list - const U32 max_neighbors = 64; - U32 neighbor_count = 0; - - for (auto& neighbor : refmap->mNeighbors) - { - if (ni >= 4096) - { // out of space - break; - } - - GLint idx = neighbor->mProbeIndex; - if (idx == -1 || neighbor->mOccluded || neighbor->mCubeIndex == -1) - { - continue; - } - - // this neighbor may be sampled - rpd.refNeighbor[ni++] = idx; - - neighbor_count++; - if (neighbor_count >= max_neighbors) - { - break; - } - } - } - - if (nc == ni) - { - //no neighbors, tag as empty - rpd.refIndex[count][1] = -1; - } - else - { - rpd.refIndex[count][2] = ni - nc; - - // move the cursor forward - nc = ni; - if (nc % 4 != 0) - { // jump to next power of 4 for compatibility with ivec4 - nc += 4 - (nc % 4); - } - } - - - count++; - } - -#if 0 - { - // fill in gaps in refBucket - S32 probe_idx = mReflectionProbeCount; - - for (int i = 0; i < 256; ++i) - { - if (i < count) - { // for debugging, store depth of mReflectionsMaps[i] - rpd.refBucket[i][1] = (S32) (mReflectionMaps[i]->mDepth * 10); - } - - if (rpd.refBucket[i][0] == mReflectionProbeCount) - { - rpd.refBucket[i][0] = probe_idx; - } - else - { - probe_idx = rpd.refBucket[i][0]; - } - } - } -#endif - - rpd.refmapCount = count; - - //copy rpd into uniform buffer object - if (mUBO == 0) - { - glGenBuffers(1, &mUBO); - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); - glBindBuffer(GL_UNIFORM_BUFFER, mUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - } struct HeroProbeData { @@ -1124,22 +333,23 @@ void LLHeroProbeManager::updateUniforms() HeroProbeData hpd; + LLMatrix4a modelview; modelview.loadu(gGLModelView); - + LLVector4a oa; // scratch space for transformed origin oa.set(0, 0, 0, 0); hpd.heroProbeCount = 1; - modelview.affineTransform(mHeroProbe->mOrigin, oa); + modelview.affineTransform(mProbes[0]->mOrigin, oa); hpd.heroPosition[0].set(oa.getF32ptr()); //copy rpd into uniform buffer object if (mUBO == 0) { - glGenBuffers(1, &mHeroUBO); + glGenBuffers(1, &mUBO); } { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); - glBindBuffer(GL_UNIFORM_BUFFER, mHeroUBO); + glBindBuffer(GL_UNIFORM_BUFFER, mUBO); glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -1190,11 +400,11 @@ void LLHeroProbeManager::initReflectionMaps() { U32 count = LL_MAX_REFLECTION_PROBE_COUNT; - if (mTexture.isNull() || mReflectionProbeCount != count || mReset || mHeroArray.isNull()) + if (mTexture.isNull() || mReflectionProbeCount != count || mReset) { mReset = false; mReflectionProbeCount = count; - mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); + mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderHeroProbeResolution"), (U32)128, (U32)1024)); mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 mTexture = new LLCubeMapArray(); @@ -1205,25 +415,6 @@ void LLHeroProbeManager::initReflectionMaps() mIrradianceMaps = new LLCubeMapArray(); mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); - // reset probe state - mUpdatingFace = 0; - mUpdatingProbe = nullptr; - mRadiancePass = false; - mRealtimeRadiancePass = false; - - for (auto& probe : mProbes) - { - probe->mLastUpdateTime = 0.f; - probe->mComplete = false; - probe->mProbeIndex = -1; - probe->mCubeArray = nullptr; - probe->mCubeIndex = -1; - probe->mNeighbors.clear(); - } - - mCubeFree.clear(); - initCubeFree(); - if (mDefaultProbe.isNull()) { llassert(mProbes.empty()); // default probe MUST be the first probe created @@ -1233,6 +424,8 @@ void LLHeroProbeManager::initReflectionMaps() llassert(mProbes[0] == mDefaultProbe); + // For hero probes, we treat this as the main mirror probe. + mDefaultProbe->mCubeIndex = 0; mDefaultProbe->mCubeArray = mTexture; mDefaultProbe->mDistance = 64.f; @@ -1240,27 +433,7 @@ void LLHeroProbeManager::initReflectionMaps() mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); - mHeroProbeResolution = 128; - - // Revise when we have both water and mirrors in hero probes. - mHeroProbeCount = 1; - - mHeroArray = new LLCubeMapArray(); - - // We use an extra probe for scratch space on these. - mHeroArray->allocate(mHeroProbeResolution, 3, mHeroProbeCount + 1, true); - - if (mHeroProbe.isNull()) { - mHeroProbe = new LLReflectionMap(); - } - - mHeroProbe->mCubeIndex = 0; - mHeroProbe->mCubeArray = mHeroArray; - mHeroProbe->mDistance = 64.f; - mHeroProbe->mRadius = 4096.f; - mHeroProbe->mProbeIndex = 0; - touch_default_probe(mHeroProbe); - + mProbes.push_back(mDefaultProbe); } if (mVertexBuffer.isNull()) @@ -1294,28 +467,16 @@ void LLHeroProbeManager::cleanup() mTexture = nullptr; mIrradianceMaps = nullptr; - mHeroArray = nullptr; mProbes.clear(); - mKillList.clear(); - mCreateList.clear(); mReflectionMaps.clear(); - mUpdatingFace = 0; mDefaultProbe = nullptr; mUpdatingProbe = nullptr; - - mHeroProbe = nullptr; glDeleteBuffers(1, &mUBO); mUBO = 0; - - glDeleteBuffers(1, &mHeroUBO); - mHeroUBO = 0; - - // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state - initCubeFree(); } void LLHeroProbeManager::doOcclusion() diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index be761a680e..95e3963d1a 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -35,13 +35,7 @@ class LLSpatialGroup; class LLViewerObject; // number of reflection probes to keep in vram -#define LL_MAX_REFLECTION_PROBE_COUNT 256 - -// reflection probe resolution -#define LL_IRRADIANCE_MAP_RESOLUTION 64 - -// reflection probe mininum scale -#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; +#define LL_MAX_HERO_PROBE_COUNT 2 class alignas(16) LLHeroProbeManager { @@ -63,30 +57,6 @@ public: // maintain reflection probes void update(); - // add a probe for the given spatial group - LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr); - - // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size() - // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr. - // maps -- presized array of Reflection Map pointers - void getReflectionMaps(std::vector& maps); - - // called by LLSpatialGroup constructor - // If spatial group should receive a Reflection Probe, will create one for the specified spatial group - LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group); - - // presently hacked into LLViewerObject::setTE - // Used by LLViewerObjects that are Reflection Probes - // vobj must not be null - // Guaranteed to not return null - LLReflectionMap* registerViewerObject(LLViewerObject* vobj); - - // reset all state on the next update - void reset(); - - // called on region crossing to "shift" probes into new coordinate frame - void shift(const LLVector4a& offset); - // debug display, called from llspatialpartition if reflection // probe debug display is active void renderDebug(); @@ -94,28 +64,12 @@ public: // call once at startup to allocate cubemap arrays void initReflectionMaps(); - // 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; - - // initialize mCubeFree array to default values - void initCubeFree(); - - // delete the probe with the given index in mProbes - void deleteProbe(U32 i); - - // get a free cube index - // returns -1 if allocation failed - S32 allocateCubeIndex(); - - // update the neighbors of the given probe - void updateNeighbors(LLReflectionMap* probe); - + // update UBO used for rendering (call only once per render pipe flush) void updateUniforms(); @@ -132,8 +86,6 @@ private: // storage for reflection probe radiance maps (plus two scratch space cubemaps) LLPointer mTexture; - - LLPointer mHeroArray; // vertex buffer for pushing verts to filter shaders LLPointer mVertexBuffer; @@ -141,61 +93,28 @@ private: // storage for reflection probe irradiance maps LLPointer mIrradianceMaps; - // list of free cubemap indices - std::list mCubeFree; - - // perform an update on the currently updating Probe - void doProbeUpdate(); - // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face, U32 probeResolution, LLPointer cubeArray, std::vector &mipChain, U32 probeCount); + void updateProbeFace(LLReflectionMap* probe, U32 face); // list of active reflection maps std::vector > mProbes; - // list of reflection maps to kill - std::vector > mKillList; - - // list of reflection maps to create - std::vector > mCreateList; - // handle to UBO U32 mUBO = 0; - - // Hero UBO - U32 mHeroUBO = 0; // list of maps being used for rendering std::vector mReflectionMaps; LLReflectionMap* mUpdatingProbe = nullptr; - U32 mUpdatingFace = 0; - - // if true, we're generating the radiance map for the current probe, otherwise we're generating the irradiance map. - // Update sequence should be to generate the irradiance map from render of the world that has no irradiance, - // then generate the radiance map from a render of the world that includes irradiance. - // This should avoid feedback loops and ensure that the colors in the radiance maps match the colors in the environment. - bool mRadiancePass = false; - - // same as above, but for the realtime probe. - // Realtime probes should update all six sides of the irradiance map on "odd" frames and all six sides of the - // radiance map on "even" frames. - bool mRealtimeRadiancePass = false; LLPointer mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0) - - LLPointer mHeroProbe; // number of reflection probes to use for rendering U32 mReflectionProbeCount; - - U32 mHeroProbeCount; // resolution of reflection probes U32 mProbeResolution = 128; - U32 mHeroProbeResolution = 512; - // maximum LoD of reflection probes (mip levels - 1) F32 mMaxProbeLOD = 6.f; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 909c0f9aaa..4c951a9dea 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -642,6 +642,7 @@ void LLPipeline::cleanup() mCubeVB = NULL; mReflectionMapManager.cleanup(); + mHeroProbeManager.cleanup(); } //============================================================================ @@ -772,6 +773,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { // hacky -- allocate auxillary buffer gCubeSnapshot = TRUE; mReflectionMapManager.initReflectionMaps(); + mHeroProbeManager.initReflectionMaps(); mRT = &mAuxillaryRT; U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled allocateScreenBuffer(res, res, samples); @@ -2441,6 +2443,26 @@ void LLPipeline::doOcclusion(LLCamera& camera) gGL.setColorMask(true, true); } + + 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(); + + mHeroProbeManager.doOcclusion(); + gOcclusionCubeProgram.unbind(); + + gGL.setColorMask(true, true); + } if (LLPipeline::sUseOcclusion > 1 && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) @@ -3809,6 +3831,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) { //update reflection probe uniform mReflectionMapManager.updateUniforms(); + mHeroProbeManager.updateUniforms(); } U32 cur_type = 0; @@ -8461,14 +8484,14 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) mReflectionMapManager.mIrradianceMaps->bind(channel); bound = true; } - /* + channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); - if (channel > -1 && mReflectionMapManager.mHeroArray.notNull()) + if (channel > -1 && mHeroProbeManager.mTexture.notNull()) { - mReflectionMapManager.mHeroArray->bind(channel); + mHeroProbeManager.mTexture->bind(channel); bound = true; } - */ + if (bound) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index f3b35e0325..bfb9b95f4d 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -39,6 +39,7 @@ #include "lldrawable.h" #include "llrendertarget.h" #include "llreflectionmapmanager.h" +#include "llheroprobemanager.h" #include @@ -454,6 +455,7 @@ public: void handleShadowDetailChanged(); LLReflectionMapManager mReflectionMapManager; + LLHeroProbeManager mHeroProbeManager; private: void unloadShaders(); -- cgit v1.2.3 From d4254538d1bdd5d93a4eadea961a955ce79ab06f Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 21 Aug 2023 04:22:16 -0700 Subject: Further cleanup of the hero probe manager. DRTVWR-583 --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llheroprobemanager.cpp | 4 ---- indra/newview/pipeline.cpp | 20 -------------------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f5e7f865ab..8b9c5b50ae 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10390,6 +10390,17 @@ Value 0 + RenderHeroProbeResolution + + Comment + Resolution to render hero probes used for mirrors, water, etc. + Persist + 1 + Type + S32 + Value + 512 + RenderReflectionProbeVolumes Comment diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 5edf819fff..1773dffa8b 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -106,7 +106,6 @@ void LLHeroProbeManager::update() { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - // Probe 0 is always our mirror probe. Probe N - 1 is our water probe. mProbes[0]->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); for (U32 j = 0; j < mProbes.size(); j++) @@ -311,8 +310,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) } mMipChain[0].flush(); - - gIrradianceGenProgram.unbind(); } } @@ -466,7 +463,6 @@ void LLHeroProbeManager::cleanup() mMipChain.clear(); mTexture = nullptr; - mIrradianceMaps = nullptr; mProbes.clear(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4c951a9dea..9f8cd2c7fd 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2443,26 +2443,6 @@ void LLPipeline::doOcclusion(LLCamera& camera) gGL.setColorMask(true, true); } - - 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(); - - mHeroProbeManager.doOcclusion(); - gOcclusionCubeProgram.unbind(); - - gGL.setColorMask(true, true); - } if (LLPipeline::sUseOcclusion > 1 && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) -- cgit v1.2.3 From 869bb7f16ae3e931f11840332ab00715a4ef27af Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 21 Aug 2023 05:15:48 -0700 Subject: Readd occlusion culling for hero probes. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 19 ++----------------- indra/newview/pipeline.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 1773dffa8b..33a54c797e 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -132,23 +132,8 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mAuxillaryRT; mLightScale = 1.f; - static LLCachedControl max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f); - if (probe->getAmbiance() > max_local_light_ambiance) - { - mLightScale = max_local_light_ambiance / probe->getAmbiance(); - } - { - gPipeline.pushRenderTypeMask(); - - //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_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::END_RENDER_TYPES); - - probe->update(mRenderTarget.getWidth(), face); - - gPipeline.popRenderTypeMask(); - } + probe->update(mRenderTarget.getWidth(), face); gPipeline.mRT = &gPipeline.mMainRT; @@ -401,7 +386,7 @@ void LLHeroProbeManager::initReflectionMaps() { mReset = false; mReflectionProbeCount = count; - mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderHeroProbeResolution"), (U32)128, (U32)1024)); + mProbeResolution = nhpo2(1024); mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 mTexture = new LLCubeMapArray(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9f8cd2c7fd..4c951a9dea 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2443,6 +2443,26 @@ void LLPipeline::doOcclusion(LLCamera& camera) gGL.setColorMask(true, true); } + + 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(); + + mHeroProbeManager.doOcclusion(); + gOcclusionCubeProgram.unbind(); + + gGL.setColorMask(true, true); + } if (LLPipeline::sUseOcclusion > 1 && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) -- cgit v1.2.3 From 0eba1396dcc7ec5c32124dbfd48abb75c1a5b524 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 21 Aug 2023 07:59:06 -0700 Subject: Experiment with placement a bit when there's no drawable. DRTVWR-583 --- .../shaders/class3/deferred/softenLightF.glsl | 5 +- indra/newview/llheroprobemanager.cpp | 80 ++++++++++++++++++++-- indra/newview/llheroprobemanager.h | 10 ++- indra/newview/llvovolume.cpp | 7 +- indra/newview/pipeline.cpp | 22 ------ indra/newview/pipeline.h | 5 -- 6 files changed, 88 insertions(+), 41 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index e485c26e9b..742b52b074 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -213,13 +213,14 @@ void main() vec3 v = -normalize(pos.xyz); color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; + if (do_atmospherics) { color = atmosFragLightingLinear(color, additive, atten); } - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - color = texture(heroProbes, vec4(env_mat * refnormpersp, 0), 0).xyz; } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 33a54c797e..0d2e8da294 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -36,6 +36,11 @@ #include "llviewercontrol.h" #include "llenvironment.h" #include "llstartup.h" +#include "llagent.h" +#include "llagentcamera.h" +#include "llviewerwindow.h" +#include "llviewerjoystick.h" +#include "llviewermediafocus.h" extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; @@ -98,16 +103,60 @@ void LLHeroProbeManager::update() llassert(mProbes[0] == mDefaultProbe); - LLVector4a camera_pos; - camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); + LLVector3 camera_pos = LLViewerCamera::instance().getOrigin(); + LLVector4a probe_pos; + + LLVector3 focus_point; + + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); + + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + } + } + } + + probe_pos.load3(((focus_point + camera_pos) / 2).mV); static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); - // Probe 0 is always our mirror probe. Probe N - 1 is our water probe. - mProbes[0]->mOrigin.load3(LLViewerCamera::instance().mOrigin.mV); + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); + // Probe 0 is always our mirror probe. + mProbes[0]->mOrigin = probe_pos; for (U32 j = 0; j < mProbes.size(); j++) { for (U32 i = 0; i < 6; ++i) @@ -131,8 +180,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; - mLightScale = 1.f; - probe->update(mRenderTarget.getWidth(), face); gPipeline.mRT = &gPipeline.mMainRT; @@ -458,6 +505,9 @@ void LLHeroProbeManager::cleanup() glDeleteBuffers(1, &mUBO); mUBO = 0; + + mHeroList.clear(); + mNearestHero = nullptr; } void LLHeroProbeManager::doOcclusion() @@ -473,3 +523,19 @@ void LLHeroProbeManager::doOcclusion() } } } + +void LLHeroProbeManager::registerHeroDrawable(LLDrawable* drawablep) +{ + if (mHeroList.find(drawablep) == mHeroList.end()) + { + mHeroList.insert(drawablep); + } +} + +void LLHeroProbeManager::unregisterHeroDrawable(LLDrawable *drawablep) +{ + if (mHeroList.find(drawablep) != mHeroList.end()) + { + mHeroList.erase(drawablep); + } +} diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 95e3963d1a..c6df963cfd 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -30,6 +30,7 @@ #include "llrendertarget.h" #include "llcubemaparray.h" #include "llcubemap.h" +#include "lldrawable.h" class LLSpatialGroup; class LLViewerObject; @@ -67,6 +68,9 @@ public: // perform occlusion culling on all active reflection probes void doOcclusion(); + void registerHeroDrawable(LLDrawable* drawablep); + void unregisterHeroDrawable(LLDrawable* drawablep); + private: friend class LLPipeline; @@ -118,10 +122,10 @@ private: // maximum LoD of reflection probes (mip levels - 1) F32 mMaxProbeLOD = 6.f; - // amount to scale local lights during an irradiance map update (set during updateProbeFace and used by LLPipeline) - F32 mLightScale = 1.f; - // if true, reset all probe render state on the next update (for teleports and sky changes) bool mReset = false; + + LLDrawable::ordered_drawable_set_t mHeroList; + LLDrawable* mNearestHero; }; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 254e945243..2589beefe9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1045,7 +1045,7 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) updateReflectionProbePtr(); } - gPipeline.setMirror(mDrawable, isMirror()); + gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); updateRadius(); bool force_update = true; // avoid non-alpha mDistance update being optimized away @@ -4454,7 +4454,10 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u updateReflectionProbePtr(); - gPipeline.setMirror(mDrawable, isMirror()); + if (isMirror()) + gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + else + gPipeline.mHeroProbeManager.unregisterHeroDrawable(mDrawable); } void LLVOVolume::updateReflectionProbePtr() diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4c951a9dea..792cad02bd 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2783,23 +2783,6 @@ void LLPipeline::markShift(LLDrawable *drawablep) } } -void LLPipeline::setMirror(LLDrawable *drawablep, bool is_mirror) -{ - if (drawablep && assertInitialized()) - { - if (is_mirror) - { - drawablep->setState(LLDrawable::MIRROR); - mMirrorList.insert(drawablep); - } - else - { - mMirrorList.erase(drawablep); - drawablep->clearState(LLDrawable::MIRROR); - } - } -} - void LLPipeline::shiftObjects(const LLVector3 &offset) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -5852,11 +5835,6 @@ void LLPipeline::findReferences(LLDrawable *drawablep) { LL_INFOS() << "In mRetexturedList" << LL_ENDL; } - - if (std::find(mMirrorList.begin(), mMirrorList.end(), drawablep) != mMirrorList.end()) - { - LL_INFOS() << "In mMirrorList" << LL_ENDL; - } if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index bfb9b95f4d..1361441844 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -358,7 +358,6 @@ public: void shiftObjects(const LLVector3 &offset); void setLight(LLDrawable *drawablep, bool is_light); - void setMirror(LLDrawable *drawablep, bool is_mirror); bool hasRenderBatches(const U32 type) const; LLCullResult::drawinfo_iterator beginRenderMap(U32 type); @@ -821,10 +820,6 @@ protected: LLDrawable::ordered_drawable_set_t mLights; light_set_t mNearbyLights; // lights near camera LLColor4 mHWLightColors[8]; - - - LLDrawable::ordered_drawable_set_t mMirrorList; - LLDrawable* mNearestMirror; ///////////////////////////////////////////// // -- cgit v1.2.3 From 316052024958dde817a8d0809c77e29ec4cef64c Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 24 Aug 2023 12:51:19 -0700 Subject: Fix the probe flashing, and avatars. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 9 ++++++++- indra/newview/llreflectionmap.cpp | 5 +++-- indra/newview/llreflectionmap.h | 2 +- indra/newview/llreflectionmapmanager.h | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 0d2e8da294..729603e960 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -157,6 +157,11 @@ void LLHeroProbeManager::update() LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); // Probe 0 is always our mirror probe. mProbes[0]->mOrigin = probe_pos; + + bool radiance_pass = gPipeline.mReflectionMapManager.isRadiancePass(); + + gPipeline.mReflectionMapManager.mRadiancePass = true; + for (U32 j = 0; j < mProbes.size(); j++) { for (U32 i = 0; i < 6; ++i) @@ -164,6 +169,8 @@ void LLHeroProbeManager::update() updateProbeFace(mProbes[j], i); } } + + gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; } } @@ -180,7 +187,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; - probe->update(mRenderTarget.getWidth(), face); + probe->update(mRenderTarget.getWidth(), face, true); gPipeline.mRT = &gPipeline.mMainRT; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index efaf068bd2..022b7d11d8 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -49,7 +49,7 @@ LLReflectionMap::~LLReflectionMap() } } -void LLReflectionMap::update(U32 resolution, U32 face) +void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; mLastUpdateTime = gFrameTimeSeconds; @@ -63,7 +63,8 @@ void LLReflectionMap::update(U32 resolution, U32 face) { resolution /= 2; } - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic()); + + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic() || force_dynamic); } void LLReflectionMap::autoAdjustOrigin() diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 831a6358ee..a23bdc3a98 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -52,7 +52,7 @@ public: // update this environment map // resolution - size of cube map to generate - void update(U32 resolution, U32 face); + void update(U32 resolution, U32 face, bool force_dynamic = false); // for volume partition probes, try to place this probe in the best spot void autoAdjustOrigin(); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 7b17112814..4ef6c5fdff 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -104,6 +104,7 @@ public: private: friend class LLPipeline; + friend class LLHeroProbeManager; // initialize mCubeFree array to default values void initCubeFree(); -- cgit v1.2.3 From fbecd348f897ee91a5639e7e9fe4f0578d72b8e2 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 29 Aug 2023 03:04:04 -0700 Subject: Add protocol level mirror support, and UI. --- indra/llprimitive/llprimitive.cpp | 39 ++++++++-- indra/llprimitive/llprimitive.h | 12 ++- indra/llprimitive/llprimtexturelist.cpp | 10 --- indra/llprimitive/llprimtexturelist.h | 1 - indra/llprimitive/lltextureentry.cpp | 10 --- indra/llprimitive/lltextureentry.h | 10 --- indra/newview/llheroprobemanager.cpp | 87 +++++++++++++--------- indra/newview/llpanelface.cpp | 17 ----- indra/newview/llpanelface.h | 2 - indra/newview/llpanelvolume.cpp | 34 +++++++++ indra/newview/llpanelvolume.h | 2 + indra/newview/llselectmgr.cpp | 41 ---------- indra/newview/llselectmgr.h | 1 - indra/newview/llviewerobject.cpp | 28 ++----- indra/newview/llviewerobject.h | 1 - indra/newview/llvovolume.cpp | 60 ++++++++------- indra/newview/llvovolume.h | 5 +- .../newview/skins/default/xui/en/floater_tools.xml | 10 ++- 18 files changed, 185 insertions(+), 185 deletions(-) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index b45ead92d3..703584ed62 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -404,11 +404,6 @@ S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) return mTextureList.setFullbright(index, fullbright); } -S32 LLPrimitive::setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target) -{ - return mTextureList.setRenderableTarget(te, target); -} - S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) { return mTextureList.setMediaFlags(index, media_flags); @@ -1828,6 +1823,40 @@ bool LLLightParams::fromLLSD(LLSD& sd) //============================================================================ +LLMirrorParams::LLMirrorParams() +{ + mType = PARAMS_MIRROR; +} + +BOOL LLMirrorParams::pack(LLDataPacker &dp) const +{ + return TRUE; +} + +BOOL LLMirrorParams::unpack(LLDataPacker &dp) +{ + return TRUE; +} + +bool LLMirrorParams::operator==(const LLNetworkData& data) const +{ + if (data.mType != PARAMS_REFLECTION_PROBE) + { + return false; + } + return true; +} + +void LLMirrorParams::copy(const LLNetworkData& data) +{ + const LLMirrorParams *param = (LLMirrorParams*)&data; + mType = param->mType; +} + +//============================================================================ + +//============================================================================ + LLReflectionProbeParams::LLReflectionProbeParams() { mType = PARAMS_REFLECTION_PROBE; diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 520c7c7ac8..1af9bca42e 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -109,6 +109,7 @@ public: PARAMS_EXTENDED_MESH = 0x70, PARAMS_RENDER_MATERIAL = 0x80, PARAMS_REFLECTION_PROBE = 0x90, + PARAMS_MIRROR = 0x100, }; public: @@ -172,6 +173,16 @@ public: F32 getCutoff() const { return mCutoff; } }; +class LLMirrorParams : public LLNetworkData +{ +public: + LLMirrorParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); +}; + extern const F32 REFLECTION_PROBE_MIN_AMBIANCE; extern const F32 REFLECTION_PROBE_MAX_AMBIANCE; extern const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE; @@ -485,7 +496,6 @@ public: virtual S32 setTETexGen(const U8 te, const U8 texgen); virtual S32 setTEShiny(const U8 te, const U8 shiny); virtual S32 setTEFullbright(const U8 te, const U8 fullbright); - virtual S32 setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target); virtual S32 setTEMediaFlags(const U8 te, const U8 flags); virtual S32 setTEGlow(const U8 te, const F32 glow); virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index 49b59e35cb..f4f08248b8 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -341,16 +341,6 @@ S32 LLPrimTextureList::setFullbright(const U8 index, const U8 fullbright) return TEM_CHANGE_NONE; } -S32 LLPrimTextureList::setRenderableTarget(const U8 index, const U8 target) -{ - if (index < mEntryList.size()) - { - return mEntryList[index]->setRenderableTarget((LLTextureEntry::eRenderableTarget)target); - } - - return TEM_CHANGE_NONE; -} - S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) { if (index < mEntryList.size()) diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 34b87d879f..49c636e40f 100644 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -102,7 +102,6 @@ public: S32 setTexGen(const U8 index, const U8 texgen); S32 setShiny(const U8 index, const U8 shiny); S32 setFullbright(const U8 index, const U8 t); - S32 setRenderableTarget(const U8 index, const U8 target); S32 setMediaFlags(const U8 index, const U8 media_flags); S32 setGlow(const U8 index, const F32 glow); S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index fdf3774bfa..ee2a4c769a 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -504,16 +504,6 @@ S32 LLTextureEntry::setFullbright(U8 fullbright) return TEM_CHANGE_NONE; } -S32 LLTextureEntry::setRenderableTarget(eRenderableTarget target) -{ - if (getRenderableTarget() != target) { - mRenderableTarget = target; - return TEM_CHANGE_TEXTURE; - } - - return TEM_CHANGE_NONE; -} - S32 LLTextureEntry::setShiny(U8 shiny) { shiny &= TEM_SHINY_MASK; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 2c0832e1d4..0935147688 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -80,12 +80,6 @@ public: TEX_GEN_SPHERICAL = 0x04, TEX_GEN_CYLINDRICAL = 0x06 } eTexGen; - - - typedef enum e_renderable_target { - RT_DISABLED = 0x00, - RT_MIRROR = 0x02 - } eRenderableTarget; LLTextureEntry(); LLTextureEntry(const LLUUID& tex_id); @@ -141,8 +135,6 @@ public: S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); - S32 setRenderableTarget(eRenderableTarget target); - virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -160,7 +152,6 @@ public: U8 getBumpmap() const { return mBump & TEM_BUMP_MASK; } U8 getFullbright() const { return (mBump>>TEM_FULLBRIGHT_SHIFT) & TEM_FULLBRIGHT_MASK; } - eRenderableTarget getRenderableTarget() const { return mRenderableTarget; } U8 getShiny() const { return (mBump>>TEM_SHINY_SHIFT) & TEM_SHINY_MASK; } U8 getBumpShiny() const { return mBump & TEM_BUMP_SHINY_MASK; } U8 getBumpShinyFullbright() const { return mBump; } @@ -242,7 +233,6 @@ protected: LLColor4 mColor; U8 mBump; // Bump map, shiny, and fullbright U8 mMediaFlags; // replace with web page, movie, etc. - eRenderableTarget mRenderableTarget; F32 mGlow; bool mMaterialUpdatePending; LLMaterialID mMaterialID; diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 729603e960..6374b10823 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -103,53 +103,71 @@ void LLHeroProbeManager::update() llassert(mProbes[0] == mDefaultProbe); - LLVector3 camera_pos = LLViewerCamera::instance().getOrigin(); - LLVector4a probe_pos; - LLVector3 focus_point; - - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) + if (mHeroList.empty()) + { + LLVector3 focus_point; + + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + + if (focus_point.isExactlyZero()) { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); + + focus_point.set(result.getF32ptr()); + } + else { - focus_point = face->getPositionAgent(); + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + } } } + + probe_pos.load3(((focus_point)).mV); } - - if (focus_point.isExactlyZero()) + else { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); - - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); - - focus_point.set(result.getF32ptr()); - } - else + // Get the nearest hero. + float distance = F32_MAX; + + for (auto drawable : mHeroList) { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) + if (drawable.notNull()) { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + if (drawable->mDistanceWRTCamera < distance) + { + probe_pos.load3(drawable->mXform.getPosition().mV); + } } } } - probe_pos.load3(((focus_point + camera_pos) / 2).mV); static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); @@ -464,7 +482,7 @@ void LLHeroProbeManager::initReflectionMaps() mDefaultProbe->mCubeIndex = 0; mDefaultProbe->mCubeArray = mTexture; - mDefaultProbe->mDistance = 64.f; + mDefaultProbe->mDistance = 12.f; mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); @@ -536,6 +554,7 @@ void LLHeroProbeManager::registerHeroDrawable(LLDrawable* drawablep) if (mHeroList.find(drawablep) == mHeroList.end()) { mHeroList.insert(drawablep); + LL_INFOS() << "Added hero drawable." << LL_ENDL; } } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 9233ec6277..25f42e6dae 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -596,17 +596,6 @@ void LLPanelFace::sendFullbright() LLSelectMgr::getInstance()->selectionSetFullbright( fullbright ); } -void LLPanelFace::sendMirror() -{ - LLCheckBoxCtrl* mCheckMirror = getChild("checkbox mirror"); - - if (!mCheckMirror) - return; - - LLTextureEntry::eRenderableTarget target = mCheckMirror->get() ? LLTextureEntry::RT_MIRROR : LLTextureEntry::RT_DISABLED; - LLSelectMgr::getInstance()->selectionSetRenderableTarget(target); -} - void LLPanelFace::sendColor() { @@ -3007,12 +2996,6 @@ void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata) self->sendFullbright(); } -void LLPanelFace::onCommitMirror(LLUICtrl* ctrl, void* userdata) -{ - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendMirror(); -} - // static void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata) { diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 0b7486232d..5cad8cefcf 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -139,7 +139,6 @@ protected: void sendShiny(U32 shininess); // applies and sends shininess void sendFullbright(); // applies and sends full bright - void sendMirror(); void sendGlow(); void alignTestureLayer(); @@ -229,7 +228,6 @@ protected: static void onCommitShiny( LLUICtrl* ctrl, void* userdata); static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); - static void onCommitMirror(LLUICtrl* ctrl, void* userdata); static void onCommitGlow( LLUICtrl* ctrl, void *userdata); static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index ed244f773c..d62a640b5c 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -114,6 +114,11 @@ BOOL LLPanelVolume::postBuild() getChild("FlexForceZ")->setValidateBeforeCommit(precommitValidate); } + // Mirror Parameters + { + childSetCommitCallback("Mirror Checkbox Ctrl", onCommitIsMirror, this); + } + // LIGHT Parameters { childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this); @@ -305,6 +310,10 @@ void LLPanelVolume::getState( ) getChildView("select_single")->setEnabled(true); } + BOOL is_mirror = volobjp && volobjp->isMirror(); + getChild("Mirror Checkbox Ctrl")->setValue(is_mirror); + getChildView("Mirror Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); + // Light properties BOOL is_light = volobjp && volobjp->getIsLight(); getChild("Light Checkbox Ctrl")->setValue(is_light); @@ -737,6 +746,25 @@ void LLPanelVolume::sendIsLight() LL_INFOS() << "update light sent" << LL_ENDL; } +void LLPanelVolume::sendIsMirror() +{ + LLViewerObject* objectp = mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + // Quick hack to set the mirror locally. + + gPipeline.mHeroProbeManager.registerHeroDrawable(volobjp->mDrawable); + + BOOL value = getChild("Mirror Checkbox Ctrl")->getValue(); + volobjp->setIsMirror(value); + LL_INFOS() << "update mirror sent" << LL_ENDL; +} + + void LLPanelVolume::sendIsReflectionProbe() { LLViewerObject* objectp = mObject; @@ -1403,6 +1431,12 @@ void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata ) self->sendIsLight(); } +void LLPanelVolume::onCommitIsMirror( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + self->sendIsMirror(); +} + // static void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp) { diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 01b7ebb75c..a658351624 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -58,6 +58,7 @@ public: void sendIsLight(); + void sendIsMirror(); // when an object is becoming a refleciton probe, present a dialog asking for confirmation // otherwise, send the reflection probe update immediately void sendIsReflectionProbe(); @@ -71,6 +72,7 @@ public: static void onCommitIsLight( LLUICtrl* ctrl, void* userdata); static void onCommitLight( LLUICtrl* ctrl, void* userdata); + static void onCommitIsMirror( LLUICtrl* ctrl, void* userdata); static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata); static void onCommitProbe(LLUICtrl* ctrl, void* userdata); void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 2b1b4b79b2..5c1a339570 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2355,47 +2355,6 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright) getSelection()->applyToObjects(&sendfunc); } -void LLSelectMgr::selectionSetRenderableTarget(LLTextureEntry::eRenderableTarget target) -{ - struct f : public LLSelectedTEFunctor - { - LLTextureEntry::eRenderableTarget mRenderableTarget; - - f(const LLTextureEntry::eRenderableTarget& t) : mRenderableTarget(t) {} - - bool apply(LLViewerObject* object, S32 te) - { - if (object->permModify()) - { - object->setTERenderableTarget(te, mRenderableTarget); - } - - return true; - } - } setfunc(target); - - getSelection()->applyToTEs(&setfunc); - - struct g : public LLSelectedObjectFunctor - { - LLTextureEntry::eRenderableTarget mRenderableTarget; - - g(const LLTextureEntry::eRenderableTarget& t) : mRenderableTarget(t) {} - - virtual bool apply(LLViewerObject* object) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - - return true; - } - } sendfunc(target); - - getSelection()->applyToObjects(&sendfunc); -} - // This function expects media_data to be a map containing relevant // media data name/value pairs (e.g. home_url, etc.) void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 8ce59c6654..327134a487 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -653,7 +653,6 @@ public: void selectionSetGlow(const F32 glow); void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1); void selectionRemoveMaterial(); - void selectionSetRenderableTarget(LLTextureEntry::eRenderableTarget target); void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); void selectionSetObjectName(const std::string& name); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 7871815fda..68162f83c0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5296,29 +5296,6 @@ S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright) return retval; } -S32 LLViewerObject::setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target) -{ - S32 retval = 0; - - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (target != tep->getRenderableTarget()) - { - retval = LLPrimitive::setTERenderableTarget(te, target); - setChanged(TEXTURE); - if (mDrawable.notNull() && retval) - { - //gPipeline.markMirror(mDrawable); - } - } - - return retval; -} - - S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags) { // this might need work for media type @@ -6251,6 +6228,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para { new_block = new LLReflectionProbeParams(); break; + } + case LLNetworkData::PARAMS_MIRROR: + { + new_block = new LLMirrorParams(); + break; } default: { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index fe33047218..a87644476f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -360,7 +360,6 @@ public: /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media ); // *FIXME: this confusingly acts upon a superset of setTETexGen's flags without absorbing its semantics /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny ); /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright ); - /*virtual*/ S32 setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target); /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags ); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2589beefe9..175ce93b14 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1045,7 +1045,10 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) updateReflectionProbePtr(); } - gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + if (isMirror()) + { + gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + } updateRadius(); bool force_update = true; // avoid non-alpha mDistance update being optimized away @@ -2369,16 +2372,6 @@ S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright) return res; } -S32 LLVOVolume::setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget mirror) -{ - S32 res = LLViewerObject::setTERenderableTarget(te, mirror); - if (res) - { - //gPipeline.markMirror(mDrawable); - } - return res; -} - S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) { S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump); @@ -3379,28 +3372,41 @@ F32 LLVOVolume::getLightCutoff() const } } -BOOL LLVOVolume::isMirror() const +bool LLVOVolume::setIsMirror(BOOL is_mirror) { - S32 faceCount = getNumFaces(); - - // Temporary hack to set the object to mirror. - for (int i = 0; i < faceCount; i++) + BOOL was_mirror = isMirror(); + if (is_mirror != was_mirror) { - const LLTextureEntry* te = getTE(i); - - if (te->getMaterialParams().notNull()) + if (is_mirror) { - LLViewerTexture* specularp = getTESpecularMap(0); - - if (specularp && specularp->getID() == "da7ecda1-e780-423f-ce27-26df7dc69cb6") - { - LL_INFOS() << "BELLADONNA OF SADNESS" << LL_ENDL; - return TRUE; - } + setParameterEntryInUse(LLNetworkData::PARAMS_MIRROR, TRUE, true); + } + else + { + setParameterEntryInUse(LLNetworkData::PARAMS_MIRROR, FALSE, true); } } - return FALSE; + updateMirrorDrawable(); + + return was_mirror != is_mirror; +} + +void LLVOVolume::updateMirrorDrawable() +{ + if (isMirror()) + { + gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + } + else + { + gPipeline.mHeroProbeManager.unregisterHeroDrawable(mDrawable); + } +} + +BOOL LLVOVolume::isMirror() const +{ + return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); } BOOL LLVOVolume::isReflectionProbe() const diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index cecf726763..32c89ddae2 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -209,7 +209,6 @@ public: /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override; /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override; /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override; - /*virtual*/ S32 setTERenderableTarget(const U8 te, const LLTextureEntry::eRenderableTarget target) override; /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override; /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override; /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override; @@ -295,6 +294,10 @@ public: F32 getLightRadius() const; F32 getLightFalloff(const F32 fudge_factor = 1.f) const; F32 getLightCutoff() const; + + // Mirrors + bool setIsMirror(BOOL is_mirror); + void updateMirrorDrawable(); // Reflection Probes bool setIsReflectionProbe(BOOL is_probe); diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 5e999ed245..4094a487a9 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2406,7 +2406,15 @@ even though the user gets a free copy. name="object_horizontal" top_pad="10" width="278" /> - + Date: Tue, 29 Aug 2023 05:08:47 -0700 Subject: Add a probe strength uniform for hero probes. On standard reflection probes this doesn't really do anything. DRTVWR-583 --- indra/llrender/llshadermgr.cpp | 1 + indra/llrender/llshadermgr.h | 1 + .../shaders/class1/interface/radianceGenF.glsl | 2 + indra/newview/llheroprobemanager.cpp | 73 +++++++--------------- indra/newview/llheroprobemanager.h | 7 ++- indra/newview/llreflectionmapmanager.cpp | 1 + indra/newview/llvovolume.cpp | 2 +- 7 files changed, 34 insertions(+), 53 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 6730a12d6c..8bb5be0332 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1460,6 +1460,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("cloud_variance"); mReservedUniforms.push_back("reflection_probe_ambiance"); mReservedUniforms.push_back("max_probe_lod"); + mReservedUniforms.push_back("probe_strength"); mReservedUniforms.push_back("sh_input_r"); mReservedUniforms.push_back("sh_input_g"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 53c8323cff..6a5243a898 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -278,6 +278,7 @@ public: REFLECTION_PROBE_AMBIANCE, // "reflection_probe_ambiance" REFLECTION_PROBE_MAX_LOD, // "max_probe_lod" + REFLECTION_PROBE_STRENGTH, // "probe_strength" SH_INPUT_L1R, // "sh_input_r" SH_INPUT_L1G, // "sh_input_g" SH_INPUT_L1B, // "sh_input_b" diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index 9ecdf0bf77..cb6f34713c 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -38,6 +38,7 @@ in vec3 vary_dir; uniform float mipLevel; uniform int u_width; uniform float max_probe_lod; +uniform float probe_strength; // ============================================================================================================= @@ -163,5 +164,6 @@ void main() { vec3 N = normalize(vary_dir); frag_color = max(prefilterEnvMap(N), vec4(0)); + frag_color.a *= probe_strength; } // ============================================================================================================= diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 6374b10823..c385c9a99f 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -104,68 +104,41 @@ void LLHeroProbeManager::update() llassert(mProbes[0] == mDefaultProbe); LLVector4a probe_pos; - - if (mHeroList.empty()) + LLVector3 camera_pos = LLViewerCamera::instance().mOrigin; { - LLVector3 focus_point; + // Get the nearest hero. + float distance = F32_MAX; - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } + if (mNearestHero.notNull()) + { + distance = mNearestHero->mDistanceWRTCamera; } - if (focus_point.isExactlyZero()) + for (auto drawable : mHeroList) { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); - - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); - - focus_point.set(result.getF32ptr()); - } - else + if (drawable.notNull() && drawable != mNearestHero) { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) + if (drawable->mDistanceWRTCamera < distance) { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + mIsInTransition = true; + mNearestHero = drawable; } } } - - probe_pos.load3(((focus_point)).mV); + } + + if (mIsInTransition && mHeroProbeStrength > 0.f) + { + mHeroProbeStrength -= 0.05f; } else { - // Get the nearest hero. - float distance = F32_MAX; + if (mNearestHero.notNull()) + probe_pos.set(mNearestHero->mXform.getPosition().mV[0], mNearestHero->mXform.getPosition().mV[1], camera_pos.mV[2]); - for (auto drawable : mHeroList) - { - if (drawable.notNull()) - { - if (drawable->mDistanceWRTCamera < distance) - { - probe_pos.load3(drawable->mXform.getPosition().mV); - } - } - } + + if (mHeroProbeStrength < 1.f) + mHeroProbeStrength += 0.05f; } static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); @@ -328,7 +301,8 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(channel); gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); - + gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength); + U32 res = mMipChain[0].getWidth(); for (int i = 0; i < mMipChain.size(); ++i) @@ -554,7 +528,6 @@ void LLHeroProbeManager::registerHeroDrawable(LLDrawable* drawablep) if (mHeroList.find(drawablep) == mHeroList.end()) { mHeroList.insert(drawablep); - LL_INFOS() << "Added hero drawable." << LL_ENDL; } } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index c6df963cfd..24246af3d3 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -117,15 +117,18 @@ private: U32 mReflectionProbeCount; // resolution of reflection probes - U32 mProbeResolution = 128; + U32 mProbeResolution = 1024; // maximum LoD of reflection probes (mip levels - 1) F32 mMaxProbeLOD = 6.f; + + F32 mHeroProbeStrength = 1.f; + bool mIsInTransition = false; // if true, reset all probe render state on the next update (for teleports and sky changes) bool mReset = false; LLDrawable::ordered_drawable_set_t mHeroList; - LLDrawable* mNearestHero; + LLPointer mNearestHero; }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e855be8fbd..61143c61e8 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -714,6 +714,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(channel); gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); + gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, 1.f); U32 res = mMipChain[0].getWidth(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6db1ae07de..3c3d8d5123 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1045,7 +1045,7 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) updateReflectionProbePtr(); } - if (isMirror()) + //if (isMirror()) { gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); } -- cgit v1.2.3 From 32d1984bf98dce6e4938534342e67dbc40fbb073 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 1 Sep 2023 08:28:57 -0700 Subject: Temporary data model shenanigans. Should help tweak and tune placement with direct community guidance. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 66 +++++++++++++++++++++++++++--------- indra/newview/llheroprobemanager.h | 8 ++--- indra/newview/llpanelvolume.cpp | 4 --- indra/newview/llviewerobject.cpp | 34 ++++++++++++++++++- indra/newview/llviewerobject.h | 4 +++ indra/newview/llvovolume.cpp | 22 ++++++++---- indra/newview/llvovolume.h | 1 + 7 files changed, 107 insertions(+), 32 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index c385c9a99f..166321930f 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -109,16 +109,16 @@ void LLHeroProbeManager::update() // Get the nearest hero. float distance = F32_MAX; - if (mNearestHero.notNull()) + if (mNearestHero != nullptr) { - distance = mNearestHero->mDistanceWRTCamera; + distance = mNearestHero->mDrawable->mDistanceWRTCamera; } - for (auto drawable : mHeroList) + for (auto drawable : mHeroVOList) { - if (drawable.notNull() && drawable != mNearestHero) + if (drawable != nullptr && drawable != mNearestHero && drawable->mDrawable.notNull()) { - if (drawable->mDistanceWRTCamera < distance) + if (drawable->mDrawable->mDistanceWRTCamera < distance) { mIsInTransition = true; mNearestHero = drawable; @@ -133,8 +133,41 @@ void LLHeroProbeManager::update() } else { - if (mNearestHero.notNull()) - probe_pos.set(mNearestHero->mXform.getPosition().mV[0], mNearestHero->mXform.getPosition().mV[1], camera_pos.mV[2]); + + if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) + { + + LLVector3 hero_pos = mNearestHero->mDrawable->mXform.getPosition(); + switch (mNearestHero->mirrorPlacementMode()) { + case 0: + probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]); + break; + case 1: + + probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]); + break; + case 2: + + probe_pos.set(hero_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]); + break; + + case 3: + // Find the nearest point relative to the camera on the VOVolume. + LLVector4a hit_pos; + bool hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), + LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), + -1, + FALSE, + FALSE, + FALSE, + NULL, + &hit_pos); + if (hit) + probe_pos = hit_pos; + + break; + } + } if (mHeroProbeStrength < 1.f) @@ -505,7 +538,7 @@ void LLHeroProbeManager::cleanup() glDeleteBuffers(1, &mUBO); mUBO = 0; - mHeroList.clear(); + mHeroVOList.clear(); mNearestHero = nullptr; } @@ -523,18 +556,19 @@ void LLHeroProbeManager::doOcclusion() } } -void LLHeroProbeManager::registerHeroDrawable(LLDrawable* drawablep) +void LLHeroProbeManager::registerHeroDrawable(LLVOVolume* drawablep) { - if (mHeroList.find(drawablep) == mHeroList.end()) - { - mHeroList.insert(drawablep); - } + if (mHeroVOList.find(drawablep) == mHeroVOList.end()) + { + mHeroVOList.insert(drawablep); + LL_INFOS() << "Mirror drawable registered." << LL_ENDL; + } } -void LLHeroProbeManager::unregisterHeroDrawable(LLDrawable *drawablep) +void LLHeroProbeManager::unregisterHeroDrawable(LLVOVolume* drawablep) { - if (mHeroList.find(drawablep) != mHeroList.end()) + if (mHeroVOList.find(drawablep) != mHeroVOList.end()) { - mHeroList.erase(drawablep); + mHeroVOList.erase(drawablep); } } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 24246af3d3..b817b2396f 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -68,8 +68,8 @@ public: // perform occlusion culling on all active reflection probes void doOcclusion(); - void registerHeroDrawable(LLDrawable* drawablep); - void unregisterHeroDrawable(LLDrawable* drawablep); + void registerHeroDrawable(LLVOVolume* drawablep); + void unregisterHeroDrawable(LLVOVolume* drawablep); private: friend class LLPipeline; @@ -128,7 +128,7 @@ private: // if true, reset all probe render state on the next update (for teleports and sky changes) bool mReset = false; - LLDrawable::ordered_drawable_set_t mHeroList; - LLPointer mNearestHero; + std::set mHeroVOList; + LLVOVolume* mNearestHero; }; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index d62a640b5c..74c02099f8 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -755,10 +755,6 @@ void LLPanelVolume::sendIsMirror() } LLVOVolume *volobjp = (LLVOVolume *)objectp; - // Quick hack to set the mirror locally. - - gPipeline.mHeroProbeManager.registerHeroDrawable(volobjp->mDrawable); - BOOL value = getChild("Mirror Checkbox Ctrl")->getValue(); volobjp->setIsMirror(value); LL_INFOS() << "update mirror sent" << LL_ENDL; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 59a61f0c63..7032ce41d5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1524,11 +1524,43 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, std::string temp_string; mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num ); + std::stringstream ss(temp_string); + std::string word; + bool mirror_detected = false; + while (ss >> word) + { + if (word == "Mirror") + { + mirror_detected = true; + mIsMirror = true; + } + else if (word == "XAlign" && mIsMirror) + { + mMirrorPlacementMode = 0; + } + else if (word == "YAlign" && mIsMirror) + { + mMirrorPlacementMode = 1; + } + else if (word == "ZAlign" && mIsMirror) + { + mMirrorPlacementMode = 2; + } + else if (word == "NearestPoint" && mIsMirror) + { + mMirrorPlacementMode = 3; + } + } + LLColor4U coloru; mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num); - + // alpha was flipped so that it zero encoded better coloru.mV[3] = 255 - coloru.mV[3]; + + if (mirror_detected) + coloru.mV[3] = 0; + mText->setColor(LLColor4(coloru)); mText->setString(temp_string); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 7175b088d9..c165f164a8 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -258,6 +258,7 @@ public: virtual BOOL hasLightTexture() const { return FALSE; } virtual BOOL isReflectionProbe() const { return FALSE; } virtual BOOL isMirror() const { return FALSE; } + virtual U8 mirrorPlacementMode() const { return 0; } // This method returns true if the object is over land owned by // the agent, one of its groups, or it encroaches and @@ -878,6 +879,9 @@ protected: F32 mPhysicsCost; F32 mLinksetPhysicsCost; + bool mIsMirror; + U8 mMirrorPlacementMode; + // If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap" bool mShouldShrinkWrap = false; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3c3d8d5123..23580c4ec0 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -249,6 +249,9 @@ LLVOVolume::~LLVOVolume() mTextureAnimp = NULL; delete mVolumeImpl; mVolumeImpl = NULL; + + if (mIsMirror) + gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); gMeshRepo.unregisterMesh(this); @@ -1045,9 +1048,9 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) updateReflectionProbePtr(); } - //if (isMirror()) + if (isMirror()) { - gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + gPipeline.mHeroProbeManager.registerHeroDrawable(this); } updateRadius(); @@ -3396,17 +3399,22 @@ void LLVOVolume::updateMirrorDrawable() { if (isMirror()) { - gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + gPipeline.mHeroProbeManager.registerHeroDrawable(this); } else { - gPipeline.mHeroProbeManager.unregisterHeroDrawable(mDrawable); + gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); } } BOOL LLVOVolume::isMirror() const { - return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); + return mIsMirror; +} + +U8 LLVOVolume::mirrorPlacementMode() const +{ + return mMirrorPlacementMode; } BOOL LLVOVolume::isReflectionProbe() const @@ -4461,9 +4469,9 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u updateReflectionProbePtr(); if (isMirror()) - gPipeline.mHeroProbeManager.registerHeroDrawable(mDrawable); + gPipeline.mHeroProbeManager.registerHeroDrawable(this); else - gPipeline.mHeroProbeManager.unregisterHeroDrawable(mDrawable); + gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); } void LLVOVolume::updateReflectionProbePtr() diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 32c89ddae2..848f455e2a 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -298,6 +298,7 @@ public: // Mirrors bool setIsMirror(BOOL is_mirror); void updateMirrorDrawable(); + U8 mirrorPlacementMode() const override; // Reflection Probes bool setIsReflectionProbe(BOOL is_probe); -- cgit v1.2.3 From 25aee5e983a8de712565d8241cbdb18da832a4d1 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 8 Sep 2023 15:54:52 -0700 Subject: Some more modes for mirrors to place the probe. DRTVWR-583 --- .../shaders/class3/deferred/softenLightF.glsl | 3 + indra/newview/llheroprobemanager.cpp | 165 +++++++++++++-------- indra/newview/llviewerobject.cpp | 93 ++++++++---- 3 files changed, 171 insertions(+), 90 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 742b52b074..2483355205 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -280,6 +280,9 @@ void main() // add radiance map applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); + + color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - spec.a) * 11).xyz * spec.rgb; + } color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 166321930f..64c9ab1527 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -105,75 +105,121 @@ void LLHeroProbeManager::update() LLVector4a probe_pos; LLVector3 camera_pos = LLViewerCamera::instance().mOrigin; + if (mHeroVOList.size() > 0) { - // Get the nearest hero. - float distance = F32_MAX; - - if (mNearestHero != nullptr) { - distance = mNearestHero->mDrawable->mDistanceWRTCamera; - } - - for (auto drawable : mHeroVOList) - { - if (drawable != nullptr && drawable != mNearestHero && drawable->mDrawable.notNull()) + if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { - if (drawable->mDrawable->mDistanceWRTCamera < distance) - { - mIsInTransition = true; - mNearestHero = drawable; + LLVector3 hero_pos = mNearestHero->getPosition(); + + // Make sure our camera is clamped to the hero's bounding box. + camera_pos.clamp(mNearestHero->getBoundingBoxAgent().getMinAgent(), mNearestHero->getBoundingBoxAgent().getMaxAgent()); + bool hit = false; + LLVector4a hit_pos; + LLVector3 focus_point; + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + LLQuaternion camera_rot; + + switch (mNearestHero->mirrorPlacementMode()) { + case 0: + probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]); + break; + case 1: + + probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]); + break; + case 2: + + probe_pos.set(hero_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]); + break; + + case 3: + // Find the nearest point relative to the camera on the VOVolume. + hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), + LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), + -1, + FALSE, + FALSE, + FALSE, + NULL, + &hit_pos); + if (hit) + probe_pos = hit_pos; + break; + + case 4: + probe_pos.load3(hero_pos.mV); + break; + case 5: + focus_point.set(hero_pos.mV[0] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[0], hero_pos.mV[1], hero_pos.mV[2]); + probe_pos.load3(focus_point.mV); + break; + case 6: + focus_point.set(hero_pos.mV[0] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[0], hero_pos.mV[1], hero_pos.mV[2]); + probe_pos.load3(focus_point.mV); + break; + case 7: + + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, NULL, &result); + + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + } + } + } + + probe_pos.load3(focus_point.mV); + + break; + case 8: + camera_rot.setAngleAxis(180, 0, 0, 1); + focus_point = camera_pos - hero_pos; + focus_point.rotVec(camera_rot); + probe_pos.load3((camera_pos + focus_point).mV); + break; } } + + mHeroProbeStrength = 1; } } - - if (mIsInTransition && mHeroProbeStrength > 0.f) - { - mHeroProbeStrength -= 0.05f; - } else { - - if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) - { - - LLVector3 hero_pos = mNearestHero->mDrawable->mXform.getPosition(); - switch (mNearestHero->mirrorPlacementMode()) { - case 0: - probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]); - break; - case 1: - - probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]); - break; - case 2: - - probe_pos.set(hero_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]); - break; - - case 3: - // Find the nearest point relative to the camera on the VOVolume. - LLVector4a hit_pos; - bool hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), - LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), - -1, - FALSE, - FALSE, - FALSE, - NULL, - &hit_pos); - if (hit) - probe_pos = hit_pos; - - break; - } - } - - - if (mHeroProbeStrength < 1.f) - mHeroProbeStrength += 0.05f; + probe_pos.load3(camera_pos.mV); } + static LLCachedControl sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1); static LLCachedControl sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3); @@ -224,7 +270,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); LLGLDisable blend(GL_BLEND); - + // downsample to placeholder map { gGL.matrixMode(gGL.MM_MODELVIEW); @@ -558,6 +604,7 @@ void LLHeroProbeManager::doOcclusion() void LLHeroProbeManager::registerHeroDrawable(LLVOVolume* drawablep) { + mNearestHero = drawablep; if (mHeroVOList.find(drawablep) == mHeroVOList.end()) { mHeroVOList.insert(drawablep); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 7032ce41d5..adb4683af0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -314,7 +314,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mLastUpdateCached(FALSE), mCachedMuteListUpdateTime(0), mCachedOwnerInMuteList(false), - mRiggedAttachedWarned(false) + mRiggedAttachedWarned(false), +mIsMirror(false), +mMirrorPlacementMode(3) { if (!is_global) { @@ -1148,6 +1150,61 @@ U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector return parent_id; } +void detectMirror(const std::string &str, bool &mirror, U8 &mode) +{ + + std::stringstream ss(str); + std::string word; + while (ss >> word) + { + if (word == "IsMirror") + { + mirror = true; + } + else if (word == "XAlign" && mirror) + { + LL_INFOS() << "Mirror wants camera X placement." << LL_ENDL; + mode = 0; + } + else if (word == "YAlign" && mirror) + { + LL_INFOS() << "Mirror wants camera Y placement." << LL_ENDL; + mode = 1; + } + else if (word == "ZAlign" && mirror) + { + LL_INFOS() << "Mirror wants camera Z placement." << LL_ENDL; + mode = 2; + } + else if (word == "NearestPoint" && mirror) + { + LL_INFOS() << "Mirror wants nearest point placement." << LL_ENDL; + mode = 3; + } + else if (word == "Center" && mirror) + { + LL_INFOS() << "Mirror wants center of object." << LL_ENDL; + mode = 4; + } + else if (word == "XMin" && mirror) + { + mode = 5; + } + else if (word == "XMax" && mirror) + { + mode = 6; + } + else if (word == "FocusPoint" && mirror) + { + mode = 7; + } + else if (word == "Reflected" && mirror) + { + mode = 8; + } + } +} + U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, @@ -1524,33 +1581,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, std::string temp_string; mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num ); - std::stringstream ss(temp_string); - std::string word; - bool mirror_detected = false; - while (ss >> word) - { - if (word == "Mirror") - { - mirror_detected = true; - mIsMirror = true; - } - else if (word == "XAlign" && mIsMirror) - { - mMirrorPlacementMode = 0; - } - else if (word == "YAlign" && mIsMirror) - { - mMirrorPlacementMode = 1; - } - else if (word == "ZAlign" && mIsMirror) - { - mMirrorPlacementMode = 2; - } - else if (word == "NearestPoint" && mIsMirror) - { - mMirrorPlacementMode = 3; - } - } + detectMirror(temp_string, mIsMirror, mMirrorPlacementMode); LLColor4U coloru; mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num); @@ -1558,9 +1589,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // alpha was flipped so that it zero encoded better coloru.mV[3] = 255 - coloru.mV[3]; - if (mirror_detected) - coloru.mV[3] = 0; - mText->setColor(LLColor4(coloru)); mText->setString(temp_string); @@ -1940,6 +1968,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, { std::string temp_string; dp->unpackString(temp_string, "Text"); + + detectMirror(temp_string, mIsMirror, mMirrorPlacementMode); + LLColor4U coloru; dp->unpackBinaryDataFixed(coloru.mV, 4, "Color"); coloru.mV[3] = 255 - coloru.mV[3]; -- cgit v1.2.3 From 091beab79872fbaf4e3e7de39c8e69ef08e5a1c7 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 8 Sep 2023 17:43:24 -0700 Subject: Even more placement modes. Reflected axis modes need work. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 93 +++++++++++++++++++++++++++++++++++- indra/newview/llviewerobject.cpp | 53 +++++++++++++++++--- 2 files changed, 138 insertions(+), 8 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 64c9ab1527..caeb9d4e8e 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -159,6 +159,22 @@ void LLHeroProbeManager::update() probe_pos.load3(focus_point.mV); break; case 7: + focus_point.set(hero_pos.mV[0], hero_pos.mV[1] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[1], hero_pos.mV[2]); + probe_pos.load3(focus_point.mV); + break; + case 8: + focus_point.set(hero_pos.mV[0], hero_pos.mV[1] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[1], hero_pos.mV[2]); + probe_pos.load3(focus_point.mV); + break; + case 9: + focus_point.set(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[2]); + probe_pos.load3(focus_point.mV); + break; + case 10: + focus_point.set(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[2]); + probe_pos.load3(focus_point.mV); + break; + case 11: if (obj && obj->mDrawable && obj->isSelected()) { // focus on selected media object @@ -202,12 +218,87 @@ void LLHeroProbeManager::update() probe_pos.load3(focus_point.mV); break; - case 8: + case 12: + + hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), + LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), + -1, + FALSE, + FALSE, + FALSE, + NULL, + &hit_pos); + if (hit) + { + hero_pos.mV[0] = hit_pos.getF32ptr()[0]; + hero_pos.mV[1] = hit_pos.getF32ptr()[1]; + hero_pos.mV[2] = hit_pos.getF32ptr()[2]; + } + + camera_rot.setAngleAxis(180, 1, 0, 0); + focus_point = camera_pos - hero_pos; + focus_point.rotVec(camera_rot); + probe_pos.load3((camera_pos + focus_point).mV); + break; + case 13: + + hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), + LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), + -1, + FALSE, + FALSE, + FALSE, + NULL, + &hit_pos); + if (hit) + { + hero_pos.mV[0] = hit_pos.getF32ptr()[0]; + hero_pos.mV[1] = hit_pos.getF32ptr()[1]; + hero_pos.mV[2] = hit_pos.getF32ptr()[2]; + } + + camera_rot.setAngleAxis(180, 0, 1, 0); + focus_point = camera_pos - hero_pos; + focus_point.rotVec(camera_rot); + probe_pos.load3((camera_pos + focus_point).mV); + break; + case 14: + + hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), + LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), + -1, + FALSE, + FALSE, + FALSE, + NULL, + &hit_pos); + if (hit) + { + hero_pos.mV[0] = hit_pos.getF32ptr()[0]; + hero_pos.mV[1] = hit_pos.getF32ptr()[1]; + hero_pos.mV[2] = hit_pos.getF32ptr()[2]; + } + camera_rot.setAngleAxis(180, 0, 0, 1); focus_point = camera_pos - hero_pos; focus_point.rotVec(camera_rot); probe_pos.load3((camera_pos + focus_point).mV); break; + case 15: + probe_pos.set(camera_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]); + break; + case 16: + probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]); + break; + case 17: + probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]); + break; + case 18: + probe_pos.load3(camera_pos.mV); + break; + case 19: + probe_pos.load3(((camera_pos + hero_pos) / 2).mV); + break; } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index adb4683af0..950c672a42 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1163,27 +1163,22 @@ void detectMirror(const std::string &str, bool &mirror, U8 &mode) } else if (word == "XAlign" && mirror) { - LL_INFOS() << "Mirror wants camera X placement." << LL_ENDL; mode = 0; } else if (word == "YAlign" && mirror) { - LL_INFOS() << "Mirror wants camera Y placement." << LL_ENDL; mode = 1; } else if (word == "ZAlign" && mirror) { - LL_INFOS() << "Mirror wants camera Z placement." << LL_ENDL; mode = 2; } else if (word == "NearestPoint" && mirror) { - LL_INFOS() << "Mirror wants nearest point placement." << LL_ENDL; mode = 3; } else if (word == "Center" && mirror) { - LL_INFOS() << "Mirror wants center of object." << LL_ENDL; mode = 4; } else if (word == "XMin" && mirror) @@ -1194,14 +1189,58 @@ void detectMirror(const std::string &str, bool &mirror, U8 &mode) { mode = 6; } - else if (word == "FocusPoint" && mirror) + else if (word == "YMin" && mirror) { mode = 7; } - else if (word == "Reflected" && mirror) + else if (word == "YMax" && mirror) { mode = 8; } + else if (word == "ZMin" && mirror) + { + mode = 9; + } + else if (word == "ZMax" && mirror) + { + mode = 10; + } + else if (word == "FocusPoint" && mirror) + { + mode = 11; + } + else if (word == "ReflectedX" && mirror) + { + mode = 12; + } + else if (word == "ReflectedY" && mirror) + { + mode = 13; + } + else if (word == "ReflectedZ" && mirror) + { + mode = 14; + } + else if (word == "XYAlign" && mirror) + { + mode = 15; + } + else if (word == "XZAlign" && mirror) + { + mode = 16; + } + else if (word == "ZYAlign" && mirror) + { + mode = 17; + } + else if (word == "XYZAlign" && mirror) + { + mode = 18; + } + else if (word == "XYZAlignCenter" && mirror) + { + mode = 19; + } } } -- cgit v1.2.3 From d4c75b9b765631c1ccfc369e765529aefe3e061a Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 8 Sep 2023 21:29:05 -0700 Subject: Mostly fixed placement math. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 210 ++++++++--------------------------- indra/newview/llviewerobject.cpp | 74 +----------- 2 files changed, 47 insertions(+), 237 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index caeb9d4e8e..f1906272b8 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -110,194 +110,57 @@ void LLHeroProbeManager::update() { if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { - LLVector3 hero_pos = mNearestHero->getPosition(); + LLVector3 hero_pos = mNearestHero->mDrawable->mXform.getWorldPosition(); - // Make sure our camera is clamped to the hero's bounding box. - camera_pos.clamp(mNearestHero->getBoundingBoxAgent().getMinAgent(), mNearestHero->getBoundingBoxAgent().getMaxAgent()); bool hit = false; LLVector4a hit_pos; LLVector3 focus_point; LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); LLQuaternion camera_rot; + F32 angleInRadians = 180 * DEG_TO_RAD; + + LLMatrix4 rotationMatrix; + + LLVector3 translatedPoint; + LLVector3 rotatedTranslatedPoint; + LLVector3 rotatedPoint; switch (mNearestHero->mirrorPlacementMode()) { case 0: - probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]); - break; - case 1: - probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]); - break; - case 2: + hero_pos.mV[1] = camera_pos.mV[1]; - probe_pos.set(hero_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]); - break; + rotationMatrix.rotate(angleInRadians, LLVector4(1, 0, 0, 0)); - case 3: - // Find the nearest point relative to the camera on the VOVolume. - hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), - LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), - -1, - FALSE, - FALSE, - FALSE, - NULL, - &hit_pos); - if (hit) - probe_pos = hit_pos; - break; + translatedPoint = camera_pos - hero_pos; + rotatedTranslatedPoint = translatedPoint * rotationMatrix; + rotatedPoint = rotatedTranslatedPoint + hero_pos; - case 4: - probe_pos.load3(hero_pos.mV); - break; - case 5: - focus_point.set(hero_pos.mV[0] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[0], hero_pos.mV[1], hero_pos.mV[2]); - probe_pos.load3(focus_point.mV); + probe_pos.load3(rotatedPoint.mV); break; - case 6: - focus_point.set(hero_pos.mV[0] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[0], hero_pos.mV[1], hero_pos.mV[2]); - probe_pos.load3(focus_point.mV); - break; - case 7: - focus_point.set(hero_pos.mV[0], hero_pos.mV[1] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[1], hero_pos.mV[2]); - probe_pos.load3(focus_point.mV); - break; - case 8: - focus_point.set(hero_pos.mV[0], hero_pos.mV[1] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[1], hero_pos.mV[2]); - probe_pos.load3(focus_point.mV); - break; - case 9: - focus_point.set(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2] - mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[2]); - probe_pos.load3(focus_point.mV); - break; - case 10: - focus_point.set(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2] + mNearestHero->getBoundingBoxAgent().getExtentLocal().mV[2]); - probe_pos.load3(focus_point.mV); - break; - case 11: - - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } - } - - if (focus_point.isExactlyZero()) - { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); - - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, NULL, &result); - - focus_point.set(result.getF32ptr()); - } - else - { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); - } - } - } + case 1: - probe_pos.load3(focus_point.mV); + hero_pos.mV[2] = camera_pos.mV[2]; - break; - case 12: + rotationMatrix.rotate(angleInRadians, LLVector4(0, 1, 0, 0)); - hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), - LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), - -1, - FALSE, - FALSE, - FALSE, - NULL, - &hit_pos); - if (hit) - { - hero_pos.mV[0] = hit_pos.getF32ptr()[0]; - hero_pos.mV[1] = hit_pos.getF32ptr()[1]; - hero_pos.mV[2] = hit_pos.getF32ptr()[2]; - } + translatedPoint = camera_pos - hero_pos; + rotatedTranslatedPoint = translatedPoint * rotationMatrix; + rotatedPoint = rotatedTranslatedPoint + hero_pos; - camera_rot.setAngleAxis(180, 1, 0, 0); - focus_point = camera_pos - hero_pos; - focus_point.rotVec(camera_rot); - probe_pos.load3((camera_pos + focus_point).mV); + probe_pos.load3(rotatedPoint.mV); break; - case 13: + case 2: - hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), - LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), - -1, - FALSE, - FALSE, - FALSE, - NULL, - &hit_pos); - if (hit) - { - hero_pos.mV[0] = hit_pos.getF32ptr()[0]; - hero_pos.mV[1] = hit_pos.getF32ptr()[1]; - hero_pos.mV[2] = hit_pos.getF32ptr()[2]; - } + hero_pos.mV[0] = camera_pos.mV[0]; - camera_rot.setAngleAxis(180, 0, 1, 0); - focus_point = camera_pos - hero_pos; - focus_point.rotVec(camera_rot); - probe_pos.load3((camera_pos + focus_point).mV); - break; - case 14: + rotationMatrix.rotate(angleInRadians, LLVector4(0, 0, 1, 0)); - hit = mNearestHero->lineSegmentIntersect(LLVector4a(camera_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]), - LLVector4a(hero_pos.mV[0], hero_pos.mV[1], hero_pos.mV[2]), - -1, - FALSE, - FALSE, - FALSE, - NULL, - &hit_pos); - if (hit) - { - hero_pos.mV[0] = hit_pos.getF32ptr()[0]; - hero_pos.mV[1] = hit_pos.getF32ptr()[1]; - hero_pos.mV[2] = hit_pos.getF32ptr()[2]; - } + translatedPoint = camera_pos - hero_pos; + rotatedTranslatedPoint = translatedPoint * rotationMatrix; + rotatedPoint = rotatedTranslatedPoint + hero_pos; - camera_rot.setAngleAxis(180, 0, 0, 1); - focus_point = camera_pos - hero_pos; - focus_point.rotVec(camera_rot); - probe_pos.load3((camera_pos + focus_point).mV); - break; - case 15: - probe_pos.set(camera_pos.mV[0], camera_pos.mV[1], hero_pos.mV[2]); - break; - case 16: - probe_pos.set(camera_pos.mV[0], hero_pos.mV[1], camera_pos.mV[2]); - break; - case 17: - probe_pos.set(hero_pos.mV[0], camera_pos.mV[1], camera_pos.mV[2]); - break; - case 18: - probe_pos.load3(camera_pos.mV); - break; - case 19: - probe_pos.load3(((camera_pos + hero_pos) / 2).mV); + probe_pos.load3(rotatedPoint.mV); break; } } @@ -345,6 +208,14 @@ void LLHeroProbeManager::update() // In effect this simulates single-bounce lighting. void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) { + // Make our object invisible. + + if (mNearestHero) + { + mNearestHero->setDrawableState(LLDrawable::FORCE_INVISIBLE, true); + gPipeline.markRebuild( mNearestHero->mDrawable, LLDrawable::REBUILD_ALL); + } + // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; @@ -353,7 +224,8 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) gPipeline.mRT = &gPipeline.mMainRT; S32 sourceIdx = mReflectionProbeCount; - + + // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. sourceIdx += 1; @@ -512,6 +384,12 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) mMipChain[0].flush(); } + + if (mNearestHero) + { + mNearestHero->clearDrawableState(LLDrawable::FORCE_INVISIBLE, true); + gPipeline.markRebuild( mNearestHero->mDrawable, LLDrawable::REBUILD_ALL); + } } void LLHeroProbeManager::updateUniforms() diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 950c672a42..dcdb66a6d4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1161,85 +1161,17 @@ void detectMirror(const std::string &str, bool &mirror, U8 &mode) { mirror = true; } - else if (word == "XAlign" && mirror) - { - mode = 0; - } - else if (word == "YAlign" && mirror) - { - mode = 1; - } - else if (word == "ZAlign" && mirror) - { - mode = 2; - } - else if (word == "NearestPoint" && mirror) - { - mode = 3; - } - else if (word == "Center" && mirror) - { - mode = 4; - } - else if (word == "XMin" && mirror) - { - mode = 5; - } - else if (word == "XMax" && mirror) - { - mode = 6; - } - else if (word == "YMin" && mirror) - { - mode = 7; - } - else if (word == "YMax" && mirror) - { - mode = 8; - } - else if (word == "ZMin" && mirror) - { - mode = 9; - } - else if (word == "ZMax" && mirror) - { - mode = 10; - } - else if (word == "FocusPoint" && mirror) - { - mode = 11; - } else if (word == "ReflectedX" && mirror) { - mode = 12; + mode = 0; } else if (word == "ReflectedY" && mirror) { - mode = 13; + mode = 1; } else if (word == "ReflectedZ" && mirror) { - mode = 14; - } - else if (word == "XYAlign" && mirror) - { - mode = 15; - } - else if (word == "XZAlign" && mirror) - { - mode = 16; - } - else if (word == "ZYAlign" && mirror) - { - mode = 17; - } - else if (word == "XYZAlign" && mirror) - { - mode = 18; - } - else if (word == "XYZAlignCenter" && mirror) - { - mode = 19; + mode = 2; } } } -- cgit v1.2.3 From 7761ebea4836e0e30148711159ea744bcaea28a9 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 8 Sep 2023 21:55:15 -0700 Subject: Update llheroprobemanager.cpp DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index f1906272b8..13faf13a0f 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -112,10 +112,8 @@ void LLHeroProbeManager::update() { LLVector3 hero_pos = mNearestHero->mDrawable->mXform.getWorldPosition(); - bool hit = false; LLVector4a hit_pos; LLVector3 focus_point; - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); LLQuaternion camera_rot; F32 angleInRadians = 180 * DEG_TO_RAD; -- cgit v1.2.3 From 1433434bf134b76220fa2c31c16f36459b463e32 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 8 Sep 2023 23:01:16 -0700 Subject: Update reflectionProbeF.glsl DRTVWR-583 --- .../app_settings/shaders/class3/deferred/reflectionProbeF.glsl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index adbf7abdd1..549ac50280 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -71,9 +71,6 @@ layout (std140) uniform ReflectionProbes // number of reflection probes present in refSphere int refmapCount; - - vec4 heroPosition[1]; - int heroProbeCount; }; // Inputs @@ -523,10 +520,6 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, v = env_mat * v; -#if defined(HERO_PROBES) - vec3 mirror = textureLod(heroProbes, vec4(v.xyz, 0), lod).rgb; -#endif - vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y; return ret.rgb; -- cgit v1.2.3 From d6f15179d1a5c7bdb8977652aee557b3bd051cf7 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sat, 9 Sep 2023 14:51:12 -0700 Subject: Remove the rebuild on the drawable. Wasn't working as expected anyways. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 13faf13a0f..7c616593fc 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -206,14 +206,6 @@ void LLHeroProbeManager::update() // In effect this simulates single-bounce lighting. void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) { - // Make our object invisible. - - if (mNearestHero) - { - mNearestHero->setDrawableState(LLDrawable::FORCE_INVISIBLE, true); - gPipeline.markRebuild( mNearestHero->mDrawable, LLDrawable::REBUILD_ALL); - } - // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; @@ -382,12 +374,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) mMipChain[0].flush(); } - - if (mNearestHero) - { - mNearestHero->clearDrawableState(LLDrawable::FORCE_INVISIBLE, true); - gPipeline.markRebuild( mNearestHero->mDrawable, LLDrawable::REBUILD_ALL); - } } void LLHeroProbeManager::updateUniforms() -- cgit v1.2.3 From 3ff3e1a3537a5d051180aaf6223f5ddd8b540d35 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 20 Sep 2023 14:57:25 -0700 Subject: Remove some unnecessary irradiance map bits, also fix the leak. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 12 +++--------- indra/newview/llheroprobemanager.h | 3 --- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 7c616593fc..687ebbf168 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -300,12 +300,9 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) { LL_PROFILE_GPU_ZONE("probe mip copy"); mTexture->bind(0); - //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); - //if (i == 0) - //{ - //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); - //} + mTexture->unbind(); } mMipChain[i].flush(); @@ -458,7 +455,7 @@ void LLHeroProbeManager::renderDebug() void LLHeroProbeManager::initReflectionMaps() { - U32 count = LL_MAX_REFLECTION_PROBE_COUNT; + U32 count = LL_MAX_HERO_PROBE_COUNT; if (mTexture.isNull() || mReflectionProbeCount != count || mReset) { @@ -472,9 +469,6 @@ void LLHeroProbeManager::initReflectionMaps() // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); - if (mDefaultProbe.isNull()) { llassert(mProbes.empty()); // default probe MUST be the first probe created diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index b817b2396f..30943f739b 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -94,9 +94,6 @@ private: // vertex buffer for pushing verts to filter shaders LLPointer mVertexBuffer; - // storage for reflection probe irradiance maps - LLPointer mIrradianceMaps; - // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face); -- cgit v1.2.3 From d092f3e1dc1c322a0c3c1e55b9b6e1792d6b0f59 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 25 Sep 2023 12:18:02 -0700 Subject: Get the average normal of the face. DRTVWR-583 --- indra/newview/llface.cpp | 27 +++++++++++++++++++++++++++ indra/newview/llface.h | 5 +++++ indra/newview/llheroprobemanager.cpp | 10 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index c1776705f9..4dd991ee60 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -488,6 +488,33 @@ U16 LLFace::getGeometry(LLStrider &vertices, LLStrider &no return mGeomIndex; } +LLVector3 LLFace::getAverageNormal() +{ + if (!mHasAverageNormal) + { + if (mVertexBuffer.notNull()) + { + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) + { + LLStrider normals; + mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount); + LLVector3 normal_total; + + for (int i = 0; i < mVertexBuffer->getNumVerts(); i++) + { + normal_total += *normals.get(); + normals++; + } + + mAverageNormal = normal_total / mVertexBuffer->getNumVerts(); + mHasAverageNormal = true; + } + } + } + + return mAverageNormal; +} + void LLFace::updateCenterAgent() { if (mDrawablep->isActive()) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index eb3b47d6d6..d4f4313073 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -176,6 +176,8 @@ public: LLStrider &normals, LLStrider &texCoords, LLStrider &indices); + + LLVector3 getAverageNormal(); S32 getColors(LLStrider &colors); S32 getIndices(LLStrider &indices); @@ -278,6 +280,9 @@ private: U32 mIndicesCount; U32 mIndicesIndex; // index into mVertexBuffer's index array S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS]; + + LLVector3 mAverageNormal; + bool mHasAverageNormal; LLXformMatrix* mXform; diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 687ebbf168..c3d7ce6e76 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -118,11 +118,20 @@ void LLHeroProbeManager::update() F32 angleInRadians = 180 * DEG_TO_RAD; LLMatrix4 rotationMatrix; + + rotationMatrix.rotate(angleInRadians, LLVector4(mNearestHero->mDrawable->getFace(0)->getAverageNormal())); LLVector3 translatedPoint; LLVector3 rotatedTranslatedPoint; LLVector3 rotatedPoint; + translatedPoint = camera_pos - hero_pos; + rotatedTranslatedPoint = translatedPoint * rotationMatrix; + rotatedPoint = rotatedTranslatedPoint + hero_pos; + + probe_pos.load3(rotatedPoint.mV); + + /* switch (mNearestHero->mirrorPlacementMode()) { case 0: @@ -161,6 +170,7 @@ void LLHeroProbeManager::update() probe_pos.load3(rotatedPoint.mV); break; } + */ } mHeroProbeStrength = 1; -- cgit v1.2.3 From 18b219cf83a1cd405cf36b9f58fc48f717409598 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 25 Sep 2023 19:20:46 -0700 Subject: Start removing the concept of placement mode - it's either a mirror or not. DRTVWR-583 --- indra/newview/llface.cpp | 31 ++++++++----------------------- indra/newview/llheroprobemanager.cpp | 5 +++-- indra/newview/llviewerobject.cpp | 31 +++++++++++++++++++------------ 3 files changed, 30 insertions(+), 37 deletions(-) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4dd991ee60..2c04224fa0 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -490,28 +490,6 @@ U16 LLFace::getGeometry(LLStrider &vertices, LLStrider &no LLVector3 LLFace::getAverageNormal() { - if (!mHasAverageNormal) - { - if (mVertexBuffer.notNull()) - { - if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) - { - LLStrider normals; - mVertexBuffer->getNormalStrider(normals, mGeomIndex, mGeomCount); - LLVector3 normal_total; - - for (int i = 0; i < mVertexBuffer->getNumVerts(); i++) - { - normal_total += *normals.get(); - normals++; - } - - mAverageNormal = normal_total / mVertexBuffer->getNumVerts(); - mHasAverageNormal = true; - } - } - } - return mAverageNormal; } @@ -1916,14 +1894,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, F32* normals = (F32*) norm.get(); LLVector4a* src = vf.mNormals; LLVector4a* end = src+num_vertices; - + + LLVector4a normal_total; + while (src < end) { LLVector4a normal; mat_normal.rotate(*src++, normal); normal.store4a(normals); + normal_total.add(normal); normals += 4; } + + normal_total.div(LLVector4a(num_vertices)); + + mAverageNormal = LLVector3(normal_total[0], normal_total[1], normal_total[2]); } if (rebuild_tangent) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index c3d7ce6e76..fe9f669365 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -110,7 +110,8 @@ void LLHeroProbeManager::update() { if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { - LLVector3 hero_pos = mNearestHero->mDrawable->mXform.getWorldPosition(); + + LLVector3 hero_pos = mNearestHero->mDrawable->getFace(mNearestHero->mirrorPlacementMode())->getPositionAgent(); LLVector4a hit_pos; LLVector3 focus_point; @@ -119,7 +120,7 @@ void LLHeroProbeManager::update() LLMatrix4 rotationMatrix; - rotationMatrix.rotate(angleInRadians, LLVector4(mNearestHero->mDrawable->getFace(0)->getAverageNormal())); + rotationMatrix.rotate(angleInRadians, LLVector4(mNearestHero->mDrawable->getFace(mNearestHero->mirrorPlacementMode())->getAverageNormal())); LLVector3 translatedPoint; LLVector3 rotatedTranslatedPoint; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index dcdb66a6d4..9ac9ef7ea6 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1161,18 +1161,25 @@ void detectMirror(const std::string &str, bool &mirror, U8 &mode) { mirror = true; } - else if (word == "ReflectedX" && mirror) - { - mode = 0; - } - else if (word == "ReflectedY" && mirror) - { - mode = 1; - } - else if (word == "ReflectedZ" && mirror) - { - mode = 2; - } + + if (mirror) + { + bool num = false; + std::string::const_iterator it = word.begin(); + while (it != word.end()) + { + num = std::isdigit(*it); + ++it; + + if (!num) + break; + } + + if (num) + { + mode = atoi(word.c_str()); + } + } } } -- cgit v1.2.3 From 80df1d681e7fd83fe0806f51a3f96275b10c0a5a Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 29 Sep 2023 04:11:25 -0700 Subject: Can you say, generic reflectors? DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 100 +++++++++++------------------------ 1 file changed, 32 insertions(+), 68 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index fe9f669365..59345ca35f 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -92,7 +92,7 @@ void LLHeroProbeManager::update() { U32 res = mProbeResolution; U32 count = log2((F32)res) + 0.5f; - + mMipChain.resize(count); for (int i = 0; i < count; ++i) { @@ -102,80 +102,44 @@ void LLHeroProbeManager::update() } llassert(mProbes[0] == mDefaultProbe); - + LLVector4a probe_pos; LLVector3 camera_pos = LLViewerCamera::instance().mOrigin; if (mHeroVOList.size() > 0) { + if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { - if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) - { + U8 mode = mNearestHero->mirrorPlacementMode(); + mode = llmin(mNearestHero->mDrawable->getNumFaces() - 1, mode); - LLVector3 hero_pos = mNearestHero->mDrawable->getFace(mNearestHero->mirrorPlacementMode())->getPositionAgent(); - - LLVector4a hit_pos; - LLVector3 focus_point; - LLQuaternion camera_rot; - F32 angleInRadians = 180 * DEG_TO_RAD; - - LLMatrix4 rotationMatrix; - - rotationMatrix.rotate(angleInRadians, LLVector4(mNearestHero->mDrawable->getFace(mNearestHero->mirrorPlacementMode())->getAverageNormal())); - - LLVector3 translatedPoint; - LLVector3 rotatedTranslatedPoint; - LLVector3 rotatedPoint; - - translatedPoint = camera_pos - hero_pos; - rotatedTranslatedPoint = translatedPoint * rotationMatrix; - rotatedPoint = rotatedTranslatedPoint + hero_pos; - - probe_pos.load3(rotatedPoint.mV); - - /* - switch (mNearestHero->mirrorPlacementMode()) { - case 0: - - hero_pos.mV[1] = camera_pos.mV[1]; - - rotationMatrix.rotate(angleInRadians, LLVector4(1, 0, 0, 0)); - - translatedPoint = camera_pos - hero_pos; - rotatedTranslatedPoint = translatedPoint * rotationMatrix; - rotatedPoint = rotatedTranslatedPoint + hero_pos; - - probe_pos.load3(rotatedPoint.mV); - break; - case 1: - - hero_pos.mV[2] = camera_pos.mV[2]; - - rotationMatrix.rotate(angleInRadians, LLVector4(0, 1, 0, 0)); - - translatedPoint = camera_pos - hero_pos; - rotatedTranslatedPoint = translatedPoint * rotationMatrix; - rotatedPoint = rotatedTranslatedPoint + hero_pos; - - probe_pos.load3(rotatedPoint.mV); - break; - case 2: - - hero_pos.mV[0] = camera_pos.mV[0]; - - rotationMatrix.rotate(angleInRadians, LLVector4(0, 0, 1, 0)); - - translatedPoint = camera_pos - hero_pos; - rotatedTranslatedPoint = translatedPoint * rotationMatrix; - rotatedPoint = rotatedTranslatedPoint + hero_pos; - - probe_pos.load3(rotatedPoint.mV); - break; - } - */ - } - - mHeroProbeStrength = 1; + LLFace *face = mNearestHero->mDrawable->getFace(mode); + LLVector3 hero_pos = face->getPositionAgent(); + + + // Calculate the average normal. + LLVector4a *posp = face->getViewerObject()->getVolume()->getVolumeFace(face->getTEOffset()).mPositions; + U16 *indp = face->getViewerObject()->getVolume()->getVolumeFace(face->getTEOffset()).mIndices; + // get first three vertices (first triangle) + LLVector4a v0 = posp[indp[0]]; + LLVector4a v1 = posp[indp[1]]; + LLVector4a v2 = posp[indp[2]]; + + v1.sub(v0); + v2.sub(v0); + LLVector3 face_normal = LLVector3(v1[0], v1[1], v1[2]) % LLVector3(v2[0], v2[1], v2[2]); + + face_normal.normalize(); + face_normal *= face->getXform()->getWorldRotation(); + + LLVector3 offset = camera_pos - hero_pos; + LLVector3 project = face_normal * (offset * face_normal); + LLVector3 reject = offset - project; + LLVector3 point = (reject - project) + hero_pos; + + probe_pos.load3(point.mV); } + + mHeroProbeStrength = 1; } else { -- cgit v1.2.3 From 052d5c2802fa427ad97bc26ed4ec114b7fd1b80e Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 29 Sep 2023 04:33:11 -0700 Subject: Wire up the debug settings. DRTVWR-583 --- indra/newview/app_settings/settings.xml | 13 ++++++++++++- indra/newview/llheroprobemanager.cpp | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f4e0682ee6..709dfd3844 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10421,8 +10421,19 @@ Type S32 Value - 512 + 1024 + RenderHeroProbeDistance + + Comment + Distance in meters for hero probes to render out to. + Persist + 1 + Type + F32 + Value + 16 + RenderReflectionProbeVolumes Comment diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 59345ca35f..dec75f5d2b 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -436,7 +436,7 @@ void LLHeroProbeManager::initReflectionMaps() { mReset = false; mReflectionProbeCount = count; - mProbeResolution = nhpo2(1024); + mProbeResolution = gSavedSettings.getS32("RenderHeroProbeResolution"); mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1 mTexture = new LLCubeMapArray(); @@ -457,7 +457,7 @@ void LLHeroProbeManager::initReflectionMaps() mDefaultProbe->mCubeIndex = 0; mDefaultProbe->mCubeArray = mTexture; - mDefaultProbe->mDistance = 12.f; + mDefaultProbe->mDistance = gSavedSettings.getF32("RenderHeroProbeDistance"); mDefaultProbe->mRadius = 4096.f; mDefaultProbe->mProbeIndex = 0; touch_default_probe(mDefaultProbe); -- cgit v1.2.3 From 1d3d94a514a74b41f1fafaef45e105774d5d8505 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 29 Sep 2023 16:25:25 -0700 Subject: Add probe near clipping. DRTVWR-583 --- indra/newview/app_settings/settings.xml | 11 +++++++++ indra/newview/llheroprobemanager.cpp | 41 +++++++++++++++------------------ indra/newview/llheroprobemanager.h | 2 +- indra/newview/llreflectionmap.cpp | 6 +++-- indra/newview/llreflectionmap.h | 2 +- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 709dfd3844..82545a5dda 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10434,6 +10434,17 @@ Value 16 + RenderHeroProbeNearClipOffset + + Comment + Distance offset in meters for hero probes to near clip. + Persist + 1 + Type + F32 + Value + 2.1 + RenderReflectionProbeVolumes Comment diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index dec75f5d2b..15b54ec6bc 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -83,8 +83,8 @@ void LLHeroProbeManager::update() if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB16F; - U32 targetRes = mProbeResolution * 4; // super sample + U32 color_fmt = GL_RGBA16F; + U32 targetRes = mProbeResolution; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -96,7 +96,7 @@ void LLHeroProbeManager::update() mMipChain.resize(count); for (int i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB16F); + mMipChain[i].allocate(res, res, GL_RGBA16F); res /= 2; } } @@ -105,6 +105,7 @@ void LLHeroProbeManager::update() LLVector4a probe_pos; LLVector3 camera_pos = LLViewerCamera::instance().mOrigin; + F32 near_clip = 0.1f; if (mHeroVOList.size() > 0) { if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) @@ -136,6 +137,8 @@ void LLHeroProbeManager::update() LLVector3 reject = offset - project; LLVector3 point = (reject - project) + hero_pos; + near_clip = abs(dist_vec(hero_pos, point)) - gSavedSettings.getF32("RenderHeroProbeNearClipOffset"); + probe_pos.load3(point.mV); } @@ -163,7 +166,7 @@ void LLHeroProbeManager::update() { for (U32 i = 0; i < 6; ++i) { - updateProbeFace(mProbes[j], i); + updateProbeFace(mProbes[j], i, near_clip); } } @@ -179,12 +182,12 @@ void LLHeroProbeManager::update() // The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain. // At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe. // In effect this simulates single-bounce lighting. -void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) +void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip) { // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; - probe->update(mRenderTarget.getWidth(), face, true); + probe->update(mRenderTarget.getWidth(), face, true, near_clip); gPipeline.mRT = &gPipeline.mMainRT; @@ -217,7 +220,8 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString znear("znear"); static LLStaticHashedString zfar("zfar"); - LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen; + LLRenderTarget *screen_rt = &gPipeline.mAuxillaryRT.screen; + LLRenderTarget *depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; // perform a gaussian blur on the super sampled render before downsampling { @@ -247,6 +251,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) gReflectionMipProgram.bind(); S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); + S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE); for (int i = 0; i < mMipChain.size(); ++i) { @@ -261,8 +266,11 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1])); } + gGL.getTexUnit(depthChannel)->bind(depth_rt, true); - gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2)); + gReflectionMipProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2)); + gReflectionMipProgram.uniform1f(znear, probe->getNearClip()); + gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP); gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -315,10 +323,12 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString sMipLevel("mipLevel"); static LLStaticHashedString sRoughness("roughness"); static LLStaticHashedString sWidth("u_width"); + static LLStaticHashedString sStrength("probe_strength"); gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, i); gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); + gRadianceGenProgram.uniform1f(sStrength, 1); for (int cf = 0; cf < 6; ++cf) { // for each cube face @@ -385,21 +395,6 @@ void LLHeroProbeManager::updateUniforms() glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } - -#if 0 - if (!gCubeSnapshot) - { - for (auto& probe : mProbes) - { - LLViewerObject* vobj = probe->mViewerObject; - if (vobj) - { - F32 time = (F32)gFrameTimeSeconds - probe->mLastUpdateTime; - vobj->setDebugText(llformat("%d/%d/%d/%.1f - %.1f/%.1f", probe->mCubeIndex, probe->mProbeIndex, (U32) probe->mNeighbors.size(), probe->mMinDepth, probe->mMaxDepth, time), time > 1.f ? LLColor4::white : LLColor4::green); - } - } - } -#endif } void LLHeroProbeManager::setUniforms() diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 30943f739b..4a243e6cf2 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -95,7 +95,7 @@ private: LLPointer mVertexBuffer; // update the specified face of the specified probe - void updateProbeFace(LLReflectionMap* probe, U32 face); + void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip); // list of active reflection maps std::vector > mProbes; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 07c712a9a6..06624e8fea 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -49,7 +49,7 @@ LLReflectionMap::~LLReflectionMap() } } -void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic) +void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; mLastUpdateTime = gFrameTimeSeconds; @@ -63,8 +63,10 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic) { resolution /= 2; } + + F32 clip = (near_clip > 0) ? near_clip : getNearClip(); - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic() || force_dynamic); + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic); } void LLReflectionMap::autoAdjustOrigin() diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index a23bdc3a98..e97b28c855 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -52,7 +52,7 @@ public: // update this environment map // resolution - size of cube map to generate - void update(U32 resolution, U32 face, bool force_dynamic = false); + void update(U32 resolution, U32 face, bool force_dynamic = false, F32 near_clip = -1.f); // for volume partition probes, try to place this probe in the best spot void autoAdjustOrigin(); -- cgit v1.2.3 From e612d70fad8c6ec9335c109223211d516ebdf6f4 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Fri, 6 Oct 2023 06:21:53 -0700 Subject: Fix for probe stealing, and also make sure we're not super sampling. DRTVWR-583 --- indra/newview/llheroprobemanager.cpp | 41 ++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 15b54ec6bc..91d5f9b800 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -108,6 +108,34 @@ void LLHeroProbeManager::update() F32 near_clip = 0.1f; if (mHeroVOList.size() > 0) { + // Find our nearest hero candidate. + + float last_distance = 99999.f; + + for (auto vo : mHeroVOList) + { + if (vo) + { + if (vo->mDrawable.notNull()) + { + if (vo->mDrawable->mDistanceWRTCamera < last_distance) + { + mNearestHero = vo; + last_distance = vo->mDrawable->mDistanceWRTCamera; + } + } + else + { + // Valid drawables only please. Unregister this one. + unregisterHeroDrawable(vo); + } + } + else + { + unregisterHeroDrawable(vo); + } + } + if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { U8 mode = mNearestHero->mirrorPlacementMode(); @@ -226,7 +254,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n // perform a gaussian blur on the super sampled render before downsampling { gGaussianProgram.bind(); - gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2)); + gGaussianProgram.uniform1f(resScale, 1.f / mProbeResolution); S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE); // horizontal @@ -521,12 +549,11 @@ void LLHeroProbeManager::doOcclusion() void LLHeroProbeManager::registerHeroDrawable(LLVOVolume* drawablep) { - mNearestHero = drawablep; - if (mHeroVOList.find(drawablep) == mHeroVOList.end()) - { - mHeroVOList.insert(drawablep); - LL_INFOS() << "Mirror drawable registered." << LL_ENDL; - } + if (mHeroVOList.find(drawablep) == mHeroVOList.end()) + { + mHeroVOList.insert(drawablep); + LL_INFOS() << "Mirror drawable registered." << LL_ENDL; + } } void LLHeroProbeManager::unregisterHeroDrawable(LLVOVolume* drawablep) -- cgit v1.2.3 From 55f597e2ec363b5cb22fa8f7f5694f7ef6a17772 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:28 -0700 Subject: DRTVWR-592: Allow using RGBA textures for terrain, as the texture uploader does not consolidate opaque textures --- indra/llimage/llimage.cpp | 2 +- indra/newview/llfloaterregioninfo.cpp | 2 +- indra/newview/skins/default/xui/en/notifications.xml | 4 ++-- indra/newview/skins/default/xui/en/panel_region_terrain.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 031471d1fe..a96b6601bd 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1110,7 +1110,7 @@ void LLImageRaw::composite( LLImageRaw* src ) return; } - llassert(3 == src->getComponents()); + llassert((3 == src->getComponents()) || (4 == src->getComponents())); llassert(3 == dst->getComponents()); if( 3 == dst->getComponents() ) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index da7a4733c7..49ed58e766 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1338,7 +1338,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() //LL_INFOS() << "texture detail " << i << " is " << width << "x" << height << "x" << components << LL_ENDL; - if (components != 3) + if (components != 3 && components != 4) { LLSD args; args["TEXTURE_NUM"] = i+1; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f77b235408..5404ece6b4 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3980,7 +3980,7 @@ Are you sure you want to return objects owned by [USER_NAME]? Couldn't set region textures: Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. -Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. fail @@ -3991,7 +3991,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller ima Couldn't set region textures: Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. -Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. - Terrain Textures (requires 1024x1024, 24 bit .tga files) + Terrain Textures (maximum size: 1024x1024) Date: Fri, 13 Oct 2023 09:56:34 -0700 Subject: DRTVWR-592: (WIP) Add material terrain selection to GUI --- indra/newview/llfloaterregioninfo.cpp | 83 ++++++++++++++++++++++ indra/newview/llfloaterregioninfo.h | 3 + indra/newview/llpanelface.cpp | 2 +- indra/newview/lltexturectrl.cpp | 60 +++++++++------- indra/newview/lltexturectrl.h | 32 ++++++--- .../skins/default/xui/en/panel_region_terrain.xml | 76 ++++++++++++++++++-- 6 files changed, 212 insertions(+), 44 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 49ed58e766..8c795432ea 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1394,12 +1394,20 @@ BOOL LLPanelRegionTerrainInfo::postBuild() initCtrl("terrain_raise_spin"); initCtrl("terrain_lower_spin"); + getChild("terrain_material_type")->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); initCtrl(buffer); } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + initCtrl(buffer); + } for(S32 i = 0; i < CORNER_COUNT; ++i) { @@ -1419,6 +1427,81 @@ BOOL LLPanelRegionTerrainInfo::postBuild() return LLPanelRegionInfo::postBuild(); } +enum class TerrainMaterialType +{ + TEXTURE, + PBR_MATERIAL, + COUNT +}; + +TerrainMaterialType material_type_from_index(S32 index) +{ + if (index == 0) + { + return TerrainMaterialType::TEXTURE; + } + if (index == 1) + { + return TerrainMaterialType::PBR_MATERIAL; + } + return TerrainMaterialType::COUNT; +} + +// virtual +void LLPanelRegionTerrainInfo::refresh() +{ + std::string buffer; + + bool has_material_assets = false; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + LLTextureCtrl* material_ctrl = getChild(buffer); + if (material_ctrl && material_ctrl->getImageAssetID().notNull()) + { + has_material_assets = true; + break; + } + } + + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) + { + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + material_type_ctrl->setEnabled(!(is_material_selected && has_material_assets)); + } +} + +void LLPanelRegionTerrainInfo::onSelectMaterialType() +{ + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (!material_type_ctrl) { return; } + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool show_texture_controls = material_type == TerrainMaterialType::TEXTURE; + const bool show_material_controls = material_type == TerrainMaterialType::PBR_MATERIAL; + std::string buffer; + LLTextureCtrl* texture_ctrl; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + texture_ctrl = getChild(buffer); + if (texture_ctrl) + { + texture_ctrl->setVisible(show_texture_controls); + } + } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + texture_ctrl = getChild(buffer); + if (texture_ctrl) + { + texture_ctrl->setVisible(show_material_controls); + } + } +} + // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index c34dbb62e8..7b22002806 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -258,6 +258,9 @@ public: //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button + void refresh() override; + void onSelectMaterialType(); + virtual BOOL sendUpdate(); static void onClickDownloadRaw(void*); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7d6015f557..ba379f77d8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -328,7 +328,7 @@ BOOL LLPanelFace::postBuild() pbr_ctrl->setImmediateFilterPermMask(PERM_NONE); pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); pbr_ctrl->setBakeTextureEnabled(false); - pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL); + pbr_ctrl->setInventoryPickType(EPickInventoryType::MATERIAL); } mTextureCtrl = getChild("texture control"); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 0dd1ff5483..ef58bba71e 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -176,7 +176,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mSetImageAssetIDCallback(NULL), mOnUpdateImageStatsCallback(NULL), mBakeTextureEnabled(FALSE), - mInventoryPickType(LLTextureCtrl::PICK_TEXTURE) + mInventoryPickType(EPickInventoryType::TEXTURE) { mCanApplyImmediately = can_apply_immediately; buildFromFile("floater_texture_ctrl.xml"); @@ -356,11 +356,11 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( bool is_material = cargo_type == DAD_MATERIAL; bool allow_dnd = false; - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { allow_dnd = is_material; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { allow_dnd = is_texture || is_mesh; } @@ -570,7 +570,7 @@ void LLFloaterTexturePicker::draw() mGLTFMaterial = NULL; if (mImageAssetID.notNull()) { - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID); llassert(mGLTFMaterial == nullptr || dynamic_cast(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr); @@ -901,7 +901,7 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) self->getChild("l_bake_use_texture_combo_box")->setVisible(index == 2 ? TRUE : FALSE); bool pipette_visible = (index == 0) - && (self->mInventoryPickType != LLTextureCtrl::PICK_MATERIAL); + && (self->mInventoryPickType != EPickInventoryType::MATERIAL); self->getChild("Pipette")->setVisible(pipette_visible); if (index == 2) @@ -966,15 +966,15 @@ void LLFloaterTexturePicker::onBtnAdd(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata; - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (self->mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL_TEXTURE, true); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (self->mInventoryPickType == EPickInventoryType::TEXTURE) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_IMAGE, true); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (self->mInventoryPickType == EPickInventoryType::MATERIAL) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL, true); } @@ -1229,16 +1229,16 @@ void LLFloaterTexturePicker::refreshLocalList() { mLocalScrollCtrl->clearRows(); - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == EPickInventoryType::MATERIAL) { LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } @@ -1248,18 +1248,18 @@ void LLFloaterTexturePicker::refreshInventoryFilter() { U32 filter_types = 0x0; - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == EPickInventoryType::MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } @@ -1294,13 +1294,13 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) onModeSelect(0, this); } -void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type) +void LLFloaterTexturePicker::setInventoryPickType(EPickInventoryType type) { mInventoryPickType = type; refreshLocalList(); refreshInventoryFilter(); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { getChild("Pipette")->setVisible(false); } @@ -1316,7 +1316,7 @@ void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryT setTitle(pick + mLabel); } - else if(mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if(mInventoryPickType == EPickInventoryType::MATERIAL) { setTitle(getString("pick_material")); } @@ -1352,16 +1352,16 @@ void LLFloaterTexturePicker::onPickerCallback(const std::vector& fi LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)handle.get(); self->mLocalScrollCtrl->clearRows(); - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (self->mInventoryPickType == EPickInventoryType::TEXTURE_MATERIAL) { LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (self->mInventoryPickType == EPickInventoryType::TEXTURE) { LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (self->mInventoryPickType == EPickInventoryType::MATERIAL) { LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } @@ -1374,7 +1374,7 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) if (inventory_item_id.notNull()) { LLToolPipette::getInstance()->setResult(TRUE, ""); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { // tes have no data about material ids // Plus gltf materials are layered with overrides, @@ -1425,7 +1425,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mShowLoadingPlaceholder( TRUE ), mOpenTexPreview(false), mBakeTextureEnabled(true), - mInventoryPickType(PICK_TEXTURE), + mInventoryPickType(p.pick_type), mImageAssetID(p.image_id), mDefaultImageAssetID(p.default_image_id), mDefaultImageName(p.default_image_name), @@ -1680,7 +1680,7 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) if (!mOpenTexPreview) { showPicker(FALSE); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { //grab materials first... LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL)); @@ -1860,11 +1860,11 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, bool is_material = cargo_type == DAD_MATERIAL; bool allow_dnd = false; - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == EPickInventoryType::MATERIAL) { allow_dnd = is_material; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == EPickInventoryType::TEXTURE) { allow_dnd = is_texture || is_mesh; } @@ -2097,6 +2097,16 @@ LLSD LLTextureCtrl::getValue() const return LLSD(getImageAssetID()); } +namespace LLInitParam +{ + void TypeValues::declareValues() + { + declare("texture_material", EPickInventoryType::TEXTURE_MATERIAL); + declare("texture", EPickInventoryType::TEXTURE); + declare("material", EPickInventoryType::MATERIAL); + } +} + diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index c66e618782..28630d4ac4 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -64,10 +64,25 @@ bool get_is_predefined_texture(LLUUID asset_id); LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false); bool get_can_copy_texture(LLUUID image_id); +enum class EPickInventoryType +{ + TEXTURE_MATERIAL = 0, + TEXTURE = 1, + MATERIAL = 2, +}; + +namespace LLInitParam +{ + template<> + struct TypeValues : public TypeValuesHelper + { + static void declareValues(); + }; +} + ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl - class LLTextureCtrl : public LLUICtrl { @@ -79,19 +94,13 @@ public: TEXTURE_CANCEL } ETexturePickOp; - typedef enum e_pick_inventory_type - { - PICK_TEXTURE_MATERIAL = 0, - PICK_TEXTURE = 1, - PICK_MATERIAL = 2, - } EPickInventoryType; - public: struct Params : public LLInitParam::Block { Optional image_id; Optional default_image_id; Optional default_image_name; + Optional pick_type; Optional allow_no_texture; Optional can_apply_immediately; Optional no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty @@ -109,6 +118,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), + pick_type("pick_type", EPickInventoryType::TEXTURE), allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), @@ -260,7 +270,7 @@ private: S32 mLabelWidth; bool mOpenTexPreview; bool mBakeTextureEnabled; - LLTextureCtrl::EPickInventoryType mInventoryPickType; + EPickInventoryType mInventoryPickType; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -350,7 +360,7 @@ public: void setLocalTextureEnabled(BOOL enabled); void setBakeTextureEnabled(BOOL enabled); - void setInventoryPickType(LLTextureCtrl::EPickInventoryType type); + void setInventoryPickType(EPickInventoryType type); static void onPickerCallback(const std::vector& filenames, LLHandle handle); @@ -396,7 +406,7 @@ private: bool mCanApply; bool mCanPreview; bool mPreviewSettingChanged; - LLTextureCtrl::EPickInventoryType mInventoryPickType; + EPickInventoryType mInventoryPickType; texture_selected_callback mTextureSelectedCallback; diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 5e0dad445f..e36fb05647 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -76,29 +76,47 @@ left="8" top="30" width="460" /> + + + + - Terrain Textures (maximum size: 1024x1024) + width="200"> + Maximum size: 1024x1024 + + + + Date: Fri, 13 Oct 2023 09:56:39 -0700 Subject: DRTVWR-592: Use overrides, make mac build happy --- indra/newview/llfloaterregioninfo.h | 61 +++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 7b22002806..43a69e5804 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -75,9 +75,9 @@ class LLFloaterRegionInfo : public LLFloater public: - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ BOOL postBuild(); + BOOL postBuild() override; static void processEstateOwnerRequest(LLMessageSystem* msg, void**); @@ -98,7 +98,7 @@ public: static LLPanelRegionEnvironment* getPanelEnvironment(); // from LLPanel - virtual void refresh(); + void refresh() override; void onRegionChanged(); void requestRegionInfo(); @@ -145,7 +145,7 @@ public: virtual bool refreshFromRegion(LLViewerRegion* region); virtual bool estateUpdate(LLMessageSystem* msg) { return true; } - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); void enableButton(const std::string& btn_name, BOOL enable = TRUE); @@ -185,16 +185,15 @@ public: : LLPanelRegionInfo() {} ~LLPanelRegionGeneralInfo() {} - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; - // LLPanel - virtual BOOL postBuild(); + BOOL postBuild() override; void onBtnSet(); void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;} protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; void onClickKick(); void onKickCommit(const uuid_vec_t& ids); static void onClickKickAll(void* userdata); @@ -215,13 +214,13 @@ public: LLPanelRegionDebugInfo() : LLPanelRegionInfo(), mTargetAvatar() {} ~LLPanelRegionDebugInfo() {} - // LLPanel - virtual BOOL postBuild(); + + BOOL postBuild() override; - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; void onClickChooseAvatar(); void callbackAvatarID(const uuid_vec_t& ids, const std::vector names); @@ -248,9 +247,9 @@ public: LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {} ~LLPanelRegionTerrainInfo() {} - virtual BOOL postBuild(); // LLPanel + BOOL postBuild() override; - virtual bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator + bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region BOOL validateTextureSizes(); @@ -261,14 +260,15 @@ public: void refresh() override; void onSelectMaterialType(); - virtual BOOL sendUpdate(); - static void onClickDownloadRaw(void*); static void onClickUploadRaw(void*); static void onClickBakeTerrain(void*); bool callbackBakeTerrain(const LLSD& notification, const LLSD& response); bool callbackTextureHeights(const LLSD& notification, const LLSD& response); +protected: + BOOL sendUpdate() override; + private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; @@ -307,13 +307,12 @@ public: static void updateEstateName(const std::string& name); static void updateEstateOwnerName(const std::string& name); - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; virtual bool estateUpdate(LLMessageSystem* msg); - // LLPanel - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); - virtual void refresh(); + void refresh() override; void refreshFromEstate(); @@ -323,7 +322,7 @@ public: void setOwnerName(const std::string& name); protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; // confirmation dialog callback bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response); @@ -343,10 +342,9 @@ public: LLPanelEstateCovenant(); ~LLPanelEstateCovenant() {} - // LLPanel - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; virtual bool estateUpdate(LLMessageSystem* msg); // LLView overrides @@ -386,7 +384,7 @@ public: } EAssetStatus; protected: - virtual BOOL sendUpdate(); + BOOL sendUpdate() override; LLTextBox* mEstateNameText; LLTextBox* mEstateOwnerText; LLTextBox* mLastModifiedText; @@ -405,16 +403,19 @@ class LLPanelRegionExperiences : public LLPanelRegionInfo public: LLPanelRegionExperiences(){} - /*virtual*/ BOOL postBuild(); - virtual BOOL sendUpdate(); + BOOL postBuild() override; static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response); static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id); static void infoCallback(LLHandle handle, const LLSD& content); - bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; void sendPurchaseRequest()const; void processResponse( const LLSD& content ); + +protected: + BOOL sendUpdate() override; + private: void refreshRegionExperiences(); @@ -439,7 +440,7 @@ class LLPanelEstateAccess : public LLPanelRegionInfo public: LLPanelEstateAccess(); - virtual BOOL postBuild(); + BOOL postBuild() override; virtual void updateChild(LLUICtrl* child_ctrl); void updateControls(LLViewerRegion* region); @@ -448,7 +449,7 @@ public: void setPendingUpdate(bool pending) { mPendingUpdate = pending; } bool getPendingUpdate() { return mPendingUpdate; } - virtual bool refreshFromRegion(LLViewerRegion* region); + bool refreshFromRegion(LLViewerRegion* region) override; private: void onClickAddAllowedAgent(); -- cgit v1.2.3 From 410ab689919cd2915afc4d881b58b749d477fffc Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:44 -0700 Subject: DRTVWR-592: (WIP) Save PBR material terrain (does not yet render) --- indra/newview/llfloaterregioninfo.cpp | 101 ++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8c795432ea..e87064bc63 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -606,6 +606,26 @@ LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment() return panel; } +enum class TerrainMaterialType +{ + TEXTURE, + PBR_MATERIAL, + COUNT +}; + +TerrainMaterialType material_type_from_index(S32 index) +{ + if (index == 0) + { + return TerrainMaterialType::TEXTURE; + } + if (index == 1) + { + return TerrainMaterialType::PBR_MATERIAL; + } + return TerrainMaterialType::COUNT; +} + // static LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain() { @@ -1321,6 +1341,17 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { + // *TODO: Don't early-exit in PBR material terrain editing mode, and + // instead do some reasonable checks that the PBR material is compatible + // with the terrain rendering pipeline. Err on the side of permissive. + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) + { + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + if (is_material_selected) { return TRUE; } + } + static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { @@ -1427,26 +1458,6 @@ BOOL LLPanelRegionTerrainInfo::postBuild() return LLPanelRegionInfo::postBuild(); } -enum class TerrainMaterialType -{ - TEXTURE, - PBR_MATERIAL, - COUNT -}; - -TerrainMaterialType material_type_from_index(S32 index) -{ - if (index == 0) - { - return TerrainMaterialType::TEXTURE; - } - if (index == 1) - { - return TerrainMaterialType::PBR_MATERIAL; - } - return TerrainMaterialType::COUNT; -} - // virtual void LLPanelRegionTerrainInfo::refresh() { @@ -1518,18 +1529,31 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) getChild("region_text")->setValue(LLSD(region->getName())); LLVLComposition* compp = region->getComposition(); - LLTextureCtrl* texture_ctrl; + + // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set the IDs on both pickers for now. + // *TODO: Determine the asset type of IDs, to determine which editing mode to display. + LLTextureCtrl* asset_ctrl; std::string buffer; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); - if(texture_ctrl) + asset_ctrl = getChild(buffer); + if(asset_ctrl) { LL_DEBUGS() << "Detail Texture " << i << ": " << compp->getDetailTextureID(i) << LL_ENDL; LLUUID tmp_id(compp->getDetailTextureID(i)); - texture_ctrl->setImageAssetID(tmp_id); + asset_ctrl->setImageAssetID(tmp_id); + } + } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl) + { + LLUUID tmp_id(compp->getDetailTextureID(i)); + asset_ctrl->setImageAssetID(tmp_id); } } @@ -1596,17 +1620,36 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() } } - LLTextureCtrl* texture_ctrl; + LLTextureCtrl* asset_ctrl; std::string id_str; LLMessageSystem* msg = gMessageSystem; + // Use material IDs instead of texture IDs if all material IDs are set + S32 materials_used = 0; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); - if(texture_ctrl) + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) + { + ++materials_used; + } + } + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + if (materials_used == TERRAIN_TEXTURE_COUNT) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + } + else + { + buffer = llformat("texture_detail_%d", i); + asset_ctrl = getChild(buffer); + } + if(asset_ctrl) { - LLUUID tmp_id(texture_ctrl->getImageAssetID()); + LLUUID tmp_id(asset_ctrl->getImageAssetID()); tmp_id.toString(id_str); buffer = llformat("%d %s", i, id_str.c_str()); strings.push_back(buffer); -- cgit v1.2.3 From 2d10941459cf66d34073925c136d70bd6dbece3f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:49 -0700 Subject: DRTVWR-592: (WIP) More work on terrain texture editing GUI --- indra/newview/llfloaterregioninfo.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index e87064bc63..ff7012efb5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1624,15 +1624,24 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() std::string id_str; LLMessageSystem* msg = gMessageSystem; - // Use material IDs instead of texture IDs if all material IDs are set + // Use material IDs instead of texture IDs if all material IDs are set, AND the mode is set to PBR materials. S32 materials_used = 0; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); - if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) - { - ++materials_used; + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) + { + const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + if (is_material_selected) + { + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) + { + ++materials_used; + } + } } } for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) -- cgit v1.2.3 From 76bf3390eb119a7dfd879bbbc31b4d5e687aac8f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:55 -0700 Subject: DRTVWR-592: (WIP) Detect when terrain materials are loaded, use as fallback when terrain textures do not load --- indra/newview/lldrawpoolterrain.cpp | 32 +++++++- indra/newview/llfetchedgltfmaterial.h | 1 + indra/newview/llfloaterregioninfo.cpp | 6 +- indra/newview/llviewerregion.cpp | 16 ++-- indra/newview/llvlcomposition.cpp | 135 +++++++++++++++++++++++----------- indra/newview/llvlcomposition.h | 21 ++++-- 6 files changed, 150 insertions(+), 61 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 77189dceae..687ff5f462 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -121,8 +121,36 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures() LLVLComposition *compp = regionp->getComposition(); for (S32 i = 0; i < 4; i++) { - compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); - compp->mDetailTextures[i]->addTextureStats(1024.f * 1024.f); + constexpr LLGLTexture::EBoostLevel level = LLGLTexture::BOOST_TERRAIN; + constexpr float stats = 1024.f * 1024.f; + + LLPointer& tex = compp->mDetailTextures[i]; + llassert(tex.notNull()); + tex->setBoostLevel(level); + tex->addTextureStats(stats); + + LLPointer& mat = compp->mDetailMaterials[i]; + llassert(mat.notNull()); + if (mat->mBaseColorTexture) + { + mat->mBaseColorTexture->setBoostLevel(level); + mat->mBaseColorTexture->addTextureStats(stats); + } + if (mat->mNormalTexture) + { + mat->mNormalTexture->setBoostLevel(level); + mat->mNormalTexture->addTextureStats(stats); + } + if (mat->mMetallicRoughnessTexture) + { + mat->mMetallicRoughnessTexture->setBoostLevel(level); + mat->mMetallicRoughnessTexture->addTextureStats(stats); + } + if (mat->mEmissiveTexture) + { + mat->mEmissiveTexture->setBoostLevel(level); + mat->mEmissiveTexture->addTextureStats(stats); + } } } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 1668657281..ce4d33a213 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -49,6 +49,7 @@ public: void bind(LLViewerTexture* media_tex = nullptr); bool isFetching() const { return mFetching; } + bool isLoaded() const { return !mFetching; } // Textures used for fetching/rendering LLPointer mBaseColorTexture; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ff7012efb5..b5698c1d65 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1541,8 +1541,8 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) if(asset_ctrl) { LL_DEBUGS() << "Detail Texture " << i << ": " - << compp->getDetailTextureID(i) << LL_ENDL; - LLUUID tmp_id(compp->getDetailTextureID(i)); + << compp->getDetailAssetID(i) << LL_ENDL; + LLUUID tmp_id(compp->getDetailAssetID(i)); asset_ctrl->setImageAssetID(tmp_id); } } @@ -1552,7 +1552,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) asset_ctrl = getChild(buffer); if(asset_ctrl) { - LLUUID tmp_id(compp->getDetailTextureID(i)); + LLUUID tmp_id(compp->getDetailAssetID(i)); asset_ctrl->setImageAssetID(tmp_id); } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6b92b16ef4..9d3e63333e 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2962,20 +2962,20 @@ void LLViewerRegion::unpackRegionHandshake() // Get the 4 textures for land msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(0)); - compp->setDetailTextureID(0, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(0)); + compp->setDetailAssetID(0, tmp_id); msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(1)); - compp->setDetailTextureID(1, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(1)); + compp->setDetailAssetID(1, tmp_id); msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(2)); - compp->setDetailTextureID(2, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(2)); + compp->setDetailAssetID(2, tmp_id); msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id); - changed |= (tmp_id != compp->getDetailTextureID(3)); - compp->setDetailTextureID(3, tmp_id); + changed |= (tmp_id != compp->getDetailAssetID(3)); + compp->setDetailAssetID(3, tmp_id); // Get the start altitude and range values for land textures F32 tmp_f32; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 001fab7755..8480c9ce3d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -65,10 +65,10 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 mSurfacep = surfacep; // Load Terrain Textures - Original ones - setDetailTextureID(0, TERRAIN_DIRT_DETAIL); - setDetailTextureID(1, TERRAIN_GRASS_DETAIL); - setDetailTextureID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailTextureID(3, TERRAIN_ROCK_DETAIL); + setDetailAssetID(0, TERRAIN_DIRT_DETAIL); + setDetailAssetID(1, TERRAIN_GRASS_DETAIL); + setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); + setDetailAssetID(3, TERRAIN_ROCK_DETAIL); // Initialize the texture matrix to defaults. for (S32 i = 0; i < CORNER_COUNT; ++i) @@ -93,7 +93,7 @@ void LLVLComposition::setSurface(LLSurface *surfacep) } -void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) +void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) { if(id.isNull()) { @@ -104,6 +104,25 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; + // *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type. + // *TODO: As the material textures are loaded, prevent deletion + mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id); +} + +void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id) +{ + if(id.isNull()) + { + mDetailMaterials[corner] = nullptr; + } + else + { + // This is terrain material, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. + mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); + mDetailTextures[corner]->setNoDelete() ; + mRawImages[corner] = NULL; + } } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, @@ -149,10 +168,6 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus // simple height) - // Heights map into textures as 0-1 = first, 1-2 = second, etc. - // So we need to compress heights into this range. - const S32 NUM_TEXTURES = 4; - const F32 xyScaleInv = (1.f / xyScale); const F32 zScaleInv = (1.f / zScale); @@ -199,7 +214,7 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component twiddle *= noise_magnitude; - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range; + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; scaled_noisy_height = llmax(0.f, scaled_noisy_height); scaled_noisy_height = llmin(3.f, scaled_noisy_height); @@ -211,6 +226,37 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, static const U32 BASE_SIZE = 128; +// Boost the texture loading priority +// Return true when ready to use (i.e. texture is sufficiently loaded) +bool boost_texture_until_ready(LLPointer& tex) +{ + if (tex->getDiscardLevel() < 0) + { + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->addTextureStats(BASE_SIZE*BASE_SIZE); + return false; + } + if ((tex->getDiscardLevel() != 0 && + (tex->getWidth() < BASE_SIZE || + tex->getHeight() < BASE_SIZE))) + { + S32 width = tex->getFullWidth(); + S32 height = tex->getFullHeight(); + S32 min_dim = llmin(width, height); + S32 ddiscard = 0; + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->setMinDiscardLevel(ddiscard); + tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority + return false; + } + return true; +} + BOOL LLVLComposition::generateComposition() { @@ -220,35 +266,44 @@ BOOL LLVLComposition::generateComposition() return FALSE; } - for (S32 i = 0; i < 4; i++) + bool textures_ready = true; + for (S32 i = 0; i < ASSET_COUNT; i++) { - if (mDetailTextures[i]->getDiscardLevel() < 0) - { - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); - return FALSE; - } - if ((mDetailTextures[i]->getDiscardLevel() != 0 && - (mDetailTextures[i]->getWidth() < BASE_SIZE || - mDetailTextures[i]->getHeight() < BASE_SIZE))) - { - S32 width = mDetailTextures[i]->getFullWidth(); - S32 height = mDetailTextures[i]->getFullHeight(); - S32 min_dim = llmin(width, height); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; - } - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - mDetailTextures[i]->setMinDiscardLevel(ddiscard); - mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority - return FALSE; - } + if (!boost_texture_until_ready(mDetailTextures[i])) + { + textures_ready = false; + break; + } } + + if (textures_ready) + { + return TRUE; + } - return TRUE; + bool materials_ready = true; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const LLPointer& mat = mDetailMaterials[i]; + if (!mat.isLoaded() || + (mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) || + (mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) || + (mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) || + (mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture))) + { + materials_ready = false; + break; + } + } + + if (materials_ready) + { + return TRUE; + } + else + { + return FALSE; + } } BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, @@ -469,16 +524,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, return TRUE; } -LLUUID LLVLComposition::getDetailTextureID(S32 corner) +LLUUID LLVLComposition::getDetailAssetID(S32 corner) { + llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID()); return mDetailTextures[corner]->getID(); } -LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner) -{ - return mDetailTextures[corner]; -} - F32 LLVLComposition::getStartHeight(S32 corner) { return mStartHeight[corner]; diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 2dd04ac5a5..3e465efc95 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -28,10 +28,13 @@ #define LL_LLVLCOMPOSITION_H #include "llviewerlayer.h" -#include "llviewertexture.h" +#include "llpointer.h" class LLSurface; +class LLViewerFetchedTexture; +class LLFetchedGLTFMaterial; + class LLVLComposition : public LLViewerLayer { public: @@ -46,6 +49,10 @@ public: // Generate texture from composition values. BOOL generateTexture(const F32 x, const F32 y, const F32 width, const F32 height); + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. + static const S32 ASSET_COUNT = 4; + // Use these as indeces ito the get/setters below that use 'corner' enum ECorner { @@ -55,12 +62,12 @@ public: NORTHEAST = 3, CORNER_COUNT = 4 }; - LLUUID getDetailTextureID(S32 corner); - LLViewerFetchedTexture* getDetailTexture(S32 corner); + + LLUUID getDetailAssetID(S32 asset); F32 getStartHeight(S32 corner); F32 getHeightRange(S32 corner); - void setDetailTextureID(S32 corner, const LLUUID& id); + void setDetailAssetID(S32 asset, const LLUUID& id); void setStartHeight(S32 corner, F32 start_height); void setHeightRange(S32 corner, F32 range); @@ -73,8 +80,10 @@ protected: LLSurface *mSurfacep; BOOL mTexturesLoaded; - LLPointer mDetailTextures[CORNER_COUNT]; - LLPointer mRawImages[CORNER_COUNT]; + // TODO: Set flag to indicate whether the textures or materials loaded first + LLPointer mDetailTextures[ASSET_COUNT]; + LLPointer mRawImages[ASSET_COUNT]; + LLPointer mDetailMaterials[ASSET_COUNT]; F32 mStartHeight[CORNER_COUNT]; F32 mHeightRange[CORNER_COUNT]; -- cgit v1.2.3 From 94e824739b5e8408b52a03e5af8e3fb4e124c616 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:02 -0700 Subject: DRTVWR-592: Render PBR material terrain like legacy, using baseColor texture --- indra/newview/lldrawpoolterrain.cpp | 29 ++++- indra/newview/llvlcomposition.cpp | 239 ++++++++++++++++++++++-------------- indra/newview/llvlcomposition.h | 17 ++- 3 files changed, 187 insertions(+), 98 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 687ff5f462..9f0f9fd1b2 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -256,10 +256,31 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; - LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; - LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; - LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLViewerTexture *detail_texture0p; + LLViewerTexture *detail_texture1p; + LLViewerTexture *detail_texture2p; + LLViewerTexture *detail_texture3p; + BOOL use_textures = compp->texturesReady() || !compp->materialsReady(); + if (use_textures) + { + detail_texture0p = compp->mDetailTextures[0]; + detail_texture1p = compp->mDetailTextures[1]; + detail_texture2p = compp->mDetailTextures[2]; + detail_texture3p = compp->mDetailTextures[3]; + } + else // use materials + { + detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture; + detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture; + detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture; + detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture; + LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep; + if (!detail_texture0p) { detail_texture0p = blank; } + if (!detail_texture1p) { detail_texture1p = blank; } + if (!detail_texture2p) { detail_texture2p = blank; } + if (!detail_texture3p) { detail_texture3p = blank; } + } LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8480c9ce3d..9ad1a3dd17 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -34,6 +34,8 @@ #include "lltextureview.h" #include "llviewertexture.h" #include "llviewertexturelist.h" +#include "llfetchedgltfmaterial.h" +#include "llgltfmateriallist.h" #include "llviewerregion.h" #include "noise.h" #include "llregionhandle.h" // for from_region_handle @@ -59,8 +61,7 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : - LLViewerLayer(width, scale), - mParamsReady(FALSE) + LLViewerLayer(width, scale) { mSurfacep = surfacep; @@ -76,9 +77,11 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); } - mTexScaleX = 16.f; - mTexScaleY = 16.f; - mTexturesLoaded = FALSE; + + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + mMaterialTexturesSet[i] = false; + } } @@ -92,8 +95,19 @@ void LLVLComposition::setSurface(LLSurface *surfacep) mSurfacep = surfacep; } +LLPointer fetch_terrain_texture(const LLUUID& id) +{ + if (id.isNull()) + { + return nullptr; + } + + LLPointer tex = LLViewerTextureManager::getFetchedTexture(id); + tex->setNoDelete(); + return tex; +} -void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) +void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { if(id.isNull()) { @@ -101,28 +115,11 @@ void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) } // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. - mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); - mDetailTextures[corner]->setNoDelete() ; - mRawImages[corner] = NULL; - // *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type. - // *TODO: As the material textures are loaded, prevent deletion - mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id); -} - -void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id) -{ - if(id.isNull()) - { - mDetailMaterials[corner] = nullptr; - } - else - { - // This is terrain material, but we are not setting it as BOOST_TERRAIN - // since we will be manipulating it later as needed. - mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); - mDetailTextures[corner]->setNoDelete() ; - mRawImages[corner] = NULL; - } + mDetailTextures[asset] = fetch_terrain_texture(id); + mRawImages[asset] = NULL; + LLPointer& mat = mDetailMaterials[asset]; + mat = gGLTFMaterialList.getMaterial(id); + mMaterialTexturesSet[asset] = false; } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, @@ -228,82 +225,130 @@ static const U32 BASE_SIZE = 128; // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) -bool boost_texture_until_ready(LLPointer& tex) +// static +BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) { if (tex->getDiscardLevel() < 0) { - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->addTextureStats(BASE_SIZE*BASE_SIZE); - return false; + if (boost) + { + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->addTextureStats(BASE_SIZE*BASE_SIZE); + } + return FALSE; } if ((tex->getDiscardLevel() != 0 && (tex->getWidth() < BASE_SIZE || tex->getHeight() < BASE_SIZE))) { - S32 width = tex->getFullWidth(); - S32 height = tex->getFullHeight(); - S32 min_dim = llmin(width, height); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + if (boost) { - ddiscard++; - min_dim /= 2; + S32 width = tex->getFullWidth(); + S32 height = tex->getFullHeight(); + S32 min_dim = llmin(width, height); + S32 ddiscard = 0; + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->setMinDiscardLevel(ddiscard); + tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority } - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->setMinDiscardLevel(ddiscard); - tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority - return false; + return FALSE; } - return true; + return TRUE; } -BOOL LLVLComposition::generateComposition() +// Boost the loading priority of every known texture in the material +// Return true when ready to use (i.e. material and all textures within are sufficiently loaded) +// static +BOOL LLVLComposition::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) { + if (!mat->isLoaded()) + { + return FALSE; + } - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } + // Material is loaded, but textures may not be + if (!textures_set) + { + // *NOTE: These can sometimes be set to to nullptr due to + // updateTEMaterialTextures. For the sake of robustness, we emulate + // that fetching behavior by setting textures of null IDs to nullptr. + mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); + mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); + mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); + textures_set = true; - bool textures_ready = true; + return FALSE; + } + + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost)) + { + return FALSE; + } + + return TRUE; +} + +BOOL LLVLComposition::texturesReady(BOOL boost) +{ for (S32 i = 0; i < ASSET_COUNT; i++) { - if (!boost_texture_until_ready(mDetailTextures[i])) + if (!textureReady(mDetailTextures[i], boost)) { - textures_ready = false; - break; + return FALSE; } } + return TRUE; +} - if (textures_ready) - { - return TRUE; - } - - bool materials_ready = true; +BOOL LLVLComposition::materialsReady(BOOL boost) +{ for (S32 i = 0; i < ASSET_COUNT; i++) { - const LLPointer& mat = mDetailMaterials[i]; - if (!mat.isLoaded() || - (mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) || - (mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) || - (mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) || - (mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture))) + if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) { - materials_ready = false; - break; + return FALSE; } } + return TRUE; +} - if (materials_ready) +BOOL LLVLComposition::generateComposition() +{ + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } + + if (texturesReady(TRUE)) { return TRUE; } - else + + if (materialsReady(TRUE)) { - return FALSE; + return TRUE; } + + return FALSE; } BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, @@ -323,15 +368,28 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, // // These have already been validated by generateComposition. - U8* st_data[4]; - S32 st_data_size[4]; // for debugging + U8* st_data[ASSET_COUNT]; + S32 st_data_size[ASSET_COUNT]; // for debugging + + const bool use_textures = texturesReady(); - for (S32 i = 0; i < 4; i++) + for (S32 i = 0; i < ASSET_COUNT; i++) { if (mRawImages[i].isNull()) { // Read back a raw image for this discard level, if it exists - S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight()); + LLViewerFetchedTexture* tex; + if (use_textures) + { + tex = mDetailTextures[i]; + } + else + { + tex = mDetailMaterials[i]->mBaseColorTexture; + if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } + } + + S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) { @@ -339,31 +397,31 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, min_dim /= 2; } - BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ; - if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. + BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; + if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. { - if (mDetailTextures[i]->getFetchPriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage()) + if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP); - mDetailTextures[i]->forceToRefetchTexture(ddiscard); + tex->setBoostLevel(LLGLTexture::BOOST_MAP); + tex->forceToRefetchTexture(ddiscard); } if(delete_raw) { - mDetailTextures[i]->destroyRawImage() ; + tex->destroyRawImage() ; } - LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL; + LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } - mRawImages[i] = mDetailTextures[i]->getRawImage() ; + mRawImages[i] = tex->getRawImage() ; if(delete_raw) { - mDetailTextures[i]->destroyRawImage() ; + tex->destroyRawImage() ; } - if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE || - mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE || - mDetailTextures[i]->getComponents() != 3) + if (tex->getWidth(ddiscard) != BASE_SIZE || + tex->getHeight(ddiscard) != BASE_SIZE || + tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); @@ -514,7 +572,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - for (S32 i = 0; i < 4; i++) + for (S32 i = 0; i < ASSET_COUNT; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE); @@ -526,7 +584,10 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, LLUUID LLVLComposition::getDetailAssetID(S32 corner) { - llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID()); + llassert(mDetailTextures[corner] && mDetailMaterials[corner]); + // *HACK: Assume both the the material and texture were fetched in the same + // way using the same UUID. However, we may not know at this point which + // one will load. return mDetailTextures[corner]->getID(); } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 3e465efc95..af0cf9323c 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -30,6 +30,8 @@ #include "llviewerlayer.h" #include "llpointer.h" +#include "llimage.h" + class LLSurface; class LLViewerFetchedTexture; @@ -75,21 +77,26 @@ public: friend class LLDrawPoolTerrain; void setParamsReady() { mParamsReady = TRUE; } BOOL getParamsReady() const { return mParamsReady; } + BOOL texturesReady(BOOL boost = FALSE); + BOOL materialsReady(BOOL boost = FALSE); + protected: - BOOL mParamsReady; + static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); + static BOOL materialReady(LLPointer& mat, bool& textures_set, BOOL boost = FALSE); + + BOOL mParamsReady = FALSE; LLSurface *mSurfacep; - BOOL mTexturesLoaded; - // TODO: Set flag to indicate whether the textures or materials loaded first LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mRawImages[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; + bool mMaterialTexturesSet[ASSET_COUNT]; F32 mStartHeight[CORNER_COUNT]; F32 mHeightRange[CORNER_COUNT]; - F32 mTexScaleX; - F32 mTexScaleY; + F32 mTexScaleX = 16.f; + F32 mTexScaleY = 16.f; }; #endif //LL_LLVLCOMPOSITION_H -- cgit v1.2.3 From 3553fec2084b8be3f3de86cec293c1e363c1388e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:10 -0700 Subject: DRTVWR-592: (WIP) Separate code path for terrain rendering and shaders. Just copy/paste for now. Use same draw pool --- .../shaders/class1/deferred/pbrterrainF.glsl | 61 +++++++++ .../shaders/class1/deferred/pbrterrainV.glsl | 77 +++++++++++ indra/newview/lldrawpoolterrain.cpp | 152 +++++++++++++++++---- indra/newview/lldrawpoolterrain.h | 2 + indra/newview/llviewershadermgr.cpp | 53 ++++--- indra/newview/llviewershadermgr.h | 2 +- indra/newview/llvlcomposition.cpp | 11 +- indra/newview/llvlcomposition.h | 1 + 8 files changed, 303 insertions(+), 56 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl new file mode 100644 index 0000000000..96903aeba8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -0,0 +1,61 @@ +/** + * @file class1\deferred\terrainF.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_data[4]; + +uniform sampler2D detail_0; +uniform sampler2D detail_1; +uniform sampler2D detail_2; +uniform sampler2D detail_3; +uniform sampler2D alpha_ramp; + +in vec3 pos; +in vec3 vary_normal; +in vec4 vary_texcoord0; +in vec4 vary_texcoord1; + +vec2 encode_normal(vec3 n); + +void main() +{ + vec4 color0 = texture2D(detail_0, vary_texcoord0.xy); + vec4 color1 = texture2D(detail_1, vary_texcoord0.xy); + vec4 color2 = texture2D(detail_2, vary_texcoord0.xy); + vec4 color3 = texture2D(detail_3, vary_texcoord0.xy); + + float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; + float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; + float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; + vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); + + outColor.a = 0.0; // yes, downstream atmospherics + + frag_data[0] = outColor; + frag_data[1] = vec4(0.0,0.0,0.0,-1.0); + vec3 nvn = normalize(vary_normal); + frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); + frag_data[3] = vec4(0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl new file mode 100644 index 0000000000..e8747a1f6b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -0,0 +1,77 @@ +/** + * @file class1\environment\pbrterrainV.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$ + */ + +uniform mat3 normal_matrix; +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; + +in vec3 position; +in vec3 normal; +in vec4 diffuse_color; +in vec2 texcoord0; +in vec2 texcoord1; + +out vec3 pos; +out vec3 vary_normal; +out vec4 vary_texcoord0; +out vec4 vary_texcoord1; + +uniform vec4 object_plane_s; +uniform vec4 object_plane_t; + +vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +{ + vec4 tcoord; + + tcoord.x = dot(vpos, tp0); + tcoord.y = dot(vpos, tp1); + tcoord.z = tc.z; + tcoord.w = tc.w; + + tcoord = mat * tcoord; + + return tcoord; +} + +void main() +{ + //transform vertex + vec4 pre_pos = vec4(position.xyz, 1.0); + vec4 t_pos = modelview_projection_matrix * pre_pos; + + gl_Position = t_pos; + pos = t_pos.xyz; + + vary_normal = normalize(normal_matrix * normal); + + // Transform and pass tex coords + vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; + + vec4 t = vec4(texcoord1,0,1); + + vary_texcoord0.zw = t.xy; + vary_texcoord1.xy = t.xy-vec2(2.0, 0.0); + vary_texcoord1.zw = t.xy-vec2(1.0, 0.0); +} diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 9f0f9fd1b2..16d982ea90 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -158,10 +158,6 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN); LLFacePool::beginRenderPass(pass); - - sShader = &gDeferredTerrainProgram; - - sShader->bind(); } void LLDrawPoolTerrain::endDeferredPass(S32 pass) @@ -256,31 +252,139 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - - LLViewerTexture *detail_texture0p; - LLViewerTexture *detail_texture1p; - LLViewerTexture *detail_texture2p; - LLViewerTexture *detail_texture3p; - BOOL use_textures = compp->texturesReady() || !compp->materialsReady(); + const BOOL use_textures = compp->useTextures(); + if (use_textures) { - detail_texture0p = compp->mDetailTextures[0]; - detail_texture1p = compp->mDetailTextures[1]; - detail_texture2p = compp->mDetailTextures[2]; - detail_texture3p = compp->mDetailTextures[3]; + // Use textures + sShader = &gDeferredTerrainProgram; + sShader->bind(); + renderFullShaderTextures(); } - else // use materials + else { - detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture; - detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture; - detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture; - detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture; - LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep; - if (!detail_texture0p) { detail_texture0p = blank; } - if (!detail_texture1p) { detail_texture1p = blank; } - if (!detail_texture2p) { detail_texture2p = blank; } - if (!detail_texture3p) { detail_texture3p = blank; } + // Use materials + sShader = &gDeferredPBRTerrainProgram; + sShader->bind(); + renderFullShaderPBR(); } +} + +void LLDrawPoolTerrain::renderFullShaderTextures() +{ + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); + + LLViewerTexture *detail_texture0p = compp->mDetailTextures[0]; + LLViewerTexture *detail_texture1p = compp->mDetailTextures[1]; + LLViewerTexture *detail_texture2p = compp->mDetailTextures[2]; + LLViewerTexture *detail_texture3p = compp->mDetailTextures[3]; + + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + + LLVector4 tp0, tp1; + + tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); + tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); + + // + // detail texture 0 + // + S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); + gGL.getTexUnit(detail0)->bind(detail_texture0p); + gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail0)->activate(); + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); + + LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); + + // + // detail texture 1 + // + S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); + gGL.getTexUnit(detail1)->bind(detail_texture1p); + gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail1)->activate(); + + // detail texture 2 + // + S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); + gGL.getTexUnit(detail2)->bind(detail_texture2p); + gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail2)->activate(); + + + // detail texture 3 + // + S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); + gGL.getTexUnit(detail3)->bind(detail_texture3p); + gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail3)->activate(); + + // + // Alpha Ramp + // + S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); + gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); + gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + + // GL_BLEND disabled by default + drawLoop(); + + // Disable multitexture + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); + + gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(alpha_ramp)->disable(); + gGL.getTexUnit(alpha_ramp)->activate(); + + gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail3)->disable(); + gGL.getTexUnit(detail3)->activate(); + + gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail2)->disable(); + gGL.getTexUnit(detail2)->activate(); + + gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail1)->disable(); + gGL.getTexUnit(detail1)->activate(); + + //---------------------------------------------------------------------------- + // Restore Texture Unit 0 defaults + + gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail0)->activate(); +} + +void LLDrawPoolTerrain::renderFullShaderPBR() +{ + // Hack! Get the region that this draw pool is rendering from! + LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); + LLVLComposition *compp = regionp->getComposition(); + + LLViewerTexture *detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture; + LLViewerTexture *detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture; + LLViewerTexture *detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture; + LLViewerTexture *detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture; + LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep; + if (!detail_texture0p) { detail_texture0p = blank; } + if (!detail_texture1p) { detail_texture1p = blank; } + if (!detail_texture2p) { detail_texture2p = blank; } + if (!detail_texture3p) { detail_texture3p = blank; } LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 03bef31541..fbf6a8d917 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -79,6 +79,8 @@ protected: void renderFull2TU(); void renderFull4TU(); void renderFullShader(); + void renderFullShaderTextures(); + void renderFullShaderPBR(); void drawLoop(); private: diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4559d71d6d..19b3c59cae 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -138,7 +138,6 @@ LLGLSLShader gDeferredSkinnedDiffuseProgram; LLGLSLShader gDeferredSkinnedBumpProgram; LLGLSLShader gDeferredBumpProgram; LLGLSLShader gDeferredTerrainProgram; -LLGLSLShader gDeferredTerrainWaterProgram; LLGLSLShader gDeferredTreeProgram; LLGLSLShader gDeferredTreeShadowProgram; LLGLSLShader gDeferredSkinnedTreeShadowProgram; @@ -226,6 +225,7 @@ LLGLSLShader gDeferredPBRAlphaProgram; LLGLSLShader gDeferredSkinnedPBRAlphaProgram; LLGLSLShader gDeferredPBRAlphaWaterProgram; LLGLSLShader gDeferredSkinnedPBRAlphaWaterProgram; +LLGLSLShader gDeferredPBRTerrainProgram; //helper for making a rigged variant of a given shader bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -291,7 +291,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredEmissiveProgram); mShaderList.push_back(&gDeferredSkinnedEmissiveProgram); mShaderList.push_back(&gDeferredAvatarEyesProgram); - mShaderList.push_back(&gDeferredTerrainWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); @@ -939,7 +938,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedBumpProgram.unload(); gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); - gDeferredTerrainWaterProgram.unload(); gDeferredLightProgram.unload(); for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) { @@ -1026,6 +1024,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedPBRAlphaProgram.unload(); gDeferredPBRAlphaWaterProgram.unload(); gDeferredSkinnedPBRAlphaWaterProgram.unload(); + gDeferredPBRTerrainProgram.unload(); return TRUE; } @@ -1492,6 +1491,27 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = shader->createShader(NULL, NULL); llassert(success); } + + if (success) + { + gDeferredPBRTerrainProgram.mName = "Deferred PBR Terrain Shader"; + gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; + gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; + gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; + gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; + gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; + gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; + + gDeferredPBRTerrainProgram.mShaderFiles.clear(); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); + gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); + llassert(success); + } if (success) { @@ -2430,8 +2450,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTerrainProgram.mName = "Deferred Terrain Shader"; gDeferredTerrainProgram.mFeatures.encodesNormal = true; gDeferredTerrainProgram.mFeatures.hasSrgb = true; - gDeferredTerrainProgram.mFeatures.calculatesLighting = false; - gDeferredTerrainProgram.mFeatures.hasLighting = false; gDeferredTerrainProgram.mFeatures.isAlphaLighting = true; gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels gDeferredTerrainProgram.mFeatures.hasWaterFog = true; @@ -2447,31 +2465,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader"; - gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true; - gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true; - gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false; - gDeferredTerrainWaterProgram.mFeatures.hasLighting = false; - gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true; - gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredTerrainWaterProgram.mFeatures.hasGamma = true; - - gDeferredTerrainWaterProgram.mShaderFiles.clear(); - gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER)); - gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER)); - gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredTerrainWaterProgram.clearPermutations(); - gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1"); - success = gDeferredTerrainWaterProgram.createShader(NULL, NULL); - llassert(success); - } - if (success) { gDeferredAvatarProgram.mName = "Deferred Avatar Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index b0b9719d76..6765703ab8 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -211,7 +211,6 @@ extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; extern LLGLSLShader gDeferredBumpProgram; extern LLGLSLShader gDeferredTerrainProgram; -extern LLGLSLShader gDeferredTerrainWaterProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredTreeShadowProgram; extern LLGLSLShader gDeferredLightProgram; @@ -279,4 +278,5 @@ extern LLGLSLShader gDeferredPBROpaqueProgram; extern LLGLSLShader gDeferredPBRAlphaProgram; extern LLGLSLShader gDeferredPBRAlphaWaterProgram; extern LLGLSLShader gHUDPBRAlphaProgram; +extern LLGLSLShader gDeferredPBRTerrainProgram; #endif diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 9ad1a3dd17..5d711f4e5d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -228,6 +228,8 @@ static const U32 BASE_SIZE = 128; // static BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) { + llassert(tex.notNull()); + if (tex->getDiscardLevel() < 0) { if (boost) @@ -306,6 +308,13 @@ BOOL LLVLComposition::materialReady(LLPointer& mat, bool& return TRUE; } +BOOL LLVLComposition::useTextures() +{ + LL_PROFILE_ZONE_SCOPED; + + return texturesReady() || !materialsReady(); +} + BOOL LLVLComposition::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -371,7 +380,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = texturesReady(); + const bool use_textures = useTextures(); for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index af0cf9323c..504441d0f2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -77,6 +77,7 @@ public: friend class LLDrawPoolTerrain; void setParamsReady() { mParamsReady = TRUE; } BOOL getParamsReady() const { return mParamsReady; } + BOOL useTextures(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); -- cgit v1.2.3 From 474923e3cb29df35e8807006ad16861eb1dc24d0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:17 -0700 Subject: DRTVWR-592: (WIP) Add code for generating terrain tangents (not yet used) --- indra/newview/llvosurfacepatch.cpp | 169 +++++++++++++++++++++++++++++-------- indra/newview/llvosurfacepatch.h | 16 ++-- 2 files changed, 147 insertions(+), 38 deletions(-) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 3f5f56d378..bfa622b6c1 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -43,6 +43,9 @@ #include "pipeline.h" #include "llspatialpartition.h" +#include "mikktspace/mikktspace.h" +// mikktspace implementation already included in llvovolume object file + F32 LLVOSurfacePatch::sLODFactor = 1.f; LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -241,39 +244,53 @@ BOOL LLVOSurfacePatch::updateLOD() return TRUE; } -void LLVOSurfacePatch::getGeometry(LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp) +void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); - if (facep) - { - U32 index_offset = facep->getGeomIndex(); - - updateMainGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - updateNorthGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - updateEastGeometry(facep, - verticesp, - normalsp, - texCoords0p, - texCoords1p, - indicesp, - index_offset); - } + if (!facep) + { + return; + } + + U32 index_offset = facep->getGeomIndex(); + + updateMainGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateNorthGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateEastGeometry(facep, + verticesp, + normalsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + + const bool has_tangents = tangentsp.get() != nullptr; + if (has_tangents) + { + // Last but not least, calculate tangents for the updated terrain vertices + genTerrainTangents(facep, + verticesp, + normalsp, + tangentsp, + texCoords0p); + } } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -759,6 +776,88 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } +struct MikktData +{ + MikktData(S32 vert_offet, + S32 vert_size, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p) : + vert_offset(vert_offset), + vert_size(vert_size), + verticesp(verticesp), + normalsp(normalsp), + texCoords0p(texCoords0p) + { + } + S32 vert_offset; + U32 vert_size; + LLStrider verticesp; + LLStrider normalsp; + LLStrider tangentsp; + LLStrider texCoords0p; +}; + + +void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p) +{ + SMikkTSpaceInterface ms; + + ms.m_getNumFaces = [](const SMikkTSpaceContext *pContext) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + return S32(data->vert_size / 3); + }; + + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *pContext, const int iFace) { return 3; }; + + ms.m_getPosition = [](const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + fvPosOut[0] = data->verticesp[data->vert_offset + iVert].mV[0]; + fvPosOut[1] = data->verticesp[data->vert_offset + iVert].mV[1]; + fvPosOut[2] = data->verticesp[data->vert_offset + iVert].mV[2]; + }; + + ms.m_getNormal = [](const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + fvNormOut[0] = data->normalsp[data->vert_offset + iVert].mV[0]; + fvNormOut[1] = data->normalsp[data->vert_offset + iVert].mV[1]; + fvNormOut[2] = data->normalsp[data->vert_offset + iVert].mV[2]; + }; + + ms.m_getTexCoord = [](const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + fvTexcOut[0] = data->texCoords0p[data->vert_offset + iVert].mV[0]; + fvTexcOut[1] = data->texCoords0p[data->vert_offset + iVert].mV[1]; + }; + + ms.m_setTSpaceBasic = + [](const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData *data = (MikktData *) pContext->m_pUserData; + data->tangentsp[data->vert_offset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); + }; + + ms.m_setTSpace = nullptr; + + MikktData data(facep->getGeomIndex(), + facep->getGeomCount(), + verticesp, + normalsp, + tangentsp, + texCoords0p); + SMikkTSpaceContext ctx = { &ms, &data }; + genTangSpaceDefault(&ctx); +} + void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) { mPatchp = patchp; @@ -998,12 +1097,16 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) //get vertex buffer striders LLStrider vertices; LLStrider normals; - LLStrider texcoords2; + LLStrider tangents; LLStrider texcoords; + LLStrider texcoords2; LLStrider indices; + const bool has_tangents = buffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); + llassert_always(buffer->getVertexStrider(vertices)); llassert_always(buffer->getNormalStrider(normals)); + llassert_always(has_tangents ? buffer->getTangentStrider(tangents) : true); llassert_always(buffer->getTexCoord0Strider(texcoords)); llassert_always(buffer->getTexCoord1Strider(texcoords2)); llassert_always(buffer->getIndexStrider(indices)); @@ -1020,7 +1123,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getGeometry(vertices, normals, texcoords, texcoords2, indices); + patchp->getTerrainGeometry(vertices, normals, tangents, texcoords, texcoords2, indices); indices_index += facep->getIndicesCount(); index_offset += facep->getGeomCount(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index aed67162d1..7d0f649dea 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -63,11 +63,12 @@ public: /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); /*virtual*/ void updateFaceSize(S32 idx); - void getGeometry(LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp); + void getTerrainGeometry(LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -136,6 +137,11 @@ protected: LLStrider &texCoords1p, LLStrider &indicesp, U32 &index_offset); + void genTerrainTangents(LLFace *facep, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 49a5b79c2b1ba5f4b909d1bfab89bb7ad9c1e888 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:24 -0700 Subject: DRTVWR-592: (WIP) Debugging, rethinking --- .../shaders/class1/deferred/pbrterrainF.glsl | 3 + .../shaders/class1/deferred/pbrterrainV.glsl | 7 ++ indra/newview/lldrawpoolterrain.h | 1 + indra/newview/llvosurfacepatch.cpp | 83 +++++++++++----------- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 96903aeba8..2426199056 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -33,6 +33,8 @@ uniform sampler2D alpha_ramp; in vec3 pos; in vec3 vary_normal; +in vec3 vary_tangent; // TODO: Decide if we want to keep this +flat in float vary_sign; // TODO: Decide if we want to keep this in vec4 vary_texcoord0; in vec4 vary_texcoord1; @@ -53,6 +55,7 @@ void main() outColor.a = 0.0; // yes, downstream atmospherics frag_data[0] = outColor; + frag_data[0] = vec4((0.5 * (1.0 + vary_sign)) * vary_tangent.xyz, 1.0); // TODO: Remove frag_data[1] = vec4(0.0,0.0,0.0,-1.0); vec3 nvn = normalize(vary_normal); frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index e8747a1f6b..fcc4448a80 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -29,15 +29,20 @@ uniform mat4 modelview_projection_matrix; in vec3 position; in vec3 normal; +in vec4 tangent; in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; out vec3 pos; out vec3 vary_normal; +out vec3 vary_tangent; // TODO: Decide if we want to keep this +flat out float vary_sign; // TODO: Decide if we want to keep this out vec4 vary_texcoord0; out vec4 vary_texcoord1; +out vec4 debug_tangent; // TODO: Remove + uniform vec4 object_plane_s; uniform vec4 object_plane_t; @@ -65,6 +70,8 @@ void main() pos = t_pos.xyz; vary_normal = normalize(normal_matrix * normal); + vary_tangent = normalize(normal_matrix * tangent.xyz); // TODO: Decide if we want to keep this + vary_sign = tangent.w; // TODO: Decide if we want to keep this // Transform and pass tex coords vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index fbf6a8d917..2a487228ed 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -37,6 +37,7 @@ public: { VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TANGENT | // Only PBR terrain uses this currently LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 }; diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index bfa622b6c1..edb07ffd9b 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -776,29 +776,33 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } -struct MikktData +struct MikktTerrainData { - MikktData(S32 vert_offet, - S32 vert_size, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p) : - vert_offset(vert_offset), - vert_size(vert_size), - verticesp(verticesp), - normalsp(normalsp), - texCoords0p(texCoords0p) + MikktTerrainData(U32 vert_offset, + U32 vert_size, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p) : + mVertOffset(vert_offset), + mVertSize(vert_size), + mVerticesp(verticesp), + mNormalsp(normalsp), + mTangentsp(tangentsp), + mTexCoords0p(texCoords0p) { } - S32 vert_offset; - U32 vert_size; - LLStrider verticesp; - LLStrider normalsp; - LLStrider tangentsp; - LLStrider texCoords0p; + U32 mVertOffset; + U32 mVertSize; + LLStrider mVerticesp; + LLStrider mNormalsp; + LLStrider mTangentsp; + LLStrider mTexCoords0p; }; +// TODO: mikktspace? lol no, use this instead +// void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +// const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, LLStrider &verticesp, @@ -810,51 +814,46 @@ void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, ms.m_getNumFaces = [](const SMikkTSpaceContext *pContext) { - MikktData *data = (MikktData *) pContext->m_pUserData; - return S32(data->vert_size / 3); + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + return S32(data->mVertSize / 3); }; ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *pContext, const int iFace) { return 3; }; ms.m_getPosition = [](const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - fvPosOut[0] = data->verticesp[data->vert_offset + iVert].mV[0]; - fvPosOut[1] = data->verticesp[data->vert_offset + iVert].mV[1]; - fvPosOut[2] = data->verticesp[data->vert_offset + iVert].mV[2]; + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + fvPosOut[0] = data->mVerticesp[data->mVertOffset + iVert].mV[0]; + fvPosOut[1] = data->mVerticesp[data->mVertOffset + iVert].mV[1]; + fvPosOut[2] = data->mVerticesp[data->mVertOffset + iVert].mV[2]; }; ms.m_getNormal = [](const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - fvNormOut[0] = data->normalsp[data->vert_offset + iVert].mV[0]; - fvNormOut[1] = data->normalsp[data->vert_offset + iVert].mV[1]; - fvNormOut[2] = data->normalsp[data->vert_offset + iVert].mV[2]; + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + fvNormOut[0] = data->mNormalsp[data->mVertOffset + iVert].mV[0]; + fvNormOut[1] = data->mNormalsp[data->mVertOffset + iVert].mV[1]; + fvNormOut[2] = data->mNormalsp[data->mVertOffset + iVert].mV[2]; }; ms.m_getTexCoord = [](const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - fvTexcOut[0] = data->texCoords0p[data->vert_offset + iVert].mV[0]; - fvTexcOut[1] = data->texCoords0p[data->vert_offset + iVert].mV[1]; + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + fvTexcOut[0] = data->mTexCoords0p[data->mVertOffset + iVert].mV[0]; + fvTexcOut[1] = data->mTexCoords0p[data->mVertOffset + iVert].mV[1]; }; ms.m_setTSpaceBasic = [](const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) { - MikktData *data = (MikktData *) pContext->m_pUserData; - data->tangentsp[data->vert_offset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); + MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; + data->mTangentsp[data->mVertOffset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); }; ms.m_setTSpace = nullptr; - MikktData data(facep->getGeomIndex(), - facep->getGeomCount(), - verticesp, - normalsp, - tangentsp, - texCoords0p); - SMikkTSpaceContext ctx = { &ms, &data }; + MikktTerrainData data((U32) (facep->getGeomIndex()), (U32) (facep->getGeomCount()), verticesp, normalsp, tangentsp, texCoords0p); + SMikkTSpaceContext ctx = {&ms, &data}; genTangSpaceDefault(&ctx); } @@ -1102,11 +1101,9 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) LLStrider texcoords2; LLStrider indices; - const bool has_tangents = buffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); - llassert_always(buffer->getVertexStrider(vertices)); llassert_always(buffer->getNormalStrider(normals)); - llassert_always(has_tangents ? buffer->getTangentStrider(tangents) : true); + llassert_always(buffer->getTangentStrider(tangents)); llassert_always(buffer->getTexCoord0Strider(texcoords)); llassert_always(buffer->getTexCoord1Strider(texcoords2)); llassert_always(buffer->getIndexStrider(indices)); -- cgit v1.2.3 From 763a9b5249640ef71d532ff3c9c28418bd90fb68 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:32 -0700 Subject: DRTVWR-592: Working tangent calculation, not yet used --- indra/llmath/llvolume.cpp | 7 +- indra/llmath/llvolume.h | 2 + indra/newview/llvosurfacepatch.cpp | 214 ++++++++++++++++--------------------- indra/newview/llvosurfacepatch.h | 6 -- 4 files changed, 94 insertions(+), 135 deletions(-) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0e3792fda3..667108320a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6465,9 +6465,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) return TRUE; } -void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, - const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); - void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -6485,7 +6482,7 @@ void LLVolumeFace::createTangents() (*ptr++).clear(); } - CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); + LLCalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); //normalize normals for (U32 i = 0; i < mNumVertices; i++) @@ -7195,7 +7192,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } //adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html -void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, +void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index afed98ff36..c2586601ae 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1142,6 +1142,8 @@ public: std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); +void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); + BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index edb07ffd9b..839eb2b737 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -39,13 +39,11 @@ #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llvlcomposition.h" +#include "llvolume.h" #include "llvovolume.h" #include "pipeline.h" #include "llspatialpartition.h" -#include "mikktspace/mikktspace.h" -// mikktspace implementation already included in llvovolume object file - F32 LLVOSurfacePatch::sLODFactor = 1.f; LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -246,7 +244,6 @@ BOOL LLVOSurfacePatch::updateLOD() void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, - LLStrider &tangentsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp) @@ -280,17 +277,6 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords1p, indicesp, index_offset); - - const bool has_tangents = tangentsp.get() != nullptr; - if (has_tangents) - { - // Last but not least, calculate tangents for the updated terrain vertices - genTerrainTangents(facep, - verticesp, - normalsp, - tangentsp, - texCoords0p); - } } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -776,87 +762,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } -struct MikktTerrainData -{ - MikktTerrainData(U32 vert_offset, - U32 vert_size, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p) : - mVertOffset(vert_offset), - mVertSize(vert_size), - mVerticesp(verticesp), - mNormalsp(normalsp), - mTangentsp(tangentsp), - mTexCoords0p(texCoords0p) - { - } - U32 mVertOffset; - U32 mVertSize; - LLStrider mVerticesp; - LLStrider mNormalsp; - LLStrider mTangentsp; - LLStrider mTexCoords0p; -}; - -// TODO: mikktspace? lol no, use this instead -// void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, -// const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) - -void LLVOSurfacePatch::genTerrainTangents(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p) -{ - SMikkTSpaceInterface ms; - - ms.m_getNumFaces = [](const SMikkTSpaceContext *pContext) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - return S32(data->mVertSize / 3); - }; - - ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext *pContext, const int iFace) { return 3; }; - - ms.m_getPosition = [](const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - fvPosOut[0] = data->mVerticesp[data->mVertOffset + iVert].mV[0]; - fvPosOut[1] = data->mVerticesp[data->mVertOffset + iVert].mV[1]; - fvPosOut[2] = data->mVerticesp[data->mVertOffset + iVert].mV[2]; - }; - - ms.m_getNormal = [](const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - fvNormOut[0] = data->mNormalsp[data->mVertOffset + iVert].mV[0]; - fvNormOut[1] = data->mNormalsp[data->mVertOffset + iVert].mV[1]; - fvNormOut[2] = data->mNormalsp[data->mVertOffset + iVert].mV[2]; - }; - - ms.m_getTexCoord = [](const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - fvTexcOut[0] = data->mTexCoords0p[data->mVertOffset + iVert].mV[0]; - fvTexcOut[1] = data->mTexCoords0p[data->mVertOffset + iVert].mV[1]; - }; - - ms.m_setTSpaceBasic = - [](const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) - { - MikktTerrainData *data = (MikktTerrainData *) pContext->m_pUserData; - data->mTangentsp[data->mVertOffset + iVert] = LLVector4a(fvTangent[0], fvTangent[1], fvTangent[2], fSign); - }; - - ms.m_setTSpace = nullptr; - - MikktTerrainData data((U32) (facep->getGeomIndex()), (U32) (facep->getGeomCount()), verticesp, normalsp, tangentsp, texCoords0p); - SMikkTSpaceContext ctx = {&ms, &data}; - genTangSpaceDefault(&ctx); -} - void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) { mPatchp = patchp; @@ -1087,6 +992,47 @@ LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } +// Do not add vertices; honor strict vertex count specified by strider_vertex_count +void gen_terrain_tangents(U16 strider_vertex_count, + U32 strider_index_count, + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &tangentsp, + LLStrider &texCoords0p, + LLStrider &indicesp) +{ + LLVector4a *vertices = new LLVector4a[strider_vertex_count]; + LLVector4a *normals = new LLVector4a[strider_vertex_count]; + LLVector4a *tangents = new LLVector4a[strider_vertex_count]; + std::vector texcoords(strider_vertex_count); + std::vector indices(strider_index_count); + + for (U16 v = 0; v < strider_vertex_count; ++v) + { + F32 *vert = verticesp[v].mV; + vertices[v] = LLVector4a(vert[0], vert[1], vert[2], 1.f); + F32 *n = normalsp[v].mV; + normals[v] = LLVector4a(n[0], n[1], n[2], 1.f); + tangents[v] = tangentsp[v]; + texcoords[v] = texCoords0p[v]; + } + for (U32 i = 0; i < strider_index_count; ++i) + { + indices[i] = indicesp[i]; + } + + LLCalculateTangentArray(strider_vertex_count, vertices, normals, texcoords.data(), strider_index_count / 3, indices.data(), tangents); + + for (U16 v = 0; v < strider_vertex_count; ++v) + { + tangentsp[v] = tangents[v]; + } + + delete[] vertices; + delete[] normals; + delete[] tangents; +} + void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; @@ -1094,37 +1040,57 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders - LLStrider vertices; - LLStrider normals; - LLStrider tangents; - LLStrider texcoords; - LLStrider texcoords2; - LLStrider indices; - - llassert_always(buffer->getVertexStrider(vertices)); - llassert_always(buffer->getNormalStrider(normals)); - llassert_always(buffer->getTangentStrider(tangents)); - llassert_always(buffer->getTexCoord0Strider(texcoords)); - llassert_always(buffer->getTexCoord1Strider(texcoords2)); - llassert_always(buffer->getIndexStrider(indices)); - - U32 indices_index = 0; - U32 index_offset = 0; - - for (std::vector::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) - { - LLFace* facep = *i; + LLStrider vertices_start; + LLStrider normals_start; + LLStrider tangents_start; + LLStrider texcoords_start; + LLStrider texcoords2_start; + LLStrider indices_start; + + llassert_always(buffer->getVertexStrider(vertices_start)); + llassert_always(buffer->getNormalStrider(normals_start)); + llassert_always(buffer->getTangentStrider(tangents_start)); + llassert_always(buffer->getTexCoord0Strider(texcoords_start)); + llassert_always(buffer->getTexCoord1Strider(texcoords2_start)); + llassert_always(buffer->getIndexStrider(indices_start)); + + U32 indices_index = 0; + U32 index_offset = 0; - facep->setIndicesIndex(indices_index); - facep->setGeomIndex(index_offset); - facep->setVertexBuffer(buffer); + { + LLStrider vertices = vertices_start; + LLStrider normals = normals_start; + LLStrider texcoords = texcoords_start; + LLStrider texcoords2 = texcoords2_start; + LLStrider indices = indices_start; + + for (std::vector::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) + { + LLFace* facep = *i; + + facep->setIndicesIndex(indices_index); + facep->setGeomIndex(index_offset); + facep->setVertexBuffer(buffer); + + LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); + patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices); + + indices_index += facep->getIndicesCount(); + index_offset += facep->getGeomCount(); + } + } - LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getTerrainGeometry(vertices, normals, tangents, texcoords, texcoords2, indices); + const bool has_tangents = tangents_start.get() != nullptr; + if (has_tangents) + { + LLStrider vertices = vertices_start; + LLStrider normals = normals_start; + LLStrider tangents = tangents_start; + LLStrider texcoords = texcoords_start; + LLStrider indices = indices_start; - indices_index += facep->getIndicesCount(); - index_offset += facep->getGeomCount(); - } + gen_terrain_tangents(index_offset, indices_index, vertices, normals, tangents, texcoords, indices); + } buffer->unmapBuffer(); mFaceList.clear(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 7d0f649dea..a3dcb945d1 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -65,7 +65,6 @@ public: /*virtual*/ void updateFaceSize(S32 idx); void getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, - LLStrider &tangentsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp); @@ -137,11 +136,6 @@ protected: LLStrider &texCoords1p, LLStrider &indicesp, U32 &index_offset); - void genTerrainTangents(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &tangentsp, - LLStrider &texCoords0p); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 7376b3e4b9c03f3ff3aa0c431c66916ac655a692 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:40 -0700 Subject: DRTVWR-592: (WIP) (does not run) PBR terrain rendering - begin work on shaders, uniforms --- indra/llrender/llshadermgr.cpp | 18 +++ indra/llrender/llshadermgr.h | 18 +++ .../shaders/class1/deferred/pbrterrainF.glsl | 142 ++++++++++++++++++--- .../shaders/class1/deferred/pbrterrainV.glsl | 21 ++- 4 files changed, 166 insertions(+), 33 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 75d6ef6c46..89f39d7011 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1427,8 +1427,26 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("detail_1"); mReservedUniforms.push_back("detail_2"); mReservedUniforms.push_back("detail_3"); + mReservedUniforms.push_back("alpha_ramp"); + mReservedUniforms.push_back("detail_0_base_color"); + mReservedUniforms.push_back("detail_1_base_color"); + mReservedUniforms.push_back("detail_2_base_color"); + mReservedUniforms.push_back("detail_3_base_color"); + mReservedUniforms.push_back("detail_0_normal"); + mReservedUniforms.push_back("detail_1_normal"); + mReservedUniforms.push_back("detail_2_normal"); + mReservedUniforms.push_back("detail_3_normal"); + mReservedUniforms.push_back("detail_0_metallic_roughness"); + mReservedUniforms.push_back("detail_1_metallic_roughness"); + mReservedUniforms.push_back("detail_2_metallic_roughness"); + mReservedUniforms.push_back("detail_3_metallic_roughness"); + mReservedUniforms.push_back("detail_0_emissive"); + mReservedUniforms.push_back("detail_1_emissive"); + mReservedUniforms.push_back("detail_2_emissive"); + mReservedUniforms.push_back("detail_3_emissive"); + mReservedUniforms.push_back("origin"); mReservedUniforms.push_back("display_gamma"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 46f352aa58..b43ccf2ec2 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -248,8 +248,26 @@ public: TERRAIN_DETAIL1, // "detail_1" TERRAIN_DETAIL2, // "detail_2" TERRAIN_DETAIL3, // "detail_3" + TERRAIN_ALPHARAMP, // "alpha_ramp" + TERRAIN_DETAIL0_BASE_COLOR, // "detail_0_base_color" (GLTF) + TERRAIN_DETAIL1_BASE_COLOR, // "detail_1_base_color" (GLTF) + TERRAIN_DETAIL2_BASE_COLOR, // "detail_2_base_color" (GLTF) + TERRAIN_DETAIL3_BASE_COLOR, // "detail_3_base_color" (GLTF) + TERRAIN_DETAIL0_NORMAL, // "detail_0_normal" (GLTF) + TERRAIN_DETAIL1_NORMAL, // "detail_1_normal" (GLTF) + TERRAIN_DETAIL2_NORMAL, // "detail_2_normal" (GLTF) + TERRAIN_DETAIL3_NORMAL, // "detail_3_normal" (GLTF) + TERRAIN_DETAIL0_METALLIC_ROUGHNESS, // "detail_0_metallic_roughness" (GLTF) + TERRAIN_DETAIL1_METALLIC_ROUGHNESS, // "detail_1_metallic_roughness" (GLTF) + TERRAIN_DETAIL2_METALLIC_ROUGHNESS, // "detail_2_metallic_roughness" (GLTF) + TERRAIN_DETAIL3_METALLIC_ROUGHNESS, // "detail_3_metallic_roughness" (GLTF) + TERRAIN_DETAIL0_EMISSIVE, // "detail_0_emissive" (GLTF) + TERRAIN_DETAIL1_EMISSIVE, // "detail_1_emissive" (GLTF) + TERRAIN_DETAIL2_EMISSIVE, // "detail_2_emissive" (GLTF) + TERRAIN_DETAIL3_EMISSIVE, // "detail_3_emissive" (GLTF) + SHINY_ORIGIN, // "origin" DISPLAY_GAMMA, // "display_gamma" diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 2426199056..f355b8ef98 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -25,40 +25,140 @@ out vec4 frag_data[4]; -uniform sampler2D detail_0; -uniform sampler2D detail_1; -uniform sampler2D detail_2; -uniform sampler2D detail_3; uniform sampler2D alpha_ramp; -in vec3 pos; +// TODO: Bind the right textures and uniforms during shader setup +// *TODO: Configurable quality level which disables PBR features on machines +// with limited texture availability +// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures +uniform sampler2D detail_0_base_color; +uniform sampler2D detail_1_base_color; +uniform sampler2D detail_2_base_color; +uniform sampler2D detail_3_base_color; +uniform sampler2D detail_0_normal; +uniform sampler2D detail_1_normal; +uniform sampler2D detail_2_normal; +uniform sampler2D detail_3_normal; +uniform sampler2D detail_0_metallic_roughness; +uniform sampler2D detail_1_metallic_roughness; +uniform sampler2D detail_2_metallic_roughness; +uniform sampler2D detail_3_metallic_roughness; +uniform sampler2D detail_0_emissive; +uniform sampler2D detail_1_emissive; +uniform sampler2D detail_2_emissive; +uniform sampler2D detail_3_emissive; + +// TODO: Needs new uniforms +// *TODO: More efficient packing? +uniform vec4 metallicFactors; +uniform vec4 roughnessFactors; +uniform vec3[4] emissiveColors; +uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() + in vec3 vary_normal; -in vec3 vary_tangent; // TODO: Decide if we want to keep this -flat in float vary_sign; // TODO: Decide if we want to keep this +in vec3 vary_tangent; +flat in float vary_sign; in vec4 vary_texcoord0; in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); +vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); -void main() +// TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly +float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal ); +} + +vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); +} + +vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); +} + +vec4 sample_and_mix_color(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec4[4] samples; + samples[0] = srgb_to_linear(texture2D(tex0, texcoord)); + samples[1] = srgb_to_linear(texture2D(tex1, texcoord)); + samples[2] = srgb_to_linear(texture2D(tex2, texcoord)); + samples[3] = srgb_to_linear(texture2D(tex3, texcoord)); + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec4 color0 = texture2D(detail_0, vary_texcoord0.xy); - vec4 color1 = texture2D(detail_1, vary_texcoord0.xy); - vec4 color2 = texture2D(detail_2, vary_texcoord0.xy); - vec4 color3 = texture2D(detail_3, vary_texcoord0.xy); + vec4[4] samples; + samples[0] = texture2D(tex0, texcoord); + samples[1] = texture2D(tex1, texcoord); + samples[2] = texture2D(tex2, texcoord); + samples[3] = texture2D(tex3, texcoord); + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} +// TODO: Implement +// TODO: Don't forget calls to srgb_to_linear during texture sampling +// TODO: Wherever base color alpha is not 1.0, blend with black +void main() +{ float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; - vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - - outColor.a = 0.0; // yes, downstream atmospherics + + vec4 base_color = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_basecolor, detail_1_basecolor, detail_2_basecolor, detail_3_basecolor); + vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); + vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); + vec4 emissive_texture = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + + float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal); + float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal); + vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal); + float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + + // TODO: OOh, we need blending for every GLTF uniform too + // TODO: Unfork + if (base_color.a < minimum_alpha) + { + base_color.rgb *= vec3(0.0); + } + + vec3 col = base_color.rgb; + + // from mikktspace.com + vec3 vNt = normal_texture.xyz*2.0-1.0; + float sign = vary_sign; + vec3 vN = vary_normal; + vec3 vT = vary_tangent.xyz; + + vec3 vB = sign * cross(vN, vT); + vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); + + // RGB = Occlusion, Roughness, Metal + // default values, see LLViewerTexture::sDefaultPBRORMImagep + // occlusion 1.0 + // roughness 0.0 + // metal 0.0 + vec3 spec = metallic_roughness.rgb; - frag_data[0] = outColor; - frag_data[0] = vec4((0.5 * (1.0 + vary_sign)) * vary_tangent.xyz, 1.0); // TODO: Remove - frag_data[1] = vec4(0.0,0.0,0.0,-1.0); - vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); - frag_data[3] = vec4(0); + spec.g *= roughness_factor; + spec.b *= metallic_factor; + + vec3 emissive = emssive_color; + emissive *= emissive_texture.rgb; + + tnorm *= gl_FrontFacing ? 1.0 : -1.0; + + + frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse + // TODO: What is packed into vertex_color.a? + frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + // TODO: What is environment intensity and do we want it? + frag_data[2] = max(vec4(encode_normal(tnorm), 0.0, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), vec4(0)); // normal, environment intensity, flags + frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index fcc4448a80..cbfe9f3ea5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -34,15 +34,12 @@ in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; -out vec3 pos; out vec3 vary_normal; -out vec3 vary_tangent; // TODO: Decide if we want to keep this -flat out float vary_sign; // TODO: Decide if we want to keep this +out vec3 vary_tangent; +flat out float vary_sign; out vec4 vary_texcoord0; out vec4 vary_texcoord1; -out vec4 debug_tangent; // TODO: Remove - uniform vec4 object_plane_s; uniform vec4 object_plane_t; @@ -63,17 +60,17 @@ vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) void main() { //transform vertex - vec4 pre_pos = vec4(position.xyz, 1.0); - vec4 t_pos = modelview_projection_matrix * pre_pos; + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - gl_Position = t_pos; - pos = t_pos.xyz; + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; - vary_normal = normalize(normal_matrix * normal); - vary_tangent = normalize(normal_matrix * tangent.xyz); // TODO: Decide if we want to keep this - vary_sign = tangent.w; // TODO: Decide if we want to keep this + vary_tangent = normalize(t); + vary_sign = tangent.w; + vary_normal = normalize(n); // Transform and pass tex coords + // *NOTE: KHR texture transform is ignored for now vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; vec4 t = vec4(texcoord1,0,1); -- cgit v1.2.3 From a7cd5f6ef9d80e77eaf87cfc605d32605f0916f1 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:48 -0700 Subject: DRTVWR-592: (WIP) (does not run) PBR terrain rendering - more work on shaders, uniforms --- indra/llrender/llshadermgr.cpp | 6 +++++ indra/llrender/llshadermgr.h | 6 +++++ .../shaders/class1/deferred/pbrterrainF.glsl | 28 +++++++++------------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 89f39d7011..b2c8255d2a 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1447,6 +1447,12 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("detail_2_emissive"); mReservedUniforms.push_back("detail_3_emissive"); + mReservedUniforms.push_back("baseColorFactors"); + mReservedUniforms.push_back("metallicFactors"); + mReservedUniforms.push_back("roughnessFactors"); + mReservedUniforms.push_back("emissiveColors"); + mReservedUniforms.push_back("minimum_alphas"); + mReservedUniforms.push_back("origin"); mReservedUniforms.push_back("display_gamma"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index b43ccf2ec2..151e94093d 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -268,6 +268,12 @@ public: TERRAIN_DETAIL2_EMISSIVE, // "detail_2_emissive" (GLTF) TERRAIN_DETAIL3_EMISSIVE, // "detail_3_emissive" (GLTF) + TERRAIN_BASE_COLOR_FACTORS, // "baseColorFactors" (GLTF) + TERRAIN_METALLIC_FACTORS, // "metallicFactors" (GLTF) + TERRAIN_ROUGHNESS_FACTORS, // "roughnessFactors" (GLTF) + TERRAIN_EMISSIVE_COLORS, // "emissiveColors" (GLTF) + TERRAIN_MINIMUM_ALPHAS, // "minimum_alphas" (GLTF) + SHINY_ORIGIN, // "origin" DISPLAY_GAMMA, // "display_gamma" diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index f355b8ef98..4a0b324558 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -48,8 +48,8 @@ uniform sampler2D detail_1_emissive; uniform sampler2D detail_2_emissive; uniform sampler2D detail_3_emissive; -// TODO: Needs new uniforms // *TODO: More efficient packing? +uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl uniform vec4 metallicFactors; uniform vec4 roughnessFactors; uniform vec3[4] emissiveColors; @@ -101,9 +101,6 @@ vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 te return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -// TODO: Implement -// TODO: Don't forget calls to srgb_to_linear during texture sampling -// TODO: Wherever base color alpha is not 1.0, blend with black void main() { float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; @@ -111,23 +108,22 @@ void main() float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; vec4 base_color = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_basecolor, detail_1_basecolor, detail_2_basecolor, detail_3_basecolor); + float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + if (base_color.a < minimum_alpha) + { + discard; + } + vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); vec4 emissive_texture = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + vec4 baseColorFactor = terrain_mix(baseColorFactors, alpha1, alpha2, alphaFinal); float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal); float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal); vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal); - float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); - - // TODO: OOh, we need blending for every GLTF uniform too - // TODO: Unfork - if (base_color.a < minimum_alpha) - { - base_color.rgb *= vec3(0.0); - } - vec3 col = base_color.rgb; + vec3 col = baseColorFactor.rgb * srgb_to_linear(basecolor.rgb); // from mikktspace.com vec3 vNt = normal_texture.xyz*2.0-1.0; @@ -155,10 +151,8 @@ void main() frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse - // TODO: What is packed into vertex_color.a? - frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. - // TODO: What is environment intensity and do we want it? - frag_data[2] = max(vec4(encode_normal(tnorm), 0.0, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), vec4(0)); // normal, environment intensity, flags + frag_data[1] = max(vec4(spec.rgb,baseColorFactor.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[2] = max(vec4(encode_normal(tnorm), baseColorFactor.a, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), vec4(0)); // normal, environment intensity, flags frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } -- cgit v1.2.3 From 5d046d8835563fcad9e8dcf948d889d9ccec41d7 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:57 -0700 Subject: DRTVWR-592: (WIP) (does not work) PBR terrain rendering - compiles, but doesn't render properly just yet --- .../shaders/class1/deferred/pbrterrainF.glsl | 41 ++++-- .../shaders/class1/deferred/pbrterrainV.glsl | 8 +- indra/newview/lldrawpoolterrain.cpp | 154 ++++++++++++--------- 3 files changed, 123 insertions(+), 80 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 4a0b324558..60e5776bc6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -27,7 +27,6 @@ out vec4 frag_data[4]; uniform sampler2D alpha_ramp; -// TODO: Bind the right textures and uniforms during shader setup // *TODO: Configurable quality level which disables PBR features on machines // with limited texture availability // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures @@ -65,7 +64,7 @@ vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); -// TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly +// *TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal ); @@ -81,13 +80,27 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); } -vec4 sample_and_mix_color(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = srgb_to_linear(texture2D(tex0, texcoord).xyz); + samples[1] = srgb_to_linear(texture2D(tex1, texcoord).xyz); + samples[2] = srgb_to_linear(texture2D(tex2, texcoord).xyz); + samples[3] = srgb_to_linear(texture2D(tex3, texcoord).xyz); + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; - samples[0] = srgb_to_linear(texture2D(tex0, texcoord)); - samples[1] = srgb_to_linear(texture2D(tex1, texcoord)); - samples[2] = srgb_to_linear(texture2D(tex2, texcoord)); - samples[3] = srgb_to_linear(texture2D(tex3, texcoord)); + samples[0] = texture2D(tex0, texcoord); + samples[1] = texture2D(tex1, texcoord); + samples[2] = texture2D(tex2, texcoord); + samples[3] = texture2D(tex3, texcoord); + samples[0].xyz = srgb_to_linear(samples[0].xyz); + samples[1].xyz = srgb_to_linear(samples[1].xyz); + samples[2].xyz = srgb_to_linear(samples[2].xyz); + samples[3].xyz = srgb_to_linear(samples[3].xyz); return terrain_mix(samples, alpha1, alpha2, alphaFinal); } @@ -107,7 +120,7 @@ void main() float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; - vec4 base_color = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_basecolor, detail_1_basecolor, detail_2_basecolor, detail_3_basecolor); + vec4 base_color = sample_and_mix_color4(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); if (base_color.a < minimum_alpha) { @@ -116,14 +129,14 @@ void main() vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); - vec4 emissive_texture = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); vec4 baseColorFactor = terrain_mix(baseColorFactors, alpha1, alpha2, alphaFinal); float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal); float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal); vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal); - vec3 col = baseColorFactor.rgb * srgb_to_linear(basecolor.rgb); + vec3 col = baseColorFactor.rgb * srgb_to_linear(base_color.rgb); // from mikktspace.com vec3 vNt = normal_texture.xyz*2.0-1.0; @@ -141,10 +154,10 @@ void main() // metal 0.0 vec3 spec = metallic_roughness.rgb; - spec.g *= roughness_factor; - spec.b *= metallic_factor; + spec.g *= roughnessFactor; + spec.b *= metallicFactor; - vec3 emissive = emssive_color; + vec3 emissive = emissiveColor; emissive *= emissive_texture.rgb; tnorm *= gl_FrontFacing ? 1.0 : -1.0; @@ -152,7 +165,7 @@ void main() frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb,baseColorFactor.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. - frag_data[2] = max(vec4(encode_normal(tnorm), baseColorFactor.a, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), vec4(0)); // normal, environment intensity, flags + frag_data[2] = max(vec4(encode_normal(tnorm), baseColorFactor.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index cbfe9f3ea5..6037a58c0d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -73,9 +73,9 @@ void main() // *NOTE: KHR texture transform is ignored for now vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; - vec4 t = vec4(texcoord1,0,1); + vec4 tc = vec4(texcoord1,0,1); - vary_texcoord0.zw = t.xy; - vary_texcoord1.xy = t.xy-vec2(2.0, 0.0); - vary_texcoord1.zw = t.xy-vec2(1.0, 0.0); + vary_texcoord0.zw = tc.xy; + vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0); + vary_texcoord1.zw = tc.xy-vec2(1.0, 0.0); } diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 16d982ea90..2a0a7bad1c 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -375,16 +375,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - - LLViewerTexture *detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture; - LLViewerTexture *detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture; - LLViewerTexture *detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture; - LLViewerTexture *detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture; - LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep; - if (!detail_texture0p) { detail_texture0p = blank; } - if (!detail_texture1p) { detail_texture1p = blank; } - if (!detail_texture2p) { detail_texture2p = blank; } - if (!detail_texture3p) { detail_texture3p = blank; } + LLPointer(& materials)[LLVLComposition::ASSET_COUNT] = compp->mDetailMaterials; LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -395,13 +386,39 @@ void LLDrawPoolTerrain::renderFullShaderPBR() tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - // - // detail texture 0 - // - S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); - gGL.getTexUnit(detail0)->bind(detail_texture0p); - gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail0)->activate(); + constexpr U32 terrain_material_count = LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; + S32 detail_basecolor[terrain_material_count]; + S32 detail_normal[terrain_material_count]; + S32 detail_metalrough[terrain_material_count]; + S32 detail_emissive[terrain_material_count]; + + for (U32 i = 0; i < terrain_material_count; ++i) + { + LLViewerTexture *detail_basecolor_texturep = materials[i]->mBaseColorTexture; + LLViewerTexture *detail_normal_texturep = materials[i]->mNormalTexture; + LLViewerTexture *detail_metalrough_texturep = materials[i]->mMetallicRoughnessTexture; + LLViewerTexture *detail_emissive_texturep = materials[i]->mEmissiveTexture; + + detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); + gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep); + gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_basecolor[i])->activate(); + + detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); + gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep); + gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_normal[i])->activate(); + + detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); + gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep); + gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_metalrough[i])->activate(); + + detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); + gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); + gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_emissive[i])->activate(); + } LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; llassert(shader); @@ -411,29 +428,6 @@ void LLDrawPoolTerrain::renderFullShaderPBR() LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); - // - // detail texture 1 - // - S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); - gGL.getTexUnit(detail1)->bind(detail_texture1p); - gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail1)->activate(); - - // detail texture 2 - // - S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); - gGL.getTexUnit(detail2)->bind(detail_texture2p); - gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail2)->activate(); - - - // detail texture 3 - // - S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); - gGL.getTexUnit(detail3)->bind(detail_texture3p); - gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail3)->activate(); - // // Alpha Ramp // @@ -441,38 +435,74 @@ void LLDrawPoolTerrain::renderFullShaderPBR() gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep); gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + // + // GLTF uniforms + // + + LLColor4 base_color_factors[terrain_material_count]; + F32 metallic_factors[terrain_material_count]; + F32 roughness_factors[terrain_material_count]; + LLColor3 emissive_colors[terrain_material_count]; + F32 minimum_alphas[terrain_material_count]; + for (U32 i = 0; i < terrain_material_count; ++i) + { + const LLFetchedGLTFMaterial* material = materials[i].get(); + + base_color_factors[i] = material->mBaseColor; + metallic_factors[i] = material->mMetallicFactor; + roughness_factors[i] = material->mRoughnessFactor; + emissive_colors[i] = material->mEmissiveColor; + // glTF 2.0 Specification 3.9.4. Alpha Coverage + // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK + // Use 0 here due to GLTF terrain blending (LLGLTFMaterial::bind uses + // -1 for easier debugging) + F32 min_alpha = 0.f; + if (material->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) + { + min_alpha = material->mAlphaCutoff; + } + + } + shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors); + shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]); + shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]); + shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors); + shader->uniform4f(LLShaderMgr::TERRAIN_MINIMUM_ALPHAS, minimum_alphas[0], minimum_alphas[1], minimum_alphas[2], minimum_alphas[3]); + // GL_BLEND disabled by default drawLoop(); // Disable multitexture + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3); gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(alpha_ramp)->disable(); gGL.getTexUnit(alpha_ramp)->activate(); - - gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail3)->disable(); - gGL.getTexUnit(detail3)->activate(); - gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail2)->disable(); - gGL.getTexUnit(detail2)->activate(); - - gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail1)->disable(); - gGL.getTexUnit(detail1)->activate(); - - //---------------------------------------------------------------------------- - // Restore Texture Unit 0 defaults - - gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail0)->activate(); + for (U32 i = 0; i < terrain_material_count; ++i) + { + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); + + gGL.getTexUnit(detail_basecolor[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_basecolor[i])->disable(); + gGL.getTexUnit(detail_basecolor[i])->activate(); + + gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_normal[i])->disable(); + gGL.getTexUnit(detail_normal[i])->activate(); + + gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_metalrough[i])->disable(); + gGL.getTexUnit(detail_metalrough[i])->activate(); + + gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_emissive[i])->disable(); + gGL.getTexUnit(detail_emissive[i])->activate(); + } } void LLDrawPoolTerrain::hilightParcelOwners() -- cgit v1.2.3 From 039116abd4166903005b8de6fa5d64f0fdf75422 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:05 -0700 Subject: DRTVWR-592: (WIP) Roughly working draft of PBR terrain --- .../shaders/class1/deferred/pbrterrainF.glsl | 20 ++++++++++++-------- indra/newview/lldrawpoolterrain.cpp | 11 +++++++---- indra/newview/llfloaterregioninfo.cpp | 1 - indra/newview/llvlcomposition.cpp | 1 + 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 60e5776bc6..4de6b9609c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -97,10 +97,11 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 te samples[1] = texture2D(tex1, texcoord); samples[2] = texture2D(tex2, texcoord); samples[3] = texture2D(tex3, texcoord); - samples[0].xyz = srgb_to_linear(samples[0].xyz); - samples[1].xyz = srgb_to_linear(samples[1].xyz); - samples[2].xyz = srgb_to_linear(samples[2].xyz); - samples[3].xyz = srgb_to_linear(samples[3].xyz); + // TODO: Why is this needed for pbropaqueF but not here? (and is there different behavior with base color vs emissive color, that also needs to be corrected?) + //samples[0].xyz = srgb_to_linear(samples[0].xyz); + //samples[1].xyz = srgb_to_linear(samples[1].xyz); + //samples[2].xyz = srgb_to_linear(samples[2].xyz); + //samples[3].xyz = srgb_to_linear(samples[3].xyz); return terrain_mix(samples, alpha1, alpha2, alphaFinal); } @@ -116,20 +117,23 @@ vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 te void main() { + // Adjust the texture repeats for a more sensible default. + float texture_density_factor = 2.0; + vec2 terrain_texcoord = texture_density_factor * vary_texcoord0.xy; float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; - vec4 base_color = sample_and_mix_color4(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); + vec4 base_color = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); if (base_color.a < minimum_alpha) { discard; } - vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); - vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); + vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); + vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); vec4 baseColorFactor = terrain_mix(baseColorFactors, alpha1, alpha2, alphaFinal); float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 2a0a7bad1c..204fbc56fd 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -370,6 +370,7 @@ void LLDrawPoolTerrain::renderFullShaderTextures() gGL.getTexUnit(detail0)->activate(); } +// TODO: Investigate use of bindFast for PBR terrain textures void LLDrawPoolTerrain::renderFullShaderPBR() { // Hack! Get the region that this draw pool is rendering from! @@ -386,7 +387,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR() tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - constexpr U32 terrain_material_count = LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; + constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; S32 detail_basecolor[terrain_material_count]; S32 detail_normal[terrain_material_count]; S32 detail_metalrough[terrain_material_count]; @@ -456,12 +457,14 @@ void LLDrawPoolTerrain::renderFullShaderPBR() // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK // Use 0 here due to GLTF terrain blending (LLGLTFMaterial::bind uses // -1 for easier debugging) - F32 min_alpha = 0.f; + F32 min_alpha = -0.0f; if (material->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) { - min_alpha = material->mAlphaCutoff; + // 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 = material->mAlphaCutoff/material->mBaseColor.mV[3]; } - + minimum_alphas[i] = min_alpha; } shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors); shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index b5698c1d65..2635ac3a71 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1531,7 +1531,6 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LLVLComposition* compp = region->getComposition(); // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set the IDs on both pickers for now. - // *TODO: Determine the asset type of IDs, to determine which editing mode to display. LLTextureCtrl* asset_ctrl; std::string buffer; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 5d711f4e5d..815489f753 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -360,6 +360,7 @@ BOOL LLVLComposition::generateComposition() return FALSE; } +// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { -- cgit v1.2.3 From 94d8f669acc57d670000498edf22589f7b178af0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:13 -0700 Subject: DRTVWR-592: Add debug options LocalTerrainAssetN. Fix PBR terrain texture flickering --- indra/newview/app_settings/settings.xml | 44 ++++ indra/newview/llappviewer.cpp | 1 + indra/newview/lldrawpoolterrain.cpp | 63 ++++-- indra/newview/lldrawpoolterrain.h | 2 +- indra/newview/llviewercontrol.cpp | 15 ++ indra/newview/llvlcomposition.cpp | 345 +++++++++++++++++--------------- indra/newview/llvlcomposition.h | 44 +++- 7 files changed, 328 insertions(+), 186 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 09eda2534c..013f0ca8ff 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16442,6 +16442,50 @@ Boolean Value 0 + + LocalTerrainAsset1 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + + LocalTerrainAsset2 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + + LocalTerrainAsset3 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + + LocalTerrainAsset4 + + Comment + If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds. + Persist + 0 + Type + String + Value + 00000000-0000-0000-0000-000000000000 PathfindingRetrieveNeighboringRegion diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cf84094aa4..edbae465f7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -227,6 +227,7 @@ #include "pipeline.h" #include "llgesturemgr.h" #include "llsky.h" +#include "llvlcomposition.h" #include "llvlmanager.h" #include "llviewercamera.h" #include "lldrawpoolbump.h" diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 204fbc56fd..8755e53763 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -249,10 +249,11 @@ void LLDrawPoolTerrain::drawLoop() void LLDrawPoolTerrain::renderFullShader() { + const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE); // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - const BOOL use_textures = compp->useTextures(); + const BOOL use_textures = !use_local_materials && compp->useTextures(); if (use_textures) { @@ -266,7 +267,7 @@ void LLDrawPoolTerrain::renderFullShader() // Use materials sShader = &gDeferredPBRTerrainProgram; sShader->bind(); - renderFullShaderPBR(); + renderFullShaderPBR(use_local_materials); } } @@ -371,12 +372,18 @@ void LLDrawPoolTerrain::renderFullShaderTextures() } // TODO: Investigate use of bindFast for PBR terrain textures -void LLDrawPoolTerrain::renderFullShaderPBR() +void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) { // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLPointer(& materials)[LLVLComposition::ASSET_COUNT] = compp->mDetailMaterials; + LLPointer (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; + + if (local_materials) + { + // Override region terrain with the global local override terrain + materials = &gLocalTerrainMaterials.mDetailMaterials; + } LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; @@ -395,28 +402,58 @@ void LLDrawPoolTerrain::renderFullShaderPBR() for (U32 i = 0; i < terrain_material_count; ++i) { - LLViewerTexture *detail_basecolor_texturep = materials[i]->mBaseColorTexture; - LLViewerTexture *detail_normal_texturep = materials[i]->mNormalTexture; - LLViewerTexture *detail_metalrough_texturep = materials[i]->mMetallicRoughnessTexture; - LLViewerTexture *detail_emissive_texturep = materials[i]->mEmissiveTexture; + const LLFetchedGLTFMaterial* material = (*materials)[i].get(); + + LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture; + LLViewerTexture *detail_normal_texturep = material->mNormalTexture; + LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture; + LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture; detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); - gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep); + if (detail_basecolor_texturep) + { + gGL.getTexUnit(detail_basecolor[i])->bind(detail_basecolor_texturep); + } + else + { + gGL.getTexUnit(detail_basecolor[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + } gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(detail_basecolor[i])->activate(); detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); - gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep); + if (detail_normal_texturep) + { + gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep); + } + else + { + gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep); + } gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(detail_normal[i])->activate(); detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); - gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep); + if (detail_metalrough_texturep) + { + gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep); + } + else + { + gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + } gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(detail_metalrough[i])->activate(); detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); - gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); + if (detail_emissive_texturep) + { + gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); + } + else + { + gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + } gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(detail_emissive[i])->activate(); } @@ -447,7 +484,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR() F32 minimum_alphas[terrain_material_count]; for (U32 i = 0; i < terrain_material_count; ++i) { - const LLFetchedGLTFMaterial* material = materials[i].get(); + const LLFetchedGLTFMaterial* material = (*materials)[i].get(); base_color_factors[i] = material->mBaseColor; metallic_factors[i] = material->mMetallicFactor; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 2a487228ed..1a27cc8be0 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -81,7 +81,7 @@ protected: void renderFull4TU(); void renderFullShader(); void renderFullShaderTextures(); - void renderFullShaderPBR(); + void renderFullShaderPBR(BOOL local_materials = false); void drawLoop(); private: diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index aae4409167..4e0ad11597 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -54,6 +54,7 @@ #include "llvotree.h" #include "llvovolume.h" #include "llworld.h" +#include "llvlcomposition.h" #include "pipeline.h" #include "llviewerjoystick.h" #include "llviewerobjectlist.h" @@ -656,6 +657,16 @@ void handleFPSTuningStrategyChanged(const LLSD& newValue) const auto newval = gSavedSettings.getU32("TuningFPSStrategy"); LLPerfStats::tunables.userFPSTuningStrategy = newval; } + +void handleLocalTerrainChanged(const LLSD& newValue) +{ + for (U32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + const auto setting = gSavedSettings.getString(std::string("LocalTerrainAsset") + std::to_string(i + 1)); + const LLUUID materialID(setting); + gLocalTerrainMaterials.setDetailAssetID(i, materialID); + } +} //////////////////////////////////////////////////////////////////////////// LLPointer setting_get_control(LLControlGroup& group, const std::string& setting) @@ -834,6 +845,10 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged); setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged); setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset1", handleLocalTerrainChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset2", handleLocalTerrainChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset3", handleLocalTerrainChanged); + setting_setup_signal_listener(gSavedSettings, "LocalTerrainAsset4", handleLocalTerrainChanged); setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged); } diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 815489f753..c4bed85be7 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -42,6 +42,8 @@ #include "llviewercontrol.h" +static const U32 BASE_SIZE = 128; + F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) { @@ -59,40 +61,40 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F return result; } - -LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : - LLViewerLayer(width, scale) +LLTerrainMaterials::LLTerrainMaterials() { - mSurfacep = surfacep; - - // Load Terrain Textures - Original ones - setDetailAssetID(0, TERRAIN_DIRT_DETAIL); - setDetailAssetID(1, TERRAIN_GRASS_DETAIL); - setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailAssetID(3, TERRAIN_ROCK_DETAIL); - - // Initialize the texture matrix to defaults. - for (S32 i = 0; i < CORNER_COUNT; ++i) - { - mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); - mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); - } - for (S32 i = 0; i < ASSET_COUNT; ++i) { mMaterialTexturesSet[i] = false; } } - -LLVLComposition::~LLVLComposition() +LLTerrainMaterials::~LLTerrainMaterials() { } +BOOL LLTerrainMaterials::generateMaterials() +{ + if (texturesReady(TRUE)) + { + return TRUE; + } -void LLVLComposition::setSurface(LLSurface *surfacep) + if (materialsReady(TRUE)) + { + return TRUE; + } + + return FALSE; +} + +LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) { - mSurfacep = surfacep; + llassert(mDetailTextures[asset] && mDetailMaterials[asset]); + // *HACK: Assume both the the material and texture were fetched in the same + // way using the same UUID. However, we may not know at this point which + // one will load. + return mDetailTextures[asset]->getID(); } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -107,126 +109,51 @@ LLPointer fetch_terrain_texture(const LLUUID& id) return tex; } -void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) +void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) { - if(id.isNull()) - { - return; - } // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); - mRawImages[asset] = NULL; LLPointer& mat = mDetailMaterials[asset]; mat = gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; } -BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, - const F32 width, const F32 height) +BOOL LLTerrainMaterials::useTextures() { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } - - llassert(mSurfacep); - - if (!mSurfacep || !mSurfacep->getRegion()) - { - // We don't always have the region yet here.... - return FALSE; - } - - S32 x_begin, y_begin, x_end, y_end; + LL_PROFILE_ZONE_SCOPED; - x_begin = ll_round( x * mScaleInv ); - y_begin = ll_round( y * mScaleInv ); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); + return texturesReady() || !materialsReady(); +} - if (x_end > mWidth) - { - x_end = mWidth; - } - if (y_end > mWidth) +BOOL LLTerrainMaterials::texturesReady(BOOL boost) +{ + for (S32 i = 0; i < ASSET_COUNT; i++) { - y_end = mWidth; + if (!textureReady(mDetailTextures[i], boost)) + { + return FALSE; + } } + return TRUE; +} - LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); - - // For perlin noise generation... - const F32 slope_squared = 1.5f*1.5f; - const F32 xyScale = 4.9215f; //0.93284f; - const F32 zScale = 4; //0.92165f; - const F32 z_offset = 0.f; - const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus - // simple height) - - const F32 xyScaleInv = (1.f / xyScale); - const F32 zScaleInv = (1.f / zScale); - - const F32 inv_width = 1.f/mWidth; - - // OK, for now, just have the composition value equal the height at the point. - for (S32 j = y_begin; j < y_end; j++) +BOOL LLTerrainMaterials::materialsReady(BOOL boost) +{ + for (S32 i = 0; i < ASSET_COUNT; i++) { - for (S32 i = x_begin; i < x_end; i++) - { - - F32 vec[3]; - F32 vec1[3]; - F32 twiddle; - - // Bilinearly interpolate the start height and height range of the textures - F32 start_height = bilinear(mStartHeight[SOUTHWEST], - mStartHeight[SOUTHEAST], - mStartHeight[NORTHWEST], - mStartHeight[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - F32 height_range = bilinear(mHeightRange[SOUTHWEST], - mHeightRange[SOUTHEAST], - mHeightRange[NORTHWEST], - mHeightRange[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - - LLVector3 location(i*mScale, j*mScale, 0.f); - - F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; - - // Step 0: Measure the exact height at this texel - vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice - vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; - vec[2] = height*zScaleInv; - // - // Choose material value by adding to the exact height a random value - // - vec1[0] = vec[0]*(0.2222222222f); - vec1[1] = vec[1]*(0.2222222222f); - vec1[2] = vec[2]*(0.2222222222f); - twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions - - twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component - twiddle *= noise_magnitude; - - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; - - scaled_noisy_height = llmax(0.f, scaled_noisy_height); - scaled_noisy_height = llmin(3.f, scaled_noisy_height); - *(mDatap + i + j*mWidth) = scaled_noisy_height; - } - } - return TRUE; + if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) + { + return FALSE; + } + } + return TRUE; } -static const U32 BASE_SIZE = 128; - // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) // static -BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) +BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BOOL boost) { llassert(tex.notNull()); @@ -266,9 +193,9 @@ BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL // Boost the loading priority of every known texture in the material // Return true when ready to use (i.e. material and all textures within are sufficiently loaded) // static -BOOL LLVLComposition::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) +BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) { - if (!mat->isLoaded()) + if (!mat || !mat->isLoaded()) { return FALSE; } @@ -308,37 +235,140 @@ BOOL LLVLComposition::materialReady(LLPointer& mat, bool& return TRUE; } -BOOL LLVLComposition::useTextures() + +LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : + LLTerrainMaterials(), + LLViewerLayer(width, scale) +{ + // Load Terrain Textures - Original ones + setDetailAssetID(0, TERRAIN_DIRT_DETAIL); + setDetailAssetID(1, TERRAIN_GRASS_DETAIL); + setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); + setDetailAssetID(3, TERRAIN_ROCK_DETAIL); + + mSurfacep = surfacep; + + // Initialize the texture matrix to defaults. + for (S32 i = 0; i < CORNER_COUNT; ++i) + { + mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); + mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); + } +} + + +LLVLComposition::~LLVLComposition() { - LL_PROFILE_ZONE_SCOPED; + LLTerrainMaterials::~LLTerrainMaterials(); +} - return texturesReady() || !materialsReady(); + +void LLVLComposition::setSurface(LLSurface *surfacep) +{ + mSurfacep = surfacep; } -BOOL LLVLComposition::texturesReady(BOOL boost) +BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, + const F32 width, const F32 height) { - for (S32 i = 0; i < ASSET_COUNT; i++) + if (!mParamsReady) { - if (!textureReady(mDetailTextures[i], boost)) - { - return FALSE; - } + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; } - return TRUE; -} -BOOL LLVLComposition::materialsReady(BOOL boost) -{ - for (S32 i = 0; i < ASSET_COUNT; i++) + llassert(mSurfacep); + + if (!mSurfacep || !mSurfacep->getRegion()) { - if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) - { - return FALSE; - } - } - return TRUE; + // We don't always have the region yet here.... + return FALSE; + } + + S32 x_begin, y_begin, x_end, y_end; + + x_begin = ll_round( x * mScaleInv ); + y_begin = ll_round( y * mScaleInv ); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { + x_end = mWidth; + } + if (y_end > mWidth) + { + y_end = mWidth; + } + + LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); + + // For perlin noise generation... + const F32 slope_squared = 1.5f*1.5f; + const F32 xyScale = 4.9215f; //0.93284f; + const F32 zScale = 4; //0.92165f; + const F32 z_offset = 0.f; + const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus + // simple height) + + const F32 xyScaleInv = (1.f / xyScale); + const F32 zScaleInv = (1.f / zScale); + + const F32 inv_width = 1.f/mWidth; + + // OK, for now, just have the composition value equal the height at the point. + for (S32 j = y_begin; j < y_end; j++) + { + for (S32 i = x_begin; i < x_end; i++) + { + + F32 vec[3]; + F32 vec1[3]; + F32 twiddle; + + // Bilinearly interpolate the start height and height range of the textures + F32 start_height = bilinear(mStartHeight[SOUTHWEST], + mStartHeight[SOUTHEAST], + mStartHeight[NORTHWEST], + mStartHeight[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + F32 height_range = bilinear(mHeightRange[SOUTHWEST], + mHeightRange[SOUTHEAST], + mHeightRange[NORTHWEST], + mHeightRange[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + + LLVector3 location(i*mScale, j*mScale, 0.f); + + F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; + + // Step 0: Measure the exact height at this texel + vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice + vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; + vec[2] = height*zScaleInv; + // + // Choose material value by adding to the exact height a random value + // + vec1[0] = vec[0]*(0.2222222222f); + vec1[1] = vec[1]*(0.2222222222f); + vec1[2] = vec[2]*(0.2222222222f); + twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions + + twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component + twiddle *= noise_magnitude; + + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; + + scaled_noisy_height = llmax(0.f, scaled_noisy_height); + scaled_noisy_height = llmin(3.f, scaled_noisy_height); + *(mDatap + i + j*mWidth) = scaled_noisy_height; + } + } + return TRUE; } +LLTerrainMaterials gLocalTerrainMaterials; + BOOL LLVLComposition::generateComposition() { if (!mParamsReady) @@ -347,17 +377,7 @@ BOOL LLVLComposition::generateComposition() return FALSE; } - if (texturesReady(TRUE)) - { - return TRUE; - } - - if (materialsReady(TRUE)) - { - return TRUE; - } - - return FALSE; + return LLTerrainMaterials::generateMaterials(); } // TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. @@ -592,18 +612,19 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, return TRUE; } -LLUUID LLVLComposition::getDetailAssetID(S32 corner) +F32 LLVLComposition::getStartHeight(S32 corner) { - llassert(mDetailTextures[corner] && mDetailMaterials[corner]); - // *HACK: Assume both the the material and texture were fetched in the same - // way using the same UUID. However, we may not know at this point which - // one will load. - return mDetailTextures[corner]->getID(); + return mStartHeight[corner]; } -F32 LLVLComposition::getStartHeight(S32 corner) +void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { - return mStartHeight[corner]; + if (id.isNull()) + { + return; + } + LLTerrainMaterials::setDetailAssetID(asset, id); + mRawImages[asset] = NULL; } void LLVLComposition::setStartHeight(S32 corner, const F32 start_height) diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 504441d0f2..9dc0b7221e 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -37,7 +37,38 @@ class LLSurface; class LLViewerFetchedTexture; class LLFetchedGLTFMaterial; -class LLVLComposition : public LLViewerLayer +class LLTerrainMaterials +{ +public: + friend class LLDrawPoolTerrain; + + LLTerrainMaterials(); + virtual ~LLTerrainMaterials(); + + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. + static const S32 ASSET_COUNT = 4; + + BOOL generateMaterials(); + + LLUUID getDetailAssetID(S32 asset); + virtual void setDetailAssetID(S32 asset, const LLUUID& id); + BOOL useTextures(); + BOOL texturesReady(BOOL boost = FALSE); + BOOL materialsReady(BOOL boost = FALSE); + +protected: + static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); + static BOOL materialReady(LLPointer& mat, bool& textures_set, BOOL boost = FALSE); + LLPointer mDetailTextures[ASSET_COUNT]; + LLPointer mDetailMaterials[ASSET_COUNT]; + bool mMaterialTexturesSet[ASSET_COUNT]; +}; + +// Local materials to override all regions +extern LLTerrainMaterials gLocalTerrainMaterials; + +class LLVLComposition : public LLTerrainMaterials, public LLViewerLayer { public: LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale); @@ -65,11 +96,10 @@ public: CORNER_COUNT = 4 }; - LLUUID getDetailAssetID(S32 asset); + void setDetailAssetID(S32 asset, const LLUUID& id) override; F32 getStartHeight(S32 corner); F32 getHeightRange(S32 corner); - void setDetailAssetID(S32 asset, const LLUUID& id); void setStartHeight(S32 corner, F32 start_height); void setHeightRange(S32 corner, F32 range); @@ -77,9 +107,6 @@ public: friend class LLDrawPoolTerrain; void setParamsReady() { mParamsReady = TRUE; } BOOL getParamsReady() const { return mParamsReady; } - BOOL useTextures(); - BOOL texturesReady(BOOL boost = FALSE); - BOOL materialsReady(BOOL boost = FALSE); protected: static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); @@ -88,10 +115,7 @@ protected: BOOL mParamsReady = FALSE; LLSurface *mSurfacep; - LLPointer mDetailTextures[ASSET_COUNT]; - LLPointer mRawImages[ASSET_COUNT]; - LLPointer mDetailMaterials[ASSET_COUNT]; - bool mMaterialTexturesSet[ASSET_COUNT]; + LLPointer mRawImages[LLTerrainMaterials::ASSET_COUNT]; F32 mStartHeight[CORNER_COUNT]; F32 mHeightRange[CORNER_COUNT]; -- cgit v1.2.3 From 14c3730bf128a6f01825954ee67a06188e134526 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:20 -0700 Subject: DRTVWR-592: Fix unable to undo effect of local terrain debug setting without restarting viewer --- indra/newview/llvlcomposition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c4bed85be7..8d55c80be8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -115,7 +115,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); LLPointer& mat = mDetailMaterials[asset]; - mat = gGLTFMaterialList.getMaterial(id); + mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; } -- cgit v1.2.3 From d2da77698005579f9fdaecad5a5d80189ad03f23 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:27 -0700 Subject: DRTVWR-592: Fix some virtual functions not being marked override --- indra/newview/llfloaterregioninfo.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 43a69e5804..bfdeb9440d 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -76,7 +76,7 @@ public: void onOpen(const LLSD& key) override; - /*virtual*/ void onClose(bool app_quitting); + void onClose(bool app_quitting) override; BOOL postBuild() override; static void processEstateOwnerRequest(LLMessageSystem* msg, void**); @@ -249,7 +249,7 @@ public: BOOL postBuild() override; - bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator + bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region BOOL validateTextureSizes(); @@ -308,10 +308,10 @@ public: static void updateEstateOwnerName(const std::string& name); bool refreshFromRegion(LLViewerRegion* region) override; - virtual bool estateUpdate(LLMessageSystem* msg); + bool estateUpdate(LLMessageSystem* msg) override; BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); + void updateChild(LLUICtrl* child_ctrl) override; void refresh() override; void refreshFromEstate(); @@ -343,15 +343,15 @@ public: ~LLPanelEstateCovenant() {} BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); + void updateChild(LLUICtrl* child_ctrl) override; bool refreshFromRegion(LLViewerRegion* region) override; - virtual bool estateUpdate(LLMessageSystem* msg); + bool estateUpdate(LLMessageSystem* msg) override; // LLView overrides BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, - std::string& tooltip_msg); + std::string& tooltip_msg) override; static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response); static void resetCovenantID(void* userdata); static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response); @@ -441,7 +441,7 @@ public: LLPanelEstateAccess(); BOOL postBuild() override; - virtual void updateChild(LLUICtrl* child_ctrl); + void updateChild(LLUICtrl* child_ctrl) override; void updateControls(LLViewerRegion* region); void updateLists(); -- cgit v1.2.3 From 1820f23b96a50962a3a6a3d48de1aff8e1acb2c0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:35 -0700 Subject: DRTVWR-592: Fix issues with blending of materials, for example when fading out an emissive texture. Also affects base color and ORM --- .../shaders/class1/deferred/pbrterrainF.glsl | 105 ++++++++++++--------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 4de6b9609c..85691ae9b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -80,38 +80,63 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); } -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = srgb_to_linear(texture2D(tex0, texcoord).xyz); - samples[1] = srgb_to_linear(texture2D(tex1, texcoord).xyz); - samples[2] = srgb_to_linear(texture2D(tex2, texcoord).xyz); - samples[3] = srgb_to_linear(texture2D(tex3, texcoord).xyz); + samples[0] = texture2D(tex0, texcoord).xyz; + samples[1] = texture2D(tex1, texcoord).xyz; + samples[2] = texture2D(tex2, texcoord).xyz; + samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = srgb_to_linear(samples[0]); + samples[1] = srgb_to_linear(samples[1]); + samples[2] = srgb_to_linear(samples[2]); + samples[3] = srgb_to_linear(samples[3]); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; samples[0] = texture2D(tex0, texcoord); samples[1] = texture2D(tex1, texcoord); samples[2] = texture2D(tex2, texcoord); samples[3] = texture2D(tex3, texcoord); - // TODO: Why is this needed for pbropaqueF but not here? (and is there different behavior with base color vs emissive color, that also needs to be corrected?) - //samples[0].xyz = srgb_to_linear(samples[0].xyz); - //samples[1].xyz = srgb_to_linear(samples[1].xyz); - //samples[2].xyz = srgb_to_linear(samples[2].xyz); - //samples[3].xyz = srgb_to_linear(samples[3].xyz); + samples[0].xyz = srgb_to_linear(samples[0].xyz); + samples[1].xyz = srgb_to_linear(samples[1].xyz); + samples[2].xyz = srgb_to_linear(samples[2].xyz); + samples[3].xyz = srgb_to_linear(samples[3].xyz); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec4[4] samples; - samples[0] = texture2D(tex0, texcoord); - samples[1] = texture2D(tex1, texcoord); - samples[2] = texture2D(tex2, texcoord); - samples[3] = texture2D(tex3, texcoord); + vec3[4] samples; + samples[0] = texture2D(tex0, texcoord).xyz; + samples[1] = texture2D(tex1, texcoord).xyz; + samples[2] = texture2D(tex2, texcoord).xyz; + samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = texture2D(tex0, texcoord).xyz; + samples[1] = texture2D(tex1, texcoord).xyz; + samples[2] = texture2D(tex2, texcoord).xyz; + samples[3] = texture2D(tex3, texcoord).xyz; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } @@ -124,23 +149,30 @@ void main() float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; - vec4 base_color = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); + vec4 col = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, baseColorFactors, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); - if (base_color.a < minimum_alpha) + if (col.a < minimum_alpha) { discard; } - vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); - vec3 emissive_texture = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - vec4 baseColorFactor = terrain_mix(baseColorFactors, alpha1, alpha2, alphaFinal); - float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal); - float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal); - vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal); + vec3[4] orm_factors; + orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); + orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); + orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); + orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); + // RGB = Occlusion, Roughness, Metal + // default values, see LLViewerTexture::sDefaultPBRORMImagep + // occlusion 1.0 + // roughness 0.0 + // metal 0.0 + vec3 spec = sample_and_mix_vector3(alpha1, alpha2, alphaFinal, terrain_texcoord, orm_factors, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); - vec3 col = baseColorFactor.rgb * srgb_to_linear(base_color.rgb); + vec3 emissive = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, emissiveColors, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); + + float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); // from mikktspace.com vec3 vNt = normal_texture.xyz*2.0-1.0; @@ -151,25 +183,12 @@ void main() vec3 vB = sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); - // RGB = Occlusion, Roughness, Metal - // default values, see LLViewerTexture::sDefaultPBRORMImagep - // occlusion 1.0 - // roughness 0.0 - // metal 0.0 - vec3 spec = metallic_roughness.rgb; - - spec.g *= roughnessFactor; - spec.b *= metallicFactor; - - vec3 emissive = emissiveColor; - emissive *= emissive_texture.rgb; - tnorm *= gl_FrontFacing ? 1.0 : -1.0; - frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse - frag_data[1] = max(vec4(spec.rgb,baseColorFactor.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. - frag_data[2] = max(vec4(encode_normal(tnorm), baseColorFactor.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags + frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse + frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } -- cgit v1.2.3 From 3b3ba3623ac816633b1bd67f5d3b4dea65a83b17 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:43 -0700 Subject: DRTVWR-592: Overdraw is not free. Render terrain after Opaque Blinn-Phong/PBR have populated the foreground --- indra/newview/lldrawpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index d5ef734c4b..c0bcb2b48d 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -56,9 +56,9 @@ public: POOL_SIMPLE = 1, POOL_FULLBRIGHT, POOL_BUMP, - POOL_TERRAIN, POOL_MATERIALS, POOL_GLTF_PBR, + POOL_TERRAIN, POOL_GRASS, POOL_GLTF_PBR_ALPHA_MASK, POOL_TREE, -- cgit v1.2.3 From de9184479cfc179ba6e9d6ff388aff7da7f0b4ab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:50 -0700 Subject: DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing --- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llsurfacepatch.cpp | 1 + indra/newview/llvlcomposition.cpp | 13 ++++-- indra/newview/llvlcomposition.h | 9 +++- indra/newview/llvosurfacepatch.cpp | 84 +++++++++++++++++++++---------------- indra/newview/llvosurfacepatch.h | 12 ++++-- 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8755e53763..e072e1def2 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - const BOOL use_textures = !use_local_materials && compp->useTextures(); + const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::MaterialType::TEXTURE); if (use_textures) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 449d3d95c8..81fb4cf0cd 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,6 +209,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); + // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? U32 surface_stride = mSurfacep->getGridsPerEdge(); U32 point_offset = x + y*surface_stride; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d55c80be8..8cd22e3bdb 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,13 +119,20 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::useTextures() +BOOL LLTerrainMaterials::getMaterialType() +{ + return mMaterialType; +} + +void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; - return texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady() || !materialsReady(); + mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } + BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -401,7 +408,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = useTextures(); + const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 9dc0b7221e..882c3d89b2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -49,11 +49,18 @@ public: // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; + enum class Type + { + TEXTURE, + PBR, + COUNT + }; + BOOL generateMaterials(); LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - BOOL useTextures(); + Type getMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 839eb2b737..69b721c899 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,7 +246,8 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp) + LLStrider &indicesp, + bool pbr) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -262,30 +263,34 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, j, x, y; @@ -321,7 +326,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -384,12 +389,13 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 vertex_count = 0; S32 i, x, y; @@ -421,7 +427,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -434,7 +440,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -471,7 +477,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -485,7 +491,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -529,7 +535,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -543,7 +549,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -581,12 +587,13 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, x, y; @@ -612,7 +619,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -624,7 +631,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -660,7 +667,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -672,7 +679,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -714,7 +721,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -726,7 +733,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -1037,6 +1044,13 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; + const LLFace* region_facep = *mFaceList.begin(); + const LLViewerObject* region_patchp = region_facep->getViewerObject(); + LLVLComposition* composition = region_patchp->mRegionp->getComposition(); + // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. + composition->updateMaterialType(); + const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; + LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a3dcb945d1..06bb373578 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,7 +67,8 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp); + LLStrider &indicesp, + bool pbr); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -121,21 +122,24 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 2318d657660320b921e1566b54d3833c0401a34c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 22 May 2023 10:10:14 -0700 Subject: Revert "DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing" This reverts commit de9184479cfc179ba6e9d6ff388aff7da7f0b4ab. --- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llsurfacepatch.cpp | 1 - indra/newview/llvlcomposition.cpp | 13 ++---- indra/newview/llvlcomposition.h | 9 +--- indra/newview/llvosurfacepatch.cpp | 84 ++++++++++++++++--------------------- indra/newview/llvosurfacepatch.h | 12 ++---- 6 files changed, 44 insertions(+), 77 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index e072e1def2..8755e53763 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::MaterialType::TEXTURE); + const BOOL use_textures = !use_local_materials && compp->useTextures(); if (use_textures) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 81fb4cf0cd..449d3d95c8 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,7 +209,6 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); - // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? U32 surface_stride = mSurfacep->getGridsPerEdge(); U32 point_offset = x + y*surface_stride; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8cd22e3bdb..8d55c80be8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,20 +119,13 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::getMaterialType() -{ - return mMaterialType; -} - -void LLTerrainMaterials::updateMaterialType() +BOOL LLTerrainMaterials::useTextures() { LL_PROFILE_ZONE_SCOPED; - const BOOL use_textures = texturesReady() || !materialsReady(); - mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; + return texturesReady() || !materialsReady(); } - BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -408,7 +401,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; + const bool use_textures = useTextures(); for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 882c3d89b2..9dc0b7221e 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -49,18 +49,11 @@ public: // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; - enum class Type - { - TEXTURE, - PBR, - COUNT - }; - BOOL generateMaterials(); LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - Type getMaterialType(); + BOOL useTextures(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 69b721c899..839eb2b737 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,8 +246,7 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr) + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -263,34 +262,30 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset, - bool pbr) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset) { S32 i, j, x, y; @@ -326,7 +321,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -389,13 +384,12 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset, - bool pbr) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset) { S32 vertex_count = 0; S32 i, x, y; @@ -427,7 +421,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -440,7 +434,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -477,7 +471,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -491,7 +485,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -535,7 +529,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -549,7 +543,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -587,13 +581,12 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset, - bool pbr) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset) { S32 i, x, y; @@ -619,7 +612,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -631,7 +624,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -667,7 +660,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -679,7 +672,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -721,7 +714,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -733,7 +726,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -1044,13 +1037,6 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; - const LLFace* region_facep = *mFaceList.begin(); - const LLViewerObject* region_patchp = region_facep->getViewerObject(); - LLVLComposition* composition = region_patchp->mRegionp->getComposition(); - // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. - composition->updateMaterialType(); - const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; - LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 06bb373578..a3dcb945d1 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,8 +67,7 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr); + LLStrider &indicesp); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -122,24 +121,21 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From dfa19c5e436edb102d8bd121c853153303631b4d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:33:16 -0700 Subject: DRTVWR-592: PBR terrain fallback for Mac/Intel: Drop emissive texture. Bump featuretable. --- indra/newview/app_settings/settings.xml | 11 +++++ .../shaders/class1/deferred/pbrterrainF.glsl | 10 ++++ indra/newview/featuretable.txt | 2 + indra/newview/featuretable_mac.txt | 1 + indra/newview/lldrawpoolterrain.cpp | 54 +++++++++++++--------- indra/newview/lldrawpoolterrain.h | 3 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 35 +++++++------- indra/newview/llviewershadermgr.h | 11 +++++ 9 files changed, 89 insertions(+), 39 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 013f0ca8ff..94cc5a14a4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10711,6 +10711,17 @@ Value 12.0 + RenderTerrainPBRDetail + + Comment + Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features in accordance with the GLTF specification, which reduces the number of texture binds. Some Intel and Mac graphics drivers do not support more than 16 texture binds. Because PBR terrain exceeds this limit at the highest detail level, reducing texture binds is necessary for compatibility. + Persist + 1 + Type + S32 + Value + 0 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 85691ae9b6..344c342189 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 + out vec4 frag_data[4]; uniform sampler2D alpha_ramp; @@ -42,16 +44,20 @@ uniform sampler2D detail_0_metallic_roughness; uniform sampler2D detail_1_metallic_roughness; uniform sampler2D detail_2_metallic_roughness; uniform sampler2D detail_3_metallic_roughness; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) uniform sampler2D detail_0_emissive; uniform sampler2D detail_1_emissive; uniform sampler2D detail_2_emissive; uniform sampler2D detail_3_emissive; +#endif // *TODO: More efficient packing? uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl uniform vec4 metallicFactors; uniform vec4 roughnessFactors; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) uniform vec3[4] emissiveColors; +#endif uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() in vec3 vary_normal; @@ -170,7 +176,11 @@ void main() // metal 0.0 vec3 spec = sample_and_mix_vector3(alpha1, alpha2, alphaFinal, terrain_texcoord, orm_factors, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) vec3 emissive = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, emissiveColors, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); +#else + vec3 emissive = vec3(0); +#endif float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 39f7996c7c..b8e8cffed8 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -48,6 +48,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 2 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 @@ -312,6 +313,7 @@ RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 RenderGLMultiThreadedMedia 1 0 +RenderTerrainPBRDetail 1 -1 list AMD RenderGLMultiThreadedTextures 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index cce403c7aa..d775f04810 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -45,6 +45,7 @@ RenderObjectBump 1 1 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 -1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8755e53763..8442e61bb9 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -54,7 +54,10 @@ const F32 DETAIL_SCALE = 1.f/16.f; int DebugDetailMap = 0; +const S32 PBR_DETAIL_EMISSIVE = 0; + S32 LLDrawPoolTerrain::sDetailMode = 1; +S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow"); @@ -66,7 +69,9 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : { // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); + // TODO: This is unused. Remove? sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); + sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD); //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); @@ -106,12 +111,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask() void LLDrawPoolTerrain::prerender() { sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); -} - -//static -S32 LLDrawPoolTerrain::getDetailMode() -{ - return sDetailMode; + sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); } void LLDrawPoolTerrain::boostTerrainDetailTextures() @@ -371,7 +371,7 @@ void LLDrawPoolTerrain::renderFullShaderTextures() gGL.getTexUnit(detail0)->activate(); } -// TODO: Investigate use of bindFast for PBR terrain textures +// *TODO: Investigate use of bindFast for PBR terrain textures void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) { // Hack! Get the region that this draw pool is rendering from! @@ -445,17 +445,20 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(detail_metalrough[i])->activate(); - detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); - if (detail_emissive_texturep) - { - gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); - } - else + if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) { - gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); + if (detail_emissive_texturep) + { + gGL.getTexUnit(detail_emissive[i])->bind(detail_emissive_texturep); + } + else + { + gGL.getTexUnit(detail_emissive[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + } + gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_emissive[i])->activate(); } - gGL.getTexUnit(detail_emissive[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail_emissive[i])->activate(); } LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; @@ -506,7 +509,10 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors); shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]); shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]); - shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors); + if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + { + shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors); + } shader->uniform4f(LLShaderMgr::TERRAIN_MINIMUM_ALPHAS, minimum_alphas[0], minimum_alphas[1], minimum_alphas[2], minimum_alphas[3]); // GL_BLEND disabled by default @@ -525,7 +531,10 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); + if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + { + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); + } gGL.getTexUnit(detail_basecolor[i])->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(detail_basecolor[i])->disable(); @@ -539,9 +548,12 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) gGL.getTexUnit(detail_metalrough[i])->disable(); gGL.getTexUnit(detail_metalrough[i])->activate(); - gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail_emissive[i])->disable(); - gGL.getTexUnit(detail_emissive[i])->activate(); + if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + { + gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_emissive[i])->disable(); + gGL.getTexUnit(detail_emissive[i])->activate(); + } } } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 1a27cc8be0..060354458d 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -43,8 +43,6 @@ public: }; virtual U32 getVertexDataMask(); - static S32 getDetailMode(); - LLDrawPoolTerrain(LLViewerTexture *texturep); virtual ~LLDrawPoolTerrain(); @@ -69,6 +67,7 @@ public: LLPointer mAlphaNoiseImagep; static S32 sDetailMode; + static S32 sPBRDetailMode; static F32 sDetailScale; // meters per texture protected: diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4e0ad11597..41b13cacbb 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -702,6 +702,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 19b3c59cae..2235b6d9a4 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1494,23 +1494,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredPBRTerrainProgram.mName = "Deferred PBR Terrain Shader"; - gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; - gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; - gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; - gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; - gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; - gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; - gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; - gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; - - gDeferredPBRTerrainProgram.mShaderFiles.clear(); - gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); - gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); - gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); + detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); + gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d", detail); + gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; + gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; + gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; + gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; + gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; + gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; + gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; + + gDeferredPBRTerrainProgram.mShaderFiles.clear(); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); + gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); + gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PBR_DETAIL", llformat("%d", detail)); success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); - llassert(success); + llassert(success); } if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 6765703ab8..8b4a19f8c3 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -278,5 +278,16 @@ extern LLGLSLShader gDeferredPBROpaqueProgram; extern LLGLSLShader gDeferredPBRAlphaProgram; extern LLGLSLShader gDeferredPBRAlphaWaterProgram; extern LLGLSLShader gHUDPBRAlphaProgram; + +// Encodes detail level for dropping textures, in accordance with the GLTF spec +// 0 is highest detail, -1 drops emissive, etc +// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures +enum TerrainPBRDetail : S32 +{ + TERRAIN_PBR_DETAIL_MAX = 0, + TERRAIN_PBR_DETAIL_EMISSIVE = 0, + TERRAIN_PBR_DETAIL_OCCLUSION = -1, + TERRAIN_PBR_DETAIL_MIN = -1, +}; extern LLGLSLShader gDeferredPBRTerrainProgram; #endif -- cgit v1.2.3 From cbf202d6324dfe67218e3a0d20ec1589f2906517 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 22 May 2023 18:19:14 -0700 Subject: SL-19750: Only disable PBR terrain emissive for machines that have a limit of 16 texture binds. Bump featuretable --- indra/newview/featuretable.txt | 5 +++-- indra/newview/featuretable_mac.txt | 6 ++++-- indra/newview/llfeaturemanager.cpp | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index b8e8cffed8..cb941b424b 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 58 +version 59 // 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 @@ -313,7 +313,6 @@ RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 RenderGLMultiThreadedMedia 1 0 -RenderTerrainPBRDetail 1 -1 list AMD RenderGLMultiThreadedTextures 1 1 @@ -323,3 +322,5 @@ RenderFSAASamples 0 0 RenderReflectionsEnabled 0 0 RenderReflectionProbeDetail 0 0 +list TexUnit16orLess +RenderTerrainPBRDetail 1 -1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index d775f04810..c04c1c9a4f 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 53 +version 54 // 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 @@ -45,7 +45,6 @@ RenderObjectBump 1 1 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 -RenderTerrainPBRDetail 1 -1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 @@ -309,6 +308,9 @@ RenderShadowDetail 0 0 list TexUnit8orLess RenderDeferredSSAO 0 0 +list TexUnit16orLess +RenderTerrainPBRDetail 1 -1 + list AMD RenderDeferredSSAO 1 0 diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index f482d5a37d..9fff505c2a 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -664,6 +664,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("TexUnit8orLess"); } + if (gGLManager.mNumTextureImageUnits <= 16) + { + maskFeatures("TexUnit16orLess"); + } if (gGLManager.mVRAM > 512) { maskFeatures("VRAMGT512"); -- cgit v1.2.3 From a65c9dad5521d8e8d375003220e362533a142250 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:33:21 -0700 Subject: DRTVWR-592: Another attempt to fix Mac build: remove deprecated use of texture2D --- .../shaders/class1/deferred/pbrterrainF.glsl | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 344c342189..73d4d9e3bc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -89,10 +89,10 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = texture2D(tex0, texcoord).xyz; - samples[1] = texture2D(tex1, texcoord).xyz; - samples[2] = texture2D(tex2, texcoord).xyz; - samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = texture(tex0, texcoord).xyz; + samples[1] = texture(tex1, texcoord).xyz; + samples[2] = texture(tex2, texcoord).xyz; + samples[3] = texture(tex3, texcoord).xyz; samples[0] = srgb_to_linear(samples[0]); samples[1] = srgb_to_linear(samples[1]); samples[2] = srgb_to_linear(samples[2]); @@ -107,10 +107,10 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 te vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; - samples[0] = texture2D(tex0, texcoord); - samples[1] = texture2D(tex1, texcoord); - samples[2] = texture2D(tex2, texcoord); - samples[3] = texture2D(tex3, texcoord); + samples[0] = texture(tex0, texcoord); + samples[1] = texture(tex1, texcoord); + samples[2] = texture(tex2, texcoord); + samples[3] = texture(tex3, texcoord); samples[0].xyz = srgb_to_linear(samples[0].xyz); samples[1].xyz = srgb_to_linear(samples[1].xyz); samples[2].xyz = srgb_to_linear(samples[2].xyz); @@ -125,10 +125,10 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 te vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = texture2D(tex0, texcoord).xyz; - samples[1] = texture2D(tex1, texcoord).xyz; - samples[2] = texture2D(tex2, texcoord).xyz; - samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = texture(tex0, texcoord).xyz; + samples[1] = texture(tex1, texcoord).xyz; + samples[2] = texture(tex2, texcoord).xyz; + samples[3] = texture(tex3, texcoord).xyz; samples[0] *= factors[0]; samples[1] *= factors[1]; samples[2] *= factors[2]; @@ -139,10 +139,10 @@ vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 t vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = texture2D(tex0, texcoord).xyz; - samples[1] = texture2D(tex1, texcoord).xyz; - samples[2] = texture2D(tex2, texcoord).xyz; - samples[3] = texture2D(tex3, texcoord).xyz; + samples[0] = texture(tex0, texcoord).xyz; + samples[1] = texture(tex1, texcoord).xyz; + samples[2] = texture(tex2, texcoord).xyz; + samples[3] = texture(tex3, texcoord).xyz; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } @@ -151,9 +151,9 @@ void main() // Adjust the texture repeats for a more sensible default. float texture_density_factor = 2.0; vec2 terrain_texcoord = texture_density_factor * vary_texcoord0.xy; - float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a; - float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a; - float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a; + float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; + float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; + float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; vec4 col = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, baseColorFactors, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); -- cgit v1.2.3 From 57433341abffba9382e6899b164af40200f5d6d3 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:35:02 -0700 Subject: Revert "Revert "DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing"" This reverts commit 2318d657660320b921e1566b54d3833c0401a34c. --- indra/newview/lldrawpoolterrain.cpp | 2 +- indra/newview/llsurfacepatch.cpp | 1 + indra/newview/llvlcomposition.cpp | 13 ++++-- indra/newview/llvlcomposition.h | 9 +++- indra/newview/llvosurfacepatch.cpp | 84 +++++++++++++++++++++---------------- indra/newview/llvosurfacepatch.h | 12 ++++-- 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8442e61bb9..926d5e78d0 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - const BOOL use_textures = !use_local_materials && compp->useTextures(); + const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::MaterialType::TEXTURE); if (use_textures) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 449d3d95c8..81fb4cf0cd 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,6 +209,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); + // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? U32 surface_stride = mSurfacep->getGridsPerEdge(); U32 point_offset = x + y*surface_stride; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d55c80be8..8cd22e3bdb 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,13 +119,20 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::useTextures() +BOOL LLTerrainMaterials::getMaterialType() +{ + return mMaterialType; +} + +void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; - return texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady() || !materialsReady(); + mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } + BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -401,7 +408,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = useTextures(); + const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 9dc0b7221e..882c3d89b2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -49,11 +49,18 @@ public: // So we need to compress heights into this range. static const S32 ASSET_COUNT = 4; + enum class Type + { + TEXTURE, + PBR, + COUNT + }; + BOOL generateMaterials(); LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); - BOOL useTextures(); + Type getMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 839eb2b737..69b721c899 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,7 +246,8 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp) + LLStrider &indicesp, + bool pbr) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -262,30 +263,34 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset); + index_offset, + pbr); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, j, x, y; @@ -321,7 +326,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -384,12 +389,13 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 vertex_count = 0; S32 i, x, y; @@ -421,7 +427,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -434,7 +440,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -471,7 +477,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -485,7 +491,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -529,7 +535,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -543,7 +549,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -581,12 +587,13 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, } void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, - LLStrider &verticesp, - LLStrider &normalsp, - LLStrider &texCoords0p, - LLStrider &texCoords1p, - LLStrider &indicesp, - U32 &index_offset) + LLStrider &verticesp, + LLStrider &normalsp, + LLStrider &texCoords0p, + LLStrider &texCoords1p, + LLStrider &indicesp, + U32 &index_offset, + bool pbr) { S32 i, x, y; @@ -612,7 +619,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -624,7 +631,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -660,7 +667,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -672,7 +679,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -714,7 +721,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -726,7 +733,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); verticesp++; normalsp++; texCoords0p++; @@ -1037,6 +1044,13 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; + const LLFace* region_facep = *mFaceList.begin(); + const LLViewerObject* region_patchp = region_facep->getViewerObject(); + LLVLComposition* composition = region_patchp->mRegionp->getComposition(); + // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. + composition->updateMaterialType(); + const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; + LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a3dcb945d1..06bb373578 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,7 +67,8 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp); + LLStrider &indicesp, + bool pbr); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -121,21 +122,24 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset); + U32 &index_offset, + bool pbr); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From b9ba57fd0004751dfbcbea90264a6e16c5849e5e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:42 -0700 Subject: DRTVWR-592: (WIP) Fix terrain PBR texture repeat seam. Legacy terrain texture repeats currently broken --- .../shaders/class1/deferred/pbrterrainF.glsl | 25 +++++++++++++++++++--- .../shaders/class1/deferred/pbrterrainV.glsl | 22 +++++++++++++------ indra/newview/lldrawpoolterrain.cpp | 4 +++- indra/newview/llsurfacepatch.cpp | 14 +++++++++--- indra/newview/llsurfacepatch.h | 2 +- indra/newview/llviewercontrol.cpp | 10 +++++++++ indra/newview/llvlcomposition.cpp | 8 +++---- indra/newview/llvlcomposition.h | 2 ++ indra/newview/llvosurfacepatch.cpp | 6 +++--- 9 files changed, 71 insertions(+), 22 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 73d4d9e3bc..5f94855963 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -70,6 +70,7 @@ vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); +in vec4 debug_pos; // TODO: Remove // *TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { @@ -148,9 +149,8 @@ vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFina void main() { - // Adjust the texture repeats for a more sensible default. - float texture_density_factor = 2.0; - vec2 terrain_texcoord = texture_density_factor * vary_texcoord0.xy; + vec2 terrain_texcoord = vary_texcoord0.xy; + terrain_texcoord -= vec2(21.0);// TODO: Remove float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; @@ -162,6 +162,25 @@ void main() discard; } + // TODO: Remove all of this + float debug_pos_x = debug_pos.x; + //float debug_pos_x = terrain_texcoord.y; + float debug_metric = debug_pos_x; + debug_metric = debug_metric - floor(debug_metric); + debug_metric *= debug_metric; + float debug_metric2 = debug_pos_x / 4.0; + debug_metric2 = debug_metric2 - floor(debug_metric2); + debug_metric2 *= debug_metric2; + debug_metric2 *= debug_metric2; + debug_metric2 *= 16.0; + float debug_metric3 = debug_pos_x / 16.0; + debug_metric3 = debug_metric3 - floor(debug_metric3); + debug_metric3 *= debug_metric3; + debug_metric3 *= debug_metric3; + debug_metric3 *= debug_metric3; + debug_metric3 *= 16.0; + //col.xyz = vec3(debug_metric3, debug_metric2, debug_metric);// TODO: Remove + vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec3[4] orm_factors; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 6037a58c0d..fd80d1bb2c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -43,24 +43,27 @@ out vec4 vary_texcoord1; uniform vec4 object_plane_s; uniform vec4 object_plane_t; -vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +vec4 texgen_object_pbr(vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { vec4 tcoord; - tcoord.x = dot(vpos, tp0); - tcoord.y = dot(vpos, tp1); - tcoord.z = tc.z; - tcoord.w = tc.w; + tcoord.x = dot(tc, tp0); + tcoord.y = dot(tc, tp1); + tcoord.z = tcoord.z; + tcoord.w = tcoord.w; tcoord = mat * tcoord; - return tcoord; + return tcoord; } +out vec4 debug_pos; // TODO: Remove + void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + debug_pos = vec4(texcoord0, 0.0, 1.0); vec3 n = normal_matrix * normal; vec3 t = normal_matrix * tangent.xyz; @@ -71,7 +74,12 @@ void main() // Transform and pass tex coords // *NOTE: KHR texture transform is ignored for now - vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + // Adjust the texture repeats for a more sensible default. + // *TODO: Remove this extra factor when KHR texture transform is added + float texture_density_factor = 3.0; + //texture_density_factor /= 256.0; // TODO: Remove + vary_texcoord0.xy *= texture_density_factor; vec4 tc = vec4(texcoord1,0,1); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 926d5e78d0..b4671963e1 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -253,7 +253,7 @@ void LLDrawPoolTerrain::renderFullShader() // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::MaterialType::TEXTURE); + const BOOL use_textures = !use_local_materials && (compp->getMaterialType() == LLTerrainMaterials::Type::TEXTURE); if (use_textures) { @@ -385,6 +385,8 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) materials = &gLocalTerrainMaterials.mDetailMaterials; } + // *TODO: I'm seeing terrain still jump when switching regions. Might have something to do with the extra repeat factor in the shader. Or is it a numerical precision issue?... + // *TODO: If we want to change the tiling, we should change this offset modulo to prevent seams LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 81fb4cf0cd..4f9911a11c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -201,7 +201,7 @@ LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, - LLVector2 *tex0, LLVector2 *tex1) + LLVector2 *tex0, LLVector2 *tex1, bool pbr) { if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp) { @@ -209,8 +209,15 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); - // TODO: I think this is off by 1. Should use 1 less (which iirc is captured in another field member. See LLSurface::create). Do some hack to fix repeats for PBR only, while keeping legacy texture the same? + // TODO: I think this operation is being applied too early because it also affects the geometry - we only want to affect the UVs + // TODO: Figure out what correct scaling is needed to prevent seams at region borders - getPatchesPerEdge seems to not be the solution, nor is getGridsPerEdge on its own U32 surface_stride = mSurfacep->getGridsPerEdge(); + U32 texture_stride = mSurfacep->getGridsPerEdge() - 1; + if (!pbr) + { + // TODO: Re-enable legacy repeats + //texture_stride = mSurfacep->getGridsPerEdge(); + } U32 point_offset = x + y*surface_stride; *normal = getNormal(x, y); @@ -222,7 +229,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); - LLVector3 tex_pos = rel_pos * (1.f/surface_stride); + // TODO: Revert for non-PBR only here, and/or add note that non-PBR doesn't actually use it. + LLVector3 tex_pos = rel_pos * (1.f/(texture_stride * mSurfacep->getMetersPerGrid())); tex0->mV[0] = tex_pos.mV[0]; tex0->mV[1] = tex_pos.mV[1]; tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y); diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 8c8f501dce..0e6c045145 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -106,7 +106,7 @@ public: const LLVector3 &getNormal(const U32 x, const U32 y) const; void eval(const U32 x, const U32 y, const U32 stride, - LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); + LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1, bool pbr); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 41b13cacbb..baf5480c6a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -124,6 +124,15 @@ static bool handleTerrainDetailChanged(const LLSD& newvalue) return true; } +static bool handleTerrainScaleChanged(const LLSD& newvalue) +{ + F64 scale = newvalue.asReal(); + if (scale != 0.0) + { + LLDrawPoolTerrain::sDetailScale = F32(1.0 / scale); + } + return true; +} static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) { @@ -702,6 +711,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8cd22e3bdb..130d74b286 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,7 +119,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::getMaterialType() +LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { return mMaterialType; } @@ -132,7 +132,6 @@ void LLTerrainMaterials::updateMaterialType() mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } - BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -408,7 +407,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; + const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { @@ -423,8 +422,9 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, else { tex = mDetailMaterials[i]->mBaseColorTexture; - if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } } + // TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) + if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 882c3d89b2..a62302292f 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -61,6 +61,7 @@ public: LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); + void updateMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); @@ -70,6 +71,7 @@ protected: LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; bool mMaterialTexturesSet[ASSET_COUNT]; + Type mMaterialType = Type::TEXTURE; }; // Local materials to override all regions diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 69b721c899..a672777914 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1046,10 +1046,10 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) const LLFace* region_facep = *mFaceList.begin(); const LLViewerObject* region_patchp = region_facep->getViewerObject(); - LLVLComposition* composition = region_patchp->mRegionp->getComposition(); + LLVLComposition* composition = region_patchp->getRegion()->getComposition(); // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. composition->updateMaterialType(); - const bool pbr = composition->getMaterialType() == LLTerrainMaterial::Type::PBR; + const bool pbr = composition->getMaterialType() == LLTerrainMaterials::Type::PBR; LLVertexBuffer* buffer = group->mVertexBuffer; @@ -1087,7 +1087,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices); + patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices, pbr); indices_index += facep->getIndicesCount(); index_offset += facep->getGeomCount(); -- cgit v1.2.3 From 35d889f7af9686b79fe0e5255121a444a044beab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:48 -0700 Subject: DRTVWR-592: Create separate config option for terrain repeats. Clean up debug --- indra/newview/app_settings/settings.xml | 13 ++++++++++++- .../shaders/class1/deferred/pbrterrainF.glsl | 21 --------------------- .../shaders/class1/deferred/pbrterrainV.glsl | 12 ++---------- indra/newview/lldrawpoolterrain.cpp | 13 +++++++------ indra/newview/lldrawpoolterrain.h | 3 ++- indra/newview/llsurfacepatch.cpp | 13 +++---------- indra/newview/llviewercontrol.cpp | 11 +++++++++++ 7 files changed, 37 insertions(+), 49 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94cc5a14a4..2dac0b5d70 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10703,7 +10703,7 @@ RenderTerrainScale Comment - Terrain detail texture scale + Terrain detail texture scale (meters) Persist 1 Type @@ -10722,6 +10722,17 @@ Value 0 + RenderTerrainPBRScale + + Comment + PBR terrain detail texture scale (meters) + Persist + 1 + Type + F32 + Value + 4.0 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 5f94855963..e6261ca85e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -70,7 +70,6 @@ vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); -in vec4 debug_pos; // TODO: Remove // *TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { @@ -150,7 +149,6 @@ vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFina void main() { vec2 terrain_texcoord = vary_texcoord0.xy; - terrain_texcoord -= vec2(21.0);// TODO: Remove float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; @@ -162,25 +160,6 @@ void main() discard; } - // TODO: Remove all of this - float debug_pos_x = debug_pos.x; - //float debug_pos_x = terrain_texcoord.y; - float debug_metric = debug_pos_x; - debug_metric = debug_metric - floor(debug_metric); - debug_metric *= debug_metric; - float debug_metric2 = debug_pos_x / 4.0; - debug_metric2 = debug_metric2 - floor(debug_metric2); - debug_metric2 *= debug_metric2; - debug_metric2 *= debug_metric2; - debug_metric2 *= 16.0; - float debug_metric3 = debug_pos_x / 16.0; - debug_metric3 = debug_metric3 - floor(debug_metric3); - debug_metric3 *= debug_metric3; - debug_metric3 *= debug_metric3; - debug_metric3 *= debug_metric3; - debug_metric3 *= 16.0; - //col.xyz = vec3(debug_metric3, debug_metric2, debug_metric);// TODO: Remove - vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec3[4] orm_factors; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index fd80d1bb2c..1653cc1a90 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -52,18 +52,15 @@ vec4 texgen_object_pbr(vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) tcoord.z = tcoord.z; tcoord.w = tcoord.w; - tcoord = mat * tcoord; + tcoord = mat * tcoord; return tcoord; } -out vec4 debug_pos; // TODO: Remove - void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - debug_pos = vec4(texcoord0, 0.0, 1.0); vec3 n = normal_matrix * normal; vec3 t = normal_matrix * tangent.xyz; @@ -71,15 +68,10 @@ void main() vary_tangent = normalize(t); vary_sign = tangent.w; vary_normal = normalize(n); - + // Transform and pass tex coords // *NOTE: KHR texture transform is ignored for now vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - // Adjust the texture repeats for a more sensible default. - // *TODO: Remove this extra factor when KHR texture transform is added - float texture_density_factor = 3.0; - //texture_density_factor /= 256.0; // TODO: Remove - vary_texcoord0.xy *= texture_density_factor; vec4 tc = vec4(texcoord1,0,1); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b4671963e1..85b4bb3dca 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -59,6 +59,7 @@ const S32 PBR_DETAIL_EMISSIVE = 0; S32 LLDrawPoolTerrain::sDetailMode = 1; S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; +F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow"); @@ -69,6 +70,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : { // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); + sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale"); // TODO: This is unused. Remove? sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); @@ -385,16 +387,15 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) materials = &gLocalTerrainMaterials.mDetailMaterials; } - // *TODO: I'm seeing terrain still jump when switching regions. Might have something to do with the extra repeat factor in the shader. Or is it a numerical precision issue?... - // *TODO: If we want to change the tiling, we should change this offset modulo to prevent seams + // *TODO: Figure out why this offset is *sometimes* producing seams at the region edge, and repeat jumps when crossing regions, when RenderTerrainPBRScale is not a factor of the region scale. LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; LLVector4 tp0, tp1; - tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); + tp0.setVec(sPBRDetailScale, 0.0f, 0.0f, offset_x); + tp1.setVec(0.0f, sPBRDetailScale, 0.0f, offset_y); constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; S32 detail_basecolor[terrain_material_count]; diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 060354458d..99d192da86 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -68,7 +68,8 @@ public: static S32 sDetailMode; static S32 sPBRDetailMode; - static F32 sDetailScale; // meters per texture + static F32 sDetailScale; // textures per meter + static F32 sPBRDetailScale; // textures per meter protected: void boostTerrainDetailTextures(); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 4f9911a11c..5bc220fcbd 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -209,15 +209,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } llassert_always(vertex && normal && tex0 && tex1); - // TODO: I think this operation is being applied too early because it also affects the geometry - we only want to affect the UVs - // TODO: Figure out what correct scaling is needed to prevent seams at region borders - getPatchesPerEdge seems to not be the solution, nor is getGridsPerEdge on its own U32 surface_stride = mSurfacep->getGridsPerEdge(); - U32 texture_stride = mSurfacep->getGridsPerEdge() - 1; - if (!pbr) - { - // TODO: Re-enable legacy repeats - //texture_stride = mSurfacep->getGridsPerEdge(); - } U32 point_offset = x + y*surface_stride; *normal = getNormal(x, y); @@ -229,8 +221,9 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent(); LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); - // TODO: Revert for non-PBR only here, and/or add note that non-PBR doesn't actually use it. - LLVector3 tex_pos = rel_pos * (1.f/(texture_stride * mSurfacep->getMetersPerGrid())); + // *NOTE: Only PBR terrain uses the UVs right now. Texture terrain just ignores it. + // *NOTE: In the future, UVs and horizontal position will no longer have a 1:1 relationship for PBR terrain + LLVector3 tex_pos = rel_pos; tex0->mV[0] = tex_pos.mV[0]; tex0->mV[1] = tex_pos.mV[1]; tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index baf5480c6a..8ee675820c 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -134,6 +134,16 @@ static bool handleTerrainScaleChanged(const LLSD& newvalue) return true; } +static bool handlePBRTerrainScaleChanged(const LLSD& newvalue) +{ + F64 scale = newvalue.asReal(); + if (scale != 0.0) + { + LLDrawPoolTerrain::sPBRDetailScale = F32(1.0 / scale); + } + return true; +} + static bool handleDebugAvatarJointsChanged(const LLSD& newvalue) { std::string new_string = newvalue.asString(); @@ -712,6 +722,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); -- cgit v1.2.3 From d6aced7abf0c54ec94033534124025c87fb9aeb2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:54 -0700 Subject: DRTVWR-592: Remove WIP separate code path for terrain geometry rebuilds for PBR as that is not needed at the moment --- indra/newview/lldrawpoolterrain.cpp | 4 --- indra/newview/lldrawpoolterrain.h | 1 - indra/newview/llsurfacepatch.cpp | 2 +- indra/newview/llsurfacepatch.h | 2 +- indra/newview/llviewercontrol.cpp | 7 ----- indra/newview/llvlcomposition.cpp | 11 ++------ indra/newview/llvlcomposition.h | 2 -- indra/newview/llvosurfacepatch.cpp | 56 ++++++++++++++----------------------- indra/newview/llvosurfacepatch.h | 12 +++----- 9 files changed, 30 insertions(+), 67 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 85b4bb3dca..fb27729b57 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -56,7 +56,6 @@ int DebugDetailMap = 0; const S32 PBR_DETAIL_EMISSIVE = 0; -S32 LLDrawPoolTerrain::sDetailMode = 1; S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE; @@ -71,8 +70,6 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : // Hack! sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale"); sPBRDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainPBRScale"); - // TODO: This is unused. Remove? - sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD); @@ -112,7 +109,6 @@ U32 LLDrawPoolTerrain::getVertexDataMask() void LLDrawPoolTerrain::prerender() { - sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); sPBRDetailMode = gSavedSettings.getS32("RenderTerrainPBRDetail"); } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 99d192da86..13f031c8e7 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -66,7 +66,6 @@ public: LLPointer m2DAlphaRampImagep; LLPointer mAlphaNoiseImagep; - static S32 sDetailMode; static S32 sPBRDetailMode; static F32 sDetailScale; // textures per meter static F32 sPBRDetailScale; // textures per meter diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5bc220fcbd..b4daf71ce2 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -201,7 +201,7 @@ LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, - LLVector2 *tex0, LLVector2 *tex1, bool pbr) + LLVector2 *tex0, LLVector2 *tex1) { if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp) { diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 0e6c045145..8c8f501dce 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -106,7 +106,7 @@ public: const LLVector3 &getNormal(const U32 x, const U32 y) const; void eval(const U32 x, const U32 y, const U32 stride, - LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1, bool pbr); + LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 8ee675820c..ea821004a3 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -118,12 +118,6 @@ static bool handleRenderFarClipChanged(const LLSD& newvalue) return false; } -static bool handleTerrainDetailChanged(const LLSD& newvalue) -{ - LLDrawPoolTerrain::sDetailMode = newvalue.asInteger(); - return true; -} - static bool handleTerrainScaleChanged(const LLSD& newvalue) { F64 scale = newvalue.asReal(); @@ -720,7 +714,6 @@ void settings_setup_listeners() { setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); - setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 130d74b286..fa19bcae87 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -120,16 +120,11 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) } LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() -{ - return mMaterialType; -} - -void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; const BOOL use_textures = texturesReady() || !materialsReady(); - mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; + return use_textures ? Type::TEXTURE : Type::PBR; } BOOL LLTerrainMaterials::texturesReady(BOOL boost) @@ -386,7 +381,7 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. +// *TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { @@ -423,7 +418,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { tex = mDetailMaterials[i]->mBaseColorTexture; } - // TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) + // *TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index a62302292f..882c3d89b2 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -61,7 +61,6 @@ public: LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); - void updateMaterialType(); BOOL texturesReady(BOOL boost = FALSE); BOOL materialsReady(BOOL boost = FALSE); @@ -71,7 +70,6 @@ protected: LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; bool mMaterialTexturesSet[ASSET_COUNT]; - Type mMaterialType = Type::TEXTURE; }; // Local materials to override all regions diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index a672777914..6318361d8d 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -246,8 +246,7 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr) + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); if (!facep) @@ -263,24 +262,21 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider &verticesp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateNorthGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); updateEastGeometry(facep, verticesp, normalsp, texCoords0p, texCoords1p, indicesp, - index_offset, - pbr); + index_offset); } void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, @@ -289,8 +285,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr) + U32 &index_offset) { S32 i, j, x, y; @@ -326,7 +321,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, { x = i * render_stride; y = j * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -394,8 +389,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr) + U32 &index_offset) { S32 vertex_count = 0; S32 i, x, y; @@ -427,7 +421,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -440,7 +434,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, { x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -477,7 +471,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -491,7 +485,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -535,7 +529,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16 - render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -549,7 +543,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * north_stride; y = 16; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -592,8 +586,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr) + U32 &index_offset) { S32 i, x, y; @@ -619,7 +612,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -631,7 +624,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, { x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -667,7 +660,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -679,7 +672,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -721,7 +714,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16 - render_stride; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -733,7 +726,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * east_stride; - mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get(), pbr); + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); verticesp++; normalsp++; texCoords0p++; @@ -1044,13 +1037,6 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; - const LLFace* region_facep = *mFaceList.begin(); - const LLViewerObject* region_patchp = region_facep->getViewerObject(); - LLVLComposition* composition = region_patchp->getRegion()->getComposition(); - // TODO: This is not good; it will result in wrong texture repeats in cases where the assets have not loaded. Need to rebuild terrain on asset load event if it changes the composition type. Probably best to have a flag to bookkeep that, to know if the composition type has actually changed. Make sure the draw pool is boosting the textures so they load in a timely fashion. - composition->updateMaterialType(); - const bool pbr = composition->getMaterialType() == LLTerrainMaterials::Type::PBR; - LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders @@ -1087,7 +1073,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); - patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices, pbr); + patchp->getTerrainGeometry(vertices, normals, texcoords, texcoords2, indices); indices_index += facep->getIndicesCount(); index_offset += facep->getGeomCount(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 06bb373578..a3dcb945d1 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -67,8 +67,7 @@ public: LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, - bool pbr); + LLStrider &indicesp); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -122,24 +121,21 @@ protected: LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, LLStrider &normalsp, LLStrider &texCoords0p, LLStrider &texCoords1p, LLStrider &indicesp, - U32 &index_offset, - bool pbr); + U32 &index_offset); }; #endif // LL_VOSURFACEPATCH_H -- cgit v1.2.3 From 7f7431891661668b898e03345c8023b4bbd0d9d9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:59 -0700 Subject: DRTVWR-592: Add tracy block to gen_terrain_tangents (not profiled) --- indra/newview/llvosurfacepatch.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 6318361d8d..feb1e26d57 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1001,6 +1001,8 @@ void gen_terrain_tangents(U16 strider_vertex_count, LLStrider &texCoords0p, LLStrider &indicesp) { + LL_PROFILE_ZONE_SCOPED + LLVector4a *vertices = new LLVector4a[strider_vertex_count]; LLVector4a *normals = new LLVector4a[strider_vertex_count]; LLVector4a *tangents = new LLVector4a[strider_vertex_count]; -- cgit v1.2.3 From ab3b4edac7809008cfed6d1b77e5a4debb22c88e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:03 -0700 Subject: DRTVWR-592: Fix broken minimap loading, improve minimap view of PBR materials (still not accurate, but better...) --- indra/llimage/llimage.cpp | 53 ++++++++++++++ indra/llimage/llimage.h | 6 ++ indra/newview/llfetchedgltfmaterial.cpp | 5 +- indra/newview/llfetchedgltfmaterial.h | 9 ++- indra/newview/llgltfmateriallist.cpp | 4 +- indra/newview/llsurfacepatch.cpp | 2 +- indra/newview/llvlcomposition.cpp | 125 ++++++++++++++++++++++++++++---- indra/newview/llvlcomposition.h | 2 +- 8 files changed, 179 insertions(+), 27 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index a96b6601bd..acfc254b65 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -31,6 +31,7 @@ #include "llmath.h" #include "v4coloru.h" +#include "v3color.h" #include "llimagebmp.h" #include "llimagetga.h" @@ -1026,6 +1027,34 @@ bool LLImageRaw::optimizeAwayAlpha() return false; } +bool LLImageRaw::makeAlpha() +{ + if (getComponents() == 3) + { + U8* data = getData(); + U32 pixels = getWidth() * getHeight(); + + // alpha channel doesn't exist, make a new copy of data with alpha channel + U8* new_data = (U8*) ll_aligned_malloc_16(getWidth() * getHeight() * 4); + + for (U32 i = 0; i < pixels; ++i) + { + U32 di = i * 4; + U32 si = i * 3; + for (U32 j = 0; j < 3; ++j) + { + new_data[di+j] = data[si+j]; + } + } + + setDataAndSize(new_data, getWidth(), getHeight(), 3); + + return true; + } + + return false; +} + void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image) { // Find new sizes @@ -1268,6 +1297,30 @@ void LLImageRaw::fill( const LLColor4U& color ) } } +void LLImageRaw::tint( const LLColor3& color ) +{ + llassert( (3 == getComponents()) || (4 == getComponents()) ); + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + + S32 pixels = getWidth() * getHeight(); + const S32 components = getComponents(); + U8* data = getData(); + for( S32 i = 0; i < pixels; i++ ) + { + const float c0 = data[0] * color.mV[0]; + const float c1 = data[1] * color.mV[1]; + const float c2 = data[2] * color.mV[2]; + data[0] = llclamp((U8)c0, 0, 255); + data[1] = llclamp((U8)c1, 0, 255); + data[2] = llclamp((U8)c2, 0, 255); + data += components; + } +} + LLPointer LLImageRaw::duplicate() { if(getNumRefs() < 2) diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8f9e1b3c54..77b5f0b7bc 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -71,6 +71,7 @@ const S32 HTTP_PACKET_SIZE = 1496; class LLImageFormatted; class LLImageRaw; class LLColor4U; +class LLColor3; typedef enum e_image_codec { @@ -212,6 +213,8 @@ public: // if the alpha channel is all 100% opaque, delete it // returns true if alpha channel was deleted bool optimizeAwayAlpha(); + // Create an alpha channel if this image doesn't have one + bool makeAlpha(); static S32 biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE); static S32 expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE); @@ -225,6 +228,9 @@ public: // Fill the buffer with a constant color void fill( const LLColor4U& color ); + // Multiply this raw image by the given color + void tint( const LLColor3& color ); + // Copy operations //duplicate this raw image if refCount > 1. diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 1fb3577dd7..c870d4778c 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -35,8 +35,6 @@ LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() : LLGLTFMaterial() , mExpectedFlusTime(0.f) - , mActive(true) - , mFetching(false) { } @@ -163,10 +161,11 @@ void LLFetchedGLTFMaterial::onMaterialComplete(std::function material_co materialCompleteCallbacks.push_back(material_complete); } -void LLFetchedGLTFMaterial::materialComplete() +void LLFetchedGLTFMaterial::materialComplete(bool success) { llassert(mFetching); mFetching = false; + mFetchSuccess = success; for (std::function material_complete : materialCompleteCallbacks) { diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index ce4d33a213..c5f6f6ca94 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -49,7 +49,7 @@ public: void bind(LLViewerTexture* media_tex = nullptr); bool isFetching() const { return mFetching; } - bool isLoaded() const { return !mFetching; } + bool isLoaded() const { return !mFetching && mFetchSuccess; } // Textures used for fetching/rendering LLPointer mBaseColorTexture; @@ -61,11 +61,12 @@ protected: // Lifetime management void materialBegin(); - void materialComplete(); + void materialComplete(bool success); F64 mExpectedFlusTime; // since epoch in seconds - bool mActive; - bool mFetching; + bool mActive = true; + bool mFetching = false; + bool mFetchSuccess = false; std::vector> materialCompleteCallbacks; }; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 99a052f719..7994515b61 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -549,7 +549,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp if (status != LL_ERR_NOERR) { LL_WARNS("GLTF") << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; - asset_data->mMaterial->materialComplete(); + asset_data->mMaterial->materialComplete(false); delete asset_data; } else @@ -634,7 +634,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp LL_DEBUGS("GLTF") << "Failed to get material " << id << LL_ENDL; } - asset_data->mMaterial->materialComplete(); + asset_data->mMaterial->materialComplete(true); delete asset_data; }); diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index b4daf71ce2..a6370e9ec2 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -741,7 +741,7 @@ void LLSurfacePatch::updateGL() updateCompositionStats(); F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], + if (comp->generateMinimapTileLand((F32)origin_region[VX], (F32)origin_region[VY], tex_patch_size, tex_patch_size)) { mSTexUpdate = FALSE; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index fa19bcae87..f645023217 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -129,26 +129,28 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() BOOL LLTerrainMaterials::texturesReady(BOOL boost) { + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { if (!textureReady(mDetailTextures[i], boost)) { - return FALSE; + ready = FALSE; } } - return TRUE; + return ready; } BOOL LLTerrainMaterials::materialsReady(BOOL boost) { + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) { - return FALSE; + ready = FALSE; } } - return TRUE; + return ready; } // Boost the texture loading priority @@ -188,6 +190,10 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO } return FALSE; } + if (tex->getComponents() == 0) + { + return FALSE; + } return TRUE; } @@ -381,8 +387,7 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -// *TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. -BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, +BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height) { LL_PROFILE_ZONE_SCOPED @@ -390,8 +395,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, llassert(x >= 0.f); llassert(y >= 0.f); - LLTimer gen_timer; - /////////////////////////// // // Generate raw data arrays for surface textures @@ -403,6 +406,17 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; + // *TODO: Remove this as it is reduandant computation (first and foremost + // because getMaterialType() does something similar, but also... shouldn't + // the textures/materials already be loaded by now?) + if (use_textures) + { + if (!texturesReady()) { return FALSE; } + } + else + { + if (!materialsReady()) { return FALSE; } + } for (S32 i = 0; i < ASSET_COUNT; i++) { @@ -410,16 +424,37 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { // Read back a raw image for this discard level, if it exists LLViewerFetchedTexture* tex; + LLViewerFetchedTexture* tex_emissive; // Can be null + bool has_base_color_factor; + bool has_emissive_factor; + LLColor3 base_color_factor; + LLColor3 emissive_factor; if (use_textures) { tex = mDetailTextures[i]; + tex_emissive = nullptr; + has_base_color_factor = false; + has_emissive_factor = false; + llassert(tex); } else { tex = mDetailMaterials[i]->mBaseColorTexture; + tex_emissive = mDetailMaterials[i]->mEmissiveTexture; + base_color_factor = LLColor3(mDetailMaterials[i]->mBaseColor); + // *HACK: Treat alpha as black + base_color_factor *= (mDetailMaterials[i]->mBaseColor.mV[VW]); + emissive_factor = mDetailMaterials[i]->mEmissiveColor; + has_base_color_factor = (base_color_factor.mV[VX] != 1.f || + base_color_factor.mV[VY] != 1.f || + base_color_factor.mV[VZ] != 1.f); + has_emissive_factor = (emissive_factor.mV[VX] != 1.f || + emissive_factor.mV[VY] != 1.f || + emissive_factor.mV[VZ] != 1.f); } - // *TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) - if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } + + if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } + // tex_emissive can be null, and then will be ignored S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; @@ -430,8 +465,9 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; - if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. + if(tex->getRawImageLevel() != ddiscard) { + // Raw image is not ready, will enter here again later. if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { tex->setBoostLevel(LLGLTexture::BOOST_MAP); @@ -442,21 +478,78 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { tex->destroyRawImage() ; } - LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } + if (tex_emissive) + { + if(tex_emissive->getRawImageLevel() != ddiscard) + { + // Raw image is not ready, will enter here again later. + if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) + { + tex_emissive->setBoostLevel(LLGLTexture::BOOST_MAP); + tex_emissive->forceToRefetchTexture(ddiscard); + } + + if(delete_raw) + { + tex_emissive->destroyRawImage() ; + } + return FALSE; + } + } mRawImages[i] = tex->getRawImage() ; if(delete_raw) { tex->destroyRawImage() ; } - if (tex->getWidth(ddiscard) != BASE_SIZE || + + // *TODO: This isn't quite right for PBR: + // 1) It does not convert the color images from SRGB to linear + // before mixing (which will always require copying the image). + // 2) It mixes emissive and base color before mixing terrain + // materials, but it should be the other way around + // 3) The composite function used to put emissive into base color + // is not an alpha blend. + // Long-term, we should consider a method that is more + // maintainable. Shaders, perhaps? Bake shaders to textures? + LLPointer raw_emissive; + if (tex_emissive) + { + raw_emissive = tex_emissive->getRawImage(); + if (has_emissive_factor || + tex_emissive->getWidth(ddiscard) != BASE_SIZE || + tex_emissive->getHeight(ddiscard) != BASE_SIZE || + tex_emissive->getComponents() != 4) + { + LLPointer newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); + // Copy RGB, leave alpha alone (set to opaque by default) + newraw_emissive->copy(mRawImages[i]); + if (has_emissive_factor) + { + newraw_emissive->tint(emissive_factor); + } + raw_emissive = newraw_emissive; // deletes old + } + } + if (has_base_color_factor || + raw_emissive || + tex->getWidth(ddiscard) != BASE_SIZE || tex->getHeight(ddiscard) != BASE_SIZE || tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); + if (has_base_color_factor) + { + newraw->tint(base_color_factor); + } + // Apply emissive texture + if (raw_emissive) + { + newraw->composite(raw_emissive); + } mRawImages[i] = newraw; // deletes old } } @@ -478,12 +571,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (x_end > mWidth) { - LL_WARNS("Terrain") << "x end > width" << LL_ENDL; + llassert(false); x_end = mWidth; } if (y_end > mWidth) { - LL_WARNS("Terrain") << "y end > width" << LL_ENDL; + llassert(false); y_end = mWidth; } @@ -513,7 +606,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (tex_comps != st_comps) { - LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL; + llassert(false); return FALSE; } diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 882c3d89b2..d59c0f95bb 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -87,7 +87,7 @@ public: BOOL generateHeights(const F32 x, const F32 y, const F32 width, const F32 height); BOOL generateComposition(); // Generate texture from composition values. - BOOL generateTexture(const F32 x, const F32 y, const F32 width, const F32 height); + BOOL generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. // So we need to compress heights into this range. -- cgit v1.2.3 From 754fe9d4b72c3a22fb18e32bd48daaa2ae7b02f7 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:09 -0700 Subject: DRTVWR-592: (WIP) Triplanar mapping --- indra/llrender/llglslshader.h | 1 + indra/llrender/llshadermgr.cpp | 8 ++ .../shaders/class1/deferred/pbrterrainF.glsl | 98 +++----------- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 148 +++++++++++++++++++++ .../shaders/class1/deferred/pbrterrainV.glsl | 9 +- indra/newview/llviewershadermgr.cpp | 2 + 6 files changed, 188 insertions(+), 78 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index b8071248e2..0de97da4db 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -57,6 +57,7 @@ public: bool hasAlphaMask = false; bool hasReflectionProbes = false; bool attachNothing = false; + bool isPBRTerrain = false; // include: shaders\class1\deferred\pbrterrainUtilF.glsl }; // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b2c8255d2a..91412add44 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -291,6 +291,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } + if (features->isPBRTerrain) + { + if (!shader->attachFragmentObject("deferred/pbrterrainUtilF.glsl")) + { + return FALSE; + } + } + // NOTE order of shader object attaching is VERY IMPORTANT!!! if (features->hasWaterFog) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index e6261ca85e..5bf20a3020 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -25,6 +25,15 @@ #define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config + +// TODO: Should be able to define this in another file and have it included in this one... +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +#define TerrainCoord vec4[2] +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +#define TerrainCoord vec2 +#endif + out vec4 frag_data[4]; uniform sampler2D alpha_ramp; @@ -60,6 +69,7 @@ uniform vec3[4] emissiveColors; #endif uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() +in vec4[2] vary_coords; in vec3 vary_normal; in vec3 vary_tangent; flat in float vary_sign; @@ -67,88 +77,22 @@ in vec4 vary_texcoord0; in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); -vec3 linear_to_srgb(vec3 c); -vec3 srgb_to_linear(vec3 c); - -// *TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal ); -} - -vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); -} - -vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); -} -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - vec3[4] samples; - samples[0] = texture(tex0, texcoord).xyz; - samples[1] = texture(tex1, texcoord).xyz; - samples[2] = texture(tex2, texcoord).xyz; - samples[3] = texture(tex3, texcoord).xyz; - samples[0] = srgb_to_linear(samples[0]); - samples[1] = srgb_to_linear(samples[1]); - samples[2] = srgb_to_linear(samples[2]); - samples[3] = srgb_to_linear(samples[3]); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} - -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - vec4[4] samples; - samples[0] = texture(tex0, texcoord); - samples[1] = texture(tex1, texcoord); - samples[2] = texture(tex2, texcoord); - samples[3] = texture(tex3, texcoord); - samples[0].xyz = srgb_to_linear(samples[0].xyz); - samples[1].xyz = srgb_to_linear(samples[1].xyz); - samples[2].xyz = srgb_to_linear(samples[2].xyz); - samples[3].xyz = srgb_to_linear(samples[3].xyz); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} +float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); +vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +void main() { - vec3[4] samples; - samples[0] = texture(tex0, texcoord).xyz; - samples[1] = texture(tex1, texcoord).xyz; - samples[2] = texture(tex2, texcoord).xyz; - samples[3] = texture(tex3, texcoord).xyz; - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} -vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - vec3[4] samples; - samples[0] = texture(tex0, texcoord).xyz; - samples[1] = texture(tex1, texcoord).xyz; - samples[2] = texture(tex2, texcoord).xyz; - samples[3] = texture(tex3, texcoord).xyz; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); -} +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 + TerrainCoord terrain_texcoord = vary_coords; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 + TerrainCoord terrain_texcoord = vary_texcoord0.xy; +#endif -void main() -{ - vec2 terrain_texcoord = vary_texcoord0.xy; float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl new file mode 100644 index 0000000000..4f337b5ce1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -0,0 +1,148 @@ +/** + * @file class1\deferred\pbrterrainUtilF.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$ + */ + +/** + * Triplanar mapping implementation adapted from Inigo Quilez' example shader, + * MIT license. + * https://www.shadertoy.com/view/MtsGWH + * Copyright © 2015 Inigo Quilez + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: The above copyright + * notice and this permission notice shall be included in all copies or + * substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", + * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +in vec3 vary_vertex_normal; + +vec3 srgb_to_linear(vec3 c); + +float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal ); +} + +vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); +} + +vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) +{ + return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); +} + +#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, zx, unused) +#define TerrainCoord vec4[2] +// Triplanar mapping +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ + vec4 x = texture(tex, terrain_coord[0].zw); + vec4 y = texture(tex, terrain_coord[1].xy); + vec4 z = texture(tex, terrain_coord[0].xy); + float sharpness = 8.0; + vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); +} +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +#define TerrainCoord vec2 +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ + return texture(tex, terrain_coord); +} +#endif + +vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = terrain_texture(tex0, texcoord).xyz; + samples[1] = terrain_texture(tex1, texcoord).xyz; + samples[2] = terrain_texture(tex2, texcoord).xyz; + samples[3] = terrain_texture(tex3, texcoord).xyz; + samples[0] = srgb_to_linear(samples[0]); + samples[1] = srgb_to_linear(samples[1]); + samples[2] = srgb_to_linear(samples[2]); + samples[3] = srgb_to_linear(samples[3]); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec4[4] samples; + samples[0] = terrain_texture(tex0, texcoord); + samples[1] = terrain_texture(tex1, texcoord); + samples[2] = terrain_texture(tex2, texcoord); + samples[3] = terrain_texture(tex3, texcoord); + samples[0].xyz = srgb_to_linear(samples[0].xyz); + samples[1].xyz = srgb_to_linear(samples[1].xyz); + samples[2].xyz = srgb_to_linear(samples[2].xyz); + samples[3].xyz = srgb_to_linear(samples[3].xyz); + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = terrain_texture(tex0, texcoord).xyz; + samples[1] = terrain_texture(tex1, texcoord).xyz; + samples[2] = terrain_texture(tex2, texcoord).xyz; + samples[3] = terrain_texture(tex3, texcoord).xyz; + samples[0] *= factors[0]; + samples[1] *= factors[1]; + samples[2] *= factors[2]; + samples[3] *= factors[3]; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} + +vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + vec3[4] samples; + samples[0] = terrain_texture(tex0, texcoord).xyz; + samples[1] = terrain_texture(tex1, texcoord).xyz; + samples[2] = terrain_texture(tex2, texcoord).xyz; + samples[3] = terrain_texture(tex3, texcoord).xyz; + return terrain_mix(samples, alpha1, alpha2, alphaFinal); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 1653cc1a90..991783d242 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -34,6 +34,8 @@ in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; +out vec4[2] vary_coords; +out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl out vec3 vary_normal; out vec3 vary_tangent; flat out float vary_sign; @@ -63,6 +65,8 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vec3 n = normal_matrix * normal; + // *TODO: Looks like terrain normals are per-vertex when they should be per-triangle instead, causing incorrect values on triangles touching steep edges of terrain + vary_vertex_normal = normal; vec3 t = normal_matrix * tangent.xyz; vary_tangent = normalize(t); @@ -73,7 +77,10 @@ void main() // *NOTE: KHR texture transform is ignored for now vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - vec4 tc = vec4(texcoord1,0,1); + vec4 tc = vec4(texcoord1,0,1); // TODO: This is redundant. Better to just use position and ignore texcoord? (We still need to decide how to handle alpha ramp, though...) + vary_coords[0].xy = texgen_object_pbr(vec4(position.xy, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_coords[0].zw = texgen_object_pbr(vec4(position.yz, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_coords[1].xy = texgen_object_pbr(vec4(position.zx, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; vary_texcoord0.zw = tc.xy; vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 2235b6d9a4..320801861c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -720,6 +720,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back(make_pair("deferred/pbrterrainUtilF.glsl", 1)); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); @@ -1506,6 +1507,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; gDeferredPBRTerrainProgram.mFeatures.hasTransport = true; + gDeferredPBRTerrainProgram.mFeatures.isPBRTerrain = true; gDeferredPBRTerrainProgram.mShaderFiles.clear(); gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainV.glsl", GL_VERTEX_SHADER)); -- cgit v1.2.3 From 2dc3f3ade165d7d15d8579a0f04b72f6aa56c7fe Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:16 -0700 Subject: DRTVWR-592: Add triplanar mapping setting, gate to High graphics setting or higher, bump feature table --- indra/newview/app_settings/settings.xml | 11 +++++++++++ .../app_settings/shaders/class1/deferred/pbrterrainF.glsl | 3 --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 2 -- indra/newview/featuretable.txt | 8 ++++++++ indra/newview/featuretable_mac.txt | 8 ++++++++ indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 15 ++++++++++++++- 7 files changed, 42 insertions(+), 6 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2dac0b5d70..28ee1b3a70 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10733,6 +10733,17 @@ Value 4.0 + RenderTerrainPBRPlanarSampleCount + + Comment + How many UV planes to sample PBR terrain textures from. 1 is "flat", 3 is triplanar mapping (aka box mapping) + Persist + 1 + Type + S32 + Value + 3 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 5bf20a3020..b9073a9361 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -25,9 +25,6 @@ #define TERRAIN_PBR_DETAIL_EMISSIVE 0 -#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config - -// TODO: Should be able to define this in another file and have it included in this one... #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 #define TerrainCoord vec4[2] #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 4f337b5ce1..b0b77398df 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -64,8 +64,6 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); } -#define TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT 3 // TODO: Move definition to config - #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, zx, unused) #define TerrainCoord vec4[2] diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index cb941b424b..4bc83b099f 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -49,6 +49,7 @@ RenderReflectionProbeDetail 1 2 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 @@ -95,6 +96,7 @@ RenderReflectionsEnabled 1 0 RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0 RenderVolumeLODFactor 1 1.125 RenderDeferredSSAO 1 0 @@ -124,6 +126,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 RenderDeferredSSAO 1 0 @@ -151,6 +154,7 @@ RenderLocalLights 1 1 RenderTransparentWater 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.25 RenderDeferredSSAO 1 0 @@ -180,6 +184,7 @@ RenderLocalLights 1 1 RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.375 RenderDeferredSSAO 1 0 @@ -209,6 +214,7 @@ RenderLocalLights 1 1 RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 RenderDeferredSSAO 1 1 @@ -237,6 +243,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.75 @@ -265,6 +272,7 @@ RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVolumeLODFactor 1 2.0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c04c1c9a4f..97dad655a2 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -45,6 +45,7 @@ RenderObjectBump 1 1 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 @@ -89,6 +90,7 @@ RenderLocalLights 1 0 RenderMaxPartCount 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 0 RenderTreeLODFactor 1 0 RenderVolumeLODFactor 1 1.125 @@ -118,6 +120,7 @@ RenderMaxPartCount 1 2048 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 @@ -147,6 +150,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.25 @@ -176,6 +180,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.375 @@ -205,6 +210,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 @@ -234,6 +240,7 @@ RenderMaxPartCount 1 4096 RenderLocalLights 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.75 @@ -262,6 +269,7 @@ RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVolumeLODFactor 1 2.0 diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index ea821004a3..19999545b6 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -717,6 +717,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderTerrainScale", handleTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRPlanarSampleCount", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 320801861c..c23ef1c314 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -69,6 +69,14 @@ bool LLViewerShaderMgr::sSkipReload = false; LLVector4 gShinyOrigin; +S32 clamp_terrain_mapping(S32 mapping) +{ + // 1 = "flat", 2 not implemented, 3 = triplanar mapping + mapping = llclamp(mapping, 1, 3); + if (mapping == 2) { mapping = 1; } + return mapping; +} + //utility shaders LLGLSLShader gOcclusionProgram; LLGLSLShader gSkinnedOcclusionProgram; @@ -682,6 +690,9 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["REF_SAMPLE_COUNT"] = "32"; } + const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); + attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); + LLGLSLShader::sGlobalDefines = attribs; // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. @@ -720,7 +731,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back(make_pair("deferred/pbrterrainUtilF.glsl", 1)); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); @@ -1497,6 +1508,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); + const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d", detail); gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; @@ -1514,6 +1526,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.mShaderFiles.push_back(make_pair("deferred/pbrterrainF.glsl", GL_FRAGMENT_SHADER)); gDeferredPBRTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PBR_DETAIL", llformat("%d", detail)); + gDeferredPBRTerrainProgram.addPermutation("TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT", llformat("%d", mapping)); success = gDeferredPBRTerrainProgram.createShader(NULL, NULL); llassert(success); } -- cgit v1.2.3 From ed973f4cbc58b5460513be709a0a23f0caa1120c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:22 -0700 Subject: DRTVWR-592: Add test config for triplanar mapping blend strength --- indra/newview/app_settings/settings.xml | 11 +++++++++++ .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 8 ++++++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 28ee1b3a70..85dfe688a7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10744,6 +10744,17 @@ Value 3 + RenderTerrainPBRTriplanarBlendFactor + + Comment + Higher values create sharper transitions, but are more likely to produce artifacts. + Persist + 1 + Type + F32 + Value + 8.0 + RenderTrackerBeacon Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index b0b77398df..ef2d030320 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -73,7 +73,7 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) vec4 x = texture(tex, terrain_coord[0].zw); vec4 y = texture(tex, terrain_coord[1].xy); vec4 z = texture(tex, terrain_coord[0].xy); - float sharpness = 8.0; + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 19999545b6..b6f01f2843 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -718,6 +718,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRScale", handlePBRTerrainScaleChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRPlanarSampleCount", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainPBRTriplanarBlendFactor", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index c23ef1c314..f1f92132ec 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -690,8 +690,12 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["REF_SAMPLE_COUNT"] = "32"; } - const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); - attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); + { // PBR terrain + const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); + attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); + const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor"); + attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor); + } LLGLSLShader::sGlobalDefines = attribs; -- cgit v1.2.3 From 23ca385f3dd0304a92e8da54236bc60f4f52e359 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:28 -0700 Subject: DRTVWR-592: Give PBR terrain shader more descriptive name for debugging/profiling --- indra/newview/llviewershadermgr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f1f92132ec..5849f97e0e 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1513,7 +1513,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); const S32 mapping = clamp_terrain_mapping(gSavedSettings.getS32("RenderTerrainPBRPlanarSampleCount")); - gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d", detail); + gDeferredPBRTerrainProgram.mName = llformat("Deferred PBR Terrain Shader %d %s", + detail, + (mapping == 1 ? "flat" : "triplanar")); gDeferredPBRTerrainProgram.mFeatures.encodesNormal = true; gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; -- cgit v1.2.3 From db4bc52829ec041ca0366069d07e942f0d32aacd Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:34 -0700 Subject: DRTVWR-592: (WIP) PBR Terrain: Improve orientation of textures and normal maps for triplanar mapping, minor cleanup --- .../shaders/class1/deferred/pbrterrainF.glsl | 10 ++-- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 68 ++++++++++++++++++---- .../shaders/class1/deferred/pbrterrainV.glsl | 52 +++++++++-------- .../shaders/class1/deferred/textureUtilV.glsl | 2 +- indra/newview/lldrawpoolterrain.cpp | 28 +++++---- 5 files changed, 109 insertions(+), 51 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index b9073a9361..7febbe280e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -35,7 +35,7 @@ out vec4 frag_data[4]; uniform sampler2D alpha_ramp; -// *TODO: Configurable quality level which disables PBR features on machines +// *TODO: More configurable quality level which disables PBR features on machines // with limited texture availability // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures uniform sampler2D detail_0_base_color; @@ -57,7 +57,6 @@ uniform sampler2D detail_2_emissive; uniform sampler2D detail_3_emissive; #endif -// *TODO: More efficient packing? uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl uniform vec4 metallicFactors; uniform vec4 roughnessFactors; @@ -66,7 +65,9 @@ uniform vec3[4] emissiveColors; #endif uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 in vec4[2] vary_coords; +#endif in vec3 vary_normal; in vec3 vary_tangent; flat in float vary_sign; @@ -79,7 +80,7 @@ float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); void main() { @@ -101,7 +102,6 @@ void main() discard; } - vec3 normal_texture = sample_and_mix_vector3_no_scale(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); vec3[4] orm_factors; orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); @@ -124,7 +124,7 @@ void main() float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); // from mikktspace.com - vec3 vNt = normal_texture.xyz*2.0-1.0; + vec3 vNt = sample_and_mix_normal(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index ef2d030320..a9155cc629 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -65,14 +65,56 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) } #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 -// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, zx, unused) -#define TerrainCoord vec4[2] // Triplanar mapping + +// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) +#define TerrainCoord vec4[2] + +vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) +{ + // If the vertex normal is negative, flip the texture back + // right-side up. + vec2 uv = uv_unflipped * vec2(sign, 1); + return texture(tex, uv); +} + +vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) +{ + // Unpack normal from pixel to vector + vec3 n = _t_texture(tex, uv_unflipped, sign).xyz*2.0-1.0; + // If the sign is negative, rotate normal by 180 degrees + n.xy = (min(0, sign) * n.xy) + (min(0, -sign) * -n.xy); + return n; +} + vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { - vec4 x = texture(tex, terrain_coord[0].zw); - vec4 y = texture(tex, terrain_coord[1].xy); - vec4 z = texture(tex, terrain_coord[0].xy); + // Multiplying the UVs by the sign of the normal flips the texture upright. + vec4 x = _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); + vec4 y = _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); + vec4 z = _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; + vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); +} + +// Specialized triplanar normal texture sampling implementation, taking into +// account how the rotation of the texture affects the lighting and trying to +// negate that. +// *TODO: Decide if we want this. It may be better to just calculate the +// tangents on-the-fly here rather than messing with the normals, due to the +// subtleties of the effects of triplanar mapping on UVs. These sampled normals +// are only valid on the faces of a cube, and the pregenerated tangents are +// only valid for uv = xy. +// *NOTE: Bottom face has not been tested +vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) +{ + vec3 x = _t_texture_n(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); + x.xy = vec2(-x.y, x.x); + vec3 y = _t_texture_n(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); + y.xy = -y.xy; + vec3 z = _t_texture_n(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); @@ -83,6 +125,11 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { return texture(tex, terrain_coord); } + +vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) +{ + return texture(tex, terrain_coord).xyz; +} #endif vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) @@ -135,12 +182,13 @@ vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, Terrai return terrain_mix(samples, alpha1, alpha2, alphaFinal); } -vec3 sample_and_mix_vector3_no_scale(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +// Returns the unpacked normal texture in range [-1, 1] +vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec3[4] samples; - samples[0] = terrain_texture(tex0, texcoord).xyz; - samples[1] = terrain_texture(tex1, texcoord).xyz; - samples[2] = terrain_texture(tex2, texcoord).xyz; - samples[3] = terrain_texture(tex3, texcoord).xyz; + samples[0] = terrain_texture_normal(tex0, texcoord).xyz; + samples[1] = terrain_texture_normal(tex1, texcoord).xyz; + samples[2] = terrain_texture_normal(tex2, texcoord).xyz; + samples[3] = terrain_texture_normal(tex3, texcoord).xyz; return terrain_mix(samples, alpha1, alpha2, alphaFinal); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 991783d242..2df5faf037 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -34,7 +34,9 @@ in vec4 diffuse_color; in vec2 texcoord0; in vec2 texcoord1; +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 out vec4[2] vary_coords; +#endif out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl out vec3 vary_normal; out vec3 vary_tangent; @@ -42,22 +44,13 @@ flat out float vary_sign; out vec4 vary_texcoord0; out vec4 vary_texcoord1; -uniform vec4 object_plane_s; -uniform vec4 object_plane_t; +// *HACK: tangent_space_transform should use texture_normal_transform, or maybe +// we shouldn't use tangent_space_transform at all. See the call to +// tangent_space_transform below. +uniform vec4[2] texture_base_color_transform; -vec4 texgen_object_pbr(vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) -{ - vec4 tcoord; - - tcoord.x = dot(tc, tp0); - tcoord.y = dot(tc, tp1); - tcoord.z = tcoord.z; - tcoord.w = tcoord.w; - - tcoord = mat * tcoord; - - return tcoord; -} +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); +vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() { @@ -65,23 +58,36 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vec3 n = normal_matrix * normal; - // *TODO: Looks like terrain normals are per-vertex when they should be per-triangle instead, causing incorrect values on triangles touching steep edges of terrain vary_vertex_normal = normal; vec3 t = normal_matrix * tangent.xyz; vary_tangent = normalize(t); + // *TODO: Decide if we want this. It may be better to just calculate the + // tangents on-the-fly in the fragment shader, due to the subtleties of the + // effect of triplanar mapping on UVs. + // *HACK: Should be using texture_normal_transform here. The KHR texture + // transform spec requires handling texture transforms separately for each + // individual texture. + vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_base_color_transform, texture_matrix0)); vary_sign = tangent.w; vary_normal = normalize(n); // Transform and pass tex coords - // *NOTE: KHR texture transform is ignored for now - vary_texcoord0.xy = texgen_object_pbr(vec4(texcoord0, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - - vec4 tc = vec4(texcoord1,0,1); // TODO: This is redundant. Better to just use position and ignore texcoord? (We still need to decide how to handle alpha ramp, though...) - vary_coords[0].xy = texgen_object_pbr(vec4(position.xy, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - vary_coords[0].zw = texgen_object_pbr(vec4(position.yz, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; - vary_coords[1].xy = texgen_object_pbr(vec4(position.zx, 0, 1), texture_matrix0, object_plane_s, object_plane_t).xy; + // *HACK: texture_base_color_transform is used for all of these here, but + // the KHR texture transform spec requires handling texture transforms + // separately for each individual texture. +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 + // xy + vary_coords[0].xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0); + // yz + vary_coords[0].zw = texture_transform(position.yz, texture_base_color_transform, texture_matrix0); + // (-x)z + vary_coords[1].xy = texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform, texture_matrix0); +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 + vary_texcoord0.xy = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); +#endif + vec4 tc = vec4(texcoord1,0,1); vary_texcoord0.zw = tc.xy; vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0); vary_texcoord1.zw = tc.xy-vec2(1.0, 0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl index 636dfed4ba..732333311c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl @@ -65,7 +65,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl // 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. + // for rotation and scale 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 diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index fb27729b57..6f48971ca0 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -383,16 +383,6 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) materials = &gLocalTerrainMaterials.mDetailMaterials; } - // *TODO: Figure out why this offset is *sometimes* producing seams at the region edge, and repeat jumps when crossing regions, when RenderTerrainPBRScale is not a factor of the region scale. - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; - F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; - - LLVector4 tp0, tp1; - - tp0.setVec(sPBRDetailScale, 0.0f, 0.0f, offset_x); - tp1.setVec(0.0f, sPBRDetailScale, 0.0f, offset_y); - constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; S32 detail_basecolor[terrain_material_count]; S32 detail_normal[terrain_material_count]; @@ -463,8 +453,22 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; llassert(shader); - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV); + + // *TODO: Figure out why this offset is *sometimes* producing seams at the + // region edge, and repeat jumps when crossing regions, when + // RenderTerrainPBRScale is not a factor of the region scale. + LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); + F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sPBRDetailScale)*sPBRDetailScale; + + LLGLTFMaterial::TextureTransform base_color_transform; + base_color_transform.mScale = LLVector2(sPBRDetailScale, sPBRDetailScale); + base_color_transform.mOffset = LLVector2(offset_x, offset_y); + F32 base_color_packed[8]; + base_color_transform.getPacked(base_color_packed); + // *HACK: Use the same texture repeats for all PBR terrain textures for now + // (not compliant with KHR texture transform spec) + shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed); LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -- cgit v1.2.3 From 3e3a3c1c5262e65df3edf27c4e27a6bbc8d49a01 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:40 -0700 Subject: DRTVWR-592: Fix terrain normal sampling in non-triplanar case --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a9155cc629..a89bc6f211 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -128,7 +128,7 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - return texture(tex, terrain_coord).xyz; + return texture(tex, terrain_coord).xyz*2.0-1.0; } #endif -- cgit v1.2.3 From 2895b7bf81c3d076a8ceaa4ce77037e870069365 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:45 -0700 Subject: DRTVWR-592: Triplanar performance pass --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 63 ++++++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a89bc6f211..1b13bc8836 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -109,14 +109,67 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) // *NOTE: Bottom face has not been tested vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - vec3 x = _t_texture_n(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; + vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + float threshold = 0.01; + vec3 significant = max(vec3(0), sign(weight - threshold)); + int sample_type = (int(significant.x) << 2) | + (int(significant.y) << 1) | + (int(significant.z) << 0); + + #define SAMPLE_X 1 << 2 + #define SAMPLE_Y 1 << 1 + #define SAMPLE_Z 1 << 0 + #define terrain_coord_x terrain_coord[0].zw + #define terrain_coord_y terrain_coord[1].xy + #define terrain_coord_z terrain_coord[0].xy + vec3 x; + vec3 y; + vec3 z; + switch (sample_type) + { + case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X | SAMPLE_Y: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec3(0); + break; + case SAMPLE_X | SAMPLE_Z: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec3(0); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_Y | SAMPLE_Z: + x = vec3(0); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X: + x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec3(0); + z = vec3(0); + break; + case SAMPLE_Y: + x = vec3(0); + y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec3(0); + break; + case SAMPLE_Z: + default: + x = vec3(0); + y = vec3(0); + z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + } + + // *HACK: Transform normals according to orientation of the UVs x.xy = vec2(-x.y, x.x); - vec3 y = _t_texture_n(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); y.xy = -y.xy; - vec3 z = _t_texture_n(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); - float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -- cgit v1.2.3 From a8d69a4baecfae81b4adb68992f02e3ebc47b876 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:50 -0700 Subject: DRTVWR-592: Fix weights --- .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 1b13bc8836..e69ee54a8c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -112,10 +112,10 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); float threshold = 0.01; - vec3 significant = max(vec3(0), sign(weight - threshold)); - int sample_type = (int(significant.x) << 2) | - (int(significant.y) << 1) | - (int(significant.z) << 0); + weight = max(vec3(0), sign(weight - threshold)); + int sample_type = (int(weight.x) << 2) | + (int(weight.y) << 1) | + (int(weight.z) << 0); #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 -- cgit v1.2.3 From bb0ae367d705e6d45f21526b26caa962824d6375 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:56 -0700 Subject: DRTVWR-592: (WIP) Test impact of higher threshold on performance and visuals --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index e69ee54a8c..4f2619f811 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -111,7 +111,7 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); - float threshold = 0.01; + float threshold = 0.1; weight = max(vec3(0), sign(weight - threshold)); int sample_type = (int(weight.x) << 2) | (int(weight.y) << 1) | -- cgit v1.2.3 From e6777d566fddc79d1194a2090e5df5b609285d89 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:02 -0700 Subject: DRTVWR-592: Fix not thresholding texture lookups for non-normal textures. Also decrease threshold to (hopefully) reasonable level --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 72 +++++++++++++++++++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 4f2619f811..b89edc9731 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,6 +69,7 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) { @@ -89,12 +90,63 @@ vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { - // Multiplying the UVs by the sign of the normal flips the texture upright. - vec4 x = _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); - vec4 y = _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); - vec4 z = _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); + vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; + weight = max(vec3(0), sign(weight - threshold)); + + #define SAMPLE_X 1 << 2 + #define SAMPLE_Y 1 << 1 + #define SAMPLE_Z 1 << 0 + int sample_type = (int(weight.x) * SAMPLE_X) | + (int(weight.y) * SAMPLE_Y) | + (int(weight.z) * SAMPLE_Z); + #define terrain_coord_x terrain_coord[0].zw + #define terrain_coord_y terrain_coord[1].xy + #define terrain_coord_z terrain_coord[0].xy + vec4 x; + vec4 y; + vec4 z; + switch (sample_type) + { + case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X | SAMPLE_Y: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec4(0); + break; + case SAMPLE_X | SAMPLE_Z: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec4(0); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_Y | SAMPLE_Z: + x = vec4(0); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + case SAMPLE_X: + x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); + y = vec4(0); + z = vec4(0); + break; + case SAMPLE_Y: + x = vec4(0); + y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); + z = vec4(0); + break; + case SAMPLE_Z: + default: + x = vec4(0); + y = vec4(0); + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + break; + } + return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); } @@ -110,16 +162,16 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = pow(abs(vary_vertex_normal), vec3(sharpness)); - float threshold = 0.1; + vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; weight = max(vec3(0), sign(weight - threshold)); - int sample_type = (int(weight.x) << 2) | - (int(weight.y) << 1) | - (int(weight.z) << 0); #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 #define SAMPLE_Z 1 << 0 + int sample_type = (int(weight.x) * SAMPLE_X) | + (int(weight.y) * SAMPLE_Y) | + (int(weight.z) * SAMPLE_Z); #define terrain_coord_x terrain_coord[0].zw #define terrain_coord_y terrain_coord[1].xy #define terrain_coord_z terrain_coord[0].xy -- cgit v1.2.3 From 53a5055ab72c3fb77892a3e43c769c3b19c1e97d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:07 -0700 Subject: DRTVWR-592: (WIP) (has debug) Convert colors to linear before triplanar blending. General refactor. --- .../shaders/class1/deferred/pbrterrainF.glsl | 11 + .../shaders/class1/deferred/pbrterrainUtilF.glsl | 249 ++++++++++++--------- 2 files changed, 160 insertions(+), 100 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7febbe280e..ba917416ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,6 +135,17 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if 0 // TODO: Remove debug + //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove + //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove + //col.xyz = spec; // TODO: Remove + //col.xyz = vec3(1); // TODO: Remove + //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove + tnorm = vary_normal; // TODO: Remove + spec.r = 1.0; // TODO: Remove + spec.gb = vec2(1.0, 0.0); // TODO: Remove + emissive.rgb = vec3(0); // TODO: Remove +#endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index b89edc9731..c72bc65cca 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,7 +69,15 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] +#if 0 // TODO: Revert #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 +#else +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 +#endif + +// Positive value prevents artifacts when weights are close to zero +// TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) +#define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0 vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) { @@ -79,35 +87,60 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) return texture(tex, uv); } -vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) +vec4 _t_texture_c(sampler2D tex, vec2 uv_unflipped, float sign) { - // Unpack normal from pixel to vector - vec3 n = _t_texture(tex, uv_unflipped, sign).xyz*2.0-1.0; - // If the sign is negative, rotate normal by 180 degrees - n.xy = (min(0, sign) * n.xy) + (min(0, -sign) * -n.xy); - return n; + vec4 c = _t_texture(tex, uv_unflipped, sign); + c.xyz = srgb_to_linear(c.xyz); + return c; } -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +#define SAMPLE_X 1 << 2 +#define SAMPLE_Y 1 << 1 +#define SAMPLE_Z 1 << 0 +#define terrain_coord_x terrain_coord[0].zw +#define terrain_coord_y terrain_coord[1].xy +#define terrain_coord_z terrain_coord[0].xy +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainWeight +{ + vec3 weight; +#if TERRAIN_DEBUG + vec3 usage; +#endif + int type; +}; + +TerrainWeight _t_weight(TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - weight = max(vec3(0), sign(weight - threshold)); - - #define SAMPLE_X 1 << 2 - #define SAMPLE_Y 1 << 1 - #define SAMPLE_Z 1 << 0 - int sample_type = (int(weight.x) * SAMPLE_X) | - (int(weight.y) * SAMPLE_Y) | - (int(weight.z) * SAMPLE_Z); - #define terrain_coord_x terrain_coord[0].zw - #define terrain_coord_y terrain_coord[1].xy - #define terrain_coord_z terrain_coord[0].xy + vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + weight_signed -= vec3(threshold); + TerrainWeight tw; + tw.weight = max(vec3(0), weight_signed); + vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); +#if TERRAIN_DEBUG + tw.usage = usage; +#endif + tw.type = (int(usage.x) * SAMPLE_X) | + (int(usage.y) * SAMPLE_Y) | + (int(usage.z) * SAMPLE_Z); + return tw; +} + +struct TerrainSample +{ vec4 x; vec4 y; vec4 z; - switch (sample_type) +}; + +TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ + vec4 x; + vec4 y; + vec4 z; + switch (tw.type) { case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); @@ -117,37 +150,98 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) case SAMPLE_X | SAMPLE_Y: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec4(0); + z = x; break; case SAMPLE_X | SAMPLE_Z: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec4(0); z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + y = x; break; case SAMPLE_Y | SAMPLE_Z: - x = vec4(0); y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + x = y; break; case SAMPLE_X: x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec4(0); - z = vec4(0); + y = x; + z = x; break; case SAMPLE_Y: - x = vec4(0); y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec4(0); + x = y; + z = y; break; case SAMPLE_Z: + z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + x = z; + y = z; + break; default: x = vec4(0); - y = vec4(0); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + y = x; + z = x; break; } - return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); + TerrainSample ts; + ts.x = x; + ts.y = y; + ts.z = z; + return ts; +} + +struct TerrainSampleNormal +{ + vec3 x; + vec3 y; + vec3 z; +}; + +TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ + TerrainSample ts = _t_sample(tex, terrain_coord, tw); + TerrainSampleNormal tsn; + tsn.x = ts.x.xyz; + tsn.y = ts.y.xyz; + tsn.z = ts.z.xyz; + vec3 ns = sign(vary_vertex_normal); + // If the sign is negative, rotate normal by 180 degrees + tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); + tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); + tsn.z.xy = (min(0, ns.z) * tsn.z.xy) + (min(0, -ns.z) * -tsn.z.xy); + // *HACK: Transform normals according to orientation of the UVs + tsn.x.xy = vec2(-tsn.x.y, tsn.x.x); + tsn.y.xy = -tsn.y.xy; + return tsn; +} + +TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ + TerrainSample ts = _t_sample(tex, terrain_coord, tw); + ts.x.xyz = srgb_to_linear(ts.x.xyz); + ts.y.xyz = srgb_to_linear(ts.y.xyz); + ts.z.xyz = srgb_to_linear(ts.z.xyz); + return ts; +} + +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ + TerrainWeight tw = _t_weight(terrain_coord); + + TerrainSample ts = _t_sample(tex, terrain_coord, tw); + +#if 1 + return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +#else // TODO: Remove debug + //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); +#if 1 + return vec4(tw.usage, 1.0); +#else + //return vec4(tw.usage, 1.0); + return vec4((tw.usage + weight) / 2.0, 1.0); +#endif +#endif } // Specialized triplanar normal texture sampling implementation, taking into @@ -156,74 +250,26 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) // *TODO: Decide if we want this. It may be better to just calculate the // tangents on-the-fly here rather than messing with the normals, due to the // subtleties of the effects of triplanar mapping on UVs. These sampled normals -// are only valid on the faces of a cube, and the pregenerated tangents are -// only valid for uv = xy. +// are only valid on the faces of a cube. // *NOTE: Bottom face has not been tested vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); - float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - weight = max(vec3(0), sign(weight - threshold)); - - #define SAMPLE_X 1 << 2 - #define SAMPLE_Y 1 << 1 - #define SAMPLE_Z 1 << 0 - int sample_type = (int(weight.x) * SAMPLE_X) | - (int(weight.y) * SAMPLE_Y) | - (int(weight.z) * SAMPLE_Z); - #define terrain_coord_x terrain_coord[0].zw - #define terrain_coord_y terrain_coord[1].xy - #define terrain_coord_z terrain_coord[0].xy - vec3 x; - vec3 y; - vec3 z; - switch (sample_type) - { - case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - case SAMPLE_X | SAMPLE_Y: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec3(0); - break; - case SAMPLE_X | SAMPLE_Z: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec3(0); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - case SAMPLE_Y | SAMPLE_Z: - x = vec3(0); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - case SAMPLE_X: - x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = vec3(0); - z = vec3(0); - break; - case SAMPLE_Y: - x = vec3(0); - y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = vec3(0); - break; - case SAMPLE_Z: - default: - x = vec3(0); - y = vec3(0); - z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - break; - } + TerrainWeight tw = _t_weight(terrain_coord); - // *HACK: Transform normals according to orientation of the UVs - x.xy = vec2(-x.y, x.x); - y.xy = -y.xy; + TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); - return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); + return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); } + +vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) +{ + TerrainWeight tw = _t_weight(terrain_coord); + + TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); + + return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +} + #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 #define TerrainCoord vec2 vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) @@ -235,6 +281,13 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { return texture(tex, terrain_coord).xyz*2.0-1.0; } + +vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) +{ + vec4 col = texture(tex, terrain_coord); + col.xyz = srgb_to_linear(col.xyz); + return col; +} #endif vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) @@ -258,14 +311,10 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, Terrain vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { vec4[4] samples; - samples[0] = terrain_texture(tex0, texcoord); - samples[1] = terrain_texture(tex1, texcoord); - samples[2] = terrain_texture(tex2, texcoord); - samples[3] = terrain_texture(tex3, texcoord); - samples[0].xyz = srgb_to_linear(samples[0].xyz); - samples[1].xyz = srgb_to_linear(samples[1].xyz); - samples[2].xyz = srgb_to_linear(samples[2].xyz); - samples[3].xyz = srgb_to_linear(samples[3].xyz); + samples[0] = terrain_texture_color(tex0, texcoord); + samples[1] = terrain_texture_color(tex1, texcoord); + samples[2] = terrain_texture_color(tex2, texcoord); + samples[3] = terrain_texture_color(tex3, texcoord); samples[0] *= factors[0]; samples[1] *= factors[1]; samples[2] *= factors[2]; -- cgit v1.2.3 From a9a08f72be2c30a40f7c6565bb82e7356245e8ec Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:13 -0700 Subject: DRTVWR-592: (WIP) Cleanup --- .../shaders/class1/deferred/pbrterrainF.glsl | 8 +-- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 77 ++++++++++------------ 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index ba917416ce..10a147a039 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -141,10 +141,10 @@ void main() //col.xyz = spec; // TODO: Remove //col.xyz = vec3(1); // TODO: Remove //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove - tnorm = vary_normal; // TODO: Remove - spec.r = 1.0; // TODO: Remove - spec.gb = vec2(1.0, 0.0); // TODO: Remove - emissive.rgb = vec3(0); // TODO: Remove + //tnorm = vary_normal; // TODO: Remove + //spec.r = 1.0; // TODO: Remove + //spec.gb = vec2(1.0, 0.0); // TODO: Remove + //emissive.rgb = vec3(0); // TODO: Remove #endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index c72bc65cca..1f8b0b97c7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -87,19 +87,9 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) return texture(tex, uv); } -vec4 _t_texture_c(sampler2D tex, vec2 uv_unflipped, float sign) -{ - vec4 c = _t_texture(tex, uv_unflipped, sign); - c.xyz = srgb_to_linear(c.xyz); - return c; -} - #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 #define SAMPLE_Z 1 << 0 -#define terrain_coord_x terrain_coord[0].zw -#define terrain_coord_y terrain_coord[1].xy -#define terrain_coord_z terrain_coord[0].xy #define TERRAIN_DEBUG 1 // TODO: Remove debug struct TerrainWeight { @@ -137,57 +127,55 @@ struct TerrainSample TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) { - vec4 x; - vec4 y; - vec4 z; + TerrainSample ts; + +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); switch (tw.type) { case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); + ts.x = do_sample_x(); + ts.y = do_sample_y(); + ts.z = do_sample_z(); break; case SAMPLE_X | SAMPLE_Y: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = x; + ts.x = do_sample_x(); + ts.y = do_sample_y(); + ts.z = ts.x; break; case SAMPLE_X | SAMPLE_Z: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - y = x; + ts.x = do_sample_x(); + ts.z = do_sample_z(); + ts.y = ts.x; break; case SAMPLE_Y | SAMPLE_Z: - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - x = y; + ts.y = do_sample_y(); + ts.z = do_sample_z(); + ts.x = ts.y; break; case SAMPLE_X: - x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); - y = x; - z = x; + ts.x = do_sample_x(); + ts.y = ts.x; + ts.z = ts.x; break; case SAMPLE_Y: - y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); - x = y; - z = y; + ts.y = do_sample_y(); + ts.x = ts.y; + ts.z = ts.y; break; case SAMPLE_Z: - z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); - x = z; - y = z; + ts.z = do_sample_z(); + ts.x = ts.z; + ts.y = ts.z; break; default: - x = vec4(0); - y = x; - z = x; + ts.x = vec4(0); + ts.y = ts.x; + ts.z = ts.x; break; } - TerrainSample ts; - ts.x = x; - ts.y = y; - ts.z = z; return ts; } @@ -202,9 +190,9 @@ TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, Terra { TerrainSample ts = _t_sample(tex, terrain_coord, tw); TerrainSampleNormal tsn; - tsn.x = ts.x.xyz; - tsn.y = ts.y.xyz; - tsn.z = ts.z.xyz; + tsn.x = ts.x.xyz*2.0-1.0; + tsn.y = ts.y.xyz*2.0-1.0; + tsn.z = ts.z.xyz*2.0-1.0; vec3 ns = sign(vary_vertex_normal); // If the sign is negative, rotate normal by 180 degrees tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); @@ -261,6 +249,7 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); } +// Triplanar sampling of colors. Colors are converted to linear space before blending. vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) { TerrainWeight tw = _t_weight(terrain_coord); -- cgit v1.2.3 From d745b6321306a44ae9bbd5afc6fff376ebaf12e9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:19 -0700 Subject: DRTVWR-592: (DEBUG) (broken) Strange sampling behavior survives weight bypass --- .../shaders/class1/deferred/pbrterrainF.glsl | 10 +++++----- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 10a147a039..19de8568b8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,16 +135,16 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; -#if 0 // TODO: Remove debug +#if 1 // TODO: Remove debug //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove //col.xyz = spec; // TODO: Remove //col.xyz = vec3(1); // TODO: Remove //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove - //tnorm = vary_normal; // TODO: Remove - //spec.r = 1.0; // TODO: Remove - //spec.gb = vec2(1.0, 0.0); // TODO: Remove - //emissive.rgb = vec3(0); // TODO: Remove + tnorm = vary_normal; // TODO: Remove + spec.r = 1.0; // TODO: Remove + spec.gb = vec2(1.0, 0.0); // TODO: Remove + emissive.rgb = vec3(0); // TODO: Remove #endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 1f8b0b97c7..327d23d2e7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -129,8 +129,13 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)); -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)); +#if 0 +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#else // TODO: Remove debug +#define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#endif #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); switch (tw.type) { @@ -219,15 +224,15 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample(tex, terrain_coord, tw); -#if 1 +#if 0 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); #else // TODO: Remove debug //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); -#if 1 +#if 0 return vec4(tw.usage, 1.0); #else //return vec4(tw.usage, 1.0); - return vec4((tw.usage + weight) / 2.0, 1.0); + return vec4((tw.usage + tw.weight) / 2.0, 1.0); #endif #endif } @@ -256,7 +261,11 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); +#if 0 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +#else // TODO: Remove debug + return ts.x; +#endif } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -- cgit v1.2.3 From aba9185f3a27221f71aa53001b45db0337a0b904 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:24 -0700 Subject: DRTVWR-592: (DEBUG) (broken) Strange sampling behavior isolated to switch..case blocks --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 179 ++++++++++++++++++--- 1 file changed, 155 insertions(+), 24 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 327d23d2e7..5067e94efe 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -79,12 +79,29 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) #define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0 -vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) +vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { + // Handle case where sign is 0 + // TODO: Why didn't this fix the seams? +#if 0 + float sign = (2.0*sign_or_zero) + 1.0; + sign /= sign; // If the vertex normal is negative, flip the texture back // right-side up. vec2 uv = uv_unflipped * vec2(sign, 1); return texture(tex, uv); +#else // TODO: Remove debug +#if 0 + // Name mangling test + float l_sign = (2.0*sign_or_zero) + 1.0; + l_sign /= l_sign; + vec2 l_uv = uv_unflipped * vec2(l_sign, 1); + return texture(tex, l_uv); +#else + // Simplified uv test + return texture(tex, uv_unflipped); +#endif +#endif } #define SAMPLE_X 1 << 2 @@ -94,10 +111,11 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign) struct TerrainWeight { vec3 weight; + int type; #if TERRAIN_DEBUG + vec3 weight_signed; vec3 usage; #endif - int type; }; TerrainWeight _t_weight(TerrainCoord terrain_coord) @@ -109,12 +127,13 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) TerrainWeight tw; tw.weight = max(vec3(0), weight_signed); vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); -#if TERRAIN_DEBUG - tw.usage = usage; -#endif tw.type = (int(usage.x) * SAMPLE_X) | (int(usage.y) * SAMPLE_Y) | (int(usage.z) * SAMPLE_Z); +#if TERRAIN_DEBUG + tw.weight_signed = weight_signed; + tw.usage = usage; +#endif return tw; } @@ -129,32 +148,44 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#if 0 +#if 1 +#if 1 +#if 1 #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) #else // TODO: Remove debug +// Still an error despite sampling the same texture three times from the same location #define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #endif -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#else // TODO: Remove? + vec2 coord_z = terrain_coord[0].xy; + vec2 coord_z_2 = terrain_coord[0].xy; + vec2 coord_z_3 = terrain_coord[0].xy; +#define do_sample_x() texture(tex, coord_z) +#define do_sample_y() texture(tex, coord_z_2) +#define do_sample_z() texture(tex, coord_z_3) +#endif +#if 0 switch (tw.type) { - case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: + case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): ts.x = do_sample_x(); ts.y = do_sample_y(); ts.z = do_sample_z(); break; - case SAMPLE_X | SAMPLE_Y: + case (SAMPLE_X | SAMPLE_Y): ts.x = do_sample_x(); ts.y = do_sample_y(); ts.z = ts.x; break; - case SAMPLE_X | SAMPLE_Z: + case (SAMPLE_X | SAMPLE_Z): ts.x = do_sample_x(); ts.z = do_sample_z(); ts.y = ts.x; break; - case SAMPLE_Y | SAMPLE_Z: + case (SAMPLE_Y | SAMPLE_Z): ts.y = do_sample_y(); ts.z = do_sample_z(); ts.x = ts.y; @@ -175,11 +206,114 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.y = ts.z; break; default: - ts.x = vec4(0); + ts.x = vec4(1.0, 0.0, 1.0, 1.0); + ts.y = ts.x; + ts.z = ts.x; + break; + } +#else // TODO: Remove debug +#if 0 + // This case works - no ant trails despite using a switch...case statement + switch (tw.type) + { + case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + break; + case (SAMPLE_X | SAMPLE_Y): + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.z = ts.x; + break; + case (SAMPLE_X | SAMPLE_Z): + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + ts.y = ts.x; + break; + case (SAMPLE_Y | SAMPLE_Z): + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + ts.x = ts.y; + break; + case SAMPLE_X: + ts.x = vec4(1.0, 0.0, 0.0, 1.0); + ts.y = ts.x; + ts.z = ts.x; + break; + case SAMPLE_Y: + ts.y = vec4(0.0, 1.0, 0.0, 1.0); + ts.x = ts.y; + ts.z = ts.y; + break; + case SAMPLE_Z: + ts.z = vec4(0.0, 0.0, 1.0, 1.0); + ts.x = ts.z; + ts.y = ts.z; + break; + default: + ts.x = vec4(1.0, 0.0, 1.0, 1.0); + ts.y = ts.x; + ts.z = ts.x; + break; + } +#else +// This shows the bug: case of sampling beforehand, assigning in switch..case + vec4 x = do_sample_x(); + vec4 y = do_sample_y(); + vec4 z = do_sample_z(); + switch (tw.type) + { + case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): + ts.x = x; + ts.y = y; + ts.z = z; + break; + case (SAMPLE_X | SAMPLE_Y): + ts.x = x; + ts.y = y; + ts.z = ts.x; + break; + case (SAMPLE_X | SAMPLE_Z): + ts.x = x; + ts.z = z; + ts.y = ts.x; + break; + case (SAMPLE_Y | SAMPLE_Z): + ts.y = y; + ts.z = z; + ts.x = ts.y; + break; + case SAMPLE_X: + ts.x = x; + ts.y = ts.x; + ts.z = ts.x; + break; + case SAMPLE_Y: + ts.y = y; + ts.x = ts.y; + ts.z = ts.y; + break; + case SAMPLE_Z: + ts.z = z; + ts.x = ts.z; + ts.y = ts.z; + break; + default: + ts.x = vec4(1.0, 0.0, 1.0, 1.0); ts.y = ts.x; ts.z = ts.x; break; } +#endif +#endif +#else // TODO: Remove debug +// No error +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); +ts.z = do_sample_z(); +ts.x = ts.z; +ts.y = ts.z; +#endif return ts; } @@ -218,23 +352,14 @@ TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeig return ts; } +// Triplanar sampling of things that are neither colors nor normals (i.e. orm) vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { TerrainWeight tw = _t_weight(terrain_coord); TerrainSample ts = _t_sample(tex, terrain_coord, tw); -#if 0 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -#else // TODO: Remove debug - //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); -#if 0 - return vec4(tw.usage, 1.0); -#else - //return vec4(tw.usage, 1.0); - return vec4((tw.usage + tw.weight) / 2.0, 1.0); -#endif -#endif } // Specialized triplanar normal texture sampling implementation, taking into @@ -261,10 +386,16 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); -#if 0 +#if 1 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); #else // TODO: Remove debug - return ts.x; + //return vec4(vec3(isnan(ts.x)), 1.0); + //return ts.x; +#if 0 + return vec4(1.0+sign(vary_vertex_normal)/2.0, 1.0); +#else + return vec4(isnan(tw.weight_signed), 1.0); +#endif #endif } -- cgit v1.2.3 From fb12fb4bf7bbbf457b4f81356b0d0fadf2b42664 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:40:29 -0700 Subject: DRTVWR-592: (DEBUG) (broken) Clean up a few debug cases not used for reproducing the bug --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 100 +++------------------ 1 file changed, 12 insertions(+), 88 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 5067e94efe..a40f70a9e2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,39 +69,22 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -#if 0 // TODO: Revert +// TODO: Decide if we want this threshold +#if 0 #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 -#else +#else // TODO: Remove debug #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 #endif -// Positive value prevents artifacts when weights are close to zero -// TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) -#define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0 - vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 - // TODO: Why didn't this fix the seams? -#if 0 float sign = (2.0*sign_or_zero) + 1.0; sign /= sign; // If the vertex normal is negative, flip the texture back // right-side up. vec2 uv = uv_unflipped * vec2(sign, 1); return texture(tex, uv); -#else // TODO: Remove debug -#if 0 - // Name mangling test - float l_sign = (2.0*sign_or_zero) + 1.0; - l_sign /= l_sign; - vec2 l_uv = uv_unflipped * vec2(l_sign, 1); - return texture(tex, l_uv); -#else - // Simplified uv test - return texture(tex, uv_unflipped); -#endif -#endif } #define SAMPLE_X 1 << 2 @@ -126,7 +109,7 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) weight_signed -= vec3(threshold); TerrainWeight tw; tw.weight = max(vec3(0), weight_signed); - vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); + vec3 usage = max(vec3(0), sign(weight_signed)); tw.type = (int(usage.x) * SAMPLE_X) | (int(usage.y) * SAMPLE_Y) | (int(usage.z) * SAMPLE_Z); @@ -149,25 +132,16 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight TerrainSample ts; #if 1 -#if 1 -#if 1 +// This demonstrates the case when the bug occurs: Sampling in switch..case +#if 0 #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) #else // TODO: Remove debug -// Still an error despite sampling the same texture three times from the same location +// Bug still occurs despite sampling the same texture three times from the same location #define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #endif #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#else // TODO: Remove? - vec2 coord_z = terrain_coord[0].xy; - vec2 coord_z_2 = terrain_coord[0].xy; - vec2 coord_z_3 = terrain_coord[0].xy; -#define do_sample_x() texture(tex, coord_z) -#define do_sample_y() texture(tex, coord_z_2) -#define do_sample_z() texture(tex, coord_z_3) -#endif -#if 0 switch (tw.type) { case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): @@ -212,53 +186,11 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight break; } #else // TODO: Remove debug -#if 0 - // This case works - no ant trails despite using a switch...case statement - switch (tw.type) - { - case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - break; - case (SAMPLE_X | SAMPLE_Y): - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.z = ts.x; - break; - case (SAMPLE_X | SAMPLE_Z): - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - break; - case (SAMPLE_Y | SAMPLE_Z): - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - ts.x = ts.y; - break; - case SAMPLE_X: - ts.x = vec4(1.0, 0.0, 0.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; - case SAMPLE_Y: - ts.y = vec4(0.0, 1.0, 0.0, 1.0); - ts.x = ts.y; - ts.z = ts.y; - break; - case SAMPLE_Z: - ts.z = vec4(0.0, 0.0, 1.0, 1.0); - ts.x = ts.z; - ts.y = ts.z; - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; - } -#else -// This shows the bug: case of sampling beforehand, assigning in switch..case +// This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case +// This otherwise uses the same logic as in the case that reproduces the bug. +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) vec4 x = do_sample_x(); vec4 y = do_sample_y(); vec4 z = do_sample_z(); @@ -305,14 +237,6 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.z = ts.x; break; } -#endif -#endif -#else // TODO: Remove debug -// No error -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)); -ts.z = do_sample_z(); -ts.x = ts.z; -ts.y = ts.z; #endif return ts; -- cgit v1.2.3 From be39e92f7d3c6df80eeb1f183723978ce1bf1b52 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:41:19 -0700 Subject: DRTVWR-592: (WIP) (has debug) Fix "ant trail" seams in terrain caused by multiple texture lookups in a switch..case block --- .../shaders/class1/deferred/pbrterrainF.glsl | 2 +- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 44 +++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 19de8568b8..ba917416ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,7 +135,7 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; -#if 1 // TODO: Remove debug +#if 0 // TODO: Remove debug //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove //col.xyz = spec; // TODO: Remove diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a40f70a9e2..fc04afe513 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -131,7 +131,7 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#if 1 +#if 0 // This demonstrates the case when the bug occurs: Sampling in switch..case #if 0 #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) @@ -142,7 +142,12 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight #define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) #endif #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#if 0 switch (tw.type) +#else // TODO: Remove debug +// Bug still occurs when the type is masked + switch (tw.type & (SAMPLE_X | SAMPLE_Y | SAMPLE_Z)) +#endif { case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): ts.x = do_sample_x(); @@ -186,6 +191,7 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight break; } #else // TODO: Remove debug +#if 0 // This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case // This otherwise uses the same logic as in the case that reproduces the bug. #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) @@ -237,6 +243,42 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.z = ts.x; break; } +#else // TODO: Keep? +// Test case where the switch..case is broken up into three parts +// This fixes unexplained, "ant trail" seams in terrain. (as seen on Nvidia/Windows 10) +// The extra two branches are not free, but it's still a performance win +// compared to sampling along all three axes for every terrain fragment. +#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) +switch (tw.type & SAMPLE_X) +{ + case SAMPLE_X: + ts.x = do_sample_x(); + break; + default: + ts.x = vec4(1.0, 0.0, 1.0, 1.0); + break; +} +switch (tw.type & SAMPLE_Y) +{ + case SAMPLE_Y: + ts.y = do_sample_y(); + break; + default: + ts.y = vec4(1.0, 0.0, 1.0, 1.0); + break; +} +switch (tw.type & SAMPLE_Z) +{ + case SAMPLE_Z: + ts.z = do_sample_z(); + break; + default: + ts.z = vec4(1.0, 0.0, 1.0, 1.0); + break; +} +#endif #endif return ts; -- cgit v1.2.3 From 823fcddcb508fac6d1f819633f6a91230f06b114 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:02 -0700 Subject: DRTVWR-592: (WIP) (has debug) Fix removing axial sign flip of normal texture during zero check, add another zero check --- .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index fc04afe513..c5de74604f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -80,7 +80,7 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 float sign = (2.0*sign_or_zero) + 1.0; - sign /= sign; + sign /= abs(sign); // If the vertex normal is negative, flip the texture back // right-side up. vec2 uv = uv_unflipped * vec2(sign, 1); @@ -190,8 +190,8 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight ts.z = ts.x; break; } -#else // TODO: Remove debug -#if 0 +#else +#if 0 // TODO: Remove debug // This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case // This otherwise uses the same logic as in the case that reproduces the bug. #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) @@ -295,10 +295,15 @@ TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, Terra { TerrainSample ts = _t_sample(tex, terrain_coord, tw); TerrainSampleNormal tsn; + // Unpack normals tsn.x = ts.x.xyz*2.0-1.0; tsn.y = ts.y.xyz*2.0-1.0; tsn.z = ts.z.xyz*2.0-1.0; + // Get sign vec3 ns = sign(vary_vertex_normal); + // Handle case where sign is 0 + ns = (2.0*ns) + 1.0; + ns /= abs(ns); // If the sign is negative, rotate normal by 180 degrees tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); -- cgit v1.2.3 From c48837ef9b7cd016577b2f54f3f6b52764c32e17 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:07 -0700 Subject: DRTVWR-592: (WIP) (has debug) More rigorous definition of usage vector for triplanar that avoids possible case where 1 = 0.9999, which gets rounded down to 0 on int cast --- .../app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index c5de74604f..1ea1ced45b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -97,7 +97,7 @@ struct TerrainWeight int type; #if TERRAIN_DEBUG vec3 weight_signed; - vec3 usage; + ivec3 usage; #endif }; @@ -109,10 +109,10 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) weight_signed -= vec3(threshold); TerrainWeight tw; tw.weight = max(vec3(0), weight_signed); - vec3 usage = max(vec3(0), sign(weight_signed)); - tw.type = (int(usage.x) * SAMPLE_X) | - (int(usage.y) * SAMPLE_Y) | - (int(usage.z) * SAMPLE_Z); + ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); + tw.type = ((usage.x) * SAMPLE_X) | + ((usage.y) * SAMPLE_Y) | + ((usage.z) * SAMPLE_Z); #if TERRAIN_DEBUG tw.weight_signed = weight_signed; tw.usage = usage; -- cgit v1.2.3 From fa11e94c3cf4fad439dc10db630c747c8da42dd8 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:12 -0700 Subject: DRTVWR-592: Clean up debug and test cases for ant trails artifact. Fix whitespace --- .../shaders/class1/deferred/pbrterrainF.glsl | 11 -- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 182 +++------------------ 2 files changed, 24 insertions(+), 169 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index ba917416ce..7febbe280e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,17 +135,6 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; -#if 0 // TODO: Remove debug - //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove - //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove - //col.xyz = spec; // TODO: Remove - //col.xyz = vec3(1); // TODO: Remove - //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove - tnorm = vary_normal; // TODO: Remove - spec.r = 1.0; // TODO: Remove - spec.gb = vec2(1.0, 0.0); // TODO: Remove - emissive.rgb = vec3(0); // TODO: Remove -#endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 1ea1ced45b..e2d6cdb2d6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,12 +69,7 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -// TODO: Decide if we want this threshold -#if 0 #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 -#else // TODO: Remove debug -#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 -#endif vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { @@ -90,15 +85,10 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) #define SAMPLE_X 1 << 2 #define SAMPLE_Y 1 << 1 #define SAMPLE_Z 1 << 0 -#define TERRAIN_DEBUG 1 // TODO: Remove debug struct TerrainWeight { vec3 weight; int type; -#if TERRAIN_DEBUG - vec3 weight_signed; - ivec3 usage; -#endif }; TerrainWeight _t_weight(TerrainCoord terrain_coord) @@ -131,155 +121,41 @@ TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight { TerrainSample ts; -#if 0 -// This demonstrates the case when the bug occurs: Sampling in switch..case -#if 0 -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) -#else // TODO: Remove debug -// Bug still occurs despite sampling the same texture three times from the same location -#define do_sample_x() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#define do_sample_y() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#endif -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -#if 0 - switch (tw.type) -#else // TODO: Remove debug -// Bug still occurs when the type is masked - switch (tw.type & (SAMPLE_X | SAMPLE_Y | SAMPLE_Z)) -#endif + // The switch..case is broken up into three parts deliberately. A single + // switch..case caused unexplained, "ant trail" seams in terrain. (as seen + // on Nvidia/Windows 10). The extra two branches are not free, but it's + // still a performance win compared to sampling along all three axes for + // every terrain fragment. + #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) + #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) + #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) + switch (tw.type & SAMPLE_X) { - case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): - ts.x = do_sample_x(); - ts.y = do_sample_y(); - ts.z = do_sample_z(); - break; - case (SAMPLE_X | SAMPLE_Y): - ts.x = do_sample_x(); - ts.y = do_sample_y(); - ts.z = ts.x; - break; - case (SAMPLE_X | SAMPLE_Z): - ts.x = do_sample_x(); - ts.z = do_sample_z(); - ts.y = ts.x; - break; - case (SAMPLE_Y | SAMPLE_Z): - ts.y = do_sample_y(); - ts.z = do_sample_z(); - ts.x = ts.y; - break; case SAMPLE_X: ts.x = do_sample_x(); - ts.y = ts.x; - ts.z = ts.x; - break; - case SAMPLE_Y: - ts.y = do_sample_y(); - ts.x = ts.y; - ts.z = ts.y; - break; - case SAMPLE_Z: - ts.z = do_sample_z(); - ts.x = ts.z; - ts.y = ts.z; - break; + break; default: ts.x = vec4(1.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; + break; } -#else -#if 0 // TODO: Remove debug -// This demonstrates the case when the bug does not occur: Sampling beforehand and assigning in switch..case -// This otherwise uses the same logic as in the case that reproduces the bug. -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) - vec4 x = do_sample_x(); - vec4 y = do_sample_y(); - vec4 z = do_sample_z(); - switch (tw.type) + switch (tw.type & SAMPLE_Y) { - case (SAMPLE_X | SAMPLE_Y | SAMPLE_Z): - ts.x = x; - ts.y = y; - ts.z = z; - break; - case (SAMPLE_X | SAMPLE_Y): - ts.x = x; - ts.y = y; - ts.z = ts.x; - break; - case (SAMPLE_X | SAMPLE_Z): - ts.x = x; - ts.z = z; - ts.y = ts.x; - break; - case (SAMPLE_Y | SAMPLE_Z): - ts.y = y; - ts.z = z; - ts.x = ts.y; - break; - case SAMPLE_X: - ts.x = x; - ts.y = ts.x; - ts.z = ts.x; - break; case SAMPLE_Y: - ts.y = y; - ts.x = ts.y; - ts.z = ts.y; - break; + ts.y = do_sample_y(); + break; + default: + ts.y = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tw.type & SAMPLE_Z) + { case SAMPLE_Z: - ts.z = z; - ts.x = ts.z; - ts.y = ts.z; - break; + ts.z = do_sample_z(); + break; default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - ts.y = ts.x; - ts.z = ts.x; - break; + ts.z = vec4(1.0, 0.0, 1.0, 1.0); + break; } -#else // TODO: Keep? -// Test case where the switch..case is broken up into three parts -// This fixes unexplained, "ant trail" seams in terrain. (as seen on Nvidia/Windows 10) -// The extra two branches are not free, but it's still a performance win -// compared to sampling along all three axes for every terrain fragment. -#define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) -#define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) -#define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) -switch (tw.type & SAMPLE_X) -{ - case SAMPLE_X: - ts.x = do_sample_x(); - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - break; -} -switch (tw.type & SAMPLE_Y) -{ - case SAMPLE_Y: - ts.y = do_sample_y(); - break; - default: - ts.y = vec4(1.0, 0.0, 1.0, 1.0); - break; -} -switch (tw.type & SAMPLE_Z) -{ - case SAMPLE_Z: - ts.z = do_sample_z(); - break; - default: - ts.z = vec4(1.0, 0.0, 1.0, 1.0); - break; -} -#endif -#endif return ts; } @@ -357,17 +233,7 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); -#if 1 return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -#else // TODO: Remove debug - //return vec4(vec3(isnan(ts.x)), 1.0); - //return ts.x; -#if 0 - return vec4(1.0+sign(vary_vertex_normal)/2.0, 1.0); -#else - return vec4(isnan(tw.weight_signed), 1.0); -#endif -#endif } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -- cgit v1.2.3 From b1a3a274ffe539ea61d9fd7aa6f95f44049964e2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:18 -0700 Subject: DRTVWR-592: Don't read UVs for PBR terrain in single-plane case - works out to be more expensive than triplanar in some cases, and UVs are already trivial --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 2df5faf037..64ab3bbb13 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -84,7 +84,7 @@ void main() // (-x)z vary_coords[1].xy = texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform, texture_matrix0); #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 - vary_texcoord0.xy = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + vary_texcoord0.xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0); #endif vec4 tc = vec4(texcoord1,0,1); -- cgit v1.2.3 From 6e949e5d63c56a899b6a7745fcca04e0cd2f9639 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:24 -0700 Subject: DRTVWR-592: Remove shader cruft --- .../app_settings/shaders/class1/deferred/pbrterrainV.glsl | 1 - indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index 64ab3bbb13..dbb9404219 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -31,7 +31,6 @@ in vec3 position; in vec3 normal; in vec4 tangent; in vec4 diffuse_color; -in vec2 texcoord0; in vec2 texcoord1; #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index f6d3b59e85..33a78fd26d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -30,7 +30,6 @@ uniform mat4 modelview_projection_matrix; in vec3 position; in vec3 normal; in vec4 diffuse_color; -in vec2 texcoord0; in vec2 texcoord1; out vec3 pos; @@ -41,18 +40,16 @@ out vec4 vary_texcoord1; uniform vec4 object_plane_s; uniform vec4 object_plane_t; -vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +vec2 texgen_object(vec4 vpos, mat4 mat, vec4 tp0, vec4 tp1) { vec4 tcoord; tcoord.x = dot(vpos, tp0); tcoord.y = dot(vpos, tp1); - tcoord.z = tc.z; - tcoord.w = tc.w; tcoord = mat * tcoord; - return tcoord; + return tcoord.xy; } void main() @@ -67,7 +64,7 @@ void main() vary_normal = normalize(normal_matrix * normal); // Transform and pass tex coords - vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; + vary_texcoord0.xy = texgen_object(vec4(position, 1.0), texture_matrix0, object_plane_s, object_plane_t); vec4 t = vec4(texcoord1,0,1); -- cgit v1.2.3 From 1d885181d850388feb89c92a018cb591b5cc7f18 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:29 -0700 Subject: DRTVWR-592: (WIP) (has debug) Apply triplanar optimization technique to PBR material sampling. Use slightly different alpha ramp to hide unused materials --- .../shaders/class1/deferred/pbrterrainF.glsl | 61 ++++- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 288 +++++++++++++++++---- 2 files changed, 301 insertions(+), 48 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7febbe280e..7b5eba14b7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -82,6 +82,19 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +#if 1 // TODO: Remove +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainMix +{ + vec4 weight; + int type; +#if TERRAIN_DEBUG + ivec4 usage; +#endif +}; +TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal); +#endif + void main() { @@ -125,16 +138,60 @@ void main() // from mikktspace.com vec3 vNt = sample_and_mix_normal(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); - float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; - vec3 vB = sign * cross(vN, vT); + vec3 vB = vary_sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if 0 // TODO: Remove (terrain weights visualization) + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); +#if 1 + // Show full usage and weights + float uw = 0.3; +#if 1 +#if 0 + vec4 mix_usage = vec4(tm.usage); +#else + vec4 mix_usage = vec4(tm.weight); +#endif +#else + // Version with easier-to-see boundaries of weights vs usage + vec4 mix_usage = mix(vec4(tm.usage), + mix(max(vec4(0.0), sign(tm.weight - 0.01)), + max(vec4(0.0), sign(tm.weight - 0.005)), + 0.5), + uw); +#endif + col.xyz = mix_usage.xyz; + col.x = max(col.x, mix_usage.w); + //col.y = 0.0; + //col.z = 0.0; +#else + // Show places where weight > usage + tolerance + float tolerance = 0.005; + vec4 weight_gt_usage = sign( + max( + vec4(0.0), + (tm.weight - (vec4(tm.usage) + vec4(tolerance))) + ) + ); + col.xyz = weight_gt_usage.xyz; + col.x = max(col.x, weight_gt_usage.w); +#endif +#endif +#if 0 // TODO: Remove (material channel discriminator) + //col.rgb = vec3(0.0, 1.0, 0.0); + //col.rgb = spec.rgb; + //col.rgb = (vNt + 1.0) / 2.0; + col.rgb = (tnorm + 1.0) / 2.0; + spec.rgb = vec3(1.0, 1.0, 0.0); + tnorm = vary_normal; + emissive = vec3(0); +#endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index e2d6cdb2d6..59b273afc3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -49,11 +49,62 @@ in vec3 vary_vertex_normal; vec3 srgb_to_linear(vec3 c); +// A relatively agressive threshold ensures that only one or two materials are used in most places +#define TERRAIN_RAMP_MIX_THRESHOLD 0.1 + +#define MIX_X 1 << 3 +#define MIX_Y 1 << 2 +#define MIX_Z 1 << 1 +#define MIX_W 1 << 0 + +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainMix +{ + vec4 weight; + int type; +#if TERRAIN_DEBUG + ivec4 usage; +#endif +}; + +#define TerrainMixSample vec4[4] +#define TerrainMixSample3 vec3[4] + +TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) +{ + TerrainMix tm; + vec4 sample_x = vec4(1,0,0,0); + vec4 sample_y = vec4(0,1,0,0); + vec4 sample_z = vec4(0,0,1,0); + vec4 sample_w = vec4(0,0,0,1); + + tm.weight = mix( mix(sample_w, sample_z, alpha2), mix(sample_y, sample_x, alpha1), alphaFinal ); + tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD; + ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight))); + // Prevent negative weights and keep weights balanced + tm.weight = normalize(tm.weight*vec4(usage)); + + tm.type = (usage.x * MIX_X) | + (usage.y * MIX_Y) | + (usage.z * MIX_Z) | + (usage.w * MIX_W); +#if TERRAIN_DEBUG // TODO: Remove debug + tm.usage = usage; +#endif + return tm; +} + float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { - return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal ); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + // Assume weights are normalized + return tm.weight.x * samples.x + + tm.weight.y * samples.y + + tm.weight.z * samples.z + + tm.weight.w * samples.w; } +#if 0 // TODO: Decide if still needed, and if so, use _t_mix internally for weights vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) { return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); @@ -63,6 +114,25 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) { return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); } +#endif + +vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) +{ + // Assume weights are normalized + return tm.weight.x * tms[0] + + tm.weight.y * tms[1] + + tm.weight.z * tms[2] + + tm.weight.w * tms[3]; +} + +vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) +{ + // Assume weights are normalized + return tm.weight.x * tms3[0] + + tm.weight.y * tms3[1] + + tm.weight.z * tms3[2] + + tm.weight.w * tms3[3]; +} #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 // Triplanar mapping @@ -98,15 +168,12 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); weight_signed -= vec3(threshold); TerrainWeight tw; - tw.weight = max(vec3(0), weight_signed); + // *NOTE: Make sure the threshold doesn't affect the materials + tw.weight = normalize(max(vec3(0), weight_signed)); ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); tw.type = ((usage.x) * SAMPLE_X) | ((usage.y) * SAMPLE_Y) | ((usage.z) * SAMPLE_Z); -#if TERRAIN_DEBUG - tw.weight_signed = weight_signed; - tw.usage = usage; -#endif return tw; } @@ -256,59 +323,188 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) } #endif +// The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. +// *TODO: Currently, there is much more switch..case branching than needed. This could be simplified by branching per-material rather than per-texture. + +TerrainMixSample _tmix_sample(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + TerrainMixSample tms; + + switch (tm.type & MIX_X) + { + case MIX_X: + tms[0] = terrain_texture(tex0, texcoord); + break; + default: + tms[0] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + tms[1] = terrain_texture(tex1, texcoord); + break; + default: + tms[1] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + tms[2] = terrain_texture(tex2, texcoord); + break; + default: + tms[2] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + tms[3] = terrain_texture(tex3, texcoord); + break; + default: + tms[3] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + + return tms; +} + +TerrainMixSample _tmix_sample_color(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + TerrainMixSample tmix; + + switch (tm.type & MIX_X) + { + case MIX_X: + tmix[0] = terrain_texture_color(tex0, texcoord); + break; + default: + tmix[0] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + tmix[1] = terrain_texture_color(tex1, texcoord); + break; + default: + tmix[1] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + tmix[2] = terrain_texture_color(tex2, texcoord); + break; + default: + tmix[2] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + tmix[3] = terrain_texture_color(tex3, texcoord); + break; + default: + tmix[3] = vec4(1.0, 0.0, 1.0, 1.0); + break; + } + + return tmix; +} + +TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) +{ + TerrainMixSample3 tmix3; + + switch (tm.type & MIX_X) + { + case MIX_X: + tmix3[0] = terrain_texture_normal(tex0, texcoord); + break; + default: + tmix3[0] = vec3(1.0, 0.0, 1.0); + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + tmix3[1] = terrain_texture_normal(tex1, texcoord); + break; + default: + tmix3[1] = vec3(1.0, 0.0, 1.0); + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + tmix3[2] = terrain_texture_normal(tex2, texcoord); + break; + default: + tmix3[2] = vec3(1.0, 0.0, 1.0); + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + tmix3[3] = terrain_texture_normal(tex3, texcoord); + break; + default: + tmix3[3] = vec3(1.0, 0.0, 1.0); + break; + } + + return tmix3; +} + vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec3[4] samples; - samples[0] = terrain_texture(tex0, texcoord).xyz; - samples[1] = terrain_texture(tex1, texcoord).xyz; - samples[2] = terrain_texture(tex2, texcoord).xyz; - samples[3] = terrain_texture(tex3, texcoord).xyz; - samples[0] = srgb_to_linear(samples[0]); - samples[1] = srgb_to_linear(samples[1]); - samples[2] = srgb_to_linear(samples[2]); - samples[3] = srgb_to_linear(samples[3]); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); + vec3[4] tms3; + tms3[0] = tms[0].xyz; + tms3[1] = tms[1].xyz; + tms3[2] = tms[2].xyz; + tms3[3] = tms[3].xyz; + tms3[0] *= factors[0]; + tms3[1] *= factors[1]; + tms3[2] *= factors[2]; + tms3[3] *= factors[3]; + return terrain_mix(tm, tms3); } vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec4[4] samples; - samples[0] = terrain_texture_color(tex0, texcoord); - samples[1] = terrain_texture_color(tex1, texcoord); - samples[2] = terrain_texture_color(tex2, texcoord); - samples[3] = terrain_texture_color(tex3, texcoord); - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); + tms[0] *= factors[0]; + tms[1] *= factors[1]; + tms[2] *= factors[2]; + tms[3] *= factors[3]; + return terrain_mix(tm, tms); } vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec3[4] samples; - samples[0] = terrain_texture(tex0, texcoord).xyz; - samples[1] = terrain_texture(tex1, texcoord).xyz; - samples[2] = terrain_texture(tex2, texcoord).xyz; - samples[3] = terrain_texture(tex3, texcoord).xyz; - samples[0] *= factors[0]; - samples[1] *= factors[1]; - samples[2] *= factors[2]; - samples[3] *= factors[3]; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); + vec3[4] tms3; + tms3[0] = tms[0].xyz; + tms3[1] = tms[1].xyz; + tms3[2] = tms[2].xyz; + tms3[3] = tms[3].xyz; + tms3[0] *= factors[0]; + tms3[1] *= factors[1]; + tms3[2] *= factors[2]; + tms3[3] *= factors[3]; + return terrain_mix(tm, tms3); } // Returns the unpacked normal texture in range [-1, 1] vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - vec3[4] samples; - samples[0] = terrain_texture_normal(tex0, texcoord).xyz; - samples[1] = terrain_texture_normal(tex1, texcoord).xyz; - samples[2] = terrain_texture_normal(tex2, texcoord).xyz; - samples[3] = terrain_texture_normal(tex3, texcoord).xyz; - return terrain_mix(samples, alpha1, alpha2, alphaFinal); + TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); + return terrain_mix(tm, tms3); } -- cgit v1.2.3 From 86f0c9faa83ce4917ce7820a3295b39369d994ee Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:35 -0700 Subject: DRTVWR-592: (WIP) (has debug) Fix PBR terrain material mixing and triplanar mapping using wrong mix, causing bright spots --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 59b273afc3..13f3934689 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -82,7 +82,8 @@ TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD; ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight))); // Prevent negative weights and keep weights balanced - tm.weight = normalize(tm.weight*vec4(usage)); + tm.weight = tm.weight*vec4(usage); + tm.weight /= (tm.weight.x + tm.weight.y + tm.weight.z + tm.weight.w); tm.type = (usage.x * MIX_X) | (usage.y * MIX_Y) | @@ -97,7 +98,7 @@ TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); - // Assume weights are normalized + // Assume weights add to 1 return tm.weight.x * samples.x + tm.weight.y * samples.y + tm.weight.z * samples.z + @@ -118,7 +119,7 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) { - // Assume weights are normalized + // Assume weights add to 1 return tm.weight.x * tms[0] + tm.weight.y * tms[1] + tm.weight.z * tms[2] + @@ -127,7 +128,7 @@ vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) { - // Assume weights are normalized + // Assume weights add to 1 return tm.weight.x * tms3[0] + tm.weight.y * tms3[1] + tm.weight.z * tms3[2] + @@ -165,11 +166,13 @@ TerrainWeight _t_weight(TerrainCoord terrain_coord) { float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); + vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); + weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); weight_signed -= vec3(threshold); TerrainWeight tw; // *NOTE: Make sure the threshold doesn't affect the materials - tw.weight = normalize(max(vec3(0), weight_signed)); + tw.weight = max(vec3(0), weight_signed); + tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); tw.type = ((usage.x) * SAMPLE_X) | ((usage.y) * SAMPLE_Y) | -- cgit v1.2.3 From 00d56e2607a671b9478bf06b7df808b2f4141395 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:39 -0700 Subject: DRTVWR-592: Disable (but do not remove) shader debug --- .../shaders/class1/deferred/pbrterrainF.glsl | 9 ++++++--- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 16 +++------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7b5eba14b7..f788b46aa7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -82,7 +82,7 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -#if 1 // TODO: Remove +#if 0 // TODO: Remove #define TERRAIN_DEBUG 1 // TODO: Remove debug struct TerrainMix { @@ -147,6 +147,7 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if TERRAIN_DEBUG // TODO: Remove #if 0 // TODO: Remove (terrain weights visualization) TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); #if 1 @@ -187,10 +188,12 @@ void main() //col.rgb = vec3(0.0, 1.0, 0.0); //col.rgb = spec.rgb; //col.rgb = (vNt + 1.0) / 2.0; - col.rgb = (tnorm + 1.0) / 2.0; - spec.rgb = vec3(1.0, 1.0, 0.0); + //col.rgb = (tnorm + 1.0) / 2.0; + //spec.rgb = vec3(1.0, 1.0, 0.0); + col.rgb = spec.rgb; tnorm = vary_normal; emissive = vec3(0); +#endif #endif frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 13f3934689..9d1990bd4a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -57,7 +57,9 @@ vec3 srgb_to_linear(vec3 c); #define MIX_Z 1 << 1 #define MIX_W 1 << 0 -#define TERRAIN_DEBUG 1 // TODO: Remove debug +#if 0 // TODO: Remove debug +#define TERRAIN_DEBUG 1 +#endif struct TerrainMix { vec4 weight; @@ -105,18 +107,6 @@ float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) tm.weight.w * samples.w; } -#if 0 // TODO: Decide if still needed, and if so, use _t_mix internally for weights -vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); -} - -vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal) -{ - return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal ); -} -#endif - vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) { // Assume weights add to 1 -- cgit v1.2.3 From b163f72ecc2ebdb553b312e5e399d103f00eaf34 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:44 -0700 Subject: DRTVWR-592: (WIP) (has debug) Add new functions for mixing PBR materials. Not yet used. --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 286 ++++++++++++++++++--- 1 file changed, 252 insertions(+), 34 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 9d1990bd4a..a8d8b1a91d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -44,18 +44,99 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 in vec3 vary_vertex_normal; vec3 srgb_to_linear(vec3 c); -// A relatively agressive threshold ensures that only one or two materials are used in most places +// A relatively agressive threshold for terrain material mixing sampling +// cutoff. This ensures that only one or two materials are used in most places, +// making PBR terrain blending more performant. Should be greater than 0 to work. #define TERRAIN_RAMP_MIX_THRESHOLD 0.1 +// A small threshold for triplanar mapping sampling cutoff. This and +// TERRAIN_TRIPLANAR_BLEND_FACTOR together ensures that only one or two samples +// per texture are used in most places, making triplanar mapping more +// performant. Should be greater than 0 to work. +// There's also an artistic design choice in the use of these factors, and the +// use of triplanar generally. Don't take these triplanar constants for granted. +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 + +#define SAMPLE_X 1 << 0 +#define SAMPLE_Y 1 << 1 +#define SAMPLE_Z 1 << 2 +#define MIX_X 1 << 3 +#define MIX_Y 1 << 4 +#define MIX_Z 1 << 5 +#define MIX_W 1 << 6 + +struct PBRMix +{ + vec4 col; // RGB color with alpha, linear space + vec3 orm; // Occlusion, roughness, metallic + vec3 vNt; // Unpacked normal texture sample, vector +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + vec3 emissive; // RGB emissive color, linear space +#endif +}; -#define MIX_X 1 << 3 -#define MIX_Y 1 << 2 -#define MIX_Z 1 << 1 -#define MIX_W 1 << 0 +PBRMix init_pbr_mix() +{ + PBRMix mix; + mix.col = vec4(0); + mix.orm = vec3(0); + mix.vNt = vec3(0); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive = vec3(0); +#endif + return mix; +} + +// Usage example, for two weights: +// vec2 weights = ... // Weights must add up to 1 +// PBRMix mix = init_pbr_mix(); +// PBRMix mix1 = ... +// mix = mix_pbr(mix, mix1, weights.x); +// PBRMix mix2 = ... +// mix = mix_pbr(mix, mix2, weights.y); +PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight) +{ + PBRMix mix; + mix.col = mix1.col + (mix2.col * mix2_weight); + mix.orm = mix1.orm + (mix2.orm * mix2_weight); + mix.vNt = mix1.vNt + (mix2.vNt * mix2_weight); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight); +#endif + return mix; +} + +PBRMix sample_pbr( + vec2 uv + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + ) +{ + PBRMix mix; + mix.col = texture(tex_col, uv); + mix.col.rgb = srgb_to_linear(mix.col.rgb); + mix.orm = texture(tex_orm, uv).xyz; + mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz); +#endif + return mix; +} + +struct TerrainTriplanar +{ + vec3 weight; + int type; +}; #if 0 // TODO: Remove debug #define TERRAIN_DEBUG 1 @@ -97,6 +178,24 @@ TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) return tm; } +TerrainTriplanar _t_triplanar() +{ + float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; + float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; + vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); + weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); + weight_signed -= vec3(threshold); + TerrainTriplanar tw; + // *NOTE: Make sure the threshold doesn't affect the materials + tw.weight = max(vec3(0), weight_signed); + tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); + ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); + tw.type = ((usage.x) * SAMPLE_X) | + ((usage.y) * SAMPLE_Y) | + ((usage.z) * SAMPLE_Z); + return tw; +} + float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); @@ -130,7 +229,6 @@ vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) { @@ -143,31 +241,50 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) return texture(tex, uv); } -#define SAMPLE_X 1 << 2 -#define SAMPLE_Y 1 << 1 -#define SAMPLE_Z 1 << 0 -struct TerrainWeight +vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero) { - vec3 weight; - int type; -}; + // Handle case where sign is 0 + float sign = (2.0*sign_or_zero) + 1.0; + sign /= abs(sign); + // If the vertex normal is negative, flip the texture back + // right-side up. + vec2 uv = uv_unflipped * vec2(sign, 1); + return uv; +} -TerrainWeight _t_weight(TerrainCoord terrain_coord) +vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero) { - float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; - float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; - vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); - weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); - weight_signed -= vec3(threshold); - TerrainWeight tw; - // *NOTE: Make sure the threshold doesn't affect the materials - tw.weight = max(vec3(0), weight_signed); - tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); - ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); - tw.type = ((usage.x) * SAMPLE_X) | - ((usage.y) * SAMPLE_Y) | - ((usage.z) * SAMPLE_Z); - return tw; + // Assume normal is unpacked + vec3 vNt1 = vNt0; + // Get sign + float sign = sign_or_zero; + // Handle case where sign is 0 + sign = (2.0*sign) + 1.0; + sign /= abs(sign); + // If the sign is negative, rotate normal by 180 degrees + vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy); + return vNt1; +} + +// Triplanar-specific normal texture fixes +vec3 _t_normal_post_x(vec3 vNt0) +{ + vec3 vNt_x = _t_normal_post_1(vNt0, sign(vary_vertex_normal.x)); + // *HACK: Transform normals according to orientation of the UVs + vNt_x.xy = vec2(-vNt_x.y, vNt_x.x); + return vNt_x; +} +vec3 _t_normal_post_y(vec3 vNt0) +{ + vec3 vNt_y = _t_normal_post_1(vNt0, sign(vary_vertex_normal.y)); + // *HACK: Transform normals according to orientation of the UVs + vNt_y.xy = -vNt_y.xy; + return vNt_y; +} +vec3 _t_normal_post_z(vec3 vNt0) +{ + vec3 vNt_z = _t_normal_post_1(vNt0, sign(vary_vertex_normal.z)); + return vNt_z; } struct TerrainSample @@ -177,7 +294,7 @@ struct TerrainSample vec4 z; }; -TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) { TerrainSample ts; @@ -227,7 +344,7 @@ struct TerrainSampleNormal vec3 z; }; -TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) { TerrainSample ts = _t_sample(tex, terrain_coord, tw); TerrainSampleNormal tsn; @@ -250,7 +367,7 @@ TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, Terra return tsn; } -TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) { TerrainSample ts = _t_sample(tex, terrain_coord, tw); ts.x.xyz = srgb_to_linear(ts.x.xyz); @@ -262,7 +379,7 @@ TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeig // Triplanar sampling of things that are neither colors nor normals (i.e. orm) vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) { - TerrainWeight tw = _t_weight(terrain_coord); + TerrainTriplanar tw = _t_triplanar(); TerrainSample ts = _t_sample(tex, terrain_coord, tw); @@ -279,7 +396,7 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) // *NOTE: Bottom face has not been tested vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) { - TerrainWeight tw = _t_weight(terrain_coord); + TerrainTriplanar tw = _t_triplanar(); TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); @@ -289,13 +406,92 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) // Triplanar sampling of colors. Colors are converted to linear space before blending. vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) { - TerrainWeight tw = _t_weight(terrain_coord); + TerrainTriplanar tw = _t_triplanar(); TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); } +PBRMix terrain_sample_pbr( + TerrainCoord terrain_coord + , TerrainTriplanar tw + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + ) +{ + PBRMix mix = init_pbr_mix(); + + #define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) + #define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) + #define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) + switch (tw.type & SAMPLE_X) + { + case SAMPLE_X: + PBRMix mix_x = sample_pbr( + get_uv_x() + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + // Triplanar-specific normal texture fix + mix_x.vNt = _t_normal_post_x(mix_x.vNt); + mix = mix_pbr(mix, mix_x, tw.weight.x); + break; + default: + break; + } + + switch (tw.type & SAMPLE_Y) + { + case SAMPLE_Y: + PBRMix mix_y = sample_pbr( + get_uv_y() + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + // Triplanar-specific normal texture fix + mix_y.vNt = _t_normal_post_y(mix_y.vNt); + mix = mix_pbr(mix, mix_y, tw.weight.y); + break; + default: + break; + } + + switch (tw.type & SAMPLE_Z) + { + case SAMPLE_Z: + PBRMix mix_z = sample_pbr( + get_uv_z() + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + // Triplanar-specific normal texture fix + mix_z.vNt = _t_normal_post_z(mix_z.vNt); + mix = mix_pbr(mix, mix_z, tw.weight.z); + break; + default: + break; + } + + return mix; +} + #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 #define TerrainCoord vec2 vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) @@ -314,6 +510,28 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) col.xyz = srgb_to_linear(col.xyz); return col; } + +// TODO: Implement this for the more complex triplanar case +PBRMix terrain_sample_pbr( + TerrainCoord terrain_coord + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + ) +{ + return sample_pbr( + terrain_coord + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); +} #endif // The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -- cgit v1.2.3 From b162ff3cae482a443f93d818125f6e22d647451f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:50 -0700 Subject: DRTVWR-592: Implement reduced branching terrain shader --- .../shaders/class1/deferred/pbrterrainF.glsl | 207 ++++++++++++--------- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 70 ++++++- 2 files changed, 186 insertions(+), 91 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index f788b46aa7..22071421de 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -31,6 +31,52 @@ #define TerrainCoord vec2 #endif +#if 0 // TODO: Remove debug +#define TERRAIN_DEBUG 1 +#endif + +// TODO: Decide if this struct needs to be declared +struct TerrainMix +{ + vec4 weight; + int type; +#if TERRAIN_DEBUG + ivec4 usage; +#endif +}; + +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); + +// TODO: Decide if this struct needs to be declared +struct PBRMix +{ + vec4 col; // RGB color with alpha, linear space + vec3 orm; // Occlusion, roughness, metallic + vec3 vNt; // Unpacked normal texture sample, vector +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + vec3 emissive; // RGB emissive color, linear space +#endif +}; + +PBRMix init_pbr_mix(); + +PBRMix terrain_sample_and_multiply_pbr( + TerrainCoord terrain_coord + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + , vec4 factor_col + , vec3 factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , vec3 factor_emissive +#endif + ); + +PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight); + out vec4 frag_data[4]; uniform sampler2D alpha_ramp; @@ -82,19 +128,6 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -#if 0 // TODO: Remove -#define TERRAIN_DEBUG 1 // TODO: Remove debug -struct TerrainMix -{ - vec4 weight; - int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif -}; -TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal); -#endif - void main() { @@ -108,36 +141,91 @@ void main() float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; - vec4 col = sample_and_mix_color4(alpha1, alpha2, alphaFinal, terrain_texcoord, baseColorFactors, detail_0_base_color, detail_1_base_color, detail_2_base_color, detail_3_base_color); - float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); - if (col.a < minimum_alpha) - { - discard; - } + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - - vec3[4] orm_factors; - orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); - orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); - orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); - orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); // RGB = Occlusion, Roughness, Metal // default values, see LLViewerTexture::sDefaultPBRORMImagep // occlusion 1.0 // roughness 0.0 // metal 0.0 - vec3 spec = sample_and_mix_vector3(alpha1, alpha2, alphaFinal, terrain_texcoord, orm_factors, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness); + vec3[4] orm_factors; + orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); + orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); + orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); + orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); -#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - vec3 emissive = sample_and_mix_color3(alpha1, alpha2, alphaFinal, terrain_texcoord, emissiveColors, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive); -#else - vec3 emissive = vec3(0); -#endif + PBRMix mix = init_pbr_mix(); + PBRMix mix2; + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_0_base_color + , detail_0_metallic_roughness + , detail_0_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_0_emissive + #endif + , baseColorFactors[0] + , orm_factors[0] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[0] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[0]); + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_1_base_color + , detail_1_metallic_roughness + , detail_1_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_1_emissive + #endif + , baseColorFactors[1] + , orm_factors[1] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[1] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[1]); + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_2_base_color + , detail_2_metallic_roughness + , detail_2_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_2_emissive + #endif + , baseColorFactors[2] + , orm_factors[2] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[2] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[2]); + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_3_base_color + , detail_3_metallic_roughness + , detail_3_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_3_emissive + #endif + , baseColorFactors[3] + , orm_factors[3] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[3] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight[3]); + float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + if (mix.col.a < minimum_alpha) + { + discard; + } float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); // from mikktspace.com - vec3 vNt = sample_and_mix_normal(alpha1, alpha2, alphaFinal, terrain_texcoord, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal); + vec3 vNt = mix.vNt; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; @@ -145,59 +233,10 @@ void main() vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); tnorm *= gl_FrontFacing ? 1.0 : -1.0; - -#if TERRAIN_DEBUG // TODO: Remove -#if 0 // TODO: Remove (terrain weights visualization) - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); -#if 1 - // Show full usage and weights - float uw = 0.3; -#if 1 -#if 0 - vec4 mix_usage = vec4(tm.usage); -#else - vec4 mix_usage = vec4(tm.weight); -#endif -#else - // Version with easier-to-see boundaries of weights vs usage - vec4 mix_usage = mix(vec4(tm.usage), - mix(max(vec4(0.0), sign(tm.weight - 0.01)), - max(vec4(0.0), sign(tm.weight - 0.005)), - 0.5), - uw); -#endif - col.xyz = mix_usage.xyz; - col.x = max(col.x, mix_usage.w); - //col.y = 0.0; - //col.z = 0.0; -#else - // Show places where weight > usage + tolerance - float tolerance = 0.005; - vec4 weight_gt_usage = sign( - max( - vec4(0.0), - (tm.weight - (vec4(tm.usage) + vec4(tolerance))) - ) - ); - col.xyz = weight_gt_usage.xyz; - col.x = max(col.x, weight_gt_usage.w); -#endif -#endif -#if 0 // TODO: Remove (material channel discriminator) - //col.rgb = vec3(0.0, 1.0, 0.0); - //col.rgb = spec.rgb; - //col.rgb = (vNt + 1.0) / 2.0; - //col.rgb = (tnorm + 1.0) / 2.0; - //spec.rgb = vec3(1.0, 1.0, 0.0); - col.rgb = spec.rgb; - tnorm = vary_normal; - emissive = vec3(0); -#endif -#endif - frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse - frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse + frag_data[1] = max(vec4(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags - frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive + frag_data[3] = max(vec4(mix.emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a8d8b1a91d..a87927786c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -153,7 +153,7 @@ struct TerrainMix #define TerrainMixSample vec4[4] #define TerrainMixSample3 vec3[4] -TerrainMix _t_mix(float alpha1, float alpha2, float alphaFinal) +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) { TerrainMix tm; vec4 sample_x = vec4(1,0,0,0); @@ -198,7 +198,7 @@ TerrainTriplanar _t_triplanar() float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); // Assume weights add to 1 return tm.weight.x * samples.x + tm.weight.y * samples.y + @@ -511,7 +511,6 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) return col; } -// TODO: Implement this for the more complex triplanar case PBRMix terrain_sample_pbr( TerrainCoord terrain_coord , sampler2D tex_col @@ -671,7 +670,7 @@ TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, samp vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); vec3[4] tms3; tms3[0] = tms[0].xyz; @@ -687,7 +686,7 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, Terrain vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); tms[0] *= factors[0]; tms[1] *= factors[1]; @@ -698,7 +697,7 @@ vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, Terrain vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); vec3[4] tms3; tms3[0] = tms[0].xyz; @@ -715,7 +714,64 @@ vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, Terrai // Returns the unpacked normal texture in range [-1, 1] vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) { - TerrainMix tm = _t_mix(alpha1, alpha2, alphaFinal); + TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); return terrain_mix(tm, tms3); } + +PBRMix multiply_factors_pbr( + PBRMix mix_in + , vec4 factor_col + , vec3 factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , vec3 factor_emissive +#endif + ) +{ + PBRMix mix = mix_in; + mix.col *= factor_col; + mix.orm *= factor_orm; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + mix.emissive *= factor_emissive; +#endif + return mix; +} + +PBRMix terrain_sample_and_multiply_pbr( + TerrainCoord terrain_coord + , sampler2D tex_col + , sampler2D tex_orm + , sampler2D tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , sampler2D tex_emissive +#endif + , vec4 factor_col + , vec3 factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , vec3 factor_emissive +#endif + ) +{ + PBRMix mix = terrain_sample_pbr( + terrain_coord +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 + , _t_triplanar() +#endif + , tex_col + , tex_orm + , tex_vNt +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , tex_emissive +#endif + ); + + mix = multiply_factors_pbr(mix + , factor_col + , factor_orm +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , factor_emissive +#endif + ); + + return mix; +} -- cgit v1.2.3 From be38adebbe46d62bc07d504a70556062f4e55101 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:42:56 -0700 Subject: DRTVWR-592: Add missing branching for terrain sampling. Jury is still out on which version is faster --- .../shaders/class1/deferred/pbrterrainF.glsl | 154 +++++++++++++-------- 1 file changed, 94 insertions(+), 60 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 22071421de..0a7c58451d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -31,6 +31,11 @@ #define TerrainCoord vec2 #endif +#define MIX_X 1 << 3 +#define MIX_Y 1 << 4 +#define MIX_Z 1 << 5 +#define MIX_W 1 << 6 + #if 0 // TODO: Remove debug #define TERRAIN_DEBUG 1 #endif @@ -123,6 +128,7 @@ in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); +// TODO: Clean these up vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); @@ -156,66 +162,94 @@ void main() PBRMix mix = init_pbr_mix(); PBRMix mix2; - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_0_base_color - , detail_0_metallic_roughness - , detail_0_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_0_emissive - #endif - , baseColorFactors[0] - , orm_factors[0] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[0] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[0]); - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_1_base_color - , detail_1_metallic_roughness - , detail_1_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_1_emissive - #endif - , baseColorFactors[1] - , orm_factors[1] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[1] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[1]); - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_2_base_color - , detail_2_metallic_roughness - , detail_2_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_2_emissive - #endif - , baseColorFactors[2] - , orm_factors[2] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[2] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[2]); - mix2 = terrain_sample_and_multiply_pbr( - terrain_texcoord - , detail_3_base_color - , detail_3_metallic_roughness - , detail_3_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , detail_3_emissive - #endif - , baseColorFactors[3] - , orm_factors[3] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , emissiveColors[3] - #endif - ); - mix = mix_pbr(mix, mix2, tm.weight[3]); + switch (tm.type & MIX_X) + { + case MIX_X: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_0_base_color + , detail_0_metallic_roughness + , detail_0_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_0_emissive + #endif + , baseColorFactors[0] + , orm_factors[0] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[0] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.x); + break; + default: + break; + } + switch (tm.type & MIX_Y) + { + case MIX_Y: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_1_base_color + , detail_1_metallic_roughness + , detail_1_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_1_emissive + #endif + , baseColorFactors[1] + , orm_factors[1] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[1] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.y); + break; + default: + break; + } + switch (tm.type & MIX_Z) + { + case MIX_Z: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_2_base_color + , detail_2_metallic_roughness + , detail_2_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_2_emissive + #endif + , baseColorFactors[2] + , orm_factors[2] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[2] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.z); + break; + default: + break; + } + switch (tm.type & MIX_W) + { + case MIX_W: + mix2 = terrain_sample_and_multiply_pbr( + terrain_texcoord + , detail_3_base_color + , detail_3_metallic_roughness + , detail_3_normal + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , detail_3_emissive + #endif + , baseColorFactors[3] + , orm_factors[3] + #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) + , emissiveColors[3] + #endif + ); + mix = mix_pbr(mix, mix2, tm.weight.w); + break; + default: + break; + } float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); if (mix.col.a < minimum_alpha) -- cgit v1.2.3 From f9bd70efc9ab25dfc1ab0b9aa10d16aec271410b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:02 -0700 Subject: DRTVWR-592: Fix non-triplanar being slower somehow in some cases. --- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index a87927786c..078c753a35 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -511,26 +511,8 @@ vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) return col; } -PBRMix terrain_sample_pbr( - TerrainCoord terrain_coord - , sampler2D tex_col - , sampler2D tex_orm - , sampler2D tex_vNt -#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , sampler2D tex_emissive -#endif - ) -{ - return sample_pbr( - terrain_coord - , tex_col - , tex_orm - , tex_vNt -#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) - , tex_emissive -#endif - ); -} +#define terrain_sample_pbr sample_pbr + #endif // The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -- cgit v1.2.3 From f3c98a548a688199114763cfc4eb90bb3d2fbd5c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:08 -0700 Subject: DRTVWR-592: Clean up --- .../shaders/class1/deferred/pbrterrainF.glsl | 50 +-- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 387 +-------------------- 2 files changed, 30 insertions(+), 407 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 0a7c58451d..18f8c4aa73 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -36,18 +36,11 @@ #define MIX_Z 1 << 5 #define MIX_W 1 << 6 -#if 0 // TODO: Remove debug -#define TERRAIN_DEBUG 1 -#endif - // TODO: Decide if this struct needs to be declared struct TerrainMix { vec4 weight; int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif }; TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); @@ -127,12 +120,7 @@ in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); -// TODO: Clean these up -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +float terrain_mix(TerrainMix tm, vec4 tms4); void main() { @@ -170,14 +158,14 @@ void main() , detail_0_base_color , detail_0_metallic_roughness , detail_0_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_0_emissive - #endif +#endif , baseColorFactors[0] , orm_factors[0] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[0] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.x); break; @@ -192,14 +180,14 @@ void main() , detail_1_base_color , detail_1_metallic_roughness , detail_1_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_1_emissive - #endif +#endif , baseColorFactors[1] , orm_factors[1] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[1] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.y); break; @@ -214,14 +202,14 @@ void main() , detail_2_base_color , detail_2_metallic_roughness , detail_2_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_2_emissive - #endif +#endif , baseColorFactors[2] , orm_factors[2] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[2] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.z); break; @@ -236,14 +224,14 @@ void main() , detail_3_base_color , detail_3_metallic_roughness , detail_3_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_3_emissive - #endif +#endif , baseColorFactors[3] , orm_factors[3] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[3] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.w); break; @@ -251,12 +239,12 @@ void main() break; } - float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + float minimum_alpha = terrain_mix(tm, minimum_alphas); if (mix.col.a < minimum_alpha) { discard; } - float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); + float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z)); // from mikktspace.com vec3 vNt = mix.vNt; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 078c753a35..c18cf832f8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -138,16 +138,10 @@ struct TerrainTriplanar int type; }; -#if 0 // TODO: Remove debug -#define TERRAIN_DEBUG 1 -#endif struct TerrainMix { vec4 weight; int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif }; #define TerrainMixSample vec4[4] @@ -172,9 +166,6 @@ TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) (usage.y * MIX_Y) | (usage.z * MIX_Z) | (usage.w * MIX_W); -#if TERRAIN_DEBUG // TODO: Remove debug - tm.usage = usage; -#endif return tm; } @@ -196,32 +187,13 @@ TerrainTriplanar _t_triplanar() return tw; } -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - // Assume weights add to 1 - return tm.weight.x * samples.x + - tm.weight.y * samples.y + - tm.weight.z * samples.z + - tm.weight.w * samples.w; -} - -vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) -{ - // Assume weights add to 1 - return tm.weight.x * tms[0] + - tm.weight.y * tms[1] + - tm.weight.z * tms[2] + - tm.weight.w * tms[3]; -} - -vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) +// Assume weights add to 1 +float terrain_mix(TerrainMix tm, vec4 tms4) { - // Assume weights add to 1 - return tm.weight.x * tms3[0] + - tm.weight.y * tms3[1] + - tm.weight.z * tms3[2] + - tm.weight.w * tms3[3]; + return (tm.weight.x * tms4[0]) + + (tm.weight.y * tms4[1]) + + (tm.weight.z * tms4[2]) + + (tm.weight.w * tms4[3]); } #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 @@ -230,17 +202,6 @@ vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) -{ - // Handle case where sign is 0 - float sign = (2.0*sign_or_zero) + 1.0; - sign /= abs(sign); - // If the vertex normal is negative, flip the texture back - // right-side up. - vec2 uv = uv_unflipped * vec2(sign, 1); - return texture(tex, uv); -} - vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 @@ -287,132 +248,6 @@ vec3 _t_normal_post_z(vec3 vNt0) return vNt_z; } -struct TerrainSample -{ - vec4 x; - vec4 y; - vec4 z; -}; - -TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts; - - // The switch..case is broken up into three parts deliberately. A single - // switch..case caused unexplained, "ant trail" seams in terrain. (as seen - // on Nvidia/Windows 10). The extra two branches are not free, but it's - // still a performance win compared to sampling along all three axes for - // every terrain fragment. - #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) - #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) - #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) - switch (tw.type & SAMPLE_X) - { - case SAMPLE_X: - ts.x = do_sample_x(); - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tw.type & SAMPLE_Y) - { - case SAMPLE_Y: - ts.y = do_sample_y(); - break; - default: - ts.y = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tw.type & SAMPLE_Z) - { - case SAMPLE_Z: - ts.z = do_sample_z(); - break; - default: - ts.z = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return ts; -} - -struct TerrainSampleNormal -{ - vec3 x; - vec3 y; - vec3 z; -}; - -TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - TerrainSampleNormal tsn; - // Unpack normals - tsn.x = ts.x.xyz*2.0-1.0; - tsn.y = ts.y.xyz*2.0-1.0; - tsn.z = ts.z.xyz*2.0-1.0; - // Get sign - vec3 ns = sign(vary_vertex_normal); - // Handle case where sign is 0 - ns = (2.0*ns) + 1.0; - ns /= abs(ns); - // If the sign is negative, rotate normal by 180 degrees - tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); - tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); - tsn.z.xy = (min(0, ns.z) * tsn.z.xy) + (min(0, -ns.z) * -tsn.z.xy); - // *HACK: Transform normals according to orientation of the UVs - tsn.x.xy = vec2(-tsn.x.y, tsn.x.x); - tsn.y.xy = -tsn.y.xy; - return tsn; -} - -TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - ts.x.xyz = srgb_to_linear(ts.x.xyz); - ts.y.xyz = srgb_to_linear(ts.y.xyz); - ts.z.xyz = srgb_to_linear(ts.z.xyz); - return ts; -} - -// Triplanar sampling of things that are neither colors nor normals (i.e. orm) -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - - return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -} - -// Specialized triplanar normal texture sampling implementation, taking into -// account how the rotation of the texture affects the lighting and trying to -// negate that. -// *TODO: Decide if we want this. It may be better to just calculate the -// tangents on-the-fly here rather than messing with the normals, due to the -// subtleties of the effects of triplanar mapping on UVs. These sampled normals -// are only valid on the faces of a cube. -// *NOTE: Bottom face has not been tested -vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); - - return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -} - -// Triplanar sampling of colors. Colors are converted to linear space before blending. -vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); - - return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); -} - PBRMix terrain_sample_pbr( TerrainCoord terrain_coord , TerrainTriplanar tw @@ -426,9 +261,9 @@ PBRMix terrain_sample_pbr( { PBRMix mix = init_pbr_mix(); - #define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) - #define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) - #define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) switch (tw.type & SAMPLE_X) { case SAMPLE_X: @@ -482,6 +317,7 @@ PBRMix terrain_sample_pbr( #endif ); // Triplanar-specific normal texture fix + // *NOTE: Bottom face has not been tested mix_z.vNt = _t_normal_post_z(mix_z.vNt); mix = mix_pbr(mix, mix_z, tw.weight.z); break; @@ -493,214 +329,13 @@ PBRMix terrain_sample_pbr( } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -#define TerrainCoord vec2 -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) -{ - return texture(tex, terrain_coord); -} - -vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) -{ - return texture(tex, terrain_coord).xyz*2.0-1.0; -} -vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) -{ - vec4 col = texture(tex, terrain_coord); - col.xyz = srgb_to_linear(col.xyz); - return col; -} +#define TerrainCoord vec2 #define terrain_sample_pbr sample_pbr #endif -// The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -// *TODO: Currently, there is much more switch..case branching than needed. This could be simplified by branching per-material rather than per-texture. - -TerrainMixSample _tmix_sample(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample tms; - - switch (tm.type & MIX_X) - { - case MIX_X: - tms[0] = terrain_texture(tex0, texcoord); - break; - default: - tms[0] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tms[1] = terrain_texture(tex1, texcoord); - break; - default: - tms[1] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tms[2] = terrain_texture(tex2, texcoord); - break; - default: - tms[2] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tms[3] = terrain_texture(tex3, texcoord); - break; - default: - tms[3] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return tms; -} - -TerrainMixSample _tmix_sample_color(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample tmix; - - switch (tm.type & MIX_X) - { - case MIX_X: - tmix[0] = terrain_texture_color(tex0, texcoord); - break; - default: - tmix[0] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tmix[1] = terrain_texture_color(tex1, texcoord); - break; - default: - tmix[1] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tmix[2] = terrain_texture_color(tex2, texcoord); - break; - default: - tmix[2] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tmix[3] = terrain_texture_color(tex3, texcoord); - break; - default: - tmix[3] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return tmix; -} - -TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample3 tmix3; - - switch (tm.type & MIX_X) - { - case MIX_X: - tmix3[0] = terrain_texture_normal(tex0, texcoord); - break; - default: - tmix3[0] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tmix3[1] = terrain_texture_normal(tex1, texcoord); - break; - default: - tmix3[1] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tmix3[2] = terrain_texture_normal(tex2, texcoord); - break; - default: - tmix3[2] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tmix3[3] = terrain_texture_normal(tex3, texcoord); - break; - default: - tmix3[3] = vec3(1.0, 0.0, 1.0); - break; - } - - return tmix3; -} - -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); - vec3[4] tms3; - tms3[0] = tms[0].xyz; - tms3[1] = tms[1].xyz; - tms3[2] = tms[2].xyz; - tms3[3] = tms[3].xyz; - tms3[0] *= factors[0]; - tms3[1] *= factors[1]; - tms3[2] *= factors[2]; - tms3[3] *= factors[3]; - return terrain_mix(tm, tms3); -} - -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); - tms[0] *= factors[0]; - tms[1] *= factors[1]; - tms[2] *= factors[2]; - tms[3] *= factors[3]; - return terrain_mix(tm, tms); -} - -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); - vec3[4] tms3; - tms3[0] = tms[0].xyz; - tms3[1] = tms[1].xyz; - tms3[2] = tms[2].xyz; - tms3[3] = tms[3].xyz; - tms3[0] *= factors[0]; - tms3[1] *= factors[1]; - tms3[2] *= factors[2]; - tms3[3] *= factors[3]; - return terrain_mix(tm, tms3); -} - -// Returns the unpacked normal texture in range [-1, 1] -vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); - return terrain_mix(tm, tms3); -} - PBRMix multiply_factors_pbr( PBRMix mix_in , vec4 factor_col -- cgit v1.2.3 From 8d9933b37057a67652512d949cedb24b9b087810 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:13 -0700 Subject: DRTVWR-592: EXTRA_CODE_HERE is actually important - bring that back --- indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 2 ++ indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 18f8c4aa73..4bb9758224 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + #define TERRAIN_PBR_DETAIL_EMISSIVE 0 #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index c18cf832f8..316b751590 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +/*[EXTRA_CODE_HERE]*/ + /** * Triplanar mapping implementation adapted from Inigo Quilez' example shader, * MIT license. -- cgit v1.2.3 From cc0f831aaa960552b218da436da57b44cb2dfe0f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:43:18 -0700 Subject: DRTVWR-592: Fix PBR terrain shader compile crash when emissive textures are disabled --- .../newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 8 +++++++- indra/newview/llviewershadermgr.cpp | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 4bb9758224..db03e0885c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -258,9 +258,15 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#define emissive mix.emissive +#else +#define emissive vec3(0) +#endif frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse frag_data[1] = max(vec4(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags - frag_data[3] = max(vec4(mix.emissive,0), vec4(0)); // PBR sRGB Emissive + frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5849f97e0e..d545ef97fd 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -695,6 +695,8 @@ std::string LLViewerShaderMgr::loadBasicShaders() attribs["TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT"] = llformat("%d", mapping); const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor"); attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor); + S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); + attribs["TERRAIN_PBR_DETAIL"] = llformat("%d", detail); } LLGLSLShader::sGlobalDefines = attribs; -- cgit v1.2.3 From 45547c7bbadf15804f54bb28fd1c94eb5f080bf5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 16:19:20 -0700 Subject: DRTVWR-592: Attempt to fix Mac build --- indra/newview/lltexturectrl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 08c530314e..ee7095dd50 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -133,7 +133,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), - pick_type("pick_type", PICK_TEXTURE), + pick_type("pick_type", LLTexPickInventoryType::TEXTURE), allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), -- cgit v1.2.3 From e841c73a9972fc184487c061e8a80add3a18aff1 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 16 Oct 2023 08:45:48 -0700 Subject: Tons of masking changes and tweaks. We now support masking mirrors in the GBuffer. We also now support the concept of one arbitrary clip plane. DRTVWR-583 --- indra/llrender/llshadermgr.cpp | 4 +++ indra/llrender/llshadermgr.h | 3 ++ .../shaders/class1/deferred/materialV.glsl | 17 +++-------- .../shaders/class1/deferred/pbropaqueF.glsl | 27 ++++++++++++++++++ .../shaders/class3/deferred/materialF.glsl | 30 ++++++++++++++++++-- .../shaders/class3/deferred/softenLightF.glsl | 6 ++-- indra/newview/lldrawpoolmaterials.cpp | 13 +++++++++ indra/newview/llfetchedgltfmaterial.cpp | 1 + indra/newview/llheroprobemanager.cpp | 33 +++++++++++++++++----- indra/newview/llheroprobemanager.h | 11 ++++++++ indra/newview/llreflectionmap.cpp | 4 +-- indra/newview/llreflectionmap.h | 2 +- indra/newview/llviewerdisplay.cpp | 2 +- indra/newview/llviewerwindow.cpp | 15 +++++++++- indra/newview/llviewerwindow.h | 3 +- scripts/messages/message_template.msg.sha1 | 2 +- 16 files changed, 141 insertions(+), 32 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 645a78bfac..8ae23989c9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -651,6 +651,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS 0.34\n"); // bit 0 extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR 0.67\n"); // bit 1 + extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_MIRROR 1.0\n"); // bit 2 extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (abs(norm.w-flag)< 0.1)\n"); if (defines) @@ -1256,6 +1257,9 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("emissiveColor"); mReservedUniforms.push_back("metallicFactor"); mReservedUniforms.push_back("roughnessFactor"); + mReservedUniforms.push_back("mirror_flag"); + mReservedUniforms.push_back("clipPlane"); + mReservedUniforms.push_back("clipSign"); mReservedUniforms.push_back("diffuseMap"); mReservedUniforms.push_back("altDiffuseMap"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index a326a5593d..5824c03e2a 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -85,6 +85,9 @@ public: EMISSIVE_COLOR, // "emissiveColor" METALLIC_FACTOR, // "metallicFactor" ROUGHNESS_FACTOR, // "roughnessFactor" + MIRROR_FLAG, // "mirror_flag" + CLIP_PLANE, // "clipPlane" + CLIP_SIGN, // "clipSign" DIFFUSE_MAP, // "diffuseMap" ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap" SPECULAR_MAP, // "specularMap" diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 7cdddfe8db..65706e2c3f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -28,25 +28,18 @@ #define DIFFUSE_ALPHA_MODE_MASK 2 #define DIFFUSE_ALPHA_MODE_EMISSIVE 3 -#ifdef HAS_SKIN uniform mat4 modelview_matrix; uniform mat4 projection_matrix; +uniform mat4 modelview_projection_matrix; + +#ifdef HAS_SKIN mat4 getObjectSkinnedTransform(); #else uniform mat3 normal_matrix; -uniform mat4 modelview_projection_matrix; -#endif - -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - -#if !defined(HAS_SKIN) -uniform mat4 modelview_matrix; #endif out vec3 vary_position; -#endif - uniform mat4 texture_matrix0; in vec3 position; @@ -133,10 +126,8 @@ void main() vertex_color = diffuse_color; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) #if !defined(HAS_SKIN) - vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; -#endif + vary_position = (projection_matrix*vec4(position.xyz, 1.0)).xyz; #endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index faa273b834..9b98a37925 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -58,10 +58,37 @@ vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); +uniform vec4 clipPlane; +uniform float clipSign; +uniform float mirror_flag; +void applyClip(vec3 pos) +{ + if (mirror_flag > 0) + { + // TODO: make this less branchy + if (clipSign > 0) + { + if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) + { + discard; + } + } + else + { + if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) > 0.0) + { + discard; + } + } + } +} + uniform mat3 normal_matrix; void main() { + applyClip(vary_position); + vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba; if (basecolor.a < minimum_alpha) { diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 319f2f25b7..af49e76984 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -51,6 +51,23 @@ vec3 linear_to_srgb(vec3 cs); vec3 legacy_adjust(vec3 c); vec3 legacy_adjust_fullbright(vec3 c); +uniform vec4 clipPlane; +uniform float clipSign; +uniform float mirror_flag; +void applyClip(vec3 pos) +{ + float funnyClip = 0; + if (mirror_flag > 0) + { + if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) > 0.0) + { + discard; + } + } +} + +in vec3 vary_position; + #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) out vec4 frag_color; @@ -72,12 +89,12 @@ uniform vec4 morphFactor; uniform vec3 camPosLocal; uniform mat3 env_mat; +uniform float is_mirror; + uniform vec3 sun_dir; uniform vec3 moon_dir; in vec2 vary_fragcoord; -in vec3 vary_position; - uniform mat4 proj_mat; uniform mat4 inv_proj; uniform vec2 screen_res; @@ -291,6 +308,7 @@ float getShadow(vec3 pos, vec3 norm) void main() { + applyClip(vary_position); waterClip(); // diffcol == diffuse map combined with vertex color @@ -419,9 +437,15 @@ void main() #else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer // deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl + + float flag = GBUFFER_FLAG_HAS_ATMOS; + + if (mirror_flag > 0) + flag = 1; + 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) + frag_data[2] = vec4(encode_normal(norm), env, flag);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog) frag_data[3] = vec4(0); #endif } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 20a5ad66b6..d42388ae78 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -191,7 +191,7 @@ void main() vec3 irradiance = vec3(0); vec3 radiance = vec3(0); - if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR) || GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_MIRROR)) { vec3 orm = texture(specularRect, tc).rgb; float perceptualRoughness = orm.g; @@ -214,7 +214,9 @@ void main() color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; + + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_MIRROR)) + color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; if (do_atmospherics) { diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 6a7e05ac74..373103ce0a 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -190,6 +190,19 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) glUniform4fv(specular, 1, lastSpecular.mV); } + if (gPipeline.mHeroProbeManager.isMirrorPass()) + { + glUniform1f(LLShaderMgr::MIRROR_FLAG, 1); + } + + LLVector4 clipPlane = LLVector4(gPipeline.mHeroProbeManager.currentMirrorClip()[0], + gPipeline.mHeroProbeManager.currentMirrorClip()[1], + gPipeline.mHeroProbeManager.currentMirrorClip()[2], + gPipeline.mHeroProbeManager.currentMirrorClip()[3]); + + mShader->uniform4fv(LLShaderMgr::CLIP_PLANE, + 1, clipPlane.mV); + LLVOAvatar* lastAvatar = nullptr; for (LLCullResult::drawinfo_iterator i = begin; i != end; ) diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 1fb3577dd7..9590066b55 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -128,6 +128,7 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor); shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); + shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0); F32 normal_packed[8]; mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 91d5f9b800..b6db123cd9 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -141,13 +141,13 @@ void LLHeroProbeManager::update() U8 mode = mNearestHero->mirrorPlacementMode(); mode = llmin(mNearestHero->mDrawable->getNumFaces() - 1, mode); - LLFace *face = mNearestHero->mDrawable->getFace(mode); - LLVector3 hero_pos = face->getPositionAgent(); + mCurrentFace = mNearestHero->mDrawable->getFace(mode); + LLVector3 hero_pos = mCurrentFace->getPositionAgent(); // Calculate the average normal. - LLVector4a *posp = face->getViewerObject()->getVolume()->getVolumeFace(face->getTEOffset()).mPositions; - U16 *indp = face->getViewerObject()->getVolume()->getVolumeFace(face->getTEOffset()).mIndices; + LLVector4a *posp = mCurrentFace->getViewerObject()->getVolume()->getVolumeFace(mCurrentFace->getTEOffset()).mPositions; + U16 *indp = mCurrentFace->getViewerObject()->getVolume()->getVolumeFace(mCurrentFace->getTEOffset()).mIndices; // get first three vertices (first triangle) LLVector4a v0 = posp[indp[0]]; LLVector4a v1 = posp[indp[1]]; @@ -158,14 +158,27 @@ void LLHeroProbeManager::update() LLVector3 face_normal = LLVector3(v1[0], v1[1], v1[2]) % LLVector3(v2[0], v2[1], v2[2]); face_normal.normalize(); - face_normal *= face->getXform()->getWorldRotation(); + face_normal *= mCurrentFace->getXform()->getWorldRotation(); LLVector3 offset = camera_pos - hero_pos; LLVector3 project = face_normal * (offset * face_normal); LLVector3 reject = offset - project; LLVector3 point = (reject - project) + hero_pos; - near_clip = abs(dist_vec(hero_pos, point)) - gSavedSettings.getF32("RenderHeroProbeNearClipOffset"); + glh::matrix4f mat = copy_matrix(gGLModelView); + glh::vec4f tc(face_normal.mV); + mat.mult_matrix_vec(tc); + + LLVector3 mirror_normal; + mirror_normal.set(tc.v); + + LLVector3 hero_pos_render; + tc = glh::vec4f(hero_pos.mV); + + mat.mult_matrix_vec(tc); + hero_pos_render.set(tc.v); + + mCurrentClipPlane.setVec(hero_pos_render, mirror_normal); probe_pos.load3(point.mV); } @@ -189,7 +202,7 @@ void LLHeroProbeManager::update() bool radiance_pass = gPipeline.mReflectionMapManager.isRadiancePass(); gPipeline.mReflectionMapManager.mRadiancePass = true; - + mRenderingMirror = true; for (U32 j = 0; j < mProbes.size(); j++) { for (U32 i = 0; i < 6; ++i) @@ -197,6 +210,7 @@ void LLHeroProbeManager::update() updateProbeFace(mProbes[j], i, near_clip); } } + mRenderingMirror = false; gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; } @@ -563,3 +577,8 @@ void LLHeroProbeManager::unregisterHeroDrawable(LLVOVolume* drawablep) mHeroVOList.erase(drawablep); } } + +bool LLHeroProbeManager::isViableMirror(LLFace* face) const +{ + return face == mCurrentFace; +} diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 4a243e6cf2..68cfdbfd99 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -70,6 +70,12 @@ public: void registerHeroDrawable(LLVOVolume* drawablep); void unregisterHeroDrawable(LLVOVolume* drawablep); + + bool isViableMirror(LLFace* face) const; + + bool isMirrorPass() const { return mRenderingMirror; } + + LLPlane currentMirrorClip() const { return mCurrentClipPlane; } private: friend class LLPipeline; @@ -94,6 +100,8 @@ private: // vertex buffer for pushing verts to filter shaders LLPointer mVertexBuffer; + LLPlane mCurrentClipPlane; + // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip); @@ -124,8 +132,11 @@ private: // if true, reset all probe render state on the next update (for teleports and sky changes) bool mReset = false; + + bool mRenderingMirror = false; std::set mHeroVOList; LLVOVolume* mNearestHero; + LLFace* mCurrentFace; }; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 06624e8fea..5fc9851709 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -49,7 +49,7 @@ LLReflectionMap::~LLReflectionMap() } } -void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip) +void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip, bool useClipPlane, LLPlane clipPlane) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; mLastUpdateTime = gFrameTimeSeconds; @@ -66,7 +66,7 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 n F32 clip = (near_clip > 0) ? near_clip : getNearClip(); - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic); + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane); } void LLReflectionMap::autoAdjustOrigin() diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index e97b28c855..9e888f20d0 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -52,7 +52,7 @@ public: // update this environment map // resolution - size of cube map to generate - void update(U32 resolution, U32 face, bool force_dynamic = false, F32 near_clip = -1.f); + void update(U32 resolution, U32 face, bool force_dynamic = false, F32 near_clip = -1.f, bool useClipPlane = false, LLPlane clipPlane = LLPlane(LLVector3(0, 0, 0), LLVector3(0, 0, 1))); // for volume partition probes, try to place this probe in the best spot void autoAdjustOrigin(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 04ca62e0ec..a1e7d69ae4 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1063,7 +1063,7 @@ void display_cube_face() LLSpatialGroup::sNoDelete = TRUE; S32 occlusion = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots + LLPipeline::sUseOcclusion = 1; // occlusion data is from main camera point of view, don't read or write it during cube snapshots //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data static LLCullResult result; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ba2b6e1c7c..e0ec8eec25 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5304,7 +5304,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ void display_cube_face(); -BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render) +BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render, bool useCustomClipPlane, LLPlane clipPlane) { // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; @@ -5335,6 +5335,14 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea camera->setOrigin(origin); camera->setNear(near_clip); + LLPlane previousClipPlane; + + if (useCustomClipPlane) + { + previousClipPlane = camera->getUserClipPlane(); + camera->setUserClipPlane(clipPlane); + } + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT); U32 dynamic_render_types[] = { @@ -5441,6 +5449,11 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea gPipeline.resetDrawOrders(); mWorldViewRectRaw = window_rect; + + if (useCustomClipPlane) + { + camera->setUserClipPlane(previousClipPlane); + } // restore original view/camera/avatar settings settings *camera = saved_camera; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 6e8a5b2f4e..4da6a1360f 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -374,7 +374,8 @@ public: // index - cube index in the array to use (cube index, not face-layer) // face - which cube face to update // near_clip - near clip setting to use - BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars); + BOOL cubeSnapshot(const LLVector3 &origin, LLCubeMapArray *cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars, + bool customCullingPlane = false, LLPlane cullingPlane = LLPlane(LLVector3(0, 0, 0), LLVector3(0, 0, 1))); // special implementation of simpleSnapshot for reflection maps diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1 index 5ad85458e9..8dd2aba32a 100755 --- a/scripts/messages/message_template.msg.sha1 +++ b/scripts/messages/message_template.msg.sha1 @@ -1 +1 @@ -e3bd0529a647d938ab6d48f26d21dd52c07ebc6e \ No newline at end of file +e11941c09b42eb7cc9c56dae08afc03cbf1a22d8 \ No newline at end of file -- cgit v1.2.3 From 0bfeb74172b172fc3202d67fab04df25e23591b0 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 16 Oct 2023 08:48:00 -0700 Subject: Revert an accidental message template sha1 update. DRTVWR-583 --- scripts/messages/message_template.msg.sha1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1 index 8dd2aba32a..5ad85458e9 100755 --- a/scripts/messages/message_template.msg.sha1 +++ b/scripts/messages/message_template.msg.sha1 @@ -1 +1 @@ -e11941c09b42eb7cc9c56dae08afc03cbf1a22d8 \ No newline at end of file +e3bd0529a647d938ab6d48f26d21dd52c07ebc6e \ No newline at end of file -- cgit v1.2.3 From dc1676af27b1a6a1d33d293b22627a6fa3749316 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Dec 2023 00:41:40 +0200 Subject: SL-20734 Uploaded Materials should use 'Uploads' permissions --- indra/newview/llmaterialeditor.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 292ddb765f..ae61198110 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1376,10 +1376,23 @@ bool LLMaterialEditor::saveIfNeeded() LLPermissions local_permissions; local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); - U32 everyone_perm = LLFloaterPerms::getEveryonePerms("Materials"); - U32 group_perm = LLFloaterPerms::getGroupPerms("Materials"); - U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); - local_permissions.initMasks(PERM_ALL, PERM_ALL, everyone_perm, group_perm, next_owner_perm); + if (mIsOverride) + { + // Shouldn't happen, but just in case it ever changes + U32 everyone_perm = LLFloaterPerms::getEveryonePerms("Materials"); + U32 group_perm = LLFloaterPerms::getGroupPerms("Materials"); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); + local_permissions.initMasks(PERM_ALL, PERM_ALL, everyone_perm, group_perm, next_owner_perm); + + } + else + { + // Uploads are supposed to use Upload permissions, not material permissions + U32 everyone_perm = LLFloaterPerms::getEveryonePerms("Uploads"); + U32 group_perm = LLFloaterPerms::getGroupPerms("Uploads"); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Uploads"); + local_permissions.initMasks(PERM_ALL, PERM_ALL, everyone_perm, group_perm, next_owner_perm); + } std::string res_desc = buildMaterialDescription(); createInventoryItem(buffer, mMaterialName, res_desc, local_permissions); -- cgit v1.2.3 From 422c006e32109890aa3cde23c40f334868187cbf Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 15 Dec 2023 18:02:55 +0200 Subject: SL-20702 Remove ALM info in About --- indra/newview/llappviewer.cpp | 1 - indra/newview/skins/default/xui/en/strings.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4a43133ff6..e6a47f1c64 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3328,7 +3328,6 @@ LLSD LLAppViewer::getViewerInfo() const info["NET_BANDWITH"] = gSavedSettings.getF32("ThrottleBandwidthKBPS"); info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor"); info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance"); - info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled"; info["TEXTURE_MEMORY"] = gGLManager.mVRAM; #if LL_DARWIN diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 5d33853adc..e405d9ea10 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -53,7 +53,6 @@ Draw distance: [DRAW_DISTANCE]m Bandwidth: [NET_BANDWITH]kbit/s LOD factor: [LOD_FACTOR] Render quality: [RENDER_QUALITY] -Advanced Lighting Model: [GPU_SHADERS] Texture memory: [TEXTURE_MEMORY]MB Disk cache: [DISK_CACHE_INFO] -- cgit v1.2.3 From 1df31d64e8f06c3aa64714af631750263e9cc9ce Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 15 Dec 2023 16:13:51 -0500 Subject: DRTVWR-601: Update mikktspace and tinygltf to GHA package builds. Ditch 32-bit Windows build of mikktspace. --- autobuild.xml | 88 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 0e5a5a2a25..936c86c84d 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1734,18 +1734,6 @@ mikktspace - canonical_repo - https://bitbucket.org/lindenlab/3p-mikktspace - copyright - Copyright (C) 2011 by Morten S. Mikkelsen - description - Mikktspace Tangent Generator - license - Copyright (C) 2011 by Morten S. Mikkelsen - license_file - mikktspace.txt - name - mikktspace platforms darwin64 @@ -1753,40 +1741,58 @@ archive hash - b48b7ac0792d3ea8f087d99d9e4a29d8 + 6542ca342661ec4dc7f3fbcd29ca7962d3bf4a01 + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104415/914944/mikktspace-1-darwin64-574859.tar.bz2 + https://github.com/secondlife/3p-mikktspace/releases/download/v1-12b73ee/mikktspace-1-darwin64-12b73ee.tar.zst name darwin64 - windows + windows64 archive hash - 0a016b9c0c1e2c0b557e0124094da6c5 + b4c1138005a224018e8c1b9c057f03695b23e70b + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104407/914918/mikktspace-1-windows-574859.tar.bz2 + https://github.com/secondlife/3p-mikktspace/releases/download/v1-12b73ee/mikktspace-1-windows64-12b73ee.tar.zst name - windows + windows64 - windows64 + linux64 archive hash - 02e9e5b6fe6788f4d2babb83ec544843 + e61c1e678b82d75764e29cac107431bdddb3f21f + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104406/914909/mikktspace-1-windows64-574859.tar.bz2 + https://github.com/secondlife/3p-mikktspace/releases/download/v1-12b73ee/mikktspace-1-linux64-12b73ee.tar.zst name - windows64 + linux64 + license + Copyright (C) 2011 by Morten S. Mikkelsen + license_file + mikktspace.txt + copyright + Copyright (C) 2011 by Morten S. Mikkelsen version 1 + name + mikktspace + canonical_repo + https://bitbucket.org/lindenlab/3p-mikktspace + description + Mikktspace Tangent Generator minizip-ng @@ -2376,18 +2382,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors tinygltf - canonical_repo - https://bitbucket.org/lindenlab/3p-tinygltf - copyright - // Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors. - description - tinygltf import library - license - MIT - license_file - LICENSES/tinygltf_license.txt - name - tinygltf platforms common @@ -2395,20 +2389,34 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 4dad1c0948141e1667c01a3ee755e4dc + eee6b755cea664e228dcc28b2ea2a036741a4d77 + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105849/926137/tinygltf-v2.5.0-common-575729.tar.bz2 + https://github.com/secondlife/3p-tinygltf/releases/download/v2.5.0-5d136c3/tinygltf-v2.5.0-common-5d136c3.tar.zst name common + license + MIT + license_file + LICENSES/tinygltf_license.txt + copyright + // Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors. + version + v2.5.0 + name + tinygltf + canonical_repo + https://bitbucket.org/lindenlab/3p-tinygltf + description + tinygltf import library source https://bitbucket.org/lindenlab/3p-tinygltf source_type git - version - v2.5.0 tracy @@ -2448,7 +2456,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl) version - v0.8.1.235e98f + v0.8.1.578241 name tracy canonical_repo @@ -2459,8 +2467,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors https://bitbucket.org/lindenlab/3p-tracy source_type git - version - v0.8.1.578241 tut -- cgit v1.2.3 From d07cd115e3bdef8a2b1d2f6a5a507ddb67ff8cd9 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 15 Dec 2023 16:14:38 -0500 Subject: DRTVWR-601: Drop 32-bit Windows build of llphysicsextension_stub. --- autobuild.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 936c86c84d..a3cf4970e8 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1582,18 +1582,6 @@ name linux64 - windows - - archive - - hash - 2e5f1f7046a49d8b0bc295aa878116bc - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60043/564063/llphysicsextensions_stub-1.0.542456-windows-542456.tar.bz2 - - name - windows - license internal -- cgit v1.2.3 From 67da0c7f604c970c6f637700d84ae0f631b9843a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 15 Dec 2023 16:23:49 -0500 Subject: DRTVWR-601: Update vulkan_gltf to GHA build. --- autobuild.xml | 60 +++++++++++++++++++---------------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index a3cf4970e8..6004096ac7 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2718,59 +2718,37 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors vulkan_gltf - canonical_repo - https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr - copyright - Copyright (c) 2018 Sascha Willems - description - Vulkan GLTF Sample Implementation - license - Copyright (c) 2018 Sascha Willems - license_file - LICENSES/vulkan_gltf.txt - name - vulkan_gltf platforms - darwin64 - - archive - - hash - 8cff2060843db3db788511ee34a8e8cc - url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2 - - name - darwin64 - - windows - - archive - - hash - 58eea384be49ba756ce9c5e66669540b - url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2 - - name - windows - - windows64 + common archive hash - 79b6a11622c2f83cfc2b7cd1fafb867b + 0c4742a4b1a870de9ef0ecfc3ba7ee7d996cb8fc + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2 + https://github.com/secondlife/3p-vulkan-gltf-pbr/releases/download/v1.0.0-93b7b3b/vulkan_gltf-1.0.0-common-93b7b3b.tar.zst name - windows64 + common + license + Copyright (c) 2018 Sascha Willems + license_file + vulkan_gltf.txt + copyright + Copyright (c) 2018 Sascha Willems version - 1 + 1.0.0 + name + vulkan_gltf + canonical_repo + https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr + description + Vulkan GLTF Sample Implementation xxhash -- cgit v1.2.3 From c85d244b61cce60c110da415fb8adf9760455e33 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 08:38:05 -0500 Subject: DRTVWR-601: fix source nanny complaint about VIEWER_VERSION.txt EOL --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 0e7b60da8a..a8a1887568 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.2 \ No newline at end of file +7.1.2 -- cgit v1.2.3 From b782ab73e640e434e4ed67fa8dfc951f09757585 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 10:59:03 -0500 Subject: DRTVWR-601: Make autobuild set vcs_url, vcs_branch, vcs_revision in viewer's autobuild-package.xml. Ensure that AUTOBUILD_VCS_BRANCH is set before the build. --- .github/workflows/build.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 849c10d62e..ad494cb3a4 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -33,6 +33,9 @@ jobs: AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }} AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables + # Direct autobuild to store vcs_url, vcs_branch and vcs_revision in + # autobuild-package.xml. + AUTOBUILD_VCS_INFO: "true" AUTOBUILD_VSVER: "170" DEVELOPER_DIR: ${{ matrix.developer_dir }} # Ensure that Linden viewer builds engage Bugsplat. @@ -192,6 +195,11 @@ jobs: fi export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")" + # branch will be something like "origin/mybranch" + branch="$(git branch -r --contains ${{ github.event.pull_request.head.sha || github.sha }} | head -n 1)" + # strip off "origin/" + export AUTOBUILD_VCS_BRANCH="${branch#*/}" + ./build.sh # Each artifact is downloaded as a distinct .zip file. Multiple jobs -- cgit v1.2.3 From 6f4dcd58b75b536f78eaa1314ce3daa76621c283 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 14:47:03 -0500 Subject: DRTVWR-601: Update mikktspace, tinygltf, tracy, vulkan_gltf, xxhash to latest GitHub builds. Some of these were still referencing codeticket builds produced by TeamCity. --- autobuild.xml | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6004096ac7..f036675b15 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1729,11 +1729,11 @@ archive hash - 6542ca342661ec4dc7f3fbcd29ca7962d3bf4a01 + 6cc1585dba85b0226a2e7033a7e2a2ceaae7c983 hash_algorithm sha1 url - https://github.com/secondlife/3p-mikktspace/releases/download/v1-12b73ee/mikktspace-1-darwin64-12b73ee.tar.zst + https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-darwin64-5cee1f4.tar.zst name darwin64 @@ -1743,11 +1743,11 @@ archive hash - b4c1138005a224018e8c1b9c057f03695b23e70b + 6b7d01ad54e4a88a001f66840c32329cedb28202 hash_algorithm sha1 url - https://github.com/secondlife/3p-mikktspace/releases/download/v1-12b73ee/mikktspace-1-windows64-12b73ee.tar.zst + https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-windows64-5cee1f4.tar.zst name windows64 @@ -1757,11 +1757,11 @@ archive hash - e61c1e678b82d75764e29cac107431bdddb3f21f + edc9782bf209e17ad1845498b42f16d733582082 hash_algorithm sha1 url - https://github.com/secondlife/3p-mikktspace/releases/download/v1-12b73ee/mikktspace-1-linux64-12b73ee.tar.zst + https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-linux64-5cee1f4.tar.zst name linux64 @@ -2377,11 +2377,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - eee6b755cea664e228dcc28b2ea2a036741a4d77 + 2c47ae2d0c38c86b8c2db8d9317f0ab15edfc74f hash_algorithm sha1 url - https://github.com/secondlife/3p-tinygltf/releases/download/v2.5.0-5d136c3/tinygltf-v2.5.0-common-5d136c3.tar.zst + https://github.com/secondlife/3p-tinygltf/releases/download/v2.5.0-1ae57fd/tinygltf-v2.5.0-common-1ae57fd.tar.zst name common @@ -2415,9 +2415,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 9b6e1a1f4b0969d38a1ca8ee00aeb548 + 49650353442698c3e05102676fe427d0ebe02f0b + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110584/960613/tracy-v0.8.1.578241-darwin64-578241.tar.bz2 + https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-darwin64-eecbf72.tar.zst name darwin64 @@ -2427,11 +2429,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 05b72ae5d733aed7d3bf142287601cc6 + 2b80e7407e4f3e82eff3879add0e9ad63e7fcace hash_algorithm - md5 + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110586/960637/tracy-v0.8.1.578241-windows64-578241.tar.bz2 + https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-windows64-eecbf72.tar.zst name windows64 @@ -2444,7 +2446,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl) version - v0.8.1.578241 + v0.8.1-eecbf72 name tracy canonical_repo @@ -2725,11 +2727,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 0c4742a4b1a870de9ef0ecfc3ba7ee7d996cb8fc + 8e365eff8dcace48d91e2530f8b13e420849aefc hash_algorithm sha1 url - https://github.com/secondlife/3p-vulkan-gltf-pbr/releases/download/v1.0.0-93b7b3b/vulkan_gltf-1.0.0-common-93b7b3b.tar.zst + https://github.com/secondlife/3p-vulkan-gltf-pbr/releases/download/v1.0.0-d7c372f/vulkan_gltf-1.0.0-common-d7c372f.tar.zst name common @@ -2771,11 +2773,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - fdcc803a76a3359bb426db7dac161406676d51e7 + 71921e972a9181da916d9f9da6bceaa99935901b hash_algorithm sha1 url - https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-darwin64-7501c90.tar.zst + https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-d405199/xxhash-0.8.1-d405199-darwin64-d405199.tar.zst name darwin64 @@ -2785,11 +2787,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 7acb3f94a549fbb9bd7bc16604e34f33c5365a9b + b5b47855316f1f82266e3f9086997048b8d81952 hash_algorithm sha1 url - https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-linux64-7501c90.tar.zst + https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-d405199/xxhash-0.8.1-d405199-linux64-d405199.tar.zst name linux64 @@ -2799,11 +2801,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 4522d075ea4703ef4b527c3039864ef735ea7953 + 069d5f4a4b25462092d74da24d03db34cc2b91f3 hash_algorithm sha1 url - https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-windows64-7501c90.tar.zst + https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-d405199/xxhash-0.8.1-d405199-windows64-d405199.tar.zst name windows64 @@ -2816,7 +2818,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2012-2021 Yann Collet version - 0.8.1.7501c90 + 0.8.1-d405199 name xxhash description @@ -3341,4 +3343,4 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors Second Life Viewer - + \ No newline at end of file -- cgit v1.2.3 From 2c5066f1fcc0c9f145698ef3aaec72d27bce7181 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 17:35:23 -0500 Subject: DRTVWR-601: Use viewer-build-util/which-branch to determine branch. --- .github/workflows/build.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ad494cb3a4..dee1ca24ab 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -99,10 +99,17 @@ jobs: if: runner.os == 'Windows' run: choco install nsis-unicode + - name: Determine source branch + id: which-branch + uses: secondlife/viewer-build-util/which-branch@v1 + with: + token: ${{ github.token }} + - name: Build id: build shell: bash env: + AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }} RUNNER_OS: ${{ runner.os }} run: | # set up things the viewer's build.sh script expects @@ -153,7 +160,7 @@ jobs: } repo_branch() { - git -C "$1" branch | grep '^* ' | cut -c 3- + echo "$AUTOBUILD_VCS_BRANCH" } record_dependencies_graph() { @@ -195,11 +202,6 @@ jobs: fi export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")" - # branch will be something like "origin/mybranch" - branch="$(git branch -r --contains ${{ github.event.pull_request.head.sha || github.sha }} | head -n 1)" - # strip off "origin/" - export AUTOBUILD_VCS_BRANCH="${branch#*/}" - ./build.sh # Each artifact is downloaded as a distinct .zip file. Multiple jobs -- cgit v1.2.3 From f43e4c6253e14309ceffbe215a7f03b49b7215e8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 19 Dec 2023 10:20:37 -0600 Subject: SL-20611 Followup -- fix for water haze artifacts on fullbright objects above water. --- indra/newview/pipeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3a1edb0d00..f740fa60be 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8359,7 +8359,7 @@ void LLPipeline::doWaterHaze() else { //render water patches like LLDrawPoolWater does - LLGLDepthTest depth(GL_FALSE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDisable cull(GL_CULL_FACE); gGLLastMatrix = NULL; -- cgit v1.2.3 From 575dc8f4105828b421dd1a3856412a6dc4f16618 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 19 Dec 2023 15:36:34 -0600 Subject: SL-20754 Modify default midday to be a better approximation of Cloud Layers HDRI (addresses blue sheen). --- indra/newview/llenvironment.cpp | 2 +- indra/newview/llmaterialeditor.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index edc7bdef5f..ffaca846dd 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -815,7 +815,7 @@ const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f); const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb"); -const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("651510b8-5f4d-8991-1592-e7eeab2a5a06"); +const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("c46226b4-0e43-5a56-9708-d27ca1df3292"); const LLUUID LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY("cef49723-0292-af49-9b14-9598a616b8a3"); const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2"); const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090"); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index ae61198110..db9589666c 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2241,7 +2241,7 @@ bool LLMaterialEditor::canModifyObjectsMaterial() LLSelectedTEGetMatData func(true); LLPermissions permissions; LLViewerInventoryItem* item_out; - return can_use_objects_material(func, std::vector({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out); + return can_use_objects_material(func, std::vector({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out); } bool LLMaterialEditor::canSaveObjectsMaterial() @@ -2249,7 +2249,7 @@ bool LLMaterialEditor::canSaveObjectsMaterial() LLSelectedTEGetMatData func(true); LLPermissions permissions; LLViewerInventoryItem* item_out; - return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out); + return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out); } bool LLMaterialEditor::canClipboardObjectsMaterial() @@ -2275,7 +2275,7 @@ bool LLMaterialEditor::canClipboardObjectsMaterial() LLSelectedTEGetMatData func(true); LLPermissions permissions; LLViewerInventoryItem* item_out; - return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out); + return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out); } void LLMaterialEditor::saveObjectsMaterialAs() @@ -2283,7 +2283,7 @@ void LLMaterialEditor::saveObjectsMaterialAs() LLSelectedTEGetMatData func(true); LLPermissions permissions; LLViewerInventoryItem* item = nullptr; - bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item); + bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item); if (!allowed) { LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL; -- cgit v1.2.3 From bc3076938ea3c812054db41a72bdd5d5fbc46d3f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 20 Dec 2023 12:50:34 -0500 Subject: DRTVWR-601: Update xxhash common platform to GHA build. Remove identical platform-specific package references. --- autobuild.xml | 50 +++++--------------------------------------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index f036675b15..522d9e6df4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2761,54 +2761,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - e4f77ba0a9b8ec3cc3fabc51c4da81d2 - url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110070/956941/xxhash-0.8.1.578006-windows-578006.tar.bz2 - - name - common - - darwin64 - - archive - - hash - 71921e972a9181da916d9f9da6bceaa99935901b - hash_algorithm - sha1 - url - https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-d405199/xxhash-0.8.1-d405199-darwin64-d405199.tar.zst - - name - darwin64 - - linux64 - - archive - - hash - b5b47855316f1f82266e3f9086997048b8d81952 - hash_algorithm - sha1 - url - https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-d405199/xxhash-0.8.1-d405199-linux64-d405199.tar.zst - - name - linux64 - - windows64 - - archive - - hash - 069d5f4a4b25462092d74da24d03db34cc2b91f3 + 1a73c476b371b62066d1c3eced249660e9467e53 hash_algorithm sha1 url - https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-d405199/xxhash-0.8.1-d405199-windows64-d405199.tar.zst + https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-69ff69a/xxhash-0.8.1-69ff69a-common-69ff69a.tar.zst name - windows64 + common license @@ -2818,7 +2778,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2012-2021 Yann Collet version - 0.8.1-d405199 + 0.8.1-69ff69a name xxhash description @@ -3343,4 +3303,4 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors Second Life Viewer - \ No newline at end of file + -- cgit v1.2.3 From 4392f1bc8f3e44cc5b92bc1ed7b51744ef3c4c38 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 5 Jan 2024 00:57:58 +0200 Subject: SL-20748 Fix library materials not being previewable on an object --- indra/newview/llpanelface.cpp | 3 ++- indra/newview/llselectmgr.cpp | 38 ++++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 5f8071d3eb..033c396d08 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -5176,8 +5176,9 @@ void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp) bool can_modify = itemp->getPermissions().allowOperationBy(PERM_MODIFY, gAgentID); // do we have perm to transfer this material? bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply material belong to the agent? bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply material not for sale? + bool from_library = ALEXANDRIA_LINDEN_ID == itemp->getPermissions().getOwner(); - if (can_copy && can_transfer && can_modify) + if ((can_copy && can_transfer && can_modify) || from_library) { pbr_ctrl->setCanApply(true, true); return; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index d172a87b1d..c2e3857af0 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1959,26 +1959,30 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) { return false; } - if (mItem && objectp->isAttachment()) + LLUUID asset_id = mMatId; + if (mItem) { const LLPermissions& perm = mItem->getPermissions(); - BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE; - if (!unrestricted) + bool from_library = perm.getOwner() == ALEXANDRIA_LINDEN_ID; + if (objectp->isAttachment()) { - // Attachments are in world and in inventory simultaneously, - // at the moment server doesn't support such a situation. - return false; + bool unrestricted = (perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED; + + if (!unrestricted && !from_library) + { + // Attachments are in world and in inventory simultaneously, + // at the moment server doesn't support such a situation. + return false; + } } - } - LLUUID asset_id = mMatId; - if (mItem) - { - // If success, the material may be copied into the object's inventory - BOOL success = LLToolDragAndDrop::handleDropMaterialProtections(objectp, mItem, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); - if (!success) + + if (!from_library + // Check if item may be copied into the object's inventory + && !LLToolDragAndDrop::handleDropMaterialProtections(objectp, mItem, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null)) { return false; } + asset_id = mItem->getAssetUUID(); if (asset_id.isNull()) { @@ -1994,11 +1998,13 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) }; bool success = true; - if (item && - (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) || + if (item + && (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) || !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) || !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()) - )) + ) + && item->getPermissions().getOwner() != ALEXANDRIA_LINDEN_ID + ) { success = success && getSelection()->applyRestrictedPbrMaterialToTEs(item); } -- cgit v1.2.3 From 983a3c7207bcb233fb5a1cfdfbed8b9a3f992a73 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 9 Jan 2024 15:52:33 -0600 Subject: SL-20780 Clean up some dead code. --- indra/newview/llgltfmateriallist.cpp | 171 +---------------------------------- indra/newview/llgltfmateriallist.h | 4 - indra/newview/llstartup.cpp | 3 - indra/newview/llviewerobject.cpp | 5 - indra/newview/llviewerregion.cpp | 11 --- indra/newview/llviewerregion.h | 2 - 6 files changed, 2 insertions(+), 194 deletions(-) diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 8919229c78..92c58a2dbc 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -139,69 +139,18 @@ static bool is_valid_update(const LLSD& data) } #endif -class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler +class LLGLTFMaterialOverrideDispatchHandler { LOG_CLASS(LLGLTFMaterialOverrideDispatchHandler); public: LLGLTFMaterialOverrideDispatchHandler() = default; - ~LLGLTFMaterialOverrideDispatchHandler() override = default; + ~LLGLTFMaterialOverrideDispatchHandler() = default; void addCallback(void(*callback)(const LLUUID& object_id, S32 side)) { mSelectionCallbacks.push_back(callback); } - bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override - { - LL_PROFILE_ZONE_SCOPED; - // receive override data from simulator via LargeGenericMessage - // message should have: - // object_id - UUID of LLViewerObject - // sides - array of S32 indices of texture entries - // gltf_json - array of corresponding Strings of GLTF json for override data - - LLSD message; - bool success = true; -#if 0 //deprecated - for(const std::string& llsdRaw : strings) - { - std::istringstream llsdData(llsdRaw); - if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length())) - { - LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; - success = false; - continue; - } - - LLGLTFOverrideCacheEntry object_override; - if (!object_override.fromLLSD(message)) - { - // malformed message, nothing we can do to handle it - LL_DEBUGS("GLTF") << "Message without id:" << message << LL_ENDL; - success = false; - continue; - } - - // Cache the data - { - LLViewerRegion * region = LLWorld::instance().getRegionFromHandle(object_override.mRegionHandle); - - if (region) - { - region->cacheFullUpdateGLTFOverride(object_override); - } - else - { - LL_WARNS("GLTF") << "could not access region for material overrides message cache, region_handle: " << LL_ENDL; - } - } - applyData(object_override); - } - -#endif - return success; - } - void doSelectionCallbacks(const LLUUID& object_id, S32 side) { for (auto& callback : mSelectionCallbacks) @@ -210,112 +159,6 @@ public: } } - void applyData(const LLGLTFOverrideCacheEntry &object_override) - { - // Parse the data - -#if 0 // DEPRECATED - LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); - LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); - - struct ReturnData - { - public: - LLGLTFMaterial mMaterial; - S32 mSide; - bool mSuccess; - }; - - if (!object_override.mSides.empty()) - { - // fromJson() is performance heavy offload to a thread. - main_queue->postTo( - general_queue, - [sides=object_override.mSides]() // Work done on general queue - { - std::vector results; - - results.reserve(sides.size()); - // parse json - std::unordered_map::const_iterator iter = sides.begin(); - std::unordered_map::const_iterator end = sides.end(); - while (iter != end) - { - ReturnData result; - - result.mMaterial.applyOverrideLLSD(iter->second); - - result.mSuccess = true; - result.mSide = iter->first; - - results.push_back(result); - iter++; - } - return results; - }, - [object_id=object_override.mObjectId, this](std::vector results) // Callback to main thread - { - LLViewerObject * obj = gObjectList.findObject(object_id); - - if (results.size() > 0 ) - { - std::unordered_set side_set; - - for (auto const & result : results) - { - S32 side = result.mSide; - if (result.mSuccess) - { - // copy to heap here because LLTextureEntry is going to take ownership with an LLPointer - LLGLTFMaterial * material = new LLGLTFMaterial(result.mMaterial); - - // flag this side to not be nulled out later - side_set.insert(side); - - if (obj) - { - obj->setTEGLTFMaterialOverride(side, material); - } - } - - // unblock material editor - if (obj && obj->getTE(side) && obj->getTE(side)->isSelected()) - { - doSelectionCallbacks(object_id, side); - } - } - - if (obj && side_set.size() != obj->getNumTEs()) - { // object exists and at least one texture entry needs to have its override data nulled out - for (int i = 0; i < obj->getNumTEs(); ++i) - { - if (side_set.find(i) == side_set.end()) - { - obj->setTEGLTFMaterialOverride(i, nullptr); - if (obj->getTE(i) && obj->getTE(i)->isSelected()) - { - doSelectionCallbacks(object_id, i); - } - } - } - } - } - else if (obj) - { // override list was empty or an error occurred, null out all overrides for this object - for (int i = 0; i < obj->getNumTEs(); ++i) - { - obj->setTEGLTFMaterialOverride(i, nullptr); - if (obj->getTE(i) && obj->getTE(i)->isSelected()) - { - doSelectionCallbacks(obj->getID(), i); - } - } - } - }); - } -#endif - } - private: std::vector mSelectionCallbacks; @@ -821,12 +664,6 @@ void LLGLTFMaterialList::flushMaterials() } } -// static -void LLGLTFMaterialList::registerCallbacks() -{ - gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message); -} - // static void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool) ) { @@ -864,7 +701,3 @@ void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, } } -void LLGLTFMaterialList::loadCacheOverrides(const LLGLTFOverrideCacheEntry& override) -{ - handle_gltf_override_message.applyData(override); -} diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 7317214019..f1c4ce20f9 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -52,8 +52,6 @@ public: void flushMaterials(); - static void registerCallbacks(); - // Queue an modification of a material that we want to send to the simulator. Call "flushUpdates" to flush pending updates. // id - ID of object to modify // side - TexureEntry index to modify, or -1 for all sides @@ -99,8 +97,6 @@ public: // any override data that arrived before the object was ready to receive it void applyQueuedOverrides(LLViewerObject* obj); - static void loadCacheOverrides(const LLGLTFOverrideCacheEntry& override); - // Apply an override update with the given data void applyOverrideMessage(LLMessageSystem* msg, const std::string& data); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d0b76848f7..8681bf6e2a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1511,9 +1511,6 @@ bool idle_startup() gXferManager->registerCallbacks(gMessageSystem); display_startup(); - LLGLTFMaterialList::registerCallbacks(); - display_startup(); - LLStartUp::initNameCache(); display_startup(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index d4346ee2d9..a741f57753 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5041,11 +5041,6 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) LLViewerObject* obj = gObjectList.findObject(id); if (obj) { - LLViewerRegion* region = obj->getRegion(); - if(region) - { - region->loadCacheMiscExtras(obj->getLocalID()); - } obj->markForUpdate(); } }); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 452dcdd8fd..60862ae5bd 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1879,8 +1879,6 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) addActiveCacheEntry(entry); } - loadCacheMiscExtras(entry->getLocalID()); - return obj; } @@ -3655,15 +3653,6 @@ std::string LLViewerRegion::getSimHostName() return std::string("..."); } -void LLViewerRegion::loadCacheMiscExtras(U32 local_id) -{ - auto iter = mImpl->mGLTFOverridesLLSD.find(local_id); - if (iter != mImpl->mGLTFOverridesLLSD.end()) - { - LLGLTFMaterialList::loadCacheOverrides(iter->second); - } -} - void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index a409d837a4..622490c881 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -435,8 +435,6 @@ private: bool isNonCacheableObjectCreated(U32 local_id); public: - void loadCacheMiscExtras(U32 local_id); - void applyCacheMiscExtras(LLViewerObject* obj); struct CompareDistance -- cgit v1.2.3 From 390a5031dcdbc6bf191f49a105021c8a707a9949 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 10 Jan 2024 01:43:36 +0200 Subject: SL-19555 Fix picker failing to highlight default material in inventory --- indra/newview/llfloaterchangeitemthumbnail.cpp | 3 +- indra/newview/llinventoryfunctions.cpp | 6 ++ indra/newview/llinventoryfunctions.h | 22 +++++ indra/newview/llpanelface.cpp | 2 +- indra/newview/llpanelprofile.cpp | 6 +- indra/newview/lltexturectrl.cpp | 123 +++++++++++++++---------- indra/newview/lltexturectrl.h | 24 ++--- 7 files changed, 119 insertions(+), 67 deletions(-) diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index 0301627c15..776f8dc785 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -751,7 +751,8 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) PERM_NONE, PERM_NONE, FALSE, - NULL); + NULL, + PICK_TEXTURE); mPickerHandle = floaterp->getHandle(); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 4aeacae6ed..207dd692a8 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2554,6 +2554,12 @@ bool LLIsOfAssetType::operator()(LLInventoryCategory* cat, LLInventoryItem* item return FALSE; } +bool LLAssetIDAndTypeMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + if (!item) return false; + return (item->getActualType() == mType && item->getAssetUUID() == mAssetID); +} + bool LLIsValidItemLink::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { LLViewerInventoryItem *vitem = dynamic_cast(item); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 925217dda3..2056a7f6a3 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -278,6 +278,28 @@ protected: LLAssetType::EType mType; }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLAssetIDAndTypeMatches +// +// Implementation of a LLInventoryCollectFunctor which returns TRUE if +// the item matches both asset type and asset id. +// This is needed in case you are looking for a specific type with default id +// (since null is default for multiple asset types) +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLAssetIDAndTypeMatches: public LLInventoryCollectFunctor +{ +public: + LLAssetIDAndTypeMatches(const LLUUID& asset_id, LLAssetType::EType type): mAssetID(asset_id), mType(type) {} + virtual ~LLAssetIDAndTypeMatches() {} + bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); + +protected: + LLUUID mAssetID; + LLAssetType::EType mType; +}; + class LLIsValidItemLink : public LLInventoryCollectFunctor { public: diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 033c396d08..269ae23eb8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -330,7 +330,7 @@ BOOL LLPanelFace::postBuild() pbr_ctrl->setImmediateFilterPermMask(PERM_NONE); pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); pbr_ctrl->setBakeTextureEnabled(false); - pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL); + pbr_ctrl->setInventoryPickType(PICK_MATERIAL); } mTextureCtrl = getChild("texture control"); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index ffbed778c1..8114e05a94 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1969,7 +1969,8 @@ void LLPanelProfileSecondLife::onShowTexturePicker() PERM_NONE, PERM_NONE, FALSE, - NULL); + NULL, + PICK_TEXTURE); mFloaterTexturePickerHandle = texture_floaterp->getHandle(); @@ -2304,7 +2305,8 @@ void LLPanelProfileFirstLife::onChangePhoto() PERM_NONE, PERM_NONE, FALSE, - NULL); + NULL, + PICK_TEXTURE); mFloaterTexturePickerHandle = texture_floaterp->getHandle(); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 28e01c6c21..233b864fba 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -151,7 +151,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( PermissionMask immediate_filter_perm_mask, PermissionMask dnd_filter_perm_mask, BOOL can_apply_immediately, - LLUIImagePtr fallback_image) + LLUIImagePtr fallback_image, + EPickInventoryType pick_type) : LLFloater(LLSD()), mOwner( owner ), mImageAssetID( image_asset_id ), @@ -181,7 +182,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mSetImageAssetIDCallback(NULL), mOnUpdateImageStatsCallback(NULL), mBakeTextureEnabled(FALSE), - mInventoryPickType(LLTextureCtrl::PICK_TEXTURE) + mInventoryPickType(pick_type) { mCanApplyImmediately = can_apply_immediately; buildFromFile("floater_texture_ctrl.xml"); @@ -225,7 +226,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID()); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL + if (mInventoryPickType == PICK_MATERIAL && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID && itemp && itemp->getAssetUUID().isNull()) { @@ -266,7 +267,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection) { LLUUID asset_id = itemp->getAssetUUID(); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL && asset_id.isNull()) + if (mInventoryPickType == PICK_MATERIAL && asset_id.isNull()) { // If an inventory item has a null asset, consider it a valid blank material(gltf) asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID; @@ -425,11 +426,11 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( bool is_material = cargo_type == DAD_MATERIAL; bool allow_dnd = false; - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { allow_dnd = is_material; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == PICK_TEXTURE) { allow_dnd = is_texture || is_mesh; } @@ -602,9 +603,7 @@ BOOL LLFloaterTexturePicker::postBuild() // don't put keyboard focus on selected item, because the selection callback // will assume that this was user input - - - if(!mImageAssetID.isNull()) + if(!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL) { mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); } @@ -661,7 +660,7 @@ void LLFloaterTexturePicker::draw() mGLTFMaterial = NULL; if (mImageAssetID.notNull()) { - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID); llassert(mGLTFMaterial == nullptr || dynamic_cast(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr); @@ -786,27 +785,43 @@ void LLFloaterTexturePicker::draw() const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library) { - LLUUID loockup_id = asset_id; - if (loockup_id.isNull()) + if (asset_id.isNull()) { - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) - { - loockup_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID; - } - else - { - return LLUUID::null; - } + // null asset id means, no material or texture assigned + return LLUUID::null; } + LLUUID loockup_id = asset_id; + if (mInventoryPickType == PICK_MATERIAL && loockup_id == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID) + { + // default asset id means we are looking for an inventory item with a default asset UUID (null) + loockup_id = LLUUID::null; + } + LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(loockup_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); + + if (loockup_id.isNull()) + { + // looking for a material with a null id, null id is shared by a lot + // of objects as a default value, so have to filter by type as well + LLAssetIDAndTypeMatches matches(loockup_id, LLAssetType::AT_MATERIAL); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + matches); + } + else + { + LLAssetIDMatches asset_id_matches(loockup_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + } + if (items.size()) { @@ -871,7 +886,7 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op) LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID()); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL + if (mInventoryPickType == PICK_MATERIAL && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID && itemp && itemp->getAssetUUID().isNull()) { @@ -1064,15 +1079,15 @@ void LLFloaterTexturePicker::onBtnAdd(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata; - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (self->mInventoryPickType == PICK_TEXTURE_MATERIAL) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL_TEXTURE, true); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (self->mInventoryPickType == PICK_TEXTURE) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_IMAGE, true); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (self->mInventoryPickType == PICK_MATERIAL) { LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL, true); } @@ -1351,7 +1366,7 @@ void LLFloaterTexturePicker::changeMode() getChild("hide_base_mesh_region")->setVisible(FALSE);// index == 2 ? TRUE : FALSE); bool pipette_visible = (index == PICKER_INVENTORY) - && (mInventoryPickType != LLTextureCtrl::PICK_MATERIAL); + && (mInventoryPickType != PICK_MATERIAL); mPipetteBtn->setVisible(pipette_visible); if (index == PICKER_BAKE) @@ -1414,16 +1429,16 @@ void LLFloaterTexturePicker::refreshLocalList() { mLocalScrollCtrl->clearRows(); - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == PICK_TEXTURE_MATERIAL) { LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == PICK_TEXTURE) { LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == PICK_MATERIAL) { LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } @@ -1433,18 +1448,18 @@ void LLFloaterTexturePicker::refreshInventoryFilter() { U32 filter_types = 0x0; - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == PICK_TEXTURE_MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == PICK_TEXTURE) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == PICK_MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } @@ -1479,13 +1494,13 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) onModeSelect(0, this); } -void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type) +void LLFloaterTexturePicker::setInventoryPickType(EPickInventoryType type) { mInventoryPickType = type; refreshLocalList(); refreshInventoryFilter(); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { getChild("Pipette")->setVisible(false); } @@ -1501,7 +1516,7 @@ void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryT setTitle(pick + mLabel); } - else if(mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if(mInventoryPickType == PICK_MATERIAL) { setTitle(getString("pick_material")); } @@ -1509,6 +1524,12 @@ void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryT { setTitle(getString("pick_texture")); } + + // refresh selection + if (!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL) + { + mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); + } } void LLFloaterTexturePicker::setImmediateFilterPermMask(PermissionMask mask) @@ -1543,16 +1564,16 @@ void LLFloaterTexturePicker::onPickerCallback(const std::vector& fi LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)handle.get(); self->mLocalScrollCtrl->clearRows(); - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (self->mInventoryPickType == PICK_TEXTURE_MATERIAL) { LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (self->mInventoryPickType == PICK_TEXTURE) { LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + else if (self->mInventoryPickType == PICK_MATERIAL) { LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); } @@ -1565,7 +1586,7 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) if (inventory_item_id.notNull()) { LLToolPipette::getInstance()->setResult(TRUE, ""); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { // tes have no data about material ids // Plus gltf materials are layered with overrides, @@ -1807,7 +1828,8 @@ void LLTextureCtrl::showPicker(BOOL take_focus) mImmediateFilterPermMask, mDnDFilterPermMask, mCanApplyImmediately, - mFallbackImage); + mFallbackImage, + mInventoryPickType); mFloaterHandle = floaterp->getHandle(); LLFloaterTexturePicker* texture_floaterp = dynamic_cast(floaterp); @@ -1828,7 +1850,6 @@ void LLTextureCtrl::showPicker(BOOL take_focus) texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled); - texture_floaterp->setInventoryPickType(mInventoryPickType); } LLFloater* root_floater = gFloaterView->getParentFloater(this); @@ -1891,7 +1912,7 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) if (!mOpenTexPreview) { showPicker(FALSE); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { //grab materials first... LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL)); @@ -2089,11 +2110,11 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, bool is_material = cargo_type == DAD_MATERIAL; bool allow_dnd = false; - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { allow_dnd = is_material; } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == PICK_TEXTURE) { allow_dnd = is_texture || is_mesh; } @@ -2156,7 +2177,7 @@ void LLTextureCtrl::draw() if (texture.isNull()) { - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + if (mInventoryPickType == PICK_MATERIAL) { LLPointer material = gGLTFMaterialList.getMaterial(mImageAssetID); if (material) @@ -2313,7 +2334,7 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item) // no callback installed, so just set the image ids and carry on. LLUUID asset_id = item->getAssetUUID(); - if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL && asset_id.isNull()) + if (mInventoryPickType == PICK_MATERIAL && asset_id.isNull()) { // If an inventory material has a null asset, consider it a valid blank material(gltf) asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID; diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 7a96eea60d..cb6ce636e0 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -72,6 +72,13 @@ enum LLPickerSource PICKER_UNKNOWN, // on cancel, default ids }; +typedef enum e_pick_inventory_type +{ + PICK_TEXTURE_MATERIAL = 0, + PICK_TEXTURE = 1, + PICK_MATERIAL = 2, +} EPickInventoryType; + ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl @@ -87,13 +94,6 @@ public: TEXTURE_CANCEL } ETexturePickOp; - typedef enum e_pick_inventory_type - { - PICK_TEXTURE_MATERIAL = 0, - PICK_TEXTURE = 1, - PICK_MATERIAL = 2, - } EPickInventoryType; - public: struct Params : public LLInitParam::Block { @@ -276,7 +276,7 @@ private: S32 mLabelWidth; bool mOpenTexPreview; bool mBakeTextureEnabled; - LLTextureCtrl::EPickInventoryType mInventoryPickType; + EPickInventoryType mInventoryPickType; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -300,8 +300,8 @@ public: PermissionMask immediate_filter_perm_mask, PermissionMask dnd_filter_perm_mask, BOOL can_apply_immediately, - LLUIImagePtr fallback_image_name - ); + LLUIImagePtr fallback_image_name, + EPickInventoryType pick_type); virtual ~LLFloaterTexturePicker(); @@ -369,7 +369,7 @@ public: void setLocalTextureEnabled(BOOL enabled); void setBakeTextureEnabled(BOOL enabled); - void setInventoryPickType(LLTextureCtrl::EPickInventoryType type); + void setInventoryPickType(EPickInventoryType type); void setImmediateFilterPermMask(PermissionMask mask); static void onPickerCallback(const std::vector& filenames, LLHandle handle); @@ -428,7 +428,7 @@ private: bool mLimitsSet; S32 mMaxDim; S32 mMinDim; - LLTextureCtrl::EPickInventoryType mInventoryPickType; + EPickInventoryType mInventoryPickType; texture_selected_callback mTextureSelectedCallback; -- cgit v1.2.3 From fab4cfbab26948fbec9015bd2ba1e8b05c3cd9e3 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 10 Jan 2024 13:50:15 -0600 Subject: SL-20704 Fix for pathfinding debug display not working. --- autobuild.xml | 1542 ++++++++++++++++++------------------ indra/llrender/llrendernavprim.cpp | 10 +- 2 files changed, 783 insertions(+), 769 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 0e5a5a2a25..6098b4ffdf 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1,14 +1,20 @@ - version - 1.3 - type - autobuild installables SDL + copyright + Copyright (C) 1997-2012 Sam Lantinga + description + Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. + license + lgpl + license_file + LICENSES/SDL.txt + name + SDL platforms linux64 @@ -24,21 +30,21 @@ linux64 - license - lgpl - license_file - LICENSES/SDL.txt - copyright - Copyright (C) 1997-2012 Sam Lantinga version 1.2.15 - name - SDL - description - Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. apr_suite + copyright + Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. + description + Apache portable runtime project + license + apache + license_file + LICENSES/apr_suite.txt + name + apr_suite platforms darwin64 @@ -82,21 +88,21 @@ windows64 - license - apache - license_file - LICENSES/apr_suite.txt - copyright - Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. version 1.7.2-e935465 - name - apr_suite - description - Apache portable runtime project boost + copyright + (see individual source files) + description + Boost C++ Libraries + license + boost 1.0 + license_file + LICENSES/boost.txt + name + boost platforms darwin64 @@ -140,21 +146,21 @@ windows64 - license - boost 1.0 - license_file - LICENSES/boost.txt - copyright - (see individual source files) version 1.81 - name - boost - description - Boost C++ Libraries bugsplat + copyright + Copyright 2003-2017, BugSplat + description + Bugsplat crash reporting package + license + Proprietary + license_file + LICENSES/BUGSPLAT_LICENSE.txt + name + bugsplat platforms darwin64 @@ -186,21 +192,19 @@ windows64 - license - Proprietary - license_file - LICENSES/BUGSPLAT_LICENSE.txt - copyright - Copyright 2003-2017, BugSplat version 4.0.3.0-527603a - name - bugsplat - description - Bugsplat crash reporting package colladadom + copyright + Copyright 2006 Sony Computer Entertainment Inc. + license + SCEA + license_file + LICENSES/collada.txt + name + colladadom platforms darwin64 @@ -244,19 +248,19 @@ windows64 - license - SCEA - license_file - LICENSES/collada.txt - copyright - Copyright 2006 Sony Computer Entertainment Inc. version 2.3.d1ef72a - name - colladadom cubemaptoequirectangular + copyright + Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com + license + MIT + license_file + LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt + name + cubemaptoequirectangular platforms darwin64 @@ -300,19 +304,21 @@ windows64 - license - MIT - license_file - LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt - copyright - Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com version 1.1.0 - name - cubemaptoequirectangular curl + copyright + Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se). + description + Library for transferring data specified with URL syntax + license + curl + license_file + LICENSES/curl.txt + name + curl platforms darwin64 @@ -356,21 +362,21 @@ windows64 - license - curl - license_file - LICENSES/curl.txt - copyright - Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se). version 7.54.1-5a4a82d - name - curl - description - Library for transferring data specified with URL syntax dbus_glib + copyright + Copyright (C) Red Hat Inc. + description + D-Bus bindings for glib + license + Academic Free License v. 2.1 + license_file + LICENSES/dbus-glib.txt + name + dbus_glib platforms linux64 @@ -386,21 +392,21 @@ linux64 - license - Academic Free License v. 2.1 - license_file - LICENSES/dbus-glib.txt - copyright - Copyright (C) Red Hat Inc. version 0.76 - name - dbus_glib - description - D-Bus bindings for glib dictionaries + copyright + Copyright 2014 Apache OpenOffice software + description + Spell checking dictionaries to bundled into the viewer + license + various open source + license_file + LICENSES/dictionaries.txt + name + dictionaries platforms common @@ -418,21 +424,21 @@ common - license - various open source - license_file - LICENSES/dictionaries.txt - copyright - Copyright 2014 Apache OpenOffice software version None - name - dictionaries - description - Spell checking dictionaries to bundled into the viewer dullahan + copyright + Copyright (c) 2017, Linden Research, Inc. + description + A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. + license + MPL + license_file + LICENSES/LICENSE.txt + name + dullahan platforms darwin64 @@ -464,21 +470,21 @@ windows64 - license - MPL - license_file - LICENSES/LICENSE.txt - copyright - Copyright (c) 2017, Linden Research, Inc. version 1.14.0.202310131404_118.4.1_g3dd6078_chromium-118.0.5993.54 - name - dullahan - description - A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. expat + copyright + Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. + description + Expat is an XML parser library written in C + license + expat + license_file + LICENSES/expat.txt + name + expat platforms darwin64 @@ -524,21 +530,21 @@ windows64 - license - expat - license_file - LICENSES/expat.txt - copyright - Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. version 2.1.1.1f36d02 - name - expat - description - Expat is an XML parser library written in C fmodstudio + copyright + FMOD Studio by Firelight Technologies Pty Ltd. + description + FMOD Studio API + license + fmod + license_file + LICENSES/fmodstudio.txt + name + fmodstudio platforms darwin64 @@ -590,21 +596,21 @@ windows64 - license - fmod - license_file - LICENSES/fmodstudio.txt - copyright - FMOD Studio by Firelight Technologies Pty Ltd. version 2.02.13.578928 - name - fmodstudio - description - FMOD Studio API fontconfig + copyright + Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc. + description + Fontconfig is a library for configuring and customizing font access. + license + bsd + license_file + LICENSES/fontconfig.txt + name + fontconfig platforms linux64 @@ -620,21 +626,21 @@ linux64 - license - bsd - license_file - LICENSES/fontconfig.txt - copyright - Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc. version 2.11.0 - name - fontconfig - description - Fontconfig is a library for configuring and customizing font access. freetype + copyright + Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. + description + Font rendering library + license + FreeType + license_file + LICENSES/freetype.txt + name + freetype platforms darwin64 @@ -680,21 +686,21 @@ windows64 - license - FreeType - license_file - LICENSES/freetype.txt - copyright - Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. version 2.4.4.4f739fa - name - freetype - description - Font rendering library glext + copyright + Copyright (c) 2007-2010 The Khronos Group Inc. + description + glext headers define function prototypes and constants for OpenGL extensions + license + Copyright (c) 2007-2010 The Khronos Group Inc. + license_file + LICENSES/glext.txt + name + glext platforms common @@ -712,21 +718,21 @@ common - license - Copyright (c) 2007-2010 The Khronos Group Inc. - license_file - LICENSES/glext.txt - copyright - Copyright (c) 2007-2010 The Khronos Group Inc. version 68 - name - glext - description - glext headers define function prototypes and constants for OpenGL extensions glh_linear + copyright + Copyright (c) 2000 Cass Everitt + description + glh - is a platform-indepenedent C++ OpenGL helper library + license + BSD + license_file + LICENSES/glh-linear.txt + name + glh_linear platforms common @@ -744,21 +750,21 @@ common - license - BSD - license_file - LICENSES/glh-linear.txt - copyright - Copyright (c) 2000 Cass Everitt version None - name - glh_linear - description - glh - is a platform-indepenedent C++ OpenGL helper library googlemock + copyright + Copyright 2008, Google Inc. + description + a library for writing and using C++ mock classes + license + BSD + license_file + LICENSES/gmock.txt + name + googlemock platforms darwin64 @@ -802,21 +808,19 @@ windows64 - license - BSD - license_file - LICENSES/gmock.txt - copyright - Copyright 2008, Google Inc. version 1.7.0.77bba00 - name - googlemock - description - a library for writing and using C++ mock classes gstreamer + copyright + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + license + LGPL + license_file + LICENSES/gstreamer.txt + name + gstreamer platforms linux64 @@ -832,19 +836,19 @@ linux64 - license - LGPL - license_file - LICENSES/gstreamer.txt - copyright - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> version 0.10.6.314267 - name - gstreamer gtk-atk-pango-glib + copyright + Copyright (various, see sources) + license + lgpl + license_file + LICENSES/gtk-atk-pango-glib.txt + name + gtk-atk-pango-glib platforms linux64 @@ -860,19 +864,21 @@ linux64 - license - lgpl - license_file - LICENSES/gtk-atk-pango-glib.txt - copyright - Copyright (various, see sources) version 0.1 - name - gtk-atk-pango-glib havok-source + copyright + Uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. + description + Havok source code for libs and demos + license + havok + license_file + LICENSES/havok.txt + name + havok-source platforms darwin64 @@ -920,21 +926,19 @@ windows64 - license - havok - license_file - LICENSES/havok.txt - copyright - Uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. version 2012.1-2 - name - havok-source - description - Havok source code for libs and demos jpegencoderbasic + copyright + Andreas Ritter, www.bytestrom.eu, 11/2009 + license + NONE + license_file + LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt + name + jpegencoderbasic platforms darwin64 @@ -978,19 +982,21 @@ windows64 - license - NONE - license_file - LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt - copyright - Andreas Ritter, www.bytestrom.eu, 11/2009 version 1.0 - name - jpegencoderbasic jpeglib + copyright + Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding. + description + JPEG encoding, decoding library + license + jpeglib + license_file + LICENSES/jpeglib.txt + name + jpeglib platforms darwin64 @@ -1036,21 +1042,21 @@ windows64 - license - jpeglib - license_file - LICENSES/jpeglib.txt - copyright - Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding. version 8c.7846234 - name - jpeglib - description - JPEG encoding, decoding library jsoncpp + copyright + Copyright (c) 2007-2010 Baptiste Lepilleur + description + jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++. + license + public domain + license_file + LICENSES/jsoncpp.txt + name + jsoncpp platforms darwin64 @@ -1096,21 +1102,21 @@ windows64 - license - public domain - license_file - LICENSES/jsoncpp.txt - copyright - Copyright (c) 2007-2010 Baptiste Lepilleur version 0.5.0.bc46e62 - name - jsoncpp - description - jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++. kdu + copyright + Kakadu software + description + JPEG2000 library by Kakadu + license + Kakadu + license_file + LICENSES/kdu.txt + name + kdu platforms darwin64 @@ -1162,21 +1168,21 @@ windows64 - license - Kakadu - license_file - LICENSES/kdu.txt - copyright - Kakadu software version 7.10.4.539108 - name - kdu - description - JPEG2000 library by Kakadu libhunspell + copyright + See hunspell.txt + description + Spell checking library + license + LGPL + license_file + LICENSES/hunspell.txt + name + libhunspell platforms darwin64 @@ -1222,21 +1228,21 @@ windows64 - license - LGPL - license_file - LICENSES/hunspell.txt - copyright - See hunspell.txt version 1.3.2.650fb94 - name - libhunspell - description - Spell checking library libndofdev + copyright + Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved. + description + 3DConnexion SDK + license + BSD + license_file + LICENSES/libndofdev.txt + name + libndofdev platforms darwin64 @@ -1268,29 +1274,29 @@ windows64 - license - BSD - license_file - LICENSES/libndofdev.txt - copyright - Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved. version 0.1.8e9edc7 - name - libndofdev - description - 3DConnexion SDK libpng - platforms - - darwin64 - - archive - - hash - fea8f0684a4ed0a73343651948b13049a135a92a + copyright + Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson + description + PNG Reference library + license + libpng + license_file + LICENSES/libpng.txt + name + libpng + platforms + + darwin64 + + archive + + hash + fea8f0684a4ed0a73343651948b13049a135a92a hash_algorithm sha1 url @@ -1326,21 +1332,21 @@ windows64 - license - libpng - license_file - LICENSES/libpng.txt - copyright - Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson version 1.6.38-ca06e99 - name - libpng - description - PNG Reference library libuuid + copyright + Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/> + description + OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). + license + UUID + license_file + LICENSES/uuid.txt + name + libuuid platforms linux64 @@ -1356,21 +1362,21 @@ linux64 - license - UUID - license_file - LICENSES/uuid.txt - copyright - Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/> version 1.6.2 - name - libuuid - description - OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). libxml2 + copyright + Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. + description + Libxml2 is the XML C parser and toolkit developed for the Gnome project. + license + mit + license_file + LICENSES/libxml2.txt + name + libxml2 platforms darwin64 @@ -1416,21 +1422,21 @@ windows64 - license - mit - license_file - LICENSES/libxml2.txt - copyright - Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. version 2.9.4.7476681 - name - libxml2 - description - Libxml2 is the XML C parser and toolkit developed for the Gnome project. llappearance_utility + copyright + Copyright (c) 2000-2012, Linden Research, Inc. + description + Linden Lab appearance utility for server-side avatar baking services. + license + Proprietary + license_file + LICENSES/llappearanceutility.txt + name + llappearance_utility platforms linux @@ -1446,21 +1452,20 @@ linux - license - Proprietary - license_file - LICENSES/llappearanceutility.txt - copyright - Copyright (c) 2000-2012, Linden Research, Inc. version 0.0.1 - name - llappearance_utility - description - Linden Lab appearance utility for server-side avatar baking services. llca + copyright + Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project. + + license + mit + license_file + LICENSES/ca-license.txt + name + llca platforms common @@ -1478,20 +1483,19 @@ common - license - mit - license_file - LICENSES/ca-license.txt - copyright - Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project. - version 202310121530.0 - name - llca llphysicsextensions_source + copyright + Copyright (c) 2010, Linden Research, Inc. + license + internal + license_file + LICENSES/llphysicsextensions.txt + name + llphysicsextensions_source platforms darwin64 @@ -1501,11 +1505,11 @@ creds github hash - 48bca5d0233d1e724a59f649a2c6c7ac5f40ec3c + b037cc0b29ea70ee834cfae6dda5b7a25cd57174 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009335 + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851460 name darwin64 @@ -1517,15 +1521,31 @@ creds github hash - 39f52d0350e130f41c5c758f7cb94e87b962c223 + bdea1fd5c4da9da5afde088d16188b45d0853e04 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009336 + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851461 name linux64 + windows + + archive + + creds + github + hash + 2e6a66da6071253ae888839cfab59d3f5c1b8b4c + hash_algorithm + sha1 + url + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851462 + + name + windows + windows64 archive @@ -1533,29 +1553,29 @@ creds github hash - 7b5e645fb7eb399abbea63bd21e8063bbb32a911 + f652ce0d6aef864689f0ed44255da4d9cd65a43f hash_algorithm sha1 url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009339 + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851463 name windows64 + version + 1.0.479d20a + + llphysicsextensions_stub + + copyright + Copyright (c) 2010, Linden Research, Inc. license internal license_file LICENSES/llphysicsextensions.txt - copyright - Copyright (c) 2010, Linden Research, Inc. - version - 1.0.565768 name - llphysicsextensions_source - - llphysicsextensions_stub - + llphysicsextensions_stub platforms darwin64 @@ -1595,19 +1615,19 @@ windows - license - internal - license_file - LICENSES/llphysicsextensions.txt - copyright - Copyright (c) 2010, Linden Research, Inc. version 1.0.542456 - name - llphysicsextensions_stub llphysicsextensions_tpv + copyright + Copyright (c) 2010, Linden Research, Inc. + license + internal + license_file + LICENSES/HavokSublicense.pdf + name + llphysicsextensions_tpv platforms darwin64 @@ -1647,19 +1667,17 @@ windows - license - internal - license_file - LICENSES/HavokSublicense.pdf - copyright - Copyright (c) 2010, Linden Research, Inc. version 1.0.561752 - name - llphysicsextensions_tpv mesa + license + mesa + license_file + LICENSES/mesa.txt + name + mesa platforms linux @@ -1675,17 +1693,23 @@ linux - license - mesa - license_file - LICENSES/mesa.txt version 7.11.1.297294 - name - mesa meshoptimizer + canonical_repo + https://bitbucket.org/lindenlab/3p-meshoptimizer + copyright + Copyright (c) 2016-2021 Arseny Kapoulkine + description + Meshoptimizer. Mesh optimization library. + license + meshoptimizer + license_file + LICENSES/meshoptimizer.txt + name + meshoptimizer platforms darwin64 @@ -1717,20 +1741,8 @@ windows64 - license - meshoptimizer - license_file - LICENSES/meshoptimizer.txt - copyright - Copyright (c) 2016-2021 Arseny Kapoulkine version 160 - name - meshoptimizer - canonical_repo - https://bitbucket.org/lindenlab/3p-meshoptimizer - description - Meshoptimizer. Mesh optimization library. mikktspace @@ -1790,6 +1802,18 @@ minizip-ng + canonical_repo + https://bitbucket.org/lindenlab/3p-minizip-ng + copyright + This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + description + minizip-ng is a zip manipulation library. Based on work of Gilles Vollant. + license + minizip-ng + license_file + LICENSES/minizip-ng.txt + name + minizip-ng platforms darwin64 @@ -1835,23 +1859,22 @@ windows64 - license - minizip-ng - license_file - LICENSES/minizip-ng.txt - copyright - This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler version 3.0.2.3e9876e - name - minizip-ng - canonical_repo - https://bitbucket.org/lindenlab/3p-minizip-ng - description - minizip-ng is a zip manipulation library. Based on work of Gilles Vollant. nghttp2 + copyright + Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa +Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors + description + Library providing HTTP 2 support for libcurl + license + MIT + license_file + LICENSES/nghttp2.txt + name + nghttp2 platforms darwin64 @@ -1897,28 +1920,27 @@ windows64 - license - MIT - license_file - LICENSES/nghttp2.txt - copyright - Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa -Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors - version - 1.40.0.b1526c6 - name - nghttp2 - description - Library providing HTTP 2 support for libcurl source_type hg + version + 1.40.0.b1526c6 nvapi - platforms - - windows64 - + copyright + Copyright © 2012 NVIDIA Corporation. All rights reserved. + description + NVAPI provides an interface to NVIDIA devices. + license + NVIDIA Corporation Software License Agreement – NVAPI SDK + license_file + LICENSES/NVAPI_SDK_License_Agreement.pdf + name + nvapi + platforms + + windows64 + archive hash @@ -1932,21 +1954,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - NVIDIA Corporation Software License Agreement – NVAPI SDK - license_file - LICENSES/NVAPI_SDK_License_Agreement.pdf - copyright - Copyright © 2012 NVIDIA Corporation. All rights reserved. version 352.aac0e19 - name - nvapi - description - NVAPI provides an interface to NVIDIA devices. ogg_vorbis + copyright + Copyright (c) 2002, Xiph.org Foundation + description + Audio encoding library + license + ogg-vorbis + license_file + LICENSES/ogg-vorbis.txt + name + ogg_vorbis platforms darwin64 @@ -1990,96 +2012,96 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - ogg-vorbis - license_file - LICENSES/ogg-vorbis.txt - copyright - Copyright (c) 2002, Xiph.org Foundation version 1.3.3-1.3.6.e4101b6 - name - ogg_vorbis - description - Audio encoding library open-libndofdev + copyright + Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) + description + Open Source replacement for 3DConnection SDK license BSD license_file LICENSES/libndofdev.txt - copyright - Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) - version - 0.3 name open-libndofdev - description - Open Source replacement for 3DConnection SDK + version + 0.3 openal + copyright + Copyright (C) 1999-2007 by authors. + description + OpenAL Soft is a software implementation of the OpenAL 3D audio API. + license + LGPL2 + license_file + LICENSES/openal-soft.txt + name + openal platforms - linux64 + darwin64 archive hash - e0fbc4874acc4167a6e2b6489fbb8258d98fd665 + 4edaef5f03a1122eae8467c4a04d9caccaaaf847 hash_algorithm sha1 url - https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-linux64-18e315c.tar.zst + https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-darwin64-18e315c.tar.zst name - linux64 + darwin64 - windows64 + linux64 archive hash - 6ae3b5310eb1988741bc55416681ca9d64f76f85 + e0fbc4874acc4167a6e2b6489fbb8258d98fd665 hash_algorithm sha1 url - https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-windows64-18e315c.tar.zst + https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-linux64-18e315c.tar.zst name - windows64 + linux64 - darwin64 + windows64 archive hash - 4edaef5f03a1122eae8467c4a04d9caccaaaf847 + 6ae3b5310eb1988741bc55416681ca9d64f76f85 hash_algorithm sha1 url - https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-darwin64-18e315c.tar.zst + https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-windows64-18e315c.tar.zst name - darwin64 + windows64 - license - LGPL2 - license_file - LICENSES/openal-soft.txt - copyright - Copyright (C) 1999-2007 by authors. version 1.23.1 - name - openal - description - OpenAL Soft is a software implementation of the OpenAL 3D audio API. openjpeg + copyright + Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France; + description + The OpenJPEG library is an open-source JPEG 2000 codec written in C language. + license + BSD + license_file + LICENSES/openjpeg.txt + name + openjpeg platforms darwin64 @@ -2125,21 +2147,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - BSD - license_file - LICENSES/openjpeg.txt - copyright - Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France; version 2.5.0.ea12248 - name - openjpeg - description - The OpenJPEG library is an open-source JPEG 2000 codec written in C language. openssl + copyright + Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + description + Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library + license + openssl + license_file + LICENSES/openssl.txt + name + openssl platforms darwin64 @@ -2185,21 +2207,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - openssl - license_file - LICENSES/openssl.txt - copyright - Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) version 1.1.1q.de53f55 - name - openssl - description - Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library pcre + copyright + Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc. + description + PCRE Perl-compatible regular expression library + license + bsd + license_file + LICENSES/pcre-license.txt + name + pcre platforms darwin64 @@ -2243,21 +2265,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - bsd - license_file - LICENSES/pcre-license.txt - copyright - Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc. version 8.35.979fd86 - name - pcre - description - PCRE Perl-compatible regular expression library slvoice + copyright + 2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C) + description + Vivox SDK components + license + Mixed + license_file + LICENSES/vivox_licenses.txt + name + slvoice platforms darwin64 @@ -2305,21 +2327,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - Mixed - license_file - LICENSES/vivox_licenses.txt - copyright - 2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C) version 4.10.0000.32327.5fc3fe7c.571099 - name - slvoice - description - Vivox SDK components threejs + copyright + Copyright © 2010-2021 three.js authors + license + MIT + license_file + LICENSES/THREEJS_LICENSE.txt + name + threejs platforms darwin64 @@ -2363,16 +2383,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - MIT - license_file - LICENSES/THREEJS_LICENSE.txt - copyright - Copyright © 2010-2021 three.js authors version 0.132.2 - name - threejs tinygltf @@ -2412,6 +2424,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors tracy + canonical_repo + https://bitbucket.org/lindenlab/3p-tracy + copyright + Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl) + description + Tracy Profiler Library + license + bsd + license_file + LICENSES/tracy_license.txt + name + tracy platforms darwin64 @@ -2441,20 +2465,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - bsd - license_file - LICENSES/tracy_license.txt - copyright - Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl) - version - v0.8.1.235e98f - name - tracy - canonical_repo - https://bitbucket.org/lindenlab/3p-tracy - description - Tracy Profiler Library source https://bitbucket.org/lindenlab/3p-tracy source_type @@ -2464,6 +2474,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors tut + copyright + Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008-2009 Michał Rzechonek + description + TUT is a small and portable unit test framework for C++. + license + bsd + license_file + LICENSES/tut.txt + name + tut platforms common @@ -2481,21 +2501,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors common - license - bsd - license_file - LICENSES/tut.txt - copyright - Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008-2009 Michał Rzechonek version 2008.11.30 - name - tut - description - TUT is a small and portable unit test framework for C++. uriparser + copyright + Copyright (C) 2007, Weijia Song <songweijia@gmail.com>, Sebastian Pipping <webmaster@hartwork.org> + description + uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license. + license + New BSD license + license_file + LICENSES/uriparser.txt + name + uriparser platforms darwin64 @@ -2541,21 +2561,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - New BSD license - license_file - LICENSES/uriparser.txt - copyright - Copyright (C) 2007, Weijia Song <songweijia@gmail.com>, Sebastian Pipping <webmaster@hartwork.org> version 0.9.4 - name - uriparser - description - uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license. viewer-manager + copyright + Copyright (c) 2000-2012, Linden Research, Inc. + description + Linden Lab Viewer Management Process suite. + license + viewerlgpl + license_file + LICENSE + name + viewer-manager platforms darwin64 @@ -2601,25 +2621,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - viewerlgpl - license_file - LICENSE - copyright - Copyright (c) 2000-2012, Linden Research, Inc. - version - 3.0-08bf5ee - name - viewer-manager - description - Linden Lab Viewer Management Process suite. source https://bitbucket.org/lindenlab/vmp-standalone source_type hg + version + 3.0-08bf5ee vlc-bin + copyright + Copyright (C) 1998-2016 VLC authors and VideoLAN + license + GPL2 + license_file + LICENSES/vlc.txt + name + vlc-bin platforms darwin64 @@ -2651,19 +2669,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - GPL2 - license_file - LICENSES/vlc.txt - copyright - Copyright (C) 1998-2016 VLC authors and VideoLAN version 3.0.16.c219a5d - name - vlc-bin - xmlrpc-epi + vulkan_gltf + canonical_repo + https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr + copyright + Copyright (c) 2018 Sascha Willems + description + Vulkan GLTF Sample Implementation + license + Copyright (c) 2018 Sascha Willems + license_file + LICENSES/vulkan_gltf.txt + name + vulkan_gltf platforms darwin64 @@ -2671,71 +2693,53 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - aa12611374876196b3ebb6bda8d419a697217b8b - hash_algorithm - sha1 + 8cff2060843db3db788511ee34a8e8cc url - https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2 name darwin64 - linux64 + windows archive hash - ad0c8b41ee4b4de216382bec46ee1c25962a3f12 - hash_algorithm - sha1 + 58eea384be49ba756ce9c5e66669540b url - https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-linux64-8a05acf.tar.zst + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2 name - linux64 + windows windows64 archive hash - e53fd38c14b8c47c7c84dead8a1b211bb8be170c - hash_algorithm - sha1 + 79b6a11622c2f83cfc2b7cd1fafb867b url - https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-windows64-8a05acf.tar.zst + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2 name windows64 - license - xmlrpc-epi - license_file - LICENSES/xmlrpc-epi.txt - copyright - Copyright: (C) 2000 Epinions, Inc. version - 0.54.1.8a05acf - name - xmlrpc-epi - description - XMLRPC Library + 1 - vulkan_gltf + xmlrpc-epi - canonical_repo - https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr copyright - Copyright (c) 2018 Sascha Willems + Copyright: (C) 2000 Epinions, Inc. description - Vulkan GLTF Sample Implementation + XMLRPC Library license - Copyright (c) 2018 Sascha Willems + xmlrpc-epi license_file - LICENSES/vulkan_gltf.txt + LICENSES/xmlrpc-epi.txt name - vulkan_gltf + xmlrpc-epi platforms darwin64 @@ -2743,43 +2747,59 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 8cff2060843db3db788511ee34a8e8cc + aa12611374876196b3ebb6bda8d419a697217b8b + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2 + https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst name darwin64 - windows + linux64 archive hash - 58eea384be49ba756ce9c5e66669540b + ad0c8b41ee4b4de216382bec46ee1c25962a3f12 + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2 + https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-linux64-8a05acf.tar.zst name - windows + linux64 windows64 archive hash - 79b6a11622c2f83cfc2b7cd1fafb867b + e53fd38c14b8c47c7c84dead8a1b211bb8be170c + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2 + https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-windows64-8a05acf.tar.zst name windows64 version - 1 + 0.54.1.8a05acf xxhash + copyright + Copyright (c) 2012-2021 Yann Collet + description + xxHash Library + license + xxhash + license_file + LICENSES/xxhash.txt + name + xxhash platforms common @@ -2837,21 +2857,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - xxhash - license_file - LICENSES/xxhash.txt - copyright - Copyright (c) 2012-2021 Yann Collet version 0.8.1.7501c90 - name - xxhash - description - xxHash Library zlib-ng + canonical_repo + https://bitbucket.org/lindenlab/3p-zlib-ng + copyright + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + description + zlib data compression library for the next generation systems + license + zlib-ng + license_file + LICENSES/zlib-ng.txt + name + zlib-ng platforms darwin64 @@ -2897,24 +2919,24 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - license - zlib-ng - license_file - LICENSES/zlib-ng.txt - copyright - Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler version 1.2.11.zlib-ng.32fd361 - name - zlib-ng - canonical_repo - https://bitbucket.org/lindenlab/3p-zlib-ng - description - zlib data compression library for the next generation systems package_description + canonical_repo + https://github.com/secondlife/viewer + copyright + Copyright (c) 2020, Linden Research, Inc. + description + Second Life Viewer + license + LGPL + license_file + docs/LICENSE-source.txt + name + Second Life Viewer platforms common @@ -2923,6 +2945,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors RelWithDebInfo + build + + configure command @@ -2933,10 +2958,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=TRUE - - - build - + name RelWithDebInfo @@ -2945,6 +2967,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors configure + arguments + + ../indra + command cmake options @@ -2953,17 +2979,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=FALSE - - arguments - - ../indra - + name RelWithDebInfoOS Release + build + + configure command @@ -2974,10 +2999,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=TRUE - - - build - + name Release @@ -2986,6 +3008,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors configure + arguments + + ../indra + command cmake options @@ -2994,11 +3020,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=FALSE - - arguments - - ../indra - + name ReleaseOS @@ -3009,22 +3031,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors darwin64 + build_directory + build-darwin-x86_64 configurations RelWithDebInfo - configure - - options - - -G - Xcode - - arguments - - ../indra - - build command @@ -3036,23 +3048,27 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - + - default - True - name - RelWithDebInfo - - RelWithDebInfoOS - configure + arguments + + ../indra + options -G Xcode - + + default + True + name + RelWithDebInfo + + RelWithDebInfoOS + build command @@ -3064,25 +3080,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - + - name - RelWithDebInfoOS - - Release - configure options -G Xcode - - arguments - - ../indra - + + name + RelWithDebInfoOS + + Release + build command @@ -3094,21 +3106,25 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - + - name - Release - - ReleaseOS - configure + arguments + + ../indra + options -G Xcode - + + name + Release + + ReleaseOS + build command @@ -3120,40 +3136,48 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - + + + configure + + options + + -G + Xcode + name ReleaseOS - build_directory - build-darwin-x86_64 name darwin64 linux64 + build_directory + build-linux-x86_64 configurations Release + build + + command + ninja + configure + arguments + + ../indra + options -G Ninja -DLL_TESTS=Off - - arguments - - ../indra - - - build - - command - ninja + default True @@ -3162,6 +3186,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors ReleaseOS + build + + command + ninja + configure options @@ -3169,12 +3198,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -G Ninja -DLL_TESTS=Off - - - build - - command - ninja + name ReleaseOS @@ -3188,44 +3212,44 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors default - build_directory - build-linux-x86_64 name linux64 windows + build_directory + build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE configurations RelWithDebInfo - configure + build - options - - -G - ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} - -A - ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - arguments - ..\indra - - - build - + SecondLife.sln + command devenv options /build RelWithDebInfo|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - + + + configure + arguments - SecondLife.sln - + ..\indra + + options + + -G + ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} + -A + ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} + default True @@ -3234,25 +3258,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors RelWithDebInfoOS - configure + build - options - - -G - ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} - -A - ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - -DINSTALL_PROPRIETARY=FALSE - -DUSE_KDU=FALSE - -DUSE_OPENAL:BOOL=ON - arguments - ..\indra - - - build - + SecondLife.sln + command msbuild.exe options @@ -3263,70 +3274,69 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors /p:useenv=true /verbosity:minimal /p:VCBuildAdditionalOptions= /incremental - - arguments - - SecondLife.sln - + - name - RelWithDebInfoOS - - Release - configure + arguments + + ..\indra + options -G ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} -A ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - - arguments - - ..\indra - + -DINSTALL_PROPRIETARY=FALSE + -DUSE_KDU=FALSE + -DUSE_OPENAL:BOOL=ON + + name + RelWithDebInfoOS + + Release + build + arguments + + SecondLife.sln + command devenv options /build Release|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - - arguments - - SecondLife.sln - + - name - Release - - ReleaseOS - configure + arguments + + ..\indra + options -G ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} -A ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - -DUNATTENDED:BOOL=ON - -DINSTALL_PROPRIETARY=FALSE - -DUSE_KDU=FALSE - -DUSE_OPENAL:BOOL=ON - - arguments - - ..\indra - + + name + Release + + ReleaseOS + build + arguments + + SecondLife.sln + command msbuild.exe options @@ -3337,36 +3347,40 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors /p:useenv=true /verbosity:minimal /p:VCBuildAdditionalOptions= /incremental - + + + configure + arguments - SecondLife.sln - + ..\indra + + options + + -G + ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} + -A + ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} + -DUNATTENDED:BOOL=ON + -DINSTALL_PROPRIETARY=FALSE + -DUSE_KDU=FALSE + -DUSE_OPENAL:BOOL=ON + name ReleaseOS - build_directory - build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE name windows - license - LGPL - license_file - docs/LICENSE-source.txt - copyright - Copyright (c) 2020, Linden Research, Inc. version_file newview/viewer_version.txt - name - Second Life Viewer - canonical_repo - https://github.com/secondlife/viewer - description - Second Life Viewer + type + autobuild + version + 1.3 diff --git a/indra/llrender/llrendernavprim.cpp b/indra/llrender/llrendernavprim.cpp index d610a44bc6..eea3077632 100644 --- a/indra/llrender/llrendernavprim.cpp +++ b/indra/llrender/llrendernavprim.cpp @@ -40,20 +40,20 @@ LLRenderNavPrim gRenderNav; //============================================================================= void LLRenderNavPrim::renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const { - LLColor4 cV(color); - gGL.color4fv( cV.mV ); - gGL.begin(LLRender::TRIANGLES); + gGL.color4ubv(color.mV); + + gGL.begin(LLRender::TRIANGLES); { gGL.vertex3fv( a.mV ); gGL.vertex3fv( b.mV ); gGL.vertex3fv( c.mV ); } - gGL.end(); + gGL.end(); } //============================================================================= void LLRenderNavPrim::renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt ) { pVBO->setBuffer(); - pVBO->drawArrays( mode, 0, vertCnt ); + pVBO->drawArrays( mode, 0, vertCnt ); } //============================================================================= -- cgit v1.2.3 From 577706eddc22cd750c11e2110c79b7ead85e6005 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 12 Jan 2024 00:20:46 +0200 Subject: SL-20629 Fix first opened legacy env displaying probe ambience as '1' --- indra/newview/llenvironment.cpp | 8 ++++++++ indra/newview/llsettingsvo.cpp | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index ffaca846dd..60c2682078 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -895,6 +895,14 @@ void LLEnvironment::initSingleton() gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler); } + gSavedSettings.getControl("RenderSkyAutoAdjustProbeAmbiance")->getSignal()->connect( + [](LLControlVariable*, const LLSD& new_val, const LLSD& old_val) + { + LLSettingsSky::sAutoAdjustProbeAmbiance = new_val.asReal(); + } + ); + LLSettingsSky::sAutoAdjustProbeAmbiance = gSavedSettings.getF32("RenderSkyAutoAdjustProbeAmbiance"); + LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME); LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; }); } diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 7009fb98ab..c07c939862 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -739,7 +739,6 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) static LLCachedControl auto_adjust_blue_horizon_scale(gSavedSettings, "RenderSkyAutoAdjustBlueHorizonScale", 1.f); static LLCachedControl auto_adjust_blue_density_scale(gSavedSettings, "RenderSkyAutoAdjustBlueDensityScale", 1.f); static LLCachedControl auto_adjust_sun_color_scale(gSavedSettings, "RenderSkyAutoAdjustSunColorScale", 1.f); - static LLCachedControl auto_adjust_probe_ambiance(gSavedSettings, "RenderSkyAutoAdjustProbeAmbiance", 1.f); static LLCachedControl sunlight_scale(gSavedSettings, "RenderSkySunlightScale", 1.5f); static LLCachedControl ambient_scale(gSavedSettings, "RenderSkyAmbientScale", 1.5f); @@ -772,8 +771,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV); shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV); - LLSettingsSky::sAutoAdjustProbeAmbiance = auto_adjust_probe_ambiance; - probe_ambiance = auto_adjust_probe_ambiance; // NOTE -- must match LLSettingsSky::getReflectionProbeAmbiance value for "auto_adjust" true + probe_ambiance = sAutoAdjustProbeAmbiance; } else { -- cgit v1.2.3 From 2c8532bdc7afa8ff380fbae7c2be8300b5ce8214 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 12 Jan 2024 00:22:47 +0200 Subject: SL-20629 Fix Probe ambiance being displayed as 0 when it isn't And hide warning when it's already 0 --- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llfloatereditextdaycycle.cpp | 4 +++- indra/newview/llfloaterfixedenvironment.cpp | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 00b59f9a4d..8fbeb82d07 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10720,7 +10720,7 @@ Type F32 Value - 0.001 + 0.01 RenderSkySunlightScale diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index bb47feaa95..4e764674e5 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -1724,7 +1724,9 @@ void LLFloaterEditExtDayCycle::showHDRNotification(const LLSettingsDay::ptr_t &p while (iter != end) { LLSettingsSky::ptr_t sky = std::static_pointer_cast(iter->second); - if (sky && sky->canAutoAdjust()) + if (sky + && sky->canAutoAdjust() + && sky->getReflectionProbeAmbiance(true) != 0.f) { LLNotificationsUtil::add("AutoAdjustHDRSky"); return; diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index 8e28fd6234..3e8bad3ef5 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -186,7 +186,8 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p // teach user about HDR settings if (mSettings && mSettings->getSettingsType() == "sky" - && ((LLSettingsSky*)mSettings.get())->canAutoAdjust()) + && ((LLSettingsSky*)mSettings.get())->canAutoAdjust() + && ((LLSettingsSky*)mSettings.get())->getReflectionProbeAmbiance(true) != 0.f) { LLNotificationsUtil::add("AutoAdjustHDRSky"); } -- cgit v1.2.3 From 25d7828bec3e54eeceb76b77fa6b8b1527611bcf Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 12 Jan 2024 12:39:57 -0600 Subject: DRTVWR-601 Fix for Tracy instrumentation (Tracy doesn't play nice with coroutines). --- indra/llcommon/llsingleton.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 51ef514cf7..fba8301c4d 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -455,7 +455,7 @@ public: static DERIVED_TYPE* getInstance() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + //LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; // TODO -- reenable this when we have a fix for using Tracy with coroutines // We know the viewer has LLSingleton dependency circularities. If you // feel strongly motivated to eliminate them, cheers and good luck. // (At that point we could consider a much simpler locking mechanism.) -- cgit v1.2.3 From 0fa6ff2b1f488165c2521ef83e8b78aa2981ac88 Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Tue, 16 Jan 2024 18:08:39 +0100 Subject: Undo re-ordering of autobuild.xml (#638) --- autobuild.xml | 1514 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 750 insertions(+), 764 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6098b4ffdf..8d73bf1fb4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1,20 +1,14 @@ + version + 1.3 + type + autobuild installables SDL - copyright - Copyright (C) 1997-2012 Sam Lantinga - description - Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. - license - lgpl - license_file - LICENSES/SDL.txt - name - SDL platforms linux64 @@ -30,21 +24,21 @@ linux64 + license + lgpl + license_file + LICENSES/SDL.txt + copyright + Copyright (C) 1997-2012 Sam Lantinga version 1.2.15 + name + SDL + description + Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. apr_suite - copyright - Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. - description - Apache portable runtime project - license - apache - license_file - LICENSES/apr_suite.txt - name - apr_suite platforms darwin64 @@ -88,21 +82,21 @@ windows64 + license + apache + license_file + LICENSES/apr_suite.txt + copyright + Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. version 1.7.2-e935465 + name + apr_suite + description + Apache portable runtime project boost - copyright - (see individual source files) - description - Boost C++ Libraries - license - boost 1.0 - license_file - LICENSES/boost.txt - name - boost platforms darwin64 @@ -146,21 +140,21 @@ windows64 + license + boost 1.0 + license_file + LICENSES/boost.txt + copyright + (see individual source files) version 1.81 + name + boost + description + Boost C++ Libraries bugsplat - copyright - Copyright 2003-2017, BugSplat - description - Bugsplat crash reporting package - license - Proprietary - license_file - LICENSES/BUGSPLAT_LICENSE.txt - name - bugsplat platforms darwin64 @@ -192,19 +186,21 @@ windows64 + license + Proprietary + license_file + LICENSES/BUGSPLAT_LICENSE.txt + copyright + Copyright 2003-2017, BugSplat version 4.0.3.0-527603a + name + bugsplat + description + Bugsplat crash reporting package colladadom - copyright - Copyright 2006 Sony Computer Entertainment Inc. - license - SCEA - license_file - LICENSES/collada.txt - name - colladadom platforms darwin64 @@ -248,19 +244,19 @@ windows64 + license + SCEA + license_file + LICENSES/collada.txt + copyright + Copyright 2006 Sony Computer Entertainment Inc. version 2.3.d1ef72a + name + colladadom cubemaptoequirectangular - copyright - Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com - license - MIT - license_file - LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt - name - cubemaptoequirectangular platforms darwin64 @@ -304,21 +300,19 @@ windows64 + license + MIT + license_file + LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt + copyright + Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com version 1.1.0 + name + cubemaptoequirectangular curl - copyright - Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se). - description - Library for transferring data specified with URL syntax - license - curl - license_file - LICENSES/curl.txt - name - curl platforms darwin64 @@ -362,21 +356,21 @@ windows64 + license + curl + license_file + LICENSES/curl.txt + copyright + Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se). version 7.54.1-5a4a82d + name + curl + description + Library for transferring data specified with URL syntax dbus_glib - copyright - Copyright (C) Red Hat Inc. - description - D-Bus bindings for glib - license - Academic Free License v. 2.1 - license_file - LICENSES/dbus-glib.txt - name - dbus_glib platforms linux64 @@ -392,21 +386,21 @@ linux64 + license + Academic Free License v. 2.1 + license_file + LICENSES/dbus-glib.txt + copyright + Copyright (C) Red Hat Inc. version 0.76 + name + dbus_glib + description + D-Bus bindings for glib dictionaries - copyright - Copyright 2014 Apache OpenOffice software - description - Spell checking dictionaries to bundled into the viewer - license - various open source - license_file - LICENSES/dictionaries.txt - name - dictionaries platforms common @@ -424,21 +418,21 @@ common + license + various open source + license_file + LICENSES/dictionaries.txt + copyright + Copyright 2014 Apache OpenOffice software version None + name + dictionaries + description + Spell checking dictionaries to bundled into the viewer dullahan - copyright - Copyright (c) 2017, Linden Research, Inc. - description - A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. - license - MPL - license_file - LICENSES/LICENSE.txt - name - dullahan platforms darwin64 @@ -470,21 +464,21 @@ windows64 + license + MPL + license_file + LICENSES/LICENSE.txt + copyright + Copyright (c) 2017, Linden Research, Inc. version 1.14.0.202310131404_118.4.1_g3dd6078_chromium-118.0.5993.54 + name + dullahan + description + A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. expat - copyright - Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. - description - Expat is an XML parser library written in C - license - expat - license_file - LICENSES/expat.txt - name - expat platforms darwin64 @@ -530,21 +524,21 @@ windows64 + license + expat + license_file + LICENSES/expat.txt + copyright + Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. version 2.1.1.1f36d02 + name + expat + description + Expat is an XML parser library written in C fmodstudio - copyright - FMOD Studio by Firelight Technologies Pty Ltd. - description - FMOD Studio API - license - fmod - license_file - LICENSES/fmodstudio.txt - name - fmodstudio platforms darwin64 @@ -596,21 +590,21 @@ windows64 + license + fmod + license_file + LICENSES/fmodstudio.txt + copyright + FMOD Studio by Firelight Technologies Pty Ltd. version 2.02.13.578928 + name + fmodstudio + description + FMOD Studio API fontconfig - copyright - Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc. - description - Fontconfig is a library for configuring and customizing font access. - license - bsd - license_file - LICENSES/fontconfig.txt - name - fontconfig platforms linux64 @@ -626,21 +620,21 @@ linux64 + license + bsd + license_file + LICENSES/fontconfig.txt + copyright + Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc. version 2.11.0 + name + fontconfig + description + Fontconfig is a library for configuring and customizing font access. freetype - copyright - Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. - description - Font rendering library - license - FreeType - license_file - LICENSES/freetype.txt - name - freetype platforms darwin64 @@ -686,21 +680,21 @@ windows64 + license + FreeType + license_file + LICENSES/freetype.txt + copyright + Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. version 2.4.4.4f739fa + name + freetype + description + Font rendering library glext - copyright - Copyright (c) 2007-2010 The Khronos Group Inc. - description - glext headers define function prototypes and constants for OpenGL extensions - license - Copyright (c) 2007-2010 The Khronos Group Inc. - license_file - LICENSES/glext.txt - name - glext platforms common @@ -718,21 +712,21 @@ common + license + Copyright (c) 2007-2010 The Khronos Group Inc. + license_file + LICENSES/glext.txt + copyright + Copyright (c) 2007-2010 The Khronos Group Inc. version 68 + name + glext + description + glext headers define function prototypes and constants for OpenGL extensions glh_linear - copyright - Copyright (c) 2000 Cass Everitt - description - glh - is a platform-indepenedent C++ OpenGL helper library - license - BSD - license_file - LICENSES/glh-linear.txt - name - glh_linear platforms common @@ -750,21 +744,21 @@ common + license + BSD + license_file + LICENSES/glh-linear.txt + copyright + Copyright (c) 2000 Cass Everitt version None + name + glh_linear + description + glh - is a platform-indepenedent C++ OpenGL helper library googlemock - copyright - Copyright 2008, Google Inc. - description - a library for writing and using C++ mock classes - license - BSD - license_file - LICENSES/gmock.txt - name - googlemock platforms darwin64 @@ -808,19 +802,21 @@ windows64 + license + BSD + license_file + LICENSES/gmock.txt + copyright + Copyright 2008, Google Inc. version 1.7.0.77bba00 + name + googlemock + description + a library for writing and using C++ mock classes gstreamer - copyright - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - license - LGPL - license_file - LICENSES/gstreamer.txt - name - gstreamer platforms linux64 @@ -836,19 +832,19 @@ linux64 + license + LGPL + license_file + LICENSES/gstreamer.txt + copyright + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> version 0.10.6.314267 + name + gstreamer gtk-atk-pango-glib - copyright - Copyright (various, see sources) - license - lgpl - license_file - LICENSES/gtk-atk-pango-glib.txt - name - gtk-atk-pango-glib platforms linux64 @@ -864,21 +860,19 @@ linux64 + license + lgpl + license_file + LICENSES/gtk-atk-pango-glib.txt + copyright + Copyright (various, see sources) version 0.1 + name + gtk-atk-pango-glib havok-source - copyright - Uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. - description - Havok source code for libs and demos - license - havok - license_file - LICENSES/havok.txt - name - havok-source platforms darwin64 @@ -926,19 +920,21 @@ windows64 + license + havok + license_file + LICENSES/havok.txt + copyright + Uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. version 2012.1-2 + name + havok-source + description + Havok source code for libs and demos jpegencoderbasic - copyright - Andreas Ritter, www.bytestrom.eu, 11/2009 - license - NONE - license_file - LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt - name - jpegencoderbasic platforms darwin64 @@ -982,21 +978,19 @@ windows64 + license + NONE + license_file + LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt + copyright + Andreas Ritter, www.bytestrom.eu, 11/2009 version 1.0 + name + jpegencoderbasic jpeglib - copyright - Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding. - description - JPEG encoding, decoding library - license - jpeglib - license_file - LICENSES/jpeglib.txt - name - jpeglib platforms darwin64 @@ -1042,21 +1036,21 @@ windows64 + license + jpeglib + license_file + LICENSES/jpeglib.txt + copyright + Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding. version 8c.7846234 + name + jpeglib + description + JPEG encoding, decoding library jsoncpp - copyright - Copyright (c) 2007-2010 Baptiste Lepilleur - description - jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++. - license - public domain - license_file - LICENSES/jsoncpp.txt - name - jsoncpp platforms darwin64 @@ -1102,21 +1096,21 @@ windows64 + license + public domain + license_file + LICENSES/jsoncpp.txt + copyright + Copyright (c) 2007-2010 Baptiste Lepilleur version 0.5.0.bc46e62 + name + jsoncpp + description + jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++. kdu - copyright - Kakadu software - description - JPEG2000 library by Kakadu - license - Kakadu - license_file - LICENSES/kdu.txt - name - kdu platforms darwin64 @@ -1168,21 +1162,21 @@ windows64 + license + Kakadu + license_file + LICENSES/kdu.txt + copyright + Kakadu software version 7.10.4.539108 + name + kdu + description + JPEG2000 library by Kakadu libhunspell - copyright - See hunspell.txt - description - Spell checking library - license - LGPL - license_file - LICENSES/hunspell.txt - name - libhunspell platforms darwin64 @@ -1228,21 +1222,21 @@ windows64 + license + LGPL + license_file + LICENSES/hunspell.txt + copyright + See hunspell.txt version 1.3.2.650fb94 + name + libhunspell + description + Spell checking library libndofdev - copyright - Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved. - description - 3DConnexion SDK - license - BSD - license_file - LICENSES/libndofdev.txt - name - libndofdev platforms darwin64 @@ -1274,21 +1268,21 @@ windows64 + license + BSD + license_file + LICENSES/libndofdev.txt + copyright + Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved. version 0.1.8e9edc7 + name + libndofdev + description + 3DConnexion SDK libpng - copyright - Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson - description - PNG Reference library - license - libpng - license_file - LICENSES/libpng.txt - name - libpng platforms darwin64 @@ -1332,21 +1326,21 @@ windows64 + license + libpng + license_file + LICENSES/libpng.txt + copyright + Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson version 1.6.38-ca06e99 + name + libpng + description + PNG Reference library libuuid - copyright - Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/> - description - OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). - license - UUID - license_file - LICENSES/uuid.txt - name - libuuid platforms linux64 @@ -1362,21 +1356,21 @@ linux64 + license + UUID + license_file + LICENSES/uuid.txt + copyright + Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/> version 1.6.2 + name + libuuid + description + OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). libxml2 - copyright - Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. - description - Libxml2 is the XML C parser and toolkit developed for the Gnome project. - license - mit - license_file - LICENSES/libxml2.txt - name - libxml2 platforms darwin64 @@ -1422,21 +1416,21 @@ windows64 + license + mit + license_file + LICENSES/libxml2.txt + copyright + Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. version 2.9.4.7476681 + name + libxml2 + description + Libxml2 is the XML C parser and toolkit developed for the Gnome project. llappearance_utility - copyright - Copyright (c) 2000-2012, Linden Research, Inc. - description - Linden Lab appearance utility for server-side avatar baking services. - license - Proprietary - license_file - LICENSES/llappearanceutility.txt - name - llappearance_utility platforms linux @@ -1452,20 +1446,21 @@ linux + license + Proprietary + license_file + LICENSES/llappearanceutility.txt + copyright + Copyright (c) 2000-2012, Linden Research, Inc. version 0.0.1 + name + llappearance_utility + description + Linden Lab appearance utility for server-side avatar baking services. llca - copyright - Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project. - - license - mit - license_file - LICENSES/ca-license.txt - name - llca platforms common @@ -1483,19 +1478,20 @@ common + license + mit + license_file + LICENSES/ca-license.txt + copyright + Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project. + version 202310121530.0 + name + llca llphysicsextensions_source - copyright - Copyright (c) 2010, Linden Research, Inc. - license - internal - license_file - LICENSES/llphysicsextensions.txt - name - llphysicsextensions_source platforms darwin64 @@ -1530,22 +1526,6 @@ name linux64 - windows - - archive - - creds - github - hash - 2e6a66da6071253ae888839cfab59d3f5c1b8b4c - hash_algorithm - sha1 - url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851462 - - name - windows - windows64 archive @@ -1563,19 +1543,19 @@ windows64 - version - 1.0.479d20a - - llphysicsextensions_stub - - copyright - Copyright (c) 2010, Linden Research, Inc. license internal license_file LICENSES/llphysicsextensions.txt + copyright + Copyright (c) 2010, Linden Research, Inc. + version + 1.0.479d20a name - llphysicsextensions_stub + llphysicsextensions_source + + llphysicsextensions_stub + platforms darwin64 @@ -1615,19 +1595,19 @@ windows + license + internal + license_file + LICENSES/llphysicsextensions.txt + copyright + Copyright (c) 2010, Linden Research, Inc. version 1.0.542456 + name + llphysicsextensions_stub llphysicsextensions_tpv - copyright - Copyright (c) 2010, Linden Research, Inc. - license - internal - license_file - LICENSES/HavokSublicense.pdf - name - llphysicsextensions_tpv platforms darwin64 @@ -1667,17 +1647,19 @@ windows + license + internal + license_file + LICENSES/HavokSublicense.pdf + copyright + Copyright (c) 2010, Linden Research, Inc. version 1.0.561752 + name + llphysicsextensions_tpv mesa - license - mesa - license_file - LICENSES/mesa.txt - name - mesa platforms linux @@ -1693,23 +1675,17 @@ linux + license + mesa + license_file + LICENSES/mesa.txt version 7.11.1.297294 + name + mesa meshoptimizer - canonical_repo - https://bitbucket.org/lindenlab/3p-meshoptimizer - copyright - Copyright (c) 2016-2021 Arseny Kapoulkine - description - Meshoptimizer. Mesh optimization library. - license - meshoptimizer - license_file - LICENSES/meshoptimizer.txt - name - meshoptimizer platforms darwin64 @@ -1741,8 +1717,20 @@ windows64 + license + meshoptimizer + license_file + LICENSES/meshoptimizer.txt + copyright + Copyright (c) 2016-2021 Arseny Kapoulkine version 160 + name + meshoptimizer + canonical_repo + https://bitbucket.org/lindenlab/3p-meshoptimizer + description + Meshoptimizer. Mesh optimization library. mikktspace @@ -1802,18 +1790,6 @@ minizip-ng - canonical_repo - https://bitbucket.org/lindenlab/3p-minizip-ng - copyright - This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - description - minizip-ng is a zip manipulation library. Based on work of Gilles Vollant. - license - minizip-ng - license_file - LICENSES/minizip-ng.txt - name - minizip-ng platforms darwin64 @@ -1859,22 +1835,23 @@ windows64 + license + minizip-ng + license_file + LICENSES/minizip-ng.txt + copyright + This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler version 3.0.2.3e9876e + name + minizip-ng + canonical_repo + https://bitbucket.org/lindenlab/3p-minizip-ng + description + minizip-ng is a zip manipulation library. Based on work of Gilles Vollant. nghttp2 - copyright - Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa -Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors - description - Library providing HTTP 2 support for libcurl - license - MIT - license_file - LICENSES/nghttp2.txt - name - nghttp2 platforms darwin64 @@ -1920,23 +1897,24 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - source_type - hg + license + MIT + license_file + LICENSES/nghttp2.txt + copyright + Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa +Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version 1.40.0.b1526c6 + name + nghttp2 + description + Library providing HTTP 2 support for libcurl + source_type + hg nvapi - copyright - Copyright © 2012 NVIDIA Corporation. All rights reserved. - description - NVAPI provides an interface to NVIDIA devices. - license - NVIDIA Corporation Software License Agreement – NVAPI SDK - license_file - LICENSES/NVAPI_SDK_License_Agreement.pdf - name - nvapi platforms windows64 @@ -1954,21 +1932,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + NVIDIA Corporation Software License Agreement – NVAPI SDK + license_file + LICENSES/NVAPI_SDK_License_Agreement.pdf + copyright + Copyright © 2012 NVIDIA Corporation. All rights reserved. version 352.aac0e19 - - ogg_vorbis - - copyright - Copyright (c) 2002, Xiph.org Foundation - description - Audio encoding library - license - ogg-vorbis - license_file - LICENSES/ogg-vorbis.txt name - ogg_vorbis + nvapi + description + NVAPI provides an interface to NVIDIA devices. + + ogg_vorbis + platforms darwin64 @@ -2012,96 +1990,96 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + ogg-vorbis + license_file + LICENSES/ogg-vorbis.txt + copyright + Copyright (c) 2002, Xiph.org Foundation version 1.3.3-1.3.6.e4101b6 + name + ogg_vorbis + description + Audio encoding library open-libndofdev - copyright - Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) - description - Open Source replacement for 3DConnection SDK license BSD license_file LICENSES/libndofdev.txt - name - open-libndofdev + copyright + Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) version 0.3 + name + open-libndofdev + description + Open Source replacement for 3DConnection SDK openal - copyright - Copyright (C) 1999-2007 by authors. - description - OpenAL Soft is a software implementation of the OpenAL 3D audio API. - license - LGPL2 - license_file - LICENSES/openal-soft.txt - name - openal platforms - darwin64 + linux64 archive hash - 4edaef5f03a1122eae8467c4a04d9caccaaaf847 + e0fbc4874acc4167a6e2b6489fbb8258d98fd665 hash_algorithm sha1 url - https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-darwin64-18e315c.tar.zst + https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-linux64-18e315c.tar.zst name - darwin64 + linux64 - linux64 + windows64 archive hash - e0fbc4874acc4167a6e2b6489fbb8258d98fd665 + 6ae3b5310eb1988741bc55416681ca9d64f76f85 hash_algorithm sha1 url - https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-linux64-18e315c.tar.zst + https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-windows64-18e315c.tar.zst name - linux64 + windows64 - windows64 + darwin64 archive hash - 6ae3b5310eb1988741bc55416681ca9d64f76f85 + 4edaef5f03a1122eae8467c4a04d9caccaaaf847 hash_algorithm sha1 url - https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-windows64-18e315c.tar.zst + https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-darwin64-18e315c.tar.zst name - windows64 + darwin64 + license + LGPL2 + license_file + LICENSES/openal-soft.txt + copyright + Copyright (C) 1999-2007 by authors. version 1.23.1 + name + openal + description + OpenAL Soft is a software implementation of the OpenAL 3D audio API. openjpeg - copyright - Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France; - description - The OpenJPEG library is an open-source JPEG 2000 codec written in C language. - license - BSD - license_file - LICENSES/openjpeg.txt - name - openjpeg platforms darwin64 @@ -2147,21 +2125,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + BSD + license_file + LICENSES/openjpeg.txt + copyright + Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France; version 2.5.0.ea12248 + name + openjpeg + description + The OpenJPEG library is an open-source JPEG 2000 codec written in C language. openssl - copyright - Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - description - Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library - license - openssl - license_file - LICENSES/openssl.txt - name - openssl platforms darwin64 @@ -2207,21 +2185,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + openssl + license_file + LICENSES/openssl.txt + copyright + Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) version 1.1.1q.de53f55 + name + openssl + description + Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library pcre - copyright - Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc. - description - PCRE Perl-compatible regular expression library - license - bsd - license_file - LICENSES/pcre-license.txt - name - pcre platforms darwin64 @@ -2265,21 +2243,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + bsd + license_file + LICENSES/pcre-license.txt + copyright + Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc. version 8.35.979fd86 + name + pcre + description + PCRE Perl-compatible regular expression library slvoice - copyright - 2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C) - description - Vivox SDK components - license - Mixed - license_file - LICENSES/vivox_licenses.txt - name - slvoice platforms darwin64 @@ -2327,19 +2305,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + Mixed + license_file + LICENSES/vivox_licenses.txt + copyright + 2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C) version 4.10.0000.32327.5fc3fe7c.571099 + name + slvoice + description + Vivox SDK components threejs - copyright - Copyright © 2010-2021 three.js authors - license - MIT - license_file - LICENSES/THREEJS_LICENSE.txt - name - threejs platforms darwin64 @@ -2383,8 +2363,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + MIT + license_file + LICENSES/THREEJS_LICENSE.txt + copyright + Copyright © 2010-2021 three.js authors version 0.132.2 + name + threejs tinygltf @@ -2424,18 +2412,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors tracy - canonical_repo - https://bitbucket.org/lindenlab/3p-tracy - copyright - Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl) - description - Tracy Profiler Library - license - bsd - license_file - LICENSES/tracy_license.txt - name - tracy platforms darwin64 @@ -2465,6 +2441,20 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + bsd + license_file + LICENSES/tracy_license.txt + copyright + Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl) + version + v0.8.1.235e98f + name + tracy + canonical_repo + https://bitbucket.org/lindenlab/3p-tracy + description + Tracy Profiler Library source https://bitbucket.org/lindenlab/3p-tracy source_type @@ -2474,16 +2464,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors tut - copyright - Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008-2009 Michał Rzechonek - description - TUT is a small and portable unit test framework for C++. - license - bsd - license_file - LICENSES/tut.txt - name - tut platforms common @@ -2501,21 +2481,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors common + license + bsd + license_file + LICENSES/tut.txt + copyright + Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008-2009 Michał Rzechonek version 2008.11.30 + name + tut + description + TUT is a small and portable unit test framework for C++. uriparser - copyright - Copyright (C) 2007, Weijia Song <songweijia@gmail.com>, Sebastian Pipping <webmaster@hartwork.org> - description - uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license. - license - New BSD license - license_file - LICENSES/uriparser.txt - name - uriparser platforms darwin64 @@ -2561,21 +2541,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + New BSD license + license_file + LICENSES/uriparser.txt + copyright + Copyright (C) 2007, Weijia Song <songweijia@gmail.com>, Sebastian Pipping <webmaster@hartwork.org> version 0.9.4 + name + uriparser + description + uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license. viewer-manager - copyright - Copyright (c) 2000-2012, Linden Research, Inc. - description - Linden Lab Viewer Management Process suite. - license - viewerlgpl - license_file - LICENSE - name - viewer-manager platforms darwin64 @@ -2621,23 +2601,25 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 - source - https://bitbucket.org/lindenlab/vmp-standalone - source_type - hg + license + viewerlgpl + license_file + LICENSE + copyright + Copyright (c) 2000-2012, Linden Research, Inc. version 3.0-08bf5ee + name + viewer-manager + description + Linden Lab Viewer Management Process suite. + source + https://bitbucket.org/lindenlab/vmp-standalone + source_type + hg vlc-bin - copyright - Copyright (C) 1998-2016 VLC authors and VideoLAN - license - GPL2 - license_file - LICENSES/vlc.txt - name - vlc-bin platforms darwin64 @@ -2669,23 +2651,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + GPL2 + license_file + LICENSES/vlc.txt + copyright + Copyright (C) 1998-2016 VLC authors and VideoLAN version 3.0.16.c219a5d + name + vlc-bin - vulkan_gltf + xmlrpc-epi - canonical_repo - https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr - copyright - Copyright (c) 2018 Sascha Willems - description - Vulkan GLTF Sample Implementation - license - Copyright (c) 2018 Sascha Willems - license_file - LICENSES/vulkan_gltf.txt - name - vulkan_gltf platforms darwin64 @@ -2693,53 +2671,71 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 8cff2060843db3db788511ee34a8e8cc + aa12611374876196b3ebb6bda8d419a697217b8b + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2 + https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst name darwin64 - windows + linux64 archive hash - 58eea384be49ba756ce9c5e66669540b + ad0c8b41ee4b4de216382bec46ee1c25962a3f12 + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2 + https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-linux64-8a05acf.tar.zst name - windows + linux64 windows64 archive hash - 79b6a11622c2f83cfc2b7cd1fafb867b + e53fd38c14b8c47c7c84dead8a1b211bb8be170c + hash_algorithm + sha1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2 + https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-windows64-8a05acf.tar.zst name windows64 + license + xmlrpc-epi + license_file + LICENSES/xmlrpc-epi.txt + copyright + Copyright: (C) 2000 Epinions, Inc. version - 1 + 0.54.1.8a05acf + name + xmlrpc-epi + description + XMLRPC Library - xmlrpc-epi + vulkan_gltf + canonical_repo + https://bitbucket.org/lindenlab/3p-vulkan-gltf-pbr copyright - Copyright: (C) 2000 Epinions, Inc. + Copyright (c) 2018 Sascha Willems description - XMLRPC Library + Vulkan GLTF Sample Implementation license - xmlrpc-epi + Copyright (c) 2018 Sascha Willems license_file - LICENSES/xmlrpc-epi.txt + LICENSES/vulkan_gltf.txt name - xmlrpc-epi + vulkan_gltf platforms darwin64 @@ -2747,59 +2743,43 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - aa12611374876196b3ebb6bda8d419a697217b8b - hash_algorithm - sha1 + 8cff2060843db3db788511ee34a8e8cc url - https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101316/891509/vulkan_gltf-1-darwin64-572743.tar.bz2 name darwin64 - linux64 + windows archive hash - ad0c8b41ee4b4de216382bec46ee1c25962a3f12 - hash_algorithm - sha1 + 58eea384be49ba756ce9c5e66669540b url - https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-linux64-8a05acf.tar.zst + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101318/891520/vulkan_gltf-1-windows-572743.tar.bz2 name - linux64 + windows windows64 archive hash - e53fd38c14b8c47c7c84dead8a1b211bb8be170c - hash_algorithm - sha1 + 79b6a11622c2f83cfc2b7cd1fafb867b url - https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-windows64-8a05acf.tar.zst + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/101319/891521/vulkan_gltf-1-windows64-572743.tar.bz2 name windows64 version - 0.54.1.8a05acf + 1 xxhash - copyright - Copyright (c) 2012-2021 Yann Collet - description - xxHash Library - license - xxhash - license_file - LICENSES/xxhash.txt - name - xxhash platforms common @@ -2857,23 +2837,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + xxhash + license_file + LICENSES/xxhash.txt + copyright + Copyright (c) 2012-2021 Yann Collet version 0.8.1.7501c90 + name + xxhash + description + xxHash Library zlib-ng - canonical_repo - https://bitbucket.org/lindenlab/3p-zlib-ng - copyright - Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - description - zlib data compression library for the next generation systems - license - zlib-ng - license_file - LICENSES/zlib-ng.txt - name - zlib-ng platforms darwin64 @@ -2919,24 +2897,24 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows64 + license + zlib-ng + license_file + LICENSES/zlib-ng.txt + copyright + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler version 1.2.11.zlib-ng.32fd361 + name + zlib-ng + canonical_repo + https://bitbucket.org/lindenlab/3p-zlib-ng + description + zlib data compression library for the next generation systems package_description - canonical_repo - https://github.com/secondlife/viewer - copyright - Copyright (c) 2020, Linden Research, Inc. - description - Second Life Viewer - license - LGPL - license_file - docs/LICENSE-source.txt - name - Second Life Viewer platforms common @@ -2945,9 +2923,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors RelWithDebInfo - build - - configure command @@ -2958,7 +2933,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=TRUE - + + + build + name RelWithDebInfo @@ -2967,10 +2945,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors configure - arguments - - ../indra - command cmake options @@ -2979,16 +2953,17 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=FALSE - + + arguments + + ../indra + name RelWithDebInfoOS Release - build - - configure command @@ -2999,7 +2974,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=TRUE - + + + build + name Release @@ -3008,10 +2986,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors configure - arguments - - ../indra - command cmake options @@ -3020,7 +2994,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DROOT_PROJECT_NAME:STRING=SecondLife -DINSTALL_PROPRIETARY=FALSE - + + arguments + + ../indra + name ReleaseOS @@ -3031,12 +3009,22 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors darwin64 - build_directory - build-darwin-x86_64 configurations RelWithDebInfo + configure + + options + + -G + Xcode + + arguments + + ../indra + + build command @@ -3048,19 +3036,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - - - configure - - arguments - - ../indra - - options - - -G - Xcode - + default True @@ -3069,6 +3045,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors RelWithDebInfoOS + configure + + options + + -G + Xcode + + build command @@ -3080,21 +3064,25 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - + + name + RelWithDebInfoOS + + Release + configure options -G Xcode - + + arguments + + ../indra + - name - RelWithDebInfoOS - - Release - build command @@ -3106,25 +3094,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - + + name + Release + + ReleaseOS + configure - arguments - - ../indra - options -G Xcode - + - name - Release - - ReleaseOS - build command @@ -3136,48 +3120,40 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -project SecondLife.xcodeproj -parallelizeTargets - - - configure - - options - - -G - Xcode - + name ReleaseOS + build_directory + build-darwin-x86_64 name darwin64 linux64 - build_directory - build-linux-x86_64 configurations Release - build - - command - ninja - configure - arguments - - ../indra - options -G Ninja -DLL_TESTS=Off - + + arguments + + ../indra + + + build + + command + ninja default True @@ -3186,11 +3162,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors ReleaseOS - build - - command - ninja - configure options @@ -3198,7 +3169,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors -G Ninja -DLL_TESTS=Off - + + + build + + command + ninja name ReleaseOS @@ -3212,44 +3188,44 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors default + build_directory + build-linux-x86_64 name linux64 windows - build_directory - build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE configurations RelWithDebInfo - build + configure + options + + -G + ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} + -A + ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} + arguments - SecondLife.sln - + ..\indra + + + build + command devenv options /build RelWithDebInfo|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - - - configure - + arguments - ..\indra - - options - - -G - ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} - -A - ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - + SecondLife.sln + default True @@ -3258,12 +3234,25 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors RelWithDebInfoOS - build + configure + options + + -G + ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} + -A + ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} + -DINSTALL_PROPRIETARY=FALSE + -DUSE_KDU=FALSE + -DUSE_OPENAL:BOOL=ON + arguments - SecondLife.sln - + ..\indra + + + build + command msbuild.exe options @@ -3274,69 +3263,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors /p:useenv=true /verbosity:minimal /p:VCBuildAdditionalOptions= /incremental - + + arguments + + SecondLife.sln + + name + RelWithDebInfoOS + + Release + configure - arguments - - ..\indra - options -G ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} -A ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - -DINSTALL_PROPRIETARY=FALSE - -DUSE_KDU=FALSE - -DUSE_OPENAL:BOOL=ON - + + arguments + + ..\indra + - name - RelWithDebInfoOS - - Release - build - arguments - - SecondLife.sln - command devenv options /build Release|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - + + arguments + + SecondLife.sln + + name + Release + + ReleaseOS + configure - arguments - - ..\indra - options -G ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} -A ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - + -DUNATTENDED:BOOL=ON + -DINSTALL_PROPRIETARY=FALSE + -DUSE_KDU=FALSE + -DUSE_OPENAL:BOOL=ON + + arguments + + ..\indra + - name - Release - - ReleaseOS - build - arguments - - SecondLife.sln - command msbuild.exe options @@ -3347,40 +3337,36 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors /p:useenv=true /verbosity:minimal /p:VCBuildAdditionalOptions= /incremental - - - configure - + arguments - ..\indra - - options - - -G - ${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN} - -A - ${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - -DUNATTENDED:BOOL=ON - -DINSTALL_PROPRIETARY=FALSE - -DUSE_KDU=FALSE - -DUSE_OPENAL:BOOL=ON - + SecondLife.sln + name ReleaseOS + build_directory + build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE name windows + license + LGPL + license_file + docs/LICENSE-source.txt + copyright + Copyright (c) 2020, Linden Research, Inc. version_file newview/viewer_version.txt + name + Second Life Viewer + canonical_repo + https://github.com/secondlife/viewer + description + Second Life Viewer - type - autobuild - version - 1.3 -- cgit v1.2.3 From bf43a8574c394c27bad1b0b08c88cad308a55572 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 16 Jan 2024 12:09:26 -0500 Subject: Fix failure to optimize away alpha channel on some GLTF upload paths (#606) Co-authored-by: RunitaiLinden --- indra/newview/lltinygltfhelper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index 999be07dba..5b75db37d0 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -178,6 +178,7 @@ LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tiny { rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component); rawImage->verticalFlip(); + rawImage->optimizeAwayAlpha(); } return rawImage; -- cgit v1.2.3 From 71bcc8977646072d4fbf3a2cd49c7a4ee1b4ea78 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 16 Jan 2024 22:04:18 +0200 Subject: SL-20669 Material editor uses incorect blank normal maps --- indra/newview/llmaterialeditor.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index db9589666c..34f2f77d25 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -43,6 +43,7 @@ #include "llnotificationsutil.h" #include "lltexturectrl.h" #include "lltrans.h" +#include "llviewercontrol.h" #include "llviewermenufile.h" #include "llviewertexture.h" #include "llsdutil.h" @@ -448,6 +449,10 @@ BOOL LLMaterialEditor::postBuild() mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); + // should match normal textures from mBumpyTextureCtrl + mNormalTextureCtrl->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("DefaultObjectNormalTexture"))); + mNormalTextureCtrl->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture"))); + if (mIsOverride) { // Live editing needs a recovery mechanism on cancel -- cgit v1.2.3 From 586e4cd090b22f11a68fa635e598847ce3b84d21 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 17 Jan 2024 12:14:44 -0600 Subject: SL-18429 Make it so auto adjusting legacy skies merely turns on tonemapping. --- indra/newview/app_settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8fbeb82d07..77ca52a7f7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10676,7 +10676,7 @@ Type F32 Value - 2.0 + 1.0 RendeSkyAutoAdjustBlueHorizonScale -- cgit v1.2.3 From 0ed6112967f2240de689b08373bf61905321e199 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 17 Jan 2024 16:23:16 -0600 Subject: https://github.com/secondlife/viewer-issues/issues/21 Add RenderMaxTextureResolution debug setting --- indra/newview/app_settings/settings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 77ca52a7f7..76e635744e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9405,6 +9405,17 @@ U32 Value 16 + + RenderMaxTextureResolution + + Comment + Maximum texture resolution. + Persist + 1 + Type + U32 + Value + 1024 RenderDebugTextureBind -- cgit v1.2.3 From 19163fd0fea6c92712b37e29f34b72edbbfe152d Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 18 Jan 2024 10:33:02 -0600 Subject: Allow for upload of 2k textures (#652) * SL-20760 Allow 2k texture uploads * SL-20760 Fix for textures not downloading. --- indra/llimage/llimage.h | 8 ++++---- indra/llrender/llgltexture.h | 2 +- indra/newview/llmaterialeditor.cpp | 2 +- indra/newview/llviewertexture.cpp | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8f9e1b3c54..d1929b693f 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -33,7 +33,7 @@ #include "lltrace.h" const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2 -const S32 MAX_IMAGE_MIP = 11; // 2048x2048 +const S32 MAX_IMAGE_MIP = 12; // 4096x4096 // *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number // of levels is read from the header's file, not inferred from its size. @@ -44,7 +44,7 @@ const S32 MAX_DISCARD_LEVEL = 5; // and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL. const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is) -const S32 MAX_PRECINCT_SIZE = 2048; // No reason to be bigger than MAX_IMAGE_SIZE +const S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec @@ -52,11 +52,11 @@ const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after hea const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit) const S32 MIN_IMAGE_SIZE = (1<getDataSize() << LL_ENDL; } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 56bba51692..8436159e14 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1699,7 +1699,7 @@ void LLViewerFetchedTexture::processTextureStats() { if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) { - mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 } else { @@ -1712,7 +1712,7 @@ void LLViewerFetchedTexture::processTextureStats() } else { - U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight) { if (mFullWidth > desired_size || mFullHeight > desired_size) @@ -3089,7 +3089,7 @@ void LLViewerLODTexture::processTextureStats() { mDesiredDiscardLevel = 0; if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) - mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 } else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f) { @@ -3134,7 +3134,7 @@ void LLViewerLODTexture::processTextureStats() discard_level = floorf(discard_level); F32 min_discard = 0.f; - U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) { desired_size = DESIRED_NORMAL_TEXTURE_SIZE; -- cgit v1.2.3 From 46bc94074d59a898e94eefd73363aed2d27f3e05 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 19 Jan 2024 10:22:52 -0600 Subject: https://github.com/secondlife/viewer-issues/issues/21 Just use existing settings to block uploads larger than 1024. --- indra/newview/app_settings/settings.xml | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 76e635744e..4a95cb1ed2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9405,17 +9405,6 @@ U32 Value 16 - - RenderMaxTextureResolution - - Comment - Maximum texture resolution. - Persist - 1 - Type - U32 - Value - 1024 RenderDebugTextureBind @@ -15700,7 +15689,7 @@ Type S32 Value - 2048 + 1024 max_texture_dimension_Y @@ -15711,7 +15700,7 @@ Type S32 Value - 2048 + 1024 teleport_offer_invitation_max_length -- cgit v1.2.3 From ae3990e24f3ec27ce66b00faa57bf27f3bbdaef5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 28 Nov 2023 16:47:44 -0800 Subject: SL-20606: Remove unused LLRenderPass func --- indra/newview/lldrawpool.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 0925a01439..f6200d1f6d 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -349,8 +349,6 @@ public: void resetDrawOrders() { } static void applyModelMatrix(const LLDrawInfo& params); - // Use before a non-GLTF batch if it is interleaved with GLTF batches that share the same shader - static void resetGLTFTextureTransform(); void pushBatches(U32 type, bool texture = true, bool batch_textures = false); void pushUntexturedBatches(U32 type); -- cgit v1.2.3 From 7c2c49dd262020fcf36c12ce3fcb23d2222c146d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 28 Nov 2023 17:23:59 -0800 Subject: SL-20606: Make push GLTF single batch static --- indra/newview/lldrawpool.cpp | 4 ++++ indra/newview/lldrawpool.h | 8 ++++---- indra/newview/pipeline.cpp | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 50210b06c4..f10c9047a3 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -746,6 +746,7 @@ void LLRenderPass::pushUntexturedGLTFBatches(U32 type) } } +// static void LLRenderPass::pushGLTFBatch(LLDrawInfo& params) { auto& mat = params.mGLTFMaterial; @@ -764,6 +765,7 @@ void LLRenderPass::pushGLTFBatch(LLDrawInfo& params) teardown_texture_matrix(params); } +// static void LLRenderPass::pushUntexturedGLTFBatch(LLDrawInfo& params) { auto& mat = params.mGLTFMaterial; @@ -825,6 +827,7 @@ void LLRenderPass::pushUntexturedRiggedGLTFBatches(U32 type) } +// static void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId) { if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash)) @@ -837,6 +840,7 @@ void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvat pushGLTFBatch(params); } +// static void LLRenderPass::pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId) { if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash)) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index f6200d1f6d..365c022285 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -372,10 +372,10 @@ public: void pushUntexturedRiggedGLTFBatches(U32 type); // push a single GLTF draw call - void pushGLTFBatch(LLDrawInfo& params); - void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId); - void pushUntexturedGLTFBatch(LLDrawInfo& params); - void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId); + static void pushGLTFBatch(LLDrawInfo& params); + static void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId); + static void pushUntexturedGLTFBatch(LLDrawInfo& params); + static void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId); void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false); void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f740fa60be..3882472b49 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6536,7 +6536,7 @@ void LLPipeline::renderAlphaObjects(bool rigged) LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF); - mSimplePool->pushRiggedGLTFBatch(*pparams, lastAvatar, lastMeshId); + LLRenderPass::pushRiggedGLTFBatch(*pparams, lastAvatar, lastMeshId); } else { @@ -6562,7 +6562,7 @@ void LLPipeline::renderAlphaObjects(bool rigged) LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up); LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF); - mSimplePool->pushGLTFBatch(*pparams); + LLRenderPass::pushGLTFBatch(*pparams); } else { -- cgit v1.2.3 From 42dafa5f09d3921617f54be712907ee12f1e8940 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 15 Sep 2023 17:18:07 -0700 Subject: SL-20606: Refactor model matrix code --- indra/newview/lldrawpool.cpp | 13 +++++++++---- indra/newview/lldrawpool.h | 2 ++ indra/newview/lldrawpoolterrain.cpp | 15 ++------------- indra/newview/lldrawpooltree.cpp | 13 ++----------- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index f10c9047a3..556760632a 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -567,14 +567,19 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) { - if (params.mModelMatrix != gGLLastMatrix) + applyModelMatrix(params.mModelMatrix); +} + +void LLRenderPass::applyModelMatrix(const LLMatrix4* model_matrix) +{ + if (model_matrix != gGLLastMatrix) { - gGLLastMatrix = params.mModelMatrix; + gGLLastMatrix = model_matrix; gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.loadMatrix(gGLModelView); - if (params.mModelMatrix) + if (model_matrix) { - gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix); + gGL.multMatrix((GLfloat*) model_matrix->mMatrix); } gPipeline.mMatrixOpCount++; } diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 365c022285..0a9c2cc420 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -349,6 +349,8 @@ public: void resetDrawOrders() { } static void applyModelMatrix(const LLDrawInfo& params); + // For rendering that doesn't use LLDrawInfo for some reason + static void applyModelMatrix(const LLMatrix4* model_matrix); void pushBatches(U32 type, bool texture = true, bool batch_textures = false); void pushUntexturedBatches(U32 type); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 77189dceae..43f7587591 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -204,19 +204,8 @@ void LLDrawPoolTerrain::drawLoop() { LLFace *facep = *iter; - LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix); - - if (model_matrix != gGLLastMatrix) - { - llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); - gGLLastMatrix = model_matrix; - gGL.loadMatrix(gGLModelView); - if (model_matrix) - { - gGL.multMatrix((GLfloat*) model_matrix->mMatrix); - } - gPipeline.mMatrixOpCount++; - } + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); + LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix); facep->renderIndexed(); } diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 9dcbc48697..50c4a2c1b3 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -85,17 +85,8 @@ void LLDrawPoolTree::renderDeferred(S32 pass) { LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); - if (model_matrix != gGLLastMatrix) - { - gGLLastMatrix = model_matrix; - gGL.loadMatrix(gGLModelView); - if (model_matrix) - { - llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); - gGL.multMatrix((GLfloat*)model_matrix->mMatrix); - } - gPipeline.mMatrixOpCount++; - } + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); + LLRenderPass::applyModelMatrix(model_matrix); buff->setBuffer(); buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts() - 1, buff->getNumIndices(), 0); -- cgit v1.2.3 From 22d0d81f719ef00d28255d4f8af5702752c731f6 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 4 Dec 2023 12:18:56 -0800 Subject: SL-20606: Add Tracy profile zone for LLViewerDynamicTexture::updateAllInstances --- indra/newview/lldynamictexture.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 425acd3392..1a817e4fd9 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -181,6 +181,8 @@ void LLViewerDynamicTexture::postRender(BOOL success) //----------------------------------------------------------------------------- BOOL LLViewerDynamicTexture::updateAllInstances() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + sNumRenders = 0; if (gGLManager.mIsDisabled) { -- cgit v1.2.3 From c2a30057f8c8dde913d12c0ee21d98191f58c5f1 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 12 Dec 2023 17:47:33 -0800 Subject: SL-20606: Remove unused strider getters --- indra/llrender/llvertexbuffer.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index f2d146d4bb..197fdbb189 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -187,10 +187,6 @@ public: bool getWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); bool getWeight4Strider(LLStrider& strider, U32 index=0, S32 count = -1); bool getClothWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getBasecolorTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getNormalTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getMetallicRoughnessTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); - bool getEmissiveTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); void setPositionData(const LLVector4a* data); void setTexCoordData(const LLVector2* data); -- cgit v1.2.3 From 2f18d74f9ab3165da680ce2ee2f0c455ce7e0796 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 13 Nov 2023 17:26:14 -0800 Subject: SL-20606: Full GLTF material preview. Works for most materials. --- indra/llmath/llcamera.h | 1 - indra/llrender/llvertexbuffer.cpp | 4 + indra/llrender/llvertexbuffer.h | 1 + indra/newview/CMakeLists.txt | 2 + .../class1/deferred/postDeferredNoDoFF.glsl | 4 + indra/newview/lldynamictexture.cpp | 27 +- indra/newview/llfetchedgltfmaterial.cpp | 52 --- indra/newview/llfetchedgltfmaterial.h | 5 - indra/newview/llgltfmaterialpreviewmgr.cpp | 501 +++++++++++++++++++++ indra/newview/llgltfmaterialpreviewmgr.h | 82 ++++ indra/newview/llreflectionmapmanager.cpp | 32 ++ indra/newview/llreflectionmapmanager.h | 5 + indra/newview/lltexturectrl.cpp | 93 ++-- indra/newview/lltexturectrl.h | 3 + indra/newview/pipeline.cpp | 15 +- indra/newview/pipeline.h | 4 +- 16 files changed, 728 insertions(+), 103 deletions(-) create mode 100644 indra/newview/llgltfmaterialpreviewmgr.cpp create mode 100644 indra/newview/llgltfmaterialpreviewmgr.h diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index c4d04f5d02..e1d3536f66 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -65,7 +65,6 @@ class LLCamera : public LLCoordFrame { public: - LLCamera(const LLCamera& rhs) { *this = rhs; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index de27636c33..4f5f30d7c2 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1319,6 +1319,10 @@ bool LLVertexBuffer::getNormalStrider(LLStrider& strider, U32 index, { return VertexBufferStrider::get(*this, strider, index, count); } +bool LLVertexBuffer::getNormalStrider(LLStrider& strider, U32 index, S32 count) +{ + return VertexBufferStrider::get(*this, strider, index, count); +} bool LLVertexBuffer::getTangentStrider(LLStrider& strider, U32 index, S32 count) { return VertexBufferStrider::get(*this, strider, index, count); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 197fdbb189..cc59e322ed 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -180,6 +180,7 @@ public: bool getTexCoord1Strider(LLStrider& strider, U32 index=0, S32 count = -1); bool getTexCoord2Strider(LLStrider& strider, U32 index=0, S32 count = -1); bool getNormalStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getNormalStrider(LLStrider& strider, U32 index = 0, S32 count = -1); bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); bool getColorStrider(LLStrider& strider, U32 index=0, S32 count = -1); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7a70d0b6e6..8268fb3d97 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -310,6 +310,7 @@ set(viewer_SOURCE_FILES llgiveinventory.cpp llglsandbox.cpp llgltfmateriallist.cpp + llgltfmaterialpreviewmgr.cpp llgroupactions.cpp llgroupiconctrl.cpp llgrouplist.cpp @@ -963,6 +964,7 @@ set(viewer_HEADER_FILES llgesturemgr.h llgiveinventory.h llgltfmateriallist.h + llgltfmaterialpreviewmgr.h llgroupactions.h llgroupiconctrl.h llgrouplist.h diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index bace9b8c90..cd4ae8110a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -37,7 +37,11 @@ void main() { vec4 diff = texture(diffuseRect, vary_fragcoord.xy); +#if 1 frag_color = diff; +#else + frag_color = vec4(1,0,1,1); +#endif gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r; } diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 1a817e4fd9..a66c3876fc 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -189,13 +189,18 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; + LLRenderTarget& bake_target = gPipeline.mAuxillaryRT.deferredScreen; - if (use_fbo) - { - gPipeline.mBake.bindTarget(); - gPipeline.mBake.clear(); - } + if (!bake_target.isComplete()) + { + llassert(false); + return FALSE; + } + llassert(bake_target.getWidth() >= LLPipeline::MAX_BAKE_WIDTH); + llassert(bake_target.getHeight() >= LLPipeline::MAX_BAKE_WIDTH); + + bake_target.bindTarget(); + bake_target.clear(); LLGLSLShader::unbind(); LLVertexBuffer::unbind(); @@ -210,11 +215,14 @@ BOOL LLViewerDynamicTexture::updateAllInstances() LLViewerDynamicTexture *dynamicTexture = *iter; if (dynamicTexture->needsRender()) { + llassert(dynamicTexture->getFullWidth() <= LLPipeline::MAX_BAKE_WIDTH); + llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH); + glClear(GL_DEPTH_BUFFER_BIT); gDepthDirty = TRUE; gGL.color4f(1,1,1,1); - dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr); + dynamicTexture->setBoundTarget(&bake_target); dynamicTexture->preRender(); // Must be called outside of startRender() result = FALSE; if (dynamicTexture->render()) @@ -231,10 +239,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() } } - if (use_fbo) - { - gPipeline.mBake.flush(); - } + bake_target.flush(); gGL.flush(); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 46b9dffae9..90ec08391d 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -254,55 +254,3 @@ void LLFetchedGLTFMaterial::materialComplete() materialCompleteCallbacks.clear(); materialCompleteCallbacks.shrink_to_fit(); } - -LLPointer LLFetchedGLTFMaterial::getUITexture() -{ - if (mFetching) - { - return nullptr; - } - - auto fetch_texture_for_ui = [](LLPointer& img, const LLUUID& id) - { - if (id.notNull()) - { - if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) - { - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if (obj) - { - LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id); - img = viewerTexture ? dynamic_cast(viewerTexture) : NULL; - } - - } - else - { - img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } - } - if (img) - { - img->setBoostLevel(LLGLTexture::BOOST_PREVIEW); - img->forceToSaveRawImage(0); - } - }; - - fetch_texture_for_ui(mBaseColorTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); - fetch_texture_for_ui(mNormalTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); - fetch_texture_for_ui(mMetallicRoughnessTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); - fetch_texture_for_ui(mEmissiveTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); - - if ((mBaseColorTexture && (mBaseColorTexture->getRawImageLevel() != 0)) || - (mNormalTexture && (mNormalTexture->getRawImageLevel() != 0)) || - (mMetallicRoughnessTexture && (mMetallicRoughnessTexture->getRawImageLevel() != 0)) || - (mEmissiveTexture && (mEmissiveTexture->getRawImageLevel() != 0))) - { - return nullptr; - } - - // *HACK: Use one of the PBR texture components as the preview texture for now - mPreviewTexture = mBaseColorTexture; - - return mPreviewTexture; -} diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index a9e539633d..2559aa46cc 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,8 +50,6 @@ public: bool isFetching() const { return mFetching; } - LLPointer getUITexture(); - void addTextureEntry(LLTextureEntry* te) override; void removeTextureEntry(LLTextureEntry* te) override; virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override; @@ -65,9 +63,6 @@ public: std::set mTextureEntires; - // Texture used for previewing the material in the UI - LLPointer mPreviewTexture; - protected: // Lifetime management diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp new file mode 100644 index 0000000000..9ef1bbf884 --- /dev/null +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -0,0 +1,501 @@ +/** + * @file llgltfmaterialpreviewmgr.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 "llviewerprecompiledheaders.h" + +#include "llgltfmaterialpreviewmgr.h" + +#include + +#include "llavatarappearancedefines.h" +#include "llenvironment.h" +#include "llselectmgr.h" +#include "llviewercamera.h" +#include "llviewerobject.h" +#include "llviewershadermgr.h" +#include "llviewertexturelist.h" +#include "llviewerwindow.h" +#include "llvolumemgr.h" +#include "pipeline.h" + +LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr; + +namespace +{ + constexpr S32 FULLY_LOADED = 0; + constexpr S32 NOT_LOADED = 99; +}; + +LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels() +{ + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + levels[i] = NOT_LOADED; + } +} + +S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i) +{ + llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT); + return levels[i]; +} + +const S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i) const +{ + llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT); + return levels[i]; +} + +bool LLGLTFPreviewTexture::MaterialLoadLevels::operator<(const MaterialLoadLevels& other) const +{ + bool less = false; + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (((*this)[i] > other[i])) { return false; } + less = less || ((*this)[i] < other[i]); + } + return less; +} + +bool LLGLTFPreviewTexture::MaterialLoadLevels::operator>(const MaterialLoadLevels& other) const +{ + bool great = false; + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (((*this)[i] < other[i])) { return false; } + great = great || ((*this)[i] > other[i]); + } + return great; +} + +namespace +{ + void fetch_texture_for_ui(LLPointer& img, const LLUUID& id) + { + if (id.notNull()) + { + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id); + img = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + } + } + else + { + img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + } + if (img) + { + img->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + img->forceToSaveRawImage(0); + } + }; + + // *NOTE: Does not use the same conventions as texture discard level. Lower is better. + S32 get_texture_load_level(const LLPointer& texture) + { + if (!texture) { return FULLY_LOADED; } + const S32 raw_level = texture->getDiscardLevel(); + if (raw_level < 0) { return NOT_LOADED; } + return raw_level; + } + + LLGLTFPreviewTexture::MaterialLoadLevels get_material_load_levels(LLFetchedGLTFMaterial& material) + { + using MaterialTextures = LLPointer*[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT]; + + MaterialTextures textures; + + textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = &material.mBaseColorTexture; + textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = &material.mNormalTexture; + textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = &material.mMetallicRoughnessTexture; + textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = &material.mEmissiveTexture; + + LLGLTFPreviewTexture::MaterialLoadLevels levels; + + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + fetch_texture_for_ui(*textures[i], material.mTextureId[i]); + levels[i] = get_texture_load_level(*textures[i]); + } + + return levels; + } + + // Is the material loaded enough to start rendering a preview? + bool is_material_loaded_enough_for_ui(LLFetchedGLTFMaterial& material) + { + if (material.isFetching()) + { + return false; + } + + LLGLTFPreviewTexture::MaterialLoadLevels levels = get_material_load_levels(material); + + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (levels[i] == NOT_LOADED) + { + return false; + } + } + + return true; + } + +}; // namespace + +LLGLTFPreviewTexture::LLGLTFPreviewTexture(LLPointer material, S32 width) + : LLViewerDynamicTexture(width, width, 4, EOrder::ORDER_MIDDLE, FALSE) + , mGLTFMaterial(material) +{ +} + +// static +LLPointer LLGLTFPreviewTexture::create(LLPointer material) +{ + return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH); +} + +void LLGLTFPreviewTexture::preRender(BOOL clear_depth) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + + MaterialLoadLevels current_load = get_material_load_levels(*mGLTFMaterial.get()); + if (current_load < mBestLoad) + { + mShouldRender = true; + mBestLoad = current_load; + } + + if (!mShouldRender) { return; } + + LLViewerDynamicTexture::preRender(clear_depth); +} + + +namespace { + +struct GLTFPreviewModel +{ + GLTFPreviewModel(LLPointer& info, const LLMatrix4& mat) + : mDrawInfo(info) + , mModelMatrix(mat) + { + mDrawInfo->mModelMatrix = &mModelMatrix; + } + LLPointer mDrawInfo; + LLMatrix4 mModelMatrix; // Referenced by mDrawInfo +}; + +// Like LLVolumeGeometryManager::registerFace but without batching or too-many-indices/vertices checking. +std::vector create_preview_sphere(LLPointer& material, const LLMatrix4& model_matrix) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + + const LLColor4U vertex_color(material->mBaseColor); + + LLPrimitive prim; + prim.init_primitive(LL_PCODE_VOLUME); + LLVolumeParams params; + params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE); + params.setBeginAndEndS(0.f, 1.f); + params.setBeginAndEndT(0.f, 1.f); + params.setRatio(1, 1); + params.setShear(0, 0); + constexpr auto MAX_LOD = LLVolumeLODGroup::NUM_LODS - 1; + prim.setVolume(params, MAX_LOD); + + LLVolume* volume = prim.getVolume(); + llassert(volume); + for (LLVolumeFace& face : volume->getVolumeFaces()) + { + face.createTangents(); + } + + std::vector preview_sphere; + preview_sphere.reserve(volume->getNumFaces()); + + LLPointer buf = new LLVertexBuffer( + LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_TANGENT + ); + U32 nv = 0; + U32 ni = 0; + for (LLVolumeFace& face : volume->getVolumeFaces()) + { + nv += face.mNumVertices; + ni += face.mNumIndices; + } + buf->allocateBuffer(nv, ni); + + // UV hacks + // Higher factor helps to see more details on the preview sphere + const LLVector2 uv_factor(2.0f, 2.0f); + // Offset places center of material in center of view + const LLVector2 uv_offset(-0.5f, -0.5f); + + LLStrider indices; + LLStrider positions; + LLStrider normals; + LLStrider texcoords; + LLStrider colors; + LLStrider tangents; + buf->getIndexStrider(indices); + buf->getVertexStrider(positions); + buf->getNormalStrider(normals); + buf->getTexCoord0Strider(texcoords); + buf->getColorStrider(colors); + buf->getTangentStrider(tangents); + U32 index_offset = 0; + U32 vertex_offset = 0; + for (const LLVolumeFace& face : volume->getVolumeFaces()) + { + for (S32 i = 0; i < face.mNumIndices; ++i) + { + *indices++ = face.mIndices[i] + vertex_offset; + } + for (S32 v = 0; v < face.mNumVertices; ++v) + { + *positions++ = face.mPositions[v]; + *normals++ = face.mNormals[v]; + LLVector2 uv(face.mTexCoords[v]); + uv.scaleVec(uv_factor); + uv += uv_offset; + *texcoords++ = uv; + *colors++ = vertex_color; + *tangents++ = face.mTangents[v]; + } + + constexpr LLViewerTexture* no_media = nullptr; + LLPointer info = new LLDrawInfo(U16(vertex_offset), U16(vertex_offset + face.mNumVertices - 1), face.mNumIndices, index_offset, no_media, buf.get()); + info->mGLTFMaterial = material; + preview_sphere.emplace_back(info, model_matrix); + index_offset += face.mNumIndices; + vertex_offset += face.mNumVertices; + } + + buf->unmapBuffer(); + + return preview_sphere; +} + +// Final, direct modifications to shader constants, just before render +void fixup_shader_constants(LLGLSLShader& shader) +{ + // Sunlight intensity of 0 no matter what + shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1); + shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, LLColor3::white.mV); + shader.uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, 0.0f); + + // Ignore sun shadow (if enabled) + for (U32 i = 0; i < 6; i++) + { + const S32 channel = shader.getTextureChannel(LLShaderMgr::DEFERRED_SHADOW0+i); + if (channel != -1) + { + gGL.getTexUnit(channel)->bind(LLViewerFetchedTexture::sWhiteImagep, TRUE); + } + } +} + +// Set a variable to a value temporarily, and restor the variable's old value +// when this object leaves scope. +template +struct SetTemporarily +{ + T* mRef; + T mOldVal; + SetTemporarily(T* var, T temp_val) + { + mRef = var; + mOldVal = *mRef; + *mRef = temp_val; + } + ~SetTemporarily() + { + *mRef = mOldVal; + } +}; + +}; // namespace + +BOOL LLGLTFPreviewTexture::render() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + + if (!mShouldRender) { return FALSE; } + + LLGLDepthTest(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); + LLGLDisable scissor(GL_SCISSOR_TEST); + SetTemporarily no_glow(&LLPipeline::sRenderGlow, false); + SetTemporarily no_ssr(&LLPipeline::RenderScreenSpaceReflections, false); + SetTemporarily no_fxaa(&LLPipeline::RenderFSAASamples, U32(0)); + SetTemporarily use_auxiliary_render_target(&gPipeline.mRT, &gPipeline.mAuxillaryRT); + + LLVector3 light_dir3(1.0f, 1.0f, 1.0f); + light_dir3.normalize(); + const LLVector4 light_dir = LLVector4(light_dir3, 0); + SetTemporarily sun_light_only(&LLPipeline::RenderLocalLightCount, 0); + + gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(); + + LLViewerCamera camera; + + // Calculate the object distance at which the object of a given radius will + // span the partial width of the screen given by fill_ratio. + // Assume the primitive has a scale of 1 (this is the default). + constexpr F32 fill_ratio = 0.8f; + constexpr F32 object_radius = 0.5f; + const F32 object_distance = (object_radius / fill_ratio) * tan(camera.getDefaultFOV()); + // Negative coordinate shows the textures on the sphere right-side up, when + // combined with the UV hacks in create_preview_sphere + const LLVector3 object_position(0.0, -object_distance, 0.0); + LLMatrix4 object_transform; + object_transform.translate(object_position); + + // Set up camera and viewport + const LLVector3 origin(0.0, 0.0, 0.0); + camera.lookAt(origin, object_position); + camera.setAspect(mFullHeight / mFullWidth); + const LLRect texture_rect(0, mFullHeight, mFullWidth, 0); + camera.setPerspective(NOT_FOR_SELECTION, texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight(), FALSE, camera.getNear(), MAX_FAR_CLIP*2.f); + + // Generate sphere object on-the-fly. Discard afterwards. (Vertex buffer is + // discarded, but the sphere should be cached in LLVolumeMgr.) + std::vector preview_sphere = create_preview_sphere(mGLTFMaterial, object_transform); + + glClearColor(0, 0, 0, 0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + gPipeline.setupHWLights(); + glh::matrix4f mat = copy_matrix(gGLModelView); + glh::vec4f transformed_light_dir(light_dir.mV); + mat.mult_matrix_vec(transformed_light_dir); + SetTemporarily force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir.v)); + // Override lights to ensure the sun is always shining from a certain direction (low graphics) + // See also force_sun_direction_high_graphics and fixup_shader_constants + { + LLLightState* light = gGL.getLight(0); + light->setPosition(light_dir); + constexpr bool sun_up = true; + light->setSunPrimary(sun_up); + } + + LLRenderTarget& screen = gPipeline.mAuxillaryRT.screen; + +#if 0 + if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE || mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) + { + // *TODO: Opaque/alpha mask rendering (gDeferredPBROpaqueProgram) + } + else +#endif + { + // Alpha blend rendering + + screen.bindTarget(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + LLGLSLShader& shader = gDeferredPBRAlphaProgram; + + gPipeline.bindDeferredShader(shader); + fixup_shader_constants(shader); + + for (GLTFPreviewModel& part : preview_sphere) + { + LLRenderPass::pushGLTFBatch(*part.mDrawInfo); + } + + gPipeline.unbindDeferredShader(shader); + + screen.flush(); + } + + gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap); + gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap); + gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap); + gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap); + LLVertexBuffer::unbind(); + gPipeline.generateGlow(&gPipeline.mPostMap); + gPipeline.combineGlow(&gPipeline.mPostMap, &screen); + gPipeline.renderDoF(&screen, &gPipeline.mPostMap); + gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); + + gDeferredPostNoDoFProgram.bind(); + + // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems." + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen); + gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true); + + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + + gDeferredPostNoDoFProgram.unbind(); + + // Clean up + gPipeline.setupHWLights(); + gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(false); + + return TRUE; +} + +void LLGLTFPreviewTexture::postRender(BOOL success) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + + if (!mShouldRender) { return; } + mShouldRender = false; + + LLViewerDynamicTexture::postRender(success); +} + +// static +LLPointer LLGLTFMaterialPreviewMgr::getPreview(LLPointer &material) +{ + if (!material) + { + return nullptr; + } + + if (!is_material_loaded_enough_for_ui(*material)) + { + return nullptr; + } + + return LLGLTFPreviewTexture::create(material); +} diff --git a/indra/newview/llgltfmaterialpreviewmgr.h b/indra/newview/llgltfmaterialpreviewmgr.h new file mode 100644 index 0000000000..cc40a6f2e2 --- /dev/null +++ b/indra/newview/llgltfmaterialpreviewmgr.h @@ -0,0 +1,82 @@ +/** + * @file llgltfmaterialpreviewmgr.h + * + * $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$ + */ + +#pragma once + +#include "lldrawpool.h" +#include "lldynamictexture.h" +#include "llfetchedgltfmaterial.h" +#include "llsingleton.h" +#include "lltexture.h" + +class LLGLTFPreviewTexture : public LLViewerDynamicTexture +{ +protected: + LLGLTFPreviewTexture(LLPointer material, S32 width); + +public: + // Width scales with size of material's textures + static LLPointer create(LLPointer material); + + BOOL needsRender() override { return mNeedsRender; } + void preRender(BOOL clear_depth = TRUE) override; + BOOL render() override; + void postRender(BOOL success) override; + + struct MaterialLoadLevels + { + S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT]; + + MaterialLoadLevels(); + + S32& operator[](size_t i); + + const S32& operator[](size_t i) const; + + // Less is better + // Returns false if lhs is not strictly less or equal for all levels + bool operator<(const MaterialLoadLevels& other) const; + + // Less is better + // Returns false if lhs is not strictly greater or equal for all levels + bool operator>(const MaterialLoadLevels& other) const; + }; + +private: + LLPointer mGLTFMaterial; + bool mNeedsRender = true; + bool mShouldRender = true; + MaterialLoadLevels mBestLoad; +}; + +class LLGLTFMaterialPreviewMgr +{ + public: + // Returns null if the material is not loaded yet. + // *NOTE: User should cache the texture if the same material is being previewed + LLPointer getPreview(LLPointer &material); +}; + +extern LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 69674417c1..84f6dd7a4f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -27,6 +27,9 @@ #include "llviewerprecompiledheaders.h" #include "llreflectionmapmanager.h" + +#include + #include "llviewercamera.h" #include "llspatialpartition.h" #include "llviewerregion.h" @@ -1383,3 +1386,32 @@ void LLReflectionMapManager::doOcclusion() } } } + +void LLReflectionMapManager::forceDefaultProbeAndUpdateUniforms(bool force) +{ + static std::bitset mProbeWasOccluded; + + if (force) + { + for (size_t i = 0; i < mProbes.size(); ++i) + { + auto& probe = mProbes[i]; + mProbeWasOccluded[i] = probe->mOccluded; + if (probe != nullptr && probe != mDefaultProbe) + { + probe->mOccluded = true; + } + } + + updateUniforms(); + } + else + { + for (size_t i = 0; i < mProbes.size(); ++i) + { + auto& probe = mProbes[i]; + llassert(probe->mOccluded == (probe != mDefaultProbe)); + probe->mOccluded = mProbeWasOccluded[i]; + } + } +} diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index b77a33da89..dd641452ae 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -106,6 +106,11 @@ public: // perform occlusion culling on all active reflection probes void doOcclusion(); + // *HACK: "cull" all reflection probes except the default one. Only call + // this if you don't intend to call updateUniforms directly. Call again + // with false when done. + void forceDefaultProbeAndUpdateUniforms(bool force = true); + private: friend class LLPipeline; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 233b864fba..b9cb00b561 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -72,6 +72,7 @@ #include "llradiogroup.h" #include "llfloaterreg.h" +#include "llgltfmaterialpreviewmgr.h" #include "lllocalbitmaps.h" #include "lllocalgltfmaterials.h" #include "llerror.h" @@ -657,6 +658,7 @@ void LLFloaterTexturePicker::draw() if( mOwner ) { mTexturep = NULL; + LLPointer old_material = mGLTFMaterial; mGLTFMaterial = NULL; if (mImageAssetID.notNull()) { @@ -664,10 +666,23 @@ void LLFloaterTexturePicker::draw() { mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID); llassert(mGLTFMaterial == nullptr || dynamic_cast(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr); + if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get()))) + { + // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview. + if (mGLTFMaterial.isNull()) + { + mGLTFPreview = nullptr; + } + else + { + mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial); + } + } } else { LLPointer texture = NULL; + mGLTFPreview = nullptr; if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { @@ -677,7 +692,7 @@ void LLFloaterTexturePicker::draw() if (obj) { LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); - texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; } } @@ -718,27 +733,29 @@ void LLFloaterTexturePicker::draw() // If the floater is focused, don't apply its alpha to the texture (STORM-677). const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - LLViewerTexture* texture = nullptr; + LLViewerTexture* preview = nullptr; if (mGLTFMaterial) { - texture = mGLTFMaterial->getUITexture(); + preview = mGLTFPreview.get(); } else { - texture = mTexturep.get(); + preview = mTexturep.get(); + if (mTexturep) + { + // Pump the priority + mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); + } } - if( texture ) + if( preview ) { - if( texture->getComponents() == 4 ) + if( preview->getComponents() == 4 ) { gl_rect_2d_checkerboard( interior, alpha ); } - gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), texture, UI_VERTEX_COLOR % alpha ); - - // Pump the priority - texture->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); + gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha ); } else if (!mFallbackImage.isNull()) { @@ -2156,48 +2173,69 @@ void LLTextureCtrl::draw() { mBorder->setKeyboardFocusHighlight(hasFocus()); + LLPointer preview = NULL; + if (!mValid) { mTexturep = NULL; + mGLTFMaterial = NULL; + mGLTFPreview = NULL; } else if (!mImageAssetID.isNull()) { - LLPointer texture = NULL; - if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (obj) { LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); - texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + mTexturep = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + mGLTFMaterial = NULL; + mGLTFPreview = NULL; + + preview = mTexturep; } } - if (texture.isNull()) + if (preview.isNull()) { + LLPointer old_material = mGLTFMaterial; + mGLTFMaterial = NULL; + mTexturep = NULL; if (mInventoryPickType == PICK_MATERIAL) { - LLPointer material = gGLTFMaterialList.getMaterial(mImageAssetID); - if (material) + mGLTFMaterial = gGLTFMaterialList.getMaterial(mImageAssetID); + if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get()))) { - texture = material->getUITexture(); + // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview. + if (mGLTFMaterial.isNull()) + { + mGLTFPreview = nullptr; + } + else + { + mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial); + } } + + preview = mGLTFPreview; } else { - texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW); - texture->forceToSaveRawImage(0); + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + mTexturep->forceToSaveRawImage(0); + + preview = mTexturep; } } - - mTexturep = texture; } else//mImageAssetID == LLUUID::null { mTexturep = NULL; + mGLTFMaterial = NULL; + mGLTFPreview = NULL; } // Border @@ -2210,15 +2248,18 @@ void LLTextureCtrl::draw() // If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677). const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - if( mTexturep ) + if( preview ) { - if( mTexturep->getComponents() == 4 ) + if( preview->getComponents() == 4 ) { gl_rect_2d_checkerboard( interior, alpha ); } - gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha); - mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); + gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha); + if (mTexturep) + { + mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); + } } else if (!mFallbackImage.isNull()) { diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index cb6ce636e0..77919637ac 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -250,6 +250,8 @@ private: commit_callback_t mOnCloseCallback; texture_selected_callback mOnTextureSelectedCallback; LLPointer mTexturep; + LLPointer mGLTFMaterial; + LLPointer mGLTFPreview; LLUIColor mBorderColor; LLUUID mImageItemID; LLUUID mImageAssetID; @@ -382,6 +384,7 @@ protected: LLPointer mTexturep; LLPointer mGLTFMaterial; + LLPointer mGLTFPreview; LLView* mOwner; LLUUID mImageAssetID; // Currently selected texture diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3882472b49..f34d5360e2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -163,6 +163,7 @@ F32 LLPipeline::CameraFocusTransitionTime; F32 LLPipeline::CameraFNumber; F32 LLPipeline::CameraFocalLength; F32 LLPipeline::CameraFieldOfView; +S32 LLPipeline::RenderLocalLightCount; F32 LLPipeline::RenderShadowNoise; F32 LLPipeline::RenderShadowBlurSize; F32 LLPipeline::RenderSSAOScale; @@ -200,6 +201,8 @@ S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples; S32 LLPipeline::RenderBufferVisualization; LLTrace::EventStatHandle LLPipeline::sStatBatchSize("renderbatchsize"); +const U32 LLPipeline::MAX_BAKE_WIDTH = 512; + const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; const F32 ALPHA_BLEND_CUTOFF = 0.598f; @@ -521,6 +524,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("CameraFNumber"); connectRefreshCachedSettingsSafe("CameraFocalLength"); connectRefreshCachedSettingsSafe("CameraFieldOfView"); + connectRefreshCachedSettingsSafe("RenderLocalLightCount"); connectRefreshCachedSettingsSafe("RenderShadowNoise"); connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); connectRefreshCachedSettingsSafe("RenderSSAOScale"); @@ -1009,6 +1013,7 @@ void LLPipeline::refreshCachedSettings() CameraFNumber = gSavedSettings.getF32("CameraFNumber"); CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); + RenderLocalLightCount = gSavedSettings.getS32("RenderLocalLightCount"); RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); @@ -1072,7 +1077,6 @@ void LLPipeline::releaseGLBuffers() releaseLUTBuffers(); mWaterDis.release(); - mBake.release(); mSceneMap.release(); @@ -1151,9 +1155,6 @@ void LLPipeline::createGLBuffers() stop_glerror(); assertInitialized(); - // Use FBO for bake tex - mBake.allocate(512, 512, GL_RGBA, true); // SL-12781 Build > Upload > Model; 3D Preview - stop_glerror(); GLuint resX = gViewerWindow->getWorldViewWidthRaw(); @@ -5227,7 +5228,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) return; } - static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); + const S32 local_light_count = LLPipeline::RenderLocalLightCount; if (local_light_count >= 1) { @@ -5496,7 +5497,7 @@ void LLPipeline::setupHWLights() mLightMovingMask = 0; - static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); + const S32 local_light_count = LLPipeline::RenderLocalLightCount; if (local_light_count >= 1) { @@ -7930,7 +7931,7 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSoftenProgram); } - static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); + const S32 local_light_count = LLPipeline::RenderLocalLightCount; if (local_light_count > 0) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 88a7eab813..dd5040f76e 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -694,6 +694,7 @@ public: RenderTargetPack mMainRT; // auxillary 512x512 render target pack + // used by reflection probes and dynamic texture bakes RenderTargetPack mAuxillaryRT; // currently used render target pack @@ -754,7 +755,7 @@ public: //water distortion texture (refraction) LLRenderTarget mWaterDis; - LLRenderTarget mBake; + static const U32 MAX_BAKE_WIDTH; //texture for making the glow LLRenderTarget mGlow[3]; @@ -1012,6 +1013,7 @@ public: static F32 CameraFNumber; static F32 CameraFocalLength; static F32 CameraFieldOfView; + static S32 RenderLocalLightCount; static F32 RenderShadowNoise; static F32 RenderShadowBlurSize; static F32 RenderSSAOScale; -- cgit v1.2.3 From 8a3d82dd5fb6a9c5003a60a67e1c8c204caa67ab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 18 Jan 2024 16:22:20 -0800 Subject: SL-20606: Reuse vertex buffer between preview renders. Fix preview sometimes zoomed in too much. Miscellaneous cleanup --- .../class1/deferred/postDeferredNoDoFF.glsl | 4 -- indra/newview/llgltfmaterialpreviewmgr.cpp | 76 ++++++++++++++++++---- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index cd4ae8110a..bace9b8c90 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -37,11 +37,7 @@ void main() { vec4 diff = texture(diffuseRect, vary_fragcoord.xy); -#if 1 frag_color = diff; -#else - frag_color = vec4(1,0,1,1); -#endif gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r; } diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 9ef1bbf884..a8ea3429f4 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -27,6 +27,7 @@ #include "llgltfmaterialpreviewmgr.h" +#include #include #include "llavatarappearancedefines.h" @@ -210,12 +211,22 @@ struct GLTFPreviewModel { mDrawInfo->mModelMatrix = &mModelMatrix; } + GLTFPreviewModel(GLTFPreviewModel&) = delete; + ~GLTFPreviewModel() + { + // No model matrix necromancy + llassert(gGLLastMatrix != &mModelMatrix); + gGLLastMatrix = nullptr; + } LLPointer mDrawInfo; LLMatrix4 mModelMatrix; // Referenced by mDrawInfo }; +using PreviewSpherePart = std::unique_ptr; +using PreviewSphere = std::vector; + // Like LLVolumeGeometryManager::registerFace but without batching or too-many-indices/vertices checking. -std::vector create_preview_sphere(LLPointer& material, const LLMatrix4& model_matrix) +PreviewSphere create_preview_sphere(LLPointer& material, const LLMatrix4& model_matrix) { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; @@ -239,7 +250,7 @@ std::vector create_preview_sphere(LLPointer preview_sphere; + PreviewSphere preview_sphere; preview_sphere.reserve(volume->getNumFaces()); LLPointer buf = new LLVertexBuffer( @@ -299,7 +310,7 @@ std::vector create_preview_sphere(LLPointer info = new LLDrawInfo(U16(vertex_offset), U16(vertex_offset + face.mNumVertices - 1), face.mNumIndices, index_offset, no_media, buf.get()); info->mGLTFMaterial = material; - preview_sphere.emplace_back(info, model_matrix); + preview_sphere.emplace_back(std::make_unique(info, model_matrix)); index_offset += face.mNumIndices; vertex_offset += face.mNumVertices; } @@ -309,6 +320,44 @@ std::vector create_preview_sphere(LLPointer& material) +{ + llassert(!preview_sphere.empty()); + if (preview_sphere.empty()) { return; } + + const LLColor4U vertex_color(material->mBaseColor); + + // See comments about unmapBuffer in llvertexbuffer.h + for (PreviewSpherePart& part : preview_sphere) + { + LLDrawInfo* info = part->mDrawInfo.get(); + info->mGLTFMaterial = material; + LLVertexBuffer* buf = info->mVertexBuffer.get(); + LLStrider colors; + const S32 count = info->mEnd - info->mStart; + buf->getColorStrider(colors, info->mStart, count); + for (S32 i = 0; i < count; ++i) + { + *colors++ = vertex_color; + } + buf->unmapBuffer(); + } +} + +PreviewSphere& get_preview_sphere(LLPointer& material, const LLMatrix4& model_matrix) +{ + static PreviewSphere preview_sphere; + if (preview_sphere.empty()) + { + preview_sphere = create_preview_sphere(material, model_matrix); + } + else + { + set_preview_sphere_material(preview_sphere, material); + } + return preview_sphere; +} + // Final, direct modifications to shader constants, just before render void fixup_shader_constants(LLGLSLShader& shader) { @@ -354,10 +403,14 @@ BOOL LLGLTFPreviewTexture::render() LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (!mShouldRender) { return FALSE; } + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); LLGLDepthTest(GL_FALSE); LLGLDisable stencil(GL_STENCIL_TEST); LLGLDisable scissor(GL_SCISSOR_TEST); + SetTemporarily no_dof(&LLPipeline::RenderDepthOfField, false); SetTemporarily no_glow(&LLPipeline::sRenderGlow, false); SetTemporarily no_ssr(&LLPipeline::RenderScreenSpaceReflections, false); SetTemporarily no_fxaa(&LLPipeline::RenderFSAASamples, U32(0)); @@ -393,11 +446,7 @@ BOOL LLGLTFPreviewTexture::render() // Generate sphere object on-the-fly. Discard afterwards. (Vertex buffer is // discarded, but the sphere should be cached in LLVolumeMgr.) - std::vector preview_sphere = create_preview_sphere(mGLTFMaterial, object_transform); - - glClearColor(0, 0, 0, 0); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + PreviewSphere& preview_sphere = get_preview_sphere(mGLTFMaterial, object_transform); gPipeline.setupHWLights(); glh::matrix4f mat = copy_matrix(gGLModelView); @@ -415,10 +464,13 @@ BOOL LLGLTFPreviewTexture::render() LLRenderTarget& screen = gPipeline.mAuxillaryRT.screen; + // *HACK: Force reset of the model matrix + gGLLastMatrix = nullptr; + #if 0 if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE || mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) { - // *TODO: Opaque/alpha mask rendering (gDeferredPBROpaqueProgram) + // *TODO: Opaque/alpha mask rendering } else #endif @@ -433,9 +485,9 @@ BOOL LLGLTFPreviewTexture::render() gPipeline.bindDeferredShader(shader); fixup_shader_constants(shader); - for (GLTFPreviewModel& part : preview_sphere) + for (PreviewSpherePart& part : preview_sphere) { - LLRenderPass::pushGLTFBatch(*part.mDrawInfo); + LLRenderPass::pushGLTFBatch(*part->mDrawInfo); } gPipeline.unbindDeferredShader(shader); @@ -453,6 +505,8 @@ BOOL LLGLTFPreviewTexture::render() gPipeline.renderDoF(&screen, &gPipeline.mPostMap); gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); + // Final render + gDeferredPostNoDoFProgram.bind(); // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems." -- cgit v1.2.3 From 529d56ed9cc0b8399df79af40bea44431fc1def5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 19 Jan 2024 17:09:11 -0800 Subject: SL-20606: Fix cached probe flags for material preview potentially exceeding storage bounds --- indra/newview/llreflectionmapmanager.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 84f6dd7a4f..2b6985b214 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -28,7 +28,7 @@ #include "llreflectionmapmanager.h" -#include +#include #include "llviewercamera.h" #include "llspatialpartition.h" @@ -1389,14 +1389,16 @@ void LLReflectionMapManager::doOcclusion() void LLReflectionMapManager::forceDefaultProbeAndUpdateUniforms(bool force) { - static std::bitset mProbeWasOccluded; + static std::vector mProbeWasOccluded; if (force) { + llassert(mProbeWasOccluded.empty()); + for (size_t i = 0; i < mProbes.size(); ++i) { auto& probe = mProbes[i]; - mProbeWasOccluded[i] = probe->mOccluded; + mProbeWasOccluded.push_back(probe->mOccluded); if (probe != nullptr && probe != mDefaultProbe) { probe->mOccluded = true; @@ -1407,11 +1409,16 @@ void LLReflectionMapManager::forceDefaultProbeAndUpdateUniforms(bool force) } else { - for (size_t i = 0; i < mProbes.size(); ++i) + llassert(mProbes.size() == mProbeWasOccluded.size()); + + const size_t n = llmin(mProbes.size(), mProbeWasOccluded.size()); + for (size_t i = 0; i < n; ++i) { auto& probe = mProbes[i]; llassert(probe->mOccluded == (probe != mDefaultProbe)); probe->mOccluded = mProbeWasOccluded[i]; } + mProbeWasOccluded.clear(); + mProbeWasOccluded.shrink_to_fit(); } } -- cgit v1.2.3 From 42623ad81142f93290b31b380cc0f888a1c3c3b6 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 19 Jan 2024 17:11:54 -0800 Subject: SL-20606: Fix no material preview on OpenGL 3.2 --- indra/newview/pipeline.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f34d5360e2..53be4c135e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -768,10 +768,13 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - if (mRT == &mMainRT && sReflectionProbesEnabled) + if (mRT == &mMainRT) { // hacky -- allocate auxillary buffer - gCubeSnapshot = TRUE; - mReflectionMapManager.initReflectionMaps(); + if (sReflectionProbesEnabled) + { + gCubeSnapshot = TRUE; + mReflectionMapManager.initReflectionMaps(); + } mRT = &mAuxillaryRT; U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled allocateScreenBuffer(res, res, samples); -- cgit v1.2.3 From 0625516e3838b940d3ed4be1167b7def147f5d22 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 22 Jan 2024 11:58:48 -0600 Subject: https://github.com/secondlife/viewer-issues/issues/22 partial build fix --- indra/newview/llviewershadermgr.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f9c2906170..6495692e9a 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1275,7 +1275,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBRTerrainProgram.mFeatures.hasSrgb = true; gDeferredPBRTerrainProgram.mFeatures.isAlphaLighting = true; gDeferredPBRTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredPBRTerrainProgram.mFeatures.hasWaterFog = true; gDeferredPBRTerrainProgram.mFeatures.calculatesAtmospherics = true; gDeferredPBRTerrainProgram.mFeatures.hasAtmospherics = true; gDeferredPBRTerrainProgram.mFeatures.hasGamma = true; -- cgit v1.2.3 From 210d9204813318f55fb39505fda88d4a3544ae0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 22 Jan 2024 20:43:53 +0200 Subject: Build fix for issues/22 --- indra/newview/lltexturectrl.cpp | 12 ++++++------ indra/newview/lltexturectrl.h | 28 ++++++++-------------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index c330696fb2..368222f7a0 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -2367,12 +2367,12 @@ LLSD LLTextureCtrl::getValue() const namespace LLInitParam { - void TypeValues::declareValues() - { - declare("texture_material", LLTextureCtrl::PICK_TEXTURE_MATERIAL); - declare("texture", LLTextureCtrl::PICK_TEXTURE); - declare("material", LLTextureCtrl::PICK_MATERIAL); - } + void TypeValues::declareValues() + { + declare("texture_material", PICK_TEXTURE_MATERIAL); + declare("texture", PICK_TEXTURE); + declare("material", PICK_MATERIAL); + } } diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index d71566c526..5c7091a9b5 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -64,17 +64,18 @@ bool get_is_predefined_texture(LLUUID asset_id); LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false); bool get_can_copy_texture(LLUUID image_id); -enum class LLTexPickInventoryType : U32 + +typedef enum e_pick_inventory_type { - TEXTURE_MATERIAL = 0, - TEXTURE = 1, - MATERIAL = 2, -}; + PICK_TEXTURE_MATERIAL = 0, + PICK_TEXTURE = 1, + PICK_MATERIAL = 2, +} EPickInventoryType; namespace LLInitParam { template<> - struct TypeValues : public TypeValuesHelper + struct TypeValues : public TypeValuesHelper { static void declareValues(); }; @@ -88,13 +89,6 @@ enum LLPickerSource PICKER_UNKNOWN, // on cancel, default ids }; -typedef enum e_pick_inventory_type -{ - PICK_TEXTURE_MATERIAL = 0, - PICK_TEXTURE = 1, - PICK_MATERIAL = 2, -} EPickInventoryType; - ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl @@ -110,12 +104,6 @@ public: TEXTURE_CANCEL } ETexturePickOp; - // *HACK: Can't forward-declare an enum scoped inside a class. Maybe there's a better way to initialize LLInitParam::TypeValues that doesn't run into this limitation. - typedef LLTexPickInventoryType EPickInventoryType; - static const EPickInventoryType PICK_TEXTURE_MATERIAL = LLTexPickInventoryType::TEXTURE_MATERIAL; - static const EPickInventoryType PICK_TEXTURE = LLTexPickInventoryType::TEXTURE; - static const EPickInventoryType PICK_MATERIAL = LLTexPickInventoryType::MATERIAL; - public: struct Params : public LLInitParam::Block { @@ -140,7 +128,7 @@ public: : image_id("image"), default_image_id("default_image_id"), default_image_name("default_image_name"), - pick_type("pick_type", LLTexPickInventoryType::TEXTURE), + pick_type("pick_type", PICK_TEXTURE), allow_no_texture("allow_no_texture", false), can_apply_immediately("can_apply_immediately"), no_commit_on_selection("no_commit_on_selection", false), -- cgit v1.2.3 From 7b0372ac1f6191ef9216296cef2f476caadee40c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 23 Jan 2024 13:12:54 -0800 Subject: Put PBR terrain behind feature flag --- indra/newview/app_settings/settings.xml | 11 ++++++ indra/newview/llfloaterregioninfo.cpp | 41 ++++++++++++++-------- .../skins/default/xui/en/panel_region_terrain.xml | 16 ++++++++- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 578bb02387..df30b8d298 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10833,6 +10833,17 @@ Value 12.0 + RenderTerrainPBREnabled + + Comment + EXPERIMENTAL: Enable PBR Terrain features. Requires restart. + Persist + 1 + Type + Boolean + Value + 0 + RenderTerrainPBRDetail Comment diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 15ac46dc21..2c743d596e 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1441,32 +1441,45 @@ BOOL LLPanelRegionTerrainInfo::postBuild() mAskedTextureHeights = false; mConfirmedTextureHeights = false; + refresh(); + return LLPanelRegionInfo::postBuild(); } // virtual void LLPanelRegionTerrainInfo::refresh() { - std::string buffer; + // For simplicity, require restart + static BOOL feature_pbr_terrain_enabled = gSavedSettings.getBOOL("RenderTerrainPBREnabled"); - bool has_material_assets = false; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - LLTextureCtrl* material_ctrl = getChild(buffer); - if (material_ctrl && material_ctrl->getImageAssetID().notNull()) - { - has_material_assets = true; - break; - } - } + LLTextBox* texture_text = getChild("detail_texture_text"); + if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); } LLComboBox* material_type_ctrl = getChild("terrain_material_type"); if (material_type_ctrl) { - const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + material_type_ctrl->setVisible(feature_pbr_terrain_enabled); + + bool has_material_assets = false; + + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + LLTextureCtrl* material_ctrl = getChild(buffer); + if (material_ctrl && material_ctrl->getImageAssetID().notNull()) + { + has_material_assets = true; + break; + } + } + + TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); + + if (!feature_pbr_terrain_enabled) { material_type = TerrainMaterialType::TEXTURE; } + const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; - material_type_ctrl->setEnabled(!(is_material_selected && has_material_assets)); + material_type_ctrl->setEnabled(feature_pbr_terrain_enabled && !(is_material_selected && has_material_assets)); } } diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index e36fb05647..88855ab739 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -92,6 +92,20 @@ name="PBRMaterials" value="PBRMaterials" /> + + Terrain Textures + Maximum size: 1024x1024 -- cgit v1.2.3 From 79f5231db23dfa22d8981940864d1f3a450e3e02 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 23 Jan 2024 15:45:33 -0600 Subject: Create test plan for optimizeAwayAlpha (#663) --- doc/testplans/optimize_away_alpha.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 doc/testplans/optimize_away_alpha.md diff --git a/doc/testplans/optimize_away_alpha.md b/doc/testplans/optimize_away_alpha.md new file mode 100644 index 0000000000..f0c8d1e8d6 --- /dev/null +++ b/doc/testplans/optimize_away_alpha.md @@ -0,0 +1,5 @@ +Textures imported via Build->Upload->Material that have an all opaque (255) alpha channel should have their alpha channel removed before upload. + +1. Make 4 images that have different colors but all 255 alpha channels +2. Upload them all using Build->Upload->Material, with one in each of the material texture slots +3. Verify that using the textures as a blinn-phong diffuse map does not make the corresponding face render in the alpha pass (face should stay visible after disabling alpha pass by unchecking Advanced->Render Types->Alpha). -- cgit v1.2.3 From 869712e273caa0a655f7b6a1f189a8bc6399f51d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 17 Jan 2024 20:06:56 +0200 Subject: SL-20669 Move constants out of settings.xml UIImgInvisibleUUID doesn't exist Default normal for material is 'null' --- indra/llcommon/indra_constants.cpp | 6 +++ indra/llcommon/indra_constants.h | 5 +++ indra/newview/app_settings/settings.xml | 55 ---------------------------- indra/newview/llfloaterenvironmentadjust.cpp | 2 +- indra/newview/llmaterialeditor.cpp | 4 +- indra/newview/llpaneleditwater.cpp | 2 +- indra/newview/llpanelface.cpp | 10 ++--- indra/newview/lltexturectrl.cpp | 11 +++--- 8 files changed, 25 insertions(+), 70 deletions(-) diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index 1b48e4daf3..473b3ebdc9 100644 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp @@ -50,6 +50,7 @@ const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver +const LLUUID IMG_WHITE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver @@ -71,6 +72,11 @@ const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // V const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER +const LLUUID DEFAULT_OBJECT_TEXTURE ("89556747-24cb-43ed-920b-47caed15465f"); // On dataserver +const LLUUID DEFAULT_OBJECT_SPECULAR ("87e0e8f7-8729-1ea8-cfc9-8915773009db"); // On dataserver +const LLUUID DEFAULT_OBJECT_NORMAL ("85f28839-7a1c-b4e3-d71d-967792970a7b"); // On dataserver +const LLUUID BLANK_OBJECT_NORMAL ("5b53359e-59dd-d8a2-04c3-9e65134da47a"); // VIEWER (has a verion on dataserver, but with compression artifacts) + const LLUUID IMG_USE_BAKED_HEAD ("5a9f4a74-30f2-821c-b88d-70499d3e7183"); const LLUUID IMG_USE_BAKED_UPPER ("ae2de45c-d252-50b8-5c6e-19f39ce79317"); const LLUUID IMG_USE_BAKED_LOWER ("24daea5f-0539-cfcf-047f-fbc40b2786ba"); diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 679f79039b..a16cfac2b9 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -197,6 +197,7 @@ LL_COMMON_API extern const LLUUID IMG_FIRE; LL_COMMON_API extern const LLUUID IMG_FACE_SELECT; LL_COMMON_API extern const LLUUID IMG_DEFAULT_AVATAR; LL_COMMON_API extern const LLUUID IMG_INVISIBLE; +LL_COMMON_API extern const LLUUID IMG_WHITE; LL_COMMON_API extern const LLUUID IMG_EXPLOSION; LL_COMMON_API extern const LLUUID IMG_EXPLOSION_2; @@ -230,6 +231,10 @@ LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX3; LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; +LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_TEXTURE; +LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_SPECULAR; +LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_NORMAL; +LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL; // radius within which a chat message is fully audible const F32 CHAT_NORMAL_RADIUS = 20.f; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 77ca52a7f7..3d43a20c21 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3244,17 +3244,6 @@ Value 0 - DefaultBlankNormalTexture - - Comment - Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference) - Persist - 1 - Type - String - Value - 5b53359e-59dd-d8a2-04c3-9e65134da47a - DefaultFemaleAvatar Comment @@ -3288,39 +3277,6 @@ Value Male Shape & Outfit - DefaultObjectNormalTexture - - Comment - Texture used as 'Default' in texture picker for normal map. (UUID texture reference) - Persist - 1 - Type - String - Value - 85f28839-7a1c-b4e3-d71d-967792970a7b - - DefaultObjectSpecularTexture - - Comment - Texture used as 'Default' in texture picker for specular map. (UUID texture reference) - Persist - 1 - Type - String - Value - 87e0e8f7-8729-1ea8-cfc9-8915773009db - - DefaultObjectTexture - - Comment - Texture used as 'Default' in texture picker. (UUID texture reference) - Persist - 1 - Type - String - Value - 89556747-24cb-43ed-920b-47caed15465f - DefaultUploadCost Comment @@ -13620,17 +13576,6 @@ Value F3E07BC8-A973-476D-8C7F-F3B7293975D1 - UIImgWhiteUUID - - Comment - - Persist - 0 - Type - String - Value - 5748decc-f629-461c-9a36-a35a221fe21f - UILineEditorCursorThickness Comment diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index c64ee5a69c..c98afefa65 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -116,7 +116,7 @@ BOOL LLFloaterEnvironmentAdjust::postBuild() getChild(FIELD_SKY_CLOUD_MAP)->setAllowNoTexture(TRUE); getChild(FIELD_WATER_NORMAL_MAP)->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId()); - getChild(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture"))); + getChild(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(BLANK_OBJECT_NORMAL); getChild(FIELD_WATER_NORMAL_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onWaterMapChanged(); }); getChild(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); }); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 34f2f77d25..b7828db3a9 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -449,9 +449,7 @@ BOOL LLMaterialEditor::postBuild() mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY)); mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY)); - // should match normal textures from mBumpyTextureCtrl - mNormalTextureCtrl->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("DefaultObjectNormalTexture"))); - mNormalTextureCtrl->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture"))); + mNormalTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL); if (mIsOverride) { diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp index a09964e17d..cf536dd87e 100644 --- a/indra/newview/llpaneleditwater.cpp +++ b/indra/newview/llpaneleditwater.cpp @@ -89,7 +89,7 @@ BOOL LLPanelSettingsWaterMainTab::postBuild() getChild(FIELD_WATER_UNDERWATER_MOD)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogUnderWaterChanged(); }); mTxtNormalMap->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId()); - mTxtNormalMap->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); + mTxtNormalMap->setBlankImageAssetID(BLANK_OBJECT_NORMAL); mTxtNormalMap->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalMapChanged(); }); getChild(FIELD_WATER_WAVE2_XY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSmallWaveChanged(); }); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 269ae23eb8..7979261bae 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -353,7 +353,7 @@ BOOL LLPanelFace::postBuild() mShinyTextureCtrl = getChild("shinytexture control"); if(mShinyTextureCtrl) { - mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" ))); + mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR); mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) ); mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) ); mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); @@ -370,8 +370,8 @@ BOOL LLPanelFace::postBuild() mBumpyTextureCtrl = getChild("bumpytexture control"); if(mBumpyTextureCtrl) { - mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" ))); - mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); + mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL); + mBumpyTextureCtrl->setBlankImageAssetID(BLANK_OBJECT_NORMAL); mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) ); mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) ); mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); @@ -4413,7 +4413,7 @@ void LLPanelFace::onCopyTexture() LLUUID id = mat_data["NormMap"].asUUID(); if (id.notNull() && !get_can_copy_texture(id)) { - mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + mat_data["NormMap"] = DEFAULT_OBJECT_TEXTURE; mat_data["NormMapNoCopy"] = true; } @@ -4423,7 +4423,7 @@ void LLPanelFace::onCopyTexture() LLUUID id = mat_data["SpecMap"].asUUID(); if (id.notNull() && !get_can_copy_texture(id)) { - mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + mat_data["SpecMap"] = DEFAULT_OBJECT_TEXTURE; mat_data["SpecMapNoCopy"] = true; } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 233b864fba..62d3fa28bf 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -82,9 +82,11 @@ //static bool get_is_predefined_texture(LLUUID asset_id) { - if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) - || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) - || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + if (asset_id == DEFAULT_OBJECT_TEXTURE + || asset_id == DEFAULT_OBJECT_SPECULAR + || asset_id == DEFAULT_OBJECT_NORMAL + || asset_id == BLANK_OBJECT_NORMAL + || asset_id == IMG_WHITE || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) { return true; @@ -1646,8 +1648,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) // Default of defaults is white image for diff tex // - LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) ); - setBlankImageAssetID( whiteImage ); + setBlankImageAssetID(IMG_WHITE); setAllowNoTexture(p.allow_no_texture); setCanApplyImmediately(p.can_apply_immediately); -- cgit v1.2.3 From ea4dc1f35d9515cc8e130e4246eb08f7558c421b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 17 Jan 2024 20:08:14 +0200 Subject: SL-20669 Force blank normal id into a local blank normal texture Dataserver's version has compression artifacts --- indra/newview/llviewertexturelist.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9a6d40ab0a..ebf03ae988 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -121,8 +121,17 @@ void LLViewerTextureList::doPreloadImages() LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); LLUIImageList* image_list = LLUIImageList::getInstance(); - // Set the default flat normal map - LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP); + // Set the default flat normal map + // BLANK_OBJECT_NORMAL has a version on dataserver, but it has compression artifacts + LLViewerFetchedTexture::sFlatNormalImagep = + LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", + FTT_LOCAL_FILE, + MIPMAP_NO, + LLViewerFetchedTexture::BOOST_BUMP, + LLViewerTexture::FETCHED_TEXTURE, + 0, + 0, + BLANK_OBJECT_NORMAL); // PBR: irradiance LLViewerFetchedTexture::sDefaultIrradiancePBRp = LLViewerTextureManager::getFetchedTextureFromFile("default_irradiance.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); -- cgit v1.2.3 From 4d39d889976dcc3b7aa7098bc70ab7ebb881c0a8 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 24 Jan 2024 15:50:13 -0800 Subject: https://github.com/secondlife/viewer/issues/671 Wire up the RenderMirrors debug setting. --- indra/newview/app_settings/settings.xml | 2 +- .../app_settings/shaders/class3/deferred/softenLightF.glsl | 11 ++++++----- indra/newview/llheroprobemanager.cpp | 2 +- indra/newview/llviewershadermgr.cpp | 5 ++++- indra/newview/pipeline.cpp | 14 ++++++++++---- indra/newview/pipeline.h | 1 + 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 493ccec560..242e274daf 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9206,7 +9206,7 @@ Type Boolean Value - 1 + 0 RenderScreenSpaceReflections diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index f5541df227..79d9000482 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -34,11 +34,13 @@ uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal uniform samplerCubeArray heroProbes; +#if defined(HERO_PROBES) layout (std140) uniform HeroProbeData { vec4 heroPosition[1]; int heroProbeCount; }; +#endif const float M_PI = 3.14159265; @@ -196,15 +198,12 @@ void main() vec3 v = -normalize(pos.xyz); color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); + #ifdef HERO_PROBES vec3 refnormpersp = reflect(pos.xyz, norm.xyz); if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_MIRROR)) color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; - - if (do_atmospherics) - { - color = atmosFragLightingLinear(color, additive, atten); - } + #endif } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { @@ -263,7 +262,9 @@ void main() // add radiance map applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); + #ifdef HERO_PROBES color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - spec.a) * 11).xyz * spec.rgb; + #endif } diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index b6db123cd9..fdf782adee 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -67,7 +67,7 @@ LLHeroProbeManager::LLHeroProbeManager() // helper class to seed octree with probes void LLHeroProbeManager::update() { - if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE) + if (!LLPipeline::RenderMirrors || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE) { return; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 693297d1e1..48c54f3dcc 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1805,7 +1805,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1"); } - gDeferredSoftenProgram.addPermutation("HERO_PROBES", "1"); + if (LLPipeline::RenderMirrors) + { + gDeferredSoftenProgram.addPermutation("HERO_PROBES", "1"); + } if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { //if using SSAO, take screen space light map into account as if shadows are enabled diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9e6af24f80..94f2dc4a2a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -199,6 +199,7 @@ F32 LLPipeline::RenderScreenSpaceReflectionDepthRejectBias; F32 LLPipeline::RenderScreenSpaceReflectionAdaptiveStepMultiplier; S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples; S32 LLPipeline::RenderBufferVisualization; +bool LLPipeline::RenderMirrors; LLTrace::EventStatHandle LLPipeline::sStatBatchSize("renderbatchsize"); const U32 LLPipeline::MAX_BAKE_WIDTH = 512; @@ -559,6 +560,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionAdaptiveStepMultiplier"); connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionGlossySamples"); connectRefreshCachedSettingsSafe("RenderBufferVisualization"); + connectRefreshCachedSettingsSafe("RenderMirrors"); gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } @@ -1058,6 +1060,7 @@ void LLPipeline::refreshCachedSettings() RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier"); RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples"); RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization"); + RenderMirrors = gSavedSettings.getBOOL("RenderMirrors"); sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled"); RenderSpotLight = nullptr; @@ -8645,11 +8648,14 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) bound = true; } - channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); - if (channel > -1 && mHeroProbeManager.mTexture.notNull()) + if (RenderMirrors) { - mHeroProbeManager.mTexture->bind(channel); - bound = true; + channel = shader.enableTexture(LLShaderMgr::HERO_PROBE, LLTexUnit::TT_CUBE_MAP_ARRAY); + if (channel > -1 && mHeroProbeManager.mTexture.notNull()) + { + mHeroProbeManager.mTexture->bind(channel); + bound = true; + } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 30bc95ad19..21c1d9a25d 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -1051,6 +1051,7 @@ public: static F32 RenderScreenSpaceReflectionAdaptiveStepMultiplier; static S32 RenderScreenSpaceReflectionGlossySamples; static S32 RenderBufferVisualization; + static bool RenderMirrors; }; void render_bbox(const LLVector3 &min, const LLVector3 &max); -- cgit v1.2.3 From 42b51bfd2cccba1dfdc820a4a033481fd42c1907 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 24 Jan 2024 16:02:31 -0800 Subject: https://github.com/secondlife/viewer-issues/issues/23 Fix for merge up to the featurettes branch, and reflection probes being "hazy" --- .../shaders/class3/deferred/softenLightF.glsl | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 79d9000482..f1de0b88d6 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -114,8 +114,8 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 additive, vec3 atten); -vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, - float perceptualRoughness, +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, float metallic, vec3 n, // normal vec3 v, // surface point to camera @@ -176,9 +176,9 @@ void main() vec3 irradiance = vec3(0); vec3 radiance = vec3(0); - if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR) || GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_MIRROR)) + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { - vec3 orm = texture(specularRect, tc).rgb; + vec3 orm = texture(specularRect, tc).rgb; float perceptualRoughness = orm.g; float metallic = orm.b; float ao = orm.r; @@ -275,12 +275,7 @@ void main() applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); } } - - #ifdef WATER_FOG - vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); - color = fogged.rgb; - #endif - + frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results frag_color.a = 0.0; } -- cgit v1.2.3 From a888531fd1fbf7de0d71b4d04195d4267c882154 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 24 Jan 2024 16:22:45 -0800 Subject: https://github.com/secondlife/viewer-issues/issues/23 Make the face selection for mirrors actually reflect what it does --- indra/newview/llheroprobemanager.cpp | 2 +- indra/newview/llviewerobject.cpp | 8 ++++---- indra/newview/llviewerobject.h | 4 ++-- indra/newview/llvovolume.cpp | 4 ++-- indra/newview/llvovolume.h | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index fdf782adee..1ecafd4f54 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -138,7 +138,7 @@ void LLHeroProbeManager::update() if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { - U8 mode = mNearestHero->mirrorPlacementMode(); + U8 mode = mNearestHero->mirrorFace(); mode = llmin(mNearestHero->mDrawable->getNumFaces() - 1, mode); mCurrentFace = mNearestHero->mDrawable->getFace(mode); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 88494f419c..691a2e14d3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -314,8 +314,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mCachedMuteListUpdateTime(0), mCachedOwnerInMuteList(false), mRiggedAttachedWarned(false), -mIsMirror(false), -mMirrorPlacementMode(3) + mIsMirror(false), + mMirrorFace(3) { if (!is_global) { @@ -1558,7 +1558,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, std::string temp_string; mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num ); - detectMirror(temp_string, mIsMirror, mMirrorPlacementMode); + detectMirror(temp_string, mIsMirror, mMirrorFace); LLColor4U coloru; mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num); @@ -1946,7 +1946,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, std::string temp_string; dp->unpackString(temp_string, "Text"); - detectMirror(temp_string, mIsMirror, mMirrorPlacementMode); + detectMirror(temp_string, mIsMirror, mMirrorFace); LLColor4U coloru; dp->unpackBinaryDataFixed(coloru.mV, 4, "Color"); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 6ed37bf014..f3c00e83dc 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -258,7 +258,7 @@ public: virtual BOOL hasLightTexture() const { return FALSE; } virtual BOOL isReflectionProbe() const { return FALSE; } virtual BOOL isMirror() const { return FALSE; } - virtual U8 mirrorPlacementMode() const { return 0; } + virtual U8 mirrorFace() const { return 0; } // This method returns true if the object is over land owned by // the agent, one of its groups, or it encroaches and @@ -881,7 +881,7 @@ protected: F32 mLinksetPhysicsCost; bool mIsMirror; - U8 mMirrorPlacementMode; + U8 mMirrorFace; // If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap" bool mShouldShrinkWrap = false; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 91e64d611c..9813039145 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3364,9 +3364,9 @@ BOOL LLVOVolume::isMirror() const return mIsMirror; } -U8 LLVOVolume::mirrorPlacementMode() const +U8 LLVOVolume::mirrorFace() const { - return mMirrorPlacementMode; + return mMirrorFace; } BOOL LLVOVolume::isReflectionProbe() const diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 848f455e2a..b03fc4b862 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -298,7 +298,7 @@ public: // Mirrors bool setIsMirror(BOOL is_mirror); void updateMirrorDrawable(); - U8 mirrorPlacementMode() const override; + U8 mirrorFace() const override; // Reflection Probes bool setIsReflectionProbe(BOOL is_probe); -- cgit v1.2.3 From 2510134f40c2edd2eea40f486f094517b8ffaa51 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 24 Jan 2024 17:07:56 -0800 Subject: https://github.com/secondlife/viewer-issues/issues/23 Cleaning out some unused code. --- indra/newview/llface.cpp | 12 ------------ indra/newview/llface.h | 5 ----- 2 files changed, 17 deletions(-) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 2c04224fa0..69e43bb458 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -488,11 +488,6 @@ U16 LLFace::getGeometry(LLStrider &vertices, LLStrider &no return mGeomIndex; } -LLVector3 LLFace::getAverageNormal() -{ - return mAverageNormal; -} - void LLFace::updateCenterAgent() { if (mDrawablep->isActive()) @@ -1895,20 +1890,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a* src = vf.mNormals; LLVector4a* end = src+num_vertices; - LLVector4a normal_total; - while (src < end) { LLVector4a normal; mat_normal.rotate(*src++, normal); normal.store4a(normals); - normal_total.add(normal); normals += 4; } - - normal_total.div(LLVector4a(num_vertices)); - - mAverageNormal = LLVector3(normal_total[0], normal_total[1], normal_total[2]); } if (rebuild_tangent) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index d4f4313073..eb3b47d6d6 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -176,8 +176,6 @@ public: LLStrider &normals, LLStrider &texCoords, LLStrider &indices); - - LLVector3 getAverageNormal(); S32 getColors(LLStrider &colors); S32 getIndices(LLStrider &indices); @@ -280,9 +278,6 @@ private: U32 mIndicesCount; U32 mIndicesIndex; // index into mVertexBuffer's index array S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS]; - - LLVector3 mAverageNormal; - bool mHasAverageNormal; LLXformMatrix* mXform; -- cgit v1.2.3 From 4e90bd3cc0a4c1021cf8e688e008a0f0418d8364 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 24 Jan 2024 22:34:25 -0800 Subject: https://github.com/secondlife/viewer-issues/issues/36 Make sure we set the mirror flag appropriately. --- indra/newview/lldrawpoolmaterials.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index ec229711ea..063dd948f7 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -185,7 +185,11 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) if (gPipeline.mHeroProbeManager.isMirrorPass()) { - glUniform1f(LLShaderMgr::MIRROR_FLAG, 1); + mShader->uniform1f(LLShaderMgr::MIRROR_FLAG, 1); + } + else + { + mShader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0); } LLVector4 clipPlane = LLVector4(gPipeline.mHeroProbeManager.currentMirrorClip()[0], -- cgit v1.2.3 From 97764080b0eaf7b359b7e2332e6c1257ba86a71a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 23 Jan 2024 15:17:15 -0800 Subject: Review feedback: Remove static RenderLocalLightCount, as cached settings refresh has surprising performance cost --- indra/newview/llgltfmaterialpreviewmgr.cpp | 5 ++++- indra/newview/pipeline.cpp | 9 +++------ indra/newview/pipeline.h | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index a8ea3429f4..1dba3f082f 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -34,6 +34,7 @@ #include "llenvironment.h" #include "llselectmgr.h" #include "llviewercamera.h" +#include "llviewercontrol.h" #include "llviewerobject.h" #include "llviewershadermgr.h" #include "llviewertexturelist.h" @@ -419,7 +420,8 @@ BOOL LLGLTFPreviewTexture::render() LLVector3 light_dir3(1.0f, 1.0f, 1.0f); light_dir3.normalize(); const LLVector4 light_dir = LLVector4(light_dir3, 0); - SetTemporarily sun_light_only(&LLPipeline::RenderLocalLightCount, 0); + const S32 old_local_light_count = gSavedSettings.get("RenderLocalLightCount"); + gSavedSettings.set("RenderLocalLightCount", 0); gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(); @@ -524,6 +526,7 @@ BOOL LLGLTFPreviewTexture::render() // Clean up gPipeline.setupHWLights(); gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(false); + gSavedSettings.set("RenderLocalLightCount", old_local_light_count); return TRUE; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 94f2dc4a2a..d81bcef259 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -163,7 +163,6 @@ F32 LLPipeline::CameraFocusTransitionTime; F32 LLPipeline::CameraFNumber; F32 LLPipeline::CameraFocalLength; F32 LLPipeline::CameraFieldOfView; -S32 LLPipeline::RenderLocalLightCount; F32 LLPipeline::RenderShadowNoise; F32 LLPipeline::RenderShadowBlurSize; F32 LLPipeline::RenderSSAOScale; @@ -525,7 +524,6 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("CameraFNumber"); connectRefreshCachedSettingsSafe("CameraFocalLength"); connectRefreshCachedSettingsSafe("CameraFieldOfView"); - connectRefreshCachedSettingsSafe("RenderLocalLightCount"); connectRefreshCachedSettingsSafe("RenderShadowNoise"); connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); connectRefreshCachedSettingsSafe("RenderSSAOScale"); @@ -1025,7 +1023,6 @@ void LLPipeline::refreshCachedSettings() CameraFNumber = gSavedSettings.getF32("CameraFNumber"); CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); - RenderLocalLightCount = gSavedSettings.getS32("RenderLocalLightCount"); RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); @@ -5262,7 +5259,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) return; } - const S32 local_light_count = LLPipeline::RenderLocalLightCount; + static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); if (local_light_count >= 1) { @@ -5531,7 +5528,7 @@ void LLPipeline::setupHWLights() mLightMovingMask = 0; - const S32 local_light_count = LLPipeline::RenderLocalLightCount; + static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); if (local_light_count >= 1) { @@ -7965,7 +7962,7 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSoftenProgram); } - const S32 local_light_count = LLPipeline::RenderLocalLightCount; + static LLCachedControl local_light_count(gSavedSettings, "RenderLocalLightCount", 256); if (local_light_count > 0) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 21c1d9a25d..5ace90b000 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -1015,7 +1015,6 @@ public: static F32 CameraFNumber; static F32 CameraFocalLength; static F32 CameraFieldOfView; - static S32 RenderLocalLightCount; static F32 RenderShadowNoise; static F32 RenderShadowBlurSize; static F32 RenderSSAOScale; -- cgit v1.2.3 From 1691a25ce801bfd22cfc89958a07c4f53d3af772 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 24 Jan 2024 13:57:46 -0800 Subject: Fix material preview sometimes not updating when transitioning from blank material to non-blank material --- indra/newview/llfetchedgltfmaterial.h | 2 ++ indra/newview/llgltfmaterialpreviewmgr.cpp | 2 ++ indra/newview/lltexturectrl.cpp | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 3fa4619d8c..42c835a416 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -40,6 +40,8 @@ public: virtual ~LLFetchedGLTFMaterial(); LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs); + // LLGLTFMaterial::operator== is defined, but LLFetchedGLTFMaterial::operator== is not. + bool operator==(const LLGLTFMaterial& rhs) const = delete; // If this material is loaded, fire the given function void onMaterialComplete(std::function material_complete); diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 1dba3f082f..394f600a92 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -130,6 +130,8 @@ namespace LLGLTFPreviewTexture::MaterialLoadLevels get_material_load_levels(LLFetchedGLTFMaterial& material) { + llassert(!material.isFetching()); + using MaterialTextures = LLPointer*[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT]; MaterialTextures textures; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 916c0194c2..febda177e2 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -666,7 +666,7 @@ void LLFloaterTexturePicker::draw() { mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID); llassert(mGLTFMaterial == nullptr || dynamic_cast(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr); - if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get()))) + if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (old_material.get() != mGLTFMaterial.get()))) { // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview. if (mGLTFMaterial.isNull()) @@ -2206,7 +2206,7 @@ void LLTextureCtrl::draw() if (mInventoryPickType == PICK_MATERIAL) { mGLTFMaterial = gGLTFMaterialList.getMaterial(mImageAssetID); - if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get()))) + if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (old_material.get() != mGLTFMaterial.get()))) { // Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview. if (mGLTFMaterial.isNull()) -- cgit v1.2.3 From 8a1e2f98cbbc242d2721deaa92ed34c3f3fcf788 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 24 Jan 2024 14:33:24 -0800 Subject: Fix vertex color indexing in material preview --- indra/newview/llgltfmaterialpreviewmgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 394f600a92..09a2954710 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -337,7 +337,7 @@ void set_preview_sphere_material(PreviewSphere& preview_sphere, LLPointermGLTFMaterial = material; LLVertexBuffer* buf = info->mVertexBuffer.get(); LLStrider colors; - const S32 count = info->mEnd - info->mStart; + const S32 count = info->mEnd - info->mStart + 1; buf->getColorStrider(colors, info->mStart, count); for (S32 i = 0; i < count; ++i) { -- cgit v1.2.3 From 18669f3be7d61815203eddbfb866d551aba9bc69 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 25 Jan 2024 16:05:55 -0800 Subject: Don't refetch textures for LLFetchedGLTFMaterial if present --- indra/newview/llgltfmaterialpreviewmgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 09a2954710..53d9d7d0ba 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -96,7 +96,7 @@ namespace { void fetch_texture_for_ui(LLPointer& img, const LLUUID& id) { - if (id.notNull()) + if (!img && id.notNull()) { if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) { -- cgit v1.2.3 From 3b9a1a44b352b655ace39194317a3250bab4c6c9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 26 Jan 2024 00:37:13 +0200 Subject: SL-20669 Fix missed uuid --- indra/newview/llpanelface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7979261bae..f936739fde 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -336,7 +336,7 @@ BOOL LLPanelFace::postBuild() mTextureCtrl = getChild("texture control"); if(mTextureCtrl) { - mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" ))); + mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE); mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) ); mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) ); mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) ); -- cgit v1.2.3 From a5a4fd0c1026a994dd81ea6b703bcabcd8ed9501 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 29 Jan 2024 21:21:08 +0200 Subject: Issue #696 RenderResolutionDivisor no longer works resizeScreenTexture works if gResizeScreenTexture is true or render target was resized --- indra/newview/llviewerdisplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a936012781..e1d6f71cce 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -730,8 +730,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 2") if (gResizeScreenTexture) { - gResizeScreenTexture = FALSE; gPipeline.resizeScreenTexture(); + gResizeScreenTexture = FALSE; } gGL.setColorMask(true, true); -- cgit v1.2.3 From d5c69290ff425178636990f027a8d554f7dc31f8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 31 Jan 2024 02:35:07 +0200 Subject: Issue #24 GLTF material disappears from object playing media Check texture type, if media is stopped, it won't be a MEDIA_TEXTURE --- indra/newview/llvovolume.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ec2f490742..716a65dbcf 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5262,8 +5262,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); - U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; - U8 shiny = facep->getTextureEntry()->getShiny(); + const LLTextureEntry* te = facep->getTextureEntry(); + U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0; + U8 shiny = te->getShiny(); LLViewerTexture* tex = facep->getTexture(); @@ -5273,22 +5274,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLUUID mat_id; - auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial(); - llassert(gltf_mat == nullptr || dynamic_cast(facep->getTextureEntry()->getGLTFRenderMaterial()) != nullptr); + auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial(); + llassert(gltf_mat == nullptr || dynamic_cast(te->getGLTFRenderMaterial()) != nullptr); if (gltf_mat != nullptr) { mat_id = gltf_mat->getHash(); // TODO: cache this hash - if (!facep->hasMedia()) + if (!facep->hasMedia() || (tex && tex->getType() != LLViewerTexture::MEDIA_TEXTURE)) { // no media texture, face texture will be unused tex = nullptr; } } else { - mat = facep->getTextureEntry()->getMaterialParams().get(); + mat = te->getMaterialParams().get(); if (mat) { - mat_id = facep->getTextureEntry()->getMaterialParams()->getHash(); + mat_id = te->getMaterialParams()->getHash(); } } @@ -5298,7 +5299,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (mat) { - BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (facep->getTextureEntry()->getColor().mV[3] < 0.999f) ? TRUE : FALSE; + BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE; if (type == LLRenderPass::PASS_ALPHA) { shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha); -- cgit v1.2.3 From 00c65b62707f5c30cf2d48c0bd0c975c3bceb513 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 15 Sep 2023 14:27:15 -0700 Subject: secondlife/viewer-issues#43: Fix debug normals not rendering for terrain --- indra/llrender/llshadermgr.cpp | 23 ++- indra/llrender/llshadermgr.h | 3 + .../shaders/class1/interface/normaldebugF.glsl | 33 ++++ .../shaders/class1/interface/normaldebugG.glsl | 76 +++++++++ .../shaders/class1/interface/normaldebugV.glsl | 74 +++++++++ indra/newview/llspatialpartition.cpp | 171 +++++++++++++++------ indra/newview/llviewershadermgr.cpp | 29 ++++ indra/newview/llviewershadermgr.h | 8 + indra/newview/pipeline.cpp | 1 + 9 files changed, 365 insertions(+), 53 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl create mode 100644 indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl create mode 100644 indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 14f3086eb6..33d229bcc9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -588,11 +588,22 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } else { - //set version to 1.40 - shader_code_text[shader_code_count++] = strdup("#version 140\n"); - //some implementations of GLSL 1.30 require integer precision be explicitly declared - extra_code_text[extra_code_count++] = strdup("precision mediump int;\n"); - extra_code_text[extra_code_count++] = strdup("precision highp float;\n"); + if (type == GL_GEOMETRY_SHADER) + { + //set version to 1.50 + shader_code_text[shader_code_count++] = strdup("#version 150\n"); + //some implementations of GLSL 1.30 require integer precision be explicitly declared + extra_code_text[extra_code_count++] = strdup("precision mediump int;\n"); + extra_code_text[extra_code_count++] = strdup("precision highp float;\n"); + } + else + { + //set version to 1.40 + shader_code_text[shader_code_count++] = strdup("#version 140\n"); + //some implementations of GLSL 1.30 require integer precision be explicitly declared + extra_code_text[extra_code_count++] = strdup("precision mediump int;\n"); + extra_code_text[extra_code_count++] = strdup("precision highp float;\n"); + } } extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n"); @@ -1453,6 +1464,8 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("sun_up_factor"); mReservedUniforms.push_back("moonlight_color"); + mReservedUniforms.push_back("debug_normal_draw_length"); + llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); std::set dupe_check; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index ebd682141d..4ee5c8ef47 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -316,6 +316,9 @@ public: WATER_EDGE_FACTOR, // "water_edge" SUN_UP_FACTOR, // "sun_up_factor" MOONLIGHT_COLOR, // "moonlight_color" + + DEBUG_NORMAL_DRAW_LENGTH, // "debug_normal_draw_length" + END_RESERVED_UNIFORMS } eGLSLReservedUniforms; // clang-format on diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl new file mode 100644 index 0000000000..388042e7e0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl @@ -0,0 +1,33 @@ +/** + * @file normaldebugF.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; + +in vec4 vertex_color; + +void main() +{ + frag_color = max(vertex_color, vec4(0)); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl new file mode 100644 index 0000000000..ea04ce1cae --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl @@ -0,0 +1,76 @@ +/** + * @file normaldebugG.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$ + */ + +// *NOTE: Geometry shaders have a reputation for being slow. Consider using +// compute shaders instead, which have a reputation for being fast. This +// geometry shader in particular seems to run fine on my machine, but I won't +// vouch for this in performance-critical areas. +// -Cosmic,2023-09-28 + +out vec4 vertex_color; + +in vec4 normal_g[]; +#if HAS_ATTRIBUTE_TANGENT == 1 +in vec4 tangent_g[]; +#endif + +layout(TRIANGLES) in; +#if HAS_ATTRIBUTE_TANGENT == 1 +layout(LINE_STRIP, max_vertices = 12) out; +#else +layout(LINE_STRIP, max_vertices = 6) out; +#endif + +void triangle_normal_debug(int i) +{ + // Normal + vec4 normal_color = vec4(1.0, 1.0, 0.0, 1.0); + gl_Position = gl_in[i].gl_Position; + vertex_color = normal_color; + EmitVertex(); + gl_Position = normal_g[i]; + vertex_color = normal_color; + EmitVertex(); + EndPrimitive(); + +#if HAS_ATTRIBUTE_TANGENT == 1 + // Tangent + vec4 tangent_color = vec4(0.0, 1.0, 1.0, 1.0); + gl_Position = gl_in[i].gl_Position; + vertex_color = tangent_color; + EmitVertex(); + gl_Position = tangent_g[i]; + vertex_color = tangent_color; + EmitVertex(); + EndPrimitive(); +#endif +} + +void main() +{ + triangle_normal_debug(0); + triangle_normal_debug(1); + triangle_normal_debug(2); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl new file mode 100644 index 0000000000..d1596b9d2a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl @@ -0,0 +1,74 @@ +/** + * @file normaldebugV.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$ + */ + +in vec3 position; +in vec3 normal; +out vec4 normal_g; +#if HAS_ATTRIBUTE_TANGENT == 1 +in vec4 tangent; +out vec4 tangent_g; +#endif + +uniform float debug_normal_draw_length; + +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +#else +uniform mat3 normal_matrix; +#endif +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; + +// *NOTE: Should use the modelview_projection_matrix here in the non-skinned +// case for efficiency, but opting for the simplier implementation for now as +// this is debug code. Also, the skinned version hasn't beeen tested yet. +// world_pos = mat * vec4(position.xyz, 1.0) +vec4 get_screen_normal(vec3 position, vec4 world_pos, vec3 normal, mat4 mat) +{ + vec4 world_norm = mat * vec4((position + normal), 1.0); + world_norm.xyz -= world_pos.xyz; + world_norm.xyz = debug_normal_draw_length * normalize(world_norm.xyz); + world_norm.xyz += world_pos.xyz; + return projection_matrix * world_norm; +} + +void main() +{ +#ifdef HAS_SKIN + mat4 mat = getObjectSkinnedTransform(); + mat = modelview_matrix * mat; +#else +#define mat modelview_matrix +#endif + + vec4 world_pos = mat * vec4(position.xyz,1.0); + + gl_Position = projection_matrix * world_pos; + normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat); +#if HAS_ATTRIBUTE_TANGENT == 1 + tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat); +#endif +} + diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 931880a475..40e8e526d1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -47,6 +47,7 @@ #include "pipeline.h" #include "llmeshrepository.h" #include "llrender.h" +#include "lldrawpool.h" #include "lloctree.h" #include "llphysicsshapebuilderutil.h" #include "llvoavatar.h" @@ -2000,7 +2001,11 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) drawBoxOutline(pos,size); } } - +// *TODO: LLDrawables which are not part of LLVOVolumes fall into a different +// code path which uses a shader - it was tested to be faster than mapping a +// vertex buffer in the terrain case. Consider using it for LLVOVolumes as well +// to simplify and speed up this debug code. Alternatively, a compute shader is +// likely faster. -Cosmic,2023-09-28 void renderNormals(LLDrawable *drawablep) { if (!drawablep->isVisible()) @@ -2008,11 +2013,13 @@ void renderNormals(LLDrawable *drawablep) LLVertexBuffer::unbind(); + LLViewerObject* obj = drawablep->getVObj(); LLVOVolume *vol = drawablep->getVOVolume(); - if (vol) + if (obj) { - LLVolume *volume = vol->getVolume(); + LLGLEnable blend(GL_BLEND); + LLGLDepthTest gl_depth(GL_TRUE, GL_FALSE); // Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied. // @@ -2021,68 +2028,136 @@ void renderNormals(LLDrawable *drawablep) // transform. We get that effect here by pre-applying the inverse scale (twice, because // one forward scale will be re-applied via the MVP in the vertex shader) - LLVector3 scale_v3 = vol->getScale(); - float scale_len = scale_v3.length(); - LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]); - obj_scale.normalize3(); + LLVector4a inv_scale; + float scale_len; + if (vol) + { + LLVector3 scale_v3 = vol->getScale(); + LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]); + obj_scale.normalize3(); - // Normals &tangent line segments get scaled along with the object. Divide by scale length - // to keep the as-viewed lengths (relatively) constant with the debug setting length - float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len; + // Create inverse-scale vector for normals + inv_scale.set(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ], 0.0); + inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice - // Create inverse-scale vector for normals - LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]); - inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice - inv_scale.normalize3fast(); + inv_scale.normalize3fast(); + scale_len = scale_v3.length(); + } + else + { + inv_scale.set(1.0, 1.0, 1.0, 0.0); + scale_len = 1.0; + } gGL.pushMatrix(); - gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix); + if (vol) + { + gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix); + } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + // Normals &tangent line segments get scaled along with the object. Divide by scale length + // to keep the as-viewed lengths (relatively) constant with the debug setting length + float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len; + + std::vector* faces = nullptr; + std::vector* drawable_faces = nullptr; + if (vol) + { + LLVolume* volume = vol->getVolume(); + faces = &volume->getVolumeFaces(); + } + else { - const LLVolumeFace &face = volume->getVolumeFace(i); + drawable_faces = &drawablep->getFaces(); + } - gGL.flush(); - gGL.diffuseColor4f(1, 1, 0, 1); - gGL.begin(LLRender::LINES); - for (S32 j = 0; j < face.mNumVertices; ++j) - { - LLVector4a n, p; + if (faces) + { + for (auto it = faces->begin(); it != faces->end(); ++it) + { + const LLVolumeFace& face = *it; + + gGL.flush(); + gGL.diffuseColor4f(1, 1, 0, 1); + gGL.begin(LLRender::LINES); + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a n, p; - n.setMul(face.mNormals[j], 1.0); - n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP - n.normalize3fast(); - n.mul(draw_length); - p.setAdd(face.mPositions[j], n); + n.setMul(face.mNormals[j], 1.0); + n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP + n.normalize3fast(); + n.mul(draw_length); + p.setAdd(face.mPositions[j], n); - gGL.vertex3fv(face.mPositions[j].getF32ptr()); - gGL.vertex3fv(p.getF32ptr()); - } - gGL.end(); + gGL.vertex3fv(face.mPositions[j].getF32ptr()); + gGL.vertex3fv(p.getF32ptr()); + } + gGL.end(); + + // Tangents are simple vectors and do not require reorientation via pre-scaling + if (face.mTangents) + { + gGL.flush(); + gGL.diffuseColor4f(0, 1, 1, 1); + gGL.begin(LLRender::LINES); + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a t, p; - // Tangents are simple vectors and do not require reorientation via pre-scaling - if (face.mTangents) + t.setMul(face.mTangents[j], 1.0f); + t.normalize3fast(); + t.mul(draw_length); + p.setAdd(face.mPositions[j], t); + + gGL.vertex3fv(face.mPositions[j].getF32ptr()); + gGL.vertex3fv(p.getF32ptr()); + } + gGL.end(); + } + } + } + else if (drawable_faces) + { + // *HACK: Prepare to restore previous shader as other debug code depends on a simpler shader being present + llassert(LLGLSLShader::sCurBoundShaderPtr == &gDebugProgram); + LLGLSLShader* prev_shader = LLGLSLShader::sCurBoundShaderPtr; + for (auto it = drawable_faces->begin(); it != drawable_faces->end(); ++it) { - gGL.flush(); - gGL.diffuseColor4f(0, 1, 1, 1); - gGL.begin(LLRender::LINES); - for (S32 j = 0; j < face.mNumVertices; ++j) + LLFace* facep = *it; + LLFace& face = **it; + LLVertexBuffer* buf = face.getVertexBuffer(); + if (!buf) { continue; } + U32 mask_vn = LLVertexBuffer::TYPE_VERTEX | LLVertexBuffer::TYPE_NORMAL; + if ((buf->getTypeMask() & mask_vn) != mask_vn) { continue; } + + LLGLSLShader* shader; + if ((buf->getTypeMask() & LLVertexBuffer::TYPE_TANGENT) != LLVertexBuffer::TYPE_TANGENT) { - LLVector4a t, p; + shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_DEFAULT]; + } + else + { + shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_WITH_TANGENTS]; + } + shader->bind(); - t.setMul(face.mTangents[j], 1.0f); - t.normalize3fast(); - t.mul(draw_length); - p.setAdd(face.mPositions[j], t); + shader->uniform1f(LLShaderMgr::DEBUG_NORMAL_DRAW_LENGTH, draw_length); - gGL.vertex3fv(face.mPositions[j].getF32ptr()); - gGL.vertex3fv(p.getF32ptr()); - } - gGL.end(); + LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix); + + buf->setBuffer(); + // *NOTE: The render type in the vertex shader is TRIANGLES, but gets converted to LINES in the geometry shader + // *NOTE: For terrain normal debug, this seems to also include vertices for water, which is technically not part of the terrain. Should fix that at some point. + buf->drawRange(LLRender::TRIANGLES, face.getGeomIndex(), face.getGeomIndex() + face.getGeomCount()-1, face.getIndicesCount(), face.getIndicesStart()); } - } + if (prev_shader) + { + prev_shader->bind(); + } + } gGL.popMatrix(); } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 48c54f3dcc..7e49ea3b7c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -91,6 +91,8 @@ LLGLSLShader gTwoTextureCompareProgram; LLGLSLShader gOneTextureFilterProgram; LLGLSLShader gDebugProgram; LLGLSLShader gSkinnedDebugProgram; +LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; +LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; LLGLSLShader gClipProgram; LLGLSLShader gAlphaMaskProgram; LLGLSLShader gBenchmarkProgram; @@ -2692,6 +2694,33 @@ BOOL LLViewerShaderMgr::loadShadersInterface() success = success && gDebugProgram.createShader(NULL, NULL); } + if (success) + { + for (S32 variant = 0; variant < NORMAL_DEBUG_SHADER_COUNT; ++variant) + { + LLGLSLShader& shader = gNormalDebugProgram[variant]; + LLGLSLShader& skinned_shader = gSkinnedNormalDebugProgram[variant]; + shader.mName = "Normal Debug Shader"; + shader.mShaderFiles.clear(); + shader.mShaderFiles.push_back(make_pair("interface/normaldebugV.glsl", GL_VERTEX_SHADER)); + // *NOTE: Geometry shaders have a reputation for being slow. + // Consider using compute shaders instead, which have a reputation + // for being fast. This geometry shader in particular seems to run + // fine on my machine, but I won't vouch for this in + // performance-critical areas. -Cosmic,2023-09-28 + shader.mShaderFiles.push_back(make_pair("interface/normaldebugG.glsl", GL_GEOMETRY_SHADER)); + shader.mShaderFiles.push_back(make_pair("interface/normaldebugF.glsl", GL_FRAGMENT_SHADER)); + shader.mRiggedVariant = &skinned_shader; + shader.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + if (variant == NORMAL_DEBUG_SHADER_WITH_TANGENTS) + { + shader.addPermutation("HAS_ATTRIBUTE_TANGENT", "1"); + } + success = make_rigged_variant(shader, skinned_shader); + success = success && shader.createShader(NULL, NULL); + } + } + if (success) { gClipProgram.mName = "Clip Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index cb1729cd1b..4273c3e70c 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -156,6 +156,14 @@ extern LLGLSLShader gRadianceGenProgram; extern LLGLSLShader gIrradianceGenProgram; extern LLGLSLShader gGlowCombineFXAAProgram; extern LLGLSLShader gDebugProgram; +enum NormalDebugShaderVariant : S32 +{ + NORMAL_DEBUG_SHADER_DEFAULT, + NORMAL_DEBUG_SHADER_WITH_TANGENTS, + NORMAL_DEBUG_SHADER_COUNT +}; +extern LLGLSLShader gNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; +extern LLGLSLShader gSkinnedNormalDebugProgram[NORMAL_DEBUG_SHADER_COUNT]; extern LLGLSLShader gClipProgram; extern LLGLSLShader gBenchmarkProgram; extern LLGLSLShader gReflectionProbeDisplayProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d81bcef259..fb57042110 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8241,6 +8241,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, END_RENDER_TYPES); -- cgit v1.2.3 From 118996225bb588dcaef415dfe18f5e4aca9c35b8 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 29 Sep 2023 17:19:48 -0700 Subject: secondlife/viewer-issues#43: Proof-of-concept PBR terrain normal gen feature flag. Final implementation would likely be very different. --- indra/newview/app_settings/settings.xml | 11 ++ indra/newview/llsurface.cpp | 14 +- indra/newview/llsurface.h | 6 +- indra/newview/llsurfacepatch.cpp | 197 +++++++++++++++++++-- indra/newview/llsurfacepatch.h | 13 ++ indra/newview/llviewermenu.cpp | 18 ++ indra/newview/llviewerregion.cpp | 35 +++- indra/newview/llviewerregion.h | 3 + indra/newview/llvosurfacepatch.cpp | 1 + indra/newview/pipeline.cpp | 9 + indra/newview/pipeline.h | 2 + indra/newview/skins/default/xui/en/menu_viewer.xml | 7 + 12 files changed, 292 insertions(+), 24 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 242e274daf..ff0f4fd8a1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10932,6 +10932,17 @@ Value 8.0 + RenderTerrainPBRNormalsEnabled + + Comment + EXPERIMENTAL: Change normal gen for PBR Terrain. + Persist + 1 + Type + Boolean + Value + 0 + RenderTrackerBeacon Comment diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 1418499f8b..804afe6266 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -643,17 +643,18 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent) } } -BOOL LLSurface::idleUpdate(F32 max_update_time) +template +bool LLSurface::idleUpdate(F32 max_update_time) { if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) { - return FALSE; + return false; } // Perform idle time update of non-critical stuff. // In this case, texture and normal updates. LLTimer update_timer; - BOOL did_update = FALSE; + bool did_update = false; // If the Z height data has changed, we need to rebuild our // property line vertex arrays. @@ -669,13 +670,13 @@ BOOL LLSurface::idleUpdate(F32 max_update_time) { std::set::iterator curiter = iter++; LLSurfacePatch *patchp = *curiter; - patchp->updateNormals(); + patchp->updateNormals(); patchp->updateVerticalStats(); if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time) { if (patchp->updateTexture()) { - did_update = TRUE; + did_update = true; patchp->clearDirty(); mDirtyPatchList.erase(curiter); } @@ -691,6 +692,9 @@ BOOL LLSurface::idleUpdate(F32 max_update_time) return did_update; } +template bool LLSurface::idleUpdate(F32 max_update_time); +template bool LLSurface::idleUpdate(F32 max_update_time); + void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch) { diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 33a64ae7d5..b7b47d2a1c 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -112,7 +112,8 @@ public: LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const; // Update methods (called during idle, normally) - BOOL idleUpdate(F32 max_update_time); + template + bool idleUpdate(F32 max_update_time); BOOL containsPosition(const LLVector3 &position); @@ -224,6 +225,9 @@ private: static S32 sTextureSize; // Size of the surface texture }; +extern template bool LLSurface::idleUpdate(F32 max_update_time); +extern template bool LLSurface::idleUpdate(F32 max_update_time); + // . __. diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index a6370e9ec2..92b1273041 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -243,7 +243,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 } -void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) +template<> +void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { U32 patch_width = mSurfacep->mPVArray.mPatchWidth; U32 surface_stride = mSurfacep->getGridsPerEdge(); @@ -356,6 +357,166 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) *(mDataNorm + surface_stride * y + x) = normal; } +template<> +void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) +{ + llassert(mDataNorm); + constexpr U32 index = 0; + + const U32 surface_stride = mSurfacep->getGridsPerEdge(); + LLVector3& normal_out = *(mDataNorm + surface_stride * y + x); + calcNormalFlat(normal_out, x, y, index); +} + +// Calculate the flat normal of a triangle whose least coordinate is specified by the given x,y values. +// If index = 0, calculate the normal of the first triangle, otherwise calculate the normal of the second. +void LLSurfacePatch::calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index) +{ + llassert(index == 0 || index == 1); + + U32 patch_width = mSurfacep->mPVArray.mPatchWidth; + U32 surface_stride = mSurfacep->getGridsPerEdge(); + + // Vertex stride is always 1 because we want the flat surface of the current triangle face + constexpr U32 stride = 1; + + const F32 mpg = mSurfacep->getMetersPerGrid() * stride; + + S32 poffsets[2][2][2]; + poffsets[0][0][0] = x; + poffsets[0][0][1] = y; + + poffsets[0][1][0] = x; + poffsets[0][1][1] = y + stride; + + poffsets[1][0][0] = x + stride; + poffsets[1][0][1] = y; + + poffsets[1][1][0] = x + stride; + poffsets[1][1][1] = y + stride; + + const LLSurfacePatch *ppatches[2][2]; + + // LLVector3 p1, p2, p3, p4; + + ppatches[0][0] = this; + ppatches[0][1] = this; + ppatches[1][0] = this; + ppatches[1][1] = this; + + U32 i, j; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 2; j++) + { + if (poffsets[i][j][0] < 0) + { + if (!ppatches[i][j]->getNeighborPatch(WEST)) + { + poffsets[i][j][0] = 0; + } + else + { + poffsets[i][j][0] += patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST); + } + } + if (poffsets[i][j][1] < 0) + { + if (!ppatches[i][j]->getNeighborPatch(SOUTH)) + { + poffsets[i][j][1] = 0; + } + else + { + poffsets[i][j][1] += patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH); + } + } + if (poffsets[i][j][0] >= (S32)patch_width) + { + if (!ppatches[i][j]->getNeighborPatch(EAST)) + { + poffsets[i][j][0] = patch_width - 1; + } + else + { + poffsets[i][j][0] -= patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST); + } + } + if (poffsets[i][j][1] >= (S32)patch_width) + { + if (!ppatches[i][j]->getNeighborPatch(NORTH)) + { + poffsets[i][j][1] = patch_width - 1; + } + else + { + poffsets[i][j][1] -= patch_width; + ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH); + } + } + } + } + + LLVector3 p00(-mpg,-mpg, + *(ppatches[0][0]->mDataZ + + poffsets[0][0][0] + + poffsets[0][0][1]*surface_stride)); + LLVector3 p01(-mpg,+mpg, + *(ppatches[0][1]->mDataZ + + poffsets[0][1][0] + + poffsets[0][1][1]*surface_stride)); + LLVector3 p10(+mpg,-mpg, + *(ppatches[1][0]->mDataZ + + poffsets[1][0][0] + + poffsets[1][0][1]*surface_stride)); + LLVector3 p11(+mpg,+mpg, + *(ppatches[1][1]->mDataZ + + poffsets[1][1][0] + + poffsets[1][1][1]*surface_stride)); + + // Triangle index / coordinate convention + // for a single surface patch + // + // p01 p11 + // + // ^ ._____. + // | |\ | + // | | \ 1 | + // | | \ | + // | 0 \ | + // y |____\| + // + // p00 x ---> p10 + // + // (z up / out of the screen due to right-handed coordinate system) + + LLVector3 normal; + if (index == 0) + { + LLVector3 c1 = p10 - p00; + LLVector3 c2 = p01 - p00; + + normal = c1; + normal %= c2; + normal.normVec(); + } + else // index == 1 + { + LLVector3 c1 = p11 - p01; + LLVector3 c2 = p11 - p10; + + normal = c1; + normal %= c2; + normal.normVec(); + } + + llassert(&normal_out); + normal_out = normal; +} + const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const { U32 surface_stride = mSurfacep->getGridsPerEdge(); @@ -453,6 +614,7 @@ void LLSurfacePatch::updateVerticalStats() } +template void LLSurfacePatch::updateNormals() { if (mSurfacep->mType == 'w') @@ -470,9 +632,9 @@ void LLSurfacePatch::updateNormals() { for (j = 0; j <= grids_per_patch_edge; j++) { - calcNormal(grids_per_patch_edge, j, 2); - calcNormal(grids_per_patch_edge - 1, j, 2); - calcNormal(grids_per_patch_edge - 2, j, 2); + calcNormal(grids_per_patch_edge, j, 2); + calcNormal(grids_per_patch_edge - 1, j, 2); + calcNormal(grids_per_patch_edge - 2, j, 2); } dirty_patch = TRUE; @@ -483,9 +645,9 @@ void LLSurfacePatch::updateNormals() { for (i = 0; i <= grids_per_patch_edge; i++) { - calcNormal(i, grids_per_patch_edge, 2); - calcNormal(i, grids_per_patch_edge - 1, 2); - calcNormal(i, grids_per_patch_edge - 2, 2); + calcNormal(i, grids_per_patch_edge, 2); + calcNormal(i, grids_per_patch_edge - 1, 2); + calcNormal(i, grids_per_patch_edge - 2, 2); } dirty_patch = TRUE; @@ -496,8 +658,8 @@ void LLSurfacePatch::updateNormals() { for (j = 0; j < grids_per_patch_edge; j++) { - calcNormal(0, j, 2); - calcNormal(1, j, 2); + calcNormal(0, j, 2); + calcNormal(1, j, 2); } dirty_patch = TRUE; } @@ -507,8 +669,8 @@ void LLSurfacePatch::updateNormals() { for (i = 0; i < grids_per_patch_edge; i++) { - calcNormal(i, 0, 2); - calcNormal(i, 1, 2); + calcNormal(i, 0, 2); + calcNormal(i, 1, 2); } dirty_patch = TRUE; } @@ -584,10 +746,10 @@ void LLSurfacePatch::updateNormals() // We've got a northeast patch in the same surface. // The z and normals will be handled by that patch. } - calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2); - calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2); - calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2); - calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2); + calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2); + calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2); + calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2); + calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2); dirty_patch = TRUE; } @@ -598,7 +760,7 @@ void LLSurfacePatch::updateNormals() { for (i=2; i < grids_per_patch_edge - 2; i++) { - calcNormal(i, j, 2); + calcNormal(i, j, 2); } } dirty_patch = TRUE; @@ -615,6 +777,9 @@ void LLSurfacePatch::updateNormals() } } +template void LLSurfacePatch::updateNormals(); +template void LLSurfacePatch::updateNormals(); + void LLSurfacePatch::updateEastEdge() { U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 8c8f501dce..ec3864ce44 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -77,6 +77,7 @@ public: void updateVerticalStats(); void updateCompositionStats(); + template void updateNormals(); void updateEastEdge(); @@ -102,9 +103,18 @@ public: LLVector3 getPointAgent(const U32 x, const U32 y) const; // get the point at the offset. LLVector2 getTexCoords(const U32 x, const U32 y) const; + // Per-vertex normals + // *TODO: PBR=true is a test implementation solely for proof-of-concept. + // Final implementation would likely be very different and may not even use + // this function. If we decide to keep calcNormalFlat, remove index as it + // is a debug parameter for testing. + template void calcNormal(const U32 x, const U32 y, const U32 stride); const LLVector3 &getNormal(const U32 x, const U32 y) const; + // Per-triangle normals for flat edges + void calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index /* 0 or 1 */); + void eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex0, LLVector2 *tex1); @@ -181,5 +191,8 @@ protected: LLSurface *mSurfacep; // Pointer to "parent" surface }; +extern template void LLSurfacePatch::updateNormals(); +extern template void LLSurfacePatch::updateNormals(); + #endif // LL_LLSURFACEPATCH_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9db9d97ddc..da7b1131a3 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2122,6 +2122,20 @@ class LLAdvancedPurgeShaderCache : public view_listener_t } }; +///////////////////// +// REBUILD TERRAIN // +///////////////////// + + +class LLAdvancedRebuildTerrain : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + gPipeline.rebuildTerrain(); + return true; + } +}; + //////////////////// // EVENT Recorder // /////////////////// @@ -9492,6 +9506,10 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile"); view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache"); + if (gSavedSettings.get("RenderTerrainPBREnabled")) + { + view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); + } #ifdef TOGGLE_HACKED_GODLIKE_VIEWER view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index dae476d9d7..d541bb6647 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1105,6 +1105,11 @@ void LLViewerRegion::dirtyHeights() } } +void LLViewerRegion::dirtyAllPatches() +{ + getLand().dirtyAllPatches(); +} + //physically delete the cache entry void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering) { @@ -1605,7 +1610,19 @@ void LLViewerRegion::idleUpdate(F32 max_update_time) mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame(); - mImpl->mLandp->idleUpdate(max_update_time); + static bool pbr_terrain_enabled = gSavedSettings.get("RenderTerrainPBREnabled"); + static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE); + bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR); + bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals; + + if (!pbr_land) + { + mImpl->mLandp->idleUpdate(max_update_time); + } + else + { + mImpl->mLandp->idleUpdate(max_update_time); + } if (mParcelOverlay) { @@ -1906,7 +1923,21 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() { - mImpl->mLandp->idleUpdate(0.f); + constexpr F32 max_update_time = 0.f; + + static bool pbr_terrain_enabled = gSavedSettings.get("RenderTerrainPBREnabled"); + static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE); + bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR); + bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals; + + if (!pbr_land) + { + mImpl->mLandp->idleUpdate(max_update_time); + } + else + { + mImpl->mLandp->idleUpdate(max_update_time); + } if (mParcelOverlay) { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 622490c881..1c2ff9bc97 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -163,6 +163,9 @@ public: // Call this whenever you change the height data in the region. // (Automatically called by LLSurfacePatch's update routine) void dirtyHeights(); + // Call this whenever you want to force all terrain to rebuild. + // (For example, if a global terrain config option has changed) + void dirtyAllPatches(); LLViewerParcelOverlay *getParcelOverlay() const { return mParcelOverlay; } diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 9544450a69..69b9476d38 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -214,6 +214,7 @@ BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) void LLVOSurfacePatch::updateFaceSize(S32 idx) { + LL_PROFILE_ZONE_SCOPED; if (idx != 0) { LL_WARNS() << "Terrain partition requested invalid face!!!" << LL_ENDL; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index fb57042110..d63b9d317e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10870,3 +10870,12 @@ void LLPipeline::rebuildDrawInfo() } } +void LLPipeline::rebuildTerrain() +{ + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + region->dirtyAllPatches(); + } +} diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5ace90b000..fb28a0e41c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -134,6 +134,8 @@ public: // rebuild all LLVOVolume render batches void rebuildDrawInfo(); + // Rebuild all terrain + void rebuildTerrain(); // Clear LLFace mVertexBuffer pointers void resetVertexBuffers(LLDrawable* drawable); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 660f4b62c7..9b238693e0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3297,6 +3297,13 @@ function="World.EnvPreset" + + + Date: Wed, 31 Jan 2024 15:54:14 -0800 Subject: #677 Some clipping WIP --- .../shaders/class1/deferred/materialV.glsl | 2 +- .../shaders/class3/deferred/materialF.glsl | 12 +++++++----- .../shaders/class3/deferred/softenLightF.glsl | 1 - indra/newview/lldrawpoolmaterials.cpp | 8 ++++---- indra/newview/llheroprobemanager.cpp | 18 ++++-------------- indra/newview/llheroprobemanager.h | 5 ++++- indra/newview/llsettingsvo.cpp | 12 +++++++++++- 7 files changed, 31 insertions(+), 27 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 65706e2c3f..41112bce30 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -127,7 +127,7 @@ void main() vertex_color = diffuse_color; #if !defined(HAS_SKIN) - vary_position = (projection_matrix*vec4(position.xyz, 1.0)).xyz; + vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; #endif } diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index b3b1aaed56..8fe0e1cec8 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -48,15 +48,18 @@ vec3 linear_to_srgb(vec3 cs); uniform vec4 clipPlane; uniform float clipSign; uniform float mirror_flag; +uniform mat4 modelview_matrix; +uniform mat3 normal_matrix; void applyClip(vec3 pos) { - float funnyClip = 0; + if (mirror_flag > 0) { - if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) > 0.0) - { + if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) + { discard; - } + } + } } @@ -308,7 +311,6 @@ void main() // diffcol == diffuse map combined with vertex color vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; - alphaMask(diffcol.a); // spec == specular map combined with specular color diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index f1de0b88d6..b49c3386db 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -201,7 +201,6 @@ void main() #ifdef HERO_PROBES vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_MIRROR)) color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; #endif } diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 063dd948f7..15033160d5 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -192,10 +192,10 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) mShader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0); } - LLVector4 clipPlane = LLVector4(gPipeline.mHeroProbeManager.currentMirrorClip()[0], - gPipeline.mHeroProbeManager.currentMirrorClip()[1], - gPipeline.mHeroProbeManager.currentMirrorClip()[2], - gPipeline.mHeroProbeManager.currentMirrorClip()[3]); + LLVector4 clipPlane = LLVector4(gPipeline.mHeroProbeManager.mMirrorPosition[0], + gPipeline.mHeroProbeManager.mMirrorPosition[1], + gPipeline.mHeroProbeManager.mMirrorPosition[2], + 1); mShader->uniform4fv(LLShaderMgr::CLIP_PLANE, 1, clipPlane.mV); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 1ecafd4f54..bbe493f6a9 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -165,20 +165,10 @@ void LLHeroProbeManager::update() LLVector3 reject = offset - project; LLVector3 point = (reject - project) + hero_pos; - glh::matrix4f mat = copy_matrix(gGLModelView); - glh::vec4f tc(face_normal.mV); - mat.mult_matrix_vec(tc); - - LLVector3 mirror_normal; - mirror_normal.set(tc.v); - - LLVector3 hero_pos_render; - tc = glh::vec4f(hero_pos.mV); - - mat.mult_matrix_vec(tc); - hero_pos_render.set(tc.v); - - mCurrentClipPlane.setVec(hero_pos_render, mirror_normal); + mCurrentClipPlane.setVec(hero_pos, face_normal); + mMirrorPosition = hero_pos; + mMirrorNormal = LLVector3(0, 0, 1); + probe_pos.load3(point.mV); } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 68cfdbfd99..0b32768bb1 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -75,7 +75,9 @@ public: bool isMirrorPass() const { return mRenderingMirror; } - LLPlane currentMirrorClip() const { return mCurrentClipPlane; } + LLPlane currentMirrorClip() const { return mCurrentClipPlane; } + LLVector3 mMirrorPosition; + LLVector3 mMirrorNormal; private: friend class LLPipeline; @@ -102,6 +104,7 @@ private: LLPlane mCurrentClipPlane; + // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index c07c939862..9cfb774a90 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -1017,10 +1017,20 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); + norm = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorNormal.mV[0], gPipeline.mHeroProbeManager.mMirrorNormal.mV[1], + gPipeline.mHeroProbeManager.mMirrorNormal.mV[2]); + p = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorPosition.mV[0], gPipeline.mHeroProbeManager.mMirrorPosition.mV[1], + gPipeline.mHeroProbeManager.mMirrorPosition.mV[2]); + invtrans.mult_matrix_vec(norm, enorm); + enorm.normalize(); + mat.mult_matrix_vec(p, ep); + + LLVector4 mirrorPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); + LLDrawPoolAlpha::sWaterPlane = waterPlane; shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV); - + shader->uniform4fv(LLShaderMgr::CLIP_PLANE, mirrorPlane.mV); LLVector4 light_direction = env.getClampedLightNorm(); F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); -- cgit v1.2.3 From a4225663ac3feb641fb8fb416889fd46b52763f5 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 1 Feb 2024 10:16:52 -0600 Subject: #677 Set mirror pass flag in llsettingsvo --- indra/newview/lldrawpoolmaterials.cpp | 17 ----------------- indra/newview/llheroprobemanager.cpp | 2 +- indra/newview/llsettingsvo.cpp | 9 +++++++++ 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 15033160d5..c0e4ed38c1 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -183,23 +183,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) glUniform4fv(specular, 1, lastSpecular.mV); } - if (gPipeline.mHeroProbeManager.isMirrorPass()) - { - mShader->uniform1f(LLShaderMgr::MIRROR_FLAG, 1); - } - else - { - mShader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0); - } - - LLVector4 clipPlane = LLVector4(gPipeline.mHeroProbeManager.mMirrorPosition[0], - gPipeline.mHeroProbeManager.mMirrorPosition[1], - gPipeline.mHeroProbeManager.mMirrorPosition[2], - 1); - - mShader->uniform4fv(LLShaderMgr::CLIP_PLANE, - 1, clipPlane.mV); - LLVOAvatar* lastAvatar = nullptr; for (LLCullResult::drawinfo_iterator i = begin; i != end; ) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index bbe493f6a9..ed37a67c85 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -166,7 +166,7 @@ void LLHeroProbeManager::update() LLVector3 point = (reject - project) + hero_pos; mCurrentClipPlane.setVec(hero_pos, face_normal); - mMirrorPosition = hero_pos; + mMirrorPosition = mNearestHero->getPositionAgent(); mMirrorNormal = LLVector3(0, 0, 1); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 9cfb774a90..da5504f83f 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -1033,6 +1033,15 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) shader->uniform4fv(LLShaderMgr::CLIP_PLANE, mirrorPlane.mV); LLVector4 light_direction = env.getClampedLightNorm(); + if (gPipeline.mHeroProbeManager.isMirrorPass()) + { + shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 1); + } + else + { + shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0); + } + F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP); shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS); -- cgit v1.2.3 From 78140786ce4a89a4ee252dabc74e3a28461e9c15 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 1 Feb 2024 10:18:17 -0800 Subject: #689 Fix for mirror stuttering. --- indra/newview/llappviewer.cpp | 1 - indra/newview/llviewerdisplay.cpp | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 038858321c..28dd2a3c9a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1520,7 +1520,6 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot"); pingMainloopTimeout("Main:Snapshot"); gPipeline.mReflectionMapManager.update(); - gPipeline.mHeroProbeManager.update(); LLFloaterSnapshot::update(); // take snapshots LLFloaterSimpleSnapshot::update(); gGLActive = FALSE; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6261f62fbe..1d168de80d 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -656,6 +656,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!gDisconnected) { + // Render mirrors and associated hero probes before we render the rest of the scene. + // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it. + if (gPipeline.RenderMirrors && !gSnapshot) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes"); + gPipeline.mHeroProbeManager.update(); + } + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1"); LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -696,7 +704,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } gPipeline.updateGL(); - + stop_glerror(); LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); -- cgit v1.2.3 From b2462355a39a8473065c279c66daba307f1fa9bf Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 1 Feb 2024 13:19:20 -0600 Subject: #677 WIP -- add mirror clipping to more shaders --- indra/llrender/llshadermgr.cpp | 8 +++- .../shaders/class1/deferred/bumpF.glsl | 4 ++ .../shaders/class1/deferred/bumpV.glsl | 5 ++- .../shaders/class1/deferred/diffuseF.glsl | 3 ++ .../shaders/class1/deferred/diffuseIndexedF.glsl | 3 ++ .../shaders/class1/deferred/diffuseV.glsl | 7 +++- .../shaders/class1/deferred/fullbrightF.glsl | 4 +- .../shaders/class1/deferred/globalF.glsl | 45 ++++++++++++++++++++++ .../shaders/class1/deferred/pbropaqueF.glsl | 26 ++----------- .../app_settings/shaders/class1/objects/bumpF.glsl | 4 ++ .../app_settings/shaders/class1/objects/bumpV.glsl | 5 ++- .../shaders/class3/deferred/fullbrightShinyF.glsl | 3 ++ .../shaders/class3/deferred/materialF.glsl | 22 ++--------- indra/newview/llviewershadermgr.cpp | 4 ++ 14 files changed, 96 insertions(+), 47 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/globalF.glsl diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 14f3086eb6..758b54cf1f 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -183,7 +183,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) // Attach Fragment Shader Features Next /////////////////////////////////////// -// NOTE order of shader object attaching is VERY IMPORTANT!!! + // NOTE order of shader object attaching is VERY IMPORTANT!!! + + if (!shader->attachFragmentObject("deferred/globalF.glsl")) + { + return FALSE; + } + if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred) { if (!shader->attachFragmentObject("environment/srgbF.glsl")) diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 35f483f633..a22c174349 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -37,11 +37,15 @@ in vec3 vary_mat2; in vec4 vertex_color; in vec2 vary_texcoord0; +in vec3 vary_position; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos); void main() { + mirrorClip(vary_position); + vec4 col = texture(diffuseMap, vary_texcoord0.xy); if(col.a < minimum_alpha) diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 3af2eab1e4..74319349f6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -23,6 +23,7 @@ * $/LicenseInfo$ */ +uniform mat4 modelview_matrix; uniform mat3 normal_matrix; uniform mat4 texture_matrix0; uniform mat4 modelview_projection_matrix; @@ -38,11 +39,11 @@ out vec3 vary_mat1; out vec3 vary_mat2; out vec4 vertex_color; out vec2 vary_texcoord0; +out vec3 vary_position; #ifdef HAS_SKIN mat4 getObjectSkinnedTransform(); uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; #endif void main() @@ -52,11 +53,13 @@ void main() mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; + vary_position = pos; gl_Position = projection_matrix*vec4(pos, 1.0); vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); #else + vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vec3 n = normalize(normal_matrix * normal); vec3 t = normalize(normal_matrix * tangent.xyz); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 68fb8bf499..76776ede2c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -32,11 +32,14 @@ uniform sampler2D diffuseMap; in vec3 vary_normal; in vec4 vertex_color; in vec2 vary_texcoord0; +in vec3 vary_position; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos); void main() { + mirrorClip(vary_position); vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb; frag_data[0] = vec4(col, 0.0); frag_data[1] = vertex_color.aaaa; // spec diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 93d561504e..b983acf657 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -30,12 +30,15 @@ out vec4 frag_data[4]; in vec3 vary_normal; in vec4 vertex_color; in vec2 vary_texcoord0; +in vec3 vary_position; +void mirrorClip(vec3 pos); vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); void main() { + mirrorClip(vary_position); vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; vec3 spec; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 2402cc3b70..64230dc680 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -36,13 +36,16 @@ out vec3 vary_normal; out vec4 vertex_color; out vec2 vary_texcoord0; +out vec3 vary_position; void passTextureIndex(); +uniform mat4 modelview_matrix; + #ifdef HAS_SKIN mat4 getObjectSkinnedTransform(); uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; + #endif void main() @@ -51,9 +54,11 @@ void main() mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; vec4 pos = mat * vec4(position.xyz, 1.0); + vary_position = pos.xyz; gl_Position = projection_matrix * pos; vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); #else + vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vary_normal = normalize(normal_matrix * normal); #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index a6fab10791..52dfed06ae 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -50,9 +50,11 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color); #endif +void mirrorClip(vec3 pos); + void main() { - + mirrorClip(vary_position); #ifdef IS_ALPHA waterClip(vary_position.xyz); #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl new file mode 100644 index 0000000000..7e3e7d9271 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl @@ -0,0 +1,45 @@ +/** + * @file class1/deferred/globalF.glsl + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, 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$ + */ + + + // Global helper functions included in every fragment shader + // DO NOT declare sampler uniforms here as OS X doesn't compile + // them out + +uniform float mirror_flag; +uniform vec4 clipPlane; +uniform float clipSign; + +void mirrorClip(vec3 pos) +{ + if (mirror_flag > 0) + { + if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) + { + discard; + } + } +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 9b98a37925..0683236460 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -60,34 +60,14 @@ vec3 srgb_to_linear(vec3 c); uniform vec4 clipPlane; uniform float clipSign; -uniform float mirror_flag; -void applyClip(vec3 pos) -{ - if (mirror_flag > 0) - { - // TODO: make this less branchy - if (clipSign > 0) - { - if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) - { - discard; - } - } - else - { - if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) > 0.0) - { - discard; - } - } - } -} + +void mirrorClip(vec3 pos); uniform mat3 normal_matrix; void main() { - applyClip(vary_position); + mirrorClip(vary_position); vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba; if (basecolor.a < minimum_alpha) diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl index 67c99530e3..142f2a5d71 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl @@ -30,9 +30,13 @@ uniform sampler2D texture1; in vec2 vary_texcoord0; in vec2 vary_texcoord1; +in vec3 vary_position; + +void mirrorClip(vec3 pos); void main() { + mirrorClip(vary_position); float tex0 = texture(texture0, vary_texcoord0.xy).a; float tex1 = texture(texture1, vary_texcoord1.xy).a; diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl index 7d5417919e..b8a02fbdec 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -23,6 +23,7 @@ * $/LicenseInfo$ */ +uniform mat4 modelview_matrix; uniform mat4 texture_matrix0; uniform mat4 modelview_projection_matrix; @@ -32,11 +33,11 @@ in vec2 texcoord1; out vec2 vary_texcoord0; out vec2 vary_texcoord1; +out vec3 vary_position; #ifdef HAS_SKIN mat4 getObjectSkinnedTransform(); uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; #endif void main() @@ -46,8 +47,10 @@ void main() mat4 mat = getObjectSkinnedTransform(); mat = modelview_matrix * mat; vec4 pos = mat * vec4(position.xyz, 1.0); + vary_position = pos.xyz; gl_Position = projection_matrix * pos; #else + vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); #endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index 8430cca325..c382a9fbc0 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -53,8 +53,11 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); +void mirrorClip(vec3 pos); + void main() { + mirrorClip(vary_position); #ifdef HAS_DIFFUSE_LOOKUP vec4 color = diffuseLookup(vary_texcoord0.xy); #else diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 8fe0e1cec8..0476b98e10 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -45,26 +45,13 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float vec3 srgb_to_linear(vec3 cs); vec3 linear_to_srgb(vec3 cs); -uniform vec4 clipPlane; -uniform float clipSign; -uniform float mirror_flag; uniform mat4 modelview_matrix; uniform mat3 normal_matrix; -void applyClip(vec3 pos) -{ - - if (mirror_flag > 0) - { - if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) - { - discard; - } - - } -} in vec3 vary_position; +void mirrorClip(vec3 pos); + #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) out vec4 frag_color; @@ -305,7 +292,7 @@ float getShadow(vec3 pos, vec3 norm) void main() { - applyClip(vary_position); + mirrorClip(vary_position); waterClip(); // diffcol == diffuse map combined with vertex color @@ -430,9 +417,6 @@ void main() float flag = GBUFFER_FLAG_HAS_ATMOS; - if (mirror_flag > 0) - flag = 1; - 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, flag);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 48c54f3dcc..a93d60cb70 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -291,6 +291,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma mShaderList.push_back(&gNoPostGammaCorrectProgram); mShaderList.push_back(&gLegacyPostGammaCorrectProgram); + mShaderList.push_back(&gDeferredDiffuseProgram); + mShaderList.push_back(&gObjectBumpProgram); + mShaderList.push_back(&gDeferredBumpProgram); } @@ -676,6 +679,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/globalF.glsl", 1)); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) ); -- cgit v1.2.3 From 169562bf13ca6ed47dac1e73c6d8e72cd89861eb Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 1 Feb 2024 13:50:47 -0600 Subject: #677 WIP -- Add clipping to alpha and pbr (not working on PBR for some reason) --- indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl | 7 +++++-- indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl | 4 ++++ indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl | 3 +++ indra/newview/llviewershadermgr.cpp | 3 ++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 160ae7a215..5e0141910b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -28,8 +28,9 @@ //deferred opaque implementation -#ifdef HAS_SKIN uniform mat4 modelview_matrix; + +#ifdef HAS_SKIN uniform mat4 projection_matrix; mat4 getObjectSkinnedTransform(); #else @@ -59,6 +60,7 @@ out vec4 vertex_color; out vec3 vary_tangent; flat out float vary_sign; out vec3 vary_normal; +out vec3 vary_position; vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); @@ -71,10 +73,11 @@ void main() mat = modelview_matrix * mat; vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; - + vary_position = pos; gl_Position = projection_matrix*vec4(pos,1.0); #else + vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index acd32a81b3..4aef22c296 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -78,6 +78,8 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); float getAmbientClamp(); +void mirrorClip(vec3 pos); + void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear); @@ -167,6 +169,8 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec void main() { + mirrorClip(vary_position); + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; vec4 pos = vec4(vary_position, 1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 003dd05e6f..059c2a64ce 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -90,6 +90,7 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); +void mirrorClip(vec3 pos); void waterClip(vec3 pos); void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor); @@ -156,6 +157,8 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor, void main() { + mirrorClip(vary_position); + vec3 color = vec3(0,0,0); vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index a93d60cb70..7dbfad4b82 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -294,7 +294,8 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredDiffuseProgram); mShaderList.push_back(&gObjectBumpProgram); mShaderList.push_back(&gDeferredBumpProgram); - + mShaderList.push_back(&gDeferredPBROpaqueProgram); + mShaderList.push_back(&gDeferredPBRAlphaProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() -- cgit v1.2.3 From b1410c8b679c14432038a62bff2de772f490bc4a Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 1 Feb 2024 14:00:40 -0600 Subject: #677 WIP -- fix PBR and avatar mirror clipping. --- indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl | 4 ++++ indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl | 2 ++ indra/newview/llfetchedgltfmaterial.cpp | 1 - indra/newview/llviewershadermgr.cpp | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 6ebe4ce251..c0607d0149 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -33,11 +33,15 @@ uniform float minimum_alpha; in vec3 vary_normal; in vec2 vary_texcoord0; +in vec3 vary_position; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos); void main() { + mirrorClip(vary_position); + vec4 diff = texture(diffuseMap, vary_texcoord0.xy); if (diff.a < minimum_alpha) diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index bc0c11ec46..5cc2846156 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -35,6 +35,7 @@ in vec4 weight; out vec3 vary_normal; out vec2 vary_texcoord0; +out vec3 vary_position; void main() { @@ -57,6 +58,7 @@ void main() vary_normal = norm; + vary_position = pos.xyz; gl_Position = projection_matrix * pos; } diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 6bd613622e..97b959e5cb 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -128,7 +128,6 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor); shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); - shader->uniform1f(LLShaderMgr::MIRROR_FLAG, 0); F32 normal_packed[8]; mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 7dbfad4b82..bb60ceed2a 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -296,6 +296,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredBumpProgram); mShaderList.push_back(&gDeferredPBROpaqueProgram); mShaderList.push_back(&gDeferredPBRAlphaProgram); + mShaderList.push_back(&gDeferredAvatarProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() -- cgit v1.2.3 From fac63e473a4b2b7b9b361c4d5656c94d47d88ef0 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 1 Feb 2024 12:11:20 -0800 Subject: #684 Fix pixellation on mirrors regardless of mirror resolution. --- indra/newview/app_settings/settings.xml | 15 ++--------- .../shaders/class1/interface/radianceGenF.glsl | 2 +- indra/newview/llheroprobemanager.cpp | 29 +++++++++++----------- indra/newview/llviewershadermgr.cpp | 16 +++++++++++- indra/newview/llviewershadermgr.h | 1 + indra/newview/pipeline.cpp | 5 ++++ indra/newview/pipeline.h | 3 +++ 7 files changed, 42 insertions(+), 29 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 242e274daf..f2ba4ba29e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10421,7 +10421,7 @@ Type S32 Value - 1024 + 2048 RenderHeroProbeDistance @@ -10432,18 +10432,7 @@ Type F32 Value - 16 - - RenderHeroProbeNearClipOffset - - Comment - Distance offset in meters for hero probes to near clip. - Persist - 1 - Type - F32 - Value - 2.1 + 8 RenderReflectionProbeVolumes diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index cb6f34713c..c1ed1bfe6e 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -130,7 +130,7 @@ vec4 prefilterEnvMap(vec3 R) float totalWeight = 0.0; float envMapDim = float(textureSize(reflectionProbes, 0).s); float roughness = mipLevel/max_probe_lod; - int numSamples = max(int(32*roughness), 1); + int numSamples = max(int(PROBE_FILTER_SAMPLES*roughness), 1); float numMips = max_probe_lod+1; diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ed37a67c85..42c8d4fb3f 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -217,7 +217,7 @@ void LLHeroProbeManager::update() void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip) { // hacky hot-swap of camera specific render targets - gPipeline.mRT = &gPipeline.mAuxillaryRT; + gPipeline.mRT = &gPipeline.mHeroProbeRT; probe->update(mRenderTarget.getWidth(), face, true, near_clip); @@ -252,9 +252,10 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n static LLStaticHashedString znear("znear"); static LLStaticHashedString zfar("zfar"); - LLRenderTarget *screen_rt = &gPipeline.mAuxillaryRT.screen; - LLRenderTarget *depth_rt = &gPipeline.mAuxillaryRT.deferredScreen; + LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen; + LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.deferredScreen; + /* // perform a gaussian blur on the super sampled render before downsampling { gGaussianProgram.bind(); @@ -277,7 +278,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); screen_rt->flush(); } - + */ S32 mips = log2((F32)mProbeResolution) + 0.5f; @@ -338,14 +339,14 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n { //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) - gRadianceGenProgram.bind(); + gHeroRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); - S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + S32 channel = gHeroRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); - gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); - gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength); + gHeroRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); + gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); + gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength); U32 res = mMipChain[0].getWidth(); @@ -357,10 +358,10 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n static LLStaticHashedString sWidth("u_width"); static LLStaticHashedString sStrength("probe_strength"); - gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); - gRadianceGenProgram.uniform1f(sMipLevel, i); - gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); - gRadianceGenProgram.uniform1f(sStrength, 1); + gHeroRadianceGenProgram.uniform1f(sRoughness, (F32) i / (F32) (mMipChain.size() - 1)); + gHeroRadianceGenProgram.uniform1f(sMipLevel, i); + gHeroRadianceGenProgram.uniform1i(sWidth, mProbeResolution); + gHeroRadianceGenProgram.uniform1f(sStrength, 1); for (int cf = 0; cf < 6; ++cf) { // for each cube face @@ -383,7 +384,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n } } - gRadianceGenProgram.unbind(); + gHeroRadianceGenProgram.unbind(); } mMipChain[0].flush(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index a93d60cb70..5e9c8f5595 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -84,7 +84,8 @@ LLGLSLShader gOcclusionCubeProgram; LLGLSLShader gGlowCombineProgram; LLGLSLShader gReflectionMipProgram; LLGLSLShader gGaussianProgram; -LLGLSLShader gRadianceGenProgram; +LLGLSLShader gRadianceGenProgram; +LLGLSLShader gHeroRadianceGenProgram; LLGLSLShader gIrradianceGenProgram; LLGLSLShader gGlowCombineFXAAProgram; LLGLSLShader gTwoTextureCompareProgram; @@ -2799,8 +2800,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface() gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER)); gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER)); gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + gRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "32"); success = gRadianceGenProgram.createShader(NULL, NULL); } + + if (success && gGLManager.mHasCubeMapArray) + { + gHeroRadianceGenProgram.mName = "Hero Radiance Gen Shader"; + gHeroRadianceGenProgram.mShaderFiles.clear(); + gHeroRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER)); + gHeroRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER)); + gHeroRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + gHeroRadianceGenProgram.addPermutation("HERO_PROBES", "1"); + gHeroRadianceGenProgram.addPermutation("PROBE_FILTER_SAMPLES", "4"); + success = gHeroRadianceGenProgram.createShader(NULL, NULL); + } if (success && gGLManager.mHasCubeMapArray) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index cb1729cd1b..21c8d2089b 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -153,6 +153,7 @@ extern LLGLSLShader gGlowCombineProgram; extern LLGLSLShader gReflectionMipProgram; extern LLGLSLShader gGaussianProgram; extern LLGLSLShader gRadianceGenProgram; +extern LLGLSLShader gHeroRadianceGenProgram; extern LLGLSLShader gIrradianceGenProgram; extern LLGLSLShader gGlowCombineFXAAProgram; extern LLGLSLShader gDebugProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d81bcef259..3bd7acb06a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -785,6 +785,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mRT = &mAuxillaryRT; U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled allocateScreenBuffer(res, res, samples); + + res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it. + mRT = &mHeroProbeRT; + allocateScreenBuffer(res, res, samples); + mRT = &mMainRT; gCubeSnapshot = FALSE; } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5ace90b000..bbe34933f7 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -699,6 +699,9 @@ public: // used by reflection probes and dynamic texture bakes RenderTargetPack mAuxillaryRT; + // Auxillary render target pack scaled to the hero probe's per-face size. + RenderTargetPack mHeroProbeRT; + // currently used render target pack RenderTargetPack* mRT; -- cgit v1.2.3 From aab98046b9971717ecdc739b2230377278c83da3 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 1 Feb 2024 13:03:28 -0800 Subject: #677 More clipping fixes. --- .../shaders/class1/deferred/terrainF.glsl | 2 ++ .../shaders/class3/environment/waterF.glsl | 3 +++ indra/newview/llheroprobemanager.cpp | 27 +--------------------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index f6d509e2c6..2dba7cb9d9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -39,9 +39,11 @@ in vec4 vary_texcoord0; in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 position); void main() { + mirrorClip(pos); /// Note: This should duplicate the blending functionality currently used for the terrain rendering. vec4 color0 = texture(detail_0, vary_texcoord0.xy); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index b364e454e8..b2a81aa025 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -35,6 +35,8 @@ vec3 scaleSoftClipFragLinear(vec3 l); void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); vec4 applyWaterFogViewLinear(vec3 pos, vec4 color); +void mirrorClip(vec3 pos); + // PBR interface vec2 BRDF(float NoV, float roughness); @@ -129,6 +131,7 @@ vec3 getPositionWithNDC(vec3 ndc); void main() { + mirrorClip(vary_position); vN = vary_normal; vT = vary_tangent; vB = cross(vN, vT); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 42c8d4fb3f..39f5bdec5a 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -167,7 +167,7 @@ void LLHeroProbeManager::update() mCurrentClipPlane.setVec(hero_pos, face_normal); mMirrorPosition = mNearestHero->getPositionAgent(); - mMirrorNormal = LLVector3(0, 0, 1); + mMirrorNormal = face_normal; probe_pos.load3(point.mV); @@ -255,31 +255,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen; LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.deferredScreen; - /* - // perform a gaussian blur on the super sampled render before downsampling - { - gGaussianProgram.bind(); - gGaussianProgram.uniform1f(resScale, 1.f / mProbeResolution); - 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(); -- cgit v1.2.3 From 2d4a63833c2515ae36c614fce8101f41be0e1d61 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 1 Feb 2024 15:34:34 -0800 Subject: #677 Clip underwater. --- indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 223e55eb69..ef086fc3be 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -55,9 +55,11 @@ in vec4 view; in vec3 vary_position; vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color); +void mirrorClip(vec3 position); void main() { + mirrorClip(vary_position); vec4 color; //get detail normals -- cgit v1.2.3 From ee5fe08603a1250fb5e2c1196a082897134ebb53 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 2 Feb 2024 11:52:18 -0600 Subject: #677 Fix clip plane glitching out at certain angles --- indra/newview/llsettingsvo.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index da5504f83f..deeecc6b3c 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -1009,6 +1009,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) glh::matrix4f mat(modelView); glh::matrix4f invtrans = mat.inverse().transpose(); + invtrans.m[3] = invtrans.m[7] = invtrans.m[11] = 0.f; glh::vec3f enorm; glh::vec3f ep; invtrans.mult_matrix_vec(norm, enorm); @@ -1017,10 +1018,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); - norm = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorNormal.mV[0], gPipeline.mHeroProbeManager.mMirrorNormal.mV[1], - gPipeline.mHeroProbeManager.mMirrorNormal.mV[2]); - p = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorPosition.mV[0], gPipeline.mHeroProbeManager.mMirrorPosition.mV[1], - gPipeline.mHeroProbeManager.mMirrorPosition.mV[2]); + norm = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorNormal.mV); + p = glh::vec3f(gPipeline.mHeroProbeManager.mMirrorPosition.mV); invtrans.mult_matrix_vec(norm, enorm); enorm.normalize(); mat.mult_matrix_vec(p, ep); -- cgit v1.2.3 From 6846600e3ef1eec7fade19f61d2d45614ae1a8b0 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 2 Feb 2024 13:49:06 -0600 Subject: #677 Fix terrain clipping and tweak hero probe mixing with radiance --- .../shaders/class1/deferred/terrainV.glsl | 3 +- .../shaders/class3/deferred/softenLightF.glsl | 34 +++++++++++++++++++--- indra/newview/llviewershadermgr.cpp | 1 + 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index 33a78fd26d..8e1e4b54d5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -25,6 +25,7 @@ uniform mat3 normal_matrix; uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix; uniform mat4 modelview_projection_matrix; in vec3 position; @@ -59,7 +60,7 @@ void main() vec4 t_pos = modelview_projection_matrix * pre_pos; gl_Position = t_pos; - pos = t_pos.xyz; + pos = (modelview_matrix*pre_pos).xyz; vary_normal = normalize(normal_matrix * normal); diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index b49c3386db..be180b877f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -60,6 +60,7 @@ uniform float ssao_irradiance_max; #endif // Inputs +uniform vec4 clipPlane; uniform mat3 env_mat; uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; @@ -189,6 +190,19 @@ void main() sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear); + #ifdef HERO_PROBES + float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; + if (clipDist > 0.0 && clipDist < 0.1 && perceptualRoughness < 0.2) + { + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) + { + radiance = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), perceptualRoughness*11).xyz; + } + } + #endif + + adjustIrradiance(irradiance, ambocc); vec3 diffuseColor; @@ -198,11 +212,11 @@ void main() vec3 v = -normalize(pos.xyz); color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); - #ifdef HERO_PROBES + /*#ifdef HERO_PROBES vec3 refnormpersp = reflect(pos.xyz, norm.xyz); color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; - #endif + #endif*/ } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { @@ -226,6 +240,18 @@ void main() sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity, false, amblit_linear); + #ifdef HERO_PROBES + float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; + if (clipDist > 0.0 && clipDist < 0.1 && spec.a > 0.8) + { + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) + { + radiance = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-spec.a)*11).xyz; + } + } + #endif + adjustIrradiance(irradiance, ambocc); // apply lambertian IBL only (see pbrIbl) @@ -261,9 +287,9 @@ void main() // add radiance map applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); - #ifdef HERO_PROBES + /*#ifdef HERO_PROBES color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - spec.a) * 11).xyz * spec.rgb; - #endif + #endif*/ } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index d0a54d8cfc..0aa0e13270 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -298,6 +298,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredPBROpaqueProgram); mShaderList.push_back(&gDeferredPBRAlphaProgram); mShaderList.push_back(&gDeferredAvatarProgram); + mShaderList.push_back(&gDeferredTerrainProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() -- cgit v1.2.3 From 5abc68ad438c1feb79f008aa8148dda77aae2af9 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 2 Feb 2024 15:43:56 -0600 Subject: #677 Move PBR mirror radiance mixing to reflectionProbeF so transparent PBR surfaces can be mirrors --- indra/llrender/llshadermgr.cpp | 6 ++++++ indra/llrender/llshadermgr.h | 1 + .../shaders/class3/deferred/reflectionProbeF.glsl | 18 ++++++++++++++++++ .../shaders/class3/deferred/softenLightF.glsl | 13 ------------- indra/newview/llviewercamera.cpp | 6 ++++++ indra/newview/llviewershadermgr.cpp | 7 ++----- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 758b54cf1f..e974fb636d 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -44,6 +44,7 @@ using std::make_pair; using std::string; LLShaderMgr * LLShaderMgr::sInstance = NULL; +bool LLShaderMgr::sMirrorsEnabled = false; LLShaderMgr::LLShaderMgr() { @@ -604,6 +605,11 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n"); } + if (sMirrorsEnabled) + { + extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n"); + } + // Use alpha float to store bit flags // See: C++: addDeferredAttachment(), shader: frag_data[2] extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index ebd682141d..2c66965344 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -365,6 +365,7 @@ public: bool mShaderCacheInitialized = false; bool mShaderCacheEnabled = false; std::string mShaderCacheDir; + static bool sMirrorsEnabled; protected: diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index d9dc83bb10..fe2647452f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -682,6 +682,12 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit) return col[1]+col[0]; } + +#if defined(HERO_PROBES) +uniform vec4 clipPlane; +uniform samplerCubeArray heroProbes; +#endif + void doProbeSample(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit) { @@ -713,6 +719,18 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv, glossenv = mix(glossenv, ssr.rgb, ssr.a); } #endif + +#if defined(HERO_PROBES) + float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; + if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8) + { + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) + { + glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz; + } + } +#endif } void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index be180b877f..a8cfc3537e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -189,19 +189,6 @@ void main() float gloss = 1.0 - perceptualRoughness; sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear); - - #ifdef HERO_PROBES - float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; - if (clipDist > 0.0 && clipDist < 0.1 && perceptualRoughness < 0.2) - { - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) - { - radiance = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), perceptualRoughness*11).xyz; - } - } - #endif - adjustIrradiance(irradiance, ambocc); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 4134e35f87..9ba42e4f47 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -764,6 +764,12 @@ BOOL LLViewerCamera::cameraUnderWater() const { LLViewerRegion* regionp = LLWorld::instance().getRegionFromPosAgent(getOrigin()); + if (gPipeline.mHeroProbeManager.isMirrorPass()) + { + // TODO: figure out how to handle this case + return FALSE; + } + if (!regionp) { regionp = gAgent.getRegion(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 0aa0e13270..e9562d64e4 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -359,6 +359,8 @@ void LLViewerShaderMgr::setShaders() return; } + LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors; + if (!gGLManager.mHasRequirements) { // Viewer will show 'hardware requirements' warning later @@ -1813,11 +1815,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1"); } - if (LLPipeline::RenderMirrors) - { - gDeferredSoftenProgram.addPermutation("HERO_PROBES", "1"); - } - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { //if using SSAO, take screen space light map into account as if shadows are enabled gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); -- cgit v1.2.3 From 8075cf04c4d55b5978a6a19efbf329d332fd85a0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 2 Feb 2024 23:51:56 +0200 Subject: Issue #26 Support texture drop onto PBR materials --- indra/newview/llpanelface.cpp | 15 ++- indra/newview/llpanelface.h | 1 + indra/newview/llselectmgr.cpp | 3 +- indra/newview/lltooldraganddrop.cpp | 220 +++++++++++++++++++++++++++--------- indra/newview/lltooldraganddrop.h | 5 +- 5 files changed, 188 insertions(+), 56 deletions(-) diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f936739fde..a527ebe47f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -227,6 +227,17 @@ LLRender::eTexIndex LLPanelFace::getTextureDropChannel() return LLRender::eTexIndex(MATTYPE_DIFFUSE); } +LLGLTFMaterial::TextureInfo LLPanelFace::getPBRDropChannel() +{ + if (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR) + { + LLRadioGroup* radio_pbr_type = getChild("radio_pbr_type"); + return texture_info_from_pbrtype(radio_pbr_type->getSelectedIndex()); + } + + return texture_info_from_pbrtype(PBRTYPE_BASE_COLOR); +} + // Things the UI provides... // LLUUID LLPanelFace::getCurrentNormalMap() { return getChild("bumpytexture control")->getImageAssetID(); } @@ -4653,7 +4664,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) LLToolDragAndDrop::dropTextureAllFaces(objectp, itemp_res, from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); + LLUUID::null, + false); } else // one face { @@ -4662,6 +4674,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) itemp_res, from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null, + false, 0); } } diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 5ca6a95699..a64b85815f 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -126,6 +126,7 @@ public: LLRender::eTexIndex getTextureChannelToEdit(); LLRender::eTexIndex getTextureDropChannel(); + LLGLTFMaterial::TextureInfo getPBRDropChannel(); protected: void navigateToTitleMedia(const std::string url); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index c2e3857af0..30e12faca5 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1879,7 +1879,8 @@ bool LLSelectMgr::selectionSetImage(const LLUUID& imageid) te, mItem, LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); + LLUUID::null, + false); } else // not an inventory item { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index e7f96239fd..bfa9386cd4 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1071,10 +1071,64 @@ BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj, return TRUE; } +void set_texture_to_material(LLViewerObject* hit_obj, + S32 hit_face, + const LLUUID& asset_id, + LLGLTFMaterial::TextureInfo drop_channel) +{ + LLTextureEntry* te = hit_obj->getTE(hit_face); + if (te) + { + LLPointer material = te->getGLTFMaterialOverride(); + + // make a copy to not invalidate existing + // material for multiple objects + if (material.isNull()) + { + // Start with a material override which does not make any changes + material = new LLGLTFMaterial(); + } + else + { + material = new LLGLTFMaterial(*material); + } + + switch (drop_channel) + { + case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: + default: + { + material->setBaseColorId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: + { + material->setOcclusionRoughnessMetallicId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: + { + material->setEmissiveId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: + { + material->setNormalId(asset_id); + } + break; + } + LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); + } +} + void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, LLInventoryItem* item, LLToolDragAndDrop::ESource source, - const LLUUID& src_id) + const LLUUID& src_id, + bool remove_pbr) { if (!item) { @@ -1091,28 +1145,46 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, break; } } - if (!has_non_pbr_faces) + + if (has_non_pbr_faces || remove_pbr) { - return; + BOOL res = handleDropMaterialProtections(hit_obj, item, source, src_id); + if (!res) + { + return; + } } LLUUID asset_id = item->getAssetUUID(); - BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); - if (!success) - { - return; - } + + // Overrides require textures to be copy and transfer free + LLPermissions item_permissions = item->getPermissions(); + bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()); + allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); add(LLStatViewer::EDIT_TEXTURE, 1); for( S32 face = 0; face < num_faces; face++ ) { - if (hit_obj->getRenderMaterialID(face).isNull()) + if (remove_pbr) + { + hit_obj->setRenderMaterialID(face, LLUUID::null); + hit_obj->setTEImage(face, image); + dialog_refresh_all(); + } + else if (hit_obj->getRenderMaterialID(face).isNull()) { - // update viewer side image in anticipation of update from simulator + // update viewer side hit_obj->setTEImage(face, image); dialog_refresh_all(); } + else if (allow_adding_to_override) + { + set_texture_to_material(hit_obj, face, asset_id, LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR); + } } + // send the update to the simulator + LLGLTFMaterialList::flushUpdates(nullptr); hit_obj->sendTEUpdate(); } @@ -1260,21 +1332,13 @@ void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, dialog_refresh_all(); } -/* -void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item) -{ - if (hit_face == -1) return; - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID()); - - avatar->userSetOptionalTE( hit_face, image); -} -*/ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, ESource source, const LLUUID& src_id, bool all_faces, + bool remove_pbr, S32 tex_channel) { LLSelectNode* nodep = nullptr; @@ -1286,13 +1350,15 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, if (all_faces) { - dropTextureAllFaces(hit_obj, item, source, src_id); + dropTextureAllFaces(hit_obj, item, source, src_id, remove_pbr); // If user dropped a texture onto face it implies // applying texture now without cancel, save to selection if (nodep) { uuid_vec_t texture_ids; + uuid_vec_t material_ids; + gltf_materials_vec_t override_materials; S32 num_faces = hit_obj->getNumTEs(); for (S32 face = 0; face < num_faces; face++) { @@ -1305,13 +1371,35 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, { texture_ids.push_back(LLUUID::null); } + + // either removed or modified materials + if (remove_pbr) + { + material_ids.push_back(LLUUID::null); + } + else + { + material_ids.push_back(hit_obj->getRenderMaterialID(face)); + } + + LLTextureEntry* te = hit_obj->getTE(hit_face); + if (te && !remove_pbr) + { + override_materials.push_back(te->getGLTFMaterialOverride()); + } + else + { + override_materials.push_back(nullptr); + } } + nodep->saveTextures(texture_ids); + nodep->saveGLTFMaterials(material_ids, override_materials); } } else { - dropTextureOneFace(hit_obj, hit_face, item, source, src_id); + dropTextureOneFace(hit_obj, hit_face, item, source, src_id, remove_pbr, tex_channel); // If user dropped a texture onto face it implies // applying texture now without cancel, save to selection @@ -1331,6 +1419,16 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, { nodep->mSavedTextures[hit_face] = LLUUID::null; } + + LLTextureEntry* te = hit_obj->getTE(hit_face); + if (te && !remove_pbr) + { + nodep->mSavedGLTFOverrideMaterials[hit_face] = te->getGLTFMaterialOverride(); + } + else + { + nodep->mSavedGLTFOverrideMaterials[hit_face] = nullptr; + } } } } @@ -1340,6 +1438,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, LLInventoryItem* item, LLToolDragAndDrop::ESource source, const LLUUID& src_id, + bool remove_pbr, S32 tex_channel) { if (hit_face == -1) return; @@ -1348,21 +1447,44 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL; return; } - if (hit_obj->getRenderMaterialID(hit_face).notNull()) + + LLUUID asset_id = item->getAssetUUID(); + + if (hit_obj->getRenderMaterialID(hit_face).notNull() && !remove_pbr) { + // Overrides require textures to be copy and transfer free + LLPermissions item_permissions = item->getPermissions(); + bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()); + allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + if (allow_adding_to_override) + { + LLGLTFMaterial::TextureInfo drop_channel = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR; + LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + if (gFloaterTools->getVisible() && panel_face) + { + drop_channel = panel_face->getPBRDropChannel(); + } + set_texture_to_material(hit_obj, hit_face, asset_id, drop_channel); + LLGLTFMaterialList::flushUpdates(nullptr); + } return; } - LLUUID asset_id = item->getAssetUUID(); BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id); if (!success) { return; } + if (remove_pbr) + { + hit_obj->setRenderMaterialID(hit_face, LLUUID::null); + } + // update viewer side image in anticipation of update from simulator LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); add(LLStatViewer::EDIT_TEXTURE, 1); - LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL; + LLTextureEntry* tep = hit_obj->getTE(hit_face); LLPanelFace* panel_face = gFloaterTools->getPanelFace(); @@ -1380,6 +1502,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, break; case 1: + if (tep) { LLMaterialPtr old_mat = tep->getMaterialParams(); LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); @@ -1391,6 +1514,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, break; case 2: + if (tep) { LLMaterialPtr old_mat = tep->getMaterialParams(); LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); @@ -2200,6 +2324,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( LLViewerInventoryCategory* cat; locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; + LLPermissions item_permissions = item->getPermissions(); EAcceptance rv = willObjectAcceptInventory(obj, item); if((mask & MASK_CONTROL)) { @@ -2214,12 +2339,12 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( return ACCEPT_NO_LOCKED; } - if (cargo_type == DAD_TEXTURE) + if (cargo_type == DAD_TEXTURE && (mask & MASK_ALT) == 0) { + bool has_non_pbr_faces = false; if ((mask & MASK_SHIFT)) { S32 num_faces = obj->getNumTEs(); - bool has_non_pbr_faces = false; for (S32 face = 0; face < num_faces; face++) { if (obj->getRenderMaterialID(face).isNull()) @@ -2228,14 +2353,19 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( break; } } - if (!has_non_pbr_faces) - { - return ACCEPT_NO; - } } - else if (obj->getRenderMaterialID(face).notNull()) + else + { + has_non_pbr_faces = obj->getRenderMaterialID(face).isNull(); + } + + if (!has_non_pbr_faces) { - return ACCEPT_NO; + // Only pbr faces selected, texture will be added to an override + // Overrides require textures to be copy and transfer free + bool allow_adding_to_override = item_permissions.allowOperationBy(PERM_COPY, gAgent.getID()); + allow_adding_to_override &= item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + if (!allow_adding_to_override) return ACCEPT_NO; } } @@ -2244,15 +2374,16 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( if (cargo_type == DAD_TEXTURE) { bool all_faces = mask & MASK_SHIFT; - if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + bool remove_pbr = mask & MASK_ALT; + if (item_permissions.allowOperationBy(PERM_COPY, gAgent.getID())) { - dropTexture(obj, face, item, mSource, mSourceID, all_faces); + dropTexture(obj, face, item, mSource, mSourceID, all_faces, remove_pbr); } else { ESource source = mSource; LLUUID source_id = mSourceID; - LLNotificationsUtil::add("ApplyInventoryToObject", LLSD(), LLSD(), [obj, face, item, source, source_id, all_faces](const LLSD& notification, const LLSD& response) + LLNotificationsUtil::add("ApplyInventoryToObject", LLSD(), LLSD(), [obj, face, item, source, source_id, all_faces, remove_pbr](const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); // if Cancel pressed @@ -2260,7 +2391,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( { return; } - dropTexture(obj, face, item, source, source_id, all_faces); + dropTexture(obj, face, item, source, source_id, all_faces, remove_pbr); }); } } @@ -2327,23 +2458,6 @@ EAcceptance LLToolDragAndDrop::dad3dMeshObject( return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH); } - -/* -EAcceptance LLToolDragAndDrop::dad3dTextureSelf( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) -{ - LL_DEBUGS() << "LLToolDragAndDrop::dad3dTextureAvatar()" << LL_ENDL; - if(drop) - { - if( !(mask & MASK_SHIFT) ) - { - dropTextureOneFaceAvatar( (LLVOAvatar*)obj, face, (LLInventoryItem*)mCargoData); - } - } - return (mask & MASK_SHIFT) ? ACCEPT_NO : ACCEPT_YES_SINGLE; -} -*/ - EAcceptance LLToolDragAndDrop::dad3dWearItem( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 7bdd2d1a49..db2fe87f20 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -249,17 +249,20 @@ public: ESource source, const LLUUID& src_id, bool all_faces, + bool replace_pbr, S32 tex_channel = -1); static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, ESource source, const LLUUID& src_id, + bool remove_pbr, S32 tex_channel = -1); static void dropTextureAllFaces(LLViewerObject* hit_obj, LLInventoryItem* item, ESource source, - const LLUUID& src_id); + const LLUUID& src_id, + bool remove_pbr); static void dropMaterial(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, -- cgit v1.2.3 From 23aa975cf0b516bc7de9f767967c52c5fd08dd12 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 5 Feb 2024 16:05:51 +0200 Subject: SL-20669 Fix white uuid --- indra/llcommon/indra_constants.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index 473b3ebdc9..9a0c565b06 100644 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp @@ -50,7 +50,7 @@ const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver -const LLUUID IMG_WHITE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver +const LLUUID IMG_WHITE ("5748decc-f629-461c-9a36-a35a221fe21f"); // dataserver const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver -- cgit v1.2.3 From 4e61152ca2fc2fdaedc9e27c4d1a16e248b59d9a Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 5 Feb 2024 12:00:38 -0600 Subject: #677 Add clipping to trees and alpha masked blinn-phong --- .../app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl | 6 ++++++ .../shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl | 5 +++++ indra/newview/app_settings/shaders/class1/deferred/treeF.glsl | 3 +++ indra/newview/app_settings/shaders/class1/deferred/treeV.glsl | 4 ++++ indra/newview/llviewershadermgr.cpp | 3 +++ 5 files changed, 21 insertions(+) diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index 6f3b94f734..e8ead91504 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -31,14 +31,20 @@ uniform float minimum_alpha; uniform sampler2D diffuseMap; +in vec3 vary_position; + in vec3 vary_normal; in vec4 vertex_color; in vec2 vary_texcoord0; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos); + void main() { + mirrorClip(vary_position); + vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color; if (col.a < minimum_alpha) diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index e5f2af2c53..a07c892d8e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -28,6 +28,7 @@ out vec4 frag_data[4]; in vec3 vary_normal; +in vec3 vary_position; uniform float minimum_alpha; @@ -36,8 +37,12 @@ in vec2 vary_texcoord0; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos); + void main() { + mirrorClip(vary_position); + vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; if (col.a < minimum_alpha) diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index e2d87e68fa..f108faf283 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -32,13 +32,16 @@ uniform sampler2D diffuseMap; in vec4 vertex_color; in vec3 vary_normal; in vec2 vary_texcoord0; +in vec3 vary_position; uniform float minimum_alpha; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos); void main() { + mirrorClip(vary_position); vec4 col = texture(diffuseMap, vary_texcoord0.xy); if (col.a < minimum_alpha) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index ce8a10712c..c84fccd4c6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -24,6 +24,7 @@ */ uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix; uniform mat4 modelview_projection_matrix; uniform mat3 normal_matrix; @@ -34,11 +35,14 @@ in vec2 texcoord0; out vec3 vary_normal; out vec4 vertex_color; out vec2 vary_texcoord0; +out vec3 vary_position; void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; + vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; vary_normal = normalize(normal_matrix * normal); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e9562d64e4..1fecf90c1f 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -299,6 +299,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredPBRAlphaProgram); mShaderList.push_back(&gDeferredAvatarProgram); mShaderList.push_back(&gDeferredTerrainProgram); + mShaderList.push_back(&gDeferredDiffuseAlphaMaskProgram); + mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram); + mShaderList.push_back(&gDeferredTreeProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() -- cgit v1.2.3 From 0e91d18da3f203bcef681d3134b736978114c2bd Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 5 Feb 2024 15:36:42 -0600 Subject: #677 Add mirror clipping to rigged shaders --- .../shaders/class1/deferred/materialV.glsl | 2 - indra/newview/llenvironment.cpp | 6 +- indra/newview/llviewershadermgr.cpp | 118 +++++++++++++-------- indra/newview/llviewershadermgr.h | 5 +- 4 files changed, 83 insertions(+), 48 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 41112bce30..ddf878ae60 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -78,9 +78,7 @@ void main() vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) vary_position = pos; -#endif gl_Position = projection_matrix*vec4(pos,1.0); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 60c2682078..affea3f69c 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -1675,8 +1675,6 @@ void LLEnvironment::update(const LLViewerCamera * cam) updateSettingsUniforms(); - // *TODO: potential optimization - this block may only need to be - // executed some of the time. For example for water shaders only. { LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; end_shaders = LLViewerShaderMgr::instance()->endShaders(); @@ -1687,6 +1685,10 @@ void LLEnvironment::update(const LLViewerCamera * cam) || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) { shaders_iter->mUniformsDirty = TRUE; + if (shaders_iter->mRiggedVariant) + { + shaders_iter->mRiggedVariant->mUniformsDirty = TRUE; + } } } } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 1fecf90c1f..164b36af65 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -104,7 +104,6 @@ LLGLSLShader gObjectPreviewProgram; LLGLSLShader gSkinnedObjectPreviewProgram; LLGLSLShader gPhysicsPreviewProgram; LLGLSLShader gObjectFullbrightAlphaMaskProgram; -LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram; LLGLSLShader gObjectBumpProgram; LLGLSLShader gSkinnedObjectBumpProgram; LLGLSLShader gObjectAlphaMaskNoColorProgram; @@ -226,7 +225,7 @@ LLGLSLShader gDeferredSkinnedPBRAlphaProgram; LLGLSLShader gDeferredPBRTerrainProgram; //helper for making a rigged variant of a given shader -bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) +static bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) { riggedShader.mName = llformat("Skinned %s", shader.mName.c_str()); riggedShader.mFeatures = shader.mFeatures; @@ -241,73 +240,94 @@ bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) return riggedShader.createShader(NULL, NULL); } +static bool no_redundant_shaders(const std::vector& shaders) +{ + std::set names; + for (LLGLSLShader* shader : shaders) + { + if (names.find(shader->mName) != names.end()) + { + LL_WARNS("Shader") << "Redundant shader: " << shader->mName << LL_ENDL; + return false; + } + names.insert(shader->mName); + + if (shader->mRiggedVariant) + { + if (names.find(shader->mRiggedVariant->mName) != names.end()) + { + LL_WARNS("Shader") << "Redundant shader: " << shader->mRiggedVariant->mName << LL_ENDL; + return false; + } + names.insert(shader->mRiggedVariant->mName); + } + } + return true; +} + + LLViewerShaderMgr::LLViewerShaderMgr() : mShaderLevel(SHADER_COUNT, 0), mMaxAvatarShaderLevel(0) { +} + +LLViewerShaderMgr::~LLViewerShaderMgr() +{ + mShaderLevel.clear(); + mShaderList.clear(); +} + +void LLViewerShaderMgr::finalizeShaderList() +{ //ONLY shaders that need WL Param management should be added here - mShaderList.push_back(&gAvatarProgram); - mShaderList.push_back(&gWaterProgram); - mShaderList.push_back(&gWaterEdgeProgram); - mShaderList.push_back(&gAvatarEyeballProgram); - mShaderList.push_back(&gImpostorProgram); - mShaderList.push_back(&gObjectBumpProgram); - mShaderList.push_back(&gSkinnedObjectBumpProgram); - mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram); - mShaderList.push_back(&gObjectAlphaMaskNoColorProgram); - mShaderList.push_back(&gUnderWaterProgram); - mShaderList.push_back(&gDeferredSunProgram); + mShaderList.push_back(&gAvatarProgram); + mShaderList.push_back(&gWaterProgram); + mShaderList.push_back(&gWaterEdgeProgram); + mShaderList.push_back(&gAvatarEyeballProgram); + mShaderList.push_back(&gImpostorProgram); + mShaderList.push_back(&gObjectBumpProgram); + mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); + mShaderList.push_back(&gObjectAlphaMaskNoColorProgram); + mShaderList.push_back(&gUnderWaterProgram); + mShaderList.push_back(&gDeferredSunProgram); mShaderList.push_back(&gHazeProgram); mShaderList.push_back(&gHazeWaterProgram); - mShaderList.push_back(&gDeferredSoftenProgram); - mShaderList.push_back(&gDeferredAlphaProgram); + mShaderList.push_back(&gDeferredSoftenProgram); + mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gHUDAlphaProgram); - mShaderList.push_back(&gDeferredSkinnedAlphaProgram); - mShaderList.push_back(&gDeferredAlphaImpostorProgram); - mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram); - mShaderList.push_back(&gDeferredFullbrightProgram); + mShaderList.push_back(&gDeferredAlphaImpostorProgram); + mShaderList.push_back(&gDeferredFullbrightProgram); mShaderList.push_back(&gHUDFullbrightProgram); - mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram); mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram); mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram); - mShaderList.push_back(&gDeferredFullbrightShinyProgram); + mShaderList.push_back(&gDeferredFullbrightShinyProgram); mShaderList.push_back(&gHUDFullbrightShinyProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskAlphaProgram); - mShaderList.push_back(&gDeferredEmissiveProgram); - mShaderList.push_back(&gDeferredSkinnedEmissiveProgram); - mShaderList.push_back(&gDeferredAvatarEyesProgram); - mShaderList.push_back(&gDeferredAvatarAlphaProgram); - mShaderList.push_back(&gDeferredWLSkyProgram); - mShaderList.push_back(&gDeferredWLCloudProgram); + mShaderList.push_back(&gDeferredEmissiveProgram); + mShaderList.push_back(&gDeferredAvatarEyesProgram); + mShaderList.push_back(&gDeferredAvatarAlphaProgram); + mShaderList.push_back(&gDeferredWLSkyProgram); + mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); mShaderList.push_back(&gDeferredWLSunProgram); mShaderList.push_back(&gDeferredPBRAlphaProgram); mShaderList.push_back(&gHUDPBRAlphaProgram); - mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma mShaderList.push_back(&gNoPostGammaCorrectProgram); mShaderList.push_back(&gLegacyPostGammaCorrectProgram); mShaderList.push_back(&gDeferredDiffuseProgram); - mShaderList.push_back(&gObjectBumpProgram); mShaderList.push_back(&gDeferredBumpProgram); mShaderList.push_back(&gDeferredPBROpaqueProgram); - mShaderList.push_back(&gDeferredPBRAlphaProgram); mShaderList.push_back(&gDeferredAvatarProgram); mShaderList.push_back(&gDeferredTerrainProgram); mShaderList.push_back(&gDeferredDiffuseAlphaMaskProgram); mShaderList.push_back(&gDeferredNonIndexedDiffuseAlphaMaskProgram); mShaderList.push_back(&gDeferredTreeProgram); -} -LLViewerShaderMgr::~LLViewerShaderMgr() -{ - mShaderLevel.clear(); - mShaderList.clear(); + // make sure there are no redundancies + llassert(no_redundant_shaders(mShaderList)); } // static @@ -362,6 +382,8 @@ void LLViewerShaderMgr::setShaders() return; } + mShaderList.clear(); + LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors; if (!gGLManager.mHasRequirements) @@ -545,6 +567,8 @@ void LLViewerShaderMgr::setShaders() } gPipeline.createGLBuffers(); + finalizeShaderList(); + reentrance = false; } @@ -1077,9 +1101,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { if (success) { - mShaderList.push_back(&gDeferredMaterialProgram[i]); + bool has_skin = i & 0x10; - gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i); + if (!has_skin) + { + mShaderList.push_back(&gDeferredMaterialProgram[i]); + gDeferredMaterialProgram[i].mName = llformat("Material Shader %d", i); + } + else + { + gDeferredMaterialProgram[i].mName = llformat("Skinned Material Shader %d", i); + } U32 alpha_mode = i & 0x3; @@ -1116,7 +1148,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); } - bool has_skin = i & 0x10; + gDeferredMaterialProgram[i].mFeatures.hasSrgb = true; gDeferredMaterialProgram[i].mFeatures.encodesNormal = true; gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 21c8d2089b..9b4583cacf 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -41,6 +41,10 @@ public: LLViewerShaderMgr(); /* virtual */ ~LLViewerShaderMgr(); + // Add shaders to mShaderList for later uniform propagation + // Will assert on redundant shader entries in debug builds + void finalizeShaderList(); + // singleton pattern implementation static LLViewerShaderMgr * instance(); static void releaseInstance(); @@ -172,7 +176,6 @@ extern LLGLSLShader gOneTextureFilterProgram; //object shaders extern LLGLSLShader gObjectPreviewProgram; extern LLGLSLShader gPhysicsPreviewProgram; -extern LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram; extern LLGLSLShader gObjectBumpProgram; extern LLGLSLShader gSkinnedObjectBumpProgram; extern LLGLSLShader gObjectAlphaMaskNoColorProgram; -- cgit v1.2.3 From 75b67c3750083e5ea150432d999866a0e383f927 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 5 Feb 2024 16:01:47 -0600 Subject: #677 Add hero probes to blinn-phong surfaces --- .../shaders/class3/deferred/reflectionProbeF.glsl | 39 ++++++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index fe2647452f..4f6e01764a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -684,10 +684,33 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit) #if defined(HERO_PROBES) + uniform vec4 clipPlane; uniform samplerCubeArray heroProbes; + +void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) +{ + float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; + if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8) + { + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) + { + glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz; + } + } +} + +#else + +void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) +{ +} + #endif + + void doProbeSample(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit) { @@ -720,17 +743,7 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv, } #endif -#if defined(HERO_PROBES) - float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; - if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8) - { - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) - { - glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz; - } - } -#endif + tapHeroProbe(glossenv, pos, norm, glossiness); } void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, @@ -818,6 +831,7 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout { float lod = (1.0-glossiness)*reflection_lods; glossenv = sampleProbes(pos, normalize(refnormpersp), lod); + } if (envIntensity > 0.0) @@ -845,6 +859,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout } #endif + tapHeroProbe(glossenv, pos, norm, glossiness); + tapHeroProbe(legacyenv, pos, norm, 1.0); + glossenv = clamp(glossenv, vec3(0), vec3(10)); } -- cgit v1.2.3 From 086249191078bcfb81d2697509c325fb34ffaf94 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 6 Feb 2024 01:31:13 -0800 Subject: #679 Add mirror update params to the volume floater. #740 Add support for FLAG_MIRROR in the viewer for mirror probes. --- indra/llprimitive/llprimitive.cpp | 13 ++++++ indra/llprimitive/llprimitive.h | 3 ++ indra/newview/llpanelvolume.cpp | 38 ++++++++++++++--- indra/newview/llvovolume.cpp | 44 ++++++++++++++++++++ indra/newview/llvovolume.h | 4 ++ .../newview/skins/default/xui/en/floater_tools.xml | 47 ++++++++++++++-------- 6 files changed, 127 insertions(+), 22 deletions(-) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index f67959de5b..0f538ffd0c 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1968,6 +1968,19 @@ void LLReflectionProbeParams::setIsDynamic(bool is_dynamic) } } + +void LLReflectionProbeParams::setIsMirror(bool is_mirror) +{ + if (is_mirror) + { + mFlags |= FLAG_MIRROR; + } + else + { + mFlags &= ~FLAG_MIRROR; + } +} + //============================================================================ LLFlexibleObjectData::LLFlexibleObjectData() { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 88bac34ef2..db4f4ddeba 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -197,6 +197,7 @@ public: { FLAG_BOX_VOLUME = 0x01, // use a box influence volume FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe + FLAG_MIRROR = 0x04, // This probe is used for reflections on realtime mirrors. }; protected: @@ -220,11 +221,13 @@ public: void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); } void setIsBox(bool is_box); void setIsDynamic(bool is_dynamic); + void setIsMirror(bool is_mirror); F32 getAmbiance() const { return mAmbiance; } F32 getClipDistance() const { return mClipDistance; } bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; } bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; } + bool getIsMirror() const { return (mFlags & FLAG_MIRROR) != 0; } }; //------------------------------------------------- diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index a306a0a9ac..c03f52d23f 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -155,7 +155,7 @@ BOOL LLPanelVolume::postBuild() // REFLECTION PROBE Parameters { childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this); - childSetCommitCallback("Probe Dynamic", onCommitProbe, this); + childSetCommitCallback("Probe Update Type", onCommitProbe, this); childSetCommitCallback("Probe Volume Type", onCommitProbe, this); childSetCommitCallback("Probe Ambiance", onCommitProbe, this); childSetCommitCallback("Probe Near Clip", onCommitProbe, this); @@ -401,17 +401,18 @@ void LLPanelVolume::getState( ) bool probe_enabled = is_probe && editable && single_volume; - getChildView("Probe Dynamic")->setEnabled(probe_enabled); + getChildView("Probe Update Type")->setEnabled(probe_enabled); getChildView("Probe Volume Type")->setEnabled(probe_enabled); getChildView("Probe Ambiance")->setEnabled(probe_enabled); getChildView("Probe Near Clip")->setEnabled(probe_enabled); + getChildView("Probe Update Label")->setEnabled(probe_enabled); if (!probe_enabled) { getChild("Probe Volume Type", true)->clear(); getChild("Probe Ambiance", true)->clear(); getChild("Probe Near Clip", true)->clear(); - getChild("Probe Dynamic", true)->clear(); + getChild("Probe Update Type", true)->clear(); } else { @@ -425,10 +426,28 @@ void LLPanelVolume::getState( ) volume_type = "Sphere"; } + std::string update_type; + if (volobjp->getReflectionProbeIsDynamic()) + { + update_type = "Dynamic"; + } + else if (volobjp->getReflectionProbeIsMirror()) + { + update_type = "Mirror"; + + } + else + { + update_type = "Static"; + } + + getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror"); + getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror"); + getChild("Probe Volume Type", true)->setValue(volume_type); getChild("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance()); getChild("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip()); - getChild("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic()); + getChild("Probe Update Type", true)->setValue(update_type); } // Animated Mesh @@ -715,7 +734,7 @@ void LLPanelVolume::clearCtrls() getChildView("Reflection Probe")->setEnabled(false);; getChildView("Probe Volume Type")->setEnabled(false); - getChildView("Probe Dynamic")->setEnabled(false); + getChildView("Probe Update Type")->setEnabled(false); getChildView("Probe Ambiance")->setEnabled(false); getChildView("Probe Near Clip")->setEnabled(false); getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false); @@ -1422,7 +1441,14 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) volobjp->setReflectionProbeAmbiance((F32)self->getChild("Probe Ambiance")->getValue().asReal()); volobjp->setReflectionProbeNearClip((F32)self->getChild("Probe Near Clip")->getValue().asReal()); - volobjp->setReflectionProbeIsDynamic(self->getChild("Probe Dynamic")->getValue().asBoolean()); + + std::string update_type = self->getChild("Probe Update Type")->getValue().asString(); + + volobjp->setReflectionProbeIsDynamic(update_type == "Dynamic"); + volobjp->setReflectionProbeIsMirror(update_type == "Mirror"); + + self->getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror"); + self->getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror"); std::string shape_type = self->getChild("Probe Volume Type")->getValue().asString(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9813039145..77f654be23 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3442,6 +3442,22 @@ bool LLVOVolume::setReflectionProbeIsBox(bool is_box) return false; } +bool LLVOVolume::setReflectionProbeIsPlane(bool is_plane) +{ + LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + if (param_block->getIsBox() != is_plane) + { + param_block->setIsBox(is_plane); + parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + return true; + } + } + + return false; +} + bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic) { LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -3458,6 +3474,22 @@ bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic) return false; } +bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror) +{ + LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + if (param_block->getIsMirror() != is_mirror) + { + param_block->setIsMirror(is_mirror); + parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + return true; + } + } + + return false; +} + F32 LLVOVolume::getReflectionProbeAmbiance() const { const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -3506,6 +3538,18 @@ bool LLVOVolume::getReflectionProbeIsDynamic() const return false; } +bool LLVOVolume::getReflectionProbeIsMirror() const +{ + const LLReflectionProbeParams *param_block = + (const LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + return param_block->getIsMirror(); + } + + return false; +} + U32 LLVOVolume::getVolumeInterfaceID() const { if (mVolumeImpl) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index b03fc4b862..89ef1d7d7a 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -305,13 +305,17 @@ public: bool setReflectionProbeAmbiance(F32 ambiance); bool setReflectionProbeNearClip(F32 near_clip); bool setReflectionProbeIsBox(bool is_box); + bool setReflectionProbeIsPlane(bool is_plane); bool setReflectionProbeIsDynamic(bool is_dynamic); + bool setReflectionProbeIsMirror(bool is_mirror); BOOL isReflectionProbe() const override; F32 getReflectionProbeAmbiance() const; F32 getReflectionProbeNearClip() const; bool getReflectionProbeIsBox() const; + bool getReflectionProbeIsPlane() const; bool getReflectionProbeIsDynamic() const; + bool getReflectionProbeIsMirror() const; BOOL isMirror() const override; diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 510351b471..4f4216c85a 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2410,15 +2410,6 @@ even though the user gets a free copy. name="object_horizontal" top_pad="10" width="278" /> - - + name="Probe Update Label" + text_readonly_color="LabelDisabledColor" + width="100"> + Probe Update + + + + + + Date: Tue, 6 Feb 2024 02:53:57 -0800 Subject: #740 Make sure we evaluate if the probe is a mirror probe or not. #682 Re-enable gaussian filtering, and reduce the mirror resolution back to 1024. Also just generally clean up the code a bit. --- indra/llprimitive/llprimitive.cpp | 34 ------------ indra/llprimitive/llprimitive.h | 11 ---- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llheroprobemanager.cpp | 65 ++++++++++++----------- indra/newview/llheroprobemanager.h | 7 +-- indra/newview/llpanelvolume.cpp | 29 ----------- indra/newview/llpanelvolume.h | 4 +- indra/newview/llviewerobject.cpp | 46 +---------------- indra/newview/llviewerobject.h | 5 -- indra/newview/llvovolume.cpp | 91 ++++++--------------------------- indra/newview/llvovolume.h | 9 ---- 11 files changed, 57 insertions(+), 246 deletions(-) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 0f538ffd0c..53d09df618 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1825,40 +1825,6 @@ bool LLLightParams::fromLLSD(LLSD& sd) //============================================================================ -LLMirrorParams::LLMirrorParams() -{ - mType = PARAMS_MIRROR; -} - -BOOL LLMirrorParams::pack(LLDataPacker &dp) const -{ - return TRUE; -} - -BOOL LLMirrorParams::unpack(LLDataPacker &dp) -{ - return TRUE; -} - -bool LLMirrorParams::operator==(const LLNetworkData& data) const -{ - if (data.mType != PARAMS_REFLECTION_PROBE) - { - return false; - } - return true; -} - -void LLMirrorParams::copy(const LLNetworkData& data) -{ - const LLMirrorParams *param = (LLMirrorParams*)&data; - mType = param->mType; -} - -//============================================================================ - -//============================================================================ - LLReflectionProbeParams::LLReflectionProbeParams() { mType = PARAMS_REFLECTION_PROBE; diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index db4f4ddeba..5622483861 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -109,7 +109,6 @@ public: PARAMS_EXTENDED_MESH = 0x70, PARAMS_RENDER_MATERIAL = 0x80, PARAMS_REFLECTION_PROBE = 0x90, - PARAMS_MIRROR = 0x100, }; public: @@ -173,16 +172,6 @@ public: F32 getCutoff() const { return mCutoff; } }; -class LLMirrorParams : public LLNetworkData -{ -public: - LLMirrorParams(); - /*virtual*/ BOOL pack(LLDataPacker &dp) const; - /*virtual*/ BOOL unpack(LLDataPacker &dp); - /*virtual*/ bool operator==(const LLNetworkData& data) const; - /*virtual*/ void copy(const LLNetworkData& data); -}; - extern const F32 REFLECTION_PROBE_MIN_AMBIANCE; extern const F32 REFLECTION_PROBE_MAX_AMBIANCE; extern const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f2ba4ba29e..ef51c7f0dc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10421,7 +10421,7 @@ Type S32 Value - 2048 + 1024 RenderHeroProbeDistance diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 39f5bdec5a..c9728b8d93 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -127,38 +127,22 @@ void LLHeroProbeManager::update() else { // Valid drawables only please. Unregister this one. - unregisterHeroDrawable(vo); + unregisterViewerObject(vo); } } else { - unregisterHeroDrawable(vo); + unregisterViewerObject(vo); } } if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) { - U8 mode = mNearestHero->mirrorFace(); - mode = llmin(mNearestHero->mDrawable->getNumFaces() - 1, mode); - - mCurrentFace = mNearestHero->mDrawable->getFace(mode); - LLVector3 hero_pos = mCurrentFace->getPositionAgent(); - - - // Calculate the average normal. - LLVector4a *posp = mCurrentFace->getViewerObject()->getVolume()->getVolumeFace(mCurrentFace->getTEOffset()).mPositions; - U16 *indp = mCurrentFace->getViewerObject()->getVolume()->getVolumeFace(mCurrentFace->getTEOffset()).mIndices; - // get first three vertices (first triangle) - LLVector4a v0 = posp[indp[0]]; - LLVector4a v1 = posp[indp[1]]; - LLVector4a v2 = posp[indp[2]]; - - v1.sub(v0); - v2.sub(v0); - LLVector3 face_normal = LLVector3(v1[0], v1[1], v1[2]) % LLVector3(v2[0], v2[1], v2[2]); + LLVector3 hero_pos = mNearestHero->getPositionAgent(); + LLVector3 face_normal = LLVector3(0, 0, 1); + face_normal *= mNearestHero->mDrawable->getXform()->getWorldRotation(); face_normal.normalize(); - face_normal *= mCurrentFace->getXform()->getWorldRotation(); LLVector3 offset = camera_pos - hero_pos; LLVector3 project = face_normal * (offset * face_normal); @@ -166,7 +150,7 @@ void LLHeroProbeManager::update() LLVector3 point = (reject - project) + hero_pos; mCurrentClipPlane.setVec(hero_pos, face_normal); - mMirrorPosition = mNearestHero->getPositionAgent(); + mMirrorPosition = hero_pos; mMirrorNormal = face_normal; @@ -254,6 +238,30 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen; LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.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(); + gGaussianProgram.unbind(); + } S32 mips = log2((F32)mProbeResolution) + 0.5f; @@ -527,24 +535,21 @@ void LLHeroProbeManager::doOcclusion() } } -void LLHeroProbeManager::registerHeroDrawable(LLVOVolume* drawablep) +void LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep) { + llassert(drawablep != nullptr); + if (mHeroVOList.find(drawablep) == mHeroVOList.end()) { + // Probe isn't in our list for consideration. Add it. mHeroVOList.insert(drawablep); - LL_INFOS() << "Mirror drawable registered." << LL_ENDL; } } -void LLHeroProbeManager::unregisterHeroDrawable(LLVOVolume* drawablep) +void LLHeroProbeManager::unregisterViewerObject(LLVOVolume* drawablep) { if (mHeroVOList.find(drawablep) != mHeroVOList.end()) { mHeroVOList.erase(drawablep); } } - -bool LLHeroProbeManager::isViableMirror(LLFace* face) const -{ - return face == mCurrentFace; -} diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 0b32768bb1..7485a8cd72 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -68,10 +68,8 @@ public: // perform occlusion culling on all active reflection probes void doOcclusion(); - void registerHeroDrawable(LLVOVolume* drawablep); - void unregisterHeroDrawable(LLVOVolume* drawablep); - - bool isViableMirror(LLFace* face) const; + void registerViewerObject(LLVOVolume *drawablep); + void unregisterViewerObject(LLVOVolume* drawablep); bool isMirrorPass() const { return mRenderingMirror; } @@ -140,6 +138,5 @@ private: std::set mHeroVOList; LLVOVolume* mNearestHero; - LLFace* mCurrentFace; }; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index c03f52d23f..e0d95c5386 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -114,11 +114,6 @@ BOOL LLPanelVolume::postBuild() getChild("FlexForceZ")->setValidateBeforeCommit(precommitValidate); } - // Mirror Parameters - { - childSetCommitCallback("Mirror Checkbox Ctrl", onCommitIsMirror, this); - } - // LIGHT Parameters { childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this); @@ -309,10 +304,6 @@ void LLPanelVolume::getState( ) getChildView("select_single")->setVisible(true); getChildView("select_single")->setEnabled(true); } - - BOOL is_mirror = volobjp && volobjp->isMirror(); - getChild("Mirror Checkbox Ctrl")->setValue(is_mirror); - getChildView("Mirror Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); // Light properties BOOL is_light = volobjp && volobjp->getIsLight(); @@ -774,20 +765,6 @@ void LLPanelVolume::sendIsLight() LL_INFOS() << "update light sent" << LL_ENDL; } -void LLPanelVolume::sendIsMirror() -{ - LLViewerObject* objectp = mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - - BOOL value = getChild("Mirror Checkbox Ctrl")->getValue(); - volobjp->setIsMirror(value); - LL_INFOS() << "update mirror sent" << LL_ENDL; -} - void notify_cant_select_reflection_probe() { if (!gSavedSettings.getBOOL("SelectReflectionProbes")) @@ -1495,12 +1472,6 @@ void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata ) self->sendIsLight(); } -void LLPanelVolume::onCommitIsMirror( LLUICtrl* ctrl, void* userdata ) -{ - LLPanelVolume* self = (LLPanelVolume*) userdata; - self->sendIsMirror(); -} - // static void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp) { diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index a658351624..aafefa918f 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -57,8 +57,7 @@ public: void refresh(); void sendIsLight(); - - void sendIsMirror(); + // when an object is becoming a refleciton probe, present a dialog asking for confirmation // otherwise, send the reflection probe update immediately void sendIsReflectionProbe(); @@ -72,7 +71,6 @@ public: static void onCommitIsLight( LLUICtrl* ctrl, void* userdata); static void onCommitLight( LLUICtrl* ctrl, void* userdata); - static void onCommitIsMirror( LLUICtrl* ctrl, void* userdata); static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata); static void onCommitProbe(LLUICtrl* ctrl, void* userdata); void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 691a2e14d3..d71814bd3f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -313,9 +313,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mLastUpdateCached(FALSE), mCachedMuteListUpdateTime(0), mCachedOwnerInMuteList(false), - mRiggedAttachedWarned(false), - mIsMirror(false), - mMirrorFace(3) + mRiggedAttachedWarned(false) { if (!is_global) { @@ -1149,39 +1147,6 @@ U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector return parent_id; } -void detectMirror(const std::string &str, bool &mirror, U8 &mode) -{ - - std::stringstream ss(str); - std::string word; - while (ss >> word) - { - if (word == "IsMirror") - { - mirror = true; - } - - if (mirror) - { - bool num = false; - std::string::const_iterator it = word.begin(); - while (it != word.end()) - { - num = std::isdigit(*it); - ++it; - - if (!num) - break; - } - - if (num) - { - mode = atoi(word.c_str()); - } - } - } -} - U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, @@ -1557,8 +1522,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, std::string temp_string; mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num ); - - detectMirror(temp_string, mIsMirror, mMirrorFace); LLColor4U coloru; mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num); @@ -1946,8 +1909,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, std::string temp_string; dp->unpackString(temp_string, "Text"); - detectMirror(temp_string, mIsMirror, mMirrorFace); - LLColor4U coloru; dp->unpackBinaryDataFixed(coloru.mV, 4, "Color"); coloru.mV[3] = 255 - coloru.mV[3]; @@ -6327,11 +6288,6 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para { new_block = new LLReflectionProbeParams(); break; - } - case LLNetworkData::PARAMS_MIRROR: - { - new_block = new LLMirrorParams(); - break; } default: { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index f3c00e83dc..80da7b2f73 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -257,8 +257,6 @@ public: virtual BOOL isRiggedMesh() const { return FALSE; } virtual BOOL hasLightTexture() const { return FALSE; } virtual BOOL isReflectionProbe() const { return FALSE; } - virtual BOOL isMirror() const { return FALSE; } - virtual U8 mirrorFace() const { return 0; } // This method returns true if the object is over land owned by // the agent, one of its groups, or it encroaches and @@ -880,9 +878,6 @@ protected: F32 mPhysicsCost; F32 mLinksetPhysicsCost; - bool mIsMirror; - U8 mMirrorFace; - // If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap" bool mShouldShrinkWrap = false; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 77f654be23..54e0a0113d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -249,9 +249,6 @@ LLVOVolume::~LLVOVolume() mTextureAnimp = NULL; delete mVolumeImpl; mVolumeImpl = NULL; - - if (mIsMirror) - gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); gMeshRepo.unregisterMesh(this); @@ -1000,11 +997,6 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) updateReflectionProbePtr(); } - if (isMirror()) - { - gPipeline.mHeroProbeManager.registerHeroDrawable(this); - } - updateRadius(); bool force_update = true; // avoid non-alpha mDistance update being optimized away mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); @@ -3327,48 +3319,6 @@ F32 LLVOVolume::getLightCutoff() const } } -bool LLVOVolume::setIsMirror(BOOL is_mirror) -{ - BOOL was_mirror = isMirror(); - if (is_mirror != was_mirror) - { - if (is_mirror) - { - setParameterEntryInUse(LLNetworkData::PARAMS_MIRROR, TRUE, true); - } - else - { - setParameterEntryInUse(LLNetworkData::PARAMS_MIRROR, FALSE, true); - } - } - - updateMirrorDrawable(); - - return was_mirror != is_mirror; -} - -void LLVOVolume::updateMirrorDrawable() -{ - if (isMirror()) - { - gPipeline.mHeroProbeManager.registerHeroDrawable(this); - } - else - { - gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); - } -} - -BOOL LLVOVolume::isMirror() const -{ - return mIsMirror; -} - -U8 LLVOVolume::mirrorFace() const -{ - return mMirrorFace; -} - BOOL LLVOVolume::isReflectionProbe() const { return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -3442,22 +3392,6 @@ bool LLVOVolume::setReflectionProbeIsBox(bool is_box) return false; } -bool LLVOVolume::setReflectionProbeIsPlane(bool is_plane) -{ - LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); - if (param_block) - { - if (param_block->getIsBox() != is_plane) - { - param_block->setIsBox(is_plane); - parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); - return true; - } - } - - return false; -} - bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic) { LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); @@ -4463,25 +4397,34 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u } updateReflectionProbePtr(); - - if (isMirror()) - gPipeline.mHeroProbeManager.registerHeroDrawable(this); - else - gPipeline.mHeroProbeManager.unregisterHeroDrawable(this); } void LLVOVolume::updateReflectionProbePtr() { if (isReflectionProbe()) { - if (mReflectionProbe.isNull()) + if (mReflectionProbe.isNull() && !getReflectionProbeIsMirror()) { mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this); } + else if (mReflectionProbe.isNull() && getReflectionProbeIsMirror()) + { + // Geenz: This is a special case - what we want here is a hero probe. + // What we want to do here is instantiate a hero probe from the hero probe manager. + gPipeline.mHeroProbeManager.registerViewerObject(this); + } } - else if (mReflectionProbe.notNull()) + else if (mReflectionProbe.notNull() || getReflectionProbeIsMirror()) { - mReflectionProbe = nullptr; + if (mReflectionProbe.notNull()) + { + mReflectionProbe = nullptr; + } + + if (getReflectionProbeIsMirror()) + { + gPipeline.mHeroProbeManager.unregisterViewerObject(this); + } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 89ef1d7d7a..cac09609b3 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -294,18 +294,12 @@ public: F32 getLightRadius() const; F32 getLightFalloff(const F32 fudge_factor = 1.f) const; F32 getLightCutoff() const; - - // Mirrors - bool setIsMirror(BOOL is_mirror); - void updateMirrorDrawable(); - U8 mirrorFace() const override; // Reflection Probes bool setIsReflectionProbe(BOOL is_probe); bool setReflectionProbeAmbiance(F32 ambiance); bool setReflectionProbeNearClip(F32 near_clip); bool setReflectionProbeIsBox(bool is_box); - bool setReflectionProbeIsPlane(bool is_plane); bool setReflectionProbeIsDynamic(bool is_dynamic); bool setReflectionProbeIsMirror(bool is_mirror); @@ -313,11 +307,8 @@ public: F32 getReflectionProbeAmbiance() const; F32 getReflectionProbeNearClip() const; bool getReflectionProbeIsBox() const; - bool getReflectionProbeIsPlane() const; bool getReflectionProbeIsDynamic() const; bool getReflectionProbeIsMirror() const; - - BOOL isMirror() const override; // Flexible Objects U32 getVolumeInterfaceID() const; -- cgit v1.2.3 From b0c7dc653dc730f1f95aa95fc6df876dfe7b04a0 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 6 Feb 2024 12:02:51 -0600 Subject: #677 Fix for mac build --- indra/newview/llviewershadermgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 164b36af65..91983f6603 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -240,6 +240,9 @@ static bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader return riggedShader.createShader(NULL, NULL); } +#ifdef SHOW_ASSERT +// return true if there are no redundant shaders in the given vector +// also checks for redundant variants static bool no_redundant_shaders(const std::vector& shaders) { std::set names; @@ -264,6 +267,7 @@ static bool no_redundant_shaders(const std::vector& shaders) } return true; } +#endif LLViewerShaderMgr::LLViewerShaderMgr() : -- cgit v1.2.3 From dd8f936ba8e18171770e9971675a2433d25751f1 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 7 Feb 2024 11:09:27 -0600 Subject: #665 Make viewer respect MaxTextureResolution from SimulatorFeatures --- indra/newview/llviewerregion.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index dae476d9d7..53dd3af9ef 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2407,7 +2407,19 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) mSimulatorFeatures = sim_features; setSimulatorFeaturesReceived(true); - + + // if region has MaxTextureResolution, set max_texture_dimension settings, otherwise use default + if (mSimulatorFeatures.has("MaxTextureResolution")) + { + S32 max_texture_resolution = mSimulatorFeatures["MaxTextureResolution"].asInteger(); + gSavedSettings.setS32("max_texture_dimension_X", max_texture_resolution); + gSavedSettings.setS32("max_texture_dimension_Y", max_texture_resolution); + } + else + { + gSavedSettings.setS32("max_texture_dimension_X", 1024); + gSavedSettings.setS32("max_texture_dimension_Y", 1024); + } } //this is called when the parent is not cacheable. -- cgit v1.2.3 From c583c666d2f463e9de43a571a62b74c3817e5038 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 7 Feb 2024 09:05:25 -0800 Subject: secondlife/viewer#67: (debug) Add temporary setting to force-load PBR terrain --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llvlcomposition.cpp | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4413cf9269..e1fb82be32 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10844,6 +10844,17 @@ Value 0 + RenderTerrainPBRForce + + Comment + Force-load PBR terrain if enabled + Persist + 0 + Type + Boolean + Value + 0 + RenderTerrainPBRDetail Comment diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index f645023217..7c16ee4f61 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -142,6 +142,27 @@ BOOL LLTerrainMaterials::texturesReady(BOOL boost) BOOL LLTerrainMaterials::materialsReady(BOOL boost) { +#if 1 + static bool sRenderTerrainPBREnabled = gSavedSettings.get("RenderTerrainPBREnabled"); + static LLCachedControl sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false); + if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce) + { + bool defined = true; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + if (!mDetailMaterials[i]) + { + defined = false; + break; + } + } + if (defined) + { + return TRUE; + } + } +#endif + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { -- cgit v1.2.3 From 78f7423bcd1d0980a1e99cfa92b620dc74063169 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 31 Jan 2024 17:03:28 -0800 Subject: secondlife/viewer#711: More thoroughly clamp terrain PBR detail --- indra/newview/llviewershadermgr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 7e49ea3b7c..7149dc781f 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -640,6 +640,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() const F32 triplanar_factor = gSavedSettings.getF32("RenderTerrainPBRTriplanarBlendFactor"); attribs["TERRAIN_TRIPLANAR_BLEND_FACTOR"] = llformat("%.2f", triplanar_factor); S32 detail = gSavedSettings.getS32("RenderTerrainPBRDetail"); + detail = llclamp(detail, TERRAIN_PBR_DETAIL_MIN, TERRAIN_PBR_DETAIL_MAX); attribs["TERRAIN_PBR_DETAIL"] = llformat("%d", detail); } -- cgit v1.2.3 From 139c10dbeb4270259160e8e7988c6d916033c32e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 31 Jan 2024 17:50:04 -0800 Subject: secondlife/viewer#711: Add more options to drop textures from terrain, not yet used --- indra/newview/app_settings/settings.xml | 2 +- .../shaders/class1/deferred/pbrterrainF.glsl | 80 +++++++++++++++++++- .../shaders/class1/deferred/pbrterrainUtilF.glsl | 77 +++++++++++++++++++ indra/newview/lldrawpoolterrain.cpp | 87 +++++++++++++--------- indra/newview/llviewershadermgr.h | 14 ++-- 5 files changed, 217 insertions(+), 43 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e1fb82be32..85b90a8da5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10858,7 +10858,7 @@ RenderTerrainPBRDetail Comment - Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features in accordance with the GLTF specification, which reduces the number of texture binds. Some Intel and Mac graphics drivers do not support more than 16 texture binds. Because PBR terrain exceeds this limit at the highest detail level, reducing texture binds is necessary for compatibility. + Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features, in accordance with the GLTF specification when possible, which reduces the number of texture binds. Persist 1 Type diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index db03e0885c..adb3319934 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -26,6 +26,9 @@ /*[EXTRA_CODE_HERE]*/ #define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PBR_DETAIL_OCCLUSION -1 +#define TERRAIN_PBR_DETAIL_NORMAL -2 +#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 #define TerrainCoord vec4[2] @@ -51,8 +54,14 @@ TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) struct PBRMix { vec4 col; // RGB color with alpha, linear space +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) vec3 orm; // Occlusion, roughness, metallic +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + vec2 rm; // Roughness, metallic +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) vec3 vNt; // Unpacked normal texture sample, vector +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) vec3 emissive; // RGB emissive color, linear space #endif @@ -63,13 +72,21 @@ PBRMix init_pbr_mix(); PBRMix terrain_sample_and_multiply_pbr( TerrainCoord terrain_coord , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , sampler2D tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , sampler2D tex_emissive #endif , vec4 factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , vec3 factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , vec2 factor_rm +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , vec3 factor_emissive #endif @@ -81,21 +98,23 @@ out vec4 frag_data[4]; uniform sampler2D alpha_ramp; -// *TODO: More configurable quality level which disables PBR features on machines -// with limited texture availability // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures uniform sampler2D detail_0_base_color; uniform sampler2D detail_1_base_color; uniform sampler2D detail_2_base_color; uniform sampler2D detail_3_base_color; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) uniform sampler2D detail_0_normal; uniform sampler2D detail_1_normal; uniform sampler2D detail_2_normal; uniform sampler2D detail_3_normal; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) uniform sampler2D detail_0_metallic_roughness; uniform sampler2D detail_1_metallic_roughness; uniform sampler2D detail_2_metallic_roughness; uniform sampler2D detail_3_metallic_roughness; +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) uniform sampler2D detail_0_emissive; uniform sampler2D detail_1_emissive; @@ -104,8 +123,10 @@ uniform sampler2D detail_3_emissive; #endif uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) uniform vec4 metallicFactors; uniform vec4 roughnessFactors; +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) uniform vec3[4] emissiveColors; #endif @@ -139,6 +160,7 @@ void main() TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) // RGB = Occlusion, Roughness, Metal // default values, see LLViewerTexture::sDefaultPBRORMImagep // occlusion 1.0 @@ -149,6 +171,13 @@ void main() orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + vec2[4] rm_factors; + rm_factors[0] = vec2(roughnessFactors.x, metallicFactors.x); + rm_factors[1] = vec2(roughnessFactors.y, metallicFactors.y); + rm_factors[2] = vec2(roughnessFactors.z, metallicFactors.z); + rm_factors[3] = vec2(roughnessFactors.w, metallicFactors.w); +#endif PBRMix mix = init_pbr_mix(); PBRMix mix2; @@ -158,13 +187,21 @@ void main() mix2 = terrain_sample_and_multiply_pbr( terrain_texcoord , detail_0_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , detail_0_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , detail_0_normal +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_0_emissive #endif , baseColorFactors[0] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , orm_factors[0] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , rm_factors[0] +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[0] #endif @@ -180,13 +217,21 @@ void main() mix2 = terrain_sample_and_multiply_pbr( terrain_texcoord , detail_1_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , detail_1_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , detail_1_normal +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_1_emissive #endif , baseColorFactors[1] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , orm_factors[1] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , rm_factors[1] +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[1] #endif @@ -202,13 +247,21 @@ void main() mix2 = terrain_sample_and_multiply_pbr( terrain_texcoord , detail_2_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , detail_2_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , detail_2_normal +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_2_emissive #endif , baseColorFactors[2] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , orm_factors[2] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , rm_factors[2] +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[2] #endif @@ -224,13 +277,21 @@ void main() mix2 = terrain_sample_and_multiply_pbr( terrain_texcoord , detail_3_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , detail_3_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , detail_3_normal +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_3_emissive #endif , baseColorFactors[3] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , orm_factors[3] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , rm_factors[3] +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[3] #endif @@ -248,6 +309,7 @@ void main() } float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z)); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) // from mikktspace.com vec3 vNt = mix.vNt; vec3 vN = vary_normal; @@ -257,15 +319,27 @@ void main() vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#else + vec3 tnorm = vary_normal; + tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) #define emissive mix.emissive #else #define emissive vec3(0) +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +#define orm mix.orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +#define orm vec3(1.0, mix.rm) +#else +// Matte plastic potato terrain +#define orm vec3(1.0, 1.0, 0.0) #endif frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0)); // Diffuse - frag_data[1] = max(vec4(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. + frag_data[1] = max(vec4(orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal. frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 316b751590..935c3f9301 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -47,6 +47,9 @@ */ #define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PBR_DETAIL_OCCLUSION -1 +#define TERRAIN_PBR_DETAIL_NORMAL -2 +#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 in vec3 vary_vertex_normal; @@ -75,8 +78,14 @@ vec3 srgb_to_linear(vec3 c); struct PBRMix { vec4 col; // RGB color with alpha, linear space +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) vec3 orm; // Occlusion, roughness, metallic +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + vec2 rm; // Roughness, metallic +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) vec3 vNt; // Unpacked normal texture sample, vector +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) vec3 emissive; // RGB emissive color, linear space #endif @@ -86,8 +95,14 @@ PBRMix init_pbr_mix() { PBRMix mix; mix.col = vec4(0); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) mix.orm = vec3(0); +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + mix.rm = vec2(0); +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) mix.vNt = vec3(0); +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) mix.emissive = vec3(0); #endif @@ -105,8 +120,14 @@ PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight) { PBRMix mix; mix.col = mix1.col + (mix2.col * mix2_weight); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) mix.orm = mix1.orm + (mix2.orm * mix2_weight); +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + mix.rm = mix1.rm + (mix2.rm * mix2_weight); +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) mix.vNt = mix1.vNt + (mix2.vNt * mix2_weight); +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight); #endif @@ -116,8 +137,12 @@ PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight) PBRMix sample_pbr( vec2 uv , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , sampler2D tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , sampler2D tex_emissive #endif @@ -126,8 +151,14 @@ PBRMix sample_pbr( PBRMix mix; mix.col = texture(tex_col, uv); mix.col.rgb = srgb_to_linear(mix.col.rgb); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) mix.orm = texture(tex_orm, uv).xyz; +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + mix.rm = texture(tex_orm, uv).yz; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0; +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz); #endif @@ -254,8 +285,12 @@ PBRMix terrain_sample_pbr( TerrainCoord terrain_coord , TerrainTriplanar tw , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , sampler2D tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , sampler2D tex_emissive #endif @@ -272,14 +307,20 @@ PBRMix terrain_sample_pbr( PBRMix mix_x = sample_pbr( get_uv_x() , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , tex_emissive #endif ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) // Triplanar-specific normal texture fix mix_x.vNt = _t_normal_post_x(mix_x.vNt); +#endif mix = mix_pbr(mix, mix_x, tw.weight.x); break; default: @@ -292,14 +333,20 @@ PBRMix terrain_sample_pbr( PBRMix mix_y = sample_pbr( get_uv_y() , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , tex_emissive #endif ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) // Triplanar-specific normal texture fix mix_y.vNt = _t_normal_post_y(mix_y.vNt); +#endif mix = mix_pbr(mix, mix_y, tw.weight.y); break; default: @@ -312,15 +359,21 @@ PBRMix terrain_sample_pbr( PBRMix mix_z = sample_pbr( get_uv_z() , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , tex_emissive #endif ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) // Triplanar-specific normal texture fix // *NOTE: Bottom face has not been tested mix_z.vNt = _t_normal_post_z(mix_z.vNt); +#endif mix = mix_pbr(mix, mix_z, tw.weight.z); break; default: @@ -341,7 +394,11 @@ PBRMix terrain_sample_pbr( PBRMix multiply_factors_pbr( PBRMix mix_in , vec4 factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , vec3 factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , vec2 factor_rm +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , vec3 factor_emissive #endif @@ -349,7 +406,11 @@ PBRMix multiply_factors_pbr( { PBRMix mix = mix_in; mix.col *= factor_col; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) mix.orm *= factor_orm; +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + mix.rm *= factor_rm; +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) mix.emissive *= factor_emissive; #endif @@ -359,13 +420,21 @@ PBRMix multiply_factors_pbr( PBRMix terrain_sample_and_multiply_pbr( TerrainCoord terrain_coord , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , sampler2D tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , sampler2D tex_emissive #endif , vec4 factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , vec3 factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , vec2 factor_rm +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , vec3 factor_emissive #endif @@ -377,8 +446,12 @@ PBRMix terrain_sample_and_multiply_pbr( , _t_triplanar() #endif , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) , tex_vNt +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , tex_emissive #endif @@ -386,7 +459,11 @@ PBRMix terrain_sample_and_multiply_pbr( mix = multiply_factors_pbr(mix , factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) , factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + , factor_rm +#endif #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , factor_emissive #endif diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index fc8e9fcfe5..3a943f27f6 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -54,8 +54,6 @@ const F32 DETAIL_SCALE = 1.f/16.f; int DebugDetailMap = 0; -const S32 PBR_DETAIL_EMISSIVE = 0; - S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE; @@ -399,31 +397,37 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); gGL.getTexUnit(detail_basecolor[i])->activate(); - detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); - if (detail_normal_texturep) - { - gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep); - } - else + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL) { - gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep); + detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); + if (detail_normal_texturep) + { + gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep); + } + else + { + gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep); + } + gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_normal[i])->activate(); } - gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail_normal[i])->activate(); - detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); - if (detail_metalrough_texturep) + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) { - gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep); - } - else - { - gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); + if (detail_metalrough_texturep) + { + gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep); + } + else + { + gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep); + } + gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(detail_metalrough[i])->activate(); } - gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP); - gGL.getTexUnit(detail_metalrough[i])->activate(); - if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE) { detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); if (detail_emissive_texturep) @@ -499,9 +503,12 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) minimum_alphas[i] = min_alpha; } shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors); - shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]); - shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]); - if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + { + shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]); + shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]); + } + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE) { shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors); } @@ -521,9 +528,15 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) for (U32 i = 0; i < terrain_material_count; ++i) { sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); - sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); - if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL) + { + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i); + } + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + { + sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i); + } + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE) { sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i); } @@ -532,15 +545,21 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) gGL.getTexUnit(detail_basecolor[i])->disable(); gGL.getTexUnit(detail_basecolor[i])->activate(); - gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail_normal[i])->disable(); - gGL.getTexUnit(detail_normal[i])->activate(); + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL) + { + gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_normal[i])->disable(); + gGL.getTexUnit(detail_normal[i])->activate(); + } - gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(detail_metalrough[i])->disable(); - gGL.getTexUnit(detail_metalrough[i])->activate(); + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) + { + gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(detail_metalrough[i])->disable(); + gGL.getTexUnit(detail_metalrough[i])->activate(); + } - if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE) + if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE) { gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(detail_emissive[i])->disable(); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 4273c3e70c..824c66ab49 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -281,15 +281,19 @@ extern LLGLSLShader gDeferredPBROpaqueProgram; extern LLGLSLShader gDeferredPBRAlphaProgram; extern LLGLSLShader gHUDPBRAlphaProgram; -// Encodes detail level for dropping textures, in accordance with the GLTF spec +// Encodes detail level for dropping textures, in accordance with the GLTF spec where possible // 0 is highest detail, -1 drops emissive, etc +// Dropping metallic roughness is off-spec - Reserve for potato machines as needed // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures enum TerrainPBRDetail : S32 { - TERRAIN_PBR_DETAIL_MAX = 0, - TERRAIN_PBR_DETAIL_EMISSIVE = 0, - TERRAIN_PBR_DETAIL_OCCLUSION = -1, - TERRAIN_PBR_DETAIL_MIN = -1, + TERRAIN_PBR_DETAIL_MAX = 0, + TERRAIN_PBR_DETAIL_EMISSIVE = 0, + TERRAIN_PBR_DETAIL_OCCLUSION = -1, + TERRAIN_PBR_DETAIL_NORMAL = -2, + TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS = -3, + TERRAIN_PBR_DETAIL_BASE_COLOR = -4, + TERRAIN_PBR_DETAIL_MIN = -4, }; extern LLGLSLShader gDeferredPBRTerrainProgram; #endif -- cgit v1.2.3 From c790fe58e63b851a730c1aaedde62e3ffbdf064a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 7 Feb 2024 09:34:52 -0800 Subject: secondlife/viewer#711: Reduce PBR terrain textures at low graphics settings --- .../newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 2 -- indra/newview/featuretable.txt | 7 +++++++ indra/newview/featuretable_mac.txt | 8 ++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index adb3319934..c83a6be85d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -41,7 +41,6 @@ #define MIX_Z 1 << 5 #define MIX_W 1 << 6 -// TODO: Decide if this struct needs to be declared struct TerrainMix { vec4 weight; @@ -50,7 +49,6 @@ struct TerrainMix TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); -// TODO: Decide if this struct needs to be declared struct PBRMix { vec4 col; // RGB color with alpha, linear space diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index c341097dfc..f32c0f698b 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -96,6 +96,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 +RenderTerrainPBRDetail 1 -4 RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0 RenderVolumeLODFactor 1 1.125 @@ -126,6 +127,7 @@ RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRDetail 1 -1 RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 @@ -154,6 +156,7 @@ RenderLocalLightCount 1 512 RenderTransparentWater 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.25 @@ -184,6 +187,7 @@ RenderLocalLightCount 1 1024 RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.375 @@ -214,6 +218,7 @@ RenderLocalLightCount 1 2048 RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.5 @@ -243,6 +248,7 @@ RenderMaxPartCount 1 4096 RenderLocalLightCount 1 4096 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 @@ -272,6 +278,7 @@ RenderLocalLightCount 1 8192 RenderMaxPartCount 1 8192 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index ac0ac15bd0..8770ca3c7f 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -45,6 +45,7 @@ RenderObjectBump 1 1 RenderLocalLightCount 1 4096 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 @@ -90,6 +91,7 @@ RenderLocalLightCount 1 8 RenderMaxPartCount 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 +RenderTerrainPBRDetail 1 -4 RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 0 RenderTreeLODFactor 1 0 @@ -120,6 +122,7 @@ RenderMaxPartCount 1 2048 RenderLocalLightCount 1 256 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRDetail 1 -1 RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 @@ -150,6 +153,7 @@ RenderMaxPartCount 1 4096 RenderLocalLightCount 1 512 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 @@ -180,6 +184,7 @@ RenderMaxPartCount 1 4096 RenderLocalLightCount 1 1024 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 @@ -210,6 +215,7 @@ RenderMaxPartCount 1 4096 RenderLocalLightCount 1 2048 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 @@ -240,6 +246,7 @@ RenderMaxPartCount 1 4096 RenderLocalLightCount 1 4096 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 @@ -269,6 +276,7 @@ RenderLocalLightCount 1 8192 RenderMaxPartCount 1 8192 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 -- cgit v1.2.3 From cae3e086ce7937d2851238f30f4f13fa41eadc6c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 7 Feb 2024 09:36:50 -0800 Subject: secondlife/viewer#711: Bump featuretable --- indra/newview/featuretable.txt | 2 +- indra/newview/featuretable_mac.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index f32c0f698b..965391b5cf 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 59 +version 60 // 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 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 8770ca3c7f..61cde82512 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 56 +version 57 // 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 -- cgit v1.2.3 From c74adabdb58e8123c53aa2123075b00b159fda23 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 7 Feb 2024 11:33:33 -0800 Subject: secondlife/viewer#711: Add test plan --- doc/testplans/pbr_terrain_feature_gating.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 doc/testplans/pbr_terrain_feature_gating.md diff --git a/doc/testplans/pbr_terrain_feature_gating.md b/doc/testplans/pbr_terrain_feature_gating.md new file mode 100644 index 0000000000..13108c1534 --- /dev/null +++ b/doc/testplans/pbr_terrain_feature_gating.md @@ -0,0 +1,22 @@ +# PBR Terrain Feature Gating + +PBR terrain should have lower detail on lower graphics settings. PBR terrain will also not show emissive textures on some machines (like Macs) which do not support more than 16 textures. + +## Triplanar Mapping + +Triplanar mapping improves the texture repeats on the sides of terrain slopes. + +Availability of Triplanar mapping: + +- Medium-High and below: No triplanar mapping +- High and above: Triplanar mapping + +## PBR Textures + +At the highest graphics support level, PBR terrain supports all PBR textures. + +Availability of PBR textures varies by machine and graphics setting: + +- Low: Base color only (looks similar to texture terrain) +- Medium-Low, and machines that do not support greater than 16 textures such as Macs: All PBR textures enabled except emissive textures. +- Medium: All PBR textures enabled -- cgit v1.2.3 From 1940188e75806ffdd60807017210092b0dbe0dcf Mon Sep 17 00:00:00 2001 From: Henri Beauchamp Date: Wed, 7 Feb 2024 21:40:17 +0100 Subject: Confusion between light diffuse and light color in HDR auto-adjust mode While the SUNLIGHT_COLOR uniform is initialized with getSunlightColor() when not auto-adjusting for HDR, it is overwritten with getSunDiffuse()*auto_adjust_factor when auto-adjusting, causing very bad lighting discrepancies in the latter mode (especially when not at midday or midnight). Let's use getSunlightColor() everywhere, shall we ?... --- indra/newview/llsettingsvo.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 7009fb98ab..17405ca864 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -718,11 +718,11 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); // TODO -- make these getters return vec3s - LLVector3 sunDiffuse = LLVector3(psky->getSunlightColor().mV); - LLVector3 moonDiffuse = LLVector3(psky->getMoonlightColor().mV); + LLVector3 sun_light_color = LLVector3(psky->getSunlightColor().mV); + LLVector3 moon_light_color = LLVector3(psky->getMoonlightColor().mV); - shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); - shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); + shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color); + shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moon_light_color); shader->uniform3fv(LLShaderMgr::CLOUD_COLOR, LLVector3(psky->getCloudColor().mV)); @@ -766,9 +766,9 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale); LLColor3 blue_horizon = getBlueHorizon() * auto_adjust_blue_horizon_scale; LLColor3 blue_density = getBlueDensity() * auto_adjust_blue_density_scale; - LLColor3 sun_diffuse = getSunDiffuse() * auto_adjust_sun_color_scale; + sun_light_color = sun_light_color * auto_adjust_sun_color_scale; - shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_diffuse.mV); + shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_light_color.mV); shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV); shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV); -- cgit v1.2.3 From 192e77344f44d4a2d6bc765403b27f611b106240 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 8 Feb 2024 10:40:56 -0800 Subject: Make the UI conditional. --- indra/newview/llpanelvolume.cpp | 5 +++++ indra/newview/skins/default/xui/en/floater_tools.xml | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index e0d95c5386..6b5b691587 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -392,6 +392,11 @@ void LLPanelVolume::getState( ) bool probe_enabled = is_probe && editable && single_volume; + getChildView("Probe Update Type")->setVisible(LLPipeline::RenderMirrors); + getChildView("Probe Update Label")->setVisible(LLPipeline::RenderMirrors); + getChildView("Probe Dynamic")->setVisible(!LLPipeline::RenderMirrors); + + getChildView("Probe Dynamic")->setEnabled(probe_enabled); getChildView("Probe Update Type")->setEnabled(probe_enabled); getChildView("Probe Volume Type")->setEnabled(probe_enabled); getChildView("Probe Ambiance")->setEnabled(probe_enabled); diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 4f4216c85a..72c78fec3d 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2559,7 +2559,19 @@ even though the user gets a free copy. name="Box" value="Box"/> + + + - Date: Thu, 8 Feb 2024 11:39:35 -0800 Subject: #671 Setup the viewer to respect the MirrorsEnabled simulator feature. --- indra/llrender/llshadermgr.cpp | 8 -------- indra/newview/llheroprobemanager.cpp | 12 ++++++++++++ indra/newview/llheroprobemanager.h | 3 ++- indra/newview/llpanelvolume.cpp | 8 +++++--- indra/newview/llviewershadermgr.cpp | 2 +- indra/newview/pipeline.cpp | 6 +++++- 6 files changed, 25 insertions(+), 14 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index d510e061a2..5384133220 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -231,14 +231,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - - if (features->hasHeroProbes) - { - if (!shader->attachFragmentObject("deferred/heroProbesUtil.glsl")) - { - return FALSE; - } - } if (features->hasShadows) { diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index c9728b8d93..a105fd2fa8 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -72,6 +72,18 @@ void LLHeroProbeManager::update() return; } + // This should be moved elsewhere. + LLSD features; + gAgent.getRegion()->getSimulatorFeatures(features); + if (mHasMirrors != features.has("MirrorsEnabled")) + { + mHasMirrors = features.has("MirrorsEnabled"); + LLViewerShaderMgr::instance()->setShaders(); + } + + if (!mHasMirrors) + return; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 7485a8cd72..5ec1101b45 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -72,8 +72,8 @@ public: void unregisterViewerObject(LLVOVolume* drawablep); bool isMirrorPass() const { return mRenderingMirror; } + bool hasMirrors() const { return mHasMirrors; } - LLPlane currentMirrorClip() const { return mCurrentClipPlane; } LLVector3 mMirrorPosition; LLVector3 mMirrorNormal; @@ -135,6 +135,7 @@ private: bool mReset = false; bool mRenderingMirror = false; + bool mHasMirrors = false; std::set mHeroVOList; LLVOVolume* mNearestHero; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 6b5b691587..f64106948f 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -392,9 +392,11 @@ void LLPanelVolume::getState( ) bool probe_enabled = is_probe && editable && single_volume; - getChildView("Probe Update Type")->setVisible(LLPipeline::RenderMirrors); - getChildView("Probe Update Label")->setVisible(LLPipeline::RenderMirrors); - getChildView("Probe Dynamic")->setVisible(!LLPipeline::RenderMirrors); + bool mirrors_enabled = LLPipeline::RenderMirrors && gPipeline.mHeroProbeManager.hasMirrors(); + + getChildView("Probe Update Type")->setVisible(mirrors_enabled); + getChildView("Probe Update Label")->setVisible(mirrors_enabled); + getChildView("Probe Dynamic")->setVisible(!mirrors_enabled); getChildView("Probe Dynamic")->setEnabled(probe_enabled); getChildView("Probe Update Type")->setEnabled(probe_enabled); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e3c2c429da..e6cf37bc3c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -390,7 +390,7 @@ void LLViewerShaderMgr::setShaders() mShaderList.clear(); - LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors; + LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors && gPipeline.mHeroProbeManager.hasMirrors(); if (!gGLManager.mHasRequirements) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9fb9ade943..32c7563aa0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1062,7 +1062,11 @@ void LLPipeline::refreshCachedSettings() RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier"); RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples"); RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization"); - RenderMirrors = gSavedSettings.getBOOL("RenderMirrors"); + if (gSavedSettings.getBOOL("RenderMirrors") != (BOOL)RenderMirrors) + { + RenderMirrors = gSavedSettings.getBOOL("RenderMirrors"); + LLViewerShaderMgr::instance()->setShaders(); + } sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled"); RenderSpotLight = nullptr; -- cgit v1.2.3 From c721152c444ee7a13e4217f86dfcce34b7488ee5 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 8 Feb 2024 14:54:01 -0600 Subject: Fix for crash in LLHeroProbeManager --- indra/newview/llheroprobemanager.cpp | 8 ++++++-- indra/newview/llheroprobemanager.h | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index a105fd2fa8..c66054f618 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -126,7 +126,7 @@ void LLHeroProbeManager::update() for (auto vo : mHeroVOList) { - if (vo) + if (vo && !vo->isDead()) { if (vo->mDrawable.notNull()) { @@ -148,7 +148,7 @@ void LLHeroProbeManager::update() } } - if (mNearestHero != nullptr && mNearestHero->mDrawable.notNull()) + if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull()) { LLVector3 hero_pos = mNearestHero->getPositionAgent(); LLVector3 face_normal = LLVector3(0, 0, 1); @@ -168,6 +168,10 @@ void LLHeroProbeManager::update() probe_pos.load3(point.mV); } + else + { + mNearestHero = nullptr; + } mHeroProbeStrength = 1; } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 5ec1101b45..9151189a92 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -137,7 +137,7 @@ private: bool mRenderingMirror = false; bool mHasMirrors = false; - std::set mHeroVOList; - LLVOVolume* mNearestHero; + std::set> mHeroVOList; + LLPointer mNearestHero; }; -- cgit v1.2.3 From a7310ae7417b2f6e7013762a1cfe3211a163a8d7 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 8 Feb 2024 15:07:54 -0600 Subject: #671 Nudge RenderMirrors and clear shader cache as needed based on SimulatorFeatures --- indra/newview/llheroprobemanager.cpp | 12 ------------ indra/newview/llheroprobemanager.h | 2 -- indra/newview/llpanelvolume.cpp | 2 +- indra/newview/llviewerregion.cpp | 8 ++++++++ indra/newview/llviewershadermgr.cpp | 2 +- indra/newview/pipeline.cpp | 1 + 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index c66054f618..2a81919856 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -72,18 +72,6 @@ void LLHeroProbeManager::update() return; } - // This should be moved elsewhere. - LLSD features; - gAgent.getRegion()->getSimulatorFeatures(features); - if (mHasMirrors != features.has("MirrorsEnabled")) - { - mHasMirrors = features.has("MirrorsEnabled"); - LLViewerShaderMgr::instance()->setShaders(); - } - - if (!mHasMirrors) - return; - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 9151189a92..552c5dcaab 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -72,7 +72,6 @@ public: void unregisterViewerObject(LLVOVolume* drawablep); bool isMirrorPass() const { return mRenderingMirror; } - bool hasMirrors() const { return mHasMirrors; } LLVector3 mMirrorPosition; LLVector3 mMirrorNormal; @@ -135,7 +134,6 @@ private: bool mReset = false; bool mRenderingMirror = false; - bool mHasMirrors = false; std::set> mHeroVOList; LLPointer mNearestHero; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index f64106948f..8d8263448d 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -392,7 +392,7 @@ void LLPanelVolume::getState( ) bool probe_enabled = is_probe && editable && single_volume; - bool mirrors_enabled = LLPipeline::RenderMirrors && gPipeline.mHeroProbeManager.hasMirrors(); + bool mirrors_enabled = LLPipeline::RenderMirrors; getChildView("Probe Update Type")->setVisible(mirrors_enabled); getChildView("Probe Update Label")->setVisible(mirrors_enabled); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ce57585d82..cea083e07d 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2451,6 +2451,14 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) gSavedSettings.setS32("max_texture_dimension_X", 1024); gSavedSettings.setS32("max_texture_dimension_Y", 1024); } + + bool mirrors_enabled = false; + if (mSimulatorFeatures.has("MirrorsEnabled")) + { + mirrors_enabled = mSimulatorFeatures["MirrorsEnabled"].asBoolean(); + } + + gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled); } //this is called when the parent is not cacheable. diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b175172b9b..4eb934114d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -390,7 +390,7 @@ void LLViewerShaderMgr::setShaders() mShaderList.clear(); - LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors && gPipeline.mHeroProbeManager.hasMirrors(); + LLShaderMgr::sMirrorsEnabled = LLPipeline::RenderMirrors; if (!gGLManager.mHasRequirements) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 32c7563aa0..9d90002eb9 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1065,6 +1065,7 @@ void LLPipeline::refreshCachedSettings() if (gSavedSettings.getBOOL("RenderMirrors") != (BOOL)RenderMirrors) { RenderMirrors = gSavedSettings.getBOOL("RenderMirrors"); + LLViewerShaderMgr::instance()->clearShaderCache(); LLViewerShaderMgr::instance()->setShaders(); } sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled"); -- cgit v1.2.3 From c3d4f571aa5522e3028842c6d7caa977819a7393 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 8 Feb 2024 13:22:10 -0800 Subject: Update softenLightF.glsl --- .../shaders/class3/deferred/softenLightF.glsl | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index a8cfc3537e..cc6e16c64f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -198,12 +198,6 @@ void main() vec3 v = -normalize(pos.xyz); color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); - - /*#ifdef HERO_PROBES - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - - color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - gloss) * 11).xyz * specularColor; - #endif*/ } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { @@ -226,18 +220,6 @@ void main() vec3 legacyenv = vec3(0); sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity, false, amblit_linear); - - #ifdef HERO_PROBES - float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; - if (clipDist > 0.0 && clipDist < 0.1 && spec.a > 0.8) - { - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) - { - radiance = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-spec.a)*11).xyz; - } - } - #endif adjustIrradiance(irradiance, ambocc); @@ -274,10 +256,6 @@ void main() // add radiance map applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); - /*#ifdef HERO_PROBES - color = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0 - spec.a) * 11).xyz * spec.rgb; - #endif*/ - } color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a); -- cgit v1.2.3 From 9c6e351e05d7e0580700f040af8161da52de7a08 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 8 Feb 2024 13:24:16 -0800 Subject: secondlife/viewer-issues#67: Improve PBR terrain loading robustness --- indra/newview/lldrawpoolterrain.cpp | 78 +++++++++++++--------- indra/newview/llvlcomposition.cpp | 128 +++++++++++++++++++++--------------- indra/newview/llvlcomposition.h | 16 +++-- 3 files changed, 133 insertions(+), 89 deletions(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 3a943f27f6..8844f1d7e4 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -125,27 +125,29 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures() tex->setBoostLevel(level); tex->addTextureStats(stats); - LLPointer& mat = compp->mDetailMaterials[i]; - llassert(mat.notNull()); - if (mat->mBaseColorTexture) + LLPointer& fetched_material = compp->mDetailMaterials[i]; + if (fetched_material) { - mat->mBaseColorTexture->setBoostLevel(level); - mat->mBaseColorTexture->addTextureStats(stats); - } - if (mat->mNormalTexture) - { - mat->mNormalTexture->setBoostLevel(level); - mat->mNormalTexture->addTextureStats(stats); - } - if (mat->mMetallicRoughnessTexture) - { - mat->mMetallicRoughnessTexture->setBoostLevel(level); - mat->mMetallicRoughnessTexture->addTextureStats(stats); - } - if (mat->mEmissiveTexture) - { - mat->mEmissiveTexture->setBoostLevel(level); - mat->mEmissiveTexture->addTextureStats(stats); + if (fetched_material->mBaseColorTexture) + { + fetched_material->mBaseColorTexture->setBoostLevel(level); + fetched_material->mBaseColorTexture->addTextureStats(stats); + } + if (fetched_material->mNormalTexture) + { + fetched_material->mNormalTexture->setBoostLevel(level); + fetched_material->mNormalTexture->addTextureStats(stats); + } + if (fetched_material->mMetallicRoughnessTexture) + { + fetched_material->mMetallicRoughnessTexture->setBoostLevel(level); + fetched_material->mMetallicRoughnessTexture->addTextureStats(stats); + } + if (fetched_material->mEmissiveTexture) + { + fetched_material->mEmissiveTexture->setBoostLevel(level); + fetched_material->mEmissiveTexture->addTextureStats(stats); + } } } } @@ -234,7 +236,7 @@ void LLDrawPoolTerrain::drawLoop() void LLDrawPoolTerrain::renderFullShader() { - const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE); + const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(true, false); // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); @@ -362,15 +364,24 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); - LLPointer (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; + LLPointer (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; + + constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; + constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT; + llassert(shader_material_count == terrain_material_count); if (local_materials) { // Override region terrain with the global local override terrain - materials = &gLocalTerrainMaterials.mDetailMaterials; + fetched_materials = &gLocalTerrainMaterials.mDetailMaterials; } + const LLGLTFMaterial* materials[terrain_material_count]; + for (U32 i = 0; i < terrain_material_count; ++i) + { + materials[i] = (*fetched_materials)[i].get(); + if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; } + } - constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; S32 detail_basecolor[terrain_material_count]; S32 detail_normal[terrain_material_count]; S32 detail_metalrough[terrain_material_count]; @@ -378,12 +389,19 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) for (U32 i = 0; i < terrain_material_count; ++i) { - const LLFetchedGLTFMaterial* material = (*materials)[i].get(); + LLViewerTexture* detail_basecolor_texturep = nullptr; + LLViewerTexture* detail_normal_texturep = nullptr; + LLViewerTexture* detail_metalrough_texturep = nullptr; + LLViewerTexture* detail_emissive_texturep = nullptr; - LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture; - LLViewerTexture *detail_normal_texturep = material->mNormalTexture; - LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture; - LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture; + const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get(); + if (fetched_material) + { + detail_basecolor_texturep = fetched_material->mBaseColorTexture; + detail_normal_texturep = fetched_material->mNormalTexture; + detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture; + detail_emissive_texturep = fetched_material->mEmissiveTexture; + } detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i); if (detail_basecolor_texturep) @@ -483,7 +501,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) F32 minimum_alphas[terrain_material_count]; for (U32 i = 0; i < terrain_material_count; ++i) { - const LLFetchedGLTFMaterial* material = (*materials)[i].get(); + const LLGLTFMaterial* material = materials[i]; base_color_factors[i] = material->mBaseColor; metallic_factors[i] = material->mMetallicFactor; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 7c16ee4f61..c092eb82f3 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -75,12 +75,12 @@ LLTerrainMaterials::~LLTerrainMaterials() BOOL LLTerrainMaterials::generateMaterials() { - if (texturesReady(TRUE)) + if (texturesReady(true, true)) { return TRUE; } - if (materialsReady(TRUE)) + if (materialsReady(true, true)) { return TRUE; } @@ -123,25 +123,41 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { LL_PROFILE_ZONE_SCOPED; - const BOOL use_textures = texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false); return use_textures ? Type::TEXTURE : Type::PBR; } -BOOL LLTerrainMaterials::texturesReady(BOOL boost) +bool LLTerrainMaterials::texturesReady(bool boost, bool strict) { - BOOL ready = TRUE; - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (!textureReady(mDetailTextures[i], boost)) + bool ready[ASSET_COUNT]; + // *NOTE: Calls to textureReady may boost textures. Do not early-return. + for (S32 i = 0; i < ASSET_COUNT; i++) + { + ready[i] = textureReady(mDetailTextures[i], boost); + } + + bool one_ready = false; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const bool current_ready = ready[i]; + one_ready = one_ready || current_ready; + if (!current_ready && strict) { - ready = FALSE; + return false; } - } - return ready; + } + return one_ready; } -BOOL LLTerrainMaterials::materialsReady(BOOL boost) +bool LLTerrainMaterials::materialsReady(bool boost, bool strict) { + bool ready[ASSET_COUNT]; + // *NOTE: Calls to materialReady may boost materials/textures. Do not early-return. + for (S32 i = 0; i < ASSET_COUNT; i++) + { + ready[i] = materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost, strict); + } + #if 1 static bool sRenderTerrainPBREnabled = gSavedSettings.get("RenderTerrainPBREnabled"); static LLCachedControl sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false); @@ -158,28 +174,31 @@ BOOL LLTerrainMaterials::materialsReady(BOOL boost) } if (defined) { - return TRUE; + return true; } } #endif - BOOL ready = TRUE; - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) + bool one_ready = false; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const bool current_ready = ready[i]; + one_ready = one_ready || current_ready; + if (!current_ready && strict) { - ready = FALSE; + return false; } } - return ready; + return one_ready; } // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) // static -BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BOOL boost) +bool LLTerrainMaterials::textureReady(LLPointer& tex, bool boost) { - llassert(tex.notNull()); + llassert(tex); + if (!tex) { return false; } if (tex->getDiscardLevel() < 0) { @@ -188,7 +207,7 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail tex->addTextureStats(BASE_SIZE*BASE_SIZE); } - return FALSE; + return false; } if ((tex->getDiscardLevel() != 0 && (tex->getWidth() < BASE_SIZE || @@ -209,23 +228,23 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO tex->setMinDiscardLevel(ddiscard); tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority } - return FALSE; + return false; } if (tex->getComponents() == 0) { - return FALSE; + return false; } - return TRUE; + return true; } // Boost the loading priority of every known texture in the material -// Return true when ready to use (i.e. material and all textures within are sufficiently loaded) +// Return true when ready to use // static -BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) +bool LLTerrainMaterials::materialReady(LLPointer &mat, bool &textures_set, bool boost, bool strict) { if (!mat || !mat->isLoaded()) { - return FALSE; + return false; } // Material is loaded, but textures may not be @@ -234,33 +253,39 @@ BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bo // *NOTE: These can sometimes be set to to nullptr due to // updateTEMaterialTextures. For the sake of robustness, we emulate // that fetching behavior by setting textures of null IDs to nullptr. - mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); - mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); + mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); - mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); - textures_set = true; + mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); + textures_set = true; - return FALSE; + return false; } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost)) - { - return FALSE; - } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost)) - { - return FALSE; - } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost)) + // *NOTE: Calls to textureReady may boost textures. Do not early-return. + bool ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT]; + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].isNull() || textureReady(mat->mBaseColorTexture, boost); + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].isNull() || textureReady(mat->mNormalTexture, boost); + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].isNull() || + textureReady(mat->mMetallicRoughnessTexture, boost); + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].isNull() || textureReady(mat->mEmissiveTexture, boost); + + if (strict) { - return FALSE; - } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost)) - { - return FALSE; + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (!ready[i]) + { + return false; + } + } } - return TRUE; + return true; } @@ -427,16 +452,13 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; - // *TODO: Remove this as it is reduandant computation (first and foremost - // because getMaterialType() does something similar, but also... shouldn't - // the textures/materials already be loaded by now?) if (use_textures) { - if (!texturesReady()) { return FALSE; } + if (!texturesReady(true, true)) { return FALSE; } } else { - if (!materialsReady()) { return FALSE; } + if (!materialsReady(true, true)) { return FALSE; } } for (S32 i = 0; i < ASSET_COUNT; i++) diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index d59c0f95bb..73bfca6ed4 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -61,12 +61,16 @@ public: LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); - BOOL texturesReady(BOOL boost = FALSE); - BOOL materialsReady(BOOL boost = FALSE); + bool texturesReady(bool boost, bool strict); + // strict = true -> all materials must be sufficiently loaded + // strict = false -> at least one material must be loaded + bool materialsReady(bool boost, bool strict); protected: - static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); - static BOOL materialReady(LLPointer& mat, bool& textures_set, BOOL boost = FALSE); + static bool textureReady(LLPointer& tex, bool boost); + // strict = true -> all materials must be sufficiently loaded + // strict = false -> at least one material must be loaded + static bool materialReady(LLPointer& mat, bool& textures_set, bool boost, bool strict); LLPointer mDetailTextures[ASSET_COUNT]; LLPointer mDetailMaterials[ASSET_COUNT]; bool mMaterialTexturesSet[ASSET_COUNT]; @@ -116,8 +120,8 @@ public: BOOL getParamsReady() const { return mParamsReady; } protected: - static BOOL textureReady(LLPointer& tex, BOOL boost = FALSE); - static BOOL materialReady(LLPointer& mat, bool& textures_set, BOOL boost = FALSE); + static bool textureReady(LLPointer& tex, bool boost = false); + static bool materialReady(LLPointer& mat, bool& textures_set, bool boost = false); BOOL mParamsReady = FALSE; LLSurface *mSurfacep; -- cgit v1.2.3 From 0ca75120bec28fbc0ed0fc3392bca0a7a5e85a37 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 8 Feb 2024 14:39:02 -0800 Subject: secondlife/viewer-issues#67: Add test plan --- doc/testplans/terrain_loading.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 doc/testplans/terrain_loading.md diff --git a/doc/testplans/terrain_loading.md b/doc/testplans/terrain_loading.md new file mode 100644 index 0000000000..b84daf6f73 --- /dev/null +++ b/doc/testplans/terrain_loading.md @@ -0,0 +1,4 @@ +- Texture terrain should load +- PBR terrain should load if enabled +- Related subsystem: A change to the PBR terrain loading system may affect the texture terrain loading system and vice-versa +- Related subsystem: Minimaps should load if terrain loads (may take longer) -- cgit v1.2.3 From ae46dc068e47475c9a874c22047312152cd8fdab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 8 Feb 2024 14:39:31 -0800 Subject: secondlife/viewer-issues#67: Fix Windows release build warning --- indra/newview/lldrawpoolterrain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 8844f1d7e4..2d198c5b4b 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -366,9 +366,11 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials) LLVLComposition *compp = regionp->getComposition(); LLPointer (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials; - constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT; +#ifdef SHOW_ASSERT + constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR; llassert(shader_material_count == terrain_material_count); +#endif if (local_materials) { -- cgit v1.2.3 From d6048bfcb2442ca7ec278864b9827d74873efa3a Mon Sep 17 00:00:00 2001 From: cosmic-linden <111533034+cosmic-linden@users.noreply.github.com> Date: Fri, 9 Feb 2024 07:16:01 -0800 Subject: Put PBR material swatch behind feature flag (#775) * secondlife/viewer#771: Put PBR material swatch behind feature flag * secondlife/viewer#771: Make viewer respect PBRMaterialSwatchEnabled from SimulatorFeatures --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llgltfmaterialpreviewmgr.cpp | 8 +++++++- indra/newview/lltexturectrl.cpp | 21 +++++++++++---------- indra/newview/llviewerregion.cpp | 10 ++++++++++ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6ec9a9acc5..1a614062d9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -13829,6 +13829,17 @@ Value 2 + UIPreviewMaterial + + Comment + Whether or not PBR material swatch is enabled + Persist + 1 + Type + Boolean + Value + 0 + UIResizeBarHeight Comment diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 53d9d7d0ba..901db87eed 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -543,7 +543,6 @@ void LLGLTFPreviewTexture::postRender(BOOL success) LLViewerDynamicTexture::postRender(success); } -// static LLPointer LLGLTFMaterialPreviewMgr::getPreview(LLPointer &material) { if (!material) @@ -551,6 +550,13 @@ LLPointer LLGLTFMaterialPreviewMgr::getPreview(LLPointer sUIPreviewMaterial(gSavedSettings, "UIPreviewMaterial", false); + if (!sUIPreviewMaterial) + { + fetch_texture_for_ui(material->mBaseColorTexture, material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + return material->mBaseColorTexture; + } + if (!is_material_loaded_enough_for_ui(*material)) { return nullptr; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 0439b0b115..5415f9bd9a 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -680,6 +680,10 @@ void LLFloaterTexturePicker::draw() mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial); } } + if (mGLTFPreview) + { + mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + } } else { @@ -735,7 +739,7 @@ void LLFloaterTexturePicker::draw() // If the floater is focused, don't apply its alpha to the texture (STORM-677). const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - LLViewerTexture* preview = nullptr; + LLViewerTexture* preview; if (mGLTFMaterial) { preview = mGLTFPreview.get(); @@ -743,15 +747,11 @@ void LLFloaterTexturePicker::draw() else { preview = mTexturep.get(); - if (mTexturep) - { - // Pump the priority - mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); - } } if( preview ) { + preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); if( preview->getComponents() == 4 ) { gl_rect_2d_checkerboard( interior, alpha ); @@ -2219,6 +2219,10 @@ void LLTextureCtrl::draw() mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial); } } + if (mGLTFPreview) + { + mGLTFPreview->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + } preview = mGLTFPreview; } @@ -2257,10 +2261,7 @@ void LLTextureCtrl::draw() } gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha); - if (mTexturep) - { - mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); - } + preview->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) ); } else if (!mFallbackImage.isNull()) { diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index cea083e07d..5b51267cbe 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2459,6 +2459,16 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) } gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled); + + if (mSimulatorFeatures.has("PBRMaterialSwatchEnabled")) + { + bool enabled = mSimulatorFeatures["PBRMaterialSwatchEnabled"]; + gSavedSettings.setBOOL("UIPreviewMaterial", enabled); + } + else + { + gSavedSettings.setBOOL("UIPreviewMaterial", false); + } } //this is called when the parent is not cacheable. -- cgit v1.2.3 From 4e5344ba76dd89373259e7286807ceba48bb5f82 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 9 Feb 2024 13:10:26 -0600 Subject: https://github.com/secondlife/jira-archive-internal/issues/70847 Fix for more inaccurate than usual alpha sorting (#781) --- indra/newview/app_settings/settings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1a614062d9..e7d947b85f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8699,7 +8699,7 @@ OctreeAlphaDistanceFactor Comment - Multiplier on alpha object distance for determining octree node size + Multiplier on alpha object distance for determining octree node size. First two parameters are currently unused. Third parameter is distance at which to perform detailed alpha sorting. Persist 1 Type @@ -8708,7 +8708,7 @@ 0.1 0.0 - 0.0 + 64.0 -- cgit v1.2.3 From 2cbf4a15df940d92d38003d302e61fda14e1dc51 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 9 Feb 2024 12:34:02 -0800 Subject: secondlife/viewer#773: Fix RenderTerrainPBREnabled requiring restart and respect simulator feature PBRTerrainEnabled --- indra/newview/llfloaterregioninfo.cpp | 32 ++++++++++++++++++++++++++++++-- indra/newview/llfloaterregioninfo.h | 3 +++ indra/newview/llviewermenu.cpp | 5 +---- indra/newview/llviewerregion.cpp | 18 ++++++++++++++---- indra/newview/llvlcomposition.cpp | 2 +- 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 2c743d596e..8b335d57d7 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1441,6 +1441,11 @@ BOOL LLPanelRegionTerrainInfo::postBuild() mAskedTextureHeights = false; mConfirmedTextureHeights = false; + if (!mRegionChangedSlot.connected()) + { + mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLPanelRegionTerrainInfo::onRegionChanged,this)); + } + refresh(); return LLPanelRegionInfo::postBuild(); @@ -1449,8 +1454,7 @@ BOOL LLPanelRegionTerrainInfo::postBuild() // virtual void LLPanelRegionTerrainInfo::refresh() { - // For simplicity, require restart - static BOOL feature_pbr_terrain_enabled = gSavedSettings.getBOOL("RenderTerrainPBREnabled"); + static LLCachedControl feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); LLTextBox* texture_text = getChild("detail_texture_text"); if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); } @@ -1512,6 +1516,27 @@ void LLPanelRegionTerrainInfo::onSelectMaterialType() } } +void LLPanelRegionTerrainInfo::onRegionChanged() +{ + LLViewerRegion *region = gAgent.getRegion(); + if (!region) { return; } + + if (region->simulatorFeaturesReceived()) + { + onSimulatorFeaturesReceived(region->getRegionID(), region); + } + else + { + // See "RenderTerrainPBREnabled" in LLViewerRegion::setSimulatorFeatures + region->setSimulatorFeaturesReceivedCallback(boost::bind(&LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived,this,_1, _2)); + } +} + +void LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp) +{ + refresh(); +} + // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { @@ -1568,6 +1593,9 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LL_DEBUGS() << "no region set" << LL_ENDL; getChild("region_text")->setValue(LLSD("")); } + + // Update visibility of terrain swatches, etc + refresh(); getChildView("download_raw_btn")->setEnabled(owner_or_god); getChildView("upload_raw_btn")->setEnabled(owner_or_god); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 91fd54fcf9..91e1f5b058 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -248,6 +248,8 @@ public: BOOL postBuild() override; + void onRegionChanged(); + void onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp); bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region @@ -271,6 +273,7 @@ protected: private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; + boost::signals2::connection mRegionChangedSlot; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index da7b1131a3..981984db6a 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -9506,10 +9506,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile"); view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache"); - if (gSavedSettings.get("RenderTerrainPBREnabled")) - { - view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); - } + view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); #ifdef TOGGLE_HACKED_GODLIKE_VIEWER view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 5b51267cbe..d887a579e4 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1610,8 +1610,8 @@ void LLViewerRegion::idleUpdate(F32 max_update_time) mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame(); - static bool pbr_terrain_enabled = gSavedSettings.get("RenderTerrainPBREnabled"); - static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE); + static LLCachedControl pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); + static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false); bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR); bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals; @@ -1925,8 +1925,8 @@ void LLViewerRegion::forceUpdate() { constexpr F32 max_update_time = 0.f; - static bool pbr_terrain_enabled = gSavedSettings.get("RenderTerrainPBREnabled"); - static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE); + static LLCachedControl pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); + static LLCachedControl pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false); bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR); bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals; @@ -2460,6 +2460,16 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled); + if (mSimulatorFeatures.has("PBRTerrainEnabled")) + { + bool enabled = mSimulatorFeatures["PBRTerrainEnabled"]; + gSavedSettings.setBOOL("RenderTerrainPBREnabled", enabled); + } + else + { + gSavedSettings.setBOOL("RenderTerrainPBREnabled", false); + } + if (mSimulatorFeatures.has("PBRMaterialSwatchEnabled")) { bool enabled = mSimulatorFeatures["PBRMaterialSwatchEnabled"]; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c092eb82f3..09b21e4e0a 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -159,7 +159,7 @@ bool LLTerrainMaterials::materialsReady(bool boost, bool strict) } #if 1 - static bool sRenderTerrainPBREnabled = gSavedSettings.get("RenderTerrainPBREnabled"); + static LLCachedControl sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false); static LLCachedControl sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false); if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce) { -- cgit v1.2.3 From 7a9cdf2b52ca95c8e269e2bb4ed01379b76434d6 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 15 Feb 2024 09:38:29 -0800 Subject: #682 Do conservative updates on probes. --- indra/newview/llheroprobemanager.cpp | 22 +++++++++++++++++++++- indra/newview/llheroprobemanager.h | 1 + indra/newview/pipeline.cpp | 9 ++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 2a81919856..1f050a5166 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -155,6 +155,25 @@ void LLHeroProbeManager::update() probe_pos.load3(point.mV); + + // Collect the list of faces that need updating based upon the camera's rotation. + LLVector3 cam_direction = LLVector3(0, 0, -1) * LLViewerCamera::instance().getQuaternion(); + + static LLVector3 cubeFaces[6] = { + LLVector3(1, 0, 0), + LLVector3(-1, 0, 0), + LLVector3(0, 1, 0), + LLVector3(0, -1, 0), + LLVector3(0, 0, 1), + LLVector3(0, 0, -1) + }; + + for (int i = 0; i < 6; i++) + { + bool shouldUpdate = (cam_direction * cubeFaces[i]) > 0; + + mFaceUpdateList[i] = shouldUpdate; + } } else { @@ -185,7 +204,8 @@ void LLHeroProbeManager::update() { for (U32 i = 0; i < 6; ++i) { - updateProbeFace(mProbes[j], i, near_clip); + if (mFaceUpdateList[i]) + updateProbeFace(mProbes[j], i, near_clip); } } mRenderingMirror = false; diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 552c5dcaab..d2a319c500 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -134,6 +134,7 @@ private: bool mReset = false; bool mRenderingMirror = false; + std::map mFaceUpdateList; std::set> mHeroVOList; LLPointer mNearestHero; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9d90002eb9..180204b0ce 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -786,9 +786,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled allocateScreenBuffer(res, res, samples); - res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it. - mRT = &mHeroProbeRT; - allocateScreenBuffer(res, res, samples); + if (RenderMirrors) + { + res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it. + mRT = &mHeroProbeRT; + allocateScreenBuffer(res, res, samples); + } mRT = &mMainRT; gCubeSnapshot = FALSE; -- cgit v1.2.3 From 3e4e414011b032e64b5fd477f2c561fc2b4553f7 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 16 Feb 2024 09:49:45 -0800 Subject: secondlife/viewer-issues#72: Material preview shouldRender should return false if no render needed --- indra/newview/lldynamictexture.cpp | 2 ++ indra/newview/llgltfmaterialpreviewmgr.cpp | 20 +++++++++++++++++++- indra/newview/llgltfmaterialpreviewmgr.h | 8 ++------ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index a66c3876fc..f8a6195bdd 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -118,6 +118,8 @@ BOOL LLViewerDynamicTexture::render() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::preRender(BOOL clear_depth) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + //use the bottom left corner mOrigin.set(0, 0); diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 901db87eed..36bd552c31 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -58,6 +58,15 @@ LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels() } } +bool LLGLTFPreviewTexture::MaterialLoadLevels::isFullyLoaded() +{ + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (levels[i] != FULLY_LOADED) { return false; } + } + return true; +} + S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i) { llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT); @@ -187,17 +196,26 @@ LLPointer LLGLTFPreviewTexture::create(LLPointer create(LLPointer material); - BOOL needsRender() override { return mNeedsRender; } + BOOL needsRender() override; void preRender(BOOL clear_depth = TRUE) override; BOOL render() override; void postRender(BOOL success) override; @@ -50,15 +50,12 @@ public: S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT]; MaterialLoadLevels(); - + bool isFullyLoaded(); S32& operator[](size_t i); - const S32& operator[](size_t i) const; - // Less is better // Returns false if lhs is not strictly less or equal for all levels bool operator<(const MaterialLoadLevels& other) const; - // Less is better // Returns false if lhs is not strictly greater or equal for all levels bool operator>(const MaterialLoadLevels& other) const; @@ -66,7 +63,6 @@ public: private: LLPointer mGLTFMaterial; - bool mNeedsRender = true; bool mShouldRender = true; MaterialLoadLevels mBestLoad; }; -- cgit v1.2.3 From ab9ec50df9dda3ac52752d44b7d5529ed26db7bf Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 16 Feb 2024 12:52:50 -0800 Subject: secondlife/viewer-issues#72: Don't dirty depth in LLViewerDynamicTexture::updateAllInstances --- indra/newview/lldynamictexture.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index f8a6195bdd..24818241ab 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -221,7 +221,6 @@ BOOL LLViewerDynamicTexture::updateAllInstances() llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH); glClear(GL_DEPTH_BUFFER_BIT); - gDepthDirty = TRUE; gGL.color4f(1,1,1,1); dynamicTexture->setBoundTarget(&bake_target); -- cgit v1.2.3 From bbc7d63a79b9744acaff51315e5e9a9d7299bd12 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 20 Feb 2024 16:10:05 -0800 Subject: secondlife/viewer-issues#72: Clean up material preview when hidden or floater closed --- indra/newview/lltexturectrl.cpp | 15 +++++++++++++++ indra/newview/lltexturectrl.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 5415f9bd9a..d9001bc16a 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -538,6 +538,8 @@ void LLFloaterTexturePicker::onClose(bool app_quitting) } stopUsingPipette(); sLastPickerMode = mModeSelector->getValue().asInteger(); + // *NOTE: Vertex buffer for sphere preview is still cached + mGLTFPreview = nullptr; } // virtual @@ -1760,6 +1762,19 @@ void LLTextureCtrl::setFilterPermissionMasks(PermissionMask mask) setDnDFilterPermMask(mask); } +void LLTextureCtrl::onVisibilityChange(BOOL new_visibility) +{ + if (!new_visibility) + { + // *NOTE: Vertex buffer for sphere preview is still cached + mGLTFPreview = nullptr; + } + else + { + llassert(!mGLTFPreview); + } +} + void LLTextureCtrl::setVisible( BOOL visible ) { if( !visible ) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 05ea185b1b..a19c8b6e3d 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -160,6 +160,8 @@ public: virtual void setVisible( BOOL visible ); virtual void setEnabled( BOOL enabled ); + void onVisibilityChange(BOOL new_visibility) override; + void setValid(BOOL valid); // LLUICtrl interface -- cgit v1.2.3 From 8cea28511448eb750561252f202f96ae815e37f8 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 20 Feb 2024 18:21:45 -0800 Subject: #682 Separate out the radiance gen. --- indra/newview/llheroprobemanager.cpp | 45 ++++++++++++------------------------ indra/newview/llheroprobemanager.h | 1 + 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 1f050a5166..929364be44 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -157,7 +157,7 @@ void LLHeroProbeManager::update() probe_pos.load3(point.mV); // Collect the list of faces that need updating based upon the camera's rotation. - LLVector3 cam_direction = LLVector3(0, 0, -1) * LLViewerCamera::instance().getQuaternion(); + LLVector3 cam_direction = LLVector3(-1, -1, -1) * LLViewerCamera::instance().getQuaternion(); static LLVector3 cubeFaces[6] = { LLVector3(1, 0, 0), @@ -207,6 +207,7 @@ void LLHeroProbeManager::update() if (mFaceUpdateList[i]) updateProbeFace(mProbes[j], i, near_clip); } + generateRadiance(mProbes[j]); } mRenderingMirror = false; @@ -262,30 +263,6 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen; LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.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(); - gGaussianProgram.unbind(); - } S32 mips = log2((F32)mProbeResolution) + 0.5f; @@ -338,14 +315,22 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE); gReflectionMipProgram.unbind(); } +} - if (face == 5) +void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) +{ + S32 sourceIdx = mReflectionProbeCount; + + // Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes. + sourceIdx += 1; { mMipChain[0].bindTarget(); static LLStaticHashedString sSourceIdx("sourceIdx"); { - //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) + + + // generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) gHeroRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); @@ -354,10 +339,10 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gHeroRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength); - + U32 res = mMipChain[0].getWidth(); - for (int i = 0; i < mMipChain.size(); ++i) + for (int i = 0; i < mMipChain.size() / 4; ++i) { LL_PROFILE_GPU_ZONE("probe radiance gen"); static LLStaticHashedString sMipLevel("mipLevel"); @@ -371,7 +356,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n gHeroRadianceGenProgram.uniform1f(sStrength, 1); for (int cf = 0; cf < 6; ++cf) - { // for each cube face + { // for each cube face LLCoordFrame frame; frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index d2a319c500..7cc7e3b144 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -104,6 +104,7 @@ private: // update the specified face of the specified probe void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip); + void generateRadiance(LLReflectionMap *probe); // list of active reflection maps std::vector > mProbes; -- cgit v1.2.3 From e68735ad3a6da635a447eb9ed1981e5c360fd2f2 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 21 Feb 2024 11:51:46 -0800 Subject: #682 Add an update rate parameter to help throttle mirror updates. So far 4 seems like a good balance for performance and quality. 2 is great for quality, with 6 or 8 being for higher performance. Also bring back the gaussian filter - may end up adding the FXAA filter though instead. --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llheroprobemanager.cpp | 24 ++++++++++++++++++++++++ indra/newview/llviewerdisplay.cpp | 2 +- indra/newview/pipeline.cpp | 4 ++++ indra/newview/pipeline.h | 1 + 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6ec9a9acc5..7e4058cc6e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10390,6 +10390,17 @@ Value 8 + RenderHeroProbeUpdateRate + + Comment + How many frames to wait for until it's time to render the probe. E.g., every other frame (1), every two frames (2), every three frames (3) etc. + Persist + 1 + Type + S32 + Value + 1 + RenderReflectionProbeVolumes Comment diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 929364be44..0d9efb860a 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -264,6 +264,30 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n LLRenderTarget *screen_rt = &gPipeline.mHeroProbeRT.screen; LLRenderTarget *depth_rt = &gPipeline.mHeroProbeRT.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(); + gGaussianProgram.unbind(); + } + S32 mips = log2((F32)mProbeResolution) + 0.5f; gReflectionMipProgram.bind(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index e6d9aed1a3..2a77146101 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -658,7 +658,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { // Render mirrors and associated hero probes before we render the rest of the scene. // This ensures the scene state in the hero probes are exactly the same as the rest of the scene before we render it. - if (gPipeline.RenderMirrors && !gSnapshot) + if (gPipeline.RenderMirrors && !gSnapshot && (gPipeline.RenderHeroProbeUpdateRate == 0 || (gFrameCount % gPipeline.RenderHeroProbeUpdateRate) == 0)) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes"); gPipeline.mHeroProbeManager.update(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 180204b0ce..269b40a6c5 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -199,6 +199,7 @@ F32 LLPipeline::RenderScreenSpaceReflectionAdaptiveStepMultiplier; S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples; S32 LLPipeline::RenderBufferVisualization; bool LLPipeline::RenderMirrors; +S32 LLPipeline::RenderHeroProbeUpdateRate; LLTrace::EventStatHandle LLPipeline::sStatBatchSize("renderbatchsize"); const U32 LLPipeline::MAX_BAKE_WIDTH = 512; @@ -559,6 +560,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionGlossySamples"); connectRefreshCachedSettingsSafe("RenderBufferVisualization"); connectRefreshCachedSettingsSafe("RenderMirrors"); + connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate"); gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } @@ -1071,6 +1073,8 @@ void LLPipeline::refreshCachedSettings() LLViewerShaderMgr::instance()->clearShaderCache(); LLViewerShaderMgr::instance()->setShaders(); } + RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate"); + sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled"); RenderSpotLight = nullptr; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e8c6da1473..2937b1fa1a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -1056,6 +1056,7 @@ public: static S32 RenderScreenSpaceReflectionGlossySamples; static S32 RenderBufferVisualization; static bool RenderMirrors; + static S32 RenderHeroProbeUpdateRate; }; void render_bbox(const LLVector3 &min, const LLVector3 &max); -- cgit v1.2.3 From 589910f445efa9690b543a37b9e2e14792a0e133 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 21 Feb 2024 12:53:10 -0800 Subject: secondlife/viewer-issues#72: Fix material preview affecting exposure on main screen --- indra/llrender/llrendertarget.cpp | 26 ++++++++ indra/llrender/llrendertarget.h | 3 + .../shaders/class1/deferred/exposureF.glsl | 6 +- indra/newview/llgltfmaterialpreviewmgr.cpp | 8 ++- indra/newview/llviewershadermgr.cpp | 17 ++++++ indra/newview/llviewershadermgr.h | 1 + indra/newview/pipeline.cpp | 71 ++++++++++++++-------- indra/newview/pipeline.h | 2 +- 8 files changed, 104 insertions(+), 30 deletions(-) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 88c48e5166..3dccb9c8fd 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -567,4 +567,30 @@ bool LLRenderTarget::isBoundInStack() const return cur == this; } +void LLRenderTarget::swapFBORefs(LLRenderTarget& other) +{ + // Must be initialized + llassert(mFBO); + llassert(other.mFBO); + // Must be unbound + // *NOTE: mPreviousRT can be non-null even if this target is unbound - presumably for debugging purposes? + llassert(sCurFBO != mFBO); + llassert(sCurFBO != other.mFBO); + llassert(!isBoundInStack()); + llassert(!other.isBoundInStack()); + + // Must be same type + llassert(sUseFBO == other.sUseFBO); + llassert(mResX == other.mResX); + llassert(mResY == other.mResY); + llassert(mInternalFormat == other.mInternalFormat); + llassert(mTex.size() == other.mTex.size()); + llassert(mDepth == other.mDepth); + llassert(mUseDepth == other.mUseDepth); + llassert(mGenerateMipMaps == other.mGenerateMipMaps); + llassert(mMipLevels == other.mMipLevels); + llassert(mUsage == other.mUsage); + + std::swap(mFBO, other.mFBO); +} diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 9fcea35e3d..da401572d1 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -169,6 +169,9 @@ public: static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } + // *HACK + void swapFBORefs(LLRenderTarget& other); + protected: U32 mResX; U32 mResY; diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl index 9ac4ceb37e..eff7221ae7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl @@ -28,7 +28,9 @@ out vec4 frag_color; uniform sampler2D emissiveRect; +#ifdef USE_LAST_EXPOSURE uniform sampler2D exposureMap; +#endif uniform float dt; uniform vec2 noiseVec; @@ -51,10 +53,12 @@ void main() L /= max_L; L = pow(L, 2.0); float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L); - + +#ifdef USE_LAST_EXPOSURE float prev = texture(exposureMap, vec2(0.5,0.5)).r; s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04)); +#endif frag_color = max(vec4(s, s, s, dt), vec4(0.0)); } diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 36bd552c31..1c39f1ae7d 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -517,9 +517,12 @@ BOOL LLGLTFPreviewTexture::render() screen.flush(); } + // *HACK: Hide mExposureMap from generateExposure + gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); + gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap); gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap); - gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap); + gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false); gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap); LLVertexBuffer::unbind(); gPipeline.generateGlow(&gPipeline.mPostMap); @@ -527,6 +530,9 @@ BOOL LLGLTFPreviewTexture::render() gPipeline.renderDoF(&screen, &gPipeline.mPostMap); gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); + // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) + gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); + // Final render gDeferredPostNoDoFProgram.bind(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4eb934114d..354cc79036 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -196,6 +196,7 @@ LLGLSLShader gDeferredPostGammaCorrectProgram; LLGLSLShader gNoPostGammaCorrectProgram; LLGLSLShader gLegacyPostGammaCorrectProgram; LLGLSLShader gExposureProgram; +LLGLSLShader gExposureProgramNoFade; LLGLSLShader gLuminanceProgram; LLGLSLShader gFXAAProgram; LLGLSLShader gDeferredPostNoDoFProgram; @@ -980,6 +981,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredCoFProgram.unload(); gDeferredDoFCombineProgram.unload(); gExposureProgram.unload(); + gExposureProgramNoFade.unload(); gLuminanceProgram.unload(); gDeferredPostGammaCorrectProgram.unload(); gNoPostGammaCorrectProgram.unload(); @@ -2127,6 +2129,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gExposureProgram.mFeatures.isDeferred = true; gExposureProgram.mShaderFiles.clear(); gExposureProgram.clearPermutations(); + gExposureProgram.addPermutation("USE_LAST_EXPOSURE", "1"); gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER)); gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; @@ -2134,6 +2137,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } + if (success) + { + gExposureProgramNoFade.mName = "Exposure (no fade)"; + gExposureProgramNoFade.mFeatures.hasSrgb = true; + gExposureProgramNoFade.mFeatures.isDeferred = true; + gExposureProgramNoFade.mShaderFiles.clear(); + gExposureProgramNoFade.clearPermutations(); + gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gExposureProgramNoFade.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER)); + gExposureProgramNoFade.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gExposureProgramNoFade.createShader(NULL, NULL); + llassert(success); + } + if (success) { gLuminanceProgram.mName = "Luminance"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 57fc66ce0d..2502be6bb1 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -249,6 +249,7 @@ extern LLGLSLShader gDeferredPostGammaCorrectProgram; extern LLGLSLShader gNoPostGammaCorrectProgram; extern LLGLSLShader gLegacyPostGammaCorrectProgram; extern LLGLSLShader gExposureProgram; +extern LLGLSLShader gExposureProgramNoFade; extern LLGLSLShader gLuminanceProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAvatarAlphaShadowProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9d90002eb9..6ceaca731b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6772,11 +6772,12 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) } } -void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) { +void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history) { // exposure sample { LL_PROFILE_GPU_ZONE("exposure sample"); + if (use_history) { // copy last frame's exposure into mLastExposure mLastExposure.bindTarget(); @@ -6793,51 +6794,67 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) { LLGLDepthTest depth(GL_FALSE, GL_FALSE); - gExposureProgram.bind(); + LLGLSLShader* shader; + if (use_history) + { + shader = &gExposureProgram; + } + else + { + shader = &gExposureProgramNoFade; + } + + shader->bind(); - S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); if (channel > -1) { - mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR); + src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR); } - channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP); - if (channel > -1) + if (use_history) { - mLastExposure.bindTexture(0, channel); + channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP); + if (channel > -1) + { + mLastExposure.bindTexture(0, channel); + } } static LLStaticHashedString dt("dt"); static LLStaticHashedString noiseVec("noiseVec"); static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); static LLCachedControl dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f); - static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); + static LLCachedControl should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); + LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); - F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); - F32 exp_min = 1.f; - F32 exp_max = 1.f; - - if (probe_ambiance > 0.f) - { - F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma())*2.f; + F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); + F32 exp_min = 1.f; + F32 exp_max = 1.f; - if (hdr_scale > 1.f) - { - exp_min = 1.f / hdr_scale; - exp_max = hdr_scale; - } - } - gExposureProgram.uniform1f(dt, gFrameIntervalSeconds); - gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); - gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max); + if (probe_ambiance > 0.f) + { + F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma()) * 2.f; + + if (hdr_scale > 1.f) + { + exp_min = 1.f / hdr_scale; + exp_max = hdr_scale; + } + } + shader->uniform1f(dt, gFrameIntervalSeconds); + shader->uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); + shader->uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage()); - gExposureProgram.unbind(); + if (use_history) + { + gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage()); + } + shader->unbind(); dst->flush(); } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e8c6da1473..259dc3f9d0 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -154,7 +154,7 @@ public: void renderFinalize(); void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst); - void generateExposure(LLRenderTarget* src, LLRenderTarget* dst); + void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true); void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst); void generateGlow(LLRenderTarget* src); void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst); -- cgit v1.2.3 From 97f049db3b396c7a12d723f3305084570866a475 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 21 Feb 2024 13:00:53 -0800 Subject: secondlife/viewer-issues#72: Fix clang warnings (virtual override) --- indra/newview/lltexturectrl.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index a19c8b6e3d..f193b0c083 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -148,28 +148,28 @@ public: // LLView interface - virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, - BOOL drop, EDragAndDropType cargo_type, void *cargo_data, - EAcceptance *accept, - std::string& tooltip_msg); - virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual BOOL handleUnicodeCharHere(llwchar uni_char); + BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, EDragAndDropType cargo_type, void *cargo_data, + EAcceptance *accept, + std::string& tooltip_msg) override; + BOOL handleHover(S32 x, S32 y, MASK mask) override; + BOOL handleUnicodeCharHere(llwchar uni_char) override; - virtual void draw(); - virtual void setVisible( BOOL visible ); - virtual void setEnabled( BOOL enabled ); + void draw() override; + void setVisible( BOOL visible ) override; + void setEnabled( BOOL enabled ) override; - void onVisibilityChange(BOOL new_visibility) override; + void onVisibilityChange(BOOL new_visibility) override; - void setValid(BOOL valid); + void setValid(BOOL valid); - // LLUICtrl interface - virtual void clear(); + // LLUICtrl interface + void clear() override; - // Takes a UUID, wraps get/setImageAssetID - virtual void setValue(const LLSD& value); - virtual LLSD getValue() const; + // Takes a UUID, wraps get/setImageAssetID + void setValue(const LLSD& value) override; + LLSD getValue() const override; // LLTextureCtrl interface void showPicker(BOOL take_focus); -- cgit v1.2.3 From ce55ff2e77db649f71107230609fc20fc86a0af3 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 21 Feb 2024 15:02:03 -0800 Subject: secondlife/viewer-issues#72: Add test plan --- doc/testplans/material_preview.md | 81 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 doc/testplans/material_preview.md diff --git a/doc/testplans/material_preview.md b/doc/testplans/material_preview.md new file mode 100644 index 0000000000..d653fc45ca --- /dev/null +++ b/doc/testplans/material_preview.md @@ -0,0 +1,81 @@ +# Material Preview + +## Overview + +Material preview is a UI feature which displays a lit spherical preview of a PBR material. It can be found in the following UIs: + +- The material picker swatch + - In the build floater, in the Texture tab, when applying a PBR material + - (If the feature is enabled) In the Region/Estate floater, in the Terrain tab, when applying PBR materials to terrain +- In the floater to select a material from inventory, which can be opened by clicking the material picker swatch + +## Known Issues + +These are known issues that the current implementation of this feature does not address: + +- Material swatch preview is a preview of the base material ID only, and ignores other properties on the prim face like material overrides +- Alpha mask previews as alpha blend +- Double-sided previews as single-sided +- Material swatch preview inherits some of its lighting from the current environment, and reflections from the default reflection probe + +## General Regression Testing + +- Check that the material preview swatch looks OK with different materials selected +- Check that the material preview swatch runs reasonably well on different systems, especially when the select material from inventory floater is also open + - In particular: AMD, MacOS, minimum spec machines +- Watch out for regressions in rendering caused by opening a floater with a material preview swatch + +## Bug Fixes + +### Disappearing Objects Fix Test + +This test is recommended for verifying that secondlife/viewer-issues#72 is fixed. + +#### Symptoms + +The following types of objects could randomly disappear until relog in the main view when the bug occured: + +- Objects +- Water level in current region +- Adjacent region/void water + +Note: Disappearing objects in reflections have a different root cause and are not covered by the fix. + +#### Bug Reproduction Steps + +Verify the disappearing objects bug does not reproduce, given the following steps: + +- Runtime prerequisites: Material preview swatch is enabled ("UIPreviewMaterial") by visiting a test region with the feature enabled, or by manually enabling "UIPreviewMaterial" in the advanced settings for the current session +- Region prerequisites: Unknown, but a region with lots of stuff in it (like Rumpus Room 2048 on Aditi) seems to increase repro rate +- Right click an object and select, "Edit item" +- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory +- Ensure "Apply now" is checked in the inventory selection floater +- Alternate between different materials from the inventory selection floater +- Look around the world and check for permanently disappeared objects. + +### Dynamic Exposure Influence Fix Test + +This test is recommended for verifying that secondlife/viewer-issues#72 is fixed. + +#### Symptoms + +Dynamic exposure in the world could be influenced by the material preview being displayed. If a material preview was being generated in a given frame, then, depending on the current environment, the user would observe an unpleasant flashing effect in the environment: + +- The world view could suddenly get darker and then fade back to normal exposure levels +- The world view could suddenly get brighter and then fade back to normal exposure levels + +#### Bug Reproduction Steps + +Verify the dynamic exposure influence bug does not reproduce. Test using a few environment presets such as Default Midday, Sunset, and Midnight. + +- Right click an object and select, "Edit item" +- Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory +- Alternate between different materials from the inventory selection floater + +#### Regression Testing + +Dynamic exposure in the world should continue to work correctly. In particular: + +- Exposure should fade gradually from high exposure to low exposure and back as needed +- Exposure should decrease in brighter environments +- Exposure should increase in darker environments -- cgit v1.2.3 From fc7abe8cb9ef737cb1ad4431e30c42f08d6e8899 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 21 Feb 2024 16:06:11 -0800 Subject: secondlife/viewer-issues#72: More correct interpretation of swapFBORefs --- indra/llrender/llrendertarget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 3dccb9c8fd..9cd7527d3e 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -593,4 +593,5 @@ void LLRenderTarget::swapFBORefs(LLRenderTarget& other) llassert(mUsage == other.mUsage); std::swap(mFBO, other.mFBO); + std::swap(mTex, other.mTex); } -- cgit v1.2.3 From a1aa0b7c5e1840e4eff6aa07a3f41906072831f2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 21 Feb 2024 17:44:01 -0800 Subject: secondlife/viewer-issues#72: Test plan feedback and additional improvements --- doc/testplans/material_preview.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/testplans/material_preview.md b/doc/testplans/material_preview.md index d653fc45ca..6d2768f72a 100644 --- a/doc/testplans/material_preview.md +++ b/doc/testplans/material_preview.md @@ -13,10 +13,10 @@ Material preview is a UI feature which displays a lit spherical preview of a PBR These are known issues that the current implementation of this feature does not address: -- Material swatch preview is a preview of the base material ID only, and ignores other properties on the prim face like material overrides -- Alpha mask previews as alpha blend -- Double-sided previews as single-sided -- Material swatch preview inherits some of its lighting from the current environment, and reflections from the default reflection probe +- The material preview in the build floater is a preview of the base material ID only, and ignores other properties on the prim face like material overrides (https://github.com/secondlife/viewer/issues/865) +- Alpha mask previews as alpha blend (https://github.com/secondlife/viewer/issues/866) +- Double-sided previews as single-sided (https://github.com/secondlife/viewer/issues/867) +- Material preview inherits some of its lighting from the current environment, and reflections from the default reflection probe (https://github.com/secondlife/viewer/issues/868) ## General Regression Testing @@ -29,11 +29,11 @@ These are known issues that the current implementation of this feature does not ### Disappearing Objects Fix Test -This test is recommended for verifying that secondlife/viewer-issues#72 is fixed. +This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed. #### Symptoms -The following types of objects could randomly disappear until relog in the main view when the bug occured: +When the bug occurs, one or more of following types of objects could randomly disappear in the world, permanently until relog: - Objects - Water level in current region @@ -45,8 +45,10 @@ Note: Disappearing objects in reflections have a different root cause and are no Verify the disappearing objects bug does not reproduce, given the following steps: -- Runtime prerequisites: Material preview swatch is enabled ("UIPreviewMaterial") by visiting a test region with the feature enabled, or by manually enabling "UIPreviewMaterial" in the advanced settings for the current session -- Region prerequisites: Unknown, but a region with lots of stuff in it (like Rumpus Room 2048 on Aditi) seems to increase repro rate +- Runtime prerequisites: Material preview swatch may not be available in your viewer or region if this feature is still behind a feature flag. It is safe to enable this feature manually by setting, "UIPreviewMaterial" to True in the advanced settings. The setting will persist for the current session. +- Region prerequisites: Unknown, but a region with lots of objects in it seems to increase repro rate. The following locations have been known to easily reproduce the bug, as of 2024-02-16: + - http://maps.secondlife.com/secondlife/LindenWorld%20B/161/75/47 + - [secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24](secondlife://Aditi/secondlife/Rumpus%20Room%202048/128/128/24) - Right click an object and select, "Edit item" - Go to texture tab, select PBR Metallic Roughness from dropdown, and click the button to select material from inventory - Ensure "Apply now" is checked in the inventory selection floater @@ -55,7 +57,7 @@ Verify the disappearing objects bug does not reproduce, given the following step ### Dynamic Exposure Influence Fix Test -This test is recommended for verifying that secondlife/viewer-issues#72 is fixed. +This test is recommended for verifying that https://github.com/secondlife/viewer-issues/issues/72 is fixed. #### Symptoms -- cgit v1.2.3 From f1e9d13b9918e44dda635a7085c4ffdd924172bd Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Fri, 23 Feb 2024 14:11:31 -0800 Subject: Fixes for some shader compilation failures on mac. * conditional compilation should use #ifdef * layout keywords need to be lowercase --- .../app_settings/shaders/class1/interface/normaldebugG.glsl | 12 ++++++------ .../app_settings/shaders/class1/interface/normaldebugV.glsl | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl index ea04ce1cae..51d05cd507 100644 --- a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl @@ -32,15 +32,15 @@ out vec4 vertex_color; in vec4 normal_g[]; -#if HAS_ATTRIBUTE_TANGENT == 1 +#ifdef HAS_ATTRIBUTE_TANGENT in vec4 tangent_g[]; #endif -layout(TRIANGLES) in; -#if HAS_ATTRIBUTE_TANGENT == 1 -layout(LINE_STRIP, max_vertices = 12) out; +layout(triangles) in; +#ifdef HAS_ATTRIBUTE_TANGENT +layout(line_strip, max_vertices = 12) out; #else -layout(LINE_STRIP, max_vertices = 6) out; +layout(line_strip, max_vertices = 6) out; #endif void triangle_normal_debug(int i) @@ -55,7 +55,7 @@ void triangle_normal_debug(int i) EmitVertex(); EndPrimitive(); -#if HAS_ATTRIBUTE_TANGENT == 1 +#ifdef HAS_ATTRIBUTE_TANGENT // Tangent vec4 tangent_color = vec4(0.0, 1.0, 1.0, 1.0); gl_Position = gl_in[i].gl_Position; diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl index d1596b9d2a..b198bc2485 100644 --- a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl @@ -26,7 +26,7 @@ in vec3 position; in vec3 normal; out vec4 normal_g; -#if HAS_ATTRIBUTE_TANGENT == 1 +#ifdef HAS_ATTRIBUTE_TANGENT in vec4 tangent; out vec4 tangent_g; #endif @@ -67,7 +67,7 @@ void main() gl_Position = projection_matrix * world_pos; normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat); -#if HAS_ATTRIBUTE_TANGENT == 1 +#ifdef HAS_ATTRIBUTE_TANGENT tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat); #endif } -- cgit v1.2.3 From 5557254c93582166b2ab2ac4ec27b6f60e4b232e Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Fri, 23 Feb 2024 14:21:52 -0800 Subject: Fix for deferred avatar eyes shader failing to link on Intel GPU. --- indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl index 83b0ba096c..43863dd37a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl @@ -26,6 +26,7 @@ uniform mat3 normal_matrix; uniform mat4 texture_matrix0; uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix; in vec3 position; in vec3 normal; @@ -35,10 +36,12 @@ in vec2 texcoord0; out vec3 vary_normal; out vec4 vertex_color; out vec2 vary_texcoord0; +out vec3 vary_position; void main() { //transform vertex + vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz; gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -- cgit v1.2.3 From 320258729757e9ef14e9509c22eca1ce6a0da856 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sun, 25 Feb 2024 22:52:23 -0800 Subject: #682 Add a low priority path for conservative probe face updates. This will update the "low priority" faces at half of the the probe update rate. Useful for less planar reflection geometry. --- indra/newview/llheroprobemanager.cpp | 29 ++++++++++++++++++++++------- indra/newview/llheroprobemanager.h | 11 +++++++---- indra/newview/llviewerobject.h | 1 + indra/newview/llvovolume.cpp | 7 ++++++- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 0d9efb860a..f350b28bf5 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -114,7 +114,7 @@ void LLHeroProbeManager::update() for (auto vo : mHeroVOList) { - if (vo && !vo->isDead()) + if (vo && (!vo->isDead() || vo != nullptr)) { if (vo->mDrawable.notNull()) { @@ -135,7 +135,7 @@ void LLHeroProbeManager::update() unregisterViewerObject(vo); } } - + if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull()) { LLVector3 hero_pos = mNearestHero->getPositionAgent(); @@ -205,7 +205,16 @@ void LLHeroProbeManager::update() for (U32 i = 0; i < 6; ++i) { if (mFaceUpdateList[i]) + { updateProbeFace(mProbes[j], i, near_clip); + } + else + { + if (mLowPriorityFaceThrottle > 0 && mCurrentProbeUpdateFrame % mLowPriorityFaceThrottle == 0) { + updateProbeFace(mProbes[j], i, near_clip); + mCurrentProbeUpdateFrame = 0; + } + } } generateRadiance(mProbes[j]); } @@ -213,6 +222,8 @@ void LLHeroProbeManager::update() gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; } + + mCurrentProbeUpdateFrame++; } // Do the reflection map update render passes. @@ -568,21 +579,25 @@ void LLHeroProbeManager::doOcclusion() } } -void LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep) +bool LLHeroProbeManager::registerViewerObject(LLVOVolume* drawablep) { llassert(drawablep != nullptr); - if (mHeroVOList.find(drawablep) == mHeroVOList.end()) + if (std::find(mHeroVOList.begin(), mHeroVOList.end(), drawablep) == mHeroVOList.end()) { // Probe isn't in our list for consideration. Add it. - mHeroVOList.insert(drawablep); + mHeroVOList.push_back(drawablep); + return true; } + + return false; } void LLHeroProbeManager::unregisterViewerObject(LLVOVolume* drawablep) { - if (mHeroVOList.find(drawablep) != mHeroVOList.end()) + std::vector::iterator found_itr = std::find(mHeroVOList.begin(), mHeroVOList.end(), drawablep); + if (found_itr != mHeroVOList.end()) { - mHeroVOList.erase(drawablep); + mHeroVOList.erase(found_itr); } } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 7cc7e3b144..b1907ef185 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -68,7 +68,7 @@ public: // perform occlusion culling on all active reflection probes void doOcclusion(); - void registerViewerObject(LLVOVolume *drawablep); + bool registerViewerObject(LLVOVolume *drawablep); void unregisterViewerObject(LLVOVolume* drawablep); bool isMirrorPass() const { return mRenderingMirror; } @@ -107,7 +107,7 @@ private: void generateRadiance(LLReflectionMap *probe); // list of active reflection maps - std::vector > mProbes; + std::vector> mProbes; // handle to UBO U32 mUBO = 0; @@ -137,7 +137,10 @@ private: bool mRenderingMirror = false; std::map mFaceUpdateList; - std::set> mHeroVOList; - LLPointer mNearestHero; + U32 mCurrentProbeUpdateFrame = 0; + U32 mLowPriorityFaceThrottle = 2; + + std::vector mHeroVOList; + LLVOVolume* mNearestHero; }; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 80da7b2f73..0c4d958aed 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -944,6 +944,7 @@ public: // reflection probe state bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager LLPointer mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed + bool mIsHeroProbe = false; // This is a special case for mirrors and other high resolution probes. // the amount of GPU time (in ms) it took to render this object according to LLPipeline::profileAvatar // -1.f if no profile data available diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 27d2e6af71..149abaf573 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -296,6 +296,11 @@ void LLVOVolume::markDead() { mLightTexture->removeVolume(LLRender::LIGHT_TEX, this); } + + if (mIsHeroProbe) + { + gPipeline.mHeroProbeManager.unregisterViewerObject(this); + } } LLViewerObject::markDead(); @@ -4411,7 +4416,7 @@ void LLVOVolume::updateReflectionProbePtr() { // Geenz: This is a special case - what we want here is a hero probe. // What we want to do here is instantiate a hero probe from the hero probe manager. - gPipeline.mHeroProbeManager.registerViewerObject(this); + mIsHeroProbe = gPipeline.mHeroProbeManager.registerViewerObject(this); } } else if (mReflectionProbe.notNull() || getReflectionProbeIsMirror()) -- cgit v1.2.3 From 2ba5449b8b888b64ed87ef801426f7eab6e0be95 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Sun, 25 Feb 2024 23:38:11 -0800 Subject: #889 Start removing mDrawable references. These may be null. --- indra/newview/llheroprobemanager.cpp | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index f350b28bf5..feb81394cf 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -116,18 +116,11 @@ void LLHeroProbeManager::update() { if (vo && (!vo->isDead() || vo != nullptr)) { - if (vo->mDrawable.notNull()) + float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec(); + if (distance < last_distance) { - if (vo->mDrawable->mDistanceWRTCamera < last_distance) - { - mNearestHero = vo; - last_distance = vo->mDrawable->mDistanceWRTCamera; - } - } - else - { - // Valid drawables only please. Unregister this one. - unregisterViewerObject(vo); + mNearestHero = vo; + last_distance = distance; } } else @@ -136,12 +129,12 @@ void LLHeroProbeManager::update() } } - if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull()) + if (mNearestHero != nullptr && !mNearestHero->isDead()) { LLVector3 hero_pos = mNearestHero->getPositionAgent(); LLVector3 face_normal = LLVector3(0, 0, 1); - face_normal *= mNearestHero->mDrawable->getXform()->getWorldRotation(); + face_normal *= mNearestHero->getWorldRotation(); face_normal.normalize(); LLVector3 offset = camera_pos - hero_pos; @@ -210,7 +203,8 @@ void LLHeroProbeManager::update() } else { - if (mLowPriorityFaceThrottle > 0 && mCurrentProbeUpdateFrame % mLowPriorityFaceThrottle == 0) { + if (mLowPriorityFaceThrottle > 0 && mCurrentProbeUpdateFrame % mLowPriorityFaceThrottle == 0) + { updateProbeFace(mProbes[j], i, near_clip); mCurrentProbeUpdateFrame = 0; } @@ -352,6 +346,9 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, F32 n } } +// Separate out radiance generation as a separate stage. +// This is to better enable independent control over how we generate radiance vs. having it coupled with processing the final face of the probe. +// Useful when we may not always be rendering a full set of faces of the probe. void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) { S32 sourceIdx = mReflectionProbeCount; -- cgit v1.2.3 From 1b8523a7b6293db89b16ca8e08330969cf1d9166 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 26 Feb 2024 00:30:44 -0800 Subject: #890 Make sure we're doing the correct distance check. #682 Improve the conservative update functionality for mirror faces. Make it attenuate depending on how much the camera is facing that specific cubemap face. --- indra/newview/llheroprobemanager.cpp | 29 ++++++++++++----------------- indra/newview/llheroprobemanager.h | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index feb81394cf..3adf460432 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -114,7 +114,7 @@ void LLHeroProbeManager::update() for (auto vo : mHeroVOList) { - if (vo && (!vo->isDead() || vo != nullptr)) + if (vo && !vo->isDead() && vo->mDrawable.notNull()) { float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec(); if (distance < last_distance) @@ -129,12 +129,12 @@ void LLHeroProbeManager::update() } } - if (mNearestHero != nullptr && !mNearestHero->isDead()) + if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull()) { LLVector3 hero_pos = mNearestHero->getPositionAgent(); LLVector3 face_normal = LLVector3(0, 0, 1); - - face_normal *= mNearestHero->getWorldRotation(); + + face_normal *= mNearestHero->mDrawable->getWorldRotation(); face_normal.normalize(); LLVector3 offset = camera_pos - hero_pos; @@ -150,7 +150,7 @@ void LLHeroProbeManager::update() probe_pos.load3(point.mV); // Collect the list of faces that need updating based upon the camera's rotation. - LLVector3 cam_direction = LLVector3(-1, -1, -1) * LLViewerCamera::instance().getQuaternion(); + LLVector3 cam_direction = LLVector3(0, 0, 1) * LLViewerCamera::instance().getQuaternion(); static LLVector3 cubeFaces[6] = { LLVector3(1, 0, 0), @@ -163,9 +163,11 @@ void LLHeroProbeManager::update() for (int i = 0; i < 6; i++) { - bool shouldUpdate = (cam_direction * cubeFaces[i]) > 0; - - mFaceUpdateList[i] = shouldUpdate; + float shouldUpdate = cam_direction * cubeFaces[i] * 0.5 + 0.5; + + int updateRate = fmaxf(1, (1 - shouldUpdate) * 8); + + mFaceUpdateList[i] = updateRate; } } else @@ -197,17 +199,10 @@ void LLHeroProbeManager::update() { for (U32 i = 0; i < 6; ++i) { - if (mFaceUpdateList[i]) + if (mFaceUpdateList[i] > 0 && mCurrentProbeUpdateFrame % mFaceUpdateList[i] == 0) { updateProbeFace(mProbes[j], i, near_clip); - } - else - { - if (mLowPriorityFaceThrottle > 0 && mCurrentProbeUpdateFrame % mLowPriorityFaceThrottle == 0) - { - updateProbeFace(mProbes[j], i, near_clip); - mCurrentProbeUpdateFrame = 0; - } + mCurrentProbeUpdateFrame = 0; } } generateRadiance(mProbes[j]); diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index b1907ef185..038a8fd45a 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -135,7 +135,7 @@ private: bool mReset = false; bool mRenderingMirror = false; - std::map mFaceUpdateList; + std::map mFaceUpdateList; U32 mCurrentProbeUpdateFrame = 0; U32 mLowPriorityFaceThrottle = 2; -- cgit v1.2.3 From 8c79297a8957fec13fadd2a2932b4b03b148d5a5 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 26 Feb 2024 01:21:41 -0800 Subject: #682 Further tweak the conservative update mechanism. --- indra/newview/app_settings/settings.xml | 13 ++++++++++++- indra/newview/llheroprobemanager.cpp | 7 ++++++- indra/newview/llheroprobemanager.h | 1 - indra/newview/pipeline.cpp | 3 +++ indra/newview/pipeline.h | 1 + 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6a84f64030..e707e1eb5e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10399,7 +10399,18 @@ Type S32 Value - 1 + 2 + + RenderHeroProbeConservativeUpdateMultiplier + + Comment + How many probe updates to wait until it's time to update faces that are not directly facing the camera. Acts as a multiplier. E.g., frames to the periphery of the camera updating once every 3 updates, vs ones directly facing the camera updating every update. + Persist + 1 + Type + S32 + Value + 16 RenderReflectionProbeVolumes diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 3adf460432..a00b6d6b5d 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -165,7 +165,12 @@ void LLHeroProbeManager::update() { float shouldUpdate = cam_direction * cubeFaces[i] * 0.5 + 0.5; - int updateRate = fmaxf(1, (1 - shouldUpdate) * 8); + int updateRate = ceilf((1 - shouldUpdate) * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); + + // Chances are this is a face that's non-visible to the camera when it's being reflected. + // Set it to 0. It will be skipped below. + if (updateRate == gPipeline.RenderHeroProbeConservativeUpdateMultiplier) + updateRate = 0; mFaceUpdateList[i] = updateRate; } diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 038a8fd45a..e430cae203 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -138,7 +138,6 @@ private: std::map mFaceUpdateList; U32 mCurrentProbeUpdateFrame = 0; - U32 mLowPriorityFaceThrottle = 2; std::vector mHeroVOList; LLVOVolume* mNearestHero; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e3e2da3b30..94ec5c0817 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -200,6 +200,7 @@ S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples; S32 LLPipeline::RenderBufferVisualization; bool LLPipeline::RenderMirrors; S32 LLPipeline::RenderHeroProbeUpdateRate; +S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier; LLTrace::EventStatHandle LLPipeline::sStatBatchSize("renderbatchsize"); const U32 LLPipeline::MAX_BAKE_WIDTH = 512; @@ -561,6 +562,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderBufferVisualization"); connectRefreshCachedSettingsSafe("RenderMirrors"); connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate"); + connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier"); gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } @@ -1074,6 +1076,7 @@ void LLPipeline::refreshCachedSettings() LLViewerShaderMgr::instance()->setShaders(); } RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate"); + RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier"); sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled"); RenderSpotLight = nullptr; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index fe00c52e6d..817750b4a1 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -1057,6 +1057,7 @@ public: static S32 RenderBufferVisualization; static bool RenderMirrors; static S32 RenderHeroProbeUpdateRate; + static S32 RenderHeroProbeConservativeUpdateMultiplier; }; void render_bbox(const LLVector3 &min, const LLVector3 &max); -- cgit v1.2.3 From 4ed5b59a601cfc58c3d5a5d4c1b56d4cdc73be2c Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 26 Feb 2024 01:34:40 -0800 Subject: Make sure to check if we're a hero probe before attempting to register with the hero probe manager. If we're already in the list, this will return false. --- indra/newview/llvovolume.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 149abaf573..d7af7a42d1 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4416,7 +4416,9 @@ void LLVOVolume::updateReflectionProbePtr() { // Geenz: This is a special case - what we want here is a hero probe. // What we want to do here is instantiate a hero probe from the hero probe manager. - mIsHeroProbe = gPipeline.mHeroProbeManager.registerViewerObject(this); + + if (!mIsHeroProbe) + mIsHeroProbe = gPipeline.mHeroProbeManager.registerViewerObject(this); } } else if (mReflectionProbe.notNull() || getReflectionProbeIsMirror()) -- cgit v1.2.3 From b3283036af886de56f45c731ab21e2b16383a770 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Mon, 26 Feb 2024 04:02:09 -0800 Subject: #681 Start adding blending boilerplate. --- .../shaders/class3/deferred/reflectionProbeF.glsl | 71 +++++++++++++++++++++- .../shaders/class3/deferred/softenLightF.glsl | 10 --- indra/newview/llheroprobemanager.cpp | 37 +++++++++-- indra/newview/llreflectionmapmanager.cpp | 1 - 4 files changed, 100 insertions(+), 19 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 4f6e01764a..14d9cf798f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -686,17 +686,82 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit) #if defined(HERO_PROBES) uniform vec4 clipPlane; -uniform samplerCubeArray heroProbes; + +uniform samplerCubeArray heroProbes; + +layout (std140) uniform HeroProbeData +{ + mat4 heroBox[1]; + vec4 heroSphere[1]; + uint heroShape[1]; + int heroMipCount; + int heroProbeCount; +}; + +vec3 boxIntersectHero(vec3 origin, vec3 dir, int i, out float d, float scale) +{ + // Intersection with OBB convert to unit box space + // Transform in local unit parallax cube space (scaled and rotated) + mat4 clipToLocal = heroBox[i]; + + vec3 RayLS = mat3(clipToLocal) * dir; + vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; + + d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z)); + + vec3 Unitary = vec3(scale); + vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS; + vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; + vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); + float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z)); + + // Use Distance in CS directly to recover intersection + vec3 IntersectPositionCS = origin + dir * Distance; + + return IntersectPositionCS; +} + +float sphereWeightHero(vec3 pos, vec3 dir, vec3 origin, float r, 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 atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001); + float w = 1.0 / d2; + + dw = w * atten * max(r, 1.0)*4; + + w *= atten; + + return w; +} void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) { float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; - if (clipDist > 0.0 && clipDist < 0.1 && glossiness > 0.8) + float w = 0; + float dw = 0; + if (heroShape[0] < 1) + { + float d = 0; + boxIntersectHero(pos, norm, 0, d, 1.0); + + w = max(d, 0.001); + } + else + { + float r = heroSphere[0].w; + //v = sphereIntersect(pos, norm, heroSphere[0].xyz, 4096.0*4096.0); + + w = sphereWeightHero(pos, norm, heroSphere[0].xyz, r, dw); + } + { vec3 refnormpersp = reflect(pos.xyz, norm.xyz); if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) { - glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*10).xyz; + glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz * w; } } } diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index cc6e16c64f..2f90249169 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -32,16 +32,6 @@ uniform sampler2D specularRect; uniform sampler2D normalMap; uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl -uniform samplerCubeArray heroProbes; - -#if defined(HERO_PROBES) -layout (std140) uniform HeroProbeData -{ - vec4 heroPosition[1]; - int heroProbeCount; -}; -#endif - const float M_PI = 3.14159265; #if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index a00b6d6b5d..ee993c6ba1 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -417,7 +417,7 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) void LLHeroProbeManager::updateUniforms() { - if (!LLPipeline::sReflectionProbesEnabled) + if (!gPipeline.RenderMirrors) { return; } @@ -426,8 +426,11 @@ void LLHeroProbeManager::updateUniforms() struct HeroProbeData { - LLVector4 heroPosition[1]; - GLint heroProbeCount = 1; + LLMatrix4 heroBox[1]; + LLVector4 heroSphere[1]; + GLint heroShape[1]; + GLint heroMipCount; + GLint heroProbeCount; }; HeroProbeData hpd; @@ -437,8 +440,32 @@ void LLHeroProbeManager::updateUniforms() LLVector4a oa; // scratch space for transformed origin oa.set(0, 0, 0, 0); hpd.heroProbeCount = 1; - modelview.affineTransform(mProbes[0]->mOrigin, oa); - hpd.heroPosition[0].set(oa.getF32ptr()); + + if (mNearestHero != nullptr) + { + mProbes[0]->mViewerObject = mNearestHero; + if (mNearestHero->getReflectionProbeIsBox()) + { + LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); + mProbes[0]->mRadius = s.magVec(); + } + else + { + mProbes[0]->mRadius = mNearestHero->getScale().mV[0] * 0.5f; + } + + modelview.affineTransform(mProbes[0]->mOrigin, oa); + hpd.heroShape[0] = 0; + if (!mProbes[0]->getBox(hpd.heroBox[0])) + { + hpd.heroShape[0] = 1; + } + + hpd.heroSphere[0].set(oa.getF32ptr()); + hpd.heroSphere[0].mV[3] = mProbes[0]->mRadius; + } + + hpd.heroMipCount = mMipChain.size(); //copy rpd into uniform buffer object if (mUBO == 0) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8506886409..3144260905 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1016,7 +1016,6 @@ void LLReflectionMapManager::updateUniforms() { refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f; } - } modelview.affineTransform(refmap->mOrigin, oa); rpd.refSphere[count].set(oa.getF32ptr()); -- cgit v1.2.3 From 95e1badaa4566bea41479623bf5b5112f7184cd5 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 26 Feb 2024 13:46:39 -0600 Subject: https://github.com/secondlife/jira-archive-internal/issues/71006 Fix for probes going off the rails -- sanity clamp sky glow (#893) --- .../app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl index a1da4b1f9a..8769cc0239 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl @@ -98,7 +98,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) haze_glow *= glow.x; // higher glow.x gives dimmer glow (because next step is 1 / "angle") - haze_glow = pow(haze_glow, glow.z); + haze_glow = clamp(pow(haze_glow, glow.z), -10, 10); // glow.z should be negative, so we're doing a sort of (1 / "angle") function // add "minimum anti-solar illumination" -- cgit v1.2.3 From 8b374f733360650c95d3ec021f1ec351e8b5dc21 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 27 Feb 2024 13:18:03 -0800 Subject: #681 Make our sampling code for probes a good deal more generic to make sure all probes can benefit from the same blending functions. --- .../shaders/class3/deferred/reflectionProbeF.glsl | 49 ++++++---------------- 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 14d9cf798f..7df9bdba5d 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -366,11 +366,11 @@ return texCUBE(envMap, ReflDirectionWS); // i - probe index in refBox/refSphere // d - distance to nearest wall in clip space // scale - scale of box, default 1.0 -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d, float scale) { // Intersection with OBB convert to unit box space // Transform in local unit parallax cube space (scaled and rotated) - mat4 clipToLocal = refBox[i]; + mat4 clipToLocal = i; vec3 RayLS = mat3(clipToLocal) * dir; vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -389,7 +389,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) return IntersectPositionCS; } -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d) { return boxIntersect(origin, dir, i, d, 1.0); } @@ -444,9 +444,9 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col) } -void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col) +void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col) { - mat4 clipToLocal = refBox[i]; + mat4 clipToLocal = i; // transform into unit cube space origin = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -463,7 +463,7 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col) // r - radius of probe influence volume // i - index of probe in refSphere // dw - distance weight -float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw) +float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, vec4 i, out float dw) { float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down) vec3 delta = pos.xyz - origin; @@ -472,7 +472,7 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001); float w = 1.0 / d2; - w *= refParams[i].z; + w *= i.z; dw = w * atten * max(r, 1.0)*4; @@ -498,7 +498,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, if (refIndex[i].w < 0) { // box probe float d = 0; - v = boxIntersect(pos, dir, i, d); + v = boxIntersect(pos, dir, refBox[i], d); w = max(d, 0.001); } @@ -512,7 +512,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 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 rr); - w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw); + w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw); } v -= c; @@ -538,7 +538,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int if (refIndex[i].w < 0) { float d = 0.0; - v = boxIntersect(pos, dir, i, d, 3.0); + v = boxIntersect(pos, dir, refBox[i], d, 3.0); w = max(d, 0.001); } else @@ -552,7 +552,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int 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, i, dw); + w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw); } v -= c; @@ -698,29 +698,6 @@ layout (std140) uniform HeroProbeData int heroProbeCount; }; -vec3 boxIntersectHero(vec3 origin, vec3 dir, int i, out float d, float scale) -{ - // Intersection with OBB convert to unit box space - // Transform in local unit parallax cube space (scaled and rotated) - mat4 clipToLocal = heroBox[i]; - - vec3 RayLS = mat3(clipToLocal) * dir; - vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; - - d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z)); - - vec3 Unitary = vec3(scale); - vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS; - vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS; - vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect); - float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z)); - - // Use Distance in CS directly to recover intersection - vec3 IntersectPositionCS = origin + dir * Distance; - - return IntersectPositionCS; -} - float sphereWeightHero(vec3 pos, vec3 dir, vec3 origin, float r, out float dw) { float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down) @@ -745,7 +722,7 @@ void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) if (heroShape[0] < 1) { float d = 0; - boxIntersectHero(pos, norm, 0, d, 1.0); + boxIntersect(pos, norm, heroBox[0], d, 1.0); w = max(d, 0.001); } @@ -844,7 +821,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col) { if (refIndex[i].w < 0) { - boxIntersectDebug(origin, pos, i, col); + boxIntersectDebug(origin, pos, refBox[i], col); } else { -- cgit v1.2.3 From 47cd3cb0ad03c91f118fd20fea8d8924759fd2b7 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 27 Feb 2024 13:46:49 -0800 Subject: #681 More generalization of falloff. --- .../shaders/class3/deferred/reflectionProbeF.glsl | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 7df9bdba5d..257299258e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -698,22 +698,6 @@ layout (std140) uniform HeroProbeData int heroProbeCount; }; -float sphereWeightHero(vec3 pos, vec3 dir, vec3 origin, float r, 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 atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001); - float w = 1.0 / d2; - - dw = w * atten * max(r, 1.0)*4; - - w *= atten; - - return w; -} - void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) { float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; @@ -729,16 +713,15 @@ void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) else { float r = heroSphere[0].w; - //v = sphereIntersect(pos, norm, heroSphere[0].xyz, 4096.0*4096.0); - w = sphereWeightHero(pos, norm, heroSphere[0].xyz, r, dw); + w = sphereWeight(pos, norm, heroSphere[0].xyz, r, vec4(1), dw); } { vec3 refnormpersp = reflect(pos.xyz, norm.xyz); if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) { - glossenv = textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz * w; + glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w); } } } -- cgit v1.2.3 From d79498e25991e425510643ecd1303a5675c5fbf6 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 28 Feb 2024 15:02:18 -0800 Subject: secondlife/viewer#712: More intuitive selection of PBR vs texture terrain, and update dropdown to match --- indra/newview/llfloaterregioninfo.cpp | 183 +++++++++++++++++++--------------- indra/newview/llfloaterregioninfo.h | 2 +- indra/newview/llvlcomposition.cpp | 14 ++- indra/newview/llvlcomposition.h | 2 +- 4 files changed, 108 insertions(+), 93 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8b335d57d7..8e2fb24923 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -340,7 +340,6 @@ void LLFloaterRegionInfo::onRegionChanged() } } -// static void LLFloaterRegionInfo::requestRegionInfo() { LLTabContainer* tab = findChild("region_panels"); @@ -1327,9 +1326,6 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { - // *TODO: Don't early-exit in PBR material terrain editing mode, and - // instead do some reasonable checks that the PBR material is compatible - // with the terrain rendering pipeline. Err on the side of permissive. LLComboBox* material_type_ctrl = getChild("terrain_material_type"); if (material_type_ctrl) { @@ -1446,54 +1442,24 @@ BOOL LLPanelRegionTerrainInfo::postBuild() mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLPanelRegionTerrainInfo::onRegionChanged,this)); } - refresh(); - return LLPanelRegionInfo::postBuild(); } -// virtual -void LLPanelRegionTerrainInfo::refresh() +void LLPanelRegionTerrainInfo::onSelectMaterialType() { - static LLCachedControl feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); - - LLTextBox* texture_text = getChild("detail_texture_text"); - if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); } - - LLComboBox* material_type_ctrl = getChild("terrain_material_type"); - if (material_type_ctrl) - { - material_type_ctrl->setVisible(feature_pbr_terrain_enabled); - - bool has_material_assets = false; - - std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - LLTextureCtrl* material_ctrl = getChild(buffer); - if (material_ctrl && material_ctrl->getImageAssetID().notNull()) - { - has_material_assets = true; - break; - } - } - - TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); - - if (!feature_pbr_terrain_enabled) { material_type = TerrainMaterialType::TEXTURE; } - - const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; - material_type_ctrl->setEnabled(feature_pbr_terrain_enabled && !(is_material_selected && has_material_assets)); - } + updateForMaterialType(); + onChangeAnything(); } -void LLPanelRegionTerrainInfo::onSelectMaterialType() +void LLPanelRegionTerrainInfo::updateForMaterialType() { LLComboBox* material_type_ctrl = getChild("terrain_material_type"); if (!material_type_ctrl) { return; } const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); const bool show_texture_controls = material_type == TerrainMaterialType::TEXTURE; const bool show_material_controls = material_type == TerrainMaterialType::PBR_MATERIAL; + + // Toggle visibility of correct swatches std::string buffer; LLTextureCtrl* texture_ctrl; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) @@ -1554,31 +1520,98 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LLVLComposition* compp = region->getComposition(); - // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set the IDs on both pickers for now. + static LLCachedControl feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false); + + const bool textures_ready = compp->texturesReady(false, false); + const bool materials_ready = feature_pbr_terrain_enabled && compp->materialsReady(false, false); + + LLTextBox* texture_text = getChild("detail_texture_text"); + if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); } + + bool set_texture_swatches; + bool set_material_swatches; + bool clear_texture_swatches; + bool clear_material_swatches; + LLTerrainMaterials::Type material_type; + if (!textures_ready && !materials_ready) + { + // Are these 4 texture IDs or 4 material IDs? Who knows! Let's set + // the IDs on both pickers for now. + material_type = LLTerrainMaterials::Type::TEXTURE; + set_texture_swatches = true; + set_material_swatches = true; + clear_texture_swatches = false; + clear_material_swatches = false; + } + else + { + material_type = compp->getMaterialType(); + set_texture_swatches = material_type == LLTerrainMaterials::Type::TEXTURE; + set_material_swatches = !set_texture_swatches; + clear_texture_swatches = !set_texture_swatches; + clear_material_swatches = !set_material_swatches; + } + + LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) { material_type_ctrl->setCurrentByIndex(S32(material_type)); } + updateForMaterialType(); + LLTextureCtrl* asset_ctrl; std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - asset_ctrl = getChild(buffer); - if(asset_ctrl) - { - LL_DEBUGS() << "Detail Texture " << i << ": " - << compp->getDetailAssetID(i) << LL_ENDL; - LLUUID tmp_id(compp->getDetailAssetID(i)); - asset_ctrl->setImageAssetID(tmp_id); - } - } - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); - if(asset_ctrl) - { - LLUUID tmp_id(compp->getDetailAssetID(i)); - asset_ctrl->setImageAssetID(tmp_id); - } - } + if (set_texture_swatches) + { + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl) + { + LL_DEBUGS() << "Detail Texture " << i << ": " + << compp->getDetailAssetID(i) << LL_ENDL; + LLUUID tmp_id(compp->getDetailAssetID(i)); + asset_ctrl->setImageAssetID(tmp_id); + } + } + } + if (set_material_swatches) + { + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl) + { + LL_DEBUGS() << "Detail Material " << i << ": " + << compp->getDetailAssetID(i) << LL_ENDL; + LLUUID tmp_id(compp->getDetailAssetID(i)); + asset_ctrl->setImageAssetID(tmp_id); + } + } + } + if (clear_texture_swatches) + { + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl) + { + asset_ctrl->setImageAssetID(LLUUID::null); + } + } + } + if (clear_material_swatches) + { + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("material_detail_%d", i); + asset_ctrl = getChild(buffer); + if(asset_ctrl) + { + asset_ctrl->setImageAssetID(LLUUID::null); + } + } + } for(S32 i = 0; i < CORNER_COUNT; ++i) { @@ -1650,29 +1683,13 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() std::string id_str; LLMessageSystem* msg = gMessageSystem; - // Use material IDs instead of texture IDs if all material IDs are set, AND the mode is set to PBR materials. - S32 materials_used = 0; + // Send either material IDs instead of texture IDs depending on + // terrain_material_type - they both occupy the same slot. LLComboBox* material_type_ctrl = getChild("terrain_material_type"); - if (material_type_ctrl) - { - const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); - const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; - if (is_material_selected) - { - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); - if(asset_ctrl && asset_ctrl->getImageAssetID().notNull()) - { - ++materials_used; - } - } - } - } + const TerrainMaterialType material_type = material_type_ctrl ? material_type_from_index(material_type_ctrl->getCurrentIndex()) : TerrainMaterialType::TEXTURE; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { - if (materials_used == TERRAIN_TEXTURE_COUNT) + if (material_type == TerrainMaterialType::PBR_MATERIAL) { buffer = llformat("material_detail_%d", i); asset_ctrl = getChild(buffer); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 91e1f5b058..abd8e21503 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -258,8 +258,8 @@ public: //static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button - void refresh() override; void onSelectMaterialType(); + void updateForMaterialType(); static void onClickDownloadRaw(void*); static void onClickUploadRaw(void*); diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 09b21e4e0a..9c64381a07 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -91,10 +91,10 @@ BOOL LLTerrainMaterials::generateMaterials() LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) { llassert(mDetailTextures[asset] && mDetailMaterials[asset]); - // *HACK: Assume both the the material and texture were fetched in the same - // way using the same UUID. However, we may not know at this point which - // one will load. - return mDetailTextures[asset]->getID(); + // Assume both the the material and texture were fetched in the same way + // using the same UUID. However, we may not know at this point which one + // will load. + return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null; } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -133,7 +133,7 @@ bool LLTerrainMaterials::texturesReady(bool boost, bool strict) // *NOTE: Calls to textureReady may boost textures. Do not early-return. for (S32 i = 0; i < ASSET_COUNT; i++) { - ready[i] = textureReady(mDetailTextures[i], boost); + ready[i] = mDetailTextures[i].notNull() && textureReady(mDetailTextures[i], boost); } bool one_ready = false; @@ -250,6 +250,7 @@ bool LLTerrainMaterials::materialReady(LLPointer &mat, bo // Material is loaded, but textures may not be if (!textures_set) { + textures_set = true; // *NOTE: These can sometimes be set to to nullptr due to // updateTEMaterialTextures. For the sake of robustness, we emulate // that fetching behavior by setting textures of null IDs to nullptr. @@ -257,9 +258,6 @@ bool LLTerrainMaterials::materialReady(LLPointer &mat, bo mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); - textures_set = true; - - return false; } // *NOTE: Calls to textureReady may boost textures. Do not early-return. diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 73bfca6ed4..dea776849a 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -58,7 +58,7 @@ public: BOOL generateMaterials(); - LLUUID getDetailAssetID(S32 asset); + virtual LLUUID getDetailAssetID(S32 asset); virtual void setDetailAssetID(S32 asset, const LLUUID& id); Type getMaterialType(); bool texturesReady(bool boost, bool strict); -- cgit v1.2.3 From 0cb9e7f7e5bd02ded8b9f2bd9cd6c57a70187dcc Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 29 Feb 2024 16:52:35 -0800 Subject: secondlife/viewer#712: Remember previously set textures/materials when possible. Not persistent. --- indra/newview/llfloaterregioninfo.cpp | 88 ++++++++++++++++++++++------------- indra/newview/llfloaterregioninfo.h | 5 +- indra/newview/llvlcomposition.cpp | 22 +++++++-- indra/newview/llvlcomposition.h | 9 ++-- 4 files changed, 81 insertions(+), 43 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8e2fb24923..a865ad19d3 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -86,7 +86,6 @@ #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" -#include "llvlcomposition.h" #include "lltrans.h" #include "llagentui.h" #include "llmeshrepository.h" @@ -100,7 +99,6 @@ #include "llavatarnamecache.h" #include "llenvironment.h" -const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; const U32 MAX_LISTED_NAMES = 100; @@ -1335,7 +1333,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() } static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { std::string buffer; buffer = llformat("texture_detail_%d", i); @@ -1397,6 +1395,21 @@ BOOL LLPanelRegionTerrainInfo::validateTextureHeights() ///////////////////////////////////////////////////////////////////////////// // LLPanelRegionTerrainInfo ///////////////////////////////////////////////////////////////////////////// + +LLPanelRegionTerrainInfo::LLPanelRegionTerrainInfo() +: LLPanelRegionInfo() +{ + const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures(); + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + mLastSetTextures[i] = default_textures[i]; + } + for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { + mLastSetMaterials[i] = LLUUID::null; + } +} + // Initialize statics BOOL LLPanelRegionTerrainInfo::postBuild() @@ -1411,12 +1424,12 @@ BOOL LLPanelRegionTerrainInfo::postBuild() std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); initCtrl(buffer); } - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); initCtrl(buffer); @@ -1462,7 +1475,7 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() // Toggle visibility of correct swatches std::string buffer; LLTextureCtrl* texture_ctrl; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); texture_ctrl = getChild(buffer); @@ -1471,7 +1484,7 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() texture_ctrl->setVisible(show_texture_controls); } } - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); texture_ctrl = getChild(buffer); @@ -1530,8 +1543,8 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) bool set_texture_swatches; bool set_material_swatches; - bool clear_texture_swatches; - bool clear_material_swatches; + bool reset_texture_swatches; + bool reset_material_swatches; LLTerrainMaterials::Type material_type; if (!textures_ready && !materials_ready) { @@ -1540,16 +1553,16 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) material_type = LLTerrainMaterials::Type::TEXTURE; set_texture_swatches = true; set_material_swatches = true; - clear_texture_swatches = false; - clear_material_swatches = false; + reset_texture_swatches = false; + reset_material_swatches = false; } else { material_type = compp->getMaterialType(); set_texture_swatches = material_type == LLTerrainMaterials::Type::TEXTURE; set_material_swatches = !set_texture_swatches; - clear_texture_swatches = !set_texture_swatches; - clear_material_swatches = !set_material_swatches; + reset_texture_swatches = !set_texture_swatches; + reset_material_swatches = !set_material_swatches; } LLComboBox* material_type_ctrl = getChild("terrain_material_type"); @@ -1560,7 +1573,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) std::string buffer; if (set_texture_swatches) { - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); asset_ctrl = getChild(buffer); @@ -1575,7 +1588,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) } if (set_material_swatches) { - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); asset_ctrl = getChild(buffer); @@ -1588,27 +1601,27 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) } } } - if (clear_texture_swatches) + if (reset_texture_swatches) { - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); asset_ctrl = getChild(buffer); if(asset_ctrl) { - asset_ctrl->setImageAssetID(LLUUID::null); + asset_ctrl->setImageAssetID(mLastSetTextures[i]); } } } - if (clear_material_swatches) + if (reset_material_swatches) { - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); asset_ctrl = getChild(buffer); if(asset_ctrl) { - asset_ctrl->setImageAssetID(LLUUID::null); + asset_ctrl->setImageAssetID(mLastSetMaterials[i]); } } } @@ -1687,26 +1700,35 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() // terrain_material_type - they both occupy the same slot. LLComboBox* material_type_ctrl = getChild("terrain_material_type"); const TerrainMaterialType material_type = material_type_ctrl ? material_type_from_index(material_type_ctrl->getCurrentIndex()) : TerrainMaterialType::TEXTURE; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { + for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) + { if (material_type == TerrainMaterialType::PBR_MATERIAL) { buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); } else { buffer = llformat("texture_detail_%d", i); - asset_ctrl = getChild(buffer); } - if(asset_ctrl) - { - LLUUID tmp_id(asset_ctrl->getImageAssetID()); - tmp_id.toString(id_str); - buffer = llformat("%d %s", i, id_str.c_str()); - strings.push_back(buffer); - } - } + asset_ctrl = getChild(buffer); + + if (!asset_ctrl) { continue; } + + LLUUID tmp_id(asset_ctrl->getImageAssetID()); + tmp_id.toString(id_str); + buffer = llformat("%d %s", i, id_str.c_str()); + strings.push_back(buffer); + + // Store asset for later terrain editing + if (material_type == TerrainMaterialType::PBR_MATERIAL) + { + mLastSetMaterials[i] = tmp_id; + } + else + { + mLastSetTextures[i] = tmp_id; + } + } sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); strings.clear(); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index abd8e21503..315c6aca0f 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -36,6 +36,7 @@ #include "llpanel.h" #include "llextendedstatus.h" #include "llpanelenvironment.h" +#include "llvlcomposition.h" #include "lleventcoro.h" @@ -243,7 +244,7 @@ class LLPanelRegionTerrainInfo : public LLPanelRegionInfo LOG_CLASS(LLPanelRegionTerrainInfo); public: - LLPanelRegionTerrainInfo() : LLPanelRegionInfo() {} + LLPanelRegionTerrainInfo(); ~LLPanelRegionTerrainInfo() {} BOOL postBuild() override; @@ -274,6 +275,8 @@ private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; boost::signals2::connection mRegionChangedSlot; + LLUUID mLastSetTextures[LLTerrainMaterials::ASSET_COUNT]; + LLUUID mLastSetMaterials[LLTerrainMaterials::ASSET_COUNT]; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 9c64381a07..506ab005c5 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -44,7 +44,6 @@ static const U32 BASE_SIZE = 128; - F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) { // Not sure if this is the right math... @@ -286,16 +285,29 @@ bool LLTerrainMaterials::materialReady(LLPointer &mat, bo return true; } +// static +const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT] +{ + const static LLUUID default_textures[LLVLComposition::ASSET_COUNT] = + { + TERRAIN_DIRT_DETAIL, + TERRAIN_GRASS_DETAIL, + TERRAIN_MOUNTAIN_DETAIL, + TERRAIN_ROCK_DETAIL + }; + return default_textures; +} LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : LLTerrainMaterials(), LLViewerLayer(width, scale) { // Load Terrain Textures - Original ones - setDetailAssetID(0, TERRAIN_DIRT_DETAIL); - setDetailAssetID(1, TERRAIN_GRASS_DETAIL); - setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailAssetID(3, TERRAIN_ROCK_DETAIL); + const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures(); + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + setDetailAssetID(i, default_textures[i]); + } mSurfacep = surfacep; diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index dea776849a..7397ff1e8d 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -82,6 +82,11 @@ extern LLTerrainMaterials gLocalTerrainMaterials; class LLVLComposition : public LLTerrainMaterials, public LLViewerLayer { public: + // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. + // So we need to compress heights into this range. + static const S32 ASSET_COUNT = 4; + static const LLUUID (&getDefaultTextures())[ASSET_COUNT]; + LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale); /*virtual*/ ~LLVLComposition(); @@ -93,10 +98,6 @@ public: // Generate texture from composition values. BOOL generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height); - // Heights map into textures (or materials) as 0-1 = first, 1-2 = second, etc. - // So we need to compress heights into this range. - static const S32 ASSET_COUNT = 4; - // Use these as indeces ito the get/setters below that use 'corner' enum ECorner { -- cgit v1.2.3 From e0ae227d0af39ee1c55d167d5091889f821ce124 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 31 Oct 2023 10:50:39 -0400 Subject: SL-20546: Add viewer channel and full version to GitHub release page. (cherry picked from commit f71662225eadf1589f5331e763e02e0bb1b72137) --- .github/workflows/build.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1dd2c1d5df..9d04fbe87a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -360,6 +360,11 @@ jobs: # name the release page for the build number so we can find it # easily (analogous to looking up a codeticket build page) name: "v${{ github.run_id }}" + # SL-20546: want the channel and version to be visible on the + # release page + body: | + ${{ needs.build.outputs.viewer_channel }} + ${{ needs.build.outputs.viewer_version }} prerelease: true generate_release_notes: true # the only reason we generate a GH release is to post build products -- cgit v1.2.3 From cac7023996d691f00101429830a23b2cef3a2f83 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 14 Nov 2023 04:09:56 -0500 Subject: SL-20546: Append generated release notes body to our explicit body. For a tag build that generates a release page, try to deduce the git branch to which the tag we're building corresponds and add that to release notes. (cherry picked from commit 9e99bb04a32f2ecc0f0b99686ce5a7adb356596d) --- .github/workflows/build.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9d04fbe87a..c0bec11275 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,6 +24,7 @@ jobs: outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} + viewer_branch: ${{ steps.build.outputs.viewer_branch }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -176,9 +177,17 @@ jobs: if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]] then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" + # Since GITHUB_REF_NAME is a tag rather than a branch, we need + # to discover to what branch this tag corresponds. Get the tip + # commit (for the tag) and then ask for branches containing it. + # Assume GitHub cloned only this tag and its containing branch. + viewer_branch="$(git branch --contains "$(git log -n 1 --format=%h)" | + grep -v '(HEAD')" else export viewer_channel="Second Life Test" + viewer_branch="${GITHUB_REF_NAME}" fi echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT" + echo "viewer_branch=$viewer_branch" >> "$GITHUB_OUTPUT" # On windows we need to point the build to the correct python # as neither CMake's FindPython nor our custom Python.cmake module @@ -365,8 +374,10 @@ jobs: body: | ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} + ${{ needs.build.outputs.viewer_branch }} prerelease: true generate_release_notes: true + append_body: true # the only reason we generate a GH release is to post build products fail_on_unmatched_files: true files: | -- cgit v1.2.3 From a13e70aeffb87e2934f1b01f85dc2c78ea10e20c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 14 Nov 2023 14:20:51 -0500 Subject: SL-20546: Try harder to infer the branch corresponding to build tag. (cherry picked from commit 59eeaed1187e7592fd83380045916f2d8b9d58e7) --- .github/workflows/build.yaml | 8 ++-- .github/workflows/which_branch.py | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/which_branch.py diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c0bec11275..6c40c173db 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -178,11 +178,9 @@ jobs: then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" # Since GITHUB_REF_NAME is a tag rather than a branch, we need - # to discover to what branch this tag corresponds. Get the tip - # commit (for the tag) and then ask for branches containing it. - # Assume GitHub cloned only this tag and its containing branch. - viewer_branch="$(git branch --contains "$(git log -n 1 --format=%h)" | - grep -v '(HEAD')" + # to discover to what branch this tag corresponds. + viewer_branch="$(python3 .github/workflows/which_branch.py \ + --token "${{ github.token }}" ${{ github.workflow_sha }})" else export viewer_channel="Second Life Test" viewer_branch="${GITHUB_REF_NAME}" fi diff --git a/.github/workflows/which_branch.py b/.github/workflows/which_branch.py new file mode 100644 index 0000000000..802ea44b5a --- /dev/null +++ b/.github/workflows/which_branch.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""\ +@file which_branch.py +@author Nat Goodspeed +@date 2023-11-14 +@brief Discover which git branch(es) correspond to a given commit hash. + +$LicenseInfo:firstyear=2023&license=viewerlgpl$ +Copyright (c) 2023, Linden Research, Inc. +$/LicenseInfo$ +""" + +import github +import re +import sys +import subprocess + +class Error(Exception): + pass + +def branches_for(token, commit, repo=None): + """ + Use the GitHub REST API to discover which branch(es) correspond to the + passed commit hash. The commit string can actually be any of the ways git + permits to identify a commit: + + https://git-scm.com/docs/gitrevisions#_specifying_revisions + + branches_for() generates a (possibly empty) sequence of all the branches + of the specified repo for which the specified commit is the tip. + + If repo is omitted or None, assume the current directory is a local clone + whose 'origin' remote is the GitHub repository of interest. + """ + if not repo: + url = subprocess.check_output(['git', 'remote', 'get-url', 'origin'], + text=True) + parts = re.split(r'[:/]', url.rstrip()) + repo = '/'.join(parts[-2:]).removesuffix('.git') + + gh = github.MainClass.Github(token) + grepo = gh.get_repo(repo) + for branch in grepo.get_branches(): + try: + delta = grepo.compare(base=commit, head=branch.name) + except github.GithubException: + continue + + if delta.ahead_by == 0 and delta.behind_by == 0: + yield branch + +def main(*raw_args): + from argparse import ArgumentParser + parser = ArgumentParser(description= +"%(prog)s reports the branch(es) for which the specified commit hash is the tip.", + epilog="""\ +When GitHub Actions launches a tag build, it checks out the specific changeset +identified by the tag, and so 'git branch' reports detached HEAD. But we use +tag builds to build a GitHub 'release' of the tip of a particular branch, and +it's useful to be able to identify which branch that is. +""") + parser.add_argument('-t', '--token', required=True, + help="""GitHub REST API access token""") + parser.add_argument('-r', '--repo', + help="""GitHub repository name, in the form OWNER/REPOSITORY""") + parser.add_argument('commit', + help="""commit hash at the tip of the sought branch""") + + args = parser.parse_args(raw_args) + for branch in branches_for(token=args.token, commit=args.commit, repo=args.repo): + print(branch.name) + +if __name__ == "__main__": + try: + sys.exit(main(*sys.argv[1:])) + except Error as err: + sys.exit(str(err)) -- cgit v1.2.3 From e4865db0cae7dc3b4e37543cb7cd57d357048340 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 14 Nov 2023 14:30:44 -0500 Subject: SL-20546: Add PyGithub to installed Python packages. (cherry picked from commit 6654ad14eed674e894d2903e0f2ea37c4e806c0f) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6c40c173db..6704737409 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -81,7 +81,7 @@ jobs: path: .master-message-template - name: Install autobuild and python dependencies - run: pip3 install autobuild llsd + run: pip3 install autobuild PyGithub llsd - name: Cache autobuild packages uses: actions/cache@v3 -- cgit v1.2.3 From cfbef4e4f961cafaa004089e2055ff13de35b8dc Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 Nov 2023 09:44:38 -0500 Subject: SL-20546: Make dependency on build job explicit, not indirect. The release job has been dependent on sign-and-package-windows and sign-and-package-mac, each of which depends on build. But that indirect dependency doesn't convey access to ${{ needs.build.outputs.xxx }}. Add the build job to direct dependencies so release can access its outputs. (cherry picked from commit 819604d2cee6d4527cc436bebfacddf8642635ff) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6704737409..861f1567c6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -331,7 +331,7 @@ jobs: version: ${{ needs.build.outputs.viewer_version }} release: - needs: [sign-and-package-windows, sign-and-package-mac] + needs: [build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life_') steps: -- cgit v1.2.3 From 8590ce0533a4bc273b6c0094250fe31fc8e78f1f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 10:59:03 -0500 Subject: DRTVWR-601: Make autobuild set vcs_url, vcs_branch, vcs_revision in viewer's autobuild-package.xml. Ensure that AUTOBUILD_VCS_BRANCH is set before the build. (cherry picked from commit b782ab73e640e434e4ed67fa8dfc951f09757585) (cherry picked from commit 6e8d4f48466a5bbad2fcc27bc2877a30e575d4ce) --- .github/workflows/build.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 861f1567c6..f127ac3f0f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -34,6 +34,9 @@ jobs: AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }} AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables + # Direct autobuild to store vcs_url, vcs_branch and vcs_revision in + # autobuild-package.xml. + AUTOBUILD_VCS_INFO: "true" AUTOBUILD_VSVER: "170" DEVELOPER_DIR: ${{ matrix.developer_dir }} # Ensure that Linden viewer builds engage Bugsplat. @@ -199,6 +202,11 @@ jobs: fi export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")" + # branch will be something like "origin/mybranch" + branch="$(git branch -r --contains ${{ github.event.pull_request.head.sha || github.sha }} | head -n 1)" + # strip off "origin/" + export AUTOBUILD_VCS_BRANCH="${branch#*/}" + ./build.sh # Each artifact is downloaded as a distinct .zip file. Multiple jobs -- cgit v1.2.3 From 9b3d4325d9f049bc7315e3772eee2fb5e4bfc83a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 17:35:23 -0500 Subject: DRTVWR-601: Use viewer-build-util/which-branch to determine branch. (cherry picked from commit 2c5066f1fcc0c9f145698ef3aaec72d27bce7181) (cherry picked from commit ff1741cecae0fac6d94507fa4a6e4662219af707) --- .github/workflows/build.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f127ac3f0f..f172883ae6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -100,10 +100,17 @@ jobs: if: runner.os == 'Windows' run: choco install nsis-unicode + - name: Determine source branch + id: which-branch + uses: secondlife/viewer-build-util/which-branch@v1 + with: + token: ${{ github.token }} + - name: Build id: build shell: bash env: + AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }} RUNNER_OS: ${{ runner.os }} run: | # set up things the viewer's build.sh script expects @@ -154,7 +161,7 @@ jobs: } repo_branch() { - git -C "$1" branch | grep '^* ' | cut -c 3- + echo "$AUTOBUILD_VCS_BRANCH" } record_dependencies_graph() { @@ -202,11 +209,6 @@ jobs: fi export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")" - # branch will be something like "origin/mybranch" - branch="$(git branch -r --contains ${{ github.event.pull_request.head.sha || github.sha }} | head -n 1)" - # strip off "origin/" - export AUTOBUILD_VCS_BRANCH="${branch#*/}" - ./build.sh # Each artifact is downloaded as a distinct .zip file. Multiple jobs -- cgit v1.2.3 From 8f68199ccd4beeee827ff360e2f36871cedacdfe Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 18 Jan 2024 13:34:40 -0500 Subject: SL-20546: Use branch for autobuild package as well as release page. which_branch.py has moved to viewer-build-util as a reusable action. (cherry picked from commit 09f66828ba573515c3766cce32f4746b8189efcf) --- .github/workflows/build.yaml | 8 +--- .github/workflows/which_branch.py | 77 --------------------------------------- 2 files changed, 1 insertion(+), 84 deletions(-) delete mode 100644 .github/workflows/which_branch.py diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f172883ae6..b323290f6b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,7 +24,7 @@ jobs: outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} - viewer_branch: ${{ steps.build.outputs.viewer_branch }} + viewer_branch: ${{ steps.which-branch.outputs.branch }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -187,15 +187,9 @@ jobs: if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]] then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" - # Since GITHUB_REF_NAME is a tag rather than a branch, we need - # to discover to what branch this tag corresponds. - viewer_branch="$(python3 .github/workflows/which_branch.py \ - --token "${{ github.token }}" ${{ github.workflow_sha }})" else export viewer_channel="Second Life Test" - viewer_branch="${GITHUB_REF_NAME}" fi echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT" - echo "viewer_branch=$viewer_branch" >> "$GITHUB_OUTPUT" # On windows we need to point the build to the correct python # as neither CMake's FindPython nor our custom Python.cmake module diff --git a/.github/workflows/which_branch.py b/.github/workflows/which_branch.py deleted file mode 100644 index 802ea44b5a..0000000000 --- a/.github/workflows/which_branch.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -"""\ -@file which_branch.py -@author Nat Goodspeed -@date 2023-11-14 -@brief Discover which git branch(es) correspond to a given commit hash. - -$LicenseInfo:firstyear=2023&license=viewerlgpl$ -Copyright (c) 2023, Linden Research, Inc. -$/LicenseInfo$ -""" - -import github -import re -import sys -import subprocess - -class Error(Exception): - pass - -def branches_for(token, commit, repo=None): - """ - Use the GitHub REST API to discover which branch(es) correspond to the - passed commit hash. The commit string can actually be any of the ways git - permits to identify a commit: - - https://git-scm.com/docs/gitrevisions#_specifying_revisions - - branches_for() generates a (possibly empty) sequence of all the branches - of the specified repo for which the specified commit is the tip. - - If repo is omitted or None, assume the current directory is a local clone - whose 'origin' remote is the GitHub repository of interest. - """ - if not repo: - url = subprocess.check_output(['git', 'remote', 'get-url', 'origin'], - text=True) - parts = re.split(r'[:/]', url.rstrip()) - repo = '/'.join(parts[-2:]).removesuffix('.git') - - gh = github.MainClass.Github(token) - grepo = gh.get_repo(repo) - for branch in grepo.get_branches(): - try: - delta = grepo.compare(base=commit, head=branch.name) - except github.GithubException: - continue - - if delta.ahead_by == 0 and delta.behind_by == 0: - yield branch - -def main(*raw_args): - from argparse import ArgumentParser - parser = ArgumentParser(description= -"%(prog)s reports the branch(es) for which the specified commit hash is the tip.", - epilog="""\ -When GitHub Actions launches a tag build, it checks out the specific changeset -identified by the tag, and so 'git branch' reports detached HEAD. But we use -tag builds to build a GitHub 'release' of the tip of a particular branch, and -it's useful to be able to identify which branch that is. -""") - parser.add_argument('-t', '--token', required=True, - help="""GitHub REST API access token""") - parser.add_argument('-r', '--repo', - help="""GitHub repository name, in the form OWNER/REPOSITORY""") - parser.add_argument('commit', - help="""commit hash at the tip of the sought branch""") - - args = parser.parse_args(raw_args) - for branch in branches_for(token=args.token, commit=args.commit, repo=args.repo): - print(branch.name) - -if __name__ == "__main__": - try: - sys.exit(main(*sys.argv[1:])) - except Error as err: - sys.exit(str(err)) -- cgit v1.2.3 From a8cd70123b075440c6343862349495421d12be45 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 18 Jan 2024 13:43:34 -0500 Subject: SL-20546: PyGithub was only needed for local which_branch.py. Now that which_branch.py has moved to viewer-build-util, so has the PyGithub dependency. (cherry picked from commit dd0ec112fe5ded8ed5f69b72b3df26343ca12d35) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b323290f6b..0cd5595e4b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -84,7 +84,7 @@ jobs: path: .master-message-template - name: Install autobuild and python dependencies - run: pip3 install autobuild PyGithub llsd + run: pip3 install autobuild llsd - name: Cache autobuild packages uses: actions/cache@v3 -- cgit v1.2.3 From 9f326f5b960b0d039280e4c04e7eb44fc094e40e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 15 Feb 2024 11:21:31 -0500 Subject: Engage new viewer-build-util/which-branch with relnotes output. Put whatever release notes we retrieve into the generated release page. (cherry picked from commit ff543b744ee0b0fd4dd90b46419ae50a570572ab) --- .github/workflows/build.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0cd5595e4b..4d3dd31801 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -25,6 +25,7 @@ jobs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} viewer_branch: ${{ steps.which-branch.outputs.branch }} + relnotes: ${{ steps.which-branch.outputs.relnotes }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -102,7 +103,7 @@ jobs: - name: Determine source branch id: which-branch - uses: secondlife/viewer-build-util/which-branch@v1 + uses: secondlife/viewer-build-util/which-branch@relnotes with: token: ${{ github.token }} @@ -377,6 +378,7 @@ jobs: ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} ${{ needs.build.outputs.viewer_branch }} + ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true append_body: true -- cgit v1.2.3 From 603d3a865a0f619488555dd2d205e0eff4280cc5 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 11:23:47 -0500 Subject: Try to generate release notes for this specific branch. Also try to cross-reference release page and build page. (cherry picked from commit a908b4cfa98716d4a838fc1e5a6789faa15d16cf) --- .github/workflows/build.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4d3dd31801..6713e429cc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -367,25 +367,30 @@ jobs: mv newview/viewer_version.txt macOS-viewer_version.txt # forked from softprops/action-gh-release - - uses: secondlife-3p/action-gh-release@v1 + - name: Create GitHub release + id: release + uses: secondlife-3p/action-gh-release@v1 with: - # name the release page for the build number so we can find it - # easily (analogous to looking up a codeticket build page) - name: "v${{ github.run_id }}" + # name the release page for the branch + name: "${{ needs.build.outputs.viewer_branch }}" # SL-20546: want the channel and version to be visible on the # release page body: | + Build ${{ github.repositoryUrl }}/actions/runs/${{ github.run_id }} ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} - ${{ needs.build.outputs.viewer_branch }} ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true + target_commitish: ${{ github.ref }} append_body: true - # the only reason we generate a GH release is to post build products fail_on_unmatched_files: true files: | *.dmg *.exe *-autobuild-package.xml *-viewer_version.txt + + - name: post release URL + run: | + echo "::notice::Release ${{ steps.release.outputs.url }}" -- cgit v1.2.3 From d7e6a7dbd057e03984583f4524953f8ae5250f17 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 12:20:31 -0500 Subject: Try basing the GH release on github.ref_name instead of github.ref. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using github.ref as action-gh-release's target_commitish produces: ⚠️ GitHub release failed with status: 422 [{"resource":"Release","code":"invalid","field":"target_commitish"}] (cherry picked from commit c6a6db8488a8b3e7ea6534fbf5e2fe2b17864421) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6713e429cc..b156133799 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -382,7 +382,7 @@ jobs: ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true - target_commitish: ${{ github.ref }} + target_commitish: ${{ github.ref_name }} append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 7c52db381c61f10aa5e4e9c5414c54c0e49d5815 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 13:26:29 -0500 Subject: Try basing release notes on github.sha rather than github.ref_name. (cherry picked from commit 4edd78f2e54b3cd2e0b0a4b9300dfc669231dd98) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b156133799..1816e8b48f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -382,7 +382,7 @@ jobs: ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true - target_commitish: ${{ github.ref_name }} + target_commitish: ${{ github.sha }} append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 7ad13c851198d3ea2692c0c16f2eb844ebca8bf5 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 15:51:31 -0500 Subject: Leverage action-gh-release's new previous_tag input. This should (!) allow us to generate full release notes relative to the previous viewer release, instead of letting action-gh-release guess incorrectly. Also try again to add to the release page a back-link to the specific build. (cherry picked from commit 88ebb92f05dade00cc8fc519cc062a458ecd48f2) --- .github/workflows/build.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1816e8b48f..f76d4286e2 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -369,20 +369,21 @@ jobs: # forked from softprops/action-gh-release - name: Create GitHub release id: release - uses: secondlife-3p/action-gh-release@v1 + uses: secondlife-3p/action-gh-release@feat/add-generateReleaseNotes with: # name the release page for the branch name: "${{ needs.build.outputs.viewer_branch }}" # SL-20546: want the channel and version to be visible on the # release page body: | - Build ${{ github.repositoryUrl }}/actions/runs/${{ github.run_id }} + Build ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true target_commitish: ${{ github.sha }} + previous_tag: 7.1.2-release append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 3ee3e011ffe2b0d0810f61b5d35afb24ee4095a0 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 17:05:56 -0500 Subject: Base generated release notes on new floating tag 'release' instead of on the current tag 7.1.2-release. (cherry picked from commit 27b298d8bc720ff315c8e74cc5bff9ff9ead0552) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f76d4286e2..b3dafd43c9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -383,7 +383,7 @@ jobs: prerelease: true generate_release_notes: true target_commitish: ${{ github.sha }} - previous_tag: 7.1.2-release + previous_tag: release append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 00d7fef75ed860596ab87904209a827fd9de867e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 28 Feb 2024 08:45:12 -0500 Subject: Reference updated action-gh-release@v1 instead of the branch that got pulled. (cherry picked from commit b42e01d7acf5d4c55612c3a7df0e1ff6ee5ed951) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b3dafd43c9..8b08bb3960 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -369,7 +369,7 @@ jobs: # forked from softprops/action-gh-release - name: Create GitHub release id: release - uses: secondlife-3p/action-gh-release@feat/add-generateReleaseNotes + uses: secondlife-3p/action-gh-release@v1 with: # name the release page for the branch name: "${{ needs.build.outputs.viewer_branch }}" -- cgit v1.2.3 From 9b8800f216fb0a6efa80b76ca15d0491bd9948ee Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 1 Mar 2024 16:43:15 -0500 Subject: Now that viewer-build-util@relnotes has merged to v1, use @v1. --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8b08bb3960..df49f5fa42 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -103,7 +103,7 @@ jobs: - name: Determine source branch id: which-branch - uses: secondlife/viewer-build-util/which-branch@relnotes + uses: secondlife/viewer-build-util/which-branch@v1 with: token: ${{ github.token }} -- cgit v1.2.3 From 94c5baeb6146598a9a280e27e584c241b7b3b9e0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 1 Mar 2024 17:26:24 -0800 Subject: secondlife/viewer#712: Use checkbox to make it more obvious that only one set of terrain assets is preserved. Clean up enums. --- indra/newview/llfloaterregioninfo.cpp | 56 ++++++++++------------ .../skins/default/xui/en/panel_region_terrain.xml | 45 ++++++++--------- 2 files changed, 46 insertions(+), 55 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index a865ad19d3..6e8e37621e 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -602,24 +602,14 @@ LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment() return panel; } -enum class TerrainMaterialType +LLTerrainMaterials::Type material_type_from_ctrl(LLCheckBoxCtrl* ctrl) { - TEXTURE, - PBR_MATERIAL, - COUNT -}; + return ctrl->get() ? LLTerrainMaterials::Type::PBR : LLTerrainMaterials::Type::TEXTURE; +} -TerrainMaterialType material_type_from_index(S32 index) +void material_type_to_ctrl(LLCheckBoxCtrl* ctrl, LLTerrainMaterials::Type new_type) { - if (index == 0) - { - return TerrainMaterialType::TEXTURE; - } - if (index == 1) - { - return TerrainMaterialType::PBR_MATERIAL; - } - return TerrainMaterialType::COUNT; + ctrl->set(new_type == LLTerrainMaterials::Type::PBR); } // static @@ -1324,11 +1314,11 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { - LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); if (material_type_ctrl) { - const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); - const bool is_material_selected = material_type == TerrainMaterialType::PBR_MATERIAL; + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(material_type_ctrl); + const bool is_material_selected = material_type == LLTerrainMaterials::Type::PBR; if (is_material_selected) { return TRUE; } } @@ -1466,11 +1456,11 @@ void LLPanelRegionTerrainInfo::onSelectMaterialType() void LLPanelRegionTerrainInfo::updateForMaterialType() { - LLComboBox* material_type_ctrl = getChild("terrain_material_type"); + LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); if (!material_type_ctrl) { return; } - const TerrainMaterialType material_type = material_type_from_index(material_type_ctrl->getCurrentIndex()); - const bool show_texture_controls = material_type == TerrainMaterialType::TEXTURE; - const bool show_material_controls = material_type == TerrainMaterialType::PBR_MATERIAL; + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(material_type_ctrl); + const bool show_texture_controls = material_type == LLTerrainMaterials::Type::TEXTURE; + const bool show_material_controls = material_type == LLTerrainMaterials::Type::PBR; // Toggle visibility of correct swatches std::string buffer; @@ -1493,6 +1483,12 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() texture_ctrl->setVisible(show_material_controls); } } + + // Toggle visibility of labels + LLUICtrl* texture_label = getChild("detail_texture_text"); + if (texture_label) { texture_label->setVisible(show_texture_controls); } + LLUICtrl* material_label = getChild("detail_material_text"); + if (material_label) { material_label->setVisible(show_material_controls); } } void LLPanelRegionTerrainInfo::onRegionChanged() @@ -1538,9 +1534,6 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) const bool textures_ready = compp->texturesReady(false, false); const bool materials_ready = feature_pbr_terrain_enabled && compp->materialsReady(false, false); - LLTextBox* texture_text = getChild("detail_texture_text"); - if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); } - bool set_texture_swatches; bool set_material_swatches; bool reset_texture_swatches; @@ -1565,9 +1558,10 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) reset_material_swatches = !set_material_swatches; } - LLComboBox* material_type_ctrl = getChild("terrain_material_type"); - if (material_type_ctrl) { material_type_ctrl->setCurrentByIndex(S32(material_type)); } + LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); + if (material_type_ctrl) { material_type_to_ctrl(material_type_ctrl, material_type); } updateForMaterialType(); + material_type_ctrl->setVisible(feature_pbr_terrain_enabled); LLTextureCtrl* asset_ctrl; std::string buffer; @@ -1698,11 +1692,11 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() // Send either material IDs instead of texture IDs depending on // terrain_material_type - they both occupy the same slot. - LLComboBox* material_type_ctrl = getChild("terrain_material_type"); - const TerrainMaterialType material_type = material_type_ctrl ? material_type_from_index(material_type_ctrl->getCurrentIndex()) : TerrainMaterialType::TEXTURE; + LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); + const LLTerrainMaterials::Type material_type = material_type_ctrl ? material_type_from_ctrl(material_type_ctrl) : LLTerrainMaterials::Type::TEXTURE; for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - if (material_type == TerrainMaterialType::PBR_MATERIAL) + if (material_type == LLTerrainMaterials::Type::PBR) { buffer = llformat("material_detail_%d", i); } @@ -1720,7 +1714,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() strings.push_back(buffer); // Store asset for later terrain editing - if (material_type == TerrainMaterialType::PBR_MATERIAL) + if (material_type == LLTerrainMaterials::Type::PBR) { mLastSetMaterials[i] = tmp_id; } diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 88855ab739..f8d2c90d0a 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -76,33 +76,17 @@ left="8" top="30" width="460" /> - - - - Terrain Textures @@ -114,12 +98,25 @@ follows="left|top" height="20" layout="topleft" - top_delta="0" - left_delta="180" - name="detail_texture_limits_text" - width="200"> - Maximum size: 1024x1024 + name="detail_material_text" + left="10" + top="105" + width="170"> + Terrain Materials + Date: Wed, 3 Jan 2024 22:57:28 +0200 Subject: SL-17896 Don't crash silently if files are missing or out of memory Under debug LL_ERRS will show a message as well, but release won't show anything and will quit silently so show a notification when applicable. --- indra/llcommon/llcoros.cpp | 1 + indra/llcommon/llerror.cpp | 42 ++++++++++++++++++++++ indra/llcommon/llerror.h | 23 ++++++++++++ indra/llcommon/llexception.cpp | 1 + indra/llcorehttp/_httpservice.cpp | 1 + indra/llimage/llimagebmp.cpp | 1 + indra/llimage/llimagedxt.cpp | 1 + indra/llimage/llimagetga.cpp | 1 + indra/llrender/llimagegl.cpp | 3 ++ indra/llui/llnotifications.cpp | 3 ++ indra/llui/lltexteditor.cpp | 1 + indra/llui/lltransutil.cpp | 8 ++++- indra/newview/llappcorehttp.cpp | 1 + indra/newview/llappviewer.cpp | 29 ++++++++++++--- indra/newview/llappviewer.h | 1 + indra/newview/llavatarrenderinfoaccountant.cpp | 2 ++ indra/newview/llmeshrepository.cpp | 8 ++--- indra/newview/llviewermenu.cpp | 16 +++++++++ indra/newview/skins/default/xui/en/menu_viewer.xml | 6 ++++ indra/newview/skins/default/xui/en/strings.xml | 13 ++++++- 20 files changed, 152 insertions(+), 10 deletions(-) diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 3ab97b557f..1d383f174d 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -278,6 +278,7 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl catch (std::bad_alloc&) { // Out of memory on stack allocation? + LLError::LLUserWarningMsg::showOutOfMemory(); printActiveCoroutines(); LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL; } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 414515854a..3de641fcba 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1601,6 +1601,48 @@ namespace LLError { return out << boost::stacktrace::stacktrace(); } + + // LLOutOfMemoryWarning + std::string LLUserWarningMsg::sLocalizedOutOfMemoryTitle; + std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning; + LLUserWarningMsg::Handler LLUserWarningMsg::sHandler; + + void LLUserWarningMsg::show(const std::string& message) + { + if (sHandler) + { + sHandler(std::string(), message); + } + } + + void LLUserWarningMsg::showOutOfMemory() + { + if (sHandler && !sLocalizedOutOfMemoryTitle.empty()) + { + sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning); + } + } + + void LLUserWarningMsg::showMissingFiles() + { + // Files Are missing, likely can't localize. + const std::string error_string = + "Second Life viewer couldn't access some of the files it needs and will be closed." + "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and " + "contact https://support.secondlife.com if issue persists after reinstall."; + sHandler("Missing Files", error_string); + } + + void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler) + { + sHandler = handler; + } + + void LLUserWarningMsg::setOutOfMemoryStrings(const std::string& title, const std::string& message) + { + sLocalizedOutOfMemoryTitle = title; + sLocalizedOutOfMemoryWarning = message; + } } void crashdriver(void (*callback)(int*)) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 05dd88ee51..6f6b349cf5 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -39,6 +39,7 @@ #include "llpreprocessor.h" #include +#include // std::function const int LL_ERR_NOERR = 0; @@ -301,6 +302,28 @@ namespace LLError { friend std::ostream& operator<<(std::ostream& out, const LLStacktrace&); }; + + // Provides access to OS notification popup on error, since + // not everything has access to OS's messages + class LLUserWarningMsg + { + public: + typedef std::function Handler; + static void setHandler(const Handler&); + static void setOutOfMemoryStrings(const std::string& title, const std::string& message); + + // When viewer encounters bad alloc or can't access files try warning user about reasons + static void showOutOfMemory(); + static void showMissingFiles(); + // Genering error + static void show(const std::string&); + + private: + // needs to be preallocated before viewer runs out of memory + static std::string sLocalizedOutOfMemoryTitle; + static std::string sLocalizedOutOfMemoryWarning; + static Handler sHandler; + }; } //this is cheaper than llcallstacks if no need to output other variables to call stacks. diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 46560b5e4c..0787bde57f 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -37,6 +37,7 @@ #include "llerror.h" #include "llerrorcontrol.h" + // used to attach and extract stacktrace information to/from boost::exception, // see https://www.boost.org/doc/libs/release/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.exceptions_with_stacktrace // apparently the struct passed as the first template param needs no definition? diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 294acd7f63..517076804d 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -320,6 +320,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread) LLMemory::logMemoryInfo(TRUE); //output possible call stacks to log file. + LLError::LLUserWarningMsg::showOutOfMemory(); LLError::LLCallStacks::print(); LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL; diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index 90b7272efa..cdea0da68d 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -321,6 +321,7 @@ bool LLImageBMP::updateData() mColorPalette = new(std::nothrow) U8[color_palette_size]; if (!mColorPalette) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL; return false; } diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 36317a5ba8..ae76c5243f 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -437,6 +437,7 @@ bool LLImageDXT::convertToDXR() U8* newdata = (U8*)ll_aligned_malloc_16(total_bytes); if (!newdata) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Out of memory in LLImageDXT::convertToDXR()" << LL_ENDL; return false; } diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index 88bdae9b80..152a7f309c 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -266,6 +266,7 @@ bool LLImageTGA::updateData() mColorMap = new(std::nothrow) U8[ color_map_bytes ]; if (!mColorMap) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Out of Memory in bool LLImageTGA::updateData()" << LL_ENDL; return false; } diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c6fd824c4e..56a12b07b1 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1353,6 +1353,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt scratch = new(std::nothrow) U32[width * height]; if (!scratch) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } @@ -1378,6 +1379,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt scratch = new(std::nothrow) U32[width * height]; if (!scratch) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } @@ -1406,6 +1408,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt scratch = new(std::nothrow) U32[width * height]; if (!scratch) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index d736aa6634..2fe9ee18e3 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1553,6 +1553,7 @@ bool LLNotifications::loadTemplates() if (!success || root.isNull() || !root->hasName( "notifications" )) { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL; return false; } @@ -1563,6 +1564,7 @@ bool LLNotifications::loadTemplates() if(!params.validateBlock()) { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL; return false; } @@ -1629,6 +1631,7 @@ bool LLNotifications::loadVisibilityRules() if(!params.validateBlock()) { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL; return false; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 092739a538..a247e8700a 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2694,6 +2694,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length ) char* text = new char[ text_len + 1]; if (text == NULL) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Memory allocation failure." << LL_ENDL; return FALSE; } diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 5da722a72b..6c486f29ba 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -44,8 +44,13 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::setdumpCurrentDirectories(LLError::LEVEL_WARN); - LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; + LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL; return false; } @@ -60,6 +65,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename) if (!success) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Couldn't load localization table " << xml_filename << LL_ENDL; return false; } diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index debf93dccd..51e259992d 100644 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -168,6 +168,7 @@ void LLAppCoreHttp::init() } else { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS("Init") << "Missing CA File; should be at " << ca_file << LL_ENDL; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e6a47f1c64..a1fecdb981 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -362,7 +362,6 @@ BOOL gRandomizeFramerate = FALSE; BOOL gPeriodicSlowFrame = FALSE; BOOL gCrashOnStartup = FALSE; -BOOL gLLErrorActivated = FALSE; BOOL gLogoutInProgress = FALSE; BOOL gSimulateMemLeak = FALSE; @@ -2253,9 +2252,6 @@ void errorCallback(LLError::ELevel level, const std::string &error_string) OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); #endif - //Set the ErrorActivated global so we know to create a marker file - gLLErrorActivated = true; - gDebugInfo["FatalMessage"] = error_string; // We're not already crashing -- we simply *intend* to crash. Since we // haven't actually trashed anything yet, we can afford to write the whole @@ -2264,6 +2260,14 @@ void errorCallback(LLError::ELevel level, const std::string &error_string) } } +void errorMSG(const std::string& title_string, const std::string& message_string) +{ + if (!message_string.empty()) + { + OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK); + } +} + void LLAppViewer::initLoggingAndGetLastDuration() { // @@ -2275,6 +2279,8 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::addGenericRecorder(&errorCallback); //LLError::setTimeFunction(getRuntime); + LLError::LLUserWarningMsg::setHandler(errorMSG); + if (mSecondInstance) { @@ -2412,6 +2418,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, { // failed to load if(file.required) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL; return false; } @@ -2510,6 +2517,7 @@ bool LLAppViewer::initConfiguration() if (!success) { LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + LLError::LLUserWarningMsg::showMissingFiles(); if (gDirUtilp->fileExists(settings_file_list)) { LL_ERRS() << "Cannot load default configuration file settings_files.xml. " @@ -2533,6 +2541,7 @@ bool LLAppViewer::initConfiguration() if (!mSettingsLocationList->validateBlock()) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL; } @@ -2967,6 +2976,8 @@ bool LLAppViewer::initConfiguration() LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key)); } + LLError::LLUserWarningMsg::setOutOfMemoryStrings(LLTrans::getString("MBOutOfMemoryTitle"), LLTrans::getString("MBOutOfMemoryErr")); + return true; // Config was successful. } @@ -3004,6 +3015,7 @@ void LLAppViewer::initStrings() // initial check to make sure files are there failed gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN); + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Viewer failed to find localization and UI files." << " Please reinstall viewer from https://secondlife.com/support/downloads" << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; @@ -4309,6 +4321,7 @@ void LLAppViewer::loadKeyBindings() key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml"); if (!gViewerInput.loadBindingsXML(key_bindings_file)) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; } } @@ -5399,6 +5412,14 @@ void LLAppViewer::forceErrorLLError() LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; } +void LLAppViewer::forceErrorLLErrorMsg() +{ + LLError::LLUserWarningMsg::show("Deliberate error"); + // Note: under debug this will show a message as well, + // but release won't show anything and will quit silently + LL_ERRS() << "This is a deliberate llerror with a message" << LL_ENDL; +} + void LLAppViewer::forceErrorBreakpoint() { LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 6d1496d517..77a1cdb485 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -152,6 +152,7 @@ public: // LLAppViewer testing helpers. // *NOTE: These will potentially crash the viewer. Only for debugging. virtual void forceErrorLLError(); + virtual void forceErrorLLErrorMsg(); virtual void forceErrorBreakpoint(); virtual void forceErrorBadMemoryAccess(); virtual void forceErrorInfiniteLoop(); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index a6c9a41fa4..b95b971890 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -339,6 +339,7 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio } catch (std::bad_alloc&) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; } } @@ -370,6 +371,7 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi } catch (std::bad_alloc&) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; } } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 01d6469010..6dc4f25d02 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1360,7 +1360,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; return false; } LLMeshRepository::sCacheBytesRead += size; @@ -1473,7 +1473,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; return false; } LLMeshRepository::sCacheBytesRead += size; @@ -1575,7 +1575,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; return false; } file.read(buffer, size); @@ -1770,7 +1770,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; // todo: for now it will result in indefinite constant retries, should result in timeout // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) return false; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2cf341f87f..289ad2a948 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -289,6 +289,7 @@ void handle_disconnect_viewer(void *); void force_error_breakpoint(void *); void force_error_llerror(void *); +void force_error_llerror_msg(void*); void force_error_bad_memory_access(void *); void force_error_infinite_loop(void *); void force_error_software_exception(void *); @@ -2400,6 +2401,15 @@ class LLAdvancedForceErrorLlerror : public view_listener_t } }; +class LLAdvancedForceErrorLlerrorMsg: public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_error_llerror_msg(NULL); + return true; + } +}; + class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -8379,6 +8389,11 @@ void force_error_llerror(void *) LLAppViewer::instance()->forceErrorLLError(); } +void force_error_llerror_msg(void*) +{ + LLAppViewer::instance()->forceErrorLLErrorMsg(); +} + void force_error_bad_memory_access(void *) { LLAppViewer::instance()->forceErrorBadMemoryAccess(); @@ -9604,6 +9619,7 @@ void initialize_menus() // Advanced > Debugging view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint"); view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror"); + view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg"); view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop"); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 38763cd9a8..7b3b4ed395 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2716,6 +2716,12 @@ function="World.EnvPreset" + + + diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f3b26820d2..7360c06f86 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3019,8 +3019,19 @@ Running in window. If you continue to receive this message, contact the [SUPPORT_SITE]. + Out Of Memory + + [APP_NAME]'s request for memory failed. Application can't proceed and will be closed. - +If your computer's RAM is low, quit any heavy applications before runing Second Life, allocate a page file or reduce graphical settings like draw distance. + + + [APP_NAME] couldn't access or find some of the files it needs and will be closed. + +Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall. + + + 5 O'Clock Shadow All White -- cgit v1.2.3 From 0cf4141d7dddfcaf5399bc99306a7426b561953c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 4 Mar 2024 14:44:41 -0800 Subject: secondlife/viewer#712: Add/update test plans for PBR terrain composition --- doc/testplans/pbr_terrain_composition.md | 59 +++++++++++++++++++++++++++++ doc/testplans/pbr_terrain_feature_gating.md | 4 ++ 2 files changed, 63 insertions(+) create mode 100644 doc/testplans/pbr_terrain_composition.md diff --git a/doc/testplans/pbr_terrain_composition.md b/doc/testplans/pbr_terrain_composition.md new file mode 100644 index 0000000000..127fe950a8 --- /dev/null +++ b/doc/testplans/pbr_terrain_composition.md @@ -0,0 +1,59 @@ +# PBR Terrain Composition + +## Feature Availability + +PBR Terrain is visible for all viewers with the PBR Terrain feature, regardless of if the feature flag is enabled. + +There is only one set of four asset IDs applied to the terrain. In other words, unlike PBR materials on prims, there is no fallback texture set for viewers that do not support PBR terrain. Viewers without support will view terrain as blank (solid grey or white). + +## Editing Terrain Composition + +All tests in this section assume the PBR terrain feature flag is enabled, and that the user has appropriate permissions to modify the terrain textures. + +### Feature Availability + +When the PBR terrain feature flag is disabled: + +- The "PBR Metallic Roughness" checkbox should not be visible +- The user should not be able to apply PBR terrain to the region, only textures. + +When the PBR terrain feature flag is enabled: + +- The "PBR Metallic Roughness" checkbox should be visible +- The user should be able to apply PBR terrain or textures to the region, depending on if the "PBR Metallic Roughness" checkbox is checked. + +### Current Composition Type + +When the Region/Estate floater is opened to the terrain Tab, the current terrain should be shown in the four swatches, and the "PBR Metallic Roughness" checkbox should be checked or unchecked accordingly. + +- If it is texture terrain, the "PBR Metallic Roughness" checkbox should be unchecked, and the floater should display the four textures applied to the terrain. +- If it is material terrain, the "PBR Metallic Roughness" checkbox should be checked, and the floater should display the four materials applied to the terrain. + +### Toggling Composition Type + +When toggling the "PBR Metallic Roughness" checkbox to the opposite value, which does not correspond to the current terrain type, one of the following sets of four terrain swatches will be displayed: + +- The default textures/materials + - For textures, this is the default terrain texture set + - For materials, this is blank/null, but this is subject to change +- The previously applied texture/material set + - History is available on a best-effort basis only. In particular, the history does not persist on viewer restart. + +When toggling back the "PBR Metallic Roughness" checkbox to the original value, assuming nothing else has changed, then the current terrain should be shown in the four swatches again. + +### Saving Composition + +A user with appropriate permissions can change and save the textures or materials to the terrain. If the "PBR Metallic Roughness" checkbox is checked, the user applies materials, otherwise the user applies textures. + +Saving may fail for the following reasons: + +- A terrain or material texture is invalid or null +- A terrain texture is greater than 1024 resolution (Subject to change. See https://github.com/secondlife/viewer/issues/760) + +Unlike a viewer without PBR terrain support, the new viewer will no longer treat textures with alpha channels as invalid. + +## Graphics Features + +Texture terrain with transparency will render as opaque. Parts of the texture that would be partially transparent will instead display as a mix of the color and black, depending on how transparent the texture is. + +See [PBR Terrain Feature Gating](./pbr_terrain_feature_gating.md) for supported PBR terrain features. diff --git a/doc/testplans/pbr_terrain_feature_gating.md b/doc/testplans/pbr_terrain_feature_gating.md index 13108c1534..2d27a5d73e 100644 --- a/doc/testplans/pbr_terrain_feature_gating.md +++ b/doc/testplans/pbr_terrain_feature_gating.md @@ -20,3 +20,7 @@ Availability of PBR textures varies by machine and graphics setting: - Low: Base color only (looks similar to texture terrain) - Medium-Low, and machines that do not support greater than 16 textures such as Macs: All PBR textures enabled except emissive textures. - Medium: All PBR textures enabled + +## PBR Alpha + +PBR terrain does not support materials with alpha blend or double-sided. In addition, the viewer does not make any guarantees about what will render behind the terrain if alpha is used. -- cgit v1.2.3 From 6c43baf0298929ee315bdb3d95f0bd23f589a4cf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 24 Jan 2024 23:56:22 +0200 Subject: Issue #54 LLRender::init crash --- indra/llrender/llrender.cpp | 10 +++++++++- indra/llrender/llrender.h | 2 +- indra/newview/llviewerwindow.cpp | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index ee66122774..4d64dc9e10 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -857,7 +857,7 @@ LLRender::~LLRender() shutdown(); } -void LLRender::init(bool needs_vertex_buffer) +bool LLRender::init(bool needs_vertex_buffer) { #if LL_WINDOWS if (gGLManager.mHasDebugOutput && gDebugGL) @@ -879,6 +879,13 @@ void LLRender::init(bool needs_vertex_buffer) // necessary for reflection maps glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); +#if LL_WINDOWS + if (glGenVertexArrays == nullptr) + { + return false; + } +#endif + { //bind a dummy vertex array object so we're core profile compliant U32 ret; glGenVertexArrays(1, &ret); @@ -889,6 +896,7 @@ void LLRender::init(bool needs_vertex_buffer) { initVertexBuffer(); } + return true; } void LLRender::initVertexBuffer() diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index fd922affba..716b52354d 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -375,7 +375,7 @@ public: LLRender(); ~LLRender(); - void init(bool needs_vertex_buffer); + bool init(bool needs_vertex_buffer); void initVertexBuffer(); void resetVertexBuffer(); void shutdown(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 47c7eed872..37e64dfc17 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1957,7 +1957,11 @@ LLViewerWindow::LLViewerWindow(const Params& p) // Initialize OpenGL Renderer LLVertexBuffer::initClass(mWindow); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; - gGL.init(true); + if (!gGL.init(true)) + { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBVideoDrvErr")); + LL_ERRS() << "gGL not initialized" << LL_ENDL; + } if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) -- cgit v1.2.3 From 55fdd540d2ef2a1616d928aac1d945008043c74e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 6 Mar 2024 13:04:40 -0800 Subject: secondlife/viewer#712: Clean up unused region change callback checks --- indra/newview/llfloaterregioninfo.cpp | 26 -------------------------- indra/newview/llfloaterregioninfo.h | 3 --- 2 files changed, 29 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 6e8e37621e..3256527ee5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1440,11 +1440,6 @@ BOOL LLPanelRegionTerrainInfo::postBuild() mAskedTextureHeights = false; mConfirmedTextureHeights = false; - if (!mRegionChangedSlot.connected()) - { - mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLPanelRegionTerrainInfo::onRegionChanged,this)); - } - return LLPanelRegionInfo::postBuild(); } @@ -1491,27 +1486,6 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() if (material_label) { material_label->setVisible(show_material_controls); } } -void LLPanelRegionTerrainInfo::onRegionChanged() -{ - LLViewerRegion *region = gAgent.getRegion(); - if (!region) { return; } - - if (region->simulatorFeaturesReceived()) - { - onSimulatorFeaturesReceived(region->getRegionID(), region); - } - else - { - // See "RenderTerrainPBREnabled" in LLViewerRegion::setSimulatorFeatures - region->setSimulatorFeaturesReceivedCallback(boost::bind(&LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived,this,_1, _2)); - } -} - -void LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp) -{ - refresh(); -} - // virtual bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 315c6aca0f..93a4d3a795 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -249,8 +249,6 @@ public: BOOL postBuild() override; - void onRegionChanged(); - void onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp); bool refreshFromRegion(LLViewerRegion* region) override; // refresh local settings from region update from simulator void setEnvControls(bool available); // Whether environment settings are available for this region @@ -274,7 +272,6 @@ protected: private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; - boost::signals2::connection mRegionChangedSlot; LLUUID mLastSetTextures[LLTerrainMaterials::ASSET_COUNT]; LLUUID mLastSetMaterials[LLTerrainMaterials::ASSET_COUNT]; }; -- cgit v1.2.3 From 1fc45a50ff15e6f31a4554da83256b7f59b1af15 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 6 Mar 2024 17:56:16 -0800 Subject: #681 Add probe blending for mirrors. --- .../shaders/class1/deferred/pbrterrainF.glsl | 4 ++ .../shaders/class1/deferred/pbrterrainV.glsl | 3 ++ .../shaders/class3/deferred/reflectionProbeF.glsl | 43 +++++++-------- indra/newview/llheroprobemanager.cpp | 62 +++++----------------- indra/newview/llheroprobemanager.h | 18 +++++-- indra/newview/llreflectionmapmanager.cpp | 18 +++++++ 6 files changed, 69 insertions(+), 79 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index c83a6be85d..57c0a6024f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -133,6 +133,7 @@ uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlpha #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 in vec4[2] vary_coords; #endif +in vec3 vary_position; in vec3 vary_normal; in vec3 vary_tangent; flat in float vary_sign; @@ -140,11 +141,14 @@ in vec4 vary_texcoord0; in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); +void mirrorClip(vec3 position); float terrain_mix(TerrainMix tm, vec4 tms4); void main() { + // Make sure we clip the terrain if we're in a mirror. + mirrorClip(vary_position); #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 TerrainCoord terrain_texcoord = vary_coords; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index dbb9404219..489fc26e3f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -25,6 +25,7 @@ uniform mat3 normal_matrix; uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix; uniform mat4 modelview_projection_matrix; in vec3 position; @@ -42,6 +43,7 @@ out vec3 vary_tangent; flat out float vary_sign; out vec4 vary_texcoord0; out vec4 vary_texcoord1; +out vec3 vary_position; // *HACK: tangent_space_transform should use texture_normal_transform, or maybe // we shouldn't use tangent_space_transform at all. See the call to @@ -55,6 +57,7 @@ void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; vec3 n = normal_matrix * normal; vary_vertex_normal = normal; diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 257299258e..4f2475b101 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -48,6 +48,7 @@ layout (std140) uniform ReflectionProbes /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation // box[3][0..2] - plane thickness mat4 refBox[MAX_REFMAP_COUNT]; + mat4 heroBox; // list of bounding spheres for reflection probes sorted by distance to camera (closest first) vec4 refSphere[MAX_REFMAP_COUNT]; // extra parameters @@ -56,6 +57,7 @@ layout (std140) uniform ReflectionProbes // z - fade in // w - znear vec4 refParams[MAX_REFMAP_COUNT]; + vec4 heroSphere; // index of cube map in reflectionProbes for a corresponding reflection probe // e.g. cube map channel of refSphere[2] is stored in refIndex[2] // refIndex.x - cubemap channel in reflectionProbes @@ -71,6 +73,10 @@ layout (std140) uniform ReflectionProbes // number of reflection probes present in refSphere int refmapCount; + + int heroShape; + int heroMipCount; + int heroProbeCount; }; // Inputs @@ -682,48 +688,37 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit) return col[1]+col[0]; } - #if defined(HERO_PROBES) uniform vec4 clipPlane; - uniform samplerCubeArray heroProbes; -layout (std140) uniform HeroProbeData -{ - mat4 heroBox[1]; - vec4 heroSphere[1]; - uint heroShape[1]; - int heroMipCount; - int heroProbeCount; -}; - void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) { float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; float w = 0; float dw = 0; - if (heroShape[0] < 1) + float falloffMult = 10; + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + if (heroShape < 1) { float d = 0; - boxIntersect(pos, norm, heroBox[0], d, 1.0); + boxIntersect(pos, norm, heroBox, d, 1.0); - w = max(d, 0.001); + w = max(d, 0); } else { - float r = heroSphere[0].w; + float r = heroSphere.w; - w = sphereWeight(pos, norm, heroSphere[0].xyz, r, vec4(1), dw); - } - - { - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - if (dot(refnormpersp.xyz, clipPlane.xyz) > 0.0) - { - glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w); - } + w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw); } + + clipDist = clipDist * 0.95 + 0.05; + clipDist = clamp(clipDist * falloffMult, 0, 1); + w = clamp(w * falloffMult * clipDist, 0, 1); + + glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w); } #else diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ee993c6ba1..8f1c1848cc 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -151,6 +151,7 @@ void LLHeroProbeManager::update() // Collect the list of faces that need updating based upon the camera's rotation. LLVector3 cam_direction = LLVector3(0, 0, 1) * LLViewerCamera::instance().getQuaternion(); + cam_direction.normalize(); static LLVector3 cubeFaces[6] = { LLVector3(1, 0, 0), @@ -163,7 +164,7 @@ void LLHeroProbeManager::update() for (int i = 0; i < 6; i++) { - float shouldUpdate = cam_direction * cubeFaces[i] * 0.5 + 0.5; + float shouldUpdate = fminf(1, (fmaxf(-1, cam_direction * cubeFaces[i]) * 0.5 + 0.5)); int updateRate = ceilf((1 - shouldUpdate) * gPipeline.RenderHeroProbeConservativeUpdateMultiplier); @@ -215,6 +216,9 @@ void LLHeroProbeManager::update() mRenderingMirror = false; gPipeline.mReflectionMapManager.mRadiancePass = radiance_pass; + + mProbes[0]->mViewerObject = mNearestHero; + mProbes[0]->autoAdjustOrigin(); } mCurrentProbeUpdateFrame++; @@ -424,26 +428,14 @@ void LLHeroProbeManager::updateUniforms() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - struct HeroProbeData - { - LLMatrix4 heroBox[1]; - LLVector4 heroSphere[1]; - GLint heroShape[1]; - GLint heroMipCount; - GLint heroProbeCount; - }; - - HeroProbeData hpd; - LLMatrix4a modelview; modelview.loadu(gGLModelView); LLVector4a oa; // scratch space for transformed origin oa.set(0, 0, 0, 0); - hpd.heroProbeCount = 1; + mHeroData.heroProbeCount = 1; if (mNearestHero != nullptr) { - mProbes[0]->mViewerObject = mNearestHero; if (mNearestHero->getReflectionProbeIsBox()) { LLVector3 s = mNearestHero->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); @@ -455,44 +447,17 @@ void LLHeroProbeManager::updateUniforms() } modelview.affineTransform(mProbes[0]->mOrigin, oa); - hpd.heroShape[0] = 0; - if (!mProbes[0]->getBox(hpd.heroBox[0])) + mHeroData.heroShape = 0; + if (!mProbes[0]->getBox(mHeroData.heroBox)) { - hpd.heroShape[0] = 1; + mHeroData.heroShape = 1; } - hpd.heroSphere[0].set(oa.getF32ptr()); - hpd.heroSphere[0].mV[3] = mProbes[0]->mRadius; + mHeroData.heroSphere.set(oa.getF32ptr()); + mHeroData.heroSphere.mV[3] = mProbes[0]->mRadius; } - hpd.heroMipCount = mMipChain.size(); - - //copy rpd into uniform buffer object - if (mUBO == 0) - { - glGenBuffers(1, &mUBO); - } - - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); - glBindBuffer(GL_UNIFORM_BUFFER, mUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(HeroProbeData), &hpd, GL_STREAM_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - } -} - -void LLHeroProbeManager::setUniforms() -{ - if (!LLPipeline::sReflectionProbesEnabled) - { - return; - } - - if (mUBO == 0) - { - updateUniforms(); - } - glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO); + mHeroData.heroMipCount = mMipChain.size(); } void LLHeroProbeManager::renderDebug() @@ -581,9 +546,6 @@ void LLHeroProbeManager::cleanup() mDefaultProbe = nullptr; mUpdatingProbe = nullptr; - - glDeleteBuffers(1, &mUBO); - mUBO = 0; mHeroVOList.clear(); mNearestHero = nullptr; diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index e430cae203..04027cd57e 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -38,6 +38,15 @@ class LLViewerObject; // number of reflection probes to keep in vram #define LL_MAX_HERO_PROBE_COUNT 2 +struct HeroProbeData +{ + LLMatrix4 heroBox; + LLVector4 heroSphere; + GLint heroShape; + GLint heroMipCount; + GLint heroProbeCount; +}; + class alignas(16) LLHeroProbeManager { LL_ALIGN_NEW @@ -74,16 +83,17 @@ public: bool isMirrorPass() const { return mRenderingMirror; } LLVector3 mMirrorPosition; - LLVector3 mMirrorNormal; + LLVector3 mMirrorNormal; + HeroProbeData mHeroData; private: friend class LLPipeline; + friend class LLReflectionMapManager; // update UBO used for rendering (call only once per render pipe flush) void updateUniforms(); // bind UBO used for rendering - void setUniforms(); // render target for cube snapshots // used to generate mipmaps without doing a copy-to-texture @@ -109,9 +119,6 @@ private: // list of active reflection maps std::vector> mProbes; - // handle to UBO - U32 mUBO = 0; - // list of maps being used for rendering std::vector mReflectionMaps; @@ -141,5 +148,6 @@ private: std::vector mHeroVOList; LLVOVolume* mNearestHero; + }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 3144260905..ce389a5cad 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -906,6 +906,8 @@ void LLReflectionMapManager::updateUniforms() // the box probe LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; + LLMatrix4 heroBox; + // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; @@ -916,6 +918,8 @@ void LLReflectionMapManager::updateUniforms() // w - znear LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; + LLVector4 heroSphere; + // indices used by probe: // [i][0] - cubemap array index for this probe // [i][1] - index into "refNeighbor" for probes that intersect this probe @@ -929,6 +933,10 @@ void LLReflectionMapManager::updateUniforms() GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth // numbrer of active refmaps GLint refmapCount; + + GLint heroShape; + GLint heroMipCount; + GLint heroProbeCount; }; mReflectionMaps.resize(mReflectionProbeCount); @@ -1118,6 +1126,16 @@ void LLReflectionMapManager::updateUniforms() rpd.refmapCount = count; + gPipeline.mHeroProbeManager.updateUniforms(); + + // Get the hero data. + + rpd.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; + rpd.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; + rpd.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape; + rpd.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; + rpd.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; + //copy rpd into uniform buffer object if (mUBO == 0) { -- cgit v1.2.3 From 4b738a619a475447af8b917644357cb49dc22fb9 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Wed, 6 Mar 2024 18:24:36 -0800 Subject: #681 Small fix for if a viewer object may be dead. --- indra/newview/llheroprobemanager.cpp | 2 +- indra/newview/llreflectionmap.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 8f1c1848cc..10b743ceef 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -434,7 +434,7 @@ void LLHeroProbeManager::updateUniforms() oa.set(0, 0, 0, 0); mHeroData.heroProbeCount = 1; - if (mNearestHero != nullptr) + if (mNearestHero != nullptr && !mNearestHero->isDead()) { if (mNearestHero->getReflectionProbeIsBox()) { diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 6d5797395c..30a61144b9 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -166,7 +166,7 @@ void LLReflectionMap::autoAdjustOrigin() } } - else if (mViewerObject) + else if (mViewerObject && !mViewerObject->isDead()) { mPriority = 1; mOrigin.load3(mViewerObject->getPositionAgent().mV); -- cgit v1.2.3 From 327764231543df768c09a976441e35312f6f2c49 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 7 Mar 2024 02:14:08 +0200 Subject: viewer-private#41 Texture fail to apply to materials in some cases Shift-dropping textures can fail if one of 'early' faces has nomod material --- indra/newview/lltooldraganddrop.cpp | 96 ++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index bfa9386cd4..2a17882ff1 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1077,51 +1077,71 @@ void set_texture_to_material(LLViewerObject* hit_obj, LLGLTFMaterial::TextureInfo drop_channel) { LLTextureEntry* te = hit_obj->getTE(hit_face); - if (te) + if (!te) { - LLPointer material = te->getGLTFMaterialOverride(); + return; + } - // make a copy to not invalidate existing - // material for multiple objects - if (material.isNull()) - { - // Start with a material override which does not make any changes - material = new LLGLTFMaterial(); - } - else - { - material = new LLGLTFMaterial(*material); - } + const LLUUID base_mat_id = hit_obj->getRenderMaterialID(hit_face); + if (base_mat_id.isNull()) + { + return; + } - switch (drop_channel) - { - case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: - default: - { - material->setBaseColorId(asset_id); - } - break; + if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners()) + { + hit_obj->requestInventory(); + return; + } - case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: - { - material->setOcclusionRoughnessMetallicId(asset_id); - } - break; + LLViewerInventoryItem* mat_item = hit_obj->getInventoryItemByAsset(base_mat_id); + if (mat_item && !mat_item->getPermissions().allowModifyBy(gAgentID)) + { + return; + } - case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: - { - material->setEmissiveId(asset_id); - } - break; + LLPointer material = te->getGLTFMaterialOverride(); - case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: - { - material->setNormalId(asset_id); - } - break; - } - LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); + // make a copy to not invalidate existing + // material for multiple objects + if (material.isNull()) + { + // Start with a material override which does not make any changes + material = new LLGLTFMaterial(); + } + else + { + material = new LLGLTFMaterial(*material); + } + + switch (drop_channel) + { + case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: + default: + { + material->setBaseColorId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: + { + material->setOcclusionRoughnessMetallicId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: + { + material->setEmissiveId(asset_id); + } + break; + + case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: + { + material->setNormalId(asset_id); + } + break; } + LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); } void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, -- cgit v1.2.3 From 7f2e3d0f278f55d8c831273547e49077764c9f14 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 7 Mar 2024 17:32:23 -0800 Subject: secondlife/viewer#712: Consolidate accesses to terrain_material_type control --- indra/newview/llfloaterregioninfo.cpp | 48 +++++++++++++++++------------------ indra/newview/llfloaterregioninfo.h | 1 + 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 3256527ee5..c6d8317128 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1314,10 +1314,9 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { - LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); - if (material_type_ctrl) + if (mMaterialTypeCtrl) { - const LLTerrainMaterials::Type material_type = material_type_from_ctrl(material_type_ctrl); + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); const bool is_material_selected = material_type == LLTerrainMaterials::Type::PBR; if (is_material_selected) { return TRUE; } } @@ -1327,7 +1326,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { std::string buffer; buffer = llformat("texture_detail_%d", i); - LLTextureCtrl* texture_ctrl = getChild(buffer); + LLTextureCtrl* texture_ctrl = findChild(buffer); if (!texture_ctrl) continue; LLUUID image_asset_id = texture_ctrl->getImageAssetID(); @@ -1410,7 +1409,8 @@ BOOL LLPanelRegionTerrainInfo::postBuild() initCtrl("terrain_raise_spin"); initCtrl("terrain_lower_spin"); - getChild("terrain_material_type")->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); + mMaterialTypeCtrl = findChild("terrain_material_type"); + if (mMaterialTypeCtrl) { mMaterialTypeCtrl->setCommitCallback(boost::bind(&LLPanelRegionTerrainInfo::onSelectMaterialType, this)); } std::string buffer; @@ -1451,9 +1451,8 @@ void LLPanelRegionTerrainInfo::onSelectMaterialType() void LLPanelRegionTerrainInfo::updateForMaterialType() { - LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); - if (!material_type_ctrl) { return; } - const LLTerrainMaterials::Type material_type = material_type_from_ctrl(material_type_ctrl); + if (!mMaterialTypeCtrl) { return; } + const LLTerrainMaterials::Type material_type = material_type_from_ctrl(mMaterialTypeCtrl); const bool show_texture_controls = material_type == LLTerrainMaterials::Type::TEXTURE; const bool show_material_controls = material_type == LLTerrainMaterials::Type::PBR; @@ -1463,7 +1462,7 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild(buffer); + texture_ctrl = findChild(buffer); if (texture_ctrl) { texture_ctrl->setVisible(show_texture_controls); @@ -1472,7 +1471,7 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); - texture_ctrl = getChild(buffer); + texture_ctrl = findChild(buffer); if (texture_ctrl) { texture_ctrl->setVisible(show_material_controls); @@ -1480,9 +1479,9 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() } // Toggle visibility of labels - LLUICtrl* texture_label = getChild("detail_texture_text"); + LLUICtrl* texture_label = findChild("detail_texture_text"); if (texture_label) { texture_label->setVisible(show_texture_controls); } - LLUICtrl* material_label = getChild("detail_material_text"); + LLUICtrl* material_label = findChild("detail_material_text"); if (material_label) { material_label->setVisible(show_material_controls); } } @@ -1532,10 +1531,12 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) reset_material_swatches = !set_material_swatches; } - LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); - if (material_type_ctrl) { material_type_to_ctrl(material_type_ctrl, material_type); } - updateForMaterialType(); - material_type_ctrl->setVisible(feature_pbr_terrain_enabled); + if (mMaterialTypeCtrl) + { + material_type_to_ctrl(mMaterialTypeCtrl, material_type); + updateForMaterialType(); + mMaterialTypeCtrl->setVisible(feature_pbr_terrain_enabled); + } LLTextureCtrl* asset_ctrl; std::string buffer; @@ -1544,7 +1545,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); - asset_ctrl = getChild(buffer); + asset_ctrl = findChild(buffer); if(asset_ctrl) { LL_DEBUGS() << "Detail Texture " << i << ": " @@ -1559,7 +1560,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); + asset_ctrl = findChild(buffer); if(asset_ctrl) { LL_DEBUGS() << "Detail Material " << i << ": " @@ -1574,7 +1575,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("texture_detail_%d", i); - asset_ctrl = getChild(buffer); + asset_ctrl = findChild(buffer); if(asset_ctrl) { asset_ctrl->setImageAssetID(mLastSetTextures[i]); @@ -1586,7 +1587,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); - asset_ctrl = getChild(buffer); + asset_ctrl = findChild(buffer); if(asset_ctrl) { asset_ctrl->setImageAssetID(mLastSetMaterials[i]); @@ -1665,9 +1666,8 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() LLMessageSystem* msg = gMessageSystem; // Send either material IDs instead of texture IDs depending on - // terrain_material_type - they both occupy the same slot. - LLCheckBoxCtrl* material_type_ctrl = getChild("terrain_material_type"); - const LLTerrainMaterials::Type material_type = material_type_ctrl ? material_type_from_ctrl(material_type_ctrl) : LLTerrainMaterials::Type::TEXTURE; + // material_type - they both occupy the same slot. + const LLTerrainMaterials::Type material_type = mMaterialTypeCtrl ? material_type_from_ctrl(mMaterialTypeCtrl) : LLTerrainMaterials::Type::TEXTURE; for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { if (material_type == LLTerrainMaterials::Type::PBR) @@ -1678,7 +1678,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() { buffer = llformat("texture_detail_%d", i); } - asset_ctrl = getChild(buffer); + asset_ctrl = findChild(buffer); if (!asset_ctrl) { continue; } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 93a4d3a795..a38344c861 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -272,6 +272,7 @@ protected: private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; + LLCheckBoxCtrl* mMaterialTypeCtrl = nullptr; LLUUID mLastSetTextures[LLTerrainMaterials::ASSET_COUNT]; LLUUID mLastSetMaterials[LLTerrainMaterials::ASSET_COUNT]; }; -- cgit v1.2.3 From c1bde75768e1374d4f094936d52ed29f6f5d3cba Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 8 Mar 2024 12:01:20 -0600 Subject: HDRI Local Preview (#953) * #926 WIP - HDRI import prototype v0 * #926 WIP -- add OpenEXR to autobuild.xml * #926 WIP -- Add OpenEXR cmake * #926 WIP -- Attempt at using OpenEXR autobuild package and don't hard code .exr file to load * #926 Unmangle autobuild.xml and get dll's in the right place (thanks, Caladbolg!) * implement mac shared libs plumbing for OpenEXR for secondlife/viewer#926 * Fix Xcode/clang compile error regarding new[]/delete[] mismatch * #926 HDRI Preview finishing touches. - Full ACES when HDRI is enabled - Fix for probes getting stuck paused - Add exposure and rotation controls --------- Co-authored-by: Brad Linden --- autobuild.xml | 56 +++++++++ indra/cmake/Copy3rdPartyLibs.cmake | 12 ++ indra/cmake/OpenEXR.cmake | 18 +++ indra/llrender/llshadermgr.cpp | 2 +- indra/newview/CMakeLists.txt | 9 +- indra/newview/app_settings/settings.xml | 33 ++++++ .../class1/deferred/postDeferredGammaCorrect.glsl | 3 +- .../app_settings/shaders/class1/deferred/skyF.glsl | 23 +++- .../app_settings/shaders/class1/deferred/skyV.glsl | 8 ++ .../shaders/class3/deferred/softenLightF.glsl | 4 + indra/newview/lldrawpoolwlsky.cpp | 38 +++++- indra/newview/llenvironment.cpp | 8 +- indra/newview/llfilepicker.cpp | 7 ++ indra/newview/llfilepicker.h | 1 + indra/newview/llreflectionmapmanager.cpp | 131 ++++++++++++++++++++- indra/newview/llreflectionmapmanager.h | 4 +- indra/newview/llviewermenu.cpp | 14 +++ indra/newview/llviewershadermgr.cpp | 23 ++++ indra/newview/llviewershadermgr.h | 1 + indra/newview/llvoavatar.cpp | 3 - indra/newview/pipeline.cpp | 4 + indra/newview/skins/default/xui/en/menu_viewer.xml | 6 + .../newview/skins/default/xui/en/notifications.xml | 9 ++ indra/newview/viewer_manifest.py | 14 +++ 24 files changed, 415 insertions(+), 16 deletions(-) create mode 100644 indra/cmake/OpenEXR.cmake diff --git a/autobuild.xml b/autobuild.xml index 11b2783bd7..f0038f6532 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2198,6 +2198,62 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors description OpenAL Soft is a software implementation of the OpenAL 3D audio API. + openexr + + canonical_repo + https://github.com/secondlife/3p-openexr + copyright + Copyright (c) Contributors to the OpenEXR Project. All rights reserved. + description + OpenEXR provides the specification and reference implementation of the EXR file format, the professional-grade image storage format of the motion picture industry. + license + OpenEXR + license_file + LICENSES/openexr.txt + name + openexr + platforms + + darwin64 + + archive + + hash + 158cbe79bef4ecafb870052bbaca541e07107228 + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-openexr/releases/download/v1.8/openexr-3.2.2-darwin64-6501c65.tar.zst + + name + darwin64 + + windows64 + + archive + + hash + 924f6ddf6669af023d1f3832cb79b50b913ae0ca + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-openexr/releases/download/v1.8/openexr-3.2.2-windows64-6501c65.tar.zst + + name + windows64 + + + source_type + git + vcs_branch + debug_autobuild + vcs_revision + 5cd1075295c17b5f7085e83d5c16b13c7ecb2eb1 + vcs_url + https://github.com/secondlife/3p-openexr + version + 3.2.2 + openjpeg platforms diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 9f79c13a97..415641f65f 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -60,6 +60,12 @@ if(WINDOWS) nghttp2.dll libhunspell.dll uriparser.dll + Iex-3_2.dll + IlmThread-3_2.dll + Imath-3_1.dll + OpenEXR-3_2.dll + OpenEXRCore-3_2.dll + OpenEXRUtil-3_2.dll ) # ICU4C (same filenames for 32 and 64 bit builds) @@ -184,6 +190,12 @@ elseif(DARWIN) liburiparser.dylib liburiparser.1.dylib liburiparser.1.0.27.dylib + libIex-3_2.dylib + libIlmThread-3_2.dylib + libImath-3_1.dylib + libOpenEXR-3_2.dylib + libOpenEXRCore-3_2.dylib + libOpenEXRUtil-3_2.dylib ) if (TARGET ll::fmodstudio) diff --git a/indra/cmake/OpenEXR.cmake b/indra/cmake/OpenEXR.cmake new file mode 100644 index 0000000000..ee21fac541 --- /dev/null +++ b/indra/cmake/OpenEXR.cmake @@ -0,0 +1,18 @@ +# -*- cmake -*- + +include(Prebuilt) + +include_guard() +add_library( ll::openexr INTERFACE IMPORTED ) + +if(USE_CONAN ) + target_link_libraries( ll::openexr INTERFACE CONAN_PKG::openexr ) + return() +endif() + +use_prebuilt_binary(openexr) + +target_link_libraries( ll::openexr INTERFACE Iex-3_2 IlmThread-3_2 Imath-3_1 OpenEXR-3_2 OpenEXRCore-3_2 OpenEXRUtil-3_2) + +target_include_directories( ll::openexr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/OpenEXR ${LIBS_PREBUILT_DIR}/include/Imath) + diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 5384133220..6cfe065355 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -618,7 +618,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_ATMOS 0.34\n"); // bit 0 extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_PBR 0.67\n"); // bit 1 - extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_MIRROR 1.0\n"); // bit 2 + extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_HAS_HDRI 1.0\n"); // bit 2 extra_code_text[extra_code_count++] = strdup("#define GET_GBUFFER_FLAG(flag) (abs(norm.w-flag)< 0.1)\n"); if (defines) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 6b15e847a3..8494ba5b49 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -34,6 +34,7 @@ include(LLWindow) include(NDOF) include(NVAPI) include(OPENAL) +include(OpenEXR) include(OpenGL) include(OpenSSL) include(PNG) @@ -72,7 +73,6 @@ if (NOT HAVOK_TPV) endif() endif (NOT HAVOK_TPV) - set(viewer_SOURCE_FILES groupchatlistener.cpp llaccountingcostmanager.cpp @@ -1744,6 +1744,12 @@ if (WINDOWS) media_plugin_cef media_plugin_libvlc media_plugin_example + ${SHARED_LIB_STAGING_DIR}/Iex-3_2.dll + ${SHARED_LIB_STAGING_DIR}/IlmThread-3_2.dll + ${SHARED_LIB_STAGING_DIR}/Imath-3_1.dll + ${SHARED_LIB_STAGING_DIR}/OpenEXR-3_2.dll + ${SHARED_LIB_STAGING_DIR}/OpenEXRCore-3_2.dll + ${SHARED_LIB_STAGING_DIR}/OpenEXRUtil-3_2.dll ) if (ADDRESS_SIZE EQUAL 64) @@ -1937,6 +1943,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ll::bugsplat ll::tracy ll::icu4c + ll::openexr ) if( TARGET ll::intel_memops ) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9d4f4cf911..8420f32db8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9274,6 +9274,17 @@ Value 1 + RenderDesaturateIrradiance + + Comment + Desaturate irradiance to remove blue tint + Persist + 1 + Type + Boolean + Value + 1 + RenderDebugAlphaMask Comment @@ -9340,6 +9351,28 @@ Value 0 + RenderHDRIExposure + + Comment + Exposure adjustment of HDRI when previewing an HDRI. Units are EV. Sane values would be -10 to 10. + Persist + 1 + Type + F32 + Value + 0.0 + + RenderHDRIRotation + + Comment + Rotation (in degrees) of environment when previewing an HDRI. + Persist + 1 + Type + F32 + Value + 0.0 + RenderMaxOpenGLVersion Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 3443785e1a..d89377326e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -97,6 +97,7 @@ vec3 toneMapACES_Hill(vec3 color) uniform float exposure; uniform float gamma; +uniform float aces_mix; vec3 toneMap(vec3 color) { @@ -106,7 +107,7 @@ vec3 toneMap(vec3 color) color *= exposure * exp_scale; // mix ACES and Linear here as a compromise to avoid over-darkening legacy content - color = mix(toneMapACES_Hill(color), color, 0.3); + color = mix(toneMapACES_Hill(color), color, aces_mix); #endif return color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 9d9ba49d82..cc5280d929 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -27,6 +27,13 @@ in vec3 vary_HazeColor; in float vary_LightNormPosDot; +#ifdef HAS_HDRI +in vec3 vary_position; +uniform float sky_hdr_scale; +uniform mat3 env_mat; +uniform sampler2D environmentMap; +#endif + uniform sampler2D rainbow_map; uniform sampler2D halo_map; @@ -37,6 +44,9 @@ uniform float ice_level; out vec4 frag_data[4]; vec3 srgb_to_linear(vec3 c); +vec3 linear_to_srgb(vec3 c); + +#define PI 3.14159265 ///////////////////////////////////////////////////////////////////////// // The fragment shader for the sky @@ -71,6 +81,14 @@ vec3 halo22(float d) void main() { +#ifdef HAS_HDRI + vec3 pos = normalize(vary_position); + pos = env_mat * pos; + vec2 texCoord = vec2(atan(pos.z, pos.x) + PI, acos(pos.y)) / vec2(2.0 * PI, PI); + vec3 color = textureLod(environmentMap, texCoord.xy, 0).rgb * sky_hdr_scale; + color = min(color, vec3(8192*8192*16)); +#else + // Potential Fill-rate optimization. Add cloud calculation // back in and output alpha of 0 (so that alpha culling kills // the fragment) if the sky wouldn't show up because the clouds @@ -86,9 +104,12 @@ void main() color.rgb *= 2.; color.rgb = clamp(color.rgb, vec3(0), vec3(5)); +#endif + frag_data[0] = vec4(0); frag_data[1] = vec4(0); - frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog + frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); frag_data[3] = vec4(color.rgb, 1.0); + } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 17ce2dee5b..bbe9a5a838 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -35,6 +35,10 @@ in vec3 position; out vec3 vary_HazeColor; out float vary_LightNormPosDot; +#ifdef HAS_HDRI +out vec3 vary_position; +#endif + // Inputs uniform vec3 camPosLocal; @@ -72,6 +76,10 @@ void main() // Get relative position vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); +#ifdef HAS_HDRI + vary_position = rel_pos; +#endif + // Adj position vector to clamp altitude if (rel_pos.y > 0.) { diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 2f90249169..5cc7ea698a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -189,6 +189,10 @@ void main() vec3 v = -normalize(pos.xyz); color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); } + else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI)) + { + color = texture(emissiveRect, tc).rgb; + } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { //should only be true of WL sky, just port over base color value diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index b14235f25c..a9cc138549 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -44,6 +44,7 @@ #include "llsky.h" #include "llvowlsky.h" #include "llsettingsvo.h" +#include "llviewercontrol.h" extern BOOL gCubeSnapshot; @@ -127,6 +128,8 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca gGL.popMatrix(); } +extern LLPointer gEXRImage; + void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const { if (!gSky.mVOSkyp) @@ -138,9 +141,33 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) { + if (gEXRImage.notNull()) + { + sky_shader = &gEnvironmentMapProgram; + sky_shader->bind(); + S32 idx = sky_shader->enableTexture(LLShaderMgr::ENVIRONMENT_MAP); + if (idx > -1) + { + gGL.getTexUnit(idx)->bind(gEXRImage); + } + + static LLCachedControl hdri_exposure(gSavedSettings, "RenderHDRIExposure", 0.0f); + static LLCachedControl hdri_rotation(gSavedSettings, "RenderHDRIRotation", 0.f); + + LLMatrix3 rot; + rot.setRot(0.f, hdri_rotation*DEG_TO_RAD, 0.f); + + sky_shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, powf(2.f, hdri_exposure)); + sky_shader->uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, GL_FALSE, (F32*) rot.mMatrix); + } + else + { + sky_shader->bind(); + } + LLGLSPipelineDepthTestSkyBox sky(true, true); - sky_shader->bind(); + sky_shader->uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0); @@ -180,7 +207,7 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const { - if (!gSky.mVOSkyp) + if (!gSky.mVOSkyp || gEXRImage.notNull()) { return; } @@ -251,6 +278,11 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const { + if (gEXRImage.notNull()) + { + return; + } + if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex()) { LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); @@ -310,7 +342,7 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 void LLDrawPoolWLSky::renderHeavenlyBodies() { - if (!gSky.mVOSkyp) return; + if (!gSky.mVOSkyp || gEXRImage.notNull()) return; LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index affea3f69c..0b535e15b0 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -1770,8 +1770,10 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con case LLSD::TypeArray: { LLVector4 vect4(value); + // always identify as a radiance pass if desaturating irradiance is disabled + static LLCachedControl desaturate_irradiance(gSavedSettings, "RenderDesaturateIrradiance", true); - if (gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass()) + if (desaturate_irradiance && gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass()) { // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color auto max_vec = [](LLVector4 col) { @@ -2966,7 +2968,7 @@ void LLEnvironment::DayTransition::animate() // pause probe updates and reset reflection maps on sky change - gPipeline.mReflectionMapManager.pause(); + gPipeline.mReflectionMapManager.pause(mTransitionTime); gPipeline.mReflectionMapManager.reset(); mSky = mStartSky->buildClone(); @@ -3569,7 +3571,7 @@ namespace mInjectedSky->setSource(target_sky); // clear reflection probes and pause updates during sky change - gPipeline.mReflectionMapManager.pause(); + gPipeline.mReflectionMapManager.pause(transition); gPipeline.mReflectionMapManager.reset(); mBlenderSky = std::make_shared(target_sky, start_sky, psky, transition); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 4ad136e13a..b82172c506 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -61,6 +61,7 @@ LLFilePicker LLFilePicker::sInstance; #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" #define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" #define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0" +#define HDRI_FILTER L"HDRI Files (*.exr)\0*.exr\0" #define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" #define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" @@ -228,6 +229,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) IMAGE_FILTER \ L"\0"; break; + case FFLOAD_HDRI: + mOFN.lpstrFilter = HDRI_FILTER \ + L"\0"; + break; case FFLOAD_SCRIPT: mOFN.lpstrFilter = SCRIPT_FILTER \ L"\0"; @@ -663,6 +668,8 @@ std::unique_ptr> LLFilePicker::navOpenFilterProc(ELoadF allowedv->push_back("gltf"); allowedv->push_back("glb"); break; + case FFLOAD_HDRI: + allowedv->push_back("exr"); case FFLOAD_COLLADA: allowedv->push_back("dae"); break; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 38daff9937..891c0c0482 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -89,6 +89,7 @@ public: FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin FFLOAD_MATERIAL = 15, FFLOAD_MATERIAL_TEXTURE = 16, + FFLOAD_HDRI = 17, }; enum ESaveFilter diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index ce389a5cad..f9c5421866 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -38,6 +38,126 @@ #include "llviewercontrol.h" #include "llenvironment.h" #include "llstartup.h" +#include "llviewermenufile.h" +#include "llnotificationsutil.h" + + +// load an OpenEXR image from a file +#define IMATH_HALF_NO_LOOKUP_TABLE 1 +#include +#include +#include +#include +#include + +LLPointer gEXRImage; + +void load_exr(const std::string& filename) +{ + // reset reflection maps when previewing a new HDRI + gPipeline.mReflectionMapManager.reset(); + gPipeline.mReflectionMapManager.initReflectionMaps(); + + try { + Imf::InputFile file(filename.c_str()); + Imath::Box2i dw = file.header().dataWindow(); + int width = dw.max.x - dw.min.x + 1; + int height = dw.max.y - dw.min.y + 1; + + Imf::Array2D rPixels; + Imf::Array2D gPixels; + Imf::Array2D bPixels; + + rPixels.resizeErase(height, width); + gPixels.resizeErase(height, width); + bPixels.resizeErase(height, width); + + Imf::FrameBuffer frameBuffer; + + frameBuffer.insert("R", // name + Imf::Slice(Imf::HALF, // type + (char*)(&rPixels[0][0] - // base + dw.min.x - + dw.min.y * width), + sizeof(rPixels[0][0]) * 1, // xStride + sizeof(rPixels[0][0]) * width, // yStride + 1, 1, // x/y sampling + 0.0)); // fillValue + + frameBuffer.insert("G", // name + Imf::Slice(Imf::HALF, // type + (char*)(&gPixels[0][0] - // base + dw.min.x - + dw.min.y * width), + sizeof(gPixels[0][0]) * 1, // xStride + sizeof(gPixels[0][0]) * width, // yStride + 1, 1, // x/y sampling + 0.0)); // fillValue + + frameBuffer.insert("B", // name + Imf::Slice(Imf::HALF, // type + (char*)(&bPixels[0][0] - // base + dw.min.x - + dw.min.y * width), + sizeof(bPixels[0][0]) * 1, // xStride + sizeof(bPixels[0][0]) * width, // yStride + 1, 1, // x/y sampling + FLT_MAX)); // fillValue + + file.setFrameBuffer(frameBuffer); + file.readPixels(dw.min.y, dw.max.y); + + U32 texName = 0; + LLImageGL::generateTextures(1, &texName); + + gEXRImage = new LLImageGL(texName, 4, GL_TEXTURE_2D, GL_RGB16F, GL_RGB16F, GL_FLOAT, LLTexUnit::TAM_CLAMP); + gEXRImage->setHasMipMaps(TRUE); + gEXRImage->setUseMipMaps(TRUE); + gEXRImage->setFilteringOption(LLTexUnit::TFO_TRILINEAR); + + gGL.getTexUnit(0)->bind(gEXRImage); + + std::vector data(width * height * 3); + for (int i = 0; i < width * height; ++i) + { + data[i * 3 + 0] = rPixels[i / width][i % width]; + data[i * 3 + 1] = gPixels[i / width][i % width]; + data[i * 3 + 2] = bPixels[i / width][i % width]; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data.data()); + + glGenerateMipmap(GL_TEXTURE_2D); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + } + catch (const std::exception& e) { + LLSD notif_args; + notif_args["WHAT"] = filename; + notif_args["REASON"] = e.what(); + LLNotificationsUtil::add("CannotLoad", notif_args); + return; + } +} + +void hdri_preview() +{ + LLFilePickerReplyThread::startPicker( + [](const std::vector& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter) + { + if (LLAppViewer::instance()->quitRequested()) + { + return; + } + if (filenames.size() > 0) + { + load_exr(filenames[0]); + } + }, + LLFilePicker::FFLOAD_HDRI, + true); +} extern BOOL gCubeSnapshot; extern BOOL gTeleportDisplay; @@ -133,6 +253,11 @@ void LLReflectionMapManager::update() return; } + if (mPaused && gFrameTimeSeconds > mResumeTime) + { + resume(); + } + initReflectionMaps(); if (!mRenderTarget.isComplete()) @@ -831,9 +956,10 @@ void LLReflectionMapManager::reset() mReset = true; } -void LLReflectionMapManager::pause() +void LLReflectionMapManager::pause(F32 duration) { mPaused = true; + mResumeTime = gFrameTimeSeconds + duration; } void LLReflectionMapManager::resume() @@ -1283,6 +1409,8 @@ void LLReflectionMapManager::initReflectionMaps() if (mTexture.isNull() || mReflectionProbeCount != count || mReset) { + gEXRImage = nullptr; + mReset = false; mReflectionProbeCount = count; mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512)); @@ -1340,7 +1468,6 @@ void LLReflectionMapManager::initReflectionMaps() mDefaultProbe->mComplete = default_complete; touch_default_probe(mDefaultProbe); - } if (mVertexBuffer.isNull()) diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 0fee99eefc..5c0651bc24 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -87,7 +87,8 @@ public: void reset(); // pause all updates other than the default probe - void pause(); + // duration - number of seconds to pause (default 10) + void pause(F32 duration = 10.f); // unpause (see pause) void resume(); @@ -208,5 +209,6 @@ private: // if true, only update the default probe bool mPaused = false; + F32 mResumeTime = 0.f; }; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d5e4de03a9..c50ae2e153 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7890,6 +7890,19 @@ class LLAdvancedClickRenderBenchmark: public view_listener_t } }; +void hdri_preview(); + +class LLAdvancedClickHDRIPreview: public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + // open personal lighting floater when previewing an HDRI (keeps HDRI from implicitly unloading when opening build tools) + LLFloaterReg::showInstance("env_adjust_snapshot"); + hdri_preview(); + return true; + } +}; + // these are used in the gl menus to set control values that require shader recompilation class LLToggleShaderControl : public view_listener_t { @@ -9529,6 +9542,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption"); view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile"); view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark"); + view_listener_t::addMenu(new LLAdvancedClickHDRIPreview(), "Advanced.ClickHDRIPreview"); view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache"); view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 354cc79036..dc20f035c9 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -201,6 +201,7 @@ LLGLSLShader gLuminanceProgram; LLGLSLShader gFXAAProgram; LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gDeferredWLSkyProgram; +LLGLSLShader gEnvironmentMapProgram; LLGLSLShader gDeferredWLCloudProgram; LLGLSLShader gDeferredWLSunProgram; LLGLSLShader gDeferredWLMoonProgram; @@ -315,6 +316,7 @@ void LLViewerShaderMgr::finalizeShaderList() mShaderList.push_back(&gDeferredEmissiveProgram); mShaderList.push_back(&gDeferredAvatarEyesProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); + mShaderList.push_back(&gEnvironmentMapProgram); mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); @@ -987,6 +989,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gNoPostGammaCorrectProgram.unload(); gLegacyPostGammaCorrectProgram.unload(); gFXAAProgram.unload(); + gEnvironmentMapProgram.unload(); gDeferredWLSkyProgram.unload(); gDeferredWLCloudProgram.unload(); gDeferredWLSunProgram.unload(); @@ -2268,6 +2271,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } + if (success) + { + gEnvironmentMapProgram.mName = "Environment Map Program"; + gEnvironmentMapProgram.mShaderFiles.clear(); + gEnvironmentMapProgram.mFeatures.calculatesAtmospherics = true; + gEnvironmentMapProgram.mFeatures.hasAtmospherics = true; + gEnvironmentMapProgram.mFeatures.hasGamma = true; + gEnvironmentMapProgram.mFeatures.hasSrgb = true; + + gEnvironmentMapProgram.clearPermutations(); + gEnvironmentMapProgram.addPermutation("HAS_HDRI", "1"); + gEnvironmentMapProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER)); + gEnvironmentMapProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER)); + gEnvironmentMapProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gEnvironmentMapProgram.mShaderGroup = LLGLSLShader::SG_SKY; + + success = gEnvironmentMapProgram.createShader(NULL, NULL); + llassert(success); + } + if (success) { gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 2502be6bb1..c51f583ebc 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -266,6 +266,7 @@ extern LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram; extern LLGLSLShader gDeferredEmissiveProgram; extern LLGLSLShader gDeferredAvatarEyesProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; +extern LLGLSLShader gEnvironmentMapProgram; extern LLGLSLShader gDeferredWLSkyProgram; extern LLGLSLShader gDeferredWLCloudProgram; extern LLGLSLShader gDeferredWLSunProgram; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index fee00eb6f4..35e45c6cd9 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5233,9 +5233,6 @@ U32 LLVOAvatar::renderRigid() return 0; } - bool should_alpha_mask = shouldAlphaMask(); - LLGLState test(GL_ALPHA_TEST, should_alpha_mask); - if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar()) { LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 94ec5c0817..7809129743 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6869,6 +6869,8 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool } } +extern LLPointer gEXRImage; + void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { dst->bindTarget(); // gamma correct lighting @@ -6905,8 +6907,10 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { F32 e = llclamp(exposure(), 0.5f, 4.f); static LLStaticHashedString s_exposure("exposure"); + static LLStaticHashedString aces_mix("aces_mix"); shader.uniform1f(s_exposure, e); + shader.uniform1f(aces_mix, gEXRImage.notNull() ? 0.f : 0.3f); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 4719b091ab..591b5537c7 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2824,6 +2824,12 @@ function="World.EnvPreset" + + + fail + + Unable to load [WHAT]. + [REASON] + fail + + Date: Fri, 8 Mar 2024 15:13:35 -0800 Subject: secondlife/viewer#712: Consolidate accesses to texture_detail_* and material_detail_* controls --- indra/newview/llfloaterregioninfo.cpp | 40 +++++++++++++---------------------- indra/newview/llfloaterregioninfo.h | 3 +++ 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index c6d8317128..f71cbf61fc 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1324,9 +1324,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - std::string buffer; - buffer = llformat("texture_detail_%d", i); - LLTextureCtrl* texture_ctrl = findChild(buffer); + LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i]; if (!texture_ctrl) continue; LLUUID image_asset_id = texture_ctrl->getImageAssetID(); @@ -1418,11 +1416,13 @@ BOOL LLPanelRegionTerrainInfo::postBuild() { buffer = llformat("texture_detail_%d", i); initCtrl(buffer); + mTextureDetailCtrl[i] = findChild(buffer); } for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { buffer = llformat("material_detail_%d", i); initCtrl(buffer); + mMaterialDetailCtrl[i] = findChild(buffer); } for(S32 i = 0; i < CORNER_COUNT; ++i) @@ -1457,12 +1457,9 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() const bool show_material_controls = material_type == LLTerrainMaterials::Type::PBR; // Toggle visibility of correct swatches - std::string buffer; - LLTextureCtrl* texture_ctrl; for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = findChild(buffer); + LLTextureCtrl* texture_ctrl = mTextureDetailCtrl[i]; if (texture_ctrl) { texture_ctrl->setVisible(show_texture_controls); @@ -1470,11 +1467,10 @@ void LLPanelRegionTerrainInfo::updateForMaterialType() } for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("material_detail_%d", i); - texture_ctrl = findChild(buffer); - if (texture_ctrl) + LLTextureCtrl* material_ctrl = mMaterialDetailCtrl[i]; + if (material_ctrl) { - texture_ctrl->setVisible(show_material_controls); + material_ctrl->setVisible(show_material_controls); } } @@ -1538,14 +1534,11 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) mMaterialTypeCtrl->setVisible(feature_pbr_terrain_enabled); } - LLTextureCtrl* asset_ctrl; - std::string buffer; if (set_texture_swatches) { for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - asset_ctrl = findChild(buffer); + LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i]; if(asset_ctrl) { LL_DEBUGS() << "Detail Texture " << i << ": " @@ -1559,8 +1552,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("material_detail_%d", i); - asset_ctrl = findChild(buffer); + LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i]; if(asset_ctrl) { LL_DEBUGS() << "Detail Material " << i << ": " @@ -1574,8 +1566,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("texture_detail_%d", i); - asset_ctrl = findChild(buffer); + LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i]; if(asset_ctrl) { asset_ctrl->setImageAssetID(mLastSetTextures[i]); @@ -1586,8 +1577,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - buffer = llformat("material_detail_%d", i); - asset_ctrl = findChild(buffer); + LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i]; if(asset_ctrl) { asset_ctrl->setImageAssetID(mLastSetMaterials[i]); @@ -1595,6 +1585,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) } } + std::string buffer; for(S32 i = 0; i < CORNER_COUNT; ++i) { buffer = llformat("height_start_spin_%d", i); @@ -1661,7 +1652,6 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() } } - LLTextureCtrl* asset_ctrl; std::string id_str; LLMessageSystem* msg = gMessageSystem; @@ -1670,15 +1660,15 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() const LLTerrainMaterials::Type material_type = mMaterialTypeCtrl ? material_type_from_ctrl(mMaterialTypeCtrl) : LLTerrainMaterials::Type::TEXTURE; for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { + LLTextureCtrl* asset_ctrl; if (material_type == LLTerrainMaterials::Type::PBR) { - buffer = llformat("material_detail_%d", i); + asset_ctrl = mMaterialDetailCtrl[i]; } else { - buffer = llformat("texture_detail_%d", i); + asset_ctrl = mTextureDetailCtrl[i]; } - asset_ctrl = findChild(buffer); if (!asset_ctrl) { continue; } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index a38344c861..99774e5db3 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -56,6 +56,7 @@ class LLRadioGroup; class LLSliderCtrl; class LLSpinCtrl; class LLTextBox; +class LLTextureCtrl; class LLPanelRegionGeneralInfo; class LLPanelRegionDebugInfo; @@ -273,6 +274,8 @@ private: bool mConfirmedTextureHeights; bool mAskedTextureHeights; LLCheckBoxCtrl* mMaterialTypeCtrl = nullptr; + LLTextureCtrl* mTextureDetailCtrl[LLTerrainMaterials::ASSET_COUNT]; + LLTextureCtrl* mMaterialDetailCtrl[LLTerrainMaterials::ASSET_COUNT]; LLUUID mLastSetTextures[LLTerrainMaterials::ASSET_COUNT]; LLUUID mLastSetMaterials[LLTerrainMaterials::ASSET_COUNT]; }; -- cgit v1.2.3 From b84d76e243ed54b1d7db6401b78ce9122714b6e4 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 8 Mar 2024 16:29:00 -0800 Subject: secondlife/viewer#712: Slightly improved logging in refreshFromRegion --- indra/newview/llfloaterregioninfo.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index f71cbf61fc..454842999d 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1541,7 +1541,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i]; if(asset_ctrl) { - LL_DEBUGS() << "Detail Texture " << i << ": " + LL_DEBUGS("Terrain", "Texture") << "Detail Texture " << i << ": " << compp->getDetailAssetID(i) << LL_ENDL; LLUUID tmp_id(compp->getDetailAssetID(i)); asset_ctrl->setImageAssetID(tmp_id); @@ -1555,7 +1555,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i]; if(asset_ctrl) { - LL_DEBUGS() << "Detail Material " << i << ": " + LL_DEBUGS("Terrain", "Material") << "Detail Material " << i << ": " << compp->getDetailAssetID(i) << LL_ENDL; LLUUID tmp_id(compp->getDetailAssetID(i)); asset_ctrl->setImageAssetID(tmp_id); @@ -1566,6 +1566,8 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { + LL_DEBUGS("Terrain", "Texture") << "Reset Texture swatch " << i + << LL_ENDL; LLTextureCtrl* asset_ctrl = mTextureDetailCtrl[i]; if(asset_ctrl) { @@ -1577,6 +1579,8 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) { for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { + LL_DEBUGS("Terrain", "Material") << "Reset Material swatch " << i + << LL_ENDL; LLTextureCtrl* asset_ctrl = mMaterialDetailCtrl[i]; if(asset_ctrl) { -- cgit v1.2.3