SlideShare a Scribd company logo
1 of 71
마비노기2
캐릭터 렌더링 기술
      신규개발 3본부 1실 GTR팀
   전형규(henjeon@nexon.co.kr)
발표자 소개

 넥슨 8년차 프로그래머
    현재 데브캣 스튜디오 GTR팀 팀장


 참여 프로젝트:
    마비노기
    XBOX360 마비노기
    마비노기2



 주요 관심사:
    Computer Graphics
    Real–Time Rendering
발표 내용

 문제 정의 및 관련 연구 리뷰
      해결하고자 하는 문제를 설명하고 관련된 연구 자료들을 리뷰.




 새로운 해법 제안
      마비노기2 프로젝트에서 이 문제를 어떻게 해결했는지 설명.


 시연
      간단한 데모를 통해서 제안한 방법에 오류가 없음을 증명.
참고사항

 PC 플랫폼, DX9 API가 주 논의 대상
    아직도 절반 이상의 PC가 DX9만 지원한다.




 다소 난이도 있는 내용
    관련 지식이 없다면 이해하기 어려울 수 있다.
문제 정의
Problem Definition
현 세대 캐릭터 렌더링의 특징




              Assassin’s Creed, Ubisoft Montreal
멀티 패스 렌더링   Multi Pass Rendering




                              KILLZONE2, Guerrilla Games
많은 수의 본   Hundreds of Bones




                              Uncharted2, Naughtydog
캐릭터 커스터마이징   Character Customization




                               APB, Realtime Worlds
오브젝트 모션 블러   Object Motion-Blur




                                  Lost Planet, Capcom
현 세대 캐릭터 렌더링의 특징


 매 프레임, 캐릭터 하나를 적어도 5번 스키닝한다.
            그림자      +1

            깊이       +1

            속도       +2

            메인 셰이딩   +1

            Total     5
과거에는 여러 번 스키닝해도 OK


 Bone 수가 많지 않았다.
    대부분 100개 미만




 하드웨어 측면에서 Shader 유닛이 분리되어 있었다.
    Vertex Shader 유닛과 Pixel Shader 유닛이 물리적으로 분리되어 있었다.
    대부분 PS 유닛이 병목이므로 VS 유닛을 비효율적으로 사용해도 괜찮았다.
그러나 지금은…


 Bone 수가 매우 많다.
    마비노기2의 캐릭터 한 명은 약 200개의 bone을 사용한다(전작의 10배).




 통합 셰이더 모델     Unified Shader Architecture

    VS와 PS가 물리적으로 같은 유닛에서 처리된다.
    VS 처리 유닛이 적을 수록 그 만큼 PS에 더 많은 유닛이 할당된다.
그러나 지금은…


 복잡한 커스터마이징
   커스터마이징 파라메터를 전달하려면 셰이더 상수가 많이 필요하다.




 오브젝트 모션 블러
   속도 계산을 위해서 이전 프레임의 위치까지 스키닝해야 한다.
   처리해야 할 bone 수가 두 배로 늘었다고 볼 수 있다.
현 세대 캐릭터 렌더링의 특징



 스키닝이 병목이다.
    그 중에서 특히 셰이더 상수 전송이 병목이다.
관련 연구 리뷰
 Related Works
VTF 스키닝                     Vertex Texture Fetch Skinning



 “텍스쳐로” 매트릭스 팔레트를 전달한다.
   VS에서 VTF로 bone 정보를 읽는다.




                                                               Skinned Instancing, Nvidia
    http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SkinnedInstancing/doc/SkinnedInstancingWhitePaper.pdf
VTF 스키닝       Vertex Texture Fetch Skinning




 장점
      bone 수가 많을수록 일반 스키닝보다 빠르다.
      메모리 사용량이 비교적 적다.




 단점
      VTF 오버헤드가 심하다.
           버텍스 하나당 최소 3번, 최대 12번의 VTF가 필요


      모든 렌더링 패스에서 스키닝이 반복되는 점은 변함이 없다.
R2VB 스키닝       Render To Vertex Buffer Skinning



 스키닝 계산을 PS에서 처리한다.
    VTF 스키닝과 유사한 기법.
    ATI GPU의 R2VB 기능을 이용해서 bone 행렬 계산과 스키닝 모두를 PS에서 처리.




                              R2VB Animation, ATI
                     http://developer.amd.com/downloads/R2VB-Animation.zip
R2VB 스키닝        Render To Vertex Buffer Skinning




 장점
      매우 빠르다.




 단점
      ATI GPU에서만 동작한다.
      메모리 사용량이 비교적 많다.
소프트웨어 스키닝             Software Skinning



 CPU 혹은 Compute Shader로 스키닝 처리




             Unigine Engine, Unigine Corp.
                                 http://unigine.com
소프트웨어 스키닝                 Software Skinning




 장점
      멀티스레딩 최적화를 통해서 좋은 성능을 낼 수 있다.
      메모리 사용량이 적다.




 단점
      최적화하기가 매우 어렵다.
      하드웨어 제약이 심하다.
          멀티 코어 CPU 혹은 DX11 클래스 하드웨어가 필요하다.
VT 스키닝 소개
Introduction of VT Skinning
VT 스키닝   Vertex Texture Skinning



 R2VB 스키닝과 유사한 기법
    R2VB 대신 VTF를 사용한다.
    텍스쳐에 스키닝 결과를 저장하고 이후 패스에서 VTF로 그 결과를 참조한다.




   메시       VT 텍스쳐
                                   프레임 버퍼
                        VS   PS
VT 텍스쳐    Vertex Transformation Texture



 스키닝 결과가 기록된 텍스쳐
   FP(Floating Point) 포맷의 렌더 타겟 가능 텍스쳐.
   스키닝한 버텍스의 위치, 노멀, 탄젠트 벡터가 저장된다.




      렌더링된 VT 텍스쳐의 예. 좌: RGB, 우: Alpha.
    텍스쳐 크기는 512*512, 포맷은 FP16(A16R16G16B16F)
장점   Pros




 VS가 매우 간단해진다.
      버텍스 변환 패스를 제외하고 스키닝 계산이 없기 때문.


 빠르다.
      버텍스 당 VTF를 1~2회만 하므로 VTF 스키닝보다 매우 빠르다.


 하드웨어 요구사항이 낮다.
      대부분의 SM3 클래스 GPU가 VTF를 지원한다.
장점   Pros




 캐릭터 커스터마이징 처리가 쉽다.
      VS 상수 레지스터의 대부분을 차지하던 매트릭스 팔레트가 없어졌다.

      마비노기2의 레지스터 활용 예:
          커스터마이징 컬러 테이블
          모핑 파라메터



 오브젝트 모션 블러 처리가 쉽다.
      VT 텍스쳐를 더블 버퍼링하면 버텍스의 속도를 간단하게 계산할 수 있다.
      이전 프레임의 매트릭스 팔레트를 보관할 필요가 없다.
단점   Cons



 메모리 사용량이 높다.
      최적화 전: A32R32G3B32F 4장 사용(1장은 이전 프레임 텍스쳐)
      최적화 후: A16R16G16B16F 2장 사용 (1장은 이전 프레임 텍스쳐)

      수백명의 캐릭터를 렌더링하려면 적어도 1024 * 1024 크기의 VT텍스쳐가 필요하다.




 VTF는 빠르지 않다.
      DX9 클래스 GPU: 스키닝 계산보다 매우 느리다(약 6배)
      DX10 클래스 GPU: 충분히 빠르다.

      VT 스키닝으로 얻는 전체적인 성능 이득이 더 크므로 큰 문제는 아니다.
시연
DEMO
VT 스키닝 구현
 Implementations
VT 텍스쳐 렌더링                  VT Texture Rendering



 각 버텍스를 스키닝한 후에 “점”으로 출력
    D3DPT_POINTLIST로 DP()
VT 텍스쳐 형식       VT Texture Format



 4채널 FP32 세 장을 사용
               R32F G32F B32F A32F
         RT0     Position XYZ
         RT1      Normal XYZ
         RT2     Tangent XYZ




 최적화하면 4채널 FP16 한 장에 넣을 수 있다.
    자세한 설명은 이후 슬라이드에서.
스키닝 버텍스 포맷                    Skinned Vertex Format



 일반적인 스키닝 버텍스와 유사
     Position : float3
     Normal : float3
     Tangent : float3
     BlendIndices : uint32
     BlendWeights : uint64
     InstanceIndex : uint32


 InstanceIndex
     버텍스 n개가 있다면,
     각 버텍스는 0부터 n-1까지 순서대로 InstanceIndex를 갖는다.

     VS는 이 값으로부터 VT 텍스쳐 출력 좌표를 계산한다.
스키닝 VS                   Skinning Vertex Shader       1/3


struct MeshVertexTransformationVSInput
{
         float4   position          : POSITION;
         float3   normal            : NORMAL;
         float3   tangent           : TANGENT;
         float4   boneIndices       : BLENDINDICES;
         float4   blendWeights      : BLENDWEIGHT;
         float4   instanceIndex     : TEXCOORD0;
};
struct MeshVertexTransformationVSOutput
{
         float4   vtPosition        : POSITION;
         float3   position          : TEXCOORD0;
         float3   normal            : TEXCOORD1;
         float3   tangent           : TEXCOORD2;
};
스키닝 VS                     Skinning Vertex Shader                                                2/3


MeshVertexTransformationVSOutput VertexTransformationVSMain(
        MeshVertexTransformationVSInput input)
{
        MeshVertexTransformationVSOutput output;

        // 스키닝
        int4 boneIndices = (int4)input.boneIndices;
        float4 srcPosition = input.position;
        float3 srcNormal = input.normal;
        float3 srcTangent = input.tangent;

        input.position.xyz = 0.0f;
        input.normal = 0.0f;
        input.tangent = 0.0f;

        for (int i = 0; i < 4; ++i)
        {
                    float4x3 boneMatrix = BoneMatrices[boneIndices[i]];
                    input.position.xyz += mul(srcPosition, boneMatrix) * input.blendWeights[i];
                    input.normal += mul(srcNormal, (float3x3)boneMatrix) * input.blendWeights[i];
                    input.tangent += mul(srcTangent, (float3x3)boneMatrix) * input.blendWeights[i];
        }
스키닝 VS                 Skinning Vertex Shader            3/3


    // 출력 위치를계산
    float instanceOffset = dot(
               float2(input.instanceIndex.xy),
               float2(1.0f, 256.0f));

    float2 texcoord;
    texcoord.x = instanceOffset / VTTextureWidth.;
    texcoord.y = floor(texcoord.x) / VTTextureHeight;

    float2 outputPos = frac(texcoord);
    outputPos.x = outputPos.x * 2.0f - 1.0f;
    outputPos.y = 1.0f - outputPos.y * 2.0f;

    // 출력
    output.vtPosition = float4(outputPos, 0.0f, 1.0f);
    output.position = input.position.xyz;
    output.normal = input.normal;
    output.tangent = input.tangent;
    return output;
}
스키닝 PS                     Skinning Pixel Shader


struct MeshVertexTransformationPSInput
{
          float3    position         : TEXCOORD0;
          float3    normal           : TEXCOORD1;
          float3    tangent          : TEXCOORD2;
};
struct VertexTransformationPSOutput
{
          float4    position         : COLOR0;
          float4    normal           : COLOR1;
          float4    tangent          : COLOR2;
};
VertexTransformationPSOutput VertexTransformationPSMain(MeshVertexTransformationPSInput input)
{
           VertexTransformationPSOutput output;

        output.position = float4(input.position, 0.0f);
        output.normal = float4(input.normal, 0.0f);
        output.tangent = float4(input.tangent, 0.0f);

        return output;
}
일반 버텍스 포맷                    Common Vertex Format




 VT 텍스쳐를 샘플링하기 위해 InstanceIndex가 필요
    Color : uint32
    TexCoord : float2
    InstanceIndex : uint32


 기하(Geometry) 채널이 없기 때문에 크기가 매우 작다.
    그림자, 깊이 렌더링 같은 간단한 셰이딩은 버텍스 크기가 4 byte.
VT 텍스쳐 샘플링                                      VT Texture Sampling


sampler VTSampler = sampler_state
{
        MinFilter = Point;
        MagFilter = Point;
        MipFilter = None;
        AddressU = Wrap;
        AddressV = Wrap;
};

float4 SampleVTTexture(float2 instanceIndex)
{
         float instanceOffset = dot(input.instanceIndex, float2(1.0f, 256.0f));

         float2 texcoord;
         texcoord.x = instanceOffset / VTTextureWidth;
         texcoord.y = floor(texcoord.x) / VTTextureHeight;

         return tex2Dlod(VTSampler, float4(texcoord, 0.0f, 0.0f));
}
VT 스키닝 최적화
  Optimizations
16bit FP 텍스쳐 사용                16-bit FP Texturing



  FP16 : s1e5m10
      부호 1 bit, 지수 5 bit, 가수 10 bit
      손실 없이 표현할 수 있는 정수 범위 : -2048 ~ 2048



  노멀과 탄젠트는 사실상 정밀도 손실이 없다.


  위치를 그냥 FP16에 저장하면 오차가 너무 크다.
      대신, 카메라 공간(Camera Space)으로 옮겨서 저장한다.
      카메라로부터 멀리 떨어질 수록 오차가 커지지만,
      원근 투영 때문에 오차가 눈에 띄지 않는다.
