29
Far Cry and DirectX Carsten Wenzel

[14.10.21] Far Cry and DX9 번역(shaderstudy)

  • View
    463

  • Download
    2

Embed Size (px)

DESCRIPTION

원본 : http://www.crytek.com/cryengine/presentations/far-cry-and-dx9

Citation preview

Page 1: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Far Cry and DirectX

Carsten Wenzel

Page 2: [14.10.21] Far Cry and DX9 번역(shaderstudy)

• 개인적으로 공부하다 적은 것이므로 영어 & 이해 부족으로 인한 오역을 감안하세요• 틀린 부분이나 혹 문제가 될 부분이 있다면 해강 ([email protected]

) 으로 알려주시면 감사하겠습니다• 붉은 색은 개인적으로 적어놓은 메모입니다 틀릴 수도 있어요• 원본은 여기입니다

• http://www.crytek.com/cryengine/presentations/far-cry-and-dx9

CRYTEK 의 GDC2005 자료

Page 3: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Far Cry 는 최신 DX9 기능을 사용한다

• Shader Models 2.x / 3.0 - vertex textures 와 dynamic flow

control 은 제외• Geometry Instancing • Floating-point render targets

Page 4: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Dynamic flow control* in PS• 우리는 궁극적으로 하나의 패스에 여러개의

조명을 통합하기를 원한다…

float3 finalCol = 0;float3 diffuseCol = tex2D( diffuseMap, IN.diffuseUV.xy );float3 normal = mul( IN.tangentToWorldSpace, tex2D( normalMap, IN.bumpUV.xy ).xyz );for( int i = 0; i < cNumLights; i++ ){ float3 lightCol = LightColor[ i ]; float3 lightVec = normalize( cLightPos[ i ].xyz – IN.pos.xyz ); // … // Attenuation, Specular, etc. calculated via if( const_boolean ) // … float nDotL = saturate( dot( lightVec.xyz, normal ) ); final += lightCol.xyz * diffuseCol.xyz * nDotL * atten;}return( float4( finalCol, 1 ) );

* Dynamic flow control 는 동적 코드 분기 (ex : break)Shader3.0 에서 24, 4.0 부터 완전지원

Page 5: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Dynamic flow control in PS• 현실 세계에 온 것을 환영한다…

– Dynamic indexing 은 오직 input registers 에서만 허용 ; 상수 레지스터와 루프 안의 인덱스를 통해 라이트 데이터가 통과하는 것을 방지

– 입력 레지스터를 통해 라이트 정보가 통과되면 , 그것들은 충분하지 않기 때문에 제대로 실현 불가능하다 ( 오직 10 개 * )

– 동적 분기는 무료가 아니다

*3.0 기준 레지스터 제한 10http://msdn.microsoft.com/en-us/library/bb172920%28v=VS.85%29.aspx

Page 6: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Loop unrolling*• 우리는 동적 분기와 루프를 사용하지 않기로 선택했다• 대신 정적 분기를 사용하고 , 루프를 풀어서 대신했다• Far Cry 의 기존 쉐이더 프레임워크와 잘 작동한다• 쉐이더는 다른 light masks 를 위해 미리 컴파일 한다

– 0-4 개의 패스당 동적 라이트– 3 개의 다른 라이트 타입 (spot, omni(ex: 전구 ), directional)– 2 개의 라이트당 수정 타입 (specular only, occlusion map(

물체가 빛을 막아 생김 )• 4 개의 조명을 사용할 때 loop unrolling 후 160 지침 ( 지나치게 긴 쉐이더 ) 이 발생할 수 있다

– ps_2_0 에서 너무 길게 작성– ps_2_a, ps_2_b and ps_3_0 에서는 괜찮다 !

• 런타임에 뻑나는걸 방지하기 위해 , 쉐이더 캐쉬를 미리 확보* 루프를 풀어쓰는 기법 ( 예 : for(int i = 0; i < 100; ++I) -> for(int i = 0; i < 50; i += 2)분기를 줄이고 , cache hit 비율을 높여주는 효과가 있다레지스터 사용량이 증가하는건 단점정상적인 코드에 대한 최적화로 고려되는 작업이므로 무분별한 사용은 금물http://en.wikipedia.org/wiki/Loop_unrolling

Page 7: [14.10.21] Far Cry and DX9 번역(shaderstudy)

어떻게 쉐이더 캐쉬를 작업했나• 특정 쉐이더에 따라 다르다 :

1) 재질 종류(e.g. skin, phong, metal)

2) 재질 사용 항목(e.g. bump-mapped, specular)

3) 특정 환경(e.g. light mask, fog)

