94
프로젝트 <A1>의 AAA급 캐릭터 렌더링 기술 기현우 리드 그래픽스 프로그래머 A1 / NEXON * NDC 2016 발표의 공개 버전으로써, 발표 내용은 같지만 스샷과 레퍼런스에 약간의 변경이 있습니다.

NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

Embed Size (px)

Citation preview

Page 1: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

프로젝트 <A1>의

AAA급 캐릭터 렌더링 기술

기 현 우리드 그래픽스 프로그래머

A1 / NEXON

* NDC 2016 발표의 공개 버전으로써, 발표 내용은 같지만 스샷과 레퍼런스에 약간의 변경이 있습니다.

Page 2: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 넥슨의 미공개 신작 프로젝트 / 새로운 IP

아직 개발 중 (출시일 미정)

게임 개발 베테랑들로 구성된 팀

타겟 플랫폼: 하이엔드급 PC

- 풀옵 60 FPS 기준 / 보급된 평균 사양에서도 괜찮은 품질로 원만하게 동작하게 할 계획

• NDC 2016에서 처음으로 개발 소식 공개

A1

Page 3: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 프로그래밍 세션: 캐릭터 렌더링

아직 개발 중인 리소스와 구현을 포함 / 기술적인 내용을 다룸

캐릭터 중심으로 발표 / 실제 월드와 월드 렌더링에 사용된 기술은 미공개

모든 내용은 개발 과정에서 바뀔 수 있음

A1@NDC 2016

• 04/27 15:20 아트 세션:

“도전! AAA 게임 비주얼 – 프로젝트 A1의 게임 아트”

박성섭 / 아트 디렉터

• 04/27 17:05 프로그래밍 세션:

“구형맵에서는 어떻게 길을 찾아야 하나요? – 기초부터 이해하는 Recast 내비게이션 메시”

하지훈 / 시니어 게임플레이 프로그래머

Page 4: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 경쟁 게임에 차별성 있는 매우 뛰어난 품질의 비주얼이 강점

국산 게임에서 볼 수 없던 수준이 목표

마케팅용 과장이 아닌 진짜 AAA급 그래픽 품질

어떤 기술을 사용하고, 어느 정도 수준의 결과가 나오고 있는지를 보여주기 위한 발표

• UE4 + @@@

UE4의 뛰어난 기능을 최대한 활용

새로운 렌더링/애니메이션/VFX 기능 등을 추가로 구현 중

A1과 비주얼

Page 5: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 피부, 머리카락, 금속 렌더링

• 그림자 렌더링

• 로우 레벨 셰이더 최적화

• 런타임 캐릭터 리깅 피직스 시뮬레이션

• 요약

목차

Page 6: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

피부 렌더링

Page 7: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 멀티플 스케터링 Multiple Scattering

Dipole Diffusion Approximation

Jensen에 의해 그래픽스 분야에서 사용됨

• UE4에 기본 포함

Jimenez가 제안한 실시간 렌더링 기술

업계 대세 / 그대로 사용

SSSSS Screen Space SubSurface Scattering

Activision R&D. Property of Activision Publishing. Not Actual Gameplay

Page 8: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

No SSSSS

Page 9: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 부드러운 라이팅

• 부드러운 섀도우

• 촉촉함

SSSSS

Page 10: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 메시 결에 따른스페큘러 변화

베이스 노멀

Page 11: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 피부 결에 따른스페큘러 변화

디테일 노멀

Page 12: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 투과 현상 없음

스크린 스페이스의 한계

화면 밖에서 입사되는 빛을 무시

투과를 보강하는 에디션이 있음: UE4엔 미포함

• 저주파 라이팅만 Low-frequency

짧은 거리에서의 강한 산란 현상 표현 못 함

UE4 SSSSS의 한계

Burley, “Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering”, SIGGRAPH 2015

Page 13: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 투과 (역광 Back Lit)

• 백 스케터링 Back Scattering

• 고주파 라이팅 High-frequency

싱글 스케터링 Single Scattering싱글 스케터링 멀티플 스케터링 (dipole)

Page 14: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

멀티플 스케터링

Page 15: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

+ =싱글 + 멀티플 스케터링

* 싱글 스케터링은 프리젠테이션 스크린에서 눈에 좀 더 잘 띄기 위해 약간 과장된 세팅

Page 16: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• ShaderX7에 소개했던 기법

Hyunwoo Ki, “Real-Time Subsurface Scattering using Shadow Maps”

표면에 입사된 반투명 이래디언스 정보를 여러 장의 섀도우 맵에 저장

레이 마칭 시 섀도우 맵 투영으로 빛의 단일 산란 거리 근사

이래디언스와 산란 거리를 기반으로 조명식을 계산

• 변형해서 UE4에 통합하여 사용

디퍼드 싱글 스케터링

섀도우 맵을 사용한 싱글 스케터링

ground truth Ki09

Page 17: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 카메라에서 광선 Ray 출발

표면에서 굴절 (방출 방향)

• 전진 거리를 샘플링

콰지 몬테 카를로 Quasi Monte Carlo 샘플링

• 섀도우 맵으로 투영

산란 거리 근사

리뷰: [Ki09] 레이 마칭 Ray Marching

2 0

2

11

,, iiiiit

xs

oi

xs

otos

A π xiiiiiooiiooo

ωdsdω,xLωFeω,ωpeωFx

dAdωωnω,xLω,;xω,xSω,xL

itioto

i

N

i

M

jiit

xs

oi

xs

otos ω,xEeω,ωpeωFx itioto

0 0

,,

tos log

Page 18: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

1) 디퍼드 섀도우 패스:

콰지 몬테 카를로 레이 마칭 방식은 변화 없음

단, 모든 샘플링 단계에서 이래디언스와 노멀이 같다고 가정 -> 이미 준비된 섀도우 맵 한 장만 필요 (추가 없음!)

고정 산란 계수 사용: G 버퍼 제한과 성능 때문

출력: 단일 채널 싱글 스캐터링 전달량 transfer

2) 디퍼드 라이팅 패스:

디퍼드 섀도우 버퍼에 저장된 SS 전달량(스칼라) * SSS 컬러 * 양방향 프레넬 투과 * HG 위상 함수 Phase Function

출력: 디퓨즈 + 스페큘러 + 싱글 스케터링

• 물리적으로는 부정확하지만 보기엔 괜찮은 결과

디퍼드 싱글 스케터링 Deferred Single Scattering

N

i

M

j

ss

iitoiotstoieω,xEω,ωpωF

0 0

,,

2) 라이팅 패스 1) 섀도우 패스

Page 19: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

float ComputeSingleScatteringUsingShadowMap(FGBufferData GBuffer, FShadowMapSamplerSettings Settings, float3 V, float3 L, float3 WorldPosition){

const int NumSamples = SHADOW_QUALITY * 3;

const float Eta = 1.3;const float EtaInverse = 1.0 / Eta;const float ExtinctionCoefficient = 2.55;const float MeanFreePath = 1.0 / ExtinctionCoefficient;

const float3 OutgoingDirection = -refract(V, -GBuffer.WorldNormal, EtaInverse.x);

const float InverseNumSamples = 1.0f / (float) NumSamples;const float Sample = InverseNumSamples * 0.5;

float SingleScattering = 0;

for (int i = 0; i < NumSamples; ++i){

float RefractedOutgoingDistance = -log(Sample) * MeanFreePath;float3 ScatteringPoint = (OutgoingDirection * RefractedOutgoingDistance) + WorldPosition;float4 ScatteringPointInShadowSpace = mul(float4(ScatteringPoint, 1.0f), WorldToShadowMatrix);ScatteringPointInShadowSpace.xy /= ScatteringPointInShadowSpace.w;

float ShadowmapDepthAtScatteringPoint = Texture2DSampleLevel(Settings.ShadowDepthTexture, Settings.ShadowDepthTextureSampler, ScatteringPointInShadowSpace.xy, 0).r;float IncidentDistance = max(0, abs((ShadowmapDepthAtScatteringPoint + Settings.ProjectionDepthBiasParameters.x) - ScatteringPointInShadowSpace.z)) * ProjectionDepthBiasParameters.y;float TravelPathLength = IncidentDistance + RefractedOutgoingDistance * DISTANCE_SCALE;float LightContribution = exp(-ExtinctionCoefficient * TravelPathLength);

float Weight = exp(-ExtinctionCoefficient * RefractedOutgoingDistance);SingleScattering += LightContribution / Weight;Sample += InverseNumSamples;

}

return SingleScattering / (float) NumSamples * SINGLESCATTERING_INTENSITY;}

참고) 레이 마칭 셰이더 코드

Page 20: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 두께가 얇은 귀에 투과 효과

역광

• 눈 밑, 코, 입술 등을 더 밝게

마스킹 사용 / 미적인 선택

• 라이트 당 1 ms 미만 추가

근접 뷰 기준 / 뷰에 따라 다름

렌더링 결과

Page 21: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

* 싱글 스케터링은 프리젠테이션 스크린에서 눈에 좀 더 잘 띄기 위해 약간 과장된 세팅

Page 22: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 디더드 템포럴 Dithered Temporal 샘플링을 사용한 최적화

볼류메트릭 라이팅에서 사용한 다른 게임의 사례가 있음: Killzone: Shadow Fall, Loads of Fallen, INSIDE 등

템포럴 리프로젝션 Temporal Reprojection

• 피부에 한하여 섀도우 렌더링을 대체하는 용도

현재는 UE4의 원래 방식대로 불투명 표면에 대한 섀도우 렌더링과 동일 (이중 계산)

싱글 스케터링의 볼륨 라이팅 감쇠 성질상 섀도우 표현이 가능할 것으로 기대

싱글 스케터링 향후 작업

Page 23: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

머리카락 렌더링

Page 24: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 겹겹의 카드 메시 + 텍스처 알파

• 잔머리 메시

• 옵션 텍스처:

컬러, 노멀, 러프니스, AO, 스페큘러 시프트

• Destiny와 The Order: 1886도 유사

모델링과 텍스처링

Page 25: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 반투명 렌더링

알파 블렌딩: 픽셀 레벨의 드로잉 순서

라이팅: 디퍼드 라이팅의 사용 불가

섀도잉: 디퍼드 섀도잉의 사용 불가

• 물리 기반 셰이딩 모델

일반적인 GGX 모델로는 표현할 수 없음

난제

Page 26: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

알파 테스트 Alpha Test : 알파 블렌드 Alpha Blend

Page 27: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

알파 블렌딩 순서의 중요성

Page 28: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 픽셀 레벨의 정확한 알파 블렌딩이 필요

• K-Buffer 스타일로 결정

Per-Pixel Linked List (PPLL)

DX11 Unordered Access View (UAV) 사용

AMD TressFX 2.0 샘플 기반

UE4 렌더러에 통합

Order Independent Transparency (OIT)

Page 29: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• Head UAV: RWTexture2D<uint>

스크린 상의 각 픽셀의 링크드 리스트 UAV에 대한 헤드 인덱스

• PPLL UAV: RWStructuredBuffer<FOitLinkedListDataElement>

각 프레그먼트 fragment가 드로잉될 때 엘리먼트를 추가

모든 프레그먼트를 저장하는 컨테이너

리뷰: PPLL OIT

uint PixelCount = OitLinkedListPPLLDataUAV.IncrementCounter();

int2 UAVTargetIndex = int2(SVPosition.xy);uint OldStartOffset;InterlockedExchange(OitLinkedListHeadAddrUAV[UAVTargetIndex], PixelCount, OldStartOffset);

OitLinkedListPPLLDataUAV[PixelCount] = NewElement;

Page 30: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• K-Buffer

Z 기준 앞에서부터 K번째까지의 프레그먼트들만 정렬된 순서로 매뉴얼 알파 블렌딩

나머지 뒷 쪽 프레그먼트들은 정렬되지 않은 순서로 매뉴얼 알파 블렌딩

• 자세한 사항은 레퍼런스 참고

리뷰: PPLL OIT

float4 BlendTransparency(float4 FragmentColor, float4 FinalColor){

float4 OutColor;OutColor.xyz = mad(-FinalColor.xyz, FragmentColor.w, FinalColor.xyz) + FragmentColor.xyz * FragmentColor.w;OutColor.w = mad(-FinalColor.w, FragmentColor.w, FinalColor.w);return OutColor;

}

Page 31: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 반투명 포워드 라이팅 결과를 PPLL에 저장 / Early-Z 강제

• 다음 패스에서 소팅과 블렌딩

• PPLL 엘리먼트 레이아웃: DX11 StructuredBuffer

HDR 라이팅 결과(Radiance)를 half4 -> uint로 패킹: 데이터 사이즈, 메모리 대역폭, 캐시 효율(128비트)에서 이득

UE4에 통합

struct FOitLinkedListDataElement{

half4 Radiance;uint NormalAndOpacity;uint Depth;uint Next;

};

struct FOitLinkedListDataElement{

uint RadianceRGY32;uint NormalAndOpacity;uint Depth;uint Next;

};

float3 UnpackRGY32(uint PackedColor){

const float ONE_OVER_255 = 1.0f / 255.0f;float3 RGB;RGB.r = (PackedColor & 0xff000000) >> 24;RGB.g = (PackedColor & 0x00ff0000) >> 16;RGB.b = 255.0f - (RGB.r + RGB.g);float Luminance = f16tof32(PackedColor);return RGB * Luminance * ONE_OVER_255;

}

uint PackRGY32(float3 Color){

float Luminance = (Color.r + Color.g + Color.b);Color.rg /= Luminance;

uint PackedValue = uint(Color.r * 255.0f + 0.5f) << 24 | uint(Color.g * 255.0f + 0.5f) << 16;

PackedValue |= f32tof16(Luminance);return PackedValue;

}

Page 32: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

렌더링 결과

Page 33: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 카드 메시 레이어가 많아서 매우 많은 픽셀 오버 드로우

• UAV를 사용한 단일 패스 오패시티 임계처리로 최적화

사실 알파 블렌딩은 투명성을 위해서가 아닌, 단지 매우 가는 머리카락 가닥을 깨끗하게 렌더링하기 위함

헤어 끝을 제외하면 사실상 거의 불투명 (특히 안 쪽 레이어)

불투명 픽셀 뒤에 가려진 픽셀들의 오버 드로우를 최소화 해보자!

오버 드로우 최적화

Page 34: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 머티리얼마다 오패시티 임계값 Opacity Threshold을 설정: 예) 0.95

• PS에서 별도의 Z 버퍼 UAV RWTexture2D<uint>를 사용한 추가 Z 테스트

현재 픽셀이 임계값보다 큰 오패시티면 Z 쓰기 시도

오패시티 임계값 Z 버퍼와의 Z 테스트는 항상

const uint DepthAsUint = asuint(SVPosition.w);

const uint DepthToWrite = (Opacity > OpacityThreshold) ? DepthAsUint : INVALID_UINT;

