diff options
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; | 
