SlideShare a Scribd company logo
1 of 12
Download to read offline
Temporal Anti-Aliasing 1
Temporal Anti-Aliasing
목차
1. Temporal Anti-Aliasing 이란
2. 구현방식
3. 할톤수열(Halton Sequence)
4. Jittering 적용
5. 혼합
6. Ghosting
7. 동적씬에서의아티팩트해결
8. 마치며
9. Reference
Temporal Anti-Aliasing 이란
Tmporal Anti-Aliasing(이하TAA)은공간축선안티에일리어싱(Spatial anti-aliasing)의일종으로과거프레임
의이미지를현재프레임의이미지에결합하여이미지의계단현상을제거하는기법입니다. TAA는다른AA기
법들과비교했을때적은비용을사용하여안티에일리어싱효과를얻을수있다는장점이있지만이전프레임
의이미지와결합하는과정에서흐릿한이미지를얻게되는경우가있습니다. ( 이를해결하기위해서추가로
Sharpen 필터를적용하는경우가있습니다. ) 여기서는간단한TAA의구현방식을살펴보도록하겠습니다.
구현방식
TAA는다음과같은순서로구현됩니다.
1. 매프레임에씬을그릴때마다스크린평면의각기다른방향으로위치를살짝이동하여씬을그립니다. (
Jittering 적용)
2. 이렇게렌더링된현재프레임의이미지와이전프레임들의이미지(= History buffer )를조합합니다. ( 혼
합)
3. 조합한이미지를Frame Buffer에복사합니다.
이후로각단계를좀더자세히살펴보도록하겠습니다.
할톤수열(Halton Sequence)
매프레임마다씬의위치를조금씩이동시키기위해TAA에서는할톤수열이라는것사용합니다. 할톤수열은
몬테카를로시뮬레이션등에서사용되는공간상의점을생성하는데사용되는수열로결정론적(= 같은입력에
항상같은출력값을가짐) 이며저불일치(low discrepancy)인수열입니다. 저불일치수열은기존숫자로부터
가능한멀리떨어져있는숫자를연속하여생성하기때문에군집화를방지합니다. 아래도표는할톤수열로생
성한2차원점과랜덤하게생성한2차원의점216개를서로비교한결과로저불일치수열의특징을보여줍니
다.
Temporal Anti-Aliasing 2
랜덤하게생성한2차원점은다음과같은코드를통해생성하였습니다.
std::random_device rd;
std::mt19937 mt( rd() );
std::uniform_real_distribution<float> ud( 0.f, 1.f );
std::ofstream random( "random.txt" );
for ( int i = 0; i < 216; ++i )
{
random << ud( mt ) << "t" << ud( mt ) << "n";
}
이제할톤수열을어떻게생성하는지살펴보겠습니다. 할톤수열은Radical inverse라는것에기초하여생성할
수있습니다. Radical inverse이무엇인지알아보기전에양의정수를특정기수(=기저, 밑, base)로나타내는
방법을살펴보겠습니다.
양의정수 는특정기수 를사용하여다음과같이나타낼수있습니다.
여기서 는 에서 사이의숫자입니다.
수식보다좀더알기쉬운예시를보자면2진수가있겠습니다. 양의정수13을2진수로표현하면( )
가됩니다. 이를위의수식으로표현하면
가됩니다. 이식에 인것을확인할수있습니다.
Radical inverse 함수 는기수 를통해나타낸양의정수 를소수점을기준으로반전시키는것으로[0,
1) 범위의분수로변환합니다.
즉양의정수13을기수2를통해Radical inverse를적용하면다음과같습니다.
a b
a = d (a)b
i=1
∑
m
i
i−1
d (a)
i 0 b − 1
b = 2
11012
a = 1 ∗ 2 +
0
0 ∗ 2 +
1
1 ∗ 2 +
2
1 ∗ 23
d (a) =
0 1,d (a) =
1 0,d (a) =
2 1,d (a) =
3 1
ϕb b a
ϕ (a) =
b 0.d (a)d (a)...d (a)
1 2 m
Temporal Anti-Aliasing 3
이를이용해 차원의할톤수열을만들려면각차원마다서로다른기수 를사용하면됩니다. 여기서 는반드
시서로소여야하므로소수를사용하게됩니다.
TAA에서는스크린평면상에서물체를이동시킬것이므로2차원할톤수열을통해2차원의점을생성하면됩
니다. 즉 인쌍을생성합니다.
여기서 는좀더효율적으로계산할수있는데컴퓨터에서정수를이미2진수로표현하고있기때문에비
트를뒤집어주기만하면됩니다.
uint32 ReverseBits( uint32 n )
{
n = ( n << 16 ) | ( n >> 16 );
n = ( ( n & 0x00ff00ff ) << 8 ) | ( ( n & 0xff00ff00 ) >> 8 );
n = ( ( n & 0x0f0f0f0f ) << 4 ) | ( ( n & 0xf0f0f0f0 ) >> 4 );
n = ( ( n & 0x33333333 ) << 2 ) | ( ( n & 0xcccccccc ) >> 2 );
n = ( ( n & 0x55555555 ) << 1 ) | ( ( n & 0xaaaaaaaa ) >> 1 );
return n;
}
uint64 ReverseBits( uint64 n )
{
uint64 hi = ReverseBits( static_cast<uint32>( n ) );
uint64 lo = ReverseBits( static_cast<uint32>( n >> 32 ) );
return ( hi << 32 ) | lo;
}
float Halton::RadicalInverse( uint32 baseIndex, uint64 a ) const
{
switch ( baseIndex )
{
case 0:
return static_cast<float>( ReverseBits( a ) * 0x1p-64 );
case 1:
return ::RadicalInverse<3>( a );
default:
assert( false );
break;
}
return 0.5f;
}
부터는이방법을사용할수없기때문에정수를기수 로나눠가면서직접생성해줍니다.
template <uint64 base>
float RadicalInverse( uint64 a )
{
constexpr float invBase = 1.f / base;
uint64 reversedDigits = 0;
float invBaseN = 1;
while ( a )
{
uint64 next = a / base;
uint64 digit = a % base;
reversedDigits = reversedDigits * base + digit;
0.1011 =
2
16
11
10
n b b
x =
a (ϕ (a),ϕ (a),ϕ (a),...ϕ (a))
2 3 5 pn
p = (ϕ (a),ϕ (a))
2 3
ϕ (a)
2
ϕ (a)
3 b
Temporal Anti-Aliasing 4
invBaseN *= invBase;
a = next;
}
return std::min( reversedDigits * invBaseN, (float)0x1.fffffep-1 );
}
해당코드를통해생성한점은다음과같습니다.
0.5 0.333333
0.25 0.666667
0.75 0.111111
0.125 0.444444
0.625 0.777778
0.375 0.222222
0.875 0.555556
0.0625 0.888889
0.5625 0.037037
0.3125 0.37037
0.8125 0.703704
0.1875 0.148148
0.6875 0.481482
0.4375 0.814815
0.9375 0.259259
.
.
.
Jittering 적용
생성한2차원할톤수열을이용해매프레임마다지터링을적용하여씬을그리도록합니다. 할톤수열은다음
과같이앞에서16개를골라상수로사용하도록하였습니다.
static const int MAX_HALTON_SEQUENCE = 16;
static const float2 HALTON_SEQUENCE[MAX_HALTON_SEQUENCE] = {
float2( 0.5, 0.333333 ),
float2( 0.25, 0.666667 ),
float2( 0.75, 0.111111 ),
float2( 0.125, 0.444444 ),
float2( 0.625, 0.777778 ),
float2( 0.375, 0.222222 ),
float2( 0.875, 0.555556 ) ,
float2( 0.0625, 0.888889 ),
float2( 0.5625, 0.037037 ),
float2( 0.3125, 0.37037 ),
float2( 0.8125, 0.703704 ),
float2( 0.1875, 0.148148 ),
float2( 0.6875, 0.481482 ),
float2( 0.4375, 0.814815 ),
float2( 0.9375, 0.259259 ),
float2( 0.03125, 0.592593 )
};
지터링은투영변환까지적용한위치에아래와같이적용합니다. 할톤수열은[0, 1)의구간을가지므로[-1, 1)
의구간으로변경한다음픽셀하나의크기가될수있도록프레임버퍼의크기로나눠줍니다.
Temporal Anti-Aliasing 5
float4 ApplyTAAJittering( float4 clipSpace )
{
#if TAA == 1
int idx = FrameCount % MAX_HALTON_SEQUENCE;
// [0, 1) -> [-1, 1) -> 픽셀 하나 크기의 uv 좌표로 변경
float2 jitter = HALTON_SEQUENCE[idx];
jitter.x = ( jitter.x - 0.5f ) / ViewportDimensions.x * 2.f;
jitter.y = ( jitter.y - 0.5f ) / ViewportDimensions.y * 2.f;
clipSpace.xy += jitter * clipSpace.w; // Pixel Shader로 전달시 w로 나뉘므로 곱해준다.
#endif
return clipSpace;
}
혼합
이제지터링이적용된이미지를과거프레임의이미지와섞어주면됩니다. A Survey of Temporal
Antialiasing Techniques(behindthepixels.io/assets/files/TemporalAA.pdf) 에따르면TAA의혼합은다음과
같은단순한선형보간식에의해서이뤄집니다.
는 프레임의픽셀 에대한색상출력이며 는블렌딩가중치. 는 프레임에새롭게계산된색
상, 는지금까지혼합된이전프레임의색상입니다.
가중치수치 는과거색상과현재색상간의균형을맞추는데대부분의TTA 구현은고정된 를사용하며대체
로0.1이사용된다고합니다. 따라서다음과같이간단하게혼합할수있습니다.
float4 main( PS_INPUT input ) : SV_Target0
{
float3 historyColor = HistoryTex.Sample( HistoryTexSampler, input.uv ).rgb;
float4 sceneColor = SceneTex.Sample( SceneTexSampler, input.uv );
// sceneColor.rgb * ( 1 - 0.9 ) + historyColor * 0.9
// sceneColor.rgb * 1.0 + historyColor * 0.9
float3 resolveColor = lerp( sceneColor.rgb, historyColor, 0.9 );
return float4( resolveColor, sceneColor.a );
}
f (p) =
n a ∗ s (p) +
n (1 − a) ∗ f (π(p))
n−1
f (p)
n n p a s (p)
n n
f (π(p))
n−1
a a
Temporal Anti-Aliasing 6
TAA On TAA Off
적용전과비교했을때에일리어싱현상이개선된것을확인할수있습니다. 그런데이상태에서카메라를움직
여보면문제가발생합니다.
Temporal Anti-Aliasing 7
Ghosting
Temporal Anti-Aliasing 8
고스팅현상은이전프레임의이미지를섞음으로인해서잔상과같은효과가생기는아티팩트를의미합니다.
이전프레임의이미지가유령처럼남아있다는의미로이렇게불립니다. 지금까지의방법은정적인씬에서는
잘동작하지만카메라나물체의위치변환이있는동적인씬에서는이전프레임의색상위치가변경되었는데
이를적절하게처리하지못하기때문에고스팅현상을방지할수없습니다. 고스팅현상을처리하는방식은다
양한데여기서는이를해결하기위한2가지방식을보겠습니다.
동적씬에서아티팩트해결
Velocity Buffer
첫번째는Velocity Buffer를도입하는것입니다. Velocity Buffer는현재프레임과이전프레임의픽셀간위치
차이를저장하고있는버퍼로이를이용하여현재프레임의픽셀에대한알맞는과거프레임의픽셀을샘플링
할수있도록텍스쳐uv를조정합니다.
Velocity Buffer를구성해보겠습니다. 준비해야할것은이전프레임의월드, 카메라, 투영변환행렬입니다. 정
점셰이더에는해당행렬을가지고이전프레임의위치와현재프레임의위치를계산하여픽셀셰이더로전달
합니다.
VS_OUTPUT main( VS_INPUT input )
{
Temporal Anti-Aliasing 9
VS_OUTPUT output = (VS_OUTPUT)0;
PrimitiveSceneData primitiveData = GetPrimitiveData( input.primitiveId );
output.curFramePosition = mul( float4( input.position, 1.0f ), primitiveData.m_worldMatrix );
output.curFramePosition = mul( float4( output.curFramePosition.xyz, 1.0f ), ViewMatrix );
output.curFramePosition = mul( float4( output.curFramePosition.xyz, 1.0f ), ProjectionMatrix );
output.worldNormal = mul( float4( input.normal, 0.f ), transpose( primitiveData.m_invWorldMatrix ) ).xyz;
output.prevFramePosition = mul( float4( input.position, 1.0f ), primitiveData.m_prevWorldMatrix );
output.prevFramePosition = mul( float4( output.prevFramePosition.xyz, 1.0f ), PrevViewMatrix );
output.prevFramePosition = mul( float4( output.prevFramePosition.xyz, 1.0f ), PrevProjectionMatrix );
output.position = ApplyTAAJittering( output.curFramePosition );
return output;
}
픽셀셰이더는전달받은위치를스크린의uv좌표로변경하여저장합니다.
float2 CalcVelocity( float4 curFramePosition, float4 prevFramePosition )
{
float2 curFrameUV = curFramePosition.xy / curFramePosition.w;
curFrameUV = curFrameUV * 0.5f + 0.5f;
curFrameUV.y = 1.f - curFrameUV.y;
float2 prevFrameUV = prevFramePosition.xy / prevFramePosition.w;
prevFrameUV = prevFrameUV * 0.5f + 0.5f;
prevFrameUV.y = 1.f - prevFrameUV.y;
return curFrameUV - prevFrameUV;
}
Output main( PS_INPUT input )
{
Output output = (Output)0;
output.depth = input.position.w / FarPlaneDist;
float3 enc = SignedOctEncode( normalize( input.worldNormal ) );
output.packedNormal = float4( 0.f, enc );
output.velocity = CalcVelocity( input.curFramePosition, input.prevFramePosition );
return output;
}
이제TAA 셰이더는Velocity Buffer에저장된uv값을사용하여현재프레임의픽셀에알맞는이전프레임의픽
셀을샘플링합니다.
float4 main( PS_INPUT input ) : SV_Target0
{
float2 velocity = VelocityTex.Sample( VelocityTexSampler, input.uv );
float2 previousUV = input.uv - velocity;
float3 historyColor = HistoryTex.Sample( HistoryTexSampler, previousUV ).rgb;
float4 sceneColor = SceneTex.Sample( SceneTexSampler, input.uv );
float3 resolveColor = lerp( sceneColor.rgb, historyColor, BlendWeight );
return float4( resolveColor, sceneColor.a );
}
Velocity Buffer를적용한결과다음과같은결과를얻을수있습니다.
Temporal Anti-Aliasing 10
붉은네모부분을보면고스팅현상이사라진것을확인할수있습니다. 하지만여전히잔상이발생하는부분
이있습니다.
색상Clamp
두번째는색상Clamp입니다. 만약이전프레임의픽셀색상이현재프레임의픽셀색상과유사하다면잔상현
상이발생할까요? 파란색에( R : 0, G : 0, B : 255 ) 약간흐린파란색( R : 0, G : 0, B : 240 )을섞는다고해
도그리티가나지않을거라예상할수있습니다. 색상Clamp는현재프레임의색상을기준으로이전프레임의
색상을조정하는방법입니다.
여기서는색상Clamp을위해현재프레임의상하좌우로이웃하는4픽셀을추가로샘플링하여색상의최소최
대범위를계산합니다.
float3 left = SceneTex.Sample( SceneTexSampler, input.uv, int2( -1, 0 ) ).rgb;
float3 right = SceneTex.Sample( SceneTexSampler, input.uv, int2( 1, 0 ) ).rgb;
float3 top = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, -1 ) ).rgb;
float3 bottom = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, 1 ) ).rgb;
float3 lower = min( sceneColor, min( min( left, right ), min( top, bottom ) ) );
float3 upper = max( sceneColor, max( max( left, right ), max( top, bottom ) ) );
그리고이lower, upper 색상범위로이전프레임의색상을조정합니다.
historyColor = clamp( historyColor, lower, upper );
Temporal Anti-Aliasing 11
색상Clamp를적용한TAA 셰이더의전체모습은다음과같습니다.
float4 main( PS_INPUT input ) : SV_Target0
{
float2 velocity = VelocityTex.Sample( VelocityTexSampler, input.uv );
float2 previousUV = input.uv - velocity;
float3 historyColor = HistoryTex.Sample( HistoryTexSampler, previousUV ).rgb;
float4 sceneColor = SceneTex.Sample( SceneTexSampler, input.uv );
float3 left = SceneTex.Sample( SceneTexSampler, input.uv, int2( -1, 0 ) ).rgb;
float3 right = SceneTex.Sample( SceneTexSampler, input.uv, int2( 1, 0 ) ).rgb;
float3 top = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, -1 ) ).rgb;
float3 bottom = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, 1 ) ).rgb;
float3 lower = min( sceneColor, min( min( left, right ), min( top, bottom ) ) );
float3 upper = max( sceneColor, max( max( left, right ), max( top, bottom ) ) );
historyColor = clamp( historyColor, lower, upper );
float3 resolveColor = lerp( sceneColor.rgb, historyColor, BlendWeight );
return float4( resolveColor, sceneColor.a );
}
이를적용하면다음과같이고스팅현상을개선할수있습니다.
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4fbdd80c-15a1-4dea-9bff-2016
42823616/2022-10-12_23_12_55.mp4
올바르지않은과거프레임의픽셀을조정하는방식은이외에도다양한데게임‘인사이드’의GDC 자료를보면
3x3 범위의이웃픽셀에대해서과거프레임의픽셀을clipping하는방법을사용한것을볼수있습니다.
마치며…
준비한내용은여기까지입니다. 이내용은훌륭한TAA 튜토리얼글인
https://sugulee.wordpress.com/2021/06/21/temporal-anti-aliasingtaa-tutorial/ 를참고하여Direct3D11
을사용한개인프로젝트의코드를기반으로작성되었습니다.
전체코드는아래의변경점에서
https://github.com/xtozero/SSR/commit/8f732f29d23063c914e0285120abaed024f9bba3
Source/RenderCore/Private/Renderer/TemporalAntiAliasingRendering.cpp
Source/Shaders/Private/TemporalAntiAliasing/PS_TAAResolve.fx
Source/Shaders/Private/VS_DepthWrite.fx
Source/Shaders/Private/PS_DepthWrite.fx
등의파일을참고하시면됩니다.
Temporal Anti-Aliasing 12
Reference
behindthepixels.io/assets/files/TemporalAA.pdf
https://sugulee.wordpress.com/2021/06/21/temporal-anti-aliasingtaa-tutorial/
https://en.wikipedia.org/wiki/Temporal_anti-aliasing
https://pbr-book.org/3ed-2018/Sampling_and_Reconstruction/The_Halton_Sampler
https://ziyadbarakat.wordpress.com/2020/07/28/temporal-anti-aliasing-step-by-step/
http://s3.amazonaws.com/arena-attachments/655504/c5c71c5507f0f8bf344252958254fb7d.pdf?
1468341463