uint OldMinDepthAsUint;

InterlockedMin(OitOpacityThresholdingDepthUAV[int2(SVPosition.xy)], DepthToWrite, OldMinDepthAsUint);

if (DepthAsUint > OldMinDepthAsUint)

{

discard;

}

순서없는 오패시티 임계처리 Unordered Opacity Thresholding

Page 35: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 추가 UAV 버퍼 및 UAV 읽기/쓰기가 발생하지만 총 비용은 감소

• 5~10% 속도 향상과 15% 메모리 절약

라이팅 비용을 줄일 수 있음

OIT 버퍼 크기를 줄일 수 있음

단일 패스로써 드로잉 추가가 없음

래스터라이즈 순서 ‘운’?

렌더링 결과

Page 36: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 래스터라이즈 순서 예측을 통한 UOT Unordered Opacity Thresholding 효율 개선

인덱스 버퍼 순서와 로케일리티 locality?

메시 분할? - 드로우 콜보다 픽셀 오버 드로우가 더 문제이기 때문

하지만 애니메이션에 따라 순서가 뒤바뀌는 경우가 있음

• DX12의 ROV Raster Ordered View를 사용한 더 나은 구현

OIT 향후 작업

Page 37: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 반투명 머티리얼에 픽셀 단위 라이팅을 위함

• UE4의 실험적 기능을 기반으로 아직 개량 중

• 필요에 따라 제한적인 사용

현재는 머리카락 전용이나 유리/플라스틱 류에 추가 가능성 있음

• 섀도우 렌더링 지원

반투명 디퍼드 섀도우

포워드+ 라이팅 Forward+ Lighting

Page 38: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 16x16 타일 컬링

• 포워드 라이트 데이터

Constant Buffer 사용: StructuredBuffer보다 빠름 (NV)

128비트 스트라이드: 캐시 효율, 64KB 미만 유지

SOA? AOS?

포워드+ 라이팅 Forward+ Lighting

Page 39: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

포워드+ 라이팅

Page 40: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

포워드+ 라이팅 + 섀도잉 + 산란

Page 41: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 포워드 라이팅 패스에서 섀도우 계산 시 문제

복잡한 중첩 브랜치 코드 증가 / GPR General Purpose Register 압박

포워드 라이트 데이터(CB)의 증가: 섀도우 매트릭스 및 기타 섀도우 파라메터

동시에 많은 섀도우 맵의 할당 필요 (고해상도 CSM 또는 큐브맵)

• 반투명 디퍼드 섀도우:

가장 앞 면의 front-most 반투명 픽셀에 대한 디퍼드 섀도우 렌더링

일반적인 디퍼드 섀도우 패스에 통합

정확도는 희생하지만 보기에 괜찮은 결과

반투명 디퍼드 섀도우 Transparent Deferred Shadows

Page 42: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

1) 반투명 Z 프리 패스 Z Pre Pass

뎁스 렌더링 머티리얼 프록시 사용: 반투명 섀도우가 필요한 경우에만

반투명 Z 버퍼는 포스트 프로세싱에서도 사용

2) 섀도우 뎁스 렌더링 및 디퍼드 섀도우 패스

섀도우 뎁스 렌더링: 뎁스 렌더링 머티리얼 프록시 사용

디퍼드 섀도잉: 반투명 Z가 불투명 Z보다 앞 쪽에 있는 경우엔, 반투명 Z를 사용한 볼륨 라이팅 감쇠 - Deep Shadow Maps 스타일

각 라이트 별 디퍼드 섀도우 렌더링 결과를 텍스처 2D 어레이로 리졸브

3) 포워드+ 라이팅 패스

디퍼드 섀도우 텍스처 2D 어레이 인덱싱과 투명도에 따른 가중치

반투명 디퍼드 섀도우

float DeferredShadow = DeferredShadowsTextureArray.SampleLevel(PointSampler, float3(ScreenUV, LightIndex), 0).x;DeferredShadow = lerp(1, DeferredShadow, Opacity);

Page 43: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

디퍼드 섀도우 : 반투명 디퍼드 섀도우

Page 44: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

최종 렌더링

* =

Page 45: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 더 많은 라이트 및 머티리얼 지원

• 더 빠른 라이트 버퍼 액세스

• 안 쪽 레이어의 헤어에 대한 더 나은 섀도잉

Z에 따른 감쇠?

• 싱글 스케터링과의 버퍼 채널 충돌 문제

피부 위를 덮은 머리카락이 있을 때, 머리카락 섀도우가 우선시 되는 문제

포워드+ 라이팅과 섀도잉 향후 작업

Page 46: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• Marschner 모델: 헤어 가닥 = 실린더

• 반사, 2차 반사, 투과

반사: R

2차 반사: TRT

투과: TT

• 산란 효과 추가

물리 기반 셰이딩 모델

Page 47: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

헤어 라이팅

Page 48: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

R: 반사

Page 49: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

TRT: 2차 반사

Page 50: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

TT: 투과

Page 51: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 경도 산란 Longitudinal Scattering

ALU

간단한 가우시안 함수라서 텍스처 읽기보다 나은 성능

• 위도 산란 Azimuthal Scattering

매우 복잡한 수식

재질 속성을 고정하면, 2차원(각도) 함수 형태: 룩업 테이블

텍스처 2D 어레이: CosPhi, CosTheta, HairProfileID

ALU Arithmetic Logic Unit : 룩업 테이블 Lookup Table

float3 ComputeLongitudinalScattering(float3 Theta, float Roughness){

const float bR = DecodeHairLongitudinalWidth(Roughness);const float3 Beta3 = float3(bR, bR * 0.5, bR * 2);return exp(-0.5 * Square(Theta) / Square(Beta3) ) / (sqrt(2.0 * PI) * Beta3);

}

U V Index

Page 52: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 머티리얼 별 속성 정의

이 값을 바탕으로 위도 산란 룩업 테이블 제작

G 버퍼 절약 효과

재사용성

• 룩업 테이블

스펙트럴 형태인 TRT/TT의 흡수율 absorption은 단일 채널로 / 성능 이슈

R 채널: R, G 채널: TRT, B 채널: TT

헤어 프로파일 애셋 Hair Profile Asset

Page 53: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 단일 채널 TRT/TT를 컬러화하기 위함

• 물리적으로는 투과에 따른 빛의 흡수

각도: 라이트, 카메라, 탄젠트

두께: 1 – 오패시티 (머리카락 끝을 더 밝게 하기 위함)

이동 거리: 2 * TT = TRT

컬러 시프트 Color Shift

const float Thickness = (1.0 - Opacity);const float ColorTintFactor = saturate(CosThetaD) + Square(Thickness) + 1e-4;const float2 BaseColorTintPower = float2(0.6, 1.2) / ColorTintFactor;float3 TTColorTint = pow(BaseColor, BaseColorTintPower.x);float3 TRTColorTint = pow(BaseColor, BaseColorTintPower.y);

Page 54: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 페이크 스케터링: UE4.11 방식과 유사

볼류메트릭 흡수 Volumetric Absorption와 컬러 시프트: 반투명 디퍼드 섀도우 결과를 사용

카메라와 라이트 방향 벡터로 위상 함수 반영: 전방 산란 forward scattering ~ 후방 산란 backward scattering 조절 가능

각 라이트마다의 산란 효과

산란: 다이렉트 라이팅 Direct Lighting

float3 ScatteringLighting = 0;if (bShadowed){

float HGPhaseFunc = HGPhaseFunctionSchlick(VoL, ScatteringAnisotropy);float3 ScatteringColor = GBuffer.BaseColor * Shadow;float3 ScatterAttenuation = saturate(pow(ScatteringColor / Luminance(ScatteringColor), 1.0 - Shadow));ScatteringLighting = ScatteringColor * ScatterAttenuation * HGPhaseFunc * ScatteringIntensity;

}

Page 55: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

페이크 스케터링

Page 56: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 스크린 스페이스 볼륨 포톤 매핑 Volume Photon Mapping

OIT에 사용된 LinkedList를 포톤 맵으로 활용: 래디언스, 노멀, 뎁스 데이터

OIT 소팅 후 가장 앞 면 픽셀에서 인접 포톤 개더링

3 x 3 가우시안 커널

등방성 위상 함수: 재질 별 파라메터화의 어려움 + 성능 이슈

글로벌 산란: 인접 메시의 포톤 수집 / 오류지만 거리에 따라 감쇠됨

플리커링: UAV 쓰기로 인함 -> 씬 컬러 TAA로 완화

산란: 간접 라이팅 Indirect Lighting

float2 PhotonScreenUV = InScreenUV + float2(SEARCH_RADIUS * dx, SEARCH_RADIUS * dy);int2 PhotonAddress = int2(PhotonScreenUV * View.ViewSizeAndInvSize.xy + View.ViewSizeAndInvSize.zw);uint PhotonListIndex = OitLinkedListHeadAddressSRV[PhotonAddress];if (PhotonListIndex == INVALID_UINT){

continue;}

FOitLinkedListDataElement Photon = OitLinkedListDataSRV[PhotonListIndex];float3 PhotonRadiance = UnpackRGY32(Photon.RadianceRGY32);

float3 PhotonNormal = GetNormalFromPack(Photon.NormalAndOpacity);float CosTheta = dot(FrontmostNormal, PhotonNormal);

float3 PhotonPositionWS = ConstructWorldPosition(PhotonScreenUV, asfloat(Photon.Depth));float R3 = distance(FrontmostPositionWS, PhotonPositionWS) * PHOTON_DISTANCE_SCALE;

float3 PhotonContribution = 3.0 * PhotonRadiance;PhotonContribution /= R3;PhotonContribution *= HGPhaseFunctionSchlick(CosTheta, MATERIAL_ANISOTROPY); // isotropicGaussPhotonScattering += PhotonContribution * GaussianWeights[GaussianWeightIndex];

Page 57: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

스크린 스페이스 볼륨 포톤 매핑

Page 58: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

디퓨즈 라이팅

• 탄젠트 램버시안

DiffuseLighting = max(0, sqrt(1 – SinThetaI * SinTetaI))

* EnergeConservingWrappedDiffuse(N, L, 1)

* DiffuseIntensity

Page 59: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

종합

Page 60: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 스페큘러 파라메터

노이즈: 헤어 결의 퍼지 fuzzy 효과

러프니스: 하이라이트의 너비와 세기

시프트: 헤어 가닥의 하이라이트 기준 위치 이동

헤어 프로파일 애셋

• 디퓨즈, 페이크 스케터링, 각종 텍스처

• 기타 다수의 파라메터

-> 다양한 스타일로 제작할 수 있도록

헤어 머티리얼

Page 61: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 산란 품질 개선

• 머티리얼 LOD

• 머리카락 스타일 별로 최적의 애셋 제작 방식 찾기

헤어 셰이딩 향후 작업

Page 62: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

금속 렌더링

Page 63: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 아직 실험 단계

• Anisotropic GGX

• Far Cry 4 스타일

• 여러 라이팅에 영향

다이렉트 라이팅, 스카이 라이팅, 리플렉션 인바이론먼트, SSR

탄젠트 이래디언스 맵 사용 검토 중

비등방성 스페큘러

Page 64: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

그림자 렌더링

Page 65: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 캐릭터 뷰어 및 로비

EVSM: Exponential Variance Shadow Maps

• 게임 씬

태양 전용 - PCSS: Percentage Closer Soft Shadows

나머지 라이트 – PCF: Percentage Closer Filtering / UE4 그대로 사용

부가적 그림자 - Screen Space Inner Shadows

씬에 따라 다른 접근

Page 66: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 캐릭터 뷰어 및 로비 전용

실험적 기능 / 배경이 복잡한 경우에 만족스럽지 않은 품질

• 프리 필터드 섀도우 Pre-filtered Shadows

기본 알고리즘에서 변형 없음

• 성능 최적화

CSM 케스케이드 스플릿 제한: 최대 2개

시저 테스트: 스크린 스페이스 섀도우 바운드보다 약간 크게

EVSM

Page 67: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 게임 씬의 태양 전용

• 시간 변화 라이팅 요소 중 하나로 사용

A1은 게임 플레이 중 낮/밤 사이클이 있음

시각에 따라 다른 블러 수준: 정오 – 날카로움, 일몰 - 부드러움

오클루더-리시버 간의 거리에 따라 다른 블러 수준

• 성능 최적화

CSM 케스케이드 스플릿 제한: 최대 2개

• 템포럴 리프로젝션 Temporal Reprojection

태양의 움직임에 따른 플리커링 방지 + PCSS 샘플링 아티팩트 완화

이전 프레임과의 밝기 차이에 따라 다른 보간

PCSS

float2 Attenuation = Texture2DSample(SunLightAttenuationTexture, TextureSamplerPoint, PrevScreenUV).xy;float2 ShadowAndSSSTransmission = float2(Shadow, SSSTransmission);const float2 TAAFactor = Square(1.0 - abs(ShadowAndSSSTransmission - Attenuation));ShadowAndSSSTransmission = lerp(ShadowAndSSSTransmission, Attenuation, 0.5 * TAAFactor);

Page 68: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
Page 69: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
Page 70: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
Page 71: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 그림자 안의 그림자:

캐릭터에 의해 이중으로 태양이 가려진 배경에 더 짙은 그림자 효과

그림자가 드리운 배경 위에 캐릭터가 있을 때의 어색함 개선

뚜렷한 방향성을 가짐: AO와는 다른 룩

• 메시의 본래 형태가 섀도우에 반영

전처리나 애셋 제작 작업이 불필요

비교> 캡슐 섀도우: UE 4.11와 The Order: 1886

스크린 스페이스 이너 섀도우 Screen Space Inner Shadows

Page 72: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• G 버퍼: 캐스터 Caster와 리시버 Receiver 정보 추가

비트 마스킹

1) 스텐실 마스킹 (옵션)

태양에 대한 디퍼드 섀도우: 그림자 영역만

Unlit 머티리얼을 제외

2) 섀도우 테스트: SSR Screen Space Reflection 스타일 레이 마칭

태양과 스카이의 하프 벡터로 전진

최대 거리 제한: 근거리 오클루더만 관심 / 성능과 품질

이전 프레임 버퍼에 템포럴 리프로젝션 Temporal Reprojection

스크린 스페이스 이너 섀도우 Screen Space Inner Shadows

L Sky

H

Sun ShadowInner Shadow

Page 73: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 스카이 라이팅과 GI에 반영

• ½ 해상도 버퍼

• 블러 필터링

• 약 0.5 ms

스크린 스페이스 이너 섀도우 Screen Space Inner Shadows

Page 74: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 그림자는 비주얼에 매우 중요

입체감 증대

시각의 변화를 체감하게 하는 요소

시각을 인지하게 하는 요소

• 가장 큰 이슈는 성능 최적화와 플리커링 방지

높은 드로우 콜

