Merge branch 'release/materials_featurette' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/llprimitive/llgltfmaterial.h
#	indra/newview/app_settings/settings.xml
master
Ansariel 2024-05-10 12:12:34 +02:00
commit aaa52d0c66
19 changed files with 197 additions and 132 deletions

View File

@ -1,4 +1,29 @@
- Texture terrain should load
- PBR terrain should load if enabled
# Terrain Loading
## Behavior overview
- Texture terrain should load if textures are applied to the region, and no PBR Metallic Roughness materials are applied.
- PBR terrain should load if PBR materials are applied to the region, even if the RenderTerrainPBREnabled feature flag is disabled in debug settings. This setting only disables the display of PBR materials in the Region / Estate > Terrain UI.
- 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)
- Related subsystem: Minimap should load if terrain loads
- They may not finish loading at the same time
## Implementation details
This section is provided mainly for clarification of how the terrain loading system works.
The simulator sends 4 terrain composition UUIDs to the viewer for the region. The viewer does not know ahead-of-time if the terrain composition uses textures or materials. Therefore, to expedite terrain loading, the viewer makes up to 8 "top-level" asset requests simultaneously:
- Up to 4 texture asset requests, one for each UUID
- Up to 4 material asset requests, one for each UUID
It is therefore expected that half of these asset lookups will fail.
The viewer inspects the load success of these top-level assets to make the binary decision of whether to render all 4 texture assets or all 4 material assets. This determines the choice of composition for terrain both in-world and on the minimap.
The minimap also attempts to wait for textures to partially load before it can render a tile for a given region:
- When rendering texture terrain, the minimap attempts to wait for top-level texture assets to partially load
- When rendering PBR material terrain, the minimap attempts to wait for any base color/emissive textures in the materials to partially load, if they are present
We don't make guarantees that the minimap tile will render for the region if any aforementioned required textures/materials fail to sufficiently load. However, the minimap may make a best-effort attempt to render the region by ignoring or replacing data.

View File

@ -130,12 +130,6 @@ public:
bool mOverrideDoubleSided = false;
bool mOverrideAlphaMode = false;
// These fields are local to viewer and are a part of local bitmap support
typedef std::map<LLUUID, LLUUID> local_tex_map_t;
local_tex_map_t mTrackingIdToLocalTexture;
public:
// *TODO: If/when we implement additional GLTF extensions, they may not be
// compatible with our GLTF terrain implementation. We may want to disallow
// materials with some features from being set on terrain, if their
@ -146,6 +140,11 @@ public:
// heightmaps cannot currently be described as finite enclosed
// volumes.
// See also LLPanelRegionTerrainInfo::validateMaterials
// These fields are local to viewer and are a part of local bitmap support
typedef std::map<LLUUID, LLUUID> local_tex_map_t;
local_tex_map_t mTrackingIdToLocalTexture;
public:
// get a UUID based on a hash of this LLGLTFMaterial
LLUUID getHash() const;

View File

@ -328,7 +328,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
}
}

View File

@ -13612,51 +13612,62 @@ Change of this parameter will affect the layout of buttons in notification toast
<integer>3</integer>
</map>
<key>RenderReflectionRes</key>
<map>
<key>Comment</key>
<string>Reflection map resolution.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>64</integer>
</map>
<key>RenderResolutionDivisor</key>
<map>
<key>Comment</key>
<string>Divisor for rendering 3D scene at reduced resolution.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>RenderResolutionMultiplier</key>
<map>
<key>Comment</key>
<string>Multiplier for rendering 3D scene at reduced resolution. Valid values: 0 &lt; RenderResolutionMultiplier &lt;= 1.0 </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>RenderShaderLightingMaxLevel</key>
<map>
<key>Comment</key>
<string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>3</integer>
</map>
<map>
<key>Comment</key>
<string>Reflection map resolution.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>64</integer>
</map>
<key>RenderReservedTextureIndices</key>
<map>
<key>Comment</key>
<string>Count of texture indices to reserve for shadow and reflection maps when using indexed texture rendering. Probably only want to set from the login screen.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>14</integer>
</map>
<key>RenderResolutionDivisor</key>
<map>
<key>Comment</key>
<string>Divisor for rendering 3D scene at reduced resolution.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>RenderResolutionMultiplier</key>
<map>
<key>Comment</key>
<string>Multiplier for rendering 3D scene at reduced resolution. Valid values: 0 &lt; RenderResolutionMultiplier &lt;= 1.0 </string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>RenderShaderLightingMaxLevel</key>
<map>
<key>Comment</key>
<string>Max lighting level to use in the shader (class 3 is default, 2 is less lights, 1 is sun/moon only. Works around shader compiler bugs on certain platforms.)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>3</integer>
</map>
<key>RenderSkyAutoAdjustLegacy</key>
<map>
<key>Comment</key>

