diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl | 3 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 896 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 9 | 
4 files changed, 440 insertions, 471 deletions
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl index 6cc83138a2..c50548d528 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl @@ -30,7 +30,6 @@  out vec4 frag_color;  uniform sampler2D diffuseRect; -uniform sampler2D emissiveRect;  uniform vec2 screen_res; @@ -38,7 +37,7 @@ in vec2 vary_tc;  void main()   { -    vec3 col = texture(diffuseRect, vary_tc).rgb + texture(emissiveRect, vary_tc).rgb; +    vec3 col = texture(diffuseRect, vary_tc).rgb;      frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));  } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 59333b6cee..a44452f0d1 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1307,9 +1307,6 @@ void render_ui(F32 zoom_factor, int subfield)  		gGL.popMatrix();  	} -    // Render our post process prior to the HUD, UI, etc. -    gPipeline.renderPostProcess(); -      // apply gamma correction and post effects      gPipeline.renderFinalize(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4266c16f94..3e9a1bb353 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6924,279 +6924,7 @@ void LLPipeline::renderPostProcess()  	LLVertexBuffer::unbind(); -    { -		bool dof_enabled =  -			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && -			RenderDepthOfField && -			!gCubeSnapshot; - -		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; - -		gViewerWindow->setup3DViewport(); - -		if (dof_enabled) -		{ -			LL_PROFILE_GPU_ZONE("dof"); -			LLGLSLShader* shader = &gDeferredPostProgram; -			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; - -			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) -				{ -					LLFace* face = obj->mDrawable->getFace(face_idx); -					if (face) -					{ -						focus_point = face->getPositionAgent(); -					} -				} -			} - -			if (focus_point.isExactlyZero()) -			{ -				if (LLViewerJoystick::getInstance()->getOverrideCamera()) -				{ // focus on point under cursor -					focus_point.set(gDebugRaycastIntersection.getF32ptr()); -				} -				else if (gAgentCamera.cameraMouselook()) -				{ // focus on point under mouselook crosshairs -					LLVector4a result; -					result.clear(); - -					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); - -					focus_point.set(result.getF32ptr()); -				} -				else -				{ -					// focus on alt-zoom target -					LLViewerRegion* region = gAgent.getRegion(); -					if (region) -					{ -						focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); -					} -				} -			} - -			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.value(); -				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; -			} - -			// convert to mm -			F32 subject_distance = current_distance * 1000.f; -			F32 fnumber = CameraFNumber; -			F32 default_focal_length = CameraFocalLength; - -			F32 fov = LLViewerCamera::getInstance()->getView(); - -			const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - -			// F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); - -			F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); - -			F32 focal_length = dv / (2 * tanf(fov / 2.f)); - -			// 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 -                mRT->deferredLight.bindTarget(); -				shader = &gDeferredCoFProgram; - -				bindDeferredShader(*shader); - -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); -				if (channel > -1) -				{ -					mRT->screen.bindTexture(0, channel); -				} - -				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); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - -				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); -                mRT->deferredLight.flush(); -			} - -			U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); -			U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); - -			{ // perform DoF sampling at half-res (preserve alpha channel) -				mRT->screen.bindTarget(); -				glViewport(0, 0, dof_width, dof_height); -				gGL.setColorMask(true, false); - -				shader = &gDeferredPostProgram; -				bindDeferredShader(*shader); -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); -				if (channel > -1) -				{ -                    mRT->deferredLight.bindTexture(0, channel); -				} - -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - -				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); -				mRT->screen.flush(); -				gGL.setColorMask(true, true); -			} - -			{ // combine result based on alpha -				if (multisample) -				{ -					mRT->deferredLight.bindTarget(); -					glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight()); -				} -				else -				{ -					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -				} - -				shader = &gDeferredDoFCombineProgram; -				bindDeferredShader(*shader); - -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); -				if (channel > -1) -				{ -					mRT->screen.bindTexture(0, channel); -				} - -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth()); -				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight()); - -				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) -				{ -					mRT->deferredLight.flush(); -				} -			} -		} -		else -		{ -			LL_PROFILE_GPU_ZONE("no dof"); -			if (multisample) -			{ -				mRT->deferredLight.bindTarget(); -			} -			LLGLSLShader* shader = &gDeferredPostNoDoFProgram; - -			bindDeferredShader(*shader); - -			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); -			if (channel > -1) -			{ -				mRT->screen.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) -			{ -				mRT->deferredLight.flush(); -			} -		} -	} +      }  LLRenderTarget* LLPipeline::screenTarget() { @@ -7214,186 +6942,161 @@ LLRenderTarget* LLPipeline::screenTarget() {  	return &mRT->screen;  } -void LLPipeline::renderFinalize() -{ -    LLVertexBuffer::unbind(); -    LLGLState::checkStates(); - -    assertInitialized(); - -    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); -    LL_PROFILE_GPU_ZONE("renderFinalize"); - -    gGL.color4f(1, 1, 1, 1); -    LLGLDepthTest depth(GL_FALSE); -    LLGLDisable blend(GL_BLEND); -    LLGLDisable cull(GL_CULL_FACE); - -    enableLightsFullbright(); - -    LLGLDisable test(GL_ALPHA_TEST); - -    gGL.setColorMask(true, true); -    glClearColor(0, 0, 0, 0); - -    if (!gCubeSnapshot) -    { -        LLRenderTarget* screen_target = screenTarget(); - -        if (RenderScreenSpaceReflections && !gCubeSnapshot) -        { -            LL_PROFILE_GPU_ZONE("ssr copy"); -            LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - -            LLRenderTarget& src = *screen_target; -            LLRenderTarget& depth_src = mRT->deferredScreen; -            LLRenderTarget& dst = mSceneMap; - -            dst.bindTarget(); -            dst.clear(); -            gCopyDepthProgram.bind(); +void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) { +	// luminance sample and mipmap generation +	{ +		LL_PROFILE_GPU_ZONE("luminance sample"); -            S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP); -            S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); +		dst->bindTarget(); -            gGL.getTexUnit(diff_map)->bind(&src); -            gGL.getTexUnit(depth_map)->bind(&depth_src, true); +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); -            mScreenTriangleVB->setBuffer(); -            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +		gLuminanceProgram.bind(); -            dst.flush(); -        } +		S32 channel = 0; +		channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); +		if (channel > -1) +		{ +			src->bindTexture(0, channel, LLTexUnit::TFO_POINT); +		} -        // luminance sample and mipmap generation -        { -            LL_PROFILE_GPU_ZONE("luminance sample"); +		channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); +		if (channel > -1) +		{ +			mGlow[1].bindTexture(0, channel); +		} -            mLuminanceMap.bindTarget(); +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +		dst->flush(); -            LLGLDepthTest depth(GL_FALSE, GL_FALSE); +		dst->bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR); +		glGenerateMipmap(GL_TEXTURE_2D); -            gLuminanceProgram.bind(); +		// note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance" +		// also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader +		gLuminanceProgram.unbind(); +	} +} +void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) { +	// exposure sample +	{ +		LL_PROFILE_GPU_ZONE("exposure sample"); -            S32 channel = 0; -            channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); -            if (channel > -1) -            { -                screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT); -            } +		{ +			// copy last frame's exposure into mLastExposure +			mLastExposure.bindTarget(); +			gCopyProgram.bind(); +			gGL.getTexUnit(0)->bind(dst); -            channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); -            if (channel > -1) -            { -                mGlow[1].bindTexture(0, channel); -            } +			mScreenTriangleVB->setBuffer(); +			mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +			mLastExposure.flush(); +		} -            mScreenTriangleVB->setBuffer(); -            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -            mLuminanceMap.flush(); +		dst->bindTarget(); -            mLuminanceMap.bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR); -            glGenerateMipmap(GL_TEXTURE_2D); +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); -            // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance" -            // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader -            gLuminanceProgram.unbind(); -        } +		gExposureProgram.bind(); -        // exposure sample -        { -            LL_PROFILE_GPU_ZONE("exposure sample"); +		S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); +		if (channel > -1) +		{ +			mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR); +		} -            { -                // copy last frame's exposure into mLastExposure -                mLastExposure.bindTarget(); -                gCopyProgram.bind(); -                gGL.getTexUnit(0)->bind(&mExposureMap); +		channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP); +		if (channel > -1) +		{ +			mLastExposure.bindTexture(0, channel); +		} -                mScreenTriangleVB->setBuffer(); -                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +		static LLStaticHashedString dt("dt"); +		static LLStaticHashedString noiseVec("noiseVec"); +		static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); +		static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f); +		static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f); +		static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f); -                mLastExposure.flush(); -            } +		gExposureProgram.uniform1f(dt, gFrameIntervalSeconds); +		gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); +		gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max); -            mExposureMap.bindTarget(); +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -            LLGLDepthTest depth(GL_FALSE, GL_FALSE); -             -            gExposureProgram.bind(); +		gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage()); +		gExposureProgram.unbind(); +		dst->flush(); +	} +} -            S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE); -            if (channel > -1) -            { -                mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR); -            } +void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { +	dst->bindTarget(); +	// gamma correct lighting +	{ +		LL_PROFILE_GPU_ZONE("gamma correct"); -            channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP); -            if (channel > -1) -            { -                mLastExposure.bindTexture(0, channel); -            } +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); -            static LLStaticHashedString dt("dt"); -            static LLStaticHashedString noiseVec("noiseVec"); -            static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); -            static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f); -            static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f); -            static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f); +		// Apply gamma correction to the frame here. +		gDeferredPostGammaCorrectProgram.bind(); -            gExposureProgram.uniform1f(dt, gFrameIntervalSeconds); -            gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); -            gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max); +		S32 channel = 0; -            mScreenTriangleVB->setBuffer(); -            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +		gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); -            gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage()); -            gExposureProgram.unbind(); -            mExposureMap.flush(); -        } +		gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); -        mPostMap.bindTarget(); +		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight()); -        // gamma correct lighting -        { -            LL_PROFILE_GPU_ZONE("gamma correct"); +		static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); -            LLGLDepthTest depth(GL_FALSE, GL_FALSE); +		F32 e = llclamp(exposure(), 0.5f, 4.f);        -            // Apply gamma correction to the frame here. -            gDeferredPostGammaCorrectProgram.bind(); -             -            S32 channel = 0; +		static LLStaticHashedString s_exposure("exposure"); -            gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget(), false, LLTexUnit::TFO_POINT); +		gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e); -            gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -            gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight()); +		gGL.getTexUnit(channel)->unbind(src->getUsage()); +		gDeferredPostGammaCorrectProgram.unbind(); +	} +	dst->flush(); +} -            static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); +void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) { -            F32 e = llclamp(exposure(), 0.5f, 4.f); +	if (RenderScreenSpaceReflections && !gCubeSnapshot) +	{ +		LL_PROFILE_GPU_ZONE("ssr copy"); +		LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); -            static LLStaticHashedString s_exposure("exposure"); +		LLRenderTarget& depth_src = mRT->deferredScreen; -            gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e); +		dst->bindTarget(); +		dst->clear(); +		gCopyDepthProgram.bind(); -            mScreenTriangleVB->setBuffer(); -            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +		S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP); +		S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); -            gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage()); -            gDeferredPostGammaCorrectProgram.unbind(); -        } +		gGL.getTexUnit(diff_map)->bind(src); +		gGL.getTexUnit(depth_map)->bind(&depth_src, true); -        mPostMap.flush(); +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -        LLVertexBuffer::unbind(); -    } +		dst->flush(); +	} +} +void LLPipeline::generateGlow(LLRenderTarget* src) {  	if (sRenderGlow)  	{  		LL_PROFILE_GPU_ZONE("glow"); @@ -7420,7 +7123,7 @@ void LLPipeline::renderFinalize()  			gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -			gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mPostMap); +			gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);  			gGL.color4f(1, 1, 1, 1);  			gPipeline.enableLightsFullbright(); @@ -7480,7 +7183,7 @@ void LLPipeline::renderFinalize()  		}  		gGlowProgram.unbind(); -		gGL.setSceneBlendType(LLRender::BT_ALPHA); +  	}  	else // !sRenderGlow, skip the glow ping-pong and just clear the result target  	{ @@ -7488,17 +7191,17 @@ void LLPipeline::renderFinalize()  		mGlow[1].clear();  		mGlow[1].flush();  	} +} +void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {  	{ -        llassert(!gCubeSnapshot); +		llassert(!gCubeSnapshot);  		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();  		LLGLSLShader* shader = &gGlowCombineProgram;  		S32 width = screenTarget()->getWidth();  		S32 height = screenTarget()->getHeight(); -		S32 channel = -1; -  		// Present everything.  		if (multisample)  		{ @@ -7506,38 +7209,27 @@ void LLPipeline::renderFinalize()  			// bake out texture2D with RGBL for FXAA shader  			mRT->fxaaBuffer.bindTarget(); -			glViewport(0, 0, width, height); -  			shader = &gGlowCombineFXAAProgram; -  			shader->bind(); -			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); -			channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage()); +			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());  			if (channel > -1)  			{ -				mPostMap.bindTexture(0, channel); +				src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);  			} -			channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, mGlow[1].getUsage()); -			if (channel > -1)  			{ -				mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); +				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); +				mScreenTriangleVB->setBuffer(); +				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);  			} -            { -                LLGLDepthTest depth_test(GL_FALSE, GL_FALSE, GL_ALWAYS); -                mScreenTriangleVB->setBuffer(); -                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -            } - -			gGL.flush(); - -			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage()); +			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());  			shader->unbind();  			mRT->fxaaBuffer.flush(); +			dst->bindTarget();  			shader = &gFXAAProgram;  			shader->bind(); @@ -7547,12 +7239,6 @@ void LLPipeline::renderFinalize()  				mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);  			} -			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -  			F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();  			F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();  			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); @@ -7562,45 +7248,323 @@ void LLPipeline::renderFinalize()  			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); -            { -                // at this point we should pointed at the backbuffer (or a snapshot render target) -                llassert(gSnapshot || LLRenderTarget::sCurFBO == 0); -                LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); -                S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); -                gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); +			{ +				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); +				S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); +				gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); + +				mScreenTriangleVB->setBuffer(); +				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +			} -                mScreenTriangleVB->setBuffer(); -                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -            } -			  			shader->unbind(); +			dst->flush();  		} -		else +		else { +			copyRenderTarget(src, dst); +		} +	} +} + +void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) { + +	LL_PROFILE_GPU_ZONE("copyRenderTarget"); +	dst->bindTarget(); + +	gDeferredPostNoDoFProgram.bind(); + +	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); +	if (channel > -1) +	{ +		src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); +	} + +	{ +		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +	} + +	gDeferredPostNoDoFProgram.unbind(); + +	dst->flush(); +} + +void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) { +	// Go ahead and do our glow combine here in our destination.  We blit this later into the front buffer. + +	dst->bindTarget(); + +	{ +		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + +		gGlowCombineProgram.bind(); + +		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); +		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); +		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); + +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +	} + +	dst->flush(); +} + +void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) { +	{ +		bool dof_enabled = +			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && +			RenderDepthOfField && +			!gCubeSnapshot; + +		gViewerWindow->setup3DViewport(); + +		if (dof_enabled)  		{ -            // at this point we should pointed at the backbuffer (or a snapshot render target) -            llassert(gSnapshot || LLRenderTarget::sCurFBO == 0); +			LL_PROFILE_GPU_ZONE("dof"); +			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; -            LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); +			LLVector3 focus_point; -			shader->bind(); +			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) +					{ +						focus_point = face->getPositionAgent(); +					} +				} +			} -			shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mPostMap); -			shader->bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); -			shader->bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); +			if (focus_point.isExactlyZero()) +			{ +				if (LLViewerJoystick::getInstance()->getOverrideCamera()) +				{ // focus on point under cursor +					focus_point.set(gDebugRaycastIntersection.getF32ptr()); +				} +				else if (gAgentCamera.cameraMouselook()) +				{ // focus on point under mouselook crosshairs +					LLVector4a result; +					result.clear(); -			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); +					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); -            mScreenTriangleVB->setBuffer(); -            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +					focus_point.set(result.getF32ptr()); +				} +				else +				{ +					// focus on alt-zoom target +					LLViewerRegion* region = gAgent.getRegion(); +					if (region) +					{ +						focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); +					} +				} +			} -			gGL.flush(); -			shader->unbind(); +			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.value(); +				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; +			} + +			// convert to mm +			F32 subject_distance = current_distance * 1000.f; +			F32 fnumber = CameraFNumber; +			F32 default_focal_length = CameraFocalLength; + +			F32 fov = LLViewerCamera::getInstance()->getView(); + +			const F32 default_fov = CameraFieldOfView * F_PI / 180.f; + +			// F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); + +			F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); + +			F32 focal_length = dv / (2 * tanf(fov / 2.f)); + +			// 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 +				mRT->deferredLight.bindTarget(); + +				gDeferredCoFProgram.bind(); + +				gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); +				gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); +				gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + +				mScreenTriangleVB->setBuffer(); +				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +				gDeferredCoFProgram.unbind(); +				mRT->deferredLight.flush(); +			} + +			U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); +			U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); + +			{ // perform DoF sampling at half-res (preserve alpha channel) +				src->bindTarget(); +				glViewport(0, 0, dof_width, dof_height); +				gGL.setColorMask(true, false); + +				gDeferredPostProgram.bind(); +				gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT); + +				gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); +				gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + +				mScreenTriangleVB->setBuffer(); +				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + +				gDeferredPostProgram.unbind(); + +				src->flush(); +				gGL.setColorMask(true, true); +			} + +			{ // combine result based on alpha +				 +				dst->bindTarget(); +				glViewport(0, 0, dst->getWidth(), dst->getHeight()); + +				gDeferredDoFCombineProgram.bind();	 +				gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); +				gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT); + +				gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight()); +				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); +				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); + +				mScreenTriangleVB->setBuffer(); +				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + +				gDeferredDoFCombineProgram.unbind(); + +				dst->flush(); +			} +		} +		else +		{ +			copyRenderTarget(src, dst);  		}  	} +} + +void LLPipeline::renderFinalize() +{ +    LLVertexBuffer::unbind(); +    LLGLState::checkStates(); + +    assertInitialized(); + +    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); +    LL_PROFILE_GPU_ZONE("renderFinalize"); + +    gGL.color4f(1, 1, 1, 1); +    LLGLDepthTest depth(GL_FALSE); +    LLGLDisable blend(GL_BLEND); +    LLGLDisable cull(GL_CULL_FACE); + +    enableLightsFullbright(); + +    LLGLDisable test(GL_ALPHA_TEST); + +    gGL.setColorMask(true, true); +    glClearColor(0, 0, 0, 0); + +    if (!gCubeSnapshot) +    { +		copyScreenSpaceReflections(&mRT->screen, &mSceneMap); + +		generateLuminance(&mRT->screen, &mLuminanceMap); + +		generateExposure(&mLuminanceMap, &mExposureMap); + +		gammaCorrect(&mRT->screen, &mPostMap); + +        LLVertexBuffer::unbind(); +    } + +	generateGlow(&mPostMap); + +	combineGlow(&mPostMap, &mRT->screen); + +	renderDoF(&mRT->screen, &mPostMap); + +	applyFXAA(&mPostMap, &mRT->screen); + + +	// Present the screen target. + +	gDeferredPostNoDoFProgram.bind(); + +	// Whatever is last in the above post processing chain should _always_ be rendered directly here.  If not, expect problems. +	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); +	if (channel > -1) +	{ +		mRT->screen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); +	} + +	{ +		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); +		mScreenTriangleVB->setBuffer(); +		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +	} + +	gDeferredPostNoDoFProgram.unbind();      gGL.setSceneBlendType(LLRender::BT_ALPHA); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a231084e5c..ed9e2dc452 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -135,6 +135,15 @@ public:  	void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);  	void bindScreenToTexture();  	void renderFinalize(); +	void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); +	void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst); +	void generateExposure(LLRenderTarget* src, LLRenderTarget* dst); +	void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst); +	void generateGlow(LLRenderTarget* src); +	void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst); +	void renderDoF(LLRenderTarget* src, LLRenderTarget* dst); +	void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst); +	void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);  	void renderPostProcess();  	LLRenderTarget* screenTarget();  | 
