Merge branch 'release/materials_featurette' of https://github.com/secondlife/viewer
# Conflicts: # indra/llprimitive/llgltfmaterial.h # indra/newview/app_settings/settings.xmlmaster
commit
aaa52d0c66
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 < RenderResolutionMultiplier <= 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 < RenderResolutionMultiplier <= 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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue