SlideShare une entreprise Scribd logo
1  sur  94
Télécharger pour lire hors ligne
프로젝트 <A1>의
AAA급 캐릭터 렌더링 기술
기 현 우
리드 그래픽스 프로그래머
A1 / NEXON
* NDC 2016 발표의 공개 버전으로써, 발표 내용은 같지만 스샷과 레퍼런스에 약간의 변경이 있습니다.
• 넥슨의 미공개 신작 프로젝트 / 새로운 IP
 아직 개발 중 (출시일 미정)
 게임 개발 베테랑들로 구성된 팀
 타겟 플랫폼: 하이엔드급 PC
- 풀옵 60 FPS 기준 / 보급된 평균 사양에서도 괜찮은 품질로 원만하게 동작하게 할 계획
• NDC 2016에서 처음으로 개발 소식 공개
A1
• 프로그래밍 세션: 캐릭터 렌더링
 아직 개발 중인 리소스와 구현을 포함 / 기술적인 내용을 다룸
 캐릭터 중심으로 발표 / 실제 월드와 월드 렌더링에 사용된 기술은 미공개
 모든 내용은 개발 과정에서 바뀔 수 있음
A1@NDC 2016
• 04/27 15:20 아트 세션:
“도전! AAA 게임 비주얼 – 프로젝트 A1의 게임 아트”
박성섭 / 아트 디렉터
• 04/27 17:05 프로그래밍 세션:
“구형맵에서는 어떻게 길을 찾아야 하나요? – 기초부터 이해하는 Recast 내비게이션 메시”
하지훈 / 시니어 게임플레이 프로그래머
• 경쟁 게임에 차별성 있는 매우 뛰어난 품질의 비주얼이 강점
 국산 게임에서 볼 수 없던 수준이 목표
 마케팅용 과장이 아닌 진짜 AAA급 그래픽 품질
 어떤 기술을 사용하고, 어느 정도 수준의 결과가 나오고 있는지를 보여주기 위한 발표
• UE4 + @@@
 UE4의 뛰어난 기능을 최대한 활용
 새로운 렌더링/애니메이션/VFX 기능 등을 추가로 구현 중
A1과 비주얼
• 피부, 머리카락, 금속 렌더링
• 그림자 렌더링
• 로우 레벨 셰이더 최적화
• 런타임 캐릭터 리깅 피직스 시뮬레이션
• 요약
목차
피부 렌더링
• 멀티플 스케터링 Multiple Scattering
 Dipole Diffusion Approximation
 Jensen에 의해 그래픽스 분야에서 사용됨
• UE4에 기본 포함
 Jimenez가 제안한 실시간 렌더링 기술
 업계 대세 / 그대로 사용
SSSSS Screen Space SubSurface Scattering
Activision R&D. Property of Activision Publishing. Not Actual Gameplay
No SSSSS
• 부드러운 라이팅
• 부드러운 섀도우
• 촉촉함
SSSSS
• 메시 결에 따른
스페큘러 변화
베이스 노멀
• 피부 결에 따른
스페큘러 변화
디테일 노멀
• 투과 현상 없음
 스크린 스페이스의 한계
 화면 밖에서 입사되는 빛을 무시
 투과를 보강하는 에디션이 있음: UE4엔 미포함
• 저주파 라이팅만 Low-frequency
 짧은 거리에서의 강한 산란 현상 표현 못 함
UE4 SSSSS의 한계
Burley, “Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering”, SIGGRAPH 2015
• 투과 (역광 Back Lit)
• 백 스케터링 Back Scattering
• 고주파 라이팅 High-frequency
싱글 스케터링 Single Scattering
싱글 스케터링 멀티플 스케터링 (dipole)
멀티플 스케터링
+ =싱글 + 멀티플 스케터링
* 싱글 스케터링은 프리젠테이션 스크린에서 눈에 좀 더 잘 띄기 위해 약간 과장된 세팅
• ShaderX7에 소개했던 기법
 Hyunwoo Ki, “Real-Time Subsurface Scattering using Shadow Maps”
 표면에 입사된 반투명 이래디언스 정보를 여러 장의 섀도우 맵에 저장
 레이 마칭 시 섀도우 맵 투영으로 빛의 단일 산란 거리 근사
 이래디언스와 산란 거리를 기반으로 조명식을 계산
• 변형해서 UE4에 통합하여 사용
 디퍼드 싱글 스케터링
섀도우 맵을 사용한 싱글 스케터링
ground truth Ki09
• 카메라에서 광선 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
j
iit
xs
oi
xs
otos ω,xEeω,ωpeωFx itioto
0 0
,,   
  tos log
1) 디퍼드 섀도우 패스:
 콰지 몬테 카를로 레이 마칭 방식은 변화 없음
 단, 모든 샘플링 단계에서 이래디언스와 노멀이 같다고 가정 -> 이미 준비된 섀도우 맵 한 장만 필요 (추가 없음!)
 고정 산란 계수 사용: G 버퍼 제한과 성능 때문
 출력: 단일 채널 싱글 스캐터링 전달량 transfer
2) 디퍼드 라이팅 패스:
 디퍼드 섀도우 버퍼에 저장된 SS 전달량(스칼라) * SSS 컬러 * 양방향 프레넬 투과 * HG 위상 함수 Phase Function
 출력: 디퓨즈 + 스페큘러 + 싱글 스케터링
• 물리적으로는 부정확하지만 보기엔 괜찮은 결과
디퍼드 싱글 스케터링 Deferred Single Scattering
       
  


N
i
M
j
ss
iitoiots
toi
eω,xEω,ωpωF
0 0
,, 


2) 라이팅 패스 1) 섀도우 패스
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;
}
참고) 레이 마칭 셰이더 코드
• 두께가 얇은 귀에 투과 효과
 역광
• 눈 밑, 코, 입술 등을 더 밝게
 마스킹 사용 / 미적인 선택
• 라이트 당 1 ms 미만 추가
 근접 뷰 기준 / 뷰에 따라 다름
렌더링 결과
* 싱글 스케터링은 프리젠테이션 스크린에서 눈에 좀 더 잘 띄기 위해 약간 과장된 세팅
• 디더드 템포럴 Dithered Temporal 샘플링을 사용한 최적화
 볼류메트릭 라이팅에서 사용한 다른 게임의 사례가 있음: Killzone: Shadow Fall, Loads of Fallen, INSIDE 등
 템포럴 리프로젝션 Temporal Reprojection
• 피부에 한하여 섀도우 렌더링을 대체하는 용도
 현재는 UE4의 원래 방식대로 불투명 표면에 대한 섀도우 렌더링과 동일 (이중 계산)
 싱글 스케터링의 볼륨 라이팅 감쇠 성질상 섀도우 표현이 가능할 것으로 기대
싱글 스케터링 향후 작업
머리카락 렌더링
• 겹겹의 카드 메시 + 텍스처 알파
• 잔머리 메시
• 옵션 텍스처:
 컬러, 노멀, 러프니스, AO, 스페큘러 시프트
• Destiny와 The Order: 1886도 유사
모델링과 텍스처링
• 반투명 렌더링
 알파 블렌딩: 픽셀 레벨의 드로잉 순서
 라이팅: 디퍼드 라이팅의 사용 불가
 섀도잉: 디퍼드 섀도잉의 사용 불가
• 물리 기반 셰이딩 모델
 일반적인 GGX 모델로는 표현할 수 없음
난제
알파 테스트 Alpha Test : 알파 블렌드 Alpha Blend
알파 블렌딩 순서의 중요성
• 픽셀 레벨의 정확한 알파 블렌딩이 필요
• K-Buffer 스타일로 결정
 Per-Pixel Linked List (PPLL)
 DX11 Unordered Access View (UAV) 사용
 AMD TressFX 2.0 샘플 기반
 UE4 렌더러에 통합
Order Independent Transparency (OIT)
• 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;
• 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;
}
• 반투명 포워드 라이팅 결과를 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;
}
렌더링 결과
• 카드 메시 레이어가 많아서 매우 많은 픽셀 오버 드로우
• UAV를 사용한 단일 패스 오패시티 임계처리로 최적화
 사실 알파 블렌딩은 투명성을 위해서가 아닌, 단지 매우 가는 머리카락 가닥을 깨끗하게 렌더링하기 위함
 헤어 끝을 제외하면 사실상 거의 불투명 (특히 안 쪽 레이어)
 불투명 픽셀 뒤에 가려진 픽셀들의 오버 드로우를 최소화 해보자!
오버 드로우 최적화
• 머티리얼마다 오패시티 임계값 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
• 추가 UAV 버퍼 및 UAV 읽기/쓰기가 발생하지만 총 비용은 감소
• 5~10% 속도 향상과 15% 메모리 절약
 라이팅 비용을 줄일 수 있음
 OIT 버퍼 크기를 줄일 수 있음
 단일 패스로써 드로잉 추가가 없음
 래스터라이즈 순서 ‘운’?
렌더링 결과
• 래스터라이즈 순서 예측을 통한 UOT Unordered Opacity Thresholding 효율 개선
 인덱스 버퍼 순서와 로케일리티 locality?
 메시 분할? - 드로우 콜보다 픽셀 오버 드로우가 더 문제이기 때문
 하지만 애니메이션에 따라 순서가 뒤바뀌는 경우가 있음
• DX12의 ROV Raster Ordered View를 사용한 더 나은 구현
OIT 향후 작업
• 반투명 머티리얼에 픽셀 단위 라이팅을 위함
• UE4의 실험적 기능을 기반으로 아직 개량 중
• 필요에 따라 제한적인 사용
 현재는 머리카락 전용이나 유리/플라스틱 류에 추가 가능성 있음
• 섀도우 렌더링 지원
 반투명 디퍼드 섀도우
포워드+ 라이팅 Forward+ Lighting
• 16x16 타일 컬링
• 포워드 라이트 데이터
 Constant Buffer 사용: StructuredBuffer보다 빠름 (NV)
 128비트 스트라이드: 캐시 효율, 64KB 미만 유지
 SOA? AOS?
포워드+ 라이팅 Forward+ Lighting
포워드+ 라이팅
포워드+ 라이팅 + 섀도잉 + 산란
• 포워드 라이팅 패스에서 섀도우 계산 시 문제
 복잡한 중첩 브랜치 코드 증가 / GPR General Purpose Register 압박
 포워드 라이트 데이터(CB)의 증가: 섀도우 매트릭스 및 기타 섀도우 파라메터
 동시에 많은 섀도우 맵의 할당 필요 (고해상도 CSM 또는 큐브맵)
• 반투명 디퍼드 섀도우:
 가장 앞 면의 front-most 반투명 픽셀에 대한 디퍼드 섀도우 렌더링
 일반적인 디퍼드 섀도우 패스에 통합
 정확도는 희생하지만 보기에 괜찮은 결과
반투명 디퍼드 섀도우 Transparent Deferred Shadows
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);
디퍼드 섀도우 : 반투명 디퍼드 섀도우
최종 렌더링
* =
• 더 많은 라이트 및 머티리얼 지원
• 더 빠른 라이트 버퍼 액세스
• 안 쪽 레이어의 헤어에 대한 더 나은 섀도잉
 Z에 따른 감쇠?
• 싱글 스케터링과의 버퍼 채널 충돌 문제
 피부 위를 덮은 머리카락이 있을 때, 머리카락 섀도우가 우선시 되는 문제
포워드+ 라이팅과 섀도잉 향후 작업
• Marschner 모델: 헤어 가닥 = 실린더
• 반사, 2차 반사, 투과
 반사: R
 2차 반사: TRT
 투과: TT
• 산란 효과 추가
물리 기반 셰이딩 모델
헤어 라이팅
R: 반사
TRT: 2차 반사
TT: 투과
• 경도 산란 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
• 머티리얼 별 속성 정의
 이 값을 바탕으로 위도 산란 룩업 테이블 제작
 G 버퍼 절약 효과
 재사용성
• 룩업 테이블
 스펙트럴 형태인 TRT/TT의 흡수율 absorption은 단일 채널로 / 성능 이슈
 R 채널: R, G 채널: TRT, B 채널: TT
