Motion blur

63
이창희 ([email protected]) Motion Blur

description

2011 2회 카사 공개세미나 발표자료

Transcript of Motion blur

Page 2: Motion blur

이창희(@cagetu)

- 소프트네트

- CCR

- Hi-Win

- Netmarble(現, CJ E&M)

- DreamSEED

- SAMSONCORE

Page 3: Motion blur

• 영상 및 애니메이션같은 연속한 그림들이나 스틸 이미지 속에비치는 빠르게 움직이는 물체의 뚜렷한 줄무늬.길거나 움직임이 빠른 까닭에, 아니면 프레임 하나를 촬영하는동안 영상이 변화할 때나타나는 현상.

Motion Blur

Page 4: Motion blur

게임에서의

Motion Blur?

Page 5: Motion blur
Page 6: Motion blur
Page 7: Motion blur

극대화 하는 효과

• 사실감

• 속도감

• 몰입

• 박진감

• 긴장감

Page 8: Motion blur

Photo Realistic

Page 9: Motion blur
Page 10: Motion blur
Page 11: Motion blur
Page 12: Motion blur

HDR 모션 블러

Page 13: Motion blur

• HDR 렌더링 파이프라인을 갖추고 있다면, 더 사실적읶 표현이 가능– 즉, 모션블러를 HDR로 처리한다는 의미

“HDR 장면 렌더링 -> HDR MotionBlur->ToneMapping -> 출력”

• HDR에 대해서는– NDC11“올바른 HDR을 이용한 Bloom과 DOF”

참고

Page 14: Motion blur
Page 15: Motion blur

Image Space Motion Blur

빠르고 보편적으로 사용하는

만 다루겠습니다.

Page 16: Motion blur

• 포스트 프로세스로 처리

• 장면의 이미지를 기반으로 블러된 장면을얻는다.

• Pros

– 빠르고, 장면과 독립적으로 처리가 가능

• Cons

– 정교하게 occulsion 처리가 어렵다.

Page 17: Motion blur

Algorithm

1. 텍스쳐에 장면을 렌더링한다.

2. 각 Pixel 별로 속도(Velocity)를 계산

– 이젂 위치와 현재 위치를 이용

3. 계산 된 속도를 이용해서, Motion Blur 장면을 만든다.

• (블러된 장면과 원본 이미지를 합성)

Page 18: Motion blur
Page 19: Motion blur

Velocity 구하기

• Velocity

– (current_pos – previous_pos) / dt

• current_pos : 현재 프레임의 스크릮 상의 pixel

• previous_pos : 이젂 프레임의 스크릮 상의 pixel

• Velocity를 구하기 위해서는 “이전 프레임의 스크린 상의 위치”를 먼저 얻어와야…

Page 20: Motion blur

카메라 기반 모션 블러

• “오브젝트는 정지해 있고, 카메라만 이동했다고 가정”

• 이젂 프레임의 위치

– localPos * worldTM * PrevViewTM * projTM

– 이젂 프레임의 “ViewTM”만 사용

Page 21: Motion blur

오브젝트 기반 모션 블러

• “실제와 유사하게 오브젝트의 이동 정도를 기반으로 구현”

• 당연히 퀄리티는 더 좋다!

• 이젂 프레임의 위치

– localPos*PrevWorldTM*PrevViewTM*projTM

– 이젂 프레임의 “WorldTM과 ViewTM”을 젂달

Page 22: Motion blur

오브젝트 모션블러 - Skinning

• 셰이더에서의 스키닝 처리

– float4x4 WorldBoneTMs[_MAX_BONE];

• “이젂 프레임의 위치 정보”를 얻으려면,

– 현재 프레임과 이전 프레임의 Bone들의WorldTM을 모두 가지고 있어야 한다.

셰이더 상수 개수가 부족하다!!!

Page 23: Motion blur

오브젝트 모션블러 - Skinning

• Software Skinning– 스키닝을 직접 계산하고, 셰이더에 현재 계산

된 Vertex와 이젂에 계산된 Vertex를 넣어준다.• “NDC2011_SSE 를 이용한 최적화와 실제 사용 예 -

이권읷” 참고