View File

@ -55,7 +55,7 @@ void main()
frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0);
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
frag_data[3] = vec4(c.rgb, c.a);
// Added and commented out for a ground truth. Do not uncomment - Geenz

View File

@ -75,6 +75,7 @@ RenderGLMultiThreadedTextures 1 0
RenderGLMultiThreadedMedia 1 1
RenderReflectionProbeResolution 1 128
RenderScreenSpaceReflections 1 1
RenderMirrors 1 1
//
@ -251,8 +252,8 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
RenderMirrors 1 0
RenderHeroProbeResolution 1 1024
RenderMirrors 1 1
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 8
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
@ -287,7 +288,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
RenderMirrors 1 0
RenderMirrors 1 1
RenderHeroProbeResolution 1 1024
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1

View File

@ -74,6 +74,7 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 2
RenderScreenSpaceReflections 1 1
RenderReflectionProbeLevel 1 3
RenderMirrors 1 1
//
// Low Graphics Settings
@ -249,8 +250,8 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 1
RenderMirrors 1 0
RenderHeroProbeResolution 1 1024
RenderMirrors 1 1
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 8
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
@ -285,8 +286,8 @@ RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 2
RenderMirrors 1 0
RenderHeroProbeResolution 1 1024
RenderMirrors 1 1
RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
@ -322,7 +323,7 @@ RenderReflectionProbeDetail 1 1
RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
RenderMirrors 1 1
RenderHeroProbeResolution 1 2048
RenderHeroProbeResolution 1 1024
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4

View File