Page 8: [14.10.21] Far Cry and DX9 번역(shaderstudy)

어떻게 쉐이더 캐쉬를 작업했나• Cache access:

– 객체가 랜더링할때 이미 쉐이더 핸들을 가지고 있나 ? 그것들을 사용해라 !– 그렇지 않다면 메모리에서 쉐이더를 찾아봐라– 만약 하드디스크에서 로드에 실패하면 ,( 다음 )– 만약 하드디스크에 저장된 백업에서 VS/PS 생성에 실패한다면 , ( 다음 )– 마지막으로 객체의 쉐이더 핸들을 저장한다

• 이상적인 해결책은 아니다 , 그러나– 기존의 하드웨어에서 꽤 잘 작동한다– assets 의 변경 없이 손쉽게 통합시킬 수 있었다

• 캐쉬를 효율적으로 써야…– HD 에 미리 캐쉬된 파일 같은 것들이 존재해야 모든 쉐이더의 통합이 가능

• 즉시 사용할 경우 쉐이더 컴파일에 필요한 시간 때문에 맛이 간다 !– 그러나 , 캐쉬를 계속 유지하는 것은 번거로운 일이다

Page 9: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Loop unrolling – 장점 /단점• 장점 :

– 속도 ! 동적으로 분기되지 않아 꽤 많은 사이클을 절약한다

– 이때 , 우리는 동적 분기보다 더 효율적으로 쉐이더를 바꿀 수 있다는 것을 찾아냈다

• 단점 :– light mask 당 쉐이더 조합 번호를 쓰기때문에 ,

정교한 쉐이더 캐싱이 필요하다 ( 조합의 사전정렬 후 244)

– 쉐이더를 미리 컴파일하는 것은 시간이 걸린다– Far Cry 1.3 의 쉐이더 캐쉬는 430 MB ( 압축하면

~23 MB 인 EXE 패치 ) 가 필요하다

Page 10: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Geometry Instancing• 오브젝트의 인스턴스를 n 만큼 랜더링할 때 n-1 의

드로우콜 비용이 절약될 가능성이 있다 *• Far Cry 는 식물의 랜더링 속도를 올리기 위해 주로

사용했다• 인스턴스 속성당 :

– Position– Size– Bending info– Rotation ( 필요할때만 )

• 인스턴스 속성의 수를 줄이는 ! 두가지 방법 :– 버텍스 쉐이더 상수

• 100 개 이상의 폴리곤을 가지고 있는 오브젝트에 사용– 속성을 연속된 열 (stream) 로 만든다

• 작은 오브젝트에 사용 (sprites, impostors)

* 인스턴싱은 동일한 데이터를 가지고 여러 사본을 만들어 랜더링 하는 방법이다 . n-1 의 비용이 절약된다는 말은 10 개의 오브젝트를 찍는다고 했을 때 10 번의 호출이 인스턴싱을 통해 최초 1 번만 들 수 있다는 이야기다

Page 11: [14.10.21] Far Cry and DX9 번역(shaderstudy)

VS 상수안의 인스턴스 속성• 많은 숫자의 폴리곤을 가진 오브젝트를 위한

최고의 방법• 인스턴스 인덱스를 연속적인 열 (stream) 로 넣어 덧붙인다

• SetStreamSourceFrequency 를 사용하여 다음과 같이 지오메트리 인스턴싱에 설정한다…SetStreamSourceFrequency( geomStream,

D3DSTREAMSOURCE_INDEXEDDATA | numInstances );SetStreamSourceFrequency( instStream,

D3DSTREAMSOURCE_INSTANCEDATA | 1 );

• SSSF( 위함수 ) 가 완료되면 당신은 버텍스 스트림의 빈도를 재설정 해야 한다 ( strNum, 1 )!

Page 12: [14.10.21] Far Cry and DX9 번역(shaderstudy)

const float4x4 cMatViewProj;const float4 cPackedInstanceData[ numInstances ];

float4x4 matWorld;float4x4 matMVP;

int i = IN.InstanceIndex;

matWorld[ 0 ] = float4( cPackedInstanceData[ i ].w, 0, 0, cPackedInstanceData[ i ].x );

matWorld[ 1 ] = float4( 0, cPackedInstanceData[ i ].w, 0, cPackedInstanceData[ i ].y );

matWorld[ 2 ] = float4( 0, 0, cPackedInstanceData[ i ].w, cPackedInstanceData[ i ].z );

matWorld[ 3 ] = float4( 0, 0, 0, 1 );

matMVP = mul( cMatViewProj, matWorld );OUT.HPosition = mul( matMVP, IN.Position );

VS 상수로 만들어낸 matMVP 와 변환된 버텍스로부터 VS 속성 ( 위치 & 크기 ) 들을 분석해낸다

Page 13: [14.10.21] Far Cry and DX9 번역(shaderstudy)

인스턴스 속성 stream(열 )

• 폴리곤이 많지 않은 오브젝트를 위한 최고의 방법• 인스턴스 데이터를 stream 에 추가해 넣는다• 버텍스 스트림 설정이 완료되면 다시 이전으로

되돌린다

Page 14: [14.10.21] Far Cry and DX9 번역(shaderstudy)

const float4x4 cMatViewProj;

float4x4 matWorld;float4x4 matMVP;

matWorld[ 0 ] = float4( IN.PackedInstData.w, 0, 0, IN.PackedInstData.x );

matWorld[ 1 ] = float4( 0, IN.PackedInstData.w, 0, IN.PackedInstData.y );

matWorld[ 2 ] = float4( 0, 0, IN.PackedInstData.w, IN.PackedInstData.z );

matWorld[ 3 ] = float4( 0, 0, 0, 1 );

matMVP = mul( cMatViewProj, matWorld );OUT.HPosition = mul( matMVP, IN.Position );

특성 stream 으로 만들어낸 matMVP 와 변환된 버텍스로부터 VS 속성 ( 위치 & 크기 ) 들을 분석해낸다

Page 15: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Geometry Instancing – 결과• 식물의 양에 따라 랜더링 속도를 40%까지 증가시킬 수 있다

( draw call 이 심하게 제한될 때 )

• 우리는 스프라이트의 거리비율을 증가시켜 , 좋은 비주얼과 적당한 랜더링 속도를 얻을 수 있었다

Page 16: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Scene 을 일반적으로 그렸을 때Scene 을 일반적으로 그렸을 때

Page 17: [14.10.21] Far Cry and DX9 번역(shaderstudy)

배치 시각화 – 동일한 식물 오브젝트를 채워 넣는 방법을 통해 하나의 드로우콜로 처리할

수 있었다 !

배치 시각화 – 동일한 식물 오브젝트를 채워 넣는 방법을 통해 하나의 드로우콜로 처리할

수 있었다 !

Page 18: [14.10.21] Far Cry and DX9 번역(shaderstudy)

High Dynamic Range RenderingHigh Dynamic Range Rendering

Page 19: [14.10.21] Far Cry and DX9 번역(shaderstudy)

High Dynamic Range Rendering*• A16B16G16R16F 랜더 타겟 포멧 사용• Alpha blending 과 filtering 은

필수다• 후처리를 위한 통합 솔루션• 후처리에 큰 영향을 주는 것들의

전체범위를 대체 (glare(눈부심 ), flares( 불꽃 ))

* HDR 참고http://www.slideshare.net/agebreak/ndc12-hdr

Page 20: [14.10.21] Far Cry and DX9 번역(shaderstudy)

HDR – 구현• Far Cry 의 HDR 표준 접근 방법

