Jump to content

View more

Image of the Day

Adding some finishing touches...
Follow us for more
#screenshotsaturday #indiedev... by #MakeGoodGames https://t.co/Otbwywbm3a
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.


Sign up now

DLAA

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
8 replies to this topic

#1 facepuncherfromrussia   Members   

100
Like
0Likes
Like

Posted 28 January 2011 - 07:05 PM

Hi All,

I've been experimenting with full-screen AA techniques, and DLAA looked like a promising technique from what the developers said and the results in TFU2.
I had been looking for details on the this technique for a while but there isn't much out there, so I've set out to uncover the technique. Here are my results:

The technique is based on detecting short and long - vertical and horizontal edges.
1) The first pass does a simple color average space edge detection.
2) The second pass does localized edge detection and blurs directionally (vertically and horizontally).
Next it determines if the current edge is a long one, in which case it does a wider vertical and horizontal direction blur

that's about it.

The following pixel shader produces pretty much the same output as the 360 version of TFU2.
Performance is around ~3.2 ms in a X360 class GPU.

#define PIXEL_SIZE float2(1.0/1280, 1.0/720)

float4 sampleOffseted(const in sampler2D tex, const in float2 texCoord, const float2 pixelOffset )
{
   return tex2D(tex, texCoord + pixelOffset * PIXEL_SIZE);
}

float3 avg(const in float3 value)
{
   static const float oneThird = 1.0 / 3.0;
   return dot(value.xyz, float3(oneThird, oneThird, oneThird) );
}

float4 firsPassEdgeDetect( float2 texCoord  : TEXCOORD0 ) : COLOR
{
   float4 sCenter	= sampleOffseted(Texture0, texCoord, float2( 0.0,  0.0) );
   float4 sUpLeft	= sampleOffseted(Texture0, texCoord, float2(-0.5, -0.5) );
   float4 sUpRight   = sampleOffseted(Texture0, texCoord, float2( 0.5, -0.5) );
   float4 sDownLeft  = sampleOffseted(Texture0, texCoord, float2(-0.5,  0.5) );
   float4 sDownRight = sampleOffseted(Texture0, texCoord, float2( 0.5,  0.5) );
 
   float4 diff   	= abs( ((sUpLeft + sUpRight + sDownLeft + sDownRight) * 4.0) - (sCenter * 16.0) );
   float edgeMask	= avg(diff.xyz);

   return float4(sCenter.rgb, edgeMask);
}