헤어 프로파일 애셋 Hair Profile Asset
• 단일 채널 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);
• 페이크 스케터링: 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;
}
페이크 스케터링
• 스크린 스페이스 볼륨 포톤 매핑 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); // isotropic
GaussPhotonScattering += PhotonContribution * GaussianWeights[GaussianWeightIndex];
스크린 스페이스 볼륨 포톤 매핑
디퓨즈 라이팅
• 탄젠트 램버시안
DiffuseLighting = max(0, sqrt(1 – SinThetaI * SinTetaI))
* EnergeConservingWrappedDiffuse(N, L, 1)
* DiffuseIntensity
종합
• 스페큘러 파라메터
 노이즈: 헤어 결의 퍼지 fuzzy 효과
 러프니스: 하이라이트의 너비와 세기
 시프트: 헤어 가닥의 하이라이트 기준 위치 이동
 헤어 프로파일 애셋
• 디퓨즈, 페이크 스케터링, 각종 텍스처
• 기타 다수의 파라메터
-> 다양한 스타일로 제작할 수 있도록
헤어 머티리얼
• 산란 품질 개선
• 머티리얼 LOD
• 머리카락 스타일 별로 최적의 애셋 제작 방식 찾기
헤어 셰이딩 향후 작업
금속 렌더링
• 아직 실험 단계
• Anisotropic GGX
• Far Cry 4 스타일
• 여러 라이팅에 영향
 다이렉트 라이팅, 스카이 라이팅, 리플렉션 인바이론먼트, SSR
 탄젠트 이래디언스 맵 사용 검토 중
비등방성 스페큘러
그림자 렌더링
• 캐릭터 뷰어 및 로비
 EVSM: Exponential Variance Shadow Maps
• 게임 씬
 태양 전용 - PCSS: Percentage Closer Soft Shadows
 나머지 라이트 – PCF: Percentage Closer Filtering / UE4 그대로 사용
 부가적 그림자 - Screen Space Inner Shadows
씬에 따라 다른 접근
• 캐릭터 뷰어 및 로비 전용
 실험적 기능 / 배경이 복잡한 경우에 만족스럽지 않은 품질
• 프리 필터드 섀도우 Pre-filtered Shadows
 기본 알고리즘에서 변형 없음
• 성능 최적화
 CSM 케스케이드 스플릿 제한: 최대 2개
 시저 테스트: 스크린 스페이스 섀도우 바운드보다 약간 크게
EVSM
• 게임 씬의 태양 전용
• 시간 변화 라이팅 요소 중 하나로 사용
 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);
• 그림자 안의 그림자:
 캐릭터에 의해 이중으로 태양이 가려진 배경에 더 짙은 그림자 효과
 그림자가 드리운 배경 위에 캐릭터가 있을 때의 어색함 개선
 뚜렷한 방향성을 가짐: AO와는 다른 룩
• 메시의 본래 형태가 섀도우에 반영
 전처리나 애셋 제작 작업이 불필요
 비교> 캡슐 섀도우: UE 4.11와 The Order: 1886
스크린 스페이스 이너 섀도우 Screen Space Inner Shadows
• G 버퍼: 캐스터 Caster와 리시버 Receiver 정보 추가
 비트 마스킹
1) 스텐실 마스킹 (옵션)
 태양에 대한 디퍼드 섀도우: 그림자 영역만
 Unlit 머티리얼을 제외
2) 섀도우 테스트: SSR Screen Space Reflection 스타일 레이 마칭
 태양과 스카이의 하프 벡터로 전진
 최대 거리 제한: 근거리 오클루더만 관심 / 성능과 품질
 이전 프레임 버퍼에 템포럴 리프로젝션 Temporal Reprojection
스크린 스페이스 이너 섀도우 Screen Space Inner Shadows
L Sky
H
Sun ShadowInner Shadow
• 스카이 라이팅과 GI에 반영
• ½ 해상도 버퍼
• 블러 필터링
• 약 0.5 ms
스크린 스페이스 이너 섀도우 Screen Space Inner Shadows
• 그림자는 비주얼에 매우 중요
 입체감 증대
 시각의 변화를 체감하게 하는 요소
 시각을 인지하게 하는 요소
• 가장 큰 이슈는 성능 최적화와 플리커링 방지
 높은 드로우 콜
 느리게 움직이는 디렉셔널 라이트 (태양)
그림자 렌더링 향후 작업
런타임 캐릭터 리깅된
피직스 시뮬레이션
• 짧은 머리카락의 움직임
• 신체나 옷의 미세한 떨림
• 아티스트의 작업을 최소화
목적
• 시뮬레이터 애셋 설정 (에디터)
 현재는 스프링 시뮬레이션만
• 버텍스 그룹화
 미리 정의한 버텍스 컬러와 시뮬레이터 애셋 기준
• 시뮬레이터 본 샘플링
 버텍스 그룹의 바운딩 박스 내에, 애셋에 지정된 밀도에 따라 / 위치는 인접 버텍스에 스냅 snap
 Poisson 분포 / 결정적 Deterministic 샘플링
• 리깅
 시뮬레이터 본 -> 가까운 캐릭터 본의 차일드로
 버텍스 -> 가까운 시뮬레이터 본에 리깅
 거리에 따라 스키닝 웨이팅
구현
• 이 외에도 다양한 방식을 도입하여 풍부한 표현을 시도
 모듈식 애니메이션
 절차적 애니메이션
 물리 시뮬레이션
• 다른 기회를 통해 공개가 될 수도 있음
 예) NDC 2017?
A1의 애니메이션 기술
로우 레벨 셰이더 최적화
• UE4의 GPU 프로파일러
 대략적인 비용 산출과 하이 레벨 셰이더 최적화
• RenderDoc, Intel GPA, AMD GPU PerfStudio 활용
 로우 레벨 셰이더 최적화와 디버깅
• 최적화 관련 레퍼런스를 따라 손(hand)파일러 작업
방법
• 에픽이 작성한 셰이더 코드는 크리티컬한 부분만 수정
 지속적인 엔진 버전 업그레이드 때문에 아직은 소극적
 게임 런칭 전에 전반적으로 검토 계획