More Related Content

Similar to Temporal Anti-Aliasing

Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerJAX London
 
fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920
fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920
fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920Karl Rudeen
 
Time Series Analysis with R
Time Series Analysis with RTime Series Analysis with R
Time Series Analysis with RARCHIT GUPTA
 
Fourier series example
Fourier series exampleFourier series example
Fourier series exampleAbi finni
 
Optimization Of Fuzzy Bexa Using Nm
Optimization Of Fuzzy Bexa Using NmOptimization Of Fuzzy Bexa Using Nm
Optimization Of Fuzzy Bexa Using NmAshish Khetan
 
Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance PuzzlersDoug Hawkins
 
New SPL Features in PHP 5.3 (TEK-X)
New SPL Features in PHP 5.3 (TEK-X)New SPL Features in PHP 5.3 (TEK-X)
New SPL Features in PHP 5.3 (TEK-X)Matthew Turland
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrencyAlex Navis
 
Unit 2-data types,Variables,Operators,Conitionals,loops and arrays
Unit 2-data types,Variables,Operators,Conitionals,loops and arraysUnit 2-data types,Variables,Operators,Conitionals,loops and arrays
Unit 2-data types,Variables,Operators,Conitionals,loops and arraysDevaKumari Vijay
 
public void turnRight(double degrees) {rotationInDegrees + - = deg.pdf
public void turnRight(double degrees) {rotationInDegrees + - = deg.pdfpublic void turnRight(double degrees) {rotationInDegrees + - = deg.pdf
public void turnRight(double degrees) {rotationInDegrees + - = deg.pdfisenbergwarne4100
 
MuVM: Higher Order Mutation Analysis Virtual Machine for C
MuVM: Higher Order Mutation Analysis Virtual Machine for CMuVM: Higher Order Mutation Analysis Virtual Machine for C
MuVM: Higher Order Mutation Analysis Virtual Machine for CSusumu Tokumoto
 
Planet of the AOPs
Planet of the AOPsPlanet of the AOPs
Planet of the AOPsJames Ward
 
Doppler Processing Project
Doppler Processing ProjectDoppler Processing Project
Doppler Processing ProjectAssignmentpedia
 

Similar to Temporal Anti-Aliasing (20)

Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael Barker
 
fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920
fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920
fb69b412-97cb-4e8d-8a28-574c09557d35-160618025920
 
Project Paper
Project PaperProject Paper
Project Paper
 
Time Series Analysis with R
Time Series Analysis with RTime Series Analysis with R
Time Series Analysis with R
 
solver (1)
solver (1)solver (1)
solver (1)
 
Fourier series example
Fourier series exampleFourier series example
Fourier series example
 
Implimenting_HJM
Implimenting_HJMImplimenting_HJM
Implimenting_HJM
 
Radio ad blocker
Radio ad blockerRadio ad blocker
Radio ad blocker
 
Optimization Of Fuzzy Bexa Using Nm
Optimization Of Fuzzy Bexa Using NmOptimization Of Fuzzy Bexa Using Nm
Optimization Of Fuzzy Bexa Using Nm
 
Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance Puzzlers
 
New SPL Features in PHP 5.3 (TEK-X)
New SPL Features in PHP 5.3 (TEK-X)New SPL Features in PHP 5.3 (TEK-X)
New SPL Features in PHP 5.3 (TEK-X)
 
ch08.ppt
ch08.pptch08.ppt
ch08.ppt
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
 
Unit 2-data types,Variables,Operators,Conitionals,loops and arrays
Unit 2-data types,Variables,Operators,Conitionals,loops and arraysUnit 2-data types,Variables,Operators,Conitionals,loops and arrays
Unit 2-data types,Variables,Operators,Conitionals,loops and arrays
 
Unit 8
Unit 8Unit 8
Unit 8
 
10.1.1.2.9988
10.1.1.2.998810.1.1.2.9988
10.1.1.2.9988
 
public void turnRight(double degrees) {rotationInDegrees + - = deg.pdf
public void turnRight(double degrees) {rotationInDegrees + - = deg.pdfpublic void turnRight(double degrees) {rotationInDegrees + - = deg.pdf
public void turnRight(double degrees) {rotationInDegrees + - = deg.pdf
 
MuVM: Higher Order Mutation Analysis Virtual Machine for C
MuVM: Higher Order Mutation Analysis Virtual Machine for CMuVM: Higher Order Mutation Analysis Virtual Machine for C
MuVM: Higher Order Mutation Analysis Virtual Machine for C
 
Planet of the AOPs
Planet of the AOPsPlanet of the AOPs
Planet of the AOPs
 
Doppler Processing Project
Doppler Processing ProjectDoppler Processing Project
Doppler Processing Project
 

More from Bongseok Cho

Light Propagation Volume.pdf
Light Propagation Volume.pdfLight Propagation Volume.pdf
Light Propagation Volume.pdfBongseok Cho
 
Spherical Harmonics.pdf
Spherical Harmonics.pdfSpherical Harmonics.pdf
Spherical Harmonics.pdfBongseok Cho
 
Reflective Shadow Maps
Reflective Shadow MapsReflective Shadow Maps
Reflective Shadow MapsBongseok Cho
 
C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현Bongseok Cho
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)Bongseok Cho
 
비동기 파일 로딩
비동기 파일 로딩비동기 파일 로딩
비동기 파일 로딩Bongseok Cho
 
Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Bongseok Cho
 
Screen space reflection
Screen space reflectionScreen space reflection
Screen space reflectionBongseok Cho
 
Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Bongseok Cho
 

More from Bongseok Cho (11)

Light Propagation Volume.pdf
Light Propagation Volume.pdfLight Propagation Volume.pdf
Light Propagation Volume.pdf
 
Spherical Harmonics.pdf
Spherical Harmonics.pdfSpherical Harmonics.pdf
Spherical Harmonics.pdf
 
Reflective Shadow Maps
Reflective Shadow MapsReflective Shadow Maps
Reflective Shadow Maps
 
Volumetric Fog
Volumetric FogVolumetric Fog
Volumetric Fog
 
C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
 
비동기 파일 로딩
비동기 파일 로딩비동기 파일 로딩
비동기 파일 로딩
 
Lock free queue
Lock free queueLock free queue
Lock free queue
 
Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)
 
Screen space reflection
Screen space reflectionScreen space reflection
Screen space reflection
 
Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)
 

Recently uploaded

Furniture showroom management system project.pdf
Furniture showroom management system project.pdfFurniture showroom management system project.pdf
Furniture showroom management system project.pdfKamal Acharya
 
KIT-601 Lecture Notes-UNIT-3.pdf Mining Data Stream
KIT-601 Lecture Notes-UNIT-3.pdf Mining Data StreamKIT-601 Lecture Notes-UNIT-3.pdf Mining Data Stream
KIT-601 Lecture Notes-UNIT-3.pdf Mining Data StreamDr. Radhey Shyam
 
internship exam ppt.pptx on embedded system and IOT
internship exam ppt.pptx on embedded system and IOTinternship exam ppt.pptx on embedded system and IOT
internship exam ppt.pptx on embedded system and IOTNavyashreeS6
 
Digital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdfDigital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdfAbrahamGadissa
 
Laundry management system project report.pdf
Laundry management system project report.pdfLaundry management system project report.pdf
Laundry management system project report.pdfKamal Acharya
 
RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5
RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5
RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5T.D. Shashikala
 
一比一原版(UofT毕业证)多伦多大学毕业证成绩单
一比一原版(UofT毕业证)多伦多大学毕业证成绩单一比一原版(UofT毕业证)多伦多大学毕业证成绩单
一比一原版(UofT毕业证)多伦多大学毕业证成绩单tuuww
 
KIT-601 Lecture Notes-UNIT-5.pdf Frame Works and Visualization
KIT-601 Lecture Notes-UNIT-5.pdf Frame Works and VisualizationKIT-601 Lecture Notes-UNIT-5.pdf Frame Works and Visualization
KIT-601 Lecture Notes-UNIT-5.pdf Frame Works and VisualizationDr. Radhey Shyam
 
An improvement in the safety of big data using blockchain technology
An improvement in the safety of big data using blockchain technologyAn improvement in the safety of big data using blockchain technology
An improvement in the safety of big data using blockchain technologyBOHRInternationalJou1
 
Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.PrashantGoswami42
 
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdfONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdfKamal Acharya
 
RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4
RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4
RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4T.D. Shashikala
 
"United Nations Park" Site Visit Report.
"United Nations Park" Site  Visit Report."United Nations Park" Site  Visit Report.
"United Nations Park" Site Visit Report.MdManikurRahman
 
Dairy management system project report..pdf
Dairy management system project report..pdfDairy management system project report..pdf
Dairy management system project report..pdfKamal Acharya
 
Top 13 Famous Civil Engineering Scientist
Top 13 Famous Civil Engineering ScientistTop 13 Famous Civil Engineering Scientist
Top 13 Famous Civil Engineering Scientistgettygaming1
 
Paint shop management system project report.pdf
Paint shop management system project report.pdfPaint shop management system project report.pdf
Paint shop management system project report.pdfKamal Acharya
 
The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...
The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...
The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...Roi Lipman
 
BRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWING
BRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWINGBRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWING
BRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWINGKOUSTAV SARKAR
 
Teachers record management system project report..pdf
Teachers record management system project report..pdfTeachers record management system project report..pdf
Teachers record management system project report..pdfKamal Acharya
 
Supermarket billing system project report..pdf
Supermarket billing system project report..pdfSupermarket billing system project report..pdf
Supermarket billing system project report..pdfKamal Acharya
 

Recently uploaded (20)

Furniture showroom management system project.pdf
Furniture showroom management system project.pdfFurniture showroom management system project.pdf
Furniture showroom management system project.pdf
 
KIT-601 Lecture Notes-UNIT-3.pdf Mining Data Stream
KIT-601 Lecture Notes-UNIT-3.pdf Mining Data StreamKIT-601 Lecture Notes-UNIT-3.pdf Mining Data Stream
KIT-601 Lecture Notes-UNIT-3.pdf Mining Data Stream
 
internship exam ppt.pptx on embedded system and IOT
internship exam ppt.pptx on embedded system and IOTinternship exam ppt.pptx on embedded system and IOT
internship exam ppt.pptx on embedded system and IOT
 
Digital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdfDigital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdf
 
Laundry management system project report.pdf
Laundry management system project report.pdfLaundry management system project report.pdf
Laundry management system project report.pdf
 
RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5
RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5
RM&IPR M5 notes.pdfResearch Methodolgy & Intellectual Property Rights Series 5
 
一比一原版(UofT毕业证)多伦多大学毕业证成绩单
一比一原版(UofT毕业证)多伦多大学毕业证成绩单一比一原版(UofT毕业证)多伦多大学毕业证成绩单
一比一原版(UofT毕业证)多伦多大学毕业证成绩单
 
KIT-601 Lecture Notes-UNIT-5.pdf Frame Works and Visualization
KIT-601 Lecture Notes-UNIT-5.pdf Frame Works and VisualizationKIT-601 Lecture Notes-UNIT-5.pdf Frame Works and Visualization
KIT-601 Lecture Notes-UNIT-5.pdf Frame Works and Visualization
 
An improvement in the safety of big data using blockchain technology
An improvement in the safety of big data using blockchain technologyAn improvement in the safety of big data using blockchain technology
An improvement in the safety of big data using blockchain technology
 
Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.
 
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdfONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
 
RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4
RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4
RM&IPR M4.pdfResearch Methodolgy & Intellectual Property Rights Series 4
 
"United Nations Park" Site Visit Report.
"United Nations Park" Site  Visit Report."United Nations Park" Site  Visit Report.
"United Nations Park" Site Visit Report.
 
Dairy management system project report..pdf
Dairy management system project report..pdfDairy management system project report..pdf
Dairy management system project report..pdf
 
Top 13 Famous Civil Engineering Scientist
Top 13 Famous Civil Engineering ScientistTop 13 Famous Civil Engineering Scientist
Top 13 Famous Civil Engineering Scientist
 
Paint shop management system project report.pdf
Paint shop management system project report.pdfPaint shop management system project report.pdf
Paint shop management system project report.pdf
 
The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...
The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...
The battle for RAG, explore the pros and cons of using KnowledgeGraphs and Ve...
 
BRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWING
BRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWINGBRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWING
BRAKING SYSTEM IN INDIAN RAILWAY AutoCAD DRAWING
 
Teachers record management system project report..pdf
Teachers record management system project report..pdfTeachers record management system project report..pdf
Teachers record management system project report..pdf
 
Supermarket billing system project report..pdf
Supermarket billing system project report..pdfSupermarket billing system project report..pdf
Supermarket billing system project report..pdf
 

Temporal Anti-Aliasing

  • 1. Temporal Anti-Aliasing 1 Temporal Anti-Aliasing 목차 1. Temporal Anti-Aliasing 이란 2. 구현방식 3. 할톤수열(Halton Sequence) 4. Jittering 적용 5. 혼합 6. Ghosting 7. 동적씬에서의아티팩트해결 8. 마치며 9. Reference Temporal Anti-Aliasing 이란 Tmporal Anti-Aliasing(이하TAA)은공간축선안티에일리어싱(Spatial anti-aliasing)의일종으로과거프레임 의이미지를현재프레임의이미지에결합하여이미지의계단현상을제거하는기법입니다. TAA는다른AA기 법들과비교했을때적은비용을사용하여안티에일리어싱효과를얻을수있다는장점이있지만이전프레임 의이미지와결합하는과정에서흐릿한이미지를얻게되는경우가있습니다. ( 이를해결하기위해서추가로 Sharpen 필터를적용하는경우가있습니다. ) 여기서는간단한TAA의구현방식을살펴보도록하겠습니다. 구현방식 TAA는다음과같은순서로구현됩니다. 1. 매프레임에씬을그릴때마다스크린평면의각기다른방향으로위치를살짝이동하여씬을그립니다. ( Jittering 적용) 2. 이렇게렌더링된현재프레임의이미지와이전프레임들의이미지(= History buffer )를조합합니다. ( 혼 합) 3. 조합한이미지를Frame Buffer에복사합니다. 이후로각단계를좀더자세히살펴보도록하겠습니다. 할톤수열(Halton Sequence) 매프레임마다씬의위치를조금씩이동시키기위해TAA에서는할톤수열이라는것사용합니다. 할톤수열은 몬테카를로시뮬레이션등에서사용되는공간상의점을생성하는데사용되는수열로결정론적(= 같은입력에 항상같은출력값을가짐) 이며저불일치(low discrepancy)인수열입니다. 저불일치수열은기존숫자로부터 가능한멀리떨어져있는숫자를연속하여생성하기때문에군집화를방지합니다. 아래도표는할톤수열로생 성한2차원점과랜덤하게생성한2차원의점216개를서로비교한결과로저불일치수열의특징을보여줍니 다.
  • 2. Temporal Anti-Aliasing 2 랜덤하게생성한2차원점은다음과같은코드를통해생성하였습니다. std::random_device rd; std::mt19937 mt( rd() ); std::uniform_real_distribution<float> ud( 0.f, 1.f ); std::ofstream random( "random.txt" ); for ( int i = 0; i < 216; ++i ) { random << ud( mt ) << "t" << ud( mt ) << "n"; } 이제할톤수열을어떻게생성하는지살펴보겠습니다. 할톤수열은Radical inverse라는것에기초하여생성할 수있습니다. Radical inverse이무엇인지알아보기전에양의정수를특정기수(=기저, 밑, base)로나타내는 방법을살펴보겠습니다. 양의정수 는특정기수 를사용하여다음과같이나타낼수있습니다. 여기서 는 에서 사이의숫자입니다. 수식보다좀더알기쉬운예시를보자면2진수가있겠습니다. 양의정수13을2진수로표현하면( ) 가됩니다. 이를위의수식으로표현하면 가됩니다. 이식에 인것을확인할수있습니다. Radical inverse 함수 는기수 를통해나타낸양의정수 를소수점을기준으로반전시키는것으로[0, 1) 범위의분수로변환합니다. 즉양의정수13을기수2를통해Radical inverse를적용하면다음과같습니다. a b a = d (a)b i=1 ∑ m i i−1 d (a) i 0 b − 1 b = 2 11012 a = 1 ∗ 2 + 0 0 ∗ 2 + 1 1 ∗ 2 + 2 1 ∗ 23 d (a) = 0 1,d (a) = 1 0,d (a) = 2 1,d (a) = 3 1 ϕb b a ϕ (a) = b 0.d (a)d (a)...d (a) 1 2 m
  • 3. Temporal Anti-Aliasing 3 이를이용해 차원의할톤수열을만들려면각차원마다서로다른기수 를사용하면됩니다. 여기서 는반드 시서로소여야하므로소수를사용하게됩니다. TAA에서는스크린평면상에서물체를이동시킬것이므로2차원할톤수열을통해2차원의점을생성하면됩 니다. 즉 인쌍을생성합니다. 여기서 는좀더효율적으로계산할수있는데컴퓨터에서정수를이미2진수로표현하고있기때문에비 트를뒤집어주기만하면됩니다. uint32 ReverseBits( uint32 n ) { n = ( n << 16 ) | ( n >> 16 ); n = ( ( n & 0x00ff00ff ) << 8 ) | ( ( n & 0xff00ff00 ) >> 8 ); n = ( ( n & 0x0f0f0f0f ) << 4 ) | ( ( n & 0xf0f0f0f0 ) >> 4 ); n = ( ( n & 0x33333333 ) << 2 ) | ( ( n & 0xcccccccc ) >> 2 ); n = ( ( n & 0x55555555 ) << 1 ) | ( ( n & 0xaaaaaaaa ) >> 1 ); return n; } uint64 ReverseBits( uint64 n ) { uint64 hi = ReverseBits( static_cast<uint32>( n ) ); uint64 lo = ReverseBits( static_cast<uint32>( n >> 32 ) ); return ( hi << 32 ) | lo; } float Halton::RadicalInverse( uint32 baseIndex, uint64 a ) const { switch ( baseIndex ) { case 0: return static_cast<float>( ReverseBits( a ) * 0x1p-64 ); case 1: return ::RadicalInverse<3>( a ); default: assert( false ); break; } return 0.5f; } 부터는이방법을사용할수없기때문에정수를기수 로나눠가면서직접생성해줍니다. template <uint64 base> float RadicalInverse( uint64 a ) { constexpr float invBase = 1.f / base; uint64 reversedDigits = 0; float invBaseN = 1; while ( a ) { uint64 next = a / base; uint64 digit = a % base; reversedDigits = reversedDigits * base + digit; 0.1011 = 2 16 11 10 n b b x = a (ϕ (a),ϕ (a),ϕ (a),...ϕ (a)) 2 3 5 pn p = (ϕ (a),ϕ (a)) 2 3 ϕ (a) 2 ϕ (a) 3 b
  • 4. Temporal Anti-Aliasing 4 invBaseN *= invBase; a = next; } return std::min( reversedDigits * invBaseN, (float)0x1.fffffep-1 ); } 해당코드를통해생성한점은다음과같습니다. 0.5 0.333333 0.25 0.666667 0.75 0.111111 0.125 0.444444 0.625 0.777778 0.375 0.222222 0.875 0.555556 0.0625 0.888889 0.5625 0.037037 0.3125 0.37037 0.8125 0.703704 0.1875 0.148148 0.6875 0.481482 0.4375 0.814815 0.9375 0.259259 . . . Jittering 적용 생성한2차원할톤수열을이용해매프레임마다지터링을적용하여씬을그리도록합니다. 할톤수열은다음 과같이앞에서16개를골라상수로사용하도록하였습니다. static const int MAX_HALTON_SEQUENCE = 16; static const float2 HALTON_SEQUENCE[MAX_HALTON_SEQUENCE] = { float2( 0.5, 0.333333 ), float2( 0.25, 0.666667 ), float2( 0.75, 0.111111 ), float2( 0.125, 0.444444 ), float2( 0.625, 0.777778 ), float2( 0.375, 0.222222 ), float2( 0.875, 0.555556 ) , float2( 0.0625, 0.888889 ), float2( 0.5625, 0.037037 ), float2( 0.3125, 0.37037 ), float2( 0.8125, 0.703704 ), float2( 0.1875, 0.148148 ), float2( 0.6875, 0.481482 ), float2( 0.4375, 0.814815 ), float2( 0.9375, 0.259259 ), float2( 0.03125, 0.592593 ) }; 지터링은투영변환까지적용한위치에아래와같이적용합니다. 할톤수열은[0, 1)의구간을가지므로[-1, 1) 의구간으로변경한다음픽셀하나의크기가될수있도록프레임버퍼의크기로나눠줍니다.
  • 5. Temporal Anti-Aliasing 5 float4 ApplyTAAJittering( float4 clipSpace ) { #if TAA == 1 int idx = FrameCount % MAX_HALTON_SEQUENCE; // [0, 1) -> [-1, 1) -> 픽셀 하나 크기의 uv 좌표로 변경 float2 jitter = HALTON_SEQUENCE[idx]; jitter.x = ( jitter.x - 0.5f ) / ViewportDimensions.x * 2.f; jitter.y = ( jitter.y - 0.5f ) / ViewportDimensions.y * 2.f; clipSpace.xy += jitter * clipSpace.w; // Pixel Shader로 전달시 w로 나뉘므로 곱해준다. #endif return clipSpace; } 혼합 이제지터링이적용된이미지를과거프레임의이미지와섞어주면됩니다. A Survey of Temporal Antialiasing Techniques(behindthepixels.io/assets/files/TemporalAA.pdf) 에따르면TAA의혼합은다음과 같은단순한선형보간식에의해서이뤄집니다. 는 프레임의픽셀 에대한색상출력이며 는블렌딩가중치. 는 프레임에새롭게계산된색 상, 는지금까지혼합된이전프레임의색상입니다. 가중치수치 는과거색상과현재색상간의균형을맞추는데대부분의TTA 구현은고정된 를사용하며대체 로0.1이사용된다고합니다. 따라서다음과같이간단하게혼합할수있습니다. float4 main( PS_INPUT input ) : SV_Target0 { float3 historyColor = HistoryTex.Sample( HistoryTexSampler, input.uv ).rgb; float4 sceneColor = SceneTex.Sample( SceneTexSampler, input.uv ); // sceneColor.rgb * ( 1 - 0.9 ) + historyColor * 0.9 // sceneColor.rgb * 1.0 + historyColor * 0.9 float3 resolveColor = lerp( sceneColor.rgb, historyColor, 0.9 ); return float4( resolveColor, sceneColor.a ); } f (p) = n a ∗ s (p) + n (1 − a) ∗ f (π(p)) n−1 f (p) n n p a s (p) n n f (π(p)) n−1 a a
  • 6. Temporal Anti-Aliasing 6 TAA On TAA Off 적용전과비교했을때에일리어싱현상이개선된것을확인할수있습니다. 그런데이상태에서카메라를움직 여보면문제가발생합니다.
  • 8. Temporal Anti-Aliasing 8 고스팅현상은이전프레임의이미지를섞음으로인해서잔상과같은효과가생기는아티팩트를의미합니다. 이전프레임의이미지가유령처럼남아있다는의미로이렇게불립니다. 지금까지의방법은정적인씬에서는 잘동작하지만카메라나물체의위치변환이있는동적인씬에서는이전프레임의색상위치가변경되었는데 이를적절하게처리하지못하기때문에고스팅현상을방지할수없습니다. 고스팅현상을처리하는방식은다 양한데여기서는이를해결하기위한2가지방식을보겠습니다. 동적씬에서아티팩트해결 Velocity Buffer 첫번째는Velocity Buffer를도입하는것입니다. Velocity Buffer는현재프레임과이전프레임의픽셀간위치 차이를저장하고있는버퍼로이를이용하여현재프레임의픽셀에대한알맞는과거프레임의픽셀을샘플링 할수있도록텍스쳐uv를조정합니다. Velocity Buffer를구성해보겠습니다. 준비해야할것은이전프레임의월드, 카메라, 투영변환행렬입니다. 정 점셰이더에는해당행렬을가지고이전프레임의위치와현재프레임의위치를계산하여픽셀셰이더로전달 합니다. VS_OUTPUT main( VS_INPUT input ) {
  • 9. Temporal Anti-Aliasing 9 VS_OUTPUT output = (VS_OUTPUT)0; PrimitiveSceneData primitiveData = GetPrimitiveData( input.primitiveId ); output.curFramePosition = mul( float4( input.position, 1.0f ), primitiveData.m_worldMatrix ); output.curFramePosition = mul( float4( output.curFramePosition.xyz, 1.0f ), ViewMatrix ); output.curFramePosition = mul( float4( output.curFramePosition.xyz, 1.0f ), ProjectionMatrix ); output.worldNormal = mul( float4( input.normal, 0.f ), transpose( primitiveData.m_invWorldMatrix ) ).xyz; output.prevFramePosition = mul( float4( input.position, 1.0f ), primitiveData.m_prevWorldMatrix ); output.prevFramePosition = mul( float4( output.prevFramePosition.xyz, 1.0f ), PrevViewMatrix ); output.prevFramePosition = mul( float4( output.prevFramePosition.xyz, 1.0f ), PrevProjectionMatrix ); output.position = ApplyTAAJittering( output.curFramePosition ); return output; } 픽셀셰이더는전달받은위치를스크린의uv좌표로변경하여저장합니다. float2 CalcVelocity( float4 curFramePosition, float4 prevFramePosition ) { float2 curFrameUV = curFramePosition.xy / curFramePosition.w; curFrameUV = curFrameUV * 0.5f + 0.5f; curFrameUV.y = 1.f - curFrameUV.y; float2 prevFrameUV = prevFramePosition.xy / prevFramePosition.w; prevFrameUV = prevFrameUV * 0.5f + 0.5f; prevFrameUV.y = 1.f - prevFrameUV.y; return curFrameUV - prevFrameUV; } Output main( PS_INPUT input ) { Output output = (Output)0; output.depth = input.position.w / FarPlaneDist; float3 enc = SignedOctEncode( normalize( input.worldNormal ) ); output.packedNormal = float4( 0.f, enc ); output.velocity = CalcVelocity( input.curFramePosition, input.prevFramePosition ); return output; } 이제TAA 셰이더는Velocity Buffer에저장된uv값을사용하여현재프레임의픽셀에알맞는이전프레임의픽 셀을샘플링합니다. float4 main( PS_INPUT input ) : SV_Target0 { float2 velocity = VelocityTex.Sample( VelocityTexSampler, input.uv ); float2 previousUV = input.uv - velocity; float3 historyColor = HistoryTex.Sample( HistoryTexSampler, previousUV ).rgb; float4 sceneColor = SceneTex.Sample( SceneTexSampler, input.uv ); float3 resolveColor = lerp( sceneColor.rgb, historyColor, BlendWeight ); return float4( resolveColor, sceneColor.a ); } Velocity Buffer를적용한결과다음과같은결과를얻을수있습니다.
  • 10. Temporal Anti-Aliasing 10 붉은네모부분을보면고스팅현상이사라진것을확인할수있습니다. 하지만여전히잔상이발생하는부분 이있습니다. 색상Clamp 두번째는색상Clamp입니다. 만약이전프레임의픽셀색상이현재프레임의픽셀색상과유사하다면잔상현 상이발생할까요? 파란색에( R : 0, G : 0, B : 255 ) 약간흐린파란색( R : 0, G : 0, B : 240 )을섞는다고해 도그리티가나지않을거라예상할수있습니다. 색상Clamp는현재프레임의색상을기준으로이전프레임의 색상을조정하는방법입니다. 여기서는색상Clamp을위해현재프레임의상하좌우로이웃하는4픽셀을추가로샘플링하여색상의최소최 대범위를계산합니다. float3 left = SceneTex.Sample( SceneTexSampler, input.uv, int2( -1, 0 ) ).rgb; float3 right = SceneTex.Sample( SceneTexSampler, input.uv, int2( 1, 0 ) ).rgb; float3 top = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, -1 ) ).rgb; float3 bottom = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, 1 ) ).rgb; float3 lower = min( sceneColor, min( min( left, right ), min( top, bottom ) ) ); float3 upper = max( sceneColor, max( max( left, right ), max( top, bottom ) ) ); 그리고이lower, upper 색상범위로이전프레임의색상을조정합니다. historyColor = clamp( historyColor, lower, upper );
  • 11. Temporal Anti-Aliasing 11 색상Clamp를적용한TAA 셰이더의전체모습은다음과같습니다. float4 main( PS_INPUT input ) : SV_Target0 { float2 velocity = VelocityTex.Sample( VelocityTexSampler, input.uv ); float2 previousUV = input.uv - velocity; float3 historyColor = HistoryTex.Sample( HistoryTexSampler, previousUV ).rgb; float4 sceneColor = SceneTex.Sample( SceneTexSampler, input.uv ); float3 left = SceneTex.Sample( SceneTexSampler, input.uv, int2( -1, 0 ) ).rgb; float3 right = SceneTex.Sample( SceneTexSampler, input.uv, int2( 1, 0 ) ).rgb; float3 top = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, -1 ) ).rgb; float3 bottom = SceneTex.Sample( SceneTexSampler, input.uv, int2( 0, 1 ) ).rgb; float3 lower = min( sceneColor, min( min( left, right ), min( top, bottom ) ) ); float3 upper = max( sceneColor, max( max( left, right ), max( top, bottom ) ) ); historyColor = clamp( historyColor, lower, upper ); float3 resolveColor = lerp( sceneColor.rgb, historyColor, BlendWeight ); return float4( resolveColor, sceneColor.a ); } 이를적용하면다음과같이고스팅현상을개선할수있습니다. https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4fbdd80c-15a1-4dea-9bff-2016 42823616/2022-10-12_23_12_55.mp4 올바르지않은과거프레임의픽셀을조정하는방식은이외에도다양한데게임‘인사이드’의GDC 자료를보면 3x3 범위의이웃픽셀에대해서과거프레임의픽셀을clipping하는방법을사용한것을볼수있습니다. 마치며… 준비한내용은여기까지입니다. 이내용은훌륭한TAA 튜토리얼글인 https://sugulee.wordpress.com/2021/06/21/temporal-anti-aliasingtaa-tutorial/ 를참고하여Direct3D11 을사용한개인프로젝트의코드를기반으로작성되었습니다. 전체코드는아래의변경점에서 https://github.com/xtozero/SSR/commit/8f732f29d23063c914e0285120abaed024f9bba3 Source/RenderCore/Private/Renderer/TemporalAntiAliasingRendering.cpp Source/Shaders/Private/TemporalAntiAliasing/PS_TAAResolve.fx Source/Shaders/Private/VS_DepthWrite.fx Source/Shaders/Private/PS_DepthWrite.fx 등의파일을참고하시면됩니다.