@ -497,7 +497,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
}
}
}
return tex_setup;
}
@ -696,7 +696,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
if ((bool)params.mAvatar != rigged)
@ -842,9 +842,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
current_shader->setMinimumAlpha(0.f);
reset_minimum_alpha = true;
}
params.mVertexBuffer->setBuffer();
params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
stop_glerror();
if (reset_minimum_alpha)
{

View File

@ -1953,7 +1953,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
S32* vp = (S32*) &val;
*vp = index;
llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
llassert(index < LLGLSLShader::sIndexedTextureChannels);
LLVector4Logical mask;
mask.clear();

View File

@ -113,22 +113,40 @@ void LLHeroProbeManager::update()
LLVector4a probe_pos;
LLVector3 camera_pos = LLViewerCamera::instance().mOrigin;
F32 near_clip = 0.1f;
bool probe_present = false;
LLQuaternion cameraOrientation = LLViewerCamera::instance().getQuaternion();
LLVector3 cameraDirection = LLVector3::z_axis * cameraOrientation;
if (mHeroVOList.size() > 0)
{
// Find our nearest hero candidate.
float last_distance = 99999.f;
float camera_center_distance = 99999.f;
for (auto vo : mHeroVOList)
{
if (vo && !vo->isDead() && vo->mDrawable.notNull())
{
float distance = (LLViewerCamera::instance().getOrigin() - vo->getPositionAgent()).magVec();
if (distance < last_distance)
float center_distance = cameraDirection * (vo->getPositionAgent() - camera_pos);
if (distance > LLViewerCamera::instance().getFar())
continue;
LLVector4a center;
center.load3(vo->getPositionAgent().mV);
LLVector4a size;
size.load3(vo->getScale().mV);
bool visible = LLViewerCamera::instance().AABBInFrustum(center, size);
if (distance < last_distance && center_distance < camera_center_distance && visible)
{
mNearestHero = vo;
last_distance = distance;
}
probe_present = true;
mNearestHero = vo;
last_distance = distance;
camera_center_distance = center_distance;
}
}
else
{
@ -136,6 +154,10 @@ void LLHeroProbeManager::update()
}
}
// Don't even try to do anything if we didn't find a single mirror present.
if (!probe_present)
return;
if (mNearestHero != nullptr && !mNearestHero->isDead() && mNearestHero->mDrawable.notNull())
{
LLVector3 hero_pos = mNearestHero->getPositionAgent();
@ -152,14 +174,12 @@ void LLHeroProbeManager::update()
mCurrentClipPlane.setVec(hero_pos, face_normal);
mMirrorPosition = hero_pos;
mMirrorNormal = face_normal;
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();
cam_direction.normalize();
// Detect visible faces of a cube based on camera direction and distance
// Define the cube faces
static LLVector3 cubeFaces[6] = {
LLVector3(1, 0, 0),
LLVector3(-1, 0, 0),
@ -169,17 +189,21 @@ void LLHeroProbeManager::update()
LLVector3(0, 0, -1)
};
// Iterate through each face of the cube
for (int i = 0; i < 6; i++)
{
float shouldUpdate = fminf(1, (fmaxf(-1, cam_direction * cubeFaces[i]) * 0.5 + 0.5));
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)
float cube_facing = fmax(-1, fmin(1.0f, cameraDirection * cubeFaces[i])) * 0.6 + 0.4;
float updateRate;
if (cube_facing < 0.1f)
{
updateRate = 0;
}
else
{
updateRate = ceilf(cube_facing * gPipeline.RenderHeroProbeConservativeUpdateMultiplier);
}
mFaceUpdateList[i] = updateRate;
}
}
@ -199,6 +223,7 @@ void LLHeroProbeManager::update()
static LLCachedControl<S32> sDetail(gSavedSettings, "RenderHeroReflectionProbeDetail", -1);
static LLCachedControl<S32> sLevel(gSavedSettings, "RenderHeroReflectionProbeLevel", 3);
if (mNearestHero != nullptr)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime");
// Probe 0 is always our mirror probe.
@ -208,13 +233,16 @@ void LLHeroProbeManager::update()
gPipeline.mReflectionMapManager.mRadiancePass = true;
mRenderingMirror = true;
doOcclusion();
for (U32 j = 0; j < mProbes.size(); j++)
{
for (U32 i = 0; i < 6; ++i)
{
if (mFaceUpdateList[i] > 0 && mCurrentProbeUpdateFrame % mFaceUpdateList[i] == 0)
{
updateProbeFace(mProbes[j], i, near_clip);
updateProbeFace(mProbes[j], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip);
mCurrentProbeUpdateFrame = 0;
}
}
@ -239,18 +267,17 @@ 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, F32 near_clip)
void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip)
{
// hacky hot-swap of camera specific render targets
gPipeline.mRT = &gPipeline.mHeroProbeRT;
probe->update(mRenderTarget.getWidth(), face, true, near_clip);
probe->update(mRenderTarget.getWidth(), face, is_dynamic, near_clip);
gPipeline.mRT = &gPipeline.mMainRT;
S32 sourceIdx = mReflectionProbeCount;
// Unlike the reflectionmap manager, all probes are considered "realtime" for hero probes.
sourceIdx += 1;
@ -371,8 +398,6 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe)
static LLStaticHashedString sSourceIdx("sourceIdx");
{
// generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map)
gHeroRadianceGenProgram.bind();
mVertexBuffer->setBuffer();

View File

@ -116,7 +116,7 @@ private:
// update the specified face of the specified probe
void updateProbeFace(LLReflectionMap* probe, U32 face, F32 near_clip);
void updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip);
void generateRadiance(LLReflectionMap *probe);
// list of active reflection maps

View File