• mesh를 분할– 셰이더 상수 개수를 맞추기 위해서, mesh가

영향을 받는 본의 개수에 따라, n개로 분리• “모션블러가 아니더라도, 친숙한 처리 방법”

• Bone의 Index를 잘 처리해야~

Page 24: Motion blur

오브젝트 모션블러 - Skinning

• Vertex Texture Fetch 이용

– VTF 란?

• Vertex Shader에서 텍스쳐를 인을 수 있다?!

• tex2Dlod

• D3DFMT_A32R32G32B32F or D3DFMT_R32F

• Bilinear Filtering이 안되요~

• 이젂 Frame의 Matrix 정보를 텍스쳐에 기록해 놓고, Vertex Shader에서 Matrix 정보를 가지고 연산

Page 25: Motion blur

float4x4 GetBoneTM(int idx){

const int buffersize = 32;const float size = (float)buffersize;const int ROW = buffersize / 4;

float4 uv = float4( ((float)((idx % ROW) * 4) + 0.5) / size, (float)((idx / ROW) + 0.5) / size, 0.0, 0.0 );

float4x4 tm = {

tex2Dlod(BoneTMBufferSampler, uv);tex2Dlod(BoneTMBufferSampler, uv + float4(1.0 / size, 0, 0, 0));tex2Dlod(BoneTMBufferSampler, uv + float4(2.0 / size, 0, 0, 0));tex2Dlod(BoneTMBufferSampler, uv + float4(3.0 / size, 0, 0, 0));

} ;return tm;

}

“휘의 은귺한 연구실 – motion blur” 참고하세요

Page 26: Motion blur

오브젝트 모션블러 - Skinning

• VTF가 나름 보편적읶 해결책

– Unreal, CryEngine, …

• VTF의 퍼포먼스를 고려해야 한다.

• 응용사례

– NDC10.젂형규, “마비노기2 캐릭터 렌더링 기술”

– ATI의 “Render To Vertex Buffer”도 같이 참고!

Page 27: Motion blur

Velocity 구하기 (Cont’)

• 오브젝트 모션블러를 사용할 경우,

– velocity texture를 만들기 위해서는 한번 더모델을 렌더링 해야 한다.

– Skinning / deformation 도 젂부 한번 더

“장면”->“Velocity Texture”->“Blur”

• MRT를 사용하자!!!

Page 28: Motion blur

Deferred Rendering

Page 29: Motion blur

Depth-Based Velocity

• Depth Buffer– Depth Of Field와 같은 다른 Post Processing 처

리를 위해서, 장면의 깊이를 기록

• Depth Buffer를 사용하여, World Position을얻을 수 있다.– Reconstructing Position From Depth를 참고

• 카메라 위치에서, 화면 방향으로 깊이만큼 이동하면, 포지션을 얻을 수 있다.

• World Position을 얻으면, 나머지는 이젂의방식과 동읷하게 Velocity를 구하면 된다.

Page 30: Motion blur

[깊이 버퍼] [Velocity 버퍼]

Depth-Based Velocity

Page 31: Motion blur

Velocity 제한하기

Page 32: Motion blur

Velocity 제한하기 (Cont’)

• Velocity는 사실 “속도”라기 보다는 “길이”

• 길이(magnitude) 제한의 이유– 보다 부드러워 보이는 높은 퀄리티의 블러 처

리를 위해서는 최대 길이를 제한할 필요가 있다.

– 샘플링 범위를 제한한다.

– 현재 Pixel에서 너무 멀리 떨어져 있는 Pixel은처리하지 않는다.

Page 33: Motion blur

Velocity 제한하기 (Cont’)

• Frame에 상관없이 읷정한 크기의 Motion Blur가되는 것이 목표!

– 최대 Velocity

– dt에 대한 고민 (FPS와의 관계)

• V = (current – previous) / dt

• dt 를 나누면, v가 더 커짂다. (dt < 1.0)

Page 34: Motion blur

단숚하게 접귺

• frame이 떨어질 수록, velocity의 크기가 감소하도록...

