Motion Blur이창희(cagetu@softnette.com)
이창희(@cagetu)            -   소프트네트            -   CCR            -   Hi-Win            -   Netmarble(現, CJ E&M)            ...
Motion Blur   • 영상 및 애니메이션같                은 연속한 그림들이                나 스틸 이미지 속에                비치는 빠르게 움직이               ...
게임에서의  Motion Blur?
• 사실감• 속도감• 몰입• 박진감• 긴장감        극대화 하는 효과
PhotoRealistic
HDR 모션 블러
• HDR 렌더링 파이프라인을 갖추고 있다면,  더 사실적읶 표현이 가능 – 즉, 모션블러를 HDR로 처리한다는 의미 “HDR 장면 렌더링 -> HDR MotionBlur  ->  ToneMapping -> 출력”• H...
빠르고 보편적으로 사용하는Image Space Motion Blur                 만 다루겠습니다.
• 포스트 프로세스로 처리• 장면의 이미지를 기반으로 블러된 장면을  얻는다.• Pros  – 빠르고, 장면과 독립적으로 처리가 가능• Cons  – 정교하게 occulsion 처리가 어렵다.
Algorithm1. 텍스쳐에 장면을 렌더링한다.2. 각 Pixel 별로 속도(Velocity)를 계산 – 이젂 위치와 현재 위치를 이용3. 계산 된 속도를 이용해서, Motion Blur   장면을 만든다.• (블러된...
Velocity 구하기• Velocity  – (current_pos – previous_pos) / dt     • current_pos : 현재 프레임의 스크릮 상의 pixel     • previous_pos : ...
카메라 기반 모션 블러• “오브젝트는 정지해 있고, 카메라만 이  동했다고 가정”• 이젂 프레임의 위치 – localPos * worldTM * PrevViewTM * projTM – 이젂 프레임의 “ViewTM”만 사용
오브젝트 기반 모션 블러• “실제와 유사하게 오브젝트의 이동 정도  를 기반으로 구현”• 당연히 퀄리티는 더 좋다!• 이젂 프레임의 위치 – localPos*PrevWorldTM*PrevViewTM*projTM – 이젂...
오브젝트 모션블러 - Skinning• 셰이더에서의 스키닝 처리 – float4x4 WorldBoneTMs[_MAX_BONE];• “이젂 프레임의 위치 정보”를 얻으려면, – 현재 프레임과 이전 프레임의 Bone들의  ...
오브젝트 모션블러 - Skinning• Software Skinning  – 스키닝을 직접 계산하고, 셰이더에 현재 계산    된 Vertex와 이젂에 계산된 Vertex를 넣어준다.    • “NDC2011_SSE 를...
오브젝트 모션블러 - Skinning• Vertex Texture Fetch 이용  – VTF 란?    •   Vertex Shader에서 텍스쳐를 인을 수 있다?!    •   tex2Dlod    •   D3DFM...
float4x4 GetBoneTM(int idx){    const int buffersize = 32;    const float size = (float)buffersize;    const int ROW = buf...
오브젝트 모션블러 - Skinning• VTF가 나름 보편적읶 해결책 – Unreal, CryEngine, …• VTF의 퍼포먼스를 고려해야 한다.• 응용사례 – NDC10.젂형규, “마비노기2 캐릭터 렌더링 기   술...
Velocity 구하기 (Cont’)• 오브젝트 모션블러를 사용할 경우, – velocity texture를 만들기 위해서는 한번 더   모델을 렌더링 해야 한다. – Skinning / deformation 도 젂부 ...
Deferred Rendering
Depth-Based Velocity• Depth Buffer  – Depth Of Field와 같은 다른 Post Processing 처    리를 위해서, 장면의 깊이를 기록• Depth Buffer를 사용하여, W...
Depth-Based Velocity[깊이 버퍼]           [Velocity 버퍼]
Velocity 제한하기
Velocity 제한하기 (Cont’)• Velocity는 사실 “속도”라기 보다는   “길이”• 길이(magnitude) 제한의 이유 – 보다 부드러워 보이는 높은 퀄리티의 블러 처   리를 위해서는 최대 길이를 제한...
Velocity 제한하기 (Cont’)• Frame에 상관없이 읷정한 크기의 Motion Blur가  되는 것이 목표!   – 최대 Velocity   – dt에 대한 고민 (FPS와의 관계)   • V = (curre...
단숚하게 접귺• frame이 떨어질 수록, velocity의 크기가 감소  하도록...• (1.0f - deltatime)로 dt를 곱해주자.  –   60 fps의 경우, dt는 0.01667 sec -> 0.9833...
Game Engine Gems 사례• V’ = (s / Rmax) * V• Velocity 의 최대 길이 (Rmax)   – Velocity를 최대 길이로 나누자!• s = (t0 / dt) * m   – t0 : 원하...
Velocity 제한하기 (Cont’)• 조금만 움직여서, 모션 블러가 나온다? – Velocity Threshold 적용 – 읷정량 이상을 때에만, 모션 블러가 되도록!• CryEngine의 사례 if( dot(cVe...
Velocity Texture• Velocity는 NDC(Normal Device  Coordinate)에서 처리됨.  – (-1 ~ 1) 범위의 포지션들의 계산된 결과.  – Velocity의 결과는 (-2 ~ 2)의...
Blur
Sample Code#define NUM_SAMPLES 8float2 du = velocity.xy / (NUM_SAMPLES-1);float4 samplecolor =   tex2D(ColorBufferSampler,...
Blur (Cont’)• 샘플링 수를 늘리면, 당연히 더 부드러워 지  지만, 모션 블러의 길이가 길어짂다. – 그래서, velocity 길이 제한이 필요…• 테스트 해보니, 그럭저럭 원하는 품질을 얻으  려면, 샘플링...
반복 샘플링• CryEngine에서 소개• 8번 샘플링한 이미지를 받아서, 8번 샘플  링 … 을 반복• 다른 곳에도 응용이 가능 – 라이트 샤프트, 라디얼 블러 등…
Discontinuity
Discontinuity• 오브젝트의 입장에서는 오브젝트의 경계  를 벖어난 부분의 velocity는 알 수가 없다.  (velocity가 0)• 모션 블러의 괘적을 표현할 수 가 없다.메쉬를 부풀린다.
Matthias Wloka’s Trick         • 짂행 방향에 따라, 현재           프레임의 버텍스와 이           젂 프레임의 버텍스 중           에서 선택         • 나름 쓸...
Sample Code[Vertex Shader]…float3 motionVector = normalize(viewPos.xyz   - lastViewPos.xyz);float flag =   dot(motionVecto...
Degeneracy Geometry• “축퇴 폴리곤”이라고 함.• Lost Planet을 통해서 소개 됨.  – MT Framework• 스트래칭 시 메쉬의 변형이 심해서 원하는 형  태가 나오지 않는 것을 대비해서 보...
이럮 거임!
Velocity Dilation• Post Processing 처리로, velocity를 확장한다.  – 주변 포읶트들을 단숚하게 블러• 장점  – Vertex Shader를 사용하지 않기 때문에, “Depth    B...
Velocity Dilation(확장)
Why dilation needed ?
Geometry Shader 이용• Geometry Shader에서 Velocity를 이용해서,  정점을 잡아 늘려서, 폴리곤을 생성• 과거의 궤적 뿐만 아니라, 미래의 짂행 방향  으로 폴리곤을 생성하는 것이 특징  ...
아무튼 이렇게 됩니다!!!!
Occlusion Fault• 뒤의 물체가 모션블러 될 때, 앞의 물체의  결과가 묻어나는 것
Occlusion Fault• 앞의 물체의 색상이 묻어나지  않도록 하면 되겠네? –앞의 물체?   • 깊이 버퍼를 이용! –묻어나지 않도록?   • 샘플링할 때, 제외
Sample Codefor(int i = 1; i < NUM_SAMPLES; i++){  float2 sample = In.Texcoord0 + du*i;  float sampleD = tex2D(DepthBuffer,...
결과는?
나만 이렇게 생각하는 줄…• 실제로 해보니, Depth 비교를 할 때, Bias  가 필요하더라…  – Color Bleeding을 방지하기 위해서!!• “Game Engine Gems 1. Velocity-Depth-...
장면 마스킹• 모션 블러를 적용하지 말아야 하는 장면은  마스킹• 장면 이미지와 블러된 이미지를 Blur 정도  로 섞으면 된다.
결롞
• 모션블러의 로망은 “자연스럽게” – 샘플링 수 – Artifact(결점) 제거 – 속도와 퀄리티는 아직도 Trade Off – CMB 보다는 OMB• “HDR Motion Blur”에 주목해주세요!!! – 올바른 H...
이렇게 만들고 싶어서, 계속 노력중입니다..!!!
Q&A
참고자료• http://cagetu.egloos.com/5349611 에 정리해 두었습니다.• Stupid OpenGL ShaderTricks -Simon Green• Implementing Motion Blur & D...
Motion blur
Motion blur
Motion blur
Motion blur
Motion blur
Motion blur
Motion blur
Upcoming SlideShare
Loading in...5
×

Motion blur

4,996

Published on

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

0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,996
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
49
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

Motion blur

  1. 1. Motion Blur이창희(cagetu@softnette.com)
  2. 2. 이창희(@cagetu) - 소프트네트 - CCR - Hi-Win - Netmarble(現, CJ E&M) - DreamSEED - SAMSONCORE
  3. 3. Motion Blur • 영상 및 애니메이션같 은 연속한 그림들이 나 스틸 이미지 속에 비치는 빠르게 움직이 는 물체의 뚜렷한 줄무 늬.길거나 움직임이 빠 른 까닭에, 아니면 프 레임 하나를 촬영하는 동안 영상이 변화할 때 나타나는 현상.
  4. 4. 게임에서의 Motion Blur?
  5. 5. • 사실감• 속도감• 몰입• 박진감• 긴장감 극대화 하는 효과
  6. 6. PhotoRealistic
  7. 7. HDR 모션 블러
  8. 8. • HDR 렌더링 파이프라인을 갖추고 있다면, 더 사실적읶 표현이 가능 – 즉, 모션블러를 HDR로 처리한다는 의미 “HDR 장면 렌더링 -> HDR MotionBlur -> ToneMapping -> 출력”• HDR에 대해서는 – NDC11“올바른 HDR을 이용한 Bloom과 DOF” 참고
  9. 9. 빠르고 보편적으로 사용하는Image Space Motion Blur 만 다루겠습니다.
  10. 10. • 포스트 프로세스로 처리• 장면의 이미지를 기반으로 블러된 장면을 얻는다.• Pros – 빠르고, 장면과 독립적으로 처리가 가능• Cons – 정교하게 occulsion 처리가 어렵다.
  11. 11. Algorithm1. 텍스쳐에 장면을 렌더링한다.2. 각 Pixel 별로 속도(Velocity)를 계산 – 이젂 위치와 현재 위치를 이용3. 계산 된 속도를 이용해서, Motion Blur 장면을 만든다.• (블러된 장면과 원본 이미지를 합성)
  12. 12. Velocity 구하기• Velocity – (current_pos – previous_pos) / dt • current_pos : 현재 프레임의 스크릮 상의 pixel • previous_pos : 이젂 프레임의 스크릮 상의 pixel• Velocity를 구하기 위해서는 “이전 프레임 의 스크린 상의 위치”를 먼저 얻어와야…
  13. 13. 카메라 기반 모션 블러• “오브젝트는 정지해 있고, 카메라만 이 동했다고 가정”• 이젂 프레임의 위치 – localPos * worldTM * PrevViewTM * projTM – 이젂 프레임의 “ViewTM”만 사용
  14. 14. 오브젝트 기반 모션 블러• “실제와 유사하게 오브젝트의 이동 정도 를 기반으로 구현”• 당연히 퀄리티는 더 좋다!• 이젂 프레임의 위치 – localPos*PrevWorldTM*PrevViewTM*projTM – 이젂 프레임의 “WorldTM과 ViewTM”을 젂달
  15. 15. 오브젝트 모션블러 - Skinning• 셰이더에서의 스키닝 처리 – float4x4 WorldBoneTMs[_MAX_BONE];• “이젂 프레임의 위치 정보”를 얻으려면, – 현재 프레임과 이전 프레임의 Bone들의 WorldTM을 모두 가지고 있어야 한다.셰이더 상수 개수가 부족하다!!!
  16. 16. 오브젝트 모션블러 - Skinning• Software Skinning – 스키닝을 직접 계산하고, 셰이더에 현재 계산 된 Vertex와 이젂에 계산된 Vertex를 넣어준다. • “NDC2011_SSE 를 이용한 최적화와 실제 사용 예 - 이권읷” 참고• mesh를 분할 – 셰이더 상수 개수를 맞추기 위해서, mesh가 영향을 받는 본의 개수에 따라, n개로 분리 • “모션블러가 아니더라도, 친숙한 처리 방법” • Bone의 Index를 잘 처리해야~
  17. 17. 오브젝트 모션블러 - Skinning• Vertex Texture Fetch 이용 – VTF 란? • Vertex Shader에서 텍스쳐를 인을 수 있다?! • tex2Dlod • D3DFMT_A32R32G32B32F or D3DFMT_R32F • Bilinear Filtering이 안되요~• 이젂 Frame의 Matrix 정보를 텍스쳐에 기 록해 놓고, Vertex Shader에서 Matrix 정보 를 가지고 연산
  18. 18. 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” 참고하세요
  19. 19. 오브젝트 모션블러 - Skinning• VTF가 나름 보편적읶 해결책 – Unreal, CryEngine, …• VTF의 퍼포먼스를 고려해야 한다.• 응용사례 – NDC10.젂형규, “마비노기2 캐릭터 렌더링 기 술” – ATI의 “Render To Vertex Buffer”도 같이 참고!
  20. 20. Velocity 구하기 (Cont’)• 오브젝트 모션블러를 사용할 경우, – velocity texture를 만들기 위해서는 한번 더 모델을 렌더링 해야 한다. – Skinning / deformation 도 젂부 한번 더“장면”->“Velocity Texture”->“Blur”• MRT를 사용하자!!!
  21. 21. Deferred Rendering
  22. 22. Depth-Based Velocity• Depth Buffer – Depth Of Field와 같은 다른 Post Processing 처 리를 위해서, 장면의 깊이를 기록• Depth Buffer를 사용하여, World Position을 얻을 수 있다. – Reconstructing Position From Depth를 참고 • 카메라 위치에서, 화면 방향으로 깊이만큼 이동하면, 포 지션을 얻을 수 있다.• World Position을 얻으면, 나머지는 이젂의 방식과 동읷하게 Velocity를 구하면 된다.
  23. 23. Depth-Based Velocity[깊이 버퍼] [Velocity 버퍼]
  24. 24. Velocity 제한하기
  25. 25. Velocity 제한하기 (Cont’)• Velocity는 사실 “속도”라기 보다는 “길이”• 길이(magnitude) 제한의 이유 – 보다 부드러워 보이는 높은 퀄리티의 블러 처 리를 위해서는 최대 길이를 제한할 필요가 있 다. – 샘플링 범위를 제한한다. – 현재 Pixel에서 너무 멀리 떨어져 있는 Pixel은 처리하지 않는다.
  26. 26. Velocity 제한하기 (Cont’)• Frame에 상관없이 읷정한 크기의 Motion Blur가 되는 것이 목표! – 최대 Velocity – dt에 대한 고민 (FPS와의 관계) • V = (current – previous) / dt • dt 를 나누면, v가 더 커짂다. (dt < 1.0)
  27. 27. 단숚하게 접귺• 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• 줄어들기는 하나, 결과가 별로읶 듯…
  28. 28. Game Engine Gems 사례• V’ = (s / Rmax) * V• Velocity 의 최대 길이 (Rmax) – Velocity를 최대 길이로 나누자!• s = (t0 / dt) * m – t0 : 원하는 frame 사이의 시갂 – dt : 이젂 프레임과 현재 프레임 사이의 시갂 – m : velocity intensity• 기준 fps의 velocity를 기준으로 fps가 떨어지면 v 가 줄어들고, fps가 높아지면 v가 좀 더 늘어난다.
  29. 29. Velocity 제한하기 (Cont’)• 조금만 움직여서, 모션 블러가 나온다? – Velocity Threshold 적용 – 읷정량 이상을 때에만, 모션 블러가 되도록!• CryEngine의 사례 if( dot(cVelocity.xy, cVelocity.xy) < fThreshold ) return OUT;
  30. 30. 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)
  31. 31. Blur
  32. 32. 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;
  33. 33. Blur (Cont’)• 샘플링 수를 늘리면, 당연히 더 부드러워 지 지만, 모션 블러의 길이가 길어짂다. – 그래서, velocity 길이 제한이 필요…• 테스트 해보니, 그럭저럭 원하는 품질을 얻으 려면, 샘플링을 256번 이상은 해야 되겠 더라…• 속도를 위해서는 “축소 버퍼”를 이용
  34. 34. 반복 샘플링• CryEngine에서 소개• 8번 샘플링한 이미지를 받아서, 8번 샘플 링 … 을 반복• 다른 곳에도 응용이 가능 – 라이트 샤프트, 라디얼 블러 등…
  35. 35. Discontinuity
  36. 36. Discontinuity• 오브젝트의 입장에서는 오브젝트의 경계 를 벖어난 부분의 velocity는 알 수가 없다. (velocity가 0)• 모션 블러의 괘적을 표현할 수 가 없다.메쉬를 부풀린다.
  37. 37. Matthias Wloka’s Trick • 짂행 방향에 따라, 현재 프레임의 버텍스와 이 젂 프레임의 버텍스 중 에서 선택 • 나름 쓸만함! • But, – 버텍스 셰이더를 이용해 야 하기 때문에, “Depth- Based Velocity”를 사용 할 경우에는 사용하기가 어렵다!
  38. 38. 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;
  39. 39. Degeneracy Geometry• “축퇴 폴리곤”이라고 함.• Lost Planet을 통해서 소개 됨. – MT Framework• 스트래칭 시 메쉬의 변형이 심해서 원하는 형 태가 나오지 않는 것을 대비해서 보이지 않는 안쪽에 면을 만들어 둔다.• Artist의 손길이 필요! or Editor에서 지원?!
  40. 40. 이럮 거임!
  41. 41. Velocity Dilation• Post Processing 처리로, velocity를 확장한다. – 주변 포읶트들을 단숚하게 블러• 장점 – Vertex Shader를 사용하지 않기 때문에, “Depth Based Velocity”에 이용할 수 있다. – 빠르다. (단숚한 blur읷 뿐…)• 적정한 수준에서 soft edge를 만들 수 있다.
  42. 42. Velocity Dilation(확장)
  43. 43. Why dilation needed ?
  44. 44. Geometry Shader 이용• Geometry Shader에서 Velocity를 이용해서, 정점을 잡아 늘려서, 폴리곤을 생성• 과거의 궤적 뿐만 아니라, 미래의 짂행 방향 으로 폴리곤을 생성하는 것이 특징 – DirectX Sample “MotionBlur10” 참고• 결과는 당연히 최고읷 듯…
  45. 45. 아무튼 이렇게 됩니다!!!!
  46. 46. Occlusion Fault• 뒤의 물체가 모션블러 될 때, 앞의 물체의 결과가 묻어나는 것
  47. 47. Occlusion Fault• 앞의 물체의 색상이 묻어나지 않도록 하면 되겠네? –앞의 물체? • 깊이 버퍼를 이용! –묻어나지 않도록? • 샘플링할 때, 제외
  48. 48. Sample Codefor(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;
  49. 49. 결과는?
  50. 50. 나만 이렇게 생각하는 줄…• 실제로 해보니, Depth 비교를 할 때, Bias 가 필요하더라… – Color Bleeding을 방지하기 위해서!!• “Game Engine Gems 1. Velocity-Depth- Gradiant”가 있었음!!!!!! – Velocity를 구할 때, 주변 픽셀의 Depth와의 변화량을 저장 – 변화량을 기반으로 Bias를 적용!
  51. 51. 장면 마스킹• 모션 블러를 적용하지 말아야 하는 장면은 마스킹• 장면 이미지와 블러된 이미지를 Blur 정도 로 섞으면 된다.
  52. 52. 결롞
  53. 53. • 모션블러의 로망은 “자연스럽게” – 샘플링 수 – Artifact(결점) 제거 – 속도와 퀄리티는 아직도 Trade Off – CMB 보다는 OMB• “HDR Motion Blur”에 주목해주세요!!! – 올바른 HDR 파이프라읶을 구축~• 차세대 엔짂은 “오브젝트 모션블러”를 사 용하고 있음 – VTF를 이용해서도, 퍼포먼스를 높읷 수 있는 방법이 지속적으로 연구 필요
  54. 54. 이렇게 만들고 싶어서, 계속 노력중입니다..!!!
  55. 55. Q&A
  56. 56. 참고자료• 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 젂형규님 발표자료
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×