– Kawase’s bloom filters*– Reinhard’s tone mapping operator– See DXSDK sample

• Performance hint– 후처리를 위해 컬러를 RG, BA 로 색을 나눈 뒤 , G16R16F포멧의 두 MRT 로 읽어들여라 . 일부 카드에서 더 효율적으로 캐시를 처리한다

*GDC2004 - Practical Implementation of High Dynamic Range RenderingGDC2003 도 있다 뒤에 기록

Page 21: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Bloom from [Kawase03]• 반복적으로 작은 블러 필터를 적용한다 *• 원본 이미지와 bloom 을 합성한다

– 이상적으로는 HDR 공간에서 바로 tone mapping

* 전체를 blur 하기엔 부하가 크기에 축소 버퍼를 반복적으로 사용한다이 방법으로 넓은 범위를 더 빠르고 , 높은 품질로 blur 할 수 있다

Page 22: [14.10.21] Far Cry and DX9 번역(shaderstudy)

텍스처 샘플링 지점픽셀이 랜더링 되는 지점

1st pass

2nd pass

3rd pass

From [Kawase03]

필터 크기가 각 패스마다 증가

Page 23: [14.10.21] Far Cry and DX9 번역(shaderstudy)

No HDRNo HDR

Page 24: [14.10.21] Far Cry and DX9 번역(shaderstudy)

HDR (tone mapped scene + bloom + stars)

HDR (tone mapped scene + bloom + stars)

Page 25: [14.10.21] Far Cry and DX9 번역(shaderstudy)

[Reinhard02] – Tone Mapping*

1) scene 휘도를 계산 GPU 에서 log()값을 샘플링 완료 1X1 다운스케일링 , exp()(지수함수 ) 로 계산

2) 평균 휘도 α 를 목표로 확장

3) 톤맵핑 연산자 적용

• 휘도값을 Lumavg 의 값으로 천천히 맞춰가면서 2 와 3 의 단계에 따라 Lumavg 으로 대체해 빛의 적응을 시뮬레이션 한다

• 자세한 내용은 “ Tone Reproduction In Interactive Applications” 라는 Reinhard 의 세션에 참석해 봐라

*HDR값을 LDR 영역 값으로 돌려주는 것이 톤맵핑이다LDR 의 부족한 출력영역을 보정해 보다 리얼한 표현이 가능해진다http://www.cs.utah.edu/~reinhard/cdrom/

Page 26: [14.10.21] Far Cry and DX9 번역(shaderstudy)

HDR – 주의사항• 현재 FSAA(Full Screen Anti-Aliasing) 는 사용하지

않는다• 매우 느린 채우기 속도• float buffer blending 지원 필요• HDR관련 제작 1 :

– Light maps – Skybox

1) 프로토 타입을 위해 우리는 실제로 라이트맵 생성기 를 수정해 HDR맵과 HDR 스카이박스를 생성하도록 시도했다 . 그들은 좋아 보인다 . 그러나 우리는 패치에 포함하지 않았다 ( 아래 이유 때문에 )…– HDR light map textures 압축에 도전중이다– 대역폭 ( 사양 ) 요구사항이 더 커졌을 것이다– Far Cry 패치 크기가 거대했을 것이다– 모든 레벨을 조정하고 테스트하기엔 시간이 없었다

Page 27: [14.10.21] Far Cry and DX9 번역(shaderstudy)

결론• Dynamic flow control in

ps_3_0• Geometry Instancing• High Dynamic Range

Rendering

Page 28: [14.10.21] Far Cry and DX9 번역(shaderstudy)

References• [Kawase03] Masaki Kawase,

“Frame Buffer Postprocessing Effects in DOUBLE-S.T.E.A.L (Wreckless),” Game Developer’s Conference 2003

• [Reinhard02] Erik Reinhard, Michael Stark, Peter Shirley and James Ferwerda, “Photographic Tone Reproduction for Digital Images,” SIGGRAPH 2002.

Page 29: [14.10.21] Far Cry and DX9 번역(shaderstudy)

Questions

???