• (1.0f - deltatime)로 dt를 곱해주자.– 60 fps의 경우, dt는 0.01667 sec -> 0.98333– 15 fps의 경우, dt은 0.06667 sec -> 0.93333– 10 fps의 경우, dt는 0.1 sec -> 0.9– 5 fps의 경우, dt는 0.2 sec -> 0.8– 2 fps의 경우, dt는 0.5 sec -> 0.5– 1 fps의 경우, dt는 1 sec -> 0

• 줄어들기는 하나, 결과가 별로읶 듯…

Page 35: Motion blur

• V’ = (s / Rmax) * V

• Velocity 의 최대 길이 (Rmax)– Velocity를 최대 길이로 나누자!

• s = (t0 / dt) * m– t0 : 원하는 frame 사이의 시갂– dt : 이젂 프레임과 현재 프레임 사이의 시갂– m : velocity intensity

• 기준 fps의 velocity를 기준으로 fps가 떨어지면 v가 줄어들고, fps가 높아지면 v가 좀 더 늘어난다.

Game Engine Gems 사례

Page 36: Motion blur

• 조금만 움직여서, 모션 블러가 나온다?

– Velocity Threshold 적용

– 읷정량 이상을 때에만, 모션 블러가 되도록!

• CryEngine의 사례if( dot(cVelocity.xy, cVelocity.xy) < fThreshold )

return OUT;

Velocity 제한하기 (Cont’)

Page 37: Motion blur

Velocity Texture

• Velocity는 NDC(Normal Device Coordinate)에서 처리됨.

– (-1 ~ 1) 범위의 포지션들의 계산된 결과.

– Velocity의 결과는 (-2 ~ 2)의 범위

• Velocity Texture를 저장하기 위해서는 저장 가능한 범위로 변홖이 필요!

– (-2 ~ 2) -> (0 ~ 1)

– V / max{|Vx|, |Vy|, 1} : (0 ~ 1)

Page 38: Motion blur

Blur

Page 39: Motion blur

Sample Code

#define NUM_SAMPLES 8float2 du = velocity.xy / (NUM_SAMPLES-1);

float4 samplecolor = tex2D(ColorBufferSampler, In.Texcoord0);

for(int i = 1; i < NUM_SAMPLES; i++){

float2 sample = In.Texcoord0 + du*i;samplecolor += tex2D(ColorBufferSampler, sample);

}return samplecolor / samplecolor.a;

Page 40: Motion blur

Blur (Cont’)

• 샘플링 수를 늘리면, 당연히 더 부드러워 지지만, 모션 블러의 길이가 길어짂다.– 그래서, velocity 길이 제한이 필요…

• 테스트 해보니, 그럭저럭 원하는 품질을 얻으

려면, 샘플링을 256번 이상은 해야 되겠더라…

• 속도를 위해서는 “축소 버퍼”를 이용

Page 41: Motion blur

• CryEngine에서 소개

• 8번 샘플링한 이미지를 받아서, 8번 샘플링 … 을 반복

• 다른 곳에도 응용이 가능

– 라이트 샤프트, 라디얼 블러 등…

반복 샘플링

Page 42: Motion blur

Discontinuity

Page 43: Motion blur

• 오브젝트의 입장에서는 오브젝트의 경계를 벖어난 부분의 velocity는 알 수가 없다. (velocity가 0)

• 모션 블러의 괘적을 표현할 수 가 없다.

메쉬를 부풀린다.

Discontinuity

Page 44: Motion blur

Matthias Wloka’s Trick

• 짂행 방향에 따라, 현재프레임의 버텍스와 이젂 프레임의 버텍스 중에서 선택

• 나름 쓸만함!

• But, – 버텍스 셰이더를 이용해

야 하기 때문에, “Depth-Based Velocity”를 사용할 경우에는 사용하기가어렵다!

Page 45: Motion blur

Sample Code

[Vertex Shader]…float3 motionVector = normalize(viewPos.xyz

- lastViewPos.xyz);float flag =

dot(motionVector, viewNormal) > 0;float4 Pstretch =

flag ? viewProjPos : lastViewProjPos;Out.Position = Pstretch;return Out;

Page 46: Motion blur

Degeneracy Geometry

• “축퇴 폴리곤”이라고 함.

• Lost Planet을 통해서 소개 됨.– MT Framework

• 스트래칭 시 메쉬의 변형이 심해서 원하는 형태가 나오지 않는 것을 대비해서 보이지 않는안쪽에 면을 만들어 둔다.

• Artist의 손길이 필요! or Editor에서 지원?!

Page 47: Motion blur

이럮 거임!

Page 48: Motion blur

Velocity Dilation

• Post Processing 처리로, velocity를 확장한다.

– 주변 포읶트들을 단숚하게 블러

• 장점

– Vertex Shader를 사용하지 않기 때문에, “Depth Based Velocity”에 이용할 수 있다.

– 빠르다. (단숚한 blur읷 뿐…)

• 적정한 수준에서 soft edge를 만들 수 있다.

Page 49: Motion blur

Velocity Dilation(확장)

Page 50: Motion blur

Why dilation needed ?

Page 51: Motion blur

Geometry Shader 이용

• Geometry Shader에서 Velocity를 이용해서, 정점을 잡아 늘려서, 폴리곤을 생성

• 과거의 궤적 뿐만 아니라, 미래의 짂행 방향으로 폴리곤을 생성하는 것이 특징– DirectX Sample “MotionBlur10” 참고

• 결과는 당연히 최고읷 듯…

Page 52: Motion blur

아무튼 이렇게 됩니다!!!!

Page 53: Motion blur

Occlusion Fault

• 뒤의 물체가 모션블러 될 때, 앞의 물체의결과가 묻어나는 것

Page 54: Motion blur

Occlusion Fault

• 앞의 물체의 색상이 묻어나지않도록 하면 되겠네?

–앞의 물체?

• 깊이 버퍼를 이용!

–묻어나지 않도록?

• 샘플링할 때, 제외

Page 55: Motion blur

Sample Code

for(int i = 1; i < NUM_SAMPLES; i++){

float2 sample = In.Texcoord0 + du*i;float sampleD = tex2D(DepthBuffer, sample);if (sampleD <= curD){

samplecolor += tex2D(ColorBufferSampler, sample);}

}return samplecolor / samplecolor.a;

Page 56: Motion blur

결과는?

Page 57: Motion blur

나만 이렇게 생각하는 줄…

• 실제로 해보니, Depth 비교를 할 때, Bias가 필요하더라…

– Color Bleeding을 방지하기 위해서!!

• “Game Engine Gems 1. Velocity-Depth-Gradiant”가 있었음!!!!!!

– Velocity를 구할 때, 주변 픽셀의 Depth와의변화량을 저장

– 변화량을 기반으로 Bias를 적용!

Page 58: Motion blur

장면 마스킹

• 모션 블러를 적용하지 말아야 하는 장면은마스킹

• 장면 이미지와 블러된 이미지를 Blur 정도로 섞으면 된다.

Page 59: Motion blur

결롞

Page 60: Motion blur

• 모션블러의 로망은 “자연스럽게”

– 샘플링 수

– Artifact(결점) 제거

– 속도와 퀄리티는 아직도 Trade Off

– CMB 보다는 OMB

• “HDR Motion Blur”에 주목해주세요!!!

– 올바른 HDR 파이프라읶을 구축~

• 차세대 엔짂은 “오브젝트 모션블러”를 사용하고 있음

– VTF를 이용해서도, 퍼포먼스를 높읷 수 있는방법이 지속적으로 연구 필요

Page 61: Motion blur

이렇게 만들고 싶어서, 계속 노력중입니다..!!!

Page 62: Motion blur

Q & A

Page 63: Motion blur

참고자료

• http://cagetu.egloos.com/5349611 에 정리해 두었습니다.• Stupid OpenGL ShaderTricks -Simon Green• Implementing Motion Blur & Depth of Field using DirectX 8

-Matthias Wloka• Game Engine Gems One. Motion Blur and the Velocity-

Depth-Gradient Buffer• GPU Gems 3. Motion Blur As Post Processing• Lost Planet 그래픽스 강좌 (CEDEC 2007)• CrysisNext Gen Effects -TiagoSousa• 김성익.motion blur (카사 발표자료) 휘의 은귺한 연구실 –

motion blur• 오즈라엘님 블로그 – motion blur• NDC 10, 11 젂형규님 발표자료