느리게 움직이는 디렉셔널 라이트 (태양)

그림자 렌더링 향후 작업

Page 75: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

런타임 캐릭터 리깅된피직스 시뮬레이션

Page 76: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 짧은 머리카락의 움직임

• 신체나 옷의 미세한 떨림

• 아티스트의 작업을 최소화

목적

Page 77: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 시뮬레이터 애셋 설정 (에디터)

현재는 스프링 시뮬레이션만

• 버텍스 그룹화

미리 정의한 버텍스 컬러와 시뮬레이터 애셋 기준

• 시뮬레이터 본 샘플링

버텍스 그룹의 바운딩 박스 내에, 애셋에 지정된 밀도에 따라 / 위치는 인접 버텍스에 스냅 snap

Poisson 분포 / 결정적 Deterministic 샘플링

• 리깅

시뮬레이터 본 -> 가까운 캐릭터 본의 차일드로

버텍스 -> 가까운 시뮬레이터 본에 리깅

거리에 따라 스키닝 웨이팅

구현

Page 78: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 이 외에도 다양한 방식을 도입하여 풍부한 표현을 시도

모듈식 애니메이션

절차적 애니메이션

물리 시뮬레이션

• 다른 기회를 통해 공개가 될 수도 있음

예) NDC 2017?

A1의 애니메이션 기술

Page 79: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

로우 레벨 셰이더 최적화

Page 80: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• UE4의 GPU 프로파일러

대략적인 비용 산출과 하이 레벨 셰이더 최적화

• RenderDoc, Intel GPA, AMD GPU PerfStudio 활용

로우 레벨 셰이더 최적화와 디버깅

• 최적화 관련 레퍼런스를 따라 손(hand)파일러 작업

방법

Page 81: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 에픽이 작성한 셰이더 코드는 크리티컬한 부분만 수정

지속적인 엔진 버전 업그레이드 때문에 아직은 소극적

게임 런칭 전에 전반적으로 검토 계획

• 우리가 직접 작성한 코드에 집중

• 이번 발표에서는 몇 가지 사례를 보여줌

최적화 대상

Page 82: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

수정 전 수정 후

전처리기를 사용한 스태틱 브랜칭

float3 L = (LightPositionAndIsDirectional.w == 1)? -LightPositionAndIsDirectional.xyz : normalize(LightPositionAndIsDirectional.xyz

- OpaqueWorldPosition);

#if USE_FADE_PLANE // CSM 사용 = 디렉셔널 라이트float3 L = -LightPositionAndIsDirectional.xyz;

#elsefloat3 L = (LightPositionAndIsDirectional.w == 1)

? -LightPositionAndIsDirectional.xyz : normalize(LightPositionAndIsDirectional.xyz

- OpaqueWorldPosition);#endif

Page 83: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

수정 전 수정 후

벡터라이즈와 명시적 MAD

float2 LookupUV = float2(CosPhiD, CosThetaD) * 0.5 + 0.5;float Backlit = saturate(-CosThetaD * 0.5 + 0.5);

float3 LookupUVandBacklit = saturate(mad(float3(CosPhiD, CosThetaD, -CosThetaD), 0.5, 0.5));

Page 84: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

수정 전 수정 후

앞선 계산 결과를 공유

