SL-17574 Add probe detail combo box to advanced graphics preferences. Fix spot light shadows not working in probes.
parent
03d85bfb33
commit
509476f95e
|
|
@ -473,6 +473,8 @@ void LLRenderTarget::release()
|
|||
|
||||
void LLRenderTarget::bindTarget()
|
||||
{
|
||||
llassert(mFBO);
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
stop_glerror();
|
||||
|
|
@ -514,6 +516,7 @@ void LLRenderTarget::bindTarget()
|
|||
void LLRenderTarget::clear(U32 mask_in)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("clear");
|
||||
llassert(mFBO);
|
||||
U32 mask = GL_COLOR_BUFFER_BIT;
|
||||
if (mUseDepth)
|
||||
{
|
||||
|
|
@ -579,6 +582,7 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt
|
|||
void LLRenderTarget::flush(bool fetch_depth)
|
||||
{
|
||||
gGL.flush();
|
||||
llassert(mFBO);
|
||||
if (!mFBO)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
|
|
|
|||
|
|
@ -10280,6 +10280,17 @@
|
|||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>RenderReflectionProbeDetail</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Detail of reflections.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
|
||||
<key>RenderReflectionProbeDrawDistance</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ bool isAbove(vec3 pos, vec4 plane)
|
|||
return (dot(plane.xyz, pos) + plane.w) > 0;
|
||||
}
|
||||
|
||||
int max_priority = 0;
|
||||
|
||||
// return true if probe at index i influences position pos
|
||||
bool shouldSampleProbe(int i, vec3 pos)
|
||||
{
|
||||
|
|
@ -86,6 +88,8 @@ bool shouldSampleProbe(int i, vec3 pos)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
max_priority = max(max_priority, -refIndex[i].w);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -98,6 +102,8 @@ bool shouldSampleProbe(int i, vec3 pos)
|
|||
{ //outside bounding sphere
|
||||
return false;
|
||||
}
|
||||
|
||||
max_priority = max(max_priority, refIndex[i].w);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -343,8 +349,13 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
|
|||
for (int idx = 0; idx < probeInfluences; ++idx)
|
||||
{
|
||||
int i = probeIndex[idx];
|
||||
if (refIndex[i].w < max_priority)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float r = refSphere[i].w; // radius of sphere volume
|
||||
float p = float(abs(refIndex[i].w)); // priority
|
||||
|
||||
float rr = r*r; // radius squred
|
||||
float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
|
||||
vec3 delta = pos.xyz-refSphere[i].xyz;
|
||||
|
|
@ -358,7 +369,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight)
|
|||
|
||||
float atten = 1.0-max(d2-r2, 0.0)/(rr-r2);
|
||||
w *= atten;
|
||||
w *= p; // boost weight based on priority
|
||||
//w *= p; // boost weight based on priority
|
||||
col += refcol*w*max(minweight, refParams[i].x);
|
||||
|
||||
wsum += w;
|
||||
|
|
|
|||
|
|
@ -152,8 +152,6 @@ BOOL LLPanelVolume::postBuild()
|
|||
childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
|
||||
childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
|
||||
childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// PHYSICS Parameters
|
||||
|
|
@ -695,7 +693,7 @@ void LLPanelVolume::clearCtrls()
|
|||
getChildView("Light Radius")->setEnabled(false);
|
||||
getChildView("Light Falloff")->setEnabled(false);
|
||||
|
||||
getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(false);;
|
||||
getChildView("Reflection Probe")->setEnabled(false);;
|
||||
getChildView("Probe Volume Type")->setEnabled(false);
|
||||
getChildView("Probe Dynamic")->setEnabled(false);
|
||||
getChildView("Probe Ambiance")->setEnabled(false);
|
||||
|
|
@ -746,7 +744,7 @@ void LLPanelVolume::sendIsReflectionProbe()
|
|||
}
|
||||
LLVOVolume* volobjp = (LLVOVolume*)objectp;
|
||||
|
||||
BOOL value = getChild<LLUICtrl>("Reflection Probe Checkbox Ctrl")->getValue();
|
||||
BOOL value = getChild<LLUICtrl>("Reflection Probe")->getValue();
|
||||
volobjp->setIsReflectionProbe(value);
|
||||
LL_INFOS() << "update reflection probe sent" << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,28 +54,6 @@ void LLReflectionMap::update(U32 resolution, U32 face)
|
|||
gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic());
|
||||
}
|
||||
|
||||
bool LLReflectionMap::shouldUpdate()
|
||||
{
|
||||
const F32 TIMEOUT_INTERVAL = 30.f; // update no less than this often
|
||||
const F32 RENDER_TIMEOUT = 1.f; // don't update if hasn't been used for rendering for this long
|
||||
|
||||
if (mLastBindTime > gFrameTimeSeconds - RENDER_TIMEOUT)
|
||||
{
|
||||
if (mLastUpdateTime < gFrameTimeSeconds - TIMEOUT_INTERVAL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLReflectionMap::dirty()
|
||||
{
|
||||
mDirty = true;
|
||||
mLastUpdateTime = gFrameTimeSeconds;
|
||||
}
|
||||
|
||||
void LLReflectionMap::autoAdjustOrigin()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
|
|
@ -245,7 +223,9 @@ F32 LLReflectionMap::getNearClip()
|
|||
|
||||
bool LLReflectionMap::getIsDynamic()
|
||||
{
|
||||
if (mViewerObject && mViewerObject->getVolume())
|
||||
if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
|
||||
mViewerObject &&
|
||||
mViewerObject->getVolume())
|
||||
{
|
||||
return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,6 @@ public:
|
|||
// resolution - size of cube map to generate
|
||||
void update(U32 resolution, U32 face);
|
||||
|
||||
// return true if this probe should update *now*
|
||||
bool shouldUpdate();
|
||||
|
||||
// Mark this reflection map as needing an update (resets last update time, so spamming this call will cause a cube map to never update)
|
||||
void dirty();
|
||||
|
||||
// for volume partition probes, try to place this probe in the best spot
|
||||
void autoAdjustOrigin();
|
||||
|
||||
|
|
@ -104,7 +98,5 @@ public:
|
|||
|
||||
// what priority should this probe have (higher is higher priority)
|
||||
U32 mPriority = 1;
|
||||
|
||||
bool mDirty = true;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -96,11 +96,13 @@ void LLReflectionMapManager::update()
|
|||
mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE);
|
||||
|
||||
// hack to allocate render targets using gPipeline code
|
||||
gCubeSnapshot = TRUE;
|
||||
auto* old_rt = gPipeline.mRT;
|
||||
gPipeline.mRT = &gProbeRT;
|
||||
gPipeline.allocateScreenBuffer(targetRes, targetRes);
|
||||
gPipeline.allocateShadowBuffer(targetRes, targetRes);
|
||||
gPipeline.mRT = old_rt;
|
||||
gCubeSnapshot = FALSE;
|
||||
}
|
||||
|
||||
if (mMipChain.empty())
|
||||
|
|
@ -154,6 +156,10 @@ void LLReflectionMapManager::update()
|
|||
|
||||
bool did_update = false;
|
||||
|
||||
bool realtime = gSavedSettings.getS32("RenderReflectionProbeDetail") >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
|
||||
|
||||
LLReflectionMap* closestDynamic = nullptr;
|
||||
|
||||
LLReflectionMap* oldestProbe = nullptr;
|
||||
|
||||
if (mUpdatingProbe != nullptr)
|
||||
|
|
@ -183,11 +189,30 @@ void LLReflectionMapManager::update()
|
|||
oldestProbe = probe;
|
||||
}
|
||||
|
||||
if (realtime &&
|
||||
closestDynamic == nullptr &&
|
||||
probe->mCubeArray.notNull() &&
|
||||
probe->getIsDynamic())
|
||||
{
|
||||
closestDynamic = probe;
|
||||
}
|
||||
|
||||
d.setSub(camera_pos, probe->mOrigin);
|
||||
probe->mDistance = d.getLength3().getF32()-probe->mRadius;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (realtime && closestDynamic != nullptr)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime");
|
||||
// update the closest dynamic probe realtime
|
||||
closestDynamic->autoAdjustOrigin();
|
||||
for (U32 i = 0; i < 6; ++i)
|
||||
{
|
||||
updateProbeFace(closestDynamic, i);
|
||||
}
|
||||
}
|
||||
|
||||
// switch to updating the next oldest probe
|
||||
if (!did_update && oldestProbe != nullptr)
|
||||
{
|
||||
LLReflectionMap* probe = oldestProbe;
|
||||
|
|
@ -201,9 +226,7 @@ void LLReflectionMapManager::update()
|
|||
|
||||
mUpdatingProbe = probe;
|
||||
doProbeUpdate();
|
||||
probe->mDirty = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// update distance to camera for all probes
|
||||
std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());
|
||||
|
|
@ -214,7 +237,6 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
|
|||
LLReflectionMap* probe = new LLReflectionMap();
|
||||
probe->mGroup = group;
|
||||
probe->mOrigin = group->getOctreeNode()->getCenter();
|
||||
probe->mDirty = true;
|
||||
|
||||
if (gCubeSnapshot)
|
||||
{ //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
|
||||
|
|
@ -295,7 +317,6 @@ LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vo
|
|||
LLReflectionMap* probe = new LLReflectionMap();
|
||||
probe->mViewerObject = vobj;
|
||||
probe->mOrigin.load3(vobj->getPositionAgent().mV);
|
||||
probe->mDirty = true;
|
||||
|
||||
if (gCubeSnapshot)
|
||||
{ //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
|
||||
|
|
@ -368,10 +389,23 @@ void LLReflectionMapManager::doProbeUpdate()
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
llassert(mUpdatingProbe != nullptr);
|
||||
|
||||
updateProbeFace(mUpdatingProbe, mUpdatingFace);
|
||||
|
||||
if (++mUpdatingFace == 6)
|
||||
{
|
||||
updateNeighbors(mUpdatingProbe);
|
||||
mUpdatingProbe = nullptr;
|
||||
mUpdatingFace = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
|
||||
{
|
||||
mRenderTarget.bindTarget();
|
||||
// hacky hot-swap of camera specific render targets
|
||||
auto* old_rt = gPipeline.mRT;
|
||||
gPipeline.mRT = &gProbeRT;
|
||||
mUpdatingProbe->update(mRenderTarget.getWidth(), mUpdatingFace);
|
||||
probe->update(mRenderTarget.getWidth(), face);
|
||||
gPipeline.mRT = old_rt;
|
||||
mRenderTarget.flush();
|
||||
|
||||
|
|
@ -390,9 +424,9 @@ void LLReflectionMapManager::doProbeUpdate()
|
|||
gGL.loadIdentity();
|
||||
|
||||
gGL.flush();
|
||||
U32 res = LL_REFLECTION_PROBE_RESOLUTION*2;
|
||||
U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2;
|
||||
|
||||
S32 mips = log2((F32) LL_REFLECTION_PROBE_RESOLUTION)+0.5f;
|
||||
S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
|
||||
|
||||
for (int i = 0; i < mMipChain.size(); ++i)
|
||||
{
|
||||
|
|
@ -409,10 +443,10 @@ void LLReflectionMapManager::doProbeUpdate()
|
|||
}
|
||||
|
||||
gGL.begin(gGL.QUADS);
|
||||
|
||||
|
||||
gGL.texCoord2f(0, 0);
|
||||
gGL.vertex2f(-1, -1);
|
||||
|
||||
|
||||
gGL.texCoord2f(res, 0);
|
||||
gGL.vertex2f(1, -1);
|
||||
|
||||
|
|
@ -431,7 +465,7 @@ void LLReflectionMapManager::doProbeUpdate()
|
|||
if (mip >= 0)
|
||||
{
|
||||
mTexture->bind(0);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, mUpdatingProbe->mCubeIndex * 6 + mUpdatingFace, 0, 0, res, res);
|
||||
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
|
||||
mTexture->unbind();
|
||||
}
|
||||
mMipChain[i].flush();
|
||||
|
|
@ -443,13 +477,6 @@ void LLReflectionMapManager::doProbeUpdate()
|
|||
|
||||
gReflectionMipProgram.unbind();
|
||||
}
|
||||
|
||||
if (++mUpdatingFace == 6)
|
||||
{
|
||||
updateNeighbors(mUpdatingProbe);
|
||||
mUpdatingProbe = nullptr;
|
||||
mUpdatingFace = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLReflectionMapManager::rebuild()
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ class alignas(16) LLReflectionMapManager
|
|||
{
|
||||
LL_ALIGN_NEW
|
||||
public:
|
||||
enum class DetailLevel
|
||||
{
|
||||
STATIC_ONLY = 0,
|
||||
STATIC_AND_DYNAMIC,
|
||||
REALTIME = 2
|
||||
};
|
||||
|
||||
// allocate an environment map of the given resolution
|
||||
LLReflectionMapManager();
|
||||
|
||||
|
|
@ -115,6 +122,9 @@ private:
|
|||
|
||||
// perform an update on the currently updating Probe
|
||||
void doProbeUpdate();
|
||||
|
||||
// update the specified face of the specified probe
|
||||
void updateProbeFace(LLReflectionMap* probe, U32 face);
|
||||
|
||||
// list of active reflection maps
|
||||
std::vector<LLPointer<LLReflectionMap> > mProbes;
|
||||
|
|
@ -133,6 +143,5 @@ private:
|
|||
|
||||
LLReflectionMap* mUpdatingProbe = nullptr;
|
||||
U32 mUpdatingFace = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -738,17 +738,8 @@ BOOL LLSpatialGroup::changeLOD()
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void LLSpatialGroup::dirtyReflectionProbe()
|
||||
{
|
||||
if (mReflectionProbe != nullptr)
|
||||
{
|
||||
mReflectionProbe->dirty();
|
||||
}
|
||||
}
|
||||
|
||||
void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry)
|
||||
{
|
||||
dirtyReflectionProbe();
|
||||
addObject((LLDrawable*)entry->getDrawable());
|
||||
unbound();
|
||||
setState(OBJECT_DIRTY);
|
||||
|
|
@ -756,7 +747,6 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry*
|
|||
|
||||
void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry)
|
||||
{
|
||||
dirtyReflectionProbe();
|
||||
removeObject((LLDrawable*)entry->getDrawable(), TRUE);
|
||||
LLViewerOctreeGroup::handleRemoval(node, entry);
|
||||
}
|
||||
|
|
@ -793,8 +783,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL
|
||||
|
||||
dirtyReflectionProbe();
|
||||
|
||||
if (child->getListenerCount() == 0)
|
||||
{
|
||||
new LLSpatialGroup(child, getSpatialPartition());
|
||||
|
|
@ -809,11 +797,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
|
|||
assert_states_valid(this);
|
||||
}
|
||||
|
||||
void LLSpatialGroup::handleChildRemoval(const oct_node* parent, const oct_node* child)
|
||||
{
|
||||
dirtyReflectionProbe();
|
||||
}
|
||||
|
||||
void LLSpatialGroup::destroyGL(bool keep_occlusion)
|
||||
{
|
||||
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
|
||||
|
|
|
|||
|
|
@ -333,7 +333,6 @@ public:
|
|||
virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);
|
||||
virtual void handleDestruction(const TreeNode* node);
|
||||
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
|
||||
virtual void handleChildRemoval(const oct_node* parent, const oct_node* child);
|
||||
|
||||
public:
|
||||
LL_ALIGN_16(LLVector4a mViewAngle);
|
||||
|
|
@ -341,8 +340,6 @@ public:
|
|||
|
||||
F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
|
||||
|
||||
void dirtyReflectionProbe();
|
||||
|
||||
protected:
|
||||
virtual ~LLSpatialGroup();
|
||||
|
||||
|
|
|
|||
|
|
@ -47,15 +47,14 @@ public:
|
|||
typedef enum
|
||||
{
|
||||
CAMERA_WORLD = 0,
|
||||
CAMERA_SHADOW0,
|
||||
CAMERA_SHADOW1,
|
||||
CAMERA_SHADOW2,
|
||||
CAMERA_SHADOW3,
|
||||
CAMERA_SHADOW4,
|
||||
CAMERA_SHADOW5,
|
||||
CAMERA_SUN_SHADOW0,
|
||||
CAMERA_SUN_SHADOW1,
|
||||
CAMERA_SUN_SHADOW2,
|
||||
CAMERA_SUN_SHADOW3,
|
||||
CAMERA_SPOT_SHADOW0,
|
||||
CAMERA_SPOT_SHADOW1,
|
||||
CAMERA_WATER0,
|
||||
CAMERA_WATER1,
|
||||
CAMERA_GI_SOURCE,
|
||||
NUM_CAMERAS
|
||||
} eCameraID;
|
||||
|
||||
|
|
|
|||
|
|
@ -739,7 +739,8 @@ void LLPipeline::requestResizeShadowTexture()
|
|||
|
||||
void LLPipeline::resizeShadowTexture()
|
||||
{
|
||||
releaseShadowTargets();
|
||||
releaseSunShadowTargets();
|
||||
releaseSpotShadowTargets();
|
||||
allocateShadowBuffer(mRT->width, mRT->height);
|
||||
gResizeShadowTexture = FALSE;
|
||||
}
|
||||
|
|
@ -754,7 +755,8 @@ void LLPipeline::resizeScreenTexture()
|
|||
if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))
|
||||
{
|
||||
releaseScreenBuffers();
|
||||
releaseShadowTargets();
|
||||
releaseSunShadowTargets();
|
||||
releaseSpotShadowTargets();
|
||||
allocateScreenBuffer(resX,resY);
|
||||
gResizeScreenTexture = FALSE;
|
||||
}
|
||||
|
|
@ -913,7 +915,8 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
{
|
||||
mRT->deferredLight.release();
|
||||
|
||||
releaseShadowTargets();
|
||||
releaseSunShadowTargets();
|
||||
releaseSpotShadowTargets();
|
||||
|
||||
mRT->fxaaBuffer.release();
|
||||
mRT->screen.release();
|
||||
|
|
@ -942,66 +945,66 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0
|
|||
bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
S32 shadow_detail = RenderShadowDetail;
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
S32 shadow_detail = RenderShadowDetail;
|
||||
|
||||
const U32 occlusion_divisor = 3;
|
||||
const U32 occlusion_divisor = 3;
|
||||
|
||||
F32 scale = llmax(0.f,RenderShadowResolutionScale);
|
||||
U32 sun_shadow_map_width = BlurHappySize(resX, scale);
|
||||
U32 sun_shadow_map_height = BlurHappySize(resY, scale);
|
||||
F32 scale = llmax(0.f, RenderShadowResolutionScale);
|
||||
U32 sun_shadow_map_width = BlurHappySize(resX, scale);
|
||||
U32 sun_shadow_map_height = BlurHappySize(resY, scale);
|
||||
|
||||
if (shadow_detail > 0)
|
||||
{ //allocate 4 sun shadow maps
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
|
||||
if (shadow_detail > 0)
|
||||
{ //allocate 4 sun shadow maps
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
|
||||
if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
releaseShadowTarget(i);
|
||||
}
|
||||
}
|
||||
|
||||
U32 width = (U32) (resX*scale);
|
||||
U32 height = width;
|
||||
|
||||
if (shadow_detail > 1)
|
||||
{ //allocate two spot shadow maps
|
||||
U32 spot_shadow_map_width = width;
|
||||
U32 spot_shadow_map_height = height;
|
||||
for (U32 i = 4; i < 6; i++)
|
||||
{
|
||||
if (!mRT->shadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!mRT->shadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 4; i < 6; i++)
|
||||
{
|
||||
releaseShadowTarget(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
releaseSunShadowTarget(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gCubeSnapshot) // hack to not allocate spot shadow maps during ReflectionMapManager init
|
||||
{
|
||||
U32 width = (U32)(resX * scale);
|
||||
U32 height = width;
|
||||
|
||||
if (shadow_detail > 1)
|
||||
{ //allocate two spot shadow maps
|
||||
U32 spot_shadow_map_width = width;
|
||||
U32 spot_shadow_map_height = height;
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
{
|
||||
if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
releaseSpotShadowTargets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1175,7 +1178,8 @@ void LLPipeline::releaseLUTBuffers()
|
|||
|
||||
void LLPipeline::releaseShadowBuffers()
|
||||
{
|
||||
releaseShadowTargets();
|
||||
releaseSunShadowTargets();
|
||||
releaseSpotShadowTargets();
|
||||
}
|
||||
|
||||
void LLPipeline::releaseScreenBuffers()
|
||||
|
|
@ -1191,20 +1195,33 @@ void LLPipeline::releaseScreenBuffers()
|
|||
}
|
||||
|
||||
|
||||
void LLPipeline::releaseShadowTarget(U32 index)
|
||||
void LLPipeline::releaseSunShadowTarget(U32 index)
|
||||
{
|
||||
llassert(index < 4);
|
||||
mRT->shadow[index].release();
|
||||
mRT->shadowOcclusion[index].release();
|
||||
}
|
||||
|
||||
void LLPipeline::releaseShadowTargets()
|
||||
void LLPipeline::releaseSunShadowTargets()
|
||||
{
|
||||
for (U32 i = 0; i < 6; i++)
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
releaseShadowTarget(i);
|
||||
releaseSunShadowTarget(i);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPipeline::releaseSpotShadowTargets()
|
||||
{
|
||||
if (!gCubeSnapshot) // hack to avoid freeing spot shadows during ReflectionMapManager init
|
||||
{
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
{
|
||||
mSpotShadow[i].release();
|
||||
mSpotShadowOcclusion[i].release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPipeline::createGLBuffers()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
|
||||
|
|
@ -8162,7 +8179,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
LLRenderTarget* shadow_target = getShadowTarget(i);
|
||||
LLRenderTarget* shadow_target = getSunShadowTarget(i);
|
||||
if (shadow_target)
|
||||
{
|
||||
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
|
||||
|
|
@ -8170,7 +8187,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
if (channel > -1)
|
||||
{
|
||||
stop_glerror();
|
||||
gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE);
|
||||
gGL.getTexUnit(channel)->bind(getSunShadowTarget(i), TRUE);
|
||||
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
||||
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
|
|
@ -8182,27 +8199,27 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
}
|
||||
}
|
||||
|
||||
for (U32 i = 4; i < 6; i++)
|
||||
{
|
||||
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i);
|
||||
stop_glerror();
|
||||
if (channel > -1)
|
||||
{
|
||||
stop_glerror();
|
||||
LLRenderTarget* shadow_target = getShadowTarget(i);
|
||||
if (shadow_target)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
|
||||
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
||||
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (U32 i = 4; i < 6; i++)
|
||||
{
|
||||
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0 + i);
|
||||
stop_glerror();
|
||||
if (channel > -1)
|
||||
{
|
||||
stop_glerror();
|
||||
LLRenderTarget* shadow_target = getSpotShadowTarget(i-4);
|
||||
if (shadow_target)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
|
||||
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
||||
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -8313,7 +8330,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
|
|||
shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
|
||||
shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV);
|
||||
shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight());
|
||||
shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mRT->shadow[4].getWidth(), mRT->shadow[4].getHeight());
|
||||
shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
|
||||
shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
|
||||
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
|
||||
|
||||
|
|
@ -9077,7 +9094,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
|
|||
shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
|
||||
}
|
||||
|
||||
if (!gCubeSnapshot)
|
||||
//if (!gCubeSnapshot)
|
||||
{
|
||||
LLDrawable* potential = drawablep;
|
||||
//determine if this is a good light for casting shadows
|
||||
|
|
@ -9668,7 +9685,9 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
|
|||
gDeferredShadowCubeProgram.bind();
|
||||
}
|
||||
|
||||
LLRenderTarget& occlusion_target = mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - 1];
|
||||
LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
|
||||
mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
|
||||
mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
|
||||
|
||||
occlusion_target.bindTarget();
|
||||
updateCull(shadow_cam, result);
|
||||
|
|
@ -9812,7 +9831,9 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
|
|||
gGLLastMatrix = NULL;
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
|
||||
LLRenderTarget& occlusion_source = mRT->shadow[LLViewerCamera::sCurCameraID - 1];
|
||||
LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
|
||||
mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
|
||||
mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
|
||||
|
||||
if (occlude > 1)
|
||||
{
|
||||
|
|
@ -10087,11 +10108,18 @@ void LLPipeline::generateHighlight(LLCamera& camera)
|
|||
}
|
||||
}
|
||||
|
||||
LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
|
||||
LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i)
|
||||
{
|
||||
llassert(i < 4);
|
||||
return &mRT->shadow[i];
|
||||
}
|
||||
|
||||
LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i)
|
||||
{
|
||||
llassert(i < 2);
|
||||
return &mSpotShadow[i];
|
||||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
|
||||
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render");
|
||||
|
||||
|
|
@ -10371,7 +10399,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
mShadowFrustPoints[j].clear();
|
||||
}
|
||||
|
||||
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
|
||||
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j);
|
||||
|
||||
//restore render matrices
|
||||
set_current_modelview(saved_view);
|
||||
|
|
@ -10745,116 +10773,119 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
{
|
||||
if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
|
||||
{
|
||||
LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
|
||||
F32 fade_amt = gFrameIntervalSeconds.value()
|
||||
* llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
|
||||
LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
|
||||
F32 fade_amt = gFrameIntervalSeconds.value()
|
||||
* llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
|
||||
|
||||
//update shadow targets
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
{ //for each current shadow
|
||||
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
|
||||
//update shadow targets
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
{ //for each current shadow
|
||||
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
|
||||
|
||||
if (mShadowSpotLight[i].notNull() &&
|
||||
(mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
|
||||
mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
|
||||
{ //keep this spotlight
|
||||
mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
|
||||
}
|
||||
else
|
||||
{ //fade out this light
|
||||
mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
|
||||
|
||||
if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
|
||||
{ //faded out, grab one of the pending spots (whichever one isn't already taken)
|
||||
if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
|
||||
{
|
||||
mShadowSpotLight[i] = mTargetShadowSpotLight[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
mShadowSpotLight[i] = mTargetShadowSpotLight[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mShadowSpotLight[i].notNull() &&
|
||||
(mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
|
||||
mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
|
||||
{ //keep this spotlight
|
||||
mSpotLightFade[i] = llmin(mSpotLightFade[i] + fade_amt, 1.f);
|
||||
}
|
||||
else
|
||||
{ //fade out this light
|
||||
mSpotLightFade[i] = llmax(mSpotLightFade[i] - fade_amt, 0.f);
|
||||
|
||||
for (S32 i = 0; i < 2; i++)
|
||||
if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
|
||||
{ //faded out, grab one of the pending spots (whichever one isn't already taken)
|
||||
if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i + 1) % 2])
|
||||
{
|
||||
mShadowSpotLight[i] = mTargetShadowSpotLight[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
mShadowSpotLight[i] = mTargetShadowSpotLight[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < 2; i++)
|
||||
{
|
||||
set_current_modelview(saved_view);
|
||||
set_current_projection(saved_proj);
|
||||
|
||||
if (mShadowSpotLight[i].isNull())
|
||||
{
|
||||
set_current_modelview(saved_view);
|
||||
set_current_projection(saved_proj);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mShadowSpotLight[i].isNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
|
||||
|
||||
LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
|
||||
if (!volume)
|
||||
{
|
||||
mShadowSpotLight[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!volume)
|
||||
{
|
||||
mShadowSpotLight[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
LLDrawable* drawable = mShadowSpotLight[i];
|
||||
|
||||
LLDrawable* drawable = mShadowSpotLight[i];
|
||||
LLVector3 params = volume->getSpotLightParams();
|
||||
F32 fov = params.mV[0];
|
||||
|
||||
LLVector3 params = volume->getSpotLightParams();
|
||||
F32 fov = params.mV[0];
|
||||
//get agent->light space matrix (modelview)
|
||||
LLVector3 center = drawable->getPositionAgent();
|
||||
LLQuaternion quat = volume->getRenderRotation();
|
||||
|
||||
//get agent->light space matrix (modelview)
|
||||
LLVector3 center = drawable->getPositionAgent();
|
||||
LLQuaternion quat = volume->getRenderRotation();
|
||||
//get near clip plane
|
||||
LLVector3 scale = volume->getScale();
|
||||
LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f);
|
||||
at_axis *= quat;
|
||||
|
||||
//get near clip plane
|
||||
LLVector3 scale = volume->getScale();
|
||||
LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f);
|
||||
at_axis *= quat;
|
||||
LLVector3 np = center + at_axis;
|
||||
at_axis.normVec();
|
||||
|
||||
LLVector3 np = center + at_axis;
|
||||
at_axis.normVec();
|
||||
//get origin that has given fov for plane np, at_axis, and given scale
|
||||
F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f);
|
||||
|
||||
//get origin that has given fov for plane np, at_axis, and given scale
|
||||
F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f);
|
||||
LLVector3 origin = np - at_axis * dist;
|
||||
|
||||
LLVector3 origin = np - at_axis * dist;
|
||||
LLMatrix4 mat(quat, LLVector4(origin, 1.f));
|
||||
|
||||
LLMatrix4 mat(quat, LLVector4(origin, 1.f));
|
||||
view[i + 4] = glh::matrix4f((F32*)mat.mMatrix);
|
||||
|
||||
view[i + 4] = glh::matrix4f((F32*)mat.mMatrix);
|
||||
view[i + 4] = view[i + 4].inverse();
|
||||
|
||||
view[i + 4] = view[i + 4].inverse();
|
||||
//get perspective matrix
|
||||
F32 near_clip = dist + 0.01f;
|
||||
F32 width = scale.mV[VX];
|
||||
F32 height = scale.mV[VY];
|
||||
F32 far_clip = dist + volume->getLightRadius() * 1.5f;
|
||||
|
||||
//get perspective matrix
|
||||
F32 near_clip = dist + 0.01f;
|
||||
F32 width = scale.mV[VX];
|
||||
F32 height = scale.mV[VY];
|
||||
F32 far_clip = dist + volume->getLightRadius() * 1.5f;
|
||||
F32 fovy = fov * RAD_TO_DEG;
|
||||
F32 aspect = width / height;
|
||||
|
||||
F32 fovy = fov * RAD_TO_DEG;
|
||||
F32 aspect = width / height;
|
||||
proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip);
|
||||
|
||||
proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip);
|
||||
//translate and scale to from [-1, 1] to [0, 1]
|
||||
glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
|
||||
0.f, 0.5f, 0.f, 0.5f,
|
||||
0.f, 0.f, 0.5f, 0.5f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
//translate and scale to from [-1, 1] to [0, 1]
|
||||
glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
|
||||
0.f, 0.5f, 0.f, 0.5f,
|
||||
0.f, 0.f, 0.5f, 0.5f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
set_current_modelview(view[i + 4]);
|
||||
set_current_projection(proj[i + 4]);
|
||||
|
||||
set_current_modelview(view[i + 4]);
|
||||
set_current_projection(proj[i + 4]);
|
||||
mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view;
|
||||
|
||||
mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view;
|
||||
for (U32 j = 0; j < 16; j++)
|
||||
{
|
||||
gGLLastModelView[j] = mShadowModelview[i + 4].m[j];
|
||||
gGLLastProjection[j] = mShadowProjection[i + 4].m[j];
|
||||
}
|
||||
|
||||
for (U32 j = 0; j < 16; j++)
|
||||
{
|
||||
gGLLastModelView[j] = mShadowModelview[i + 4].m[j];
|
||||
gGLLastProjection[j] = mShadowProjection[i + 4].m[j];
|
||||
}
|
||||
|
||||
mShadowModelview[i + 4] = view[i + 4];
|
||||
mShadowProjection[i + 4] = proj[i + 4];
|
||||
mShadowModelview[i + 4] = view[i + 4];
|
||||
mShadowProjection[i + 4] = proj[i + 4];
|
||||
|
||||
if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
|
||||
{
|
||||
LLCamera shadow_cam = camera;
|
||||
shadow_cam.setFar(far_clip);
|
||||
shadow_cam.setOrigin(origin);
|
||||
|
|
@ -10863,15 +10894,17 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
|
||||
stop_glerror();
|
||||
|
||||
mRT->shadow[i + 4].bindTarget();
|
||||
mRT->shadow[i + 4].getViewport(gGLViewport);
|
||||
mRT->shadow[i + 4].clear();
|
||||
//
|
||||
|
||||
mSpotShadow[i].bindTarget();
|
||||
mSpotShadow[i].getViewport(gGLViewport);
|
||||
mSpotShadow[i].clear();
|
||||
|
||||
U32 target_width = mRT->shadow[i + 4].getWidth();
|
||||
U32 target_width = mSpotShadow[i].getWidth();
|
||||
|
||||
static LLCullResult result[2];
|
||||
|
||||
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
|
||||
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
|
||||
|
||||
RenderSpotLight = drawable;
|
||||
|
||||
|
|
@ -10879,7 +10912,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|
|||
|
||||
RenderSpotLight = nullptr;
|
||||
|
||||
mRT->shadow[i + 4].flush();
|
||||
mSpotShadow[i].flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,8 +218,9 @@ public:
|
|||
U32 addObject(LLViewerObject *obj);
|
||||
|
||||
void enableShadows(const bool enable_shadows);
|
||||
void releaseShadowTargets();
|
||||
void releaseShadowTarget(U32 index);
|
||||
void releaseSpotShadowTargets();
|
||||
void releaseSunShadowTargets();
|
||||
void releaseSunShadowTarget(U32 index);
|
||||
|
||||
// void setLocalLighting(const bool local_lighting);
|
||||
// bool isLocalLightingEnabled() const;
|
||||
|
|
@ -304,7 +305,8 @@ public:
|
|||
|
||||
void generateWaterReflection(LLCamera& camera);
|
||||
void generateSunShadow(LLCamera& camera);
|
||||
LLRenderTarget* getShadowTarget(U32 i);
|
||||
LLRenderTarget* getSunShadowTarget(U32 i);
|
||||
LLRenderTarget* getSpotShadowTarget(U32 i);
|
||||
|
||||
void generateHighlight(LLCamera& camera);
|
||||
void renderHighlight(const LLViewerObject* obj, F32 fade);
|
||||
|
|
@ -660,12 +662,15 @@ public:
|
|||
LLRenderTarget deferredLight;
|
||||
|
||||
//sun shadow map
|
||||
LLRenderTarget shadow[6];
|
||||
LLRenderTarget shadowOcclusion[6];
|
||||
LLRenderTarget shadow[4];
|
||||
LLRenderTarget shadowOcclusion[4];
|
||||
};
|
||||
|
||||
RenderTargetPack* mRT;
|
||||
|
||||
LLRenderTarget mSpotShadow[2];
|
||||
LLRenderTarget mSpotShadowOcclusion[2];
|
||||
|
||||
LLRenderTarget mHighlight;
|
||||
LLRenderTarget mPhysicsDisplay;
|
||||
|
||||
|
|
@ -688,6 +693,7 @@ public:
|
|||
LLVector3 mShadowFrustOrigin[4];
|
||||
LLCamera mShadowCamera[8];
|
||||
LLVector3 mShadowExtents[4][2];
|
||||
// TODO : separate Sun Shadow and Spot Shadow matrices
|
||||
glh::matrix4f mSunShadowMatrix[6];
|
||||
glh::matrix4f mShadowModelview[6];
|
||||
glh::matrix4f mShadowProjection[6];
|
||||
|
|
|
|||
|
|
@ -863,8 +863,42 @@
|
|||
name="2"
|
||||
value="2"/>
|
||||
</combo_box>
|
||||
|
||||
<!-- End of Advanced Settings block -->
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="480"
|
||||
name="RenderReflectionDetailText"
|
||||
text_readonly_color="LabelDisabledColor"
|
||||
top_delta="16"
|
||||
width="128">
|
||||
Reflections:
|
||||
</text>
|
||||
<combo_box
|
||||
control_name="RenderReflectionProbeDetail"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left_delta="130"
|
||||
top_delta="0"
|
||||
name="ReflectionDetial"
|
||||
width="150">
|
||||
<combo_box.item
|
||||
label="Static Only"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="Static+Dynamic"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="Realtime"
|
||||
name="2"
|
||||
value="2"/>
|
||||
</combo_box>
|
||||
|
||||
<!-- End of Advanced Settings block -->
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue