diff options
| author | William Todd Stinson <stinson@lindenlab.com> | 2012-10-09 12:32:45 -0700 | 
|---|---|---|
| committer | William Todd Stinson <stinson@lindenlab.com> | 2012-10-09 12:32:45 -0700 | 
| commit | 9b05e5f35baeaace95dbbbb1fbccb9b79f7da847 (patch) | |
| tree | 1c904fd6f0bb23371a47d246cb7dc823c5fccf2b /indra | |
| parent | 38a565f71a54aaa66300a0ab593e366731aac769 (diff) | |
| parent | 1991d95e852b3798ab3e41706525c843dd54914a (diff) | |
Pull and merge from ssh://hg@bitbucket.org/lindenlab/viewer-development-materials.
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/edit-me-to-trigger-new-build.txt | 1 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 66 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.h | 13 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 10 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.h | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl | 3 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl | 3 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl | 2 | ||||
| -rw-r--r-- | indra/newview/llviewershadermgr.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 52 | 
11 files changed, 122 insertions, 42 deletions
| diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index e69de29bb2..8d1c8b69c3 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -0,0 +1 @@ +  diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 7cbf39096e..39e81c4bfc 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -150,7 +150,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();  	for ( ; fileIter != mShaderFiles.end(); fileIter++ )  	{ -		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels); +		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mDefines, mFeatures.mIndexedTextureChannels);  		LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;  		if (shaderhandle > 0)  		{ @@ -372,7 +372,17 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)  			}  		}  	} - } +} + +void LLGLSLShader::addPermutation(std::string name, std::string value) +{ +	mDefines[name] = value; +} + +void LLGLSLShader::removePermutation(std::string name) +{ +	mDefines[name].erase(); +}  GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)  { @@ -471,6 +481,58 @@ void LLGLSLShader::bindNoShader(void)  	}  } +S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode) +{ +	S32 channel = 0; +	channel = getUniformLocation(uniform); +	 +	return bindTexture(channel, texture, mode); +} + +S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode) +{ +	if (uniform < 0 || uniform >= (S32)mTexture.size()) +	{ +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; +		return -1; +	} +	 +	uniform = mTexture[uniform]; +	 +	if (uniform > -1) +	{ +		gGL.getTexUnit(uniform)->bind(texture, mode); +	} +	 +	return uniform; +} + +S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) +{ +	S32 channel = 0; +	channel = getUniformLocation(uniform); +	 +	return unbindTexture(channel); +} + +S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) +{ +	if (uniform < 0 || uniform >= (S32)mTexture.size()) +	{ +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; +		return -1; +	} +	 +	uniform = mTexture[uniform]; +	 +	if (uniform > -1) +	{ +		gGL.getTexUnit(uniform)->unbind(mode); +	} +	 +	return uniform; +} +  S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)  {  	if (uniform < 0 || uniform >= (S32)mTexture.size()) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 5c68cb46eb..2af74c20ff 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -123,12 +123,22 @@ public:  	GLint getAttribLocation(U32 attrib);  	GLint mapUniformTextureChannel(GLint location, GLenum type); +	void addPermutation(std::string name, std::string value); +	void removePermutation(std::string name); +	  	//enable/disable texture channel for specified uniform  	//if given texture uniform is active in the shader,   	//the corresponding channel will be active upon return  	//returns channel texture is enabled in from [0-MAX)  	S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); -	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);  +	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	 +	// bindTexture returns the texture unit we've bound the texture to. +	// You can reuse the return value to unbind a texture when required. +	S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);      BOOL link(BOOL suppress_errors = FALSE);  	void bind(); @@ -153,6 +163,7 @@ public:  	LLShaderFeatures mFeatures;  	std::vector< std::pair< std::string, GLenum > > mShaderFiles;  	std::string mName; +	boost::unordered_map<std::string, std::string> mDefines;  };  //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b6a9a6b653..3b1ec281c9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)  	}   } -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels) +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string> defines, S32 texture_index_channels)  {  	GLenum error = GL_NO_ERROR;  	if (gDebugGL) @@ -657,6 +657,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		std::string define = "#define " + iter->first + " " + iter->second + "\n";  		text[count++] = (GLcharARB *) strdup(define.c_str());  	} +	 +	for (boost::unordered_map<std::string,std::string>::iterator iter = defines.begin(); iter != defines.end(); ++iter) +	{ +		std::string define = "#define " + iter->first + " " + iter->second + "\n"; +		text[count++] = (GLcharARB *) strdup(define.c_str()); +	}  	if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)  	{ @@ -854,7 +860,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		if (shader_level > 1)  		{  			shader_level--; -			return loadShaderFile(filename,shader_level,type,texture_index_channels); +			return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);  		}  		LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;	  	} diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 7a16b7c20f..4b93aae735 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -176,7 +176,7 @@ public:  	void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);  	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);  	BOOL	validateProgramObject(GLhandleARB obj); -	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1); +	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string> defines, S32 texture_index_channels = -1);  	// Implemented in the application to actually point to the shader directory.  	virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 7e79317543..9e194cdcd1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -128,8 +128,7 @@ void main()  				if (sa > 0.0)  				{ -					sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); -					sa *= noise; +					sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);  					col += da*sa*light_col[i].rgb*spec.rgb;  				}  			} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 75757b26c8..6e5ac8317b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -110,8 +110,7 @@ void main()  		float sa = dot(normalize(lv-normalize(pos)),norm);  		if (sa > 0.0)  		{ -			sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); -			sa *= noise; +			sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);  			col += da*sa*color.rgb*spec.rgb;  		}  	} diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 89448e2167..14eaafeb68 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -301,7 +301,7 @@ void main()  			//  			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));  			float sa = dot(refnormpersp, sun_dir.xyz); -			vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); +			vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);  			// add the two types of shiny together  			vec3 spec_contrib = dumbshiny * spec.rgb; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 9df9d75905..457189b48e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -309,7 +309,7 @@ void main()  			//  			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));  			float sa = dot(refnormpersp, sun_dir.xyz); -			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); +			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);  			// add the two types of shiny together  			vec3 spec_contrib = dumbshiny * spec.rgb; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4b0e0598f6..43de7450c8 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -826,12 +826,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  		shaders.push_back( make_pair( "objects/indexedTextureV.glsl",			1 ) );  	}  	shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl",		1 ) ); - +	 +	boost::unordered_map<std::string, std::string> attribs; +	  	// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_VERTEX_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, attribs) == 0)  		{  			return FALSE;  		} @@ -879,11 +881,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );  	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );  	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); -	 +  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_FRAGMENT_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, attribs, index_channels[i]) == 0)  		{  			return FALSE;  		} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e324d60fec..8c989ca77f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -397,7 +397,7 @@ void validate_framebuffer_object();  bool addDeferredAttachments(LLRenderTarget& target)  {  	return target.addColorAttachment(GL_RGBA) && //specular -			target.addColorAttachment(GL_RGBA); //normal+z	 +			target.addColorAttachment(GL_RGB10_A2); //normal+z  }  LLPipeline::LLPipeline() : @@ -863,7 +863,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!addDeferredAttachments(mDeferredScreen)) return false; -	 +		  		if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (samples > 0)  		{ @@ -1206,6 +1206,11 @@ void LLPipeline::createGLBuffers()  	gBumpImageList.restoreGL();  } +F32 lerpf(F32 a, F32 b, F32 w) +{ +	return a + w * (b - a); +} +  void LLPipeline::createLUTBuffers()  {  	if (sRenderDeferred) @@ -1214,45 +1219,40 @@ void LLPipeline::createLUTBuffers()  		{  			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");  			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); -			U8* ls = new U8[lightResX*lightResY]; -			F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); -            // Calculate the (normalized) Blinn-Phong specular lookup texture. +			F32* ls = new F32[lightResX*lightResY]; +			//F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions. +            // Calculate the (normalized) Gaussian specular lookup texture. (with a few tweaks)  			for (U32 y = 0; y < lightResY; ++y)  			{  				for (U32 x = 0; x < lightResX; ++x)  				{  					ls[y*lightResX+x] = 0;  					F32 sa = (F32) x/(lightResX-1); -					F32 spec = (F32) y/(lightResY-1); -					F32 n = spec * spec * specExp; +					F32 spec = (F32) y/(lightResY); +					F32 n = spec; -					// Nothing special here.  Just your typical blinn-phong term. -					spec = powf(sa, n); +					float angleNormalHalf = acosf(sa); +					float exponent = angleNormalHalf / ((1 - n)); +					exponent = -(exponent * exponent); +					spec = expf(exponent);  					// Apply our normalization function. -					// Note: This is the full equation that applies the full normalization curve, not an approximation. -					// This is fine, given we only need to create our LUT once per buffer initialization. -					// The only trade off is we have a really low dynamic range. -					// This means we have to account for things not being able to exceed 0 to 1 in our shaders. -					spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); +					// This is based around the phong normalization function, trading n+2 for n+1 instead. +					// Since we're using a gaussian model here, we actually don't really need as large of an exponent as blinn-phong shading. +					// Instead, we assume that the correct exponent is 8 here. +					// This was achieved through much tweaking to find a decent "middleground" with our specular highlights with the gaussian term. +					// Bigger highlights don't look too soft, smaller highlights don't look too bright, and everything in the middle seems to have a well maintained highlight curvature. +					// There isn't really much theory behind this one.  This was done purely to produce a nice and mostly customizable BRDF. -					// Always sample at a 1.0/2.2 curve. -					// This "Gamma corrects" our specular term, boosting our lower exponent reflections. -					spec = powf(spec, 1.f/2.2f); +					spec = lerpf(spec, spec * (n * 8 + 1) / 4.5, n); -					// Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders. -					// This allows for our specular term to exceed a value of 1 in our shaders. -					// This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1. -					// Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times. -					// This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents. -					// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable. -					ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255); +					ls[y*lightResX+x] = spec;  				}  			} -			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false); +			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);  			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); | 
