diff options
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 40 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl | 172 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolalpha.cpp | 45 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 60 | 
5 files changed, 282 insertions, 55 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5cc8c34cd5..4efb8edd63 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1332,7 +1332,45 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>CertStore</key> + +  <key>CameraFNumber</key> +  <map> +    <key>Comment</key> +    <string>Camera f-number value for DoF effect</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>2.8</real> +  </map> + +  <key>CameraFocalLength</key> +  <map> +    <key>Comment</key> +    <string>Camera focal length for DoF effect (in millimeters)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>50</real> +  </map> + +  <key>CameraCoC</key> +  <map> +    <key>Comment</key> +    <string>Camera circle of confusion for DoF effect (in millimeters)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0.5</real> +  </map> + +   +  <key>CertStore</key>      <map>        <key>Comment</key>        <string>Specifies the Certificate Store for certificate trust verification</string> diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 03c2e63fb1..eec44d9d42 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -17,6 +17,8 @@ uniform sampler2D bloomMap;  uniform float depth_cutoff;  uniform float norm_cutoff; +uniform float near_focal_distance; +uniform float far_focal_distance;  uniform mat4 inv_proj;  uniform vec2 screen_res; @@ -32,55 +34,149 @@ float getDepth(vec2 pos_screen)  	return p.z/p.w;  } +void dofSample(inout vec4 diff, inout float w, float fd, float x, float y) +{ +	vec2 tc = vary_fragcoord.xy+vec2(x,y); +	float d = getDepth(tc); +	 +	if (d < fd) +	{ +		diff += texture2DRect(diffuseRect, tc); +		w += 1.0; +	} +} + +void dofSampleNear(inout vec4 diff, inout float w, float x, float y) +{ +	vec2 tc = vary_fragcoord.xy+vec2(x,y); +		 +	diff += texture2DRect(diffuseRect, tc); +	w += 1.0; +} +  void main()   {  	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;  	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm -	float depth = getDepth(vary_fragcoord.xy); +	  	vec2 tc = vary_fragcoord.xy;  	float sc = 0.75; -	vec2 de; -	de.x = (depth-getDepth(tc+vec2(sc, sc))) + (depth-getDepth(tc+vec2(-sc, -sc))); -	de.y = (depth-getDepth(tc+vec2(-sc, sc))) + (depth-getDepth(tc+vec2(sc, -sc))); -	de /= depth; -	de *= de; -	de = step(depth_cutoff, de); -	 -	vec2 ne; -	vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb; -	nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm -	ne.x = dot(nexnorm, norm); -	vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).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); -	 -	float edge_weight = clamp(dot(de,de)+dot(ne,ne), 0.0, 1.0); -	//edge_weight *= 0.0; -	 -	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); +	float depth[5]; +	depth[0] = getDepth(tc); +		  	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,1))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,-1))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,1))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,-1))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,0))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,0))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,1))*edge_weight; -	diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,-1))*edge_weight; -	 -	diff /= 1.0+edge_weight*8.0; +	bool do_aa = true; -	vec4 blur = texture2DRect(edgeMap, vary_fragcoord.xy); -	 -	//gl_FragColor = vec4(edge_weight,edge_weight,edge_weight, 1.0); +	if (depth[0] < far_focal_distance) +	{ //pixel is behind far focal plane +		float w = 1.0; +		 +		float fd = far_focal_distance; +		float sc = clamp(depth[0]/fd, 0.0, -8.0/fd); +		sc = min(sc, 8.0); +		 +		//fd = depth[0]*0.5; +			 +		while (sc > 1.0) +		{ +			do_aa = false; +			dofSample(diff,w, fd, sc,sc); +			dofSample(diff,w, fd, -sc,sc); +			dofSample(diff,w, fd, sc,-sc); +			dofSample(diff,w, fd, -sc,-sc); +			 +			sc -= 0.5; +			float sc2 = sc*1.414; +			dofSample(diff,w, fd, 0,sc2); +			dofSample(diff,w, fd, 0,-sc2); +			dofSample(diff,w, fd, -sc2,0); +			dofSample(diff,w, fd, sc2,0); +			sc -= 0.5; +		} +		diff /= w; +	} +	else +	{ +		float fd = near_focal_distance; +		 +		if (depth[0] > fd) +		{ //pixel is in front of near focal plane +			//diff.r = 1.0; +			float w = 1.0; +			float sc = depth[0] - fd; +			sc = min(-sc/fd*16.0, 8.0); +						 +			fd = depth[0]; +			while (sc > 1.0) +			{ +				do_aa = false; +				dofSampleNear(diff,w, sc,sc); +				dofSampleNear(diff,w, -sc,sc); +				dofSampleNear(diff,w, sc,-sc); +				dofSampleNear(diff,w, -sc,-sc); +				 +				sc -= 0.5; +				float sc2 = sc*1.414; +				dofSampleNear(diff,w, 0,sc2); +				dofSampleNear(diff,w, 0,-sc2); +				dofSampleNear(diff,w, -sc2,0); +				dofSampleNear(diff,w, sc2,0); +				sc -= 0.5; +			} +			diff /= w; +		}	 +		 +		if (do_aa) +		{ +			depth[1] = getDepth(tc+vec2(sc,sc)); +			depth[2] = getDepth(tc+vec2(-sc,-sc)); +			depth[3] = getDepth(tc+vec2(-sc,sc)); +			depth[4] = getDepth(tc+vec2(sc, -sc)); +				 +			 +			vec2 de; +			de.x = (depth[0]-depth[1]) + (depth[0]-depth[2]); +			de.y = (depth[0]-depth[3]) + (depth[0]-depth[4]); +			de /= depth[0]; +			de *= de; +			de = step(depth_cutoff, de); +			 +			vec2 ne; +			vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb; +			nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm +			ne.x = dot(nexnorm, norm); +			vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).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); +			 +			float edge_weight = clamp(dot(de,de)+dot(ne,ne), 0.0, 1.0); +			//edge_weight *= 0.0; +			 +			//diff.r = edge_weight; +			 +			if (edge_weight > 0.0) +			{ +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,1))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,-1))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,1))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,-1))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(-1,0))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(1,0))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,1))*edge_weight; +				diff += texture2DRect(diffuseRect, vary_fragcoord.xy+vec2(0,-1))*edge_weight; +				diff /= 1.0+edge_weight*8.0; +			} +		} +	} +			 +	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);  	gl_FragColor = diff + bloom; -	//gl_FragColor.r = edge_weight;  } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index a2428d2de0..2519d0297c 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -103,16 +103,29 @@ void LLDrawPoolAlpha::renderDeferred(S32 pass)  S32 LLDrawPoolAlpha::getNumPostDeferredPasses()   {  -	return 1;  +	return 2;   }  void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)   {   	LLFastTimer t(FTM_RENDER_ALPHA); -	simple_shader = &gDeferredAlphaProgram; -	fullbright_shader = &gDeferredFullbrightProgram; -	 +	if (pass == 0) +	{ +		simple_shader = &gDeferredAlphaProgram; +		fullbright_shader = &gDeferredFullbrightProgram; +	} +	else +	{ +		//update depth buffer sampler +		gPipeline.mScreen.flush(); +		gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), +							0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	 +		gPipeline.mDeferredDepth.bindTarget(); +		simple_shader = NULL; +		fullbright_shader = NULL; +	} +  	deferred_render = TRUE;  	if (mVertexShaderLevel > 0)  	{ @@ -124,6 +137,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)   {  +	gPipeline.mDeferredDepth.flush(); +	gPipeline.mScreen.bindTarget();  	deferred_render = FALSE;  	endRenderPass(pass);  } @@ -174,7 +189,14 @@ void LLDrawPoolAlpha::render(S32 pass)  	LLGLSPipelineAlpha gls_pipeline_alpha; -	gGL.setColorMask(true, true); +	if (deferred_render && pass == 1) +	{ //depth only +		gGL.setColorMask(false, false); +	} +	else +	{ +		gGL.setColorMask(true, true); +	}  	if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render)  	{ @@ -206,7 +228,13 @@ void LLDrawPoolAlpha::render(S32 pass)  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  	} -	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); +	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||  +				(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE); + +	if (deferred_render && pass == 1) +	{ +		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); +	}  	mColorSFactor = LLRender::BF_SOURCE_ALPHA;           // } regular alpha blend  	mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } @@ -218,6 +246,11 @@ void LLDrawPoolAlpha::render(S32 pass)  	gGL.setColorMask(true, false); +	if (deferred_render && pass == 1) +	{ +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +	} +  	if (deferred_render && current_shader != NULL)  	{  		gPipeline.unbindDeferredShader(*current_shader); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 972c9c255e..20d9f49a3e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3549,6 +3549,8 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	LLVector3 mouse_world_start = mouse_point_global;  	LLVector3 mouse_world_end   = mouse_point_global + mouse_direction_global * depth; +	//gDebugRaycastIntersection = mouse_world_end; +  	if (start)  	{  		*start = mouse_world_start; @@ -3570,8 +3572,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  			{  				found = this_object;  			} -			} -		 +		}  		else // is a world object  		{  			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent, @@ -3579,21 +3580,22 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  			{  				found = this_object;  			} -			} -			} - +		} +	}  	else // check ALL objects -			{ +	{  		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,  													face_hit, intersection, uv, normal, binormal);  		if (!found) // if not found in HUD, look in world: - -			{ +		{  			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,  														  face_hit, intersection, uv, normal, binormal); +			if (found) +			{ +				gDebugRaycastIntersection = *intersection;  			} - +		}  	}  	return found; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4007d9d8f3..a189d17dc8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6253,14 +6253,71 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		{  			shader = &gDeferredGIFinalProgram;  		} - +		  		LLGLDisable blend(GL_BLEND);  		bindDeferredShader(*shader); + +		//depth of field focal plane calculations + +		F32 subject_distance = 16.f; +		if (LLViewerJoystick::getInstance()->getOverrideCamera()) +		{ +			//flycam mode, use mouse cursor as focus point +			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); +			subject_distance = (eye-gDebugRaycastIntersection).magVec(); +		} +		else +		{ +			LLViewerObject* obj = gAgentCamera.getFocusObject(); +			if (obj) +			{ +				LLVector3 focus = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); +				LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); +				subject_distance = (focus-eye).magVec(); +			} +		} + +		//convert to mm +		subject_distance *= 1000.f; +		F32 fnumber = gSavedSettings.getF32("CameraFNumber"); +		F32 focal_length = gSavedSettings.getF32("CameraFocalLength"); +		F32 coc = gSavedSettings.getF32("CameraCoC"); + + +		F32 hyperfocal_distance = (focal_length*focal_length)/(fnumber*coc); + +		subject_distance = llmin(hyperfocal_distance, subject_distance); + +		//adjust focal length for subject distance +		focal_length = llmax(focal_length, 1.f/(1.f/focal_length - 1.f/subject_distance)); + +		//adjust focal length for zoom +		F32 fov = LLViewerCamera::getInstance()->getView(); +		F32 default_fov = LLViewerCamera::getInstance()->getDefaultFOV(); +		focal_length *= default_fov/fov; + +		F32 near_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance+subject_distance); +		 +		//beyond far clip plane is effectively infinity +		F32 far_focal_distance = 4096.f; + +		if (subject_distance < hyperfocal_distance) +		{ +			far_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance-subject_distance); +			far_focal_distance /= 1000.f; +		} + +		near_focal_distance /= 1000.f; + +		shader->uniform1f("far_focal_distance", -far_focal_distance); +		shader->uniform1f("near_focal_distance", -near_focal_distance); +  		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);  		if (channel > -1)  		{  			mScreen.bindTexture(0, channel); +			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  		}  		gGL.begin(LLRender::TRIANGLE_STRIP); @@ -6753,6 +6810,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  	shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight());  	shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff"));  	shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff")); +	  	if (shader.getUniformLocation("norm_mat") >= 0)  	{ | 
