diff options
5 files changed, 248 insertions, 258 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl index c639f25fc6..d2903b545c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl @@ -47,6 +47,6 @@ void main()  	vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy); -	float a = min(diff.a * max_cof*0.125, 1.0); +	float a = min(diff.a * max_cof*0.333, 1.0);  	gl_FragColor = mix(diff, dof, a);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index bf029d1db5..629648ddc3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -73,7 +73,7 @@ void main()  		{  			while (sc > 0.5)  			{ -				int its = int(max(1.0,(sc*3.7*0.5))); +				int its = int(max(1.0,(sc*3.7)));  				for (int i=0; i<its; ++i)  				{  					float ang = sc+i*2*PI/its; // sc is added for rotary perturbance @@ -82,7 +82,7 @@ void main()  					// you could test sample coords against an interesting non-circular aperture shape here, if desired.  					dofSample(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));  				} -				sc -= 2.0; +				sc -= 1.0;  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl index 7136d412ea..c66a6e5b48 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl @@ -29,17 +29,14 @@  out vec4 gl_FragColor;  #endif -uniform sampler2D glowMap; -uniform sampler2DRect screenMap; +uniform sampler2DRect diffuseRect;  uniform vec2 screen_res;  VARYING vec2 vary_tc;  void main()   { -	vec3 col = texture2D(glowMap, vary_tc).rgb + -					texture2DRect(screenMap, vary_tc*screen_res).rgb; - +	vec3 col = texture2DRect(diffuseRect, vary_tc*screen_res).rgb;  	gl_FragColor = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));  } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d9210877dd..03d765eaee 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -574,6 +574,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	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)); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d524ddd62d..59e6c3cf07 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -745,8 +745,8 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  			mFXAABuffer.release();  		} -		if (shadow_detail > 0 || ssao || RenderDepthOfField) -		{ //only need mDeferredLight for shadows OR ssao OR dof +		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) +		{ //only need mDeferredLight for shadows OR ssao OR dof OR fxaa  			if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;  		}  		else @@ -6416,308 +6416,199 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		multisample = false;  #endif -		if (multisample) -		{ -			//bake out texture2D with RGBL for FXAA shader -			mFXAABuffer.bindTarget(); -			 -			S32 width = mScreen.getWidth(); -			S32 height = mScreen.getHeight(); -			glViewport(0, 0, width, height); - -			gGlowCombineFXAAProgram.bind(); -			gGlowCombineFXAAProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); - -			gGL.getTexUnit(0)->bind(&mGlow[1]); -			gGL.getTexUnit(1)->bind(&mScreen); - -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.vertex2f(-1,-1); -			gGL.vertex2f(-1,3); -			gGL.vertex2f(3,-1); -			gGL.end(); - -			gGL.flush(); - -			gGlowCombineFXAAProgram.unbind(); -			mFXAABuffer.flush(); - -			if (dof_enabled) -			{ //if depth of field is not enabled, this is the final pass (draw to window) -				mScreen.bindTarget(); -			} -			LLGLSLShader* shader = &gFXAAProgram; -			shader->bind(); - -			S32 channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); -			if (channel > -1) -			{ -				mFXAABuffer.bindTexture(0, channel); -				gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); -			} - -			 -			F32 scale_x = (F32) width/mFXAABuffer.getWidth(); -			F32 scale_y = (F32) height/mFXAABuffer.getHeight(); -			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); -			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); -			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); -			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); -			 -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.vertex2f(-1,-1); -			gGL.vertex2f(-1,3); -			gGL.vertex2f(3,-1); -			gGL.end(); - -			gGL.flush(); -			if (dof_enabled) -			{ -				mScreen.flush(); -			} -			shader->unbind(); -		} -  		gViewerWindow->setup3DViewport(); -		if (dof_enabled || !multisample) +		if (dof_enabled)  		{  			LLGLSLShader* shader = &gDeferredPostProgram; -			if (!dof_enabled) -			{  -				shader = &gDeferredPostNoDoFProgram; -			} -				  			LLGLDisable blend(GL_BLEND); +			//depth of field focal plane calculations +			static F32 current_distance = 16.f; +			static F32 start_distance = 16.f; +			static F32 transition_time = 1.f; -			if (dof_enabled) -			{ -				//depth of field focal plane calculations - -				static F32 current_distance = 16.f; -				static F32 start_distance = 16.f; -				static F32 transition_time = 1.f; +			LLVector3 focus_point; -				LLVector3 focus_point; - -				LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); -				if (obj && obj->mDrawable && obj->isSelected()) -				{ //focus on selected media object -					S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); -					if (obj && obj->mDrawable) +			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); +			if (obj && obj->mDrawable && obj->isSelected()) +			{ //focus on selected media object +				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); +				if (obj && obj->mDrawable) +				{ +					LLFace* face = obj->mDrawable->getFace(face_idx); +					if (face)  					{ -						LLFace* face = obj->mDrawable->getFace(face_idx); -						if (face) -						{ -							focus_point = face->getPositionAgent(); -						} +						focus_point = face->getPositionAgent();  					}  				} +			} -				if (focus_point.isExactlyZero()) +			if (focus_point.isExactlyZero()) +			{ +				if (LLViewerJoystick::getInstance()->getOverrideCamera()) +				{ //focus on point under cursor +					focus_point = gDebugRaycastIntersection; +				} +				else if (gAgentCamera.cameraMouselook()) +				{ //focus on point under mouselook crosshairs +					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, +													NULL, +													&focus_point); +				} +				else  				{ -					if (LLViewerJoystick::getInstance()->getOverrideCamera()) -					{ //focus on point under cursor -						focus_point = gDebugRaycastIntersection; -					} -					else if (gAgentCamera.cameraMouselook()) -					{ //focus on point under mouselook crosshairs -						gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, -													  NULL, -													  &focus_point); +					LLViewerObject* obj = gAgentCamera.getFocusObject(); +					if (obj) +					{ //focus on alt-zoom target +						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());  					}  					else -					{ -						LLViewerObject* obj = gAgentCamera.getFocusObject(); -						if (obj) -						{ //focus on alt-zoom target -							focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); -						} -						else -						{ //focus on your avatar -							focus_point = gAgent.getPositionAgent(); -						} +					{ //focus on your avatar +						focus_point = gAgent.getPositionAgent();  					}  				} +			} -				LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); -				F32 target_distance = 16.f; -				if (!focus_point.isExactlyZero()) -				{ -					target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); -				} +			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); +			F32 target_distance = 16.f; +			if (!focus_point.isExactlyZero()) +			{ +				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); +			} -				if (transition_time >= 1.f && -					fabsf(current_distance-target_distance)/current_distance > 0.01f) -				{ //large shift happened, interpolate smoothly to new target distance -					transition_time = 0.f; -					start_distance = current_distance; -				} -				else if (transition_time < 1.f) -				{ //currently in a transition, continue interpolating -					transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds; -					transition_time = llmin(transition_time, 1.f); +			if (transition_time >= 1.f && +				fabsf(current_distance-target_distance)/current_distance > 0.01f) +			{ //large shift happened, interpolate smoothly to new target distance +				transition_time = 0.f; +				start_distance = current_distance; +			} +			else if (transition_time < 1.f) +			{ //currently in a transition, continue interpolating +				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds; +				transition_time = llmin(transition_time, 1.f); -					F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; -					current_distance = start_distance + (target_distance-start_distance)*t; -				} -				else -				{ //small or no change, just snap to target distance -					current_distance = target_distance; -				} +				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; +				current_distance = start_distance + (target_distance-start_distance)*t; +			} +			else +			{ //small or no change, just snap to target distance +				current_distance = target_distance; +			} -				//convert to mm -				F32 subject_distance = current_distance*1000.f; -				F32 fnumber = CameraFNumber; -				F32 default_focal_length = CameraFocalLength; +			//convert to mm +			F32 subject_distance = current_distance*1000.f; +			F32 fnumber = CameraFNumber; +			F32 default_focal_length = CameraFocalLength; -				F32 fov = LLViewerCamera::getInstance()->getView(); +			F32 fov = LLViewerCamera::getInstance()->getView(); -				const F32 default_fov = CameraFieldOfView * F_PI/180.f; -				//const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); +			const F32 default_fov = CameraFieldOfView * F_PI/180.f; +			//const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); -				//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); +			//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); -				F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); -				//F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f); +			F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); +			//F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f); -				F32 focal_length = dv/(2*tanf(fov/2.f)); +			F32 focal_length = dv/(2*tanf(fov/2.f)); -				//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); +			//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); -				// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) -				// where	 N = fnumber -				//			 s2 = dot distance -				//			 s1 = subject distance -				//			 f = focal length -				//	 - -				F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); -				blur_constant /= 1000.f; //convert to meters for shader -				F32 magnification = focal_length/(subject_distance-focal_length); - -				{ //build diffuse+bloom+CoF -					mDeferredLight.bindTarget(); -					shader = &gDeferredCoFProgram; +			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) +			// where	 N = fnumber +			//			 s2 = dot distance +			//			 s1 = subject distance +			//			 f = focal length +			//	 -					bindDeferredShader(*shader); +			F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); +			blur_constant /= 1000.f; //convert to meters for shader +			F32 magnification = focal_length/(subject_distance-focal_length); -					S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -					if (channel > -1) -					{ -						mScreen.bindTexture(0, channel); -					} +			{ //build diffuse+bloom+CoF +				mDeferredLight.bindTarget(); +				shader = &gDeferredCoFProgram; -					if (multisample) -					{ //bloom has already been added, bind black -						channel = shader->enableTexture(LLShaderMgr::DEFERRED_BLOOM); -						if (channel > -1) -						{ -							gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sBlackImagep); -						} -					} -				 -					shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); -					shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); -					shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); -					shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); -					shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - -					gGL.begin(LLRender::TRIANGLE_STRIP); -					gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -					gGL.vertex2f(-1,-1); -		 -					gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -					gGL.vertex2f(-1,3); -		 -					gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -					gGL.vertex2f(3,-1); -		 -					gGL.end(); +				bindDeferredShader(*shader); -					unbindDeferredShader(*shader); -					mDeferredLight.flush(); +				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +				if (channel > -1) +				{ +					mScreen.bindTexture(0, channel);  				} -				{ //perform DoF sampling at half-res (preserve alpha channel) -					mScreen.bindTarget(); -					glViewport(0,0,mScreen.getWidth()/2, mScreen.getHeight()/2); -					gGL.setColorMask(true, false); - -					shader = &gDeferredPostProgram; -					bindDeferredShader(*shader); -					S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -					if (channel > -1) -					{ -						mDeferredLight.bindTexture(0, channel); -					} - -					shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); +				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); +				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); +				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); +				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -					gGL.begin(LLRender::TRIANGLE_STRIP); -					gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -					gGL.vertex2f(-1,-1); +				gGL.begin(LLRender::TRIANGLE_STRIP); +				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +				gGL.vertex2f(-1,-1); -					gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -					gGL.vertex2f(-1,3); +				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +				gGL.vertex2f(-1,3); -					gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -					gGL.vertex2f(3,-1); +				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +				gGL.vertex2f(3,-1); -					gGL.end(); +				gGL.end(); -					unbindDeferredShader(*shader); -					mScreen.flush(); -					gGL.setColorMask(true, true); -				} +				unbindDeferredShader(*shader); +				mDeferredLight.flush(); +			} -				{ //combine result based on alpha -					shader = &gDeferredDoFCombineProgram; -					bindDeferredShader(*shader); -					glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); -					S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -					if (channel > -1) -					{ -						mScreen.bindTexture(0, channel); -					} +			{ //perform DoF sampling at half-res (preserve alpha channel) +				mScreen.bindTarget(); +				glViewport(0,0,mScreen.getWidth()/2, mScreen.getHeight()/2); +				gGL.setColorMask(true, false); + +				shader = &gDeferredPostProgram; +				bindDeferredShader(*shader); +				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +				if (channel > -1) +				{ +					mDeferredLight.bindTexture(0, channel); +				} -					shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -					gGL.begin(LLRender::TRIANGLE_STRIP); -					gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -					gGL.vertex2f(-1,-1); +				gGL.begin(LLRender::TRIANGLE_STRIP); +				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +				gGL.vertex2f(-1,-1); -					gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -					gGL.vertex2f(-1,3); +				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +				gGL.vertex2f(-1,3); -					gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -					gGL.vertex2f(3,-1); +				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +				gGL.vertex2f(3,-1); -					gGL.end(); +				gGL.end(); -					unbindDeferredShader(*shader); -				} +				unbindDeferredShader(*shader); +				mScreen.flush(); +				gGL.setColorMask(true, true);  			} -			else -			{ -				bindDeferredShader(*shader); +	 +			{ //combine result based on alpha +				if (multisample) +				{ +					mDeferredLight.bindTarget(); +				} +				shader = &gDeferredDoFCombineProgram; +				bindDeferredShader(*shader); +				glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());  				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());  				if (channel > -1)  				{  					mScreen.bindTexture(0, channel);  				} -				if (multisample) -				{ //bloom has already been added, bind black -					channel = shader->enableTexture(LLShaderMgr::DEFERRED_BLOOM); -					if (channel > -1) -					{ -						gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sBlackImagep); -					} -				} -				 +				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +  				gGL.begin(LLRender::TRIANGLE_STRIP);  				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);  				gGL.vertex2f(-1,-1); @@ -6731,7 +6622,107 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  				gGL.end();  				unbindDeferredShader(*shader); + +				if (multisample) +				{ +					mDeferredLight.flush(); +				} +			} +		} +		else +		{ +			if (multisample) +			{ +				mDeferredLight.bindTarget();  			} +			LLGLSLShader* shader = &gDeferredPostNoDoFProgram; +			 +			bindDeferredShader(*shader); +							 +			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +			if (channel > -1) +			{ +				mScreen.bindTexture(0, channel); +			} + +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +			gGL.vertex2f(-1,-1); +		 +			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +			gGL.vertex2f(-1,3); +		 +			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +			gGL.vertex2f(3,-1); +		 +			gGL.end(); + +			unbindDeferredShader(*shader); + +			if (multisample) +			{ +				mDeferredLight.flush(); +			} +		} + +		if (multisample) +		{ +			//bake out texture2D with RGBL for FXAA shader +			mFXAABuffer.bindTarget(); +			 +			S32 width = mScreen.getWidth(); +			S32 height = mScreen.getHeight(); +			glViewport(0, 0, width, height); + +			LLGLSLShader* shader = &gGlowCombineFXAAProgram; + +			shader->bind(); +			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + +			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +			if (channel > -1) +			{ +				mDeferredLight.bindTexture(0, channel); +			} +						 +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.vertex2f(-1,-1); +			gGL.vertex2f(-1,3); +			gGL.vertex2f(3,-1); +			gGL.end(); + +			gGL.flush(); + +			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +			shader->unbind(); +			 +			mFXAABuffer.flush(); + +			shader = &gFXAAProgram; +			shader->bind(); + +			channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); +			if (channel > -1) +			{ +				mFXAABuffer.bindTexture(0, channel); +				gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); +			} +						 +			F32 scale_x = (F32) width/mFXAABuffer.getWidth(); +			F32 scale_y = (F32) height/mFXAABuffer.getHeight(); +			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); +			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); +			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); +			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); +			 +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.vertex2f(-1,-1); +			gGL.vertex2f(-1,3); +			gGL.vertex2f(3,-1); +			gGL.end(); + +			gGL.flush(); +			shader->unbind();  		}  	}  	else | 