float4 secondPassEdgeDetectAndBlur(  float2 texCoord  : TEXCOORD0 ) : COLOR
{
	// short edges
	float4 sampleCenter  	= sampleOffseted(Texture0, texCoord.xy, float2( 0.0,  0.0) );   
	float4 sampleHorizNeg0   = sampleOffseted(Texture0, texCoord.xy, float2(-1.5,  0.0) );
	float4 sampleHorizPos0   = sampleOffseted(Texture0, texCoord.xy, float2( 1.5,  0.0) ); 
	float4 sampleVertNeg0	= sampleOffseted(Texture0, texCoord.xy, float2( 0.0, -1.5) ); 
	float4 sampleVertPos0	= sampleOffseted(Texture0, texCoord.xy, float2( 0.0,  1.5) );

	float4 sumHoriz      	= sampleHorizNeg0 + sampleHorizPos0;
	float4 sumVert   		= sampleVertNeg0  + sampleVertPos0;

	float4 diffToCenterHoriz = abs( sumHoriz - (2.0 * sampleCenter) ) / 2.0;  
	float4 diffToCenterVert  = abs( sumHoriz - (2.0 * sampleCenter) ) / 2.0;

	float valueEdgeHoriz 	= avg( diffToCenterHoriz.xyz );
	float valueEdgeVert  	= avg( diffToCenterVert.xyz );
	
	float edgeDetectHoriz	= saturate( (3.0 * valueEdgeHoriz) - 0.1);
	float edgeDetectVert 	= saturate( (3.0 * valueEdgeVert)  - 0.1);

	float4 avgHoriz      	= ( sumHoriz + sampleCenter) / 3.0;
	float4 avgVert   		= ( sumVert  + sampleCenter) / 3.0;

	float valueHoriz 		= avg( avgHoriz.xyz );
	float valueVert      	= avg( avgVert.xyz );

	float blurAmountHoriz	= saturate( edgeDetectHoriz / valueHoriz );
	float blurAmountVert 	= saturate( edgeDetectVert  / valueVert );

	float4 aaResult      	= lerp( sampleCenter,  avgHoriz, blurAmountHoriz );
	aaResult         		= lerp( aaResult,  	avgVert,  blurAmountVert );
  
	// long edges
	float4 sampleVertNeg1	= sampleOffseted(Texture0, texCoord.xy, float2(0.0, -3.5) ); 
	float4 sampleVertNeg2	= sampleOffseted(Texture0, texCoord.xy, float2(0.0, -7.5) );
	float4 sampleVertPos1	= sampleOffseted(Texture0, texCoord.xy, float2(0.0,  3.5) ); 
	float4 sampleVertPos2	= sampleOffseted(Texture0, texCoord.xy, float2(0.0,  7.5) ); 

	float4 sampleHorizNeg1   = sampleOffseted(Texture0, texCoord.xy, float2(-3.5, 0.0) ); 
	float4 sampleHorizNeg2   = sampleOffseted(Texture0, texCoord.xy, float2(-7.5, 0.0) );
	float4 sampleHorizPos1   = sampleOffseted(Texture0, texCoord.xy, float2( 3.5, 0.0) ); 
	float4 sampleHorizPos2   = sampleOffseted(Texture0, texCoord.xy, float2( 7.5, 0.0) ); 

	float pass1EdgeAvgHoriz  = ( sampleHorizNeg2.a + sampleHorizNeg1.a + sampleCenter.a + sampleHorizPos1.a + sampleHorizPos2.a ) / 5.0;
	float pass1EdgeAvgVert   = ( sampleVertNeg2.a  + sampleVertNeg1.a  + sampleCenter.a + sampleVertPos1.a  + sampleVertPos2.a  ) / 5.0;
	pass1EdgeAvgHoriz    	= saturate( pass1EdgeAvgHoriz * 2.0f - 1.0f );
	pass1EdgeAvgVert 		= saturate( pass1EdgeAvgVert  * 2.0f - 1.0f );
	float longEdge   		= max( pass1EdgeAvgHoriz, pass1EdgeAvgVert);

	if ( longEdge > 0 )
	{
    	float4 avgHorizLong  = ( sampleHorizNeg2 + sampleHorizNeg1 + sampleCenter + sampleHorizPos1 + sampleHorizPos2 ) / 5.0;
    	float4 avgVertLong   = ( sampleVertNeg2  + sampleVertNeg1  + sampleCenter + sampleVertPos1  + sampleVertPos2  ) / 5.0;
    	float valueHorizLong   = avg(avgHorizLong.xyz);
    	float valueVertLong	= avg(avgVertLong.xyz);

    	float4 sampleLeft	= sampleOffseted(Texture0, texCoord.xy, float2(-1.0,  0.0) );
    	float4 sampleRight   = sampleOffseted(Texture0, texCoord.xy, float2( 1.0,  0.0) );
    	float4 sampleUp  	= sampleOffseted(Texture0, texCoord.xy, float2( 0.0, -1.0) );
    	float4 sampleDown	= sampleOffseted(Texture0, texCoord.xy, float2( 0.0,  1.0) );

    	float valueCenter	= avg(sampleCenter.xyz);
    	float valueLeft  	= avg(sampleLeft.xyz);
    	float valueRight 	= avg(sampleRight.xyz);
    	float valueTop   	= avg(sampleUp.xyz);
    	float valueBottom	= avg(sampleDown.xyz);

    	float4 diffToCenter  = valueCenter - float4(valueLeft, valueTop, valueRight, valueBottom);   	
    	float blurAmountLeft = saturate( 0.0 + ( valueVertLong  - valueLeft   ) / diffToCenter.x );
    	float blurAmountUp   = saturate( 0.0 + ( valueHorizLong - valueTop	) / diffToCenter.y );
    	float blurAmountRight= saturate( 1.0 + ( valueVertLong  - valueCenter ) / diffToCenter.z );
    	float blurAmountDown = saturate( 1.0 + ( valueHorizLong - valueCenter ) / diffToCenter.w );  	

    	float4 blurAmounts   = float4( blurAmountLeft, blurAmountRight, blurAmountUp, blurAmountDown );
    	blurAmounts      	= (blurAmounts == float4(0.0, 0.0, 0.0, 0.0)) ? float4(1.0, 1.0, 1.0, 1.0) : blurAmounts;

    	float4 longBlurHoriz = lerp( sampleLeft,  sampleCenter,  blurAmounts.x );
    	longBlurHoriz    	= lerp( sampleRight, longBlurHoriz, blurAmounts.y );
    	float4 longBlurVert  = lerp( sampleUp,	sampleCenter,  blurAmounts.z );
    	longBlurVert 		= lerp( sampleDown,  longBlurVert,  blurAmounts.w );

    	aaResult     		= lerp( aaResult,	longBlurHoriz, pass1EdgeAvgVert);
    	aaResult     		= lerp( aaResult,	longBlurVert,  pass1EdgeAvgHoriz);
   }

   return float4(aaResult.rgb, 1.0f);
}


