summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-05-04 20:31:14 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-05-05 11:31:12 +0300
commit4b0a2463914e8228bc8797e6720b92c89f7949c1 (patch)
tree7050bd2cf2008a46ae0eb5956b0ff408ce86dbce /indra/newview/pipeline.cpp
parent30234c508b4ef8921359371de7ef79546aea5626 (diff)
SL-12743 Unified code
Fade out for deferred, fixed distance, reused non-deferred logic, fixed flicker
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r--indra/newview/pipeline.cpp169
1 files changed, 107 insertions, 62 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 01438bfb9f..b41ac29906 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6059,25 +6059,18 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
{
return max_dist;
}
- F32 radius = light->getLightRadius();
bool selected = light->isSelected();
- LLVector3 dpos = light->getRenderPosition() - cam_pos;
- F32 dist2 = dpos.lengthSquared();
- if (!selected && dist2 > (max_dist + radius)*(max_dist + radius))
- {
- return max_dist;
- }
- F32 dist = (F32) sqrt(dist2);
- dist *= 1.f / inten;
- dist -= radius;
if (selected)
{
- dist -= 10000.f; // selected lights get highest priority
+ return 0.f; // selected lights get highest priority
}
+ F32 radius = light->getLightRadius();
+ F32 dist = dist_vec(light->getRenderPosition(), cam_pos);
+ dist = llmax(dist - radius, 0.f);
if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
{
// moving lights get a little higher priority (too much causes artifacts)
- dist -= light->getLightRadius()*0.25f;
+ dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
}
return dist;
}
@@ -6096,12 +6089,17 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
// mNearbyLight (and all light_set_t's) are sorted such that
// begin() == the closest light and rbegin() == the farthest light
const S32 MAX_LOCAL_LIGHTS = 6;
-// LLVector3 cam_pos = gAgent.getCameraPositionAgent();
- LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
- camera.getOrigin() :
- gAgent.getPositionAgent();
+ LLVector3 cam_pos = camera.getOrigin();
- F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad
+ F32 max_dist;
+ if (LLPipeline::sRenderDeferred)
+ {
+ max_dist = RenderFarClip;
+ }
+ else
+ {
+ max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f);
+ }
// UPDATE THE EXISTING NEARBY LIGHTS
light_set_t cur_nearby_lights;
@@ -6136,8 +6134,38 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue;
}
- F32 dist = calc_light_dist(volight, cam_pos, max_dist);
- cur_nearby_lights.insert(Light(drawable, dist, light->fade));
+ F32 dist = calc_light_dist(volight, cam_pos, max_dist);
+ F32 fade = light->fade;
+ // actual fade gets decreased/increased by setupHWLights
+ // light->fade value is 'time'.
+ // >=0 and light will become visible as value increases
+ // <0 and light will fade out
+ if (dist < max_dist)
+ {
+ if (fade < 0)
+ {
+ // mark light to fade in
+ // if fade was -LIGHT_FADE_TIME - it was fully invisible
+ // if fade -0 - it was fully visible
+ // visibility goes up from 0 to LIGHT_FADE_TIME.
+ fade += LIGHT_FADE_TIME;
+ }
+ }
+ else
+ {
+ // mark light to fade out
+ // visibility goes down from -0 to -LIGHT_FADE_TIME.
+ if (fade >= LIGHT_FADE_TIME)
+ {
+ fade = -0.0001f; // was fully visible
+ }
+ else if (fade >= 0)
+ {
+ // 0.75 visible light should stay 0.75 visible, but should reverse direction
+ fade -= LIGHT_FADE_TIME;
+ }
+ }
+ cur_nearby_lights.insert(Light(drawable, dist, fade));
}
mNearbyLights = cur_nearby_lights;
@@ -6156,17 +6184,23 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
{
continue; // no lighting from HUD objects
}
- F32 dist = calc_light_dist(light, cam_pos, max_dist);
- if (dist >= max_dist)
+ if (!sRenderAttachedLights && light && light->isAttachment())
{
continue;
}
- if (!sRenderAttachedLights && light && light->isAttachment())
+ LLVOAvatar *av = light->getAvatar();
+ if (av && (av->isTooComplex() || av->isInMuteList()))
+ {
+ // avatars that are already in the list will be removed by removeMutedAVsLights
+ continue;
+ }
+ F32 dist = calc_light_dist(light, cam_pos, max_dist);
+ if (dist >= max_dist)
{
continue;
}
new_nearby_lights.insert(Light(drawable, dist, 0.f));
- if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
+ if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
{
new_nearby_lights.erase(--new_nearby_lights.end());
const Light& last = *new_nearby_lights.rbegin();
@@ -6179,7 +6213,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
iter != new_nearby_lights.end(); iter++)
{
const Light* light = &(*iter);
- if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
+ if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
{
mNearbyLights.insert(*light);
((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
@@ -6192,10 +6226,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
if (light->dist < farthest_light->dist)
{
- if (farthest_light->fade >= 0.f)
- {
- farthest_light->fade = -(gFrameIntervalSeconds.value());
- }
+ // mark light to fade out
+ // visibility goes down from -0 to -LIGHT_FADE_TIME.
+ //
+ // This is a mess, but for now it needs to be in sync
+ // with fade code above. Ex: code above detects distance < max,
+ // sets fade time to positive, this code then detects closer
+ // lights and sets fade time negative, fully compensating
+ // for the code above
+ if (farthest_light->fade >= LIGHT_FADE_TIME)
+ {
+ farthest_light->fade = -0.0001f; // was fully visible
+ }
+ else if (farthest_light->fade >= 0)
+ {
+ farthest_light->fade -= LIGHT_FADE_TIME;
+ }
}
else
{
@@ -6315,12 +6361,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
}
- const LLViewerObject *vobj = drawable->getVObj();
- if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList())
- {
- continue;
- }
-
if (drawable->isState(LLDrawable::ACTIVE))
{
mLightMovingMask |= (1<<cur_light);
@@ -6403,6 +6443,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setSpecular(specular);
}
else // omnidirectional (point) light
+
{
light_state->setSpotExponent(0.f);
light_state->setSpotCutoff(180.f);
@@ -8722,47 +8763,51 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
- if (!volume)
- {
- continue;
- }
-
- if (volume->isAttachment())
- {
- if (!sRenderAttachedLights)
- {
- continue;
- }
- }
+ // mNearbyLights already includes distance calculation and excludes muted avatars.
+ // It is calculated from mLights
+ // mNearbyLights also provides fade value to gracefully fade-out out of range lights
+ for (light_set_t::iterator iter = mNearbyLights.begin(); iter != mNearbyLights.end(); ++iter)
+ {
+ LLDrawable* drawablep = iter->drawable;
+ LLVOVolume* volume = drawablep->getVOVolume();
+ if (!volume)
+ {
+ continue;
+ }
- const LLViewerObject *vobj = drawablep->getVObj();
- if (vobj)
+ if (volume->isAttachment())
{
- LLVOAvatar *av = vobj->getAvatar();
- if (av && (av->isTooComplex() || av->isInMuteList()))
+ if (!sRenderAttachedLights)
{
continue;
}
}
- const LLVector3 position = drawablep->getPositionAgent();
- if (dist_vec(position, LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip + volume->getLightRadius())
- {
- continue;
- }
-
LLVector4a center;
- center.load3(position.mV);
+ center.load3(drawablep->getPositionAgent().mV);
const F32* c = center.getF32ptr();
F32 s = volume->getLightRadius()*1.5f;
//send light color to shader in linear space
LLColor3 col = volume->getLightLinearColor();
+
+ // fade also works as flicker prevention during reparenting
+ // because reparenting causes distance to jump temporary
+ F32 fade = iter->fade;
+ if (fade < LIGHT_FADE_TIME)
+ {
+ // fade in/out light
+ if (fade >= 0.f)
+ {
+ fade = fade / LIGHT_FADE_TIME;
+ }
+ else
+ {
+ fade = 1.f + fade / LIGHT_FADE_TIME;
+ }
+ fade = llclamp(fade, 0.f, 1.f);
+ col *= fade;
+ }
if (col.magVecSquared() < 0.001f)
{