diff options
| author | Dave Parks <davep@lindenlab.com> | 2011-05-25 15:53:45 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2011-05-25 15:53:45 -0500 | 
| commit | dbefd976ed137e04b7f43949b029ccb3db6a5399 (patch) | |
| tree | f220831b20c6c2855ef75a84e1d2ecf0ee0ab709 | |
| parent | 8e728befa57bcea0981179709dd5f13af1cd29a8 (diff) | |
| parent | 9eea451a82379a61fa4a6cc2a55274e06cecbd58 (diff) | |
merge
55 files changed, 3832 insertions, 522 deletions
| diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index a460912e70..77b34eb546 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -178,6 +178,12 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL;  PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;  PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL; +//GL_ARB_texture_multisample +PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +PFNGLSAMPLEMASKIPROC glSampleMaski; +  // GL_EXT_blend_func_separate  PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL; @@ -321,6 +327,7 @@ LLGLManager::LLGLManager() :  	mHasMipMapGeneration(FALSE),  	mHasCompressedTextures(FALSE),  	mHasFramebufferObject(FALSE), +	mMaxSamples(0),  	mHasBlendFuncSeparate(FALSE),  	mHasVertexBufferObject(FALSE), @@ -334,6 +341,11 @@ LLGLManager::LLGLManager() :  	mHasPointParameters(FALSE),  	mHasDrawBuffers(FALSE),  	mHasTextureRectangle(FALSE), +	mHasTextureMultisample(FALSE), +	mMaxSampleMaskWords(0), +	mMaxColorTextureSamples(0), +	mMaxDepthTextureSamples(0), +	mMaxIntegerSamples(0),  	mHasAnisotropic(FALSE),  	mHasARBEnvCombine(FALSE), @@ -541,6 +553,19 @@ bool LLGLManager::initGL()  		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);  		mNumTextureImageUnits = num_tex_image_units;  	} + +	if (mHasTextureMultisample) +	{ +		glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); +		glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); +		glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); +		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); +	} + +	if (mHasFramebufferObject) +	{ +		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); +	}  	setToDebugGPU(); @@ -648,6 +673,14 @@ std::string LLGLManager::getRawGLString()  	return gl_string;  } +U32 LLGLManager::getNumFBOFSAASamples(U32 samples) +{ +	samples = llmin(samples, (U32) mMaxColorTextureSamples); +	samples = llmin(samples, (U32) mMaxDepthTextureSamples); +	samples = llmin(samples, (U32) 4); +	return samples; +} +  void LLGLManager::shutdownGL()  {  	if (mInited) @@ -742,6 +775,7 @@ void LLGLManager::initExtensions()  	mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);  	mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);  	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); +	mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);  #if !LL_DARWIN  	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);  #endif @@ -953,6 +987,13 @@ void LLGLManager::initExtensions()  	{  		glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");  	} +	if (mHasTextureMultisample) +	{ +		glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample"); +		glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample"); +		glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv"); +		glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski"); +	}	  #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS  	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah  	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements"); @@ -1384,7 +1425,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)  		"GL_TEXTURE_GEN_T",  		"GL_TEXTURE_GEN_Q",  		"GL_TEXTURE_GEN_R", -		"GL_TEXTURE_RECTANGLE_ARB" +		"GL_TEXTURE_RECTANGLE_ARB", +		"GL_TEXTURE_2D_MULTISAMPLE"  	};  	static GLint value[] = @@ -1397,7 +1439,8 @@ void LLGLState::checkTextureChannels(const std::string& msg)  		GL_TEXTURE_GEN_T,  		GL_TEXTURE_GEN_Q,  		GL_TEXTURE_GEN_R, -		GL_TEXTURE_RECTANGLE_ARB +		GL_TEXTURE_RECTANGLE_ARB, +		GL_TEXTURE_2D_MULTISAMPLE  	};  	GLint stackDepth = 0; @@ -1439,9 +1482,17 @@ void LLGLState::checkTextureChannels(const std::string& msg)  		} +		S32 num_texture_types = 8; +		  		for (S32 j = (i == 0 ? 1 : 0);  -			j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++) +			j < 9; j++)  		{ +			if (j == 8 && !gGLManager.mHasTextureRectangle || +				j == 9 && !gGLManager.mHasTextureMultisample) +			{ +				continue; +			} +				  			if (glIsEnabled(value[j]))  			{  				error = TRUE; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 1d7ab188fc..420922cf06 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -83,8 +83,9 @@ public:  	BOOL mHasMipMapGeneration;  	BOOL mHasCompressedTextures;  	BOOL mHasFramebufferObject; +	S32 mMaxSamples;  	BOOL mHasBlendFuncSeparate; -	 +		  	// ARB Extensions  	BOOL mHasVertexBufferObject;  	BOOL mHasPBuffer; @@ -98,6 +99,11 @@ public:  	BOOL mHasDrawBuffers;  	BOOL mHasDepthClamp;  	BOOL mHasTextureRectangle; +	BOOL mHasTextureMultisample; +	S32 mMaxSampleMaskWords; +	S32 mMaxColorTextureSamples; +	S32 mMaxDepthTextureSamples; +	S32 mMaxIntegerSamples;  	// Other extensions.  	BOOL mHasAnisotropic; @@ -139,6 +145,7 @@ public:  	void printGLInfoString();  	void getGLInfo(LLSD& info); +	U32 getNumFBOFSAASamples(U32 desired_samples = 32);  	// In ALL CAPS  	std::string mGLVendor;  	std::string mGLVendorShort; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index d8140a124d..825d304d35 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -474,6 +474,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;  //GL_ARB_draw_buffers  extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +//GL_ARB_texture_multisample +extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +extern PFNGLSAMPLEMASKIPROC glSampleMaski;  #elif LL_WINDOWS  //---------------------------------------------------------------------------- @@ -673,6 +678,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;  //GL_ARB_draw_buffers  extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +//GL_ARB_texture_multisample +extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +extern PFNGLSAMPLEMASKIPROC glSampleMaski;  #elif LL_DARWIN  //---------------------------------------------------------------------------- diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 257bcd9380..2e7147a3b4 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -293,7 +293,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)  GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)  { -	if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) +	if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB || +		type == GL_SAMPLER_2D_MULTISAMPLE)  	{	//this here is a texture  		glUniform1iARB(location, mActiveTextureChannels);  		LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d408077c68..3a4139bace 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1083,12 +1083,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)  }  // static -void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) +void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)  {  	for (S32 i = 0; i < numTextures; i++)  	{  		sDeadTextureList.push_back(textures[i]);  	} + +	if (immediate) +	{ +		LLImageGL::deleteDeadTextures(); +	}  }  // static @@ -1417,7 +1422,7 @@ void LLImageGL::deleteDeadTextures()  		{  			if (sCurrentBoundTextures[i] == tex)  			{ -				gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); +				gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());  				stop_glerror();  			}  		} diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6c980984c0..2cfb15b0d9 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -98,7 +98,7 @@ public:  	// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()   	// for tracking purposes and will be deprecated in the future  	static void generateTextures(S32 numTextures, U32 *textures); -	static void deleteTextures(S32 numTextures, U32 *textures); +	static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);  	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);  	BOOL createGLTexture() ; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c37139ac4c..049dd4346b 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -53,7 +53,8 @@ static GLenum sGLTextureType[] =  {  	GL_TEXTURE_2D,  	GL_TEXTURE_RECTANGLE_ARB, -	GL_TEXTURE_CUBE_MAP_ARB +	GL_TEXTURE_CUBE_MAP_ARB, +	GL_TEXTURE_2D_MULTISAMPLE  };  static GLint sGLAddressMode[] = @@ -124,7 +125,7 @@ void LLTexUnit::refreshState(void)  	// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units  	// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html  	// -	bool enableDisable = (mIndex < gGLManager.mNumTextureUnits); +	bool enableDisable = (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;  	if (mCurrTexType != TT_NONE)  	{ @@ -182,8 +183,8 @@ void LLTexUnit::enable(eTextureType type)  		mCurrTexType = type;  		gGL.flush(); -		 -		if (mIndex < gGLManager.mNumTextureUnits) +		if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && +			mIndex < gGLManager.mNumTextureUnits)  		{  			glEnable(sGLTextureType[type]);  		} @@ -199,8 +200,8 @@ void LLTexUnit::disable(void)  		activate();  		unbind(mCurrTexType);  		gGL.flush(); -		 -		if (mIndex < gGLManager.mNumTextureUnits) +		if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE && +			mIndex < gGLManager.mNumTextureUnits)  		{  			glDisable(sGLTextureType[mCurrTexType]);  		} @@ -423,7 +424,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)  void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)  { -	if (mIndex < 0 || mCurrTexture == 0) return; +	if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;  	gGL.flush(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7ba14f7b40..41e7b35341 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -57,6 +57,7 @@ public:  		TT_TEXTURE = 0,			// Standard 2D Texture  		TT_RECT_TEXTURE,	// Non power of 2 texture  		TT_CUBE_MAP,		// 6-sided cube map texture +		TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample  		TT_NONE 		// No texture type is currently enabled  	} eTextureType; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index da1e94df64..715f466314 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -63,8 +63,7 @@ LLRenderTarget::LLRenderTarget() :  	mUseDepth(false),  	mRenderDepth(false),  	mUsage(LLTexUnit::TT_TEXTURE), -	mSamples(0), -	mSampleBuffer(NULL) +	mSamples(0)  {  } @@ -73,13 +72,7 @@ LLRenderTarget::~LLRenderTarget()  	release();  } - -void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer) -{ -	mSampleBuffer = buffer; -} - -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo) +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)  {  	stop_glerror();  	mResX = resx; @@ -88,6 +81,20 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo  	mStencil = stencil;  	mUsage = usage;  	mUseDepth = depth; +	mSamples = samples; + +	mSamples = gGLManager.getNumFBOFSAASamples(mSamples); +	 +	if (mSamples > 1 && gGLManager.mHasTextureMultisample) +	{ +		mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE; +		//no support for multisampled stencil targets yet +		mStencil = false; +	} +	else +	{ +		mSamples = 0; +	}  	release(); @@ -146,29 +153,47 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)  	stop_glerror(); -	LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -	stop_glerror(); - -	if (offset == 0) +	if (mSamples > 1)  	{ -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); +		glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);  	}  	else -	{ //don't filter data attachments -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -	} -	if (mUsage != LLTexUnit::TT_RECT_TEXTURE)  	{ -		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); +		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  	} -	else -	{ -		// ATI doesn't support mirrored repeat for rectangular textures. -		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); +	 +	stop_glerror(); + +	if (mSamples == 0) +	{  +		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); @@ -181,6 +206,12 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)  	mTex.push_back(tex); +	if (gDebugGL) +	{ //bind and unbind to validate target +		bindTarget(); +		flush(); +	} +  }  void LLRenderTarget::allocateDepth() @@ -197,9 +228,16 @@ void LLRenderTarget::allocateDepth()  	{  		LLImageGL::generateTextures(1, &mDepth);  		gGL.getTexUnit(0)->bindManual(mUsage, mDepth); -		U32 internal_type = LLTexUnit::getInternalType(mUsage); -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); +		if (mSamples == 0) +		{ +			U32 internal_type = LLTexUnit::getInternalType(mUsage); +			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +			LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); +		} +		else +		{ +			glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE); +		}  	}  } @@ -239,6 +277,9 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)  			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);  			stop_glerror();  		} + +		check_framebuffer_status(); +  		glBindFramebuffer(GL_FRAMEBUFFER, 0);  		target.mUseDepth = true; @@ -256,7 +297,7 @@ void LLRenderTarget::release()  		}  		else  		{ -			LLImageGL::deleteTextures(1, &mDepth); +			LLImageGL::deleteTextures(1, &mDepth, true);  			stop_glerror();  		}  		mDepth = 0; @@ -285,11 +326,10 @@ void LLRenderTarget::release()  	if (mTex.size() > 0)  	{ -		LLImageGL::deleteTextures(mTex.size(), &mTex[0]); +		LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);  		mTex.clear();  	} -	mSampleBuffer = NULL;  	sBoundTarget = NULL;  } @@ -298,34 +338,27 @@ void LLRenderTarget::bindTarget()  	if (mFBO)  	{  		stop_glerror(); -		if (mSampleBuffer) -		{ -			mSampleBuffer->bindTarget(this); -			stop_glerror(); +		 +		glBindFramebuffer(GL_FRAMEBUFFER, mFBO); +		stop_glerror(); +		if (gGLManager.mHasDrawBuffers) +		{ //setup multiple render targets +			GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, +									GL_COLOR_ATTACHMENT1, +									GL_COLOR_ATTACHMENT2, +									GL_COLOR_ATTACHMENT3}; +			glDrawBuffersARB(mTex.size(), drawbuffers);  		} -		else -		{ -			glBindFramebuffer(GL_FRAMEBUFFER, mFBO); -			stop_glerror(); -			if (gGLManager.mHasDrawBuffers) -			{ //setup multiple render targets -				GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, -										GL_COLOR_ATTACHMENT1, -										GL_COLOR_ATTACHMENT2, -										GL_COLOR_ATTACHMENT3}; -				glDrawBuffersARB(mTex.size(), drawbuffers); -			} -			if (mTex.empty()) -			{ //no color buffer to draw to -				glDrawBuffer(GL_NONE); -				glReadBuffer(GL_NONE); -			} +		if (mTex.empty()) +		{ //no color buffer to draw to +			glDrawBuffer(GL_NONE); +			glReadBuffer(GL_NONE); +		} -			check_framebuffer_status(); +		check_framebuffer_status(); -			stop_glerror(); -		} +		stop_glerror();  	}  	glViewport(0, 0, mResX, mResY); @@ -407,50 +440,8 @@ void LLRenderTarget::flush(bool fetch_depth)  	else  	{  		stop_glerror(); -  		glBindFramebuffer(GL_FRAMEBUFFER, 0); -  		stop_glerror(); -	 -		if (mSampleBuffer) -		{ -			LLGLEnable multisample(GL_MULTISAMPLE); -			stop_glerror(); -			glBindFramebuffer(GL_FRAMEBUFFER, mFBO); -			stop_glerror(); -			check_framebuffer_status(); -			glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO); -			check_framebuffer_status(); -			 -			stop_glerror(); -			glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -			stop_glerror();		 - -			if (mTex.size() > 1) -			{		 -				for (U32 i = 1; i < mTex.size(); ++i) -				{ -					glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -										LLTexUnit::getInternalType(mUsage), mTex[i], 0); -					stop_glerror(); -					glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); -					stop_glerror(); -					glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST);		 -					stop_glerror(); -				} - -				for (U32 i = 0; i < mTex.size(); ++i) -				{ -					glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, -										LLTexUnit::getInternalType(mUsage), mTex[i], 0); -					stop_glerror(); -					glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); -					stop_glerror(); -				} -			} -		} - -		glBindFramebuffer(GL_FRAMEBUFFER, 0);  	}  } @@ -467,37 +458,36 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,  		llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;  	} -	if (mSampleBuffer) +	 +	if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)  	{ -		mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +		stop_glerror(); +		 +		glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); +		check_framebuffer_status(); +		gGL.getTexUnit(0)->bind(this, true); +		stop_glerror(); +		glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); +		stop_glerror(); +		glBindFramebuffer(GL_FRAMEBUFFER, 0); +		stop_glerror();  	}  	else  	{ -		if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) -		{ -			stop_glerror(); -		 -			glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); -			gGL.getTexUnit(0)->bind(this, true); -			stop_glerror(); -			glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); -			stop_glerror(); -			glBindFramebuffer(GL_FRAMEBUFFER, 0); -			stop_glerror(); -		} -		else -		{ -			glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); -			stop_glerror(); -			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); -			stop_glerror(); -			check_framebuffer_status(); -			stop_glerror(); -			glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -			stop_glerror(); -			glBindFramebuffer(GL_FRAMEBUFFER, 0); -			stop_glerror(); -		} +		glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); +		stop_glerror(); +		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); +		stop_glerror(); +		check_framebuffer_status(); +		stop_glerror(); +		glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +		stop_glerror(); +		glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +		stop_glerror(); +		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +		stop_glerror(); +		glBindFramebuffer(GL_FRAMEBUFFER, 0); +		stop_glerror();  	}  } @@ -540,179 +530,3 @@ void LLRenderTarget::getViewport(S32* viewport)  	viewport[3] = mResY;  } -//================================================== -// LLMultisampleBuffer implementation -//================================================== -LLMultisampleBuffer::LLMultisampleBuffer() -{ - -} - -LLMultisampleBuffer::~LLMultisampleBuffer() -{ -	release(); -} - -void LLMultisampleBuffer::release() -{ -	if (mFBO) -	{ -		glDeleteFramebuffers(1, (GLuint *) &mFBO); -		mFBO = 0; -	} - -	if (mTex.size() > 0) -	{ -		glDeleteRenderbuffers(mTex.size(), (GLuint *) &mTex[0]); -		mTex.clear(); -	} - -	if (mDepth) -	{ -		glDeleteRenderbuffers(1, (GLuint *) &mDepth); -		mDepth = 0; -	} -} - -void LLMultisampleBuffer::bindTarget() -{ -	bindTarget(this); -} - -void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref) -{ -	if (!ref) -	{ -		ref = this; -	} - -	glBindFramebuffer(GL_FRAMEBUFFER, mFBO); -	if (gGLManager.mHasDrawBuffers) -	{ //setup multiple render targets -		GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, -								GL_COLOR_ATTACHMENT1, -								GL_COLOR_ATTACHMENT2, -								GL_COLOR_ATTACHMENT3}; -		glDrawBuffersARB(ref->mTex.size(), drawbuffers); -	} - -	check_framebuffer_status(); - -	glViewport(0, 0, mResX, mResY); - -	sBoundTarget = this; -} - -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil,  LLTexUnit::eTextureType usage, bool use_fbo ) -{ -	allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2); -} - -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil,  LLTexUnit::eTextureType usage, bool use_fbo, U32 samples ) -{ -	stop_glerror(); -	mResX = resx; -	mResY = resy; - -	mUsage = usage; -	mUseDepth = depth; -	mStencil = stencil; - -	release(); - -	mSamples = samples; -	 -	if (mSamples <= 1) -	{ -		llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; -	} - -	stop_glerror(); - -	if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) -	{ - -		if (depth) -		{ -			stop_glerror(); -			allocateDepth(); -			stop_glerror(); -		} - -		glGenFramebuffers(1, (GLuint *) &mFBO); - -		glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - -		if (mDepth) -		{ -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); -			if (mStencil) -			{ -				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);			 -			} -		} -	 -		stop_glerror(); -		glBindFramebuffer(GL_FRAMEBUFFER, 0); -		stop_glerror(); -	} - -	addColorAttachment(color_fmt); -} - -void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) -{ -	if (color_fmt == 0) -	{ -		return; -	} - -	U32 offset = mTex.size(); -	if (offset >= 4 || -		(offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) -	{ -		llerrs << "Too many color attachments!" << llendl; -	} - -	U32 tex; -	glGenRenderbuffers(1, &tex); -	 -	glBindRenderbuffer(GL_RENDERBUFFER, tex); -	glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, color_fmt, mResX, mResY); -	stop_glerror(); - -	if (mFBO) -	{ -		glBindFramebuffer(GL_FRAMEBUFFER, mFBO); -		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex); -		stop_glerror(); -		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); -		switch (status) -		{ -		case GL_FRAMEBUFFER_COMPLETE: -			break; -		default: -			llerrs << "WTF? " << std::hex << status << llendl; -			break; -		} - -		glBindFramebuffer(GL_FRAMEBUFFER, 0); -	} - -	mTex.push_back(tex); -} - -void LLMultisampleBuffer::allocateDepth() -{ -	glGenRenderbuffers(1, (GLuint* ) &mDepth); -	glBindRenderbuffer(GL_RENDERBUFFER, mDepth); -	if (mStencil) -	{ -		glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY);	 -	} -	else -	{ -		glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16, mResX, mResY);	 -	} -} - diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 12dd1c8b90..094b58b562 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -71,10 +71,7 @@ public:  	//allocate resources for rendering  	//must be called before use  	//multiple calls will release previously allocated resources -	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE); - -	//provide this render target with a multisample resource. -	void setSampleBuffer(LLMultisampleBuffer* buffer); +	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);  	//add color buffer attachment  	//limit of 4 color attachments per render target @@ -141,7 +138,6 @@ public:  	static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }  protected: -	friend class LLMultisampleBuffer;  	U32 mResX;  	U32 mResY;  	std::vector<U32> mTex; @@ -152,26 +148,8 @@ protected:  	bool mRenderDepth;  	LLTexUnit::eTextureType mUsage;  	U32 mSamples; -	LLMultisampleBuffer* mSampleBuffer; - -	static LLRenderTarget* sBoundTarget; -}; - -class LLMultisampleBuffer : public LLRenderTarget -{ -public: -	LLMultisampleBuffer(); -	virtual ~LLMultisampleBuffer(); - -	virtual void release(); - -	virtual void bindTarget(); -	void bindTarget(LLRenderTarget* ref); -	virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo); -	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples); -	virtual void addColorAttachment(U32 color_fmt); -	virtual void allocateDepth(); +	static LLRenderTarget* sBoundTarget;  };  #endif //!LL_MESA_HEADLESS diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 98a0a93084..b8f9c60ca9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -374,6 +374,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	GLcharARB* text[1024];  	GLuint count = 0; +	//copy preprocessor definitions into buffer +	for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) +	{ +		std::string define = "#define " + iter->first + " " + iter->second + "\n"; +		text[count++] = (GLcharARB *) strdup(define.c_str()); +	}  	//copy file into memory  	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )  diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index c54c4608d7..9ee11b98c8 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -60,6 +60,9 @@ public:  	std::vector<std::string> mReservedUniforms; +	//preprocessor definitions (name/value) +	std::map<std::string, std::string> mDefinitions; +  protected:  	// our parameter manager singleton instance diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index d9f021b114..98d034c2b5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -26,7 +26,7 @@ uniform vec2 screen_res;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -39,7 +39,7 @@ vec4 getPosition(vec2 pos_screen)  void main()   { -        vec2 tc = vary_fragcoord.xy; +    vec2 tc = vary_fragcoord.xy;  	vec3 norm = texture2DRect(normalMap, tc).xyz;  	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	vec3 pos = getPosition(tc).xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl new file mode 100644 index 0000000000..edec83ea07 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl @@ -0,0 +1,113 @@ +/**  + * @file blurLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; + +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform vec3 kern[4]; +uniform float kern_scale; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec3 texture2DMS3(sampler2DMS tex, ivec2 tc) +{ +	vec3 ret = vec3(0,0,0); +	for (int i = 0; i < samples; i++) +	{ +		ret += texelFetch(tex, tc, i).rgb; +	} + +	return ret/samples; +} + +float texture2DMS1(sampler2DMS tex, ivec2 tc) +{ +	float ret = 0; +	for (int i = 0; i < samples; i++) +	{ +		ret += texelFetch(tex, tc, i).r; +	} + +	return ret/samples; +} + +vec4 getPosition(ivec2 pos_screen) +{ +	float depth = texture2DMS1(depthMap, pos_screen.xy); +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +    vec2 tc = vary_fragcoord.xy; +	ivec2 itc = ivec2(tc); + +	vec3 norm = texture2DMS3(normalMap, itc).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	vec3 pos = getPosition(itc).xyz; +	vec4 ccol = texture2DRect(lightMap, tc).rgba; +	 +	vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); +	dlt /= max(-pos.z*dist_factor, 1.0); +	 +	vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' +	vec4 col = defined_weight.xyxx * ccol; + +	// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances +	float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; + +	// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large +	tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 ); + +	for (int i = 1; i < 4; i++) +	{ +		vec2 samptc = tc + kern[i].z*dlt; +		vec3 samppos = getPosition(ivec2(samptc)).xyz;  +		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane +		if (d*d <= pointplanedist_tolerance_pow2) +		{ +			col += texture2DRect(lightMap, samptc)*kern[i].xyxx; +			defined_weight += kern[i].xy; +		} +	} +	for (int i = 1; i < 4; i++) +	{ +		vec2 samptc = vec2(tc - kern[i].z*dlt); +		vec3 samppos = getPosition(ivec2(samptc)).xyz;  +		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane +		if (d*d <= pointplanedist_tolerance_pow2) +		{ +			col += texture2DRect(lightMap, samptc)*kern[i].xyxx; +			defined_weight += kern[i].xy; +		} +	} + +	col /= defined_weight.xyxx; +	col.y *= col.y; + +	gl_FragColor = col; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl new file mode 100644 index 0000000000..9e551fa976 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -0,0 +1,79 @@ +/**  + * @file WLCloudsF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +varying vec4 vary_CloudColorSun; +varying vec4 vary_CloudColorAmbient; +varying float vary_CloudDensity; + +uniform sampler2D cloud_noise_texture; +uniform vec4 cloud_pos_density1; +uniform vec4 cloud_pos_density2; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { +	//soft clip effect: +	light = 1. - clamp(light, vec3(0.), vec3(1.)); +	light = 1. - pow(light, gamma.xxx); + +	return light; +} + +void main() +{ +	// Set variables +	vec2 uv1 = gl_TexCoord[0].xy; +	vec2 uv2 = gl_TexCoord[1].xy; + +	vec4 cloudColorSun = vary_CloudColorSun; +	vec4 cloudColorAmbient = vary_CloudColorAmbient; +	float cloudDensity = vary_CloudDensity; +	vec2 uv3 = gl_TexCoord[2].xy; +	vec2 uv4 = gl_TexCoord[3].xy; + +	// Offset texture coords +	uv1 += cloud_pos_density1.xy;	//large texture, visible density +	uv2 += cloud_pos_density1.xy;	//large texture, self shadow +	uv3 += cloud_pos_density2.xy;	//small texture, visible density +	uv4 += cloud_pos_density2.xy;	//small texture, self shadow + + +	// Compute alpha1, the main cloud opacity +	float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z; +	alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.); + +	// And smooth +	alpha1 = 1. - alpha1 * alpha1; +	alpha1 = 1. - alpha1 * alpha1;	 + + +	// Compute alpha2, for self shadowing effect +	// (1 - alpha2) will later be used as percentage of incoming sunlight +	float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5); +	alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.); + +	// And smooth +	alpha2 = 1. - alpha2; +	alpha2 = 1. - alpha2 * alpha2;	 + +	// Combine +	vec4 color; +	color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient); +	color *= 2.; + +	/// Gamma correct for WL (soft clip effect). +	gl_FragData[0] = vec4(scaleSoftClip(color.rgb), alpha1); +	gl_FragData[1] = vec4(0.0,0.0,0.0,0.0); +	gl_FragData[2] = vec4(0,0,1,0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl new file mode 100644 index 0000000000..267ef36d4d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl @@ -0,0 +1,165 @@ +/**  + * @file WLCloudsV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +////////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +varying vec4 vary_CloudColorSun; +varying vec4 vary_CloudColorAmbient; +varying float vary_CloudDensity; + +// Inputs +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; + +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform vec4 cloud_scale; + +void main() +{ + +	// World / view / projection +	gl_Position = ftransform(); + +	gl_TexCoord[0] = gl_MultiTexCoord0; + +	// Get relative position +	vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0); + +	// Set altitude +	if (P.y > 0.) +	{ +		P *= (max_y.x / P.y); +	} +	else +	{ +		P *= (-32000. / P.y); +	} + +	// Can normalize then +	vec3 Pn = normalize(P); +	float  Plen = length(P); + +	// Initialize temp variables +	vec4 temp1 = vec4(0.); +	vec4 temp2 = vec4(0.); +	vec4 blue_weight; +	vec4 haze_weight; +	vec4 sunlight = sunlight_color; +	vec4 light_atten; + + +	// Sunlight attenuation effect (hue and brightness) due to atmosphere +	// this is used later for sunlight modulation at various altitudes +	light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + +	// Calculate relative weights +	temp1 = blue_density + haze_density.x; +	blue_weight = blue_density / temp1; +	haze_weight = haze_density.x / temp1; + +	// Compute sunlight from P & lightnorm (for long rays like sky) +	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// Distance +	temp2.z = Plen * density_multiplier.x; + +	// Transparency (-> temp1) +	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati +	// compiler gets confused. +	temp1 = exp(-temp1 * temp2.z); + + +	// Compute haze glow +	temp2.x = dot(Pn, lightnorm.xyz); +	temp2.x = 1. - temp2.x; +		// temp2.x is 0 at the sun and increases away from sun +	temp2.x = max(temp2.x, .001);	 +		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.x *= glow.x; +		// Higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.x = pow(temp2.x, glow.z); +		// glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	// Add "minimum anti-solar illumination" +	temp2.x += .25; + +	// Increase ambient when there are more clouds +	vec4 tmpAmbient = ambient; +	tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5;  + +	// Dim sunlight by cloud shadow percentage +	sunlight *= (1. - cloud_shadow.x); + +	// Haze color below cloud +	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient) +				+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) +			 );	 + +	// CLOUDS + +	sunlight = sunlight_color; +	temp2.y = max(0., lightnorm.y * 2.); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// Cloud color out +	vary_CloudColorSun = (sunlight * temp2.x) * cloud_color; +	vary_CloudColorAmbient = tmpAmbient * cloud_color; +	 +	// Attenuate cloud color by atmosphere +	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds +	vary_CloudColorSun *= temp1; +	vary_CloudColorAmbient *= temp1; +	vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); + +	// Make a nice cloud density based on the cloud_shadow value that was passed in. +	vary_CloudDensity = 2. * (cloud_shadow.x - 0.25); + + +	// Texture coords +	gl_TexCoord[0] = gl_MultiTexCoord0; +	gl_TexCoord[0].xy -= 0.5; +	gl_TexCoord[0].xy /= cloud_scale.x; +	gl_TexCoord[0].xy += 0.5; + +	gl_TexCoord[1] = gl_TexCoord[0]; +	gl_TexCoord[1].x += lightnorm.x * 0.0125; +	gl_TexCoord[1].y += lightnorm.z * 0.0125; + +	gl_TexCoord[2] = gl_TexCoord[0] * 16.; +	gl_TexCoord[3] = gl_TexCoord[1] * 16.; + +	// Combine these to minimize register use +	vary_CloudColorAmbient += oHazeColorBelowCloud; + +	// needs this to compile on mac +	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0); + +	// END CLOUDS +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 609fc4f14f..e10fb105e8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -36,7 +36,7 @@ uniform mat4 inv_proj;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl new file mode 100644 index 0000000000..66c7a5cb4a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl @@ -0,0 +1,137 @@ +/**  + * @file multiPointLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + + +uniform vec3 env_mat[3]; +uniform float sun_wash; + +uniform int light_count; + +#define MAX_LIGHT_COUNT		16 +uniform vec4 light[MAX_LIGHT_COUNT]; +uniform vec4 light_col[MAX_LIGHT_COUNT]; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform float far_z; + +uniform mat4 inv_proj; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; +	ivec2 itc = ivec2(frag); + +	int wght = 0; +	vec3 fcol = vec3(0,0,0); + +	for (int s = 0; s < samples; ++s) +	{ +		vec3 pos = getPosition(itc, s).xyz; +		if (pos.z >= far_z) +		{ +			vec3 norm = texelFetch(normalMap, itc, s).xyz; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +			norm = normalize(norm); +			vec4 spec = texelFetch(specularRect, itc, s); +			vec3 diff = texelFetch(diffuseRect, itc, s).rgb; +			float noise = texture2D(noiseMap, frag.xy/128.0).b; +			vec3 out_col = vec3(0,0,0); +			vec3 npos = normalize(-pos); + +			// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop +			for (int i = 0; i < MAX_LIGHT_COUNT; ++i) +			{ +				bool light_contrib = (i < light_count); +		 +				vec3 lv = light[i].xyz-pos; +				float dist2 = dot(lv,lv); +				dist2 /= light[i].w; +				if (dist2 > 1.0) +				{ +					light_contrib = false; +				} +		 +				float da = dot(norm, lv); +				if (da < 0.0) +				{ +					light_contrib = false; +				} +		 +				if (light_contrib) +				{ +					lv = normalize(lv); +					da = dot(norm, lv); +					 +					float fa = light_col[i].a+1.0; +					float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +					dist_atten *= noise; + +					float lit = da * dist_atten; +			 +					vec3 col = light_col[i].rgb*lit*diff; +					//vec3 col = vec3(dist2, light_col[i].a, lit); +			 +					if (spec.a > 0.0) +					{ +						//vec3 ref = dot(pos+lv, norm); +				 +						float sa = dot(normalize(lv+npos),norm); +				 +						if (sa > 0.0) +						{ +							sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); +							sa *= noise; +							col += da*sa*light_col[i].rgb*spec.rgb; +						} +					} +			 +					out_col += col; +				} +			} +	 +			fcol += out_col; +			++wght; +		} +	} + +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/samples; +	gl_FragColor.a = 0.0; + +	 +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..b450ff1ca2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl @@ -0,0 +1,232 @@ +/**  + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod;  //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	int wght = 0; + +	vec3 fcol = vec3(0,0,0); + +	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; +	 +	ivec2 itc = ivec2(frag.xy); + +	for (int i = 0; i < samples; ++i) +	{ +		vec3 pos = getPosition(itc, i).xyz; +		vec3 lv = vary_light.xyz-pos.xyz; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			vec3 norm = texelFetch(normalMap, itc, i).xyz*2.0-1.0; +	 +			norm = normalize(norm); +			float l_dist = -dot(lv, proj_n); +	 +			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); +			if (proj_tc.z >= 0.0) +			{ +				proj_tc.xyz /= proj_tc.w; +	 +				float fa = gl_Color.a+1.0; +				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +				if (dist_atten > 0.0) +				{ +					lv = proj_origin-pos.xyz; +					lv = normalize(lv); +					float da = dot(norm, lv); +		 +					vec3 col = vec3(0,0,0); +		 +					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb; +		 +					float noise = texture2D(noiseMap, frag.xy/128.0).b; +					if (proj_tc.z > 0.0 && +						proj_tc.x < 1.0 && +						proj_tc.y < 1.0 && +						proj_tc.x > 0.0 && +						proj_tc.y > 0.0) +					{ +						float lit = 0.0; +						float amb_da = proj_ambiance; +		 +						if (da > 0.0) +						{ +							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); +							float lod = diff * proj_lod; +			 +							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); +		 +							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; +			 +							lit = da * dist_atten * noise; +			 +							col = lcol*lit*diff_tex; +							amb_da += (da*0.5)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						amb_da += (da*da*0.5+0.5)*proj_ambiance; +				 +						amb_da *= dist_atten * noise; +			 +						amb_da = min(amb_da, 1.0-lit); +			 +						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +					} +	 +	 +					vec4 spec = texelFetch(specularRect, itc, i); +					if (spec.a > 0.0) +					{ +						vec3 ref = reflect(normalize(pos), norm); +		 +						//project from point pos in direction ref to plane proj_p, proj_n +						vec3 pdelta = proj_p-pos; +						float ds = dot(ref, proj_n); +		 +						if (ds < 0.0) +						{ +							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; +			 +							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + +							if (stc.z > 0.0) +							{ +								stc.xy /= stc.w; + +								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								 +								if (stc.x < 1.0 && +									stc.y < 1.0 && +									stc.x > 0.0 && +									stc.y > 0.0) +								{ +									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb; +								} +							} +						} +					} +	 +					fcol += col; +					++wght; +				} +			} +		} +	} + +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/samples;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 22ed9dcd40..0d771109fb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -30,7 +30,7 @@ uniform vec4 viewport;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = (pos_screen.xy-viewport.xy)*2.0;  	sc /= viewport.zw;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl new file mode 100644 index 0000000000..7521c3310c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl @@ -0,0 +1,108 @@ +/**  + * @file pointLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  + #version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + + +uniform vec3 env_mat[3]; +uniform float sun_wash; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; +uniform vec4 viewport; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = (vec2(pos_screen.xy)-viewport.xy)*2.0; +	sc /= viewport.zw; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	vec4 frag = vary_fragcoord; +	frag.xyz /= frag.w; +	frag.xyz = frag.xyz*0.5+0.5; +	frag.xy *= screen_res; +	 +	ivec2 itc = ivec2(frag.xy); + +	int wght = 0; +	vec3 fcol = vec3(0,0,0); + +	for (int s = 0; s < samples; ++s) +	{ +		vec3 pos = getPosition(itc, s).xyz; +		vec3 lv = vary_light.xyz-pos; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			vec3 norm = texelFetch(normalMap, itc, s).xyz; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +			float da = dot(norm, lv); +			if (da >= 0.0) +			{ +				norm = normalize(norm); +				lv = normalize(lv); +				da = dot(norm, lv); +	 +				float noise = texture2D(noiseMap, frag.xy/128.0).b; +	 +				vec3 col = texelFetch(diffuseRect, itc, s).rgb; +				float fa = gl_Color.a+1.0; +				float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +				float lit = da * dist_atten * noise; +	 +				col = gl_Color.rgb*lit*col; + +				vec4 spec = texelFetch(specularRect, itc, s); +				if (spec.a > 0.0) +				{ +					float sa = dot(normalize(lv-normalize(pos)),norm); +					if (sa > 0.0) +					{ +						sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); +						sa *= noise; +						col += da*sa*gl_Color.rgb*spec.rgb; +					} +				} + +				fcol += col; +				++wght; +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} +		 +	gl_FragColor.rgb = fcol/samples;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index 8e74feb615..2377947e7f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -10,14 +10,9 @@  varying vec4 vary_light;  varying vec4 vary_fragcoord; -uniform vec2 screen_res; -uniform float near_clip; -  void main()  {  	//transform vertex -	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  -  	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;  	vary_fragcoord = pos; @@ -25,6 +20,8 @@ void main()  	tex.w = 1.0;  	vary_light = gl_MultiTexCoord0; +	 +	gl_Position = pos;  	gl_FrontColor = gl_Color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 77f1b2224c..d389add03b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -29,7 +29,7 @@ varying vec2 vary_fragcoord;  float getDepth(vec2 pos_screen)  { -	float z = texture2DRect(depthMap, pos_screen.xy).a; +	float z = texture2DRect(depthMap, pos_screen.xy).r;  	z = z*2.0-1.0;  	vec4 ndc = vec4(0.0, 0.0, z, 1.0);  	vec4 p = inv_proj*ndc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl new file mode 100644 index 0000000000..711c6dc96d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl @@ -0,0 +1,133 @@ +/**  + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS edgeMap; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2D bloomMap; + +uniform float depth_cutoff; +uniform float norm_cutoff; +uniform float focal_distance; +uniform float blur_constant; +uniform float tan_pixel_angle; +uniform float magnification; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec2 vary_fragcoord; + +vec4 texture2DMS(sampler2DMS tex, ivec2 tc) +{ +	vec4 ret = vec4(0,0,0,0); +	for (int i = 0; i < samples; ++i) +	{ +		ret += texelFetch(tex, tc, i); +	} + +	return ret/samples; +} + +float getDepth(ivec2 pos_screen) +{ +	float z = texture2DMS(depthMap, pos_screen.xy).r; +	z = z*2.0-1.0; +	vec4 ndc = vec4(0.0, 0.0, z, 1.0); +	vec4 p = inv_proj*ndc; +	return p.z/p.w; +} + +float calc_cof(float depth) +{ +	float sc = abs(depth-focal_distance)/-depth*blur_constant; +		 +	sc /= magnification; +	 +	// tan_pixel_angle = pixel_length/-depth; +	float pixel_length =  tan_pixel_angle*-focal_distance; +	 +	sc = sc/pixel_length; +	sc *= 1.414; +	 +	return sc; +} + +void dofSample(inout vec4 diff, inout float w, float min_sc, float cur_depth, ivec2 tc) +{ +	float d = getDepth(tc); +	 +	float sc = calc_cof(d); +	 +	if (sc > min_sc //sampled pixel is more "out of focus" than current sample radius +	   || d < cur_depth) //sampled pixel is further away than current pixel +	{ +		float wg = 0.25; +		 +		vec4 s = texture2DMS(diffuseRect, tc); +		// de-weight dull areas to make highlights 'pop' +		wg += s.r+s.g+s.b; +	 +		diff += wg*s; +		 +		w += wg; +	} +} + + +void main()  +{ +	ivec2 itc = ivec2(vary_fragcoord.xy); + +	vec3 norm = texture2DMS(normalMap, itc).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		 +	float depth = getDepth(itc); +	 +	vec4 diff = texture2DMS(diffuseRect, itc); +	 +	{  +		float w = 1.0; +		 +		float sc = calc_cof(depth); +		sc = min(abs(sc), 10.0); +		 +		float fd = depth*0.5f; +		 +		float PI = 3.14159265358979323846264; + +		int isc = int(sc); +		 +		// sample quite uniformly spaced points within a circle, for a circular 'bokeh'		 +		//if (depth < focal_distance) +		{ +			for (int x = -isc; x <= isc; x+=2) +			{ +				for (int y = -isc; y <= isc; y+=2) +				{ +					ivec2 cur_samp = ivec2(x,y); +					float cur_sc = length(vec2(cur_samp)); +					if (cur_sc < sc) +					{ +						dofSample(diff, w, cur_sc, depth, itc+cur_samp); +					} +				} +			} +		} +		 +		diff /= w; +	} +		 +	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); +	gl_FragColor = diff + bloom; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl new file mode 100644 index 0000000000..359b26b7d4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl @@ -0,0 +1,37 @@ +/**  + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2D bloomMap; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +vec4 texture2DMS(sampler2DMS tex, ivec2 tc) +{ +	vec4 ret = vec4(0,0,0,0); + +	for (int i = 0; i < samples; ++i) +	{ +		 ret += texelFetch(tex,tc,i); +	} + +	return ret/samples; +} + +void main()  +{ +	vec4 diff = texture2DMS(diffuseRect, ivec2(vary_fragcoord.xy)); + +	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); +	gl_FragColor = diff + bloom; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl new file mode 100644 index 0000000000..91143943b6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -0,0 +1,44 @@ +/**  + * @file WLSkyF.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +varying vec4 vary_HazeColor; + +uniform sampler2D cloud_noise_texture; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { +	//soft clip effect: +	light = 1. - clamp(light, vec3(0.), vec3(1.)); +	light = 1. - pow(light, gamma.xxx); + +	return light; +} + +void main() +{ +	// Potential Fill-rate optimization.  Add cloud calculation  +	// back in and output alpha of 0 (so that alpha culling kills  +	// the fragment) if the sky wouldn't show up because the clouds  +	// are fully opaque. + +	vec4 color; +	color = vary_HazeColor; +	color *= 2.; + +	/// Gamma correct for WL (soft clip effect). +	gl_FragData[0] = vec4(scaleSoftClip(color.rgb), 1.0); +	gl_FragData[1] = vec4(0.0,0.0,0.0,0.0); +	gl_FragData[2] = vec4(0,0,1,0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl new file mode 100644 index 0000000000..03bca8f27e --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -0,0 +1,140 @@ +/**  + * @file WLSkyV.glsl + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +// SKY //////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +varying vec4 vary_HazeColor; + +// Inputs +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; + +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform vec4 cloud_scale; + +void main() +{ + +	// World / view / projection +	gl_Position = ftransform(); +	gl_TexCoord[0] = gl_MultiTexCoord0; + +	// Get relative position +	vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0); +	//vec3 P = gl_Vertex.xyz + vec3(0,50,0); + +	// Set altitude +	if (P.y > 0.) +	{ +		P *= (max_y.x / P.y); +	} +	else +	{ +		P *= (-32000. / P.y); +	} + +	// Can normalize then +	vec3 Pn = normalize(P); +	float  Plen = length(P); + +	// Initialize temp variables +	vec4 temp1 = vec4(0.); +	vec4 temp2 = vec4(0.); +	vec4 blue_weight; +	vec4 haze_weight; +	vec4 sunlight = sunlight_color; +	vec4 light_atten; + + +	// Sunlight attenuation effect (hue and brightness) due to atmosphere +	// this is used later for sunlight modulation at various altitudes +	light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + +	// Calculate relative weights +	temp1 = blue_density + haze_density.x; +	blue_weight = blue_density / temp1; +	haze_weight = haze_density.x / temp1; + +	// Compute sunlight from P & lightnorm (for long rays like sky) +	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// Distance +	temp2.z = Plen * density_multiplier.x; + +	// Transparency (-> temp1) +	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati +	// compiler gets confused. +	temp1 = exp(-temp1 * temp2.z); + + +	// Compute haze glow +	temp2.x = dot(Pn, lightnorm.xyz); +	temp2.x = 1. - temp2.x; +		// temp2.x is 0 at the sun and increases away from sun +	temp2.x = max(temp2.x, .001);	 +		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.x *= glow.x; +		// Higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.x = pow(temp2.x, glow.z); +		// glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	// Add "minimum anti-solar illumination" +	temp2.x += .25; + + +	// Haze color above cloud +	vary_HazeColor = (	  blue_horizon * blue_weight * (sunlight + ambient) +				+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + ambient) +			 );	 + + +	// Increase ambient when there are more clouds +	vec4 tmpAmbient = ambient; +	tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5;  + +	// Dim sunlight by cloud shadow percentage +	sunlight *= (1. - cloud_shadow.x); + +	// Haze color below cloud +	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient) +				+ (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) +			 );	 + +	// Final atmosphere additive +	vary_HazeColor *= (1. - temp1); +	 +	// Attenuate cloud color by atmosphere +	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds + +	// At horizon, blend high altitude sky color towards the darker color below the clouds +	vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1)); +	 +	// won't compile on mac without this being set +	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 29340c7e9f..c1147feff6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -259,7 +259,7 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	float depth = texture2DRect(depthMap, tc.xy).a; +	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz;  	vec3 norm = texture2DRect(normalMap, tc).xyz;  	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl new file mode 100644 index 0000000000..fcba4f57e6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl @@ -0,0 +1,318 @@ +/**  + * @file softenLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2DMS depthMap; +uniform sampler2D	  noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D	  lightFunc; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +//uniform mat4 shadow_matrix[3]; +//uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +vec3 getPositionEye() +{ +	return vary_PositionEye; +} +vec3 getSunlitColor() +{ +	return vary_SunlitColor; +} +vec3 getAmblitColor() +{ +	return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ +	return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ +	return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ +	vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ +	vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ +	vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ +	vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ +	vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + +	vec3 P = inPositionEye; +	setPositionEye(P); +	 +	//(TERRAIN) limit altitude +	if (P.y > max_y.x) P *= (max_y.x / P.y); +	if (P.y < -max_y.x) P *= (-max_y.x / P.y); + +	vec3 tmpLightnorm = lightnorm.xyz; + +	vec3 Pn = normalize(P); +	float Plen = length(P); + +	vec4 temp1 = vec4(0); +	vec3 temp2 = vec3(0); +	vec4 blue_weight; +	vec4 haze_weight; +	vec4 sunlight = sunlight_color; +	vec4 light_atten; + +	//sunlight attenuation effect (hue and brightness) due to atmosphere +	//this is used later for sunlight modulation at various altitudes +	light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); +		//I had thought blue_density and haze_density should have equal weighting, +		//but attenuation due to haze_density tends to seem too strong + +	temp1 = blue_density + vec4(haze_density.r); +	blue_weight = blue_density / temp1; +	haze_weight = vec4(haze_density.r) / temp1; + +	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) +	temp2.y = max(0.0, tmpLightnorm.y); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// main atmospheric scattering line integral +	temp2.z = Plen * density_multiplier.x; + +	// Transparency (-> temp1) +	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati +	// compiler gets confused. +	temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + +	//final atmosphere attenuation factor +	setAtmosAttenuation(temp1.rgb); +	 +	//compute haze glow +	//(can use temp2.x as temp because we haven't used it yet) +	temp2.x = dot(Pn, tmpLightnorm.xyz); +	temp2.x = 1. - temp2.x; +		//temp2.x is 0 at the sun and increases away from sun +	temp2.x = max(temp2.x, .03);	//was glow.y +		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.x *= glow.x; +		//higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.x = pow(temp2.x, glow.z); +		//glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	//add "minimum anti-solar illumination" +	temp2.x += .25; +	 +	//increase ambient when there are more clouds +	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; +	 +	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas +	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html +	 * // The following line of code performs the equivalent of: +	 * float ambAlpha = tmpAmbient.a; +	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis +	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); +	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); +	 */ +	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + +	//haze color +	setAdditiveColor( +		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) +	  + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x +		  + tmpAmbient))); + +	//brightness of surface both sunlight and ambient +	setSunlitColor(vec3(sunlight * .5)); +	setAmblitColor(vec3(tmpAmbient * .25)); +	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor(); +	return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor() * 2.0; +	return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ +	return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ +	return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ +	return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ +	return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ +	return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ +	//soft clip effect: +	light = 1. - clamp(light, vec3(0.), vec3(1.)); +	light = 1. - pow(light, gamma.xxx); + +	return light; +} + +vec4 texture2DMS(sampler2DMS tex, ivec2 tc) +{ +	vec4 ret = vec4(0,0,0,0); + +	for (int i = 0; i < samples; ++i) +	{ +		 ret += texelFetch(tex,tc,i); +	} + +	return ret/samples; +} + +void main()  +{ +	vec2 tc = vary_fragcoord.xy; +	ivec2 itc = ivec2(tc); + +	vec3 fcol = vec3(0,0,0); + +	for (int i = 0; i < samples; ++i) +	{ +		float depth = texelFetch(depthMap, itc, i).r; +		vec3 pos = getPosition_d(tc, depth).xyz; +		vec3 norm = texelFetch(normalMap, itc, i).xyz; + +		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; +	 +		float da = max(dot(norm.xyz, vary_light.xyz), 0.0); +	 +		vec4 diffuse = texelFetch(diffuseRect, itc, i); +		if (diffuse.a >= 1.0) +		{ +			fcol += diffuse.rgb; +		} +		else +		{ +			vec4 spec = texelFetch(specularRect, itc, i); +	 +			calcAtmospherics(pos.xyz, 1.0); +	 +			vec3 col = atmosAmbient(vec3(0)); +			col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a)); +	 +			col *= diffuse.rgb; +	 +			if (spec.a > 0.0) // specular reflection +			{ +				// the old infinite-sky shiny reflection +				// +				vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +				float sa = dot(refnormpersp, vary_light.xyz); +				vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a; + +				// add the two types of shiny together +				col += dumbshiny * spec.rgb; +			} + +			col = atmosLighting(col); +			col = scaleSoftClip(col); +			fcol += col; +		} +	} +				 +	gl_FragColor.rgb = fcol.rgb/samples; +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..6702bd5014 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl @@ -0,0 +1,234 @@ +/**  + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod;  //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	vec4 frag = vary_fragcoord; +	frag.xyz /= frag.w; +	frag.xyz = frag.xyz*0.5+0.5; +	frag.xy *= screen_res; +	ivec2 itc = ivec2(frag.xy); + +	vec3 fcol = vec3(0,0,0); +	int wght = 0; +	 +	for (int i = 0; i < samples; ++i) +	{ +		vec3 pos = getPosition(itc, i).xyz; +		vec3 lv = vary_light.xyz-pos.xyz; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			vec3 norm = texelFetch(normalMap, itc, i).xyz*2.0-1.0; +	 +			norm = normalize(norm); +			float l_dist = -dot(lv, proj_n); +	 +			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); +			if (proj_tc.z >= 0.0) +			{ +				proj_tc.xyz /= proj_tc.w; +	 +				float fa = gl_Color.a+1.0; +				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +				if (dist_atten > 0.0) +				{ +					lv = proj_origin-pos.xyz; +					lv = normalize(lv); +					float da = dot(norm, lv); +		 +					vec3 col = vec3(0,0,0); +		 +					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb; +		 +					float noise = texture2D(noiseMap, frag.xy/128.0).b; +					if (proj_tc.z > 0.0 && +						proj_tc.x < 1.0 && +						proj_tc.y < 1.0 && +						proj_tc.x > 0.0 && +						proj_tc.y > 0.0) +					{ +						float lit = 0.0; +						float amb_da = proj_ambiance; +		 +						if (da > 0.0) +						{ +							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); +							float lod = diff * proj_lod; +			 +							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); +		 +							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; +			 +							lit = da * dist_atten * noise; +			 +							col = lcol*lit*diff_tex; +							amb_da += (da*0.5)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						amb_da += (da*da*0.5+0.5)*proj_ambiance; +				 +						amb_da *= dist_atten * noise; +			 +						amb_da = min(amb_da, 1.0-lit); +			 +						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +					} +	 +	 +					vec4 spec = texelFetch(specularRect, itc, i); +					if (spec.a > 0.0) +					{ +						vec3 ref = reflect(normalize(pos), norm); +		 +						//project from point pos in direction ref to plane proj_p, proj_n +						vec3 pdelta = proj_p-pos; +						float ds = dot(ref, proj_n); +		 +						if (ds < 0.0) +						{ +							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; +			 +							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + +							if (stc.z > 0.0) +							{ +								stc.xy /= stc.w; + +								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								 +								if (stc.x < 1.0 && +									stc.y < 1.0 && +									stc.x > 0.0 && +									stc.y > 0.0) +								{ +									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb; +								} +							} +						} +					} +	 +					fcol += col; +					++wght; +				} +			} +		} +	} + +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/samples;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl new file mode 100644 index 0000000000..b1c25b7fd3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -0,0 +1,19 @@ +/**  + * @file starsF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +uniform sampler2D diffuseMap; + +void main()  +{ +	vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); +	 +	gl_FragData[0] = col; +	gl_FragData[1] = vec4(0,0,0,0); +	gl_FragData[2] = vec4(0,0,1,0);	 +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl new file mode 100644 index 0000000000..1f0376ce6b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl @@ -0,0 +1,17 @@ +/**  + * @file starsV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + + +void main() +{ +	//transform vertex +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..00093836a2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl @@ -0,0 +1,17 @@ +/**  + * @file sunLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +//class 1, no shadow, no SSAO, should never be called + +#extension GL_ARB_texture_rectangle : enable + +void main()  +{ +	gl_FragColor = vec4(0,0,0,0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index cd91351ad4..d1e8359742 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -35,7 +35,7 @@ uniform float shadow_offset;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..ce0ebc54f8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,123 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 1 -- no shadow, SSAO only + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2D noiseMap; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample) +{ +	float ret = 1.0; +	 +	vec2 kern[8]; +	// exponentially (^2) distant occlusion samples spread around origin +	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; +	kern[1] = vec2(1.0, 0.0) * 0.250*0.250; +	kern[2] = vec2(0.0, 1.0) * 0.375*0.375; +	kern[3] = vec2(0.0, -1.0) * 0.500*0.500; +	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; +	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; +	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; +	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + +	vec2 pos_screen = vary_fragcoord.xy; +	vec3 pos_world = pos.xyz; +	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; +		 +	float angle_hidden = 0.0; +	int points = 0; +		 +	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); +		 +	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?) +	for (int i = 0; i < 8; i++) +	{ +		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); +		vec3 samppos_world = getPosition(samppos_screen, sample).xyz;  +			 +		vec3 diff = pos_world - samppos_world; +		float dist2 = dot(diff, diff); +			 +		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area +		// --> solid angle shrinking by the square of distance +		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 +		//(k should vary inversely with # of samples, but this is taken care of later) +			 +		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); +			 +		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  +		points = points + int(diff.z > -1.0); +	} +		 +	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); +		 +	ret = (1.0 - (float(points != 0) * angle_hidden)); +	 +	return min(ret, 1.0); +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); +		 +	float col = 0; + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +		vec3 norm = texelFetch(normalMap, itc, i).xyz; +		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		col += calcAmbientOcclusion(pos,norm,i); +	} + +	col /= samples; + +	gl_FragColor[0] = 1.0; +	gl_FragColor[1] = col; +	gl_FragColor[2] = 1.0;  +	gl_FragColor[3] = 1.0; +} diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl new file mode 100644 index 0000000000..c03a0c61bd --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl @@ -0,0 +1,38 @@ +/**  + * @file glowExtractF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseMap; +uniform float minLuminance; +uniform float maxExtractAlpha; +uniform vec3 lumWeights; +uniform vec3 warmthWeights; +uniform float warmthAmount; + +void main() +{ +	ivec2 itc = ivec2(gl_TexCoord[0].xy); +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 col = texelFetch(diffuseMap, itc, i);	 + +		/// CALCULATING LUMINANCE (Using NTSC lum weights) +		/// http://en.wikipedia.org/wiki/Luma_%28video%29 +		float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) ); +		float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) );  +	 +		fcol += vec4(col.rgb, max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha)); +	} + +	gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl index 3155f3f929..30e1702e9f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -22,7 +22,7 @@ uniform vec2 screen_res;  float getDepth(vec2 pos_screen)  { -	float z = texture2DRect(depthMap, pos_screen.xy).a; +	float z = texture2DRect(depthMap, pos_screen.xy).r;  	z = z*2.0-1.0;  	vec4 ndc = vec4(0.0, 0.0, z, 1.0);  	vec4 p = inv_proj*ndc; diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl new file mode 100644 index 0000000000..38100d1523 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl @@ -0,0 +1,74 @@ +/**  + * @file edgeF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; + +varying vec2 vary_fragcoord; + +uniform float depth_cutoff; +uniform float norm_cutoff; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +float getDepth(ivec2 pos_screen, int sample) +{ +	float z = texelFetch(depthMap, pos_screen, sample).r; +	z = z*2.0-1.0; +	vec4 ndc = vec4(0.0, 0.0, z, 1.0); +	vec4 p = inv_proj*ndc; +	return p.z/p.w; +} + +void main()  +{ +	float e = 0; +	 +	ivec2 itc = ivec2(vary_fragcoord.xy); + +	for (int i = 0; i < samples; i++) +	{	 +		vec3 norm = texelFetch(normalMap, itc, i).xyz; +		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		float depth = getDepth(itc, i); +	 +		vec2 tc = vary_fragcoord.xy; +	 +		int sc = 1; +	 +		vec2 de; +		de.x = (depth-getDepth(itc+ivec2(sc, sc),i)) + (depth-getDepth(itc+ivec2(-sc, -sc), i)); +		de.y = (depth-getDepth(itc+ivec2(-sc, sc),i)) + (depth-getDepth(itc+ivec2(sc, -sc), i)); +		de /= depth; +		de *= de; +		de = step(depth_cutoff, de); +	 +		vec2 ne; +		vec3 nexnorm = texelFetch(normalMap, itc+ivec2(-sc,-sc), i).rgb; +		nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm +		ne.x = dot(nexnorm, norm); +		vec3 neynorm = texelFetch(normalMap, itc+ivec2(sc,sc), i).rgb; +		neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm +		ne.y = dot(neynorm, norm); +	 +		ne = 1.0-ne; +	 +		ne = step(norm_cutoff, ne); + +		e += dot(de,de)+dot(ne,ne); +	} + +	e /= samples; +	 +	gl_FragColor.a = e; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index d6cd984ebe..de987b1233 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -91,7 +91,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl new file mode 100644 index 0000000000..d0f9101774 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl @@ -0,0 +1,244 @@ +/**  + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod;  //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	int wght = 0; + +	vec3 fcol = vec3(0,0,0); + +	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; +	 +	ivec2 itc = ivec2(frag.xy); + +	float shadow = 1.0; + +	if (proj_shadow_idx >= 0) +	{ +		vec4 shd = texture2DRect(lightMap, frag); +		float sh[2]; +		sh[0] = shd.b; +		sh[1] = shd.a; +		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); +	} +		 +	for (int i = 0; i < samples; i++) +	{ +		vec3 pos = getPosition(itc, i).xyz; +		vec3 lv = vary_light.xyz-pos.xyz; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			vec3 norm = texelFetch(normalMap, itc, i).xyz; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	 +			norm = normalize(norm); +			float l_dist = -dot(lv, proj_n); +	 +			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); +			if (proj_tc.z >= 0.0) +			{ +				proj_tc.xyz /= proj_tc.w; +	 +				float fa = gl_Color.a+1.0; +				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +				if (dist_atten > 0.0) +				{ +					lv = proj_origin-pos.xyz; +					lv = normalize(lv); +					float da = dot(norm, lv); +		 +					vec3 col = vec3(0,0,0); +		 +					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb; +		 +					float noise = texture2D(noiseMap, frag.xy/128.0).b; +					if (proj_tc.z > 0.0 && +						proj_tc.x < 1.0 && +						proj_tc.y < 1.0 && +						proj_tc.x > 0.0 && +						proj_tc.y > 0.0) +					{ +						float lit = 0.0; +						float amb_da = proj_ambiance; +		 +						if (da > 0.0) +						{ +							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); +							float lod = diff * proj_lod; +			 +							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); +		 +							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; +			 +							lit = da * dist_atten * noise; +			 +							col = lcol*lit*diff_tex*shadow; +							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						amb_da += (da*da*0.5+0.5)*proj_ambiance; +				 +						amb_da *= dist_atten * noise; +			 +						amb_da = min(amb_da, 1.0-lit); +			 +						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +					} +	 +	 +					vec4 spec = texelFetch(specularRect, itc, i); +					if (spec.a > 0.0) +					{ +						vec3 ref = reflect(normalize(pos), norm); +		 +						//project from point pos in direction ref to plane proj_p, proj_n +						vec3 pdelta = proj_p-pos; +						float ds = dot(ref, proj_n); +		 +						if (ds < 0.0) +						{ +							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; +			 +							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + +							if (stc.z > 0.0) +							{ +								stc.xy /= stc.w; + +								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								 +								if (stc.x < 1.0 && +									stc.y < 1.0 && +									stc.x > 0.0 && +									stc.y > 0.0) +								{ +									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; +								} +							} +						} +					} + +					fcol += col; +					wght++; +				} +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/samples;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 0160e84278..dfa1964142 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -71,7 +71,7 @@ vec4 getPosition_d(vec2 pos_screen, float depth)  vec4 getPosition(vec2 pos_screen)  { //get position in screen space (world units) given window coordinate and depth map -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	return getPosition_d(pos_screen, depth);  } @@ -258,7 +258,7 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	float depth = texture2DRect(depthMap, tc.xy).a; +	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz;  	vec3 norm = texture2DRect(normalMap, tc).xyz;  	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm @@ -288,54 +288,8 @@ void main()  		float sa = dot(refnormpersp, vary_light.xyz);  		vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; -		/* -		// screen-space cheap fakey reflection map -		// -		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); -		depth -= 0.5; // unbias depth -		// first figure out where we'll make our 2D guess from -		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; -		// Offset the guess source a little according to a trivial -		// checkerboard dither function and spec.a. -		// This is meant to be similar to sampling a blurred version -		// of the diffuse map.  LOD would be better in that regard. -		// The goal of the blur is to soften reflections in surfaces -		// with low shinyness, and also to disguise our lameness. -		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 -		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); -		ref2d += vec2(checkoffset, checkoffset); -		ref2d += tc.xy; // use as offset from destination -		// Get attributes from the 2D guess point. -		// We average two samples of diffuse (not of anything else) per -		// pixel to try to reduce aliasing some more. -		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + -				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); -		float refdepth = texture2DRect(depthMap, ref2d).a; -		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; -		float refshad = texture2DRect(lightMap, ref2d).r; -		vec3 refn = texture2DRect(normalMap, ref2d).rgb; -		refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm -		refn = normalize(refn); -		// figure out how appropriate our guess actually was -		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); -		// darken reflections from points which face away from the reflected ray - our guess was a back-face -		//refapprop *= step(dot(refnorm, refn), 0.0); -		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant -		// get appropriate light strength for guess-point -		// reflect light direction to increase the illusion that -		// these are reflections. -		vec3 reflight = reflect(lightnorm.xyz, norm.xyz); -		float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); -		// apply sun color to guess-point, dampen according to inappropriateness of guess -		float refmod = min(refapprop, reflit); -		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; -		vec3 ssshiny = (refprod * spec.a); -		ssshiny *= 0.3; // dampen it even more -		*/ -		vec3 ssshiny = vec3(0,0,0); -  		// add the two types of shiny together -		col += (ssshiny + dumbshiny) * spec.rgb; +		col += dumbshiny * spec.rgb;  	}  	col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl new file mode 100644 index 0000000000..cb09fe9895 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl @@ -0,0 +1,307 @@ +/**  + * @file softenLightMSF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DMS depthMap; +uniform sampler2D	  noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D	  lightFunc; +uniform vec3 gi_quad; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +vec3 getPositionEye() +{ +	return vary_PositionEye; +} +vec3 getSunlitColor() +{ +	return vary_SunlitColor; +} +vec3 getAmblitColor() +{ +	return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ +	return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ +	return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ +	vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ +	vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ +	vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ +	vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ +	vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + +	vec3 P = inPositionEye; +	setPositionEye(P); +	 +	//(TERRAIN) limit altitude +	if (P.y > max_y.x) P *= (max_y.x / P.y); +	if (P.y < -max_y.x) P *= (-max_y.x / P.y); + +	vec3 tmpLightnorm = lightnorm.xyz; + +	vec3 Pn = normalize(P); +	float Plen = length(P); + +	vec4 temp1 = vec4(0); +	vec3 temp2 = vec3(0); +	vec4 blue_weight; +	vec4 haze_weight; +	vec4 sunlight = sunlight_color; +	vec4 light_atten; + +	//sunlight attenuation effect (hue and brightness) due to atmosphere +	//this is used later for sunlight modulation at various altitudes +	light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); +		//I had thought blue_density and haze_density should have equal weighting, +		//but attenuation due to haze_density tends to seem too strong + +	temp1 = blue_density + vec4(haze_density.r); +	blue_weight = blue_density / temp1; +	haze_weight = vec4(haze_density.r) / temp1; + +	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) +	temp2.y = max(0.0, tmpLightnorm.y); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// main atmospheric scattering line integral +	temp2.z = Plen * density_multiplier.x; + +	// Transparency (-> temp1) +	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati +	// compiler gets confused. +	temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + +	//final atmosphere attenuation factor +	setAtmosAttenuation(temp1.rgb); +	 +	//compute haze glow +	//(can use temp2.x as temp because we haven't used it yet) +	temp2.x = dot(Pn, tmpLightnorm.xyz); +	temp2.x = 1. - temp2.x; +		//temp2.x is 0 at the sun and increases away from sun +	temp2.x = max(temp2.x, .03);	//was glow.y +		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.x *= glow.x; +		//higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.x = pow(temp2.x, glow.z); +		//glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	//add "minimum anti-solar illumination" +	temp2.x += .25; +	 +	//increase ambient when there are more clouds +	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; +	 +	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas +	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html +	 * // The following line of code performs the equivalent of: +	 * float ambAlpha = tmpAmbient.a; +	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis +	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); +	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); +	 */ +	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + +	//haze color +	setAdditiveColor( +		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) +	  + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x +		  + tmpAmbient))); + +	//brightness of surface both sunlight and ambient +	setSunlitColor(vec3(sunlight * .5)); +	setAmblitColor(vec3(tmpAmbient * .25)); +	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor(); +	return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor() * 2.0; +	return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ +	return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ +	return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ +	return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ +	return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ +	return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ +	//soft clip effect: +	light = 1. - clamp(light, vec3(0.), vec3(1.)); +	light = 1. - pow(light, gamma.xxx); + +	return light; +} + +void main()  +{ +	vec2 tc = vary_fragcoord.xy; +	ivec2 itc = ivec2(tc); + +	vec3 fcol = vec3(0,0,0); + +	vec2 scol_ambocc = texture2DRect(lightMap, tc).rg; +	float ambocc = scol_ambocc.g; + +	for (int i = 0; i < samples; ++i) +	{ +		float depth = texelFetch(depthMap, itc.xy, i).r; +		vec3 pos = getPosition_d(tc, depth).xyz; +		vec3 norm = texelFetch(normalMap, itc, i).xyz; +		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +			 +		float da = max(dot(norm.xyz, vary_light.xyz), 0.0); +	 +		vec4 diffuse = texelFetch(diffuseRect, itc, i); +		vec4 spec = texelFetch(specularRect, itc, i); +	 +		float amb = 0; + +		float scol = max(scol_ambocc.r, diffuse.a);  +		amb += ambocc; + +		calcAtmospherics(pos.xyz, ambocc); +	 +		vec3 col = atmosAmbient(vec3(0)); +		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); +	 +		col *= diffuse.rgb; +	 +		if (spec.a > 0.0) // specular reflection +		{ +			// the old infinite-sky shiny reflection +			// +			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +			float sa = dot(refnormpersp, vary_light.xyz); +			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; + +			// add the two types of shiny together +			col += dumbshiny * spec.rgb; +		} +	 +		col = atmosLighting(col); +		col = scaleSoftClip(col); + +		fcol += col; +	} +		 +	gl_FragColor.rgb = fcol/samples;  +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl new file mode 100644 index 0000000000..8d6ffd79c5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl @@ -0,0 +1,245 @@ +/**  + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +uniform sampler2DMS diffuseRect; +uniform sampler2DMS specularRect; +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod;  //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +void main()  +{ +	vec4 frag = vary_fragcoord; +	frag.xyz /= frag.w; +	frag.xyz = frag.xyz*0.5+0.5; +	frag.xy *= screen_res; +	ivec2 itc = ivec2(frag.xy); +	 +	vec3 fcol = vec3(0,0,0); +	int wght = 0; + +	float shadow = 1.0; +	 +	if (proj_shadow_idx >= 0) +	{ +		vec4 shd = texture2DRect(lightMap, frag.xy); +		float sh[2]; +		sh[0] = shd.b; +		sh[1] = shd.a; +		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); +	} +	 +	for (int i = 0; i < samples; i++) +	{ +		vec3 pos = getPosition(itc, i).xyz; +		vec3 lv = vary_light.xyz-pos.xyz; +		float dist2 = dot(lv,lv); +		dist2 /= vary_light.w; +		if (dist2 <= 1.0) +		{ +			vec3 norm = texelFetch(normalMap, itc, i).xyz; +			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	 +			norm = normalize(norm); +			float l_dist = -dot(lv, proj_n); +	 +			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); +			if (proj_tc.z >= 0.0) +			{ +				proj_tc.xyz /= proj_tc.w; +	 +				float fa = gl_Color.a+1.0; +				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +				if (dist_atten > 0.0) +				{ +					lv = proj_origin-pos.xyz; +					lv = normalize(lv); +					float da = dot(norm, lv); +		 +					vec3 col = vec3(0,0,0); +		 +					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb; +		 +					float noise = texture2D(noiseMap, frag.xy/128.0).b; +					if (proj_tc.z > 0.0 && +						proj_tc.x < 1.0 && +						proj_tc.y < 1.0 && +						proj_tc.x > 0.0 && +						proj_tc.y > 0.0) +					{ +						float lit = 0.0; +						float amb_da = proj_ambiance; +		 +						if (da > 0.0) +						{ +							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); +							float lod = diff * proj_lod; +			 +							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); +		 +							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; +			 +							lit = da * dist_atten * noise; +			 +							col = lcol*lit*diff_tex*shadow; +							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; +						} +		 +						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); +							 +						amb_da += (da*da*0.5+0.5)*proj_ambiance; +				 +						amb_da *= dist_atten * noise; +			 +						amb_da = min(amb_da, 1.0-lit); +			 +						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +					} +	 +	 +					vec4 spec = texelFetch(specularRect, itc, i); +					if (spec.a > 0.0) +					{ +						vec3 ref = reflect(normalize(pos), norm); +		 +						//project from point pos in direction ref to plane proj_p, proj_n +						vec3 pdelta = proj_p-pos; +						float ds = dot(ref, proj_n); +		 +						if (ds < 0.0) +						{ +							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; +			 +							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + +							if (stc.z > 0.0) +							{ +								stc.xy /= stc.w; + +								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								 +								if (stc.x < 1.0 && +									stc.y < 1.0 && +									stc.x > 0.0 && +									stc.y > 0.0) +								{ +									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); +									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; +								} +							} +						} +					} + +					fcol += col; +					wght++; +				} +			} +		} +	} +	 +	if (wght <= 0) +	{ +		discard; +	} + +	gl_FragColor.rgb = fcol/wght;	 +	gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 4369b3b34f..b724c134b9 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -45,7 +45,7 @@ uniform float spot_shadow_offset;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl new file mode 100644 index 0000000000..dd6fa958c9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl @@ -0,0 +1,202 @@ +/**  + * @file sunLightMSF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2, shadows, no SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen.xy, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +				 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); + +	//try doing an unproject here +	 +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +	 +		vec4 nmap4 = texelFetch(normalMap, itc, i); +		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +		float displace = nmap4.w; +		vec3 norm = nmap4.xyz; +	 +		/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL +		{ +			gl_FragColor = vec4(0.0); // doesn't matter +			return; +		}*/ +	 +		float shadow = 1.0; +		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + +		vec3 shadow_pos = pos.xyz + displace*norm; +		vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); +	 +		if (spos.z > -shadow_clip.w) +		{	 +			if (dp_directional_light == 0.0) +			{ +				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup +				shadow = 0.0; +			} +			else +			{ +				vec4 lpos; +			 +				if (spos.z < -shadow_clip.z) +				{ +					lpos = shadow_matrix[3]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap3, lpos, 0.25); +					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +				} +				else if (spos.z < -shadow_clip.y) +				{ +					lpos = shadow_matrix[2]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap2, lpos, 0.5); +				} +				else if (spos.z < -shadow_clip.x) +				{ +					lpos = shadow_matrix[1]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap1, lpos, 0.75); +				} +				else +				{ +					lpos = shadow_matrix[0]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap0, lpos, 1.0); +				} +		 +				// take the most-shadowed value out of these two: +				//  * the blurred sun shadow in the light (shadow) map +				//  * an unblurred dot product between the sun and this norm +				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting +				shadow = min(shadow, dp_directional_light); +			 +				//lpos.xy /= lpos.w*32.0; +				//if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) +				//{ +				//	shadow = 0.0; +				//} +			 +			} +		} +		else +		{ +			// more distant than the shadow map covers +			shadow = 1.0; +		} +	 +		fcol[0] += shadow; +		fcol[1] += 1.0; + +		spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); +	 +		//spotlight shadow 1 +		vec4 lpos = shadow_matrix[4]*spos; +		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8);  +	 +		//spotlight shadow 2 +		lpos = shadow_matrix[5]*spos; +		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8);  +	} + +	gl_FragColor = fcol/samples; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 847b36b1ac..68e18162f6 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -45,7 +45,7 @@ uniform float spot_shadow_offset;  vec4 getPosition(vec2 pos_screen)  { -	float depth = texture2DRect(depthMap, pos_screen.xy).a; +	float depth = texture2DRect(depthMap, pos_screen.xy).r;  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl new file mode 100644 index 0000000000..d28741f945 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl @@ -0,0 +1,241 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  +#version 120 + +#extension GL_ARB_texture_rectangle : enable +#extension GL_ARB_texture_multisample : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DMS depthMap; +uniform sampler2DMS normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; +uniform sampler2D noiseMap; + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(ivec2 pos_screen, int sample) +{ +	float depth = texelFetch(depthMap, pos_screen, sample).r; +	vec2 sc = vec2(pos_screen.xy)*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample) +{ +	float ret = 1.0; + +	vec2 kern[8]; +	// exponentially (^2) distant occlusion samples spread around origin +	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; +	kern[1] = vec2(1.0, 0.0) * 0.250*0.250; +	kern[2] = vec2(0.0, 1.0) * 0.375*0.375; +	kern[3] = vec2(0.0, -1.0) * 0.500*0.500; +	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; +	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; +	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; +	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + +	vec2 pos_screen = vary_fragcoord.xy; +	vec3 pos_world = pos.xyz; +	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; +		 +	float angle_hidden = 0.0; +	int points = 0; +		 +	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); +		 +	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) +	for (int i = 0; i < 8; i++) +	{ +		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect)); +		vec3 samppos_world = getPosition(samppos_screen, sample).xyz;  +			 +		vec3 diff = pos_world - samppos_world; +		float dist2 = dot(diff, diff); +			 +		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area +		// --> solid angle shrinking by the square of distance +		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 +		//(k should vary inversely with # of samples, but this is taken care of later) +			 +		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); +			 +		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"  +		points = points + int(diff.z > -1.0); +	} +		 +	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); +		 +	ret = (1.0 - (float(points != 0) * angle_hidden)); +	 +	return min(ret, 1.0); +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +	 +			 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	ivec2 itc = ivec2(pos_screen); +	vec4 fcol = vec4(0,0,0,0); + +	for (int i = 0; i < samples; i++) +	{ +		vec4 pos = getPosition(itc, i); +	 +		vec4 nmap4 = texelFetch(normalMap, itc, i); +		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +		float displace = nmap4.w; +		vec3 norm = nmap4.xyz; +	 +		float shadow = 1.0; +		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + +		vec3 shadow_pos = pos.xyz + displace*norm; +		vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); +	 +		if (spos.z > -shadow_clip.w) +		{	 +			if (dp_directional_light == 0.0) +			{ +				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup +				shadow = 0.0; +			} +			else +			{ +				vec4 lpos; +			 +				if (spos.z < -shadow_clip.z) +				{ +					lpos = shadow_matrix[3]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap3, lpos, 0.25); +					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +				} +				else if (spos.z < -shadow_clip.y) +				{ +					lpos = shadow_matrix[2]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap2, lpos, 0.5); +				} +				else if (spos.z < -shadow_clip.x) +				{ +					lpos = shadow_matrix[1]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap1, lpos, 0.75); +				} +				else +				{ +					lpos = shadow_matrix[0]*spos; +					lpos.xy *= shadow_res; +					shadow = pcfShadow(shadowMap0, lpos, 1.0); +				} +		 +				// take the most-shadowed value out of these two: +				//  * the blurred sun shadow in the light (shadow) map +				//  * an unblurred dot product between the sun and this norm +				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting +				shadow = min(shadow, dp_directional_light); +			 +			} +		} +		else +		{ +			// more distant than the shadow map covers +			shadow = 1.0; +		} +	 +		 +		fcol[0] += shadow; +		fcol[1] += calcAmbientOcclusion(pos, norm, i); + +		spos.xyz = shadow_pos+offset*spot_shadow_offset; +	 +		//spotlight shadow 1 +		vec4 lpos = shadow_matrix[4]*spos; +		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8);  +	 +		//spotlight shadow 2 +		lpos = shadow_matrix[5]*spos; +		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8);  +	} +		 +	gl_FragColor = fcol / samples; +} diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 696c2d1abd..409b18d522 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -44,6 +44,8 @@ LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;  LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; +static LLGLSLShader* cloud_shader = NULL; +static LLGLSLShader* sky_shader = NULL;  LLDrawPoolWLSky::LLDrawPoolWLSky(void) : @@ -83,12 +85,32 @@ LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()  void LLDrawPoolWLSky::beginRenderPass( S32 pass )  { +	sky_shader = +		LLPipeline::sUnderWaterRender ? +			&gObjectSimpleWaterProgram : +			&gWLSkyProgram; + +	cloud_shader = +			LLPipeline::sUnderWaterRender ? +				&gObjectSimpleWaterProgram : +				&gWLCloudProgram;  }  void LLDrawPoolWLSky::endRenderPass( S32 pass )  {  } +void LLDrawPoolWLSky::beginDeferredPass(S32 pass) +{ +	sky_shader = &gDeferredWLSkyProgram; +	cloud_shader = &gDeferredWLCloudProgram; +} + +void LLDrawPoolWLSky::endDeferredPass(S32 pass) +{ + +} +  void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const  {  	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); @@ -128,19 +150,14 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const  {  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))  	{ -		LLGLSLShader* shader = -			LLPipeline::sUnderWaterRender ? -				&gObjectSimpleWaterProgram : -				&gWLSkyProgram; -  		LLGLDisable blend(GL_BLEND); -		shader->bind(); +		sky_shader->bind();  		/// Render the skydome -		renderDome(camHeightLocal, shader);	 +		renderDome(camHeightLocal, sky_shader);	 -		shader->unbind(); +		sky_shader->unbind();  	}  } @@ -186,23 +203,18 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const  {  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))  	{ -		LLGLSLShader* shader = -			LLPipeline::sUnderWaterRender ? -				&gObjectSimpleWaterProgram : -				&gWLCloudProgram; -  		LLGLEnable blend(GL_BLEND);  		gGL.setSceneBlendType(LLRender::BT_ALPHA);  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  		gGL.getTexUnit(0)->bind(sCloudNoiseTexture); -		shader->bind(); +		cloud_shader->bind();  		/// Render the skydome -		renderDome(camHeightLocal, shader); +		renderDome(camHeightLocal, cloud_shader); -		shader->unbind(); +		cloud_shader->unbind();  	}  } @@ -246,6 +258,53 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()  	}  } +void LLDrawPoolWLSky::renderDeferred(S32 pass) +{ +	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) +	{ +		return; +	} +	LLFastTimer ftm(FTM_RENDER_WL_SKY); + +	const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); + +	LLGLSNoFog disableFog; +	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	LLGLDisable clip(GL_CLIP_PLANE0); + +	gGL.setColorMask(true, false); + +	LLGLSquashToFarClip far_clip(glh_get_current_projection()); + +	renderSkyHaze(camHeightLocal); + +	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); +	glPushMatrix(); + +		 +		glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); + +		gDeferredStarProgram.bind(); +		// *NOTE: have to bind a texture here since register combiners blending in +		// renderStars() requires something to be bound and we might as well only +		// bind the moon's texture once.		 +		gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture()); + +		renderHeavenlyBodies(); + +		renderStars(); +		 +		gDeferredStarProgram.unbind(); + +	glPopMatrix(); + +	renderSkyClouds(camHeightLocal); + +	gGL.setColorMask(true, true); +	//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +} +  void LLDrawPoolWLSky::render(S32 pass)  {  	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index 8ca1ebb942..cd15c991ee 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -44,10 +44,10 @@ public:  	/*virtual*/ BOOL isDead() { return FALSE; } -	/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } -	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } -	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } -	/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +	/*virtual*/ S32 getNumDeferredPasses() { return 1; } +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass);  	/*virtual*/ LLViewerTexture *getDebugTexture();  	/*virtual*/ void beginRenderPass( S32 pass ); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 379bbe614d..00a0b87d93 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -183,6 +183,21 @@ static bool handleReleaseGLBufferChanged(const LLSD& newvalue)  	return true;  } +static bool handleFSAASamplesChanged(const LLSD& newvalue) +{ +	if (gPipeline.isInit()) +	{ +		gPipeline.releaseGLBuffers(); +		gPipeline.createGLBuffers(); + +		if (LLPipeline::sRenderDeferred) +		{ +			LLViewerShaderMgr::instance()->setShaders(); +		} +	} +	return true; +} +  static bool handleAnisotropicChanged(const LLSD& newvalue)  {  	LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); @@ -568,7 +583,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); -	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleFSAASamplesChanged, _2));  	gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));  	gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index e41773d273..10e96525ce 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -836,7 +836,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)  			{  				gPipeline.mDeferredScreen.bindTarget(); -				glClearColor(0,0,0,0); +				glClearColor(1,0,1,1);  				gPipeline.mDeferredScreen.clear();  			}  			else diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 3e85802ba6..b818da205e 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -138,7 +138,9 @@ LLGLSLShader			gDeferredGIFinalProgram;  LLGLSLShader			gDeferredPostGIProgram;  LLGLSLShader			gDeferredPostProgram;  LLGLSLShader			gDeferredPostNoDoFProgram; - +LLGLSLShader			gDeferredWLSkyProgram; +LLGLSLShader			gDeferredWLCloudProgram; +LLGLSLShader			gDeferredStarProgram;  LLGLSLShader			gLuminanceGatherProgram; @@ -190,6 +192,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredGIFinalProgram);  	mShaderList.push_back(&gDeferredWaterProgram);  	mShaderList.push_back(&gDeferredAvatarAlphaProgram); +	mShaderList.push_back(&gDeferredWLSkyProgram); +	mShaderList.push_back(&gDeferredWLCloudProgram); +	mShaderList.push_back(&gDeferredStarProgram);  }  LLViewerShaderMgr::~LLViewerShaderMgr() @@ -347,6 +352,9 @@ void LLViewerShaderMgr::setShaders()  		return;  	} +	//setup preprocessor definitions +	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"))); +  	reentrance = true;  	// Make sure the compiled shader map is cleared before we recompile shaders. @@ -833,6 +841,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  {  	BOOL success = TRUE; +	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); +	bool multisample = samples > 1 && LLPipeline::sRenderDeferred && gGLManager.mHasTextureMultisample; +  	if (mVertexShaderLevel[SHADER_EFFECT] == 0)  	{  		gGlowProgram.unload(); @@ -858,10 +869,21 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "effects/glowExtractMSF.glsl"; +		} +		else +		{ +			fragment = "effects/glowExtractF.glsl"; +		} +  		gGlowExtractProgram.mName = "Glow Extract Shader (Post)";  		gGlowExtractProgram.mShaderFiles.clear();  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); -		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gGlowExtractProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];  		success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms);  		if (!success) @@ -952,6 +974,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredGIProgram.unload();  		gDeferredGIFinalProgram.unload();  		gDeferredWaterProgram.unload(); +		gDeferredWLSkyProgram.unload(); +		gDeferredWLCloudProgram.unload(); +		gDeferredStarProgram.unload();  		return TRUE;  	} @@ -959,6 +984,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	BOOL success = TRUE; +	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); +	bool multisample = samples > 1 && gGLManager.mHasTextureMultisample; +  	if (success)  	{  		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; @@ -1039,40 +1067,83 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/pointLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/pointLightF.glsl"; +		} +  		gDeferredLightProgram.mName = "Deferred Light Shader";  		gDeferredLightProgram.mShaderFiles.clear();  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredLightProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; +		if (multisample) +		{ +			fragment = "deferred/multiPointLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/multiPointLightF.glsl"; +		} +  		gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader";  		gDeferredMultiLightProgram.mShaderFiles.clear();  		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredMultiLightProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/spotLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/multiSpotLightF.glsl"; +		} +  		gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";  		gDeferredSpotLightProgram.mShaderFiles.clear();  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/multiSpotLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/multiSpotLightF.glsl"; +		} +  		gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";  		gDeferredMultiSpotLightProgram.mShaderFiles.clear();  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);  	} @@ -1083,11 +1154,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ -			fragment = "deferred/sunLightSSAOF.glsl"; +			if (multisample) +			{ +				fragment = "deferred/sunlightSSAOMSF.glsl"; +			} +			else +			{ +				fragment = "deferred/sunLightSSAOF.glsl"; +			}  		}  		else  		{ -			fragment = "deferred/sunLightF.glsl"; +			if (multisample) +			{ +				fragment = "deferred/sunlightMSF.glsl"; +			} +			else +			{ +				fragment = "deferred/sunLightF.glsl"; +			}  		}  		gDeferredSunProgram.mName = "Deferred Sun Shader"; @@ -1100,10 +1185,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/blurLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/blurLightF.glsl"; +		} +  		gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";  		gDeferredBlurLightProgram.mShaderFiles.clear();  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredBlurLightProgram.createShader(NULL, NULL);  	} @@ -1153,10 +1249,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (multisample) +		{ +			fragment = "deferred/softenLightMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/softenLightF.glsl"; +		} +  		gDeferredSoftenProgram.mName = "Deferred Soften Shader";  		gDeferredSoftenProgram.mShaderFiles.clear();  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; @@ -1239,32 +1346,96 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; +		if (multisample) +		{ +			fragment = "deferred/postDeferredMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/postDeferredF.glsl"; +		} +  		gDeferredPostProgram.mName = "Deferred Post Shader";  		gDeferredPostProgram.mShaderFiles.clear();  		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredPostProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostProgram.createShader(NULL, NULL);  	}  	if (success)  	{ +		std::string fragment; +		if (multisample) +		{ +			fragment = "deferred/postDeferredNoDoFMSF.glsl"; +		} +		else +		{ +			fragment = "deferred/postDeferredNoDoFF.glsl"; +		} +  		gDeferredPostNoDoFProgram.mName = "Deferred Post Shader";  		gDeferredPostNoDoFProgram.mShaderFiles.clear();  		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);  	} +	if (success) +	{ +		gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; +		//gWLSkyProgram.mFeatures.hasGamma = true; +		gDeferredWLSkyProgram.mShaderFiles.clear(); +		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; +		success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms); +	} + +	if (success) +	{ +		gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; +		gDeferredWLCloudProgram.mShaderFiles.clear(); +		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; +		success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms); +	} + +	if (success) +	{ +		gDeferredStarProgram.mName = "Deferred Star Program"; +		gDeferredStarProgram.mShaderFiles.clear(); +		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; +		success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); +	} +  	if (mVertexShaderLevel[SHADER_DEFERRED] > 1)  	{  		if (success)  		{ +			std::string fragment; +			if (multisample) +			{ +				fragment = "deferred/edgeMSF.glsl"; +			} +			else +			{ +				fragment = "deferred/edgeF.glsl"; +			} +  			gDeferredEdgeProgram.mName = "Deferred Edge Shader";  			gDeferredEdgeProgram.mShaderFiles.clear();  			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeV.glsl", GL_VERTEX_SHADER_ARB)); -			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeF.glsl", GL_FRAGMENT_SHADER_ARB)); +			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  			gDeferredEdgeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  			success = gDeferredEdgeProgram.createShader(NULL, NULL);  		} @@ -1272,8 +1443,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (mVertexShaderLevel[SHADER_DEFERRED] > 2)  	{ -		 -  		if (success)  		{  			gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 72ac5e02ee..f5371f0619 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -374,7 +374,9 @@ extern LLGLSLShader			gDeferredAttachmentShadowProgram;  extern LLGLSLShader			gDeferredAlphaProgram;  extern LLGLSLShader			gDeferredFullbrightProgram;  extern LLGLSLShader			gDeferredAvatarAlphaProgram; - +extern LLGLSLShader			gDeferredWLSkyProgram; +extern LLGLSLShader			gDeferredWLCloudProgram; +extern LLGLSLShader			gDeferredStarProgram;  extern LLGLSLShader			gLuminanceGatherProgram;  //current avatar shader parameter pointer diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 845a87b8cf..1214d1b545 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -580,11 +580,6 @@ void LLPipeline::allocatePhysicsBuffer()  	if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY)  	{  		mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); -		if (mSampleBuffer.getWidth() == mPhysicsDisplay.getWidth() &&  -			mSampleBuffer.getHeight() == mPhysicsDisplay.getHeight()) -		{ -			mPhysicsDisplay.setSampleBuffer(&mSampleBuffer); -		}  	}  } @@ -594,8 +589,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  	mScreenWidth = resX;  	mScreenHeight = resY; -	//never use more than 4 samples for render targets -	U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 4); +	//cap samples at 4 for render targets to avoid out of memory errors +	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); +  	if (gGLManager.mIsATI)  	{ //disable multisampling of render targets where ATI is involved  		samples = 0; @@ -621,11 +617,11 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED);  		//allocate deferred rendering color buffers -		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); -		mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); +		mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples);  		addDeferredAttachments(mDeferredScreen); -		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples);		  #if LL_DARWIN  		// As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO @@ -636,7 +632,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (shadow_detail > 0 || ssao)  		{ //only need mDeferredLight[0] for shadows OR ssao -			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);  		}  		else  		{ @@ -645,7 +641,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (ssao)  		{ //only need mDeferredLight[1] for ssao -			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false);  		}  		else  		{ @@ -654,7 +650,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		if (gi)  		{ //only need mDeferredLight[2] and mGIMapPost for gi -			mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false);  			for (U32 i = 0; i < 2; i++)  			{  #if LL_DARWIN @@ -744,35 +740,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		  	} -	if (LLRenderTarget::sUseFBO && samples > 1) -	{  -		mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); -		if (LLPipeline::sRenderDeferred) -		{ -			addDeferredAttachments(mSampleBuffer); -			mDeferredScreen.setSampleBuffer(&mSampleBuffer); -			mEdgeMap.setSampleBuffer(&mSampleBuffer); -		} - -		mScreen.setSampleBuffer(&mSampleBuffer); - -		stop_glerror(); -	} -	else -	{ -		mSampleBuffer.release(); -	} -	  	if (LLPipeline::sRenderDeferred)  	{ //share depth buffer between deferred targets  		mDeferredScreen.shareDepthBuffer(mScreen); -		for (U32 i = 0; i < 3; i++) -		{ //share stencil buffer with screen space lightmap to stencil out sky -			if (mDeferredLight[i].getTexture(0)) -			{ -				mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); -			} -		}  	}  	gGL.getTexUnit(0)->disable(); @@ -841,7 +811,6 @@ void LLPipeline::releaseGLBuffers()  	mScreen.release();  	mPhysicsDisplay.release();  	mUIScreen.release(); -	mSampleBuffer.release();  	mDeferredScreen.release();  	mDeferredDepth.release();  	for (U32 i = 0; i < 3; i++) @@ -6195,11 +6164,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);		 -		gGL.getTexUnit(0)->disable(); -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); -		gGL.getTexUnit(0)->bind(&mScreen); - +		mScreen.bindTexture(0, 0); +		  		gGL.color4f(1,1,1,1);  		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));  		gGL.begin(LLRender::TRIANGLE_STRIP); @@ -6214,7 +6180,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.end(); -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->unbind(mScreen.getUsage());  		mGlow[2].flush();  	} @@ -6242,7 +6208,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  	for (S32 i = 0; i < kernel; i++)  	{ -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  		{  			LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);  			mGlow[i%2].bindTarget(); @@ -6435,11 +6400,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			shader->uniform1f("magnification", magnification);  		} -		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); +		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());  		if (channel > -1)  		{  			mScreen.bindTexture(0, channel); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);  		}  		//channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);  		//if (channel > -1) @@ -6582,21 +6546,21 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  	shader.bind();  	S32 channel = 0; -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());  	if (channel > -1)  	{  		mDeferredScreen.bindTexture(0,channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());  	if (channel > -1)  	{  		mDeferredScreen.bindTexture(1, channel);  		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());  	if (channel > -1)  	{  		mDeferredScreen.bindTexture(2, channel); @@ -6719,22 +6683,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  			shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m);  		}  	} -	 -	/*channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); -	if (channel > -1) -	{ -		mDeferredScreen.bindTexture(3, channel); -	}*/ +	stop_glerror(); -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage());  	if (channel > -1)  	{  		gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); -		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  		stop_glerror(); -		glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		 -		glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		 +		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		 +		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		  		stop_glerror(); @@ -6763,7 +6721,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  	stop_glerror(); -	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); +	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[light_index].getUsage());  	if (channel > -1)  	{  		mDeferredLight[light_index].bindTexture(0, channel); @@ -6983,9 +6941,9 @@ void LLPipeline::renderDeferredLighting()  		}  		//ati doesn't seem to love actually using the stencil buffer on FBO's -		LLGLEnable stencil(GL_STENCIL_TEST); -		glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); -		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +		LLGLDisable stencil(GL_STENCIL_TEST); +		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); +		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);  		gGL.setColorMask(true, true); @@ -7787,33 +7745,41 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  	LLViewerTexture* img = volume->getLightTexture(); +	if (img == NULL) +	{ +		img = LLViewerFetchedTexture::sWhiteImagep; +	} +  	S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); -	if (channel > -1 && img) +	if (channel > -1)  	{ -		gGL.getTexUnit(channel)->bind(img); +		if (img) +		{ +			gGL.getTexUnit(channel)->bind(img); -		F32 lod_range = logf(img->getWidth())/logf(2.f); +			F32 lod_range = logf(img->getWidth())/logf(2.f); -		shader.uniform1f("proj_focus", focus); -		shader.uniform1f("proj_lod", lod_range); -		shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); +			shader.uniform1f("proj_focus", focus); +			shader.uniform1f("proj_lod", lod_range); +			shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); +		}  	} +		  }  void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  {  	stop_glerror(); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[0].getUsage());  	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); -	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, mEdgeMap.getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, mDeferredLight[1].getUsage()); +	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, mDeferredLight[2].getUsage());  	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);  	shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP); @@ -9409,6 +9375,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			mShadow[i+4].flush();   		}  	} +	else +	{ //no spotlight shadows +		mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; +	} +  	if (!gSavedSettings.getBOOL("CameraOffset"))  	{ diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e9a250cd6d..ed4a803e7e 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -524,7 +524,6 @@ public:  	LLRenderTarget			mEdgeMap;  	LLRenderTarget			mDeferredDepth;  	LLRenderTarget			mDeferredLight[3]; -	LLMultisampleBuffer		mSampleBuffer;  	LLRenderTarget			mGIMap;  	LLRenderTarget			mGIMapPost[2];  	LLRenderTarget			mLuminanceMap; | 