Hope it helps.

#2 n00body   Members   

345
Like
0Likes
Like

Posted 30 January 2011 - 09:53 AM

Example images would be most appreciated. ;)

[Hardware:] Falcon Northwest Tiki, Windows 7, Nvidia Geforce GTX 970

[Websites:] Development Blog | LinkedIn
[Unity3D :] Alloy Physical Shader Framework


#3 vilgeits   Members   

100
Like
0Likes
Like

Posted 01 February 2011 - 04:12 AM

Thank you for the code.

Could you speak a little more about this? I mean advantages and disadvantages over MLAA and so.


Thanks in advance.

#4 Ashaman73   Members   

13715
Like
0Likes
Like

Posted 01 February 2011 - 04:35 AM

Thank you for the code.

Could you speak a little more about this? I mean advantages and disadvantages over MLAA and so.


Thanks in advance.

Here's an article about DLAA inTFU2 including some images and a comparision to MLAA. Thought some comparision shots of the presented shader would be nice.

Ashaman

 

Gnoblins: Website - Facebook - Twitter - Youtube - Steam Greenlit - IndieDB - Gamedev Log


#5 vilgeits   Members   

100
Like
0Likes
Like

Posted 01 February 2011 - 05:31 AM

Thanks for the link, it looks great but a bit blurry (more than the MLAA techs)

Note: How "firsPassEdgeDetect" output is used on "secondPassEdgeDetectAndBlur"?

#6 vilgeits   Members   

100
Like
0Likes
Like

Posted 01 February 2011 - 01:43 PM

Thanks for the link, it looks great but a bit blurry (more than the MLAA techs)

Note: How "firsPassEdgeDetect" output is used on "secondPassEdgeDetectAndBlur"?


I've notice that Second uses First output as input

#7 Styves   Members   

1769
Like
0Likes
Like

Posted 01 February 2011 - 04:48 PM

Thanks for the clarification and code snippets, appreciate it. It was really handy. :D

#8 Daniel P Blei   Members   

127
Like
1Likes
Like

Posted 06 February 2011 - 05:38 AM

Is DLAA provided, or programmed into the computer system?

#9 haxpor_2   Members   

124
Like
0Likes
Like

Posted 23 April 2012 - 05:58 AM

Thanks so much for DLAA code, and its explanation.
I have a look at http://www.gamedev.n...ls/page__st__20 before and applied to my engine, but no luck. It's still jaggy and bleeding.

I tried this DLAA, and the result is decent and I appreciate it.
I tested it with this set up: 1024 * 768, GTX 275

But just one point to mention, I wonder if there're some certain angles in which AA technique can't solve?
I have a long edge/line (runway) in far sight in which the camera is on not so tall tower. It's still jaggy.

Posted Image

Posted Image

Anyhow, another one.

Posted Image

Posted Image

My buffer is the same as resolution on to show which is 1024 * 768.
Any suggestions or how to solve the far sight jaggy?




Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.