Help fixing broken Depth of Field shader?

I’m using the Depth of Field shaders included in the “Shader Replacement” project ( Unity - Manual: Replacing shaders at runtime ). The problem is that it doesn’t work when anti-aliasing is used on DirectX machines (it shows the image upside down). The fix is documented ( Unity - Manual: Writing shaders for different graphics APIs ) but I just spent the last 6 hours trying to figure out how to implement the fix without success. I only know enough shader code to be dangerous, so everything I’ve tried has just triggered errors. Can anyone please help? If some kind soul were to fix the shaders I would be eternally grateful. :slight_smile:

Bump
I’m willing to pay for this, please contact me if you can do this.

Try this out (replace the fragment part of the shader). It’s a bit hacky but some of the textures are up the wrong way when they go into the shader and some are not. It looks like it’s just the original and the blur textures… A better fix would be to redo the whole DOF pipeline but this fix is ‘fit for purpose’.

uniform float4 _MainTex_TexelSize;
half4 frag (v2f i) : COLOR
{
#if SHADER_API_D3D9
	if (_MainTex_TexelSize.y < 0)
	{
		i.uv[0].y = 1-i.uv[0].y;
        i.uv[1].y = 1-i.uv[1].y;
        i.uv[2].y = 1-i.uv[2].y;
	}
#endif

	half4 original = texRECT(_MainTex,  i.uv[0]);
	half3 blur1 = texRECT(_BlurTex1, i.uv[1]).rgb;
	half3 blur2 = texRECT(_BlurTex2, i.uv[2]).rgb;
	
	// tint blur levels just for fun!
	blur1 *= float3(1,1,0.7);
	blur2 *= float3(0.7,0.7,1);
	
	float dof = texRECT(_DepthTex, i.uv[3]).r;
	
	half dof2;
	if( dof > 0.5 )
		dof2 = saturate( dof * 0.25 + 0.75 );
	else
		dof2 = saturate( dof * 1.5 );
	half factor = saturate( dof * 1.5 - 0.75 );
	half3 blur = lerp( blur1, blur2, factor );
	half3 col = lerp( original.rgb, blur, dof );
	return float4( col, original.a);
}

Unfortunately that doesn’t fix it. If you’re running Windows, try building a stand alone and running it at “Fantastic” quality setting and you’ll see it’s still rendering upside down.

Hrm that’s very odd. I have checked this using multiple AA settings on windows in standalone mode as well as in the editor.

Could you please try redownloading the example project and only making the change I gave you and touching no other code.

Here is the difference between the application before and after the fix. I have also checked this on multiple DX9 machines.

(You are making this change to the DepthOfFieldComposite shader correct? and you are using unity pro?)

Before:

After:

FIXED!!!

There must have been some issues with the old project folder because when I started with a fresh download it worked -perfectly-! Many thanks!

Hello.

Thanks heaps for the image flipping solution - it works perfectly.

Don’t think I’m ungrateful but… now (as can been see in the screen-shot 2 posts above (“After:” image)) the depth of field effect look like its a pixel off being aligned.

I think I found a website of someone explaining why here:
http://www.sjbrown.co.uk/2003/05/01/fix-directx-rasterisation/

And possibly the solution for unity on the second half of this page:

However I can’t work out where in the depth of field shader I need to implement this =/.
When I start playing around with it I get errors or the depth of field stops working completly, even if I undo changes + re-open the scene and need to start again completly from scratch to get it working again -_- (don’t understand why this is happening either…)

Summary / TLDR:

  • Is there anyone who knows where to add the line below to the depth of field shader to make it work properly?
// _MainTex_TexelSize.xy is the "one pixel" offset
float4 _MainTex_TexelSize;

Thanks

hey,I have tried this fix and it works perfectly! however, it seems it only works for depth of field shader. How about glow effect? anyone have solution for that shader?? Thanks

Please, can anyone post the complete changed script. I had the same problem, with two images, one being upside down. I changed the script, I think I did it right because there were no errors and there is only one image and a the blur is uniform as it should be.
The only problem is that the whole image is now upside down!!
Can it be fixed? Can someone post the whole script or suggest how to flip the image?

-thanks.

I meant, post the whole changed shader.

I’m sure many would like it if anyone has it? …including me ^-^

I’ve sort of given up on hope on this thread though, just hoping that its a working feature in Unity 3 =X

I don’t have the fixed shader handy, but if you take the original shader and add the fix posted above it will work.

So here is the whole corrected code plus I’ve tried to correct that offset problem and I think it is a little bit better.

Shader "Hidden/DOF Composite" {
Properties {
	_MainTex ("", RECT) = "white" {}
	_BlurTex1 ("", RECT) = "white" {}
	_BlurTex2 ("", RECT) = "white" {}
	_DepthTex ("", RECT) = "white" {}
}

SubShader {
	Pass {
		ZTest Always Cull Off ZWrite Off Fog { Mode off }

CGPROGRAM
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest 
#include "UnityCG.cginc"

uniform samplerRECT _MainTex : register(s0);
uniform samplerRECT _BlurTex1 : register(s1);
uniform samplerRECT _BlurTex2 : register(s2);
uniform samplerRECT _DepthTex : register(s3);

uniform float4 _FocalParams; // x = distance, y = 1/distance, z = range, w = 1/range

struct v2f 
{
	float2 uv[4] : TEXCOORD0;
};

float DOFFactor( float z ) 
{
	float focalDist = _FocalParams.x;
	float invRange = _FocalParams.w;
	
	float fromFocal = z - focalDist;
	if( fromFocal < 0.0 )
		fromFocal *= 4.0;
	return saturate( abs( fromFocal ) * invRange );
}

uniform float4 _MainTex_TexelSize;

half4 frag (v2f i) : COLOR
{
	#if SHADER_API_D3D9
	if (_MainTex_TexelSize.y < 0)
	{
		i.uv[0].y = 1-i.uv[0].y;
		i.uv[1].y = 1-i.uv[1].y;
		i.uv[2].y = 1-i.uv[2].y;
	}
	i.uv[0].xy -= _MainTex_TexelSize.yy;
	//i.uv[1].xy -= _MainTex_TexelSize.yy;
	//i.uv[2].xy -= _MainTex_TexelSize.yy;
	i.uv[3].xy -= _MainTex_TexelSize.yy;
	#endif
	
   half4 original = texRECT(_MainTex,  i.uv[0]);
   half3 blur1 = texRECT(_BlurTex1, i.uv[1]).rgb;
   half3 blur2 = texRECT(_BlurTex2, i.uv[2]).rgb;
   
   // tint blur levels just for fun!
   blur1 *= float3(1,1,0.7);
   blur2 *= float3(0.7,0.7,1);
   
   float dof = texRECT(_DepthTex, i.uv[3]).r;
   
   half dof2;
   if( dof > 0.5 )
      dof2 = saturate( dof * 0.25 + 0.75 );
   else
      dof2 = saturate( dof * 1.5 );
   half factor = saturate( dof * 1.5 - 0.75 );
   half3 blur = lerp( blur1, blur2, factor );
   half3 col = lerp( original.rgb, blur, dof );
   return float4( col, original.a);
}
ENDCG
	}
}

Fallback off

}

298011--10573--$dof_162.png

Thanks for posting the fixed shader, I just located my copy and was going to post it when I saw your post.

Question: Does anyone know how to change the color tint in the example DOF scene? I’m looking through all the scripts and shaders and I don’t see where this was set.

One more question: I noticed that this effect (all versions including the original) does weird things when seen through the “Stained BumpDistort Light” shader. Is this just a limitation of the blur effect?

Thank you so much greg767! :smile:

Much better than before, not perfect, but I’m not complaining, we finally can use DOF :smile:

  • The foreground and background blurs are perfect, there’s just a slight offset from the focused (unblurred) objects and the background blurred objects.
    I’m sure this can be hidden/made less obvious with some clever skyboxing, or object placement.

bigKahuna:
Question 1: File: DepthOfFieldComposite.shader
Line 62 - 64
// tint blur levels just for fun!
blur1 *= float3(1,1,0.7);
blur2 *= float3(0.7,0.7,1);

Question 2: I don’t know sorry -_-

Is your fix to the DOF the same as greg767’s?

any luck fixing any of the others…
specifically motion blur and Glow/blur

I tried Glow/Blur, several different ways, but just ended up flipping the glow, and not the source image

any ideas ?

same here. I have been waiting for a fix for gluw/blur for a long time…but never got a right answer. someone please~!!

am also have the same problem with the twirl effect , i read the answer but i don’t understand where can i put the flipping code!!

#if SHADER_API_D3D9
if (_MainTex_TexelSize.y < 0)
        uv.y = 1-uv.y;
#endif

any help please :S

I’ve also tried the completed flipped code and what happens for me on D3d with AA on is that the entire scene ends up flipped, not the mask for the DOF. At least they’re facing the same direction now…