• 우리가 직접 작성한 코드에 집중
• 이번 발표에서는 몇 가지 사례를 보여줌
최적화 대상
수정 전 수정 후
전처리기를 사용한 스태틱 브랜칭
float3 L = (LightPositionAndIsDirectional.w == 1)
? -LightPositionAndIsDirectional.xyz
: normalize(LightPositionAndIsDirectional.xyz
- OpaqueWorldPosition);
#if USE_FADE_PLANE // CSM 사용 = 디렉셔널 라이트
float3 L = -LightPositionAndIsDirectional.xyz;
#else
float3 L = (LightPositionAndIsDirectional.w == 1)
? -LightPositionAndIsDirectional.xyz
: normalize(LightPositionAndIsDirectional.xyz
- OpaqueWorldPosition);
#endif
수정 전 수정 후
벡터라이즈와 명시적 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));
수정 전 수정 후
앞선 계산 결과를 공유
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);
수정 전 수정 후
스칼라/벡터 연산 재배치
float3 DiffuseLighting = (TangentDiffuse * GBuffer.DiffuseColor)
/ PI * NoLWrapped * ShadowColor;
float3 DiffuseLighting = GBuffer.DiffuseColor
* (TangentDiffuse / PI * NoLWrapped * ShadowColor);
수정 전 수정 후
모디파이어 modifier는 인풋으로
Force += -normalize(Position) * Simulation.GravityStrength; Force += normalize(-Position) * Simulation.GravityStrength;
수정 전 수정 후
코드 라인 재배치
// 무언가 긴 작업…
//
clip(OpacityMask);
// 셰이더 메인이 시작 후 최대한 빨리…
//
clip(OpacityMask);
가능한 종료 조건이 있다면 최대한 사용
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)
{
…
데이터 패킹과 캐시라인 정렬
ALU와 룩업 테이블의 효율
기타: 앞서 언급된 내용
#if OIT_PACK_RADIANCE
uint RadianceRGY32;
#else
half4 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);
}
• 지속적인 최적화
• 에픽에서 작성한 셰이더 코드 최적화
• 셰이더 컴파일러의 최적화가 매우 적극적이고 뛰어나서 놀랍지만,
종종 기대와는 다른 결과가 나오기 때문에
명시적으로 GPU 친화적 코드 작성 및 디스어셈블리 확인 필요
로우 레벨 최적화 향후 작업
• 넥슨의 새로운 IP 게임
• AAA급 그래픽 품질을 목표
• 최신 그래픽스 기술들의 도입 및 개발
• 아직 개발 중
세션 전체 요약
• A1 프로젝트 동료들
• 에픽코리아 기술 지원팀
• 레퍼런스된 자료들의 저작자분들
 추후 토크 슬라이드의 공개 버전에서 자세히 명시 예정
도와주신 분들
감사합니다.
WE ARE HIRING!
04/27 15:20 아트 세션:
도전! AAA 게임 비주얼 – 프로젝트 A1의 게임 아트
박성섭 / 아트 디렉터
04/27 17:05 프로그래밍 세션:
구형맵에서는 어떻게 길을 찾아야 하나요?
– 기초부터 이해하는 Recast 내비게이션 메시
하지훈 / 시니어 게임플레이 프로그래머
• 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/
레퍼런스

Contenu connexe

Tendances

김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019devCAT Studio, NEXON
 
Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .YEONG-CHEON YOU
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리MinGeun Park
 
AAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptxAAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptxTonyCms
 
물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다 공개용
물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다  공개용물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다  공개용
물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다 공개용JP Jung
 
물리 기반 셰이더의 이해
물리 기반 셰이더의 이해물리 기반 셰이더의 이해
물리 기반 셰이더의 이해tartist
 
[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기
[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기
[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기Madumpa Park
 
2009-2016 기본기(손맵)의 중요성
2009-2016 기본기(손맵)의 중요성2009-2016 기본기(손맵)의 중요성
2009-2016 기본기(손맵)의 중요성Gunho Shin
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술YEONG-CHEON YOU
 
[1023 박민수] 깊이_버퍼_그림자_1
[1023 박민수] 깊이_버퍼_그림자_1[1023 박민수] 깊이_버퍼_그림자_1
[1023 박민수] 깊이_버퍼_그림자_1MoonLightMS
 
TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)
TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)
TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)valhashi
 
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리MinGeun Park
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근MinGeun Park
 
2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑Sukwoo Lee
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012devCAT Studio, NEXON
 
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례SangYun Yi
 

Tendances (20)

Motion blur
Motion blurMotion blur
Motion blur
 
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
 
Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
 
Ndc11 이창희_hdr
Ndc11 이창희_hdrNdc11 이창희_hdr
Ndc11 이창희_hdr
 
AAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptxAAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptx
 
물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다 공개용
물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다  공개용물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다  공개용
물리 기반 셰이더의 허와 실:물리기반 셰이더를 가르쳐 봤습니다 공개용
 
물리 기반 셰이더의 이해
물리 기반 셰이더의 이해물리 기반 셰이더의 이해
물리 기반 셰이더의 이해
 
[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기
[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기
[NDC19] 모바일에서 사용가능한 유니티 커스텀 섭스턴스 PBR 셰이더 만들기
 
High dynamic range
High dynamic rangeHigh dynamic range
High dynamic range
 
2009-2016 기본기(손맵)의 중요성
2009-2016 기본기(손맵)의 중요성2009-2016 기본기(손맵)의 중요성
2009-2016 기본기(손맵)의 중요성
 
Ssao
SsaoSsao
Ssao
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술
 
[1023 박민수] 깊이_버퍼_그림자_1
[1023 박민수] 깊이_버퍼_그림자_1[1023 박민수] 깊이_버퍼_그림자_1
[1023 박민수] 깊이_버퍼_그림자_1
 
TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)
TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)
TA가 뭐예요? (What is a Technical Artist? 블루홀스튜디오)
 
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
 
2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
 
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
Unity3D 엔진을 활용한 게임환경 분석 및 3D 그래픽스 기술 /제작 사례
 

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

실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬현찬 양
 
Hierachical z Map Occlusion Culling
Hierachical z Map Occlusion CullingHierachical z Map Occlusion Culling
Hierachical z Map Occlusion CullingYEONG-CHEON YOU
 