노멀을 채널 하나에 저장                               Packing normal into one fp16



 1. Map Projection 함수로 노멀벡터를 구면좌표로 옮긴다.
     http://aras-p.info/texts/CompactNormalStorage.html를 참고함

     Lambert azimuthal equal-area projection 사용해서,
     노멀 벡터 (x, y, z)를 (s, t)로 변환
     (http://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection).



 2. FP16 하나에 (s, t)를 패킹
     s와 t를 각각 7bit씩 fp16에 패킹한다.

     (0, 0, -1)에 singularity가 있으므로 항상 z가 양수가 되도록 만들고,
     1비트는 z의 부호로 사용한다.
NormalToFP16() Shader
float NormalToFP16(float3 n)
{                                                  // XXXXXXX.yyy
   // z 부호를저장한다.                                   float bit10 = bit7.x + split.y;
   float zSign = sign(n.z);
   n.z *= zSign;                                   // 0.1xxxxxxxyyy * 2^YYYY
                                                   float mantissa = bit10.x / 128.0f / 2.0f +
  // [-1,1] -> [0,1]                                                512.0f/1024.0f;
  // Lambert Azimuthal Equal-Area projection       float exponent = split.x;
  float f = sqrt(8 * n.z + 8);                     float packed = ldexp(mantissa, exponent);
  float2 biased = n.xy / f + 0.5f;
                                                   return zSign * packed;
  // 0.xxxxxxx -> XXXXXXX.0                    }
  // 0.yyyyyyy -> YYYYYYY.0
  float2 bit7 = round(biased * 127.0f);

  // YYYYYYY -> YYYY.yyy
  float2 split = bit7.y / 8.0f;
  split.x = floor(split.x);
  split.y -= split.x;
FP16ToNormal() Shader
float3 FP16ToNormal(float packed)                          // XXXXXXX
{                                                          // YYYYYYY
   float sgn = sign(packed);                               float2 bit7;
                                                           bit7.x = split.x;
  float mantissa;                                          bit7.y = (exponent + split.y) * 8.0f;
  float exponent;
  mantissa = frexp(packed, exponent);                      // [0, 1]
  mantissa = abs(mantissa);                                float2 biased = bit7 / 127.0f;

  // XXXXXXX.yyy                                           // [-1,1]
  float bit10 = (mantissa - 512.0f/1024.0f) * 2.0f *       // Lambert Azimuthal Equal-Area projection
                   128.0f;                                 float2 fenc = biased * 4 - 2;
                                                           float f = dot(fenc, fenc);
  // XXXXXX, 0.yyy
  float2 split;                                            float g = sqrt(1 - f/4);
  split.x = floor(bit10);
  split.y = bit10 - split.x;                               return float3(fenc * g, sgn*(1 - f/2));
                                                       }
탄젠트 제거         Tangent vector elimination




 t’ = normalize(t – dot(t, n’)n’)
      노멀 n, 탄젠트 t가 있을 때 스키닝된 노멀과 탄젠트를 각각 n’, t’라 하면,
      노멀과 탄젠트가 서로 직교하는 성질을 이용해서 t’를 얻을 수 있다.

                    n
              n'




                                     t'

                                          t
탄젠트 제거      Tangent vector elimination



 탄젠트 컴포넌트를 일반 버텍스 포맷으로 옮긴다.
    거의 대부분의 경우, 탄젠트 벡터는 메인 셰이딩 패스에서만 사용.
    탄젠트 컴포넌트를 메인 셰이딩 패스의 버텍스로 옮긴다.




 4채널 FP16에 모든 기하 정보를 기록
                R16F G16F B16F A16F
                                    Normal
          RT0      Position XYZ      XYZ




    최초 구현의 1/6로 줄어들었다.
버텍스 중복 제거                 Redundant vertex removal



 중복되는 스키닝 버텍스를 제거
   중복되는 스키닝 버텍스를 제거하고,
   일반 버텍스의 InstanceIndex를 다시 매핑한다.

   마비노기2의 경우, 평균적으로 25%의 버텍스가 제거되었다.



                              0    1   2   3   4     5




                              0    0   1   1   1     2

     skinning positions           instance indices
VT 라이팅 소개
Introduction of VT Lighting
VT 라이팅      Vertex Texture Lighting



 VT 텍스쳐를 사용하는 Per Vertex Deferred Lighting




        좌: VT Lighting off, 중: VT Lighting only, 우: VT Lighting on
장점   Pros



 일반적인 Deferred Lighting 기법의 단점을 해결
       메모리 사용량이 비교적 적다.
       조명 처리 비용이 해상도에 무관하다.
       Anti-Aliasing이 자유롭다.
       반투명한 물체 처리에 아무런 제약이 없다.

 Light Buffer 렌더링이 매우 빠르다.
       Light Buffer 렌더링 비용과 프레임 버퍼 해상도가 무관하다.


 Light Buffer가 시점에 독립적(View Independent)이다.
       정적인 물체와 조명에 대해서 이전 프레임의 렌더링 결과를 사용할 수 있다.
단점   Cons



 Per Pixel이 아니다.
       Light Buffer 렌더링에 노멀맵을 사용할 수 없어서 Gloss 재질 표현이 어렵다.


 장면이 복잡할수록 Light Buffer 렌더링이 느리다.
       렌더링 속도와 메모리 사용량이 장면의 버텍스 수에 비례한다.



 건물, 배경에 적용하기 어렵다.
       불가능하지는 않다.
       마비노기2는 건물과 배경에도 VT Lighting을 사용한다.


 하드웨어 요구사항이 높다.
       정수형 텍스쳐(A8R8G8B8)의 VTF가 가능해야 한다(DX10 클래스 GPU부터 지원)
시연   DEMO
VT 라이팅 구현
 Implementations
VL 텍스쳐    Vertex Light Texture



 일반 DL의 Light Buffer와 동일
     각 버텍스의 조명 결과가 저장된다.
     최종 조명 처리 패스의 VS에서 VTF로 참조한다.
     속도를 위해서 LDR 조명이라고 가정하고 A8R8G8B8 포맷을 사용한다.
     VT 텍스쳐와 동일한 크기를 가진다.




               좌: VT Texture, 우: VL Texture
VL 텍스쳐 렌더링          VL Texture Rendering



 광원을 “선”으로 렌더링
    광원 정보를 버텍스에 넣고 D3DPT_LINELIST으로 렌더링한다.
    Addtive Blending으로 조명 결과를 누적시킨다.




                      +
VL 텍스쳐 렌더링   VL Texture Rendering




                        광원 A만 받는
                        버텍스들

                       광원 A와 B 모두 받는 버텍스들

                        광원 B만 받는
                        버텍스들
Light Mesh

  같은 종류의 광원들을 하나의 Mesh로 합친다
     Light Mesh의 모양과 실제 광원의 바운딩 볼륨은 서로 무관하다.
     Light Mesh는 VT 텍스쳐 공간에 있는 라인들의 집합이다.

     광원을 하나로 합치면 DP() 한 번에 여러 광원을 렌더링할 수 있다.




  매 프레임 CPU로 생성한다.
     각 광원 볼륨과 메시 볼륨이 교차하면,
     그 메시의 VT 텍스쳐 영역을 덮는 라인을 Light Mesh에 추가한다.

     n개의 광원과 m개의 메시가 있을 경우 알고리즘의 복잡도는 O(n*m).
     공간 분할 알고리즘을 사용해서 성능을 향상시킬 수 있다.
라이트 메시 버텍스 포맷                    Light Mesh Vertex Format



 광원 종류마다 다르다.


 점광원의 예
   VT Position : float2
   Light Position : float3
   Light Color : uint32
   Light Radius : float

   VT 텍스쳐 공간은 2d 이므로 VT Positoin 타입으로 float2를 사용.
VT 라이팅 VS                             VT Lighting Vertex Shader


struct VertexLightingVSInput
{
          float2    position            : POSITION;
          float4    lightColor          : COLOR;
          float3    lightPos            : TEXCOORD0;
          float     lightRadius         : TEXCOORD1;
};
struct VertexLightingVSOutput
{
          float4    position            : POSITION;
          float4    lightColor          : COLOR;
          float3    lightPos            : TEXCOORD0;
          float     lightRadius         : TEXCOORD1;
};
VertexLightingVSOutput VertexLightingVSMain(VertexLightingVSInput input)
{
          VertexLightingVSOutput output;
          output.position = float4(input.position, 0.0f, 1.0f);
          output.lightColor = input.lightColor;
          output.lightPos = mul(float4(input.lightPos, 1.0f), (float4x3)ViewMatrix);
          output.lightRadius = input.lightRadius;
          return output;
}
VT 라이팅 PS                         VT Lighting Pixel Shader


struct VertexLightingPSInput
{
          float4    lightColor        : COLOR;
          float3    lightPos          : TEXCOORD0;
          float     lightRadius       : TEXCOORD1;
          float2    vPos              : VPOS;
};
float4 VertexLightingPSMain(VertexLightingPSInput input) : COLOR
{
          // VT텍스쳐를 샘플링해서 버텍스 위치와 노멀을 얻는다.
          float3 position;
          float3 normal;
          SampleVertex(input.vPos / RenderTargetExtent, position, normal);

         // 점광원처리
         float4 illuminance = ComputePointLight(position, normal, input.lightColor, input.lightRadius);

         // 출력
         return illuminance;
}
VT 라이팅 Technique                                      VT Lighting Technique


technique VertexLighting
{
         pass
         {
                   CullMode          = None;
                   FillMode          = Solid;

                  ZEnable            = false;

                  AlphaBlendEnable   =   true;
                  SrcBlend           =   One;
                  DestBlend          =   One;
                  BlendOp            =   Add;

                  AlphaTestEnable    = false;

                  VertexShader       = compile vs_3_0 VertexLightingVSMain();
                  PixelShader        = compile ps_3_0 VertexLightingPSMain();
         }
}
향후 과제
Future Works
하드웨어 호환성             Hardware Compatibility



 구형 ATI GPU는 VTF를 지원하지 않는다.
    SM3를 지원하는 GPU조차 그렇다.
    R2VB로 VT Skinning을 구현해야 한다.



 DX9 클래스 GPU는 FP16 텍스쳐를 VTF할 수 없다.
    DX9클래스 GPU는 R32F와 A32R32G32B32F의 VTF만 지원한다.

    답이 없다.
DX10,11로 포팅          Porting to DX10,11




 DX10에서는 VT Skinning이 필요없다.
    Stream Output이나 Constant Buffer를 사용하면 VT Skinning이 필요없다.


 DX11또한 VT Skinning이 필요없다.
    Compute Shader를 사용해서 스키닝을 처리할 수 있다.


 만들고 측정해 봐야 알 수 있다.
    VT Skinning이 필요없을 것 같다는 예측일 뿐.
버텍스 포스트 프로세싱                           Vertex Post Processing




 Special Vertex Effects
      VT텍스쳐에 여러 가지 포스트 이펙트 필터를 적용해서 ,
      재미있는 효과를 만들 수 있다.



 GPU Physics Simulation
      soft body simulation, jiggle bone 처리 등을 GPU로 옮길 수 있다.
복잡한 스키닝                                      More Advanced Skinning Method



 LBS(Linear Blend Skinning)는 이제 그만좀 쓰자.
        Spherical Blend Skinning이나 Dual Quaternion Skinning을 사용




                           Skinning with Dual Quaternions, Nvidia
   http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/QuaternionSkinning/doc/QuaternionSkinning.pdf
Real-Time GI        Real-Time Global Illumination



  VT Lighting의 View-Independency를 활용
       VT Lighting은 프레임 당 수백개~수천개의 다이나믹 라이트를 처리할 수 있다.

       View-Independency를 활용해서 전체 계산을 여러 프레임으로 분산하면,
       한 장면에 수만개의 광원을 적용할 수 있다.




  VPL(Virtual Point Light) 기반 GI
       RSM(Reflective Shadow Map) 같은 알고리즘에 응용할 수 있을 것이다.
요약
Summary
마비노기2의 캐릭터 렌더링


 VT Skinning으로 캐릭터 렌더링을 고속으로 처리
     캐릭터 커스터마이징과 오브젝트 모션 블러를 VT Skinning 기법으로 처리,
     셰이더 상수 병목 문제를 해결했다.



 VT Lighting으로 Deferred Lighting
     기존의 DL 기법의 문제점들을 해결한 Per Vertex DL 기법으로,
     많은 수의 광원을 효과적으로 처리했다.
Question?
henjeon@nexon.co.kr
WE ARE HIRING!

More Related Content

What's hot

Compute shader DX11
Compute shader DX11Compute shader DX11
Compute shader DX11민웅 이
 
[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shadingMinGeun Park
 
Cascade Shadow Mapping
Cascade Shadow MappingCascade Shadow Mapping
Cascade Shadow MappingSukwoo Lee
 
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)포프 김
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012devCAT Studio, NEXON
 
Compute shader
Compute shaderCompute shader
Compute shaderQooJuice
 
Ndc12 이창희 render_pipeline
Ndc12 이창희 render_pipelineNdc12 이창희 render_pipeline
Ndc12 이창희 render_pipelinechangehee lee
 
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018devCAT Studio, NEXON
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013devCAT Studio, NEXON
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기강 민우
 
[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅
[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅
[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅DongMin Choi
 
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화Jaeseung Ha
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희changehee lee
 
[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능Yongha Kim
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리MinGeun Park
 
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기Yongha Kim
 
[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬KyeongWon Koo
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근MinGeun Park
 

What's hot (20)

Compute shader DX11
Compute shader DX11Compute shader DX11
Compute shader DX11
 
[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading
 
Motion blur
Motion blurMotion blur
Motion blur
 
Cascade Shadow Mapping
Cascade Shadow MappingCascade Shadow Mapping
Cascade Shadow Mapping
 
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
 
Compute shader
Compute shaderCompute shader
Compute shader
 
Ndc12 이창희 render_pipeline
Ndc12 이창희 render_pipelineNdc12 이창희 render_pipeline
Ndc12 이창희 render_pipeline
 
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
 
[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅
[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅
[NDC 2018] 신입 개발자가 알아야 할 윈도우 메모리릭 디버깅
 
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
[NDC 2014] 던전앤파이터 클라이언트 로딩 최적화
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희
 
[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능[NDC 2009] 행동 트리로 구현하는 인공지능
[NDC 2009] 행동 트리로 구현하는 인공지능
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
 
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
 
[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
 

Viewers also liked

한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010devCAT Studio, NEXON
 
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용lswsox
 
KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템
KGC2010   김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템KGC2010   김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템
KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템Jubok Kim
 
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템tcaesvk
 
3 d 그래픽 엔진 비교
3 d 그래픽 엔진 비교3 d 그래픽 엔진 비교
3 d 그래픽 엔진 비교yoonhs306
 
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현MinGeun Park
 
이진훈, 영상을이용한팀얼라인먼트, NDC2010
이진훈, 영상을이용한팀얼라인먼트, NDC2010이진훈, 영상을이용한팀얼라인먼트, NDC2010
이진훈, 영상을이용한팀얼라인먼트, NDC2010devCAT Studio, NEXON
 
[KGC2014] 울프나이츠 엔진 프로그래밍 기록
[KGC2014] 울프나이츠 엔진 프로그래밍 기록 [KGC2014] 울프나이츠 엔진 프로그래밍 기록
[KGC2014] 울프나이츠 엔진 프로그래밍 기록 JiUng Choi
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9진현 조
 
게임 개발을 위한 렌더링 기법 한성환
게임 개발을 위한 렌더링 기법   한성환게임 개발을 위한 렌더링 기법   한성환
게임 개발을 위한 렌더링 기법 한성환Yggdrasil610
 
[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기changehee lee
 
모바일 엔진 개발기
모바일 엔진 개발기모바일 엔진 개발기
모바일 엔진 개발기changehee lee
 
내 손에 픽셀을 쥐어다오
내 손에 픽셀을 쥐어다오내 손에 픽셀을 쥐어다오
내 손에 픽셀을 쥐어다오KwangSam Kim
 
05_벡터와 매트릭스
05_벡터와 매트릭스05_벡터와 매트릭스
05_벡터와 매트릭스noerror
 
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기Kiheon Park
 
셰이더 합성
셰이더 합성셰이더 합성
셰이더 합성JiUng Choi
 
[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션
[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션
[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션Nexon Korea
 
Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더동석 김
 
[데브루키160409 박민근] UniRx 시작하기
[데브루키160409 박민근] UniRx 시작하기[데브루키160409 박민근] UniRx 시작하기
[데브루키160409 박민근] UniRx 시작하기MinGeun Park
 

Viewers also liked (20)

한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
한상원, 친아티스트 3D 캐릭터 리깅, NDC2010
 
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉   공개용
게임 캐릭터의 실시간 렌더링을 위한 리깅 테크닉 공개용
 
KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템
KGC2010   김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템KGC2010   김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템
KGC2010 김주복, 김충효 - M2 프로젝트의 절차적 리깅 시스템
 
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
NDC 2013, 마비노기 영웅전 개발 테크니컬 포스트-모템
 
3 d 그래픽 엔진 비교
3 d 그래픽 엔진 비교3 d 그래픽 엔진 비교
3 d 그래픽 엔진 비교
 
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
유니티의 툰셰이딩을 사용한 3D 애니메이션 표현
 
이진훈, 영상을이용한팀얼라인먼트, NDC2010
이진훈, 영상을이용한팀얼라인먼트, NDC2010이진훈, 영상을이용한팀얼라인먼트, NDC2010
이진훈, 영상을이용한팀얼라인먼트, NDC2010
 
[KGC2014] 울프나이츠 엔진 프로그래밍 기록
[KGC2014] 울프나이츠 엔진 프로그래밍 기록 [KGC2014] 울프나이츠 엔진 프로그래밍 기록
[KGC2014] 울프나이츠 엔진 프로그래밍 기록
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
게임 개발을 위한 렌더링 기법 한성환
게임 개발을 위한 렌더링 기법   한성환게임 개발을 위한 렌더링 기법   한성환
게임 개발을 위한 렌더링 기법 한성환
 
[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기
 
모바일 엔진 개발기
모바일 엔진 개발기모바일 엔진 개발기
모바일 엔진 개발기
 
Visual shock vol.2
Visual shock   vol.2Visual shock   vol.2
Visual shock vol.2
 
내 손에 픽셀을 쥐어다오
내 손에 픽셀을 쥐어다오내 손에 픽셀을 쥐어다오
내 손에 픽셀을 쥐어다오
 
05_벡터와 매트릭스
05_벡터와 매트릭스05_벡터와 매트릭스
05_벡터와 매트릭스
 
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
 
셰이더 합성
셰이더 합성셰이더 합성
셰이더 합성
 
[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션
[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션
[NDC 14] '미쿠미쿠하게 해줄게' - MMD MV 제작 사례와 매력적인 캐릭터 애니메이션
 
Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더
 
[데브루키160409 박민근] UniRx 시작하기
[데브루키160409 박민근] UniRx 시작하기[데브루키160409 박민근] UniRx 시작하기
[데브루키160409 박민근] UniRx 시작하기
 

Similar to Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술

[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)해강
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blogozlael ozlael
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011devCAT Studio, NEXON
 
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들Dae Hyek KIM
 
Implements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayImplements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayYEONG-CHEON YOU
 
NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스Sungik Kim
 
[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소
[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소
[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소강 민우
 
[14.10.10] TressFX 번역(self)
[14.10.10] TressFX 번역(self)[14.10.10] TressFX 번역(self)
[14.10.10] TressFX 번역(self)해강
 
Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01SangYun Yi
 
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로Hyunwoo Kim
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...종빈 오
 
[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유Hwan Min
 
[0326 박민근] deferred shading
[0326 박민근] deferred shading[0326 박민근] deferred shading
[0326 박민근] deferred shadingMinGeun Park
 
[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...
[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...
[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...종빈 오
 
유니티 게임 그래픽스 아트 개발 사례 분석
유니티 게임 그래픽스 아트 개발 사례 분석유니티 게임 그래픽스 아트 개발 사례 분석
유니티 게임 그래픽스 아트 개발 사례 분석SangYun Yi
 

Similar to Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술 (20)

[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blog
 
Modern gpu optimize
Modern gpu optimizeModern gpu optimize
Modern gpu optimize
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011
 
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
 
Implements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayImplements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture Array
 
NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스
 
[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소
[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소
[IGC2018] 퍼니파우 최재영 - 감성을 위한 개발요소
 
[14.10.10] TressFX 번역(self)
[14.10.10] TressFX 번역(self)[14.10.10] TressFX 번역(self)
[14.10.10] TressFX 번역(self)
 
Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01
 
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
 
[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유
 
[0326 박민근] deferred shading
[0326 박민근] deferred shading[0326 박민근] deferred shading
[0326 박민근] deferred shading
 
D2 Rain (1/2)
D2 Rain (1/2)D2 Rain (1/2)
D2 Rain (1/2)
 
[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...
[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...
[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peelin...
 
D2 Havok
D2 HavokD2 Havok
D2 Havok
 
유니티 게임 그래픽스 아트 개발 사례 분석
유니티 게임 그래픽스 아트 개발 사례 분석유니티 게임 그래픽스 아트 개발 사례 분석
유니티 게임 그래픽스 아트 개발 사례 분석
 
D2 Rain (2/2)
D2 Rain (2/2)D2 Rain (2/2)
D2 Rain (2/2)
 

Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술

  • 1. 마비노기2 캐릭터 렌더링 기술 신규개발 3본부 1실 GTR팀 전형규(henjeon@nexon.co.kr)
  • 2. 발표자 소개 넥슨 8년차 프로그래머 현재 데브캣 스튜디오 GTR팀 팀장 참여 프로젝트: 마비노기 XBOX360 마비노기 마비노기2 주요 관심사: Computer Graphics Real–Time Rendering
  • 3. 발표 내용 문제 정의 및 관련 연구 리뷰 해결하고자 하는 문제를 설명하고 관련된 연구 자료들을 리뷰. 새로운 해법 제안 마비노기2 프로젝트에서 이 문제를 어떻게 해결했는지 설명. 시연 간단한 데모를 통해서 제안한 방법에 오류가 없음을 증명.
  • 4. 참고사항 PC 플랫폼, DX9 API가 주 논의 대상 아직도 절반 이상의 PC가 DX9만 지원한다. 다소 난이도 있는 내용 관련 지식이 없다면 이해하기 어려울 수 있다.
  • 6. 현 세대 캐릭터 렌더링의 특징 Assassin’s Creed, Ubisoft Montreal
  • 7. 멀티 패스 렌더링 Multi Pass Rendering KILLZONE2, Guerrilla Games
  • 8. 많은 수의 본 Hundreds of Bones Uncharted2, Naughtydog
  • 9. 캐릭터 커스터마이징 Character Customization APB, Realtime Worlds
  • 10. 오브젝트 모션 블러 Object Motion-Blur Lost Planet, Capcom
  • 11. 현 세대 캐릭터 렌더링의 특징 매 프레임, 캐릭터 하나를 적어도 5번 스키닝한다. 그림자 +1 깊이 +1 속도 +2 메인 셰이딩 +1 Total 5
  • 12. 과거에는 여러 번 스키닝해도 OK Bone 수가 많지 않았다. 대부분 100개 미만 하드웨어 측면에서 Shader 유닛이 분리되어 있었다. Vertex Shader 유닛과 Pixel Shader 유닛이 물리적으로 분리되어 있었다. 대부분 PS 유닛이 병목이므로 VS 유닛을 비효율적으로 사용해도 괜찮았다.
  • 13. 그러나 지금은… Bone 수가 매우 많다. 마비노기2의 캐릭터 한 명은 약 200개의 bone을 사용한다(전작의 10배). 통합 셰이더 모델 Unified Shader Architecture VS와 PS가 물리적으로 같은 유닛에서 처리된다. VS 처리 유닛이 적을 수록 그 만큼 PS에 더 많은 유닛이 할당된다.
  • 14. 그러나 지금은… 복잡한 커스터마이징 커스터마이징 파라메터를 전달하려면 셰이더 상수가 많이 필요하다. 오브젝트 모션 블러 속도 계산을 위해서 이전 프레임의 위치까지 스키닝해야 한다. 처리해야 할 bone 수가 두 배로 늘었다고 볼 수 있다.
  • 15. 현 세대 캐릭터 렌더링의 특징 스키닝이 병목이다. 그 중에서 특히 셰이더 상수 전송이 병목이다.
  • 16. 관련 연구 리뷰 Related Works
  • 17. VTF 스키닝 Vertex Texture Fetch Skinning “텍스쳐로” 매트릭스 팔레트를 전달한다. VS에서 VTF로 bone 정보를 읽는다. Skinned Instancing, Nvidia http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SkinnedInstancing/doc/SkinnedInstancingWhitePaper.pdf
  • 18. VTF 스키닝 Vertex Texture Fetch Skinning 장점 bone 수가 많을수록 일반 스키닝보다 빠르다. 메모리 사용량이 비교적 적다. 단점 VTF 오버헤드가 심하다. 버텍스 하나당 최소 3번, 최대 12번의 VTF가 필요 모든 렌더링 패스에서 스키닝이 반복되는 점은 변함이 없다.
  • 19. R2VB 스키닝 Render To Vertex Buffer Skinning 스키닝 계산을 PS에서 처리한다. VTF 스키닝과 유사한 기법. ATI GPU의 R2VB 기능을 이용해서 bone 행렬 계산과 스키닝 모두를 PS에서 처리. R2VB Animation, ATI http://developer.amd.com/downloads/R2VB-Animation.zip
  • 20. R2VB 스키닝 Render To Vertex Buffer Skinning 장점 매우 빠르다. 단점 ATI GPU에서만 동작한다. 메모리 사용량이 비교적 많다.
  • 21. 소프트웨어 스키닝 Software Skinning CPU 혹은 Compute Shader로 스키닝 처리 Unigine Engine, Unigine Corp. http://unigine.com
  • 22. 소프트웨어 스키닝 Software Skinning 장점 멀티스레딩 최적화를 통해서 좋은 성능을 낼 수 있다. 메모리 사용량이 적다. 단점 최적화하기가 매우 어렵다. 하드웨어 제약이 심하다. 멀티 코어 CPU 혹은 DX11 클래스 하드웨어가 필요하다.
  • 24. VT 스키닝 Vertex Texture Skinning R2VB 스키닝과 유사한 기법 R2VB 대신 VTF를 사용한다. 텍스쳐에 스키닝 결과를 저장하고 이후 패스에서 VTF로 그 결과를 참조한다. 메시 VT 텍스쳐 프레임 버퍼 VS PS
  • 25. VT 텍스쳐 Vertex Transformation Texture 스키닝 결과가 기록된 텍스쳐 FP(Floating Point) 포맷의 렌더 타겟 가능 텍스쳐. 스키닝한 버텍스의 위치, 노멀, 탄젠트 벡터가 저장된다. 렌더링된 VT 텍스쳐의 예. 좌: RGB, 우: Alpha. 텍스쳐 크기는 512*512, 포맷은 FP16(A16R16G16B16F)
  • 26. 장점 Pros VS가 매우 간단해진다. 버텍스 변환 패스를 제외하고 스키닝 계산이 없기 때문. 빠르다. 버텍스 당 VTF를 1~2회만 하므로 VTF 스키닝보다 매우 빠르다. 하드웨어 요구사항이 낮다. 대부분의 SM3 클래스 GPU가 VTF를 지원한다.
  • 27. 장점 Pros 캐릭터 커스터마이징 처리가 쉽다. VS 상수 레지스터의 대부분을 차지하던 매트릭스 팔레트가 없어졌다. 마비노기2의 레지스터 활용 예: 커스터마이징 컬러 테이블 모핑 파라메터 오브젝트 모션 블러 처리가 쉽다. VT 텍스쳐를 더블 버퍼링하면 버텍스의 속도를 간단하게 계산할 수 있다. 이전 프레임의 매트릭스 팔레트를 보관할 필요가 없다.
  • 28. 단점 Cons 메모리 사용량이 높다. 최적화 전: A32R32G3B32F 4장 사용(1장은 이전 프레임 텍스쳐) 최적화 후: A16R16G16B16F 2장 사용 (1장은 이전 프레임 텍스쳐) 수백명의 캐릭터를 렌더링하려면 적어도 1024 * 1024 크기의 VT텍스쳐가 필요하다. VTF는 빠르지 않다. DX9 클래스 GPU: 스키닝 계산보다 매우 느리다(약 6배) DX10 클래스 GPU: 충분히 빠르다. VT 스키닝으로 얻는 전체적인 성능 이득이 더 크므로 큰 문제는 아니다.
  • 30. VT 스키닝 구현 Implementations
  • 31. VT 텍스쳐 렌더링 VT Texture Rendering 각 버텍스를 스키닝한 후에 “점”으로 출력 D3DPT_POINTLIST로 DP()
  • 32. VT 텍스쳐 형식 VT Texture Format 4채널 FP32 세 장을 사용 R32F G32F B32F A32F RT0 Position XYZ RT1 Normal XYZ RT2 Tangent XYZ 최적화하면 4채널 FP16 한 장에 넣을 수 있다. 자세한 설명은 이후 슬라이드에서.
  • 33. 스키닝 버텍스 포맷 Skinned Vertex Format 일반적인 스키닝 버텍스와 유사 Position : float3 Normal : float3 Tangent : float3 BlendIndices : uint32 BlendWeights : uint64 InstanceIndex : uint32 InstanceIndex 버텍스 n개가 있다면, 각 버텍스는 0부터 n-1까지 순서대로 InstanceIndex를 갖는다. VS는 이 값으로부터 VT 텍스쳐 출력 좌표를 계산한다.
  • 34. 스키닝 VS Skinning Vertex Shader 1/3 struct MeshVertexTransformationVSInput { float4 position : POSITION; float3 normal : NORMAL; float3 tangent : TANGENT; float4 boneIndices : BLENDINDICES; float4 blendWeights : BLENDWEIGHT; float4 instanceIndex : TEXCOORD0; }; struct MeshVertexTransformationVSOutput { float4 vtPosition : POSITION; float3 position : TEXCOORD0; float3 normal : TEXCOORD1; float3 tangent : TEXCOORD2; };
  • 35. 스키닝 VS Skinning Vertex Shader 2/3 MeshVertexTransformationVSOutput VertexTransformationVSMain( MeshVertexTransformationVSInput input) { MeshVertexTransformationVSOutput output; // 스키닝 int4 boneIndices = (int4)input.boneIndices; float4 srcPosition = input.position; float3 srcNormal = input.normal; float3 srcTangent = input.tangent; input.position.xyz = 0.0f; input.normal = 0.0f; input.tangent = 0.0f; for (int i = 0; i < 4; ++i) { float4x3 boneMatrix = BoneMatrices[boneIndices[i]]; input.position.xyz += mul(srcPosition, boneMatrix) * input.blendWeights[i]; input.normal += mul(srcNormal, (float3x3)boneMatrix) * input.blendWeights[i]; input.tangent += mul(srcTangent, (float3x3)boneMatrix) * input.blendWeights[i]; }
  • 36. 스키닝 VS Skinning Vertex Shader 3/3 // 출력 위치를계산 float instanceOffset = dot( float2(input.instanceIndex.xy), float2(1.0f, 256.0f)); float2 texcoord; texcoord.x = instanceOffset / VTTextureWidth.; texcoord.y = floor(texcoord.x) / VTTextureHeight; float2 outputPos = frac(texcoord); outputPos.x = outputPos.x * 2.0f - 1.0f; outputPos.y = 1.0f - outputPos.y * 2.0f; // 출력 output.vtPosition = float4(outputPos, 0.0f, 1.0f); output.position = input.position.xyz; output.normal = input.normal; output.tangent = input.tangent; return output; }
  • 37. 스키닝 PS Skinning Pixel Shader struct MeshVertexTransformationPSInput { float3 position : TEXCOORD0; float3 normal : TEXCOORD1; float3 tangent : TEXCOORD2; }; struct VertexTransformationPSOutput { float4 position : COLOR0; float4 normal : COLOR1; float4 tangent : COLOR2; }; VertexTransformationPSOutput VertexTransformationPSMain(MeshVertexTransformationPSInput input) { VertexTransformationPSOutput output; output.position = float4(input.position, 0.0f); output.normal = float4(input.normal, 0.0f); output.tangent = float4(input.tangent, 0.0f); return output; }
  • 38. 일반 버텍스 포맷 Common Vertex Format VT 텍스쳐를 샘플링하기 위해 InstanceIndex가 필요 Color : uint32 TexCoord : float2 InstanceIndex : uint32 기하(Geometry) 채널이 없기 때문에 크기가 매우 작다. 그림자, 깊이 렌더링 같은 간단한 셰이딩은 버텍스 크기가 4 byte.
  • 39. VT 텍스쳐 샘플링 VT Texture Sampling sampler VTSampler = sampler_state { MinFilter = Point; MagFilter = Point; MipFilter = None; AddressU = Wrap; AddressV = Wrap; }; float4 SampleVTTexture(float2 instanceIndex) { float instanceOffset = dot(input.instanceIndex, float2(1.0f, 256.0f)); float2 texcoord; texcoord.x = instanceOffset / VTTextureWidth; texcoord.y = floor(texcoord.x) / VTTextureHeight; return tex2Dlod(VTSampler, float4(texcoord, 0.0f, 0.0f)); }
  • 40. VT 스키닝 최적화 Optimizations
  • 41. 16bit FP 텍스쳐 사용 16-bit FP Texturing FP16 : s1e5m10 부호 1 bit, 지수 5 bit, 가수 10 bit 손실 없이 표현할 수 있는 정수 범위 : -2048 ~ 2048 노멀과 탄젠트는 사실상 정밀도 손실이 없다. 위치를 그냥 FP16에 저장하면 오차가 너무 크다. 대신, 카메라 공간(Camera Space)으로 옮겨서 저장한다. 카메라로부터 멀리 떨어질 수록 오차가 커지지만, 원근 투영 때문에 오차가 눈에 띄지 않는다.
  • 42. 노멀을 채널 하나에 저장 Packing normal into one fp16 1. Map Projection 함수로 노멀벡터를 구면좌표로 옮긴다. http://aras-p.info/texts/CompactNormalStorage.html를 참고함 Lambert azimuthal equal-area projection 사용해서, 노멀 벡터 (x, y, z)를 (s, t)로 변환 (http://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection). 2. FP16 하나에 (s, t)를 패킹 s와 t를 각각 7bit씩 fp16에 패킹한다. (0, 0, -1)에 singularity가 있으므로 항상 z가 양수가 되도록 만들고, 1비트는 z의 부호로 사용한다.
  • 43. NormalToFP16() Shader float NormalToFP16(float3 n) { // XXXXXXX.yyy // z 부호를저장한다. float bit10 = bit7.x + split.y; float zSign = sign(n.z); n.z *= zSign; // 0.1xxxxxxxyyy * 2^YYYY float mantissa = bit10.x / 128.0f / 2.0f + // [-1,1] -> [0,1] 512.0f/1024.0f; // Lambert Azimuthal Equal-Area projection float exponent = split.x; float f = sqrt(8 * n.z + 8); float packed = ldexp(mantissa, exponent); float2 biased = n.xy / f + 0.5f; return zSign * packed; // 0.xxxxxxx -> XXXXXXX.0 } // 0.yyyyyyy -> YYYYYYY.0 float2 bit7 = round(biased * 127.0f); // YYYYYYY -> YYYY.yyy float2 split = bit7.y / 8.0f; split.x = floor(split.x); split.y -= split.x;
  • 44. FP16ToNormal() Shader float3 FP16ToNormal(float packed) // XXXXXXX { // YYYYYYY float sgn = sign(packed); float2 bit7; bit7.x = split.x; float mantissa; bit7.y = (exponent + split.y) * 8.0f; float exponent; mantissa = frexp(packed, exponent); // [0, 1] mantissa = abs(mantissa); float2 biased = bit7 / 127.0f; // XXXXXXX.yyy // [-1,1] float bit10 = (mantissa - 512.0f/1024.0f) * 2.0f * // Lambert Azimuthal Equal-Area projection 128.0f; float2 fenc = biased * 4 - 2; float f = dot(fenc, fenc); // XXXXXX, 0.yyy float2 split; float g = sqrt(1 - f/4); split.x = floor(bit10); split.y = bit10 - split.x; return float3(fenc * g, sgn*(1 - f/2)); }
  • 45. 탄젠트 제거 Tangent vector elimination t’ = normalize(t – dot(t, n’)n’) 노멀 n, 탄젠트 t가 있을 때 스키닝된 노멀과 탄젠트를 각각 n’, t’라 하면, 노멀과 탄젠트가 서로 직교하는 성질을 이용해서 t’를 얻을 수 있다. n n' t' t
  • 46. 탄젠트 제거 Tangent vector elimination 탄젠트 컴포넌트를 일반 버텍스 포맷으로 옮긴다. 거의 대부분의 경우, 탄젠트 벡터는 메인 셰이딩 패스에서만 사용. 탄젠트 컴포넌트를 메인 셰이딩 패스의 버텍스로 옮긴다. 4채널 FP16에 모든 기하 정보를 기록 R16F G16F B16F A16F Normal RT0 Position XYZ XYZ 최초 구현의 1/6로 줄어들었다.
  • 47. 버텍스 중복 제거 Redundant vertex removal 중복되는 스키닝 버텍스를 제거 중복되는 스키닝 버텍스를 제거하고, 일반 버텍스의 InstanceIndex를 다시 매핑한다. 마비노기2의 경우, 평균적으로 25%의 버텍스가 제거되었다. 0 1 2 3 4 5 0 0 1 1 1 2 skinning positions instance indices
  • 49. VT 라이팅 Vertex Texture Lighting VT 텍스쳐를 사용하는 Per Vertex Deferred Lighting 좌: VT Lighting off, 중: VT Lighting only, 우: VT Lighting on
  • 50. 장점 Pros 일반적인 Deferred Lighting 기법의 단점을 해결 메모리 사용량이 비교적 적다. 조명 처리 비용이 해상도에 무관하다. Anti-Aliasing이 자유롭다. 반투명한 물체 처리에 아무런 제약이 없다. Light Buffer 렌더링이 매우 빠르다. Light Buffer 렌더링 비용과 프레임 버퍼 해상도가 무관하다. Light Buffer가 시점에 독립적(View Independent)이다. 정적인 물체와 조명에 대해서 이전 프레임의 렌더링 결과를 사용할 수 있다.
  • 51. 단점 Cons Per Pixel이 아니다. Light Buffer 렌더링에 노멀맵을 사용할 수 없어서 Gloss 재질 표현이 어렵다. 장면이 복잡할수록 Light Buffer 렌더링이 느리다. 렌더링 속도와 메모리 사용량이 장면의 버텍스 수에 비례한다. 건물, 배경에 적용하기 어렵다. 불가능하지는 않다. 마비노기2는 건물과 배경에도 VT Lighting을 사용한다. 하드웨어 요구사항이 높다. 정수형 텍스쳐(A8R8G8B8)의 VTF가 가능해야 한다(DX10 클래스 GPU부터 지원)
  • 52. 시연 DEMO
  • 53. VT 라이팅 구현 Implementations
  • 54. VL 텍스쳐 Vertex Light Texture 일반 DL의 Light Buffer와 동일 각 버텍스의 조명 결과가 저장된다. 최종 조명 처리 패스의 VS에서 VTF로 참조한다. 속도를 위해서 LDR 조명이라고 가정하고 A8R8G8B8 포맷을 사용한다. VT 텍스쳐와 동일한 크기를 가진다. 좌: VT Texture, 우: VL Texture
  • 55. VL 텍스쳐 렌더링 VL Texture Rendering 광원을 “선”으로 렌더링 광원 정보를 버텍스에 넣고 D3DPT_LINELIST으로 렌더링한다. Addtive Blending으로 조명 결과를 누적시킨다. +
  • 56. VL 텍스쳐 렌더링 VL Texture Rendering 광원 A만 받는 버텍스들 광원 A와 B 모두 받는 버텍스들 광원 B만 받는 버텍스들
  • 57. Light Mesh 같은 종류의 광원들을 하나의 Mesh로 합친다 Light Mesh의 모양과 실제 광원의 바운딩 볼륨은 서로 무관하다. Light Mesh는 VT 텍스쳐 공간에 있는 라인들의 집합이다. 광원을 하나로 합치면 DP() 한 번에 여러 광원을 렌더링할 수 있다. 매 프레임 CPU로 생성한다. 각 광원 볼륨과 메시 볼륨이 교차하면, 그 메시의 VT 텍스쳐 영역을 덮는 라인을 Light Mesh에 추가한다. n개의 광원과 m개의 메시가 있을 경우 알고리즘의 복잡도는 O(n*m). 공간 분할 알고리즘을 사용해서 성능을 향상시킬 수 있다.
  • 58. 라이트 메시 버텍스 포맷 Light Mesh Vertex Format 광원 종류마다 다르다. 점광원의 예 VT Position : float2 Light Position : float3 Light Color : uint32 Light Radius : float VT 텍스쳐 공간은 2d 이므로 VT Positoin 타입으로 float2를 사용.
  • 59. VT 라이팅 VS VT Lighting Vertex Shader struct VertexLightingVSInput { float2 position : POSITION; float4 lightColor : COLOR; float3 lightPos : TEXCOORD0; float lightRadius : TEXCOORD1; }; struct VertexLightingVSOutput { float4 position : POSITION; float4 lightColor : COLOR; float3 lightPos : TEXCOORD0; float lightRadius : TEXCOORD1; }; VertexLightingVSOutput VertexLightingVSMain(VertexLightingVSInput input) { VertexLightingVSOutput output; output.position = float4(input.position, 0.0f, 1.0f); output.lightColor = input.lightColor; output.lightPos = mul(float4(input.lightPos, 1.0f), (float4x3)ViewMatrix); output.lightRadius = input.lightRadius; return output; }
  • 60. VT 라이팅 PS VT Lighting Pixel Shader struct VertexLightingPSInput { float4 lightColor : COLOR; float3 lightPos : TEXCOORD0; float lightRadius : TEXCOORD1; float2 vPos : VPOS; }; float4 VertexLightingPSMain(VertexLightingPSInput input) : COLOR { // VT텍스쳐를 샘플링해서 버텍스 위치와 노멀을 얻는다. float3 position; float3 normal; SampleVertex(input.vPos / RenderTargetExtent, position, normal); // 점광원처리 float4 illuminance = ComputePointLight(position, normal, input.lightColor, input.lightRadius); // 출력 return illuminance; }
  • 61. VT 라이팅 Technique VT Lighting Technique technique VertexLighting { pass { CullMode = None; FillMode = Solid; ZEnable = false; AlphaBlendEnable = true; SrcBlend = One; DestBlend = One; BlendOp = Add; AlphaTestEnable = false; VertexShader = compile vs_3_0 VertexLightingVSMain(); PixelShader = compile ps_3_0 VertexLightingPSMain(); } }
  • 63. 하드웨어 호환성 Hardware Compatibility 구형 ATI GPU는 VTF를 지원하지 않는다. SM3를 지원하는 GPU조차 그렇다. R2VB로 VT Skinning을 구현해야 한다. DX9 클래스 GPU는 FP16 텍스쳐를 VTF할 수 없다. DX9클래스 GPU는 R32F와 A32R32G32B32F의 VTF만 지원한다. 답이 없다.
  • 64. DX10,11로 포팅 Porting to DX10,11 DX10에서는 VT Skinning이 필요없다. Stream Output이나 Constant Buffer를 사용하면 VT Skinning이 필요없다. DX11또한 VT Skinning이 필요없다. Compute Shader를 사용해서 스키닝을 처리할 수 있다. 만들고 측정해 봐야 알 수 있다. VT Skinning이 필요없을 것 같다는 예측일 뿐.
  • 65. 버텍스 포스트 프로세싱 Vertex Post Processing Special Vertex Effects VT텍스쳐에 여러 가지 포스트 이펙트 필터를 적용해서 , 재미있는 효과를 만들 수 있다. GPU Physics Simulation soft body simulation, jiggle bone 처리 등을 GPU로 옮길 수 있다.
  • 66. 복잡한 스키닝 More Advanced Skinning Method LBS(Linear Blend Skinning)는 이제 그만좀 쓰자. Spherical Blend Skinning이나 Dual Quaternion Skinning을 사용 Skinning with Dual Quaternions, Nvidia http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/QuaternionSkinning/doc/QuaternionSkinning.pdf
  • 67. Real-Time GI Real-Time Global Illumination VT Lighting의 View-Independency를 활용 VT Lighting은 프레임 당 수백개~수천개의 다이나믹 라이트를 처리할 수 있다. View-Independency를 활용해서 전체 계산을 여러 프레임으로 분산하면, 한 장면에 수만개의 광원을 적용할 수 있다. VPL(Virtual Point Light) 기반 GI RSM(Reflective Shadow Map) 같은 알고리즘에 응용할 수 있을 것이다.
  • 69. 마비노기2의 캐릭터 렌더링 VT Skinning으로 캐릭터 렌더링을 고속으로 처리 캐릭터 커스터마이징과 오브젝트 모션 블러를 VT Skinning 기법으로 처리, 셰이더 상수 병목 문제를 해결했다. VT Lighting으로 Deferred Lighting 기존의 DL 기법의 문제점들을 해결한 Per Vertex DL 기법으로, 많은 수의 광원을 효과적으로 처리했다.