@ -428,19 +428,21 @@ void LLPanelVolume::getState( )
volume_type = "Sphere";
}
std::string update_type;
if (volobjp->getReflectionProbeIsDynamic())
std::string update_type = "Static";
if (volobjp->getReflectionProbeIsDynamic() && !volobjp->getReflectionProbeIsMirror())
{
update_type = "Dynamic";
}
else if (volobjp->getReflectionProbeIsMirror())
else if (volobjp->getReflectionProbeIsMirror() && !volobjp->getReflectionProbeIsDynamic())
{
update_type = "Mirror";
}
else
{
update_type = "Static";
else if (volobjp->getReflectionProbeIsDynamic() && volobjp->getReflectionProbeIsMirror())
{
update_type = "Dynamic Mirror";
}
getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror");
@ -1246,6 +1248,7 @@ void LLPanelVolume::onCopyLight()
clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance();
clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip();
clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic();
clipboard["reflection_probe"]["mirror"] = volobjp->getReflectionProbeIsMirror();
}
mClipboardParams["light"] = clipboard;
@ -1303,6 +1306,7 @@ void LLPanelVolume::onPasteLight()
volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal());
volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal());
volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean());
volobjp->setReflectionProbeIsMirror(clipboard["reflection_probe"]["mirror"].asBoolean());
}
else
{
@ -1488,11 +1492,13 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
std::string update_type = self->getChild<LLUICtrl>("Probe Update Type")->getValue().asString();
volobjp->setReflectionProbeIsDynamic(update_type == "Dynamic");
volobjp->setReflectionProbeIsMirror(update_type == "Mirror");
bool is_mirror = update_type.find("Mirror") != std::string::npos;
self->getChildView("Probe Ambiance")->setEnabled(update_type != "Mirror");
self->getChildView("Probe Near Clip")->setEnabled(update_type != "Mirror");
volobjp->setReflectionProbeIsDynamic(update_type.find("Dynamic") != std::string::npos);
volobjp->setReflectionProbeIsMirror(is_mirror);
self->getChildView("Probe Ambiance")->setEnabled(!is_mirror);
self->getChildView("Probe Near Clip")->setEnabled(!is_mirror);
std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();

View File

@ -104,9 +104,9 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
}
}
}
else
else if (material.occlusionTexture.index == -1)
{
// no occlusion, make a white occlusion image
// no occlusion, make sure red channel of ORM is all 255
occlusion_img = new LLImageRaw(mr_img->getWidth(), mr_img->getHeight(), 3);
occlusion_img->clear(255, 255, 255);
copy_red_channel(occlusion_img, mr_img);

View File

@ -2632,14 +2632,6 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
gSavedSettings.setS32("max_texture_dimension_Y", 1024);
}
bool mirrors_enabled = false;
if (features.has("MirrorsEnabled"))
{
mirrors_enabled = features["MirrorsEnabled"].asBoolean();
}
gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled);
if (features.has("PBRTerrainEnabled"))
{
bool enabled = features["PBRTerrainEnabled"];

View File

@ -427,7 +427,10 @@ void LLViewerShaderMgr::setShaders()
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
// when using indexed texture rendering, leave some texture units available for shadow and reflection maps
LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1);
static LLCachedControl<S32> reserved_texture_units(gSavedSettings, "RenderReservedTextureIndices", 14);
LLGLSLShader::sIndexedTextureChannels =
llclamp<S32>(max_texture_index, 1, gGLManager.mNumTextureImageUnits-reserved_texture_units);
reentrance = true;

View File

@ -455,6 +455,7 @@ public:
protected:
/*virtual*/ void switchToCachedImage() override;
S32 getCurrentDiscardLevelForFetching() ;
public: // <FS:Ansariel> Needed for texture refresh
void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
private:

View File

@ -3616,8 +3616,15 @@ bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
{
if (param_block->getIsMirror() != is_mirror)
{
LL_INFOS() << "Setting reflection probe mirror to " << is_mirror << LL_ENDL;
param_block->setIsMirror(is_mirror);
parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
if (!is_mirror)
gPipeline.mHeroProbeManager.unregisterViewerObject(this);
else
gPipeline.mHeroProbeManager.registerViewerObject(this);
return true;
}
}
@ -6585,19 +6592,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
LLViewerTexture* last_tex = NULL;
S32 texture_index_channels = 1;
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{
texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity;
}
if (distance_sort)
{
texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
}
texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
S32 texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
bool flexi = false;

View File

@ -2372,7 +2372,8 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
// static
bool LLPipeline::isWaterClip()
{
return (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs;
// We always pretend that we're not clipping water when rendering mirrors.
return (gPipeline.mHeroProbeManager.isMirrorPass()) ? false : (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs;
}
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, bool hud_attachments)

View File

@ -3058,7 +3058,7 @@ Low ↔ Lwst
follows="left|top"
name="Probe Volume Type"
tool_tip="Choose the probe influence volume"
width="108">
width="140">
<combo_box.item
label="Sphere"
name="Sphere"
@ -3097,8 +3097,8 @@ Low ↔ Lwst
left="144"
follows="left|top"
name="Probe Update Type"
tool_tip="Determines how the probe updates. Static updates the slowest and without avatars. Dynamic updates more frequently, with avatars visible in the probes. Mirror turns this probe into a realtime planar projected mirror probe, but does not calculate ambiance."
width="108">
tool_tip="Determines how the probe updates. Static updates the slowest and without avatars. Dynamic updates more frequently, with avatars visible in the probes. Mirror (Environment) turns this probe into a realtime planar projected probe that only reflects the environment, but does not calculate ambiance. Mirror (Everything) is similar to Mirror (Environment), but it reflects particles and avatars."
width="140">
<combo_box.item
label="Static"
name="Static"
@ -3108,9 +3108,13 @@ Low ↔ Lwst
name="Dynamic"
value="Dynamic"/>
<combo_box.item
label="Mirror"
label="Mirror (Environment)"
name="Mirror"
value="Mirror"/>
<combo_box.item
label="Mirror (Everything)"
name="Dynamic Mirror"
value="Dynamic Mirror"/>
</combo_box>
<spinner top_pad="0"
decimal_digits="3"