[0326 박민근] deferred shading
[0326 박민근] deferred shading[0326 박민근] deferred shading
[0326 박민근] deferred shadingMinGeun Park
 
[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shadingMinGeun Park
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blogozlael ozlael
 
[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기changehee lee
 
Deferred Shading
Deferred ShadingDeferred Shading
Deferred Shading종빈 오
 
[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...종빈 오
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희changehee lee
 
Voxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseVoxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseYEONG-CHEON YOU
 
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법강 민우
 
[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트
[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트
[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트강 민우
 
[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)해강
 
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)민웅 이
 
[박민근] 3 d렌더링 옵티마이징_2
[박민근] 3 d렌더링 옵티마이징_2[박민근] 3 d렌더링 옵티마이징_2
[박민근] 3 d렌더링 옵티마이징_2MinGeun Park
 
Kgc2014 jplee allegorithmic
Kgc2014 jplee allegorithmicKgc2014 jplee allegorithmic
Kgc2014 jplee allegorithmicLee Jungpyo
 
전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011devCAT Studio, NEXON
 
니시카와젠지의 3 d 게임 팬을 위한 ps4
니시카와젠지의 3 d 게임 팬을 위한 ps4니시카와젠지의 3 d 게임 팬을 위한 ps4
니시카와젠지의 3 d 게임 팬을 위한 ps4민웅 이
 

Similaire à NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술 (20)

실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬
 
Hierachical z Map Occlusion Culling
Hierachical z Map Occlusion CullingHierachical z Map Occlusion Culling
Hierachical z Map Occlusion Culling
 
[0326 박민근] deferred shading
[0326 박민근] deferred shading[0326 박민근] deferred shading
[0326 박민근] deferred shading
 
[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading
 
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
 
[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기[Kgc2013] 모바일 엔진 개발기
[Kgc2013] 모바일 엔진 개발기
 
Deferred Shading
Deferred ShadingDeferred Shading
Deferred Shading
 
[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...
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희
 
Voxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseVoxel based game_optimazation_relelase
Voxel based game_optimazation_relelase
 
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
 
[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트
[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트
[IGC 2017] 에픽게임즈 최용훈 - 밤낮으로 부수고 짓고 액션 빌딩 게임 만들기 - 포트나이트
 
[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)
 
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
 
[박민근] 3 d렌더링 옵티마이징_2
[박민근] 3 d렌더링 옵티마이징_2[박민근] 3 d렌더링 옵티마이징_2
[박민근] 3 d렌더링 옵티마이징_2
 
Devtree illu
Devtree illuDevtree illu
Devtree illu
 
Kgc2014 jplee allegorithmic
Kgc2014 jplee allegorithmicKgc2014 jplee allegorithmic
Kgc2014 jplee allegorithmic
 
전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011전형규, Vertex Post-Processing Framework, NDC2011
전형규, Vertex Post-Processing Framework, NDC2011
 
니시카와젠지의 3 d 게임 팬을 위한 ps4
니시카와젠지의 3 d 게임 팬을 위한 ps4니시카와젠지의 3 d 게임 팬을 위한 ps4
니시카와젠지의 3 d 게임 팬을 위한 ps4
 

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

  • 1. 프로젝트 <A1>의 AAA급 캐릭터 렌더링 기술 기 현 우 리드 그래픽스 프로그래머 A1 / NEXON * NDC 2016 발표의 공개 버전으로써, 발표 내용은 같지만 스샷과 레퍼런스에 약간의 변경이 있습니다.
  • 2. • 넥슨의 미공개 신작 프로젝트 / 새로운 IP  아직 개발 중 (출시일 미정)  게임 개발 베테랑들로 구성된 팀  타겟 플랫폼: 하이엔드급 PC - 풀옵 60 FPS 기준 / 보급된 평균 사양에서도 괜찮은 품질로 원만하게 동작하게 할 계획 • NDC 2016에서 처음으로 개발 소식 공개 A1
  • 3. • 프로그래밍 세션: 캐릭터 렌더링  아직 개발 중인 리소스와 구현을 포함 / 기술적인 내용을 다룸  캐릭터 중심으로 발표 / 실제 월드와 월드 렌더링에 사용된 기술은 미공개  모든 내용은 개발 과정에서 바뀔 수 있음 A1@NDC 2016 • 04/27 15:20 아트 세션: “도전! AAA 게임 비주얼 – 프로젝트 A1의 게임 아트” 박성섭 / 아트 디렉터 • 04/27 17:05 프로그래밍 세션: “구형맵에서는 어떻게 길을 찾아야 하나요? – 기초부터 이해하는 Recast 내비게이션 메시” 하지훈 / 시니어 게임플레이 프로그래머
  • 4. • 경쟁 게임에 차별성 있는 매우 뛰어난 품질의 비주얼이 강점  국산 게임에서 볼 수 없던 수준이 목표  마케팅용 과장이 아닌 진짜 AAA급 그래픽 품질  어떤 기술을 사용하고, 어느 정도 수준의 결과가 나오고 있는지를 보여주기 위한 발표 • UE4 + @@@  UE4의 뛰어난 기능을 최대한 활용  새로운 렌더링/애니메이션/VFX 기능 등을 추가로 구현 중 A1과 비주얼
  • 5. • 피부, 머리카락, 금속 렌더링 • 그림자 렌더링 • 로우 레벨 셰이더 최적화 • 런타임 캐릭터 리깅 피직스 시뮬레이션 • 요약 목차
  • 7. • 멀티플 스케터링 Multiple Scattering  Dipole Diffusion Approximation  Jensen에 의해 그래픽스 분야에서 사용됨 • UE4에 기본 포함  Jimenez가 제안한 실시간 렌더링 기술  업계 대세 / 그대로 사용 SSSSS Screen Space SubSurface Scattering Activision R&D. Property of Activision Publishing. Not Actual Gameplay
  • 9. • 부드러운 라이팅 • 부드러운 섀도우 • 촉촉함 SSSSS
  • 10. • 메시 결에 따른 스페큘러 변화 베이스 노멀
  • 11. • 피부 결에 따른 스페큘러 변화 디테일 노멀
  • 12. • 투과 현상 없음  스크린 스페이스의 한계  화면 밖에서 입사되는 빛을 무시  투과를 보강하는 에디션이 있음: UE4엔 미포함 • 저주파 라이팅만 Low-frequency  짧은 거리에서의 강한 산란 현상 표현 못 함 UE4 SSSSS의 한계 Burley, “Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering”, SIGGRAPH 2015
  • 13. • 투과 (역광 Back Lit) • 백 스케터링 Back Scattering • 고주파 라이팅 High-frequency 싱글 스케터링 Single Scattering 싱글 스케터링 멀티플 스케터링 (dipole)
  • 15. + =싱글 + 멀티플 스케터링 * 싱글 스케터링은 프리젠테이션 스크린에서 눈에 좀 더 잘 띄기 위해 약간 과장된 세팅
  • 16. • ShaderX7에 소개했던 기법  Hyunwoo Ki, “Real-Time Subsurface Scattering using Shadow Maps”  표면에 입사된 반투명 이래디언스 정보를 여러 장의 섀도우 맵에 저장  레이 마칭 시 섀도우 맵 투영으로 빛의 단일 산란 거리 근사  이래디언스와 산란 거리를 기반으로 조명식을 계산 • 변형해서 UE4에 통합하여 사용  디퍼드 싱글 스케터링 섀도우 맵을 사용한 싱글 스케터링 ground truth Ki09
  • 17. • 카메라에서 광선 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 j iit xs oi xs otos ω,xEeω,ωpeωFx itioto 0 0 ,,      tos log
  • 18. 1) 디퍼드 섀도우 패스:  콰지 몬테 카를로 레이 마칭 방식은 변화 없음  단, 모든 샘플링 단계에서 이래디언스와 노멀이 같다고 가정 -> 이미 준비된 섀도우 맵 한 장만 필요 (추가 없음!)  고정 산란 계수 사용: G 버퍼 제한과 성능 때문  출력: 단일 채널 싱글 스캐터링 전달량 transfer 2) 디퍼드 라이팅 패스:  디퍼드 섀도우 버퍼에 저장된 SS 전달량(스칼라) * SSS 컬러 * 양방향 프레넬 투과 * HG 위상 함수 Phase Function  출력: 디퓨즈 + 스페큘러 + 싱글 스케터링 • 물리적으로는 부정확하지만 보기엔 괜찮은 결과 디퍼드 싱글 스케터링 Deferred Single Scattering              N i M j ss iitoiots toi eω,xEω,ωpωF 0 0 ,,    2) 라이팅 패스 1) 섀도우 패스
  • 19. 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; } 참고) 레이 마칭 셰이더 코드
  • 20. • 두께가 얇은 귀에 투과 효과  역광 • 눈 밑, 코, 입술 등을 더 밝게  마스킹 사용 / 미적인 선택 • 라이트 당 1 ms 미만 추가  근접 뷰 기준 / 뷰에 따라 다름 렌더링 결과
  • 21. * 싱글 스케터링은 프리젠테이션 스크린에서 눈에 좀 더 잘 띄기 위해 약간 과장된 세팅
  • 22. • 디더드 템포럴 Dithered Temporal 샘플링을 사용한 최적화  볼류메트릭 라이팅에서 사용한 다른 게임의 사례가 있음: Killzone: Shadow Fall, Loads of Fallen, INSIDE 등  템포럴 리프로젝션 Temporal Reprojection • 피부에 한하여 섀도우 렌더링을 대체하는 용도  현재는 UE4의 원래 방식대로 불투명 표면에 대한 섀도우 렌더링과 동일 (이중 계산)  싱글 스케터링의 볼륨 라이팅 감쇠 성질상 섀도우 표현이 가능할 것으로 기대 싱글 스케터링 향후 작업
  • 24. • 겹겹의 카드 메시 + 텍스처 알파 • 잔머리 메시 • 옵션 텍스처:  컬러, 노멀, 러프니스, AO, 스페큘러 시프트 • Destiny와 The Order: 1886도 유사 모델링과 텍스처링
  • 25. • 반투명 렌더링  알파 블렌딩: 픽셀 레벨의 드로잉 순서  라이팅: 디퍼드 라이팅의 사용 불가  섀도잉: 디퍼드 섀도잉의 사용 불가 • 물리 기반 셰이딩 모델  일반적인 GGX 모델로는 표현할 수 없음 난제
  • 26. 알파 테스트 Alpha Test : 알파 블렌드 Alpha Blend
  • 28. • 픽셀 레벨의 정확한 알파 블렌딩이 필요 • K-Buffer 스타일로 결정  Per-Pixel Linked List (PPLL)  DX11 Unordered Access View (UAV) 사용  AMD TressFX 2.0 샘플 기반  UE4 렌더러에 통합 Order Independent Transparency (OIT)
  • 29. • 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;
  • 30. • 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; }
  • 31. • 반투명 포워드 라이팅 결과를 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; }
  • 33. • 카드 메시 레이어가 많아서 매우 많은 픽셀 오버 드로우 • UAV를 사용한 단일 패스 오패시티 임계처리로 최적화  사실 알파 블렌딩은 투명성을 위해서가 아닌, 단지 매우 가는 머리카락 가닥을 깨끗하게 렌더링하기 위함  헤어 끝을 제외하면 사실상 거의 불투명 (특히 안 쪽 레이어)  불투명 픽셀 뒤에 가려진 픽셀들의 오버 드로우를 최소화 해보자! 오버 드로우 최적화
  • 34. • 머티리얼마다 오패시티 임계값 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
  • 35. • 추가 UAV 버퍼 및 UAV 읽기/쓰기가 발생하지만 총 비용은 감소 • 5~10% 속도 향상과 15% 메모리 절약  라이팅 비용을 줄일 수 있음  OIT 버퍼 크기를 줄일 수 있음  단일 패스로써 드로잉 추가가 없음  래스터라이즈 순서 ‘운’? 렌더링 결과
  • 36. • 래스터라이즈 순서 예측을 통한 UOT Unordered Opacity Thresholding 효율 개선  인덱스 버퍼 순서와 로케일리티 locality?  메시 분할? - 드로우 콜보다 픽셀 오버 드로우가 더 문제이기 때문  하지만 애니메이션에 따라 순서가 뒤바뀌는 경우가 있음 • DX12의 ROV Raster Ordered View를 사용한 더 나은 구현 OIT 향후 작업
  • 37. • 반투명 머티리얼에 픽셀 단위 라이팅을 위함 • UE4의 실험적 기능을 기반으로 아직 개량 중 • 필요에 따라 제한적인 사용  현재는 머리카락 전용이나 유리/플라스틱 류에 추가 가능성 있음 • 섀도우 렌더링 지원  반투명 디퍼드 섀도우 포워드+ 라이팅 Forward+ Lighting
  • 38. • 16x16 타일 컬링 • 포워드 라이트 데이터  Constant Buffer 사용: StructuredBuffer보다 빠름 (NV)  128비트 스트라이드: 캐시 효율, 64KB 미만 유지  SOA? AOS? 포워드+ 라이팅 Forward+ Lighting
  • 40. 포워드+ 라이팅 + 섀도잉 + 산란
  • 41. • 포워드 라이팅 패스에서 섀도우 계산 시 문제  복잡한 중첩 브랜치 코드 증가 / GPR General Purpose Register 압박  포워드 라이트 데이터(CB)의 증가: 섀도우 매트릭스 및 기타 섀도우 파라메터  동시에 많은 섀도우 맵의 할당 필요 (고해상도 CSM 또는 큐브맵) • 반투명 디퍼드 섀도우:  가장 앞 면의 front-most 반투명 픽셀에 대한 디퍼드 섀도우 렌더링  일반적인 디퍼드 섀도우 패스에 통합  정확도는 희생하지만 보기에 괜찮은 결과 반투명 디퍼드 섀도우 Transparent Deferred Shadows
  • 42. 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);
  • 43. 디퍼드 섀도우 : 반투명 디퍼드 섀도우
  • 45. • 더 많은 라이트 및 머티리얼 지원 • 더 빠른 라이트 버퍼 액세스 • 안 쪽 레이어의 헤어에 대한 더 나은 섀도잉  Z에 따른 감쇠? • 싱글 스케터링과의 버퍼 채널 충돌 문제  피부 위를 덮은 머리카락이 있을 때, 머리카락 섀도우가 우선시 되는 문제 포워드+ 라이팅과 섀도잉 향후 작업
  • 46. • Marschner 모델: 헤어 가닥 = 실린더 • 반사, 2차 반사, 투과  반사: R  2차 반사: TRT  투과: TT • 산란 효과 추가 물리 기반 셰이딩 모델
  • 51. • 경도 산란 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
  • 52. • 머티리얼 별 속성 정의  이 값을 바탕으로 위도 산란 룩업 테이블 제작  G 버퍼 절약 효과  재사용성 • 룩업 테이블  스펙트럴 형태인 TRT/TT의 흡수율 absorption은 단일 채널로 / 성능 이슈  R 채널: R, G 채널: TRT, B 채널: TT 헤어 프로파일 애셋 Hair Profile Asset
  • 53. • 단일 채널 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);
  • 54. • 페이크 스케터링: 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; }
  • 56. • 스크린 스페이스 볼륨 포톤 매핑 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); // isotropic GaussPhotonScattering += PhotonContribution * GaussianWeights[GaussianWeightIndex];
  • 58. 디퓨즈 라이팅 • 탄젠트 램버시안 DiffuseLighting = max(0, sqrt(1 – SinThetaI * SinTetaI)) * EnergeConservingWrappedDiffuse(N, L, 1) * DiffuseIntensity
  • 60. • 스페큘러 파라메터  노이즈: 헤어 결의 퍼지 fuzzy 효과  러프니스: 하이라이트의 너비와 세기  시프트: 헤어 가닥의 하이라이트 기준 위치 이동  헤어 프로파일 애셋 • 디퓨즈, 페이크 스케터링, 각종 텍스처 • 기타 다수의 파라메터 -> 다양한 스타일로 제작할 수 있도록 헤어 머티리얼
  • 61. • 산란 품질 개선 • 머티리얼 LOD • 머리카락 스타일 별로 최적의 애셋 제작 방식 찾기 헤어 셰이딩 향후 작업
  • 63. • 아직 실험 단계 • Anisotropic GGX • Far Cry 4 스타일 • 여러 라이팅에 영향  다이렉트 라이팅, 스카이 라이팅, 리플렉션 인바이론먼트, SSR  탄젠트 이래디언스 맵 사용 검토 중 비등방성 스페큘러
  • 65. • 캐릭터 뷰어 및 로비  EVSM: Exponential Variance Shadow Maps • 게임 씬  태양 전용 - PCSS: Percentage Closer Soft Shadows  나머지 라이트 – PCF: Percentage Closer Filtering / UE4 그대로 사용  부가적 그림자 - Screen Space Inner Shadows 씬에 따라 다른 접근
  • 66. • 캐릭터 뷰어 및 로비 전용  실험적 기능 / 배경이 복잡한 경우에 만족스럽지 않은 품질 • 프리 필터드 섀도우 Pre-filtered Shadows  기본 알고리즘에서 변형 없음 • 성능 최적화  CSM 케스케이드 스플릿 제한: 최대 2개  시저 테스트: 스크린 스페이스 섀도우 바운드보다 약간 크게 EVSM
  • 67. • 게임 씬의 태양 전용 • 시간 변화 라이팅 요소 중 하나로 사용  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);
  • 68.
  • 69.
  • 70.
  • 71. • 그림자 안의 그림자:  캐릭터에 의해 이중으로 태양이 가려진 배경에 더 짙은 그림자 효과  그림자가 드리운 배경 위에 캐릭터가 있을 때의 어색함 개선  뚜렷한 방향성을 가짐: AO와는 다른 룩 • 메시의 본래 형태가 섀도우에 반영  전처리나 애셋 제작 작업이 불필요  비교> 캡슐 섀도우: UE 4.11와 The Order: 1886 스크린 스페이스 이너 섀도우 Screen Space Inner Shadows
  • 72. • G 버퍼: 캐스터 Caster와 리시버 Receiver 정보 추가  비트 마스킹 1) 스텐실 마스킹 (옵션)  태양에 대한 디퍼드 섀도우: 그림자 영역만  Unlit 머티리얼을 제외 2) 섀도우 테스트: SSR Screen Space Reflection 스타일 레이 마칭  태양과 스카이의 하프 벡터로 전진  최대 거리 제한: 근거리 오클루더만 관심 / 성능과 품질  이전 프레임 버퍼에 템포럴 리프로젝션 Temporal Reprojection 스크린 스페이스 이너 섀도우 Screen Space Inner Shadows L Sky H Sun ShadowInner Shadow
  • 73. • 스카이 라이팅과 GI에 반영 • ½ 해상도 버퍼 • 블러 필터링 • 약 0.5 ms 스크린 스페이스 이너 섀도우 Screen Space Inner Shadows
  • 74. • 그림자는 비주얼에 매우 중요  입체감 증대  시각의 변화를 체감하게 하는 요소  시각을 인지하게 하는 요소 • 가장 큰 이슈는 성능 최적화와 플리커링 방지  높은 드로우 콜  느리게 움직이는 디렉셔널 라이트 (태양) 그림자 렌더링 향후 작업
  • 76. • 짧은 머리카락의 움직임 • 신체나 옷의 미세한 떨림 • 아티스트의 작업을 최소화 목적
  • 77. • 시뮬레이터 애셋 설정 (에디터)  현재는 스프링 시뮬레이션만 • 버텍스 그룹화  미리 정의한 버텍스 컬러와 시뮬레이터 애셋 기준 • 시뮬레이터 본 샘플링  버텍스 그룹의 바운딩 박스 내에, 애셋에 지정된 밀도에 따라 / 위치는 인접 버텍스에 스냅 snap  Poisson 분포 / 결정적 Deterministic 샘플링 • 리깅  시뮬레이터 본 -> 가까운 캐릭터 본의 차일드로  버텍스 -> 가까운 시뮬레이터 본에 리깅  거리에 따라 스키닝 웨이팅 구현
  • 78. • 이 외에도 다양한 방식을 도입하여 풍부한 표현을 시도  모듈식 애니메이션  절차적 애니메이션  물리 시뮬레이션 • 다른 기회를 통해 공개가 될 수도 있음  예) NDC 2017? A1의 애니메이션 기술
  • 80. • UE4의 GPU 프로파일러  대략적인 비용 산출과 하이 레벨 셰이더 최적화 • RenderDoc, Intel GPA, AMD GPU PerfStudio 활용  로우 레벨 셰이더 최적화와 디버깅 • 최적화 관련 레퍼런스를 따라 손(hand)파일러 작업 방법
  • 81. • 에픽이 작성한 셰이더 코드는 크리티컬한 부분만 수정  지속적인 엔진 버전 업그레이드 때문에 아직은 소극적  게임 런칭 전에 전반적으로 검토 계획 • 우리가 직접 작성한 코드에 집중 • 이번 발표에서는 몇 가지 사례를 보여줌 최적화 대상
  • 82. 수정 전 수정 후 전처리기를 사용한 스태틱 브랜칭 float3 L = (LightPositionAndIsDirectional.w == 1) ? -LightPositionAndIsDirectional.xyz : normalize(LightPositionAndIsDirectional.xyz - OpaqueWorldPosition); #if USE_FADE_PLANE // CSM 사용 = 디렉셔널 라이트 float3 L = -LightPositionAndIsDirectional.xyz; #else float3 L = (LightPositionAndIsDirectional.w == 1) ? -LightPositionAndIsDirectional.xyz : normalize(LightPositionAndIsDirectional.xyz - OpaqueWorldPosition); #endif
  • 83. 수정 전 수정 후 벡터라이즈와 명시적 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));
  • 84. 수정 전 수정 후 앞선 계산 결과를 공유 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);
  • 85. 수정 전 수정 후 스칼라/벡터 연산 재배치 float3 DiffuseLighting = (TangentDiffuse * GBuffer.DiffuseColor) / PI * NoLWrapped * ShadowColor; float3 DiffuseLighting = GBuffer.DiffuseColor * (TangentDiffuse / PI * NoLWrapped * ShadowColor);
  • 86. 수정 전 수정 후 모디파이어 modifier는 인풋으로 Force += -normalize(Position) * Simulation.GravityStrength; Force += normalize(-Position) * Simulation.GravityStrength;
  • 87. 수정 전 수정 후 코드 라인 재배치 // 무언가 긴 작업… // clip(OpacityMask); // 셰이더 메인이 시작 후 최대한 빨리… // clip(OpacityMask);
  • 88. 가능한 종료 조건이 있다면 최대한 사용 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) { …
  • 89. 데이터 패킹과 캐시라인 정렬 ALU와 룩업 테이블의 효율 기타: 앞서 언급된 내용 #if OIT_PACK_RADIANCE uint RadianceRGY32; #else half4 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); }
  • 90. • 지속적인 최적화 • 에픽에서 작성한 셰이더 코드 최적화 • 셰이더 컴파일러의 최적화가 매우 적극적이고 뛰어나서 놀랍지만, 종종 기대와는 다른 결과가 나오기 때문에 명시적으로 GPU 친화적 코드 작성 및 디스어셈블리 확인 필요 로우 레벨 최적화 향후 작업
  • 91. • 넥슨의 새로운 IP 게임 • AAA급 그래픽 품질을 목표 • 최신 그래픽스 기술들의 도입 및 개발 • 아직 개발 중 세션 전체 요약
  • 92. • A1 프로젝트 동료들 • 에픽코리아 기술 지원팀 • 레퍼런스된 자료들의 저작자분들  추후 토크 슬라이드의 공개 버전에서 자세히 명시 예정 도와주신 분들
  • 93. 감사합니다. WE ARE HIRING! 04/27 15:20 아트 세션: 도전! AAA 게임 비주얼 – 프로젝트 A1의 게임 아트 박성섭 / 아트 디렉터 04/27 17:05 프로그래밍 세션: 구형맵에서는 어떻게 길을 찾아야 하나요? – 기초부터 이해하는 Recast 내비게이션 메시 하지훈 / 시니어 게임플레이 프로그래머
  • 94. • 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/ 레퍼런스