summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llrender/llgl.cpp3
-rw-r--r--indra/llrender/llrender.cpp7
-rw-r--r--indra/llrender/llrender.h2
-rw-r--r--indra/llrender/llrendertarget.cpp786
-rw-r--r--indra/llrender/llrendertarget.h33
-rw-r--r--indra/llrender/llshadermgr.cpp8
-rw-r--r--indra/llrender/llshadermgr.h6
-rw-r--r--indra/llrender/llvertexbuffer.cpp2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflPostF.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl101
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl150
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl104
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl10
-rw-r--r--indra/newview/llfasttimerview.cpp2
-rw-r--r--indra/newview/llglsandbox.cpp2
-rw-r--r--indra/newview/llreflectionmapmanager.cpp40
-rw-r--r--indra/newview/llscenemonitor.cpp6
-rw-r--r--indra/newview/llviewercontrol.cpp1
-rw-r--r--indra/newview/llviewerdisplay.cpp9
-rw-r--r--indra/newview/llviewershadermgr.cpp8
-rw-r--r--indra/newview/llviewerwindow.cpp6
-rw-r--r--indra/newview/pipeline.cpp172
-rw-r--r--indra/newview/pipeline.h4
31 files changed, 793 insertions, 798 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 72d9c14ccf..c08c576531 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2270,7 +2270,7 @@ void do_assert_glerror()
GLenum error;
error = glGetError();
BOOL quit = FALSE;
- while (LL_UNLIKELY(error))
+ if (LL_UNLIKELY(error))
{
quit = TRUE;
GLubyte const * gl_error_msg = gluErrorString(error);
@@ -2295,7 +2295,6 @@ void do_assert_glerror()
gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
}
}
- error = glGetError();
}
if (quit)
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index d6b2aa2289..6dbde719f4 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -55,8 +55,14 @@ F32 gGLModelView[16];
F32 gGLLastModelView[16];
F32 gGLLastProjection[16];
F32 gGLProjection[16];
+
+// transform from last frame's camera space to this frame's camera space (and inverse)
+F32 gGLDeltaModelView[16];
+F32 gGLInverseDeltaModelView[16];
+
S32 gGLViewport[4];
+
U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
@@ -373,7 +379,6 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
if (bindDepth)
{
llassert(renderTarget->getDepth()); // target MUST have a depth buffer attachment
- llassert(renderTarget->canSampleDepth()); // depth buffer attachment MUST be sampleable
bindManual(renderTarget->getUsage(), renderTarget->getDepth());
}
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index cbd3de5736..e8baf6bb7e 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -507,6 +507,8 @@ extern F32 gGLLastModelView[16];
extern F32 gGLLastProjection[16];
extern F32 gGLProjection[16];
extern S32 gGLViewport[4];
+extern F32 gGLDeltaModelView[16];
+extern F32 gGLInverseDeltaModelView[16];
extern thread_local LLRender gGL;
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 9827db8084..6dac614eea 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -35,19 +35,19 @@ U32 LLRenderTarget::sBytesAllocated = 0;
void check_framebuffer_status()
{
- if (gDebugGL)
- {
- GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
- switch (status)
- {
- case GL_FRAMEBUFFER_COMPLETE:
- break;
- default:
- LL_WARNS() << "check_framebuffer_status failed -- " << std::hex << status << LL_ENDL;
- ll_fail("check_framebuffer_status failed");
- break;
- }
- }
+ if (gDebugGL)
+ {
+ GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+ switch (status)
+ {
+ case GL_FRAMEBUFFER_COMPLETE:
+ break;
+ default:
+ LL_WARNS() << "check_framebuffer_status failed -- " << std::hex << status << LL_ENDL;
+ ll_fail("check_framebuffer_status failed");
+ break;
+ }
+ }
}
bool LLRenderTarget::sUseFBO = false;
@@ -60,112 +60,86 @@ U32 LLRenderTarget::sCurResX = 0;
U32 LLRenderTarget::sCurResY = 0;
LLRenderTarget::LLRenderTarget() :
- mResX(0),
- mResY(0),
- mFBO(0),
- mPreviousFBO(0),
- mPreviousResX(0),
- mPreviousResY(0),
- mDepth(0),
- mUseDepth(false),
- mSampleDepth(false),
- mUsage(LLTexUnit::TT_TEXTURE)
+ mResX(0),
+ mResY(0),
+ mFBO(0),
+ mDepth(0),
+ mUseDepth(false),
+ mUsage(LLTexUnit::TT_TEXTURE)
{
}
LLRenderTarget::~LLRenderTarget()
{
- release();
+ release();
}
void LLRenderTarget::resize(U32 resx, U32 resy)
{
- //for accounting, get the number of pixels added/subtracted
- S32 pix_diff = (resx*resy)-(mResX*mResY);
-
- mResX = resx;
- mResY = resy;
-
- llassert(mInternalFormat.size() == mTex.size());
-
- for (U32 i = 0; i < mTex.size(); ++i)
- { //resize color attachments
- gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
- sBytesAllocated += pix_diff*4;
- }
-
- if (mDepth)
- { //resize depth attachment
- if (!mSampleDepth)
- {
- //use render buffers where stencil buffers are in play
- glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- }
- else
- {
- gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
- U32 internal_type = LLTexUnit::getInternalType(mUsage);
- LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
- }
-
- sBytesAllocated += pix_diff*4;
- }
+ //for accounting, get the number of pixels added/subtracted
+ S32 pix_diff = (resx*resy)-(mResX*mResY);
+
+ mResX = resx;
+ mResY = resy;
+
+ llassert(mInternalFormat.size() == mTex.size());
+
+ for (U32 i = 0; i < mTex.size(); ++i)
+ { //resize color attachments
+ gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ sBytesAllocated += pix_diff*4;
+ }
+
+ if (mDepth)
+ {
+ gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
+ U32 internal_type = LLTexUnit::getInternalType(mUsage);
+ LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
+
+ sBytesAllocated += pix_diff*4;
+ }
}
-
+
-bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
+bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLTexUnit::eTextureType usage)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
- resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
+ llassert(usage == LLTexUnit::TT_TEXTURE);
+ llassert(!isBoundInStack());
- stop_glerror();
- release();
- stop_glerror();
+ resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
+ resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
- mResX = resx;
- mResY = resy;
+ release();
+
+ mResX = resx;
+ mResY = resy;
- mUsage = usage;
+ mUsage = usage;
mUseDepth = depth;
- mSampleDepth = sample_depth;
-
- if ((sUseFBO || use_fbo))
- {
- if (depth)
- {
- if (!allocateDepth())
- {
- LL_WARNS() << "Failed to allocate depth buffer for render target." << LL_ENDL;
- return false;
- }
- }
-
- glGenFramebuffers(1, (GLuint *) &mFBO);
-
- if (mDepth)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+
+ if (depth)
+ {
+ if (!allocateDepth())
+ {
+ LL_WARNS() << "Failed to allocate depth buffer for render target." << LL_ENDL;
+ return false;
+ }
+ }
+
+ glGenFramebuffers(1, (GLuint *) &mFBO);
+
+ if (mDepth)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- if (!canSampleDepth())
- {
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
- }
- else
- {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
- stop_glerror();
- }
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
- }
-
- stop_glerror();
- }
-
- return addColorAttachment(color_fmt);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ }
+
+ return addColorAttachment(color_fmt);
}
void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name)
@@ -175,6 +149,7 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name)
llassert(sUseFBO); // FBO support must be enabled
llassert(mDepth == 0); // depth buffers not supported with this mode
llassert(mTex.empty()); // mTex must be empty with this mode (binding target should be done via LLImageGL)
+ llassert(!isBoundInStack());
if (mFBO == 0)
{
@@ -205,6 +180,7 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name)
void LLRenderTarget::releaseColorAttachment()
{
LL_PROFILE_ZONE_SCOPED;
+ llassert(!isBoundInStack());
llassert(mTex.size() == 1); //cannot use releaseColorAttachment with LLRenderTarget managed color targets
llassert(mFBO != 0); // mFBO must be valid
@@ -218,323 +194,291 @@ void LLRenderTarget::releaseColorAttachment()
bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- if (color_fmt == 0)
- {
- return true;
- }
-
- U32 offset = mTex.size();
-
- if( offset >= 4 )
- {
- LL_WARNS() << "Too many color attachments" << LL_ENDL;
- llassert( offset < 4 );
- return false;
- }
- if( offset > 0 && (mFBO == 0) )
- {
- llassert( mFBO != 0 );
- return false;
- }
-
- U32 tex;
- LLImageGL::generateTextures(1, &tex);
- gGL.getTexUnit(0)->bindManual(mUsage, tex);
-
- stop_glerror();
-
-
- {
- clear_glerror();
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
- if (glGetError() != GL_NO_ERROR)
- {
- LL_WARNS() << "Could not allocate color buffer for render target." << LL_ENDL;
- return false;
- }
- }
-
- sBytesAllocated += mResX*mResY*4;
-
- stop_glerror();
-
-
- if (offset == 0)
- { //use bilinear filtering on single texture render targets that aren't multisampled
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- stop_glerror();
- }
- else
- { //don't filter data attachments
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- stop_glerror();
- }
-
- if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
- {
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
- stop_glerror();
- }
- else
- {
- // ATI doesn't support mirrored repeat for rectangular textures.
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
- }
-
- if (mFBO)
- {
- stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
- LLTexUnit::getInternalType(mUsage), tex, 0);
- stop_glerror();
-
- check_framebuffer_status();
-
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
- }
-
- mTex.push_back(tex);
- mInternalFormat.push_back(color_fmt);
-
- if (gDebugGL)
- { //bind and unbind to validate target
- bindTarget();
- flush();
- }
+ llassert(!isBoundInStack());
+
+ if (color_fmt == 0)
+ {
+ return true;
+ }
+
+ U32 offset = mTex.size();
+
+ if( offset >= 4 )
+ {
+ LL_WARNS() << "Too many color attachments" << LL_ENDL;
+ llassert( offset < 4 );
+ return false;
+ }
+ if( offset > 0 && (mFBO == 0) )
+ {
+ llassert( mFBO != 0 );
+ return false;
+ }
+
+ U32 tex;
+ LLImageGL::generateTextures(1, &tex);
+ gGL.getTexUnit(0)->bindManual(mUsage, tex);
+
+ stop_glerror();
+
+
+ {
+ clear_glerror();
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ LL_WARNS() << "Could not allocate color buffer for render target." << LL_ENDL;
+ return false;
+ }
+ }
+
+ sBytesAllocated += mResX*mResY*4;
+
+ stop_glerror();
+
+
+ if (offset == 0)
+ { //use bilinear filtering on single texture render targets that aren't multisampled
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ stop_glerror();
+ }
+ else
+ { //don't filter data attachments
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ stop_glerror();
+ }
+
+ if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
+ {
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
+ stop_glerror();
+ }
+ else
+ {
+ // ATI doesn't support mirrored repeat for rectangular textures.
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+ }
+
+ if (mFBO)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset,
+ LLTexUnit::getInternalType(mUsage), tex, 0);
+
+ check_framebuffer_status();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ }
+
+ mTex.push_back(tex);
+ mInternalFormat.push_back(color_fmt);
+
+ if (gDebugGL)
+ { //bind and unbind to validate target
+ bindTarget();
+ flush();
+ }
- return true;
+ return true;
}
bool LLRenderTarget::allocateDepth()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- if (!mSampleDepth)
- {
- //use render buffers if depth buffer won't be sampled
- glGenRenderbuffers(1, (GLuint *) &mDepth);
- glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- }
- else
- {
- LLImageGL::generateTextures(1, &mDepth);
- gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
-
- U32 internal_type = LLTexUnit::getInternalType(mUsage);
- stop_glerror();
- clear_glerror();
- LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- sBytesAllocated += mResX*mResY*4;
-
- if (glGetError() != GL_NO_ERROR)
- {
- LL_WARNS() << "Unable to allocate depth buffer for render target." << LL_ENDL;
- return false;
- }
-
- return true;
+ LLImageGL::generateTextures(1, &mDepth);
+ gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
+
+ U32 internal_type = LLTexUnit::getInternalType(mUsage);
+ stop_glerror();
+ clear_glerror();
+ LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+
+ sBytesAllocated += mResX*mResY*4;
+
+ if (glGetError() != GL_NO_ERROR)
+ {
+ LL_WARNS() << "Unable to allocate depth buffer for render target." << LL_ENDL;
+ return false;
+ }
+
+ return true;
}
void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
{
- if (!mFBO || !target.mFBO)
- {
- LL_ERRS() << "Cannot share depth buffer between non FBO render targets." << LL_ENDL;
- }
-
- if (target.mDepth)
- {
- LL_ERRS() << "Attempting to override existing depth buffer. Detach existing buffer first." << LL_ENDL;
- }
-
- if (target.mUseDepth)
- {
- LL_ERRS() << "Attempting to override existing shared depth buffer. Detach existing buffer first." << LL_ENDL;
- }
-
- if (mDepth)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
-
- if (!mSampleDepth)
- {
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
- }
- else
- {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
- }
-
- check_framebuffer_status();
-
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
-
- target.mUseDepth = true;
- }
+ llassert(!isBoundInStack());
+
+ if (!mFBO || !target.mFBO)
+ {
+ LL_ERRS() << "Cannot share depth buffer between non FBO render targets." << LL_ENDL;
+ }
+
+ if (target.mDepth)
+ {
+ LL_ERRS() << "Attempting to override existing depth buffer. Detach existing buffer first." << LL_ENDL;
+ }
+
+ if (target.mUseDepth)
+ {
+ LL_ERRS() << "Attempting to override existing shared depth buffer. Detach existing buffer first." << LL_ENDL;
+ }
+
+ if (mDepth)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
+
+ check_framebuffer_status();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+
+ target.mUseDepth = true;
+ }
}
void LLRenderTarget::release()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- if (mDepth)
- {
- if (!mSampleDepth)
- {
- glDeleteRenderbuffers(1, (GLuint*) &mDepth);
- }
- else
- {
- LLImageGL::deleteTextures(1, &mDepth);
- }
- mDepth = 0;
-
- sBytesAllocated -= mResX*mResY*4;
- }
- else if (mFBO)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
-
- if (mUseDepth)
- { //detach shared depth buffer
- if (!mSampleDepth)
- { //attached as a renderbuffer
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
- mSampleDepth = false;
- }
- else
- { //attached as a texture
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
- }
- mUseDepth = false;
- }
- }
-
- // Detach any extra color buffers (e.g. SRGB spec buffers)
- //
- if (mFBO && (mTex.size() > 1))
- {
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- S32 z;
- for (z = mTex.size() - 1; z >= 1; z--)
- {
- sBytesAllocated -= mResX*mResY*4;
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
- stop_glerror();
- LLImageGL::deleteTextures(1, &mTex[z]);
- }
- }
-
- if (mFBO)
- {
- glDeleteFramebuffers(1, (GLuint *) &mFBO);
- stop_glerror();
- mFBO = 0;
- }
-
- if (mTex.size() > 0)
- {
- sBytesAllocated -= mResX*mResY*4;
- LLImageGL::deleteTextures(1, &mTex[0]);
- }
-
- mTex.clear();
- mInternalFormat.clear();
-
- mResX = mResY = 0;
-
- sBoundTarget = NULL;
+ llassert(!isBoundInStack());
+
+ if (mDepth)
+ {
+ LLImageGL::deleteTextures(1, &mDepth);
+
+ mDepth = 0;
+
+ sBytesAllocated -= mResX*mResY*4;
+ }
+ else if (mFBO)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+
+ if (mUseDepth)
+ { //detach shared depth buffer
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
+ mUseDepth = false;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ }
+
+ // Detach any extra color buffers (e.g. SRGB spec buffers)
+ //
+ if (mFBO && (mTex.size() > 1))
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ S32 z;
+ for (z = mTex.size() - 1; z >= 1; z--)
+ {
+ sBytesAllocated -= mResX*mResY*4;
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
+ LLImageGL::deleteTextures(1, &mTex[z]);
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ }
+
+ if (mFBO == sCurFBO)
+ {
+ sCurFBO = 0;
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ if (mFBO)
+ {
+ glDeleteFramebuffers(1, (GLuint *) &mFBO);
+ mFBO = 0;
+ }
+
+ if (mTex.size() > 0)
+ {
+ sBytesAllocated -= mResX*mResY*4;
+ LLImageGL::deleteTextures(1, &mTex[0]);
+ }
+
+ mTex.clear();
+ mInternalFormat.clear();
+
+ mResX = mResY = 0;
}
void LLRenderTarget::bindTarget()
{
LL_PROFILE_GPU_ZONE("bindTarget");
llassert(mFBO);
+ llassert(!isBoundInStack());
+
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ sCurFBO = mFBO;
+
+ //setup multiple render targets
+ GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
+ GL_COLOR_ATTACHMENT1,
+ GL_COLOR_ATTACHMENT2,
+ GL_COLOR_ATTACHMENT3};
+ glDrawBuffers(mTex.size(), drawbuffers);
+
+ if (mTex.empty())
+ { //no color buffer to draw to
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ }
- if (mFBO)
- {
- stop_glerror();
-
- mPreviousFBO = sCurFBO;
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- sCurFBO = mFBO;
-
- stop_glerror();
- //setup multiple render targets
- GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0,
- GL_COLOR_ATTACHMENT1,
- GL_COLOR_ATTACHMENT2,
- GL_COLOR_ATTACHMENT3};
- glDrawBuffers(mTex.size(), drawbuffers);
-
- if (mTex.empty())
- { //no color buffer to draw to
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
- }
-
- check_framebuffer_status();
-
- stop_glerror();
- }
-
- mPreviousResX = sCurResX;
- mPreviousResY = sCurResY;
- glViewport(0, 0, mResX, mResY);
- sCurResX = mResX;
- sCurResY = mResY;
-
- sBoundTarget = this;
+ check_framebuffer_status();
+
+ glViewport(0, 0, mResX, mResY);
+ sCurResX = mResX;
+ sCurResY = mResY;
+
+ mPreviousRT = sBoundTarget;
+ sBoundTarget = this;
}
void LLRenderTarget::clear(U32 mask_in)
{
LL_PROFILE_GPU_ZONE("clear");
llassert(mFBO);
- U32 mask = GL_COLOR_BUFFER_BIT;
- if (mUseDepth)
- {
- mask |= GL_DEPTH_BUFFER_BIT; // stencil buffer is deprecated, performance pnealty | GL_STENCIL_BUFFER_BIT;
+ U32 mask = GL_COLOR_BUFFER_BIT;
+ if (mUseDepth)
+ {
+ mask |= GL_DEPTH_BUFFER_BIT;
- }
- if (mFBO)
- {
- check_framebuffer_status();
- stop_glerror();
- glClear(mask & mask_in);
- stop_glerror();
- }
- else
- {
- LLGLEnable scissor(GL_SCISSOR_TEST);
- glScissor(0, 0, mResX, mResY);
- stop_glerror();
- glClear(mask & mask_in);
- }
+ }
+ if (mFBO)
+ {
+ check_framebuffer_status();
+ stop_glerror();
+ glClear(mask & mask_in);
+ stop_glerror();
+ }
+ else
+ {
+ LLGLEnable scissor(GL_SCISSOR_TEST);
+ glScissor(0, 0, mResX, mResY);
+ stop_glerror();
+ glClear(mask & mask_in);
+ }
}
U32 LLRenderTarget::getTexture(U32 attachment) const
{
- if (attachment > mTex.size()-1)
- {
- LL_ERRS() << "Invalid attachment index." << LL_ENDL;
- }
- if (mTex.empty())
- {
- return 0;
- }
- return mTex[attachment];
+ if (attachment > mTex.size()-1)
+ {
+ LL_ERRS() << "Invalid attachment index." << LL_ENDL;
+ }
+ if (mTex.empty())
+ {
+ return 0;
+ }
+ return mTex[attachment];
}
U32 LLRenderTarget::getNumTextures() const
{
- return mTex.size();
+ return mTex.size();
}
void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options)
@@ -560,64 +504,54 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt
gGL.getTexUnit(channel)->setTextureColorSpace(isSRGB ? LLTexUnit::TCS_SRGB : LLTexUnit::TCS_LINEAR);
}
-void LLRenderTarget::flush(bool fetch_depth)
+void LLRenderTarget::flush()
{
LL_PROFILE_GPU_ZONE("rt flush");
- gGL.flush();
+ gGL.flush();
llassert(mFBO);
- if (!mFBO)
- {
- gGL.getTexUnit(0)->bind(this);
- glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY);
-
- if (fetch_depth)
- {
- if (!mDepth)
- {
- allocateDepth();
- }
-
- gGL.getTexUnit(0)->bind(this);
- glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8, 0, 0, mResX, mResY, 0);
- }
-
- gGL.getTexUnit(0)->disable();
- }
- else
- {
- stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
- sCurFBO = mPreviousFBO;
-
- if (mPreviousFBO)
- {
- glViewport(0, 0, mPreviousResX, mPreviousResY);
- sCurResX = mPreviousResX;
- sCurResY = mPreviousResY;
- }
- else
- {
- glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
- sCurResX = gGLViewport[2];
- sCurResY = gGLViewport[3];
- }
-
- stop_glerror();
- }
+ llassert(sCurFBO == mFBO);
+ llassert(sBoundTarget == this);
+
+ if (mPreviousRT)
+ {
+ // a bit hacky -- pop the RT stack back two frames and push
+ // the previous frame back on to play nice with the GL state machine
+ sBoundTarget = mPreviousRT->mPreviousRT;
+ mPreviousRT->bindTarget();
+ }
+ else
+ {
+ sBoundTarget = nullptr;
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ sCurFBO = 0;
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ sCurResX = gGLViewport[2];
+ sCurResY = gGLViewport[3];
+ }
}
bool LLRenderTarget::isComplete() const
{
- return (!mTex.empty() || mDepth) ? true : false;
+ return (!mTex.empty() || mDepth) ? true : false;
}
void LLRenderTarget::getViewport(S32* viewport)
{
- viewport[0] = 0;
- viewport[1] = 0;
- viewport[2] = mResX;
- viewport[3] = mResY;
+ viewport[0] = 0;
+ viewport[1] = 0;
+ viewport[2] = mResX;
+ viewport[3] = mResY;
}
+bool LLRenderTarget::isBoundInStack() const
+{
+ LLRenderTarget* cur = sBoundTarget;
+ while (cur && cur != this)
+ {
+ cur = cur->mPreviousRT;
+ }
+
+ return cur == this;
+}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 5f3214add3..71727bf09d 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -33,6 +33,8 @@
#include "llrender.h"
/*
+ Wrapper around OpenGL framebuffer objects for use in render-to-texture
+
SAMPLE USAGE:
LLRenderTarget target;
@@ -73,7 +75,12 @@ public:
//allocate resources for rendering
//must be called before use
//multiple calls will release previously allocated resources
- bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
+ // resX - width
+ // resY - height
+ // color_fmt - GL color format (e.g. GL_RGB)
+ // depth - if true, allocate a depth buffer
+ // usage - deprecated, should always be TT_TEXTURE
+ bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE);
//resize existing attachments to use new resolution and color format
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
@@ -93,7 +100,7 @@ public:
// attachment -- LLImageGL to render into
// use_name -- optional texture name to target instead of attachment->getTexName()
// NOTE: setColorAttachment and releaseColorAttachment cannot be used in conjuction with
- // addColorAttachment, allocateDepth, resize, etc.
+ // addColorAttachment, allocateDepth, resize, etc.
void setColorAttachment(LLImageGL* attachment, LLGLuint use_name = 0);
// detach from current color attachment
@@ -111,14 +118,19 @@ public:
//free any allocated resources
//safe to call redundantly
+ // asserts that this target is not currently bound or present in the RT stack
void release();
//bind target for rendering
//applies appropriate viewport
+ // If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget
+ // and restores previous binding on flush() (maintains a stack of Render Targets)
+ // Asserts that this target is not currently bound in the stack
void bindTarget();
//clear render targer, clears depth buffer if present,
//uses scissor rect if in copy-to-texture mode
+ // asserts that this target is currently bound
void clear(U32 mask = 0xFFFFFFFF);
//get applied viewport
@@ -136,7 +148,6 @@ public:
U32 getNumTextures() const;
U32 getDepth(void) const { return mDepth; }
- bool canSampleDepth() const { return mSampleDepth; }
void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR);
@@ -144,15 +155,18 @@ public:
//must be called when rendering is complete
//should be used 1:1 with bindTarget
// call bindTarget once, do all your rendering, call flush once
- // if fetch_depth is TRUE, every effort will be made to copy the depth buffer into
- // the current depth texture. A depth texture will be allocated if needed.
- void flush(bool fetch_depth = FALSE);
+ // If an LLRenderTarget was bound when bindTarget was called, binds that RenderTarget for rendering (maintains RT stack)
+ // asserts that this target is currently bound
+ void flush();
//Returns TRUE if target is ready to be rendered into.
//That is, if the target has been allocated with at least
//one renderable attachment (i.e. color buffer, depth buffer).
bool isComplete() const;
+ // Returns true if this RenderTarget is bound somewhere in the stack
+ bool isBoundInStack() const;
+
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
protected:
@@ -161,13 +175,10 @@ protected:
std::vector<U32> mTex;
std::vector<U32> mInternalFormat;
U32 mFBO;
- U32 mPreviousFBO;
- U32 mPreviousResX;
- U32 mPreviousResY;
+ LLRenderTarget* mPreviousRT = nullptr;
- U32 mDepth;
+ U32 mDepth;
bool mUseDepth;
- bool mSampleDepth;
LLTexUnit::eTextureType mUsage;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 6001b011ee..27ac4053df 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -222,7 +222,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
- if (features->hasScreenSpaceReflections)
+ if (features->hasScreenSpaceReflections || features->hasReflectionProbes)
{
if (!shader->attachFragmentObject("deferred/screenSpaceReflUtil.glsl"))
{
@@ -1244,6 +1244,8 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("bumpMap");
mReservedUniforms.push_back("bumpMap2");
mReservedUniforms.push_back("environmentMap");
+ mReservedUniforms.push_back("sceneMap");
+ mReservedUniforms.push_back("sceneDepth");
mReservedUniforms.push_back("reflectionProbes");
mReservedUniforms.push_back("irradianceProbes");
mReservedUniforms.push_back("cloud_noise_texture");
@@ -1323,6 +1325,10 @@ void LLShaderMgr::initAttribsAndUniforms()
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH+1);
+ mReservedUniforms.push_back("modelview_delta");
+ mReservedUniforms.push_back("inv_modelview_delta");
+ mReservedUniforms.push_back("cube_snapshot");
+
mReservedUniforms.push_back("tc_scale");
mReservedUniforms.push_back("rcp_screen_res");
mReservedUniforms.push_back("rcp_frame_opt");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index f6abfe9027..86ada6c132 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -90,6 +90,8 @@ public:
BUMP_MAP, // "bumpMap"
BUMP_MAP2, // "bumpMap2"
ENVIRONMENT_MAP, // "environmentMap"
+ SCENE_MAP, // "sceneMap"
+ SCENE_DEPTH, // "sceneDepth"
REFLECTION_PROBES, // "reflectionProbes"
IRRADIANCE_PROBES, // "irradianceProbes"
CLOUD_NOISE_MAP, // "cloud_noise_texture"
@@ -158,6 +160,10 @@ public:
DEFERRED_NORM_CUTOFF, // "norm_cutoff"
DEFERRED_SHADOW_TARGET_WIDTH, // "shadow_target_width"
+ MODELVIEW_DELTA_MATRIX, // "modelview_delta"
+ INVERSE_MODELVIEW_DELTA_MATRIX, // "inv_modelview_delta"
+ CUBE_SNAPSHOT, // "cube_snapshot"
+
FXAA_TC_SCALE, // "tc_scale"
FXAA_RCP_SCREEN_RES, // "rcp_screen_res"
FXAA_RCP_FRAME_OPT, // "rcp_frame_opt"
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 40ab4a2e0f..11e2b6e5c4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -744,7 +744,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
- drawRange(mode, 0, mNumVerts, count, indices_offset);
+ drawRange(mode, 0, mNumVerts-1, count, indices_offset);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
index 95abd4d932..2ffe688524 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
@@ -25,14 +25,14 @@
// fallback stub -- will be used if actual reflection probe shader failed to load (output pink so it's obvious)
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
{
ambenv = vec3(1,0,1);
glossenv = vec3(1,0,1);
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
sampleReflectionProbes(ambenv, glossenv,
pos, norm, glossiness, false);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflPostF.glsl b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflPostF.glsl
index 8373567bb0..df16e7f0e7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflPostF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflPostF.glsl
@@ -23,35 +23,11 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
+ // debug stub
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform vec2 screen_res;
-uniform mat4 projection_matrix;
-uniform mat4 inv_proj;
-uniform float zNear;
-uniform float zFar;
-
-VARYING vec2 vary_fragcoord;
-
-uniform sampler2D depthMap;
-uniform sampler2D normalMap;
-uniform sampler2D sceneMap;
-uniform sampler2D diffuseRect;
-
-vec3 getNorm(vec2 screenpos);
-float getDepth(vec2 pos_screen);
-float linearDepth(float d, float znear, float zfar);
-void main() {
- vec2 tc = vary_fragcoord.xy;
- vec4 pos = getPositionWithDepth(tc, getDepth(tc));
- frag_color = pos;
+void main()
+{
+ frag_color = vec4(0.5, 0.4, 0.1, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl
index 6dfc89a6c6..b3da216b81 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl
@@ -23,98 +23,15 @@
* $/LicenseInfo$
*/
-uniform sampler2D depthMap;
-uniform sampler2D normalMap;
-uniform sampler2D sceneMap;
-uniform vec2 screen_res;
-uniform mat4 projection_matrix;
+// debug stub
-// Shamelessly taken from http://casual-effects.blogspot.com/2014/08/screen-space-ray-tracing.html
-// Original paper: https://jcgt.org/published/0003/04/04/
-// By Morgan McGuire and Michael Mara at Williams College 2014
-// Released as open source under the BSD 2-Clause License
-// http://opensource.org/licenses/BSD-2-Clause
-
-float distanceSquared(vec2 a, vec2 b) { a -= b; return dot(a, a); }
-
-bool traceScreenSpaceRay1(vec3 csOrig, vec3 csDir, mat4 proj, float zThickness,
- float nearPlaneZ, float stride, float jitter, const float maxSteps, float maxDistance,
- out vec2 hitPixel, out vec3 hitPoint)
+float random (vec2 uv)
{
-
- // Clip to the near plane
- float rayLength = ((csOrig.z + csDir.z * maxDistance) > nearPlaneZ) ?
- (nearPlaneZ - csOrig.z) / csDir.z : maxDistance;
- vec3 csEndPoint = csOrig + csDir * rayLength;
-
- // Project into homogeneous clip space
- vec4 H0 = proj * vec4(csOrig, 1.0);
- vec4 H1 = proj * vec4(csEndPoint, 1.0);
- float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;
-
- // The interpolated homogeneous version of the camera-space points
- vec3 Q0 = csOrig * k0, Q1 = csEndPoint * k1;
-
- // Screen-space endpoints
- vec2 P0 = H0.xy * k0, P1 = H1.xy * k1;
-
- // If the line is degenerate, make it cover at least one pixel
- // to avoid handling zero-pixel extent as a special case later
- P1 += vec2((distanceSquared(P0, P1) < 0.0001) ? 0.01 : 0.0);
- vec2 delta = P1 - P0;
-
- // Permute so that the primary iteration is in x to collapse
- // all quadrant-specific DDA cases later
- bool permute = false;
- if (abs(delta.x) < abs(delta.y)) {
- // This is a more-vertical line
- permute = true; delta = delta.yx; P0 = P0.yx; P1 = P1.yx;
- }
-
- float stepDir = sign(delta.x);
- float invdx = stepDir / delta.x;
-
- // Track the derivatives of Q and k
- vec3 dQ = (Q1 - Q0) * invdx;
- float dk = (k1 - k0) * invdx;
- vec2 dP = vec2(stepDir, delta.y * invdx);
-
- // Scale derivatives by the desired pixel stride and then
- // offset the starting values by the jitter fraction
- dP *= stride; dQ *= stride; dk *= stride;
- P0 += dP * jitter; Q0 += dQ * jitter; k0 += dk * jitter;
-
- // Slide P from P0 to P1, (now-homogeneous) Q from Q0 to Q1, k from k0 to k1
- vec3 Q = Q0;
-
- // Adjust end condition for iteration direction
- float end = P1.x * stepDir;
-
- float k = k0, stepCount = 0.0, prevZMaxEstimate = csOrig.z;
- float rayZMin = prevZMaxEstimate, rayZMax = prevZMaxEstimate;
- float sceneZMax = rayZMax + 100;
- for (vec2 P = P0;
- ((P.x * stepDir) <= end) && (stepCount < maxSteps) &&
- ((rayZMax < sceneZMax - zThickness) || (rayZMin > sceneZMax)) &&
- (sceneZMax != 0);
- P += dP, Q.z += dQ.z, k += dk, ++stepCount) {
-
- rayZMin = prevZMaxEstimate;
- rayZMax = (dQ.z * 0.5 + Q.z) / (dk * 0.5 + k);
- prevZMaxEstimate = rayZMax;
- if (rayZMin > rayZMax) {
- float t = rayZMin; rayZMin = rayZMax; rayZMax = t;
- }
-
- hitPixel = permute ? P.yx : P;
- hitPixel.y = screen_res.y - hitPixel.y;
- // You may need hitPixel.y = screen_res.y - hitPixel.y; here if your vertical axis
- // is different than ours in screen space
- sceneZMax = texelFetch(depthMap, ivec2(hitPixel)).r;
- }
-
- // Advance Q based on the number of steps
- Q.xy += dQ.xy * stepCount;
- hitPoint = Q * (1.0 / k);
- return (rayZMax >= sceneZMax - zThickness) && (rayZMin < sceneZMax);
+ return 0;
}
+
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source)
+{
+ collectedColor = vec4(0);
+ return 0;
+} \ No newline at end of file
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index 076b976dc4..7435f1c0e1 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -90,8 +90,8 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
float getAmbientClamp();
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity);
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
{
@@ -253,7 +253,7 @@ void main()
vec3 irradiance;
vec3 glossenv;
vec3 legacyenv;
- sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, pos.xyz, norm.xyz, 0.0, 0.0);
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, frag, pos.xyz, norm.xyz, 0.0, 0.0);
float da = dot(norm.xyz, light_dir.xyz);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index d81102991e..ccf20942e3 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -84,7 +84,7 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float
float calcLegacyDistanceAttenuation(float distance, float falloff);
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness);
+ vec2 tc, vec3 pos, vec3 norm, float glossiness);
void waterClip(vec3 pos);
@@ -207,7 +207,7 @@ void main()
float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbes(irradiance, radiance, pos.xyz, norm.xyz, gloss);
+ sampleReflectionProbes(irradiance, radiance, vec2(0), pos.xyz, norm.xyz, gloss);
// Take maximium of legacy ambient vs irradiance sample as irradiance
// NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
irradiance = max(amblit,irradiance);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
index af43c7b4e3..f1ee4b4681 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
@@ -34,7 +34,7 @@ uniform mat3 env_mat;
vec3 srgb_to_linear(vec3 c);
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
{
ambenv = vec3(reflection_probe_ambiance * 0.25);
@@ -44,10 +44,10 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
sampleReflectionProbes(ambenv, glossenv,
- pos, norm, glossiness, false);
+ tc, pos, norm, glossiness, false);
}
vec4 sampleReflectionProbesDebug(vec3 pos)
@@ -56,8 +56,8 @@ vec4 sampleReflectionProbesDebug(vec3 pos)
return vec4(0, 0, 0, 0);
}
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity)
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity)
{
ambenv = vec3(reflection_probe_ambiance * 0.25);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
index c0a1491446..160d360256 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -56,8 +56,9 @@ vec3 linear_to_srgb(vec3 c);
vec3 srgb_to_linear(vec3 c);
// reflection probe interface
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
@@ -91,7 +92,7 @@ void main()
vec3 legacyenv;
vec3 norm = normalize(vary_texcoord1.xyz);
vec4 spec = vec4(0,0,0,0);
- sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, env_intensity);
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, vec2(0), pos.xyz, norm.xyz, spec.a, env_intensity);
applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index 8016022d78..8d2a65d4a9 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -61,8 +61,8 @@ out vec4 frag_color;
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
#endif
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity);
void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
@@ -310,7 +310,7 @@ void main()
vec3 ambenv;
vec3 glossenv;
vec3 legacyenv;
- sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, final_specular.a, env_intensity);
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos_screen, pos.xyz, norm.xyz, final_specular.a, env_intensity);
// use sky settings ambient or irradiance map sample, whichever is brighter
color = max(amblit, ambenv);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 0cb966296a..9793ab13de 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -25,11 +25,17 @@
#define FLT_MAX 3.402823466e+38
+#if defined(SSR)
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source);
+#endif
+
#define REFMAP_COUNT 256
#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
uniform samplerCubeArray reflectionProbes;
uniform samplerCubeArray irradianceProbes;
+uniform sampler2D sceneMap;
+uniform int cube_snapshot;
layout (std140) uniform ReflectionProbes
{
@@ -92,14 +98,17 @@ bool shouldSampleProbe(int i, vec3 pos)
}
else
{
- vec3 delta = pos.xyz - refSphere[i].xyz;
- float d = dot(delta, delta);
- float r2 = refSphere[i].w;
- r2 *= r2;
-
- if (d > r2)
- { //outside bounding sphere
- return false;
+ if (refSphere[i].w > 0.0) // zero is special indicator to always sample this probe
+ {
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d = dot(delta, delta);
+ float r2 = refSphere[i].w;
+ r2 *= r2;
+
+ if (d > r2)
+ { //outside bounding sphere
+ return false;
+ }
}
max_priority = max(max_priority, refIndex[i].w);
@@ -138,13 +147,13 @@ void preProbeSample(vec3 pos)
probeIndex[probeInfluences++] = idx;
if (probeInfluences == REF_SAMPLE_COUNT)
{
- return;
+ break;
}
}
count++;
if (count == neighborCount)
{
- return;
+ break;
}
idx = refNeighbor[neighborIdx].y;
@@ -153,13 +162,13 @@ void preProbeSample(vec3 pos)
probeIndex[probeInfluences++] = idx;
if (probeInfluences == REF_SAMPLE_COUNT)
{
- return;
+ break;
}
}
count++;
if (count == neighborCount)
{
- return;
+ break;
}
idx = refNeighbor[neighborIdx].z;
@@ -168,13 +177,13 @@ void preProbeSample(vec3 pos)
probeIndex[probeInfluences++] = idx;
if (probeInfluences == REF_SAMPLE_COUNT)
{
- return;
+ break;
}
}
count++;
if (count == neighborCount)
{
- return;
+ break;
}
idx = refNeighbor[neighborIdx].w;
@@ -183,27 +192,26 @@ void preProbeSample(vec3 pos)
probeIndex[probeInfluences++] = idx;
if (probeInfluences == REF_SAMPLE_COUNT)
{
- return;
+ break;
}
}
count++;
if (count == neighborCount)
{
- return;
+ break;
}
++neighborIdx;
}
- return;
+ break;
}
}
}
- if (probeInfluences == 0)
- { // probe at index 0 is a special fallback probe
- probeIndex[0] = 0;
- probeInfluences = 1;
+ if (max_priority <= 1)
+ { // probe at index 0 is a special probe for smoothing out automatic probes
+ probeIndex[probeInfluences++] = 0;
}
}
@@ -330,7 +338,8 @@ return texCUBE(envMap, ReflDirectionWS);
// origin - ray origin in clip space
// dir - ray direction in clip space
// i - probe index in refBox/refSphere
-vec3 boxIntersect(vec3 origin, vec3 dir, int i)
+// d - distance to nearest wall in clip space
+vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
{
// Intersection with OBB convertto unit box space
// Transform in local unit parallax cube space (scaled and rotated)
@@ -339,6 +348,8 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i)
vec3 RayLS = mat3(clipToLocal) * dir;
vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
+ d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z));
+
vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
@@ -413,6 +424,29 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
}
+// get the weight of a sphere probe
+// pos - position to be weighted
+// dir - normal to be weighted
+// origin - center of sphere probe
+// r - radius of probe influence volume
+// min_da - minimum angular attenuation coefficient
+float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da)
+{
+ float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - origin;
+ float d2 = max(length(delta), 0.001);
+ float r2 = r1; //r1 * r1;
+
+ //float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);
+ float atten = 1.0 - max(d2 - r2, 0.0) / max((r - r2), 0.001);
+
+ atten *= max(dot(normalize(-delta), dir), min_da);
+ float w = 1.0 / d2;
+ w *= atten;
+
+ return w;
+}
+
// Tap a reflection probe
// pos - position of pixel
// dir - pixel normal
@@ -431,27 +465,21 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float
if (refIndex[i].w < 0)
{
- v = boxIntersect(pos, dir, i);
- w = 1.0;
+ float d = 0;
+ v = boxIntersect(pos, dir, i, d);
+
+ w = max(d, 0.001);
}
else
{
float r = refSphere[i].w; // radius of sphere volume
float rr = r * r; // radius squared
- v = sphereIntersect(pos, dir, c, rr);
-
- float p = float(abs(refIndex[i].w)); // priority
-
- float r1 = r * 0.1; // 90% of radius (outer sphere to start interpolating down)
- vec3 delta = pos.xyz - refSphere[i].xyz;
- float d2 = max(dot(delta, delta), 0.001);
- float r2 = r1 * r1;
+ v = sphereIntersect(pos, dir, c,
+ refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
+ rr);
- float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);
-
- w = 1.0 / d2;
- w *= atten;
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25);
}
vi = v;
@@ -480,8 +508,9 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
vec3 v;
if (refIndex[i].w < 0)
{
- v = boxIntersect(pos, dir, i);
- w = 1.0;
+ float d = 0.0;
+ v = boxIntersect(pos, dir, i, d);
+ w = max(d, 0.001);
}
else
{
@@ -489,17 +518,11 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
float p = float(abs(refIndex[i].w)); // priority
float rr = r * r; // radius squred
- v = sphereIntersect(pos, dir, c, rr);
-
- float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
- vec3 delta = pos.xyz - refSphere[i].xyz;
- float d2 = dot(delta, delta);
- float r2 = r1 * r1;
+ v = sphereIntersect(pos, dir, c,
+ refIndex[i].w <= 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
+ rr);
- w = 1.0 / d2;
-
- float atten = 1.0 - max(d2 - r2, 0.0) / (rr - r2);
- w *= atten;
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.001);
}
v -= c;
@@ -605,7 +628,7 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
{
// TODO - don't hard code lods
float reflection_lods = 6;
@@ -617,6 +640,17 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
float lod = (1.0-glossiness)*reflection_lods;
glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
+
+#if defined(SSR)
+ if (cube_snapshot != 1)
+ {
+ vec4 ssr = vec4(0);
+ //float w = tapScreenSpaceReflection(errorCorrect ? 1 : 4, tc, pos, norm, ssr, sceneMap);
+ float w = tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap);
+
+ glossenv = mix(glossenv, ssr.rgb, w);
+ }
+#endif
}
void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
@@ -660,15 +694,15 @@ vec4 sampleReflectionProbesDebug(vec3 pos)
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
sampleReflectionProbes(ambenv, glossenv,
- pos, norm, glossiness, false);
+ tc, pos, norm, glossiness, false);
}
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity)
{
// TODO - don't hard code lods
float reflection_lods = 7;
@@ -676,7 +710,6 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
-
ambenv = sampleProbeAmbient(pos, norm);
if (glossiness > 0.0)
@@ -689,6 +722,17 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
{
legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false);
}
+
+#if defined(SSR)
+ if (cube_snapshot != 1)
+ {
+ vec4 ssr = vec4(0);
+ float w = tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap);
+
+ glossenv = mix(glossenv, ssr.rgb, w);
+ legacyenv = mix(legacyenv, ssr.rgb, w);
+ }
+#endif
}
void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
index 4813e6c2d9..742f528cb1 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
@@ -42,10 +42,7 @@ uniform float zFar;
VARYING vec2 vary_fragcoord;
VARYING vec3 camera_ray;
-uniform sampler2D depthMap;
-uniform sampler2D normalMap;
uniform sampler2D specularRect;
-uniform sampler2D sceneMap;
uniform sampler2D diffuseRect;
uniform sampler2D diffuseMap;
@@ -57,27 +54,27 @@ float linearDepth01(float d, float znear, float zfar);
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
vec4 getPosition(vec2 pos_screen);
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
-bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float hitDepth, float depth, sampler2D textureFrame);
float random (vec2 uv);
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source);
void main()
{
vec2 tc = vary_fragcoord.xy;
float depth = linearDepth01(getDepth(tc), zNear, zFar);
- vec3 n = vec3(0, 0, 1);
float envIntensity;
+ vec3 n;
vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
vec3 pos = getPositionWithDepth(tc, getDepth(tc)).xyz;
vec4 spec = texture2D(specularRect, tc);
- vec3 viewPos = camera_ray * depth;
- vec3 rayDirection = normalize(reflect(normalize(viewPos), n)) * -viewPos.z;
vec2 hitpixel;
- vec4 hitpoint;
+
vec4 diffuse = texture2D(diffuseRect, tc);
vec3 specCol = spec.rgb;
+ frag_color = texture(diffuseMap, tc);
+
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
vec3 orm = specCol.rgb;
@@ -85,44 +82,17 @@ void main()
float metallic = orm.b;
vec3 f0 = vec3(0.04);
vec3 baseColor = diffuse.rgb;
-
+
vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
specCol = mix(f0, baseColor.rgb, metallic);
}
- vec2 uv2 = tc * screen_res;
- float c = (uv2.x + uv2.y) * 0.125;
- float jitter = mod( c, 1.0);
+ vec4 collectedColor = vec4(0);
- vec3 firstBasis = normalize(cross(vec3(1.f, 1.f, 1.f), rayDirection));
- vec3 secondBasis = normalize(cross(rayDirection, firstBasis));
-
- frag_color = texture(diffuseMap, tc);
- vec4 collectedColor;
-
- vec2 screenpos = 1 - abs(tc * 2 - 1);
- float vignette = clamp((screenpos.x * screenpos.y) * 16,0, 1);
- vignette *= clamp((dot(normalize(viewPos), n) * 0.5 + 0.5 - 0.2) * 8, 0, 1);
- vignette *= min(linearDepth(getDepth(tc), zNear, zFar) / zFar, 1);
-
- int totalSamples = 4;
-
- for (int i = 0; i < totalSamples; i++)
- {
- vec2 coeffs = vec2(random(tc + vec2(0, i)) + random(tc + vec2(i, 0)));
- vec3 reflectionDirectionRandomized = rayDirection + firstBasis * coeffs.x + secondBasis * coeffs.y;
-
- bool hit = traceScreenRay(pos, reflectionDirectionRandomized, hitpoint, depth, depth, diffuseMap);
-
- if (hit)
- {
- collectedColor += hitpoint;
- collectedColor.rgb *= specCol.rgb;
- }
- }
+ float w = tapScreenSpaceReflection(4, tc, pos, n, collectedColor, diffuseMap);
- collectedColor *= vignette;
+ collectedColor.rgb *= specCol.rgb;
- frag_color += collectedColor;
+ frag_color += collectedColor * w;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
index b6c789ad40..570235a816 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
@@ -23,19 +23,18 @@
* $/LicenseInfo$
*/
-uniform sampler2D depthMap;
-uniform sampler2D normalMap;
uniform sampler2D sceneMap;
+uniform sampler2D sceneDepth;
+
uniform vec2 screen_res;
uniform mat4 projection_matrix;
-uniform float zNear;
-uniform float zFar;
+//uniform float zNear;
+//uniform float zFar;
uniform mat4 inv_proj;
+uniform mat4 modelview_delta; // should be transform from last camera space to current camera space
+uniform mat4 inv_modelview_delta;
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-float linearDepth(float depth, float near, float far);
-float getDepth(vec2 pos_screen);
-float linearDepth01(float d, float znear, float zfar);
float random (vec2 uv)
{
@@ -62,8 +61,25 @@ float distanceBias = 0.02;
float depthRejectBias = 0.001;
float epsilon = 0.1;
+float getLinearDepth(vec2 tc)
+{
+ float depth = texture(sceneDepth, tc).r;
+
+ vec4 pos = getPositionWithDepth(tc, depth);
+
+ return -pos.z;
+}
+
bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float hitDepth, float depth, sampler2D textureFrame)
{
+ // transform position and reflection into same coordinate frame as the sceneMap and sceneDepth
+ reflection += position;
+ position = (inv_modelview_delta * vec4(position, 1)).xyz;
+ reflection = (inv_modelview_delta * vec4(reflection, 1)).xyz;
+ reflection -= position;
+
+ depth = -position.z;
+
vec3 step = rayStep * reflection;
vec3 marchingPosition = position + step;
float delta;
@@ -72,13 +88,14 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float
bool hit = false;
hitColor = vec4(0);
+
int i = 0;
if (depth > depthRejectBias)
{
for (; i < iterationCount && !hit; i++)
{
screenPosition = generateProjectedPosition(marchingPosition);
- depthFromScreen = linearDepth(getDepth(screenPosition), zNear, zFar);
+ depthFromScreen = getLinearDepth(screenPosition);
delta = abs(marchingPosition.z) - depthFromScreen;
if (depth < depthFromScreen + epsilon && depth > depthFromScreen - epsilon)
@@ -91,7 +108,7 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float
vec4 color = vec4(1);
if(debugDraw)
color = vec4( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2, 0);
- hitColor = texture(textureFrame, screenPosition) * color;
+ hitColor = texture(sceneMap, screenPosition) * color;
hitDepth = depthFromScreen;
hit = true;
break;
@@ -126,7 +143,7 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float
marchingPosition = marchingPosition - step * sign(delta);
screenPosition = generateProjectedPosition(marchingPosition);
- depthFromScreen = linearDepth(getDepth(screenPosition), zNear, zFar);
+ depthFromScreen = getLinearDepth(screenPosition);
delta = abs(marchingPosition.z) - depthFromScreen;
if (depth < depthFromScreen + epsilon && depth > depthFromScreen - epsilon)
@@ -139,7 +156,7 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float
vec4 color = vec4(1);
if(debugDraw)
color = vec4( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2, 0);
- hitColor = texture(textureFrame, screenPosition) * color;
+ hitColor = texture(sceneMap, screenPosition) * color;
hitDepth = depthFromScreen;
hit = true;
break;
@@ -150,3 +167,68 @@ bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float
return hit;
}
+
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source)
+{
+ collectedColor = vec4(0);
+ int hits = 0;
+
+ float depth = -viewPos.z;
+
+ vec3 rayDirection = normalize(reflect(viewPos, normalize(n)));
+
+ vec2 uv2 = tc * screen_res;
+ float c = (uv2.x + uv2.y) * 0.125;
+ float jitter = mod( c, 1.0);
+
+ vec3 firstBasis = normalize(cross(vec3(1,1,1), rayDirection));
+ vec3 secondBasis = normalize(cross(rayDirection, firstBasis));
+
+ vec2 screenpos = 1 - abs(tc * 2 - 1);
+ float vignette = clamp((screenpos.x * screenpos.y) * 16,0, 1);
+ vignette *= clamp((dot(normalize(viewPos), n) * 0.5 + 0.5 - 0.2) * 8, 0, 1);
+ float zFar = 64.0;
+ vignette *= clamp(1.0+(viewPos.z/zFar), 0.0, 1.0);
+ //vignette *= min(linearDepth(getDepth(tc), zNear, zFar) / zFar, 1);
+
+ vec4 hitpoint;
+
+ if (totalSamples > 1)
+ {
+ for (int i = 0; i < totalSamples; i++)
+ {
+ vec2 coeffs = vec2(random(tc + vec2(0, i)) + random(tc + vec2(i, 0)));
+ vec3 reflectionDirectionRandomized = rayDirection + firstBasis * coeffs.x + secondBasis * coeffs.y;
+
+ //float hitDepth;
+
+ bool hit = traceScreenRay(viewPos, normalize(reflectionDirectionRandomized), hitpoint, depth, depth, source);
+
+ if (hit)
+ {
+ ++hits;
+ collectedColor += hitpoint;
+ }
+ }
+ }
+ else
+ {
+ bool hit = traceScreenRay(viewPos, normalize(rayDirection), hitpoint, depth, depth, source);
+ if (hit)
+ {
+ ++hits;
+ collectedColor += hitpoint;
+ }
+ }
+
+ if (hits > 0)
+ {
+ collectedColor /= hits;
+ }
+ else
+ {
+ collectedColor = vec4(0);
+ }
+
+ return min(float(hits), 1.0) * vignette;
+} \ No newline at end of file
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 8e4197ae77..8d48e6f596 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -75,9 +75,9 @@ vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten);
// reflection probe interface
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness);
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity);
+ vec2 tc, vec3 pos, vec3 norm, float glossiness);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity);
void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
float getDepth(vec2 pos_screen);
@@ -166,7 +166,7 @@ void main()
float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbes(irradiance, radiance, pos.xyz, norm.xyz, gloss);
+ sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss);
// Take maximium of legacy ambient vs irradiance sample as irradiance
// NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
@@ -196,7 +196,7 @@ void main()
vec3 glossenv = vec3(0);
vec3 legacyenv = vec3(0);
- sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity);
// use sky settings ambient or irradiance map sample, whichever is brighter
irradiance = max(amblit, irradiance);
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 85c3f42801..b792feee2a 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -95,9 +95,6 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
vec3 srgb_to_linear(vec3 col);
-void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
- vec3 pos, vec3 norm, float glossiness, float envIntensity);
-
vec3 vN, vT, vB;
vec3 transform_normal(vec3 vNt)
@@ -106,7 +103,10 @@ vec3 transform_normal(vec3 vNt)
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
+ vec2 tc, vec3 pos, vec3 norm, float glossiness);
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
vec3 getPositionWithNDC(vec3 ndc);
@@ -225,7 +225,7 @@ void main()
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbes(irradiance, radiance, pos, refnorm, gloss, true);
+ sampleReflectionProbes(irradiance, radiance, distort, pos, refnorm, gloss, true);
radiance *= 0.5;
irradiance = fb.rgb;
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 9bb3bac104..5b8ca6c49c 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -468,7 +468,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
{
//allocate render target for drawing charts
LLRenderTarget buffer;
- buffer.allocate(1024,512, GL_RGB, FALSE, FALSE);
+ buffer.allocate(1024,512, GL_RGB);
LLSD cur;
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index fe7c1c8f2c..2e4d0f85b9 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -1050,7 +1050,7 @@ F32 gpu_benchmark()
for (U32 i = 0; i < count; ++i)
{
//allocate render targets and textures
- if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
+ if (!dest[i].allocate(res, res, GL_RGBA))
{
LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL;
// abandon the benchmark test
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index b87406cb6e..128aa99ccc 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -39,6 +39,14 @@
extern BOOL gCubeSnapshot;
extern BOOL gTeleportDisplay;
+static void touch_default_probe(LLReflectionMap* probe)
+{
+ LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
+ origin.mV[2] += 64.f;
+
+ probe->mOrigin.load3(origin.mV);
+}
+
LLReflectionMapManager::LLReflectionMapManager()
{
initCubeFree();
@@ -83,10 +91,8 @@ void LLReflectionMapManager::update()
if (!mRenderTarget.isComplete())
{
U32 color_fmt = GL_RGB16F;
- const bool use_depth_buffer = true;
- const bool use_stencil_buffer = false;
U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample
- mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_TEXTURE);
+ mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
}
if (mMipChain.empty())
@@ -97,7 +103,7 @@ void LLReflectionMapManager::update()
mMipChain.resize(count);
for (int i = 0; i < count; ++i)
{
- mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_TEXTURE);
+ mMipChain[i].allocate(res, res, GL_RGBA16F);
res /= 2;
}
}
@@ -108,9 +114,8 @@ void LLReflectionMapManager::update()
mDefaultProbe = addProbe();
mDefaultProbe->mDistance = -4096.f; // hack to make sure the default probe is always first in sort order
mDefaultProbe->mRadius = 4096.f;
+ touch_default_probe(mDefaultProbe);
}
-
- mDefaultProbe->mOrigin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
LLVector4a camera_pos;
camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
@@ -155,6 +160,8 @@ void LLReflectionMapManager::update()
doProbeUpdate();
}
+ //LL_INFOS() << mProbes.size() << LL_ENDL;
+
for (int i = 0; i < mProbes.size(); ++i)
{
LLReflectionMap* probe = mProbes[i];
@@ -403,7 +410,26 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
{
// hacky hot-swap of camera specific render targets
gPipeline.mRT = &gPipeline.mAuxillaryRT;
- probe->update(mRenderTarget.getWidth(), face);
+
+ if (probe == mDefaultProbe)
+ {
+ touch_default_probe(probe);
+
+ gPipeline.pushRenderTypeMask();
+
+ //only render sky, water, terrain, and clouds
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
+
+ probe->update(mRenderTarget.getWidth(), face);
+
+ gPipeline.popRenderTypeMask();
+ }
+ else
+ {
+ probe->update(mRenderTarget.getWidth(), face);
+ }
+
gPipeline.mRT = &gPipeline.mMainRT;
S32 targetIdx = mReflectionProbeCount;
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 49d5aa3e14..fb2577e00e 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -177,7 +177,7 @@ LLRenderTarget& LLSceneMonitor::getCaptureTarget()
if(!mFrames[0])
{
mFrames[0] = new LLRenderTarget();
- mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+ mFrames[0]->allocate(width, height, GL_RGB);
gGL.getTexUnit(0)->bind(mFrames[0]);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -187,7 +187,7 @@ LLRenderTarget& LLSceneMonitor::getCaptureTarget()
else if(!mFrames[1])
{
mFrames[1] = new LLRenderTarget();
- mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+ mFrames[1]->allocate(width, height, GL_RGB);
gGL.getTexUnit(0)->bind(mFrames[1]);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -360,7 +360,7 @@ void LLSceneMonitor::compare()
if(!mDiff)
{
mDiff = new LLRenderTarget();
- mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
+ mDiff->allocate(width, height, GL_RGBA);
generateDitheringTexture(width, height);
}
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 8b9df88fd4..5ddd8c78f7 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -682,6 +682,7 @@ void settings_setup_listeners()
// DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
setting_setup_signal_listener(gSavedSettings, "RenderReflectionsEnabled", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 5af03477d6..497b2373da 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -918,15 +918,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gGL.setColorMask(true, true);
gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
-
- //store this frame's modelview matrix for use
- //when rendering next frame's occlusion queries
- for (U32 i = 0; i < 16; i++)
- {
- gGLLastModelView[i] = gGLModelView[i];
- gGLLastProjection[i] = gGLProjection[i];
- }
- stop_glerror();
}
{
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 874dec2c2d..90b06fa133 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -843,6 +843,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
BOOL local_light_kill = gSavedSettings.getBOOL("LocalLightDisable");
+ BOOL ssr = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
if (ambient_kill)
{
@@ -871,6 +872,11 @@ std::string LLViewerShaderMgr::loadBasicShaders()
}
}
+ if (ssr)
+ {
+ attribs["SSR"] = "1";
+ }
+
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
@@ -910,7 +916,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", 3) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index bccb2a5e77..20b5f7f394 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4898,7 +4898,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
(image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
{
U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
- if (scratch_space.allocate(image_width, image_height, color_fmt, true, true))
+ if (scratch_space.allocate(image_width, image_height, color_fmt, true))
{
original_width = gPipeline.mRT->deferredScreen.getWidth();
original_height = gPipeline.mRT->deferredScreen.getHeight();
@@ -5162,9 +5162,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
LLRenderTarget scratch_space;
U32 color_fmt = GL_RGBA;
- const bool use_depth_buffer = true;
- const bool use_stencil_buffer = false;
- if (scratch_space.allocate(image_width, image_height, color_fmt, use_depth_buffer, use_stencil_buffer))
+ if (scratch_space.allocate(image_width, image_height, color_fmt, true))
{
if (gPipeline.allocateScreenBuffer(image_width, image_height))
{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f0644cbbf5..64f7535f05 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -479,14 +479,9 @@ void LLPipeline::init()
mBackfaceCull = true;
- stop_glerror();
-
// Enable features
-
LLViewerShaderMgr::instance()->setShaders();
- stop_glerror();
-
for (U32 i = 0; i < 2; ++i)
{
mSpotLightFade[i] = 1.f;
@@ -835,7 +830,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (RenderUIBuffer)
{
- if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE))
+ if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA))
{
return false;
}
@@ -845,18 +840,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
bool ssao = RenderDeferredSSAO;
//allocate deferred rendering color buffers
- if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true, true, LLTexUnit::TT_TEXTURE, false, samples)) return false;
+ if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false;
if (!addDeferredAttachments(mRT->deferredScreen)) return false;
GLuint screenFormat = GL_RGBA16;
- if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, true, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->screen.allocate(resX, resY, screenFormat)) return false;
mRT->deferredScreen.shareDepthBuffer(mRT->screen);
if (samples > 0)
{
- if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA)) return false;
}
else
{
@@ -865,7 +860,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
{ //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
- if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false;
+ if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16)) return false;
}
else
{
@@ -874,6 +869,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
allocateShadowBuffer(resX, resY);
+ if (!gCubeSnapshot && RenderScreenSpaceReflections) // hack to not allocate mSceneMap for cube snapshots
+ {
+ mSceneMap.allocate(resX, resY, GL_RGB, true);
+ }
+
//HACK make screenbuffer allocations start failing after 30 seconds
if (gSavedSettings.getBOOL("SimulateFBOFailure"))
{
@@ -903,7 +903,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{ //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, true, LLTexUnit::TT_TEXTURE))
+ if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, true))
{
return false;
}
@@ -928,7 +928,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
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, true))
+ if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, true))
{
return false;
}
@@ -1112,6 +1112,8 @@ void LLPipeline::releaseGLBuffers()
mWaterDis.release();
mBake.release();
+ mSceneMap.release();
+
for (U32 i = 0; i < 3; i++)
{
mGlow[i].release();
@@ -1185,11 +1187,11 @@ void LLPipeline::createGLBuffers()
if (LLPipeline::sRenderTransparentWater)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
- mWaterDis.allocate(res,res,GL_RGBA,true,true,LLTexUnit::TT_TEXTURE);
+ mWaterDis.allocate(res,res,GL_RGBA,true);
}
// Use FBO for bake tex
- mBake.allocate(512, 512, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, true); // SL-12781 Build > Upload > Model; 3D Preview
+ mBake.allocate(512, 512, GL_RGBA, true); // SL-12781 Build > Upload > Model; 3D Preview
stop_glerror();
@@ -1200,7 +1202,7 @@ void LLPipeline::createGLBuffers()
const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE);
+ mGlow[i].allocate(512, glow_res, GL_RGBA);
}
allocateScreenBuffer(resX, resY);
@@ -1306,7 +1308,7 @@ void LLPipeline::createLUTBuffers()
delete [] ls;
}
- mPbrBrdfLut.allocate(512, 512, GL_RG16F, false, false);
+ mPbrBrdfLut.allocate(512, 512, GL_RG16F);
mPbrBrdfLut.bindTarget();
gDeferredGenBrdfLutProgram.bind();
@@ -4019,6 +4021,26 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
+ if (&camera == LLViewerCamera::getInstance())
+ { // a bit hacky, this is the start of the main render frame, figure out delta between last modelview matrix and
+ // current modelview matrix
+ glh::matrix4f last_modelview(gGLLastModelView);
+ glh::matrix4f cur_modelview(gGLModelView);
+
+ // goal is to have a matrix here that goes from the last frame's camera space to the current frame's camera space
+ glh::matrix4f m = last_modelview.inverse(); // last camera space to world space
+ m.mult_left(cur_modelview); // world space to camera space
+
+ glh::matrix4f n = m.inverse();
+
+ for (U32 i = 0; i < 16; ++i)
+ {
+ gGLDeltaModelView[i] = m.m[i];
+ gGLInverseDeltaModelView[i] = n.m[i];
+ }
+
+ }
+
bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
setupHWLights(nullptr);
@@ -7529,10 +7551,11 @@ void LLPipeline::renderFinalize()
if (!gCubeSnapshot)
{
- screenTarget()->bindTarget();
+ LLRenderTarget* screen_target = screenTarget();
- if (RenderScreenSpaceReflections)
+ if (RenderScreenSpaceReflections && !gCubeSnapshot)
{
+#if 0
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections");
LL_PROFILE_GPU_ZONE("screen space reflections");
@@ -7565,8 +7588,33 @@ void LLPipeline::renderFinalize()
}
unbindDeferredShader(gPostScreenSpaceReflectionProgram);
+#else
+ LL_PROFILE_GPU_ZONE("ssr copy");
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ LLRenderTarget& src = *screen_target;
+ LLRenderTarget& depth_src = mRT->deferredScreen;
+ LLRenderTarget& dst = mSceneMap;
+
+ dst.bindTarget();
+ dst.clear();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(&src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst.flush();
+#endif
}
+ screenTarget()->bindTarget();
+
// gamma correct lighting
{
LL_PROFILE_GPU_ZONE("gamma correct");
@@ -7821,56 +7869,6 @@ void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
bindLightFunc(shader);
bindShadowMaps(shader);
bindReflectionProbes(shader);
-
-#if 0
- shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
- shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
-
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale);
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale);
-
- F32 ssao_factor = RenderSSAOFactor;
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor);
- shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0 / ssao_factor);
-
- LLVector3 ssao_effect = RenderSSAOEffect;
- F32 matrix_diag = (ssao_effect[0] + 2.0 * ssao_effect[1]) / 3.0;
- F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1]) / 3.0;
- // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by
- // value factor, and scales remainder by saturation factor
- F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag,
- matrix_nondiag, matrix_diag, matrix_nondiag,
- matrix_nondiag, matrix_nondiag, matrix_diag };
- shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat);
-
- //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
- F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]) / 3000.f;
- F32 shadow_bias = RenderShadowBias + shadow_bias_error;
-
- //shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_target->getWidth(), deferred_target->getHeight());
- shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear() * 2.f);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, shadow_bias);
- shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset);
- shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias);
-
- 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, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
- shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
- shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
-
- if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
- {
- glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
- shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
- }
-
- shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV);
- shader.uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
-#endif
}
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
@@ -7910,21 +7908,24 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
-#if 0
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
- if (channel > -1)
- {
- gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
- stop_glerror();
- }
-#else
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
if (channel > -1)
{
gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
stop_glerror();
}
-#endif
+
+ channel = shader.enableTexture(LLShaderMgr::SCENE_MAP);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&mSceneMap);
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::SCENE_DEPTH);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&mSceneMap, true);
+ }
if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1)
{
@@ -8090,6 +8091,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
+ shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLDeltaModelView);
+ shader.uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLInverseDeltaModelView);
+
+ shader.uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0);
+
if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
@@ -8584,6 +8590,16 @@ void LLPipeline::renderDeferredLighting()
screen_target->flush();
+ if (!gCubeSnapshot)
+ {
+ // this is the end of the 3D scene render, grab a copy of the modelview and projection
+ // matrix for use in off-by-one-frame effects in the next frame
+ for (U32 i = 0; i < 16; i++)
+ {
+ gGLLastModelView[i] = gGLModelView[i];
+ gGLLastProjection[i] = gGLProjection[i];
+ }
+ }
gGL.setColorMask(true, true);
}
@@ -10398,7 +10414,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
if (!avatar->mImpostor.isComplete())
{
- avatar->mImpostor.allocate(resX, resY, GL_RGBA, TRUE, FALSE);
+ avatar->mImpostor.allocate(resX, resY, GL_RGBA, true);
if (LLPipeline::sRenderDeferred)
{
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index d87387e4c3..0c11c7ef89 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -685,6 +685,10 @@ public:
LLRenderTarget mPbrBrdfLut;
+ // copy of the color/depth buffer just before gamma correction
+ // for use by SSR
+ LLRenderTarget mSceneMap;
+
LLCullResult mSky;
LLCullResult mReflectedObjects;
LLCullResult mRefractedObjects;