for (int X = 0; X < NumSamplesSqrt; ++X) {

for (int Y = 0; Y < NumSamplesSqrt; Y++){

float2 ShadowOffset = TexelSize * StepSize * float2(X, Y);

const float2 BaseTexelSize = TexelSize * StepSize;…for (int X = 0; X < NumSamplesSqrt; ++X) {

for (int Y = 0; Y < NumSamplesSqrt; Y++){

float2 ShadowOffset = BaseTexelSize * float2(X, Y);

Page 85: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

수정 전 수정 후

스칼라/벡터 연산 재배치

float3 DiffuseLighting = (TangentDiffuse * GBuffer.DiffuseColor) / PI * NoLWrapped * ShadowColor;

float3 DiffuseLighting = GBuffer.DiffuseColor * (TangentDiffuse / PI * NoLWrapped * ShadowColor);

Page 86: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

수정 전 수정 후

모디파이어 modifier는 인풋으로

Force += -normalize(Position) * Simulation.GravityStrength; Force += normalize(-Position) * Simulation.GravityStrength;

Page 87: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

수정 전 수정 후

코드 라인 재배치

// 무언가 긴 작업…//clip(OpacityMask);

// 셰이더 메인이 시작 후 최대한 빨리…//clip(OpacityMask);

Page 88: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

가능한 종료 조건이 있다면 최대한 사용

Early-Z, Stencil, Discard

if (GBuffer.ShadingModelID != 0){

discard;}

float Attenuation = Texture2DSample(SunLightAttenuationTexture, TextureSamplerPoint, ScreenUV).x;if (Attenuation > 0.99){

discard;}

-------

[EARLYDEPTHSTENCIL]void OrderIndependentTransparencyCompositePixelMain(

float2 InScreenUV: TexCoord0, float4 InSVPosition: SV_Position, out float4 OutColor: SV_Target0){

Page 89: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

데이터 패킹과 캐시라인 정렬

ALU와 룩업 테이블의 효율

기타: 앞서 언급된 내용

#if OIT_PACK_RADIANCEuint RadianceRGY32;

#elsehalf4 Radiance;

#endif

float3 ComputeLongitudinalScattering(float3 Theta, float Roughness){

const float bR = DecodeHairLongitudinalWidth(Roughness);const float3 Beta3 = float3(bR, bR * 0.5, bR * 2);return exp(-0.5 * Square(Theta) / Square(Beta3) ) / (sqrt(2.0 * PI) * Beta3);

}

Page 90: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 지속적인 최적화

• 에픽에서 작성한 셰이더 코드 최적화

• 셰이더 컴파일러의 최적화가 매우 적극적이고 뛰어나서 놀랍지만,

종종 기대와는 다른 결과가 나오기 때문에

명시적으로 GPU 친화적 코드 작성 및 디스어셈블리 확인 필요

로우 레벨 최적화 향후 작업

Page 91: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• 넥슨의 새로운 IP 게임

• AAA급 그래픽 품질을 목표

• 최신 그래픽스 기술들의 도입 및 개발

• 아직 개발 중

세션 전체 요약

Page 92: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• A1 프로젝트 동료들

• 에픽코리아 기술 지원팀

• 레퍼런스된 자료들의 저작자분들

추후 토크 슬라이드의 공개 버전에서 자세히 명시 예정

도와주신 분들

Page 93: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

감사합니다.

WE ARE HIRING!

04/27 15:20 아트 세션:

도전! AAA 게임 비주얼 – 프로젝트 A1의 게임 아트

박성섭 / 아트 디렉터

04/27 17:05 프로그래밍 세션:

구형맵에서는 어떻게 길을 찾아야 하나요?

– 기초부터 이해하는 Recast 내비게이션 메시

하지훈 / 시니어 게임플레이 프로그래머

Page 94: NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술

• AMD TressFX Hair http://www.amd.com/en-us/innovations/software-technologies/technologies-gaming/tressfx

• Burke, “Hair In Destiny”, SIGGRAPH 2014 http://advances.realtimerendering.com/destiny/siggraph2014/heads/

• Burley, “Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering”, SIGGRAPH 2015 http://blog.selfshadow.com/publications/s2015-shading-course/#course_content

• d‘Eon, “An Energy-Conserving Hair Reflectance Model”, ESR 2011 http://www.eugenedeon.com/

• GCN Performance Tweets http://developer.amd.com/wordpress/media/2013/05/GCNPerformanceTweets.pdf

• Wexler, “GPU-Accelerated High-Quality Hidden Surface Removal”, Graphics Hardware 2005 http://developer.amd.com/wordpress/media/2013/05/GCNPerformanceTweets.pdf

• Jensen, “A Practical Model for Subsurface Light Transport”, SIGGRAPH 2001 http://www.graphics.stanford.edu/papers/bssrdf/

• Jimenez, “Next Generation Character Rendering”, GDC 2013 http://www.iryoku.com/stare-into-the-future

• Ki, Real-Time Subsurface Scattering using Shadow Maps, ShaderX7 http://amzn.to/1TxzadP

• Marschner, “Light Scattering from Human Hair Fibers”, SIGGRAPH 2003 https://www.cs.cornell.edu/~srm/publications/SG03-hair-abstract.html

• McAuley, “Rendering the World of Far Cry 4”, GDC 2015 http://www.gdcvault.com/play/1022235/Rendering-the-World-of-Far

• Moon, Simulating multiple scattering in hair using a photon mapping approach, SIGGRAPH 2006 https://www.cs.cornell.edu/~srm/publications/SG06-hair.pdf

• More Explosions, More Chaos, and Definitely More Blowing Stuff Up: Optimizations and New DirectX Features in ‘Just Cause 3′ https://software.intel.com/sites/default/files/managed/20/d5/2016_GDC_Optimizations-and-DirectX-features-in-JC3_v0-92_X.pdf

• Nguyen, “Hair Animation and Rendering in the Nalu Demo”, GPU Gems 2 http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter23.html

• NVIDIA GameWorks Blog https://developer.nvidia.com/gameworks/blog

• Persson, Low-level Shader Optimization for Next-Gen and DX11, GDC 2014 http://www.humus.name/index.php?page=Articles

• Persson, Low-Level Thinking in High-Level Shading Languages, GDC 2013 http://www.humus.name/index.php?page=Articles

• Pettineo, “A Sampling of Shadow Techniques” https://mynameismjp.wordpress.com/2013/09/10/shadow-maps/

• Phail-Liff, “Melton and Moustaches: The Character Art and Shot Lighting Pipelines of The Order: 1886” http://www.readyatdawn.com/presentations/

• Thibieroz, Grass, Fur and all Things Hairy, GDC 2014 http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Grass-Fur-and-All-Things-Hairy-Thibieroz-Hillesland.ppsx

• Unreal Engine 4 https://www.unrealengine.com/

레퍼런스