언리얼 렌더링 시스템 분석(14) - 확장 장: 현대 렌더링 엔진의 진화 역사 3부(개화기)
🌐 원문 링크: 剖析虚幻渲染体系(14)- 延展篇:现代渲染引擎演变史Part 3(开花期) (cnblogs.com/timlly)
📅 원문 발행일: 2022-05-02 | ✍️ 저자: Timlly (00 / )💡 시리즈 분류:
History of Rendering| 국내 업계 표준 용어 감수 및 수식/도해 복원 적용 완료
본 장에서는 2010년 초반의 엔진 아키텍처, 렌더링 및 관련 모듈 기술에 대해 설명합니다.
14.4.1 그래픽 API
14.4.1.1 다이렉트X
2010년 초 DirectX는 DirectX 11(11.1, 11.2)과 DirectX 12의 두 가지 마이너 버전을 출시했습니다.

DirectX 11.1은 2012년 8월에 출시되었습니다. 새로운 기능은 다음과 같습니다.
셰이더 추적 및 컴파일러 개선
Direct3D 장치 공유
새로운 Direct3D 11.1 기능 및 형식 지원 확인
-HLSL 최소 정밀도 사용
기능 레벨 9 이상에서 HLSL로 사용자 클립 평면을 지정합니다.
셰이더가 액세스할 수 있는 것보다 더 큰 상수 버퍼를 생성합니다.
렌더 타겟에서 논리 연산 사용
샘플 수를 강제로 래스터라이저 상태 생성
셰이더를 사용하여 비디오 리소스 처리
공유 Texture2D 리소스에 대한 지원 확장
새로운 복사 옵션으로 하위 리소스 변경
리소스 및 리소스 보기 삭제
더 많은 수의 UAV 지원
상수 버퍼의 하위 범위를 셰이더에 바인딩
셰이더에 바인딩된 상수 버퍼의 하위 범위를 검색합니다.
리소스 보기 전체 또는 일부 지우기
NO_OVERWRITE를 사용하여 동적 버퍼의 SRV 매핑
모든 파이프라인 단계에서 UAV를 사용하세요.
WARP 장치에 대한 지원 확장
세션 0 프로세스에서 Direct3D 사용
기능 레벨 9에서 섀도우 버퍼 지원
DirectX 11.2는 2013년 10월에 출시되었습니다. 새로운 기능은 다음과 같습니다.
-타일형 리소스
타일식 리소스 지원 확인
WARP 장치에 대한 지원 확장
그래픽 명령에 주석 달기
HLSL 셰이더 연결
함수 연결 그래프(FLG)
- 받은 편지함 HLSL 컴파일러
DirectX 12.0은 2015년 7월에 출시되었습니다. 새로운 기능에는 리소스 바인딩, 타일형 리소스(Texture2D), 형식화된 UAV 로드(추가 형식) 등이 포함됩니다.
DirectX 11의 표면 세분화 단계에는 Hull Sahder(쉘 셰이더), Tessellator(세분할) 및 Domain Shader(도메인 셰이더)가 포함됩니다. 그 기능은 다음과 같습니다:
- 헐 샤더. 제어 지점 단계(각 제어 지점에 대해 한 번 실행)와 패킹 단계(각 입력 기본 요소에 대해 한 번 실행 및 테셀레이션 요소 반환)의 두 단계가 있습니다.
-테셀레이터. 새로운 정점이 생성되고, 테셀레이션 계수가 높을수록 더 많은 삼각형이 생성됩니다.
- 도메인 셰이더. 정점당 한 번씩 실행되며, 표면 계산은 각 정점에 대해 사용되며 버텍스 데이터는 매개변수 좌표로 전달됩니다.

DirectX 11 테셀레이션 파이프라인.

DirectX 11 테셀레이션 적용 사례 1.
DirectX 11 테셀레이션은 표면 매개변수화, 데칼 테셀레이션 등에 적용될 수도 있습니다.

도메인 셰이더에는 오버헤드가 많이 발생하며, 특히 효율성이 떨어지는 작은 삼각형이 있습니다. 하드웨어에서는 삼각형이 최소 8픽셀이기를 바랍니다. 최적화 방법은 분할 버텍스 수를 줄여 도메인 셰이더 실행을 줄이는 것입니다. 헐 셰이더는 세분화 요소를 조정할 수 있습니다.
DirectX 11 표면 세분화를 사용하면 거리 적응형 테셀레이션(Distance Adaptive Tessellation), 변위 적응(Displacement Adaptive), 데칼 세분화의 변위 적응, 헐 셰이더 기반 백 크로핑 등의 기술을 구현할 수도 있습니다.
또한 DirectX 11 표면 테셀레이션 최적화 기술에는 프러스텀 컬링, 결합된 세분화 그리기 호출, 방향 적응형 세분화(점(V, N)을 사용하여 윤곽 블록 찾기)이 포함됩니다.
, 헐 셰이더의 입력 및 출력 데이터를 줄이고 도메인 셰이더의 작업을 픽셀 셰이더로 전송하고(도메인 셰이더의 데이터 출력을 줄임) Stream Out을 사용하여 반복되는 세분화 개체를 방지합니다.
Direct3D 11 성능 팁 및 요령에서는 DirectX 11 SM 5.0, 리소스 및 리소스 보기, 멀티스레딩 및 기타 기술에 대해 설명합니다. SM 5.0의 특징은 다음과 같습니다.
- 빠른 다중 채널 텍스처 추출을 위해 Gather/GatherCmp()를 사용하십시오.
알파/깊이 영역을 얻기 위해 Gather*()를 사용하여 SSAO의 FP16 알파에 깊이를 효율적으로 획득하고 저장하는 동시에 더 적은 수의 RT를 사용합니다.
- 이미지 후처리에 자주 사용되는 단 세 번의 작업으로 4개의 RGB 값을 얻습니다.

- 빠른 깊이 스프라이트에 대해 초기 깊이 거부 효과를 유지하려면 "보수적 깊이"를 사용하세요.
PS에서 SV_Depth 대신 SV_DepthGreater/LessEqual을 출력합니다. 셰이더 수정 Z를 사용해도 초기 깊이 컬링 효과를 유지합니다.
- 하드웨어/드라이버는 법적 조치를 시행합니다. 유효하지 않은 깊이 값이 기록되면 래스터라이제이션된 값으로 잘립니다.

- 슈퍼샘플링 없이 빠른 셰이더 AA를 위해서는 EvaluateAttribute*()를 사용하세요.
하위 픽셀 위치에서 EvaluateAttribute*()를 호출하는 절차적 재질에 대한 더 간단한 셰이더 AA입니다.
SV_COVERAGE를 입력하여 각 커버리지 하위 샘플의 색상을 계산하고 평균 색상을 기록하면 순수 MSAA보다 이미지 품질이 약간 더 좋습니다.
MSAA 알파 테스트를 위한 출력 SV_Coverage. 이 기능은 DX 10.1부터 있었으며 EvaluateAttribute*()를 사용하면 구현이 더 간단해졌지만 적용 범위의 알파를 확인하는 것만으로도 더 빨라지기 때문에 이미 충분합니다.
UAV 및 원자: PS 산란, UAV 및 Interlocked*() 작업을 신중하게 사용하십시오.
스트림 출력 채널을 줄입니다. 주소 지정 가능한 스트림 출력, 채널 출력당 최대 4개의 스트림, 모든 스트림은 여러 요소를 가질 수 있습니다.
지오메트리 셰이더 인스턴싱을 사용하여 더 간단한 코드를 작성하세요. 루프 인덱스 대신 SV_SInstanceID를 사용하세요.
PS에서 초기 깊이 스텐실 테스트를 강제하려면 [earlylengthstencil]을 사용하세요.
UAV 또는 AppendBuffers에 쓰면 속도가 크게 향상될 수 있습니다.
- 활성화하려면 픽셀 셰이더 함수 선언 위에 [earlylengthstencil]을 배치하세요.

[earlylengthstencil]이 활성화되면 픽셀 셰이더는 UV를 제외한 모든 픽셀을 컬링합니다.
- 수많은 새로운 내장 함수를 사용하여 더 빠른 셰이더를 구현합니다.
빠른 비트 연산: countbits(), reversebits()(FFT에 필요함) 등
변환 지침: f16to32(), f32to16(), 더 빠른 패킹/언패킹.
빠른 대략 도함수(ddx/y_coarse).
-...
- 서브루틴의 동적 셰이더 연결을 신중하게 사용하십시오.
서브루틴은 무료가 아니며 기능 경계를 넘어서는 최적화가 없습니다.
- 큰 서브루틴에만 동적 연결을 사용하고 작은 서브루틴을 많이 사용하지 마십시오.
리소스 및 리소스 보기의 기능:
- 더 높은 성능을 위해 메모리 크기와 대역폭을 줄입니다.
BC6 및 BC7은 새로운 기능, 매우 높은 품질 및 HDR 지원을 제공하며 모든 정적 텍스처는 압축 가능해야 합니다.

- 깊이 버퍼 복사를 방지하려면 읽기 전용 깊이 버퍼를 사용하세요.
Direct3D 11에서는 깊이 테스트를 위해 여전히 바인딩된 깊이 버퍼의 샘플링을 허용합니다.
깊이가 GBuffer의 일부인 경우 지연된 조명에 유용합니다.
부드러운 입자에 적합합니다.
AMD: 깊이 버퍼를 SRV로 사용하면 압축 해제 단계가 최대한 늦게 트리거될 수 있습니다.
DX11의 다른 기능:
- 무료 스레드 리소스 생성.
일반적으로 더 빠르고 더 병렬적인 빠른 비동기 리소스 생성을 사용합니다.
자원이 사용되는 프레임 내에서 자원을 파괴하지 마십시오. 리소스를 삭제하면 동기화 이벤트가 발생할 가능성이 높습니다.
일련의 생성, 렌더링 및 파괴 순서를 피하십시오.
표시 목록(지연된 컨텍스트에서 생성된 명령 목록)
응용 프로그램이 다중 스레드인지 확인하십시오.
명령 구성에 병목 현상이 충분히 클 경우에만 표시 목록을 사용하십시오.
GPU 명령 구성의 병렬성을 표현하기 위해 표시 목록을 고려하고 세분화된 명령 목록을 피하십시오.
드라이버가 이미 다중 스레드입니다.
지연 컨텍스트.
지연된 컨텍스트에서 Map() 및 UpdateSubResource()는 추가 메모리를 사용합니다. 모든 초기 맵은 DISCARD 의미 체계를 사용해야 한다는 점을 기억하세요.
단일 코어 시스템에서 지연된 컨텍스트는 즉각적인 컨텍스트를 사용하는 것보다 속도가 느립니다. 듀얼 코어의 경우 즉각적인 컨텍스트를 사용하는 것이 더 좋습니다.
상당한 병렬성이 없는 한 지연된 컨텍스트를 사용하지 마십시오.
기타.
DrawIndirect를 사용하면 CPU 오버헤드를 더 줄일 수 있습니다. GPU 쓰기 버퍼의 매개변수를 사용하여 인스턴스화된 드로우 콜/디스패치를 시작하면 GPU를 사용한 제한된 장면 탐색 및 컬링이 가능해집니다.
- 빠른 스트림 출력을 위해 추가/소비 버퍼를 사용합니다. 입력 순서 제약이 없고 "무제한" 데이터 확장으로 출력을 스트리밍하므로 GS보다 빠릅니다.
14.4.1.2 OpenGL
2010년부터 2015년 사이에 OpenGL이 출시한 버전과 기능은 다음과 같습니다.
버전 시간 특징
OpenGL 3.3 2010년 3월 Mesa는 소프트웨어 드라이버 SWR, 소프트웨어 파이프라인 및 NV50이 포함된 이전 Nvidia 카드를 지원합니다.
OpenGL 4.0 2010년 3월 Direct3D11을 벤치마크합니다. 하드웨어 지원: GeForce 400 시리즈 이상, Radeon HD 5000 시리즈 이상, Intel Ivy Bridge 프로세서 및 HD 그래픽.
OpenGL 4.1 2010년 7월 하드웨어 지원: GeForce 400 시리즈 이상, Radeon HD 5000 시리즈 이상, Intel Ivy Bridge 프로세서 및 HD 그래픽. 이 사양을 구현하기 위한 GPU의 최소 "최대 텍스처 크기"는 16k×16k입니다.
OpenGL 4.2 2011년 8월 원자 카운터와 텍스처에 대한 로드-저장-원자 읽기-수정-쓰기 작업을 갖춘 셰이더 복잡한 객체의 효율적인 재배치 및 복사를 가능하게 하기 위해 GPU 버텍스 처리(테셀레이션 포함)에서 캡처된 데이터의 여러 인스턴스를 그리는 것, 성능을 크게 향상시키기 위해 전체 텍스처를 GPU에 다시 다운로드하지 않고도 압축된 텍스처의 임의 하위 집합 수정을 지원합니다. 부분적인 하드웨어 지원.
OpenGL 4.3 2012년 8월 컴퓨팅 셰이더, 셰이더 저장 버퍼 개체, 이미지 형식 매개변수 쿼리, 표준 기능인 ETC2/EAC 텍스처 압축, OpenGL ES 3.0 API와 완벽하게 호환, 디버그 메시지 수신, 텍스처 보기가 텍스처를 다르게 해석하고 안전성과 견고성이 향상되었습니다.
OpenGL 4.4 2013년 7월 강제 버퍼 객체 사용 제어, 버퍼 객체의 비동기 쿼리, 셰이더에서 더 많은 인터페이스 변수 레이아웃 제어 표현 및 여러 객체의 효율적인 동시 바인딩.
OpenGL 4.5 2014년 8월 DSA(Direct State Access), 새로 고침 제어, 견고성, OpenGL ES 3.1 API 및 셰이더 호환성.
같은 기간 동안 OpenGL ES가 출시한 버전과 기능은 다음과 같습니다.
버전 시간 특징
OpenGL ES 3.0 2012년 8월 렌더링 파이프라인 향상: 폐색 쿼리, 변환 피드백, 인스턴스화, MRT, ETC2/EAC 표준; 정수 및 32비트 부동 소수점 연산을 완벽하게 지원하는 새로운 버전의 GLSL ES 셰이딩 언어; 부동 소수점 텍스처, 3D 텍스처, 깊이 텍스처, 버텍스 텍스처, NPOT 텍스처, R/RG 텍스처, 불변 텍스처, 2D 배열 텍스처, 스위즐, LOD 및 밉 레벨 클램핑, 향상된 텍스처 및 렌더 버퍼 형식에 대한 지원 보장을 포함한 향상된 텍스처 기능.
OpenGL ES 3.1 2014년 3월 컴퓨팅 셰이더, 독립 버텍스 및 조각 셰이더, 간접 그리기 명령.
OpenGL ES 3.2 2015년 8월 기하학 및 테셀레이션 셰이더, 부동 소수점 렌더 타겟, ASTC, 향상된 블렌딩, 고급 텍스처 타겟: 텍스처 버퍼, 멀티샘플링된 2D 배열 및 큐브맵 배열, 디버깅 및 견고성 기능.
14.4.1.3 기타 그래픽 API
- 맨틀
원래 2013년에 AMD가 DICE와 협력하여 개발한 Mantle은 주로 개인용 컴퓨터에서 사용하기 위해 Direct3D 및 OpenGL의 대안으로 설계되었습니다. 3D 비디오 게임을 위한 낮은 오버헤드 렌더링 API입니다.
얼마 지나지 않아 **AMD는 Mantle API를 Khronos 조직에 기증하여 Vulkan API로 개발했습니다.**간단히 말하면 Vulkan의 전신은 Mantle입니다. Mantle의 공개 개발은 2015년에 중단되었고 DirectX 12와 Mantle에서 파생된 Vulkan의 인기가 높아지면서 2019년에 완전히 중단되었습니다.
- 불칸
2015년 초, LunarG(Valve에서 자금 지원)는 HD 4000 시리즈 통합 그래픽 카드에서 Vulkan 호환성을 지원하는 Linux 드라이버를 시연했습니다.
2015년 8월, Google은 향후 Android 버전에서 Vulkan을 지원할 것이라고 발표했습니다. 2015년 12월, Khronos 그룹은 Vulkan 사양 버전 1.0이 거의 완성되었으며 표준 호환 드라이버를 사용할 수 있게 되면 출시될 것이라고 발표했습니다.
- 금속
Metal은 iOS 8에서 첫선을 보인 Apple에서 만든 낮은 수준, 낮은 오버헤드 하드웨어 가속 3D 그래픽 및 컴퓨팅 셰이더 API입니다. OpenGL 및 OpenCL과 유사한 기능을 결합하고 iOS, iPadOS, macOS 및 tvOS의 애플리케이션용 GPU 하드웨어에 대한 낮은 수준의 액세스를 제공하여 성능을 향상시키도록 설계되었습니다. Vulkan 및 DirectX 12와 같은 다른 플랫폼의 하위 수준 API와 비교할 수 있습니다.
Metal은 2014년 6월부터 Apple A7 이상을 실행하는 iOS 장치와 2015년 6월부터 OS X El Capitan을 실행하는 Mac(2012 모델 이상)에서 사용할 수 있습니다.
14.4.2 하드웨어 아키텍처
PowerVR 그래픽 - 최신 개발 및 향후 계획에서는 2015 Imagination PowerVR Rogue 하드웨어 아키텍처 및 기능을 설명합니다. PowerVR Rogue는 처음 5세대 기술을 기반으로 구축된 타일 기반 지연 렌더러를 지원합니다. USC(Universal Shading Cluster)가 새로운 스칼라 SIMD 셰이더 코어라는 것이 2012 Consumer Electronics Show에서 공식 발표되었습니다. 범용 컴퓨터는 코어의 가장 큰 특징이며 전통적인 그래픽 렌더링에도 매우 적합합니다.

또한 아키텍처는 GPU가 픽셀 셰이딩을 직접 수행하도록 허용하지 않는 지연 래스터라이제이션(지연 래스터라이제이션)를 지원합니다. 하드웨어는 완전히 지연된 래스터라이제이션 및 픽셀 음영 처리를 지원하며 래스터라이제이션는 픽셀 단위로 정확합니다. 이 기술을 HSR(Hidden Surface Removal)이라고 합니다.

TBDR은 렌더링의 모든 단계에서 대역폭을 절약하여 타일에 필요한 형상만 가져오고 타일에서 보이는 픽셀만 처리합니다. 효율적인 처리, 사용 가능한 컴퓨팅 리소스 사용 극대화 및 가능한 경우 하드웨어 대역폭 활용. 코어 효율성을 극대화하고 USC 활성화를 줄여 소비량을 절감합니다. 대역폭을 최소화하고, 텍스처를 줄여 전력을 절약하고, 형상 추출 및 비닝이 일반적으로 프레임당 대역폭의 10%를 초과하여 렌더링의 다른 부분을 위한 대역폭을 절약합니다.
Rogue USC는 아키텍처의 구성 요소입니다. 전체 이름은 통합 셰이딩 클러스터입니다. 이는 Rogue 아키텍처의 기본 구성 요소입니다. 쌍으로 배치되어 있으며 TPU(텍스처 처리 장치)를 공유합니다. 1, 0.5 및 0.25의 USC 디자인은 특별합니다. 디자인의 다양한 균형은 게임이 아닌 응용 프로그램에서 사용되는 경향이 있습니다.

16개 하드웨어, 32개 분기 세분화, 클럭당 절반 작업/워프 실행, 스칼라 SIMD, 최적화된 ALU 파이프라인, F32, F16, 정수 혼합 사용, 부동 소수점 특수 값, 논리 연산. IP 코어에서 구성 가능한 F16 경로는 선택 사항인 경우도 있습니다. F16 경로의 성능은 1세대 이후 크게 향상되었습니다. 셰이더의 성능: F32 경로는 이중 FMAD이고, F16 경로는 셰이더에 따라 각 주기마다 다른 작업을 수행할 수 있지만 ISA는 디스어셈블러를 사용하여 쿼리할 수 있습니다.
벡터 아키텍처는 프로그래밍을 잘하기 어렵고 스칼라 ALU에는 많은 이점이 있습니다. 비록 공짜 점심은 아니지만 성능을 더욱 예측 가능하게 만들 수 있습니다.


PowerVR Series6XT Rogue 하드웨어 아키텍처.


PowerVR Series7XT 불량 하드웨어 아키텍처.
Series6XT에서 Series7XT로: 아키텍처 확장 방법 변경, USC 개선, ISA 간소화, 새로운 기능으로는 하드웨어 테셀레이션, USC와의 DX11 호환성(주로 정확도) 및 FP64가 있습니다.

PowerVR 그래픽 마법사 하드웨어 아키텍처, 새로 추가된 레이 트레이싱 관련 장치 및 처리.
Wizard의 3가지 고유 기능: 고정 기능 광선 상자 및 광선 삼각형 테스터, 일관성 기반 작업 형성 및 예약, 스트리밍 장면 계층 생성기. Coherency Engine을 사용하면 아래 그림과 같이 모든 광선을 동시에 처리할 수 있습니다.

PowerVR은 또한 PVRTrace, PVRTune 및 PVRShaderEditor와 같은 개발 및 분석 도구를 제공합니다.
Rogue 그래픽 드라이버의 경우 DDK(드라이버 개발 키트) 릴리스 프로세스: PowerVR IP 라이선스 사용자에게 릴리스된 참조 드라이버 소스 코드, 약 6개월마다 사소한 수정, 상위 고객의 조기 참여, DDK 공식 릴리스 직후 제품에 드라이버가 포함됩니다.
14.4.3 엔진 진화
14.4.3.1 포괄적인 진화
2010년 이전 및 이후의 일반적인 게임 엔진에는 모든 개체, 재질, 조명 및 모든 장면 설정(예: 해상도, 원근감, 앤티앨리어싱 수준 등) 목록이 포함된 장면 관리자가 있습니다. 이미 로드된 개체와 텍스처를 로드하지 않도록 텍스처와 개체 캐싱도 제공될 수 있습니다. 재료는 파일(사용자 정의 셰이더)에서 로드하거나 동적으로 생성(아래)할 수 있으며 재료 속성은 색상 및 표면 텍스처와 같은 기본 재료 설정부터 여러 텍스처를 사용한 시차 매핑과 같은 고급 기능까지 다양합니다.

Material Generator는 사용자가 정의한 재질 표면 속성(표면 속성을 정확하게 정의하는 색상이나 질감)을 기반으로 셰이더를 동적으로 생성하는 주요 구성 요소입니다. 추가, 곱셈 또는 블렌딩을 통해 결합할 수 있는 다층 색상 텍스처 외에도 범프, 시차, 환경 및 큐브맵(정적 또는 동적)을 포함한 고급 표면을 정의하는 것이 가능합니다. 이러한 모든 속성을 기반으로 재료 생성기는 원하는 재료 표면을 생성하는 명령을 실행할 수 있는 셰이더를 생성합니다.
셰이더가 연결되고 컴파일되면 기본 꼭지점 속성이 재료에 바인딩될 수 있고 재료 구성이 설정되고(균일 구조를 통해) 셰이더를 사용할 준비가 됩니다. 다른 공용 변수(예: 변환 행렬)는 균일 블록에 정의되고 모든 셰이더에서 공유됩니다.
동시에 HDR 렌더링 파이프라인은 HDR 조명의 개발 추세에 적응하기 위해 게임 엔진에서 점차 대중화되었습니다. 당시 대부분의 디스플레이 장치는 여전히 LDR이었으므로 HDR을 다시 LDR로 매핑하려면 톤매핑이 필요했습니다. (아래 사진)

는 물리조명모델 화감지색매핑 의 HDR렌더링(Render)의 구현 프로세스 :

가상 문화 교육을 위한 게임 엔진 공간: 요구 사항, 장치, 엔진, 포팅 전략 및 미래 전망에서는 2010년 게임 플랫폼 기능 동향과 문화 모델링 및 시뮬레이션과의 상관 관계, 향후 산업 발전에 대해 이야기했습니다. 당시 유행했던 게임 엔진의 특징을 자세히 설명하고, 다양한 디바이스와 플랫폼에 대한 다차원적인 기술 선택 솔루션을 제공했습니다.
이 기사에서는 언리얼 엔진 3(UE3)가 가장 일반적으로 사용되는 상용 엔진 중 하나라고 언급하는데, 부분적으로는 대부분의 엔진보다 오래 전부터 사용되었지만 Epic Games가 정기적으로 새로운 기능과 개선 사항을 추가하기 때문이기도 합니다. 시각적 충실도 측면에서 Unreal Engine 3는 다른 최고의 AAA 게임 엔진과 동등하며 문화 훈련을 위해 설계된 3D 가상 환경에서 필요한 사실성을 생성하는 데 매우 뛰어납니다.
CryENGINE 3의 강점은 고품질 그래픽, 캐릭터 및 개발 도구 측면에서 최고의 게임 엔진이라는 것입니다. 텍스처, 재질, 조명, 애니메이션의 품질이 뛰어납니다. 강력한 애니메이션 시스템을 통해 얼굴 및 전신 모션 캡처는 물론 게임 내 애니메이션 믹싱, 동기화, 레이어링 및 대상 변경을 사용할 수 있습니다.
Gamebryo Lightspeed의 장점은 신속한 애플리케이션 개발 프레임워크를 제공하고 사운드, 그래픽, 물리 및 멀티플레이어 게임 처리를 위한 다양한 기술도 지원한다는 것입니다. Gamebryo의 시각적 충실도는 업계 최고의 엔진에 필적하며 Fallout 3 및 Oblivion과 같이 광대한 풍경과 복잡한 얼굴 세부 정보가 포함된 게임을 만드는 데 사용되었습니다.
Unity3D의 장점은 동급 최고의 크로스 플랫폼 개발 지원, 강력한 커뮤니티 및 최저 진입 비용입니다. 대부분의 도구는 단순화되었습니다. 모든 3D 자산은 원본 형식으로 가져올 수 있으므로 엔진별 형식으로 가져오는 작업이 필요하지 않습니다. 자산의 원래 형식을 보존하면 비파괴적인 워크플로우가 가능하므로 파이프라인 효율성이 크게 향상됩니다.
크로스 플랫폼 및 요구 사항 충족 측면에서 위 엔진의 순위는 다음과 같습니다.

이 문서에서는 게임 개발 워크플로 속도를 높이는 파이프라인을 제공합니다.

게임 속 미래 그래픽에서는 2010년 크라이텍이 사용한 렌더링 기술을 설명하고 미래 그래픽 트렌드를 예측한다. 이 기사에서는 디퍼드 라이팅, 디퍼드 셰이딩 및 포워드 렌더링의 대역폭과 재료 유형을 비교합니다.

이 기사에서는 또한 렌더링 아키텍처의 혁신이 쉽지 않으며 하드웨어 공급업체에서 여러 번 입증했으며, 특히 거대한 인프라의 끝 부분에서 수년간의 개발 경험이 필요한 소프트웨어 렌더러를 사용하려는 최근 시도에 대해 언급했습니다. 그래픽 아키텍처는 복셀, 마이크로폴리곤 등과 같은 오래된 기술로 돌아가 더욱 다양해질 것입니다.
미래에 일부 게임을 표시할 대안: 포인트 기반 렌더링, 레이 트레이싱, 평소와 같은 래스터라이제이션, 마이크로폴리곤, 희소 복셀 옥트리(데이터 구조)를 사용한 데이터 표현, 희소 빈 옥트리.
그해(2010년)의 예측은 정말 정확했다고 말씀드리고 싶습니다. 현재(2022년) 현재 대중화되거나 점점 더 대중화되고 있는 기술에는 포인트 기반 렌더링, 레이 트레이싱, 마이크로폴리곤 및 희소 복셀 옥트리(데이터 구조), 희소 서펠 옥트리가 포함됩니다.
Sparse Voxel Octree(데이터 구조)의 장점: 데이터 구조는 대체 렌더링을 위한 미래 증거이며 고유한 형상, 질감 있는 형상에 이상적이며 텍스처 예산의 관련성이 낮아지고 예술적 자유가 현실이 되며 자연스럽게 자동화된 LOD 체계에 적합합니다. 단점은 인프라와 하드웨어가 없고 약간 더 많은 메모리를 차지하며 레이 트레이싱에 적합하지만 여전히 너무 느리다는 것입니다.
CryTek은 이미 프로덕션에서 희소 복셀 옥트리를 사용하고 있습니다. 레벨 내보내기 중 지오메트리 및 텍스처 베이킹에 사용되며, 삼각형으로 분할된 희소 옥트리에 저장되고, 지오메트리 및 텍스처 관리 및 스트리밍이 매우 쉽고, GPU 계산이 필요하지 않습니다(가상 텍스처에도 불구하고), 자동으로 수정된 LOD 빌드, 적응형 지오메트리 및 텍스처 세부 정보(게임플레이에 따라 다름). 각 레벨에는 많은 디스크 공간이 있습니다! 공격적인 텍스처 압축을 사용하고, 전체 세계가 아닌 현명하게 굽습니다.

인지 중심 그래픽에는 PCF 기반 소프트 섀도우, 랜덤 OIT, 이미지 기반 반사, SSAO, 대부분의 포스트 프로세스, LPV, 다수의 무작위 알고리즘 등이 있습니다. 실시간 그래픽에서 대부분은 인간의 인지가 제한되어 있기 때문에 가정입니다. 실시간 그래픽은 인간 눈의 특정 특성으로 인해 지각적으로 구동됩니다.
약 350M(3억 5천만) 픽셀의 공간 해상도, 이 점에서는 속이기 어렵습니다.
24Hz 정도의 시간해상도는 매우 낮아 기술적 조작의 여지가 있다. 40Hz보다 크면 사람의 눈은 깜박임을 알아차리지 못합니다.
우리는 다른 기계를 위한 이미지를 생성하지 않습니다. 우리의 대상 고객은 인간입니다.
언더샘플링/오버샘플링 기술에는 다음이 포함됩니다.
- 공간
언더샘플링
추론된 음영
- 뎁스 오브 필드(DoF)
분리된 샘플링
- 시간
시간적 안티앨리어싱
모션 블러
믹스
시공간(나중의 많은 문서에서는 공간-시간이라고 함) 앤티앨리어싱
혼합 렌더링이 존재합니다. 렌더링 파이프라인에는 마법의 총알이 없습니다. 심지어 REYES도 영화의 원래 형태로 사용되지 않았습니다. 일반적으로 레이 트레이싱 반사 및 그림자(삼각형/점 세트/복셀 구조 등), 더 나은 장면 표현을 위한 복셀(부분적으로), 화면 공간 접촉 효과(예: 반사) 등 적합하고 유용한 모든 것을 결합합니다.
최근 트렌드는 입체 렌더링인데, 이 기술은 오래 전부터 존재해왔고 그 기술로 인해 대중화되었습니다. 게임에서도 마찬가지이다. 새로운 개념은 없지만 사진 예술과 마찬가지로 하나의 황금률이 있습니다. 청중을 지치게 하지 마십시오. Crysis 2는 이미 깊이 히스토그램을 사용하여 축 간 거리를 결정하는 일류 3D 스테레오 지원 기능을 갖추고 있습니다.
CryENGINE 3에서 지원되는 입체 렌더링 모드: 강력한 입체 렌더링, 재투영 기능이 있는 중앙 눈 상자, 한쪽 눈의 실험적 무작위 렌더링. 입체 출력 모드: 릴리프(분리), 인터레이스, 수평 관절 이미지, 수직 관절 이미지, 2개의 모니터.
당시 하드웨어 아키텍처의 문제점을 확인하기 위해 작은 합성 테스트(GPU 동작 시뮬레이션)를 사용하여 512개의 코어(공유 캐시의 슬롯으로 해석될 수도 있음), 실행될 32k의 동일한 작은 작업, 각 프로젝트에는 하나의 코어에 1개의 클록(합성)이 필요하고 256~2048개의 스레드 범위에서 총 시간의 스케줄링 오버헤드를 고려하는 고도의 병렬 스케줄링을 시뮬레이션했습니다(작업 전달, 컨텍스트 전환, 오버헤드 가중치는 중요하지 않음). 몇 가지 중요한 매개변수 출력의 곡선은 다음과 같습니다.

위 그림에서 알 수 있듯이 전체 시간 곡선은 포화 단계와 동시 병렬 단계로 나눌 수 있습니다. 변곡점은 스케줄링 오버헤드가 0에서 상승하는 시점이다. 포화 단계에서는 총 시간과 실행 시간이 계속 감소하지만, 동시 병렬 단계에서는 스레드 수가 증가함에 따라 스케줄링 오버헤드가 증가하고, 총 시간도 스케줄링 오버헤드와 유사한 곡선으로 증가한다.
실제 GPU를 이용한 또 다른 테스트! 하나의 코어에서 코어당 1클럭을 요구하는 대역폭 집약적 픽셀 셰이더인 화면 공간 효과(SSAO) 렌더링(합성), 5~40개 스레드 범위의 캐시 오염으로 인해 포화 직후 스파이크가 발생하고 시간이 지나면서 더 많은 스레드로 포화 성능에 점근적으로 도달합니다.

스케줄링 오버헤드가 문제입니다. 병렬 확장성은 동종 작업의 포화 상태에서 최대치에 도달합니다. 이기종 워크로드는 어떻습니까? 최소값의 존재 여부는 스케줄링이 성능에 미치는 영향에 따라 달라지며 이를 줄여야 하며 GRAMPS와 유사한 아키텍처를 구현할 수 있고 레이 트레이싱이 더 빨라지며 SoL에서 대역폭 병목 현상이 발생하는 구성 가능한 하드웨어 스케줄러가 필요합니다.
실제로 다른 원자가 필요합니다. 이는 주로 수집/분산 작업에 사용되며 부동 소수점 숫자를 처리할 수 있어야 합니다! 대부분의 경우 결과는 필요하지 않습니다. 다시 읽기 없는 원자성(fire-and-forget 개념)을 개선하려면 메모리 컨트롤러/지능형 메모리 측에서 작업을 수행해야 합니다. 훨씬 더 많은 그래픽 원자 성능이 필요합니다.
미래의 기술 과제: 확장 가능한 코드 베이스로 전환하고, 병렬 및 비동기 작업, 다중 스레드 스케줄링, 더 큰 코드 베이스, 다중 플랫폼 및 API를 고려하십시오. 향후 생산 과제: 자산 비용은 매년 약 50% 증가하고, 콘텐츠는 품질 개선 외에도 점점 더 "상호작용"되고 있습니다. 도구, 파이프라인 및 병목 현상을 개선하여 역효과를 생성하고, 소스 백엔드 자동화 -> 리소스 컴파일러, 도구가 좋을수록 출력이 더 저렴해지고 더 좋아집니다.
효율성 측면에서 데이터 정확도가 감소할 수 있고 정지 이미지의 고해상도와 선명도가 필요하지 않으며 그래픽 하드웨어는 캐시 일관성이 없는 작업 부하에 도전해야 합니다.
요약하자면, 실시간 렌더링 파이프라인 전환이 코앞으로 다가왔습니다. 하드웨어 개선, 현재 프로덕션 실시간 렌더링 기술의 진화, 새로운 프리젠테이션 및 렌더링 파이프라인 준비, 더 나은 병렬 개발 인프라, 도구 및 저작 파이프라인을 현대화해야 하며, 서버 측 렌더링을 고려해야 합니다. 방향이 완전히 바뀔 가능성이 높습니다. 인식 기반 실시간 그래픽은 그래픽 기술의 불쾌한 골짜기를 피하는 기술 원동력입니다.
DirectCompute 최적화 및 모범 사례에서는 NVIDIA GPU에서 DirectCompute의 개념, 기능, 메커니즘, 사용법 및 최적화 기술을 공유합니다.
DirectCompute(Direct Compute)는 Windows Vista 및 Windows 7용 Microsoft의 표준 GPU 컴퓨팅 플랫폼입니다. DX10 및 DX11 하드웨어에서 지원됩니다. 이는 CUDA 아키텍처의 또 다른 구현이며 OpenCL 및 CUDA C와 동일한 수준의 API입니다.

DirectCompute를 사용하면 Windows의 모든 GPU 공급업체에 걸친 통합 API인 HLSL과 유사한 모든 텍스처 기능(큐브 맵, 밉 맵)을 포함한 Direct3D 리소스와 상호 운용되는 컴퓨팅 셰이더를 통해 CUDA GPU에서 일반 컴퓨팅을 수행할 수 있으므로 다양한 하드웨어에서 동일한 결과를 보장할 수 있습니다.
DirectCompute 프로그램은 병렬 작업을 스레드 그룹으로 나누고 여러 스레드 그룹을 예약하여 문제를 해결합니다. 아래 그림에서 볼 수 있듯이 Dispatch는 수십만 개의 스레드로 구성된 스레드 그룹의 3D 그리드입니다. 스레드 그룹은 수십 또는 수백 개의 스레드로 구성된 3D 그리드입니다. 스레드는 셰이더에 대한 호출입니다.

병렬 실행 모델은 아래와 같습니다. 동일한 그룹의 스레드는 동시에 실행되고, 다른 그룹의 스레드는 동시에 실행될 수 있습니다.

메모리 병합은 전역 메모리의 연속 영역인 반 워프(16개 스레드)의 조정된 읽기입니다. 64바이트 - 각 스레드는 한 단어를 읽습니다: int, float, ..., 128바이트 - 각 스레드는 하나의 더블 단어를 읽습니다: int2, float2, ..., 256바이트 - 각 스레드는 하나의 4개 단어를 읽습니다: int4, float4, ...
메모리 병합에 대한 추가 제한 사항은 영역의 시작 주소가 영역 크기의 배수여야 하고, 하프 워프의 k번째 스레드가 블록의 k번째 요소에 액세스해야 한다는 것입니다. 예측 액세스, 하프 워프 내의 발산과 같이 모든 스레드가 참여해야 하는 것은 아닙니다.
부동 소수점 숫자를 읽기 위한 병합 액세스의 예는 아래와 같습니다. 위쪽 행은 모든 스레드가 참여하는 반면 아래쪽 행은 그렇지 않습니다.

부동 소수점 숫자를 읽기 위한 통합되지 않은 액세스의 예는 아래와 같습니다. 위쪽 행은 스레드로 액세스되지만 아래쪽 행은 정렬되지 않은 시작 주소(64의 배수가 아님)이기 때문에 그렇지 않습니다.

병합(Compute 1.2+ GPU)의 경우 10 시리즈 아키텍처에서 병합 기능이 크게 향상되었습니다. 하드웨어는 하프워프 내의 주소를 하나 이상의 정렬된 세그먼트(32, 64 또는 128바이트)로 결합합니다. 세그먼트 내 주소의 모든 스레드는 세그먼트 내 순서나 정렬에 관계없이 단일 메모리 트랜잭션으로 처리됩니다. 다음 그림은 정렬되지 않은 시작 주소(64의 배수가 아님)의 크기를 최소화하기 위해 트랜잭션 크기를 반복적으로 줄이는 것을 보여줍니다.

충돌 없는 다이어그램과 충돌 없는 다이어그램의 공유 메모리 뱅크 주소 지정은 다음과 같습니다.

2자 갈등과 9자 갈등의 그림은 다음과 같습니다.

점유란 무엇입니까? GPU는 일반적으로 1,000~10,000개의 스레드를 동시에 실행합니다. 더 높은 점유율 = 하드웨어를 더 효율적으로 사용합니다. 병렬 코드는 주어진 순간에 동시에 실행되는 워프(32개 스레드)를 통해 하드웨어에서 실행됩니다. 스레드 명령어는 순차적으로 실행됩니다. 다른 워프를 실행하면 명령 및 메모리 지연이 하드웨어에 숨겨질 수 있습니다. 점유율을 최대한 최대화합니다. 점유율 1.0이 가장 좋은 솔루션입니다.
하나 이상의 스레드 그룹은 단일 셰이더 장치에 상주하며 스레드 그룹 크기 선언, 스레드 그룹 공유 메모리 사용량, 스레드 그룹에서 사용하는 레지스터 수 등 리소스 사용량에 따라 점유가 제한됩니다. 예: 최대 8개의 스레드 그룹, 48KB의 총 공유 메모리 및 최대 1536개의 스레드가 있는 하드웨어 셰이더 장치는 256개의 스레드 그룹 크기로 셰이더를 시작하고 32KB의 공유 메모리를 사용하여 하드웨어 셰이더 장치당 1개의 스레드 그룹만 실행됩니다. 이때는 공유 메모리에 의해 제한됩니다.

스케줄링/스레드 그룹 크기 경험적 방법:
스레드 그룹 수 > 멀티프로세서 수로 설정합니다. 모든 다중 프로세서에는 실행을 위한 스레드 그룹이 하나 이상 있습니다.
스레드 그룹 수/멀티프로세서 수 > 2. 여러 스레드 그룹은 멀티프로세서에서 동시에 실행될 수 있으며, 장벽에서 기다리지 않는 스레드 그룹은 리소스 가용성(레지스터, 공유 메모리)에 따라 하드웨어를 바쁘게 유지합니다.
향후 장치로 확장할 수 있는 스레드 그룹 >100. 파이프라인 방식으로 실행되는 스레드 그룹은 한 번에 1000개의 그룹을 예약하여 여러 세대에 걸쳐 확장됩니다.
-실/실 그룹의 수는 워프 크기의 배수입니다. 워프의 모든 스레드가 작동 중입니다.
DirectCompute에 의해 최적화된 사용 사례 중 하나는 병렬 축소(Parallel Reduction)입니다. 이는 컴퓨팅 셰이더에서 쉽게 구현할 수 있는(올바르게 구현하기가 더 어려운) 공통적이고 중요한 데이터 병렬 기본 요소(예: 배열의 합 찾기)입니다. 이 기사에서는 7가지 버전을 소개하고 몇 가지 중요한 최적화 전략을 보여줍니다.

각 스레드 블록에 사용되는 트리 기반 접근 방식에는 여러 스레드 블록을 사용하고, 매우 큰 배열을 처리하고, GPU의 모든 멀티프로세서를 계속 사용하고, 스레드 블록당 배열의 일부를 줄이는 기능이 필요합니다. 그러나 스레드 블록 간에 부분 결과를 전달하는 방법은 무엇입니까?

계산을 여러 일정으로 나누어 전역 동기화를 방지하는 셰이더 분해.

교차 주소 지정은 공유 메모리 뱅크 충돌이라는 새로운 문제를 야기합니다.

순차적 주소 지정.

다양한 병렬 프로토콜의 알고리즘 성능 비교.
이 기사에서는 다중 GPU 병렬 처리에 대해서도 언급합니다. 작업 또는 데이터 병렬 GPU 처리를 위해 단일 시스템에서 여러 GPU를 사용할 수 있습니다. 호스트는 GPU 간 통신(호스트 메모리를 통해 발생해야 함)을 최소화하기 위한 최상의 파티션을 선택하여 각 GPU의 I/O 및 작업 부하를 명시적으로 관리합니다.

여러 GPU 및 CPU 통신 모델은 작업 병렬성과 데이터 병렬성을 달성할 수 있습니다.
메모리 병합(행렬 곱셈), 각 반복, 스레드는 A의 동일한 요소에 액세스하며 CS 1.2+에서만 사용할 수 있습니다.

DX11 하드웨어의 DirectCompute 성능에서는 DirectCompute의 기능, 이점, 최적화 및 성능 모니터링을 설명합니다.
기사에서는 DirectCompute를 사용하는 이유가 GPU의 임의 프로그래밍(일반 프로그래밍, 포스트 프로세스 작업 등)을 허용하고, 심각한 TEX 또는 ALU 병목 현상이 있는 PS를 더 효과적으로 타겟팅하고, CS 스레드를 사용하여 작업을 분할하고 셰이더의 균형을 맞추는 것을 포함한다고 언급합니다. 항상 PS를 이길 수는 없지만 균형이 잘 잡힌 PS라도 CS에 패배할 가능성은 거의 없습니다.
GPU는 처리량 지향 프로세서이며 대기 시간은 작업으로 처리되며 효율적이려면 충분한 작업을 제공해야 하며 세분화된 병렬 처리를 찾고 간단한 매핑이 가장 잘 작동합니다(화면의 픽셀, 시뮬레이션의 입자). GPU에서 작은 계산을 실행하는 것은 호스트와의 데이터 교환을 피하는 데 도움이 된다면 여전히 유리할 수 있습니다. 여기에는 DispatchIndirect()와 결합하여 CPU 개입 없이 더 많은 작업을 수행할 수 있도록 하는 후속 커널 실행 또는 그리기 호출을 위한 매개변수 준비와 같은 대기 시간 이점이 포함됩니다.
NVIDIA의 GPU는 스칼라이며 명시적인 벡터화가 필요하지 않습니다. 대부분의 경우 스레드를 스칼라 데이터 요소에 매핑하면 효과가 없습니다(예외는 있음). AMD의 GPU는 벡터이므로 벡터화는 성능에 중요합니다. 스칼라 지침에 의존하지 말고 IHV 도구를 사용하여 ALU 사용량을 확인하세요.
CS4.0과 비교하여 CS5.0은 스레드, 스레드 그룹 공유 메모리, 원자적 유연성 등과 같은 많은 장점을 가지고 있습니다. 일반적으로 CS5.0의 기능을 사용하면 더 빠르게 실행됩니다. 올바른 수의 스레드 그룹을 선언하는 것은 성능에 매우 중요합니다.
numthreads(NUM_THREADS_X, NUM_THREADS_Y, 1)
void MyCSShader(...)
{
(...)
}전체 스레드 그룹 크기는 하드웨어의 웨이브프런트 크기보다 커야 합니다(크기는 GPU에 따라 다름, ATI의 최대값은 64, NV의 32). 웨이브프런트 크기보다 작은 크기는 피하고 numthreads(1,1,1)와 같은 스레드 그룹은 피하고, 더 큰 값은 일반적으로 다양한 GPU에서 작동하며, 더 나은 확장을 위해 저사양 GPU를 사용합니다.
스레드 그룹을 사용할 때 그룹의 모든 스레드에 작업을 균등하게 분배하십시오. 동적 흐름 제어는 스레드에 대해 서로 다른 워크플로를 생성합니다. 즉, 작업량이 적은 스레드는 유휴 상태이고 다른 스레드는 계속 사용 중입니다.
[numthreads(groupthreads, 1, 1)]
void CSMain(uint3 Gid : SV_GroupID, uint3 Gtid: SV_GroupThreadID)
{
(...)
if (Gtid.x == 0)
{
// 의 코드 오직 개 스레드(Thread)실행(Execute)!
}
}일반적으로 오버헤드가 높은 Compute 및 Draw 호출 간의 전환 수를 줄이기 위해 Compute와 래스터라이제이션를 혼합할 수 있습니다. 구체적인 예를 들기 위해 다음과 같은 호출 품질 순서가 있다고 가정합니다.
Compute A
Compute B
Compute C
Draw X
Draw Y
Draw ZCompute 및 Draw를 교차 호출하도록 변경할 수 있습니다.
Compute A
Draw X
Compute B
Draw Y
Compute C
Draw Z**UAV(Unordered Access View)**의 경우 엄격한 의미에서 DirectCompute 리소스가 아니며 PS에서도 사용할 수 있습니다. 비순차적 액세스는 읽기 및 쓰기 분산, 액세스 분산 = 캐시 삭제, 그룹화된 읽기/쓰기 우선 순위 지정(강력 권장)을 지원합니다. float4(float 대신)에서 읽기/쓰기가 가능하지만 NVIDIA 스칼라 아키텍처는 이로부터 이점을 얻지 못합니다. UAV에 대한 연속 쓰기의 경우 필요하지 않은 경우 UAV 플래그를 사용하여 버퍼나 텍스처를 생성하지 마세요. 렌더링 작업 후에 동기화가 필요할 수 있습니다. 필요한 경우에만 D3D11_BIND_UNORDERED_ACCESS를 사용하세요. UAV를 스크래치 패드로 사용하지 말고 TGSM(Thread Group Shared Memory)을 사용하는 것이 더 좋습니다.
계산된 UAV 버퍼링은 Shader Model 5.0에서 지원되는 기능입니다. 텍스처는 지원되지 않습니다. CreateUnorderedAccessView()에서 D3D11_BUFFER_UAV_FLAG_COUNTER 플래그를 사용합니다. 액세스 방법에는 uint IncrementCounter(), uint DecrementCounter()가 포함됩니다.
UAV에 대한 원자적 작업이 방지되므로 UINT32 크기의 R/W UAV를 사용하여 수동 카운터를 구현하는 것보다 빠릅니다. 그러나 NVIDIA 하드웨어에서는 Append 버퍼가 선호됩니다.
추가/소비 버퍼는 데이터 병렬 커널의 출력을 배열로 직렬화하는 데 사용되며 지연된 조각 처리와 같은 그래픽에도 사용할 수 있습니다. 주의해서 사용해야 하며 비용이 많이 들 수 있습니다. API에 직렬화 지점을 도입합니다. 레코드 크기가 크면 추가 작업 비용이 숨겨질 수 있습니다.
원자적 작업은 완료될 때까지 다른 스레드에 의해 중단될 수 없는 작업입니다. 일반적으로 UAV와 함께 사용됩니다. 원자적 작업은 동기화 요구 사항으로 인해 성능에 영향을 미칩니다. 필요한 경우에만 사용하십시오. 많은 문제를 보다 효율적인 병렬 축소 또는 스캔으로 재구성할 수 있습니다. 피드백을 사용한 원자적 작업은 다음과 같이 비용이 더 많이 듭니다.
Buffer->InterlockedAdd(uAddress, 1, Previous);**TGSM(스레드 그룹 공유 메모리)**은 그룹의 스레드 간에 공유되는 빠른 메모리이며 스레드 그룹 간에 공유되지 않습니다! 예를 들어:
groupshared float2 MyArray[16][32];Dispatch() 호출 간에는 지속되지 않습니다(즉, TGSM은 단일 Dispatch에만 사용할 수 있음). 계산량을 줄이고 인접 계산을 TGSM에 저장하여 사용하는 데 사용됩니다(예: 포스트 프로세스 텍스처 명령).
TGSM 성능에 영향을 미치는 주요 요인은 다음과 같습니다.
- 액세스 모드.
I/O 뱅크(리포지토리?) 수는 제한되어 있으며 ATI 및 NVIDIA 하드웨어의 뱅크는 32개이며 뱅크 충돌로 인해 효율성이 저하됩니다. 32뱅크 예에서 각 주소는 32비트이고 뱅크는 주소별로 선형으로 배열됩니다.

32 DWORD 떨어져 있는 TGSM 주소는 동일한 뱅크를 사용합니다. 여러 스레드에서 이러한 주소에 액세스하면 뱅크 충돌이 발생하고 TGSM 2D 배열을 MyArray[Y][X]로 선언하고 X를 먼저 증가시킨 다음 Y를 증가시킵니다(필요한 경우 필수).
방문을 최대한 최소화하세요. 예를 들어 데이터를 float4 대신 uint로 압축합니다(그러나 ALU가 증가합니다).
기본적으로 각 TGSM 주소는 한 번씩 읽기/쓰기를 시도합니다. 임시 배열에 복사하면 반복적인 액세스를 방지하는 데 도움이 될 수 있습니다.
공유 메모리에 액세스하는 언롤링 루프는 컴파일러가 대기 시간을 숨기는 데 도움이 됩니다.
장벽은 GroupMemoryBarrier() 및 GroupMemoryBarrierWithGroupSync()와 같이 그룹의 모든 스레드에 대한 동기화 지점을 추가합니다. 장벽이 너무 많으면 성능에 영향을 미칠 수 있습니다. 특히 작업이 스레드 간에 고르게 분산되지 않은 경우 더욱 그렇습니다. 많은 장벽을 사용하는 알고리즘을 주의하세요.
하드웨어 사용량을 극대화하세요. 스레드 그룹은 임의로 분할될 수 있는 픽셀 작업과 달리 여러 셰이더 단위로 내부 또는 외부로 분할될 수 없습니다. 점유에 영향을 미치는 요소는 스레드 그룹 크기 선언, 선언된 TGSM 크기 및 사용된 GPR 수입니다. 이 숫자는 달성할 수 있는 병렬 처리 수준에 영향을 미칩니다. 예를 들어, 하드웨어 셰이더 유닛의 매개변수는 최대 8개의 스레드 그룹, 32KB의 총 공유 메모리, 최대 1024개의 스레드입니다. 스레드 그룹 크기는 128개 스레드이며 24KB의 공유 메모리가 필요합니다. 각 셰이더 유닛(128개 스레드)은 1개의 스레드 그룹만 실행할 수 있습니다(오류).
등록 압력도 점유에 영향을 미치지만 우리는 이에 대해 거의 통제할 수 없으며 올바른 일을 하기 위해 운전자에게 의존합니다. 이상적인 균형을 찾으려면 조정과 실험이 필요하지만 그 균형은 하드웨어마다 다릅니다! 다양한 GPU에서 최적의 성능을 위해 다양한 사전 설정을 저장합니다.
DiRT2 DirectX 11 기술은 DX11로의 포팅, 표면 세분화, 직접 계산 및 스레드 리소스 로딩을 기반으로 하는 HDAO를 포함하여 게임 Colin McRae Dirt 2에 사용되는 DirectX 11 기술을 도입합니다. 이 기사에서는 테셀레이션을 기반으로 한 메시 디테일링, 옷감 및 물 시뮬레이션에 대해 언급합니다.

DX11 테셀레이션을 기반으로 한 천입니다. 왼쪽은 원본 메쉬이고, 오른쪽은 PN 세분화 + 변위 메쉬입니다.
**HDAO(High Definition Ambient Occlusion)**의 작동 원리는 기본적으로 HBAO(Horizon Based Ambient Occlusion)의 작동 원리와 동일합니다. 단순히 픽셀이 아닌 주변광과 환경을 고려하여 SSAO 픽셀 깊이 측정으로 인해 발생하는 파티클 및 노이즈 문제를 해결합니다. 가장 큰 단점은 더 많은 CPU 및 GPU 처리 능력이 필요하다는 것입니다. HBAO+는 더 적은 성능 작업으로 빛과 그림자 샘플링 알고리즘을 제공하여 AO의 세부 수준을 두 배로 높이고 실행 속도를 세 배로 높입니다.
HBAO는 깊이 버퍼 샘플링과의 통합을 근사화하는 물리적 기반 알고리즘을 사용하여 HBAO가 더 높은 품질의 SSAO를 생성하고 픽셀당 샘플 수와 AO의 정의, 품질 및 가시성을 증가시킨다는 점에서 이전 SSAO 변형과 다릅니다. 성능상의 이유로 HBAO는 일반적으로 절반 해상도로 렌더링되어 AO 픽셀 수를 3/4로 줄입니다. 그러나 HBAO를 감소된 해상도로 렌더링하면 모든 상황에서 숨기기 어려운 깜박임이 발생합니다.
PS 스타일 후처리를 사용하면 오버샘플링이 많이 발생할 수 있으며, 샘플이 다루는 영역은 커널 크기이며, 중앙 픽셀 주위에 많은 수의 텍셀이 샘플링됩니다. 이 기사에서는 컴퓨터 셰이더를 사용하여 속도를 높이려고 시도합니다.
첫 번째는 타일을 겹치고, LDS를 사용하여 텍스처 샘플링 비용을 크게 줄이고, 스레드 그룹 처리를 위해 화면을 타일로 나누는 것입니다. 커널 크기에 따라 중첩 정도가 결정됩니다. 다음 그림은 LDS 쓰기에 관련된 텍셀 샘플링 영역, LDS 읽기/쓰기에 관련된 ALU PP 계산 영역, 커널 크기를 보여줍니다.

// 구현 코드
// CS result texture
RWTexture2D<float> g_ResultTexture : register( u0 );
// LDS
groupshared float g_LDS[TEXELS_Y][TEXELS_X];
[numthreads( THREADS_X, THREADS_Y, 1 )]
void CS_PPEffect( uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID )
{
// Sample texel area based on group thread ID – store in LDS
g_LDS[GTid.y][GTid.x] = fSample;
// Enforce barrier to ensure all threads have written their
// samples to the LDS
GroupMemoryBarrierWithGroupSync();
// Perform PP ALU on LDS data and write data out
g_ResultTexture[u2ScreenPos.xy] = ComputePPEffect();
}PS 성능과 비교했을 때 CS 기반 HDAO는 심도가 1.3배, 심도+일반이 3.6배 증가했습니다(테스트 환경 Windows 7 64비트, AMD Phenom II 3.0GHz, 2GB RAM, ATi HD5870, Catalyst 10.2).

또한 DX11의 GatherCmp()를 사용하여 PCF 그림자를 빠르게 샘플링하여 더 간단하고 통일된 결과를 얻을 수도 있습니다.
DiRT2는 백그라운드 로딩 스레드를 사용하여 리소스를 대기열에 배치합니다. DX9 모드에서는 리소스가 메인 스레드에서 생성됩니다. DX11 모드에서는 로딩 스레드에서 리소스가 생성되므로 구현이 더 간단하고 빠릅니다. 로딩 시간이 약 50% 정도 빨라졌습니다.
R-Trees - 최신 메모리 아키텍처에 코어 외부 기술을 적용하면 R-Tree의 특성과 원리를 소개하고 이를 메모리 사용량에 맞게 조정하여 캐시 동작 및 SIMD 처리에서 상당한 이점을 얻는 방법을 보여줍니다.
R-Tree는 기본적으로 AABB 트리이지만 몇 가지 특정 속성과 사전 작업이 많이 필요합니다. 해당 노드는 큰 고정 크기 하위 AABB와 상위 노드에 저장된 노드에 대한 포인터로 구성된 블록으로, 다소 느슨하게(일반적으로 최대 50%) 액세스 패턴을 고려할 때 의미가 있어 토폴로지 변경 빈도를 줄입니다.
2-3 R-Tree 구성을 예로 들어보겠습니다(2-3은 하위 노드 수가 2-3으로 제어된다는 의미이며 실제로는 16-32 R-Tree와 같이 더 많은 수의 노드가 사용됩니다).

R-Tree의 장점은 다음과 같습니다.
캐시 친화적인 데이터 레이아웃.
강체 분할을 위한 모드는 없습니다.
더 높은 분기 계수.
더 짧은 깊이, 더 적은 읽기, 더 많은 작업이 각 노드 내에서 이루어집니다.
- 미리 읽기(너비 우선 순회)
스택(깊이 우선): 현재 노드는 다음 노드를 변경할 수 있습니다.
대기열: 다음 노드를 파악하여 미리 가져옵니다.
각 노드에는 많은 하위 노드가 있습니다.
VMX 대기 시간을 숨기려면 테스트를 확장하세요.
프리페치 대기 시간을 숨깁니다.
동적 개체에 사용할 수 있습니다.
객체가 이동하더라도 토폴로지는 유효하게 유지됩니다. 모든 AABB 변경 사항은 상위 노드에 전파되어야 합니다.
성과가 좋지 않을 수도 있지만 여전히 정확합니다.
물체가 상당한 거리를 이동할 때까지 재삽입을 연기합니다. AABB를 조정하는 것이 다시 삽입하는 것보다 훨씬 빠릅니다.
요약하면, R-Tree는 계층적 트리의 기존 장점을 모두 갖고 있고 매우 캐시 및 SIMD 친화적이며 대량 로딩이 필요하지 않지만 많은 선행 개발 작업이 필요한 빠른 블록 기반 AABB 트리입니다.
0~200MPH의 대규모 환경 스트리밍에서는 레이싱 게임 Forza Motorsport 3에서 대규모 트랙 환경을 생성 및 렌더링하는 데 사용되는 프로세스, 아트에서 게임까지의 프로세스, 그리고 다수의 고해상도 모델을 렌더링하기 위한 몇 가지 핵심 기술을 소개합니다.

Forza Motorsport 3의 스트리밍 목표는 트랙, 자동차 8대, 사용자 인터페이스와 같은 모듈을 포함하여 60fps로 렌더링하는 것입니다. 포스트 프로세스, 반사, 그림자, 입자, 슬라이드, 군중, 분할 화면, 재생 등을 지원합니다. 이 게임은 100개 이상의 트랙, 약 13마일 길이, 47,000개 이상의 모델, 60,000개 이상의 텍스처 등 대규모 환경을 제공합니다. 대규모 모델의 일반적인 시각화 수준:

최신 메모리 모델은 위에 표시된 것과 같이 속도는 증가하지만 용량은 감소합니다: 디스크/로컬 스토리지, 압축 캐시, 압축 해제 힙, GPU/CPU 캐시, GPU/CPU. 이러한 저장소 유형은 아래에 설명되어 있습니다.
하드 디스크에 zip 패키지로 저장되고 일부 추가 데이터가 포함된 zip 형식으로 저장되지만 기본 형식을 따르므로 표준 검색 도구(Explorer, WinZip 등)는 계속 작동하며 LZX 형식의 아카이브에서는 트랙당 90-300MB입니다.
디스크에서 압축된 캐시로의 빠른 IO를 활용하여 블록은 zip에 있는 파일 그룹으로, 전체 파일 크기는 블록 크기에 도달할 때까지 단일 읽기로 파일 그룹을 검색합니다. 압축된 캐시는 최대 15MB/s, 평균 10MB/초로 조회를 줄이지만 조회에는 100ms가 걸립니다.
압축된 캐시는 LZX 형식으로 메모리에 저장되며 필요에 따라 LRU에 들어오고 나가는 캐시 블록(약 56MB)과 함께 블록 크기는 트랙별로 조정되지만 일반적으로 1MB입니다.
압축 캐시에서 압축 해제 힙으로 이동할 때 평균 20MB/초의 빠른 플랫폼별 압축 해제가 사용됩니다. 압축 해제 힙 구현은 할당 및 할당 해제 작업 속도에 최적화되어 있으며 먼저 주소 정렬과 함께 우수한 분할 속성을 사용합니다.
압축이 풀린 힙은 GPU 또는 CPU에서 사용할 수 있으며, 각 할당은 약 194MB로 연속적이고 정렬됩니다.
다단계 텍스처 저장, 각 텍스처에 대한 세 가지 보기: Top Mip은 Mip 0, 전체 해상도 텍스처, Mip-Chain은 Mip 1, 1x1로 다운샘플링, 작은 텍스처는 32x32에서 1x1입니다. 여기에서 플랫폼별 지원은 Top Mip이 스트리밍되기 때문에 텍스처 재배치가 필요하지 않습니다.
스트리밍이 기여하지 않을 때 더 높은 LOD를 덤프할 수 있도록 다양한 LOD를 다른 객체로 처리하는 다중 레벨 지오메트리 스토리지입니다. 모델은 인스턴스별 변환 및 셰이더 데이터를 사용하여 인스턴스화됩니다.
메모리에서 GPU/CPU 캐시로 이동할 때 캐시 친화적인 렌더링을 위한 CPU별 최적화, 고주파 작업을 위한 플랫, 캐시 라인 크기 구조, CPU의 L1/L2 캐시, 불필요한 렌더링 데이터를 건드리지 않기 위한 명령 버퍼의 과도한 사용.
GPU/CPU 캐시는 셰이더 요구 사항에 따라 형식 크기 조정, GPU의 버텍스/텍스처 가져오기 캐시(예: 버텍스 형식, 스트림 수, 텍스처 형식, 크기, 밉 사용), 플랫폼별 렌더링 제어를 사용하여 밉 액세스 감소 등을 수행합니다.
미리 계산된 가시성의 경우 표준 솔루션은 주어진 위치의 주어진 장면에서 실제로 보이는 것이며 많은 구현에서는 보수적인 폐색을 사용합니다. 이 기사에서 사용된 변수에는 폐색(깊이 버퍼 거부), LOD 선택, 기여 거부(n 픽셀 미만인 경우 모델이 그려지지 않음)가 포함됩니다.
컬링 방법은 다음과 같습니다: 오클루전 컬링 - 뷰의 다른 객체에 의해 차단된 객체(아래 그림의 빨간색 사각형) 및 기여 컬링 - 뷰에 충분히 기여하지 않는 객체(아래 그림의 노란색 원).

런타임에 수행할 수 있고, LOD 및 기여가 쉽고, 폐색을 구현할 수 있습니다. 결론은 최적화가 런타임에 수행되어야 하거나 전혀 수행되지 않지만 스트리밍과 렌더링이 너무 많다는 것을 의미한다는 것입니다. 가시성 정보는 일반적으로 대용량 데이터이므로 많은 양의 데이터를 다루어야 하며 이는 캐시 성능에 해를 끼칩니다. Forza Motorsport 3의 솔루션은 오프라인으로 처리할 수 있는 작업 부하에 CPU/GPU를 소비하지 않는 것입니다.
Forza Motorsport 3의 트랙 처리 파이프라인은 샘플링, 분할, 빌드, 최적화 및 실행의 5가지 주요 샘플링 단계로 나뉩니다. 모든 단계는 장면 내 아트 검사와 최적화된 게임 준비 트랙을 생성하는 파이프라인을 통해 완전히 자동화됩니다.

최적화 단계에서는 패키지에 대한 캐시 유효 시퀀스 번호를 생성하고, 조회 거리를 단축하고, 캐시 적중률을 향상시키고, "처음 본" 측정항목을 사용하고, 영역을 살펴보고 모델이나 텍스처를 먼저 사용하는 영역을 추적하고, 모든 모델을 함께 그룹화하고 텍스처와 마찬가지로 첫 번째 영역별로 정렬합니다.
실행 단계에서는 영역 델타가 생성되고, 가시 공간에서 카메라의 위치가 결정되며, 카메라 위치가 로드할 영역에 매핑되고, 현재 로드된 영역과 로드할 영역 간의 차이가 매핑됩니다. 영역 증분, 기본적으로 참조 수를 기반으로 리소스 증분을 생성하고 작업을 통합하여 무료 첫 번째 주문을 보장합니다(이는 조각화 문제를 해결하는 데 도움이 됩니다). 데이터는 tail 영역에서 유출되고(무료) 선행 영역에서는 데이터가 유입됩니다(할당, IO 및 압축 해제).
런타임 고려 사항, 초점 영역에는 작업 순서, 힙 효율성, 압축 해제 효율성, 디스크 효율성이 포함됩니다. 많은 문제의 경우 솔루션이 없는 것보다 낫습니다. 계층 구조의 모든 수준이 해결되었는지 확인하세요.
주요 파이프라인 오류는 다음과 같습니다.
- 점프 전환.
두 가지 수준으로 제한됩니다.
지연 로딩(시스템 처리량 내에서 유지하는 데 필요한 각 지역의 양을 제한하여 조정)
가시성 오류(객체를 추가로 클러스터링하거나 샘플링 결과를 편향하여 조정)
이러한 조정 사항이 충돌하지만.
수동 조작을 제공합니다.
기하학적 편차(샘플링 결과에 영향을 미침)
텍스처 바이어스(최적화 중에 텍스처 작업 세트의 위치에 영향을 미침)
어떠한 자동화도 비현실적인 기대와 경쟁할 수 없습니다.
예를 들어, 모든 모델이 단일 영역에 표시되므로 텍스처를 위한 공간이 없습니다.
고성능 게임플레이를 위한 동적 구성 요소 아키텍처는 엔터티와 시스템 동작의 다양한 측면을 표현하기 위해 게임 시리즈 Resistance에 사용된 동적 구성 요소 아키텍처를 자세히 설명합니다. 이 구성 요소 시스템은 고성능 게임, 특히 다중 스레드 또는 다중 프로세서 환경에서 기존 게임 개체 모델의 여러 약점을 해결합니다. 동적 구성 요소는 효율적인 메모리 풀에서 요청 시 할당 및 해제되며, 시스템은 다양한 프로세서(예: SPU)에서 업데이트를 병렬로 실행하기 위한 편리한 프레임워크를 제공합니다. 시스템은 기존 게임 개체 모델 위에 계층화될 수 있으므로 코드 기반을 이 새로운 아키텍처로 점진적으로 마이그레이션할 수 있습니다. 이 문서에서는 시스템의 동기, 목표 및 구현 세부 사항에 대해 설명합니다.
과거에는 게임 개체의 구성 수준이 상대적으로 단일하고 깊이가 높으며 불균형이었습니다. 컴파일 타임에 데이터가 메모리에 묶여 있었고, 성능 측면에서 캐시 일관성이 좋지 않았으며, 아키텍처 및 사용 습관 측면에서 상속을 통해 기능을 얻었습니다.
해결책은 런타임 시 구성 요소를 데이터 변환을 나타내는 작은 덩어리로 결합하여 게임 개체를 구축하는 것입니다. 기존 코드를 리팩터링하지 않고 병렬로 구현할 수 있으며 구성 요소와 공존할 수 있습니다. 그러나 동적 구성 요소는 반영, 직렬화, 데이터 구성, 인스턴스 버전 관리 등과 같은 문제를 해결하지 못합니다.
동적 구성요소 시스템의 특징은 다음과 같습니다.
- 구성요소
구성 요소는 원래 기능이며 기본 구성 요소 클래스에는 풀에서 할당된 8바이트의 관리 데이터, 구체적인 유형당 하나의 풀, "명부" 인덱스 인스턴스 및 별도의 할당/사용 가능 인스턴스인 "파티션"이 있습니다.
- 고성능
할당/해제, 핸들 확인, 유형 가져오기, 유형 구현(파생) 및 인스턴스 복사 없음을 포함한 소수의 상수 시간 작업. 유형별(풀별) 업데이트, 캐시 친화적, 비동기 업데이트(예: SPU) 용이, 명단은 할당된 인스턴스의 연속 목록, 파티션 명단은 DMA 목록입니다. 구문 분석 핸들에는 소수의 상수 시간 작업(풀 색인, 빌드 비교, 구성 요소 반환)이 있습니다.
- 동적
게임 개체의 런타임 구성, 수하물 없이 동작을 동적으로 변경, 할당된 구성 요소 == 사용 중, 풀 크기 == 최대 동시 할당.
자주 alloc() 및 free(), alloc()에는 유용성 테스트, 인덱스 및 생성에서 핸들 구성, 명단 파티션 추가, Component::Init(), free()에는 Component::Deinit(), 명단 인덱스를 파티션 인접 인덱스와 교환, 파티션 축소 및 증분 생성이 포함됩니다. 동적 구성 요소의 릴리스 인터페이스는 다음과 같습니다.
// free the component from host's component chain
void DynamicComponent::Free( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle );아래 다이어그램과 결합하면 특정 구성 요소 유형에 대한 인스턴스 풀이 있고 인스턴스 풀에 대한 인덱스 배열인 명단이 있습니다. 풀의 모든 인스턴스는 유형이 동일하므로 크기도 동일합니다. 따라서 명단 인덱스의 값 자체가 풀에 대한 인덱스입니다. 할당된 인스턴스와 유휴 인스턴스를 나타내는 명단 인덱스를 구분하는 파티션 값이 있음을 알 수 있습니다.

세 번째 명단 요소로 표시되는 구성 요소가 이제 출시될 예정이며 현재 풀의 인덱스 3에 있습니다.

해야 할 일은 세 번째와 네 번째 명단 요소를 바꾸는 것입니다.

이제 풀의 세 번째 인스턴스를 나타내는 네 번째 명단 요소가 출시됩니다. 해제되는 요소의 ROSTER 항목은 파티션의 인접한 ROSTER 항목으로 교체되므로 인스턴스를 해제하는 데 필요한 것은 파티션의 인덱스를 1 단위(-1) 위로 이동하는 것뿐입니다. 그것은 간단합니다:

- 시스템
전부도 아니고 아무것도 아닙니다! 예를 들어 대화, 스크립트 이벤트, 사격: 게임 개체가 없습니다. 다음은 동적 구성요소 시스템의 관련 인터페이스 정의입니다.
namespace DynamicComponent
{
// Hosts' API
Component* Allocate ( Type type, HostHandle host_handle, Chain* chain, void* prius = NULL );
Component* ResolveHandle ( Type type, ComponentHandle component_handle );
Component* Get ( Type type, HostHandle host_handle, Chain chain );
Component* GetComponentThatImplements( Type type, HostHandle host_handle, Chain chain );
Component** GetComponents ( Type type, HostHandle host_handle, Chain chain, u32& count );
Component** GetComponentsThatImplement( Type type, HostHandle host_handle, Chain chain, u32& count );
void Free ( Type type, HostHandle host_handle, Chain& chain, ComponentHandle& component_handle );
void FreeChain ( HostHandle host_handle, Chain& chain );
#define COMPONENT_CAST(component, type) \
((type##Component*)ValidCast(component, DynamicComponent::type))
inline Component* ValidCast ( Component* component, Type type );
// Systems' API
Type* GetTypesThatImplement ( Type type, u32& count );
bool TypeImplements ( Type type, Type interface );
u32 GetNumAllocated ( Type type );
Component** GetComponents ( Type type, u32& count );
Component* GetComponentsIndexed ( Type type, u16*& indices, u32& count );
void UpdateComponents ( UpdateStage::Enum stage );
void Free ( Type type, ComponentHandle& component_handle );
UpdateStage::Enum GetCurrentUpdateStage ( );
u8 GetTypeUpdateStages ( Type type );
}구현 프로세스에는 스크립트 이벤트, 할당 및 초기화, 비동기 업데이트 및 기타 세부 정보가 포함됩니다.
우연히도 Entity Component Systems에서는 Unity 엔진 ECS와 운영 체제의 특징에 대해서도 이야기했습니다.
ECS(Entity Component System)는 주로 게임 및 시뮬레이션에 사용되는 데이터를 구성하는 방법입니다. 엔터티(또는 게임 개체)는 플레이어, 적, 장애물, 파워업과 같이 보거나 상호 작용할 수 있는 게임의 모든 개체입니다. 구성 요소는 플레이어 엔터티에 연결된 것과 같이 엔터티에 할당된 속성으로, 상태, 충돌, 변형 및 모션 구성 요소를 가질 수 있습니다. 시스템은 구성 요소에 기능이 추가되는 곳입니다. 즉, 모션 및 변환 구성 요소를 사용하여 기본 모션 시스템을 만들 수 있습니다. 다음 그림은 각각 엔터티, 구성 요소 및 시스템 관리자를 보여줍니다.

ECS 모델에는 순수 방법과 하이브리드 방법이 포함됩니다. 둘의 비교는 다음과 같습니다.
순수하이브리드
엔터티는 새로운 게임 객체입니다. Pure ECS의 모든 기능 포함
더 이상 모노 동작이 없습니다. 게임 개체를 엔터티로 변환하고 모노 동작을 구성 요소로 변환하는 특수 도우미 클래스를 포함합니다.
데이터는 구성 요소에 저장되고 논리는 시스템에 저장됩니다.
성능상의 이점을 제공하는 새로운 C# 운영 체제 활용
버스트는 고도로 최적화된 기계 코드를 생성할 수 있고 컴파일되는 플랫폼을 최대한 활용하며 완전히 자동화될 수 있는 Unity에서 개발한 새로운 수학 인식 컴파일러입니다. 수행해야 할 작업은 버스트 컴파일러 패키지를 프로젝트에 추가한 다음 C# 작업이 버스트 컴파일 속성으로 표시되었는지 확인하는 것입니다. 그런 다음 Unity는 운영 체제 코드를 가져와 고도로 최적화된 기계어 코드로 컴파일합니다. 즉, C++ 또는 C와 같은 언어로 작성된 로직을 프로세서에서 직접 실행할 수 있습니다. 버스트의 장점은 구현이 매우 쉽고 복잡한 하위 수준 코드에 대한 이해가 필요하지 않다는 것입니다. ECS와 결합하면 성능이 크게 향상됩니다.
Unity 잡 시스템을 사용하면 개발자는 스레드 대신 작업을 생성하여 멀티 스레드 코드를 쉽고 안전하게 작성할 수 있습니다. 작업은 시스템이 일련의 스레드로 처리할 수 있는 작업 단위를 나타냅니다. 작업이 예약되면 시스템은 이를 특수 대기열에 넣고 작업자 스레드는 대기열에서 작업을 가져와 실행합니다. 작업자 스레드는 기본 스레드를 중단하지 않도록 백그라운드에서 작업을 완료하는 작업 시스템에서 관리하는 개별 스레드입니다.
Unity 운영 체제를 사용하는 이유는 다음과 같습니다. 다중 스레드 코드가 결정적임을 보장합니다. 예를 들어, 운영 체제는 각 논리적 CPU 코어에 대해 작업자 스레드를 생성하여 컨텍스트 전환을 방지하려고 시도하므로 개발자는 CPU 성능에 어떤 영향을 미칠지 걱정하지 않고 원하는 만큼(합당한 범위 내에서) 작업을 생성할 수 있습니다. 운영 체제에는 작업 종속성 형태의 경쟁 조건을 방지하기 위한 메커니즘도 내장되어 있습니다. 예를 들어 작업 A에 작업 B에 대한 일부 데이터가 필요한 경우 작업 B의 종속성으로 할당할 수 있으므로 작업 A는 항상 먼저 실행되고 작업 B는 항상 올바른 데이터를 갖게 됩니다.
Unity 운영 체제를 사용하면 애플리케이션 계층 개발자가 Unity에서 안전하고 간단하며 완벽하게 관리되는 방식으로 멀티스레딩을 사용할 수 있습니다. Unity ECS 및 버스트 컴파일러와 결합하면 매우 성능이 뛰어나고 최적화된 코드를 즉시 얻을 수 있습니다.
도구 개발을 위한 반영은 프로그래머가 콘텐츠 제작 도구를 개발할 때 직면하는 일반적인 패턴을 탐구합니다. 애니메이션, 오디오, 그래픽, 게임플레이 등 뛰어난 워크플로우를 제공하는 도구를 개발하는 것은 쉬운 일이 아닙니다. 도구는 생산 프로세스의 변화에 적응하면서도 안정적이어야 하고, C++로 작성된 게임과 통합되어야 하며, 게임에 특화되어야 하지만 재사용이 가능해야 합니다. Jeremy Walker는 Ubisoft Vancouver가 뛰어난 워크플로우를 갖춘 도구를 신속하게 개발하는 데 사용하는 자체 개발 프레임워크를 공유했습니다.
엔진 개발 중에는 하드 코딩된 데이터 기반 시스템 권한, 선택 및 디자인을 접하는 것이 일반적입니다.


다양한 모듈이나 하위 시스템 간에는 복잡한 연결, 상호 작용 또는 종속성이 있습니다.

이러한 하위 모듈 부분은 선택적으로 직접 하드코딩할 수 있습니다.

그런 다음 각 하위 시스템의 편집, 구성, 직렬화 및 렌더링 부분이 개별적으로 모듈 그룹으로 병합되어 전체 엔진 방법을 형성합니다.

문제는 낮은 개발 비용과 훌륭한 워크플로, 변화에 대한 적응성, 안정적인 도구, 재사용 가능한 시스템 및 특정 유형의 요구 사항과 결합된 게임의 균형을 맞추는 방법입니다.

이 솔루션은 모든 유형의 콘텐츠를 위한 것입니다. 뛰어난 워크플로 개발 비용을 최소화하고, 특정 게임 요구 사항을 충족하면서 재사용 가능한 시스템을 설계하고, 제작 프로세스의 지속적인 변화에 적응할 수 있는 안정적인 도구를 개발하는 것입니다. 소프트웨어 패키지 릴리스 흐름도는 다음과 같습니다.

단일 패키지 릴리스 관련 문제:

분리된 패키지를 샘플링할 수 있습니다.

lockstep 릴리스 관련 문제:

반사 시스템을 사용하여 오버헤드와 복잡성을 줄일 수 있습니다. 다음은 하드 코딩된 모놀리식 엔진과 리플렉션을 사용하는 분리된 시스템의 비교 차트입니다. 리플렉션을 사용하는 분리된 시스템은 낮은 오버헤드, 단순성, 높은 재사용성 및 뛰어난 워크플로와 같은 목표를 달성할 수 있습니다.

이제 우리는 컴퓨터 언어의 반영 메커니즘에 대해 자세히 설명하겠습니다. 다음 그림은 함수가 선언될 때 리플렉션이 정보를 수집한 다음 수집된 정보를 함수 정의에 바인딩하는 C++의 컴파일 프로세스 및 리플렉션 메커니즘을 보여줍니다.

혼합 언어 반영의 경우 프로세스는 비슷하지만 약간 다릅니다.

게임 스크립팅 언어 반영:

게임 직렬화 반영:

공용 언어에 대한 반사 사양:

C++ 반영의 인기 있는 방법: 매크로, 코드 파서, 유형 정의 언어. 샘플 코드는 다음과 같습니다.
// ----- -----
class SimpleVehicle : public Entity
{
public:
DECLARE_TYPE();
float m_MaxSpeedKPH;
void Reset(bool useDefaults);
float GetMaxSpeedMPH() const;
void SetMaxSpeedMPH(float maxSpeedMPH);
};
//In a separate .CPP file:
DEFINE_TYPE(SimpleVehicle)
BASE_CLASS(Entity)
FIELD(“MaxSpeedKPH”, m_MaxSpeedKPH)
METHOD(Reset)
PROPERTY(GetMaxSpeedMPH, SetMaxSpeedMPH)
DEFINE_TYPE_END()
// ----- 코드 -----
/// [Class]
class SimpleVehicle : public Entity
{
public:
/// [Field(“MaxSpeedKPH”)]
float m_MaxSpeedKPH;
/// [Method]
void Reset(bool useDefaults);
/// [Property]
float GetMaxSpeedMPH() const;
/// [Property]
void SetMaxSpeedMPH(float maxSpeedMPH);
};
// ----- 타입/유형 정의 -----
class SimpleVehicle : Entity
{
float MaxSpeedKPH;
void Reset(bool useDefaults);
float MaxSpeedMPH { get; set; }
};위의 세 가지 C++ 반영 방법의 장점과 단점은 아래 표에 나와 있습니다.
C++ 반사 방법 장점 단점
매크로 외부 도구 없음 구현하기 어렵고, 디버그하기 어렵고, 런타임 시 발견됨
코드 파서 구현이 더 쉬움, 컴파일 타임에 발견됨 느린 사전 빌드 단계
유형 정의 언어 가장 쉬운 구현, 느린 사전 빌드 없음 기존 클래스를 반영할 수 없습니다.
그런데 UE의 리플렉션은 코드 파서를 주요 부분으로 사용하고 매크로를 보충으로 사용하는 하이브리드 방식입니다.
게임 유형 정의를 내보내는 프로세스는 다음과 같습니다.

위 예제 코드에서 SimpleVehicle 유형에 대한 코드 파서가 내보낸 Types.xml 데이터는 다음과 같습니다.
<type name=“SimpleVehicle”>
<field name=“MaxSpeedKPH” type=“float”/>
<method name=“Reset” returntype=“void”>
<parameter name=“useDefaults” type=“bool”/>
</method>
<property name=“MaxSpeedMPH” type=“float” hasget=“true” hasset=“true”/>
</type>내보내기 도구의 유형 정의는 게임의 유형 정의와 약간 다릅니다.

생성된 C# 프록시 유형은 다음과 같습니다.
[ProxyType(“SimpleVehicle”, 0x81c37132)]
public partial class SimpleVehicle : Entity
{
public float MaxSpeedKPH
{
get { return this.Instance.GetField(“MaxSpeedKPH”).Get<float>(); }
set { this.Instance.GetField(“MaxSpeedKPH”).Set<float>(value); } }
}
public float MaxSpeedMPH { ... }
public void Reset(bool useDefaults) { ... }
}도구에서 리플렉션의 주요 용도로는 직렬화, 클라이언트-서버 원격 및 GUI 생성이 있습니다.

클라이언트-서버 원격 프로세스 및 단계:

문제와 해결책:
유형 정의가 동기화되지 않았습니다. 유형 체크섬 불일치를 감지하고, 문제를 조기에 감지하고, 유형 정보를 자동으로 동기화하고, 데이터를 자동으로 마이그레이션합니다.
게임과 긴밀하게 결합된 도구. 생성된 프록시 클래스를 과도하게 사용하지 말고, 가능하면 생성된 UI를 사용하고 다형성 프록시 클래스를 사용하십시오.

- 과도한 메모리 사용량. 유형에서 쓸모 없는 정보를 사용 기반으로 제거하여 사용되지 않는 반사 유형을 자동으로 감지합니다.
리플렉션의 다른 용도로는 다중 프로세서 아키텍처를 위한 이벤트 마샬링, 온라인 클라이언트-서버 원격 및 저장된 게임 데이터 직렬화 등이 있습니다.
아래 그림은 Ubisoft의 콘텐츠 프레임워크입니다.

신속한 도구 개발, 모든 유형의 콘텐츠에 대한 뛰어난 워크플로, 향상된 재사용성과 변경 탄력성을 갖춘 분리된 시스템을 통해 좋은 결과를 얻을 수 있습니다.
Just Cause 2: Lessons Learns의 자산 파이프라인은 Just Cause 2 게임에 사용된 자산 조절 파이프라인에 대한 개요를 제공합니다. 여기에는 파이프라인 요구 사항을 분석하고 주요 병목 현상을 제거하고 강력한 환경을 제공하며 처리량을 향상시킬 수 있는 시스템을 설계하는 프로세스가 포함됩니다. 파이프라인을 단순화할 수 있는 주요 기본 시스템을 식별하는 프로세스에 대해 설명합니다. 이러한 시스템 중에는 플랫폼 및 언어 독립적인 데이터 관리 계층, 자산 종속성 파서 및 Python을 사용하는 컴파일러 스크립팅 프레임워크가 있습니다. 또한 제어된 방식으로 새로운 컴파일러 배포를 처리하기 위한 시스템, 이 새로운 기반, 이점, 부작용, 유지 관리성, 견고성 및 향상된 피드백 수준을 기반으로 기존 컴파일러 파이프라인을 다시 구축하는 프로세스와 파이프라인 통계를 모니터링하는 기능에 대해서도 논의됩니다. Just Cause 1의 작업 흐름은 다음과 같습니다.

이 작업 흐름에는 몇 가지 심각한 결함이 있습니다. 첫째, JustEdit에는 수동 내보내기 단계가 너무 많으며, 설상가상으로 하나의 엔터티에 대한 변경 사항이 여러 위치나 임무에 영향을 미치므로 모든 자산을 다시 내보내야 하는 게임 지원 형식으로 내보냅니다.
Just Cause 2를 통해 콘텐츠 제작자는 많은 새로운 도구를 주문하고, 세부적인 디자인 문서를 작성했으며, 각 도구에 "클라이언트"가 할당되었고, 프로그래머는 고객과 긴밀한 커뮤니케이션을 유지했으며, 고객은 도구를 테스트하고 승인하는 책임을 맡았습니다. JustEdit 플러그인의 도구로서 WTL은 편집기/플러그인의 GUI에 사용되었습니다.

10가지 새로운 도구로 프로젝트가 시작됩니다! ! 코드가 있어야 할 부분에서 90%-100% 완전하지 않습니다. 워크플로의 결함, 모든 도구가 의도한 대로 작동하는 것은 아니며, 쉬운 편집은 성능 및 메모리 측면에서 게임에 적합하지 않습니다. 디자인 문서는 "있는 그대로" 받아들여지며, 이는 본질적으로 콘텐츠 제작자의 위시리스트입니다.
고객은 개발 팀의 일원이 아니며, 의사소통에 문제가 있고, 다른 작업에 풀타임으로 일할 계획을 세우는 경우가 많으며, 책임이 불분명합니다. 플러그인으로 인해 불안정한 C++ 인터페이스가 발생했으며 지나치게 복잡한 네트워크 통신과 함께 사용되어야 했습니다. 그래픽 사용자 인터페이스: WTL 및 C++, WTL은 너무 단순하고 C++는 반복 속도를 늦춥니다.
C++ 컴파일러, C++로 스크립트 작성이 항상 편리한 것은 아니며, 빌드 시간이 길고, 조정하기 불편하며, 일부 컴파일러에는 모든 게임 코드가 포함되어 있습니다. 특히 플랫폼에 따라 매우 다르며, DirectX가 포함된 Win32는 무겁고 데스크톱 없이는 자동화된 빌더에서 실행할 수 없습니다.
프로그래머는 사물을 약간 다르게 구현하여 전반적인 오작동, 종속성 검사 중단, 컴파일러에 하드 코딩된 매개변수 등을 초래했습니다. 파일 형식이 충분히 안정적이지 않으며 문제가 발생하면 컴파일러가 충돌할 수 있으며, 더 나쁜 경우 손상된 데이터가 게임에 들어갈 수 있습니다.
컴파일러 사용을 꺼려하고, 파이프라인이 약간 마술적인 것으로 간주되고, 문서가 부족하고, 전체 프로세스를 개요하기가 쉽지 않고, 손상된 데이터 디버깅이 종종 게임 코드에서 수행되고, 프로그래머가 모든 코드와 데이터를 설정했는데, 이로 인해 컴파일러에서 버그를 수정하는 대신 런타임 수정이 수행되는 경우도 있습니다.
중앙 코드가 없고 통합할 때 중앙 코드를 사용하지 않으면 문제가 발생하고 수정 사항이 손실되어 다시 찾아야 하며 내장 컴파일러는 Perforce에서 버전 관리되며 필요할 때 자동으로 다시 빌드 및 사용되지 않으며 오래된 버그 코드를 계속 사용할 수 있습니다.
데이터 형식 측면에서는 다양한 파일 유형(약 30개)이 있고, 많은 형식이 xml 기반이고, "속성 이름"을 "값"에 매핑하고, 형식이 게임보다 편집자에 더 최적화되어 있으며, 읽기/쓰기 오류가 감지되지 않고, 버전 번호가 없고, 올바른 오류 메시지를 기록하는 기능이 없으며, 개선할 사항이 많습니다.
콘텐츠 빌드 시스템은 다소 조잡한 솔루션이며 매우 느린 종속성 검사, 불완전한 종속성 트리, 타임스탬프가 충분하지 않습니다. 버그와 동작의 이상으로 인해 사용자는 100% 신뢰할 수 없으며 신뢰가 없다는 것은 완전히 깨끗하고 완전한 재구축을 의미합니다.
JC2의 문제를 해결하기 위해 완전히 새로운 목표가 제안되었습니다. 파이프라인의 신뢰 재구축, 점진적인 구축, 매직 워크플로우 없음, 구성 용이성, 종속성 검사 사용, 100% 정확도, 개발 단순화, 공통 코드를 중앙 저장소로 이동, 도구 생성 시 처리 시간 단축.
큰 결정, 코드를 위한 중앙 빌드/배포 시스템의 필요성, 콘텐츠 빌드 시스템에 큰 추진력이 필요함, 사용하기 쉽지만 강력한 공통 데이터 형식의 필요성, JC2를 사용하여 개발을 수행해야 했고, 어디든 빠르게 이동하려면 작업에 대한 헌신이 필요했습니다.
Python으로 내부적으로 작성되고 매우 가벼운 종속성 파서 및 배포 시스템이 필요하며 빌드된 라이브러리(.h + .lib/.so), 빌드된 실행 파일, 번들 Python 스크립트(또는 원하는 모든 것), 타사 라이브러리, 실행 파일 등 패키지 본문을 처리합니다. 패키지를 중앙 저장소에 배포하고 패키지를 로컬 시스템으로 가져옵니다.
코딩 프로세스의 큰 변화, 코드 기반이 더 작은 라이브러리로 발전하고 컴파일 시간이 매우 빨라졌으며 버전 충돌을 추적하는 데 도움이 되고 매우 빠른 개발 및 테스트가 가능해졌습니다.
코드 및 데이터를 위한 경량 빌드 시스템, 오픈 소스(BSD), 소스 코드 ~80kb, 종속성 검사, 멀티 코어 지원, 유지 관리 및 확장 용이, Python으로 코딩된 내부 프로젝트 컴파일러 시스템을 대체합니다.
Avalanche 데이터 형식, 직렬화 프레임워크: C/C++, Python 지원, Xml <-> 바이너리 지원, 바이너리의 해시 기반 버전 관리, 오류 처리, Python 및 C/C++에서 데이터에 액세스하는 기능은 도구에서 콘솔로/에서 데이터를 전달하는 것과 같은 원활한 교차 언어 교환, 교차 플랫폼 지원을 가능하게 합니다.
ADF와 Python을 사용하면 데이터를 매우 쉽게 읽고 쓸 수 있으며 유형 라이브러리를 읽은 다음 xml 형식에서 소스 파일을 로드할 수 있습니다. 다음으로 첫 번째 개체의 이름을 변경하고 마지막으로 모든 것을 이진 형식(빅 엔디안)으로 다시 작성합니다. 다음 그림은 파일이 서로 어떻게 관련되어 있는지 보여주는 다이어그램입니다.

C++는 Python에서 로드된 공유 라이브러리에 사용되며, 이전 게임 코드에 대한 종속성을 제거하고, 내부 코드를 표준 코드인 CFile() 대신 fopen()으로 대체하여 복잡성을 줄이고 이식성을 높입니다. 스크립트와 로직에는 Python을 사용하고, 데이터 처리에는 Python이나 C++를 사용합니다. 예를 들어 C++는 Havok 파일을 읽고 쓰고 처리하는 데 사용됩니다.
Python은 극단적인 처리 시간, 종종 optparse, ctypes, md5, numpy, cStringIO를 사용하는 다수의 내장 모듈에 사용됩니다. 많은 모듈에 백엔드가 C++로 구현되어 있고 대부분의 컴파일러가 완전히 재작성되어 많은 종속성이 줄어들었으며 코드 크기가 1/10로 줄었습니다.
종속성 검사 측면에서 Waf 처리 메커니즘이 사용되며 스캐너는 종속성, Waf 캐시 결과, MD5 체크섬 명령줄 매개변수, 소스/종속성 파일 콘텐츠를 찾고 새 컴파일러 경로가 컴파일을 트리거합니다. Needy를 사용하여 소프트웨어 패키지를 업데이트할 때 매우 편리합니다.
증분 자동 생성기, 버전 제어에서 동기화, 필요한 것만 빌드, 완전 자동 생성기, 증분 빌드와 전체 빌드 비교, 종속성 문제 찾기, 데이터 형식의 오류 찾기.
2011년 Mortal Kombat의 멀티코어 메모리 관리 기술은 Mortal Kombat 게임에 사용된 멀티코어 메모리 관리 기술을 공유했습니다.
"MK vs DC"는 주로 두 가지 메모리 관리자, 즉 Unreal Memory Manager(FMalloc), 엔진 측 리소스, C/C++ 기반 메모리 관리를 사용합니다. 콘솔용 "게임" 메모리 관리자, 게임 측 리소스입니다.
Unreal 메모리 관리자의 제한 사항은 LibC++ 기능 세트이며 다중 힙을 지원하지 않으며 기본적으로 스레드 안전/멀티 코어가 아니며 스레드 안전하지 않은 메모리 할당자는 "전역 잠금"으로 보호되며 "MK 대 DC"는 내부적으로 DLMalloc을 사용하고 특정 작업은 긴 일시 중지를 유발할 수 있습니다.
게임 메모리 관리자의 제한 사항은 스레드로부터 안전하지 않고 "가상 메모리 인식"이 아니며 정적 고정 폴백만 지원하고 O(N) 작업이 매우 느리며 조각화(.
전역 잠금은 좋은 생각이 아닙니다. 멀티 코어 최적화가 없으면 모든 작업으로 인해 다른 스레드에서 사소한 지연이나 컨텍스트 전환이 발생할 수 있습니다. 대규모 애플리케이션 할당 요청, 힙 지원 저장소 할당, 재할당 작업 등 일부 작업으로 인해 시스템 전체가 중단될 수 있습니다.
아래 그림은 전역 잠금 재할당을 보여줍니다. 스레드 1의 재할당은 메모리 블록을 잠그고 스레드 2는 스레드 1이 메모리 할당을 완료할 때까지 기다리게 한 후 잠그고 메모리 작업을 수행합니다.

잘 세분화된 잠금 재할당으로 대기 시간을 줄일 수 있습니다.

비차단 재할당:

가상 메모리는 메모리 조각화를 해결합니다.

멀티 코어에서의 메모리 작업은 기본적으로 스레드로부터 안전하며 가능한 한 잠금이 없고 직접적이며 필요한 경우 비배타적 잠금(예: 판독기 및 기록기), 세분화된 잠금 및 스트라이프 잠금과 같은 비차단 잠금이 선호됩니다. 또한 단일 스레드의 고성능을 고려할 수 있으며, 경쟁이 없는 액세스로 인해 명백한 성능 저하가 발생하지 않습니다.
스레드 안전 및 멀티 코어에 최적화된 새로운 메모리 관리자, 게임 및 Unreal Engine을 위한 통합된 별도 메모리 관리자, 추가 기능이 있는 다중 힙 지원, 향상된 성능(CPU 주기 및 메모리 사용 효율성), 범용 추적 및 디버깅 유틸리티.
동시 힙에는 최소한의 스레드 "누화"가 있고, 여러 스레드가 단일 힙에서 동시에 할당/해제할 수 있으며(힙 유형이 지원하는 경우 대부분의 힙 유형이 지원함), 백업 스토리지 및 내부 힙 쿼리 작업은 종종 동시에 실행되며(무잠금, 스트라이핑 또는 리더-라이터 잠금 사용) Realloc()은 복사가 진행되는 동안 차단되지 않습니다. 단순화된 메모리 관리 아키텍처는 다음과 같습니다.

힙을 구현할 때 Heap API는 가상 함수, Backstore 및 OS Allocs에 대한 공통 지원 API, Global Free()를 사용하여 반환된 힙 메모리를 "인식"합니다. 다양한 힙 구현, 직접 OS 힙, 최적의 힙(레드-블랙 트리 사용), 작은 블록 힙(잠금 없는 할당/스트라이핑 없음), 고정 블록 힙(잠금 없는 - MK 게임 개체용)을 쉽게 만들 수 있습니다.
기본 힙이 할당에 혼합 접근 방식을 사용하는 혼합 기본 힙을 사용할 수 있습니다. 대규모 할당은 조각화를 최소화하기 위해 운영 체제를 직접 통과하고(그러나 내부적으로 추적됨) 중간 할당은 가장 적합한 힙으로 이동하며 작은 할당은 자체 힙에서 처리됩니다. C++ new/delete 및 C malloc/free 호출은 기본(혼합) 힙으로 라우팅됩니다.

UE의 메모리 관리는 이러한 혼합된 메인 힙 방법을 사용합니다. 자세한 내용은 1.4.3 메모리 할당을 참조하세요.
아래 그림을 보면 작은 힙이 약 23%, 중간 힙이 약 52%, 큰 힙이 약 25%를 차지하는 것을 알 수 있습니다. 할당 횟수를 보면 작은 힙이 약 96.7%, 중간 힙이 약 3.2%, 큰 힙이 약 0.26%를 차지한다. 횟수로 보면 작은 힙이 대다수를 차지하는 것을 볼 수 있습니다. 작은 힙 할당 및 기타 작업을 관리하는 것이 중요합니다! ! **

다음 그림은 다양한 크기의 힙 할당 수를 보여줍니다. 기본적으로 힙이 작을수록 더 많은 횟수가 할당됩니다.

SBMM = 매우 낮은 스레드 경합, 많은 동시 작업 지원, 빈 할당자(크기 빈, 잠금 스트라이핑 = 빈당 잠금), (주로) 잠금 없는 Alloc(), 잠금 없는 할당된 희생 블록을 사용하는 참조 캐시, 빠른 스트라이프 잠금 릴리스 기능을 갖춘 소형 블록 메모리 관리자입니다. SBMM의 포장과정은 다음과 같습니다.

SBMM의 메모리 레이아웃은 다음과 같습니다.

SBMM은 주로 잠금 없는 할당입니다. LockFree freelist는 "victim" 블록의 항목을 캐시합니다. 비어 있을 때 Bin 스트립 잠금 장치를 획득하고 무료 항목이 포함된 다음 블록에서 새로운 무료 목록을 구축하는 것은 모든 블록이 소진될 때까지 매우 빠른 작업입니다. 이 드문 경우에는 슈퍼 블록에서 새 블록을 가져와야 하며 이러한 항목에 대해 사용 가능한 목록이 초기화됩니다. 모든 SuperBlock이 소진되면 OS에서 새 SuperBlock을 요청합니다.
SBMM의 릴리스는 잠금이 없었지만 지연된 GC가 필요합니다. 스트라이프 잠금 == 쉬운 정리(지연된 GC 없음), 블록 및 저장소 크기 찾기, 빠른 잠금 상자, 메모리 항목 푸시 및 검사 카운트, 정리가 필요한 경우 풀 블록, 잠금 해제, 그렇지 않은 경우 잠금 해제, 경합 없는 케이스는 잠금 없는 속도와 매우 유사하며 스트라이프는 이전과 마찬가지로 콘텐츠가 없습니다.
잠금 없는 NR-Pool은 MK 메모리 시스템에 사용되는 간단한 제어 구조입니다.

Mega Meshes - 1000억 개의 다각형으로 구성된 세계 모델링, 렌더링 및 조명은 모델 및 파이프라인, 구성, 압축 및 스트리밍, 가상 텍스처, 실시간 GI 등의 측면에서 Milo 및 Kate 게임(아래 그림)을 개발하는 데 사용된 엔진의 콘텐츠를 공유했습니다.

기존 환경 모델 파이프라인과 달리 이 기사의 엔진은 대규모 메시 도구를 사용하여 수십억 개의 다각형이 있는 모델을 관리하고, 여러 사용자를 지원하고, DCC 도구, VC 및 조각 도구를 결합하고, 창을 다양한 세부 수준에서 편집하여 구성 프로세스를 조정할 수 있습니다.

이렇게 큰 데이터 세트를 물리적 메모리에 저장하는 것은 비현실적입니다. 기하학적 데이터는 계층적으로 저장되고, 연속적으로 세분화된 레벨은 차등 데이터와 함께 저장되며, 레벨은 요청 시 로드됩니다. 프로세스는 아래 일련의 그림을 참조하십시오.





계층적 저장의 이점은 세계의 영역을 낮은 세분화 수준에서 편집하고 높은 빈도의 세부 정보를 유지할 수 있으며, 모든 세부 사항을 잃지 않고 지형의 거시적 지형을 변경할 수 있으며, 하위 세분화 수준을 간단히 수정하여 대규모 톤 조정을 수행할 수 있다는 것입니다. 다중 편집 레벨의 격차를 해결하려면 런타임 메시를 생성하는 추가 단계가 필요합니다.

Sparse Virtual Texture의 출현은 우수한 스트리밍/렌더링 시스템이 필요한 높은 메모리 사용량과 많은 글로벌 채널 문제를 해결하기 위한 것입니다. 가상 텍스처를 사용하여 텍스처 공간을 가상화할 수 있습니다. 다음 그림은 Milo와 Kate의 초기 가상 텍스처 아틀라스, 타일로 분할된 대형 텍스처와 밉맵, 가상 텍스처의 물리적 메모리 로딩 프로세스입니다.



가상 텍스처 세부 정보: 배열의 여러 가상 텍스처, 16 32k 32k 주소 공간, 128 x 128 타일, 8:8비트 UV 타일 주소, 일부 캐릭터/소품에 대한 가상 텍스처, 나머지는 세계의 여러 영역으로 나누어지고, 사용되지 않은 바인딩은 레벨 경계에서 풀릴 수 있어 세계의 지속적인 스트리밍이 가능합니다. 2048 x 4096(28mb) 물리적 페이지입니다.
아래 그림은 거대한 텍스처를 컴파일하는 순서도를 보여줍니다.

렌더링 시 렌더링 스레드, 텍스처 캐시 스레드, GPU 스레드의 상호 작용 다이어그램은 다음과 같습니다.

또한, SH 기반 GI를 구현하는 엔진의 흐름도는 다음과 같습니다.

다각형 수프의 게임 세계: 가시성, 공간 연결 및 렌더링은 가시성, 공간 연결 및 렌더링 측면에서 Halo 시리즈 게임의 가상 세계에서 다각형 수프(구성되지 않은 다각형 그룹)의 기술 내용을 설명합니다.
가상 환경 측면에서 Halo는 셀 및 포털, 방수 쉘 기하학, 아티스트가 수동으로 포털 배치, 쉘 기하학에서 BSP 트리 구축, 셀에 Floodfill BSP 및 셀 연결 설정과 같은 기술을 적용합니다. 이러한 기술 선택의 장점은 통일된 가시성/공간 연결, 정확한 공간 분해, 내부/외부 테스트이며, 자연적인 포털이 있는 내부 공간에 이상적입니다. 단점은 수동포털화가 쉽지 않다는 점! , 수밀성은 콘텐츠 제작에 고통스럽고 초기 디자인 결정을 강요하며 실내 장면에만 최적화됩니다.
다음은 포털화 및 폴리곤 그룹의 범례입니다.


다각형 수프는 단지 몇 개의 다각형 블록을 결합한 것일 뿐이고, 비방수 구조이며, 수동 포털이 없으며, 증분 빌드/빠른 반복이 가능하므로 늦은 설계 변경이 가능합니다. 장면 세분화, 세분화된 볼륨 복셀화, 복셀을 영역으로 분할, 영역 간 연결 그래프 구축, 복셀 영역에서 단순화된 볼륨 구축 등에 사용할 수 있습니다. 아래 그림은 2D 길찾기 적용 사례입니다.

왼쪽에서 오른쪽으로, 위에서 아래로: 입력 장면, 복셀화, 보행 가능한 복셀, 거리 필드, 유역 변환 및 윤곽선입니다.

최종 생성된 탐색 메시입니다.
위 그림은 2D 공간에 있습니다. 실제로 3D 공간에는 3D가 더 어렵고 느리고, 과분할(작은 영역), 장면 변화에 대한 민감도, 단순화된 표현이 쉽지 않음, 가시성 표현 방법 등 많은 문제가 있습니다.
솔루션은 Umbra, 자동 생성 포털, 증분/로컬 업데이트, CPU 기반 솔루션, 낮은 대기 시간, 동일한 가시성 및 공간 연결 솔루션, 문 및 엘리베이터 처리, 사용자 주위에 정확하게 배치된 포털, 빠른 런타임/낮은 메모리 공간과 함께 작동하는 것입니다. Umbra 솔루션의 프로세스는 다음과 같습니다.

전체 프로세스는 장면을 복셀로 분할하고, 입력 형상을 기준으로 복셀 연결성을 결정하고, 연결된 구성 요소를 찾기 위해 연결을 전파하고, 로컬로 연결된 구성 요소 간의 포털을 결정하는 등의 단계로 나뉩니다.

타일 복셀화 과정.

복셀을 셀과 포털로 변환합니다.

셀과 포털을 구축하세요.
Halo Reach 게임 루프의 기능은 다음과 같습니다.
대략적인 병렬성.
스레드 기반 시스템.
상태 미러링을 통한 명시적 동기화.
주로 수동 로드 밸런싱을 수행합니다.

Halo Reach의 세분화된 병렬 처리.
이 병렬 시스템에서는 시뮬레이션 스레드가 다음 프레임을 자유롭게 처리하고 렌더링 스레드가 현재 프레임을 GPU에 제출할 수 있도록 프레임 끝에서 전체 게임 상태(Halo Reach의 경우 ~20MB)를 미러링(복사)해야 합니다. 게임 상태를 미러링하는 이유 중 하나는 게임 상태를 복사한 후 가시성을 계산하기 위한 것입니다. 20MB의 게임 상태를 복사하는 연속 작업은 시간이 많이 걸리며(~3ms) 전체 게임 상태에 대한 이중 버퍼링이 필요합니다. 여기서 게임 상태는 결정론적 게임 상태 데이터만 참조한다는 점에 유의하세요.

Halo Reach의 병렬 시스템에서는 프레임 끝에서 전체 게임 상태를 복사해야 합니다.
다음 그림은 다양한 스레드의 일반적인 활용을 보여줍니다.

이 문제점을 개선할 수 있는 방법이 있나요?
관찰 #1: Halo Reach에서는 렌더링하는 데 전체 게임 상태가 필요하지 않습니다. Reach에서는 가시성 계산이 완료되기 전에 게임 상태 가져오기가 발생하므로 전체 게임 상태를 복사해야 하며 비용이 많이 듭니다(밀리초 및 메모리 공간 단위). 가시성은 렌더링 스레드에서 많은 CPU 시간을 차지하지만 CPU 시간과 하드웨어 스레드는 충분히 활용되지 않습니다. 그러나 실제로는 해당 작업을 반대로 수행하여 게임 상태에서 보이는 개체의 데이터만 복사하고 렌더링할 개체의 데이터만 추출할 수 있습니다.
더 나은 접근 방식은 가시성 결과를 기반으로 게임 가져오기 및 처리를 추진하고, 전체 게임 상태를 이중 버퍼링하지 않고 보이는 객체에 대한 데이터(정적 및 동적)만 가져오고, 더 작은 메모리 공간을 사용하여 보이는 객체의 프레임별 과도 현상에 대해서만 게임 데이터를 버퍼링하는 것입니다.
더 나은 로드 밸런싱 방법: 먼저 가시성 계산을 플레이어, 그림자 및 반사 뷰에 대한 가시성 계산을 포함하여 각 뷰에 대한 작업으로 분할합니다. 가시성 작업은 뷰포트 간 종속성을 가질 수 있으며, 하나의 가시성 작업 계산 결과를 다른 작업의 입력으로 재사용할 수 있습니다.
입력 지연을 줄이는 방법: 게임 객체가 업데이트되는 동안 가시성 계산을 시차를 두고, 예측 카메라를 사용하여 프레임 초기에 정적 가시성을 시작하고, 객체가 업데이트되기 전에 실행합니다.
향상된 CPU 대기 시간: 보이는 개체에 대해서만 비용이 많이 드는 CPU 렌더링 작업을 실행하고, 표시된 후에 실행해야 합니다. 렌더링 작업(스키닝, 천 시뮬레이션, 다각형 정렬)만 게임 플레이에 영향을 주지 않습니다. 게임 루프 및 병렬 모드를 개선한 후의 실행 상황은 다음과 같습니다.

게임 상태 탐색이 드로잉과 분리되고, 인터리브된 가시성 계산을 통해 CPU 활용도가 향상되며, 렌더링 스레드가 간소화된 코어 프로세서가 된다는 이점이 있습니다. 아래 그림은 간단한 작은 작업 트리입니다.

Culling the Battlefield: Data Oriented Design in Practice에서는 Battlefield 3에서 사용된 데이터 중심 디자인과 사례를 공유합니다.
이전의 자르기 및 컬링 방법에는 계층적 구형 트리, 정적 컬링 트리, 동적 컬링 트리 등이 포함되었습니다.

그러나 Battlefield 3에서는 동적 컬링 트리 스케일링, 하위 레벨, 파이프라인 종속성, 확장의 어려움, 뷰당 하나의 작업 프러스텀 등으로 인해 여전히 이를 재구성할 계획입니다.

새로운 시스템의 요구 사항은 더 나은 확장성, 파괴성, 실시간 편집, 더 간단한 코드, 하위 시스템 통합 등입니다.
이러한 시스템에서 잘 작동하지 않는 기술로는 비로컬 데이터, 분기, 레지스터 유형 간 전환(LHS), 종종 분기가 많은 트리 기반 구조, 가장 중요한 데이터 처리 등이 있습니다. 이러한 시스템에서 잘 작동할 수 있는 기술은 지역화된 데이터, (SIMD) 컴퓨팅 성능 및 병렬성입니다.
게임 장면의 막대한 수(최대 약 15,000개)의 개체를 처리하기 위해 새로운 자르기 컬링의 첫 번째 시도는 병렬 무차별 대입만을 사용하는 것입니다. 이는 기존 컬링보다 3배 빠르고 코드 크기는 1/5이며 추가 최적화가 더 쉽습니다. 선형 배열은 규모가 크고 예측 가능한 데이터가 있으며 분기 수가 적고 컴퓨팅 성능을 최대한 활용하여 5배의 속도 향상을 달성할 수 있습니다.

새로운 클리핑 컬링은 구가 있는 "셀"에 할당된 AABB인 간단한 메시와 정적 렌더링, 동적 렌더링, 정적 물리학 및 동적 물리학을 위한 별도의 메시를 사용하여 성능을 향상시킵니다. 데이터 레이아웃은 다음과 같습니다.

객체를 추가할 때 데이터를 얻을 수 있는 사전 할당된 배열:

개체를 삭제할 때 "스왑 트릭"을 사용하면 데이터를 정렬할 필요가 없으며 마지막 항목과 교체하고 개수를 줄이면 됩니다.
클리핑을 렌더링할 때 먼저 렌더링된 데이터를 살펴보세요.
struct EntityRenderCullInfo
{
Handle entity; // handle to the entity
u16 visibleViews; // bits of which frustums that was visible
u16 classId; // type of mesh
float screenArea; // at which screen area entity should be culled
};클리핑 노드 코드는 다음과 같습니다:
while (1)
{
uint blockIter = interlockedIncrement(currentBlockIndex) - 1;
if (blockIter >= blockCount) break;
u32 masks[EntityGridCell::Block::MaxCount] = {}, frustumMask = 1;
block = gridCell->blocks[blockIter];
foreach (frustum in frustums, frustumMask <<= 1)
{
for (i = 0; i < gridCell->blockCounts[blockIter]; ++i)
{
u32 inside = intersect(frustum, block->postition[i]);
masks[i] |= frustumMask & inside;
}
}
for (i = 0; i < gridCell->blockCounts[blockIter]; ++i)
{
// filter list here (if masks[i] is zero it should be skipped)
// ...
}
}교차점 감지 코드는 다음과 같습니다.
bool intersect(const Plane* frustumPlanes, Vec4 pos)
{
float radius = pos.w;
if (distance(frustumPlanes[Frustum::Far], pos) > radius)
return false;
if (distance(frustumPlanes[Frustum::Near], pos) > radius)
return false;
if (distance(frustumPlanes[Frustum::Right], pos) > radius)
return false;
if (distance(frustumPlanes[Frustum::Left], pos) > radius)
return false;
if (distance(frustumPlanes[Frustum::Upper], pos) > radius)
return false;
if (distance(frustumPlanes[Frustum::Lower], pos) > radius)
return false;
return true;
}위의 코드에는 로컬이 아닌 데이터 및 부동 소수점 분기와 같은 많은 문제가 있습니다.

개선하는 방법은 무엇입니까? 내적은 SIMD에 그다지 친숙하지 않습니다. 일반적으로 결과를 얻기 위해 데이터를 무작위로 섞고(x0 x1 + y0 y1 + z0 z1 + w0 w1) 데이터를 AoS(구조체 배열, 구조 배열)에서 SoA(배열 구조, 배열 구조)로 재배열해야 합니다.

이제4개의 점을 완성하려면 3개의 지침만 필요합니다!

새로운 교차 테스트 코드에서 각 루프는 두 개의 프러스텀를 구, 4*3 내적, 9개의 명령어와 교차하고 모든 뷰 프러스텀를 순회하고 결과를 병합합니다.
Vec posA_xxxx = vecShuffle<VecMask::_xxxx>(posA);
Vec posA_yyyy = vecShuffle<VecMask::_yyyy>(posA);
Vec posA_zzzz = vecShuffle<VecMask::_zzzz>(posA);
Vec posA_rrrr = vecShuffle<VecMask::_wwww>(posA);
// 4 dot products
dotA_0123 = vecMulAdd(posA_zzzz, pl_z0z1z2z3, pl_w0w1w2w3);
dotA_0123 = vecMulAdd(posA_yyyy, pl_y0y1y2y3, dotA_0123);
dotA_0123 = vecMulAdd(posA_xxxx, pl_x0x1x2x3, dotA_0123);
Vec posAB_xxxx = vecInsert<VecMask::_0011>(posA_xxxx, posB_xxxx);
Vec posAB_yyyy = vecInsert<VecMask::_0011>(posA_yyyy, posB_yyyy);
Vec posAB_zzzz = vecInsert<VecMask::_0011>(posA_zzzz, posB_zzzz);
Vec posAB_rrrr = vecInsert<VecMask::_0011>(posA_rrrr, posB_rrrr);
// 4 dot products
dotA45B45 = vecMulAdd(posAB_zzzz, pl_z4z5z4z5, pl_w4w5w4w5);
dotA45B45 = vecMulAdd(posAB_yyyy, pl_y4y5y4y5, dotA45B45);
dotA45B45 = vecMulAdd(posAB_xxxx, pl_x4x5x4x5, dotA45B45);
// Compare against radius
dotA_0123 = vecCmpGTMask(dotA_0123, posA_rrrr);
dotB_0123 = vecCmpGTMask(dotB_0123, posB_rrrr);
dotA45B45 = vecCmpGTMask(dotA45B45, posAB_rrrr);
Vec dotA45 = vecInsert<VecMask::_0011>(dotA45B45, zero);
Vec dotB45 = vecInsert<VecMask::_0011>(zero, dotA45B45);
// collect the results
Vec resA = vecOrx(dotA_0123);
Vec resB = vecOrx(dotB_0123);
resA = vecOr(resA, vecOrx(dotA45));
resB = vecOr(resB, vecOrx(dotB45));
// resA = inside or outside of frustum for point A, resB for point B
Vec rA = vecNotMask(resA);
Vec rB = vecNotMask(resB);
masksCurrent[0] |= frustumMask & rA;
masksCurrent[1] |= frustumMask & rB;추가 컬링에는 프러스텀와 AABB, AABB를 화면 공간에 투영하는 것, 소프트웨어 폐색이 포함됩니다. AABB를 화면 공간에 투영할 때 화면 공간에서 AABB의 면적을 계산합니다. 설정한 영역보다 영역이 작을 경우 FOV 거리가 작동하지 않으므로 건너뜁니다.
Software Occlusion은 Frostbite에서 3년 동안 여러 플랫폼에서 주로 지형용으로 아티스트가 제작한 차단기로 사용할 수 있었습니다. 소프트웨어 오클루전을 사용하는 이유는 다음과 같습니다. GPU뿐만 아니라 CPU 시간도 제거하고 싶고, 조기에 컬링하고 싶고, GPU 쿼리는 CPU보다 뒤처지기 때문에 까다롭고, 아티스트가 쉽게 제어할 수 있는 파괴 시스템을 지원해야 합니다. 이는 소프트웨어 렌더링을 사용하여 PS1 스타일 기하학을 Z 버퍼로 렌더링함으로써 수행됩니다. 여기서 Z 버퍼는 256x114 부동 소수점입니다. 구체적인 단계에는 폐색 삼각형 설정, 지형 삼각형 설정, 래스터라이제이션 삼각형 및 컬링이 포함됩니다.

상단: 장면 폐색; 아래쪽: 폐색을 래스터라이제이션한 결과입니다.
평행 자르기 작업의 예는 다음과 같습니다.

다음은 폐색 볼륨 삼각형을 병렬로 설정하는 예입니다.


Z 버퍼 테스트 프로세스는 객체의 화면 공간 AABB를 계산하고 단일 거리 값을 얻은 다음 Z 버퍼에 따라 사각형을 테스트하는 것입니다.

요약하자면, 정확하고 성능이 뛰어난 컬링은 낮은 수준의 시스템/렌더링에 대한 스트레스를 줄이는 데 중요합니다. 모든 것은 데이터에 관한 것이며, 단순 데이터는 일반적으로 대상 하드웨어의 기능, 아키텍처 및 매개변수에 대한 완전한 지식을 갖춘 간단한 코드를 의미합니다.
Firaxis LORE 그리고 D3D11의 다른 용도는 D3D11을 사용하여 멀티스레드 렌더링을 위한 아키텍처 변환 및 최적화 기술을 달성하는 시리즈 게임 Civilization V의 엔진입니다.

문명 5 게임 스크린샷.
초기 목표는 그래픽 엔진이 D3D11 Alpha를 사용하여 엔진의 기본 D3D11 아키텍처를 구축하고 DX9와 이전 버전과 호환되도록 "시간의 시험을 견디는" 것입니다.
1단계: 간접비를 줄입니다. 셰이더는 CPP 및 헤더 파일로 컴파일된 FSL(Firaxis Shading Language)의 HLSL 상위 집합으로 시작합니다. 모든 셰이더 상수는 구조에 매핑되고 패키지로 그룹화됩니다. 모든 패키지에는 동일한 바인딩이 있습니다. 모델 코드는 템플릿화됩니다. FSL에서 생성된 헤더 파일은 템플릿 코드에 번들로 제공됩니다. 결과적으로 성능 분석에 거의 영향을 주지 않고 필요한 음영을 채우는 소량의 코드가 생성됩니다.
2단계: 추상 렌더링. DX9는 여전히 지원되어야 하고, 호스트는 향후 지원이 필요할 수 있으며, "드라이버"를 작성해야 할 수도 있습니다. 해결책은 DX9를 DX11처럼 보이게 만드는 것입니다.
렌더링 캡슐화 계층의 특징: 상태 비저장 렌더링, D3D보다 훨씬 간단합니다. 명령 세트에는 렌더링할 표면 목록이 포함될 수 있으며, 각 표면에는 셰이더 상수 로드가 있습니다. 표면은 IB, VB, 텍스처, 셰이더 정의 등으로 구성된 불변 번들(번들)이며 명령은 이러한 상태 번들 중 하나를 참조합니다. 전체 프레임이 대기열에 추가되어 프레임당 할당이 최소화됩니다. 명령은 5개뿐입니다.
COMMAND_RENDER_BATCHE
COMMAND_GENERATE_MIPS
COMMAND_RESOLVE_RENDERTEXTURE
COMMAND_COPY_RENDERTEXTURE
COMMAND_COPY_RESOURCE

렌더링 캡슐화 계층 아키텍처 다이어그램.

작업 기반 멀티스레드 병렬 시스템.
전체 프레임을 대기열에 넣어야 하는 이유는 무엇입니까? 추가 오버헤드처럼 보이지만 성능 분석에 따르면 순 이득이고, 내부 명령 설정이 매우 저렴하고, 일부 메모리 복사본만 있고, 엔진 캐시 일관성이 훨씬 더 좋고, 대규모 덤프에서 D3D 드라이버 캐시 일관성이 훨씬 더 좋으며, 커밋 시간이 총 CPU 시간의 백분율로 매우 낮고, 중복 D3D 호출을 필터링할 수 있으며, DX9에서도 빠릅니다.
구현 장점: "상태 비저장" 개념을 이해하면 코드 유지 관리가 쉬워집니다. 렌더링이 그룹화되어 있고, 각 작업 간의 통신이 거의 또는 전혀 없고, 스레딩 오류가 없기 때문에 상태 누출(깜빡이는 알파, 텍스처 등)이 거의 없습니다.
스레드 D3D11 명령 제출 관련 문제: 일괄 제출을 위한 드라이버 오버헤드는 일반적으로 높습니다. 그러나 D3D11의 다중 스레드 제출 명령 스트림이 반드시 CommandList 1:1에 매핑되는 것은 아닙니다. Civilization 5는 구성 파일을 설정하여 제출 방법을 변경할 수 있습니다.

스레드 D3D11 명령 제출.
요약하면, 애플리케이션 오버헤드의 신중한 감소, 작업 기반, 페이로드 기반 렌더링, 중복 상태 및 호출 필터링, D3D11 명령 목록 사용을 통해 높은 처리량 렌더링이 가능합니다. 엔진은 97%의 시간 동안 12개 스레드(드라이버 없이)를 완전히 활용할 수 있습니다.
Battlefield 3의 DirectX 11 렌더링에서는 2011 Frostbite 2 엔진이 DirectX 11의 기능을 사용하여 디퍼드 렌더링, 타일 렌더링, 입체 3D 렌더링, 다양한 앤티앨리어싱 및 성능 분석 등을 포함한 많은 렌더링 기능을 엔진에 구현한다는 점을 공유합니다.
당시 Frostbite 2가 직면한 렌더링 선택은 디퍼드 렌더링으로 전환, BF3의 풍부한 실외 + 실내 + 도시 환경 조합, 더 많은 광원을 원한다는 것이었습니다. 포워드 렌더링을 사용하지 않는 이유는 무엇입니까? 라이트 컬링/셰이더 배열은 비효율적이고 비용이 많이 들고 데칼/마스킹 해제가 더 어렵습니다. 라이트 프리패스를 사용하지 않는 이유는 무엇입니까? CPU 및 GPU의 2x 지오메트리 패스는 오버헤드가 너무 높기 때문에 BRDF를 몇 가지 변형으로 일반화할 수 있으면 타일 기반 디퍼드 렌더링에 대한 엄청난 잠재력을 볼 수 있습니다.
전통적인 디퍼드 라이팅/섀도잉의 단점은 큰 라이트가 많을 때 막대한 오버드로와 ROP 비용이 들고, 라이팅 셰이더에 픽셀당 머티리얼이 여럿 있으면 비용이 많이 들고, MSAA 라이팅이 느릴 수 있다는 것(고르지 않고 BW가 추가됨)입니다.
Frostbite 2의 솔루션은 타일 기반 디퍼드 렌더링을 사용하는 것입니다.
- 화면을 타일로 나누고 어떤 조명이 어떤 타일에 영향을 미치는지 결정합니다.

- 가시광선 소스만 픽셀에 적용합니다. 다중 조명을 갖춘 맞춤형 셰이더로 대역폭과 설정 비용이 절감됩니다.
주로 그림자가 없는 분석 조명(포인트 조명, 스포트라이트, 선형 조명)에 대해 컴퓨팅 셰이더를 사용하는 타일 기반 디퍼드 렌더링에는 컴퓨팅 셰이더 5.0이 필요합니다. 하이브리드 그래픽/계산 셰이딩 파이프라인을 사용할 수 있습니다. 그래픽 파이프라인은 불투명 표면에 대해 GB 버퍼를 래스터라이제이션하고, 계산 파이프라인은 GB 버퍼를 사용하고 조명을 선별하고 조명을 계산하여 이를 셰이딩과 결합하며 그래픽 파이프라인은 투명한 표면을 맨 위에 렌더링합니다.
셰이더 계산의 첫 번째 단계는 입력 및 출력 데이터를 설정하는 것입니다. 관련 코드는 다음과 같습니다.
// 입력:gbuffers、뎁스 버퍼(Depth Buffer) 및 리스트
Texture2D<float4> gbufferTexture0 : register(t0);
Texture2D<float4> gbufferTexture1 : register(t1);
Texture2D<float4> gbufferTexture2 : register(t2);
Texture2D<float4> depthTexture : register(t3);
// 출력: 및 포인트 의 HDR 텍스처(Texture)
RWTexture2D<float4> outputTexture : register(u0);
// 픽셀(Pixel)1개 스레드(Thread),16x16스레드 그룹(Thread Group)
#define BLOCK_SIZE 16
[numthreads(BLOCK_SIZE,BLOCK_SIZE,1)]
void csMain(
uint3 groupId : SV_GroupID,
uint3 groupThreadId : SV_GroupThreadID,
uint groupIndex : SV_GroupIndex,
uint3 dispatchThreadId : SV_DispatchThreadID)
{
(...)
}두 번째 단계는 gbuffer 및 깊이를 로드하고, 스레드 그룹/타일에서 최소 및 최대 z를 계산하고, 그룹 공유 변수에서 InterlockedMin/Max를 사용하고, 원자는 정수로만 작동하고, float를 int로 변환할 수 있습니다(z는 항상 +입니다).
groupshared uint minDepthInt;
groupshared uint maxDepthInt;
// --- globals above, function below -------
float depth =
depthTexture.Load(uint3(texCoord, 0)).r;
uint depthInt = asuint(depth);
minDepthInt = 0xFFFFFFFF;
maxDepthInt = 0;
GroupMemoryBarrierWithGroupSync();
InterlockedMin(minDepthInt, depthInt);
InterlockedMax(maxDepthInt, depthInt);
GroupMemoryBarrierWithGroupSync();
float minGroupDepth = asfloat(minDepthInt);
float maxGroupDepth = asfloat(maxDepthInt);
세 번째 단계는 잘라내기, 각 타일의 가시광원 결정, 프러스텀에 대한 모든 광원 제거, 전역광 목록, 프러스텀 및 SW 폐색 제거 입력, 가시광원 및 가시광원 색인 목록 출력입니다.
struct Light
{
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
};
int lightCount;
StructuredBuffer<Light> lights;
groupshared uint visibleLightCount = 0;
groupshared uint visibleLightIndices[1024];
// --- globals above, cont. function below ---
uint threadCount = BLOCK_SIZE*BLOCK_SIZE;
uint passCount = (lightCount+threadCount-1) / threadCount;
for (uint passIt = 0; passIt < passCount; ++passIt)
{
uint lightIndex = passIt*threadCount + groupIndex;
// prevent overrun by clamping to a last ”null” light
lightIndex = min(lightIndex, lightCount);
if (intersects(lights[lightIndex], tile))
{
uint offset;
InterlockedAdd(visibleLightCount, 1, offset);
visibleLightIndices[offset] = lightIndex;
}
}
GroupMemoryBarrierWithGroupSync();
마지막 단계는 그룹 공유 메모리의 타일 가시광선 인덱스 목록에서 읽어 각 픽셀에 대한 가시광선 조명을 누적하는 것입니다. 조명과 그림자 알베도를 결합하면 출력은 상단에 투명한 표면이 렌더링된 MSAA HDR 텍스처입니다.
float3 color = 0;
for (uint lightIt = 0; lightIt < visibleLightCount; ++lightIt)
{
uint lightIndex = visibleLightIndices[lightIt];
Light light = lights[lightIndex];
color += diffuseAlbedo * evaluateLightDiffuse(light, gbuffer);
color += specularAlbedo * evaluateLightSpecular(light, gbuffer);
}
MSAA를 사용하는 계산된 셰이더 조명의 경우 가장자리 픽셀에만 전체 샘플당 조명이 필요하지만 가장자리의 화면 공간 일관성은 열악하고 비효율적입니다. 컴퓨트 셰이더는 효율적인 일관성 있는 픽셀 목록을 구축하고, 각 픽셀의 조명(샘플 0)을 평가하고, 픽셀에 샘플당 조명이 필요한지 결정하고, 그렇다면 공유 메모리의 원자 목록에 추가하고, 모든 픽셀이 완료되면 동기화하고, 반복하고, 조명 샘플 1~3을 조명하여 목록의 픽셀을 가져올 수 있습니다. 성능이 크게 향상될 수 있습니다!
Frostbite 2의 지형 렌더링에서는 최적화를 위해 인스턴싱을 사용합니다. DX9 스타일 흐름 인스턴싱은 훌륭하지만 추가 버텍스 어트리뷰트, GPU 오버헤드 등의 제한이 있고 스키닝과 (효과적으로) 결합할 수 없으며 주로 작은 메시(입자, 나뭇잎)에 사용됩니다. DX10/DX11은 셰이더 버퍼 개체를 지원합니다. 버텍스 셰이더는 SV_InstanceID에 액세스할 수 있고 완전히 임의로 로드할 수 있으며 고정 요소로 제한되지 않고 인스턴스별 배열 및 기타 데이터 구조를 지원할 수 있습니다.
인스턴스화된 데이터에는 여러 개체 유형(강체, 스킨 처리, 복합 메시), 여러 개체 조명 유형(소형/동적: 라이트 프로브, 대형/정적: 라이트 맵) 및 다양한 유형의 인스턴스 데이터(변환 float4x3, 스킨 변환 float4x3 배열, SH 라이트 프로브 float4x4, 라이트 맵 UV 스케일링/오프셋 float4)가 포함됩니다. 모든 인스턴스화 데이터를 하나의 대형 버퍼에 담을 수 있습니다!
// 인스턴스 :변환(Transform)모멘트(Moment)+SH
Buffer<float4> instanceVectorBuffer : register(t0);
cbuffer a
{
float g_startVector;
float g_vectorsPerInstance;
}
VsOutput main(
// ....
uint instanceId : SV_InstanceId)
{
uint worldMatrixVectorOffset = g_startVector + input.instanceId * g_vectorsPerInstance + 0;
uint probeVectorOffset = g_startVector + input.instanceId * g_vectorsPerInstance + 3;
float4 r0 = instanceVectorBuffer.Load(worldMatrixVectorOffset + 0);
float4 r1 = instanceVectorBuffer.Load(worldMatrixVectorOffset + 1);
float4 r2 = instanceVectorBuffer.Load(worldMatrixVectorOffset + 2);
float4 lightProbeShR = instanceVectorBuffer.Load(probeVectorOffset + 0);
float4 lightProbeShG = instanceVectorBuffer.Load(probeVectorOffset + 1);
float4 lightProbeShB = instanceVectorBuffer.Load(probeVectorOffset + 2);
float4 lightProbeShO = instanceVectorBuffer.Load(probeVectorOffset + 3);
// ....
}
// 인스턴스 :
half4 weights = input.boneWeights;int4 indices = (int4)input.boneIndices;
float4 skinnedPos = mul(float4(pos,1), getSkinningMatrix(indices[0])).xyz * weights[0];
skinnedPos += mul(float4(pos,1), getSkinningMatrix(indices[1])).xyz * weights[1];
skinnedPos += mul(float4(pos,1), getSkinningMatrix(indices[2])).xyz * weights[2];
skinnedPos += mul(float4(pos,1), getSkinningMatrix(indices[3])).xyz * weights[3];
// ...
float4x3 getSkinningMatrix(uint boneIndex)
{
uint vectorOffset = g_startVector + instanceId * g_vectorsPerInstance;
vectorOffset += boneIndex*3;
float4 r0 = instanceVectorBuffer.Load(vectorOffset + 0);
float4 r1 = instanceVectorBuffer.Load(vectorOffset + 1);
float4 r2 = instanceVectorBuffer.Load(vectorOffset + 2);
return createMat4x3(r0, r1, r2);
}인스턴스화의 이점은 인스턴스당이 아닌 객체 유형당 단일 그리기 호출, 큰 CPU 이득을 위해 CPU에 미치는 영향 최소화, 스키닝 시 인스턴스화 중단 없음, 더 높은 결정성 및 더 나은 전체 성능입니다. 최종 결과는 아티스트가 배치한 객체 인스턴스 수에 관계없이 일반적으로 1500-2000개의 드로우 콜입니다!
DX11의 주요 기능에는 D3D 스케줄링을 더 많은 코어로 확장하여 성능을 향상하고 프레임 대기 시간을 줄이는 것이 포함됩니다. 하드웨어 스레드당 DX11 지연 컨텍스트인 이 기능을 활용하기 위해 렌더러는 프레임의 각 렌더링 "레이어"에 대해 실행하려는 모든 그리기 호출 목록을 작성하고, 각 레이어에 대한 그리기 호출을 ~256개 청크로 분할하고, 생성할 지연 컨텍스트와 병렬로 청크를 예약하고, 명령 목록을 사용하고, 즉각적인 컨텍스트로 렌더링하고, 명령 목록을 실행합니다.
당시에는 대규모 드라이버 코드 기반을 리팩터링하는 데 필요한 시간, Microsoft와의 IHV(독립 하드웨어 공급업체) 딜레마, 게임 스레드와의 심각한 드라이버 스레드 충돌로 인해 아직 고성능 드라이버가 없었습니다. 작동 방식은 드라이버가 자체 처리 스레드를 생성하지 않고, 게임이 여러 지연된 컨텍스트에 병렬로 작업 부하를 제출하고, 거의 모든 필수 처리가 지연된 컨텍스트의 그리기 호출에서 발생하도록 보장하고, 게임이 즉각적인 컨텍스트에서 명령 목록을 예약하고, 드라이버가 이를 사용하여 최소한의 작업을 수행한다는 것입니다.
1GB 이상의 그래픽 카드가 필요하지 않은 대용량 메모리를 갖춘 최신 GPU에도 종종 필요한 리소스 스트리밍의 경우 BF3 레벨은 1GB가 넘는 텍스처와 메시를 사용하여 로드 시간을 줄입니다. 그러나 프레임 내에서 DX 리소스를 생성하고 파괴하는 것은 결코 좋은 일이 아니며 DX에서 항상 문제였던 비결정성 및 대규모 드라이버/OS 정지로 이어질 수 있습니다.
우리는 Microsoft, Nvidia 및 AMD와 협력하여 DX11의 GPU 리소스에서 일시 중지 없는 비동기 리소스 스트리밍이 수행될 수 있도록 했습니다. 우리는 CPU 및 GPU 성능이 영향을 받는 것을 원하지 않습니다. 핵심 기반은 DX11의 동시 생성입니다.
리소스 생성 프로세스: 스트리밍 시스템은 로드할 리소스(텍스처 밉맵 또는 메시 LOD)를 결정하고, 우선 순위가 낮은 별도 스레드의 대기열에 DX 리소스 생성을 추가하고, 스레드는 초기 데이터로 리소스를 생성하고, 리소스가 생성되었음을 스트리밍 시스템에 알리고, 게임은 이를 사용하기 시작합니다. 드라이버에서 비동기식 무중단 DMA를 활성화하세요! 리소스 파괴 프로세스: 스트리밍 시스템은 D3D 리소스를 삭제하고 드라이버는 이를 사용하는 GPU 프레임이 완료될 때까지 중단 없이 내부적으로 활성 상태를 유지합니다!
CryENGINE 3 그래픽 기술의 비밀은 렌더링 파이프라인, 위치 재구성, 커버리지 버퍼, 지연 조명, 그림자, 화면 공간 기술, 지연 기술, 일괄 HDR 포스트 프로세스, 입체 렌더링 등을 포함하여 2011년 CryEngine 3의 렌더링 기술을 공유합니다.
Z 버퍼에 대한 참고 사항은 기사에 언급되어 있습니다. Z 값은 쌍곡선으로 분포되며 셰이더에서 사용하기 전에 선형 공간으로 변환해야 합니다.
// Constants
g_ProjRatio.xy = float2( zfar / (zfar-znear), znear / (znear-zfar) );
// HLSL function
float GetLinearDepth(float fDevDepth)
{
return g_ProjRatio.y/(fDevDepth-g_ProjRatio.x);
}문제는 FPV(1인칭 보기) 개체의 경우 깊이 버퍼를 사용하여 FPV 개체가 장면의 나머지 부분과 겹치는 것을 방지할 수 있으며, 다른 FOV 및 근거리/원거리 평면(아트별 선택), 실제 겹치는 것을 방지하기 위한 다른 깊이 범위로 인해 이러한 개체에 지연 기술을 100% 사용할 수 없게 됩니다. 해결책은 깊이에 따라 선택된 1인칭 시점 개체에 대해 서로 다른 깊이 스케일을 사용하여 하드웨어 깊이를 선형 깊이로 변환하도록 깊이 재구성 기능을 수정하는 것입니다.
float GetLinearDepth(float fDevDepth)
{
float bNearDepth = step(fDevDepth, g_PS_DepthRangeThreshold);
float2 ProjRatio.xy = lerp(g_PS_ProjRatio.xy, g_PS_NearestScaled.xy, bNearDepth);
return ProjRatio.y/(fDevDepth-ProjRatio.x);
}깊이에서 위치를 재구성하는 아이디어: VPOS를 스크린 공간 S에서 목표 동종 공간 W(그림자 공간 또는 월드 공간)로 직접 선형 변환, 스크린 클립 공간에서 동종 행렬로 직접 변환, VPOS는 지연된 광량을 렌더링하는 가장 간단한 방법이며 s3D는 개별적으로 조정됩니다.
float4 HPos = (vStoWBasisZ + (vStoWBasisX*VPos.x)+(vStoWBasisY*VPos.y) ) * fSceneDepth;
HPos += vCamPos.xyzw;
커버리지 버퍼 기본 오클루전 컬링 시스템으로서 기본적으로 저해상도 깊이 버퍼, 가시성 Z 테스트를 위한 객체 AABB/OBB의 대략적인 CPU 래스터라이제이션, CPU에서 완전히 상세한 C-버퍼를 준비하는 것은 너무 느리고 엄청난 계산 비용이 들고 C-버퍼의 모든 세부 정보를 얻으려면 전체 렌더링 파이프라인을 소프트웨어에서 복제해야 합니다.
CPU에서 이전 프레임의 GPU 깊이 버퍼를 다시 읽고, G-Buffer 패스(최대 필터) 후 GPU에서 ZBuffer를 축소하고, 별도의 CPU 스레드에서 BBox를 래스터라이제이션하여 컬링을 수행합니다.

왼쪽: 일반 장면; 오른쪽: 오버레이 버퍼.
오버레이 버퍼는 X360/PS3 및 DX11 하드웨어에서 사용되며, PC의 리드백 대기 시간은 더 높지만 여전히 허용 가능합니다(최대 4프레임). C-버퍼 크기는 콘솔의 Crysis 2에서 256x128로 제한됩니다. 문제: 이전 프레임/현재 프레임 카메라 간의 불일치로 인해 가시성 테스트가 잘못되었습니다.
해결책은 Coverage Buffer Reprojection입니다. 이전 프레임의 카메라에서 C-버퍼 CPU 재투영을 사용하여 픽셀의 포인트 스퍼터링을 재투영합니다. 카메라 정보는 C-버퍼 데이터로 인코딩되며 CPU 리드백 및 재투영은 별도의 스레드에서 이루어지며, 이는 SPU에서 약 2밀리초, 벡터화된 코드를 사용하는 Xbox 360에서 3-4밀리초가 소요됩니다. 재투영 후 C 버퍼에 구멍 스티칭, 3x3 확대 채널, 남은 C 버퍼 구멍: 객체가 표시된다고 가정합니다. 재투영은 컬링 효율성을 크게 향상시키고, 다양한 폐색 테스트 아티팩트를 해결하며, 유효하지 않은 영역을 감지하고, 더 높은 프레임 속도에서 더 효율적으로 작동합니다.

버퍼 재투영 재정의, 빨간색은 재투영 후에도 남아 있는 구멍입니다.
CryEngine 3의 지연 조명에는 주변광, 환경 프로브, GI, SSDO, RLR, 광원 등이 포함됩니다.
CryEngine 3의 디퍼드 섀도우는 태양의 섀도우 마스크(섀도우 마스크), 그림자 폐색을 축적하는 특수 렌더 타겟을 사용하며, 섀도우 마스크는 실제 그림자를 사용하기 전에 여러 그림자 기술을 서로 겹쳐 놓습니다. 포인트 라이트 그림자는 조명 버퍼에 직접 렌더링됩니다.
캐스케이드 그림자는 Crysis 1부터 캐스케이드 분할 체계와 함께 사용되었습니다. 대략적인 로그 텍셀 밀도 분포, 그림자 프러스텀는 카메라 뷰 프러스텀를 보수적으로 덮도록 조정되고 그림자 프러스텀의 방향은 월드 공간에서 고정됩니다. 더 나은 로그 분포 근사화, 텍셀 밀도 증가, 브레이크아웃 감소, 더 넓은 셰이딩 범위에 대한 자체 셰이딩 개선으로 인해 더 많은 캐스케이드가 허용됩니다. 각 캐스케이드에 대해 그림자 프러스텀를 SM의 텍스처 메시에 스냅합니다.
계단식 그림자용 패스: 스텐실 버퍼에 표시된 잠재적인 그림자 수신 영역에 프러스텀를 렌더링하여 지연된 방식으로 렌더링된 계단식/포인트 조명용 그림자 패스입니다. 계단식 배열로 더 복잡한 분할을 허용하고, 겹치는 영역에서 가장 높은 해상도의 계단식 배열을 선택하여 그림자 맵 공간을 낭비하지 않습니다.
캐스케이드 섀도우 캐싱: 모든 캐스케이드가 단일 프레임에서 업데이트되는 것은 아니며, 업데이트 비용이 여러 프레임에 걸쳐 분산되고, 성능상의 이유(특히 PS3)로 인해 더 많은 캐스케이드가 허용됩니다. 더 나은 섀도우 맵 밀도 분포, 캐시된 섀도우 맵은 캐시된 섀도우 매트릭스를 사용하고, 먼 캐스케이드는 덜 자주 업데이트되며, 마지막으로 캐스케이드는 VSM을 사용하고 섀도우 마스크와 추가로 혼합되어 멀리 있는 거대한 개체에서 큰 반음영을 얻을 수 있습니다.
포인트 라이트 그림자: 옴니라이트는 항상 6개의 독립적인 프로젝터로 분할되며, 각 프로젝터의 그림자 맵은 그림자 투영 범위를 기준으로 독립적으로 크기가 조정됩니다. 최종 크기는 범위를 매개변수로 사용하는 대수 그림자 맵 밀도 분포 함수의 결과입니다. 스케일링 후 프레임당 모든 섀도우 맵을 패킹하는 대형 텍스처 아틀라스, 메모리 조각화를 방지하기 위해 영구적으로 할당된 텍스처 아틀라스, 스텐실로 표시된 수신 영역.
RLR(실시간 로컬 반사): 래스터라이제이션된 반사는 비용이 많이 들고 일반적으로 평면 반사 또는 큐브맵이며 장면 재렌더링이 필요하고 표준 반사는 제한됩니다. 평면, 큐브 매핑 작은 영역, 일반적으로 표면 없음, 레이 트레이싱 직접 반사, 화면 공간에서 레이 트레이싱을 통해 로컬 반사에 근접합니다.
실시간 로컬 반사를 위한 기본 알고리즘: 각 픽셀에 대한 반사 벡터 계산, 지연된 노멀 및 깊이 대상 사용, 반사 벡터에 따른 Raymarch, 깊이 샘플링 및 광선 깊이가 장면 깊이의 임계값 내에 있는지 확인, 적중할 경우 이전 프레임의 프레임 버퍼 및 샘플 색상으로 재투영, 결과는 상대적으로 저렴하고 모든 곳에서(복잡한 표면에서도) 로컬 반사는 화면 공간의 제한된 데이터로 인해 많은 문제 사례를 유발합니다.
실시간 로컬 반사 구현 팁: 매우 제한된 화면 공간 데이터, 반사는 깨진 것보다 덜 깨지고, 반사 벡터가 뷰어를 향하는 경우 데이터가 없기 때문에 부드럽게 페이드 아웃하고, 화면 가장자리에서 반사 샘플을 부드럽게 페이드 아웃하고, 명백한 단계 아티팩트를 숨기기 위해 단계 크기에 디더링을 추가하고, Crysis 2에서 샘플링된 HDR 색상 대상, 표면 광택을 기반으로 디더 또는 흐림을 추가합니다.
접촉 섀도잉: 먼저 폐색 정보를 생성하고, SSAO 중에 굽힘 노멀 N'을 계산 및 저장합니다. 굽힘 법선은 평균 폐색되지 않은 방향이며, 자체 폐색이 없고 상대적으로 넓은 반경이 없는 깨끗한 SSAO가 필요합니다. 그런 다음 각 조명에 대해 N dot L과 N' dot L이 평소와 같이 계산되어 폐색 양에 두 내적 간의 클램핑 차이를 곱하여 조명을 감쇠시킵니다.
화면 공간 셀프 섀도잉: 각 캐릭터(메모리)에 대한 섀도우 맵을 감당할 수 없으며 메모리 부족 문제를 해결하는 방법은 간단한 트릭/근사법입니다. 광선은 화면 공간 라이트 벡터를 따라 이동하고 모든 캐릭터에 대한 매크로 셀프 섀도잉 세부 정보를 제공합니다.

문자의 화면 공간 셀프 섀도잉.
Bokeh DOF 효과는 다른 커널과 가중치를 사용합니다.

Rendering in Cars 2는 Disney가 Toy Story 3 이후 공유하는 또 다른 작품입니다. 라이트 프로브, HDR 색상 정확도, 고급 템플릿 섀도우 컬링 및 PS3 후처리를 포함하여 Cars 2 게임의 렌더링 기술을 소개합니다.
라이트 프로브의 목표는 동시에 4명의 플레이어를 지원하고, 모든 세계 기하학의 라이트 맵에서 작동하고, 실시간 조명을 일치시키는 것입니다.

라이트 프로브의 처리 과정은 공간의 한 지점에서 빛을 캡처하고, 빛을 반사하고, 환경을 매핑하는 것입니다. 바운스 조명 데이터는 구형 고조파, 3차 SH = 프로브당 108바이트로 저장되며 직접 조명으로 무료로 패킹할 수 있습니다.

라이트 프로브 캡처, GPU의 큐브맵 렌더링, HDR용 16F로 저장, 속도용 아틀라스, 바운스 조명(큐브맵에서 SH 투영까지).

방사 볼륨은 여러 개의 라이트 프로브가 포함된 볼륨으로, 월드의 다양한 반사광을 허용하며 라이트맵과 함께 사용하는 데 매우 널리 사용됩니다.

레이싱 게임의 볼륨 옵션은 세계당 2~5마일의 트랙으로, 대부분 외부에 있으며 커버리지가 필요하지 않은 얇고 곡선이 많은 영역이 많이 있습니다.
균일한 그리드 볼륨은 상자 분할(밀도 x/y/z)을 위한 다양한 수의 슬라이스와 볼륨 슬라이스를 따라 배치된 조명 프로브를 사용하여 어디든 맞도록 회전하고 크기를 조정할 수 있는 상자 볼륨입니다. 구조가 간단하고 구현이 쉽습니다. 전체 데이터는 직육면체 교차 테스트를 위한 샘플과 함께 연속 배열로 저장됩니다. 각 프로브는 오프셋을 통해 액세스할 수 있습니다. O(1) 그리드 내 샘플링. 비용은 부피만 차지할 뿐 공간 낭비입니다.
메시는 또한 전환 영역, 유효하지 않은 포인트, 볼륨 조회 등을 처리해야 합니다. 볼륨 조회의 경우 CPU와 GPU, CPU 기반의 두 가지 방법이 있습니다. 메시당 가장 가까운 SH를 할당/혼합하고, SH 데이터를 GPU에 전달합니다. GPU 기반: 픽셀별 또는 정점별, GPU의 샘플링 프로브.
셰이더 상수는 인스턴스별로 지정되고, 색상은 셰이더에서 계산되며, 큰 개체는 분할되고, 버텍스 색상 혼합으로 메쉬가 분리될 수 있으며, 월드 조명에도 동일한 문제가 있습니다.
겹치는 볼륨의 경우 블렌딩이 필요하지만 겹치는 볼륨의 원활한 블렌딩이 복잡합니다. 전역 감지기로 혼합하기 때문에 가장 가까운 점을 수집하고 조명의 평균을 낼 수 없으며 겹치는 영역은 숨기기 어려운 미친 전환을 생성합니다.

시간 평균화 방법을 사용하여 마지막 프레임의 SH %를 현재 SH에 혼합하고(세계별로 조정 가능) 삼선형 필터링 대안을 사용하여 첫 번째 프레임 혼합을 방지할 수 있습니다.
볼륨 없는 프로브는 도로 반사에 적합하며 환경 매핑 프로브를 볼륨에 할당합니다. 환경 맵을 할당할 때 볼륨 내에 있으면 볼륨의 환경 맵이 사용되고, 그렇지 않으면 전역 프로브가 사용되며 페이딩 영역 기반 전환 및 겹치는 볼륨은 큐브 맵을 공유하여 점프를 방지합니다.
직접 조명을 렌더링할 때 직접 조명을 프로브에 패키징하면 SH의 조명을 평가하고 메시 밀도에 따라 추가 성능 비용 없이 바운스에 추가할 수 있습니다.
볼륨 내에 방향성 및 주변광을 추가하는 조명 재정의도 제공되므로 아티스트는 2D 볼륨, 1D 볼륨 및 영역 조명 유형을 포함한 조명을 제어할 수 있습니다.
균일 그리드(Uniform Grid)는 간단하고 빠르며 메모리를 거의 사용하지 않고 4명의 플레이어에 잘 적응하여 아티스트에게 많은 유연성을 제공합니다.
동시에 4명의 플레이어를 지원하려면 HDR 렌더링 비용 절감, 섀도우 비용 절감, 4인 분할 화면에 대한 섀도우 맵 크기 조정, 다중 해상도 사용, 디퍼드 렌더링, 섀도우 마스킹 등 GPU 파이프라인을 최적화해야 합니다.
가장 먼저 고려해야 할 것은 렌더링 텍스처의 형식입니다. 다음 표는 다양한 형식에 대한 구체적인 설명입니다.

다음 그림은 다양한 형식으로 인해 발생하는 색상 오류를 보여줍니다.

LogLuv는 오류가 가장 낮고 안정적이지만 ALU를 소모하고, 7e3은 높지만 더 안정적이며, RGBM은 높고 불안정하다는 것을 알 수 있습니다!
위의 특수 형식을 사용하면 이미지에 색상 그라데이션 문제가 발생할 수도 있습니다.

이 문제의 원인은 HDR 처리 파이프라인에서 장면에서 렌더 타겟으로 렌더링할 때 정확도가 떨어지기 때문입니다.

톤매핑 구성 요소는 노출 보정과 이를 [0,1] 범위로 조정하는 톤매핑 연산자의 두 부분으로 나눌 수 있습니다. 이는 분리 가능하며 서로 다른 시간에 완료될 수 있습니다. 노출 보정은 Cars 2에 대한 것이지만 톤매핑 작업은 그렇지 않습니다. Cars 2는 Hable이 언급한 ALU 기반 영화 톤매핑 연산자를 사용합니다.

톤매핑을 분할한 후의 HDR 파이프라인은 다음과 같습니다.

얻은 결과 비교:

동적 객체의 경우 라이트 맵에서 그림자도 수신해야 하며 그림자에 들어가고 나갈 때 대략적인 전환만 필요합니다. 따라서 저해상도 섀도우 맵이 사용되었습니다. 256x256 섀도우 맵을 사용하고 매우 저렴하며(~0.1ms) 간단한 프록시 지오메트리를 사용했습니다. 그림자 맵을 그릴 때 동적 개체는 두 개의 계단식으로만 그려지고 그림자 거리가 줄어들며 트랙이 2D 평면에 있기 때문에 재투영 아티팩트가 허용됩니다.

지연된 그림자 폐색의 경우 처리되는 픽셀 수를 줄이고 RT를 1/4 크기로 렌더링하고 양방향 필터링을 사용하여 일반 해상도로 업샘플링합니다.

피할 수 없는 아티팩트는 가장자리 아티팩트로, 낮은 해상도에서는 너무 뚜렷해서 무시할 수 없습니다.

초기 스텐실 컬링 픽셀 셰이더에 도달하기 전에 조각을 컬링하고, PS3, 360 및 최신 PC 그래픽 카드를 지원하며, PC에서는 자동으로, PS3 및 360에서는 수동으로 제어하고, 쓰기와 테스트 사이의 지연을 지원합니다. 그러나 당시 초기 단계의 픽셀은 4x4 픽셀 블록이라는 점에 유의해야 합니다.

고급 템플릿 클리핑과 결합된 디퍼드 렌더링 프로세스는 다음과 같습니다.
- 1/16 해상도로 그림자를 렌더링합니다.

제한된 필터링을 사용하여 섀도우 마스크를 1/16 해상도로 렌더링하려면 고해상도의 가장자리가 저해상도의 가장자리와 다르기 때문에 그림자 가장자리를 확대해야 하며 확대 폭은 가장자리를 덮는 정도에 따라 구성할 수 있습니다.
- 전체 해상도 초기 스텐실을 1/16 섀도우 마스크로 채웁니다.
RT의 1/16 포인트 샘플, 고급 템플릿 쓰기를 켜고 확장 영역 내에 있는 경우 텍스트킬을 켭니다.

- 고급 스텐실 테스트를 사용하여 그림자 가장자리를 전체 해상도로 다시 렌더링합니다.
고급 스텐실 테스트를 켜면 고급 스텐실이 이전 패스에서 채워진 픽셀을 제거하여 픽셀의 약 30%만 렌더링합니다. 두 채널의 양측 흐림의 경우 고급 템플릿 테스트를 켜진 상태로 유지하고 픽셀의 약 30%만 흐리게 합니다.

양측 블러 효과 비교, 오른쪽은 블러 적용 후의 효과입니다.
다음 번에 가장자리 그림자의 경우 고급 템플릿 테스트를 사용하여 문제를 해결할 수도 있습니다. 고급 템플릿은 단지 마스크일 뿐이며 확장은 흐린 영역을 덮지 않으며 확장 범위가 넓은 극단적인 클로즈업에서만 발생합니다.

음영 값은 0 또는 1이고 계단식 선택이며 대부분의 픽셀은 교차된 양측 필터에 있습니다. 사전 노출된 색상은 제한된 정밀도로 대상을 렌더링할 때 매우 효과적이며, 동적 객체에 대한 저해상도 섀도우 맵은 저렴하고, 지연된 섀도우 마스크 렌더링 시간이 효과적으로 절반으로 줄어듭니다.
또한 이 기사에서는 SPU 기반 포스트 프로세스 파이프라인 및 최적화뿐만 아니라 입체 3D 렌더링의 듀얼 카메라 렌더링 최적화(예: 폐색, 프러스텀 병합) 등에 대해서도 자세히 설명합니다.

입체 3D 렌더링의 폐색 결함 최적화.
DX11 Performance Gems는 DX11의 고성능 최적화 기술과 제안을 자세히 설명하고 케이스 불투명도 매핑 구현 및 최적화(표면 세분화 가속 조명, GatherRed 가속 업샘플링, SV_SampleIndex 개선된 AA, 읽기 전용 소프트 입자 깊이 등)를 제공합니다.
DX11의 지연된 컨텍스트는 명령 목록을 작성하는 데 사용되는 장치와 유사한 인터페이스입니다. DX11은 "즉시" API 호출에 동일한 ID3D11DeviceContext 인터페이스를 사용합니다. 즉각적 컨텍스트는 궁극적으로 ID3D11Device::GetImmediateContext()를 통해 액세스되는 GPU에 작업을 제출하는 유일한 방법입니다. ID3D11Device에는 제출 API가 없습니다.

DirectX11의 다중 스레드 명령 생성 및 제출 메커니즘. 그림에는 지연된 컨텍스트가 있는 두 개의 스레드가 있습니다. 그들은 다양한 방법으로 명령을 기록하고 생성합니다. 생성된 명령 목록은 스레드 간에 동기화, 구성/정렬/버퍼링된 후 렌더링 메인 스레드에 의해 즉시 컨텍스트에 제출되고, 즉시 컨텍스트에 의해 GPU에 제출됩니다.
DX11의 내부 구조는 비교적 유연합니다. DX11 런타임에는 구현이 내장되어 있지만 드라이버가 자체 구현을 담당하고 사용할 수 있습니다. 예를 들어, 명령 목록을 더 낮은 수준에서 구축하여 더 많은 CPU 작업을 제출 스레드로 이동할 수 있습니다. 지연된 컨텍스트에 대한 최적화 제안:
컨텍스트/스레딩을 통해 워크로드 균형을 맞추려고 시도합니다. 그러나 커밋 워크로드는 거의 예측할 수 없으며 세분성이 도움이 되며(커밋 스레드가 작업을 동적으로 처리할 수 있는 경우) 가능하다면 더 무거운 커밋 워크로드를 먼저 수행합니다. 코어당 최대 12개의 CL(명령 목록), CL당 최대 1ms가 좋습니다.
합리적인 명령 목록 크기를 보장합니다. 명령 목록의 그리기 호출 수는 그리기 호출의 삼각형 수와 매우 흡사합니다. 즉, 각 목록에는 약 수십 개의 API 호출에 해당하는 오버헤드가 있습니다.
여유 CPU 시간을 남겨두세요. 모든 스레드를 사용 중으로 유지하면 CPU가 포화되고 스레드 렌더링에서 서비스 스레드가 차단됩니다(게임 엔진은 N-1 CPU 코어 이상을 사용하지 않음). "사용 중"에는 사용 중 대기(예: 폴링)가 포함되며 항상 그래픽 드라이버용으로 남겨집니다.
기억을 지켜보세요! 각 Map() 호출은 메모리를 CL과 연결하며, CL을 해제하는 것이 2GB 가상 주소 공간에서 빡빡할 수 있는 메모리를 해제하는 유일한 방법입니다!
본 글에서 DX11을 사용한 사례는 불투명도 맵이다. DX11 테셀레이션을 사용하여 DS의 조명을 중간 "최적 지점" 속도로 계산하면 불투명도, 가시성 등 필요에 따라 픽셀당 또는 샘플 속도당 고주파 구성 요소를 유지할 수 있습니다.

PS, VS, DS 조명의 fps 및 효과 비교는 다음과 같습니다.

적응형 테셀레이션은 클래스 VS 계산 빈도, 화면 픽셀 빈도에 대한 PS 유사 관계(이 경우 1:15가 잘 작동함)라는 두 세계의 장점을 모두 제공하며 천천히 변화하는 음영 결과(GI, 기타 체적 알고리즘)에 적합합니다. 주요 병목 현상은 테셀레이션 작업 후의 채우기 속도이므로 파티클을 저해상도 오프스크린 버퍼로 렌더링하는 것은 테셀레이션(GTX 560 Ti / HD 6950의 경우 1.2x ~ 1.5x)에서도 상당한 이점이 있습니다. 그러나 저해상도에서 간단한 이중선형 업샘플링을 수행하면 가장자리에 아티팩트가 발생합니다.

대신, 깊이 불연속점에서 가장 가까운 매칭 이웃의 샘플을 사용하여 고해상도 깊이를 인접한 저해상도 깊이와 비교하는 교차 양측 필터링과 개념적으로 유사한 가장 가까운 깊이 업샘플링을 사용합니다(그렇지 않으면 이중선형).

최근 깊이 업샘플링 계산 프로세스.

효과 비교.
SM5의 GatherRed()를 사용하여 한 번에 2x2 저해상도 깊이 이웃을 효율적으로 얻습니다.
float4 zg = g_DepthTex.GatherRed(g_Sampler, UV);
float z00 = zg.w; // w: floor(uv)
float z10 = zg.z; // z: ceil(u), floor(v)
float z01 = zg.x; // x: floor(u), ceil(v)
float z11 = zg.y; // y: ceil(uv)가장 가까운 깊이까지의 업샘플링은 모든 샘플 실행에서 AA와 잘 작동하며 성능은 놀랍습니다! (FPS 영향 < 5%)
float4 UpsamplePS( VS_OUTPUT In,
uint uSID : SV_SampleIndex //
) : SV_Target부드러운 입자(깊이 기반 알파 그라디언트)는 장면 깊이에서 읽어야 합니다. 이는 DX11 이전의 경우 깊이 테스트(및 관련 가속도)를 희생하거나 두 깊이 표면(및 필요한 모든 복사)을 유지하는 것을 의미했습니다. DX11의 해결 방법은 D3D11_DSV_READ_ONLY_DEPTH로 선언된 깊이 스텐실 버퍼를 사용하는 것입니다.

부드러운 입자의 단계는 다음과 같습니다.
- 불투명한 객체를 깊이 텍스처로 렌더링합니다.

- 깊이 테스트를 사용하여 부드러운 입자를 렌더링합니다.

최종 효과는 다음과 같이 비교됩니다.

전반적인 성능은 5~10배 향상되었으며 DX11 테셀레이션이 대부분의 기여를 제공하지만 감소된 해상도에서의 렌더링은 채우기 속도를 줄이고 테셀레이션을 빛나게 하며 GatherRed() 및 RO DSV도 주기를 절약합니다.
고성능 후처리에서는 후처리의 특성과 병목 현상, 최적화 기법에 대해 이야기하고 몇 가지 실제 사례를 제시했습니다.
이 기사에서는 DX11의 새로운 리소스 유형인 버퍼/구조화된 버퍼, UAV(Unordered Access View): RWTexture/RWBuffer를 언급합니다. 이를 통해 PS 및 CS에서 임의 읽기 및 쓰기가 가능합니다. "분산" 능력은 새로운 기회를 제공하며, 위험과 접근 패턴을 인지하고 있어야 합니다.
모든 스레드에서 실행되는 새로운 DirectCompute의 새로운 셰이더 모드는 그래픽 파이프라인의 한계에서 처리를 해방하고 기존 Direct3D 리소스에 완전히 액세스합니다. DispatchIndirect는 CPU가 아닌 장치 버퍼에서 디스패치 매개변수를 가져와 컴퓨팅 작업이 계산을 주도하도록 합니다. 여전히 CPU는 DispatchIndirect 호출을 발행하도록 바인딩되어 있으며, Append 버퍼와 결합하여 동적 작업 부하를 생성하는 데 적합합니다. 다음은 DX11의 메모리 유형 및 속성 테이블입니다.
메모리 용량 속도 가시성
전역 메모리(버퍼, 텍스처, 상수) 가장 긴 지연 모든 스레드
공유 메모리(그룹 공유) 빠르게 단일 스레드 그룹
로컬 메모리(레지스터) 매우 빠르다 단일 스레드
스레드 간 통신의 경우 그룹의 스레드는 공유 메모리를 통해 통신할 수 있으며 스레드 실행은 다른 그룹에 의존할 수 없습니다! 모든 그룹이 동시에 실행되는 것은 아니며 그룹은 디스패치 내에서 어떤 순서로든 실행될 수 있습니다. 그룹 간 종속성은 교착 상태로 이어질 수 있습니다. 한 그룹이 다른 그룹의 결과에 의존하는 경우 셰이더를 여러 디스패치로 분할하는 것이 좋습니다.
데이터 위험 및 정지의 경우 UAV로 사용되는 리소스를 리바인딩하면 데이터 위험을 피하기 위해 하드웨어가 정지될 수 있습니다. 모든 쓰기는 다음 디스패치에서 볼 수 있도록 보장되어야 하며 드라이버는 이 지연을 숨기기 위해 관련되지 않은 디스패치 호출을 재정렬할 수 있습니다.
컨텍스트 전환에는 오버헤드가 있으며 컨텍스트 전환 비용에 유의해야 합니다. 그래픽과 계산 간의 페널티 전환은 일반적으로 반복적으로 자극하지 않는 한 거의 없으며 연속(백투백) 스케줄링을 사용하면 이를 방지할 수 있으므로 그룹 호출이 가능합니다.
일반적인 함정은 메모리 제한과 계산 제한입니다. 메모리 제한에는 비효율적인 액세스 패턴, 비효율적인 형식, 너무 많은 데이터가 포함됩니다. 컴퓨팅 제한에는 다양한 스레드, 잘못된 명령 조합, 낮은 하드웨어 활용도 등이 포함됩니다.
DX11의 메모리 아키텍처는 약간 특별하며 복잡한 메모리 시스템을 도입합니다. 캐시 동작은 액세스 패턴에 따라 달라지며, 버퍼는 선형 액세스의 경우 캐시 적중률이 더 좋고, 텍스처는 그룹 내 예측 가능성이 낮고 2D 액세스가 더 많은 경우 더 좋습니다.
특별한 층화 샘플링을 사용하세요. 아래 그림은 2x2 스레드 블록에 분산된 두 가지 희소 샘플링 모드를 보여줍니다. 왼쪽 패턴은 주어진 픽셀 반경 내의 임의 위치에서 4개의 샘플을 수집하는 간단한 디더링입니다. 각 샘플에는 무작위 방사형 오프셋만 사용되므로 동일한 방문의 인접한 픽셀 사이의 위치가 크게 다를 수 있습니다. 따라서 유사한 이웃에서 파생된 일부 지역성을 가질 수 있지만 무작위 오프셋은 동시 액세스가 텍스처 캐시의 동일한 블록에 도달할 가능성이 적다는 것을 의미하므로 대역폭 요구 사항이 증가합니다. 오른쪽에는 최대 반경 내에서 유사한 4탭 희소 샘플링 패턴이 표시됩니다. 그러나 이 접근 방식은 임의의 오프셋을 사용하는 대신 계층화된 샘플링을 사용하여 모든 스레드의 액세스가 원의 동일한 섹터에 해당하므로 동시 액세스가 동일한 캐시 영역에 도달할 가능성이 더 높고 병합될 수 있습니다.

층별 샘플링의 개략도. 왼쪽의 무작위 샘플링으로 인해 적중률이 낮아질 수 있습니다. 모든 스레드의 액세스가 원의 동일한 섹터에 해당하여 적중률을 나타내고 읽기 및 쓰기 작업이 병합될 수 있도록 오른쪽에 계층화된 샘플링이 사용됩니다.
텍스처와 달리 버퍼는 선형 메모리이므로 버퍼에 매핑된 2D 배열의 간격을 최대한 많이 읽습니다!
Buffer<float> srvInput;
[numthreads(128,1,1)]
void ReadCS(
uint3 gID : SV_GroupID
uint3 tID : SV_DispatchThreadID)
{
float val;
// : 로드/읽기(Read)。
val = srvRead[128*gID.x + tID.x];
// ... Use data ...
// : 로드/읽기(Read)。
val = srvRead[128*tID.x + gID.x];
// ... Use data ...
}이론적으로 스레드는 독립적으로 실행되지만 실제로는 실행되지 않은 분기의 명령에 대해 스레드가 "차폐"되는 병렬 파면에서 실행됩니다. 다양한 웨이브프런트를 무료로 포크할 수 있으며, 웨이브프런트 크기는 하드웨어(NV:32, AMD:64)에 따라 다릅니다.

가지의 전설. 컴퓨팅 셰이더는 두 개의 파면 세트로 정의됩니다. 첫 번째 조건부 사례는 각 파면을 두 개의 인터리브 세트로 분할하여 분기되도록 합니다. 따라서 각 스레드는 두 개의 분기를 실행하며 웨이브프런트는 기본적으로 50% 유휴 상태입니다. 두 번째 조건은 스레드 그룹 내의 분기를 초래합니다. 그러나 이 경우 한 웨이브프런트의 모든 스레드는 하나의 가지를 사용하고 두 번째 웨이브프런트의 모든 스레드는 다른 가지를 사용합니다. 따라서 각 웨이브프런트는 하나의 분기만 실행하며 유휴 스레드는 없습니다.
PS에서 스레드는 2D 샘플 클러스터로 그룹화되며 이미지에서 일관성이 있으면 특히 작업을 절약하는 경우 분기가 괜찮습니다!

PS에서는 가지가 쉐이딩 효율성을 감소시킬 수 있지만 가지가 있는지 여부는 중요하지 않으며 작은 영역 내에서 얼마나 많은 가지가 분기되는지가 중요합니다. 실제로 분기를 통해 비용이 많이 드는 작업이 줄어들면(예: 더 적은 텍스처 샘플 사용) 셰이더 성능이 크게 향상될 수 있습니다.
활용도를 높이고 하드웨어를 포화시킬 만큼 충분한 작업을 생성하려면 수십 개의 스레드 그룹이 가장 적합합니다. 그룹당 스레드 수를 최대화하면 하드웨어의 대기 시간을 숨기는 데 충분한 시간이 걸리므로 256-512가 좋은 대상입니다. 공유 메모리 사용량을 시도해 보십시오. 더 많은 공유 메모리 = 더 적은 수의 그룹/프로세서, 공유 메모리/스레드가 증가함에 따라 그룹을 더 작게 만드십시오.
컴퓨팅 스레드는 "그룹 공유" 메모리를 통해 데이터를 통신하고 공유할 수 있으며, 그룹의 각 스레드에서 사용하는 데이터(압축 해제된 값, 동적 프로그래밍)를 미리 로드하고, 대역폭 및 계산을 절약하고, 일반 작업의 작업 부하를 공유하고, 합계/최대값/등을 계산할 수 있습니다. 원자를 공유하는 것보다 더 효율적으로 집합을 구성합니다.

그룹 내 공유 메모리에 데이터를 미리 로드하는 예입니다. 분리 가능한 컨볼루션: 커널의 전체 공간을 공유 메모리로 읽고, 공유 버퍼에서 값을 가져와 각 픽셀에 대해 커널을 곱하고, 가능한 한 적게 읽고 더 효율적입니다!



셰이더 합산을 위한 여러 알고리즘 및 범례. 성능은 위에서 아래로 향상됩니다.
또한 이 기사에서는 SAT DOF, Scattered Bokeh DOF 등을 포함한 포스트 프로세스 최적화 기술을 설명하는 구체적인 예를 제공합니다.


연구 및 산업 분야에서 개발된 수많은 렌더링 및 그래픽 응용 프로그램은 장면 그래프를 기반으로 합니다. 전통적인 장면 그래프는 완전한 3D 장면의 계층 구조를 캡슐화하고 의미론적 측면과 렌더링 측면을 결합합니다. 렌더링에서 의미론 분리: 그래픽 애플리케이션을 위한 장면 그래프 기반 아키텍처는 장면 그래프의 의미론적 부분과 렌더링 부분을 완전히 분리하는 방법을 제안하여 애플리케이션의 사용자 인터페이스와 계산 부분을 분리하기 위한 잘 알려진 MVC(Model View Controller) 디자인 패턴을 기반으로 느슨하게 보편적으로 적용 가능한 그래픽 애플리케이션 아키텍처를 만듭니다. 동적 장면 렌더링, 대형 장면의 코어 외부 렌더링, 나무와 초목의 형상 생성, 다중 뷰 렌더링과 같은 다양한 렌더링 및 모델링 작업에 대한 이 새로운 디자인의 이점도 살펴봅니다. 마지막으로 시각화 및 렌더링 애플리케이션의 신속한 개발을 위해 대규모 프레임워크에서 이 소프트웨어 아키텍처를 사용하는 동안 해결된 일부 구현 세부 사항이 제시됩니다. 전통적인 디자인에서 애플리케이션은 장면 그래프를 동적으로 수정하기 위해 장면 그래프의 일부에 대한 참조를 유지할 수 있습니다.

상태는 장면 그래프에 직접 저장될 수도 있으므로 순회가 복잡해집니다.

위의 두 디자인 모두 크거나 복잡한 응용 프로그램에서 결함을 발생시킵니다. 첫 번째 경우에는 상태가 장면 그래프와 분리되어 있으며, 응용 프로그램에서 상태가 저장되는 방식에 장면 그래프의 계층 구조가 반드시 반영되지는 않습니다. 이 문제를 극복하기 위해 렌더링 장면 그래프의 구조가 애플리케이션에서 부분적으로 병렬화되어 작업이 중복되거나 유지 관리가 어려울 수 있는 다른 구조 상태가 발생할 수 있습니다. 두 번째 경우와 마찬가지로 장면 그래프에 상태를 저장하면 장면 그래프의 서로 다른 부분 간에 종속성이 있는 경우 복잡성이 크게 증가할 수 있습니다.
이러한 문제에 대한 보다 완벽한 솔루션은 렌더링 장면 그래프에서 의미를 완전히 분리하고 분할 장면 그래프 아키텍처를 도입함으로써 추구됩니다.
의미론적 장면 그래프: 사용자가 모델링한 장면을 반영합니다. 순수 렌더링 응용 프로그램에서 이 그래프는 초기 생성 후에 수정되지 않습니다.
렌더링 장면 그래프: 전통적인 의미의 장면 그래프로, 장면을 표시하는 데 필요한 일련의 렌더링 작업을 생성합니다. 그 구조는 사용된 렌더링 백엔드의 영향을 받습니다.
일반적인 그래픽 응용 프로그램은 실제 또는 암시적 의미 장면 그래프를 입력으로 사용하고 3D 출력을 위해 렌더링된 장면 그래프를 생성하는 컴파일러처럼 작동합니다. 이 변환 작업 중에 의미론적 장면 그래프의 단일 노드는 일반적으로 렌더링된 장면 그래프(아래)의 여러 연결된 노드로 변환됩니다.

일반적인 그래픽 애플리케이션은 실제 또는 암시적 의미론적 장면 그래프의 노드를 변환하여 렌더링 장면 그래프를 구축합니다.
의미론적 장면 그래프에서 렌더링된 장면 그래프를 생성하는 데 사용된 동일한 기술을 사용하면 렌더링된 장면 그래프는 의미론적 장면 그래프(아래)를 탐색하는 동안 필요에 따라 동적으로 생성되는 작은 장면 그래프 조각의 숲이 됩니다. 어느 정도 의미론적 장면 그래프와 렌더링 장면 그래프의 분리는 버스 시스템인 장면 그래프를 연상시킵니다. 그러나 렌더링된 장면 타일의 숲은 의미론적 장면 그래프로부터 완전히 재구성될 수 있으며 장면 그래프의 확장되거나 번역된 버전을 나타낼 수 있습니다.

동적 변환 중에 의미론적 장면 그래프는 렌더링된 장면 그래프 조각의 숲으로 변환됩니다.
렌더링된 장면 그래프를 정말 동적으로 만들려면 전환 단계에서 상태를 도입하고 장면 그래프를 탐색하여 기존 렌더링된 장면 그래프 조각을 수정하여 새 상태를 반영하도록 허용합니다(아래 이미지). 이는 현재 번역 상태를 포함하는 규칙 객체의 생성자 기능을 포함하는 번역 규칙 사전을 생성함으로써 달성되었습니다. 이러한 규칙 객체의 각 생성자는 번역된 의미론적 장면 그래프 노드에 해당하는 렌더링 장면 그래프 조각을 만들고 이에 대한 참조를 저장합니다.

각 의미론적 장면 그래프 노드의 동적 번역은 현재 번역 상태를 포함하는 규칙 객체를 생성합니다. 각 규칙 객체에는 렌더링된 장면 그래프 조각에 대한 참조가 포함되어 있습니다. 이 구조는 MVC(Model-View-Controller) 디자인 패턴의 변형으로 볼 수 있습니다.
또한 이 기사에서는 구현 세부 사항과 적용 사례에 대해 자세히 설명합니다. 관심 있는 어린이 신발은 원문을 클릭하여 읽어보실 수 있습니다.
파이프라인 확장은 Frostbite 2 엔진의 자산 관리 및 파이프라인 확장을 공유합니다.
Frostbite 2 엔진 자산 파이프라인의 목표는 다중 사이트 협업(상하이, 유럽, 북미), 대규모 팀(경우에 따라 400명 이상의 직원), 다중 VCS 지점, 다양한 대상 플랫폼(PC, PS3, Xbox 360) 및 콘텐츠가 풍부한 게임을 지원하는 것입니다.
Battlefield 3의 크기는 기본 DCC 자산 500GB, 기본 Frostbite 자산 80GB, 파일 100,000개, 대상 데이터(PC) ~18GB, 개별 빌드 단계(PC) 100,000개에 달했으며 당시 개발 중인 게임은 훨씬 더 컸습니다.
Frostbite 엔진의 자산 파이프라인은 아래와 같습니다. 구조화된 스토리지를 사용하고, 빌드 중심이며, 단일 자산 로딩 경로를 가지며, 항상 대상에서 미리 볼 수 있고, 자산 핫 스와핑, 직접 경로 조정 및 게임 내 일부 명시적인 실시간 편집 코드를 지원합니다.

자산 패키징 모델은 아래 그림에 나와 있습니다.

묶음. 자산의 선형 흐름(일반적으로), 수준, 하위 수준(스트리밍), 선형 읽기 전용(푸시).
데이터 블록(청크). 무료 스트리밍 청크, 텍스처 밉, 동영상, 메시, 랜덤 액세스(풀).
Superbundle은 번들과 데이터 블록을 저장하는 컨테이너 파일입니다. 슈퍼 번들이 설치되면 내부 데이터가 표시됩니다.
개발 중에 레이아웃은 번들 및 슈퍼 번들에 대한 전체 설명을 저장하고 블록 참조가 있는 패키지로 저장되는 Avalanche Storage Service에 저장되며, 게임/도구에서 요청할 때(HTTP를 통해) 번들이 즉시 조립됩니다. 게임은 네트워크 빌드와 디스크 빌드(단일 경로)의 차이점을 알지 못합니다. 각 빌드 프로세스는 반복 빌드를 포함하여 완전한 패키징 논리를 수행합니다! 그래서 매우 빨라야 합니다.
자산 파이프라인 목표: 빌드 대기 시간 = 낭비, 부팅 시간 최적화(초기 빌드), 빌드 처리량, 피드백 시간 최적화(반복 빌드), 대규모 게임에는 확장성이 뛰어난 솔루션이 필요함, 도전적입니다! 또한 약간은 감사할 일이 아닙니다... 사람들이 당신의 작업을 알아차린다면 아마도 당신이 뭔가를 망가뜨렸거나 너무 느리기 때문일 것입니다!
다음은 스토리지 아키텍처와 해당 지연 시간 및 처리량 비율입니다.
저장 유형 지연 처리량
등록하다 < 1ns
- 캐시 < 10ns
100G/초
기억 < 500ns
1G/초
네트워크 캐시 < 50μs
- SSD < 200μs
200M/초
HDD < 20ms
50M/초
이는 캐시 계층 구조이며 캐시가 클수록 성능 향상에 도움이 되며 여유 시스템 RAM이 캐시로 사용됩니다. 워크스테이션에 많은 메모리를 넣는 것을 잊지 마십시오. 그러면 I/O의 영향이 줄어들고 작업 세트는 여유 RAM에 맞을 것입니다. -> 좋습니다! 작업 세트가 시스템 캐시에 맞지 않으면 CPU가 L1/L2/L3 캐시에 없을 때 작동하는 것처럼 성능이 저하됩니다.
캐시 구현 빌드:
- 빌드 입력에서 생성된 키입니다. 입력 파일 콘텐츠(SHA1), 기타 상태(빌드 설정 등), 빌드 기능 버전("수동" 해싱).

캐시 가능한 빌드 기능은 두 단계로 나뉩니다. 첫 번째 단계에서는 모든 입력을 기록하고 두 번째 단계에서는 작업을 수행합니다.
스케줄러를 빌드합니다. 첫 번째 단계를 실행하고, 캐시를 쿼리하고, 가능한 경우 결과를 사용하고, 그렇지 않으면 두 번째 단계를 실행합니다.
모델을 구축하려면 소스 데이터를 대상에 매핑하는 함수를 적용해야 합니다.
목표: 순수한 기능, 부작용 없음! 단순 병렬성
자산 데이터베이스: Avalanche Storage Service에서 관리되는 데이터는 일반 데이터 구축 프로세스와 마찬가지로 데이터를 데이터베이스로 "가져오는" 매핑 프로세스의 결과로 발생하는 저장소 구축(예: 로그 구조화)과 유사한 구현입니다. 데이터는 기본 형식 파일 또는 기타 데이터 소스(SQL, Excel 등)에서 가져올 수 있으며 저장에는 데이터베이스 자산을 파일로 다시 "내보내는" 작업(예: 역방향 매핑)이 포함됩니다.
이러한 데이터베이스의 이점은 구축하기 전에 디스크에 저장(또는 체크아웃)할 필요가 없다는 것입니다. 빌드의 스냅샷 격리; 여러 세션을 생성하기 위한 저렴한 분기(예: 서로 다른 설정으로 동일한 레벨/객체/셰이더를 나란히 미리보기) 빌드 시스템과의 긴밀한 통합 빠른 동기화, 몇 초 만에 실행, 지연된 가져오기 등이 가능합니다.
파이프 절단: 1초 미만의 반복 시간 달성은 수요 반복에 신속하게 대응하고 생산성과 품질을 높이며 파이프라인 지연을 최적화하는 반복 프로세스를 제안합니다. 논문에서 제안하는 반복 프로세스는 다음과 같습니다.

더 빠른 반복 시간이 필요한 이유는 생산성을 높이고 빌드 대기 시간을 줄이기 위한 것입니다. 품질을 높이고 더 많은 조정 및 자산을 추가하여 콘솔 게임에서 테스트할 수 있습니다.
장면을 편집할 때 캐싱 대신 실시간으로 편집하지만 실시간 편집에는 게임이 항상 최고의 편집기는 아니며, 게임 데이터가 사용 중인 바이너리 이미지인 경우 버전 제어가 까다롭고, 함께 작업하고 변경 사항을 병합하는 것도 까다로우며, 편집에 적합한 데이터 형식이 최고의 런타임 성능을 갖지 못합니다.
빠른 반복을 위한 두 가지 장점 중 가장 좋은 점은 빠른 게임과 빠른 워크플로입니다. 빠른 게임에는 바이너리 리소스, 내부 로드 및 검색 시간이 필요하지 않습니다. 빠른 워크플로에는 짧은 컴파일 시간, 핫 리로딩 및 즉각적인 피드백이 필요합니다. 공격적인 전략은 가능한 한 빨리 컴파일하고 다시 시작을 다시 로드로 바꾸는 것입니다.

모든 데이터(>1GB)를 다시 컴파일하고 다시 로드하는 것은 결코 충분히 빠르지 않으며 작은 덩어리로 수행되어야 합니다. 게임 데이터를 개별 리소스의 모음으로 생각하십시오. 각 리소스는 개별적으로 컴파일한 다음 게임이 실행되는 동안 다시 로드할 수 있으며 유형 + 이름으로 식별됩니다. 둘 다 고유 문자열 식별자(해시됨)이고 이름은 경로에서 가져오지만 ID로 처리될 수 있습니다(동등 비교를 통해서만).
리소스가 컴파일되면 각 리소스는 이름 해시로 식별되는 플랫폼별 런타임 최적화 바이너리 청크로 컴파일됩니다.

리소스를 로드할 때 리소스는 로드할 패키지로 그룹화됩니다. 패키지는 백그라운드 스레드를 통해 스트리밍됩니다. 개발 중에 리소스는 해시라는 이름의 개별 파일에 저장됩니다. 최종 릴리스의 경우 선형 로딩을 위해 패키지의 파일이 함께 번들로 제공됩니다.

리소스 다시 로드: TCP/IP 포트에서 게임 수신 대기를 실행합니다. 메시지는 JSON 구조, 내부 도구의 일반적인 명령, 성능 HUD 활성화, 디버그 라인 표시, Lua REPL(읽기-평가-인쇄-루프), 리소스 다시 로드, 모든 도구 시각화에도 사용됩니다.
리소스 다시 로드에 대한 세부 정보: 새 리소스 로드, 유형에 따라 게임 시스템에 알리기, 이전 리소스와 새 리소스에 대한 포인터, 게임 시스템에서 인스턴스 삭제(사운드), 인스턴스(입자) 중지 및 시작, 인스턴스 유지, 업데이트(텍스처), 이전 리소스 삭제/언로드 등 수행할 작업을 결정합니다.

// 로드 리소스
if (type == unit_type)
{
for (unsigned j=0; j<app().worlds().size(); ++j)
{
app().worlds()[j].reload_units(old_resource, new_resource);
}
}
void World::reload_units(UnitResource *old_ur, UnitResource *new_ur)
{
for (unsigned i=0; i<_units.size(); ++i)
{
if (_units[i]->resource() == old_ur)
_units[i]->reload(new_ur);
}
}
void Unit::reload(const UnitResource *ur)
{
Matrix4x4 m = _scene_graph.world(0);
destroy_objects();
_resource = ur;
create_objects(m);
}문제: 콘솔에 데이터 배포, 대량의 리소스 처리, 느린 리소스 컴파일, 코드 다시 로드. 일부 문제는 다음과 같이 해결됩니다.
훌륭한 자원. 매우 큰 자산(>100MB)을 신속하게 컴파일 및 로드할 수 없고, 올바른 리소스 세분성을 찾을 수 없으며, 모든 레벨의 지오메트리를 하나의 파일에 넣지 말고, 엔터티가 있는 지오메트리를 별도의 파일에 두고, 레벨 개체가 사용하는 엔터티를 참조하도록 할 수 없습니다.
느린 리소스. 긴 컴파일로 인해 빠른 반복이 불가능하고(라이트맵, 내비메시 등), 베이킹과 컴파일이 별도로 이루어지며, 베이킹은 항상 명시적인 단계입니다. "지금 라이트맵 만들기"(편집기 버튼), 구운 데이터는 소스에 저장되고 저장소에 체크인된 다음 평소대로 컴파일됩니다(원시 텍스처에서 플랫폼 압축까지).
코드를 다시 로드하세요. 다시 로드는 가장 까다로운 리소스입니다. 4개의 코드(셰이더(Cg, HLSL), 바이너리 스트림(비주얼 스크립팅), Lua, C++), 스트림 및 셰이더는 바이너리 데이터인 범용 리소스로 처리됩니다.

LUA의 실시간 재로드는 아래와 같습니다.

C++ 코드 다시 로드: 도구는 "Restart Exe"를 지원합니다. exe는 다시 로드되지만 여전히 동일한 위치에 동일한 개체가 표시됩니다. 새 엔진 코드만 있으면 상태는 도구에 의해 유지됩니다. <1s 목표에 도달하지 못했지만 여전히 매우 유용하며 작은 exe 크기가 도움이 됩니다.
범례를 빠르게 컴파일하십시오.

증분 컴파일도 지원됩니다. 마지막 컴파일 이후 수정된 모든 소스 데이터를 찾고, 이러한 파일에 의존하는 런타임 데이터를 확인하고, 필요한 부분을 다시 컴파일합니다. 중요한 것은 프로세스가 견고하고, 신뢰를 얻기 어렵고 쉽게 잃을 수 있다는 것입니다. "완전한 재컴파일이 가장 안전합니다".

의존성은 어려운 일입니다. base.shader_source에는 common.shader_source가 포함되어 있습니다. common.shader_source가 변경되면 다시 컴파일해야 합니다. 각 파일을 읽지 않고도 이를 어떻게 알 수 있습니까? 해결 방법: 이전 실행의 정보를 저장하는 데이터베이스를 컴파일하고, 시작 시 열고, 종료 시 업데이트를 저장합니다. 파일이 컴파일되면 해당 종속성이 데이터베이스에 저장되고 open_file()을 추적하여 자동으로 결정됩니다.
바이너리 버전도 문제입니다. 텍스처 리소스의 바이너리 형식이 변경되면 각 텍스처를 다시 컴파일해야 합니다. 해결 방법은 데이터베이스를 재사용하는 것입니다. 컴파일된 각 리소스의 바이너리 버전을 데이터베이스에 저장하고, 데이터 컴파일러에서 현재 버전을 확인하고, 일치하지 않으면 다시 컴파일하고, 데이터 컴파일러와 런타임에 동일한 코드베이스(동일한 exe라도)를 사용하여 바이너리 버전이 항상 동기화되도록 합니다.
컴파일러를 시작하고 종료하는 데에는 컴파일러 프로세스를 시작하고 종료하는 데 몇 초밖에 걸리지 않습니다. 해결책: 프로세스를 재사용하세요! 서버로 실행되며 TCP/IP를 통해 컴파일 요청을 받습니다.

다음 코드일 수 있는 소스 파일을 스캔합니다.
foreach (file in source)
dest = destination_file(file)
if mtime(file) > mtime(dest)
compile(file)이 방법은 속도가 느리고 각 프로젝트 파일의 mtime을 확인하며 조각화되어 있습니다(날짜에 따라 다름). 목록을 명시적으로 컴파일해 보세요. 도구는 다시 컴파일할 파일 목록을 보내고, 도구는 변경된 파일을 추적하고, 텍스처 편집기는 사용자가 변경한 모든 텍스처를 알고 있습니다. 빠르지만 조각화되어 있습니다. 도구 svn/git/hg 업데이트, Photoshop에서 편집된 텍스처, 텍스트 편집기에서 편집된 Lua 파일 외부에서는 작동하지 않습니다.
해결책: 디렉터리 감시자. 서버 시작 시 전체 스캔을 수행하고, 초기 스캔 후 디렉터리 모니터링을 사용하여 변경 사항을 감지하고, ReadDirectoryChangesW(...)를 사용하여 추가 스캔 없이 데이터베이스를 사용하여 취약점을 방지합니다. 스캔 중에 mtime 또는 파일 크기가 다른 경우 마지막으로 성공한 컴파일의 mtime을 데이터베이스에 저장합니다. - 다시 컴파일하고, 디렉터리 감시자가 변경 사항을 알리면 - 다시 컴파일합니다. 그러나 조건 경쟁이 발생하게 되는데, 이는 아래와 같이 해결될 수 있습니다.

종속성의 경우 프로세스가 파괴되지 않으므로 종속 데이터베이스를 메모리에 저장할 수 있으며 서버가 시작될 때 디스크에서 읽기만 하면 됩니다. 데이터베이스는 백그라운드 프로세스로 디스크에 저장할 수 있습니다. 재컴파일이 필요한 경우 데이터베이스가 저장될 때까지 기다릴 필요가 없습니다. 나중에 컴파일러가 유휴 상태일 때 저장됩니다.
최종 처리: 요청을 처리할 때 유일한 디스크 액세스는 수정된 파일을 컴파일하고 디렉터리 감시자 "펜스" 파일을 생성하는 것입니다. 그렇지 않으면 모든 것이 메모리에서 발생합니다. 결과는 다음과 같습니다.


일반 규칙:
리소스 세분성을 고려하세요. 별도의 컴파일/다시 로드에 적합한 크기입니다.
TCP/IP는 당신의 친구입니다. 디스크에 액세스하는 것보다 네트워크를 통해 작업을 우선적으로 수행하고 프로세스를 서버로 실행하여 시작 시간을 방지합니다.
데이터베이스 + 디렉토리 감시자를 사용하여 파일 시스템 상태를 추적합니다. 데이터베이스는 컴파일러 실행 사이에 다른 정보를 캐시하여 메모리에 유지하고 백그라운드에서 디스크에 반영할 수도 있습니다.
비행기 조합 Midair는 게임의 AI 행동 트리에 대한 몇 가지 일반적인 디자인 패턴에 대해 이야기했습니다. 스크립트, 계층적 유한 상태 머신 및 동작 트리의 장점, 단점 및 특성:
유형 장점 단점
스크립트 완전하고 직접적인 게임 제어 많은 모듈과 시스템에서 널리 사용될 수 있습니다. 디버깅 및 최적화가 어려움 설계자의 상당한 엔지니어링 전문 지식이 필요합니다.
계층적 유한 상태 머신 직관적인 디자이너 좋은 낮은 수준의 컨트롤 확장 및 재사용이 어려움 목표지향을 달성하기 어려움
행동 트리 스크립트의 강력함과 유연성을 활용하여 디자이너를 위한 간단한 시각적 언어로 만듭니다. 계층화된 FSM의 직관적이고 반응적인 기능을 활용하여 재사용 가능하고 목표 지향적으로 만듭니다.

비헤이비어 트리 범례.
행동 트리에는 여러 유형의 노드가 있습니다.
순서: AND(&&).
선택기: 또는(||).
데코레이터: FOR 루프.
조건 : 게임 상태를 확인합니다.
액션: 게임플레이 상호작용.
행동 트리를 구현하기 위한 디자인 모델은 다음과 같습니다:
- 복합. 사용자 정의 노드 및 동작 트리.

- 플라이급. 동일한 행동 트리를 사용하여 정의된 여러 AI 캐릭터.

- 방문자. 각 AI 캐릭터는 동일한 나무를 걸으며 자체 상태를 유지할 수 있어야 합니다.

디자이너가 단일 언어로 학습하고 전문가가 되어 업데이트 기반 AI 스크립트와 이벤트 기반 레벨 스크립트를 빠르게 실행할 수 있도록 하는 것이 목표인 이벤트 중심 트리(Event-Driven Tree)도 있습니다. 이벤트 중심 트리는 한 번만 틱한다는 점을 제외하면 업데이트 중심 트리와 같습니다.
2012년 양방향 반복 재투영을 사용하여 렌더링 파이프라인 가속화에서는 반복 재투영 및 양방향 재투영을 사용하여 렌더링 파이프라인을 가속화하는 기술을 설명했습니다.
현재 그래픽 아키텍처는 모든 프레임에 대해 무차별 대입 렌더링을 요구하므로 높은 프레임 속도에 맞게 확장되지 않습니다. 그러나 시간적 일관성으로 인해 근처 프레임은 매우 유사한 경우가 많으며 인접한 프레임의 렌더링 결과를 재사용함으로써 래스터라이제이션 및 셰이딩을 수행하지 않고도 합리적인 프레임을 합성할 수 있습니다.

프레임 간 보간 다이어그램.
실시간 재투영과 관련된 전략은 다음과 같습니다.
대상 관점에서 장면을 래스터라이제이션하고 소스 관점에서 샘플 음영을 래스터라이제이션합니다. (네하브2007)
픽셀당 프리미티브를 사용하여 기존 프레임을 대상 시점으로 워프합니다. (마크1997)
근사치를 사용하세요. (Andreev2010, Didyk2010)
반복 검색을 사용하여 프레임을 왜곡합니다. (양2011, 보울스2012)
렌더러를 사용하여 생성된 렌더링된 프레임이 있다고 가정하면, 렌더링된 프레임이 주어지면 새 프레임을 어떻게 합성할 수 있습니까? MV(모션 벡터)는 렌더링 파이프라인에서 공통적으로 파생된 데이터로, 소스 프레임에서 대상 프레임으로의 매핑을 제공합니다.

반복 투영의 개략도.
이미지 기반 반복 재투영 프로세스는 다음과 같습니다.
- 다음 방정식을 통해 각 픽셀의 매핑을 알아보세요.
대상 프레임:
에서 GPU 셰이더를 실행하는 것이 알려져 있습니다. 를 구문 분석하는 방법은 무엇입니까? 반복적으로 구문 분석할 수 있습니다.

- 고정 소수점 반복. 알고리즘은 다음과 같습니다.
출발점을 선택하세요:

(예:
- 수렴할 때까지 재귀 관계를 적용합니다.

.

1~4차 반복은 왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래입니다.

여러 가지 방법의 성능 비교.
간단히 말해서 반복 초기화는 FPI가 가장 가까운 솔루션으로 탐욕스럽게 수렴하는 것입니다. 아래 소스 이미지에 표시된 것처럼 대상 이미지에서 이동하고 궁극적으로 겹치도록 구성된 두 구의 예입니다. 세 가지 솔루션 - 대상 이미지에 있는 소스 이미지의 표면 점 3개, MV에서 불연속성을 생성하는 모션 경계(빨간색으로 표시). 각 영역에서 반복을 시작하면 반복을 시작하려는 가장 가까운 솔루션이 반환됩니다.

쿼드로 세분화하고 뒤틀린 위치에서 래스터라이제이션합니다.

정지해 있는 자동차 픽셀과 빠르게 움직이는 도로 픽셀 사이에 큰 모션 불연속성이 있어 소스 뷰에서 자동차 뒤 영역이 가려지는 특별한 경우가 있습니다. (아래 사진)

이전에도 불연속성 문제를 해결하기 위한 몇 가지 방법이 있었습니다.
다시 칠하기(Nehab2007). 장면을 다시 탐색해야 합니다.
수정되었습니다(Andreev2010, Bowles2012). 이미지를 기준으로 구멍 크기와 해당 영역의 시각적 눈에 띄는 정도에 따라 다릅니다.
양방향 재투영(Yang2011).
이 기사에서는 두 개의 소스 이미지를 재투영하는 자체 솔루션을 제안합니다.

장면: 프레임 보간: I 프레임(프레임 내 또는 키 프레임) 렌더링, 보간된 B 프레임(양방향 보간 프레임) 삽입, 이것이 **양방향 재투영(Bireproj)**입니다.

각
프레임 쌍에 대한 모션 흐름 필드를 생성합니다. 프레임의 각 픽셀 에 대해:
역류장
에서 검색하여 $ I t +1$로 재투영합니다. 및 프레임에서 색상을 로드하고 혼합합니다.

모션 흐름 필드는 𝛼와 관계없이 I 프레임
와 사이의 픽셀을 매핑합니다. 와 사이의 움직임이 선형이라고 가정합니다. 벡터를 𝛼(또는 1−𝛼)만큼 확장합니다. 반복 재투영을 사용하여
를 해결합니다.

후속 단계에는 모션 벡터 필드 생성, 올바른 픽셀 선택, 추가 검색 초기화 및 파티션 렌더링이 포함됩니다.

올바른 픽셀을 선택하세요

추가 검색 초기화

파티션 렌더링
제한사항:
- 동적 음영 보간.
나쁨: 하나의 소스에만 표시되는 경우 작동하지 않습니다.
양호: 각 B-프레임이 문제의 구성요소를 분리하고 렌더링합니다.
빠르게 움직이는 얇은 물체의 가시성.
나쁨: 재투영이 올바르게 초기화되지 않을 수 있습니다.
좋음: 강력한 초기화를 사용합니다(DX 10+ 레벨 하드웨어 사용).
Bireproj에는 약간의 지연이 발생합니다.
나쁨: 위치 지연이 1(I-프레임) 시간 단계보다 작습니다.
- 좋음: 응답 대기 시간이 최소화됩니다(대략 0과 동일).
요약하자면, 음영 처리 결과를 재사용하여 중복 계산을 줄입니다. 반복적인 이미지 기반 재투영은 순전히 이미지 기반(장면을 탐색할 필요 없음)이며 PS3(1280x720)에서 0.85ms로 빠르며 적절한 초기화를 통해 매우 정확한 재투영입니다. 양방향 재투영은 사실상 폐색 아티팩트를 제거하고 프레임 속도를 거의 n(보간된 프레임 수)배 증가시키며 동적 셰이딩 변경 사항을 삽입합니다.
[Deus Ex는 세부 사항에 있습니다](http://twvideo01.ubm-us.net/o1/vault/gdc2012/slides/Programming Track/DeSmedt_Matthijs_Deus Ex Is.pdf)에서는 DirectX 11의 특성과 응용 프로그램을 설명합니다.
DirectX 11 GPU 최적화에는 읽기 전용 깊이 버퍼, 컴퓨팅 셰이더 로컬 저장소 및 컬렉션 지침이 포함됩니다. 초기 CPU는 병목 현상, 장면의 많은 고유 개체, 매우 유연한 재질 시스템, 너무 많은 상태 변경, 드로콜 간의 상태 변경 최소화(인스턴스화, 상태 개체, 상수 버퍼, 풀링된 정적 버텍스 및 인덱스 버퍼)였습니다.
상태 개체는 재료의 BlendState, 해시 테이블의 JIT 생성 및 캐싱과 같은 영구 개체에 바인딩됩니다. 해시 생성 매개변수는 Create...State보다 효율적이며 생성에는 여전히 시간이 걸리고 시작 중에 상태 개체가 준비될 수 있습니다. 상수 버퍼는 조명 상태(포워드 렌더링용), 재질 매개변수, 인스턴스 매개변수 및 업데이트 빈도로 구분된 기타 상수(드로어블, 장면)와 같은 객체에 바인딩됩니다.
DirectX 11을 통해 얻은 효과에는 앤티앨리어싱, SSAO, 뎁스 오브 필드(DoF), 테셀레이션, 부드러운 그림자 등이 포함됩니다.

DX11에서 구현된 여러 가지 앤티앨리어싱.

PS와 CS의 가우시안 블러 성능 비교. 컨볼루션 커널이 클수록 CS 가속이 더 분명해집니다.
콘솔의 SSAO는 StarCraft 2와 유사하게 깊이, 반구의 PC 샘플을 흐리게 하고 왜곡을 줄이며 오버헤드를 증가시킵니다. SSAO 양측 흐림은 DX9에서 9x9 코어 픽셀 셰이더를 사용하는 반면, DX11은 19x19 코어 분리형 컴퓨팅 셰이더를 사용하므로 더 부드럽고 소음이 줄어들며 성능에 미치는 영향이 적습니다. SSAO 자체 폐색 문제: 깊이 버퍼가 노멀 매핑되지 않고 과장된 노멀 맵으로 인해 반구가 평면 형상과 교차하며 사용 가능한 버텍스 노멀이 없습니다. 해결 방법: 깊이 버퍼에는 형상이 포함되어 있습니다. 뷰 공간 버텍스 노멀을 원할 경우 SSAO에서 뷰 공간 위치를 계산하세요. ddx() 및 ddy()는 모든 변수의 기울기를 반환합니다. 뷰 공간 버텍스 노멀 재구성: Normalize(ddx(viewpos)×ddy(viewpos)).
테셀레이션 균열(아래)은 여러 하위 메시, 동일한 위치의 여러 버텍스 및 불연속 법선으로 구성된 캐릭터로 인해 발생합니다. 테셀레이션 균열 솔루션: "테셀레이션 노멀" 채널 생성, 해당 위치에 있는 모든 정점의 노멀 균등화, 삼각형 크기에 따라 가중치가 부여된 노멀, 메시 경계의 균열 복구, 낮은 오버헤드.

인레이 돌출 문제: 단단한 가장자리가 부드러운 법선으로 변경됩니다. 이 문제는 일부 모델에서 발생합니다. 법선을 평균화하여 균열을 복구합니다! 퐁 테셀레이션은 원형 기하학을 만듭니다. 해결 방법: 아티스트는 가장자리 주위에 추가 다각형을 추가합니다.

테셀레이션 최적화: 약 10m 거리에 대한 테셀레이션 활성화, 비활성화하기 전에 테셀레이션 페이드 아웃, Hull 셰이더를 간단하고 빠르게 유지, 거리만을 기준으로 테셀레이션, 최대 테셀레이션 계수 3.0, 계수 0.0으로 뒷면 삼각형 컬링.
소프트 섀도우에는 소프트 PCF를 완성하기 위해 SM5 셰이더, 9x9 필터 커널이 필요합니다. GatherCmpRed를 사용하여 4개의 샘플을 얻습니다. 부드러운 그림자 문제: 모든 그림자 투사 조명이 전방 조명을 사용하여 렌더링되면 9x9 커널은 컴파일하는 데 몇 초밖에 걸리지 않으므로 셰이더 빌드 시간이 폭발적으로 늘어나고 모든 조명이 지연될 위험이 너무 큽니다. 해결 방법: 화면 공간에서 지연된 부드러운 그림자를 렌더링합니다. 게임에는 반투명에 사용되지 않고 전방 조명 중 부드러운 그림자 버퍼의 샘플인 하나의 셰이더만 필요합니다.
다중 모니터 렌더링은 모든 구성을 지원해야 하는 공급업체별 API 확장을 사용합니다. 베젤의 십자선을 처리하는 방법은 무엇입니까? 중심에서 벗어난 투영 매트릭스를 사용하여 기본 디스플레이의 원래 시야를 유지하고 FOV가 높을 때 이를 클리핑 평면 근처로 뒤로 당겨 데칼의 깊이 편차를 늘립니다.
입체 렌더링은 공급업체별 API 확장을 사용하여 입체 투영 매트릭스의 한 번의 컬링만으로 각 눈의 프레임을 렌더링합니다.
Unity로 DirectX 11 마스터하기는 NVIDIA와 Unity 개발자들이 Unity에서 DirectX 11의 렌더러, 새로운 기능 및 효과에 대해 공유하는 주제입니다.
당시 Unity의 새로운 기능에는 Unity DirectX 11 렌더러, Unity "물리 기반" 셰이더, 수정된 조명 파이프라인, Catmull-Clark 테셀레이션, 블렌드 셰이프, PointCache(PC2) 지원, 반사(큐브맵, 쿼드) 프로브, 포스트 프로세싱 및 증분 라이트맵 베이킹이 포함되었습니다.
Unity "물리 기반" 셰이더: Mental Ray "Architecture"(MIA) 셰이더에서 영감을 얻었으며 대부분의 단단한 표면 재료(금속, 목재, 유리, 점토)의 고품질 오프라인 렌더링에 충분하며 CG/비게임 아티스트에게 친숙하며 물리적 기반을 사용하면 매개변수 수가 줄어들고 에너지 보존으로 인해 재료를 설정할 때 물리 법칙을 어기는 것이 (다소) 불가능하며 예측 가능한 결과로 직관적인 해킹이 방지되며 거의 모든 것에 대해 1개의 셰이더만 사용됩니다.
디퓨즈를 위한 Oren-Nayar, 1개 매개변수: 러프니스, Lambert(러프니스 == 0), 다양한 근사치.
스페큘러 반사: Cook-Torrance, 2개 매개변수: 러프니스(광택), 반사율, 에너지 보존, 물리학에 기초한 미시적 수준 이론.
프레넬 곡선 - 반사율이 보는 각도에 따라 달라지는 방식, 2개의 매개변수: 카메라를 향함(0도), 카메라에 대해 90도, Schlick 근사법을 사용하여 보간됨:
에너지 보존: 확산 + 반사(+ 굴절) <= 1, 열역학 제1법칙, 반사율은 디퓨즈와 투명도에서 에너지를 얻습니다. 반사율을 높이면 확산 에너지가 감소하며, 100% 반사는 결코 확산되거나 투명하지 않습니다! 투명도는 디퓨즈, 표준 알파 블렌딩에서 에너지를 흡수합니다. Cook-Torrance와 Oren-Nayar는 모두 강렬한 하이라이트가 좁고 넓은 하이라이트가 덜 강렬한 원래 Blinn-Phong과 달리 에너지를 절약합니다.

흐릿한 반사, 다양한 밉레벨(LODbias)을 샘플링하여 얻은 낮은 품질의 흐림, DX9/GL은 큐브맵 가장자리 전체에 대한 복구가 필요하고 평면 반사에서는 작동하지 않으며 상자 필터링만 가능합니다. 여러 번 샘플링하고, 표면 노멀을 구부려 거친 표면의 마이크로패싯을 시뮬레이션하고, 뷰 방향을 반영하는 "구부러진" 법선을 기반으로 다양한 노멀 분포를 시뮬레이션하여 흐림 품질(1..8)을 향상시킵니다.

2개의 노멀 맵 결합: 아티스트는 상세한 노멀 맵을 원하며, 2개의 노멀 맵을 혼합하면 둘이 "평탄화"되고, 2개의 높이 맵을 혼합하는 것과 동일한 결과를 얻고 싶어합니다. 첫 번째 노멀 맵의 법선을 사용하여 두 번째 노멀 맵을 워핑합니다.
float3x3 nBasis = float3x3(
float3 (n1.z, n1.x,-n1.y),
float3 (n1.x, n1.z,-n1.y),
float3 (n1.x, n1.y, n1.z ));
n = normalize (n2.x*nBasis[0] + n2.y*nBasis[1] + n2.z*nBasis[2]);
노멀맵 2개를 합친 예입니다. 왼쪽부터: 노멀 없음, 세부 법선만, 결합된 노멀.
"물리적 기반" 셰이더 최적화:
작은 코드 커널: 최적화가 쉽고 스킨 및 자동차 색상 코드도 동일합니다.
소비: 평균 90개의 ALU 명령어, 최대 270개의 ALU 명령어, 최대 24개의 텍스처 가져오기.
배열: 매개변수 값을 기준으로 선택합니다. 확산 러프니스 = 0인 경우 OrenNayar 대신 Lambert를 사용하고 다른 OrenNayar 근사치를 사용하고 광택 값은 반사 텍스처 샘플 수에 영향을 미칩니다.
전역 조명: Unity는 라이트 맵 베이킹에 Beast 사용을 지원하며 간접 조명만 라이트 맵에 저장됩니다. 라이트 프로브는 동적 객체를 조명하는 데 사용되며 반사 프로브에는 큐브맵(무한 거리 반사)과 사면체(국소 반사)가 포함되어 있습니다.

라이트 프로브의 사면체.
앰비언트 오클루전(AO): NVIDIA에서 개발한 HBAO(Horizon-based Ambient Occlusion)는 정의에 따라 직접 조명에 영향을 주어서는 안 됩니다! 그렇지 않으면 더러워 보입니다. SSAO를 가능한 한 빨리 계산하고 그 결과를 픽셀 셰이더에 입력합니다. min(bakedAO, objectAO, SSAO)은 간접 라이트맵, 라이트 프로브 및 반사에서만 작동합니다.
기사에서 언급된 DX11의 특수 효과로는 APEX 파괴, 헤어 파이프라인, 볼륨 폭발, 모션 블러 등이 있습니다.

NVIDIA APEX를 위한 확장 가능한 동적 프레임워크.

APEX로 인해 손상된 워크플로.
헤어 파이프라인: 머리카락과 털은 게임 캐릭터에게 다음으로 큰 도전 과제입니다. 애니메이션과 피부 셰이딩이 좋아지면 품질이 낮은 머리카락이 더욱 뚜렷해집니다. Unity 헤어 시스템은 오프라인 시스템과 최대한 유사하게 설계되었습니다. 헤어 스타일은 Softimage XSI/Maya/MAX에서 모델링하고 PC2 포인트 캐시 형식을 사용하여 Unity로 내보낼 수 있습니다. DirectX 11 테셀레이션 렌더링이 사용됩니다. 렌더링된 머리카락 형상의 생성은 전적으로 하드웨어에서 수행됩니다. 기하학 증폭, GeForce GTX 580 테셀레이션 하드웨어는 매우 빠릅니다.

머리카락은 표면 세분화를 사용하여 렌더링되며, 그 동안 노이즈와 덩어리가 추가되어 사실감을 향상시킵니다. 헤어 셰이딩의 경우 시스템은 미세한 기하학적 헤어 또는 여러 헤어 이미지가 포함된 넓은 질감의 스트립을 지원합니다. 8x MSAA는 놀랍게도 잘 작동합니다. 무작위 디더링과 함께 Alpha-To-Coverage를 사용하여 블렌딩 없이 OIT를 제공합니다. 셰이더 커버리지 출력을 사용하는 투명도 슈퍼샘플링도 가능하지만 너무 비쌉니다. 셰이더는 뿌리와 끝 부분에 페이드를 포함하고 Kajiya-Kay 이방성 셰이딩 모델을 사용하며 자체 그림자, 잘못된 가장자리 조명 효과를 지원합니다.
모션 블러: 빠르게 움직이는 장면의 "가독성"을 향상시켜 영화 같은 느낌을 줍니다. Unity에는 기존의 "모션 블러" 이미지 효과가 있지만 실제 모션 블러는 아니며 이전 프레임 위에 새 프레임을 블렌딩하여 객체 뒤에 흔적을 남길 뿐입니다.
속도 버퍼 모션 블러: 속도 버퍼가 생성되고 셰이더는 화면 공간에서 이전 위치와 현재 위치 간의 차이를 계산합니다. Unity는 이전 모델 매트릭스(UNITY_MATRIX_PREV_M), 스킨 처리된 객체의 이전 월드 공간 위치(POSITION1), 깊이 버퍼에서 계산된 카메라 모션 블러 및 이전 모델 뷰 투영 매트릭스를 제공했습니다. 카메라 클립의 첫 번째 프레임에 있는 모션 블러에 주의해야 합니다! 모션 방향에서 현재 장면의 이미지를 흐리게 하려면 이러한 속도를 사용합니다.
재구성 필터 모션 블러: "합리적인 모션 블러를 위한 재구성 필터"는 현재 프레임 이미지 및 깊이와 화면 공간 속도 버퍼를 사용하고, 수집으로 분산을 시뮬레이션하고, 깊이를 사용하여 폐색을 설명하고, 외부 개체 윤곽선을 올바르게 흐리게 하며, 특히 타일 경계에서 여전히 약간의 왜곡이 있습니다.
요약하자면, DirectX 11은 오프라인 CG 세계의 기술을 통해 가능해진 최첨단 그래픽을 Unity에 제공하며 Unity를 아티스트 친화적으로 만들기 위해 설계되었습니다.
Uncharted 3에 사용된 효과 기법: Drake's Deception은 Uncharted 3의 특수 효과 시스템, 도구, 런타임 및 기타 기술 콘텐츠를 공유합니다.
Uncharted의 입자 시스템은 레이아웃(Scheme) 매크로 언어, 다목적 셰이더 및 PPU와 SPU 간의 처리 분할을 기반으로 합니다.

새로운 시스템은 반복 시간을 획기적으로 줄이고, 더 빠른 반복 == 더 많은 효과와 광택, 더 많은 데이터 중심, 더 나은 역학, 최신 기능을 갖춘 더 유연한 셰이더, 100% 비동기 SPU 코드입니다.
효과를 구축할 때 노드에서 추출된 정보는 내보내기(입자 정의, 필드, 곡선 및 경사 테이블, 표현식)에 사용되며 표현식은 VM 바이트코드로 컴파일되고 모든 데이터는 DC 형식으로 기록됩니다. 파티클부터 게임 단계까지 파티클 프로세서는 플러그인을 사용하여 대화형 DC 세션을 생성하며 DC는 빠른 반복을 달성하기 위해 향후 빌드를 가속화해야 한다고 주장합니다.

다음 그림은 입자와 관련된 관련 인터페이스를 보여줍니다.

파티클의 런타임 디자인을 위해 시스템 디자인은 하드웨어와 엔진을 고려합니다. GPU의 입자 주기 예산은 매우 제한되어 있습니다. SPU는 더 작은 세분화로 복잡한 계산 기능을 제공하지만 프로세스 수가 증가합니다.


입자 프레임과 관련된 단계:
그래프 LR A(사전 계산) --> B(업데이트) --> C(자르기) --> D(기하학 빌드) --> E(정렬) --> F(렌더링 목록 빌드)
각 단계의 세부 내용은 다음과 같습니다.
- 미리 계산됨: 충돌.
환경과의 입자별 충돌은 비용이 너무 많이 들기 때문에 근사치만 사용할 수 있습니다. 각 입자는 입자가 충돌하는 충돌 평면을 저장합니다. 각 프레임, 충돌하는 입자의 하위 집합(10)이 선택되고 환경에 대한 레이캐스트가 선택되며 결과는 다음 프레임에 반환되어 입자 데이터에 저장됩니다. 입자 평면은 프레임당 낮은 비용으로 주기적 방식으로 업데이트되며 결과는 허용 가능합니다. 일부 입자는 형상을 통과하지만 실제로 눈에 띄지는 않습니다.

- 갱신.
응용 분야. 필드에는 중력, 난류, 항력, 볼륨 축, 방사형, 소용돌이 등, 구운 애니메이션 매개변수, 볼륨 테스트, 속도에 적용된 힘이 포함됩니다.
- 바이트코드 실행. 16개의 벡터 레지스터, 비분기, 표현식 생성 및 업데이트가 있는 VM입니다.
(particle-expr runtime
(1const 0 2)
(1const 12)
(lconst 2 2)
(store 10 0)
(store 11 1)
(store 122)
(ramp 0 1 0)
(store 9 0)
(ramp 0 0 0)
(store 13 0)
(load 0 13)
(store 14 0)
)- 기하학을 자르고 구축하십시오.
선별 및 프러스텀, 꼭지점 만들기, 인덱스 만들기 및 데이터 구조 렌더링, 메모리에 쓰기.

- 종류.
입자에 설정된 각 방사체는 거리, 생성 순서, 역생성 순서로 정렬되며 아티스트는 입자기에서 방사체 그리기 순서를 설정할 수 있습니다.
- 명령 목록을 작성합니다.
RSX 출력 명령 목록, 뷰포트, 셰이더, 렌더링 상태, 버텍스 형식 등, 캐시 셰이더 및 설정을 설정합니다.
나중에 직업 체인을 설정해야 합니다. 모든 SPU에서 실행하고 싶지만 시작 후 PPU가 참여하는 것을 원하지 않습니다. 다음 단계가 실행되기 전에 각 단계를 완료해야 합니다. 각 단계마다 얼마나 많은 작업이 필요한지 모르겠습니다. 설정 작업을 사용하여 결과를 수집하고 새 작업을 설정하세요. 직업 체인은 다음과 같습니다.

이 기사에서는 모래 발자국에 대한 특별한 사용 사례도 제공합니다. 프로세스는 대략적으로 입자를 지면에 투영하고, 입자 기하학을 구축하고, 입자 투영을 하고, 깊이를 월드 공간으로 변환한 다음 입자 공간으로 변환하는 것입니다.

모래 발자국 효과.
2012년 주류 게임 엔진은 이미 디퍼드 렌더링을 지원하지만 최신 GPU용 포워드 렌더링 파이프라인은 반대 방향으로 나아가 GPU에서의 포워드 렌더링 구현에 대해 자세히 설명하고 그 잠재력과 장점을 완전히 발견하여 놀라운 효과를 달성합니다.
포워드 렌더링은 복잡한 재질, 다양한 조명 유형, 하드웨어 앤티앨리어싱, 효율적인 메모리 사용, 우수한 캐시 사용 및 엔진에서 렌더링 데이터의 향상된 분리를 지원합니다. 그러나 이전에는 하드웨어 등록 및 API 제한으로 인해 많은 수의 광원을 지원하는 것이 불가능했으며 분기가 너무 느렸습니다.
동기는 DirectX 11 이상부터 V-ray, Maxwell, Renderman 등과 같은 오프라인 셰이더에 더 가까운 셰이딩 스타일, 아티스트 및 기술 아티스트 친화적, 아이디어에서 시각적 결과까지 빠른 반복을 얻는 것이었습니다. 최신 GPU 스칼라 아키텍처에서는 적어도 이론상으로는 시각적 품질에 제한이 없으며 전체 "렌더링 방정식"이 한 곳에 있습니다. 계산 기반 전체 경로 추적으로 넘어가기 전의 우수한 래스터라이제이션 설계.
Forward+ 렌더링은 조명 컬링을 위한 컴퓨팅 셰이더를 추가하고 기본 조명 주기를 수정하는 포워드 렌더러의 변형입니다. 조명과 음영 처리는 같은 장소에서 이루어지며 모든 정보가 유지되므로 복잡한 셰이더를 다양한 방식으로 결합할 수 있는 아름다운 "빌딩 블록"으로 추상화하는 데 도움이 됩니다. 전방향, 포인트 라이트, 시네마틱(임의 폴오프, 반도어), 머티리얼 인스턴스별 고유 BRDF와 같은 라이트 및 머티리얼 매개변수에 대한 제한이 없습니다. 디자인은 간단하고, 렌더링 데이터는 런타임 C++ 엔진에서 분리되며, 새로운 복합 재질 유형을 Maya에 동적으로 추가할 수 있습니다.
Forward+ 단계: 각 "간접 조명"(옵션)에 대해 RSM 생성, VPL 생성 및/또는 동적 조명 생성 및 기존 조명 업데이트(옵션), Z 프리패스, 라이트 컬링, 셰이딩.

앞으로+개요.
광원 클리핑을 위한 셰이더 코드는 다음과 같습니다.
// 1. prepare
float4 frustum[4];
float minZ, maxZ;
{
ConstructFrustum( frustum );
minZ = thread_REDUCE(MIN, depth );
maxZ = thread_REDUCE(MAX, depth );
ldsMinZ = SIMD_REDUCE(MIN, minZ );
ldsMaxZ = SIMD_REDUCE(MAX, maxZ );
minZ = ldsMinZ;
maxZ = ldsMaxZ;
}
// 2. overlap check, accumulate in LDS
__local u32 ldsNLights = 0;
__local u32 ldsLightBuffer[MAX];
for(int i=threadIdx; i<nLights; i+=WG_SIZE)
{
Light light = fetchAndTransform( lightBuffer[ i ] );
if( overlaps( light, frustum ) && overlaps ( light, minZ, maxZ ) )
{
AtomicAppend( ldsLightBuffer, i );
}
}
// 3. export to global
__local u32 ldsOffset;
if( threadIdx == 0 )
{
ldsOffset = AtomAdd( ldsNLights );
globalLightStart[tileIdx] = ldsOffset;
globalLightEnd[tileIdx] = ldsOffset + ldsNLights;
}
for(int i=threadIdx; i< ldsNLights; i+=WG_SIZE)
{
int dstIdx = ldsOffset + i;
globalLightIndexBuffer[dstIdx] = ldsLightBuffer[i];
}색칠 단계:
장면 재료를 렌더링합니다. 기본 조명 축적 기능은 화면 xy 위치를 사용하여 TileID를 결정하고, TileID에서 조명 시작 및 끝 인덱스를 가져오고 시작 인덱스에서 끝 인덱스까지 반복합니다. 항목은 광원 배열의 인덱스이며 광원에 닿는 픽셀을 누적하고 픽셀에 닿는 전체 직접 및 간접 조명을 반환합니다.
머티리얼 셰이더. 전체 입사광을 처리하는 방법을 결정합니다. BRDF는 셰이딩 빌딩 블록, 주변광, 베이스 라이트 축적, BRDF 등을 사용하여 재료에 전달되어 최종 픽셀 색상을 형성합니다. 기본 셰이더에 영향을 주지 않고 새로운 조명 유형과 BRDF를 추가할 수 있습니다. 플랫폼에 따라 더 낮은 오버헤드 버전을 구현할 수도 있습니다.
// 라이트(Light)누적(Accumulate)코드
StructuredBuffer<float4> LightParams : register(u0);
StructuredBuffer<uint> LowerBoundLights : register(u1);
StructuredBuffer<uint> UpperBoundLights : register(u2);
StructuredBuffer<int2> LightIndexBuffer : register(u3);
uint GetTileIndex(float2 screenPos)
{
float tileRes = (float)m_tileRes;
uint numCellsX = (m_width + m_tileRes - 1)/m_tileRes;
uint tileIdx = floor(screenPos.x/tileRes)+floor(screenPos.y/tileRes)*numCellsX;
return tileIdx;
}
StartHLSL BaseLightLoopBegin // THIS IS A MACRO, INCLUDED IN MATERIAL SHADERS
uint tileIdx = GetTileIndex( pixelScreenPos );
uint startIdx = LowerBoundLights[tileIdx];
uint endIdx = UppweBoundLights[tileIdx];
[loop]
for ( uint lightListIdx = startIdx; lightListIdx < endIdx; lightListIdx++ )
{
int lightIdx = LightIndexBuffer[lightListIdx];
// Set common light parameters
float ndotl = max(0, dot(normal, lightVec));
float3 directLight = 0;
float3 indirectLight = 0;
if( lightIdx >= numDirectLightsThisFrame ) {
CalculateIndirectLight(lightIdx , indirectLight);
} else {
if( IsConeLight( lightIdx ) ) { // <<== Can add more light types here
CalculateDirectSpotlight(lightIdx , directLight);
} else {
CalculateDirectSpherelight(lightIdx , directLight);
}
}
float3 incomingLight = (directLight + indirectLight)*ndotl;
float shadowTerm = CalcShadow();
EndHLSL
StartHLSL BaseLightLoopEnd
}
EndHLSL
// 머티리얼(Material)셰이딩 스텐실
#include "BaseLighting.inc"
float4 PS ( PSInput i ) : SV_TARGET
{
float3 totalDiffuse = 0;
float3 totalSpec = GetEnvLighting();;
$include BaseLightLoopBegin
totalDiffuse += GetDiffuse(incomingLight);
totalSpec += CalcPhong(incomingLight);
$include BaseLightLoopEnd
float3 finalColor = totalDiffuse + totalSpec;
return float4( finalColor, 1 );
}
컴퓨팅 기반 디퍼드 렌더링과 Forward+의 성능 비교.
깊이 프리패스 핵심 포인트: 픽셀 오버드로잉은 Forward+를 약화시키므로 깊이 프리패스가 필요합니다. 깊이 프리패스는 MRT를 사용하여 포스트 프로덕션 효과 및 기타 렌더링 효과에 필요한 다른 전체 화면 데이터를 생성할 수 있는 좋은 기회입니다. XBOX 360은 대역폭이 좋으므로 포워드 렌더링의 한계를 감안할 때 디퍼드 렌더링이 적합합니다. 그러나 ALU 계산은 대역폭보다 빠르게 증가하고 있으며, 많은 양의 데이터를 읽고 쓰는 것보다 계산만 수행하는 것이 더 실현 가능합니다. 동적 분기는 예전만큼 성능 저하가 심하지 않으며, 최적화로서 컴퓨팅 셰이더를 조명 유형별로 정렬하여 조명 분기 페널티를 최소화할 수 있습니다. 상수 레지스터를 설정하기 위해 각 객체에 어떤 조명이 닿는지 결정하는 모든 "조명 관리" CPU 측 코드를 버릴 수 있습니다!
요약하면, 수정된 포워드 렌더러는 1000개 이상의 광원이 있는 장면을 처리할 수 있고 자동 하드웨어 앤티앨리어싱(MSAA)이며 대역폭 친화적이며 GPU의 ALU 기능(대역폭보다 빠르게 증가)을 완전히 활용하며 셰이더는 높은 시각적 품질을 위해 오프라인 셰이더와 유사할 수 있습니다.
DirectX 11을 사용한 고급 절차적 렌더링에서는 메시 생성, GPU 스트림 압축, 지오메트리 생성, 메시 개선, 동적 유체, 조명 등과 같은 DX11 기반 절차적 효과를 설명합니다.
거리 함수는 주어진 지점에서 표면까지 가장 가까운 거리를 반환합니다. 부호 거리 함수는 점에서 표면까지 가장 가까운 거리를 반환합니다. 점이 도형 외부에 있으면 양수를 반환합니다. 점이 도형 내부에 있으면 음수를 반환합니다. 부호 디스턴스 필드 절차적 지오메트리 생성에 유용한 도구, 코드에서 쉽게 정의 가능, "무작위 수식"의 합리적인 결과, 메쉬, 입자, 유체, 복셀, CSG, 왜곡, 반복, 변환에서 생성 가능, 모든 것이 쉬워집니다. 지오메트리 토폴로지에 신경 쓰지 않고 공간에서 필드를 정의하고 나중에 다각형화하기만 하면 됩니다. SDF를 사용하여 메시 세부정보를 추가하는 과정과 그림은 다음과 같습니다.

위 범례에 해당하는 의사코드는 다음과 같습니다.
// 1: 개
Box(pos, size)
{
a = abs(pos-size) - size;
return max(a.x,a.y,a.z);
}
// 2: 을(를) 활용하여
d = Box(pos)
c = fmod(pos * A, B)
subD = max(c.y,min(c.y,c.z))
d = max(d, -subD)
// 3:
d = Box(pos)
c = fmod(pos * A, B)
subD = max(c.y,min(c.y,c.z))
subD = min(subD,cylinder(c))
subD = max(subD, Windows())
d = max(d, -subD)
// 4: 의
d = Box(pos)
e = fmod(pos + N, M)
floorD = Box(e)
d = max(d, -floorD)
// 5:
d = Box(pos)
e = fmod(pos + N, M)
floorD = Box(e)
floorD = min(floorD,holes())
d = max(d, -floorD)
// 6: 결과
d = Box(pos)
c = fmod(pos * A, B)
subD = max(c.y,min(c.y,c.z))
subD = min(subD,cylinder(c))
subD = max(subD, Windows())
e = fmod(pos + N, M)
floorD = Box(e)
floorD = min(floorD,holes())
d = max(d, -subD)
d = max(d, -floorD)
// 7:
pos.y = frac(pos.y)
d = Box(pos)
c = fmod(pos * A, B)
subD = max(c.y,min(c.y,c.z))
subD = min(subD,cylinder(c))
subD = max(subD, Windows())
e = fmod(pos + N, M)
floorD = Box(e)
floorD = min(floorD,holes())
d = max(d, -subD)
d = max(d, -floorD)
// 8:
pos.xy = frac(pos.xy)
d = Box(pos)
c = fmod(pos * A, B)
subD = max(c.y,min(c.y,c.z))
subD = min(subD,cylinder(c))
subD = max(subD, Windows())
e = fmod(pos + N, M)
floorD = Box(e)
floorD = min(floorD,holes())
d = max(d, -subD)
d = max(d, -floorD)
// 9: 추가(Add)
AddDetails()
// 10: 추가(Add)라이팅 및 톤매핑(Tonemapping)
DoLighting()
ToneMap()
// 11: 추가(Add) 및
AddDeferredTexture()
AddGodRays()
// 12: 조정(Adjust),
MoveCamera()
MakeLookGood()실제 프로그래밍 방식 SDF:
생성된 장면은 3D 아티스트를 대체할 수 없습니다.
생성된 SDF는 실제 메시에 대한 좋은 프록시입니다.
아트 데이터보다 저렴한 일부 프리미티브를 결합한 코드입니다.
아티스트가 제작한 메시를 SDF로 변환하여 결합합니다.
부울, 수정, 잘라내기, 절차적 변형.
삼각형 메시의 SDF:
- 삼각형 메쉬를 3D 텍스처의 SDF로 변환합니다.
SDF 보간법은 매우 우수하며 일반적으로 쌍삼차 보간법을 사용합니다.
저해상도 3D 텍스처는 여전히 잘 작동합니다.
폴리곤 수와 무관합니다(처리 시간 제외).
종종 오프라인으로 완료할 수 있습니다.

메쉬를 64x64x64 SDF로 변환하고 다각형화합니다.
기본적인 방법은 각 셀에서 각 삼각형까지의 거리를 계산하는 것으로, 매우 느리지만 정확합니다.
메쉬를 메쉬로 복셀화한 다음 스윕하는 것은 좋은 접근 방식이 아닙니다. 스윕은 복셀에서 셀까지의 부호 있는 거리를 계산합니다. 표면 근처의 복셀화는 너무 부정확하지만 표면 근처의 거리가 중요합니다. 보간하세요.
정확한 삼각 거리와 스윕을 결합합니다.
기하학 단계: 3D 텍스처 대상 바인딩, VS를 SDF 공간으로 변환, 기하학 셰이더가 영향을 받은 슬라이스에 삼각형을 복사하고, 삼각형을 2D로 편평화하고, 위치를 텍스처 좌표로 출력하며, 각 정점에 대한 3개 위치가 모두 사용됩니다.
픽셀 셰이더 단계: 3D 픽셀에서 삼각형까지의 거리 계산, 삼각형에서 가장 가까운 위치 계산, 무게 중심을 사용하여 버텍스 노멀 평가, 가중 법선을 사용하여 거리 부호 평가, 부호 있는 거리를 출력 색상에 쓰기, 거리에서 깊이까지, 깊이 테스트에서 가장 가까운 거리 유지.
포스트 프로세스 단계: 메시 표면 주변의 셀에는 이제 정확한 부호 있는 거리가 포함되고, 메시의 나머지 부분은 비어 있으며, 포스트 프로세스 CS, 빠른 스캔 알고리즘에서 메시의 나머지 부분을 채웁니다.
빠른 스윕: 동일한 버퍼를 읽고 쓸 수 있어야 하며, 한 줄에 하나의 스레드가 있어야 하며, 스레드의 읽기와 쓰기가 겹치지 않고, 연동이 필요하지 않으며, 전후에 동일한 축이 스캔되고, 각 축이 차례로 스캔됩니다.
d = maxPossibleDistance
for i = 0 to row length
d += cellSize
if(abs(cell[i]) > abs(d))
cell[i] = d
else
d = cell[i]SDF는 입자 시스템에서 나올 수도 있고 SDF를 시각화할 수도 있지만 여기서는 무시됩니다.
이제 GPU에서의 스트림 압축에 대해 이야기해 보겠습니다. 스트림 압축 프로세스는 희소 배열을 가져와서 채워진 요소를 모두 함께 밀어넣고 개수와 오프셋 매핑을 기억한 다음 배열의 채워진 부분만 처리하면 됩니다.

카운팅 패스 - 병렬 축소, 반복적으로 배열 크기(밉 체인과 같은)를 절반으로 줄이고 마지막 단계에 도달할 때까지 상위 셀 수의 합계를 기록합니다. 셀 1개, 총 수입니다. 오프셋 채널 - 반복 워크백, 셀 오프셋 = 상위 위치 + 형제 위치, 조직 피라미드(히스토피라미드): 3D 흐름 압축.
조직 피라미드(Histopyramid): 오프셋을 계산하기 위해 베이스에서 위쪽으로 계산하여 블록에 밉 체인을 축적합니다.

조직 피라미드 사용: 메시 볼륨 텍스처를 활성 마스크(0은 비어 있음, 1은 유효함)로 채우고, 밉 체인 아래로 카운트를 생성하고, 셀 위치에 두 번째 볼륨 텍스처를 사용하고, 밉 체인을 통과합니다.
압축 실습: 조직 콘을 사용하여 활성 세포를 압축하고 활성 세포의 수도 알아봅니다. GPU는 활성 셀 수에 대해서만 드로콜을 예약합니다. DrawInstancesIndirect를 사용하여 GS는 셀 인덱스를 기반으로 그리드 위치를 결정합니다. 이를 위해 조직 피라미드를 사용하여 GS의 세포에 대한 이동 큐브를 생성합니다. 무차별 대입에 비해 11ms에서 최대 5ms로 크게 개선되었으며, 병렬성이 크게 향상되고, 드로우 콜 크기가 감소했으며, 지오메트리는 여전히 GS에서 생성되고, 각 렌더 패스에 대해 다시 실행되며, 인덱스/버텍스 재사용이 없습니다.
DX11은 렌더링 파이프라인에서 지오메트리, 버텍스 및 기타 데이터는 물론 부드러운 메시(아래 그림)를 생성하는 데에도 사용할 수 있습니다.

또한 DX11은 부드러운 입자 유체 역학, AO 레이 트레이싱, SDF 기반 AO 및 기타 렌더링 기술에도 사용할 수 있습니다.
게임용 물리엔진 조사에서는 2012년 주류 물리엔진의 기초지식과 특성, 특징, 사용비율 등의 내용을 조사하였다.

게임 애플리케이션의 맥락에서 물리 엔진.
당시 주류 물리 엔진에는 PhysX, Havok, ODE, Bullet 등이 포함되었습니다. 처음 세 가지의 사용법은 다음과 같습니다.

그 특징은 다음과 같습니다.

'언리얼 엔진 4 엘리멘탈 데모'의 기술은 2012년 언리얼 엔진의 그래픽 기능, 간접 조명, 그림자, 포스트 프로세스, 파티클 등의 렌더링, 실습, 최적화 기술을 자세히 공유합니다.
당시 UE4는 일반적인 실시간 GI 솔루션을 고려하고 있었습니다. 복셀 원뿔 추적[Crassin11]을 사용한 대화형 간접 조명 및 앰비언트 오클루전(AO)에서 영감을 받아 마침내 복셀화 솔루션이 선택되었습니다.
체적 레이캐스팅: 일부 시작 오프셋, 콘텐츠 적응형 단계 크기로 시작하고, 방사선 및 폐색을 찾고, 폐색으로 빛을 축적하고, 폐색되거나 충분히 멀리 있으면 중지합니다. 원뿔 추적, 로컬 원뿔 너비의 Mip 수준, 점진적으로 단계 크기 증가.

GI에 복셀 원뿔 추적 사용:
"단순화된 장면에 대한 레이 트레이싱"과 같은 것입니다.
Diffuse GI: 노멀, 원뿔 수의 개방 각도에 따라 여러 방향.
스페큘러 반사: 미러링된 눈 벡터 방향에서 하이라이트 파워가 열리는 각도입니다.
레이 트레이싱만큼 정확하지는 않지만 분수 기하학 교차, 노이즈 없음, LOD.

척추체 추적의 개략도. 빨간색은 스페큘러 반사를 나타내고 녹색은 디퓨즈 GI를 나타냅니다.
더욱 최적화/근사화될 수 있습니다. 낮은 복셀 해상도, 복셀 조명 채널의 산란 대신 클러스터링, 적응형 샘플링, 샘플 멀티플렉싱.
추가 혜택. 음영처리된 IBL, 발광 재료에 대한 음영처리된 영역 조명.
복셀 원뿔 추적 과제: 얇은 벽을 통해 넓은 원뿔은 아티팩트를 표시하지만 좁은 원뿔은 속도가 느리고, 밉 매핑은 방향에 따라 달라져야 하며, 삼각형 메시에서 복셀 데이터 생성, 런타임 메모리 관리, GPU 하드웨어의 효율적인 구현, 희소 데이터 구조가 필요합니다.
희소 복셀 옥트리: 매핑 기능은 로컬 더 높은 해상도, 월드 3D 위치 <=> 인덱스 및 로컬 3D 위치를 허용합니다. GPU에서 완벽하게 유지 관리됩니다. 노드/리프별 데이터, 2x2x2 복셀 데이터(옥트리 노드 모서리에 배치), 6x 3x3x3 복셀 데이터(예: 테두리가 연결된 2x2x2)별 렌더 단계별 데이터에 액세스하기 위한 인덱스입니다.

복셀 조명 파이프라인:

위 그림의 복셀화: 모든 정적 영역의 레벨이 로드된 후 동적 개체가 움직일 때; 조명: 스포트라이트 빛과 어둠; 필터링: 방향 관련 복셀 및 밉 생성 마무리: 중복 데이터를 생성하고 이를 볼륨 텍스처에 복사합니다.
- 복셀화.
영역에 복셀 기하학 데이터를 생성합니다. 입력: 옥트리, 삼각형 메쉬, 인스턴스 데이터, 재료, 영역, 출력: 옥트리, 2x2x2 재료 속성, 노멀.
지역 복셀화. 기하학적 변화, 중요한 변화, 해상도 변화.
몇 가지 동적 개체에 최적화되었습니다. 요청 시 복셀화하고, 영역은 정적 복셀 데이터를 별도로 유지합니다.
렌더링 방법:
방법 1: 하드웨어 래스터라이저의 픽셀 셰이더 패스를 사용하고, 축(X, Y, Z)당 한 번씩 래스터라이제이션하여 구멍을 방지하고, 셰이더가 아티스트가 정의한 자료를 평가하고, 출력: CS 처리 후 타일 대기열을 출력합니다.
방법 2: 셰이더 패스 계산, 옥트리 데이터 구조 업데이트(병렬), 복셀 데이터를 리프에 저장합니다.
방법 2는 점유율(2x2 쿼드), 셰이더 컴파일 시간(CS 재사용)이 더 좋습니다.
복셀 조명.
음영 처리를 계산하고 Radiance를 저장합니다. 입력: 2x2x2 재질 속성, 노멀, 출력: 2x2x2HDR 색상 및 불투명도.
- 누적 방사조도와 그림자. 그림자 맵을 사용하여 직접 조명을 추가하고, 주변 색상을 추가하고, 알베도 색상과 결합하고, 글로우 색상을 추가합니다.

- 복셀을 필터링하고 완료했습니다.
밉맵 생성, 중복 테두리 생성, 압축. 입력: 2x2x2 HDR 색상, 폐색 및 일반, 출력: HDR 승수, 6 x 3x3x3LDR 색상 및 폐색.
- 방향에 따른 복셀을 생성합니다. 복셀 법선의 리프 수준에서는 동일한 방향의 노드 수준에서만 가능합니다.

미러 샘플링:
픽셀당 로컬 반사, Specular Power의 원뿔 각도, 일반적으로 단일 원뿔이면 충분하며 복잡한 BRDF도 가능합니다.
더 나은 성능, 하이라이트 밝기, 깊이 차이, 일반 차이에 적응합니다.


업샘플링에는 Dispatch()를 사용하세요.
디스패치 채널은 DispatchIndirect()를 사용합니다.
디퓨즈 샘플링:
파이널 게더링 [Jensen02]과 유사합니다.
문제: 좋은 성능을 얻기 위한 샘플 수가 적고, 충분한 품질의 샘플(원뿔 각도)이 반구에 고르게 분포되어 오류를 줄이고, 노이즈를 원하지 않고, 일반적인 세부 사항을 흐리게 하고 싶지 않습니다.
디퓨즈는 대부분 저주파입니다.
효율성을 위해서는 일관성이 중요합니다.

복셀 조명 비교 차트.
다음으로 UE의 컬러링에 대해 말씀드리겠습니다.
UE는 새로운 반사 전력 인코딩을 사용합니다. IBL의 더 높은 반사 전력, 더 많은 공유 값 정의, 너비가 1000픽셀인 먼 구체에 픽셀이 선명한 반사를 제공하도록 조정되었습니다.
OldEncode(x): sqrt(x / 500)
OldDecode(x): x * x * 500
NewEncode(x): (log2(Value) + 1) / 19
NewDecode(x): exp2(Value * 19 - 1)
경험적 근사치로서 가우스 스페큘러 반사를 사용하여 앨리어싱을 줄였습니다[McKesson12].
Dot = saturate(dot(N, H))
Threshold = 0.04
CosAngle = pow(Threshold, 1 / BlinnPhongSpecularPower)
NormAngle = (Dot - 1) / (CosAngle – 1)
LightSpecular = exp(- NormAngle * NormAngle) * Lambert
영역 조명 스페큘러 반사, 부드러운 구 영역 조명:
LightAreaAngle = atan(AreaLightFraction / LightDistance)
ACos = acos(CosAngle)
CosAngle = cos(ACos + LightAreaAngle)에너지 보존(대략적인 값):
SpecularLighting /= pow(ACos + LightAreaAngle, 2) * 10

새로운 포스트 프로세스 이미지:
그래픽: 모든 프레임 생성, 사용자 인터페이스 없음, 종속성 정의 실행 순서, 주문형 RT, 참조 계산, 지연 릴리스.
노드: 유형은 많지만 고정된 기능, 다중 입력 및 출력, 정의된 출력 텍스처 형식.

SSAO:
클래식 SSAO [Kajalin09]. 앰비언트 오클루전(AO)은 후처리로 계산되며 z 버퍼와 3D 포인트 샘플만 필요하며 그 중 작은 화면 정렬 모드로 배열되는 것은 거의 없습니다.
UE의 기술은 2차원 포인트 샘플을 기반으로 합니다. HBAO [Sainz08]와 유사한 각도 기반, GBuffer 법선을 사용하여 품질을 더욱 향상시키고 고주파 세부 사항으로 복셀 조명을 보완합니다.
샘플링: 6개 샘플 쌍 사용 = 12개 샘플, 16개 회전, 절반 해상도 z-버퍼에서 4x4 패턴으로 인터리브됨:

- 픽셀당 법선은 각도를 더욱 제한합니다.
A) Given: z buffer in the sample direction
B) Get equi-distant z values from samples
C) AO (so far) = min((angle_left+angle_right)/180,1)
D) Clamp against per pixel normal
E) AO (per pixel normal) = (angle_left+angle_right)/180AO ~= 1-saturate(dot(VecA,Normal)/length(VecA))
효과 비교:

HDR 히스토그램:
64 버킷, 로그, 원자 없음.
패스 1: 화면 로컬 히스토그램(CS)을 병렬로 생성합니다.
清除组共享直方图float4[64][16]
同步
并行累积直方图
同步
将多个直方图累积到一个float4[16]
在16个纹素中每行输出一个直方图- 패스 2: 모든 행을 하나로 결합하고 64개의 버킷이 16 ARGB에 저장됩니다.

인간의 눈 적응:
밝은 영역(예: >90%)만 고려하고 소수의 매우 밝은 영역(매우 밝은 방출 영역, 예: >98%)을 제외하여 히스토그램에서 평균 밝기(파란색 선)를 계산합니다.
전체 뷰포트에 대한 단일 승수를 계산하고, 마지막 프레임 평균(흰색 막대)과 부드럽게 혼합하고, 사용자 지정 영역(녹색)에 바인딩하고, 톤 매퍼(흰색 곡선)에 적용합니다.
톤매핑된 VS에서 결과를 읽고 보간기로 PS에 전달합니다.
GPU 가속 입자:
CPU: 파티클 생성(임의로 복잡한 로직), 고정 크기 버퍼의 메모리 관리(단위: 16 파티클), 이미터 관리(인덱스 버퍼, 드로우 콜 순서).
GPU: 뉴턴 모션 역학(고정 기능), 무방향 볼륨 캐스케이드의 조명(3D 조회), 필요한 경우 GPU 기수 깊이 정렬[Merrill11][Satish09], 렌더링, 벡터 필드의 추가 힘(3D 조회), 입자 속성을 조정하기 위한 입자 곡선(1D 조회).
블룸:
목표: 대규모, 고품질, 효율성
다운샘플링:
A = downsample2(FullRes)
B = downsample2(A)
C = downsample2(B)
D = downsample2(C)
E = downsample2(D)- 다운샘플링 중 흐리게 처리하면 앨리어싱을 방지할 수 있습니다.

- 재구성(해상도가 높아짐에 따라):
E’= blur(E,b5)
D’= blur(D,b4)+E’
C’= blur(C,b3)+D’
B’= blur(B,b2)+C’
A’= blur(A,b1)+B’- 업샘플링 시 흐리게 처리하면 품질이 향상되고 흐림 반경에 거의 영향을 주지 않습니다.
blur(blur(X,a),b) ~= blur(X,max(a,b))- 더티 텍스처 결합:
J*const + tex2d(Dirt,ScreenUV)*const
G버퍼 흐림:
스마트 블러: 평균 5픽셀, 일반 가중치, 깊이 차이 가중치.
응용 분야: 반사 물질(움직임이 분명한)의 앨리어싱을 줄이고 앰비언트 오클루전(AO)에서 고주파 지터 아티팩트를 줄이며 IBL 또는 복셀 조명을 사용하여 성능을 향상시킵니다.
가능하다면 깊이와 AO를 위해 Gather()를 사용하세요.
출력: SpecularPower, Normal, AmbientOcclusion.
반사광 감소 [Toksvig05] [Bruneton11]:
L = saturate(length(SumNormal) * 1.002)
SpecularPower *= L / (L + SpecularPower * (1 - L))
사진 지원:
포스트 프로세스 볼륨: 선형 블렌드 포스트 프로세싱 속성, 우선 순위는 카메라 위치에 따라 다름, 블렌드 반경을 통한 부드러운 전환, 가중치는 원격으로 제어 가능.
렌더 타겟 풀: 주문형 할당, 참조 카운팅, 지연 릴리스, 중간 버퍼 보기 도구.
데스티니: 신화 SF에서 실시간 렌더링까지에서는 데스티니 엔진의 렌더링 기술과 특수 효과를 설명합니다.
당시 데스티니 엔진은 움직이는 나무, 강, 호수가 포함된 벡터 지형, 사용자 정의 가능한 기어, 실시간 의상, 얼굴 기술, 고품질 실시간 그림자, 특수 효과, 게시판 시스템, 테셀레이션, 고품질 대형 AO(GI), 가시성, 동적 시간 등의 기능을 지원했습니다.
데스티니 엔진의 목표는 고품질의 비주얼을 통해 아트 스타일 선택과 현실감 사이의 균형을 잘 맞추는 것이지만, 범용 그래픽 엔진이 되는 것도 마찬가지로 목표입니다. 렌더링의 주요 영역은 효율적인 콘텐츠 제작 프로세스 및 파이프라인, 높은 상호 작용성을 갖춘 믿을 수 있고 복잡한 캐릭터, 역동적인 세계 및 복잡한 문제를 처리하는 능력, 차세대 하드웨어의 성능 활용, 현재 세대 콘솔에 대한 확장성입니다. 엔진 기술에는 작업 기반 멀티스레딩, 데이터 병렬성 및 캐시 일관성이 포함되어 모든 유형의 코어에서 실행됩니다.
렌더링 속도를 높이기 위해 지오메트리 패스를 줄이고, 렌더 대상 크기를 작게 유지하고, 조명+머티리얼 모델을 통합하고, 셰이더를 단순화했습니다. Halo: Reach는 하이브리드 디퍼드 렌더링 파이프라인을 사용합니다.

디퍼드 렌더링 파이프라인 사전 통과:

데스티니 엔진의 디퍼드 렌더링 파이프라인:

GBuffer 데이터 레이아웃은 다음과 같습니다:

재료 라이브러리, 재료 모델 매개변수는 G-버퍼의 테이블에 저장되며, 단일 인덱스만 테이블에 저장되고 표현 및 사용자 정의가 가능합니다. 테이블은 작성된 곡선 또는 그려진 텍스처를 사용하여 지정되는 텍스처로 저장됩니다.
반사 로브 인덱스(노멀 옆에 저장된 10비트)는 반사 하이라이트의 모양을 제어하고, 4비트는 아티스트가 그린 로브 모양을 지정하고, 6비트는 가져오기 프로세스 중에 자동으로 계산되는 러프니스 변화를 지정합니다.



조명 및 음영 처리 과정은 다음과 같습니다.




다양한 Deferred Rendering의 성능 비교는 다음과 같습니다.

데스티니 투명 조명의 목표는 대기에 적용되는 조명 불투명도, 그림자 및 불투명도 일관성의 일관성입니다. 근사치는 라이트 프로브를 투명한 장소에 동적으로 배치하고 빛과 그림자를 고려하여 매 프레임마다 검출기에 대한 저차 구면 고조파를 구축하는 것입니다.
기존 방사량 처리는 CPU에서 수행되지만 데스티니에서는 이를 GPU로 옮깁니다. 다음과 같이 처리합니다:
매 프레임마다 프로브 목록을 구축합니다. 눈에 보이는 투명 개체를 처리할 때 CPU는 빛 감지 지점 목록을 작성하고 해당 지점은 빠른 스레드 안전 잠금 없는 버퍼에 기록되며 개체 목록이 작업에 작성됩니다. XYZW의 각 구성 요소는 32비트 부동 소수점 숫자이며 라이트 프로브 반경은 W에 저장됩니다.
매 프레임마다 GPU 버퍼에 라이트 프로브를 제출합니다. 1024로 제한되며, 지연을 방지하기 위해 이중 버퍼링을 사용하여 64x64 RGBA32F 텍스처로 인코딩됩니다.
광원 프로브 GPU 생성. MRT 및 SH 조명 환경 표면 설정: 3 x 64 x 16 RGBA16F 렌더 타겟, 각 렌더 타겟은 하나의 색상 채널에 대해 4개의 SH 계수를 인코딩합니다. 태양의 쿼드를 SH 표면에 렌더링하고 방향성 조명을 SH 계수에 매핑합니다.
그림자. 계단식 그림자 맵을 샘플링하여 각 프로브의 그림자를 결정하고 PCF는 프로브 반경을 기반으로 한 샘플 반경을 사용하여 광점 버퍼 위치에서 수행됩니다.
조명 환경. 아티스트는 조명에 태그를 지정하여 투명도에 영향을 미칠 수 있으며, 조명은 단순히 아티스트가 선택할 수 있는 셰이더 구성 요소 집합입니다. 투명도에 영향을 미치는 각 조명에 대해: 쿼드를 SH 표면에 렌더링하고 조명의 매개변수를 지정된 라이트 프로브 포인트 버퍼 위치의 SH 계수에 매핑합니다.
반투명하게 렌더링합니다. 반투명은 디퍼드 라이팅과 그림자가 적용된 후 뒤의 메인 디퍼드 패스에서 렌더링됩니다. 반투명 객체를 렌더링할 때 SH 표면을 샘플링하고 빛을 픽셀 색상에 적용합니다. 주변 조명 모델은 오버헤드가 낮으며 나중에 계산할 수 있습니다.
제한 사항: SH는 불투명 조명에 완벽하게 일치하지는 않지만 합리적으로 적합하며 물체가 투명할 때 대부분의 결함이 눈에 띄지 않습니다. 부드러운 그림자 응답을 얻으려면 많은 샘플이 필요하며, 개체별 그림자 요소로 인해 64x16 버퍼에서 작동하는 것이 빠르다는 장점이 있습니다.
입자는 Über-Low 해상도 VDM(Variance Depth Map) 입자입니다.

왼쪽: 전체 해상도; 중간: 이중선형 업샘플링을 사용한 1/4 해상도; 오른쪽: VDM을 사용한 1/4 해상도
2014년 The Witcher 3: Wild Hunt with Umbra 3의 가시성 및 스트리밍 해결에서는 가시성 및 스트리밍을 위해 Umbra 구성 요소를 활용하는 The Witcher 3의 기능을 설명했습니다. Umbra는 2007년에 설립된 오클루전 컬링 전문 소규모 회사입니다. 그 작업 흐름은 다음과 같습니다:

위쳐3의 요구사항은 대규모 오픈월드 → PVS, 수동조작 불가능, Umbra는 자동, 스트리밍 데이터, LOD입니다. 데이터 흐름의 과제에는 독립적인 블록, 경계 일치 및 속도가 포함됩니다. Umbra3의 LOD의 경우 이전 장면은 단일 객체 인스턴스로 구성되었습니다. 여러 LOD 레벨, 레벨 간 자체 폐색, LOD 계층 구조가 필요합니까? 해결책은 다음과 같습니다.

LOD 챌린지; 거리 기준점, LOD 선택을 위한 기타 기준, 더욱 스마트해진 LOD 폐색 몸체.
오클루전 데이터 흐름:
특정 카메라 위치에서 필요한 타일 그룹을 결정합니다.
새로 결정된 세트가 현재 사용된 세트와 다른 경우 비동기 계산이 시작됩니다.
스트리밍 입력 사전 베이킹 버퍼(아직 스트리밍 입력 데이터가 없는 타일에만 적용됨)
책 개체를 만듭니다(이 개체가 아직 생성되지 않은 타일에만 해당).
모든 Tomes가 존재하면 TomeCollection 개체가 해당 Tomes에서 생성됩니다.
새로 생성된 컬렉션은 현재 사용되는 컬렉션을 대체하기 위해 렌더러로 전송됩니다.
더 이상 필요하지 않은 타일은 Tome 객체를 파괴하고 사전 구운 버퍼의 타일을 언스트리밍하여 이전 컬렉션 객체를 파괴합니다.

"Tianya Mingyue Knife"의 엔진 개발은 GDC China 2014에서 Tencent Northern Lights Studio의 An Bolin과 공유되어 QuickSilver 엔진의 장면, 재료, 빛 및 그림자 기술을 설명했습니다.
장면 측면에서는 플레이 가능 영역 4kmx4km, 가시 영역 12kmx12km를 충족하기 위한 과제는 개발 및 운영 효율성이다. 운영 효율성을 위해 가시성 감지 및 제거, LOD, 인스턴스화 및 멀티스레드 렌더링이 사용되며, 개발 효율성을 위해 파이프라인 도구, 보조 편집 및 외부 상호 운용성 도구가 사용됩니다.

가시성 감지 측면에서 메인 스레드는 입자, 애니메이션 및 기타 계산을 건너뛰고 행위자/엔티티 수준 감지를 사용합니다. 렌더링 스레드는 DrawCall을 건너뛰고 일반적인 가시성 감지(장면 관리, 프러스텀 컬링, 소프트 래스터 컬링, 기여 컬링), 반사 컬링, 섀도우 컬링 등을 수행합니다.
일반적인 가시성 감지를 위해 장면 관리는 빠른 메모리 액세스를 얻기 위해 두 가지 수준의 Cell/BVGrid를 사용하고 SSE2 명령어 세트, 소프트웨어 래스터라이제이션(지형, 내부 경계 상자)를 사용하고 매우 작은 화면을 차지하는 개체를 제거합니다(문자와 일반 개체는 서로 다른 임계값을 사용함).

위 매뉴얼을 통해 해당 씬의 드로우콜이 47.8% 증가하였습니다.
반사 컬링을 수행할 때 물 위의 지형은 미러링된 카메라에 보이지 않는 지상 개체를 컬링하기 위한 차단기로 사용됩니다.

그림자 제거의 경우 계산량이 매우 크고, 범위도 크고(2kmx2km 범위), 정지된 물체와 식물이 그림자를 생성하게 됩니다. 빛의 방향 변화가 고정되어 있으므로 투영 없이 오프라인으로 계산할 수 있습니다. 이미 그림자로 덮여 있는 지형, 정적 개체 및 식물은 투영되지만 개체는 허용되지 않습니다.


물에 반사되는 것이 매우 선명한 상황을 피하기 위해 반사를 더욱 단순화합니다. Z 방향으로만 투영되며 더 이상 다중 방향 투영이 아닙니다. MipmapBias = 2입니다.


조명 및 재질은 일반, 머리카락, 눈, 피부 재질을 지원하며, PBR 조명을 사용합니다. 조명은 디퓨즈와 스페큘러 반사 항목으로 구분됩니다. 스페큘러 반사에는 주 하이라이트와 보조 하이라이트라는 두 가지 하이라이트 레이어가 사용됩니다.

주요 스페큘러 반사에는 D: blinn-phong, F: Schlick 근사, G: Neumann-Neumann GAF를 포함한 주류 Cook-Torrance 모델이 사용됩니다. 하위 반사 반사는 오프라인으로 구운 IBL을 사용합니다. 헤어에는 카지야케이(Kajiya-Kay), 피부에는 5S, 눈에는 Jimenez12를 기반으로 개선되고 최적화된 버전을 사용합니다. 주변광은 3개의 반구형 조명(하늘, 지면, 태양산란)을 사용합니다.

캐릭터 조명은 어떤 상황에서도 멋지게 보여야 했기 때문에 특별하게 처리되었습니다. 조명 매개변수는 장면과 분리되어 있으며 캐릭터 아티스트가 독립적으로 디버깅합니다. 렌더링은 두 번의 패스로 이루어지며 스텐실을 사용하여 서로 다른 매개변수를 구별합니다. 카메라 라이트(카메라 뷰 방향의 라이트)를 추가하고 그림자에 머리카락의 %30~%40 DirectLighting을 남겨둡니다.
조명 파이프라인은 지연/전달 하이브리드 모드를 사용합니다.
캐스케이드 섀도우에는 원활한 전환을 보장하기 위해 4개의 캐스케이드가 있습니다. LightViewBuffer에 포함된 처음 3개의 캐스케이드는 매 프레임마다 업데이트되어 약 200미터를 포괄하고 네 번째 캐스케이드는 2km 이상을 포괄합니다. 원활한 전환 없이 완전성을 보장하기 위해 프러스텀는 캐스케이드의 주변 구체를 완전히 포함해야 하며 프러스텀의 가장 바깥쪽 부분은 캐스케이드 원뿔의 작은 부분에만 해당됩니다. 원활한 전환을 통해 Frutum을 원래 0.85x0.85=0.72로 줄일 수 있으며, 다룰 수 없는 소수의 영역은 다음 캐스케이드 블렌딩으로 처리됩니다.

4단계 그림자는 2km 이상을 덮고 프레임으로 업데이트되며 20초마다 전환됩니다(빛의 방향과 위치의 이동에 따라). 전환 프로세스 중에는 전환이 원활하게 진행됩니다. 섀도우 캐시는 정적 메시 및 지형 섹터 섀도우 렌더링의 약 70%를 절약할 수 있습니다. 세 번째 캐스케이드에 사용됩니다. 첫 번째와 두 번째 캐스케이드에서는 거의 중요하지 않으며 비디오 메모리 비용만큼 가치가 없습니다.

또한 Snapping은 지터를 처리하는 데 사용되고 Shadow Mask는 ShadowMap 구성 패스를 %10~%60으로 최적화하는 데 사용됩니다.
Codemasters의 GRID2 이상의 렌더링 PC와 태블릿 모두에서 최고의 그래픽 달성은 픽셀 셰이딩 순서, OIT, 적응형 볼륨 조명, 프로그래밍 가능한 믹싱, 입자 조명 및 기타 새로운 렌더링 기술을 포함하여 PC 및 태블릿 장치와 호환되는 게임 GT2의 렌더링 기술을 설명합니다.
2014년에는 디스플레이 해상도와 GPU에 큰 변화가 있었습니다. 해상도는 점점 더 고화질로 변해 1080p가 지배적인 위치를 차지하고 Intel의 통합 그래픽 카드가 여전히 지배적인 위치를 차지하고 GTX가 그 뒤를 따릅니다.

당시 업계 목표는 중급 설정을 현재 콘솔과 일치시켜 콘솔 품질을 확장 및 축소하는 것이었습니다.

픽셀 셰이더 순서: 충돌하는 스레드만 직렬화되므로 화면 위치에 대한 픽셀 셰이더는 상호 배타적이고 빠릅니다. 알파 블렌딩 규칙과 유사한 보장된 실행 순서, V_PrimitiveID 순서로 작성된 픽셀, 픽셀 셰이더 순서는 이 보장된 순서를 픽셀 셰이더로 이동합니다. 픽셀당 데이터 구조를 읽고, 수정하고, 쓰려는 모든 작업에 사용할 수 있습니다.

왼쪽: 픽셀 음영 처리 순서가 없으면 겹치는 픽셀을 병렬로 실행할 수 있습니다. 오른쪽: 픽셀 음영 처리 순서를 사용하면 겹치는 픽셀이 더 이상 병렬로 실행될 수 없으며 직렬이 됩니다.
OIT(Order Independent Transparency): 밀도/부드러운 나뭇잎(특히 밉으로 인해 먼 거리에서), 기타 알파 테스트 형상 개선과 같은 순서 문제 없이 여러 투명 레이어를 표현할 수 있습니다.
UAV 표면에서 가시성 함수는 순차적인 고정 크기 노드 배열로 저장되며 각 빨간색 노드는 깊이 및 투과율 값 쌍에 해당합니다. 가시성을 압축하기 위해 가장 작은 영역 변화를 생성하는 노드가 제거됩니다.

GRID2의 알파 적용 범위: 나뭇잎에 반투명한 부분이 많이 있습니다(아래 이미지에서 왼쪽 빨간색 영역). 알파 블렌딩은 옵션이 아니며 원래 시스템은 Alpha 2x 적용 범위를 사용하지만 보기 좋게 보려면 4xMSAA가 필요합니다. 블렌딩이나 A2C가 없으면 들쭉날쭉한 결과가 나옵니다.

AVSM(Adaptive Volumetric Shadow Mapping): 참여 매체를 통한 빛 투과율을 대략적으로 계산하는 데 유사한 아이디어를 사용할 수 있습니까? 광원의 관점에서 OIT를 렌더링하면 체적 연기 효과를 렌더링하는 데 사용할 수 있습니다. 예를 들어 아래 그림의 타이어는 안개로 덮여 있습니다.

빛나는 입자: 그림자 맵 읽기/쓰기 최적화에 초점을 맞춘 초기 R&D, 픽셀당 조명 시간이 10ms를 넘는 입자... 정점당 조명이 너무 거칠고, 화면 공간 분할이 있는 정점당 실제로 더 좋아 보입니다! 정점당 세분화가 2~3배 더 빠릅니다.

프로그래밍 가능한 블렌딩: R10G10B10A2 백 버퍼에 대수적으로 인코딩된 HDR 조명 값, 인코딩된 값의 고정 기능 알파 블렌딩은 효과가 없으며 결과적으로 투명한 물체 뒤의 높은 동적 범위가 손실됩니다. 해결책은 선형 공간으로 블렌딩하는 것입니다.
GPU 및 CPU 최적화: 일부는 직관에 어긋나는 개별 그래픽을 사용하여 시스템을 최적화하는 것과는 달리, 전력 및 대역폭 최적화는 원하는 성능을 달성하는 데 중요한 역할을 합니다. CPU와 GPU는 시스템의 TDP(열 설계 전력) 등급을 공유합니다. CPU와 GPU에는 최대 허용 주파수가 있습니다. 둘 중 하나만 얻을 수 있지만 동시에 둘 다 얻을 수는 없습니다! 그래픽 벤치마크에서 로드 공유는 다음과 같습니다.

게임은 아래 그림과 더 비슷해 보입니다! TDP는 CPU와 GPU 간에 보다 균등하게 공유됩니다. 오디오, AI 및 높은 그래픽 API 오버헤드는 모두 CPU 사용량을 높이고, CPU 요구 사항이 높으면 최대 Gfx 주파수에 도달하기 어려울 수 있습니다.

TDP가 낮아지고 더욱 공격적인 트레이드오프가 이루어집니다. TDP가 낮을 경우 최대 CPU 및 GPU 주파수는 크게 변경되지 않을 수 있지만 두 가지를 동시에 얻을 수는 없습니다.

그렇다면 그래픽을 최적화하면 어떻게 될까요? 프로파일링을 통해 GPU에 바인딩되어 있다고 알 수 있다면 GPU를 최적화하면 성능이 향상될 것입니다. 그렇죠? ? ? ? GPU 작업을 20% 절약하면 FPS가 20% 더 늘어납니다. ? 추가 FPS를 사용하려면 일반적으로 워크로드를 구동하기 위해 더 많은 CPU가 필요합니다.

**GPU가 제한되어 있나요? CPU를 최적화하세요! !**이상하게 들리지만 점점 더 흔해지고 있습니다. GPU와 CPU는 전력 예산을 공유하여 런타임 시 작업 부하에 따라 주파수를 동적으로 조정하고, 하나를 최적화하면 다른 하나에 더 많은 전력을 제공하며, 기본 CPU 주파수는 오해의 소지가 있을 수 있습니다.
Blogger 참고 사항: 기사의 일부 설명은 시간에 민감합니다. 현재 모바일이나 태블릿 장치에서도 이것이 여전히 해당되는지는 모르겠습니다. 추가 정보를 확인하거나 목표한 실제 측정을 수행해야 합니다!
에너지는 공유되는 유일한 것이 아닙니다! 또한 최대 1.7G의 시스템 메모리가 공유되며 링 버스, 공유 LLCache 및 CPU와 GPU 간에 공유되는 시스템 대역폭을 통해 CPU에 연결됩니다.

재미는 계속됩니다. TDP가 증가함에 따라 외부 대역폭은 거의 변하지 않으며 GPU 또는 CPU 워크로드를 추가하면 대역폭 요구 사항이 증가합니다.

시스템에 충분히 빠르게 전원을 공급할 수 있나요? TDP가 높아도 성능이 향상되지 않으면 GPU 사용량을 확인하십시오. EU 일시 중지는 RAM을 기다리면서 직접적으로 발생하거나 샘플러에 의해 간접적으로 발생할 수 있습니다. Intel GPA는 관련 데이터를 감지할 수 있습니다.

SSAO 개선 이전에는 개발 규모가 줄어들지 않고 프레임 속도가 15~20%에 불과할 때 중간 설정으로 인해 비용이 너무 높았습니다. 여러 하드웨어 공급업체에서 최적화하기 어려운 CS 기반, 매우 메모리 집약적, 폐색 결과당 깊이 샘플 2개, 깊이에서 스마트 교차 양측 흐림을 읽어 가장자리를 결정하고 1/2 x 1/2 화면 해상도에서 작동합니다.
SSAO 개선 후 Image-Space Horizon-Based Ambient Occlusion(Based on Image-Space Horizon-Based Ambient Occlusion)을 기반으로 완전히 PS를 기반으로 하며 여전히 1/2 x 1/2 해상도, 일반 및 가장자리 감지의 기본 비용 + 폐색 결과의 깊이 샘플 1개, 지능형 교차 양측 블러는 이전 프로세스의 가장자리를 사용하고 깊이를 읽지 않습니다. 아래 그림은 개선 전(상단)과 개선 후(하단)의 성능 비교를 보여줍니다.

개선된 SSAO의 성능이 일반적으로 몇 배로 크게 향상되었음을 알 수 있습니다.
MSAA 성능: 픽셀 셰이더는 더 높은 적용 범위와 폐색으로 샘플당 한 번 실행됩니다. 하위 샘플 수준에 필요한 스토리지는 대역폭과 메모리 요구 사항을 증가시키며 비용은 하드웨어 및 작업 부하에 따라 다르지만 결코 무료가 아닙니다.
포스트 프로세스 AA 대안으로 가장 일반적인 두 가지 방법인 GRID2용 SMAA 1x 및 FXAA 3.11이 평가되었습니다. FXAA 3.11은 잘 작동하지만 개발자들은 너무 흐릿하다고 생각했습니다. (텍스트 및 고주파수 텍스처에 대한 세부 정보가 손실됨) SMAA 1x는 순방향 렌더링에서 MSAA보다 약간 더 비싸며 여전히 약간 흐릿합니다. "모폴로지 안티앨리어싱"을 시작으로 사후 처리를 통해 색상 불연속성(가장자리)을 분석하여 앨리어싱을 감지하고 스마트 블러를 적용하여 앨리어싱을 줄입니다.

CMAA(Conservative Morphological AA) 입력: MLAA를 기반으로 하지만 U, Z, L 모양 대신 대칭 Z 모양만 해결하여 평균 이미지 색상과 시간적 안정성을 더 잘 보존합니다. 가장자리를 결정하고 다듬는 보수적인 접근 방식("확실하지 않으면 흐려지지 않음")을 통해 Intel Haswell용으로 맞춤 제작된 FXAA 3.11보다 전체적으로 손상이 적고 AA 품질이 향상됩니다. FXAA 3.11보다 빠르고 SMAA 1x보다 두 배 빠릅니다.

전체 화면 섀도우 패스: 픽셀 셰이더의 블록, EU 픽셀 셰이더 스톨 = 42.3%, 처음에는 4개의 섀도우 텍스처에서 읽음, 모든 품질 설정에 대한 셰이더 1개, 낮은 설정에서 깨끗한 텍스처 읽기. 스텐실 마스크를 추가하여 하늘과 같은 선택된 영역을 제거하고, 중간 및 하위 수준에서 다른 셰이더를 사용하고, 입자 그림자 텍스처에서 읽기를 제거합니다.
기타 최적화 방법: 고급 PC 기능은 제거될 수 있습니다. 태블릿 GPU 성능은 처음에는 프레임당 약 53ms이지만 공격적인 개선, 확장성(더 많은 그래픽 메뉴 옵션!), 반사 및 노멀 맵의 보다 선택적 사용 등을 위한 여지가 더 있습니다. 더 저렴한 셰이더, 메인 장면에서 환경 맵 셰이더를 사용하고 싶습니까? 이 렌더링 패스는 본질적으로 기본 색상 채널의 낮은 품질 버전이며 어떤 경우에는 품질이 너무 낮지만 GPU 시간을 20ms 절약합니다!
텍스처 LOD 편차, 시각적 품질이 매우 빠르게 떨어지며 현재 테스트에서는 게인이 최소인 것으로 나타났습니다. 더 낮은 기하학적 세부 수준, 더 가까운 그리기 거리, 나무/군중 빌보드 LOD, 감소된 버텍스 비용 및 조명 비용, 단순화된 포스트 프로세스: 톤매핑만 필요(블룸 필요), 모션 블러, 렌즈 플레어 등이 사라졌습니다.
저해상도 파티클 렌더링: 낮은 해상도에서 파티클을 렌더링하고 이를 메인 프레임 버퍼와 결합하여 채우기 속도를 줄이고 너비와 높이를 1/4로 줄이도록 콘솔/PC를 위한 효과적인 최적화, 태블릿은 고정 비용 오버헤드가 훨씬 더 높으며 다운샘플링된 깊이 버퍼 생성, 다운샘플링된 색상 버퍼 업샘플링, 전체 해상도에서 파티클을 보다 효율적으로 렌더링하고 파티클 수를 희생합니다. 높은 파티클 수는 충돌 시 또는 트랙 밖에서만 나타납니다.
요약: 새로운 확장 기능은 시각적 차별화를 가능하게 하며 전력 효율적입니다. 기존 알고리즘을 크게 최적화할 수 있습니다. 일반적인 GPU 최적화 규칙은 미묘하게 다르며 대역폭과 전력은 상황이 항상 직관적이지는 않다는 것을 의미합니다. CMAA는 모든 하드웨어를 위한 저렴한 포스트 프로세스 앤티앨리어싱 솔루션으로, 흐림/이미지 품질 저하가 문제가 되는 경우에 적합합니다. AA는 SMAA만큼 효과적이지 않습니다(특히 더 비싼 변형과 비교할 때). 전력이 제한된 하드웨어에서 최상의 시각적 균형을 이루고 있습니까?
저작 도구 프레임워크: Sony Worldwide Studios의 오픈 소스에는 메모리 내에서 관찰 가능한 XML과 유사한 데이터베이스인 DOM(문서 개체 모델)이라는 특별한 디자인 모델이 언급되어 있습니다. DomNode 트리의 루트는 일반적으로 문서입니다. DomNode에는 DomNodeType(스키마 유형과 유사)으로 지정된 속성과 하위 노드가 있습니다. XML의 속성과 마찬가지로 속성은 단순 유형(int, float, string, reference) 또는 단순 유형의 배열입니다. 자식 노드 추가 이벤트, 자식 제거 이벤트, 속성 변경 이벤트 등 노드를 관찰할 수 있습니다.
DomNode 계층 구조: 각 DomNode에는 DomNode의 DomNodeType에 의해 지정된 특정 속성과 하위 노드가 있습니다. DomNodeType은 스키마 파일을 프로그래밍하거나 로드하여 생성할 수 있으며 이벤트는 하위 노드에서 상위 노드로 전달됩니다.

노드 어댑터: 클라이언트의 "비즈니스 클래스"는 DomNodeAdapter에서 시작되며 특정 DomNodeTypes에 대해 정의됩니다. DomNode가 먼저 생성된 다음 DomNodeAdapter가 자동으로 생성되지만 필요에 따라 초기화됩니다. 전체 트리의 모든 DomNodeAdapter를 초기화하려면 루트 DomNode에서 InitializeExtensions를 호출하세요.

컨텍스트: 일반적으로 문서당 하나입니다. SelectionContext는 사용자 선택을 추적하고 변경 이벤트를 포함합니다. HistoryContext는 실행 취소/다시 실행을 위해 하위 트리에 대한 DOM 변경 사항을 추적합니다. TransactionContexts는 HistoryContext의 기본 클래스로, 변경 사항 집합의 시작 및 끝 시간을 추적하여 유효성 검사 논리가 올바른 시간에 실행될 수 있도록 합니다. InstancingContext는 복사, 붙여넣기 및 삭제를 구현합니다.
각 응용 프로그램마다 하나씩 레지스트리가 있습니다. DocumentRegistry – 문서 추적, 문서 목록 노출, 문서 추가 및 삭제, 활성 문서. ContextRegistry – 컨텍스트 추적, 사용 가능한 "컨텍스트" 목록, 컨텍스트 추가 및 제거, 활성 컨텍스트. IControlRegistry, IControlHostService 클라이언트 측 등록 컨트롤이 도크 상자에 표시되어 활성 컨트롤을 추적합니다.
PowerVR 레이 트레이싱 소개에서는 2014년 PowerVR 모바일 GPU의 레이 트레이싱 하드웨어 아키텍처를 설명합니다.
맞습니다! 2014! 모바일 GPU! ! 첨단 기술과 탐험!
다음 그림은 PowerVR의 하드웨어 아키텍처 다이어그램입니다.

위의 아키텍처에서 레이 트레이싱과 관련된 단위는 Ray Tracing Unit, Scene Hierarchy Generator, Ray Data Master 등입니다. 아래 그림은 렌더링 효과입니다.

당시에는 AR, VR, 경량 게임에 주로 사용됐다. VR에는 렌즈 왜곡 및 수차 보정이 포함됩니다.

게임 내 하이브리드 렌더링: 그림자, 반사, 투명도, 여러 동적 조명을 통한 향상된 스케일링, 래스터라이제이션된 실시간 라이트맵 업데이트, 손쉬운 통합.
완전 레이 트레이싱 그래픽: 거의 모든 3D 콘텐츠에 필요한 무차별 경로 추적, 손쉬운 포토리얼리즘, 레이 트레이싱이 오늘날 콘솔/데스크톱 기술의 마법사로 가능하며 모바일 장치에서의 완전 실시간 사용은 미래 세대에게는 현실적이지 않을 수 있으며 하위 실시간 사용에 적합합니다. 2014년 전력 및 대역폭 그래프:

Imagination의 모바일 그래픽 기능은 다음과 같습니다.

인스턴스는 버텍스, 픽셀 또는 OpenCL 스레드이며 작업은 계획의 모든 인스턴스, 유니폼, 매개변수 등을 공유합니다.

코어의 ALU, 레지스터, 일반 저장 영역의 구조는 다음과 같습니다.

각 통합 셰이딩 클러스터는 12주기 지연을 가지며 내부 구조는 다음과 같습니다.

전반적인 기능: 최신 모바일 장치에 대해 100Gflops 이상의 음영 효과를 제공하는 Series 6, OpenGL ES 3.0 지원, 엄청난 성능 개선, 수학 리셰이더 사용 허용 등을 통해 모바일 그래픽은 진정한 혁신이 있는 곳입니다.
새로운 셰이더 유형: 광선 셰이더는 광선이 삼각형을 교차할 때 호출됩니다. 셰이더 유형은 원하는 수의 광선을 방출할 수 있으며, OpenRL에는 기본 광선을 방출하는 프레임 셰이더가 있으며, 기존 프래그먼트/픽셀 셰이더도 광선을 방출할 수 있습니다! GLSL 프로그래밍 모델은 내장된 함수, 매개변수 등을 포함하여 동일합니다.
기본 개체: VBO, 유니폼, 셰이더 프로그램, 텍스처 바인딩 등을 포함하여 메시의 렌더링 상태를 캡슐화합니다. 레이 트레이싱 장치는 광선을 공통 기본 개체, 프레임 간 지속성 및 클라이언트 제공 변경 가능 개체가 있는 작업으로 정렬합니다.
제한 사항: 셰이더는 단일 레이 트레이싱 작업의 결과를 기다릴 수 없으며 셰이더는 하위 광선 수에 대한 최악의 추정치를 제공해야 하며 광선별 사용자 데이터 페이로드를 신중하게 관리해야 합니다.
병렬성은 픽셀이 아닌 광선에 따라 달라집니다.


광선에 대한 AABB 테스트: 6개의 선은 AABB의 윤곽선, 광선 원점 및 각 가장자리 벡터에 대한 6개의 평면, 평면 법선의 내적 및 광선 방향 벡터를 구성하며, 6개의 플래그는 일치하고 음수여야 합니다.

USC 명령어 그룹 패키징, 다음 그림은 26개 명령어를 보여줍니다. 압축 데이터 형식을 사용하는 경우 32개 명령어입니다.

이 기능의 영역은 44배로 줄어듭니다.

레이 트레이싱 장치 및 일관성 엔진:

아래 이미지는 변수를 포함하여 백만 개의 삼각형에 대해 약 100MB의 데이터를 저장하는 오름차순 가상 메모리 주소를 보여줍니다.

원시 객체의 계층 구조는 다음과 같습니다.

복셀화된 기본 객체:

일관성 대기열:

일관된 경로를 자동으로 찾습니다.

장면 계층 생성기:

제한 사항: 장면은 삼각형으로 표시됩니다. 평소와 같이 BVH는 구성 및 편의성을 위해 최적화된 정의된 형식이며 삼각형 순서는 일반적으로 공간적으로 일관된 흐름을 따라야 하며 대략적인 장면 규모 추정이 필요하며 지오메트리 셰이더는 레이 트레이싱 파이프라인과 인라인되지 않습니다.
장점: 셰이더 클러스터 워크로드는 버텍스 셰이더보다 높지 않고 월드 공간에서 실제로 움직이는 지오메트리만 처리하면 되며 고유한 알고리즘은 작업 세트를 내부 레지스터로만 제한합니다. 단일 패스 작업: 버텍스 셰이더 실행과 일치하며 "길고 마른 삼각형" 문제를 잘 처리하고 외부 메모리로 스트리밍하며 출력 형식은 빌드 알고리즘, 간소화된 로직으로 인해 손실 없이 압축됩니다. 희소 log2 옥트리 계층 구조를 기반으로 구축됨:

Ray Tracing의 삼각형 처리 과정은 다음과 같습니다.

일부 삼각형을 처리한 후 구조 범례는 다음과 같습니다.

상위 노드를 조립한 후에는 더 복잡해집니다.

레벨의 모든 상위 노드를 조립한 후:

하드웨어 장치의 다양한 성능 지표는 다음과 같습니다.

Practical Techniques for Ray Tracing in Games 역시 Imagination의 게임 내 Ray Tracing 탐구를 위한 실용적인 기술입니다.
레이 트레이싱에 대한 이전 신화: 레이 트레이싱은 사실적/물리적으로 정확한 렌더링에만 사용되며, 레이 트레이싱은 래스터라이제이션된 그래픽과 호환되지 않으며, 레이 트레이싱은 주어진 수의 픽셀을 렌더링하는 덜 효율적인 방법입니다. 실제로 레이 트레이싱은 한 개체의 음영이 다른 개체의 기하학적 구조를 인식할 수 있도록 하는 기술입니다. 레이 트레이싱을 사용하면 보다 사실적인 그림자, 반사, 굴절, AO, GI 및 기타 효과를 쉽게 얻을 수 있습니다.

레이 트레이싱을 사용하면 빛의 동작을 시뮬레이션할 수 있습니다.

게임에 레이 트레이싱을 추가하는 방법은 무엇입니까? 하이브리드 게임 엔진을 사용합니다. 세계 공간 장면 교차점의 레이 트레이싱 세부 정보:

래스터를 기반으로 하는 최신 게임 엔진은 대부분의 최신 게임 엔진에서 지연 음영 처리를 사용합니다.

혼합 렌더링은 G-버퍼를 사용하여 조명을 설정합니다.

레이 트레이싱은 부드러운 그림자를 얻을 수 있지만 반그림자 렌더링에는 픽셀당 여러 광선이 필요하며 각 표면 지점에 대해 여러 광선을 방출합니다(1은 표시됨). 각 광선은 하드 그림자의 경우와 동일하게 동작하여 픽셀당 모든 광선의 결과를 평균화합니다. 모든 광선이 가려지면 표면이 완전히 가려지고 모든 광선이 광원에 도달하면 광원 표면이 완전히 비춰지고 일부 광선이 가려지고 일부 광선이 광원에 도달하면 표면이 완전히 조명됩니다. 반그림자 지역에 있습니다.

빛 방향 선택: 영역의 광원이 빛을 방출하는 경우 표면에서 보이는 광원의 단면에 빛을 분산시킵니다. 무한대에서 평행광을 사용하여 일광을 근사화하려면 표면에서 빛의 원뿔을 선택하십시오. 완벽하게 맑은 날을 표현하려면 원뿔의 입체각이 0입니다. 큰 구름으로 일광을 표현하려면 입체각이 더 커집니다. 표면 지점에 도달하는 입사광을 추정합니다. 좋은 추정치를 얻으려면 샘플이 도메인을 균일하게 포함해야 합니다.

GBuffer 연속성: 부드러운 그림자를 정확하게 샘플링하려면 많은 빛이 필요합니다. 대부분의 이미지에서 표면 특성은 한 픽셀에서 인접 픽셀로 거의 변하지 않으므로 G 버퍼의 한 픽셀에서 전송된 광선은 인접 픽셀에서 전송된 동일한 광선과 동일한 개체에 부딪힐 수 있습니다. 시각적 정확성을 유지하면서 빛의 양을 줄이기 위해 이 사실을 활용할 수 있는 방법이 있습니까?
인터리브 샘플링은 인접한 픽셀의 그림자 조명 데이터를 사용합니다. 프레임 버퍼에서

반사: 빛이 완벽한 거울에 닿으면 입사각과 동일한 각도로 반사됩니다. 유클리드는 기원전 3세기에 처음으로 물리학의 기본 법칙을 성문화했습니다. 현실 세계에서는 금속 공뿐만 아니라 반사 물체도 흔합니다!
레이 트레이싱 반사: 반사 표면에서 추가 광선이 방출됩니다. 반사광선의 방향은 반사법칙을 사용하여 입사광선의 방향을 기준으로 계산됩니다. 광선이 장면의 객체에 닿으면 직접 보이는 표면과 동일한 조명 계산을 사용하여 표면이 음영처리됩니다.
레이 트레이싱 투명도, 알파 블렌딩이 아닌 "실제" 투명도! 실제 광학에서는 빛이 반투명 물체를 통과할 때 빛의 일부는 흡수되고 일부는 흡수되지 않습니다. 특별한 순서 없이 표면 뒤에서 광선을 방출하여 반사된 광선처럼 음영 처리합니다.

투명도와 그림자: 그림자 광선이 투명한 물체에 닿으면 빛을 향해 계속됩니다. 투명한 물체에 투사된 그림자 광선은 마치 그림자 광선이 아닌 것처럼 착색되고 다시 방출되어야 하며, 그림자 광선은 표면의 완전히 투명한 영역을 통과하고, 그림자 광선은 반투명 물체에서 색상을 얻고, 그림자 광선은 투명한 물체와 상호 작용합니다!
요약하면, 레이 트레이싱이 쉬워서 사실적인 광원 시뮬레이션을 간단하고 기존 래스터 기반 엔진과 쉽게 통합할 수 있습니다.
Call of Duty의 차세대 후처리는 COD에 대한 차세대 포스트 프로세스 프로세스, 기술, 적용 및 최적화를 분석합니다. 포스트 프로세스 파이프라인에는 모션 블러, Bokeh DOF, 서브서피스 스캐터링(SSS), 블룸, 섀도우 샘플링 등이 포함됩니다.
COD의 방법은 색상 버퍼, 깊이 버퍼, 속도 버퍼와 같은 입력으로 필터링하는 포스트 프로세스 특수 효과를 기반으로 하며 화면 공간 포스트 프로세스 DOF가 완전히 정확할 수 없습니다. 누락된 정보: 모션 블러에서는 객체가 움직일 때 배경이 보이고, DOF 배경에서는 뷰가 서로 다른 시점에서 누적됩니다.
산란 기술을 사용하여 자연스럽게 구현된 수집 시 산란은 필터 기반 접근 방식을 허용하지만 샘플링 영역을 결정하고 실제로 작동하는 샘플을 감지하고 배경을 복구하는 데 문제가 있습니다.

흩어져 있는 모션 블러 사례 모음입니다. 이 경우 샘플링 속도는 실제로 현재 픽셀을 커버할 수 있을 만큼 크고, 샘플도 현재 픽셀보다 카메라에 더 가깝습니다. 따라서 두 경우 모두 샘플이 작동한다는 것을 의미합니다.
모션 블러의 샘플링 영역을 결정하는 방법에 대한 문제의 경우 3개의 패스를 사용할 수 있습니다.
1차 통과[타일 최대값]: 최대 속도를 타일 단위(20x20픽셀)로 계산합니다.
2차 패스[타일 주변]: 3x3 코어에 있는 각 타일의 최대 속도를 계산합니다.
3rd Pas [모션 블러]: 타일 속도 방향으로 전체 해상도 가변 폭 블러를 적용합니다.
다음은 다양한 방법의 모션 블러 렌더링입니다.

왼쪽에서 오른쪽으로: McGuire2013 방법, 정확한 샘플 기여, 정확한 샘플 기여 + 미러링된 배경 재구성.
샘플링 측면에서 균일성, 백색 잡음, 디더링, 시간 디더링 등 여러 가지 방법이 시도되었습니다.
모션 블러 최적화: 각 타일에 대한 최소/최대 값(최대 값과 비교)을 계산합니다. [max-min]이 작으면 더 간단한 버전을 사용할 수 있고, [max-min]이 0과 같으면 알고리즘은 일반 색상 평균으로 수렴합니다.
구현 팁: [너비 x 높이]에서 [20 x 높이] 버퍼까지의 수평 패스와 [20 x 높이]에서 [20 x 20]까지의 수직 패스를 사용하여 분리 가능한 방법을 사용하여 최대 속도(더 빠르게)를 계산합니다. [Sousa2013]에서 영감을 얻은 것과 유사하게 속도를 깊이에 통합하는 COD는 R11G11B10 버퍼로, 샘플당 적중 횟수를 3(색상, 속도, 깊이)에서 2(색상, 속도/깊이)로 줄입니다. [McGuire2013]과 유사하게 디더링은 타일의 텍스처 좌표에 액세스하는 데 사용되어 타일 아티팩트를 줄이는 데 도움이 되며 포인트 샘플링을 사용하여 오버플로를 방지합니다.
DOF 개요: 모션 블러에 대한 많은 아이디어가 DOF에 적용되어 양 당사자 모두에 대한 산란 작업으로 수집됩니다. 제시된 "흩어짐으로 수집" 모션 블러 방법은 단일 레이어(단일 방향)에만 적용되며 많은 부분이 발생하고 겹칠 수 있지만 COD에서는 모션 블러가 그다지 큰 문제가 아니며 보기가 더 쉽고 움직이는 객체가 문제를 숨깁니다. 따라서 2단계 접근 방식이 개발되었습니다. 항상 좋아 보이는 것을 원한다면 실제 카메라 제어(조리개, 초점 거리...)를 사용하면 제작 시 DOF 문제를 해결하기가 더 어려워집니다. 플레이어에 의해 트리거된 DOF는 창의적으로 제어할 수 없습니다.
전통적인 DOF 문제:
- 모이는 것은 흩어지는 일이다.
모션 블러와 마찬가지로 인근 픽셀도 현재 픽셀로 번질 수 있으며 유사한 솔루션입니다. 기본 2D 필터 반경에 비례하여 타일의 최대 COC를 계산합니다.
각 샘플의 기여도를 계산하고, 샘플을 분류 및 혼합하고, 배경 재구성을 수행합니다.
필터 품질 문제. 언더샘플링에는 이중선형 필터링을 올바르게 사용해야 합니다.
성능 문제. 많은 샘플, 절반 해상도 렌더링.
수집에 이상적인 알고리즘은 다음을 분산시키는 것입니다.
샘플 COC가 현재 픽셀과 겹치는지 감지합니다.
전경인지 확인하세요.
겹치는 전경 픽셀을 뒤에서 앞으로 정렬합니다.
각 샘플
에 투명도를 할당합니다. 여기서 는 COC 반경입니다. 섞으세요.
정렬 비용이 비정상적으로 비쌉니다.

DOF 샘플의 측면도(왼쪽)와 평면도(오른쪽).
COD 분류 방법:
[Lee2008]과 유사하게 성능이 단순화되었습니다.
샘플을 배경, 전경의 두 레이어로 나눕니다.
각 레이어에 대해:
전경 알파를 계산합니다.
알파 혼합 전경/배경.
느슨한 전경/배경 분류 그라데이션.
거리 0인치: 전경.
- 거리 100인치: 배경.

현재 샘플의 COD 전경, 배경, 측면도, 상면도입니다.
이중선형으로 샘플링할 때 색상 오버플로가 발생합니다(아래 오른쪽 그림).

일반적으로 극단적인 경우에 적합한 COC 사전 곱셈을 사용하여 해결되며, 특히 높은 동적 범위 이미지에 적합한 경우 중간에 실패할 수 있습니다. RGBA16 버퍼, 더 많은 메모리가 필요하며 색상 전용 루프(타일 최적화)와 호환되지 않습니다. 더 작은 숫자로 인코딩된 색상은 정밀도를 감소시킵니다.
이중선형 필터링의 구체적인 방법:
- 사전 필터링되었습니다.
색상 버퍼는 이중선형 샘플링을 사용합니다.
깊이 버퍼는 Gather4+를 사용하여 최소 양측 가중치를 계산합니다.
메인 채널.
색상 버퍼는 포인트 샘플링 + 임의 오프셋을 사용합니다.
포인트 샘플링 + 무작위 오프셋을 사용하여 버퍼를 사전 정렬합니다.
그러나 빠른 타일(컬러 루프만 해당)의 경우 이중선형 샘플링 + 임의 오프셋을 사용합니다.
섀도우 측면에서는 60FPS가 필요하기 때문에 샘플 예산이 많지 않아 섀도우 필터링의 한계가 매우 어려웠습니다. COD는 픽셀당 무작위로 회전하는 포아송 디스크를 실험한 결과 결과의 품질이 낮고 샘플 수가 적당하며(8개) 움직임이 매우 불안정하다는 사실을 발견했습니다.
노이즈 발생기의 실험과 최적화를 통해 지터와 랜덤 사이의 중간으로 분류될 수 있는 인터리브 그라데이션 노이즈라는 노이즈 함수가 발견되었습니다.
float3 magic = float3( 0.06711056, 0.00583715, 52.9829189 );
return -scale + 2.0 * scale * frac( magic.z * frac( dot( sv_position, magic.xy ) ) );샘플 회전의 경우:
sincos( 2.0 * PI * InterleavedGradientNoise( sv_position ), rotation.y, rotation.x );
float2x2 rotationMatrix = { rotation.x, rotation.y, -rotation.y, rotation.x };
...
float2 sampleOffset = mul( offsets[i], rotationMatrix );두 가지 장점 모두: 무작위 노이즈와 유사한 풍부한 범위의 값을 생성하고 디더링 구성표와 유사하게 시간적으로 일관된 결과를 생성합니다. 이 노이즈는 엇갈린 그라데이션을 생성합니다. 즉, 일정한 속도로 움직이는 물체가 샘플을 부드럽게 회전한다는 의미입니다. 정적 이미지에 적합하게 만들려면 가로 위치를 스크롤하면 됩니다.
sv_position.x += scale * time;
엇갈린 그라데이션 노이즈 및 엇갈린 그라디언트.
엇갈린 그래디언트 노이즈의 공간적 일관성으로 인해 블러링을 통해 더 쉽게 스무딩할 수 있습니다. 이는 COD의 경우 흐려질 수 없지만 다른 상황에서는 유용할 수 있습니다.

위의 모든 개념을 종합하면 시간이 지남에 따라 부드럽게 회전하는 나선형이 있습니다. 이는 실제로 높은 프레임 속도에 제공한 것보다 더 많은 샘플입니다.

The Order: 1886을 위한 차세대 머티리얼 파이프라인 제작에서는 "Order: 1886" 게임의 차세대 머티리얼 파이프라인에 대해 설명합니다.
"Order: 1886" 엔진의 조명 파이프라인: 블록 포워드 렌더링을 사용하고 투명한 객체는 디퓨즈 + 스페큘러 반사의 완전한 조명을 사용합니다. 정적 지오메트리는 H 방향 변경 기준에 따라 Optix를 사용하여 GPU 팜에서 구운 라이트맵을 사용합니다. SH 동적 프로브는 3차(계수 9개), 사전 컨볼루션된 반사 프로브, 엔진에서 렌더링되고 컴퓨팅 셰이더에서 컨볼루션된 큐브맵을 사용합니다.

앰비언트 오클루전(AO): 방향성 AO 맵(H 기반)은 캐릭터와 정적 기하학을 굽고, 정적 기하학은 프로브의 스페큘러 반사를 차단하는 데만 사용되며, 동적 기하학은 SH 프로브의 확산에 AO를 적용합니다.
핵심 셰이딩 모델: 기본 스페큘러 반사 BRDF는 Cook Torrance이고 D 항은 Walter et al.의 GGX 분포(동일 논문에서 파생된 Smith G 항과 일치), Schlick의 프레넬 시뮬레이션 및 Lambert 디퓨즈(스페큘러 반사 강도와 균형을 이룸)입니다. GGX+Cook Torrance== 많은 수학, 최적화 가능, 삼각형을 사용하지 않음, Smith의 G 용어를 분모로 축소, 아티스트가 sqrt(러프니스)를 사용하도록 허용, 더 직관적이고 블렌딩에 더 좋음.
// Helper for computing the GGX visibility term
float GGX_V1(in float m2, in float nDotX)
{
return 1.0f / (nDotX+ sqrt(m2 + (1 -m2) * nDotX* nDotX));
}
// Computes the specular term using a GGX microfacetdistribution. m is roughness, n is the surface normal, h is the half vector, and l is the direction to the light source
float GGX_Specular(in float m, in float3 n, in float3 h, in float3 v, in float3 l)
{
float nDotH= saturate(dot(n, h));
float nDotL= saturate(dot(n, l));
float nDotV= saturate(dot(n, v));
float nDotH2 = nDotH* nDotH;
float m2 = m * m;
// Calculate the distribution term
float d = m2 / (Pi * pow(nDotH* nDotH* (m2 -1) + 1, 2.0f));
// Calculate the matching visibility term
float v1i = GGX_V1(m2, nDotL);
float v1o = GGX_V1(m2, nDotV);
float vis= v1i * v1o;
// Multiply this result with the Fresnel term
return d * vis;
}기타 사용 가능한 BRDF: Beckmann, Anisotropic GGX, Hair(Kajiya Kay), Skin(사전 통합된 확산), Cloth.
스킨: 역사상 가장 비싼 셰이더!

헤어 컬러링: 신체 기반이 아니며 Kajiya Kay 조명 모델을 사용합니다. SH 디퓨즈에 대한 탄젠트 방향을 사용하여 프레넬 곡선 조정, 이방성 표면 분석, 탄젠트 조사 환경 맵 [Mehta 2012]. 2차 스페큘러 반사 리프는 알베도 색상을 취하면서 끝 부분을 향해 탄젠트 방향으로 이동합니다.

탄젠트 방향으로 추가 이동을 통해 지도를 오프셋하여 하이라이트를 분할합니다.

탄젠트 방향을 정의하는 흐름도:

직물 색상: 디지털 사진 관찰: 크고 부드러운 감쇠를 갖는 부드러운 반사 로브, 러프니스 산란으로 인한 가장자리 보풀, 전방 각도에서 낮은 반사 기여도, 일부 직물은 투톤 반사 색상을 갖습니다.
러프니스 산란을 위한 역 가우시안. 기하학 항 없이 원점에서 변환되어 전방 각도에서 더 많은 스페큘러 반사를 제공합니다.

일반 Cook-Torrance + 노멀 맵은 뚜렷한 하이라이트 앨리어싱을 생성합니다. Han et al.의 "주파수 영역 노멀 맵 필터링"을 기반으로 한 기술을 사용하여 러프니스 맵을 수정하여 앨리어싱을 줄였습니다.

NDF는 구형 가우스 분포(vMF distribution)로 표현되고, SH로 표현된 근사 BRDF는 가우스 분포이며, 두 가우스 함수의 컨볼루션은 새로운 가우스 함수이며, 이 관계를 이용하여 새로운 거칠기를 계산한다.


사실적인 재료를 얻기 위해 3D 스캐닝 기술이 사용됩니다.

자료 = 텍스트 리소스, 사용자 정의 데이터 언어(radattr) 사용, 언어 지원: 유형, 상속, UI 레이아웃, 메타데이터. 머티리얼 생성은 셰이딩 트리가 없는 함수 기반이며 실시간 편집을 위한 머티리얼 편집기 도구도 Maya 내에서 호스팅할 수 있습니다.

템플릿 제작을 위한 Radattr 상속, 기본 재질에서 공유되는 공통 매개변수, 파생 재질은 기본 재질의 변경 사항만 저장하고, 자산을 더 빠르게 생성하며, 단일 자산에서 전역 변경이 가능합니다.

셰이더: 손으로 작성한 Uber 셰이더, 다수의 #if, 주요 재질 특성 = 매크로 정의, 셰이더에 하드코딩된 매개변수(사양 강도, 러프니스 등). 단, 애니메이션 또는 합성 시 텍스처 및 애니메이션 매개변수를 처리하기 위해 일부 코드가 자동으로 생성됩니다. 사전 정의된 "배열"을 사용하면 배열 = 매크로 정의 + 진입점, 스키닝 배열, 블렌드 셰이프, 인스턴싱, 라이트맵 등, 시각화/디버깅을 위한 디버그 배열, 배열 + 재료를 기반으로 빌드 파이프라인에서 컴파일된 셰이더입니다.

장점: 셰이더는 머티리얼에 최적화되어 있고, 최적화 프로그램은 전체 액세스 권한을 가지며, 게임 자체에서 런타임 컴파일이 없습니다(도구에서 사용). 단점: 컴파일할 셰이더가 너무 많습니다! 모든 것이 캐시되지만 반복 속도가 느려질 수 있고 전체 셰이더를 디버그하기가 어려우며 컴파일러에 크게 의존합니다.
재료 조합: 주로 오프라인 프로세스입니다. 머티리얼 애셋은 조합 스택을 지정합니다. 스택의 각 레이어에는 참조 자료, 혼합 마스크, 혼합 매개 변수, 재귀 구성 + 참조 자료 조합, 레이어별 픽셀 셰이더 사용이 포함됩니다. 재료 및 블렌드 맵에서 파라메트릭 맵을 생성합니다. BRDF, 천, GGX 및 이방성의 합성 하위 집합을 지원합니다. 합성천에는 BRDF 2겹을 적용해야 합니다.

// Compositing pixel shaderrun on a quad covering the entire output texture
CompositeOutputCompositePS(in float2 UV : UV)
{
CompositeOutputoutput;
float blendAmt= BlendScale* BlendMap.Sample(Sampler, UV);
float4 diffuseA= DiffuseTintA* DiffuseMapA.Sample(Sampler, UV);
float4 diffuseB= DiffuseTintB* DiffuseMapB.Sample(Sampler, UV);
float diffuseBlendAmt= blendAmt* DiffuseContribution;
output.Diffuse= Blend(diffuseA, diffuseB, diffuseBlendAmt, DiffuseBlendMode);
// Do the same for specular, normals, AO, etc.
return output;
}재질 레이어: 기본 재질에서 파생된 최대 4개의 레이어, 각 레이어는 버텍스 색상에 따라 구동되는 별도의 합성 체인입니다.
LayerParamscombinedParams;
[unroll]
for(uinti= 0; i< NumLayers; ++i)
{
// Build all layer paramsfrom textures and hard-coded
// material parameters
LayerParamslayerParams= GetLayerParams(i, MatParams, Textures);
// Blend with the previous layer using vertex data and blend masks
combinedParams= BlendLayer(combinedParams, layerParams, vtxData, BlendMode, Textures);
}
// Calculate all lighting using the blended params
return ComputeLighting(combinedParams);Ryse의 렌더링 기술은 Ryse: Son of Rome 게임에 사용된 엔진인 CryEngine에서 채택한 PBS, 폐색, SSDO, 반사 폐색, AO 색상 오버플로, 이미지 안정성, 기하학적 앨리어싱, 하이라이트 앨리어싱, LOD 선택, 파티클 셰이딩, 그림자(태양, 포인트 라이트 그림자, 캐릭터 그림자, 정적 그림자 맵, 입자 그림자, 영화 및 TV 수준 그림자), 대규모 AO 등을 포함하여 채택된 다양한 렌더링 기술을 설명합니다.
PBS 측에서는 일관성에 초점을 맞추고 잘 정의된 규칙 세트를 따르는 실제 동작을 기반으로 빛과 물질의 상호 작용을 모델링하는 것은 그래픽 프로그래밍에서 많은 추측을 없애고 여러 분야에 큰 영향을 미칩니다. 머티리얼 모델: 자산에 대한 명확한 규칙을 정의하여 아트/콘텐츠 일관성을 높이고 합리적인 머티리얼 매개변수를 적용하며 비현실적인 설정을 방지합니다. 조명 모델: 더욱 복잡한 BRDF, 프레넬, 반사 정규화, 전반적인 에너지 보존, 마이크로패싯 BRDF는 여전히 제한적이고 현실적인 모델입니다. 조명 모델: 파이프라인 전체에서 재료 무결성을 보호하기 위해 주의를 기울여야 합니다. 물리적 기반 셰이딩은 모든 영역이 존중되는 경우에만 잘 작동합니다.
셰이딩 모델의 한계: 주로 학문적 연구에서 모델의 수학적 정확성을 위해 많은 노력이 기울여졌으며, 일반적인 분석적 반사 마이크로패싯 BRDF는 다중 빛 바운스를 고려하지 않고 거친 표면의 파장 의존적 흡수를 무시하는 현실의 유한한 모델일 뿐입니다.
조명 모델 참고 사항: 재료의 무결성을 유지하려면 주의가 필요합니다. 광원이 스페큘러 반사에 영향을 주지 않고 무작위로 확산 기여도를 추가할 수 있다면 실제 반사율은 쓸모가 없게 됩니다. 해당 양의 스페큘러 반사를 추가하지 않고 디퓨즈를 추가하면 재료 반사율 F0이 효과적으로 감소하므로 재료가 상당히 평탄해집니다. Ryse의 모든 확산 전용 상수 및 반구형 환경 조건을 제거하고 순수 반사 표면(금속)에는 영향을 주지 않으며 확산 및 반사 큐브맵이 있는 로컬 환경 프로브에서 캡처한 모든 간접 조명, 더 넓은 영역으로 확장되는 프로브에는 로컬 조명 강도 변화가 부족하여 평평한 환경이 될 수 있습니다. 승수 조명("주변 조명")은 조명 아티스트가 바운스 조명 및 폐색을 설정하는 유틸리티로 도입되었습니다[SCHULZ14]. 주변광은 간접 확산 및 스페큘러 반사에도 영향을 주어 반사율을 유지합니다.
Occlusion은 전역 조명의 중요한 부분이고, AO는 객체 간의 공간적 관계를 이해하는 중요한 단서, 소규모 폐색: SSDO, 스크린 스페이스 리플렉션(SSR), 대규모 폐색: 음의 주변광을 사용하는 로컬 프로브, 간단한 그림자 맵을 기반으로 하는 폐색 시스템입니다. 특수 솔루션: 눈에 대해 미리 구운 오클루전 맵, 일부 자산에 대해 미리 구운 AO 맵.
SSDO: 간단한 SH와 같은 방향성 폐색 인코딩을 기반으로 단일 화면 공간 방향 기술로 SSAO를 완전히 대체합니다. 두 개의 독립적으로 사용되는 밴드: 상수 부분과 방향성 부분, 간접 확산 조명에 적용되는 상수 항(SSAO에서와 같이), 직접 조명에 사용되는 방향 항, 간단한 접촉 그림자 제공, 조회를 위해 광원 방향 사용, 빛의 확산 및 스페큘러 반사 기여에 적용됨, 두 부분 모두 반사 폐색에 사용됨, 간접 스페큘러 반사 어둡게 하기, 뷰 반사 벡터 사용 조회.

반사 폐색 켜기(왼쪽)와 끄기(오른쪽) 비교.
AO 색상 번짐: 주변광의 주요 부분을 제거하면 너무 어둡게 보일 수 있습니다. 특히 흡수율이 낮은 밝은 표면(흰 피부 포함)에서는 더욱 뚜렷해집니다. AO는 다중 빛 반사 발생을 고려하지 않습니다. 최대 AO 어두워짐을 제한하면 도움이 되지만, 어두운 표면에서는 AO가 너무 약해지기 때문에 표면 알베도에 따라 폐색 정도를 조정해야 합니다.
간단한 색상 유출 근사치: 매우 저렴해야 했던 마지막 순간 함수로, 로컬 산란의 매우 조잡한 근사치로 알베도 버퍼의 저주파 버전을 생성하고, 폐색 값에 적용된 감마 함수로, Ryse의 과장된 색상 변경으로, 약간의 GI 인상을 줍니다.
float3 occlColor = pow(occlTerm, 1 - min( bleedColor * bleedColor * bleedColor * 3, 0.7 ));
컬러 블리드 오프(위)와 온(아래) 비교. 켜면 물체의 홈이 약간 밝아집니다.
이미지 안정성: 깨끗하고 일시적으로 안정적인 이미지는 인지된 품질에 매우 중요합니다. 시각적 노이즈는 주의를 산만하게 하며 기하학적 앨리어싱, 음영 앨리어싱 및 반사 앨리어싱을 포함한 다양한 형태의 앨리어싱을 최소화해야 합니다.
음영 앨리어싱:
SSR(Ray Marching), 섀도우 맵 샘플링 등 언더샘플링, 오버샘플링, 다중 해상도 렌더링 등으로 인해
알고리즘 수준의 특정 솔루션으로 해결해야 하며 일반적으로 정적 이미지에서 약간 더 높은 품질을 제공하는 방법보다 일시적으로 안정적인 방법을 선호합니다.
기하학 톱니:
우주 톱니. MLAA, FXAA 및 SMAA와 같은 포스트 프로세스 기반 방법은 Ryse [JIMENEZ12]에서 사용되는 악명 높은 톱니 모양/계단 아티팩트인 SMAA에 매우 효과적입니다.
시간이 들쭉날쭉했습니다. 더 어려운 문제 중 하나는 하위 픽셀 크기의 삼각형이 한 프레임에서는 래스터라이제이션되지만 다른 프레임에서는 래스터라이제이션되지 않아 깜박임/반짝임이 발생한다는 것입니다. 픽셀당 더 많은 샘플 필요(MSAA, 슈퍼샘플링) 슈퍼샘플링은 Ryse에서 사전 녹화된 영화를 위해 완벽하게 지원되며 PC 버전에서도 사용할 수 있습니다.
시간 기하학이 들쭉날쭉합니다.
MSAA는 Xbox One의 지연 음영 처리 옵션이 아닙니다. 대역폭이 크게 증가하고 ESRAM 크기 문제가 발생합니다. 2x MSAA는 충분히 높지 않으며 이전 프레임의 데이터에 의존해야 합니다.
- 궁극적으로 사용된 솔루션은 새로운 SMAA 1TX [SOUSA13]였습니다. 이는 더 나은 시간적 안정성을 위해 여러 프레임을 축적하고 이전 프레임의 형상을 추적하지만 동적 객체의 픽셀을 정확하게 재투영할 수 없을 때 고스팅을 방지하기 위해 신호 변경을 제한합니다. 지나치게 매끄러운 이미지를 피하는 열쇠는 신호 주파수를 기준으로 누적된 샘플 수를 선택하는 것입니다. 이미지의 저주파 부분의 샘플 수가 적을수록 고주파 부분의 샘플이 많아집니다.
거울 톱니:
물리 기반 셰이딩은 고주파수 일반 정보와 결합된 정규화된 BRDF의 높은 밝기 값인 반사 앨리어싱에 매우 취약합니다.
Ryse의 노멀과 러프니스는 엄격하게 결합되어 있습니다. 개념적으로 법선은 거시적 규모의 표면 범프, 미시적 규모의 러프니스, 거칠기는 소스 자산의 노멀 맵 알파 채널에 저장되고 엔진당 2개의 텍스처로 분할됩니다(일반의 경우 BC5, 거칠기의 경우 BC4), 러프니스 맵의 밉의 노멀 분산[HILL12], 분산을 추정하고 새로운 거칠기를 파생하는 데 사용되는 Toksvig 계수[TOKSVIG04].
GBuffer(데칼, 빗물 습도)에서 거칠기를 수정할 때 여전히 문제가 있는데, 화면 공간에 일반 분산 필터를 적용하여 해결되었습니다[SCHULZ14].
LOD 선택: LOD 선택이 향상되어 LOD 변환을 위한 최적의 관찰자 거리를 계산하고 작은 삼각형을 피하여 앨리어싱을 줄이는 데 도움이 됩니다(성능도 향상됨). 평균 화면 공간 삼각형 크기를 계산합니다. 화면에 투영된 크기가 임계값보다 낮을 때 메시가 너무 자세하고 다음 LOD 메시를 사용해야 합니다. 오프라인으로 미리 계산된 평균 메시 삼각형 영역, 다양한 가능한 측정항목: 평균, 중앙값, 기하 평균 등. 기하 평균(로그 평균)을 선택하면 작은 삼각형이 많으면 값이 감소하지만 큰 삼각형 몇 개는 값이 거의 증가하지 않습니다. 첫 번째 LOD 전환에 대해 방금 계산한 전환 거리이며, 후속 LOD에서는 이 거리의 배수를 사용하여 특정 LOD 메시가 완전히 건너뛰는 것을 방지합니다.

위: 객체 크기를 사용한 LOD 선택; 하단: 삼각형 크기를 사용한 LOD 선택.
태양 및 점광 그림자: 태양에 대한 계단식 그림자 맵, 대략적인 로그 분할 형식, 점 조명이 개별 프로젝터로 전개되고, 각 프로젝터는 대형 그림자 아틀라스에서 블록으로 렌더링되며, 블록 해상도는 프로젝터의 중요성에 따라 다릅니다. 그림자 폐색은 전체 화면에서 평가되고 "그림자 마스크" 텍스처 배열에 누적됩니다. 조명당 하나의 색상 채널, 가능한 경우 채널 공유, 그림자 수신 영역의 효율적인 스텐실 컬링 허용, 타일 셰이딩 중 GPR 압력 감소, 픽셀 단위 회전 포아송 디스크를 통한 필터링.
캐릭터 그림자: 3인칭 관점, 항상 초점이 맞춰진 주인공, 고품질 자체 그림자, 좁은 경계 상자에 초점을 맞춘 사용자 정의 그림자 맵, "max" 연산자를 사용하여 그림자 마스크에 혼합.
정적 그림자 맵:
개발 초기에는 Draw Call이 큰 병목 현상이었으며, 특히 섀도우가 프로젝트의 주요 리스크였습니다. 대부분의 그림자 그리기 패스는 장거리 캐스케이드에 사용되며 고도로 최적화된 자산에서도 세계 적용 범위가 기하급수적으로 증가하고 집계 거리 컬링 및 그림자 투사는 가능한 경우 비활성화됩니다. 최적화의 절충점은 멀리 있는 동적 그림자가 없다는 것입니다.
간단한 접근 방식: 가장 먼 캐스케이드를 "정적 섀도우 맵"으로 교체, 8192 x 8192 픽셀, 픽셀당 16비트: 128MB 비디오 메모리, 객체당 한 번만 렌더링, 정적 섀도우 맵 채우기 후 캐스케이드를 교체하는 데 그림자 그리기가 필요하지 않음, 월드 공간 해상도(미터당 픽셀)가 첫 번째 레벨과 일치하거나 초과함, 해상도 측면에서 품질 손실이 없음, 로그 텍셀 분포의 편차로 인한 새로운 언더샘플링 왜곡, 상당히 미미함 라이즈.
어떤 캐스케이드를 선택할 것인가? 대수 분할 체계는 고정된 세계 공간 영역에 대한 기하급수적인 저장 요구 사항을 초래했으며 CryEngine은 품질 손실 없이 약 1.3km x 1.3km의 영역을 커버할 수 있는 캐스케이드 4를 최상의 옵션으로 선택했습니다.

1km x 1km 영역에 필요한 텍스처 크기는 첫 번째 교체 캐스케이드의 해상도를 일정하게 유지합니다(로그 스케일).
- 지도 배치 및 업데이트, 레벨 체크포인트, 디자이너와 조명 아티스트가 제어하는 영역 간 전환. XBox One에서 약 10-15ms의 전체 업데이트, 프레임 속도 급증을 방지하기 위한 시간 분할 업데이트 전략, 프레임당 그리기 호출 수 제한, 스트리밍 옵션: 렌더링 개체가 완전히 스트리밍된 후. 최적화된 자산에서 섀도우 드로우 호출을 약 40%-60% 절약합니다.
영화 수준의 그림자: 태양 그림자에는 샘플 분포 그림자 맵[LAURITZEN11]으로 시작하는 고품질 그림자 솔루션이 필요합니다. 좋은 결과를 얻었지만 다시 읽기를 제거하는 방법은 무엇입니까? 이전 프레임의 데이터에는 결함이 너무 많아서 다시 읽어들이는 것을 피하려면 지오메트리 셰이더를 사용해야 하거나(느리게!) GPU에서 호출을 완전히 컬링하고 그려야 하는데 이는 너무 위험합니다. 궁극적으로 매우 실용적인 솔루션이 채택되었습니다. 컷씬 제작 도구에서 근거리/원거리 그림자를 노출하고 근거리/원거리 간의 전체 로그 분할, 화면 해상도를 초과하는 2048 x 2048 그림자 맵을 사용했습니다.
대규모 AO: 마지막으로 [SWOBODA10]과 유사한 방법을 사용하여 장면을 하향식 그림자 맵으로 렌더링하여 높이 맵 근사치를 생성했습니다. 전체 화면 채널: 모든 픽셀
선택한 AO 알고리즘을 사용하여 섀도우 맵 공간에 투영하고, 주변 픽셀을 샘플링하고, 폐색을 계산합니다.

주로 가장 큰 규모의 특징 캡처에 초점을 맞춘 저해상도 섀도우 맵(픽셀당 약 0.5미터), 2048 x 2048이면 1km x 1km의 영역을 커버하기에 충분합니다. AO 커널 샘플링 반경: 7.5미터. Ryse는 움직이는 객체의 비율이 그렇게 높지 않으며 정적 섀도우 맵과 동일한 업데이트 전략을 사용합니다. 픽셀당 4개(인터리브된) 샘플을 사용하는 매우 낮은 주파수 효과는 절반 또는 1/4의 시간에 쉽게 수행할 수 있으며 일반 SSDO 패스와 병합하면 약간 더 나은 성능을 얻을 수 있습니다.

대규모 AO 끄기(왼쪽)와 켜기(오른쪽) 비교.
그 효과는 XBox One에서 0.4밀리초로 상당히 낮은 오버헤드로 놀라울 정도로 좋습니다. 집에서 창문을 통해 볼 때와 같이 하늘이 대부분 가려지는 영역에서는 큐브맵의 하늘 기여도를 적절하게 줄입니다. 하지만 실외에서만 높이 맵 표현이 장면과 일치하지 않고 구조가 겹치는 경우 문제가 발생할 수 있습니다.
Intel 그래픽 팁, 요령 및 Clever Bits를 사용하여 최고의 성능 달성에서는 Intel GPU 칩의 성능을 최적화하기 위한 팁을 설명합니다.
효율적인 GPU 프로그래밍을 위해서는 애플리케이션별 및 일반 모두에서 IA 소프트웨어 스택의 최적화와 같은 파이프라인의 완전한 활용이 필요하며 애플리케이션 최적화가 가장 큰 영향을 미칩니다.

GPU 프로그래밍 최적화에는 애플리케이션, 드라이버 및 GPU의 세 가지 계층이 포함됩니다.
도면 일정 및 리소스 업데이트: 3D/2D 작업 일정, 상태/셰이더 변경, 리소스 위치 등 예약된 작업에 대한 메모리 액세스 패턴에 주의하세요.

드로우콜 정렬 시 영향력이 가장 크며 동일한 리소스를 가진 드로우콜을 함께 정렬합니다. 예를 들어 RT가 가장 큰 영향을 미치므로 그림에서는 0과 1이 함께 배열되어 있습니다. 그러면 동일한 리소스가 참조됩니다(그림 참조).
그래픽은 퍼즐의 일부일 뿐이며 고유한 아키텍처 기능: 전력 및 성능, 메모리 계층 구조, 쌍을 이루는 플랫폼: CPU, 시스템 메모리, 기타 제약 사항: 열, 전력 등

CPU/GPU, CPU 또는 GPU 병목 현상 간의 관계, CPU가 GPU를 제한할 수 있음...

가로축은 전체 전력, 세로축은 각 하드웨어 유닛의 전력입니다. 왼쪽: 총 전력이 증가하면 GPU 전력이 먼저 감소한 다음 증가합니다. CPU의 경우 그 반대가 적용되며, 사용되지 않은 전력은 처음에는 약간 증가한 다음 감소합니다. 오른쪽: 총 전력이 증가함에 따라 GPU 주파수는 먼저 감소한 다음 일정하게 유지된 다음 증가합니다. 반면 CPU의 경우 그 반대입니다.
위 차트는 2014년경의 Intel 하드웨어 아키텍처에만 적용됩니다. 다른 GPU 제조업체에서도 이것이 여전히 적용되는지 여부는 아직 확인되지 않았습니다.
캐시 위치가 가장 중요합니다. CPU 및 GPU에 대한 메모리 액세스 최적화, 메모리 대역폭 제한, 플랫폼에 따라 계층 구조가 다름, 옵션 CPU+GPU 캐시: 최종 레벨 캐시(LLC), 내장형 DRAM(eDRAM).

아키텍처 구성요소:
- 비슬라이싱.
고정 기능: 변환, 잘라내기
- 슬라이스.
일반적인 슬라이싱: 래스터라이제이션, 셰이더 스케줄링, 컬러 백엔드
- 서브슬라이스: 셰이더 실행

스키마 확장/확장 구성요소:
슬라이싱: 병렬 원시 처리.
서브슬라이싱(Subslicing) : 평행폭(span) 처리.

샘플러: L3 캐시가 지원하는 하위 슬라이스당 1개의 샘플러 로컬 텍스처 캐시.

샘플러 성능: 캐시 위치를 기억하시나요? 처리량: 형식, 샘플링 모드, 열악한 액세스 패턴은 메모리 대역폭과 대기 시간을 증가시킵니다.

채우기 속도: 픽셀 백엔드, 컬러 캐시(RCC$) 등 슬라이스당 공통입니다.

채우기 속도 성능, 출력 색상:
-처리량.
체재.
차원 + 면적.
기타 요인.
래스터라이제이션.
고급 Z/S.
픽셀 셰이더 실행.
나중에 Z/S.
혼합된 기능 + 모드.

표면 형식: 색상 범위, 중간/최종 렌더링 대상에 적합한 형식을 선택합니다. 더 높은 정밀도 형식을 선택할 필요는 없습니다. 그렇지 않으면 채우기 속도가 감소하고 메모리 대역폭이 늘어납니다.
산술 논리: 실행 단위(EU) 및 명령어 캐시(IC$)를 포함한 하위 슬라이스 블록.

산술 논리 성능: 제어 흐름, 수학, 확장 수학, 최대 동시 레지스터 수와 같은 알고리즘 복잡성.

셰이더 최적화: 의도 기반 최적 코드, 셰이더 스케일링, 일반 셰이더 케이스, 미사용 출력 생성.

지오메트리 셰이더: 단일 비슬라이스, 고정 기능: VS, HS, TE, DS, GS, SOL, 클리핑, 설정 프런트엔드.

알고리즘 복잡성을 높이기 위한 형상 최적화, 개별 형상의 최적 정의, 플랫폼 기반 품질 확장, 의도: 조명, 깊이, 애니메이션...

기하학의 부드러운 모서리와 단단한 모서리의 방법과 효과를 비교합니다.
메모리 대역폭: 모든 것은 메모리에 관한 것이며 플랫폼마다 다릅니다. 우려되는 이유는 메모리에서 읽고 메모리에 쓰는 것입니다.
샘플러 처리량: 차원 수, 형식 및 필터링 모드를 포함하여 모든 사용 사례에 대해 측정된 다양한 아키텍처 및 플랫폼입니다.

채우기 속도: 렌더링 대상을 포함한 다양한 표면 유형: 형식, 치수, 혼합/비혼합, 깊이: 읽기/쓰기, 템플릿: 읽기/쓰기.

기하 처리량: 고정 기능 대역폭 및 산술 논리, 고정 기능(클리핑/컬링, 래스터라이제이션), 기하 변환: ALU.

2015년이 왔습니다. 올해에는 DirectX 12와 Vulkan으로 대표되는 차세대 그래픽 API가 공식적으로 출시되었습니다. 그 직후에는 그 특성과 용도를 설명하는 많은 문서가 나왔습니다. D3D12 효율성과 성능에 대한 새로운 의미가 그 중 하나입니다. 이 기사에서는 명령 목록, 루트 서명, 리소스 동기화, 장벽, 동시성, 멀티스레딩, 멀티 큐, 렌더링 애플리케이션 및 성능 분석을 얕은 것부터 깊은 것까지 설명하며 시작 및 고급에 적합합니다. 더 알고 싶다면 원본 텍스트를 읽거나 Unreal Rendering System(13) - RHI 보충 자료: 최신 그래픽 API의 신비와 지침을 분석해 보세요.
Star Citizen의 시각 효과는 CryEngine에서 개발한 Star Citizen 게임의 시각 효과를 공유했습니다.

이 게임은 매우 뛰어난 비주얼, 품질에 대한 오랜 관심, 높은 시스템 사양을 특징으로 하며 당시에는 DX11이었습니다. 선체에는 복잡한 메쉬 수, 재질 및 데칼이 있습니다.

함선 파괴 효과의 렌더링 과정은 다음과 같습니다.

파괴 효과를 추가하는 구체적인 단계는 다음과 같습니다.

게임의 MMO 부분에는 많은 환경이 필요하기 때문에 모듈식 접근 방식이 선택되었습니다. 모듈식 "키트"는 조립이 쉽고 아트 파이프라인(예: 아웃소싱)을 단순화하며 레벨 디자이너에게 매우 유연합니다.
이 기간 동안 원하는 충실도, 다각형 수, 텍스처 밀도가 너무 높고, 텍스처를 구울 수 없고, 타일링 텍스처로 인해 메시당 많은 드로우 콜이 발생하고, 방을 구축하는 데 많은 수의 메시가 필요하며, 우주 정거장에 더 많은 메시와 드로우 콜이 필요하기 때문에 많은 성능 문제가 발생했습니다.
텍스처 배열은 잠재적인 솔루션입니다. 해상도 제한은 스트리밍 데이터가 어렵다는 것을 의미합니다. 대신 LOD에 저해상도 텍스처 배열을 사용하면 단일 텍스처를 스트리밍할 필요가 없습니다. 256x256의 전체 텍스처 배열은 레벨이 15Mb 미만이며 LOD를 렌더링하는 데 단일 그리기 호출만 필요합니다! 버텍스 버퍼는 재질 ID별로 정렬되므로 필요한 경우 고해상도 텍스처를 계속 사용할 수 있습니다.
LOD를 결합하여 최소한의 드로우 콜과 메모리로 계층 구조를 구축하는 반복적 경험적 방법을 사용하여 각 개별 모듈식 자산에 대한 LOD를 구축하는 KillZone과 유사한 메시 병합 솔루션입니다. 공격적인 LOD를 사용하면 아티스트의 수동 작업 없이도 그리기 호출이 크게 줄어듭니다.
Far Cry 4의 세계 렌더링은 재료, 조명, 식물, 앤티앨리어싱, 지형 등을 포함하여 Fay Cry 4의 포괄적인 렌더링 기술을 공유합니다.
조명 측면에서 FC4는 하늘 폐색, 환경 맵, 간접 조명 및 기타 기능을 지원합니다. 스카이라이트는 Bruneton 하늘 모델과 Preetham 태양 모델을 사용하여 3차 SH 조명을 생성합니다. 하늘 폐색의 경우 직접 하늘 조명은 간접 조명과 분리됩니다. 고해상도 "하향식" 스카이 오클루전은 높이 필드에서 가시성 2차 SH를 생성하는 데 사용됩니다. SSAO와 유사한 방법을 사용하여 교합을 계산합니다.

단일 큐브맵이 하루 중 언제든지 적절한 강도를 갖도록 하기 위해 FC4는 각 프레임마다 큐브맵을 다시 조명합니다. 주요 프로세스는 다음과 같습니다.

간접광의 경우 지연된 복사 전달 볼륨[Stefanov2012]이 사용되며 복사 전달 정보를 저장하는 조명 프로브입니다. 목표는 이전 세대와 현재 세대 모두에 동일한 라이트 프로브를 사용하고, 간접 조명의 범위를 확장하고, CPU 작업을 GPU로 오프로드하여 업데이트 속도를 높이는 것입니다. 주요 프로세스는 다음과 같습니다.
오프라인: 구운 프로브, 2차 SH의 복사 전달 정보.
CPU: 프로브 데이터를 스트리밍하고 GPU에 업로드하며 페이지 테이블을 업데이트합니다.
GPU: 복사 전달을 계산하고 클립에 프로브를 삽입하고 지연된 조명에서 샘플링합니다.
전체 셀 목록에 대해 복사 전달을 수행하는 과정은 다음과 같습니다.

식물은 FC4 렌더링의 주요 초점으로, 예상과 완전히 다른 데이터 세트를 사용합니다. 목표는 긴밀한 시각적 충실도, 향상된 LOD 및 임포스터, 다양한 시뮬레이션입니다. 골격 및 물리 시뮬레이션 과정은 다음과 같습니다.

임포스터의 경우 9개의 각도(나무에 수직인 각도 8개, 위에서 아래로 1개)에서 스크린샷을 찍습니다.

G-버퍼 스크린샷: 알베도, 일반 및 재료 속성을 캡처합니다.

깊이 빌보드: 빌보드 지오메트리가 16x16 그리드로 세분화되고 GBuffer 스크린샷 중에 깊이가 캡처되며 정점은 원래 트리 깊이에 따라 변위됩니다. 깊이 데이터 및 렌더링은 다음과 같습니다.

또한 식생에 대해 AO 볼륨이 생성됩니다. 크기는 16x16x16에서 64x64x64까지이며 볼륨 주변의 32개 방향에서 그림자 맵이 캡처되고 그림자가 샘플링되고 평균화됩니다.
시각적인 관점에서 보면 식물이 완전히 정확하기는 어렵고 풀잎 사이의 빛 반사, 나뭇잎의 빛 산란 등 일부 특성이 시뮬레이션되므로 TA의 마법이 필요합니다.

안티앨리어싱에는 HRAA가 사용됩니다. 자세한 내용은 14.4.3.5 특수 기술의 하이브리드 재구성 안티 앨리어싱 섹션을 참조하세요.
Insomniac Games의 SIMD는 SSE, 기술, 모범 사례 등 Insomniac 게임에 사용되는 SIMD 기술을 공유합니다.
SIMD 프로그래밍은 PS2 VU, PS3 SPU + Altivec, X360 VMX128, SSE(+AVX)와 같은 Insomniac 회사의 스튜디오에서 오랜 역사를 가지고 있으며, 이번 주기에는 SSE 프로그래밍에 중점을 둡니다. PC + 호스트가 ISA를 공유하면 인센티브가 더 커집니다. SIMD를 사용할 때 PC 워크스테이션은 엄청나게 빠르며 많은 오래된 모범 사례가 SSE에 적용되지 않습니다.
당시 추세는 모두 GPGPU로 가는 것이었지만 GPU로 옮기기에는 문제가 너무 작아서 콘솔에서 x86 코어가 계속 낭비되었습니다. 무차별 대입 + 선형 액세스를 과소평가하지 마십시오. CPU SIMD는 성능을 크게 향상시킬 수 있으며 성능을 PC에만 남겨둘 수는 없습니다. 당시 SSE 및 AVX SIMD의 옵션은 다음과 같습니다.
컴파일러 자동 벡터화. 유토피아적 아이디어는 실제로 작동하지 않습니다. 컴파일러는 마술 지팡이가 아닌 도구이며 유지 관리 중에 자주 중단되고 성능 향상이 적습니다! 컴파일러 지원/보장 = 나쁨, VS2012에서는 지원되지 않음, VS2013에서는 일부 지원, 컴파일러마다 특징이 다릅니다.
인텔 ISPC. SSE/AVX 클래스 셰이더 컴파일러, 스칼라 코드 작성, ISPC는 SIMD 코드 생성, 또 다른 추상화 수준에 대한 투자가 필요합니다. 참고: 비효율적인 로드/저장 코드를 생성하기 쉽습니다. 주요 이점: Intel의 BCT 텍스처 압축기와 같은 자동 SSE/AVX 전환은 AVX 워크스테이션에서 자동으로 더 빠르게 실행됩니다.
내부 기능. 눈에 보이지 않는 성능 저하 없이 예측 가능하게 Insomniac 게임에서 SIMD를 작성하는 데 선호되는 방법인 조립 없이 제어하고 모든 CPU 기능을 유연하게 노출합니다. 배우고 연습하기 어렵다는 것은 실제로 반대가 아닙니다. 모든 좋은 프로그래밍은 어렵습니다(그리고 나쁜 프로그래밍은 쉽습니다).
편집. 항상 옵션입니다! 64비트 VS 컴파일러에는 인라인 어셈블리가 없으며 외부 어셈블러(예: yasm)가 필요합니다. 우선, OS 간 ABI 이식성 유지의 어려움, 상대적으로 안정적인(비휘발성) 레지스터, 64비트 Windows의 예외 처리, 스택 정렬, 디버깅 등 많은 함정이 있습니다.
SSE가 더 많이 사용되지 않는 이유는 무엇입니까? PC 공간의 조각화에 대한 두려움, 모든 x64 CPU는 SSE2를 지원하지만 일반적으로 "우리 데이터 레이아웃에 맞지 않습니다", 전통적으로 PC 엔진은 너무 무겁지 않고 OO 디자인에 SIMD 코드를 삽입하는 것이 어색합니다. "우리는 시도했지만 작동하지 않았습니다."
// SSEVec4선언
class Vec4
{
__m128 data; // X/Y/Z/W,는 4D벡터
operator+ (…)
operator- (…)
};
// 【】의 SSEVec4포인트
Vec4 Vec4Dot(Vec4 a, Vec4 b)
{
__m128 a0 = _mm_mul_ps(a.data, b.data);
__m128 a1 = _mm_shuffle_ps(a0, a0, _MM_SHUFFLE(2, 3, 0, 1));
__m128 a2 = _mm_add_ps(a1, a0);
__m128 a3 = _mm_shuffle_ps(a2, a2, _MM_SHUFFLE(0, 1, 3, 2));
__m128 dot = _mm_add_ps(a3, a2);
return dot; // WAT: the same dot product in all four lanes
}
// 【】의 SSEVec4포인트
__m128 dx = _mm_mul_ps(ax, bx); // dx = ax * bx
__m128 dy = _mm_mul_ps(ay, by); // dy = ay * by
__m128 dz = _mm_mul_ps(az, bz); // dz = az * bz
__m128 dw = _mm_mul_ps(aw, bw); // dw = aw * bw
__m128 a0 = _mm_add_ps(dx, dy); // a0 = dx + dy
__m128 a1 = _mm_add_ps(dz, dw); // a1 = dz + dw
__m128 dots = _mm_add_ps(a0, a1); // dots = a0 + a1SSE 클래스에 시간을 낭비하지 마십시오. AOS 데이터로 SOA 하드웨어를 추상화하는 것은 서투르고 느릴 것입니다. SSE 코드는 무료이고 래퍼나 프레임워크 없이 최적의 성능을 달성하며 필요에 따라 작은 도우미 루틴을 작성하기를 원합니다. "우리 데이터 레이아웃에 맞지 않습니다.", 빈 입자(float pos[3], ...), 구조 입자 {float pos[3]; ...}, SSE에서 입자 배열을 사용하는 것은 어려우므로 이 작업을 피하세요. 스폰 기능을 유지하고, 메모리 레이아웃을 변경하세요. 문제는 SSE가 아닌 구조 입자에 있습니다. 인메모리 구조화된 입자(AOS):

SOA(파티클 인 메모리):

데이터 레이아웃 선택: SSE 코드의 경우 일반적으로 SOA 형식이 훨씬 더 좋으며 명령 세트에 자연스럽게 매핑되고 SOA SIMD 코드는 스칼라 참조 코드에 밀접하게 매핑됩니다. AOS 형식은 일반적으로 스칼라 문제, 특히 값 집합에 대한 단일 캐시 누락이 있는 조회 또는 인덱싱 알고리즘에 더 적합합니다. 필요한 경우 변환에서 로컬로 SOA 데이터를 생성하고 입력/출력을 조정하여 SIMD 효율성의 균형을 맞춥니다.
구체적인 사례인 문을 살펴보겠습니다. 우익 배우의 "충성도"가 특정 반경 내에 있을 때 자동으로 열리는 문은 원래 객체 지향 솔루션으로 구현된 고전 게임 문제인 Star Trek이 성능 레이더에 나타나기 시작했다고 생각하십시오. ~100 문 x ~30 문자 테스트 = 3000 테스트! 다음은 성능 문제가 있는 버전과 그에 대한 분석입니다.

위의 원본 업데이트에서 입력 데이터의 메모리 관계는 다음과 같습니다.

SIMD 준비: 게이트 데이터를 중앙 위치로 이동합니다. 실제로는 SOA 형식의 값 패키지입니다. 게이트가 거의 생성 및 파괴되지 않으므로 좋은 접근 방식입니다. 각 게이트에는 중앙 데이터 웨어하우스에 대한 인덱스가 있고, 업데이트 시 로컬로 행위자 테이블을 구축합니다. 100개가 아닌 업데이트당 한 번씩 스택의 단순 배열(가변 크기에 할당됨)에 숨겨집니다.
// 갱신(Update)데이터 디자인/설계
// In memory, SOA
struct DoorData
{
uint32_t Count;
float *X;
float *Y;
float *Z;
float *RadiusSq;
uint32_t *Allegiance;
// Output data
uint32_t *ShouldBeOpen;
} s_Doors;
// On the stack, AOS
struct CharData
{
float X;
float Y;
float Z;
uint32_t Allegiance;
} c[MAXCHARS];SIMD 게이트의 새로운 업데이트는 모든 게이트를 한 번에 수행할 수 있으며 내부 루프에서 4개의 게이트와 1개의 액터를 테스트할 수 있으며 데이터 레이아웃의 큰 이점을 제공하므로 모든 계산이 자연스럽게 SIMD 작업의 형태로 나타납니다.
// 루프
for (int d = 0; d < door_count; d += 4)
{
// 로드 4의 ,클리어 4개 “”누적(Accumulate)
__m128 dx = _mm_load_ps(&s_Doors.X[d]);
__m128 dy = _mm_load_ps(&s_Doors.Y[d]);
__m128 dz = _mm_load_ps(&s_Doors.Z[d]);
__m128 dr = _mm_load_ps(&s_Doors.RadiusSq[d]);
__m128i da = _mm_load_si128((__m128i*) &s_Doors.Allegiance[d]);
__m128i state = _mm_setzero_si128();
// 루프
for (int cc = 0; cc < char_count; ++cc)
{
// 로드 1개 의 ,까지 4개 스레드(Thread)(lane)
__m128 char_x = _mm_broadcast_ss(&c[cc].x);
__m128 char_y = _mm_broadcast_ss(&c[cc].y);
__m128 char_z = _mm_broadcast_ss(&c[cc].z);
__m128i char_a = _mm_set1_epi32(c[cc].allegiance);
// 계산/산출(Calculate) 및 의 거리
__m128 ddy = _mm_sub_ps(dy, char_y);
__m128 ddz = _mm_sub_ps(dz, char_z);
__m128 dtx = _mm_mul_ps(ddx, ddx);
__m128 dty = _mm_mul_ps(ddy, ddy);
__m128 dtz = _mm_mul_ps(ddz, ddz);
__m128 dst = _mm_add_ps(_mm_add_ps(dtx, dty), dtz);
// 대비 및 => 또는 상태
__m128 rmask = _mm_cmple_ps(dst, dr);
__m128i amask = _mm_cmpeq_epi32(da, char_a);
__m128i mask = _mm_and_si128(_mm_castps_si128(amask), rmask);
state = _mm_or_si128(mask, state);
}
// 로 4저장(Store)“”,로 4。
_mm_store_si128((__m128i*) &s_Doors.ShouldBeOpen[d], state);
}내부 루프의 어셈블리 코드는 다음과 같이 생성됩니다.
vbroadcastss xmm6, dword ptr [rcx-8]
vbroadcastss xmm7, dword ptr [rcx-4]
vbroadcastss xmm1, dword ptr [rcx]
vbroadcastss xmm2, dword ptr [rcx+4]
vsubps xmm6, xmm8, xmm6
vsubps xmm7, xmm9, xmm7
vsubps xmm1, xmm3, xmm1
vmulps xmm6, xmm6, xmm6
vmulps xmm7, xmm7, xmm7
vmulps xmm1, xmm1, xmm1
vaddps xmm6, xmm6, xmm7
vaddps xmm1, xmm6, xmm1
vcmpps xmm1, xmm1, xmm4, 2
vpcmpeqd xmm2, xmm5, xmm2
vpand xmm1, xmm2, xmm1
vpor xmm0, xmm1, xmm0
add rcx, 10h
dec edi
jnz .loop그 결과 속도가 20~100배 향상되었으며, 이제 데이터에 대한 추론을 수행할 수 있게 되었습니다. 무차별 SIMD는 "합리적인 것"을 의미하며 게임에는 "합리적인" 문제가 많이 있습니다! 캐시 미스 제거 + SIMD ALU는 이러한 유형의 변환이 일반적으로 탐지되지 않는 "천 컷으로 인한 사망" 문제를 해결하여 큰 승리를 거둘 수 있습니다.
이 기사에서는 데이터 필터링의 예도 제공합니다.
**모범 사례: 분기.**일반적으로 분기를 피하세요. 잘못 예측된 분기는 대부분의 H/W에서 여전히 매우 비쌉니다. 내부 루프에서 분기를 예측하기 어렵게 되는 것을 원하지 않습니다. 매우 예측 가능한 경우 분기를 취할 수 있으며, 분기는 의미가 있으려면 99% 이상 올바르게 예측되어야 합니다. 데이터의 바다에서 값비싼 것. SSE2, _mm_movemask_X()의 경우 m_testz_si128() 및 SSE4.1+도 고려하세요.
분기에 대한 대안: GPU 스타일 "두 개의 분기 계산" + 선택, 많은 작은 문제의 경우 각 문제에 대한 별도의 입력 데이터 + 커널, 가능한 최고의 성능 산출, 인덱스 세트 분할 고려, 빠른 커널 실행을 통해 인덱스 데이터를 여러 세트로 나누고, 각 하위 세트에서 최적화된 커널 실행, 대부분의 인덱스에 액세스하지 않는 한 프리페칭이 유용할 수 있습니다.
**모범 사례: 프리페칭.**이전 세대 하드웨어에 절대적으로 필요합니다. 이를 맹목적으로 x86으로 일반화하는 것은 좋은 생각이 아닙니다. 지침: 선형 배열 액세스를 프리페치하지 마세요. 일부 하드웨어에서는 심각한 TLB 미스 비용 기회가 있을 수 있으며, 칩은 이미 캐시 수준에서 무료로 프리페치를 합니다. 지침: 예정된 PTR/인덱스가 서로 충분히 떨어져 있거나 불규칙하다는 것을 알고 있는 경우에는 예정된 PTR/인덱스를 프리페치할 수 있습니다. 프리페치 지침은 AMD/Intel 간에 다릅니다. 모든 하드웨어의 이점을 누릴 수 있는지 주의 깊게 테스트하세요.
**모범 사례: 확장합니다.**VMX128/SPU 스타일 코드에서 일반적이며, 머신이 대기 시간을 숨기려면 레지스터도 많이 갖는 것이 합리적입니다! 일반적으로 SSE/AVX에 16개의 (명명된) 레지스터만 있는 것은 좋은 생각이 아닙니다. 하드웨어는 내부적으로 더 많은 레지스터를 갖고 있으며 어느 정도 비순차적 실행이 펼쳐집니다. 지침: 전체 레지스터 너비까지만 펼칩니다. 128비트 루프를 얻으려면 2x 64비트 루프를 펼치십시오. 하지만 더 이상 필요하지 않습니다. 매우 작은 루프에 대해서는 필요에 따라 예외를 만들 수 있습니다.
**모범 사례: 스트리밍 읽기 및 쓰기.**스트리밍 읽기(>SSE 4.1) 및 쓰기를 사용하면 특히 대규모 조회 테이블을 사용하는 커널의 경우 캐시 쓰레기를 방지하는 데 도움이 되지만 울타리를 잊지 마세요! ! 다양한 아키텍처에 대한 다양한 옵션 _mm_fence()는 항상 작동하지만 속도가 느리고 스트림이 강력한 x86 메모리 모델을 우회하며 제한되지 않으면 미묘한 데이터 경합이 발생할 수 있습니다.
결론: SIMD는 마술이 아닙니다. 누구나 퍼포먼스 영웅이 될 수 있습니다! 작은 투자로 큰 수익을 얻을 수 있으며, 최신 SSE에는 많은 이점이 있습니다!
Shadow of Mordor의 콘텐츠를 효율적으로 작성하기 위한 전략은 동기화, 로딩, 성능, 자산 처리, 콘텐츠 종속성 등을 포함하여 Middle-earth: Shadow of Mordor 게임의 콘텐츠 제작 전략 및 효율성을 공유했습니다.
게임이 점점 복잡해짐에 따라 게임 리소스의 크기와 양, 데이터 기록은 수십 배 증가하고 있으며 텍스처가 약 55%, 오디오가 35%, 기타가 약 10%를 차지합니다. 텍스처와 오디오에서 차지하는 크기는 높은 것부터 낮은 순으로 애니메이션, 레벨, 모델, 데이터 기록, 동작, 특수 효과 및 셰이더입니다. (아래 사진)

이 기사에서는 지능형 로딩 전략을 채택하고, 소스 파일 형식을 확인하고, 데이터가 메모리(디스크)에 입력되는 속도, 데이터가 해석되는 속도(CPU) 등과 같은 최소 점유 및 최대 로딩 속도를 강조합니다. LTA(LTA-Lith Tech ASCII) 소스 파일 형식, xml과 유사한 텍스트, 사람이 읽을 수 있는 대용량 파일, 해석이 느림, 인코딩된 압축 ASCII 코드 사용, 디스크에 더 작아짐, 메모리에 더 빨리 들어가고 해석이 더 느림. 압축된 이진 표현, 디스크 크기가 작고 훨씬 빠르며 텍스트를 구문 분석할 필요가 없으며 독립적으로 압축된 파일 트리 루트(Zlib), 병렬 또는 부분 로딩/압축 풀기, 파일 손상을 노출하기 위한 CRC 검사, 사람이 읽을 수 있는 형식으로 변환하기 위해 제공되는 유틸리티입니다. 압축된 형식의 경우 설치 공간은 10배 더 작고 10배 더 빠르게 로드됩니다!
온디맨드 로딩: 필요할 때까지 대부분의 데이터를 로드하지 않으며, 추가 로드를 요청하기 위한 사용자 작업이 필요하며, 독립 실행형 워크플로에 이상적이며, 트리 제어가 이에 적합합니다. 적절한 소스 파일 세분성이 필요하므로 개별 파일을 처리하기가 어렵습니다. 지연 로딩 시간(15배 더 빠름):

백그라운드에서 로드하고, 데이터의 일부만 미리 로드하고, 초기 블록을 로드한 후 사용자가 편집을 시작할 수 있도록 합니다. 데이터는 필요하지만 즉시 필요하지 않습니다. 필요한 경우 시각적 도구, Visual Studio 스마트 프롬프트와 같은 사용자를 차단하세요. 백그라운드 로딩은 속도를 5배까지 증가시킬 수 있습니다.
수천 컷에 의한 죽음: 로드할 작은 파일이 많고, HDD는 이 작업에 형편없으며, 비동기 IO가 도움이 될 것입니다. "체크포인트" 구축, 단일 파일, 압축 후 최소 설치 공간, 만료 시 패치, 90k 파일/800m ~ 30m 체크포인트.
디스크 SSD는 직렬화 속도를 높일 수 있지만 용량이 더 작습니다. CPU 스레드 풀은 병렬화를 구현하는데, 이는 모든 곳에 적합하지 않으며 복잡하고 비용이 많이 듭니다.
스레드 풀은 CPU 대기 시간을 줄이고, 선형 속도를 높일 수 있으며, 적절한 경우 쉽게 폐기할 수 있고, 잘못된 알고리즘 선택, 핵심 경합, 더 많은 복잡성을 상쇄하지 못한다는 단점이 있으며, 속도는 가장 느린 작업만큼만 빠릅니다.
기사에 언급된 리소스 구축 파이프라인은 다음과 같습니다.

데이터 상속도 사용됩니다.

Piko: 프로그래밍 가능한 그래픽 파이프라인 작성을 위한 프레임워크는 프로그래밍 가능한 GPU 렌더링 파이프라인을 공유합니다. 기사에서는 현재 시장에 나와 있는 효율적인 그래픽 파이프라인이 다음과 같다고 언급했습니다.
렌더러 플랫폼 알고리즘
언리얼 엔진 4 GPU 지연된 음영 처리를 사용한 래스터라이제이션
유니티 5 GPU 순방향 및 지연 음영처리를 사용한 래스터라이제이션
디즈니 하이페리온 멀티코어 CPU 지연된 셰이딩 경로 추적
픽사 렌더맨 멀티코어 CPU 레이 트레이싱 레예스
솔리드 앵글 아놀드 멀티코어 CPU 경로 추적
미디어 분자의 꿈 GPU 포인트 기반 디퍼드 셰이딩 렌더링
문제는 효율적인 그래픽 파이프라인 구현이 작성하기 어렵고 디자인 공간을 탐색하기 어렵다는 것입니다.

GPU의 소프트웨어 광선은 다음과 같습니다.

유연한 그래픽 파이프라인을 도입하고 다양한 단계 유형을 추상화하며 대기열을 통한 통신을 추상화합니다.

고성능의 기본은 병렬성, 실행 지역성, 데이터 지역성, 생산자-소비자 지역성입니다. Piko 프레임워크는 실제로 위의 문제를 해결하는 가교 역할을 합니다.

Piko의 실행 프로세스는 다음과 같습니다.

파이프라인의 각 단계는 세 단계로 구성됩니다.


Piko 파이프라인은 표현하고 사용자 정의하기 쉽습니다.

공간 차단을 사용하면 병렬성 및 지역성이 향상되어 그래픽 파이프라인 효율성이 향상됩니다.


The Order: 1886의 대체 역사 렌더링은 The Order: 1886 게임의 렌더링 반복 프로세스를 공유합니다.
게임 엔진은 청크 목록으로 계산된 깊이 프리패스, 버텍스 노멀 및 속도를 사용하고, 깊이 버퍼 컬링, 투명 재질에 대한 별도 목록, 비동기 계산을 사용합니다. -> 기본적으로 무료이며 오버헤드가 낮은 MSAA입니다. 완전히 최적화된 재질 + 조명 파이프라인인 재질별 픽셀 셰이더를 생성하여 모든 경우를 수동으로 최적화하기가 더 어렵습니다. 몇 가지 GPR 문제가 있습니다. 조명은 사용된 매개변수의 함수입니다.
화면 깜박임의 원인에는 고주파 신호, 언더샘플링(시간 또는 공간), 이동 샘플링, 잘못된 필터링 방법(주파수 응답을 고려해야 하며 포스트 프로세스 앤티앨리어싱을 사용할 수 있음) 등이 있습니다.

재구성 필터는 리샘플링(업샘플링, 다운샘플링, 오버샘플링), 출력 생성(그라디언트에 영향, 인지된 세부 사항에 영향, 앨리어싱에 영향)의 중요한 부분입니다. 때로는 필터가 전체 시스템에 내재되어 있기 때문에 필터를 재구축할 수 있는 옵션이 없는 경우도 있습니다. 이에 대한 한 가지 예가 모니터입니다. 디스플레이는 개별 샘플링된 신호를 가져와 연속 신호로 변환합니다. 화면에 나타나는 실제 물리적 패턴을 보면 어떤 종류의 필터가 사용되고 있는지 알 수 있습니다. LCD 디스플레이에서 직사각형 픽셀 패턴이 일반적으로 사용되는 것은 픽셀을 "작은 사각형"으로 생각하는 이유 중 하나입니다.

다음은 몇 가지 일반적인 재구성 필터, 즉 상자, 삼각형 및 싱크입니다.



앨리어싱 소스: 래스터라이제이션(기하학적 앨리어싱), 스페큘러 반사(스페큘러 반사 앨리어싱), 그림자, 텍스처, SSAO, 포스트 프로세스 파이프라인 및 샘플링!
지오메트리 앨리어싱의 원인: 지오메트리 샘플링이 불충분함(종종 사전 필터링된 삼각형의 빈도가 매우 높음), 래스터라이저는 단계 함수, 바이너리 - 켜짐/꺼짐, 보기 흉한 바닥 계단 패턴, 카메라가 움직일 때 시간적 아티팩트, 적용 범위 변경 = 깜박임! MSAA를 사용하면 오버샘플링이 가능합니다.
반사 앨리어싱의 소스: 낮은 러프니스 = 매우 높은 빈도, 움직이는 샘플 포인트가 깜박이고, 샘플링되지 않은 지오메트리 + 노멀 맵이 상황을 더욱 악화시키고, LEAN/CLEAN/Toksvig를 사용하여 사전 필터링할 수 있습니다. 노멀 분산의 모든 소스를 설명하기는 어렵지만 반드시 수행해야 합니다!
The Order에서 사용되는 앤티앨리어싱은 EQAA(2x 조각, 4x 적용 범위, 품질과 성능/메모리의 균형), 사용자 지정 분석(고차 필터링, 안정성을 위해 일부 세부 정보 교환) 및 TAA(깜빡임 추가 감소, MSAA 솔루션과 통합)입니다.

MSAA를 사용하는 중간 채널은 지연된 데칼, 비MSAA RT에 누적됩니다. 저해상도 투명도 및 AO, 각 깊이 하위 샘플을 증폭하고 한 번 합성합니다. 알파 테스트, 깊이 하위 샘플별 테스트 또는 A2C 사용 뎁스 오브 필드(DoF)에서는 모든 하위 샘플 중 가장 작은 CoC를 사용합니다.

MSAA를 사용한 DOF.
MSAA 사용자 지정 구문 분석: 하드웨어 구문 분석 대신 컴퓨팅 셰이더 사용, 샘플 색상 조각 및 적용 범위 샘플, 2픽셀 너비 큐빅 필터, 인접 픽셀의 하위 집합 포함, 네거티브 로브 없음 - HDR에서 링잉이 너무 심함. 자세한 내용은 MSAA 해결 필터를 참조하세요.

Order에서는 더 넓고 부드러운 재구성 필터를 선택하기를 원했습니다. 포인트, 박스 및 가우스 재구성 필터를 비교한 후 마침내 후자를 선택했습니다. 더 넓고 매끄러우며 시간 영역에서 더 부드러운 전환으로 변환되어 더 나은 안정성을 제공하기 때문입니다.

HDR용 MSAA: 비선형 톤매핑, 극단적인 경우 AA를 "죽이는", 클램핑이 특히 나쁩니다! postFX 이후 톤매핑이 필요하고, 사후 처리에는 HDR이 필요하며 값비싼 솔루션이 필요합니다. 즉, MSAA 해상도에서 사후 처리하고 톤매핑 직후에 구문 분석됩니다. 저렴한 솔루션: 톤 맵 서브샘플, 구문 분석, 톤매핑 반전, 복잡한 연산자는 쉽게 되돌릴 수 없습니다. 더 저렴한 솔루션: 간단한 연산자를 사용하여 대략적인 톤매핑(Reinhard), 기본적으로 샘플 가중치를 1/(1 + 휘도)로 계산하고 깜박임을 줄이기 위해 작은 하이라이트를 억제하는 이점이 있습니다.

왼쪽: HDR의 MSAA; 오른쪽: 반전된 밝기 필터.
노출도 고려해야 합니다! 최종 톤매핑 단계와 더 잘 일치하도록 하이라이트를 과도하게 렌더링하지 않고도 노출을 1~2스톱 이동하여 과도한 감쇠와 하이라이트 억제의 균형을 맞출 수 있습니다.

왼쪽: 반전된 휘도 필터, 중앙: 반전된 휘도 필터(노출 +10), 오른쪽: 수리된 반전된 휘도 필터(노출 +10).
// 필터링 코드
float3 sample = InputTexture.Load(uint2(samplePos), subSampleIdx).xyz;
float weight = Filter(sampleDist); // Bicubic, Gaussian, etc.
float sampleLum = Luminance(sample);
sampleLum *= exposure * exp2(ExposureOffset); // ExposureOffset ~= -2.0
weight *= 1.0f / (1.0f + sampleLum);
sum += sample * weight;
totalWeight += weight;TAA의 주요 목표는 미러 깜박임을 줄이는 것입니다. 사전 필터링만으로는 충분하지 않습니다. 주요 영감은 TXAA, SMAA 1TX [Sousa13], Dust 514 [Malan12], Killzone: Shadow Fall [Valient14]입니다. 여러 샘플 축적, 지수 이동 평균, 속도 버퍼를 사용한 이전 프레임 재투영, 최소/최대 이웃을 사용한 가중치 및 클램핑, MSAA 구문 분석 중에 계산된 최소/최대, 지터 없음(주로 엔진 팀은 통합할 시간이 없었으며 어쨌든 카메라는 항상 움직였습니다).
사후 처리 AA 선명화: 넓은 해상도로 인해 시각적 스타일과 일치하는 "부드러운" 모양이 생성됩니다. 사후 처리 AA 샤프닝을 추가할 수 있습니다. 선명하지 않은 마스크는 매우 간단하지만 너무 극단적이지 않도록 주의하세요!

왼쪽에서 오른쪽으로 선명도 값은 0.0, 0.5, 1.0입니다.
그림자: 4개의 계단식 1방향 조명을 갖춘 16개의 스포트라이트 그림자 캐스팅은 최대 2개의 방향 조명을 지원합니다. 간단하게 유지하세요. 스포트라이트용 텍스처 배열 1개, 캐스케이드용 텍스처 배열 1개, 정방향 패스 샘플. 거리에 따라 서로 다른 빈도로 업데이트되는 캐시된 스포트라이트 그림자는 이동하지 않으면 그림자를 재생성하지 않습니다.
미리 계산된 그림자 가시성: 기본 가시성을 위한 시스템 확장으로, 레벨 구성 중에 미리 계산되며 비움직이는 라이트에만 사용할 수 있습니다. 스포트라이트의 경우 템플릿을 사용하여 캐스터에 태그를 지정하여 광원 POV에서 그리드 ID를 래스터라이제이션합니다(개수 >= 2). 방향성 조명의 경우 레벨을 조명 공간의 NxN 타일로 분할하고 잠재적인 그림자 투사자를 결정하고 각 카메라 샘플링 지점에 대해 카메라 가시 그리드를 렌더링하고 잠재적인 그림자 투사자를 렌더링하고 템플릿 값이 2보다 큰 경우 최종 그림자 가시성 목록에 추가합니다.
모든 그림자에 대한 EVSM, 편향 없음, 줄무늬 감소, 하드웨어 필터링(삼중선형, 이방성) 등의 이점이 있으며 사전 필터링은 포워드 렌더링에 적합하고 GPR 압력을 줄이는 데 도움이 되며 캐싱에 적합합니다.
CSM을 구현하기 위해 SDSM을 샘플링하고 깊이 버퍼를 분석했으며 눈에 보이는 표면을 기반으로 제한된 캐스케이드를 적용했습니다. 뷰 공간의 최소/최대 XYZ, 최적화된 원자가 있는 단일 채널, 이상적으로는 라이트 공간의 AABB를 링크별로 계산합니다. 리드백 시 1프레임 지연을 사용하면 GPU 경로를 사용하여 "시간 왜곡" 트릭으로 아티팩트를 줄일 수 있습니다. 즉, 각 픽셀의 속도를 계산하고, 다음 프레임 위치를 예측하고, 다음 프레임 위치를 포괄하도록 AABB를 확장합니다. 불안정하며 추가 조사가 필요합니다.

왼쪽: 일반 CSM, 오른쪽: SDSM.
또한 이 기사에서는 향상된 데칼 렌더링 방법인 하이브리드 데칼: 지연된 채널 축적, 투영에 깊이 사용, fp16 렌더 대상에 블렌딩 추가, 데칼 버퍼를 읽는 기본 순방향 채널 및 재료 속성 수정에 대해 설명합니다.
Far Cry 4 및 Assassin's Creed Unity: GameWorks를 통한 PC 그래픽 강화는 Nvidia에서 선보입니다. Far Cry 4와 Assassin's Creed가 GameWorks를 사용하여 HBAO+, PCSS, TXAA, 캐릭터 렌더링, 조명 등과 같은 PC의 다양한 그래픽 기능을 향상시키는 방법을 알려줍니다.

Far Cry 4의 히말라야 장면.

Assassin's Creed의 웅장한 중세 시대 배경.
NVIDIA GameWorks에는 ShadowWorks, PostWorks, Godrays, HairWorks 등과 같은 여러 구성 요소가 포함되어 있습니다. 그 중 ShadowWorks와 PostWorks는 Far Cry 4 및 Assassin's Creed에 매우 적합하며 HairWorks 및 Godrays는 Far Cry 4에 매우 적합합니다.
NVIDIA ShadowWorks는 시네마틱 섀도우, HBAO+, 고급 소프트 섀도우 등을 제공하는 다양한 기술로 구성되어 있습니다. HBAO+(Horizon-Based Ambient Occlusion+)는 최고의 성능과 확장성을 갖춘 당시 가장 발전된 SSAO 방식이었습니다. HBAO+ 조정: 반경은 HBAO 커널의 크기를 사용하고, 오프셋은 낮은 분할 결함, 지수적 폐색 감쇠를 숨기고, 세부 폐색은 고주파 폐색 구성 요소의 가중치이고, 거친 폐색은 저주파 폐색 구성 요소의 가중치입니다.
고급 소프트 섀도우: 가까운 PCS(Percent of Soft Shadows)를 기반으로 하는 최첨단 소프트 섀도우는 단순하면서도 강력한 인터페이스인 계단식 섀도우 맵을 지원합니다. 광원 크기, 최대 임계값, 최소 백분율, 혼합 백분율, 테두리 백분율 등 고급 부드러운 그림자의 매개변수를 조정합니다. 빛 누출 수정: 빛 크기가 너무 크면 빛 누출이 발생하고, PCSS 커널이 너무 넓어서 캐스케이드 외부에서 샘플링하고, 테두리 비율을 조정하여 커널을 제한하고, 빛 누출이 여전히 존재하는 경우 빛 크기와 최대 임계값을 줄입니다.

TXAA(Temporal Anti-Aliasing)는 시간적 앨리어싱을 줄이기 위해 설계된 필름 기반 앤티앨리어싱 기술이며 NVIDIA PostWorks 제품군에 속합니다.

NVIDIA HairWorks를 사용하면 런타임 라이브러리와 콘텐츠 생성 도구를 결합하여 진정한 대화형 게임 경험을 위해 머리카락을 시뮬레이션하고 렌더링할 수 있습니다.

HairWorks 통합 프로세스:

HairWorks는 사용자 정의 셰이딩 모델을 허용하여 순방향 셰이딩과 디퍼드 렌더링을 지원합니다. Far Cry 4에서는 Dunia 렌더링 메커니즘을 사용하여 GBuffer에 저장된 사용자 지정 재질과 HairWorks 매개변수를 사용하여 셰이딩을 수행합니다.

HairWorks GBuffer 데이터: 압축 디퓨즈, 일반, 반사 지수 및 스케일링, 탄젠트, 최종 이미징.
앤티앨리어싱: 가장 좋은 솔루션은 앤티앨리어싱이 활성화된 별도의 패스에서 HairWorks 머리카락을 렌더링하는 것입니다. Far Cry 4에서는 모피가 메인 파이프라인에서 렌더링되며 전역 앤티앨리어싱을 사용하여 깜박임을 방지합니다.

왼쪽: AA 없음, 중앙: 4xMSAA, 오른쪽: 4xTXAA.
NVIDIA Godrays는 거대한 조정 공간, 확장 가능한 성능, 그리고 게임에서 처음으로 연기 색상 통합 사용을 통해 사실적인 태양 광선을 렌더링할 수 있으며 태양 색상을 사용하여 최고의 효과를 보여줍니다.

Godrays는 균형을 찾아야 합니다. 장면이 완전히 흐릿해 보이고 실제로 밀도가 너무 높아져 빛의 강도가 날짜에 따라 달라집니다.

<br/ >
14.4.3.2 빛과 그림자 기술
2010년 비디오 게임을 위한 실시간 라디오시티 아키텍처에서는 Enlighten의 개요, 아키텍처 및 이를 Frostbite에 통합하는 방법에 대한 소개를 포함하여 Frostbite 엔진으로 구현된 실시간 라디오시티 조명 아키텍처를 설명했습니다.
기사에서는 Enlighten에 분리된 조명 파이프라인, 피드백이 포함된 단일 피드백, 라이트 맵 출력, 대상 지오메트리에서 재구성된 조명이라는 4가지 기능이 있다고 언급했습니다. Enlighten의 파이프라인은 아래와 같습니다. 사전 계산 단계에는 장면을 시스템으로 분해하고, 세부 형상을 대상 형상에 투영하여 조명을 재구성하고 대상 형상을 추출하여 실시간으로 방사선을 계산하는 작업이 포함됩니다. 런타임 단계에는 직접 조명을 렌더링하는 GPU, 방사선을 비동기적으로 생성하는 CPU, GPU에서 직접 조명과 간접 조명을 결합하는 작업이 포함됩니다.

런타임 파이프라인은 아래와 같습니다.

위 그림에 관련된 다양한 노드와 최종 조합 효과는 다음과 같습니다.





라이트맵 출력은 다음과 같습니다:

Frostbite가 Enlighten을 통합할 수 있게 하는 요소에는 워크플로우와 작업 시간, 동적 환경, 유연한 아키텍처가 포함됩니다. Frostbite의 사전 계산 과정은 다음과 같습니다.
- 정적 및 동적 개체를 수집합니다. 정적 객체는 빛을 받고 반사하는 반면, 동적 객체는 빛만 받습니다.

- 방사선 시스템을 생성합니다. 입력 종속성의 병렬 처리 및 업데이트는 방사선 세분성을 위해 광 투과를 제어합니다.

- 파라메트릭 정적 기하학. 정적 메시는 대상 형상을 사용하고, 대상 형상을 사용하여 방사선을 계산하고, 세부 메시를 대상 메시에 투영하여 UV를 얻고, 시스템은 이를 별도의 UV 아틀라스로 패키징합니다.

- 런타임 데이터를 생성합니다. 시스템당 하나의 데이터 세트(스트림 친화적), Incredibuild의 XGI를 사용한 분산 사전 계산, 형상에만 의존하는 데이터(빛이나 알베도 아님).

렌더링 시 직접 조명과 방사성 조명이 분리됩니다. CPU는 이미시브을 계산하고 GPU는 직접광을 계산합니다. Frostbite는 디퍼드 렌더링을 사용하며 모든 광원은 빛을 동적으로 반사할 수 있습니다. 라이트 맵과 라이트 프로브 렌더링을 분리하고, 라이트 맵은 순방향 패스에서 렌더링되고, 라이트 프로브는 3D 텍스처에 추가되어 디퍼드 렌더링으로 실행됩니다. 런타임 파이프라인은 세 단계로 구분됩니다.
방사성 패스(CPU). 간접 라이트 맵과 라이트 프로브를 업데이트하고 라이트 프로브를 3D 텍스처에 주입합니다.
지오메트리 패스(GPU). 별도의 GBuffer에 간접 라이트맵을 추가하고 스텐실 버퍼를 사용하여 동적 객체를 마스크 처리합니다.
조명 패스(GPU). 지연된 조명을 렌더링하고, GBuffer에서 조명 맵을 추가하고, 3D 텍스처에서 조명 프로브를 추가합니다.
위 단계의 렌더링은 다음과 같습니다.





우연히도 게임의 사전 계산 조명에서는 게임 엔진의 사전 계산 조명도 논의합니다. 이 기사에서는 베이크된 조명을 사용하는 세 가지 이유를 언급합니다.
**조명 작업 흐름.**베이크된 조명은 아티스트가 GI(Global Illumination)에 액세스하여 인공 채우기 조명 없이 조명을 형상/재료와 분리하지 않고 실제 광원을 기반으로 조명을 정의하는 방법입니다. 또한 베이크된 조명을 사용하면 더욱 풍부한 광원 세트, 물리적 기반의 부드러운 그림자, 그림자 투사 HDR 라이트 프로브를 사용할 수 있습니다.
**품질.**최고 품질의 조명 시뮬레이션 알고리즘, GI 효과, 다중 바운스를 허용하여 고품질 직접 조명을 허용합니다.
**성능.**런타임 성능은 매우 좋습니다. 조명 설정이나 GI 알고리즘과 관계없이 보기 좋은 라이트맵은 보기에 좋지 않은 라이트맵과 동일한 성능을 갖습니다.
**성능은 예측 가능합니다.**런타임 성능은 종종 매우 강력하며, 아티스트는 필요한 만큼 많은 조명을 추가할 수 있고, 실시간 그림자 맵 성능과 GI는 예측하기 어렵고, 조명 각도와 위치는 그림자 렌더링 성능에 영향을 미치며, 플레이어 위치는 조명에 필요한 해상도에 영향을 미칩니다.
- **성능 확장 가능.**Quake 1, 휴대용 장치, 고급 게임에서 사용 가능합니다.
베이크된 조명이 직면한 과제는 다음과 같습니다.
조명 설정을 변경합니다. 하루 중 다양한 시간을 적용할 수 있으며, 더 많은 가변 조명이 도입되면 조합이 폭발합니다. 이동하고 강도가 변하는 조명은 일반 런타임 조명으로 처리할 수 있으며, 간접 조명 없이 폭발하거나 번쩍이는 조명을 결합하는 데 적합합니다.
형상을 이동/변형합니다. 지역적 변화와 전역적 변화를 구별합니다. 지역적 변화에는 방 안에서 움직이는 캐릭터, 작은 가구, 총알 구멍 등이 포함됩니다. 전체적인 변화에는 파괴된 건물과 파괴된 벽이 포함됩니다.
로컬 형상이 변경되면 두 가지 문제가 있습니다. 객체가 환경에 의해 어떻게 영향을 받는가? 물체는 환경에 어떤 영향을 미칩니까?
움직이는 물체에 직접 조명을 추가하는 순진한 접근 방식은 캐릭터를 제자리에 보이지 않게 만들며, 직접적인 조명이 없는 영역에서도 캐릭터는 완전히 검은색이 됩니다. 라이트 프로브는 이러한 문제를 우아하게 해결하고 캐릭터 및 기타 움직이는 물체에 조명을 공급하기 위한 훌륭한 파이프라인을 제공합니다(아래 이미지). 일부 게임에서는 라이트 프로브 외부의 주요 조명을 가져와 보다 전통적인 직접 조명으로 추가합니다.

움직이는 물체에 대한 입사광의 경우 실내에서 라이트 프로브를 굽고 가장 가까운 것을 사용하여 물체를 조명하고 입사 조명을 전체 물체에 대한 하나의 라이트 프로브로 근사화합니다. 환경에 비해 작은 물체에 적합하며 매우 큰 물체는 특별한 취급이 필요할 수 있습니다. 인코딩은 면당 1픽셀의 큐브맵과 단일 환경 색상만 사용하여 구면 조화(보통 3차)로 이루어질 수 있습니다.
움직이는 물체도 환경에 영향을 미칠 수 있습니다. 라이트 프로브의 직접 조명은 선택 사항이므로 동적 객체의 자체 그림자를 허용하여 객체가 환경에 그림자를 드리울 수 있습니다. 라이트 프로브에서 가장 강한 빛의 방향을 추출하는 것도 가능합니다. 간접 조명에 자체 그림자를 제공하는 것도 가능할 수 있습니다. 일부 방법에서는 환경의 캐릭터 그림자가 중요한 라이트에 대해서만 간접 조명을 베이킹합니다. 캐릭터에 대한 간접 조명은 일반적으로 사소합니다.
전역 지오메트리 변경의 경우 고도로 동적인 게임은 전역 구운 조명을 피하는 경향이 있으며, 다른 하위 시스템도 정적 지오메트리에 의존하거나 더 나은 성능을 발휘하는 경향이 있습니다(경로 찾기, 충돌 감지, 게임 스토리에서는 종종 플레이어가 특정 경로를 따라야 함).
- 메모리 사용량. 조명은 전역적이며 재질 텍스처(인스턴스는 재질 텍스처를 공유하고, 여러 객체는 텍스처를 공유할 수 있으며, 텍스처는 타일링 및 미러링할 수 있음), 조명 텍스처(각 인스턴스는 고유해야 하며 타일링하거나 미러링할 수 없으며 해상도 요구 사항에 따라 해상도를 최적화할 수 있음)를 포함합니다.
노멀 맵은 기하학적 세부 수준을 높이는 데 적합합니다. 노멀 맵은 조명에 고주파 디테일을 도입합니다. 고주파 조명에는 높은 텍스처 해상도가 필요합니다.
방향성 라이트맵의 경우 세부 사항은 입사광이 아닌 형상에 있으며, 입사광의 각 텍셀 반구를 라이트맵에 저장하면 다양한 노멀 방향으로 조명을 근사화할 수 있습니다. 방향성 라이트 맵의 일반적인 인코딩은 RNM(Radiometric Normal Map), SH(보통 2밴드, 4개 구성 요소), 픽셀당 주변 및 방향성 라이트, SH 기반이므로 실제 BRDF를 사용할 수 있으며 반구는 흐려지지만 합리적인 반사 효과를 얻을 수 있습니다.



상단: 베이크된 라이트; 중간: 노멀 맵; 하단: 노멀 맵과 결합된 저해상도 방향성 라이트맵.
- 라이트 재구축 시간. 혼합 솔루션이 가능합니다.
간접 조명만 베이크됩니다. 간접 조명은 일반적으로 직접 조명보다 부드럽고 선명한 그림자에는 더 높은 텍스처 해상도가 필요합니다.
- 태양을 위한 특별 트리트먼트. 햇빛은 야외 장면에 가장 큰 영향을 미치는 빛인 경우가 많고, 직사광선은 선명한 그림자와 다이내믹 레인지 차이의 원인이 되는 경우가 많으며, 태양에서 간접광만 베이크되고 직접광은 런타임으로 추가됩니다.
이 글에서 제안하는 베이크된 조명 파이프라인은 다음과 같습니다.

파이프라인의 영향은 다음과 같습니다.
광원 구성 단계는 시간이 많이 걸릴 수 있습니다. CPU 시간 순서는 알고리즘, 해상도, 레벨 크기, 조명 설정, 바운스 횟수 등에 따라 다릅니다.
작업 속도를 높이는 도구, 선택적 조명 빌드, 미리보기 품질 빌드, 미리보기 도구, 카메라 렌더링 도구, 프로그레시브 라이트맵 생성, 배포.
조명을 항상 최신 상태로 유지하기 위한 자동 재구축.
GI 특정 광원 속성을 관리하는 도구입니다. 빛의 기여도를 증폭하고 분리하기 위한 직접 및 간접 조명의 배율입니다.
GI 특정 재료 속성을 관리하기 위한 도구입니다. 화면에 좋은 빛과 올바른 모양을 생성한다고 해서 환경에서 원하는 빛 방출이 반드시 생성되는 것은 아니며 장면의 전체 반사율이 증가하거나 감소합니다.
텍스처로 구운 모양에는 고유한 UV가 필요합니다. 어느 정도 자동화가 가능하며, 쉬운 확장이 바람직하고, 가능하다면 노멀맵 레이어에 디테일을 유지하는 것이 좋습니다.
버텍스 베이킹이 일반적입니다. 노멀 맵과 방향성 라이트맵은 이음새가 없는 텍스처 해상도가 부족하여 저해상도 조명에서 세부 정보를 제공하는 데 도움이 되며 다각형 내의 그림자 및 기타 조명 불연속성에는 적합하지 않습니다.
CryENGINE 3의 실시간 확산 전역 조명은 CLPV(Cascaded Light Propagation Volumes) 기술을 제안합니다. CLPV의 핵심 아이디어는 다음과 같습니다.

**1. 조명 표면을 샘플링하여 보조 광원으로 처리합니다.**GI용 장면을 샘플링할 때 Surfel(점, 디스크, Surfel == 표면 요소라고도 함)을 사용합니다. 모든 조명 서퍼는 광원 공간에서 2D 맵으로 평면화되고 반사 그림자 맵(RSM)을 사용하여 조명을 받을 수 있습니다. RSM은 GPU에서 조명 서퍼를 샘플링하는 가장 빠른 방법입니다. 너무 빠르더라도 O_O!

**2. 샘플을 통일된 대략적인 3D 그리드(그리드)로 클러스터링하고 각 셀(셀)의 광도를 누적하고 평균화합니다.**가상 포인트 라이트(VPL)로 표현되는 조명 빈을 클러스터링할 때 각 빈을 가장 가까운 셀에 배포하고(PBGI, 라이트 컷 및 라디오시티 클러스터링과 유사) 모든 VPL을 출력 방사 분포로 변환합니다. 이는 낮은 주파수 대역의 구형 고조파로 표현되며 소유자 셀 중앙에 누적되며 래스터라이제이션를 사용하여 GPU에서 전적으로 수행됩니다.

**3. 복사 에너지를 인접한 셀에 반복적으로 전파합니다(디퓨즈에만 적용 가능).**RSM은 조명 위치에서 정기적으로 샘플링되는 장면 VPL 세트로, 일반 그리드와 SH 이산 초기 VPL 분포를 통해 한 셀에서 다른 셀로 조명을 반복적으로 전파합니다. (아래 사진)

3D 그리드를 통한 로컬 셀 간 전파는 미디어 조명과 관련된 SH 이산 좌표 방법 [GRWS04]과 유사하며 6개의 축 방향과 윤곽 표면을 전파 파면으로 사용하고 결과적인 SH 계수는 다음 반복을 위해 대상 셀에 누적됩니다.

**4. 생성된 메시를 사용하여 장면을 밝게 합니다.**LPV를 사용한 최종 장면 렌더링, 하드웨어 삼선형 보간법을 사용하여 특정 위치에서 결과 메시 3D 텍스처 찾기, 조명 표면에 대한 법선의 코사인 로브와 방사조도 컨볼루션, 자체 출혈 방지를 위한 감쇠 계수 적용, 법선을 향한 방향 미분 계산, 강도 분포 방향의 기울기 편차에 따른 감쇠.

주입 후 8회 반복 효과:

조명 결과를 안정화하려면 다음 방법을 사용할 수 있습니다.
공간 안정성. 보수적인 래스터라이제이션를 위해 RSM을 하나의 픽셀로 캡처하고 안정적인 주입을 위해 LPV를 하나의 그리드 셀로 캡처합니다.
자체 조명. RSM 주입 중에 반쪽 셀 VPL을 정상 방향으로 오프셋합니다.
시간적 일관성과 재투영. SSAA가 RSM 주입에 대한 재투영을 수행할 시간을 정합니다.
이 방법의 한계: 확산 상호반사, 희박한 공간 및 저주파 각도 근사치(광 확산: 모든 방향으로의 광 투과 스퍼터링, 공간 이산화: 폐색 및 매우 거친 메시에 표시됨), 불완전한 2차 AO 정보.

다중 해상도 접근 방식을 채택하여 여러 개의 중첩된 RSM을 서로 다른 해상도로 렌더링할 수 있습니다. 계단식 그림자 맵 기술에서 영감을 받아 고르지 않은 다중 해상도 렌더링이 GPU에서 시뮬레이션되고 개체는 크기에 따라 다른 RSM에 할당됩니다. 해당 LPV에 RSM을 주입하고, RSM 프러스텀에 바인딩된 중첩된 LPV 메시를 생성하고, 독립적으로 전파 및 렌더링하고, 내부 LPV에서 외부로 전파합니다.
LPV는 다음과 같이 확장될 수도 있습니다.
투명한 물체.
대규모 조명 근사를 위한 조명 캐시, 광선으로 덮인 그리드 셀에 분석 방사선을 주입합니다.
동일한 트릭을 사용하여 여러 번 바운스할 수 있는 추가 오클루전 메시가 있는 보조 오클루전입니다.
LPV에서 부분적으로 일치하는 광택 반사.
커뮤니케이션 과정의 특성상 매체 조명에 참여합니다.

CLPV가 효과적인 이유는 다음과 같습니다.
간접 조명에 대한 인간의 인식. 접촉 조명(모서리, 가장자리 등)에 매우 민감한 간접 조명은 간접 그림자가 있는 경우에도 대부분 저주파이며 그림자의 평평한 환경이 아닌 부드러운 그라데이션이며 미디어와 관련된 확산 프로세스에 의해 근사됩니다.
캐스케이드: 중요도를 기준으로 클러스터링합니다. 이미터는 크기에 따라 계단식으로 분포됩니다.
오프라인 PBRT와 실시간 LPV의 비교는 아래와 같습니다. 둘 사이의 차이점은 명확하지 않습니다.

이미지 품질, 메모리, 동적 조명 지원, 동적 객체 지원, 2차 폐색, 다중 반사, 영역 조명 및 기타 매개변수 측면에서 라이트맵, PRT 및 LPV를 비교하면 다음과 같습니다.

LPV는 다른 기술과 결합될 수도 있습니다.
미세 교합 디테일을 추가하려면 SSAO를 곱하세요.
지연 환경 프로브. 장거리 GI를 향상시키기 위해 결합되었습니다.
간접광과 지연광. GI를 시뮬레이션하기 위해 특정 장소에서 간접 조명을 사용하는 것은 GI 스타일 지정 아티스트에게 중요합니다.

요약하자면, LVP는 장면/뷰/조명 변경에 대한 완전히 동적인 접근 방식이며, GPU 및 콘솔 친화적이고, 매우 빠르며(PlayStation 3의 경우 ~1ms/프레임), 프로덕션 준비가 되어 있고(실시간 조정을 위한 풍부한 도구 세트), 확장성이 뛰어나고, 품질에 비례하며, 안정적이고, 깜박임이 없으며, 복잡한 형상(예: 나뭇잎)을 지원합니다.
영화 및 게임 제작의 물리적 기반 셰이딩 모델은 Naty Hoffman과 Siggraph의 다른 사람들이 공유한 PBR에 대한 실시간 연설입니다. 연설에서는 PBR의 물리적 이론적 기초와 수학적 모델링, 그리고 이를 GPU에서 구현하는 방법에 대해 자세히 설명했습니다.

다른 물질에 의한 빛의 흡수 및 산란 성능.

미세 기하학 모델링을 기반으로 한 조명 모델입니다.

디퓨즈와 서브서피스 스캐터링(SSS) 사이의 전환 관계.

클래식 Cook-Torrance BRDF 공식.
게임 개발을 위한 물리적 동기를 부여받은 셰이딩 모델 제작은 게임 엔진에서 PBR의 구현, 개선 및 최적화와 관련된 Naty Hoffman의 연설이기도 합니다. 이 기사에서는 PBR을 사용하는 이유가 포토리얼리즘/초현실주의를 더 쉽게 달성할 수 있고, 조명 및 관측 변경 시 일관성이 있으며, 조정 및 "퍼지 요소"가 적고, 아티스트를 위한 더 간단한 머티리얼 인터페이스, 문제 해결이 더 쉽고, 확장이 더 쉽다고 언급합니다.
PBR에는 감마 보정 렌더링, HDR 값 지원, 우수한 톤매핑(영화 선호) 등 일부 사전 제작 기반이 필요합니다. 감마 보정 렌더링은 비선형(감마) 인코딩을 사용하여 음영 입력(질감, 색조, 버텍스 색상 등)을 자연스럽게 생성하고 미리 보고 (일반적으로) 저장하는 것이 특징이며, 최종 프레임 버퍼도 비선형 인코딩을 사용합니다. 여기에는 타당한 이유가 있습니다. 지각적으로 일관성이 있다는 것은 비트를 효율적으로 사용하는 것과 같으며, 레거시 이유(예: 도구, 파일 형식, 하드웨어)도 있습니다.
색상 지정이 감마 공간으로 기본 설정되어 있으면 색상 결과가 올바르지 않아 "1+1=3" 효과가 나타납니다.

HDR(High Dynamic Range)은 사실적인 렌더링을 생성할 수 있지만 음영 처리 전에 디스플레이 흰색(1.0)보다 훨씬 높은 값을 처리해야 합니다. 조명 강도, 라이트맵, 환경 맵, 음영 처리는 후광, 안개, 뎁스 오브 필드(DoF), 모션 블러 등에 영향을 미치는 하이라이트를 생성합니다. 저렴한 솔루션이 존재합니다.
이 기사에서는 Phong과 Blinn-Phong의 효과를 비교하고 어떤 경우에는 Blinn-Phong의 효과가 더 현실적이라는 사실을 발견했습니다.


기사에서는 반사 하이라이트의 경우 프레넬 항 외에도 정규화 계수


저자의 다른 기사에서는 PBR에 대해 자세히 논의했습니다. 얕은 것부터 깊은 것까지 PBR의 원리와 구현을 학습하는 것입니다.
Dx11 연결 목록을 사용한 OIT 및 간접 조명과 실시간 순서 독립적 투명도 및 Direct3D 11을 사용한 간접 조명에서는 간접 조명 효과를 얻기 위해 DirectX 11 기능을 사용하는 방법을 설명합니다. 이 기사에서는 간접 그림자가 없는 간접 조명 구성표를 언급합니다.
1. 장면 G-버퍼를 그립니다.
G-버퍼는 간접 그림자의 정확한 조명 조회를 위해 세계/카메라 공간 위치, 세계/카메라 공간 노멀, 색상/알베도, DXGI_FORMAT_R32G32B32A32_FLOAT 위치의 재구성을 허용해야 합니다.
**2. 반사 그림자 맵(RSM)을 그립니다.**RSM은 광원으로부터 직접 빛을 받는 장면 부분을 나타냅니다.
RSM은 다음 재구성을 허용해야 합니다: 월드/카메라 공간 위치, 월드/카메라 공간 노멀, 색상/알베도, 간접 조명에 대한 이미터만 그리기, 간접 그림자 광선을 정확하게 쿼리하려면 DXGI_FORMAT_R32G32B32A32_FLOAT 위치가 필요할 수 있습니다.
**3. 1/2 해상도로 간접광 버퍼를 그립니다.**RSM 텍셀은 간접 조명을 위한 G-버퍼 픽셀의 광원으로 사용됩니다. 단계는 다음과 같습니다:
1/2 해상도에서 간접광(IL)의 디퍼드 렌더링.
G-버퍼 픽셀을 RSM 공간으로 변환합니다.
G-버퍼 픽셀의 공간 변환 순서: 스크린 공간 -> 라이트 공간 -> RSM 텍셀 공간에 투영됨.
- RSM 텍셀의 커널을 광원으로 사용합니다.
RSM 텍셀은 가상 포인트 라이트(VPL)라고도 합니다.
- 커널 크기는 필요한 속도, 원하는 효과 모양, RSM 해상도에 따라 다릅니다.
G 버퍼의 한 픽셀에서 IL을 계산한 다음 커널의 모든 VPL 기여도를 누적합니다.

다음 계산 용어는 방사형 폼 팩터 계산에 사용된 용어와 매우 유사합니다.

IL을 원활하게 하기 위한 간단한 솔루션을 위해서는 t0, t1, t2 및 t3에 중심을 둔 4개의 VPL 커널을 고려해야 합니다.

대형 VPL 커널은 계산 속도가 느립니다.

다음 기술을 사용할 수 있습니다.

4. IL(간접광) 업샘플링.
간접광 버퍼는 해상도의 1/2이고 양측 업샘플링 단계가 수행되며 결과는 전체 해상도 IL입니다.
5. IL이 추가된 최종 이미지를 그립니다.
직접 조명, 간접 조명 및 그림자를 결합합니다.

왼쪽: 간접 조명 없음; 오른쪽: 간접광과 결합.
간접 그림자를 추가하려면:
- CS와 연결리스트 기술을 사용하세요.
IL의 폐색 형상(폐쇄기의 삼각형 사용)을 3D 목록 메시에 삽입하여 대체 데이터 구조의 백업을 확인하세요.

다른 VPL 커널을 읽으십시오.
폐색 삼각형에 의해 폐색된 VPL의 빛만 축적됩니다.
3D 메시를 통해 광선을 추적하여 가려진 VPL을 감지합니다.
저해상도 버퍼만 렌더링합니다.
IL 버퍼에서 가려진 간접광을 뺍니다.
저해상도 폐색이 포함된 IL의 흐린 버전이 사용되며, 흐림은 양측 흐림/업샘플링의 조합입니다.

윗줄: 3D 메시, 간접광 버퍼, 가려진 간접광; 맨 아래 줄: 간접광 버퍼, 폐색된 간접광 제외, 최종 이미징.
[Uncharted 2: 캐릭터 라이팅 및 셰이딩](http://advances.realtimerendering.com/s2010/Hable-Uncharted2(SIGGRAPH 2010 Advanced RealTime Rendering Course).pdf)에서는 피부, 머리카락, 천 및 기타 재질의 렌더링을 포함하여 Uncharted 2에 사용된 캐릭터 렌더링 기술에 대해 설명합니다.

Uncharted 2의 다양한 캐릭터의 렌더링 효과.
피부는 서브서피스 스캐터링(SSS) 모델을 사용합니다. 아래 그림은 NV가 텍스처 공간 블러를 사용하여 표면 아래 산란 효과를 근사화하는 것을 보여줍니다.

그런 다음 최종 하위 표면 산란 효과는 다양한 RGB 구성 요소가 있는 컨볼루션 커널을 통해 누적됩니다.
// :픽셀(Pixel)의 가중치(Weight),B > G > R.
diffColor = direct*float3(.233,.455,.649);
// 산란 :lm1~lm5는 블러(Blur)의 텍스처(Texture).
diffColor += lm1 * float3(.100,.336,.344);
diffColor += lm2 * float3(.118,.198,.0);
diffColor += lm3 * float3(.113,.007,.007);
diffColor += lm4 * float3(.358,.004,.0);
diffColor += lm5 * float3(.078,0,0);
왼쪽에서 오른쪽으로: 직접광만, 디퓨즈만, 둘의 조합.
NV는 블러링 과정에서 너무 많은 채널을 사용하기 때문에 성능과 파괴가 요구 사항을 충족할 수 없습니다. 이러한 이유로 Uncharted 2는 12탭 근사법을 채택합니다.

12-탭 지터의 가중치는 다음과 같습니다.
float3 blurJitteredWeights[13] =
{
// 픽셀(Pixel)의 가중치(Weight).
{ 0.220441, 0.437000, 0.635000 },
// 12-Tap의 가중치(Weight).
{ 0.076356, 0.064487, 0.039097 },
{ 0.116515, 0.103222, 0.064912 },
{ 0.064844, 0.086388, 0.062272 },
{ 0.131798, 0.151695, 0.103676 },
{ 0.025690, 0.042728, 0.033003 },
{ 0.048593, 0.064740, 0.046131 },
{ 0.048092, 0.003042, 0.000400 },
{ 0.048845, 0.005406, 0.001222 },
{ 0.051322, 0.006034, 0.001420 },
{ 0.061428, 0.009152, 0.002511 },
{ 0.030936, 0.002868, 0.000652 },
{ 0.073580, 0.023239, 0.009703 },
}12-Tap에는 두 가지 구현 방법이 있습니다.
- 흐림은 별도입니다.
라이트맵으로 렌더링합니다.
12-탭 블러 라이트맵.
마지막 장면을 렌더링합니다.

- 콤보 블러.
라이트맵으로 렌더링
- 라이트맵의 12탭 샘플링을 사용하여 최종 장면을 렌더링합니다.

위의 두 가지 방법 모두 좋은 렌더링 효과가 있습니다.

왼쪽: 분리 흐림; 오른쪽: 조합 흐림.
Uncharted 2는 또한 R/G/B 구성요소가 다른 법선에서 나온 것처럼 가장하기 위해 Bent Normal을 시도했습니다. R은 형상에 더 가깝고, G/B는 노멀 맵(아래)에 더 가깝고, 디퓨즈는 3번 계산됩니다.

그러나 R/G/B에 대해 서로 다른 법선을 사용하면 파란색 얼룩이 나타나는 것 같습니다.

파란색 점이 나타나는 이유는 내적이 극단적인 각도에 있고 확산R=0과 확산B=1 또는 그 반대가 발생할 수 있기 때문입니다.
또 다른 접근법은 지오메트리와 노멀 매핑된 노멀의 확산 계산을 수행하는 블렌디드 노멀(Blended Normal)이며, 그 사이에서 지오메트리 노멀에서 더 많은 빨간색을 얻고 노멀 매핑된 노멀에서 더 많은 녹색/파란색을 얻습니다. 구체적인 방법은 Diffuse(L, G), Diffuse(L, N), Lerp입니다. 파란색/녹색은 변경되지 않고 빨간색은 오버플로됩니다. 빨간색은 있을 수 있지만 파란색/녹색은 없고 파란색/녹색은 있지만 빨간색은 없습니다. 이 방법을 사용하면 파란색 반점을 크게 줄일 수 있습니다.

헤어 렌더링을 위해 Uncharted 2는 Kajiya-Kay의 조명 모델을 사용합니다. 구현 내용 및 특징은 다음과 같습니다.
약간의 랩어라운드 확산.
Kajiya-Kay 스페큘러 반사.
셀프 섀도잉이 없습니다. 추가 바이어스가 있는 최대 캐스케이드처럼 보입니다.
반사 마스크로 확산 맵. 부분적으로 채도가 낮습니다.
Blinn-Phong을 이용한 지연 조명.

천에서 Uncharted 2는 가장자리 조명 + 내부 조명 + 디퓨즈의 조합을 사용합니다.

천 조명. 왼쪽부터: 림 라이트, 내부 조명, 디퓨즈, 결합 조명.
천 조명의 의사 코드는 다음과 같습니다.
VdotN = saturate( dot( V, N ) );
Rim = RimScale * pow( VdotN, RimExp );
Inner = InnerScale * pow( 1-VdotN, InnerExp );
Lambert = LambertScale;
ClothMultiplier = Rim + Inner + Lambert;
FinalDiffuseLight *= ClothMultiplier;그러나 위의 천 구현은 빛의 방향을 무시하므로 광원의 방향이 바뀌어도 천의 조명이 바뀔 수 없습니다.
CryENGINE 3: 빛의 속도에 도달하는 것은 주로 CryENGINE 3의 텍스처 압축 및 지연 조명에 대한 콘솔 개선입니다.
텍스처 압축 개선:
- 색상 질감. 창의적인 정확성, 최적의 색 공간 및 DXT 블록 압축이 개선되었습니다.
히스토그램을 기반으로 올바른 색 공간을 선택하는 것이 좋습니다. 경험상 픽셀의 75% 이상이 중앙값보다 높으면(선형 공간은 116/255=0.45) 선형 공간을 사용하는 것입니다. **
- 노멀 맵 텍스처. 일반 정확도 및 3Dc 일반 맵 압축이 개선되었습니다.
이전에는 아티스트가 노멀 맵을 8bpc 텍스처에 저장하여 처음부터 노멀을 양자화했습니다! 항상 16bpc 노멀 맵을 내보내도록 워크플로를 변경하세요! 기본적으로 아티스트에게 투명하게 내보내도록 도구를 수정합니다.

상단: 8bpc 일반 텍스처; 하단: 16bpc 일반 텍스처. 분명히 후자의 하이라이트는 더 섬세하고 부드럽습니다.
노멀 맵에 사용되는 3Dc 인코딩은 개선될 수 있습니다. 3Dc는 ARGB8보다 훨씬 뛰어나며 대부분의 GPU에서 16비트 정확도로 보간을 생성합니다!
일반 3Dc 인코더: x와 y를 두 개의 알파 채널로 독립적으로 압축합니다. x-y를 법선으로 간주하지 마세요!
3Dc 인코더 개선을 위한 제안: 두 개의 알파 블록을 하나의 전체 x-y 법선으로 처리하고 "색채" 오류가 아닌 법선을 계산합니다.
압축 속도를 높이기 위해 적응형 접근 방식을 사용할 수 있습니다. 즉, 2개의 알파 블록으로 압축하고 일반 오류를 측정합니다. 오류가 임계값보다 높으면 고품질 인코더를 실행하세요.

a: 원본 텍스처; b: 기존 인코딩; c: 권장 인코딩; d: 오류입니다.
CryEngine 3의 오클루전 컬링은 소프트웨어 z-버퍼(일명 오버레이 버퍼)를 사용합니다. 단계는 다음과 같습니다:
콘솔에서 이전 프레임의 z-버퍼를 축소합니다. 잘못된 컬링을 방지하려면 보존적 폐색을 사용하세요.
밉을 생성하고 AABB 및 OOBB를 사용하여 Zcull 및 Hi-Z 기술과 유사한 계층형 오클루전 컬링을 사용하여 폐색을 테스트합니다.
PC에서: 폐색은 CPU에서 수동으로 배치되고 래스터라이제이션됩니다. CPU와 GPU 사이의 대기 시간으로 인해 z-버퍼를 컬링에 사용할 수 없게 됩니다.
SSAO의 개선 사항에는 2채널 16비트 값 [0;1]의 인코딩 깊이와 유리수인 선형 깊이(깊이=x+y/255)가 포함됩니다. 절반 화면 해상도에서 SSAO를 계산하고, SSAO를 동일한 RT(다른 채널)로 렌더링하고, 양측 흐림을 통해 SSAO와 깊이를 동시에 얻습니다. 4개의 체적 폐색 샘플, 간단한 재투영을 위한 시간 축적을 통해 전체 성능은 X360에서 1ms, PS3에서 1.2ms입니다.

컬러 그레이딩의 경우 모든 전역 색상 변환이 3D LUT로 구워집니다. 16x16x16 LUT이면 충분하다는 것이 밝혀졌습니다. 하드웨어 3D 텍스처를 사용해 보십시오. 색상 보정 채널은 조회입니다: newColor = tex3D(LUT, oldColor).

CryEngine 3는 Adobe Photoshop을 색상 교정 도구로 사용하여 Photoshop에서 변환된 색상 LUT를 읽습니다.

이 기사에서는 다음을 포함하여 디퍼드 렌더링 파이프라인의 문제에 대해 설명합니다.
앤티앨리어싱은 지원되지 않습니다. MSAA는 디퍼드 렌더링에 비해 너무 무겁습니다. 사후 처리 앤티앨리어싱은 앨리어싱을 완전히 제거하지 못하며 대부분의 경우 오버샘플링이 필요합니다.
제한된 재료 변형, 이방성 재료 없음.
투명한 물체는 지원되지 않습니다.
디퍼드 렌더링 GBuffer의 픽셀당 데이터가 작을수록 좋습니다. CryEngine 3는 GBuffer를 64비트/픽셀로 최소화합니다. 여기서 RT0은 Depth 24bpp 및 Stencil 8bpp를 저장하고 RT1은 Normals 24bpp 및 Glossiness 8bpp를 저장합니다. 조명 그룹의 개체에 라벨을 지정하기 위한 템플릿: 포털/내부, 사용자 정의 주변 반사, 다양한 환경 및 간접 조명. 조명 누적 패스에 필요한 광택은 지연될 수 없습니다. 그렇지 않으면 스페큘러 반사 반사가 누적되지 않습니다. 이 G 버퍼 레이아웃의 문제점: Phong BRDF만(노멀 + 광택), 이방성 재질 없음, 24bpp에서 과도하게 양자화된 노멀, 조명 밴딩/낮은 품질.
셰이딩 노멀 정확도의 경우 24bpp 노멀이 너무 양자화되어 조명 품질이 낮습니다. 24bpp의 정확도이면 충분합니다. 조명 품질이 낮은 이유는 무엇입니까? 그 이유는 정규화된 법선이 저장되기 때문입니다! 큐브는 256x256x256 셀 = 16777216 값이며 이 큐브에서는 단위 구의 셀만 사용됩니다. 16777216개 중 약 289880개 셀 또는 약 1.73%! !

이 대칭 큐브맵에서 가장 의미 있고 고유한 부분을 추출하고, 2D 텍스처로 저장하고, G-Buffer 생성 중에 조회하고, 법선의 크기를 조정하고, 조정된 법선을 G-Buffer에 출력합니다.

법선의 가장 잘 일치하는 부분은 알파 블렌딩을 지원합니다. 비록 가장 잘 맞는 부분이 파괴되더라도 이것은 일반적으로 문제가 되지 않습니다. 재구성은 단지 정규화일 뿐입니다! 세부적인 범프가 있는 개체를 비활성화하는 등 일부 선택적 스무딩을 개체에 적용할 수 있으며, 결과 텍스처에 대한 밉맵을 만드는 것을 잊지 마세요!
여러 가지 일반 저장 기술을 비교하면 다음과 같습니다.
일반 저장 기술 유효한 셀 유효 세포 비율
정규화된 노멀 약 289880 / 16777216 약 1.73%
최대 성분으로 나눈 값 약 390152 / 16777216 약 2.33%
제안된 방법(최적합) 약 16482364 / 16777216 약 98.2%

정규화된 노멀(상단)과 가장 잘 일치하는 노멀(하단)의 렌더링 비교.

정규화된 노멀(위)과 가장 잘 일치하는 노멀(아래)의 비교.
이 기사에서는 조명에 사용되는 계산인 클립 볼륨(클립 볼륨)에 대해서도 설명합니다. 그림자가 없는 디퍼드 라이팅은 오버플로되는 경향이 있지만 그림자는 비용이 많이 듭니다. 해결 방법: 아티스트가 정의한 클리핑 형상(라이트 볼륨 마스크 외에 클리핑 볼륨 및 마스크 템플릿)을 사용하십시오. 오버헤드가 매우 낮아 템플릿 마크업 속도가 4배 더 빠릅니다.

작물량의 예. 왼쪽 위: 잘린 볼륨 형상; 오른쪽 상단: 템플릿 표시; 왼쪽 아래: 광 축적 버퍼; 오른쪽 아래: 최종 이미징.
이방성 재료를 효율적으로 구현하기 위해 CryEngine 3는 BRDF 복잡성을 조명 복잡성에서 분리하고 BRDF 복잡성을 조명 채널에서 완전히 제거합니다. (아래 사진)

안티앨리어싱 측면에서 CryEngine 3는 하이브리드 안티앨리어싱 솔루션을 사용합니다.
**가까운 물체에 대한 포스트 프로세스 AA입니다.**오버샘플링하지 않고 가장자리에 적용하며 MLAA를 사용합니다.
**멀리 있는 물체에는 TAA를 사용하세요.**표면 공간 그림자 변화를 구분하지 않고 시간적 슈퍼샘플링을 수행합니다.
템플릿과 흔들림 방지 카메라로 분리하세요.
거리 분리는 멀리 있는 객체의 뷰 벡터에 작은 변화를 보장하여 역시간적 재투영의 근본적인 문제인 음영 영역의 뷰 관련 변경을 줄입니다. 그 이유는 재투영이 깊이 버퍼를 기반으로 하기 때문에 객체의 음영 공간의 로컬 변화를 고려할 수 없기 때문입니다. 클로즈업된 물체에 적용할 경우 잔상, 반사 등이 발생할 수 있습니다.

시간적 지터링을 위해 객체를 표시하는 템플릿을 사용하여 객체별로 분리되고 일관된 객체 공간 셰이딩 동작을 제공합니다.


위: 멀리 있는 물체에 대한 TAA; 하단: 가까운 물체에 대한 포스트 프로세스 AA.
샘플 배포 그림자 맵은 Intel에서 제안한 향상된 그림자 렌더링 방법입니다.
샘플 분포 섀도우 맵(SDSM)은 컴팩트 Z 경계의 로그 분할을 기반으로 컴팩트 Z의 최소/최대 값을 찾기 위해 그림자 샘플 분포를 분석하고 조정 없이 뷰와 형상에 적응할 수 있는 샘플 분포 섀도우 맵입니다. 각 파티션에 대해 컴팩트한 축 정렬 경계 상자를 사용하여 컴팩트한 조명 공간 경계를 계산하여 유용한 그림자 해상도를 크게 높입니다.


상단: PSSM(병렬 섀도우 맵) 파티션, 광원 공간, 광원 공간 파티션; 하단: SDSM 파티션, 광원 공간, 광원 공간 파티션.
파티션 변형은 다음과 같습니다:
K-평균에 의한 클러스터링. Z에 샘플이 많은 곳에 파티션을 배치하면 평균 오류에 대한 좋은 결과를 얻을 수 있지만 유리 턱이 있습니다.
적응 로그. 기본 로그와 유사하지만 Z의 간격을 피하고 특별한 경우에만 작동하며 일반적으로 시도해 볼 가치가 없습니다.
위의 솔루션에는 깊이 히스토그램이 필요합니다.
SDSM에는 두 가지 구현이 있습니다.
로그의 간단한 "감소" 구현. DX9/10 하드웨어의 픽셀 셰이더에서 구현할 수 있습니다.
일반 깊이 히스토그램 구현. 공유 메모리 원자성은 이를 가능하게 하지만 너무 느리고 DX11 이전 하드웨어에 의존합니다.
SDSM은 섀도우 맵에 렌더링되는 지오메트리의 양을 줄여 더 조밀한 조명 공간 프러스텀를 생성합니다.
GPU, CPU에서 생성된 파티션 경계 데이터는 프러스텀 컬링에 사용할 수 없습니다! 파티션 경계 데이터(매우 작음)를 차단하고 다시 읽는 것은 좋지 않은 것처럼 들리지만 당시에는 이것이 작동하고 꽤 빠릅니다. GPU에서의 프러스텀 컬링에 대한 향후 작업.
시간 일관성에 대한 참고 사항:
해상도를 변경하면 시간 앨리어싱이 발생할 수 있습니다.
방향성 조명에 대해서만 조명 공간의 파티션 경계를 양자화하시겠습니까? 파티션을 이동하거나 크기를 조정할 수 있는 방법이 전혀 없습니다. 카메라 변환에는 몇 가지 문제가 있으며 지나치게 제한적이고 차선책입니다.
파티션을 2가지 크기의 거듭제곱으로 양자화하시겠습니까? 작동하지만 가혹하고 많은 해상도를 낭비합니다.
대상 하위 픽셀 그림자 해상도. 적절한 파티션 해상도(화면 해상도와 거의 동일)가 필요하며, 좋은 필터링과 섀도우 맵 앤티앨리어싱을 사용하세요!
향후 개선 방향:
더 나은 파티셔닝 방식? 많은 접근 방식이 시도되었지만 실제로는 잘 작동하는 더 나은 알고리즘이 있을 수 있습니다.
프로젝션 앨리어싱을 해결하기 위한 블렌딩 알고리즘. 오류가 높은 경우 더 비싼 알고리즘을 사용하십시오.
[토이 스토리 3: 비디오 게임 렌더링 기술]( http://advances.realtimerendering.com/s2010/Ownby ,Hall%20and%20Hall%20-%20Toystory3%20(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf)은 SSAO에 대한 소개입니다. 디즈니 게임 토이스토리3에 사용된 주변광 및 그림자 렌더링 기술.
기사에서 언급한 바와 같이 SSAO가 직면한 과제와 그에 따른 솔루션은 다음과 같습니다.
- 샘플링 방법과 장소.
선형 적분을 사용합니다.

파란색 점은 여전히 샘플링되는 픽셀입니다. 3D가 아닌 2D로 샘플링된 이를 둘러싼 개념적 체적 구를 상상해 보세요. 각 샘플에는 해당 부피가 있으며, 샘플의 깊이에 따라 해당 부피의 작은 부분이 폐색됩니다.
라인 통합을 사용하면 각 샘플이 비폐색에 비해 작은 비율의 폐색을 생성하므로 폐색의 양이 원활하게 변경됩니다.

선형 적분의 알고리즘 프로세스: (x,y) 좌표를 샘플링하고, [0,1]을 따라 거리를 계산하며, 샘플의 해당 행은 이 양에 해당 볼륨을 곱하여 샘플의 폐색 기여도를 얻습니다.
- 더 많은 샘플을 얻기 위해 위조하는 방법.
2D 무작위 회전을 사용합니다. 2D 회전으로 텍스처를 생성하는 것부터 시작합니다(4x4 G16R16F 텍스처를 사용하여 각 각도의 사인과 코사인을 인코딩함).

4x4 텍스처로 인코딩된 회전:

4x4 오프셋을 사용한 순차적 회전:

너무 집중되거나 규칙적인 샘플 회전을 방지하려면 샘플을 무작위로 회전할 수 있습니다.

무작위 회전 후 효과:

회전에 지터를 추가할 수도 있습니다(아래 그림의 왼쪽에는 지터가 없고 오른쪽에는 지터가 추가되었습니다).

회전 유무에 따른 샘플 비교(왼쪽, 오른쪽 없음):

- 장거리의 깊이 차이를 처리하는 방법.
이전 접근 방식(예: CryTek)은 거리 깊이 차이가 큰 경우 AO를 직접 0으로 설정하는 것이었지만 문제는 아래 그림에 표시된 평면이 1/2 가려져야 하므로 사용할 수 없는 샘플을 0으로 설정하면 결과가 너무 가려지지 않게 편향되어 후광이 발생한다는 것입니다.

0.5를 사용하면 평면이 뷰 평면과 평행할 때 잘 작동하지만 경사면에서는 분해됩니다. 아래 이미지에서는 결과적으로 폐색이 너무 적고, 반대쪽에 폐색이 있으면 너무 많은 폐색이 발생합니다.

누락된 샘플을 추정하려면 각 샘플이 쌍의 일부(쌍 샘플링)라는 샘플링 패턴에 제약 조건을 적용해야 합니다. 이는 앞서 본 이상한 "오리온" 샘플링 패턴을 설명합니다.

주변광의 경우, 조사광원은 각 축을 따라 방향광인 SH를 사용하며 +/- 단색 주변광은 주변 조명에만 사용됩니다. 실시간으로 조정할 수 있으며, 네거티브 라이트, SH를 실시간으로 혼합할 수 있습니다. 음의 광원은 음의 y 방향에서 위쪽을 가리키는 빛에 주로 사용되며, 광원의 아래쪽을 어둡게 하고 모든 것에 약간의 그림자를 줍니다.
Wii에서 주변광을 렌더링하는 것은 SH를 사용하고 각 프레임은 법선을 사용하여 조회할 수 있는 뷰 공간에 구형 맵을 생성합니다. 환경은 국지적으로 문제가 있으며 일부 장소에서는 빛샘이 과도하게 밝아지는 문제가 있습니다. 그 이유는 각 월드마다 주변 장치가 하나만 있기 때문입니다. 의도된 효과는 위치에 관계없이 모든 것이 동일한 분위기에 제시된다는 것입니다. 가능한 솔루션은 두 가지 환경 구성 간의 혼합, 카메라 거리에 따른 혼합, 위치에 따른 환경 구성 전환, 구운 환경 조명, 실시간 복사조도 또는 전역 조명, 지정된 주변광입니다.
그러나 위의 방법을 사용하는 대신 우리는 제약 조건을 추가했습니다. 즉, 어두운 광원과 밝은 광원이라는 두 가지 유형의 광원만 있습니다.

이 솔루션은 볼륨을 지연된 버퍼로 렌더링하고 버퍼 값에 따라 밝은 환경 바인딩과 어두운 환경 바인딩을 혼합하는 방식으로 작동합니다. 가장 큰 장점은 아티스트가 주변 조명을 더 잘 제어할 수 있다는 것입니다.

기술을 지연시키는 단계:
볼륨을 사용하세요.
볼륨을 별도의 렌더 타겟으로 렌더링합니다.
출력 색상은 볼륨 중심에서 픽셀까지의 거리를 나타냅니다.
- 메인 장면 채널에 밝은 주변 색상과 어두운 주변 색상을 혼합합니다.

위에 설명된 볼륨에는 큐브, 구, 회전, 스케일링 등 다양한 지오메트리 유형과 작업이 포함됩니다.

다음은 사용된 볼륨이 있는 경우와 없는 경우의 비교 차트입니다.


그림자의 측면에서 이 기사는 라이트 맵이 없는 동적 그림자, 주인공을 위한 드롭 그림자, 그림자의 모양을 부드럽게 하고 보존하며 전체 거리를 희생하여 근거리에서 더 높은 품질의 그림자를 얻는 방법도 공유합니다.
그림자의 모양을 부드럽게 하고 보존하는 데 있어 전통적인 접근 방식은 그림자 맵을 절대 최고 해상도로 렌더링하고 필터링을 추가하여 아티팩트를 줄이는 것입니다. 그러나 더 부드러운 그림자가 필요합니다. ToyStory 3에는 최대 300만 개의 정점이 있는 장면이 포함되어 있으며 300m 거리에 4개의 폭포를 확장하는 것은 매우 비싸고 제한된 LOD 및 오클루전 컬링 기술입니다. 토이스토리3에서는 **가상 섀도우 맵(VSM)**도 고려했지만, VSM 역시 당시 너무 비싼 고해상도 섀도우 맵을 흐리게 처리하는 것, 2배 심도 쓰기가 불가능한 점, 아티스트가 좋아하지 않는 시각 효과, 관리가 어려운 빛샘 현상 등 많은 제약이 있어 결국 채택되지 않았습니다. 마지막으로 3개의 640x640 섀도우 맵, 4x4 Gaussian PCF, 5x5 교차 양측 필터링 등의 결합된 솔루션이 채택되었습니다. (아래 사진)

또한 ToyStory 3에서는 Deferred Shadow 기술도 사용합니다. R 채널은 SSAO를 저장하고, G 채널은 월드 그림자를 저장하며, B 채널은 캐릭터 그림자를 저장합니다.

Deferred Shadow Shading의 단계는 다음과 같습니다.
전체 화면 쿼드를 렌더링합니다.
뷰 공간 깊이 버퍼에서 월드 위치를 재생성합니다.
경계 상자 계단식 선택.
동적 깊이 편차 계산.
4x4 Gaussian PCF에서 최종 그림자 값까지.
또한 그림자 줄무늬 및 깊이 편차와 같은 결함을 최적화하고 개선합니다.
Direct3D 11을 사용하는 실시간 순서 독립 투명도 및 간접 조명은 DX11 기반 OIT 투명 렌더링 및 전역 조명 기술을 간접 그림자와 공유합니다. 간접 그림자는 장면에서 발생하는 미묘한 동적 변화를 인식하는 데 도움이 되며 깊이 인식에 유용한 단서를 추가합니다. 장면 픽셀에 대한 간접 조명 기여도가 더 정확합니다. 이는 환경의 조명이 어두우거나 작업이 직사광선에서 멀리 떨어져 있을 때 시각적 경험과 게임 플레이에 특히 중요합니다.
GOW3의 동적 조명은 주변 조명, 점 광원, 방향 조명 등을 포함하여 God of War III 게임에 사용되는 동적 조명 기술을 설명합니다.
주변광은 이 기사에서 다루지 않는 RGB 보간기로 결합됩니다. 포인트 라이트와 방향 라이트는 하이브리드 버텍스 라이트로 표현됩니다.
혼합 버텍스 광원은 픽셀 조명과 동일한 1개의 광원을 지원할 수 있으며 여러 광원도 지원할 수 있습니다. 각 정점의 거리 감쇠를 계산하고, 각 정점을 집합 조명으로 결합하고, 각 픽셀의 집합 조명 위치를 보간하고, 마치 단일 픽셀 빛이 있는 것처럼 조각 프로그램에서
삼각형의 두 점 위치를 보간할 때 기본 보간을 사용하면 잘못된 결과가 생성되며 광원 방향을 특별히 처리해야 합니다.

광원의 감쇠함수는 원활하고 저렴하길 바라며, 함수 자체가 0에 가깝기 때문에 1차 미분도 0에 가까웠으면 좋겠습니다. 아래 그림은 같은 방향의 빛이 똑바로 아래로 비추는 감쇠를 나타낸 것입니다. 오른쪽은 기사에서 채택한 감쇠입니다. 감쇠 기능은 동일한 거리에서 0에 도달하도록 설정됩니다.


집계된 광원을 더 잘 표현하려면 각 월드 조명 위치에서 월드 버텍스 위치를 빼서 상대 벡터를 생성하고, 길이와 가중치를 계산하고(두 조명의 조명 강도는 1이라는 점을 기억하세요), 상대 벡터에 가중치를 곱하여 방향 필드로 이동하고, 조명 방향을 추가하고, 가중치를 누적하고, 집계 방향에 누적 가중치를 곱하여 위치 필드로 돌아가면, 결국 집계된 라이트의 상대 라이트 벡터가 되고, 여기에 버텍스 월드 위치를 추가하여 집계된 세계 위치를 얻습니다. 빛.

관련 계산 공식, 기호 설명 및 그림은 다음과 같습니다.

집광 위치를 계산하는 방법을 해결하려면 적절한 감쇠 함수를 선택한 후 백라이트 소스를 해결해야 합니다. 광원은 그림자를 고려하지 않고 집계되기 때문에 정점에서 멀어지는 빛의 영향을 제거하는 것이 중요합니다. 다음 수식을 사용하십시오.

다음으로, 서로 다른 방향의 두 광원의 전환 문제를 해결해야 합니다. 다음 이미지가 완벽하게 대칭이라고 가정하면 조각 프로그램에서 계산된 N 도트 L은 정확히 1이 되며 이는 A 또는 B의 N 도트 L 값보다 훨씬 높으므로 P에서 예상치 못한 밝은 보라색 하이라이트를 볼 수 있습니다.


위 문제를 해결하는 프로세스는 다음과 같습니다. 프래그먼트 프로그램에서 꼭지점에서 보간된 빛 위치를 얻은 다음 빛 벡터를 계산하고 N 점 L을 계산하기 전에 이를 정규화합니다. 보간된 빛 벡터가 임계값보다 짧은 경우 정규화를 중지하면 위 문제를 잘 해결할 수 있습니다.

다음으로 우리는 총광 색상 문제를 다룹니다. "물리적으로 올바른" 값을 계산하는 데 사용되는 데이터 손실은 프래그먼트 프로그램에서 보간될 때 합리적인 결과를 제공할 수 있도록 해결되어야 합니다. 집계된 조명 위치를 계산하고, 정규화된 조명 방향을 계산하고, 내적을 계산합니다.



여러 벡터를 추가하면 길이가 투영의 합과 동일해집니다.

최종적으로 맞는 공식은 다음과 같습니다.

RGB로 확장:

GOW3이 구현되면 각 정점의 조명 계산이 EDGE 작업에서 사용자 정의 코드로 실행됩니다. 이는 고도로 최적화되어 있으며 참조 및 디버깅을 위해 PPU 버전을 계속 실행합니다.
[Call Of Duty: Black Ops의 물리 기반 조명](http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops (Siggraph 2011 Advances in Real-Time Rendering Course).pptx)에서는 Call of Duty 그래픽의 발전을 통해 배운 교훈과 물리 기반 조명 및 그림자를 제공합니다.
COD의 런타임 조명 전략은 모든 주요 조명이 셰이더에서 계산되고 각 주요 런타임 그림자 맵이 카메라 주변 반경에 구운 그림자를 오버레이하는 것입니다. 따라서 색상과 강도를 변경하고, 작은 범위를 이동 및 회전하면서도 정적 및 동적 그림자가 잘 혼합되어 여전히 올바르게 보이는 것이 가능합니다.
디퓨즈의 경우 주요 디퓨즈는 그림자와 확산 알베도에 의해 변조되는 고전적인 Lambert 용어를 사용합니다. 2차 확산은 확산 알베도에 의해 변조된 픽셀당 법선을 사용하여 라이트맵/라이트그리드 2차 방사조도로 재구성됩니다.
스페큘러 반사의 경우 주요 스페큘러 반사는 그림자와 "확산" 코사인 요소에 의해 변조된 마이크로패싯 BRDF를 사용합니다. 2차 반사광은 1차 하이라이트와 동일한 BRDF 매개변수를 기반으로 2차 방사조도와 관련된 픽셀별 노멀 및 프레넬 항을 사용하여 환경 프로브에서 재구성됩니다.
모듈식 접근 방식을 취하면서 Cook-Torrance를 사용한 초기 실험이 이어졌고 보다 현실적인 모양과 더 나은 성능을 위해 다양한 옵션이 시도되었습니다. BRDF의 각 부분을 개별적으로 선택할 수 있기 때문에 다양한 "레고 블록"(즉, 조합)이 시도되었습니다.
그 중 D(정규분포)는 Beckmann 방정식을 사용합니다.

F(프레넬)은 다음 방정식을 사용합니다.

G(기하학적 마스킹)는 Schlick-Smith 접합 공식을 사용합니다.

환경 맵의 경우 메모리 제한, 낮은 해상도, 전환 문제, 반사성 확산 및 대규모 메시의 연속성으로 인해 조명 조건을 일치시키는 수십 개의 환경 프로브가 있었습니다. Black Ops의 희망은 이러한 문제를 해결하고 높은 반사 지수와 일치하는 더 높은 해상도의 환경 맵을 갖는 것입니다. 해결책:
정규화 - 점의 평균 확산 조명을 캡처하여 환경 맵을 나눕니다.
비정규화 - 라이트맵/라이트그리드에서 재구성된 픽셀당 평균 확산 조명을 환경 맵에 곱합니다.
정규화를 사용하면 환경 맵이 다양한 조명 조건에 더 잘 적응할 수 있습니다. 실외 영역은 단 하나의 환경 맵으로 벗어나고 실내 영역은 보조 반사 조명을 캡처하기 위해 더 많은 위치별 환경 맵이 필요합니다. AMD/ATI의 CubeMapGen을 사용하여 Mipmap, HDR 각도 범위 필터링 및 표면 가장자리 보정을 사전 필터링하고 생성합니다.

재질 광택을 기준으로 밉 선택:
texCUBElod(uv, float4(R, nMips - gloss*nMips));텍스처 손상을 일으킬 수 있는 매우 매끄러운 표면의 경우 일부 GPU에는 하드웨어 선택 밉을 가져오는 지침이 있습니다. 환경 맵 "프레넬":

그러나 너무 많은 하이라이트가 발생하므로 Normal Variance를 사용하여 해결할 수 있습니다. 변형 맵은 노멀 맵 매핑에서 누락된 정보를 직접 인코딩할 수 있습니다. 분산 맵은 셰이더에 저장하고 읽고 디코딩하려면 높은 정밀도와 추가 비용이 필요합니다. 오프라인에서 글로스맵과 결합하면 어떨까요?
투영 변화는 노멀 맵에서 추출할 수 있으며, 항상 상단 밉에서, 바람직하게는 NxN 가중치 필터를 사용하여 추출할 수 있습니다.

변화로 변환된 창의적인 광택을 추가합니다.

분산을 다시 광택으로 변환합니다.

이 방법은 대부분의 하이라이트 강도 문제를 해결하고 반사광 반사의 앤티앨리어싱에도 사용할 수 있어 환경 맵 밉에 광택 제어를 적용할 때 텍스처 손상 가능성을 최소화합니다.
물리적 기반 셰이딩은 상대적으로 비용이 더 많이 듭니다(ALU의 평균 10-20% 증가). 특수 케이스 셰이더를 사용하면 성능에 도움이 됩니다. 텍스처 바운드 셰이더의 경우 추가 ALU 비용을 숨길 수 있습니다. 특정 경우에는 여전히 빠른 Lambert 셰이더를 사용하는 것이 좋습니다.
물리적 기반 셰이딩은 그만한 가치가 있습니다. 스페큘러 반사를 진정한 "차세대"로 만들려면 상당한 엔지니어링 및 예술적인 노력을 기울여 보상을 받을 준비를 하십시오.
묵시록 조명: RED FACTION: ARMAGEDDON의 렌더링 기술은 추론 조명과 같이 Red Faction 게임에서 사용되는 조명 기술을 공유합니다.
Inferred Lighting은 Light Pre-Pass Rendering이라고도 불리는 지연 조명의 변형입니다. 장면의 복잡성에서 조명을 분리하는 것은 장면 파괴를 처리하는 데 중요합니다. 추론 조명 = 라이트 프리패스++, 조정 가능한 조명 해상도, MSAA 지원, 알파 조명.
1년 후, 조명 및 단순화 Saints Row: The Third는 추론 조명의 최신 반복을 공유하고 몇 가지 새로운 최적화 및 기능은 물론 메시 단순화 및 실제 실행 문제를 포괄하는 자동화된 LOD 파이프라인을 추가합니다.
원본 추론 조명은 다양한 완전 동적 조명, 통합 알파 조명(포워드 렌더링 없음), 하드웨어 MSAA 지원(DX9에서도)을 지원합니다. 이를 바탕으로 이 문서에서는 빗방울 조명(IL 필요), 향상된 나뭇잎 지원(IL만 해당), 화면 공간 데칼(IL로 향상) 및 방사형 앰비언트 오클루전(AO)(RAO)(IL로 최적화)을 추가합니다. 자세한 내용은 14.4.4.1 추론된 조명 섹션을 참조하세요.
LOD의 경우 이전 방식은 주로 아티스트가 제작했기 때문에 시간이 많이 걸렸습니다. 실제로 생성된 LOD는 많지 않았으며 대부분은 "디테일 세트"로 페이드되도록 선택했습니다. 새로운 방식은 DCC 애플리케이션 대신 크런처에서 실행되는 완전한 기능의 그리드 단순화 도구를 구현합니다. 대부분은 자동으로 생성된 LOD이지만 아티스트는 건물, 캐릭터, 차량, 완전 자동화(아티스트 개입 없음) 지형 등을 조정할 수 있으며 단순화 도구를 사용하여 선체와 지형 충돌을 생성하고 섀도우 프록시를 구축할 수도 있습니다.
메시 단순화는 주로 메시 근사치가 얼마나 "나쁜"지 측정하고 수축 오류를 계산하고, 먼저 축소되는 가장자리와 결과 정점을 배치할 위치를 결정하는 데 사용되는 오류 측정항목을 사용합니다. 2차 오차 측정 개요:

구현 프로세스 중에 UV 경계 늘이기 문제가 발생할 수 있습니다.

그 이유는 UV가 불연속적이기 때문입니다.

UV 미러링을 사용하면 경계를 덜 명확하게 만들 수 있습니다.

더 나은 접근 방식은 모든 종류의 테두리와 동일한 방식으로 테두리를 유지하여 테두리 가장자리를 통해 "더미" 평면을 추가하는 것입니다.

연속 영역: 각 정점에서 연속 UV가 있는 영역을 추적합니다. 연속 영역의 문제는 UV가 꼭지점에서 연속적일 수 있다는 것입니다... 영역이 분리되어 있더라도

재료 수량: LOD가 단순해짐에 따라 재료 비용이 지배적입니다.

재료 수 줄이기: "작은" 면적의 재료를 적극적으로 찾아 동일한 그리드에 사용되는 더 큰 재료로 교체합니다. 숫자는 줄어들지만 크게 절약되지는 않습니다.

Supplemental Level of Detail은 유동 가능한 각 영역을 단일 메시로 베이킹하고 훨씬 더 단순화하며(원래 정점의 약 5%) 거의 모든 재질을 버텍스 음영 처리로 대체합니다.
CSM 스크롤링: 계단식 그림자 맵 렌더링을 위한 가속 기술은 CSM을 스크롤하고 동적 개체와 정적 개체를 구별하여 CSM 렌더링을 최적화하는 그림자 최적화 기술을 설명합니다.
이전 프레임에서 변경된 형상이 식별될 수 있고, 빛의 방향이 프레임 전체에 걸쳐 상대적으로 안정적이며, 공간 쿼리의 결과는 그림자 렌더링과 동일한 프레임에서 사용될 수 있으며 형상은 작은 인스턴스로 나뉩니다. CSM 롤링 단계는 다음 그림으로 설명할 수 있습니다.

이전 프레임의 정적 형상을 캐시된 섀도우 맵에 저장합니다.
캐시된 그림자 맵을 스크롤하여 카메라 보기의 변경 사항과 일치시킵니다.
스크롤하는 동안 노출된 가장자리에 추가 정적 지오메트리를 렌더링합니다(예: 숫자 3 옆 섀도우 맵의 오른쪽 상단에 있는 원통). 그런 다음 캐시 영역(예: 숫자 3 옆 섀도우 맵의 왼쪽 상단에 있는 원)에 새로운 정적 지오메트리를 렌더링합니다.
(위 단계는 모두 영구 캐시 섀도우 맵에서 동작하며, 다음 단계는 임시 현재 프레임 섀도우 맵에서 동작합니다)
캐시된 섀도우 맵을 현재 프레임의 최종 섀도우 맵에 복사합니다.
비정적 형상을 현재 프레임의 최종 그림자 맵으로 렌더링합니다.
이제 카메라에 움직임이 없거나 거의 없다고 가정하면 4개의 주요 단계가 관련됩니다(아래 이미지에 번호가 매겨져 있음).

이전 프레임의 "정적" 형상을 캐시 맵에 저장합니다("정적" = t 시간(예: 5초) 동안 움직임이 없음). (1과 2)
매 프레임마다 캐시된 복사본으로 비정적 형상을 렌더링합니다. (3과 4)
그러나 이전 프레임의 섀도우 맵 캐시는 카메라가 움직이고, 카메라 FOV가 변경되고, "정적" 형상이 움직일 때 무효화됩니다. 1단계를 포함합니다.
해결 방법은 2단계(빨간색 원)의 새로운 정적 형상에 대한 것입니다.
캐시 영역에 새로운 "정적" 형상을 렌더링합니다.
"정적" 형상의 상태를 쿼리하고 현재 "정적" 쿼리 결과와 이전 "정적" 쿼리 결과를 구별합니다.
동적 폐색 시스템을 사용합니다.
이 프레임을 사용하려면 새 그림자 맵 버퍼의 복사본을 만듭니다. (3)
"동적" 형상을 임시 그림자 맵으로 렌더링합니다. (4)
이제 카메라가 많이(그러나 천천히) 움직인다고 가정하면 5개의 단계가 관련됩니다(아래 이미지에 번호가 매겨져 있음).

CSM 캐시에 삽입됨: 스크롤링 그림자 맵, 노출된 가장자리에 렌더링됨. (2, 3)
카메라 보기 변경 사항을 고려하기 위해 캐시된 그림자 맵을 스크롤합니다. (2)
이전 프레임의 샘플 그림자 텍스처입니다. (2)
스크롤 영역은 테두리(아래 그림의 흰색 영역)에 고정됩니다. (3)

- 카메라 이동은 3D이므로 가로 스크롤과 깊이 스크롤이 포함됩니다. (2)
측면 스크롤: 빛에 수직으로 이동합니다.
// input는 delta라이트(Light)좌표계 내에서 변환(Transform/Convert)의 UV。
float ScrolledDepth_LateralOnly(float3 input)
{
float2 uv = input.xy;
// 의 텍스처(Texture)탐색/조회(Find/Lookup)(포인트 샘플링)
return SampleShadow(uv);
}- 깊이 롤: 광선에 평행하게 이동합니다.
// input는 delta라이트(Light)좌표계 내에서 변환(Transform/Convert)의 UV。
float ScrolledDepth(float3 input)
{
float2 uv = input.xy;
// 뎁스 의 처리(Process). input.z는 라이트(Light)좌표계 내에서 의 뎁스 의 。
float depth_offset = input.z;
float old_depth = SampleShadow(uv);
// 의 뎁스 (뎁스 )
float new_depth = old_depth + depth_offset;
// 뎁스 。
return (old_depth < 1.0f) ? new_depth : 1.0;
}- 스크롤하는 동안 노출된 가장자리에 추가 정적 형상(오른쪽 위 빨간색 원통)을 렌더링합니다. (3)
롤링 영역은 플레이트(아래 얇은 OBB)로 구분됩니다.

- "정적" 형상에는 겹치는 경계 볼륨이 있습니다.

- 뷰에 대한 형상의 러프니스:

- 일부는 겹치는 볼륨이 많고(아래 그림 왼쪽), 일부는 겹치는 볼륨이 적고(아래 그림 오른쪽), 일부는 가장자리가 뚜렷하게 들쭉날쭉합니다(아래 그림의 중간).

캐시 영역에 새로운 "정적" 형상을 렌더링합니다. (3)
현재 프레임의 최종 그림자 맵으로 사용할 그림자 맵을 복제합니다. (4)
CSM의 스크롤에는 2, 3, 4가 포함되며 렌더링 효과는 다음과 같습니다.

요약하자면, 2D 비트맵처럼 스크롤하도록 CSM 캐시에 직접 추가하면 CSM에 대한 정적 형상 렌더링이 약 70% 줄어듭니다.
실시간 실제 기반 렌더링 및 단순한 물리 기반 Blinn-Phong 모델을 넘어 실시간 렌더링 분야의 PBR 이론, 종속 지식, 특성, 구현 및 최적화에 대해 자세히 설명합니다.
실시간 PBR은 다음 사항을 포함하여 현재 콘솔의 물리적 기반을 기반으로 전체 렌더링 파이프라인을 만듭니다.
물리 기반 셰이딩 모델. 물리학 기반 BRDF 모델
물리적 기반 조명. 물리적 기반 양, 필름 시뮬레이션(스펙트럼 기반 톤매핑).
물리 기반 카메라 시뮬레이션. 실제 카메라 시스템을 기반으로 한 렌즈 시뮬레이션.
물리 기반 조명에는 물리량을 사용해야 합니다.
- 색 공간을 수정하세요.
스펙트럼 영역(380nm – 1000nm)에서 필름 시뮬레이션(톤매핑)을 처리합니다.
실제 필름 소재, 노광, 현상, 복제, 인쇄, 영사를 기반으로 한 필름 데이터베이스입니다.
와트 기준.
다른 단위(럭스, 루멘, 색온도)는 엔진에서 와트로 변환됩니다.
- 광원 영역. 지연된 조명과 전방 조명, 금속 또는 광택 개체에 대한 이미지 기반 조명 및 유사 조명 크기 조정에는 더 이상 환경 맵 셰이더가 필요하지 않습니다.
물리 기반 카메라 시뮬레이션에는 실제 카메라 시스템이 필요합니다.
- 렌즈 데이터베이스 기반 광학 시뮬레이션:
진정한 보케 시뮬레이션.
렌즈 방정식을 기반으로 합니다. 실제 카메라 매개변수 및 렌즈, 초점 시뮬레이션.
조리개 시뮬레이션. 블레이드 수, 원형 조리개, 조리개 메커니즘.
비네팅. 배럴 비네팅, 광학 비네팅.
기타 광학 효과를 지원합니다.
물리적 기반 셰이딩 모델(구현되었거나 조사 중):
- 물리학 기반 Blinn-Phong.
등방성, 이방성, 스펙트럼.
브린 베크만.
아시크민.
레이어드 소재.
오렌-나야르(Oren-Nayar), 향상된 오렌-나야르(Oren-Nayar).
재귀반사 소재.
기타 특수재료. Marschner, 금속, 유리, 인쇄, NPR.
물리학 기반 Blinn-Phong:


또한 이 기사에서는 물리학 기반 IBL의 이론, 공식, 파생 및 구현을 자세히 분석합니다.


물리 기반 IBL 공식 도출 및 근사.


복사 환경 맵(REM) 생성 과정.


IBL 효과.


미러 AO 및 효과 비교.

다양한 디퓨즈 모델의 효과 및 성능 비교.
Dust 514의 실시간 전역 조명 및 반사에서는 특수 하이트 필드 레이 트레이싱을 사용하여 간접 조명 및 반사 계산을 완료하는 방법을 설명합니다. 다음 세 이미지는 왼쪽에서 오른쪽으로 원래 환경, 이상적인 컨벌루션 환경 및 실시간 근사치를 보여줍니다.

이상적인 간접 항은 앞에서 설명한 Lambertian 컨볼루션을 사용하여 오프라인으로 계산되며 계산에는 몇 초가 걸립니다. 오른쪽에는 픽셀 셰이더에서 실시간으로 평가된 원뿔 궤적 근사치가 있습니다. 전환은 표면 노멀의 Z/up 구성 요소를 기반으로 하늘 색상과 지상 색상 간의 선형 혼합입니다. 기본 색상은 큰 밉 오프셋으로 지상 텍스처를 샘플링하여 얻습니다. 더 많은 사이클을 사용하면 더 나은 근사치를 얻을 수 있다는 것은 의심의 여지가 없습니다.
어쨌든 요점은 공간의 모든 지점과 표면의 노멀 방향에 대해 간접적인 용어를 제공하여 평평한 지평선과 스카이 큐브로 근사할 수 있는 모든 환경에 대한 솔루션을 제공하는 방법이 있다는 것입니다.
하이트 필드를 레이 트레이싱할 때 광선은 광선 원점 아래의 높이 필드를 샘플링하여 높이가 결정되는 수평 평면과 교차합니다. (아래 사진)

또 다른 접근 방식은 위쪽 및 아래쪽 추적에 별도의 바이어스 광선을 사용하여 수평 레이 트레이싱 결과가 표시되지 않도록 하는 것입니다.

단일 샘플 레이 트레이싱 단계는 대부분의 경우 잘 작동하지만 아래 단면과 같은 일부 경우에는 완전히 실패합니다. 검은색 직사각형은 다리와 같은 객체를 나타냅니다. 주황색 선은 장면이 아래에서 렌더링될 때 생성되는 높이 필드입니다. 왼쪽 하단 모서리에 있는 화살표는 아래를 지나가는 차량 상단의 반사와 같은 일부 샘플 광선을 나타냅니다. 문제는 광선의 원점이 지붕 아래로 전파됨에 따라 교차점이 불연속적으로 변하고, 이 차량 위에서는 다리 가장자리 아래 반사에 눈에 띄는 불연속성이 있다는 것입니다. 부정확한 교차점을 합리적으로 반영하는 것은 여전히 가능하지만 불연속성은 매우 명백하고 명백히 잘못된 것입니다.

해결책은 높이에 급격한 변화가 없도록 높이 필드에 후처리를 적용하는 것입니다. 그러면 아래 이미지에 표시된 단면이 생성됩니다. 즉, 반사에는 불연속성이 없으므로 1단계 레이 트레이싱 근사의 이점을 통해 보다 합리적인 반사를 얻을 수 있습니다. 하이트 필드 프로세스는 점진적으로 수행됩니다. 높이 필드가 여기에 표시된 결과로 수렴하려면 여러 번의 패스가 필요하며 이것이 작동하는 방식입니다.

높이 필드 개선 프로세스:

전체 추적 프로세스: 위/아래로 편향된 광선 벡터 계산, 광선 원점에서 압축된 높이 필드 샘플링, 각 레이어의 교차점 계산, 각 레이어의 밉 편차 계산, 4개 레이어 텍스처 및 하늘 텍스처 샘플링, 결과를 합성하여 위쪽 및 아래쪽 색상(하늘, 천장, 아래 다리, 바닥, 위 다리)을 생성하고, 쿼리 광선 방향을 기반으로 위/아래 색상을 혼합합니다.
개선: 시간 분할 계층 업데이트, 그림자, 가장자리 페이드, 양자화된 모션에 CSM을 재사용합니다.
요약하면 범용 간접 항목 제공, 가변 블러가 있는 범용 반사 항목 제공, 빠르며 임의의 복잡한 장면을 지원하지 않고 일반적으로 벽 및 수직 표면에 대처할 수 없으며 동적 객체는 간접 또는 반사에 기여하지 않으며 반사 품질이 제한됩니다.
삼중 버퍼링의 목표는 GPU가 페이지 전환이 발생할 때까지 기다리는 것을 멈추지 않고 전환이 vblank에서 발생하므로 찢어짐이 발생하지 않는 것입니다.
두 개의 Full HD 버퍼 A와 B 사이의 증폭 및 누적 스텝 핑퐁. 30fps로 실행되고 프레임 끝에서만 Full HD 버퍼에 쓰기 때문에 쓰기 사이에 제한 없이 최소 16.6ms가 필요합니다. 버퍼 중 하나에 쓰기를 마친 후에는 다음 vblank에 대한 롤오버를 요청하세요. 일반적인 이벤트 과정에서는 기본 720p 렌더링 중 어느 시점에서 발생하며, 다음 프레임에서 확대를 시작할 때가 되면 반전이 발생할 것이라고 확신할 수 있습니다.
메뉴 및 로딩 화면과 같이 RSX가 할 일이 거의 없는 상황이 있기 때문에 이러한 지연을 적용하려면 울타리가 필요합니다. 3개의 720p 버퍼에서 2개의 1080p 버퍼와 1개의 720p 버퍼로 이동하면 필요한 추가 메모리는 약 9MB입니다.

축적 단계: 현재 처리 중인 픽셀이 정적이라고 판단되면 처리 중인 고해상도 픽셀 영역에 속하는 저해상도 샘플(아래 이미지의 빨간색 점)을 모두 찾아야 합니다. 있는 경우 이를 실행 평균 색상으로 혼합하고, 그렇지 않은 경우 현재 픽셀을 변경하지 않고 유지합니다.

누적 효과 비교:


[Rock-Solid Shading](http://advances.realtimerendering.com/s2012/Ubisoft/Rock-Solid Shading.pdf)에서는 PBR의 기본 이론을 설명하고, 셰이딩 왜곡으로 이어지는 문제를 분석하고, 소재의 실제 신뢰성을 높이는 방법을 설명합니다.
무언가를 보기 좋게 만드는 것은 안정적이고 깨끗하며 앨리어스가 없고 표현이 풍부한 머티리얼 유형과 단순하고 직관적인 모델입니다. 주요 도구: Blinn-Phong, Banks, Ashikhmin-Shirley, 양식화 여부에 관계없이 대부분의 자료는 간단한 BRDF로 표현할 수 있습니다.
현재 셰이딩 모델의 문제: 객체가 너무 밝습니다. 앨리어싱: 샘플링 문제로 인해 법선이 갑자기 밝은 점과 반짝임이 되어 HDR 블루밍 중에 왜곡이 발생할 수 있습니다. 하이라이트를 완전히 놓칠 수 있으므로 높은 반사성 지수를 사용할 수 없습니다. 선명한 하이라이트를 얻기 위해 환경 맵을 사용하여 사양을 확인하는 것이 일반적입니다.
오프라인 렌더링이 위의 문제를 일으키지 않는 이유는 무엇입니까? 샘플 속도는 종종 잠겨 있습니다. REYES와 같이 잘못되었더라도 샘플은 프레임별로 이루어지므로 방정식에서 대부분의 시간 앨리어싱이 제거됩니다. 모든 것이 오버샘플링되고, 픽셀당 100개 샘플이 흔하며, 무한대 샘플링은 대부분의 문제가 사라집니다. 해결되었나요? 아니요, 하지만 무차별 대입으로 인해 속도가 느려집니다.
누락 이유: 불안정성 - 해상도가 대규모 효과에 큰 영향을 미치고, 앨리어싱 - 시간과 공간, 표현력 부족 - 광범위한 기능을 사용할 수 없음. Blinn-Phong을 올바르게 구현하는 방법은 무엇입니까? REYES와 같이 텍스처 기반 조명 접근 방식을 수행할 수 있습니까? 사실적으로 표현되는 유사한 BRDF를 찾을 수 있습니까?
LEAN 매핑 메커니즘. LEAN(Linear Efficient Anti-aliased Normal Mapping)은 Sid Meier의 Civilization V에서 사용되었으며 향후 모든 자산 제작에 배포되는 선형 효율적인 앤티앨리어싱 노멀 맵입니다. 이점: 시간적 안정성, 해상도 안정성, 높은 반사 지수를 사용할 수 있습니다(예: 10000+). Blinn-Phong 콘텐츠는 쉽게 변환될 수 있으며 자동 이방성입니다.
범프 맵의 노멀 N = (N.x, N.y, N.z)이 주어지면 다른 맵 M을 만듭니다: M = (B.x^2, B.x*B.y, B.y^2), 여기서 B = (N.x/N.z,N.y/N.z). 중복된 데이터가 아니며 이러한 용어의 선형 필터링 버전이 필요합니다!

5개 채널을 저장합니다: X, Y 및 중앙 범프의 오프셋(8비트 가능)
Blinn Phong의 초기화 내용:
블린퐁(Blinn-Phong)은 얼마나 가깝나요? 저전력(예: < 16)의 경우 LEAN 맵은 Blinn-Phong과 다르게 반응하므로 일부 항목을 다시 조정해야 할 수도 있습니다.

깔끔한 매핑: 5개 값은 비용이 많이 들 수 있음: 이방성 수정, 삭제:

3개의 값을 저장합니다: X, Y, (X^2 + Y^2)/2, (X^2 + Y^2)/2만 높은 정밀도로 저장해야 합니다.
지나치게 밝은 하이라이트 문제의 경우 하이라이트는 최소화 필터에서 더 안정적입니다. 이전에 제기된 앨리어싱 문제에는 앨리어싱이 없습니다.
목표를 달성하세요. 안정적: 렌더링 해상도가 대규모 효과에 영향을 주지 않습니다. 앤티앨리어싱: 선형 하드웨어 필터가 제대로 작동하고 표현력이 뛰어납니다. 높은 전력을 사용할 수 있으며 이방성이 지원됩니다. 또한 몇 가지 문제도 있습니다. Blinn-Phong 분기의 저전력에서는 저장 공간 요구 사항이 더 높습니다.
다음으로 셰이더 앨리어싱 익명(Shader Aliasing Anonymous)에 대해 설명하겠습니다. 옵션: Texture Space Shading, 핵심 아이디어는 MIP 조명입니다! 하지만 비용이 많이 들죠. 가상 텍스처 캐시를 사용하시나요? 옵션 1: 피팅, 핵심 아이디어는 정상, 러프니스, 반사도, 느림, 취약함, 불연속성과 같은 가장 적합한 매개변수를 찾는 것입니다. 옵션 2: 직접 분산 추정, 핵심 아이디어는 분산 -> 새로운 거칠기를 추정하는 것입니다.





베이킹 변화 프로세스: 각 MIP에 대해:
Bilinear에 작은 필터를 적용합니다.
분산을 계산합니다.
결과 저장:
직접 또는 광택 맵을 조정합니다.
- 편집을 허용하시겠습니까?

광택 조정: 다양함...미러 AA "모든 곳"!
동적 반영: MIP 생성, MIP 오프셋 조회 또는 DX11: 가변 가우스? 이미지 공간 수집?
복셀 콘 추적 [Crassin 11]
반사게시판 [Mittring11]
반사 폐색?
옵션: 사전 필터링(LEAN), 더 좋음: 더 정확한 결과, 이방성 효과.

단점은 메모리, 추가 셰이딩 비용, 탄젠트 공간입니다.
LEAN의 이변량 정규 분포:

시각화 다이어그램:

LEAN의 메모리, 베이킹, Toksvig... 이중선형 시뮬레이션은 여전히 중요합니다! 공분산 행렬 저장: [Σx, Σ y, Σz]?

정확성 문제가 있을 수 있습니다. 두 가지 광택 값을 저장하도록 변경할 수 있습니다.

BC5 또는 DXT5를 사용할 수 있으며 선택적으로 종속성을 저장할 수 있습니다:
LEAN 외에도 상세한 노멀 맵, 기하학적 개체, 확산 반사 및 환경 맵도 포함됩니다.
그중에서도 기하학 AA는 또 다른 변화의 원인입니다!
아이디어 1 - 사전 필터 기하학 노멀: 확장, MIP 생성, Toksvig 사용, 아틀라스 필요!

아이디어 2 - 픽셀 쿼드 메시지 전달 [Penner11A], 이웃 액세스 ⇒ 평균 ⇒ 분산, 평균 코드:
float2 dir = 0.5 - frac(vpos*0.5 - 0.25)*2;
float3 n0 = N;
float3 n1 = ddx_fine(n0)*dir.x;
float3 n2 = ddy_fine(n0)*dir.y;
float3 n3 = ddy_fine(n1)*dir.y;
float3 nn = n0 + n1 + n2 + n3;아이디어 3 - Kaplanyan 및 Valient의 제안: 일반 원뿔(곡률)과 반사 로브 원뿔을 결합하고 사양 출력을 원뿔 각도로 변환하고 곡률 각도를 추가합니다.
float3 dN = fwidth(N);
float3 new_normal = normalize(N + dN);
float curvature = acos(dot(new_normal, N))/(pi*0.5);새로운 힘으로 다시 변환하여 실전에 투입되었습니다! 최적화된 코드:
float3 dN = fwidth(N);
float3 new_normal = normalize(N + dN);
float curvature = sqrt(1 - dot(new_normal, N));
float angle = 4.11893/sqrt(power) + curvature;
power = 16.9656/(angle*angle);비슷한 결과. 다음은 다양한 방법의 착색 효과를 비교한 것입니다.

전체 디퓨즈율 적분 방정식은 다음과 같기 때문에 현재 디퓨즈율에 오류가 있습니다.

,을(를) 활용하여 디퓨즈(Diffuse)는 :

즉,

확산 적분에 대한 해법: 노멀 분산 ⇒ 원뿔, 평균 노멀(Na) 주위의 노멀 원뿔의 조명 적분, 원뿔 각도 공식: cos(θ) = 2*length(Na) - 1

적분은 사전 적분된 피부 음영 [Penner11B]처럼 사전 계산될 수 있습니다.
float len = length(Na);
float3 N = Na/len;
tex2D(LUT, float2(dot(N, L)*0.5 + 0.5, len));샘플 결과:

LUT를 축소합니다. 중요 영역은 0~25도입니다(아래 그림).

LUT를 피하고 곡선 피팅(

float DiffuseAA(float3 N, float3 L)
{
float a = dot(N, L);
float w = max(length(N), 0.95);
float x = sqrt(1.0 - w);
float x0 = 0.373837*a;
float x1 = 0.66874*x;
float n = x0 + x1;
return w*((abs(x0) <= x1) ? n*n/x : saturate(a));
}
18개의 명령(fxc) 정도는 너무 적합해서 대략적인 근사치를 얻을 수 있다고 할 수 있습니다. 그러나 Toksvig와 유사한 문제가 있습니다: 노멀 압축, 사전 필터링된 길이/분산 저장.

또한 LEAN은 환경 다이어그램에도 사용할 수 있습니다.

Far Cry 3의 조명 및 재료 보정에서는 Ubisoft의 물리 기반 조명 모델과 Far Cry 3 최적화에 대해 설명합니다.
물체 자체에 더 가까운 기본 색상(알베도)을 얻기 위해 Far Cry 3에서는 디지털 카메라를 사용하여 물체를 스캔한 다음 조명과 렌즈 왜곡을 제거하여 보다 물리적인 알베도 맵을 얻습니다.

확산 알베도를 캡처할 때 X-Rite에서 알려진 sRGB 값의 24개 색상 패치로 생성된 Macbeth ColorChecker를 참조로 사용하십시오.

ColorChecker 사진 자료 옆에는 ColorChecker 블록을 사용하여 변형을 찾기 위해 조명이 일관되어야 합니다.

변환에는 Affine 변환과 다항 변환의 두 가지 유형이 있습니다. 아핀 변환의 장점은 채널 간의 누화를 제거하는 것이고 단점은 선형 변환입니다. 다항식 변환은 정확한 조정 수준이라는 장점이 있지만 채널 독립성의 단점이 있습니다.
색상 교정 도구: Photoshop 스크립트에 의해 실행되는 명령줄 도구는 xyY 색상 공간에서 실행되며 다음 변환을 적용합니다[Malin11]:

아래는 수정 전(왼쪽)과 수정 후(오른쪽)를 비교한 것입니다.

하늘의 음영 처리 모델은 CIE 모델을 채택합니다.

조명 모델도 Cook-Torrance이며, 여기서 D 항은 다음과 같습니다.

F 항에는 Schlick 근사와 구형 가우스 근사의 두 가지 유형이 있습니다.

가시성 항목:

그런 다음 G 용어가 단순화됩니다.

반사광 반사의 앨리어싱을 줄이고 세부 정보를 보존하기 위해 Toksvig의 공식을 사용하여 반사광 강도를 조정합니다.

이 스케일링 데이터를 텍스처에 저장하고 이상적으로는 이를 사용하여 광택 맵을 조정합니다. 추가 텍스처를 추가하는 데 드는 비용이 너무 높으며 모든 셰이더가 글로스 맵을 사용하는 것은 아니며 Toksvig 맵을 기존 글로스 맵과 결합할 방법이 없습니다. DXT5 압축 노멀 맵에는 무료 채널이 있습니다. 아티스트는 노멀 맵의 알파 채널에 광택을 그리고 R 채널에 Toksvig와 결합된 광택을 저장합니다.

법선의 y 구성요소 압축이 영향을 받습니다.

글로스 맵은 선택 사항이며, 존재하는 경우 Toksvig와 결합되고, 그렇지 않은 경우 Toksvig는 단일 값으로 평균화됩니다.

Deferred Radiance Transfer Volumes: Far Cry 3의 글로벌 일루미네이션에서는 Far Cry 3에서 사용된 동적 글로벌 일루미네이션의 근사치를 자세히 설명하며 두 부분으로 나누어서 첫 번째는 이론적 개요와 오프라인 사전 계산, 두 번째는 실시간 렌더링 구현 및 셰이딩 세부 정보입니다. 희박한 양의 복사 전달 프로브를 사용하고 각 프로브에 구면 고조파 계수 매트릭스를 저장하면 프로브가 즉시 재조명될 수 있으므로 총구 섬광 및 폭발과 같은 국부적인 조명뿐만 아니라 하루 중 변화하는 시간에 조명을 지원할 수 있습니다. 재조명 프로브를 사용한 셰이딩은 화면 공간의 GPU에서 수행됩니다. 하이브리드 CPU/GPU 구현은 시스템이 현재 세대 콘솔에서 원활하게 실행되도록 하고 메모리 및 성능 효율성을 보장하는 데 사용되며 시스템 내부를 설명하는 코드 조각은 물론 자세한 성능 통계도 제공합니다.
지연된 방사 조도 전송 볼륨은 대략적인 전역 조명, 경량, 호스트 친화적, 실시간 재조명, 하이브리드 CPU/GPU 기능을 갖추고 있습니다. 그중 글로벌 일루미네이션은 태양과 하늘로부터의 반사와 하늘로부터의 직접적인 빛을 지원하는 저주파 복사 복사 전송입니다.
실시간 재조명은 태양/하늘 색상으로 업데이트되는 전역 조명으로, 아티스트의 직접적인 피드백을 통해 주간 주기 시간을 지원합니다.

전체 시스템 개요.
오프라인에서는 프로브가 세계에 배치되고 이에 대한 복사 전달이 미리 계산됩니다. 이 프로세스는 베이킹이라고도 합니다. 게임에서는 조명 환경이 바뀔 때마다 감지기가 실시간으로 다시 켜집니다. 새로운 방사조도 값은 동적으로 생성되어 많은 체적 텍스처에 삽입된 다음 GPU에서 화면 공간의 모든 것을 음영 처리하는 데 사용됩니다. 프로브가 구워지면 복사 전달과 하늘 가시성이 미리 계산됩니다.

PC를 위한 로컬 복사휘도 전송: 광원이 프로브와 동일한 위치에 있다고 가정하고 동적 광원의 전역 조명으로 각 프로브 위치에 백색광 PRT를 저장합니다.

실시간 재조명: 태양과 하늘에 의해 구동되는 조명이 아티스트가 만든 그라디언트인 2차 SH에 투사됩니다.

각 프로브의 빛 기여도가 계산되고 그 결과는 색상/강도 배열입니다. 각 기본 방향에 대해 하나의 색상이 있으며 더 나은 정확도를 위해 더 많은 기본 방향을 추가할 수 있습니다.
볼륨 텍스처링: 픽셀 단위로 수행할 수 있는 GPU 고속 필터링으로 대형 개체에 적합합니다. 1인칭 카메라에 연결된 복셀은 4개의 기본 강도, 96x96x16 RGBA이며 약 7ms 내에 완전히 업데이트되어 5 SPUS를 차지합니다. 시간 상각: 데이터를 사용할 수 없는 항목만 업데이트하고 기존 조각이 오프셋되지 않도록 래핑을 사용합니다.

볼륨 텍스처 래핑: 서라운드 샘플러 상태는 비용이 많이 들고, 올바르게 필터링된 반복 경계를 위해 frac()를 사용하여 래핑을 시뮬레이션합니다.

환경조명은 실내, 장거리 환경 등의 요소를 고려합니다.
다음 그림은 PS3 구현의 개요입니다.

Practical Clustered Shading에서는 클러스터 쉐이딩의 특징과 구현을 소개합니다.
Clustered Shading은 Olsson, Billeter, Assarsson 등이 HPG 2012 논문 Clustered Deferred and Forward Shading에서 제안한 블록 셰이딩을 확장하는 기술입니다. 실시간, 우수한 견고성이 특징이며, 많은 광원을 지원하고, 뷰와의 상관 관계가 낮으며, 노이즈가 있는 깊이 분포를 처리할 수 있습니다.
클러스터된 음영 처리로 가져온 대규모 광원은 전역 조명, 복잡한 광원 유형(예: 표면 조명, 볼륨 조명), 아티스트의 제약이 없는 조명 특수 효과 등을 가져올 수 있습니다. 다음 샘플 시나리오를 가정합니다.

타일 음영처리, 지연 또는 전달의 경우 단순하고 빠른 경우에 따라 2D 타일이 지원됩니다.

Tiled Shading의 가장 큰 문제점은 게임이 3D이고 2D 평면에서 블록으로 분할되어 있기 때문에 더 먼 광원이 앞에 있는 물체에 의해 차단되더라도 단일 블록이 변경된 블록의 깊이에 있는 모든 광원과 교차하게 된다는 것입니다! 즉, 타일은 2D이고, 기하학 샘플과 조각/픽셀은 3D이고, 광학 밀도는 3D이고, 뷰에 따라 다르며, 예측할 수 없는 셰이딩 시간입니다.
Clustered Shading의 핵심 아이디어는 3차원을 추가하는 것인데, 이는 깊이 방향 = 클러스터링으로 블록으로 분할되며 3차원(예: 노멀)보다 클 수도 있습니다.

블록과 클러스터의 공간적 분포는 다음과 같습니다.


클러스터 색상 지정 단계는 다음과 같습니다.
G-버퍼를 래스터라이제이션합니다. 앞으로: pre-z 채널.
클러스터 할당.
클러스터링 키: $ck = (i, j, k) $, i, j = 2D 블록 ID의 정수 튜플, 즉 gl_FragCoord.xy,

- 독특한 클러스터를 찾아보세요.
전체 화면 채널, 클러스터링을 사용한 레이블, 깊이 읽기, ck 계산, 그리드의 셀을 1로 설정. 앞으로: 부작용이 있는 형상 채널.

0이 아닌 클러스터링 값을 간소화하고 비어 있지 않은 클러스터, 병렬 접두사 및 컴퓨팅 셰이더 목록을 가져옵니다.

- 클러스터에 조명과 그림자를 할당합니다.
많은 클러스터 및 조명, 계층적 접근 방식: 광원 계층, 32방향 트리(GPU의 SIMD와 일치), GPU에서 동적으로 재구성, BV 테스트를 통해 각 클러스터의 광원 트리를 탐색합니다.
- 음영 처리된 뷰 샘플, 지연: 전체 화면 통과, 앞으로: 형상 통과.
다음은 나무와 10,000개 이상의 광원이 있는 Crytek Sponza 장면의 다양한 방법에 대한 성능 비교 차트입니다.

위 이미지는 매우 간단한 픽셀 셰이더를 사용하더라도 타일식 셰이딩이 셰이딩 시간에 의해 지배된다는 것을 보여줍니다. 즉, 타일 속도를 높여도 결과가 크게 변하지 않는다는 의미입니다. 반면, 클러스터링된 셰이딩은 셰이딩과 알고리즘의 다른 부분 사이에서 균형이 더 잘 맞습니다. 더 복잡한 노멀 기반 컬링의 세 가지 변형도 표시되지만, 더 복잡한 컬링과 더 많은 클러스터의 비용이 셰이딩 비용 절감보다 더 크기 때문에 테스트 구현에서는 성과를 거두지 못했습니다. 더 비싼 셰이딩과 더 나은 클러스터링 및 컬링 구현을 사용하면 여전히 그만한 가치가 있을 수 있습니다.
타일드 포워드 셰이딩은 투명한 물체에 사용할 수 있습니다. 문제는 뷰 의존성, 2차원으로의 저하, 전체 화면 불연속성입니다!

Clustered Forward Shading은 사전 형상 패스에서 수행되어 프래그먼트 셰이더의 부작용으로 사용된 클러스터링을 표시하고 그리드의 셀을 1로 설정합니다.

Clustered Forward Shading의 성능 데이터는 다음과 같습니다.

요약하자면, 클러스터링된 셰이딩은 고성능, 낮은 뷰 종속성, 우수한 최악의 경우 성능, 완전 동적, 투명성 지원, 정방향 또는 지연 지원 또는 둘 다를 지원합니다. 잠재적인 이점은 음영처리를 위한 샘플의 빠른 복셀화, 원뿔 추적을 위한 시작점, 근사 음영처리, 적응형 음영처리 및 기타 용도를 포함합니다.
Frostbite를 물리 기반 렌더링 3.0으로 전환하는 과정에서는 Frostbite 엔진이 PBR 관리를 어떻게 개선했는지 설명하고 이론적 기반, 관련 기술, 파생, 최적화 및 적용을 체계적으로 분류합니다. PBR의 범위에는 조명, 재료, 카메라가 포함됩니다(이전에는 조명과 재료에만 중점을 두었습니다).

외관 유형의 80%가 표준 재료입니다. 스페큘러 반사에는 GGX NDF를 적용한 마이크로패싯 모델을 사용하고, 디퓨즈에는 디즈니 모델을 사용하며 기타 재료 유형에는 지하 재료 및 단층 코팅 재료가 포함됩니다. 스페큘러 반사의 공식은 다음과 같습니다.

아래 그림은 GGX-Smith와 Height-Corlated Smith의 G 항목 비교 효과를 보여줍니다.

위 이미지는 차이가 작지만 높은 러프니스 값에서 눈에 띄는 것을 보여줍니다(오른쪽).

디퓨즈의 경우 Lambert는 더 이상 사용되지 않으며 Disney 디퓨즈로 대체됩니다. 왜냐하면 후자는 디퓨즈와 스페큘러 반사 사이에 결합된 거칠기와 역반사를 사용하기 때문입니다.

확산 대비는 아래에 나와 있습니다. 낮은 거칠기에서는 약간 더 어둡고 높은 거칠기에서는 더 밝아 미묘하지만 차이를 만들 수 있습니다.

에너지가 보존되지 않는다는 점에서 원래 디즈니 확산 항에는 문제가 있었습니다. 어떤 경우에는 반사된 빛이 입사된 빛보다 높을 수 있었습니다. Frostbite는 반사 및 확산 항이 추가될 때 반구 방향의 반사율이 1 미만이 되도록 간단한 선형 보정을 적용합니다.


스페큘러 반사 및 디퓨즈의 입력 값에 대해 Frostbite는 금속과 비금속을 분리하여 자산 생성을 더 쉽게 만드는 Burley의 근사 방법을 다시 한 번 사용합니다.

Frostbite는 아티스트에게 흰색의 부드러움이 더 직관적이기 때문에 러프니스 대신 "부드러움"을 보여 주기로 선택했습니다. 지각적 선형성을 얻기 위해 다양한 리매핑 기능도 시도하였고, 최종적으로 Burley의 방법을 다시 사용하여 거칠기를 제곱하였다.


조명 측면에서 조명 일관성을 위해 노력합니다. 모든 BRDF는 모든 광원 유형과 올바르게 통합되어야 하고, 모든 광원은 직접 및 간접 조명을 관리해야 하며, 모든 조명이 올바르게 결합되고(SSR/네이티브 IBL/...), 모든 광원이 서로 올바른 비율을 가져야 합니다. 조명을 위한 많은 단위와 기준 시스템이 있습니다. 일반적인 측광 단위 시스템은 다음과 같습니다.

Frostbite는 위의 네 가지 유형의 장치를 사용하며 해당 응용 시나리오는 다음과 같습니다.

Frostbite는 구형, 원판, 직사각형, 튜브의 네 가지 모양을 지원합니다. 각 광원은 더 간단한 버전을 가질 수 있지만 점과 점만 더 자주 사용하고 비용이 적게 들기 때문에 점과 점만 정시 광선 경로를 사용합니다.

다음은 준광, 포토메트릭 조명, 영역 조명에 대한 설명입니다.




IBL의 경우 근거리 라이트 프로브와 장거리 라이트 프로브에 중점을 둡니다. 단위, 광원 및 공식은 다음과 같습니다.


런타임 시 표면의 거울 방향을 사용하는 대신 약간 오프셋된 주요 방향(아래 그림의 하늘색 화살표)이 사용되어 적분 근사의 정확도를 향상시키는 데 도움이 됩니다.


카메라의 경우 장면 밝기를 픽셀 값, 조리개, 감광 요소, 렌즈, 셔터 등으로 변환하는 것과 같은 요소를 포함하여 물리 기반 시뮬레이션이 여전히 고려됩니다.

센서에 도달하는 장면의 밝기는 노출에 따라 결정되며, 노출은 픽셀 값으로 변환됩니다.

PBR로 전환하는 단계:
표준자료 + 관찰자 우선 + 핵심예술가 육성
PBR/비PBR 병렬성, 자동 변환.
PBR + 검증 도구를 게임팀에 홍보하세요.
Light Linked List를 통한 실시간 조명에서는 광원 연결 리스트를 사용하여 대규모 광원을 구현하고 최적화하는 기술을 설명합니다. 올바른 반투명도 순서로 조명 효과를 얻으려면 **Light Linked List(LLL)**를 사용하세요.

Light Linked List를 사용하기 전(왼쪽)과 후(오른쪽) 비교.
다음 구조를 사용하여 광원을 픽셀별 연결 목록에 저장합니다.
struct LightFragmentLink
{
float m_LightDepthMax; // 라이트(Light)뎁스
float m_LightDepthMin; // 라이트(Light)뎁스
int m_LightIndex; // 라이트(Light)
uint m_Next; // 개 라이트(Light)
};
// 압축/패킹(Packing)
struct LightFragmentLink
{
uint m_DepthInfo; // 뎁스 정보
uint m_IndexNext; // 개 라이트(Light)
};낮은 해상도가 더 좋습니다: 1/4, 8분의 1 등... 메모리 소비: 8분의 1 해상도에 대한 4개의 버퍼: 2 RWByteAddressBuffer, 1 RWStructuredBuffer, 1 깊이 버퍼(선택 사항), 평균 사전 할당된 픽셀당 40개의 조명. 총 비용: 900P: 약 7.25megs, 1080P: 약 10.15megs.

Insomniac 엔진의 렌더링 프로세스는 다음과 같습니다.

연결된 목록을 채우는 데 소요되는 소비는 다음과 같습니다.

LLL의 깊이 버퍼: 더 작은 깊이 버퍼를 생성하고, 보수적인 깊이 선택을 사용하고, GatherRed를 사용합니다.
LLL 쉐이딩 단계: 소프트웨어 깊이 테스트, 최소 및 최대 깊이 획득, LLL 조각 할당.
LLL의 깊이 테스트: 앞면은 깊이 테스트를 통과하고 뒷면은 깊이 테스트에 실패하며 하드웨어 깊이 컬링이 비활성화됩니다.

// 프론트페이스 .
// 만약 프론트페이스 Z,.
if((pface = true) && (light_depth > depth_buffer))
{
return;
}두 깊이를 모두 통과하는 경우 어떤 깊이가 우선합니까? 경계 RWByteAddressBuffer, 인코딩 깊이 + ID(16비트 ID, 16비트 깊이),
uint new_bounds_info = (light_index << 16) | f32tof16(light_depth);InterlockedExchange를 사용하여 이전 경계 값과 새 경계 값을 교환합니다.

RWStructuredBuffer를 사용하여 다음을 저장합니다.
struct LightFragmentLink
{
uint m_DepthInfo; // 뎁스 정보 ,는 뎁스 ,는 뎁스 。
uint m_IndexNext; // 개 라이트(Light)。
};
RWStructuredBuffer<LightFragmentLink> g_LightFragmentLinkedBuffer;
// 추가(Add)현재(Current)의
// 할당(Allocate).
uint new_lll_index = g_LightFragmentLinkedBuffer.IncrementCounter();
//
if(new_lll_index >= g_VP_LLLMaxCount)
{
return;
}
// 패딩/채우기 라이트(Light)의 저장(Save)。
// 출력
LightFragmentLink element;
element.m_DepthInfo = (light_depth_min << 16) | light_depth_max;
element.m_IndexNext = (light_index << 24) | (prev_lll_index & 0xFFFFFF);
// 저장(Store)라이트(Light)테이블 정보
g_LightFragmentLinkedBuffer[new_lll_index] = element;조명 계산 단계: 전체 화면 사각형 그리기, LLL 액세스, 광원 적용. LLL에 액세스할 때 첫 번째 링크 요소 오프셋을 가져옵니다. 첫 번째 링크 요소는 하위 24비트로 인코딩됩니다.
uint src_index = LLLIndexFromScreenUVs(screen_uvs);
unit first_offset = g_LightStartOffsetView[src_index];
// 개
uint elemen_index = (first_offset & 0xFFFFFF);조명 루프 시작: 0xFFFFFF와 같은 잘못된 요소 인덱스입니다.
while(element_index != 0xFFFFFF)
{
LightFragmentLink element = g_LightFragmentLinkedView[element_index];
element_indx = (element.m_IndexNext & 0xFFFFFF);
}광원의 깊이를 비교하여 광원의 최소 및 최대 깊이를 디코딩합니다.
// 라이트(Light)
float light_depth_max = f16tof32(element.m_DepthInfo >> 0);
float light_depth_min = f16tof32(element.m_DepthInfo >> 16);
// 실행(Execute)뎁스 검사/감지(Detect)
if((l_depth > light_depth_max) || (l_depth < light_depth_min))
{
continue;
}
// 페치/가져오기(Fetch)의 정보
uint light_index = (element.m_IndexNext >> 24);
GPULightEnv light_env = g_LinkedLightsEnvs[light_index];
switch(light_env.m_LightType)
{
// ......
}그림자의 경우 텍스처 배열을 사용하고 하위 영역을 할당합니다.

Quantum Break의 다중 규모 전역 조명은 대규모 조명 및 화면 공간 조명을 포함하여 Quantum Break 게임의 다중 규모 전역 조명을 보여줍니다.
기사에 언급된 가능한 전역 조명 솔루션은 다음과 같습니다.
- 동적 방법:
가상 포인트 라이트(VPL) [Keller97]
빛 전파량 [Kaplaynan10]
복셀 콘 트레이싱 [Crassin11]
디스턴스 필드 추적 [Wright15]
그리드 기반 사전 계산:
미리 계산된 복사에너지 전달(PRT) [Sloan02]
구형 조화 라이트 맵
그리드 없는 사전 계산:
방사량 [Greger98]
이 기사에서 비교한 후 Irradiance Volumes가 선택되었습니다.

조사량 원리의 개략도.
전역 조명 볼륨의 장점은 UV가 없다는 점이며 이는 LOD 모델 및 체적 조명에 적합합니다. 동적 객체와 일치하지만 데이터 양이 너무 많아 미러에는 적합하지 않습니다. 하이브리드 반사 프로브의 예는 다음과 같습니다.




프로브를 자동으로 배치하여 가시 표면적을 최대화하고 지면까지의 거리를 최소화하며 K개의 최적 프로브 위치를 선택합니다.

전역 조명 데이터(예: 반사 프로브 아틀라스)를 저장하기 위해 사용 가능한 솔루션은 다음과 같습니다.
GPU 볼륨 텍스처: 압축으로 인해 기본 보간을 사용할 수 없습니다.
GPU 희소 텍스처: 세분화된 트리 구조의 경우 페이지가 너무 커서 향후 게임이 대상으로 하는 플랫폼에서 사용하지 못할 수 있습니다.
적응형 볼륨 데이터 구조는 다음과 같습니다.
방사량 [Greger98, Tatarchuk05]
GigaVoxels [Crassin09]
희소 복셀 옥트리 [Laine and Karras 2010]
사면체화(예: [Cupisz12], [Bentley14], [Valient14])
희소 복셀 DAG [Kämpe13]
VDB 열기 [Museth13]
적응형 복셀 트리: 암시적 공간 분할, 분기 계수 64, 다중 규모 데이터.

복셀 트리 구조:

트리 순회:

복셀 트리 시각화:

원활한 보간:

이 기사의 SSAO는 LSAO(Line-Sweep Ambient Obscurance)[Timonen2013]를 기반으로 하며 LSAO는 가장 많이 기여하는 폐색체를 찾습니다.

긴 단계(~10px)와 짧은 줄 간격(~2x 간격)을 사용하여 36개 방향으로 스캔하고, GPU 친화적인 예약, Xbox One에서 720p에서 0.75ms 스캔 속도. 샘플에 디더링, 추가 근거리 샘플(약 2x 거리), 조여진 폐색기에 수직인 샘플을 추가합니다.

36개 방향은 깊이 및 일반 인식 3x3 상자 필터를 사용하여 수집된 3x3 이웃(4개 방향/픽셀)에 인터리브되어 픽셀당 수집하기에는 비용이 너무 높습니다.
화면 공간 확산 조명인 LSAO 샘플은 "가장 눈에 띄고" 들어오는 빛을 샘플링하는 데 매우 적합하며 정의에 따라 폐색될 수 없습니다(자체 폐색 제공).

효과 비교:

스크린 스페이스 리플렉션(SSR): GGX로 분산된 픽셀당 광선 1개, 모든 표면에 대해 평가, 선형 검색(7단계), 기하학적 진행을 형성하는 단계.

깊이 버퍼 샘플 처리는 다양한 거칠기를 지원하고, 원뿔 범위를 계산하고, 폐색 및 색상 샘플링을 수용하고, 단색 샘플 위치를 찾아야 합니다. 깊이 두께 = a+b*(광선을 따른 거리), 깊이 필드는 뷰 z를 따라가 아니라 카메라에서/카메라로 확장됩니다!

선형 항을 보기 공간의 단계 크기에 일치시키고, 그렇지 않으면 솔리드 형상의 구멍과 일치시킵니다.

폐색의 경우 원뿔의 하한을 표면 접선에 고정하여 원뿔의 최대 적용 범위를 계산합니다.

색상의 경우 샘플 위치가 필요하며 먼저 원뿔의 대부분을 덮는 샘플을 선택합니다. 반사된 광선을 적용 범위 중심으로 조준하고 마지막 두 샘플 사이의 직선과 교차합니다. 낮은 샘플링 밀도: 카메라(파란색)를 향해 보간합니다.

광선 위의 이전 예: 보간이 없습니다.

교차점을 최적화하고 인접한 광선의 방향이 동일할 경우 교차 검색을 수행하여 가장 가까운 적중 거리를 선택합니다.

하이브리드 레이 트레이싱 그림자는 기본 진실에 더 가까운 고품질 그림자 효과를 얻기 위한 하이브리드 레이 트레이싱 그림자 기술을 보여줍니다. 일반 섀도우 맵은 여드름, 피터 시프트 및 앨리어싱과 같은 불완전함으로 인해 어려움을 겪습니다.

기존의 경계 볼륨 계층 구조는 많은 광선 삼각형 적중 테스트를 건너뛸 수 있으므로 GPU에서 계층 구조를 재구성해야 하며 동적 개체의 경우 트리 순회가 본질적으로 느립니다.
경계 볼륨 계층 구조를 구축하지 않고도 레이 트레이싱을 위한 프리미티브를 저장하세요! 그림자 맵의 경우 광원의 깊이를 간단하고 일관된 조회로 저장합니다. 프리미티브를 저장하는 것과 유사하게 깊은 프리미티브 그래프인 전면 삼각형 세트는 텍셀 단위로 저장됩니다. 깊이 기본 지도 도면(N x N x d)에는 3가지 리소스가 포함되어 있습니다.
프림 카운트 맵(Prim Count Map): 교차하는 삼각형을 계산하기 위해 하나의 원자를 사용하여 텍스처에 몇 개의 삼각형이 있는지.
프림 인덱스 맵: 프리미티브 버퍼에 있는 삼각형의 인덱스입니다.
프림 버퍼: 변환 후 삼각형.

d는 충분히 큰가요? 점유 시각화: 검은색은 비어 있음을 의미하고 흰색은 가득 찼음을 의미하며 빨간색은 한계 초과를 의미하며 이는 알려진 모델을 사용하여 쉽게 수행할 수 있습니다.

GS는 3개의 정점과 SV_PrimitiveID를 PS로 출력합니다.
[maxvertexcount(3)]
void Primitive_Map_GS( triangle GS_Input IN[3], uint uPrimID : SV_PrimitiveID, inout TriangleStream<PS_Input> Triangles )
{
PS_Input O;
[unroll]
for( int i = 0; i < 3; ++i )
{
O.f3PositionWS0 = IN[0].f3PositionWS; // 3 WS Vertices of Primitive
O.f3PositionWS1 = IN[1].f3PositionWS;
O.f3PositionWS2 = IN[2].f3PositionWS;
O.f4PositionCS = IN[i].f4PositionCS; // SV_Position
O.uPrimID = uPrimID; // SV_PrimitiveID
Triangles.Append( O );
}
Triangles.RestartStrip();
}PS는 SV_PrimitiveID를 사용하여 그리기 호출 ID(셰이더 상수)를 해시하여 프리미티브의 인덱스/주소를 생성합니다.
float Primitive_Map_PS( PS_Input IN ) : SV_TARGET
{
// Hash draw call ID with primitive ID
uint PrimIndex = g_DrawCallOffset + IN.uPrimID;
// Write out the WS positions to prim buffer
g_PrimBuffer[PrimIndex].f3PositionWS0 = IN.f3PositionWS0;
g_PrimBuffer[PrimIndex].f3PositionWS1 = IN.f3PositionWS1;
g_PrimBuffer[PrimIndex].f3PositionWS2 = IN.f3PositionWS2;
// Increment current primitive counter uint CurrentIndexCounter;
InterlockedAdd( g_IndexCounterMap[uint2( IN.f4PositionCS.xy )], 1, CurrentIndexCounter );
// Write out the primitive index
g_IndexMap[uint3( IN.f4PositionCS.xy, CurrentIndexCounter)] = PrimIndex; return 0;
}텍셀과 접촉하는 모든 프리미티브를 캡처하려면 보수적인 래스터가 필요하며 소프트웨어나 하드웨어에서 수행할 수 있습니다. 하드웨어 보존적 래스터라이제이션: DirectX 12 및 11.3에서 활성화된 삼각형이 닿는 모든 픽셀을 래스터라이제이션합니다: D3D12_RASTERIZER_DESC, D3D11_RASTERIZER_DESC2.

소프트웨어 보수적 래스터라이제이션: GS를 사용하여 클립 공간에서 삼각형을 펼치고, AABB를 생성하여 PS에서 삼각형을 클리핑합니다. GPU Gems 2 - 42장을 참조하세요.

레이 트레이싱: 기본 좌표(그림자 맵과 동일)를 계산하고 기본 인덱스 배열을 반복하며 각 인덱스에 대해 광선 감지를 위한 삼각형을 사용합니다.
float Ray_Test( float2 MapCoord, float3 f3Origin, float3 f3Dir, out float BlockerDistance )
{
uint uCounter = tIndexCounterMap.Load( int3( MapCoord, 0 ), int2( 0, 0 ) ).x;
[branch]
if( uCounter > 0 )
{
for( uint i = 0; i < uCounter; i++ )
{
uint uPrimIndex = tIndexMap.Load( int4( MapCoord, i, 0 ), int2( 0, 0 ) ).x;
float3 v0, v1, v2;
Load_Prim( uPrimIndex, v0, v1, v2 );
// See “Fast, Minimum Storage Ray / Triangle Intersection“
// by Tomas Möller & Ben Trumbore
[branch]
if( Ray_Hit_Triangle( f3Origin, f3Dir, v0, v1, v2, BlockerDistance ) != 0.0f )
{
return 1.0f;
}
}
}
return 0.0f;
}
왼쪽: 3k x 3k 셰이딩 맵; 오른쪽: 3k x 3k 셰이딩 맵 + 1K x 1K x 64 PM.
안티앨리어싱을 위해 추가 조명을 사용할 수 있습니까? 비용이 너무 많이 든다! 간단한 트릭 - 화면 공간 AA 기술(FXAA, MLAA 등)을 적용합니다.
하이브리드 방식; 레이 트레이싱된 그림자를 기존의 부드러운 그림자와 결합하고 CHS 또는 PCS와 같은 고급 필터링 기술을 사용하며 차단기 거리를 사용하여 Lerp 계수를 계산하고 차단기 거리 -> 0일 때 레이 트레이싱 결과가 널리 사용됩니다. 보간 인자 시각화:

L = saturate( BD / WSS * PHS )
L: Lerp factor
BD: Blocker distance (from ray origin)
WSS: World space scale – chosen based upon model
PHS: Desired percentage of hard shadow
FS = lerp( RTS, PCSS, L )
FS: Final shadow result
RTS: Ray traced shadow result (0 or 1)
PCSS: PCSS+ shadow result (0 to 1)축소 반그림자 필터링을 사용하십시오. 그렇지 않으면 레이 트레이싱 결과에 부드러운 그림자 결과가 완전히 포함되지 않아 두 시스템 간에 LERPS를 수행할 때 문제가 발생하게 됩니다.

효과 비교:

다양한 기본 복잡성의 효과, 소비 및 성능은 다음과 같습니다.

제한 사항: 현재는 단일 광원으로 제한되어 있으며 전체 장면에 적용할 수 있도록 크기가 조정되지 않으며 저장 공간이 제한 요소이지만 가장 가까운 모델(현재 초점 모델, 가장 최근에 계단식으로 연결된 콘텐츠)에서 가장 잘 작동합니다. 전체적으로 전통적인 섀도우 맵 문제를 해결하고 AA 레이 트레이싱 하드 섀도우는 매우 잘 수행되며 하이브리드 섀도우는 엔진을 다시 작성할 필요 없이 두 세계의 장점을 결합하고 오늘날의 게임에 충분히 빠릅니다!
타일 기반 컴퓨팅 렌더링의 발전에서는 현재 기술, 컬링 개선, 클러스터 렌더링 등과 같은 타일 기반 컴퓨팅 셰이더의 렌더링에 대해 설명합니다.
기사의 개선 목표에는 Z-Prepass(forward+), 깊이 경계, 광원 컬링 및 색상 채널이 포함됩니다.
먼저 깊이 경계를 분석해 보겠습니다. 이전 접근 방식은 깊이 버퍼의 최소 및 최대 경계와 각 타일을 기반으로 하는 원자 연산의 최소 및 최대 값을 결정하는 것이었습니다. 이전 구현에는 종종 많은 성능 문제가 있었습니다.

Parallel Reduction(Parallel Reduction)으로 변경 가능합니다. 원자는 유용하지만 효율적이지는 않습니다. 계산 친화적인 알고리즘이 필요합니다. 현재 좋은 정보가 있습니다:
CUDA의 병렬 축소 최적화 [Harris07]
AMD GPU를 위한 컴퓨팅 셰이더 최적화: 병렬 축소 [Engel14]

구현 세부 정보: 첫 번째 패스에서는 깊이 샘플 4개를 읽고, 별도의 채널이 필요하며, UAV에 경계를 쓰고, 다른 작업에 유용할 수 있습니다.

효율성 비교:
그래픽 카드 원자 최소/최대 병렬 축소 변화
AMD R9 290X 1.8ms 1.6ms 11.1% 증가
엔비디아 GTX 980 1.8ms 1.54ms 14.4% 증가
3840x2160 해상도와 2048개의 조명에서 깊이 경계와 조명 컬링을 합친 비용으로 병렬 축소 프로세스는 약 0.35ms가 소요되며 이는 테스트된 GPU의 원자 최소/최대보다 빠릅니다.
다음으로 광원 컬링을 분석합니다.
광원 제거에는 구형 뷰 프러스텀 교차 감지가 필요합니다. 여러 가지 방법이 있습니다:

상단: 클리핑 평면; 중간: 긴 관측 프러스텀를 둘러싼 AABB; 하단: 짧은 관측 프러스텀를 둘러싼 AABB.
위의 것 외에도 Arvo[Arvo90] 교차 테스트 방법이 있으며 그 코드는 다음과 같습니다.


왼쪽: Sphere-Frustum 교차 테스트; 오른쪽: Arvo 교차 테스트. Arvo는 확실히 더 작고 정확합니다.
스포트라이트를 컬링할 때 스포트라이트 원점 주위에 경계 구를 배치하는 대신 반경 r의 구 내부 P에서 스포트라이트를 촘촘하게 둘러쌉니다.

심도 클리핑에는 2.5D 및 HalfZ 방법이 있으며 이 문서에서는 개선된 HalfZ 방법이 사용됩니다. 평소대로 최소 및 최대 Z를 계산한 다음 HalfZ를 계산하고, 각각 HalfZ 및 Max&Min의 최소 및 최대 값의 두 번째 세트를 사용하고, 근거리 및 원거리 경계를 테스트하고, 목록 중 하나 또는 둘 다를 작성하고, 깊이 경계 채널에서 반복하고, 최악의 경우는 HalfZ로 수렴합니다.

위에서 아래로: 2.5D, HalfZ, 개선된 HalfZ.

Unreal Engine 4 Infiltrator 데모 및 다양한 라이트 컬링 방법 시각화.
선별 결론: AABB로 수정된 HalfZ는 일반적으로 가장 잘 작동하지만 MinZ2 및 MaxZ2를 생성하면 약간의 비용이 추가됩니다. 각 조명이 하나가 아닌 두 개의 AABB에서 컬링되더라도 32x32 타일은 더 많은 라이트를 푸시할 때 색상 채널 효율성을 희생하는 대신 컬링 단계에서 많은 시간을 절약합니다.
클러스터링된 렌더링을 사용한 라이트 컬링의 경우 뷰 공간 AABB는 2D 그리드에서 가장 잘 작동하지만 16개 슬라이스에서는 형편 없습니다. 뷰 공간 프러스텀 평면은 타일 평면별로 계산된 다음 각 슬라이스에 대해 근거리 및 원거리를 테스트하고 (선택적으로) AABB를 테스트합니다.

VRAM 사용량: 16x16 픽셀 2D 그리드에는 numTilesX x numTilesY x maxLights 필요, 1080p: 120 x 68 x 512 x uint16 = 8MB, 4k: 240 x 135 x 512 x uint16=32MB, 각 조명 유형 목록(포인트 및 스팟): 64MB, 32 슬라이스: 포인트용 1GB 조명만 사용하려면 더 거친 메시를 사용하거나 압축된 목록을 사용하세요.
목록을 압축하는 옵션 1: CPU에서 모든 컬링을 수행하지만 이러한 조명 중 일부는 귀중한 리소스인 GPU에 의해 생성될 수 있습니다! 옵션 2: GPU에서 선별하고, TGSM에서 슬라이스당 조명 수를 추적하고, 조명 목록 헤더에 타일당 maxLights x "안전 계수"로 오프셋 테이블을 작성합니다.
Z 프리패스는 장면에 따라 매우 다르며 비용이 너무 많이 드는 것으로 간주되는 경우가 많습니다. DirectX12는 제출 비용을 줄이는 데 도움이 되며 이미 매우 최적화된 그림자 깊이 경로를 갖추고 있어야 합니다! 위치 스트림, 인덱스 버퍼 및 자료만 함께 일괄 처리되며 부분 프리패스는 실제로 지오메트리 부하를 줄이는 데 도움이 됩니다.
결론: 병렬 축소는 원자 최소/최대보다 빠르며 수정된 HalfZ와 결합된 AABB 구형 테스트는 좋은 선택입니다. 클러스터된 셰이딩은 타일 컬링을 많이 절약할 수 있고 조명 수가 적은 경우 비용이 저렴하며 2D 타일링에 비해 다른 이점을 제공합니다. 집계 자르기는 그만한 가치가 있으며 값비싼 장면 색상에 대한 최상의 최적화를 제공합니다.
2단계 전역 조명 베이킹 소프트웨어를 만드는 방법은 GDC China 2015에서 NetEase 연구소에서 발표되었으며 빠른 베이킹을 달성하는 전역 조명 렌더링을 설명했습니다. 기사에서는 당시 시중에 나와 있던 상용 베이킹 소프트웨어가 굽는 속도가 느리고, 패키지가 크고, 재료가 제한되어 있었기 때문에 자체 개발이 필요했다고 언급했습니다. CloudGI 베이킹 프로세스가 제안되었습니다.

포인트 클라우드 기반 GI가 사용됩니다.

포인트 클라우드 기반 GI는 크게 포인트 클라우드 생성, 옥트리 구성, 간접 조명 계산의 세 단계로 구성됩니다.
포인트 클라우드는 실제로 노멀, 위치, 광도, 면적 등과 같은 정보를 포함하는 표면 요소입니다. 이는 DX1의 UAV 및 원자 추가 명령을 사용합니다. 기하학 셰이더에서 실행되는 서핑 영역의 경우 공식은 다음과 같습니다.
GPU는 동시성이 높고 동기화가 필요하지 않으며 비디오 메모리를 낭비하지 않는 옥트리를 구축하는 데 사용됩니다. 리프 노드를 생성합니다(1개 레이어 인코딩에 3비트, 10개 레이어에 32비트).

간접 조명 계산 프로세스: 옥트리를 탐색하고 ID 매핑 테이블을 얻은 다음 ID에서 휘도를 계산하고 마지막으로 다음 공식을 사용하여 평균값을 구하고 PI를 곱합니다.

또한 속도를 높이기 위해 블록 베이킹 방식을 사용한다.
14.4.3.3 모바일 플랫폼
모바일 장치의 다중 CPU 코어의 이점에서는 모바일 장치의 멀티 코어, SMP 다중 프로세서, Tegra 2, 듀얼 코어 ARM Cortex A9 아키텍처 등에 대한 요구 사항을 설명합니다.
모바일 장치는 웹 검색, 비디오 재생, 모바일 게임, SMS 문자 메시지, 위치 기반 서비스 등 다양한 작업을 수행합니다. 고속 모바일 장치 및 Wi-Fi 네트워크의 가용성이 증가함에 따라 모바일 장치는 이전에 기존 PC에서 처리했던 다양한 성능 집약적 작업에도 사용될 것입니다. 차세대 스마트폰("슈퍼폰")과 태블릿은 HD 1080p 비디오 재생, Adobe Flash 기반 온라인 게임, Flash 기반 스트리밍 HD 비디오, 시각적으로 풍부한 게임, 비디오 편집, 동시 HD 비디오 다운로드, 인코딩 및 업로드, 실시간 HD 비디오 회의 등 다양한 작업에 사용될 것입니다.
현재 세대의 모바일 프로세서는 이러한 고성능 사용 사례를 처리하도록 설계되지 않았습니다. 단일 코어 CPU 기반 장치의 경험 품질은 사용자가 여러 애플리케이션을 동시에 실행하거나 성능 집약적 애플리케이션(예: 게임, 화상 회의, 비디오 편집 등)을 실행할 때 급격히 저하됩니다. CPU 성능을 향상시키기 위해 엔지니어는 더 빠르고 더 작은 반도체 프로세스 사용, 코어 작동 주파수 및 전압 증가, 더 큰 코어 사용, 더 큰 칩 캐시 사용 등 다양한 기술을 사용합니다.
CPU 코어 또는 캐시의 크기를 늘리면 특정 수준까지만 성능이 향상될 수 있으며, 그 수준을 넘어서면 열 및 열 문제로 인해 코어 및 캐시 크기를 추가로 늘릴 수 없습니다. 우리는 기본 반도체 물리학을 통해 작동 주파수와 전압이 증가하면 반도체 장치의 전력 소비가 기하급수적으로 증가할 수 있다는 것을 알고 있습니다. 엔지니어가 주파수와 전압을 높여 더 높은 성능을 짜내더라도 성능이 향상되면 배터리 수명이 크게 단축됩니다. 또한 더 높은 전력을 소비하는 프로세서에는 더 큰 냉각 솔루션이 필요하므로 장치 크기가 의도치 않게 확장됩니다. 따라서 모바일 애플리케이션의 증가하는 성능 요구 사항을 충족하기 위해 프로세서의 작동 주파수를 높이는 것은 장기적으로 실현 가능한 솔루션이 아닙니다.
모바일 장치의 성능과 세련된 외관에 대한 급속도로 증가하는 요구를 충족하기 위해 업계에서는 SMP(대칭 다중 처리) 및 이종 멀티 코어 컴퓨팅과 같은 새로운 기술을 채택하기 시작했습니다. NVIDIA Tegra는 당시 세계에서 가장 앞선 모바일 프로세서였으며, 처음부터 2개의 ARM Cortex A9 CPU 코어(아래 그림)와 오디오, 비디오, 그래픽과 같은 특수 작업을 처리하기 위한 여러 개의 전용 코어를 갖춘 이기종 멀티 코어 SoC(시스템 온 칩) 아키텍처로 구축되었습니다.

ARM Cortex A9 CPU 코어 아키텍처 다이어그램.
특수 코어는 오디오, 비디오, 그래픽 처리와 같은 작업에 사용되는 범용 처리 코어보다 더 적은 수의 트랜지스터가 필요하고, 더 낮은 주파수에서 작동하며, 더 높은 성능을 제공하고, 더 적은 전력을 소비합니다. (아래 사진)

듀얼 코어 CPU의 전압 및 주파수 확장 이점.
SMP(Symmetric Multi-Processing) 기술을 통해 모바일 프로세서는 더 높은 성능을 제공할 뿐만 아니라 모바일 전력 예산 내에서 최대 성능 요구 사항을 충족할 수 있습니다. SMP를 사용한 멀티코어 아키텍처는 다음 특성으로 정의됩니다.
아키텍처는 두 개 이상의 동일한 CPU 코어로 구성됩니다.
모든 코어는 공통 시스템 메모리를 공유하며 하나의 운영 체제에 의해 제어됩니다.
각 CPU는 서로 다른 작업 부하에서 독립적으로 실행될 수 있으며 가능할 때마다 다른 CPU와 작업 부하를 공유할 수 있습니다.


싱글 코어(위)와 듀얼 코어(아래)에서 실행되는 웹 브라우징 비교.

ARM Cortex A9 CPU가 탑재된 모바일 기기와 기타 칩이 탑재된 모바일 기기의 성능입니다. 그림을 보면 전자가 2.5배 향상되었음을 알 수 있습니다.

Dungeon Defender 게임에서 듀얼코어를 켠 후 FPS는 싱글코어의 2배 이상입니다.
요약하면, 칩 제조업체는 주파수와 코어 크기의 지속적인 증가로 인해 전력 소비가 기하급수적으로 증가하고 과도한 열 방출이 발생한다는 것을 깨달았습니다. 따라서 CPU 제조업체는 이러한 프로세서의 전력 소비를 제한하면서 더 높은 성능의 프로세서를 계속 제공하기 위해 멀티 코어 CPU 아키텍처를 개발했습니다. 스마트폰 및 태블릿과 같은 모바일 장치는 배터리 수명과 내구성이 크게 향상되므로 PC 장치보다 멀티 코어 아키텍처의 이점을 더 많이 얻습니다. 기사에서는 2011년에는 듀얼 코어 프로세서가 표준이 될 것이며 가까운 미래에 쿼드 코어 프로세서가 등장할 것이라고 예측했습니다.
성능을 더욱 향상시키고 보조 배터리 예산 내에서 유지하려면 모든 모바일 프로세서에 결국 멀티 코어 프로세서가 탑재되는 것이 불가피합니다. Android, Windows CE, Symbian과 같은 모바일 운영 체제는 멀티 코어 환경에서 실행될 수 있으며 기본 하드웨어의 여러 처리 코어를 효과적으로 활용하는 데 필요한 기능을 갖추고 있습니다. 또한, 인기 있는 웹 브라우저와 대부분의 PC 게임은 이미 멀티스레드로 구성되어 있으며, 이러한 애플리케이션이 멀티코어 CPU 기반 모바일 프로세서에서 실행되도록 포팅되면 사용자는 성능이 크게 향상되는 것을 경험할 수 있습니다.
NVIDIA Tegra는 대칭형 멀티프로세싱의 성능을 활용하여 뛰어난 웹 브라우징 경험, 반응성이 뛰어난 사용자 인터페이스, 효율적인 멀티태스킹 및 엄청난 배터리 수명을 제공하도록 설계되었습니다.
2012년 GDC 차이나에서는 '삼국지연'의 제품 개발과 기술적 통찰이 국내 대표 모바일 게임의 개발 과정과 기술, 경험과 교훈을 공유했다. 다음 그림은 게임 서버에서 사용되는 아키텍처를 보여줍니다.

아래 그림은 게임에서 사용되는 엔진 아키텍처를 보여줍니다.

모바일 게임의 엔진 선택과 관련하여 이 기사에서 제공하는 조언은 상용 엔진(Unity, Unreal, Flash)을 맹목적으로 선택하지 말라는 것입니다. 인기 있는 오픈 소스 엔진은 더욱 현실적이며 플랫폼을 맹목적으로 교차하지 않습니다. iOS와 안드로이드면 충분합니다. 당시 Cocos2D-X는 많은 모바일 게임의 첫 번째 선택이었고, 휠을 다시 발명하거나 엔진을 직접 작성하지 않는 것이 권장되었습니다. 다음 그림은 당시 모바일 게임 엔진의 공통 모듈과 아키텍처를 보여줍니다.

클라이언트 기술 및 언어 선택에 있어서는 Windows 개발 환경을 사용하여 Object C(iOS)에 대한 의존도를 줄이고 Java(Android)에 대한 의존도를 줄이고 C/C++를 주요 프로그래밍 언어로 사용하는 것이 좋습니다.
게임 품질 등급 측면에서 권장 해상도는 고급 1136x640(iPhone 5), 중급 960x640(iPhone 4S), 저가 480x320(iPhone 3GS)입니다. 메모리는 150M 내에서 제어됩니다. 패키지 크기는 50M 미만, 약 80M, 상위, 중간, 하위에서 100M 이상입니다.
사용자 경험은 특별한 작동 방법(터치 포인트 크기, 제어 범위), 새로운 화면 특성에 대한 적응(작은 화면, 고화질), 성능 최적화(로딩 시간, 메모리 제한) 및 네트워크 최적화(대기 시간, 연결 끊김 및 압축)에 중점을 둡니다.
Unity3D를 활용한 iOS 및 Android 개발에서는 2012년 Unity를 활용한 모바일 플랫폼 게임 개발 전략을 설명합니다. 당시 모바일 앱의 유료 다운로드 상황은 다음과 같습니다. iOS 사용자 중 40% 이상이 '예'를 선택했고, Android 사용자 중 30% 이상이 '예'를 선택했습니다.

향후 플랫폼 마이그레이션을 위해서는 대부분의 플랫폼에 대한 최소한의 코드, 이익을 저해하지 않는 라이선스 모델, 광범위한 커뮤니티 지원 등과 같은 요소를 고려하는 솔루션을 선택하십시오. 동시에 H5, Cocos2D, UDK, Flash, Corona 및 기타 개발 키트를 비교했습니다. Unity를 선택하는 이유를 설명하세요. 모바일 장치(iOS, Android), 웹 페이지(NaCL, Flash, 웹 플레이어), 데스크톱(Steam, Mac App Store), 콘솔 및 기본 플러그인, 광범위한 커뮤니티 등을 포함한 주요 플랫폼에 대한 최고의 지원을 설명합니다.

2012년 Unity 게임 화면입니다.
플러그인의 경우, 크로스 플랫폼 플러그인은 주로 플랫폼별 기능(Game Center 등)에 접근하는 데 사용됩니다. 플랫폼별 코드를 리팩터링하는 데 며칠 밖에 걸리지 않았으며 Android용 iOS 플러그인, 런타임 플랫폼 검사와 #IF 컴파일러 지시문의 조합, AndroidJava 클래스를 대체했습니다. 크로스 플랫폼 내보내기 도구, 압축 설정, 필터링, 캐시 서버, 다중 플랫폼 툴킷, 플랫폼별 자산, 빌드 시 자산 변경과 같은 플랫폼별 자산 설정을 제공합니다.
간단히 말해서 Unity는 최고의 비즈니스 모델, 가장 광범위한 플랫폼 지원, 최고의 커뮤니티 지원 및 매우 간단한 포팅 프로세스를 갖추고 있습니다.
AAA 그래픽을 모바일 플랫폼으로 가져오기에서는 모바일 하드웨어의 비하인드 스토리 작동과 사례 연구, 그리고 소프트웨어가 이 지식을 적용하여 콘솔 그래픽을 모바일 플랫폼으로 가져오는 방법을 설명합니다.
모바일 그래픽 프로세서의 기능에는 셰이더, 텍스처 렌더링, 깊이 텍스처 및 MSAA가 포함되며 성능이 점차 향상되고 있습니다.
모바일 GPU 아키텍처: 데스크톱이나 콘솔과 매우 다른 타일 기반 디퍼드 렌더링(TBDR)은 스마트폰 및 태블릿에서 흔히 볼 수 있으며, ImgTec SGX GPU는 물론 다른 타일 기반 GPU(예: ARM Mali) 및 기타 모바일 GPU 유형(NVIDIA Tegra가 더 전통적)에 속합니다.
타일 기반 모바일 GPU: TLDR은 화면을 타일(예: 16x16 또는 32x32 픽셀)로 분할하고 GPU는 전체 칩에 맞으며 타일에 대한 모든 그리기 호출을 처리하고 각 타일에 대해 반복하여 화면을 채우고 각 타일은 완료되면 RAM에 기록됩니다.

ImgTec 처리.
버텍스 프런트 엔드: 버텍스 프런트 엔드는 GPU 명령 버퍼에서 읽고, 버텍스 프리미티브를 모든 GPU 코어에 배포하고, 그리기 호출을 고정 버텍스 블록으로 분할하며, GPU 코어는 장면이 끝날 때까지 정점을 독립적으로 처리합니다.

Vertex 처리는 아래와 같습니다.

각 단계는 다음과 같이 설명됩니다.
버텍스 설정. 버텍스 프런트엔드에서 명령을 받습니다.
버텍스 사전 셰이딩. 입력 데이터(속성 및 유니폼)를 가져옵니다.
버텍스 셰이더. 범용 확장 가능한 셰이더 엔진, 버텍스 셰이더 프로그램 실행, 멀티스레드.
매개변수 버퍼. 시스템 메모리에 저장되지만 이 버퍼는 오버플로될 수 없습니다!
픽셀 프런트 엔드: 매개변수 버퍼를 읽고 픽셀 처리를 한 번에 타일 하나씩 모든 코어에 배포합니다. 하나의 타일은 하나의 GPU 코어에서 완전히 처리됩니다. 타일은 멀티 코어 GPU에서 병렬로 처리됩니다.

픽셀 처리(GPU 코어당)는 다음과 같습니다.

그 중에는:
픽셀 설정. Pixel Frontend에서 타일 명령 수신, 매개변수 버퍼에서 꼭짓점 셰이더 출력 가져오기, 삼각형 래스터라이제이션, 보간기 값 계산, 깊이/스텐실 테스트, 숨겨진 표면 컬링(HSR).
픽셀 사전 셰이딩. 독립적인 텍스처 읽기를 시작하기 위해 보간기와 균일한 데이터를 채웁니다.
픽셀 셰이더. 멀티 스레드 ALU, 각 스레드는 버텍스 또는 픽셀일 수 있으며 각 GPU 코어에는 여러 USSE가 있을 수 있습니다.
픽셀 백엔드. 타일의 모든 픽셀이 완료되면 트리거되고, 데이터 변환, MSAA 다운샘플링을 수행하고 완성된 타일의 색상/깊이/템플릿을 메모리에 씁니다.
셰이더 유닛 참고 사항: 동적 흐름 제어가 없는 셰이더 프로그램: 명령당 4개의 버텍스/픽셀, 동적 흐름 제어가 있는 셰이더 프로그램: 명령당 1개의 버텍스/픽셀, 셰이더의 알파 블렌딩: 전용 하드웨어는 분리되지 않으며 상태를 전환할 때 셰이더 패치가 발생할 수 있습니다.
휴대폰은 새로운 PC, 광범위한 기능 및 성능 범위, 확장 가능한 그래픽이 돌아오고, 사용자 그래픽 설정이 돌아오고, 낮음/중간/높음/울트라, 렌더 버퍼 크기 조정, 100 SKU 테스트가 돌아왔습니다.
렌더 타겟이 죽었고, MSAA는 오버헤드가 낮고 메모리를 더 적게 사용하며, 구문 분석된 데이터만 메모리에 있고, MSAA는 약 0~5ms를 소모합니다. 버퍼(색상 또는 깊이) 지원에 주의하세요! 알파 블렌딩에는 대역폭 소비가 없으며 오버헤드가 낮은 깊이/스텐실 테스트가 있습니다.
숨겨진 표면의 "무료" 제거(ImgTec SGX GPU 전용), 모든 배경 픽셀 제거, 오버드로 제거, 불투명도에 대해서만.
모바일 및 콘솔: OpenGL ES API는 매우 높은 CPU 오버헤드, 그리기 호출에 최대 100-300 CPU 사용량, 장면당 너무 많은 데이터 방지, 정점과 픽셀 처리 간의 매개변수 버퍼, 대역폭 및 GPU 새로 고침 절약, 셰이더 패키징, 특정 렌더링 상태로 인해 알파 블렌딩 설정, 버텍스 입력, 색상 쓰기 마스크 등과 같은 드라이버가 셰이더를 수정하고 재컴파일하게 됩니다.
알파 테스트/폐기: 조건부 z 쓰기는 매우 느릴 수 있으며 픽셀 설정(PDM)은 Z를 미리 작성하는 대신 픽셀 셰이더가 현재 픽셀의 가시성을 결정할 때까지 더 많은 조각을 커밋하지 않습니다. 알파 테스트 대신 알파 블렌드를 사용하여 형상을 눈에 보이는 픽셀에 맞춥니다.
렌더 버퍼 관리:
각 렌더 타겟은 완전히 새로운 장면이므로 렌더 타겟을 앞뒤로 전환할 필요가 없습니다!
전체 복원이 발생할 수 있습니다. 장면 시작 시 모든 색상/깊이/스텐실을 RAM에서 타일 메모리로 복사합니다.
전체 해결이 발생할 수 있습니다. 장면이 끝나면 타일 메모리에서 RAM으로 전체 색상/깊이/스텐실을 복사합니다.
버퍼 복구를 피하십시오. 모든 항목 지우기: 색상/깊이/스텐실, 지우기는 레지스터에 일부 더티 비트를 설정합니다.
버퍼 구문 분석을 피하세요. 폐기 확장(GL_EXT_discard_framebuffer)을 사용합니다.
서로 다른 FBO의 불필요한 조합을 피하고 드라이버가 버퍼 구문 분석 및 복원을 시작해야 한다고 생각하지 않도록 하십시오!
텍스처 조회: 픽셀 셰이더에서 텍스처 조회를 수행하지 마세요! "사전 셰이더"를 미리 대기열에 추가하세요. 즉, 텍스처 조회에 의존하지 마세요. 수학으로 텍스처 좌표를 조작하지 말고 모든 수학 연산을 버텍스 셰이더로 이동하여 전달하세요. 텍스처 좌표에 .zw 구성 요소를 사용하지 말고 종속 텍스처 조회로 처리하고 .xy를 사용하고 .zw에 다른 데이터를 전달하세요.
모바일 머티리얼 시스템: 전체 언리얼 엔진 머티리얼은 너무 복잡합니다. 초기 아이디어는 단일 텍스처로 사전 렌더링하는 것이었습니다. 현재 솔루션은 구성 요소를 별도의 텍스처로 사전 렌더링하고 모바일 장치별 설정을 추가하며 아티스트 중심 기능의 지원을 받는 것입니다.
모바일 머티리얼 셰이더: 모든 기능에 대해 많은 #ifdef가 포함된 손으로 작성한 uber 셰이더로 아티스트 UI에 체크박스, 목록, 값 등과 같은 고정 설정으로 표시됩니다.
셰이더 오프라인 처리: C 전처리기를 오프라인으로 실행하여 게임 내 컴파일 시간을 줄이고 오프라인 상태에서 중복을 제거합니다.
셰이더 컴파일: 런타임 시 중단을 방지하기 위해 시작 시 모든 셰이더를 컴파일합니다. GL 스레드에서 컴파일하고 게임 스레드에서 로드합니다. 컴파일만으로는 충분하지 않습니다. 가상 그리기 호출이 실행되어야 합니다! **특정 상태가 셰이더에 어떤 영향을 미치는지 기억하세요! 알파 블렌드 상태, 색상 쓰기 마스크와 같은 셰이더 패치를 피하는 것이 좋습니다.
이 기사는 예수 빛의 표현과 구체적인 단계에 대해 이야기합니다. 모바일 최적화에는 다음이 포함됩니다.
모든 수학 연산을 버텍스 셰이더로 옮겼습니다. 텍스처 읽기에 의존하지 않습니다!
보간기를 통해 데이터를 전달합니다. 그러나 보간기의 수는 제한되어 있습니다.
방사형 필터를 4개의 그리기 호출, 4x8 = 총 텍스처 조회 32개(256개와 동일)로 분할합니다.
30ms에서 5ms로 단축되었습니다.
이 기사에서는 캐릭터 그림자에 대해서도 다룹니다. 투영되고 변조된 동적 그림자, 상당히 표준적인 접근 방식, 그림자 깊이 버퍼 생성, 잠재 픽셀 템플릿, 그림자 깊이를 장면 깊이와 비교, 영향을 받는 픽셀을 어둡게 합니다. 구체적인 단계:
- 광원 각도에서 문자 깊이를 투영합니다.
-카메라 뷰로 다시 투영합니다.
SceneDepth와 비교하고 변조합니다.
위에 캐릭터를 그립니다(셀프 섀도우 없음).
그림자 최적화:
프레임 내 그림자는 깊이 우선입니다. 렌더 타겟 전환 방지(파싱 및 복원!)
그림자를 해결하기 전 장면의 깊이:
타일 깊이를 RAM에 기록하여 텍스처로 읽습니다.
동일한 타일에서 계속 렌더링합니다.
아쉽게도 OpenGL ES에는 이에 대한 API가 없습니다.
그림자에 대한 색상 버퍼 사용 최적화:
깊이 버퍼만 있으면 됩니다!
불필요한 버퍼이지만 OpenGL ES에서는 필요합니다.
지우고(복구 방지) 컬러 쓰기를 비활성화합니다.
구문 분석을 방지하려면 glDiscardFrameBuffer()를 사용하세요.
깊이는 F16/RGBA8로 색상으로 구분할 수 있습니다.
텍스처 조회에 의존하지 않으려면 큐브 대신 화면 공간 쿼드를 그립니다.
도구 설명: PC에서 OpenGL ES 래퍼를 사용하세요. Visual Studio에서 디버깅할 때 거의 "보이는 것이 얻는 것"입니다. Apple Xcode GL 디버거인 iOS 5는 프레임을 완전히 캡처하고, 각 그리기 호출과 상태를 별도의 창에 표시하고, 각 그리기 호출에 사용된 모든 리소스를 표시하고, 셰이더 소스 코드 + 모든 균일 값을 표시합니다.
ImgTec 6xxx 시리즈: 100+ GFLOPS(TFLOPS 범위로 확장 가능), DirectX 10, OpenGL ES “Halti”, PVRTC 2, 향상된 메모리 대역폭 사용, 향상된 대기 시간 숨김.
ARM에서 Android™용 모바일 앱 및 게임 가속화를 소개하고 Android 시스템에서 앱 기술을 최적화하는 방법을 설명합니다.
모바일 애플리케이션에는 항상 명확하지 않은 특별한 설계 고려 사항이 필요하며 점점 더 복잡해지는 시스템을 처리하기 위한 도구는 제한되어 있습니다. 애니메이션과 게임은 프레임 손실, 네트워킹, 디스플레이, 실시간 오디오 및 비디오 처리에 전력을 소비하며 애플리케이션이 메모리 제약 조건에 맞지 않습니다. 다행히 Google, ARM 및 기타 여러 회사에서 이러한 문제에 대한 분석 도구와 솔루션을 개발하고 있습니다. 애플리케이션이 CPU/GPGPU 바운드인가요, I/O 또는 메모리 바운드인가요, 아니면 전력 효율적인가요? 문제를 해결하려면 어떻게 해야 합니까?
Java SDK Android 애플리케이션 분석: SDK Lint 도구를 이용한 정적 분석, DDMS(할당/힙, 프로세스 및 스레드 활용도, Traceview(메소드), 네트워크)를 이용한 동적 분석, 계층 뷰어, 시스템 추적.
이 성능 병목 현상을 병렬화할 수 있습니까? 자바인가요 아니면 네이티브인가요? 반대라면 더 좋지 않을까요? 이전에도 이런 일이 있었나요? 바퀴를 재발명하지 마세요. 자원이 지능적으로 사용됩니까? 어떤 Android 버전을 대상으로 해야 하나요? 정적 분석: LINT(아래 그림):

DDMS(Dalvik Debug Monitor Server)의 정적 분석 외에도 DDMS 스레드 분석("top"과 유사하지만 더 좋음):

DDMS: Traceview는 각 메서드가 소비하는 CPU 시간을 추적합니다.

할당 및 HEAP 고주파수 방법으로 할당이 수행되는지 여부:

Dumpsys gfxinfo: dumpsys 데이터 열을 스프레드시트에 넣고 시각화합니다. 예: 애니메이션이 프레임을 떨어뜨리는 경우:

Systrace: 애플리케이션 내부를 분석하기 위해 할 수 있는 모든 작업을 수행했지만 여전히 병목 현상을 찾을 수 없습니다. Systrace가 구출해 드립니다! Systrace.py는 5초 시스템 수준 스냅샷을 생성합니다.


ARM DS-5 Community Edition 무료 Android 네이티브 프로파일러 및 디버거:

간소화된 개요:

Mali GPU용 그래픽 분석 도구:

ARO(Application Resource Optimizer), 무료/오픈 소스 네트워크 중심 진단 도구(AT&T에서 제공하지만 AT&T 장치가 필요하지 않음), pcap/데이터 수집에는 루트, 장치의 APK, 분석용 데이터 캡처를 위한 Java 데스크톱 애플리케이션이 필요합니다.

인터넷 자원:
연결을 닫습니다. 80%의 앱이 종료 후에도 연결을 종료하지 않으며, LTE 전력이 38% 증가합니다(3G 전력이 18% 증가).
데이터 캐싱. 모바일 트래픽의 17%는 변경되지 않은 동일한 HTTP 콘텐츠의 반복 다운로드입니다. "단지 6KB 로고일 뿐입니다." - 6KB 3DL/세션 10000명의 사용자/일 = 3.4GB/월, 로컬 캐시에서 읽는 것이 웹에서 다운로드하는 것보다 75-99% 더 빠릅니다. 캐싱이 지원되는 경우에도 기본적으로 꺼져 있습니다.
모든 연결을 관리합니다. 그룹 연결을 통해 배터리를 절약하고 애플리케이션 속도를 높입니다.
캐싱 방법: 각 파일에는 각 요청에 대해 서버에서 재검증되는 고유한 태그가 있습니다. 고성능 웹사이트: 규칙 1 – HTTP 요청을 줄이고, 연결을 추가하면 배터리가 소모되고 대기 시간이 500~3000ms 추가됩니다. Max-Age 시간을 신중하게 할당하는 것이 중요합니다. 응용 프로그램은 Max-Age에 도달할 때까지 서버의 파일을 확인하지 않으며 검색은 엄격하게 파일 처리 시간입니다.
그룹 연결: 아래 그림, 빨간색: 60초마다 이미지 다운로드, 파란색: 60초마다 광고 다운로드, 녹색: 60초마다 서버에 분석을 보냅니다.

그룹 해제: 38J의 에너지 사용, 그룹화: 16J의 에너지 사용, 58%의 전력 절약! !
기타 네트워크 최적화: 파일에 대한 리디렉션 제거, 각각 약 2-3초 요청, 일반적으로 사용되는 파일 미리 가져오기, 직렬 다운로드 대신 스레드 파일 다운로드, 4xx, 5xx http 응답 오류 코드가 없어야 함, 일반 연결에 주의, 업데이트를 위한 정기적인 3분 폴링은 하루 1.2시간 동안 연결을 열어두어 배터리를 약 20% 소모할 수 있습니다.
ARM용 NDK(네이티브 개발 키트): NDK는 애플리케이션 개발자가 ARM 프로세서용으로 직접 작성할 수 있는 포괄적인 툴킷입니다.

SMP 및 병렬화: 현재 시중에 나와 있는 거의 모든 Android 및 모바일 장치는 멀티 코어이며 이러한 추세는 계속될 것입니다. 멀티 스레드 애플리케이션 설계 Davlik Java 스레드 및 IPC, AsyncTask는 IPC 복잡성을 최소화하면서 작업을 백그라운드 작업자 스레드로 신속하게 푸시하는 가장 쉬운 방법입니다. Bionic C 라이브러리는 Pthreads API 버전을 구현하고 대부분의 pthread 및 sem_ 기능이 구현되지만 SysV IPC는 없습니다(pthread.h 또는 명령문에 있는 경우). semaphore.h를 실행하면 대부분 예상대로 작동합니다.
OpenGL ES 2.0은 프로그래밍 가능한 임베디드 GPU에서 완전히 프로그래밍 가능한 3D 그래픽, 로열티 없는 크로스 플랫폼 API, 2D 및 3D 그래픽, 프레임워크 API 및 Android용 NDK 지원을 지원합니다.
모바일/임베디드/배터리용 Java 작성: 적어도 CPU 집약적/빈번한 활동에서는 피해야 하는 새로운 접근 방식입니다. 정적 변수를 사용하거나 사전 할당 또는 활동의 자연스러운 일시 중지 시 할당을 시도하고 가비지 수집 트리거를 방지합니다(DDMS 사용). 수직 동기화 펄스를 위한 android.view.Choreographer, myView.postInvalidateOnAnimation()과 같은 JellyBean의 그래픽에 대한 새로운 기능을 사용하고, 표시되지 않는 것을 그리지 마십시오(c.quickReject(items...), Canvas.EdgeType.BW).
SIMD: NEON - 다양한 응용 프로그램에 적합한 범용 SIMD 처리, 인터넷 응용 프로그램을 위한 가장 광범위한 멀티미디어 코덱 지원, 다양한 소프트 코덱 표준: MPEG-4, H.264, On2 VP6/7/8, Real, AVS 등 모든 인터넷 및 디지털 홈 표준이 소프트웨어에서 지원됩니다. 더 적은 주기로 NEON은 복잡한 비디오 코덱에서 1.6x-2.5x 성능을 제공하고, 단일 간단한 DSP 알고리즘은 더 큰 성능 향상(4x-8x)을 보여줄 수 있으며, 프로세서는 더 빠르게 절전 모드로 전환될 수 있습니다 => 전반적인 동적 에너지 절약. 광범위한 데이터 집약적 계산에 적합한 직접 프로그래밍, 깔끔한 직교 벡터 아키텍처. 코덱뿐만 아니라 2D/3D 그래픽 및 기타 처리를 위한 32개 레지스터, 64비트 너비(16개 레지스터, 듀얼 뷰의 경우 128비트 너비), 기성 도구, 운영 체제, 상용 및 오픈 소스 생태계 지원.

스레드 파일 다운로드(왼쪽)와 직렬 다운로드(오른쪽) 비교.
OpenGL ES 3.0 - 도전 과제와 기회는 모바일 측에서 OpenGL ES 3.0의 기능, 응용 프로그램 및 최적화를 공유합니다.
OpenGL ES는 임베디드 시스템용 개방형 그래픽 라이브러리, 그래픽 하드웨어용 저수준 소프트웨어 인터페이스, OpenGL의 하위 집합, 스마트폰/태블릿, 텔레비전, 자동차 등을 위한 OpenGL ES 기반 GPU의 다양한 용도입니다. 데스크톱 GPU 컴퓨팅이 모바일 장치에 적용되기까지 얼마나 걸리나요? 컴퓨팅 성능과 대역폭 속도 곡선 및 추세 예측은 다음과 같습니다.


OpenGL ES 3.0은 2012년에 출시되었으며 OpenGL 3.3/4.x의 기능 세트를 기반으로 하여 확장 요구 사항을 줄이고 OpenGL ES 2.0과 완전히 역호환됩니다. 음영 언어 GLSL ES 3.00 모드는 다음과 같습니다.

ETC2 텍스처 압축은 알파, 1 또는 2채널을 지원하는 표준 텍스처 압축으로, ETC1의 제한 사항(알파 지원 안 함, 텍스처 불량)을 제거합니다. 이론적으로는 독점 텍스처 형식, 더 작은 파일 크기, 다른 자산 패키지가 필요하지 않습니다.

부울 폐색 쿼리: 하드웨어 기반 가시성 테스트를 위한 소프트웨어 인터페이스:
glGenQueries
glDeleteQueries
glBeginQuery
glEndQuery
glGetQueryObjectuiv...
int qid[NUM_OBJECTS];
unsigned int result = 0;
//
glGenQueries(NUM_OBJECTS, &qid[0]);
for (int i = 0; i < NUM_OBJECTS; ++i)
{
//
glBeginQuery(GL_ANY_SAMPLES_PASSED, qid[i]);
// 로써 렌더링(Render).
RenderOccluders();
// .
glEndQuery(GL_ANY_SAMPLES_PASSED);
// 결과 유효(Valid).
// ※ 주의: :동기화 결과 의 【의 성능 】!!
while (result == GL_FALSE)
{
glGetObjectuiv(qid[i], GL_QUERY_RESULT_AVAILABLE, &result);
}
// 페치/가져오기(Fetch)결과 。
glGetObjectuiv(qid[i], GL_QUERY_RESULT, &result);
if (result == GL_TRUE)
{
// 로써 정밀도 렌더링(Render)。
RenderObjects();
}
}
...
폐색 쿼리에 대한 CPU 및 GPU 타이밍 다이어그램.

ES3는 2에 비해 폐색 쿼리를 크게 향상시킬 수 있습니다.
인스턴스 렌더링: 드로잉 호출, 동일한 형상이 다수 포함된 강력한 장면, 관련 인터페이스를 최소화합니다.
glDrawArraysInstanced(GLenum mode, Glint first, GLsizei count, GLsizei primcount)
glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount)
glVertexAttribDivisor(GLuint index, GLuint divisor)
gl_InstanceID기존(2013) 렌더링 파이프라인에서는 구현하기 어려울 수 있습니다.
// OpenGL ES 2.0
for ( int i = 0; i < numInstances; i++ )
{
// set for each instance the model-view-projection matrix
glDrawElements(GL_TRIANGLES,mesh->indx_count,GL_UNSIGNED_SHORT,mesh->indx);
}
// OpenGL ES 3.0
glDrawElementsInstanced(GL_TRIANGLES,mesh->indx_count,GL_UNSIGNED_SHORT,mesh->indx, numInstances);// 인스턴스 렌더링(Render)
// Vertex shader
#version 100
uniform mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
MVP = glGetUniformLocation( programObj, "u_matViewProjection" );
glUniformMatrix4fv(MVP, 1, GL_FALSE, &mvpMatrix );
// 인스턴스 렌더링(Render)
// Vertex shader
#version 100
// uniform -> attribute
attribute mat4 u_matViewProjection;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
varying vec2 v_texCoord;
// glGetUniformLocation -> glGetAttribLocation
MVP = glGetAttribLocation( programObj, "u_matViewProjection" );
// 패딩/채우기 인스턴스 데이터 .
for (int i = 0; i < 4; i++)
{
glEnableVertexAttribArray(MVP + i);
glVertexAttribPointer(MVP + i,
4, GL_FLOAT, GL_FALSE, // vec4
16*sizeof(GLfloat), // stride
&(matArray + 4*i*sizeof(GLfloat)); // offset
glVertexAttribDivisor(MVP + i, 1);
}
#define LTP_ARRAY 0
#define VERTEX_ARRAY 4
layout(location = LTP_ARRAY) in highp mat4 inLocalToProjection;
layout(location = VERTEX ARRAY) in highp vec3 inVertex;
void main()
{
gl_Position = inLocalToProjection * inVertex;
}
MRT(Multiple Render Target)는 단일 그리기 호출로 여러 버퍼로 렌더링하여 지연 조명, 셀 셰이딩, 지연 데칼, 실시간 부분 반사 등과 같은 차세대 시각 효과를 수행할 수 있는 가능성을 제공합니다.
// C++
...
unsigned int fb;
unsigned int initializedTexture2D_1;
unsigned int initializedTexture2D_2;
GLenum buffs[] = {GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1};
glGenFrameBuffer(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, GL_TEXTURE2D, initializedTexture2D_1, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, GL_TEXTURE2D, initializedTexture2D_2, 0);
glDrawBuffers(2, buffs);
// render calls
...
// fragment shader
#version 300 es
layout(location = 0) out lowp vec4 color;
layout(location = 1) out highp vec4 normal;
in lowp vec4 v_color;
in highp vec4 v_normal;
main()
{
color = v_color;
normal = v_normal;
}
OpenGL ES 3.0 기능의 비용 편익 비율입니다.
과제:
-기존 엔진에서의 구현은 쉽지 않습니다.
제품 파이프라인 수정이 필요합니다.
어떤 경우에는 OpenGL ES 3.0 기능으로 인해 성능이 향상되지 않습니다.
그래픽 부서도 MRT를 이해해야 합니다.
OpenGL ES 3.0 장치는 현재 ES2/ES3를 동시에 지원합니다.
기회:
더 나은 성능.
에너지 소비가 적습니다.
OEM은 개발자가 사용하는 최신 기술을 보고 싶어합니다.
현재 콘솔과 모바일 기기의 격차는 점점 줄어들고 있습니다.
확장을 통해 현재 범용 하드웨어에서 일부 3.0 기능을 사용할 수 있습니다.
2013년에는 MMOG(대규모 멀티플레이어 온라인 게임)와 같은 비디오 게임이 문화 매체로 자리 잡았고, 모바일 게임은 앱 시장에 대규모 다운로드와 잠재 수익을 가져왔습니다. 모바일 장치의 처리 능력이 대역폭 전송을 증가시키는 반면, 불량한 네트워크 연결은 GaaS(Game as a Service)에 병목 현상이 될 수 있습니다. 처리 작업이 씬 클라이언트 장치와 강력한 서버 간에 분산되는 디지털 생태계의 성능을 향상시키기 위해 모바일 장치를 실시간으로 사용하는 3D 렌더링 배포를 위한 아키텍처 접근 방식은 "분할 및 정복" 접근 방식을 기반으로 합니다. 즉, 게임에서 장면 시퀀스의 트리 KD를 사용하여 체적 표면을 테셀레이션하여 표면을 작은 점 집합으로 줄입니다. 데이터 검색이 로컬 및 소규모 영역에서 수행되므로 재구성 효율성이 향상됩니다. 이 프로세스는 휴리스틱으로 구성된 도메인과 함께 숨겨진 마르코프 모델을 사용하여 구성된 유한한 상태 세트로 모델링됩니다. 제안된 모델을 검증하기 위해 간격 수를 포함하여 각 휴리스틱 상태를 제어하는 6가지 테스트를 수행했습니다. 이 검증에서는 제안된 모델이 일련의 상호 작용에 걸쳐 초당 응답 프레임을 최적화한다는 결론을 내렸습니다.

노드의 아키텍처는 완전 연결(순회) 모델입니다.
데스크탑 **가상 현실(VR)**은 역사적으로 소비자급 3D 컴퓨터 그래픽의 주요 디스플레이 기술이었습니다. 최근에는 입체 시각 및 헤드 마운트 디스플레이와 같은 보다 정교한 기술이 더욱 널리 보급되었습니다. 그러나 대부분의 3D 소프트웨어는 여전히 데스크톱 VR을 지원하도록 설계되었으며 이러한 디스플레이를 기술적으로 지원하고 사용 모범 사례를 따르도록 수정되어야 합니다. 그래픽 엔진의 가상 현실 기능은 최신 3D 게임/그래픽 엔진을 평가하고 다양한 유형의 저렴한 VR 디스플레이 출력에 얼마나 잘 적응하는지 결정하여 입체 비전이 기본적으로 또는 기존 적응을 통해 널리 지원된다는 것을 보여줍니다. 헤드 마운트 디스플레이, 헤드 결합 관점(및 후속 수조 VR)과 같은 기타 VR 기술은 기본적으로 거의 지원되지 않습니다. 그러나 이 기사에서는 이러한 디스플레이 기술에 대한 지원을 추가할 수 있는 재설계와 같은 방법을 식별하고 설명합니다.
2013년 가상현실 디스플레이 기술에는 데스크탑 VR(스트리밍), 입체 비전, 헤드 결합 관점, 헤드 마운트 디스플레이 등이 포함됩니다. 시뮬레이션 모델과 사용자 인식의 차이점은 다음과 같습니다.

입체경은 양안 시야에 적용되는 Tabletop VR 패러다임의 확장입니다. 스테레오스코프는 각 눈에 한 번씩 장면을 두 번 렌더링한 다음 각 이미지가 사용자의 한쪽 눈에만 표시되도록 이미지를 인코딩하고 필터링하여 이를 수행합니다. 이 필터링은 일치하는 디스플레이에서 생성된 두 코드 중 하나를 선택적으로 통과하도록 렌즈가 설계된 특수 안경을 통해 가장 쉽게 달성됩니다. 현재 인코딩 방법은 색상 스펙트럼, 편광, 시간 또는 공간을 통해 이루어집니다. 이러한 인코딩 방법은 수동형, 능동형 또는 무안경 입체형으로 분류되는 경우가 많습니다. 수동 인코딩과 능동 인코딩의 차이는 안경이 전기 활성인지 여부에 따라 다릅니다. 따라서 수동 인코딩 시스템은 색상과 편광인 반면 유일한 능동 인코딩은 시간입니다. 무안경 입체 디스플레이는 공간적으로 인코딩되므로 안경이 필요하지 않은 디스플레이입니다. 즉, 눈 사이의 물리적 거리가 이미지를 필터링하는 데 충분합니다.
소비자 입체 디스플레이는 데스크톱 VR 디스플레이와 동일한 방식으로 컴퓨터와 인터페이스합니다(VGA 또는 DVI와 같은 비디오 인터페이스를 통해). 이러한 인터페이스 대부분에는 특별한 입체 보기 모드가 없기 때문에 두 개의 입체 이미지가 디스플레이 하드웨어에서 인식되는 형식으로 단일 이미지로 압축됩니다. 이러한 프레임 패킹 형식에는 인터레이스, 상단-하단, 병렬, 2D+깊이 및 인터레이스가 포함됩니다. 이러한 표준화된 인터페이스는 소프트웨어가 렌더링된 이미지를 디스플레이 하드웨어에 전달하는 방식이기 때문에 소프트웨어 응용 프로그램은 인코딩 시스템의 디스플레이 하드웨어를 이해하거나 적응할 필요가 없습니다. 대신, 입체적인 관점을 지원하기 위해 그래픽 엔진에 필요한 것은 서로 다른 가상 카메라 위치에서 동일한 시뮬레이션 상태로 두 개의 이미지를 렌더링하고 이를 디스플레이에서 지원하는 프레임 패킹 형식으로 결합하는 기능입니다.
**헤드 결합 관점(HCP)**은 가상 카메라 대신 가상 창을 정의한다는 점에서 데스크톱 VR 및 입체 비전과 약간 다르게 작동하며, 그 경계는 사용자 디스플레이 가장자리에 매핑된 가상 창입니다. 따라서 가상 환경의 객체가 사용자의 눈 방향으로 디스플레이에 투사되므로 디스플레이의 이미지는 사용자 머리의 상대적인 위치에 따라 달라집니다. 이 투영은 데스크톱 VR에 사용되는 투영 수학의 축외 버전을 사용하여 수행할 수 있습니다.
이를 위해서는 디스플레이를 기준으로 한 사용자의 머리 위치를 실시간으로 정확하게 추적해야 합니다. 이러한 목적으로 사용되는 추적 시스템에는 뼈대, 전자기/초음파 추적기 및 이미지 기반 추적이 포함됩니다. HCP의 한 가지 한계는 표시되는 이미지가 사용자의 위치에 따라 달라지기 때문에 동일한 디스플레이를 보는 다른 사용자가 올바른 위치에서 볼 수 없기 때문에 왜곡된 이미지를 인식하게 된다는 것입니다.
**헤드 마운트 디스플레이(HMD)**는 향상된 입체 시야와 넓은 시야 및 HCP와 유사한 헤드 커플링을 결합한 또 다른 단일 사용자 VR 기술입니다. HMD 뒤에 있는 지각 모델은 사용자 눈의 시각적 입력을 완전히 오버레이하고 이를 가상 환경의 포함된 보기로 대체하는 것입니다. 이는 사용자의 눈에 매우 가깝게 하나 또는 두 개의 작은 디스플레이를 장착하는 렌즈 시스템을 통해 달성되어 보다 자연스러운 초점을 맞출 수 있습니다. 디스플레이가 사용자의 눈에 너무 가깝기 때문에 한쪽 눈만 디스플레이의 모든 부분을 볼 수 있어 시스템에 무안경 입체 느낌을 줍니다.
또한 헤드기어에는 사용자 머리의 회전을 추적할 수 있는 방향 추적기가 내장되어 있어 사용자가 가상 카메라의 방향을 사용자의 머리 방향에 바인딩하여 자연스러운 머리 움직임을 사용하여 가상 환경을 둘러볼 수 있습니다. 방향보다는 위치를 추적하는 HCP와 다릅니다. HMD를 지원하기 위한 소프트웨어 요구 사항은 입체 보기와 동일하지만 추가 요구 사항은 그래픽 엔진이 HMD의 방향은 물론 렌즈 시스템으로 인한 왜곡을 수정해야 한다는 것입니다.
지원 수준은 필요한 VR 디스플레이 기술을 구현하는 데 사용할 수 있는 확장 메커니즘을 결정하여 측정됩니다. 이는 무시할 수 있는 차이(예: 스크립트 및 플러그인)가 있는 확장 메커니즘과 결합되었으며 확장이 필요하지 않은(기본 지원) 및 엔진 내 지원이 없는(재설계) 두 가지 추가 수준이 도입되었습니다. 확장 메커니즘은 VR 지원을 구현하는 비엔진 코드에 대한 엔진 코드의 비율에 따라 정렬됩니다. 결과 지원 수준과 순서는 다음과 같습니다.
**5. 기본 지원.**VR 기술을 기본적으로 지원하는 엔진에서 엔진 개발자는 사용자가 최소한의 노력으로 VR 렌더링을 활성화할 수 있도록 특별히 작성된 렌더링 파이프라인을 가지고 있습니다. 필요한 것은 개발자 도구에서 옵션을 확인하거나 엔진의 스크립팅 환경에서 변수를 설정하는 것뿐입니다. 기술을 쉽게 활성화하는 것 외에도 이러한 엔진은 데스크탑 VR 디스플레이에서는 명확하지 않지만 보다 복잡한 기술에서 명백해지는 일반적인 최적화 및 바로 가기를 방지하도록 설계되었습니다. 일반적인 예는 올바른 폐색이지만 깊이가 잘못된 개체를 렌더링하는 것입니다. 이로 인해 입체경 아래에서 깊이 큐가 충돌하게 됩니다.
**4. 엔진 내 그래픽 사용자 정의(노드 그래프 포함)를 통해.**일부 엔진은 그래픽 인터페이스가 있는 사용자 정의 도구를 사용하여 렌더링 프로세스를 변경할 수 있는 방식으로 설계되었습니다. 한 가지 방법은 렌더링 파이프라인의 다양한 구성 요소를 여러 구성에서 재배치, 수정 및 다시 연결할 수 있는 노드 그래프를 이용하는 것입니다. 지원되는 노드 유형에 따라 노드는 때때로 특정 VR 기술의 효과를 생성하도록 구성될 수 있습니다. 아래 이미지는 포스트 프로세스 파이프라인로 빨간색-청록색 입체 렌더링을 사용하도록 구성된 언리얼 엔진의 머티리얼 편집 인터페이스를 보여줍니다.

**3. 엔진 내 코딩(스크립트 또는 플러그인)을 통해.**각 엔진은 잘 정의되어 있지만 제한된 확장 지점을 사용하여 사용자 정의 코드로 확장할 수 있습니다. 두 가지 일반적인 형태는 제한된 환경에서 실행되는 스크립트와 엔진이 외부에서 컴파일된 코드를 로드하고 실행하는 플러그인입니다. 두 가지 양식 모두 엔진 기능의 하위 집합에 액세스할 수 있지만 플러그인은 스크립트가 액세스할 수 없는 외부 API에도 액세스할 수 있습니다. 메커니즘은 애플리케이션 기능에 따라 구현되는 경우가 많기 때문에 사용자 정의 코드에 사용할 수 있는 엔진 기능은 정확한 렌더링 프로세스를 제어하기보다는 인공 지능, 게임 로직 및 이벤트 순서 지정에 더 적합할 수 있습니다.
**2. 엔진 소스 코드를 통해 수정합니다.**무료 오픈 소스 엔진 외에도 일부 상용 엔진은 적절한 라이센스 계약을 통해 사용자에게 완전한 소스 코드를 제공합니다. 전체 소스 코드에 액세스하면 모든 VR 기술을 구현할 수 있지만 필요한 수정량이 상당할 수 있습니다.
**1. 엔지니어링 혁신을 통해.**위의 사용자 정의 진입점을 제공하지 않는 엔진의 경우에도 재설계를 통해 일부 변경이 이루어질 수 있습니다. 엔지니어링 수정은 프로그램의 일부 작동 원리를 학습하는 것 외에도 일부 기능을 수정하는 리버스 엔지니어링의 한 형태입니다. 렌더링 파이프라인을 완전히 리버스 엔지니어링하는 데 필요한 작업량이 상당할 수 있으므로 최소 침습적 형태의 리엔지니어링이 바람직합니다. 그러한 접근 방식 중 하나는 내부 또는 라이브러리 함수에 대한 호출을 가로채서 사용자 지정 동작으로 바꾸는 함수 후킹입니다. 실시간 그래픽 엔진의 상당 부분은 하드웨어 그래픽 가속을 위해 OpenGL 또는 Direct3D 라이브러리를 사용하므로 이러한 라이브러리는 기능 후크를 통해 순수 시각적 VR 기술을 구현하기 위한 안정적인 진입점을 제공합니다. 이 접근 방식은 3D 게임에 입체 시각을 추가하는 데 효과적인 것으로 입증되었습니다. 또한 이 기사에서는 투영 행렬(glFrustum 및 glLoadMatrix)을 로드하는 OpenGL 함수를 연결하고 원래 프로그램에서 제공하는 고정 원근 행렬을 헤드 결합 행렬로 대체함으로써 이러한 방식으로 헤드 결합 원근을 구현하는 것이 가능하다는 것을 보여줍니다.
사용자 경험에 영향을 미치는 요소는 많습니다. 품질 요소는 본질적으로 디스플레이 하드웨어와 관련되어 있지만 적절한 소프트웨어 디자인은 이러한 문제를 완화할 수 있지만 부주의한 디자인은 새로운 문제를 일으킬 수 있습니다. 소프트웨어로 완화할 수 있는 하드웨어 품질 요소의 예로는 누화(스테레오), A/C 결함(스테레오) 및 추적 지연(HCP 및 HMD)이 있습니다. 이러한 요인들은 각각의 디스플레이 기술에 대해 잘 정립되어 있으므로, 이로 인해 발생하는 문제를 최소화하기 위한 기술은 잘 알려져 있습니다. 해결책은 장면 대비를 줄이고, 시차를 줄이고, 렌더링 대기 시간을 최소화하는 것입니다.
잘못된 소프트웨어 구현은 부주의로 인해 또는 데스크톱 VR 최적화로 인해 VR 효과의 품질에 영향을 미칠 수도 있습니다. 이에 대한 예는 하늘, 그림자, 1인칭 플레이어의 신체 등 어디에서나 특수 레이어에 대한 다양한 채널의 깊이입니다. 데스크톱 VR에서 올바른 폐색을 생성하는 동안 입체경 아래에 양안 시차 큐를 추가하면 잘못된 깊이가 표시되고 두 깊이 큐 사이에 충돌이 발생합니다. 데스크톱 VR의 지배적인 특성으로 인해 이는 드문 문제가 아니며 단순한 타사 구현이 기본 VR만큼 지원되지 않을 수 있음을 보여주는 또 다른 예입니다. 이러한 측면에서 비네이티브 VR 구현이 필요한 기술 요구 사항을 충족할 수 있지만 다른 요소도 고려해야 한다는 점에 유의해야 합니다.
다음 표는 2013년 주류 엔진의 VR 지원을 보여줍니다.
엔진 입체시 헤드 결합 전송 헤드마운트 디스플레이
UDK 4: 그래픽 사용자 정의. Unreal Kismet을 사용하여 듀얼 카메라 리그를 생성하고 머티리얼 편집기를 사용하여 출력용으로 패키징할 수 있습니다. 1: 엔지니어링 혁신. 커스텀 카메라 프로젝션은 엔진에서 액세스할 수 없으므로 소스 코드 액세스 없이 엔지니어링이 필요합니다. 3: 엔진 인코딩. 입체화는 사용자 정의를 통해 이루어지며, 머리 방향은 사용자 정의 DLL을 통해 획득하고 스크립트를 통해 카메라에 바인딩할 수 있습니다.
유니티 3: 엔진 인코딩. 3: 엔진 인코딩. 3: 엔진 인코딩.
크라이엔진 5: 네이티브. 3: 엔진 인코딩. 3: 엔진 인코딩.
오우거 3: 엔진 인코딩. 3: 엔진 인코딩. 3: 엔진 인코딩.
Oculus Rift를 사용한 가상 현실 경험 개발에서는 Oculus Rift의 VR 개발 기술, 프로세스, 실제 운영을 자세히 공유합니다.
2014년 Rift 기술에는 Dev Kit 2, 1920x1080 OLED 화면, 각 눈의 절반, 광각 원형 렌즈, 90-110도 FOV, GPU 수정 가능한 렌즈 왜곡, 낮은 지속성 – 프레임당 픽셀당 3밀리초 미만의 밝기, 1000Hz 자이로 추적 방향, 60Hz 위치 추적이 포함됩니다. 외부 카메라는 HMD의 LED 배열, 소프트웨어 융합, 방향 및 위치 예측을 볼 수 있습니다.
VR 플레이어에게 친절하게 대하십시오. VR 개발자는 하루에 몇 시간씩 HMD를 살펴보며 대부분의 경우 곳곳에 버그가 있을 것입니다. 두뇌는 미친 사람들을 무시하는 법을 빨리 배우겠지만, 플레이어는 그렇지 않습니다! 그들의 두뇌는 신선하고 순수하며, 모든 것이 현실이 되기를 원하며, 모든 것을 디버깅하고 진정한 "존재감"을 갖기를 원합니다. 모든 것을 11로 밀어붙이면 그들에게 충격을 주고 게임 플레이를 중단하고 별점 1개를 줄 것입니다!
모든 사람은 매우 다르며, 어떤 사람들은 다른 사람들이 볼 수 없는 것을 참지 못합니다. "VR 허용 오차" 슬라이더는 없으며, 한 측면에 매우 민감한 사람은 계단을 오르내리는 것과 같은 다른 측면을 견딜 수 있습니다. 관용은 단지 배울 수 있는 기술이 아닙니다. 부정적인 피드백이 있을 수 있습니다. 사람들은 노출에 대해 덜 관대해질 것입니다. 모범 사례 지침에는 현재 알려진 내용이 포함되어 있으므로 이를 최소한 진지하게 생각해 볼 수 있는 사항의 체크리스트로 사용하십시오.
약간 틀리거나 지나치게 강렬한 VR은 줄거리와 게임 메커니즘을 이해하기 어렵게 만들고, 긴장된 경험을 선택 사항으로 만들고, "얼굴에 닿는" 입자와 폭발을 피하려고 노력하고, 덜 느린 움직임을 피하려고 합니다. 기본값은 낮은 난이도로, 초보자가 "선택 해제"하도록 허용하는 대신 경험이 많은 VR 사용자가 "선택"할 수 있도록 하여 언제든지 쉽게 변경할 수 있도록 하고 "VR 히트"를 받은 후 실제로 게임을 플레이하는 강도를 낮출 수 있습니다.
VOR(Vestibulo-Optical Reflex): 안구와 근육, 반사 뉴런, 귀의 반고리관 등의 부위와 상호 작용은 다음과 같습니다.

정지된 물체, 움직이는 머리 등 "고정"에 사용되며, 머리 회전이 귀를 통해 감지되며, <10밀리초 후에는 스캔이 아닌 눈이 부드럽게 움직입니다! 매우 부드럽고 뛰어난 시각적 품질.
VOR 게인은 귀 움직임과 눈 반응 간의 비율로, 일반적으로 1:1 보상, +10⁰ 머리 움직임 = -10⁰ 눈 움직임을 제공하며, 고정 중에 미세 조정되고 "망막 흐름"이 0이 되도록 노력하며 매우 느리게 조정됩니다.
뷰가 압축되면 어떻게 되나요? 새로운 안경, VR의 렌더링 스케일이 올바르지 않습니다. 이제 10⁰ 머리 움직임에는 고정을 유지하기 위해 -5⁰ 눈 움직임이 필요합니다. VOR 이득은 이제 망막 흐름을 유발하여 방향 감각 상실을 유발하며 이득 적응에는 1-2주가 걸립니다(계속 사용한다고 가정!).

VOR 게인 보존: 모니터의 게임에는 일반적으로 모니터에서 허용되는 "FOV" 슬라이더가 있습니다. VOR 게인에 직접적인 영향을 주지 않고 모니터가 머리와 함께 움직이지 않습니다. "가상 응시"가 발생하지 않으며 실내 주변 시야는 실제 광학 흐름 타당성 검사를 제공합니다. 하지만 그럼에도 불구하고 일부 사람들에게는 문제가 발생할 수 있습니다. Rift에서 유일한 관심사는 VR 객체의 망막 흐름이 실제 동작과 일치해야 하는 가상 현실입니다. VR의 시야 비율은 임의의 선택이 아닙니다! "박사님, 제가 이렇게 하면 플레이어의 뇌가 아프네요..."라는 HMD+ 사용자 특성과 일치해야 합니다.
Rift 디스플레이에는 물리적 간격, 즉 "가시성당 픽셀 수"가 있으며 정확한 값은 왜곡, 사용자의 머리 및 눈 위치 등에 따라 다릅니다. SDK는 사용자 구성 도구를 통해 발견된 피치를 정확하게 일치시키는 데 도움을 주며 지정된 장치 및 사용자 크기에 대한 올바른 시야 및 크기를 제공하여 시야 변화 또는 "줌" 효과를 방지합니다. 머리를 10도 회전하면 광학 흐름이 10도 생성되어야 하며 각도당 픽셀이 조금만 변경되어도 문제가 발생합니다. 대부분의 사용자.
IPD - 동공 간 거리에는 실제로 각 눈에 두 가지 구성 요소가 있습니다. 즉, 코에서 동공까지("절반 IPD"), 시청 거리(HMD 크기에 관계없이 렌즈 표면에서 동공까지의 거리)입니다! 중심-눈 벡터는 사용자 구성 중에 설정되고 사용자 구성 파일에 저장됩니다. 거의 대칭이 아니며, 일부 사람들의 시청 거리는 2밀리미터씩 다를 수 있으며, 아래 그림에서 남자의 코와 눈동자는 1픽셀 떨어져 있습니다.

중앙 동공 - SDK에서 보고한 위치, 헬멧 디스플레이의 중심선, 왼쪽 및 오른쪽 시야 거리의 평균입니다. 플레이어가 자신이 있는 곳을 "느끼는" 대략적인 위치, 오디오 청취자 위치, 시선 확인, 십자선/십자선 레이캐스트 원점.

프레임 속도 유지: 존재 여부는 매우 이분법적인 것입니다. 유무에 관계없이 견고한 높은 FPS는 VR에서 존재감을 느끼는 데 매우 중요합니다. 75FPS로 스테레오로 표시하는 것은 어렵고, 프레임 속도와 대기 시간을 낮게 유지하기 위해 디테일과 효과를 적극적으로 제거하고, 상태 유지는 추가 효과보다 플레이어에게 훨씬 더 많은 재미를 제공하며, 주요 비용은 드로우 콜과 필 속도입니다.
그리기 호출의 경우 눈을 두 배로 늘리고 호출을 두 배로 늘리면 새 API는 Mantle(Vulkan의 이전 버전), DX12 등 여러 제출 비용을 줄여야 합니다. 일부 작업은 한 번만 수행하면 됩니다. 컬링 - 양쪽 눈, 애니메이션, 그림자 버퍼 렌더링, 일부 원거리 반사/광택 맵/AO 렌더링을 포함한 보수적 프러스텀 사용 - 하지만 전부는 아닙니다! 일부 지연 조명 기술.
채우기 속도의 경우 프레임 버퍼 크기가 아닌 가상 카메라 렌더링의 크기를 변경하십시오. 예를 들어 DK2의 경우 프레임 버퍼는 항상 1080x1920입니다. 이를 변경하지 마십시오! 그러나 카메라 눈은 일반적으로 프로필 및 SDK에서 설정한 사용자 얼굴 모양과 눈 위치에 따라 눈당 1150x1450을 렌더링합니다. 이 렌더의 크기 조정은 매우 잘 작동하고, 왜곡 보정 프로세스는 이를 다시 샘플링하고 필터링하며, 프레임당 동적 크기 조정도 좋습니다. 거의 눈에 띄지 않습니다. 프레임에 입자/폭발이 많으면 크기를 줄이세요. 동일한 RT를 사용하면 매우 짧은 시간만 필요하며 SDK는 이 사용 사례를 명시적으로 지원합니다.
가상 현실과 차세대 엔진을 최대한 활용하는 방법은 게임 엔진에 VR 렌더링을 통합하는 방법을 설명합니다. 기사에서는 조정 가능한 안경 착용자를 언급합니다.

조정 없이 동공 간 거리의 변화를 허용합니다.

아래 그림은 주요(상단) 및 허용 가능한 매개변수의 다이어그램입니다.

입체 3D의 경우 사진 입체 및 헤드 마운트 디스플레이에 대한 고정 설정에서 필요한 초점 거리 요구 사항은 다음과 같습니다.

아래 그림과 결합하면 (a) 대부분의 HMD는 좁은 시야각을 가지며, (b) 넓은 시야를 얻으려면 더 높은 해상도의 디스플레이가 필요하며, (c) 더 큰 픽셀이 필요합니다. (d) 두 세계의 장점을 모두 활용하는 방법은 무엇입니까? 눈의 다양한 시력을 활용하여 (e) 워프 셰이더를 사용하여 이미지의 가장자리를 압축하고, (f) 광학 장치가 역왜곡을 적용하여 가장자리가 다시 올바르게 보이도록 하고, (g) 중앙 픽셀은 더 작고 가장자리 픽셀은 더 큽니다.

VR 개발에서는 다음 사항에 주의해야 합니다.
플레이어의 머리를 통제하지 마세요!
1인칭 액션에 주의하세요.
사진 사실주의는 필요하지 않습니다.
영화적 렌더링을 사용하지 마세요! 가변 초점, 필터, 렌즈 플레어, 블룸, 필름 그레인, 비네팅, 뎁스 오브 필드(DoF) 등.
스테레오 렌더링 품질 확인:
왼쪽, 오른쪽 방향이 맞나요?
양쪽 눈의 성분이 동일한가요?
두 이미지가 모두 같은 시간을 나타내는가?
저울이 맞나요?
깊이가 일정합니까?
-빠른 깊이 변화를 피했나요?
VR 기능을 게임 엔진에 통합하려는 경우 각 엔진은 다르지만 항상 몇 가지 유사점이 있다는 점에 유의해야 합니다. 좋은 VR 엔진이란 무엇입니까? 대답은 다음과 같습니다.
- 고품질 시각 효과.
고품질의 영상이란 무엇을 의미합니까? 게임 플레이에 방해가 되는 요소는 없으며 좋은 음영처리(반드시 사실적일 필요는 없음)는 일반적으로 좋은 앤티앨리어싱을 의미합니다.
좋은 앤티앨리어싱이 중요한 이유는 무엇입니까? 인간 인식의 특성상 우리는 고주파 소음으로 인해 쉽게 주의가 산만해지며, 주의가 산만해지면 존재감이 줄어들 수 있고, 입체 렌더링을 사용할 때 앨리어싱 아티팩트가 더 심해질 수 있고, 망막 경쟁을 유발할 수 있으며, 좋은 앤티앨리어싱이 기본 해상도보다 더 중요합니다.
앤티앨리어싱 방법은 다음과 같습니다. 가장자리 기하학 AA, 일반적으로 하드웨어 가속; FXAA, MLAA, SMAA 등과 같은 대부분의 렌더링 파이프라인에 매우 적합한 이미지 공간 AA 시간적 슈퍼샘플링을 위해 재투영을 사용하는 시간적 AA.


MSAA는 빈도가 높은 기하학, 거의 수직선, 대각선에서 더 잘 보이지만 내부 텍스처/음영은 여전히 앨리어싱됩니다.


FXAA는 가장자리 형상, 질감/음영 세부 정보에서 더 잘 보이지만 고주파수 데이터에서는 세부 정보가 손실되는 경우가 있습니다.
오버샘플링 앤티앨리어싱은 더 큰 버퍼로 렌더링하는 것이 잘 작동합니다. 여유가 있는 경우 좋은 다운샘플링 필터와 함께 사용하면 됩니다.

앤티앨리어싱 결과: Specular AA는 이미지를 크게 향상시킬 수도 있습니다. 좋은 출발점은 LEAN, Cheap LEAN(CLEAN) 및 Toksvig AA를 살펴보는 것입니다. 왜곡 셰이더는 가장자리 앨리어싱을 줄입니다. 일부 게임에서는 LOD에 더 많은 주의를 기울여야 할 수도 있습니다.
여러 AA 방법을 조합하면 엔진에 가장 적합한 방법을 사용하여 앨리어싱의 다양한 측면을 처리하는 각기 다른 AA 솔루션을 통해 더 나은 결과를 얻을 수 있습니다.
- 일관되게 높은 프레임 속도.
일관된 높은 프레임 속도가 중요한 이유는 무엇입니까? VR에서 낮은 프레임 속도는 모양과 느낌이 좋지 않으며, 높은 프레임 속도가 없으면 테스트가 어렵습니다. 개발 전반에 걸쳐 높은 프레임 속도를 유지하면서 V-Sync가 없다는 점은 더욱 눈에 띄므로 V-Sync가 활성화되어 있는지 확인하십시오.
현재 엔진에서는 반사 렌더링, 그림자 렌더링, 포스트 프로세스 등 "채널" 개념이 널리 수용됩니다. 각 채널마다 요구 사항이 다르며 각 채널에서 병목 현상을 찾아야 합니다. CPU? 드로우콜? 상태 설정? 리소스 설정? GPU? 버텍스 처리가 제한되어 있습니까? 기하학 처리가 제한되어 있습니까? 픽셀 처리가 제한되어 있나요?
그리기 호출, 상태 설정 또는 리소스 설정 중에 CPU가 제한됩니까? 지오메트리 셰이더를 사용하면 총 그리기 호출 수, 섀도우 캐스케이드 렌더링(drawCallCount/n), 여기서 n은 캐스케이드 수, 큐브맵 렌더링(drawCallCount/6) 수를 줄일 수 있는 방법을 고려하세요. 리소스 설정 비용을 줄이고 CPU에서 처리를 이동하는 데 도움이 되는 기타 기능을 갖추고 있습니다.
지오메트리 렌더링 유닛은 픽셀 셰이더 이전, 즉 직접 버텍스 픽셀 그리기 호출의 버텍스 셰이더 이후 또는 테셀레이션이 활성화된 경우 헐 셰이더 이후에 발생하는 하나의 기본 스트림을 다른, 가능한 더 큰 기본 스트림으로 변환합니다.
지오메트리 셰이더 기능, 렌더 대상 인덱스/뷰포트 인덱스, 단일 패스 큐브맵 렌더링, 섀도우 캐스케이드, S3D, GS 인스턴스를 통해 이전 셰이더 단계를 다시 실행할 필요 없이 동일한 지오메트리 셰이더를 기본 단위별로 여러 번 실행할 수 있습니다.
입체 3D 렌더링을 위한 지오메트리 셰이더는 엔진을 입체 3D와 호환되게 만드는 간단한 방법으로 다음과 같이 각 재질에 GS를 추가하거나 기존 재질의 GS를 조정합니다.
[maxvertexcount(3)]
void main(
inout TriangleStream<GS_OUTPUT> triangleStream,
triangle GS_INPUT input[3])
{
for(uint i = 0; i < 3; ++i)
{
GS_OUTPUT output;
output.position = (input[i].worldPosition , g_ViewProjectionMatrix);
triangleStream.Append(output);
}
}버텍스/형상이 제한되어 있습니까? 속성을 압축하고 셰이더 단계 사이의 모든 속성을 패킹하여 버텍스 크기를 줄입니다. 이는 업스케일링 또는 테셀레이션 파이프라인에 지오메트리 셰이더를 사용하는 경우 중요합니다. 늦은 가져오기 접근 방식 사용을 고려하세요. 버텍스 어트리뷰트 데이터를 사용된 셰이더 단계의 버퍼로 바인딩하고 하드웨어에 크게 의존하며 항상 성능을 디버깅하고 영향이 있는지 확인하세요! GPU 주위로 이동하는 데이터를 줄입니다.
픽셀이 제한되어 있나요? 픽셀 셰이더 복잡성 감소, 프레임당 음영 처리된 픽셀 수 감소, 더 작은 렌더 타겟을 사용한 실험적 업샘플링은 고품질 비주얼과 충돌하여 후광, 쉬머 및 망막 충돌을 도입합니다.
재투영을 사용하여 입체 3D 렌더링 속도를 높이는 것을 고려해보세요. PlayStation 3 스테레오 3D 게임에서 큰 성공을 거두었지만 시차가 작은 경우에만 성공적으로 사용할 수 있습니다.
- 우수한 추적 및 교정.
Project Morpheus SDK는 SDK에서 제공하는 추적 매트릭스를 사용하여 추적을 처리합니다. 게임 정의 기본 보기 위치 및 방향:

카메라에서 플레이어 머리의 오프셋을 추적합니다.

머리 매트릭스를 기준으로 한 플레이어 눈의 오프셋:

추적기 재설정 기능: 게임 카메라의 위치 및 요에 맞춰 머리 위치를 설정합니다.
교정: 위치 및 방향 추적을 재설정하고 게임 세계와 실제 세계 간의 관계를 다시 조정하여 고정된 플레이어 위치, 패스 앤 플레이, 다양한 높이의 플레이어와 일치하도록 합니다.
- 낮은 대기 시간.
지연 시간을 줄이는 것이 왜 그렇게 중요한가요? 지연 시간은 입력과 응답 사이의 시간이며, 중요한 것은 지속적으로 높은 프레임 속도만이 아닙니다. VR 헤드 트래킹뿐만 아니라 게임에서도 반응성을 향상시키는 것이 매우 중요합니다. 게임 프로그래머는 반응형 제어의 필요성을 이해하고, 네트워크 프로그래머는 반응형 상대의 필요성을 이해하고 있습니다.
다중 컨텍스트 렌더링: 엔진 관점에서 대기 시간을 줄이는 한 가지 방법은 지연된 컨텍스트를 사용하여 여러 스레드에서 비동기적으로 명령 목록(명령 버퍼라고도 함)을 구축하는 것입니다. 즉각적인 컨텍스트로서, 명령 버퍼에 명령을 대기열에 넣을 때 렌더링 오버헤드가 있습니다. 이에 비해 명령 목록은 재생 중에 훨씬 더 효율적으로 실행되며 "채널" 개념이 적용됩니다. 다중 컨텍스트 렌더링을 사용하면 GPU가 프레임 초기에 처리를 시작하여 대기 시간을 줄일 수 있습니다.

단일 컨텍스트(상단)와 다중 컨텍스트(하단) 렌더링 비교.
다중 컨텍스트 렌더링을 위한 가장 간단한 테스트 사례: 각 눈의 보기에 대한 명령 목록의 병렬 생성 및 제출, CPU 프레임 시간의 즉각적인 감소, 즉 엔진이 CPU에 바인딩된 경우 프레임 대기 시간이 즉시 감소됩니다. 엔진이 GPU에 바인딩되어 있지만 GPU가 더 일찍 시작되었기 때문에 이제 프레임에서 더 일찍 완료되는 경우 프레임 대기 시간이 즉시 줄어듭니다.
VR에 대한 지연 시간 고려 사항: 지연 시간을 처리하는 VR 관련 방법이 있습니까? 추적 데이터 샘플링과 해당 데이터를 사용하여 프레임을 렌더링하는 사이의 시간은 최대한 짧아야 하며, 버퍼를 두 배 이상 사용하지 않아야 합니다. 최신 방향 데이터를 사용하여 이미지를 다시 투영하면 대기 시간과 프레임 속도가 눈에 띄게 향상될 수 있습니다. 추적되는 주변 장치의 대기 시간을 최대한 줄이기 위해 대기 시간을 처리하는 플랫폼별 방법이 있습니까?
예측: Project Morpheus가 포함된 PlayStation 4는 알려진 시스템입니다. 하드웨어의 지연, 라이브러리/소프트웨어의 지연을 줄이는 방법을 찾아야 합니다. 이미지가 표시될 때 HMU의 위치를 예측하는 데 사용할 수 있는 게임 지연 시간을 개발자가 계산하고 줄일 수 있는 CPU 및 GPU 성능 분석 도구를 제공합니다. 엔진 대기 시간을 줄이는 것이 중요하지만, 예측을 사용하여 남아 있는 작은 지연을 마스킹하는 것이 효과적일 수 있으며, 지정하는 예측 양이 작을수록 품질이 향상됩니다.
이제 VR에 최적화된 매우 효율적이고 높은 프레임 속도, 낮은 대기 시간, 초고품질 차세대 엔진에서 뛰어난 추적 기능을 갖추고 있다고 가정하면... 엔진의 작업이 완료된 것인가요? 물론 그렇지 않습니다! 또한 플랫폼별 최적화, 주변 장치 추적, 사회적 측면, 게임 플레이/디자인 요소 등에 대한 작업도 있습니다.
비동기 컴퓨팅: 여전히 CPU에 묶여 있나요? 아마도 Compute는 병렬화 가능한 작업을 GPU로 오프로드하는 데 도움이 될 수 있습니다. 여전히 GPU가 제한되어 있나요? 컴퓨팅을 사용하면 GPU 활용도가 낮은 곳에서 GPU 작업을 좀 더 일반적인 관점으로 생각할 수 있습니다. 그림자 렌더링에는 버텍스/형상이 필요한 경우가 많으므로 비동기 컴퓨팅 작업을 예약하기에 좋은 장소입니다.
Oculus와 함께 VR 세계에 뛰어들어 Oculus의 VR 개발 전략을 설명합니다.
가상 현실에서 가장 중요한 요소는 낮은 지속성, 대기 시간, 현실성입니다.
Oculus SDK 0.4.x의 기능: 새로운 C 인터페이스인 DK1 및 DK2를 지원합니다. 새로운 SDK를 사용하여 게임을 다시 컴파일하세요. 위치 추적의 경우 위치 원점은 현재 카메라에서 1m 떨어져 있습니다. SDK는 예측된 포즈 상태를 사용하여 방향, 위치 및 파생물을 포함한 센서 상태를 보고합니다. 추적 범위를 초과하면 플래그 프롬프트가 제공됩니다. 헤드 모델, Direct-to-Rift 및 확장 모드, OVR 구성 도구를 활용하세요.
OVR 소프트웨어 스택은 아래와 같습니다. C 인터페이스: 다른 언어와의 연결 용이, 드라이버 DLL: 하드웨어 및 기능 변경 자동 지원, OVR 서비스: 애플리케이션 간 리프트 공유 및 가상 현실 변환.

SDK 렌더링과 게임 렌더링 비교: SDK 0.2는 렌더링을 수행하지 않으며 적절한 렌더링에 필요한 매개변수만 제공합니다. SDK 0.4의 새로운 렌더링 백엔드는 주요 렌더링 기능을 계속합니다. 게임(앱) 레이어는 SDK 왼쪽 및 오른쪽 눈 텍스처 ovrHmd_EndFrame()을 제공합니다.
SDK의 일반적인 작업 흐름:
ovrHmd_CreateDistortionMesh. UV를 통해 이미지를 변환하는 것은 픽셀 셰이더 렌더링보다 더 효율적이므로 Oculus가 왜곡을 더 유연하게 수정할 수 있습니다.
ovrHmd_BeginFrame.
ovrHmd_GetEyePoses.
EyeRenderPose(게임 장면 렌더링) 기반의 입체 렌더링.
ovrHmd_EndFrame.
다음 기능을 갖춘 SDK 0.4의 완벽한 렌더링: 색수차 및 시간 왜곡을 사용한 배럴 왜곡, 내부 대기 시간 테스트 및 모션 예측, 낮은 대기 시간 수직 동기화(v-sync) 및 롤오버(직접 리프트 사용, 더 나은 기능 포함), 건강 및 안전 경고.
SDK는 통합이 쉽고 장치/시스템 포인터 및 눈 텍스처를 통해 셰이더 및 메시를 생성할 필요가 없으며 OpenGL 및 D3D9/10/11을 지원하며 다음 프레임에 대한 렌더링 상태를 다시 적용해야 합니다. 이점: 향후 Oculus 하드웨어 및 기능과의 호환성 향상, 그래픽 카드 설정 오류 감소, 전면 버퍼 렌더링 등과 같은 대기 시간이 짧은 드라이버 디스플레이 액세스 지원, 자동 적용 범위 지원: 지연된 테스트, 카메라 가이드, 디버그 데이터, 관점, 플랫폼 적용 범위.
SDK 렌더링을 사용하기 위해 Unreal Engine 3, Unreal Engine 4 및 Unity와 같은 주류 게임 엔진을 지원합니다.
확장 모드: 헤드셋이 OS 디스플레이로 표시되고, 앱이 Rift 모니터에 창을 배치해야 하며, 아이콘과 창이 잘못된 위치에 있고, Windows 컴포지터가 Present를 처리하며, 일반적으로 최소 1프레임 지연이 발생하며, CPU 및 GPU 동기화가 완료되지 않은 경우 그 이상 지연됩니다.
Direct To Rift: Rift로 출력되며 디스플레이가 데스크탑의 일부가 되지 않습니다. 헤드셋은 운영 체제에서 표시되지 않습니다. 창과 아이콘 점프를 방지하고, OS 컴포지터에서 Rift 수직 동기화(v-sync)를 분리하고, 추가 GPU 버퍼링을 방지하고, 대기 시간을 최소화하고, ovrHmd_AttachToWindow를 사용하고, 창 스왑 체인 출력이 Rift로 전달됩니다. 직접 모드가 장기적인 솔루션이 되기를 바랍니다.
지연: 동작, 센서, 처리 및 병합, 렌더링, 스캔아웃, 전송, 픽셀 변경 시간, 픽셀 지속성 등 여러 단계를 포함하는 동작-광자 지연.

지연 시간을 낮게 유지하는 것은 좋은 VR 경험을 제공하는 데 핵심이며 목표는 20ms 미만, 희망적으로는 5ms에 가깝습니다.
렌더링 지연 - 시간 왜곡: 변형과 동시에 렌더링을 이후 시점으로 다시 지연하여 인지된 지연을 줄입니다. DK2 롤링 셔터를 담당하고 SDK 0.4는 방향과 위치를 처리합니다. 프레임이 끝나기 전에 센서를 사용할 수 있는 다른 방법이 있나요? Time Warp – 예측 렌더링(John이 개척).



멀티코어 및 big.LITTLE을 위한 프로그래밍에서는 ARM의 크고 작은 코어의 특수 CPU 병렬 아키텍처에 대해 설명합니다. 이 아키텍처는 다양한 컴퓨팅 강도의 작업을 다르게 처리하여 절전과 성능 사이의 균형을 이룰 수 있습니다.
멀티 코어 및 대형 사례.LITTLE 멀티 프로세싱: 플랫폼 추세: 중급에서 고급으로 쿼드+코어가 확실히 증가하고 모든 것이 점점 더 커지고 있습니다. - LTE, GPU, 카메라, 디스플레이, 단일 스레드 성능 개선이 감소하고 있습니다. 멀티 코어에 초점을 맞추세요. 단순히 성능에 관한 것이 아니라 열적으로 제한된 사용 사례가 이제 일반화되었습니다. 소프트웨어 동향: 운영 체제 공급업체는 멀티 코어를 더 많이 활용하고, 멀티 프로세싱 지원 라이브러리를 더 폭넓게 살펴보고, 증강 현실과 같은 장치 조합의 사용을 늘리고 있습니다.
병렬성을 활용하면 코어에서는 NEON과 SIMD를 사용할 수 있고, 병렬 도구(OpenMP, Renderscript, OpenCL 등), 멀티스레드를 최대한 사용할 수 있습니다. 결코 쉬운 일은 아니지만 점점 더 필요해지고 있습니다.
2014~2015년 멀티 코어 동향: Cortex-A15/Cortex-A7 big.LITTLE의 2014년 고급 제품, 코어 수 범위: 4(2+2), 6(2+4) 및 8(4+4) 코어, Cortex-A17/Cortex-A7(32b)은 2015년에 출시될 예정입니다. 2014년에는 ARMv8-A (64b) 칩셋은 쿼드 코어 및 옥타 코어 Cortex-A53이 보급형 및 중급형에 진입하는 등 모든 시장 부문에서 두각을 나타냈으며 고급 모바일 장치는 2015년에 A57 및 A53 big.LITTLE로 마이그레이션될 것으로 예상되며 여러 big.LITTLE 토폴로지가 예상됩니다. 새로운 소형 프로세서는 Cortex-A9와 유사한 성능을 제공하며 Cortex-A15와 같은 대형 프로세서를 사용하면 성능이 크게 향상됩니다.

프로그래머의 하드웨어 관점에서 본 Big.LITTLE 시스템: 고성능 Cortex-A57 CPU 클러스터, 에너지 절약형 Cortex-A53 CPU 클러스터, CCI-400은 클러스터 간 캐시 일관성을 유지하고 GIC-400은 투명한 가상 인터럽트 제어를 제공합니다.

big.LITTLE: Quad Cortex-A15를 갖춘 4+4MP 시스템의 증거:

big.LITTLE 개발 / GTS(Global Task Scheduling)에 대한 일반적인 조언:
스케줄러를 신뢰하세요. Linux는 성능과 효율성을 위한 일정을 설정하고 모든 새로운 작업은 지연을 방지하고 작업 요구 사항에 빠르게 적응하기 위해 큰 화면에서 시작됩니다.
스레드가 집중적이지만 중요하지 않고 작은 코어에서 실행될 수 있다는 것을 알지 않는 한 큰 코어를 사용하지 마십시오. 예를 들어 작은 코어는 별도의 스레드에 자산을 로드하는 데 사용될 수 있습니다.
작은 코어가 좋습니다. 많이 사용하게 될 것이며 Cortex-A53은 Cortex-A9보다 20% 더 나은 성능을 발휘하며 대부분의 워크로드는 더 적은 수의 서버에서 실행되므로 다른 SoC 구성 요소에 더 많은 열 헤드룸이 남습니다.
큰 핵심은 중요한 동기 부여입니다. 이를 물리 기반 특수 효과와 같은 단펄스 가속기로 생각하고 설계 과정에서 절충점을 고려하십시오.
피해야 할 사항:
공통 데이터를 공유하는 불균형 스레드. 클러스터 일관성은 훌륭하지만 무료는 아닙니다.
실시간 스레드가 있는 경우 실시간 스레드는 자동으로 마이그레이션되지 않으며 실시간 스레드는 설계 결정이므로 선호도를 신중하게 고려하십시오.
대규모 코어에서 장기 실행 작업을 실행하지 마세요. 긴 처리 능력이 거의 필요하지 않은 이 작업을 병렬화할 수 있습니까?
2014년 Big.LITTLE 및 HMP(Global Task Scheduling) 장치: 장기 실행 작업 부하를 위한 에너지 효율적이고 지속 가능한 컴퓨팅을 위한 최고의 성능; 멀티프로세싱: 단일 스레드 성능의 한계를 뛰어넘고 성능에 대한 열 제약을 방지합니다.
NEON은 ARM 명령어 세트의 확장인 광범위한 SIMD 데이터 처리 아키텍처입니다. 레지스터 32개, 폭 64비트(이중 보기에서는 레지스터 16개, ARMv7에서는 폭 128비트), NEON 명령어는 "패킹된 SIMD" 처리를 수행하고, 레지스터는 동일한 데이터 유형 요소의 벡터로 처리됩니다. 데이터 유형: 부호 있는/부호 없는 8비트, 16비트, 32비트, 64비트, 단일/이중 정밀도, 부동 소수점 또는 정수. 명령어는 모든 스레드에서 동일한 작업을 수행합니다.

범용 SIMD 처리는 다양한 애플리케이션에 적합합니다.
인터넷 애플리케이션을 위한 가장 광범위한 멀티미디어 코덱을 지원합니다. 다양한 소프트 코덱 표준: MPEG-4, H.264, ON2VP6/7/8/9, Real, AVS..., 모든 인터넷 및 디지털 홈 표준이 소프트웨어에서 지원됩니다.
더 적은 주기가 필요합니다. NEON은 복잡한 비디오 코덱에서 1.6x-2.5x 성능을 제공하며 단일 간단한 DSP 알고리즘으로 훨씬 더 큰 성능 향상(4x-8x)을 보여줄 수 있습니다.
, 프로세서가 더 빨리 절전 모드로 전환될 수 있습니다 => 전반적인 동적 에너지 절약.
- 프로그래밍이 쉽습니다. 2D/3D 그래픽 및 기타 처리, 기성 도구, 운영 체제, 상용 및 오픈 소스 생태계 지원을 위해 코덱뿐만 아니라 광범위한 데이터 집약적 계산을 위한 명확한 직교 벡터 구조입니다.
NEON의 최적화 경로:
OpenMAX, libav, libjpeg, Android Skia 등 오픈소스 라이브러리, 오픈소스 최적화가 무료로 제공됩니다.
벡터화 컴파일러. 기존 소스 코드, 상태: 릴리스(DS-5 armcc, CodeSourcery, Linaro gcc 및 현재 LLVM)로 NEON SIMD를 자동으로 활용합니다.
NEON 명령어 세트. NEON 작업을 위한 C 함수 호출 인터페이스는 NEON에서 지원하는 모든 데이터 유형과 작업을 지원합니다. 상태: 릴리스됨(DS-5 및 gcc에서), LLVM/Clang은 개발 중입니다.
어셈블러. 실제로 낮은 수준에서 최적화하려는 경우 상태: 릴리스됨(DS-5 및 gcc/gas에서).
상업 채널. 기성 패키지를 최적화하고 지원합니다.
Arm의 각 세대 아키텍처 다이어그램:

ARMv7-A에서 ARMv8-A로의 발전:

예외 수준 및 상호 작용 처리:

OpenGL ES 3.0 이상: 모바일 플랫폼에서 데스크탑 그래픽을 제공하는 방법에서는 OpenGL ES 3.0을 사용하여 모바일 측에서 데스크탑과 유사한 그래픽 기능을 개발하는 방법을 설명합니다.
OpenGL ES 3.1은 2014년에 출시되었습니다. 당시 Android 애플리케이션의 비율은 62%에 달했고 ES 3.0의 사용률은 8%에 달했습니다.

OpenGL ES 3.0의 새로운 기능:
- 주요 새로운 기능:
다중 렌더 타겟
폐색 쿼리
인스턴스 렌더링
UBO(Uniform Buffer Object) 및 균일 블록
피드백 변환
기본 재시작
서수 이진
향상된 텍스처링 기능:
스위즐(Swizzle), 3D 텍스처, 2D 배열 텍스처, LOD/MIP 레벨 고정 장치, 심리스 큐브맵, 불변 텍스처, NPOT 텍스처, 샘플러 객체
- 새로운 렌더 버퍼 및 텍스처 형식:
부동 소수점 형식
공유 지수 RGB 형식
ETC/EAC 텍스처 압축
깊이 및 깊이/템플릿 형식
단일 및 이중 채널 텍스처(R 및 RG)
ES 셰이딩 언어 버전 3.00:
32비트 정수/부동 소수점 데이터 유형(IEEE754)을 완벽하게 지원합니다.
입력/출력 저장 한정자, 후속/이전 파이프라인 단계에서 복사된 값.
배열 생성자 및 작업
새로운 내장 기능
인스턴스화와 비인스턴스화의 비교:

Intel Bay Trail 플랫폼의 OpenGL ES 3.1:

OpenGL ES 3.1 - 컴퓨팅 셰이더 모델:

OpenGL ES 3.1 EXT 확장 – 테셀레이션 셰이더:

OpenGL ES 3.1 Intel 확장 – 픽셀 동기화:
- 개념
인텔 OpenGL | ES 확장: GL_INTEL_fragment_shader_ordering
셰이더에서 동기화된 비순차적 메모리 액세스 허용
동기화 지점에서 셰이더에 단일 내장 기능을 추가합니다: BeginFragmentShaderOrderingINTEL();
혜택
동일한 픽셀에 매핑된 조각에 액세스하기 위해 정렬되지 않은 메모리를 사용하면 데이터 경합이 발생할 수 있습니다.
조각은 순차적으로 음영처리될 수 있습니다.
신청
OIT
프로그래밍 가능한 믹스
적응형 체적 그림자 매핑
잠깐
Assassin's Creed Identity: 벤치마크 모바일 게임을 만들어보세요! 엔진 선택, 콘텐츠 제작, 아키텍처 개요, 게임 로직, 통합 에디터 확장 등 고성능 모바일 게임을 만드는 방법을 설명합니다.
사용되는 엔진에는 신속한 프로토타이핑 지원이 필요합니다. 즉, 애니메이션 기반 게임을 지원하는 배우기 쉬운 환경과 편집기 프레임워크가 이해하기 쉬워야 합니다. 모바일 친화적이고 아티스트 중심적이며 확장 가능한 도구, 유연한 라이센스 조건(예: iOS 및 Android는 일부 엔지니어에게만 사용 가능)에 중점을 둡니다.
아키텍처를 설계할 때 몇 가지 우선순위를 따르십시오. 우선순위 1: 다기능 업무를 촉진하기 위해 협력합니다. 우선순위 2: 사람들이 계속 일할 수 있도록 하고 빌드를 중단하지 마십시오. 우선순위 3: 민첩성을 유지하고 계획을 분리하며 처리를 간소화합니다.

전제조건: 게임 로직을 Unity 로직과 최대한 분리하세요. Unity 엔진의 Mono 동작을 제어하고 디버깅하는 것은 어려운 일로 간주됩니다. 첫 번째는 게임 로직 엔터티의 업데이트 시간을 최적화하는 것입니다.

제한된 수의 3D 캐릭터를 (재)사용하세요.

Unity 엔진의 엔터티 구성 요소 모델을 다시 작성하는 이유는 무엇입니까? 실행, 깨우기, 업데이트 및 수정 업데이트는 Assassin's Creed 팀이 원하는 세밀한 제어 제어를 허용하지 않습니다. 복합 개체는 프리팹을 통해서만 복제할 수 있으며 다음과 같이 보여야 합니다.
public class PlayerCharacter: AssassinCharacter, IPlayerCharacterStateMachinesCarrier,IPlayerEventHandlerCarrier, IParticipantCarrier, IVisionCarrier
{
public PlayerCharacter() : base(entity=> newPlayerCharacterStateMachines(entity))
{
...또한 이 기사에서는 Unity의 C#에 대한 몇 가지 심층적인 최적화 제안과 관심을 제시합니다. 관심 있는 어린이는 전체 기사를 읽을 수 있습니다.
Frostbite on Mobile은 GL에서 Metal, 셰이더, 조명 등으로의 마이그레이션을 포함하여 Frostbite의 모바일 관련 기술과 경험을 공유합니다.
GL을 Metal로 마이그레이션하는 과정에서 두 가지 주요 과제가 있습니다. 1. 엔진은 메모리 소비 측면에서 Xbox 360 시대와 달라지기 시작했습니다. 2. 많은 셰이더는 YACCGL을 셰이더 변환기로 사용하여 순수 HLSL로 작성되었습니다.
Metal 환경을 활용하여 OpenGL ES 3.0 백엔드를 개선하고 Metal 및 GL 백엔드를 콘솔/PC에 맞추는 데 시간을 투자하세요. 타일 메모리 관리: 모든 플랫폼에서 glInvalidateFramebuffer, glClear, 디퍼드 렌더링/포워드 렌더링, ES에서는 대부분의 기능을 제공하지만 성능은 낮습니다.
조명 측면에서는 많은 광원이 조명 타일 최적화 사용을 지원하고 모든 게임이 물리 기반 렌더링으로 이동됩니다. 광원 유형에는 포인트 라이트, 스포트라이트, 영역 라이트, 그림자 투사 등가물, 평면 반사, 로컬 반사 볼륨 등이 포함됩니다. 전방 및 지연 조명 블록은 아래와 같습니다.


많은 복잡한 셰이더를 크로스 컴파일하고, 라이트 컬링/비닝을 위한 셰이더를 계산하고, Deferred/Forward/Forward+ 간을 전환합니다. 로컬 반사를 위한 큐브맵 배열은 2d 위도 길이 텍스처 배열에 대해 unw(ra/ar)로 처리됩니다. 샘플링 시 약간의 알루미늄 오버헤드가 있지만 하드웨어 주소 지정/필터링/MIPMAP을 지원합니다.

CS에서 VS/PS로 지연된 조명 축적을 다시 작성하고, 타일 메모리에 조명을 축적하고, 간접 드로콜/금속에 디스패치를 사용하지 않고, 초기 버텍스 셰이더 시뮬레이션을 사용합니다. 관련 최적화:
백엔드 최적화. 타일러 프롬프트 API를 노출하고 이를 광범위하게 사용하고(타일러가 아닌 경우 nop:s) 가능한 한 많은 렌더링 프로세스를 병합하고 상태 변경을 줄입니다.
셰이더 코드. 내장 함수/내장 함수를 최대한 사용하고, 스칼라 수학을 사용하고, 데이터를 주의 깊게 압축하고 정렬하세요.
요약하자면, 세부 사항을 설명하기 전에 큰 그림을 얻으려면 오늘날의 모바일 하드웨어와 API는 전체 엔진 기능 세트를 지원하고, 데스크톱/콘솔 코드 기반에서 벗어나지 않고 많은 타일 메모리별 최적화를 수행할 수 있으며, 여러 플랫폼용으로 구축하는 경우 크로스 컴파일러를 사용하세요. Vulkan/ES 3.1, spir-v, 타일별 셰이더 최적화(디퍼드 셰이딩), 타일 로컬 스토리지를 사용한 효율적인 렌더링, 모바일 장치별 셰이더 최적화(fp16/fp32 사용, alu/대역폭 밸런싱), 테셀레이션, 비동기 컴퓨팅, 간접 드로잉 등과 같은 새로운 API가 향후 고려될 수 있습니다.
고급 VR 렌더링에서는 입체 렌더링, 타이밍(스케줄링, 예측, VSync, GPU 버블), 반사 앨리어싱 및 이방성 조명, 기타 VR 렌더링 주제를 포함하여 Valve의 VR 플랫폼에 대한 시도와 개선 사항을 설명합니다.
Valve의 VR은 하드웨어 및 소프트웨어 엔지니어, VR용으로 특별히 설계된 맞춤형 광학 장치, 디스플레이 기술 – 낮은 지속성, 글로벌 디스플레이, 추적 시스템(기본 기반 위치 추적, 포인트 기반 데스크톱 추적 및 컨트롤러, 레이저 추적 헤드셋 및 컨트롤러), SteamVR API – 크로스 플랫폼, OpenVR을 결합한 3년 이상의 연구를 보유하고 있습니다.
HTC Vive 개발자 에디션 사양: 새로 고침 빈도는 90Hz(프레임당 11.11ms), 낮은 지속성, 전역 디스플레이, 프레임 버퍼 해상도는 2160x1200(눈당 1080x1200), 오프스크린 렌더링은 약 1.4배 더 넓고 높음: 눈당 1512x1680 = 254만 음영 픽셀(무차별), FOV ~110도, 360⁰ 실내 규모 추적, 다중 추적 컨트롤러 및 기타 입력 장치.
광학 및 워프: 워프 채널은 RGB에 대해 각각 3세트의 UV를 사용하여 공간 및 색상 왜곡을 설명합니다.

1.4x 렌더 타겟을 시각화합니다. 위쪽 사진은 왜곡 전, 아래쪽 사진은 왜곡 후입니다.
음영을 위한 초당 가시 픽셀 수: 30Hz에서 720p: 2,700만 픽셀/초, 60Hz에서 1080p: 1억 2,400만 픽셀/초, 30" 모니터 2560x1600@60Hz: 2억 4,500만 픽셀/초, 4k 모니터 4096x2160@30Hz: 2억 6,500만 픽셀/초, VR은 90Hz 1512x1680x2: 4억 5,700만 픽셀/초를 3억 7,800만 픽셀/초로 낮출 수 있습니다. 이는 VR이 아닌 렌더러를 사용하는 100Hz의 30인치 모니터와 동일합니다.
"작은" 효과는 없습니다. 추적을 통해 사용자는 추적 볼륨에 있는 모든 항목에 가까워질 수 있습니다. 매우 비싼 효과를 달성하고 "모퉁이에 있는 작은 것"이라고 주장하는 것은 불가능합니다. 가장 낮은 품질이라도 기존 생성보다 더 높은 충실도가 필요합니다. 추적 볼륨에서는 높은 충실도가 있어야 합니다.
VR 렌더링 대상: 최소 GPU 최소 사양, VR이 성공하기를 원하지만 고객이 필요합니다. 최소 사양이 낮을수록 더 많은 고객이 앨리어싱을 알아차리지 않아야 하며, 고객은 앨리어싱을 "깜박임"이라고 지칭하며, 알고리즘은 여러 GPU에 걸쳐 확장되어야 합니다.
스테레오 렌더링(단일 GPU): CPU 코드를 두 번 실행하는 무차별 대입(버그), 형상 셰이더를 사용하여 형상 확대(버그), 명령 버퍼 다시 제출(좋은 솔루션), VR용 고성능 스테레오 렌더링에서 인스턴스를 사용하여 형상을 두 배(더 나은 API 호출을 절반으로 줄임, VB/IB/텍스처 읽기에 대한 캐시 일관성 향상)를 사용합니다.
입체 렌더링(다중 GPU): AMD와 NVIDIA는 모두 여러 GPU에서 입체 렌더링을 가속화하기 위해 DX11 확장을 제공합니다. AMD는 프레임 속도를 거의 두 배로 늘렸지만 NVIDIA의 구현은 아직 테스트되지 않았습니다. 개발자에게 적합하며 팀의 모든 구성원은 개발 상자에서 다중 GPU 솔루션을 사용하여 불편할 정도로 낮은 프레임 속도 없이 프레임 속도를 이길 수 있습니다.
예측: 목표는 HMD 및 컨트롤러 변환(광자로 렌더링됨)의 예측 시간을 최대한 짧게 유지하고(정확성이 총 시간보다 중요함) 낮은 지속성 전역 디스플레이를 유지하는 것입니다. 패널은 11.11ms 프레임 중 약 2ms 동안만 켜집니다.

위 이미지는 최고의 VR 렌더링은 아니지만 예측을 설명하는 데 도움이 됩니다.
파이프라인 아키텍처: 현재 프레임을 렌더링하는 동안 다음 프레임을 시뮬레이션합니다.

변환은 다시 예측되고 전역 c버퍼는 커밋 전에 업데이트됩니다. 이는 예측 제한으로 인해 실제로 VR에 필요하며 CPU에서 약 5도 정도 보수적으로 줄여야 합니다.
VSync 대기: 가장 간단한 VR 구현, VSync 직후 예측, 모드 #1: Present(), 백 버퍼 지우기, 픽셀 읽기; 모드 #2: Present(), 백 버퍼 지우기, 쿼리 실행. 초기 구현에는 적합하지만 이를 수행하지 마십시오. GPU는 이를 위해 설계되지 않았습니다.
"Run Start"를 사용한 VSync: VSync에서 얼마나 멀리 떨어져 있는지 어떻게 알 수 있습니까? 까다롭습니다. 그래픽 API는 이를 직접 제공하지 않습니다. Windows의 SteamVR/OpenVRAPI는 별도의 프로세스로 실행되어 IDXGIOutput::WaitForVBlank()가 호출될 때 시간을 기록하고 프레임 카운터를 증가시킵니다. 그런 다음 애플리케이션은 프레임 ID도 반환하는 getTimeSincelllastVsync()를 호출할 수 있습니다. GPU 공급업체, HMD 장치 및 렌더링 API가 이를 제공해야 합니다.
"실행 시작"에 대한 세부 정보: 잘못된 프레임을 처리하려면 GPU와 부분적으로 동기화하고 백 버퍼를 지운 후 쿼리를 삽입하고 전체 프레임을 제출하고 해당 쿼리에서 회전한 다음 Present()를 호출하여 현재 프레임에 대해 VSync의 올바른 측면에 있는지 확인하고 이제 실행 시작 시간까지 회전할 수 있습니다.

쿼리 질문이 중요한 이유는 무엇입니까? 프레임 지연이 있는 경우 쿼리는 다음 프레임에 대해 VSync 오른쪽에 있으므로 예측이 정확하게 유지됩니다(아래 주황색).

요약 실행 시작: 안정적인 1.5-2.0밀리초 GPU 성능 향상! 일반적인 상황에서는 NVIDIA Nsight 및 Microsoft GPUView에서 각각 다음 그림을 볼 수 있습니다.

앨리어싱은 VR의 가장 큰 적입니다. 카메라(플레이어의 머리)가 계속 움직이므로 앨리어싱이 증폭됩니다. 렌더링할 픽셀이 더 많지만 각 픽셀은 이전보다 더 큰 각도를 채웁니다. 평균은 다음과 같습니다. 2560x1600 30" 모니터: ~50픽셀/도(50도 수평 시야), 720p 30" 모니터: ~25픽셀/도(50도 수평 시야), VR: ~15.3픽셀/도(110도 시야, 비VR의 1.4배) 픽셀의 품질을 개선해야 합니다.
4xMSAA 최저 품질: MSAA가 효과적이기 때문에 포워드 렌더러가 앤티앨리어싱에서 승리합니다. 성능이 허용되면 8xMSAA를 사용하십시오. 렌더러가 업계의 다른 알고리즘과 어떻게 비교되는지 확인하려면 이미지 공간 앤티앨리어싱 알고리즘을 4xMSAA 및 8xMSAA와 나란히 비교해야 합니다. 디더링된 SSAA는 HLSL의 "샘플" 수정자를 사용할 때 확실히 최고이지만 성능을 절약할 수 있는 경우에만 가능합니다.
일반 맵은 계속 사용할 수 있으며 대부분의 일반 맵은 VR에서 잘 작동합니다. 유효하지 않은 경우: 추적된 볼륨 내에서 몇 센티미터보다 큰 지형지물은 세부 묘사가 좋지 않으며, 추적된 볼륨 내의 표면 모양은 일반 맵에 포함될 수 없습니다. 효과적인 경우: 가까이서 볼 수 없는 추적된 볼륨 외부의 멀리 있는 물체, 표면 "질감" 및 미세한 세부 사항. 노멀 맵 매핑 오류:

평균 법선만 생성하는 밉 필터는 중요한 러프니스 정보를 잃게 됩니다.


Mips로 인코딩된 러프니스: 해당 텍스처에 기여하는 가장 높은 밉에 대한 모든 2D 탄젠트 법선의 표준 편차인 등방성 값(원의 반경으로 시각화됨)을 저장할 수 있으며, 각각 X 및 Y 방향의 표준 편차에 대한 2D 이방성 값(타원의 치수로 시각화됨)을 저장할 수도 있습니다. 이는 탄젠트 공간 축 정렬 이방성 조명을 계산하는 데 사용할 수 있습니다!


추가된 아티스트는 거칠기를 생성하고 2D 광택 = 1.0 – 거칠기를 생성하고 간단한 상자 필터를 사용하여 이를 각 밉 수준에서 노멀 맵 거칠기와 추가/합산하고 결과 노멀 맵 거칠기를 저장하는 것은 이방성 광택 맵 때문에 무료였습니다.

왼쪽: 등방성 광택; 오른쪽: 이방성 광택.
탄젠트 공간 축에 정렬된 이방성 조명: 대각선을 따라 표현된 표준 등방성 조명은 탄젠트 공간 축에 이방성으로 정렬되며 2D 탄젠트 법선과 쌍을 이루는 2개의 추가 값만 필요합니다 = RGBA 텍스처에 적합합니다(DXT5 >95% 시간).

거칠기를 인덱스로 변환: 확산 조명은 Lambert를 지수(
void RoughnessEllipseToScaleAndExp(float2 vRoughness, out float o_flDiffuseExponentOut,out float2 o_vSpecularExponentOut,out float2 o_vSpecularScaleOut)
{
o_flDiffuseExponentOut=((1.0-(vRoughness.x+ vRoughness.y) * 0.5) *0.8)+0.6;// Outputs 0.6-1.4
o_vSpecularExponentOut.xy=exp2(pow(1.0-vRoughness.xy,1.5)*14.0);// Outputs 1-16384
o_vSpecularScaleOut.xy=1.0-saturate(vRoughness.xy*0.5);//This is a pseudo energy conserving scalar for the roughness exponent
}이방성 조명 계산 프로세스:

기하학적 반사 앨리어싱: 노멀 맵이 없는 조밀한 메시도 앨리어싱을 생성할 수 있으며 러프니스 밉은 도움이 되지 않습니다! 보간된 버텍스 노멀의 편도함수를 사용하여 곡률에 근접한 기하학적 러프니스 항을 생성할 수 있습니다.
float3 vNormalWsDdx = ddx(vGeometricNormalWs.xyz);
float3 vNormalWsDdy = ddy(vGeometricNormalWs.xyz);
float flGeometricRoughnessFactor = pow(saturate(max(dot(vNormalWsDdx.xyz, vNormalWsDdx.xyz), dot(vNormalWsDdy.xyz, vNormalWsDdy.xyz))), 0.333);
vRoughness.xy=max(vRoughness.xy, flGeometricRoughnessFactor.xx); // Ensure we don’t double-count roughness if normal map encodes geometric roughness
flGeometricRoughnessFactor의 시각화.
MSAA 중심 대 중심 보간은 버텍스 노멀을 과도하게 보간하고 노멀 보간으로 인해 윤곽선에서 반사광 깜박임이 발생할 수 있으므로 완벽하지 않습니다. 기사에서 사용된 기술은 다음과 같습니다.
// 보간(Interpolation)노멀(Normal)회 :회 ,회
float3 vNormalWs:TEXCOORD0;
centroid float3 vCentroidNormalWs:TEXCOORD1;
// 픽셀(Pixel)셰이딩 내에서 ,만약 노멀(Normal)1.01,노멀(Normal)
if(dot(i.vNormalWs.xyz, i.vNormalWs.xyz) >= 1.01)
{
i.vNormalWs.xyz = i.vCentroidNormalWs.xyz;
}노멀 맵 인코딩: 탄젠트 법선을 Z 평면에 투영하는 것은 2D 텍스처 범위의 약 78.5%만 사용하는 반면, 반팔면체 인코딩은 2D 텍스처의 전체 범위를 사용합니다.

렌더 대상 해상도 조정: 1.4x는 HTC Vive에 대한 권장 사항일 뿐이라는 것이 밝혀졌습니다(각 HMD 디자인에는 광학 및 패널에 따라 권장 스칼라가 다릅니다). 느린 GPU에서는 권장되는 렌더 타겟 스칼라를 축소하고, 더 빠른 GPU에서는 권장되는 렌더 타겟 스칼라를 확장하여 GPU 주기를 최대한 활용하세요.
이방성 텍스처 필터링: 모니터의 해상도를 높이고(VR은 도당 픽셀 수가 더 적다는 점을 잊지 마세요), 색상 및 일반 맵의 경우 이 옵션은 기본적으로 8x를 사용하여 강제로 활성화됩니다. 다른 모든 기능을 비활성화합니다(삼선형만 제외). 성능을 측정하는 데 필요합니다. 다른 곳에서 병목 현상이 발생하면 이방성 필터링이 "무료"일 수 있습니다.
소음은 여러분의 친구입니다. VR에서는 전환이 끔찍하고 LCD TV보다 밴딩이 더 눈에 띄며 픽셀 셰이더에 부동 소수점 정밀도가 있으면 프레임 버퍼에 소음이 추가될 수 있습니다.
float3 ScreenSpaceDither(float2vScreenPos)
{
// Iestyn's RGB dither(7 asm instructions) from Portal 2X360, slightly modified for VR
float3 vDither = dot(float2(171.0, 231.0), vScreenPos.xy + g_flTime).xxx;
vDither.rgb = frac(vDither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5);
return (vDither.rgb / 255.0) * 0.375;
}환경 맵: 무한대의 표준 구현 = 하늘에만 해당, 환경 맵에 대한 일종의 거리 재매핑이 필요합니다. 구는 저렴하고 큐브는 더 비싸며 둘 다 서로 다른 상황에서 유용합니다.
템플릿 그리드(숨겨진 영역 그리드): 템플릿을 사용하여 실제로 렌즈를 통해 볼 수 없는 픽셀을 마스크합니다. GPU는 템플릿을 미리 거부하는 속도가 매우 빠릅니다. 또는 z에 가까운 깊이 버퍼로 렌더링하여 모든 픽셀에 사전 z 테스트가 활성화되고 렌즈가 방사상 대칭 변형을 생성하도록 할 수 있습니다. 즉, 패널에 투영된 원형 영역을 효과적으로 볼 수 있습니다.

템플릿 그리드 범례. 위에서 아래로, 왼쪽에서 오른쪽으로 왜곡된 보기, 이상적인 왜곡된 보기, 낭비된 공간, 왜곡되지 않은 보기, 왜곡되지 않은 보기(잘못된 픽셀 마스킹), 최종 왜곡되지 않은 보기입니다.
템플릿 그리드(숨겨진 영역 그리드): SteamVR/OpenVRAPI는 이 그리드를 제공합니다. **채우기 속도를 17%까지 줄일 수 있습니다!**스텐실 메시: VR 1512x1680x2@90Hz: 4억 5,700만 픽셀/초, 눈당 254만 픽셀(총 508만 픽셀), 템플릿 메시 포함: VR 1512x1680x2@90Hz: 3억 7,800만 픽셀/초, 눈당 약 210만 픽셀(총 420만 픽셀).

왜곡 메시 순서: 렌즈 왜곡 메시, 폭력, 0-1 이외의 UV 제거, 템플릿 메시 제거, 수축 왜곡.
성능 쿼리가 필요합니다! 항상 vsync를 유지하고, 프레임 속도를 보기 위해 VSync를 비활성화하면 플레이어가 어지러워지며, GPU 작업량을 보고하기 위해 성능 쿼리를 사용해야 합니다. 가장 간단한 구현은 첫 번째 드로우 콜부터 마지막 드로우 콜까지 측정하는 것입니다. 이상적으로는 Present()에서 첫 번째 그리기 호출까지의 유휴 시간, 첫 번째 그리기 호출에서 마지막 그리기 호출까지의 유휴 시간, 마지막 그리기 호출에서 현재 Present()까지의 유휴 시간을 측정합니다.
요약: 스테레오 렌더링, 예측, "실행 시작"(프레임당 1.5-2.0ms 절약), 이방성 조명 및 마이핑 노멀 맵, 기하학적 반사 앤티앨리어싱, 템플릿 메시(렌더링된 픽셀의 17% 절약), 최적화된 워프 메시(비용 15% 절감).
14.4.3.4 병렬 기술
UFO 침공: DX11 및 구조용 멀티코어에서는 DirectX 11의 멀티스레딩 기능에 대해 설명합니다. 이 기사에서는 멀티스레드 및 단일 스레드 작업 실행 모드를 비교합니다. 멀티스레딩에서는 작업이 더 이상 연속적으로 실행되지 않고 여러 하위 작업으로 나누어져 여러 프레임에서 직접 겹쳐집니다.

다중 스레드 모드에서 일부 작업자 스레드가 부족(유휴)하면 완전히 로드된 다른 스레드에서 작업 실행을 훔칠 수 있습니다.

Entity의 개념과 속성은 기사에 언급되어 있습니다. 엔터티에는 상태(State)와 정신(Mind)이라는 두 가지 유형의 데이터가 포함되어 있습니다. State는 게임의 다른 시스템에 노출되는 데이터이고 Mind는 Entity의 개인 데이터입니다. Entity가 업데이트되면 State와 Mind가 동시에 업데이트될 수 있지만 따라야 할 규칙은 다음과 같습니다.
다른 인스턴스는 마음을 읽을 수 없습니다.
Mind를 업데이트할 때 State를 변경하지 마세요.
마인드 업데이트 시 다른 인스턴스에 주의하지 마세요.
엔터티 업데이트는 종속성을 허용합니다. 때로는 이전 프레임의 정보가 충분하지 않을 수도 있지만, 알고 싶은 내용을 알고 있다면 해당 엔터티가 다른(또는 다른) 엔터티에 종속된다고 선언할 수 있습니다.

렌더링은 각 스레드가 자체 대기열에 데이터를 수집하고 정렬을 통해 나중에 모든 것을 하나로 모으기 때문에 완전히 병렬입니다. 각 항목의 가중치는 128비트(64비트 키, 32비트 엔터티 ID, 32비트 매개변수)이며, 4096개 항목의 경우 정렬할 데이터가 64K에 달합니다. 이는 병렬 정렬을 겨우 정당화할 만큼 충분합니다. 여기서 동시에 많은 값비싼 렌더링 부분이 발생하며 특히 컬링이 가장 두드러집니다.

렌더링은 기본적으로 스레드에서 지속적으로 발생하며, 현재 키와 이전 키 간의 차이를 확인하여 엔진은 파이프라인 상태를 매우 효율적으로 업데이트할 수 있습니다. 범위를 벗어난 "마지막 키"로 시작하면 엔진이 올바른 렌더 대상, 뷰포트 및 다양한 상태를 선택하게 됩니다. 엔터티는 그리는 데 필요한 모든 것을 그리기 위해 다시 호출되며, 현재 키가 마지막 키가 되어 완료될 때까지 반복됩니다. 인스턴스화는 실제로 동일한 인스턴스화 ID를 가진 키를 축적하고 결과 목록을 사용하여 엔터티를 다시 호출하는 문제입니다.

DirectX 11의 멀티스레딩은 매우 간단합니다.
지연된 컨텍스트에 대한 멀티스레드 렌더링.
지연 컨텍스트 생성 명령 목록.
메인 스레드는 이를 즉각적인 컨텍스트에 제출합니다.

DirectX 11 멀티 스레드 모델에 적용된 렌더링 프로세스는 다음과 같습니다.

가장 깔끔하게 이 접근 방식은 명령 목록이 현재 파이프라인 상태에 의존하지 않는다는 요구 사항도 처리합니다. 즉, 항상 범위를 벗어난 "마지막 키"로 시작합니다. 즉, 각 명령 목록은 전체 파이프라인 상태로 시작됩니다.
Shears - CPU에서 주스 짜내기: 데이터 기반 스케줄러의 사후 분석은 멀티스레드 환경에서 데이터 경합을 해결하여 엔진 주기를 예약하는 혁신적인 접근 방식을 도입합니다. 이 데이터 기반 스케줄링은 데이터 경합을 최소화하고 Cell의 SPU를 포함한 하드웨어 사용량을 최대화합니다. 잠금 없는 알고리즘을 사용하여 구현되어 기존 스케줄러에 비해 더 나은 성능을 달성합니다.
루핑 엔진에 대한 현재 주류 접근 방식은 중첩을 사용하고 다중 스레드 병렬 처리를 사용하는 것입니다.

실행은 여러 스레드에 분산되고 동기화 지점에 대한 데이터가 수집됩니다. 미시적 및 거시적 규모 모두에서 잘 확장되더라도 데이터 액세스 문제가 있습니다. 즉, 읽기 전용 권한 또는 쓰기 액세스를 처리하지만 프로젝트별로 조정해야 하는 잠금 동기화 기본 요소가 필요합니다.

의 아키텍처 즉, 의 동기화 포인트 ,그러나 and개 ,동기화 포인트 및 / 또는 ,의 조정(Adjust):

이러한 문제를 피하기 위해 무엇을 할 수 있습니까? 가위 사용: 큰 작업을 더 작은 덩어리로 자릅니다. 아래 그림과 함께 이전 작업 순서를 살펴보세요. 많은 양의 데이터가 푸시됩니다. 작업 C는 A&B가 완전히 완료될 때까지 잠겨 있습니다. 따라서 2개의 데이터 스트림 D0&D1이 식별됩니다.

관점을 바꿔서 데이터 흐름의 관점에서 살펴보세요. 데이터 흐름 표현은 하향식이며 작업은 여전히 존재하며 중요한 요소가 추가됩니다. 작업 액세스, 작업 액세스는 일정을 정의합니다. 이제 데이터 흐름에 넣으면 작업 A&B가 먼저 실행되고 그 다음 C가 실행됩니다. 결과는 이전과 동일합니다.

이제 데이터 흐름에 데이터를 붓으면 결과 => 작업 C가 작업 A 및 B를 기다리지 않고 더 일찍 시작할 수 있습니다. 스케줄러의 입력은 작업 순서 선언이 아닌 데이터 액세스 선언을 의미합니다.

게임 루프 엔진을 예로 들어보겠습니다. 데이터는 위에서 아래로 흐릅니다. 모든 것은 데이터 흐름에 관한 것이며, 데이터 없음 => 프로세스 없음 => 필요한 코드만 실행됩니다.
이 기사는 또한 Lock-free의 실행 프로세스를 설명하기 위해 자세한 애니메이션을 제공합니다(아래 그림은 정적이므로 애니메이션을 표시할 수 없습니다).

다음 표는 인텔 코어 2 쿼드 프로세서 Q6600에서 테스트한 중요 섹션과 잠금 없는 원자의 성능 비교를 보여줍니다. 단위는 작업/ms, 2개 스레드입니다. 20% 또는 50%가 아님, 36배 빠름 - 3000% 이상, 잠금이 성공한 경우에도 유휴 시간의 57%가 잠금 기능을 호출합니다.

하드웨어 개발자가 멀티 코어 아키텍처를 대체하기 위해 더 빠른 프로세서를 만드는 것에서 벗어나면서 게임 개발자는 이러한 새로운 장치를 활용하기 위해 멀티 스레딩 기술을 활용해야 합니다. 멀티 코어 모바일 장치의 경우 네트워크 기반 멀티 스레드 게임 엔진의 필요성이 현실이 되었습니다. HTML5, CSS3 및 JavaScript를 사용하여 다중 스레드 웹 기반 게임 엔진 구축에서는 스레드 컨트롤러를 사용하여 스레드에서 요청을 동적으로 처리할 수 있도록 하는 다양한 다중 스레드 웹 엔진 아키텍처의 설계에 대해 설명합니다. WebWorkers, WebSockets 및 WebGL과 같은 HTML5 및 JavaScript API를 활용하면 플러그인 없이 모바일 및 데스크톱 장치를 지원하는 완전한 기능을 갖춘 진정한 크로스 플랫폼인 브라우저 기반 3D 게임의 새로운 표준을 설정할 수 있습니다.


웹 애플리케이션 아키텍처와 OS 커널 간의 관계.

중첩 및 공유 유형에서 작동합니다.

웹 측의 멀티스레드 아키텍처 및 운영 모델.

애플리케이션 계층, OS 및 타사 확장의 계층 구조.
우리는 CPU가 작업 병렬성에 능숙하고 GPU가 데이터 병렬성에 능숙하다는 것을 알고 있습니다. 그러나 GPU 작업 병렬성: 기본 요소 및 응용 프로그램은 다른 접근 방식을 취하고 루틴을 따르지 않습니다. GPU에 작업 병렬성을 도입하고 개념, 중요성, 실습 및 기타 기술을 설명합니다.
작업 병렬성이란 무엇입니까?
태스크(Task): 단일 컨텍스트 내에서 실행되는 논리적으로 관련된 명령어 세트입니다.
작업 병렬성: 작업이 병렬로 처리됩니다. 예약 구성 요소는 사용 가능한 컴퓨팅 리소스에 작업을 할당하는 방법을 결정합니다.
예: Cilk, Intel TBB, OpenMP.
GPU는 데이터 병렬이고 GPU 하드웨어는 데이터 병렬 처리를 중심으로 구축되었으며 CUDA는 데이터 병렬 추상화이며 작업 기반 워크로드는 (그때까지) 무시되었습니다.
GPU 작업 병렬성: GPU 프로그래밍의 범위를 확장하면 많은 작업 병렬 문제가 여전히 많은 양의 병렬성을 나타냅니다. GPU를 작업 병렬 장치로 프로그래밍하는 것은 기본 요소와 응용 프로그램의 두 부분으로 나뉩니다.
프리미티브의 목표는 다양한 워크플로를 처리하고, 불규칙한 수준의 병렬 처리를 처리하고, 작업 간의 종속성을 존중하고, 이 모든 것을 로드 밸런싱할 수 있는 작업 병렬 시스템을 구축하는 것입니다.

기본 병렬성:
작업 세분화. 작업 처리를 위한 올바른 병렬 세분성은 무엇입니까? 스레드당 하나의 작업이 좋은 습관이며, 워프당 하나의 작업이 더 좋습니다. SIMD에 초점을 맞춰 워프를 32개의 넓은 벡터 채널이 있는 MIMD 스레드로 생각하십시오.
작업 관리자(시작, 종료). 더 이상 작업이 없을 때까지 작업을 계속 처리하는 방법은 무엇입니까? 지속적인 스레드 프로그래밍 모델:
while(stillWorkToDo)
{
//
}작업 부하에서 시작 범위를 분리하고 교착 상태에 주의하세요!
임무 통신. SM 간에 작업을 균등하게 분배하는 방법은 무엇입니까? 작업 기부 절차가 포함된 분산 대기열. 이제 Atomic은 충분히 빠르고 간단하므로 단일 블록 큐를 사용할 수도 있습니다.
작업 종속성. 작업에 종속성이 있으면 어떻게 되나요? 종속성을 존중하도록 현재 시스템을 향상하려면 어떻게 해야 합니까?
종속성 의사 결정: 대기열에 추가된 모든 작업은 종속성 없이 실행됩니다. 종속성은 작업 대기열에 넣을 수 있는 작업에 영향을 줍니다. 작업 종속성 맵이 유지됩니다. 각 워프는 다른 작업을 대기열에 넣기 전에 지도를 확인해야 합니다.
while(Q is not empty)
{
task t = Q.pop()
Process (t)
Neighbors tnset = dependencyMap(t)
For each tn in tnset
tn.dependencyCount--;
if(tn.dependencyCount == 0)
Q.push(tn);
}애플리케이션 병렬 처리의 경우 작업 병렬 처리가 필요한 여러 시나리오가 있습니다. Reyes 렌더링, 지연 조명, 비디오 인코딩, 필요한 기본 요소만 사용.
Reyes 렌더링의 경우 작업 병렬성이 필요한 이유는 불규칙한 병렬성과 동적 의사소통 때문입니다. 필요한 기본 요소는 영구 스레드와 동적 작업 대기열입니다.

Reyes의 작업은 병렬적입니다.
지연된 조명을 사용하면 다양한 조명이 화면의 다양한 부분에 영향을 미치므로 타일을 너무 많은 조명으로 세분화합니다. 작업 병렬성을 요구하는 이유는 불규칙한 병렬성과 동적 의사소통 때문입니다. 필요한 기본 요소는 영구 스레드와 동적 작업 대기열입니다.
즉, 작업 병렬 처리는 중요하며 다양한 애플리케이션 시나리오를 포함합니다. 몇 가지 기본 요소: 작업 세분성 예약, 영구 스레드, 동적 대기열 및 종속성 해결.
Killzone Shadow Fall: PS4의 엔터티 업데이트 스레딩은 PS4 게임 Killzone Shadow Fall에 사용된 스레드 업데이트 엔터티 기술을 공유합니다.
엔터티는 플레이어, 적, 무기, 문과 같은 대부분의 게임 개체에 대한 기본 클래스이며 정적 세계에서 사용되지 않으며 모델, 무버, 파괴 가능 요소와 같은 구성 요소를 가지며 고정 빈도(15, 30, 60Hz)로 업데이트되고 거의 모두 15Hz로 업데이트되며 플레이어는 지연을 피하기 위해 더 자주 업데이트됩니다. 엔터티와 구성 요소는 표현적이며 렌더링, 오디오 및 VFX를 제어합니다. 상태는 엔터티가 업데이트되지 않는 프레임에 삽입됩니다. 삽입은 업데이트보다 저렴하지만 대기 시간이 발생합니다. 항상 마지막 업데이트와 일치합니다.
PS3에서는 하나의 엔터티 = 1 파이버이며 대부분의 시간이 PPU에 소비되고 명확한 동시성 모델이 없으며 부분 업데이트 상태가 읽히고 엔터티가 서로를 기다립니다.

PS4에서 하나의 엔터티 = 하나의 작업, 파이버 없음, 엔터티가 전체적으로 업데이트됩니다. 경쟁 조건을 해결하는 방법은 무엇입니까?

종속성이 있는 엔터티는 동시에 업데이트할 수 없지만 종속성이 없는 엔터티는 업데이트할 수 있습니다. (간접) 종속성 없음 = 액세스 없음, 두 가지 방식으로 작동합니다. 무기는 군인에게 접근할 수도 있고 종속성을 생성하는 데 1 프레임 지연이 있으며 전역 시스템 잠금이 필요합니다.

그러나 엔터티 수가 적으면 엄청난 병목 현상이 발생할 수 있습니다.

비배타적 종속성, "총알 시스템"에 대한 액세스는 잠금으로 보호되어야 합니다.

두 탱크가 서로 발사하는 약한 참조를 사용하는 것도 가능합니다(아래 그림). 순환 종속성이 발생하면 업데이트 순서가 바뀌고 자주 사용되지 않습니다(프레임당 <10).

업데이트되지 않는 엔터티, 업데이트를 건너뛸 수 있는 엔터티(LOD), 엔터티는 다른 프레임에서 업데이트되고 정상적으로 예약될 수 있습니다! 다음 그림은 다양한 종속성을 요약한 것입니다.

스케줄링 알고리즘: 배타적 종속성을 갖는 엔터티가 하나의 작업으로 병합됩니다. 종속성에 따라 순서가 결정됩니다. 비배타적 종속성은 작업 종속성이 됩니다. 값비싼 일을 먼저 시작하세요!

경계 사례: 비주기적 종속성은 주기적 작업 종속성이 되며 작업 1과 작업 2를 병합해야 합니다.

모든 15Hz 엔터티가 동일한 프레임에서 업데이트되지 않도록 프레임 간에 엔터티 균형을 유지합니다. 엔터티는 다른 프레임으로 이동할 수 있으며 1 업데이트의 증가 시간은 더 짧습니다. 군인의 무기, 창병, 잠긴 근접전투 등 부모-자식 관련 개체를 함께 유지하세요.
성능 문제: 메모리 할당 상호 배제, 많은 동적 할당 제거, 스택 할당자 사용, 물리 세계 잠금, 기본 시뮬레이션 세계의 R/W 상호 배제, 두 번째 "총알 충돌" 넓은 단계 + 잠금, 엔터티에 대한 과도한 의존도, 매우 비싼 플레이어 업데이트 등
컷씬 전략을 사용할 수 있습니다. 장면 엔터티를 분할하려면 종속성이 필요하며 장면에서 10개 이상의 문자를 분할하면 엄청난 작업이 생성됩니다!

위 문제에 대한 해결책은 비대화형 엔터티에 대한 하위 슬라이스 장면을 만드는 것입니다. 메인 슬라이스 장면은 시간과 프로세스를 결정하고 타임라인에서 1프레임 앞으로 스캔하여 종속성을 만듭니다.

개체 사용, 사용 가능한 개체에 의존할 수 없음(너무 많음), 사용 가능한 개체 목록 가져오기, 잠금으로 보호되는 전역 시스템, 화면에 "사용" 아이콘 표시, 플레이어 선택, 종속성 설정, "사용" 애니메이션 시작, 1 프레임 후 상호 작용 시작(종속성은 유효함), 1 프레임 지연 숨김!
위의 다양한 업데이트 방법의 성능 비교는 다음과 같습니다.


전체 프레임의 타임라인과 엔터티 업데이트의 타임라인은 다음과 같습니다.


대체로 기존 엔진에서 쉽게 구현할 수 있으므로 게임 프로그래머는 멀티스레딩 문제가 거의 없이 단일 스레드인 것처럼 프로그래밍할 수 있습니다.
Gamedev 학생들을 위한 멀티스레딩 하드웨어 지원, 일반적인 게임 엔진 스레드 모델, 경쟁 조건, 동기화 프리미티브, 원자성 및 잠금 없음, 위험과 같은 멀티스레드 코딩 관련 기술에 대해 이야기합니다.
다중 프로세서: 높은 비용, 높은 전력 소비, 칩 간 대기 시간, 캐시 일관성 문제는 일반적으로 고급 데스크톱 및 슈퍼 메인프레임 컴퓨터로 제한됩니다.

다중 코어: 다중 코어는 사용 가능한 하드웨어 리소스를 보다 효율적으로 사용할 수 있습니다. 코어는 L2/L3 캐시와 메모리 인터페이스를 공유할 수 있습니다. 데스크탑 및 게임 콘솔에 대한 가장 일반적인 설정입니다.

다중 하드웨어 스레드: Intel 영역의 동시 멀티스레딩(SMT), "하이퍼스레딩" 스레드는 실행 단위, 1차 캐시 등과 같은 핵심 리소스를 공유합니다. 코어 리소스를 보다 효율적으로 사용하는 일시 중단된 스레드는 리소스를 낭비하지 않으며 일반적으로 단일 하드웨어 스레드보다 10%-20% 빠르지만 크게 다를 수 있습니다.

다중 소프트웨어 스레드: 운영 체제는 여러 프로세스를 생성할 수 있으며 게임은 일반적으로 하나의 프로세스로 실행됩니다. 프로세스는 여러 스레드를 생성하고 메모리 주소 공간을 공유할 수 있습니다. 스레드는 여러 스레드 간에 마이그레이션되거나 스레드 선호도를 통해 특정 스레드에 고정될 수 있습니다.

하드웨어 예:
- 인텔 제온 E5-1650:
6개의 하이퍼 스레드 코어
12개의 '논리 프로세서'
- 코어당 L1 및 L2
-공유 L3
- 엑스박스 360:
IBM 제논 CPU
파워PC
- 3코어 SMT
6개의 하드웨어 스레드
- 코어당 L1, 공유 L2

- 플레이스테이션 4 / 엑스박스 원
AMD 재규어 아키텍처
- 2개의 쿼드 코어 '모듈'
8개의 하드웨어 스레드
코어당 L1 캐시
모듈의 모든 코어에서 공유되는 L2 캐시

-AMD GCN GPU
PS4와 Xbox One 모두에서 사용됨
각각 18개 및 12개의 컴퓨팅 유닛
- 렌더링은 본질적으로 병렬입니다.
하드웨어는 이를 활용하여 고속 및 처리량을 달성합니다.
- 비그래픽 워크로드로 확장 가능
컴퓨팅 및 비동기 컴퓨팅

게임 내 멀티스레딩: 30/60fps 대상, 사용 가능한 모든 리소스, 많은 상호 작용 시스템, 제한된 공유 데이터 세트, 일부 공통 스레딩 모델을 사용해야 합니다. 게임의 몇 가지 일반적인 병렬 방법:



경쟁 조건: 시스템의 출력은 타이밍에 따라 달라지며, 타이밍은 여러 요인에 의해 영향을 받고, 정의되지 않은 동작 - 모든 베팅이 실패하고, 무작위 = 예측 불가능 = 잘못된 결과, 디버깅 악몽입니다. 다음 그림은 경쟁 조건의 일반적인 경우입니다.

동기화:
- 스핀록
일반적으로 원자 변수를 통해 잠금을 얻으려고 합니다.
CPU 및 메모리 대역폭 사용량에 문제가 발생할 수 있습니다.
올바르게 사용하면 가볍습니다.
뮤텍스(뮤텍스)
페어링 잠금/잠금 해제.
단일 스레드 액세스(상호 배제)를 제공하여 코드의 중요한 부분을 보호합니다.
세마포어
내부 카운터를 유지합니다.
대기(감소) 및 신호(증가) 작업입니다. <= 0개 스레드가 휴면 상태이고, 0개 이상의 대기 스레드가 계속됩니다.
신호로 스레드를 깨울 수 있습니다.
스레드 간 신호를 보내거나 작업을 수행할 수 있는 스레드 수를 제어하는 데 사용됩니다.
조건변수
스레드는 조건이 충족될 때까지 기다립니다.
모니터 : 상호배제 + 조건변수.
게임에 사용되는 플랫폼별 이벤트.
GPU 울타리
CPU와 GPU 상호 작용용. 공유 데이터가 생성되거나 사용되는 시기를 알 수 있습니다.
- 3.2 이후 플랫폼별 API, DX12 및 OpenGL 코어.
멀티스레드 코드를 작성할 때는 메모리 순서에도 주의를 기울여야 합니다. 다음 코드를 예로 들어 보겠습니다.
// global
int data = 0;
int readyFlag = 0;
// thread A
data = 32;
readFlag = 1;
// thread B
if(readFlag == 1)
{
Output(data); // 의 data의 ,는 0 또는 32!!
}위의 오류는 멀티 스레드 간의 메모리 순서 문제로 인해 발생합니다. 컴파일러는 명령어를 재정렬할 수 있고, CPU는 명령어를 재정렬할 수 있으며, CPU는 메모리 액세스를 재정렬할 수 있습니다. 메모리 모델은 다른 작업, 하드웨어 및 소프트웨어와 관련하여 어떤 읽기 및 쓰기 작업을 재정렬할 수 있는지 결정합니다. 프로세서에는 하나의 메모리 모델만 있고 언어에는 다른 이유가 있을 수 있습니다.

순차적 일관성: 메모리 액세스, 명백한 재정렬 없음, 가능한 최적화에 대한 후속 제한, 성능이 달리 요구되지 않는 한 사용을 통해 얻을 수 있는 것입니다.
메모리 장벽: 컴파일러와 CPU에서 메모리 순서를 강제하는 데 사용되며, memory_order_relaxed 작업이 아닌 std::atomic<> 작업과 같은 특정 함수에 암시적으로 사용됩니다. 펜스를 명시적으로 획득하고 해제합니다.
잠금 없는 프로그래밍: 잠금 없는 비차단 멀티스레딩 알고리즘을 구현합니다. 스레드는 중단되어 전역 프로세스를 차단할 수 없습니다. 잠금 없는 잠금을 사용하는 이유는 잠금 경합이 없고 확장성 및 성능이 뛰어나기 때문입니다(제약되지 않은 잠금은 성능이 매우 좋습니다). 하지만 무잠금의 단점은 복잡하다는 것입니다!
멀티스레딩의 위험성은 다음과 같습니다.
**교착상태.**두 개의 자물쇠가 획득되지만 순서는 다릅니다. 한 스레드는 A를 잠그고 B를 기다리고, 다른 스레드는 B를 잠그고 A를 기다립니다.
**라이브락.**여러 스레드는 로컬로 처리되며 각 스레드의 활동으로 인해 다른 스레드가 전역 처리를 여러 번 얻지 못하게 됩니다. 고전적인 비유: 복도에 두 사람이 있습니다.
**우선순위 반전.**우선순위가 낮은 스레드는 우선순위가 높은 스레드에 필요한 잠금을 획득한 후 우선순위에 따라 절전 모드로 전환됩니다. 시스템 성능은 궁극적으로 높은 우선순위 스레드가 아닌 낮은 우선순위 스레드에 의해 결정됩니다.
**거짓 공유.**여러 스레드가 동일한 캐시 라인의 메모리를 수정하여 지속적인 캐시 무효화와 불필요한 메모리 트래픽을 유발하여 성능에 심각한 영향을 미칠 수 있습니다.
ABA 질문.

멀티스레딩의 복잡성: 조금만 아는 것은 위험합니다. 실수는 하기 쉽지만 디버깅하기는 어렵습니다. 불가능한 것은 없습니다. "백만 분의 1", 프레임당 50번, 초당 30프레임...~11분, 운이 좋으면 나쁜 일이 일어날 것입니다. 간단한 것조차도 문제를 일으킬 수 있습니다.
enum{EValueA, EValueB};
// ...
Assert(foo==EValueA || foo==EValueB);언뜻 보면 위의 코드에는 많은 문제가 없어 보이지만 가끔씩 어설션이 발생하기 시작합니다. 값은 이 두 값 중 하나만 될 수 있기 때문에 본능적으로 메모리 손상이나 정렬(GPU가 울타리를 통해 foo의 값을 설정함)과 같은 다른 메모리 문제를 생각할 수 있습니다. 상황을 더욱 혼란스럽게 만들기 위해 주장이 보고될 때마다 foo는 실제로 EValueA와 동일합니다. 실제로 어설션 논리 중간에 foo는 EValueB에서 EValueA로 변경됩니다. 즉, 첫 번째 테스트 이후, 두 번째 테스트 이전입니다! 이는 방심하면 상황이 쉽게 잘못될 수 있음을 보여줍니다! !
디버깅 가능성: 이 모든 복잡성을 염두에 두고 미리 계획하고 항상 단일 스레드 경로를 활성 상태로 유지하여 문제가 로직인지 스레딩인지, 런타임 전환 가능(가능한 경우)인지 알 수 있도록 노력하십시오. 때로는 디버깅보다 생각하는 것이 더 낫습니다.
[The Sims 4의 동시 상호 작용](https://www.gdcvault.com/play/1020190/Concurrent-Interactions-in-The-Sims#:~:text=For The Sims 4%2C we,in to 실행 the 상호 작용)에서는 상호 작용, 제약, 상호 작용 대기열, 전환, 사회화 등을 포함하여 The Sims 4(The Sims 4) 아키텍처의 동시성 기술을 설명합니다.
The Sims의 세계는 게임 개체로 구성되었습니다. 게임 개체는 상호 작용을 제공하며 심도 개체입니다! 심들은 행동의 기본 단위인 상호작용을 실행합니다. 멀티태스킹은 자연스럽고 사람들은 동시에 여러 작업을 수행하며 자주 요청되는 기능과 체계적인 접근 방식이 중요하며 임시 구현에는 많은 작업이 필요하고 결과가 일관되지 않습니다.
실제로 동시적이지 않은 실행은 까다로울 수 있으며 교착 상태, 경쟁 조건 등을 초래할 수 있습니다. 멀티태스킹에는 컨텍스트 전환 및 협업 등이 포함됩니다.


캐릭터 멀티태스킹을 위한 직렬 및 병렬 범례.
하위 작업의 개념은 멀티태스킹에 사용됩니다.

규칙: 작업을 수행할 수 있나요? 상황 → 행동. 작업을 수행하는 방법은 무엇입니까? 행동 → 조건. 반복적인 논리를 피하세요.
제약 조건: 데이터 기반 규칙, 상호 작용 실행을 위한 전제 조건입니다. 질문에 답해 보세요. 상호작용할 수 있나요? 상호 작용을 실행하는 방법은 무엇입니까?
제한된 작성: 데이터 중심. 애니메이션: 위치, 포즈, 운반, XML 조정: 기하학, 방향, 표면, 스크립팅: 채점 기능, 시선.
제약 조합: 다중 작업 조합 제약, 지원 작업: 교차 및 합집합.
상호작용 대기열: 각 시뮬레이션에는 일련의 활성 상호작용과 정렬된 대기 상호작용 대기열이 있습니다. 상호작용에는 높음(사용자 지정), 낮음(자동), 유휴(완료되었지만 계속 실행 중) 등의 우선순위가 있습니다.


큐 처리 및 대화형 처리.
생성적 동작: 제약 조건은 상호 작용을 수행하기 위한 전제 조건을 정의하고 생성적으로 사용될 수 있으므로 제약 조건으로의 변환을 찾는 기능이 필요합니다.
전환 그래프(Transition graph): 각 객체에 대한 제약 조건은 추상 그래프에 저장되고, 가장자리는 상태 변화이며, 그래프를 검색하여 전환 시퀀스를 생성합니다.

변환 그래프를 사용합니다.

그래프 검색: 여러 노드가 요구 사항을 충족할 수 있으며, 에지는 비용에 따라 가중치가 부여되고, 경로에는 대략적인 거리에 따라 가중치가 부여됩니다. 최적의 경로를 검색하여 결정하세요.
검색 최적화: 양방향 검색, 캐리 사용, 슬롯 단순화, 노드 쿼리 인덱스.
파이버를 사용하여 Naughty Dog 엔진 병렬화에서는 파이버를 사용하여 병렬화를 달성하는 Naughty Dog 엔진 기술을 설명합니다.
새로운 운영 체제의 설계 목표는 SPU로 이동할 수 없는 작업 기반 코드를 허용하고, 플레이어가 킥으로 업데이트하고 광선이 캐스팅되기를 기다리는 등 실행 중에 작업을 다른 작업으로 전달할 수 있으며, 게임 프로그래머를 위한 사용하기 쉬운 API, 사용자를 위한 메모리 관리 없음, 작업을 동기화/링크하는 간단한 방법, API 사용 편의성 다음으로 뛰어난 성능을 제공하는 것입니다.
Fiber는 로컬 스레드와 유사하며 사용자는 Fiber 상태 및 저장 레지스터가 포함된 작은 컨텍스트인 스택 공간을 제공합니다. 스레드로 실행, 협력적 멀티스레딩(선점 없음), 광섬유 간 전환이 명시적(PS4의 sceFiberSwitch)이며, 다른 운영 체제도 유사한 기능을 갖습니다. 오버헤드를 최소화하고 파이버 간 전환 시 스레드 컨텍스트 전환이 없으며 등록 저장/복원만 가능합니다. (프로그램 카운트, 포인터 스택, gprs...)
Naughty Dog 엔진의 운영 체제에는 6개의 작업 스레드가 있으며 각 스레드는 CPU 코어에 잠겨 있습니다. 스레드는 실행 단위이고 파이버는 컨텍스트입니다. 작업은 항상 파이버 환경에서 실행되며 원자 카운터는 동기화에 사용됩니다. 160개의 파이버(128 x 64k 스택, 32 x 512k 스택), 3개의 작업 대기열(낮음/보통/높은 우선순위)이 있으며 작업 도용이 없습니다.
모든 것이 작업입니다. 게임 개체 업데이트, 애니메이션 업데이트 및 뼈대 블렌딩, 레이 캐스팅, 명령 버퍼 생성. 단, 시스템 스레드인 I/O 스레드(소켓, 파일 I/O, 시스템 호출...)는 예외 처리기(데이터 읽기, 새 작업 실행)처럼 구현되며 항상 기다리고 값비싼 데이터 처리를 수행하지 않습니다.
새로운 운영 체제의 장점: 기존 게임 플레이 업데이트가 매우 쉽고, 딥 콜 스택에 문제가 없으며, 한 작업이 다른 작업을 기다리게 하는 것이 간단합니다: WaitForCounter(...). 초경량, 교체 가능한 광섬유, PS4의 sceFiberSwitch()와 같은 시스템 지원 작업, 프로그램 카운터 및 스택 포인터 및 기타 모든 레지스터 저장/복원. 단점은 시스템 동기화 프리미티브를 더 이상 사용할 수 없다는 것입니다. 뮤텍스, 세마포어, 조건 변수...는 특정 스레드에 잠겨 있고 파이버는 스레드 간에 이동합니다. 동기화는 하드웨어 수준에서 수행되어야 하며 원자 스핀록은 거의 모든 곳에 있으며 특수 작업 뮤텍스를 사용하여 오랫동안 잠금을 유지하고 필요한 경우 스핀록 대신 현재 작업을 절전 모드로 전환합니다.
파이버 지원: 파이버 및 해당 호출 스택은 디버거에서 볼 수 있고, 파이버는 스레드처럼 검사할 수 있으며, 파이버 이름 지정/변경 가능, 현재 작업 표시, 예외 처리 및 파이버 호출 스택은 스레드처럼 코어 덤프에 저장됩니다. 파이버 안전 스레드 로컬 스토리지(TLS) 최적화, 문제는 테스트 중에 TLS 주소가 캐시될 수 있으며 기본적으로 기능이 실행되고 기능 중간에 파이버를 전환하면 잘못된 TLS 포인터로 깨어난다는 것입니다. 현재 Clang에서는 지원되지 않습니다. 해결 방법: TLS 액세스에 별도의 CPP 파일을 사용하십시오. 작업 시스템에서 적응형 뮤텍스를 사용하면 일반 스레드에서 작업을 추가할 수 있습니다. 스핀 잠금 -> 교착 상태는 시스템 호출을 하기 전에 스핀하고 잠금을 시도하고 우선 순위 반전 교착 상태를 해결하며 초기 스핀으로 인해 대부분의 시스템 호출을 피할 수 있습니다.
엔진의 파이프라인은 다음과 같습니다. 게임 로직은 작업을 렌더링 로직과 GPU에 순서대로 보냅니다.

프레임 중심 설계, 각 단계는 완전히 독립적이며 동기화가 필요하지 않습니다. 한 단계에서는 다음 프레임을 즉시 처리할 수 있어 엔진 설계의 복잡성이 단순화됩니다. 병렬성으로 인해 잠금이 거의 필요하지 않습니다. 잠금은 많은 수의 작업을 단계적으로 업데이트하는 동기화에만 사용됩니다. 이전 디자인과 새로운 디자인을 비교하면 다음과 같습니다.


Naughty Dog 엔진의 프레임 정의는 "처리되어 최종적으로 화면에 표시되는 데이터 조각"입니다. 핵심은 오래 걸리지 않는 '데이터 조각'이다. 프레임은 데이터가 표시되는 이미지가 되는 단계로 정의됩니다.
프레임 매개변수(FrameParams)는 각 디스플레이 프레임의 데이터입니다. 각각의 새 프레임의 인스턴스가 최종적으로 표시됩니다. 이는 엔진의 각 단계를 통해 전송되며 프레임 번호, 증분 시간, 스키닝 매트릭스, 필요한 데이터에 액세스하기 위한 각 단계의 진입점 등 각 프레임의 상태를 포함합니다. 리소스에 대한 경쟁이 없습니다. 각 단계는 고유한 인스턴스에서 작동하므로 잠금이 필요하지 않으며 델타 시간, 카메라 위치, 스키닝 매트릭스, 렌더링할 메시 목록, 시작/종료 타임스탬프와 같은 상태 변수가 매 프레임마다 이 구조에 복사됩니다(게임, 렌더링, GPU 및 플립). 프레임이 특정 단계를 완료했는지 테스트하기 쉽습니다. HasFrameCompleted(frameNumber), 이제 GPU에서 사용할 데이터가 프레임에서 생성되면 수명 주기를 쉽게 추적할 수 있습니다.
메모리 수명 주기: 단일 게임 로직 단계(임시 메모리), 듀얼 게임 로직 단계(낮은 우선순위 레이 캐스팅), 게임 렌더링 로직 단계(객체 인스턴스 배열), 게임에서 GPU 단계(스킨 매트릭스), GPU 단계로 렌더링(명령 버퍼) 및 CPU와 GPU 모두를 위한 메모리!
메모리 부족: 다양한 선형 할당자, 다양한 수명, 최악의 경우에 맞게 크기 조정, 최악의 경우 모든 할당자에 동시에 도달하지 않음, 100-200MiB의 메모리 낭비.
태그된 힙은 블록 기반 할당자, 2M 블록 크기, 2MiB는 PS4의 "대형 페이지" -> 1 TLB 항목이며 각 블록에는 태그(uint64_t)가 있으며 "Free(ptr)" 인터페이스는 없으며 특정 태그와 연결된 모든 블록만 해제될 수 있습니다(아래 그림).

모든 할당자는 표시된 힙을 사용합니다. 2M 블록은 공유 표시된 힙에서 할당되고 할당자에 로컬로 저장됩니다. 할당의 99%는 2MB 미만입니다. 2M보다 큰 할당은 표시된 힙에서 연속적으로 2M 블록을 할당합니다. 이 로컬 블록이 빌 때까지 할당하십시오. 이와 같이 공통 블록 풀을 공유하면 할당자의 크기를 동적으로 조정할 수 있습니다.

표시된 힙을 여러 작업자 스레드에 할당하는 할당자의 그림입니다. 단일 2M 블록이 여러 스레드에서 동시에 사용되는 경우 경쟁을 방지하기 위해 잠겨야 합니다.
최적화: 각 작업자 스레드에 대한 할당자에 2M 블록을 저장하고, 작업자 스레드 인덱스를 사용하여 사용할 블록을 선택하고, 해당 스레드의 모든 할당이 해당 스레드의 블록으로 이동하여 경합을 방지하고, 99.9%의 메모리 할당에 잠금이 필요하지 않아 고용량, 고성능 할당자를 달성합니다.

스레드 블록 할당자 다이어그램.
요약: 파이버는 훌륭하고, 프레임 중심 설계는 엔진을 단순화합니다. FrameParams와 같은 방법을 사용하면 데이터 수명 주기 및 메모리 관리가 크게 단순화되며, 태그 기반 블록 할당자는 다중 프레임 엔진 설계를 처리할 때 매우 유용합니다.
14.4.3.5 특수 기술
고급 화면 공간 앤티앨리어싱에서는 형태학적 앤티앨리어싱, 화면 공간 기반 앤티앨리어싱 및 구현 세부 정보를 포함한 다양한 앤티앨리어싱 기술을 설명합니다. 이 글은 당시 주류였던 앤티앨리어싱 기술을 요약한 것입니다.

해당 글의 삭제 결함에 대한 설명은 다음과 같습니다.
- 손실된 정보는 복구할 수 없습니다. 예를 들어 다운샘플링 아티팩트는 제거할 수 없습니다.

- 반투명 결함은 더 까다롭습니다. 깊이 제거, 경로의 K-버퍼 스텐실링을 통해 이 문제를 해결할 수 있으며, 투명한 형상(예: 창 및 프레임)의 교차를 피하고 투명도가 발생하는 불투명 가장자리를 추가할 수 있습니다.

- 알파 테스트 형상 및 형상 가장자리를 처리할 수 있습니다.

형태학적 앤티앨리어싱은 중요한 가장자리(색상 차이가 작은 경우)를 놓칠 수 있고, 너무 민감할 수 있으며(텍스처 세부 사항 감지), 투명도를 감지하고, 추가 버퍼(예: 노멀, 텍스처 좌표 및 깊이)가 필요하지 않은 색상 불연속성 감지기를 사용합니다. 일반적으로 사용되는 가장자리 감지 컨볼루션 커널은 다음과 같습니다.

2개의 L자 모양으로 구성된 S자 모양과 U자 모양을 포함한 다양한 유형의 선분을 감지합니다.

필요한 실제 길이와 픽셀 위치 적용 범위는 절편 정리를 사용하여 계산할 수 있습니다.

수평 계산의 경우 가장자리 감지를 위해 2개의 추가 버퍼가 사용됩니다(한 개만 표시됨).


4개의 추가 버퍼(상단, 하단, 왼쪽, 오른쪽)에 대한 계산 기술:

수직으로 불연속적인 버퍼에 있지 않은 모든 픽셀을 항상 거부합니다.

형태학적 안티앨리어싱은 항상 U 모양을 명시적인 방식으로 처리하지만 Biri.v의 구현은 ARGB 카운트 버퍼 2개, argb 블렌드 버퍼 1개, RG 불연속 버퍼 1개, 부동 소수점 범위 계산을 위한 1512x512픽셀 조회 테이블 등 많은 메모리를 차지합니다. 현명한 캡슐화 및 버퍼 공유를 통해 전체 메모리 소비를 크게 줄일 수 있습니다(계산 비용은 증가함). 이 알고리즘은 픽셀 셰이더에서 다수의 조건부 분기를 사용하고 다수의 패스를 사용하며 Early-Stencil을 사용하지 않습니다. 따라서 당시의 콘솔에는 적합하지 않았습니다.
**ASAA(Advanced Screenspace Antialiasing)**라는 개선된 버전이 문서에 제안되어 있습니다. ASAA 구현은 불연속성 감지에 색상을 사용하지 않습니다. 깊이가 더 정확하고 깊이가 모든 가장자리와 세밀한 세부 사항이 손실되지는 않음을 보여주기 때문입니다. 추가 가장자리 감지 힌트로 노멀 및 텍스처 좌표를 추가하면 이 두 개의 추가 버퍼를 사용 중인 장면 색상과 안전하게 공유할 수 있습니다. 라플라시안 컨볼루션 커널을 사용한 불연속성 감지 → 가장자리 양쪽의 불연속성 감지:

ASAA는 에지 감지, 불연속성 감지, 계산, 적용 범위 계산 및 기타 프로세스를 개선하여 다음과 같은 이점을 달성했습니다.
적당한 메모리 사용량. 기술 및 불연속성을 위한 1개의 RGB 버퍼(2xMSAA보다 낮음), 노멀 및 텍스처 좌표를 위한 2개의 G16R16, 공유 가능, 가장자리 감지 셰이더는 텍스처 바인딩되므로 이러한 값을 압축하는 것이 좋습니다.
조건부 분기가 없습니다.
당시의 콘솔에 적합합니다.
기타 기능: U자형 흐림 처리, Xbox360 및 PS3에서 카운팅을 CPU로 전송할 수 있습니다.
ASAA의 구현 단계 및 프로세스는 다음과 같습니다.

믹싱을 최적화할 수 있고 선형 텍스처를 XBox360에서 사용할 수 있으며 계산은 GPU에서 수행할 수 있습니다. ASAA의 효과는 다음과 같이 비교됩니다.

Volume Distance Field를 사용하는 Frostbite 2의 파괴 마스킹은 Frostbite 2 엔진이 물체 파괴 효과를 렌더링하기 위해 Volume Distance Field를 사용한다고 공유했습니다.
부호 있는 체적 거리 필드를 사용하면 형상에 구를 배치하고, 마스크가 깨진 위치를 표시하고, 구 그룹에서 거리 필드를 계산하고, 낮은 해상도(~2m/픽셀, 마스크된 형상당 하나의 텍스처)를 사용하여 결과를 체적 텍스처에 저장하는 것입니다.

포인트 샘플링, 삼선형 필터링, 증폭 + 디테일 등과 같은 기술은 더 높은 디테일 효과를 얻을 수 있습니다.

// 의 거리계산/산출(Calculate)코드
float opacityFromDistanceField(float distanceField, float detail)
{
distanceField += detail * g_detailInfluence;
return saturate(distanceField * g_distMultiplier + g_distOffset);
}체적 텍스처에 대해 참고하세요. Xbox 360 체적 텍스처에는 32×32×4의 크기 배수가 필요하며, 많은 작은 텍스처는 메모리를 낭비하고, 텍스처 아틀라스를 사용하며, 차원당 하나의 아틀라스는 패키징을 단순화하고, 경계 누출을 방지하려면 패딩이 필요합니다.
파괴 마스크를 그릴 때 형상과 함께 그리고 픽셀 셰이더에서 [branch]를 사용하여 최적화하고 RSX의 동적 분기는 효율적이지 않으며 6개의 루프가 분기에 부딪히고 세그먼트 크기가 대략적(800-1600픽셀)이며 마스크를 지연 데칼로 그립니다. 지연된 데칼을 그리는 단계:
장면 기하학을 그립니다.
데칼 영역 주위에 볼록한 볼륨을 그립니다.
깊이 버퍼를 가져와 볼륨 내 로컬 위치로 변환합니다.
볼륨 텍스처와 같은 불투명도를 찾으려면 로컬 위치를 사용하십시오.
기하학적 모양 위에 블렌딩하세요.
투영된 디테일/노멀 텍스처의 경우 탄젠트 벡터가 필요하며 G-버퍼 노멀은 적합하지 않으며 노멀 맵의 데이터를 포함합니다. 제한된 수의 탄젠트 벡터가 필요합니다. 기본 기하학을 사용하여 G-버퍼에 인덱스를 쓰고, 인덱스를 사용하여 탄젠트 벡터 조회 테이블이 포함된 텍스처를 샘플링합니다.
알파 블렌딩의 경우 고정 기능 블렌딩은 블렌딩을 위한 출력 알파인 G-버퍼와 대상 알파로 블렌딩할 때 문제를 일으킵니다. 데칼의 출력 알파에 의해 제한되고 G 버퍼 레이아웃에 의해 제한되므로 프로그래밍 가능한 블렌딩이 좋은 사용 사례입니다.
텍스처 밉맵 선택의 경우 쿼드 밉맵 선택으로 인해 경계 주변에 아티팩트가 발생할 수 있으므로 샘플링을 위해 tex2Dlod를 사용하여 셰이더에서 밉 수준을 계산할 수 있습니다.

쿼드 내의 텍스처 좌표에 불연속성이 있는 경우 해당 쿼드에 대한 밉맵 선택이 올바르지 않습니다. 오른쪽의 확대된 이미지에서 쿼드의 위쪽 부분에 대한 텍스처 좌표는 벽돌 벽 텍스처에서 가져온 것이고 아래쪽 부분은 바닥 텍스처에서 가져온 것입니다. 이러한 텍스처 좌표는 텍스처 아틀라스의 서로 다른 위치에 있으며 GPU는 이 픽셀 세트에 대해 가장 낮은 밉맵을 선택합니다. 이 문제에 대한 해결책은 각 개별 픽셀에 대한 올바른 밉 수준을 수동으로 계산하고 tex2Dlod를 사용하여 명시적으로 샘플링하는 것입니다. 입력 v.n 및 distToNearPlane을 사용하여 2D 조회 테이블 텍스처를 생성하여 계산을 최적화할 수 있습니다.
디스턴스 필드 삼각형 컬링을 처리할 때 삼각형별 분기를 사용하고 디스턴스 필드에 대해 각 삼각형을 테스트하고 두 개의 인덱스 버퍼를 출력하고 두 개의 그리기 호출을 실행합니다. 컬링 결과는 거리 필드가 변경될 때 캐시되고 업데이트됩니다.

볼류메트릭 디스턴스 필드 렌더링을 기반으로 한 파괴 효과.
고급 재료 렌더링(Advanced Material Rendering)은 피부, 수정, 유리, 해수, 늪지 물, 진흙 물과 같은 고급 재료를 렌더링하기 위한 여러 기술을 도입합니다. 제안된 알고리즘은 제한된 메모리와 컴퓨팅 성능을 고려하여 현재 세대의 게임 콘솔을 대상으로 합니다. 표면 아래 산란, 반투명도, 투명도, 물 산란, 동적 표면 등과 같은 몇 가지 중요한 재료 특성을 다룹니다. 또한 디퍼드 렌더러의 기능, 성능, 미적 및 구현 문제에 대해 논의하여 앞서 언급한 재료 렌더링에 대해 검증된 솔루션을 제공합니다.
디더링 기술은 기사에 언급되어 있습니다. 디더링은 언더샘플링을 보다 합리적인 노이즈로 덮기 위해 특정 패턴으로 샘플링하는 것입니다. 분포는 일반적으로 균일 및 포아송을 포함한 샘플 오프셋의 "회전 디스크"를 사용하여 완료됩니다.

회전 디스크 디더링을 사용하면 디스크 분포의 정규화된 공간에서 N 포인트를 사용하여 미리 계산된 오프셋 분포 테이블이 사용됩니다. 각 그림자 픽셀에 대해 임의의 노멀 벡터 N을 얻고, 각 샘플에 대해 디스크 분포의 한 점을 N만큼 회전하여 해당 점을 샘플링용 스케일링 오프셋으로 사용합니다. 선형 샘플링은 불연속적인 샘플링 지점으로 인해 중요합니다.
디더링 사용 사례: 그림자. 이중 포물선형 부드러운 그림자, 단 4개의 탭, 최소한의 오버헤드, 그럴듯한 노이즈, 더 큰 부드러움에는 더 많은 패턴이 필요합니다.


디더링을 적용하지 않은 경우(위)와 디더링을 적용한 경우(아래)의 그림자 효과 비교.
투명성의 경우, 디퍼드 아키텍처의 투명성은 까다롭습니다. 일반적인 경우는 단순 투명성(밝음), 완전히 투명한 재질, 반투명 재질(빛남), 반투명 재질(항상 빛남)입니다.
간단한 투명도의 경우 스크린 도어 효과를 사용하고 디더링 패턴을 계산/찾은 다음 이를 사용하여 투명도 값에 따라 패턴을 번갈아 픽셀을 "삭제"할 수 있습니다. 레벨 4 투명도는 대역폭이 제한될 때 계산하기 쉽습니다. 컴파일러가 픽셀을 컬링하고 있는지 확인하는 것을 기억하십시오. 이 작업은 가능한 한 빨리 수행되어야 합니다. 코드는 다음과 같습니다:
float jitteredTransparency(float alpha, float2 vP)
{
const float jitterTable[4] =
{
float( 0.0 ),
float( 0.26 ),
float( 0.51 ),
float( 0.76 ),
};
float jitNo = 0.0;
int2 vPI = 0;
vPI.x = vP.x % 2;
vPI.y = vP.y % 2;
int jitterIndex = vPI.x + 2 * vPI.y;
jitNo = jitterTable[jitterIndex];
if (jitNo > alpha)
return -1;
return 1;
}
디더링된 투명도는 720p에서 보기 좋지 않습니다. 지저분한 디더링된 픽셀을 흐리게 하고 싶지만 이를 감지하고 흐리게 하는 다른 채널을 감당할 수 없습니다. Edge AA의 패스에서 이미 실행되었습니다.
사용자 정의 가장자리 AA는 디퍼드 렌더러의 일반적인 기술로, 전체 화면 패스이며, 깊이/일반 데이터를 기반으로 가장자리를 찾은 다음 흐리게 합니다. 가장자리 AA 필터에 선별된 픽셀 "사이" 가장자리를 찾도록 요청하면 무료로 멋진 블렌딩을 얻을 수 있으며, 플래그를 사용하거나 가장자리 감지 소스를 변경하여 더 해킹적인 방식으로 수행할 수 있습니다(불연속성을 더 깊게 가져옴).

왼쪽: 맞춤형 가장자리 AA 없음; 오른쪽: 사용자 지정 가장자리 AA 사용.
완전히 투명한 물체에는 조명이 필요하지 않으며 빛을 반사/굴절하기만 하면 됩니다. 유리, 물, 왜곡된 입자에 적합합니다. 이는 후유증으로 간주되며 알파 채널에서 깊이 정보를 쉽게 얻을 수 있도록 텍스처로 백 버퍼가 필요합니다.
그림자가 있는 전체 장면과 정확하고 일관성을 유지하기 위해 조명이 필요한 반투명 재질입니다. 따라서 샘플 재구성에서 디더 모드를 사용하여 단일 조명 및 음영 비용을 사용하여 지연 모드에 두기를 원합니다. 2패스 렌더링을 사용할 수 있습니다.
- 채널 1: 디더 모드를 사용하여 반투명 재질을 G 버퍼에 씁니다.
패턴 오버레이는 기본적으로 쿼드(예: 2x2)를 렌더링하며, 패턴 선택은 오버레이되는 투명 재질의 레이어 수에 따라 달라지며, 2x2 쿼드는 오버레이할 수 있으며, 추가 레이어마다 조명 품질이 저하됩니다.

- 패스 2: 올바른 조명 값을 얻기 위해 샘플 재구성을 사용하고 시퀀싱 및 알파 블렌딩이 필요한 조명 축적 후 머티리얼이 완전히 렌더링됩니다.
겹치는 반투명 머티리얼은 뒤에서 앞으로 정렬됩니다(반투명 머티리얼이 먼저 렌더링됩니다). 각각의 겹치는 재질에 대해 광 버퍼는 올바른 모드에서 샘플링되어 원래 조명 값을 얻습니다. 재질은 전체 해상도 텍스처와 재구성된 조명을 사용하여 렌더링됩니다. 투명도는 백 버퍼와의 알파 블렌딩을 통해 처리됩니다.
조명 재구성 중에 하나의 샘플만 수집하면 심각한 앨리어싱이 발생하므로 재구성을 위해 여러 샘플을 수집해야 합니다. 음영처리되는 픽셀이 원본 픽셀인지 확인하고, false인 경우 이웃을 샘플링하여 유효한 샘플을 얻고, 샘플 재구성을 위해 가중치를 부여하고 평균을 냅니다. true인 경우 변경하지 않고 그대로 둡니다. 이동 중 앨리어싱을 줄이고 안정성을 향상시키려면 2개 이상의 재질에 2x2 쿼드를 사용하는 것 = 텍스처 캐시 가비지 및 앨리어싱이 많습니다.
- 유사한 접근 방식은 추론 렌더링입니다.
단일 투명도를 갖는 지연 렌더러도 있습니다:
- 반투명 기하학은 체커보드 패턴으로 g-버퍼에 렌더링됩니다.
알베도는 1로 설정됩니다.
패스 1은 기능 가중치입니다(노멀과 반사에만 해당).
- 디퍼드 쉐이딩 이후.
누적 버퍼에는 반투명 기하학 조명 정보와 기본 그림자 기하학의 교대 픽셀이 포함되어 있습니다.
패스 2는 조명 데이터, 음영 처리된 배경을 모두 재구성합니다.
재료를 최고 품질로 렌더링합니다.
알파 블렌딩은 수동으로 수행됩니다.

반투명 외에도 이 기사에서는 피부, 머리카락, 물과 같은 특수 재질의 렌더링도 다룹니다. 물의 광학 원리에는 표면 노멀, 반사, 굴절, 광산란, 소멸, 화선, 고체 표면 데칼, 스페큘러 반사 등이 포함됩니다(아래 그림).

수면에 대한 위의 광학 원리를 고려하여 해당 렌더링 솔루션이 이 기사에 제공됩니다.

[적응형 체적 그림자 맵](http://advances.realtimerendering.com/s2010/Salvi-AVSM(SIGGRAPH 2010 Advanced RealTime Rendering Course).pdf)은 연기, 안개, 구름, 머리카락과 같은 체적 물질로부터 신뢰할 수 있는 그림자를 얻기 위해 Intel 그래픽 연구자들이 개발했습니다.
AVSM은 고정된 수의 노드, 가변 및 무한 오류, 빛 폐색체 유형 및/또는 공간 분포에 대해 어떠한 가정도 하지 않는 사용하기 쉬운 방법을 사용하여 작은 고정 메모리 공간을 사용하여 적응형 체적 광 감쇠 함수를 생성하기 위해 단순화된 알고리즘을 스트리밍할 수 있습니다.
단일 AVSM 텍셀은 N개의 노드를 인코딩하며, 각 노드는 깊이와 투과율 값으로 표시됩니다. 노드는 항상 정렬된(앞에서 뒤로) 순서로 저장됩니다. 텍셀의 모든 노드를 동일한 값으로 초기화하고 깊이를 원거리 평면으로 설정하고 투과율을 1(폐색 없음)로 설정하여 AVSM을 지웁니다. 들어오는 광선 폐색 볼륨은 라이트 뷰 벡터와 정렬된 세그먼트, 두 점(진입점과 출구점)으로 정의된 세그먼트 및 출구점의 투과율(진입점의 투과율은 암시적으로 1로 설정됨)로 표시됩니다. 입구점과 출구점 사이의 공간이 균일하게 조밀한 매질로 채워져 있다고 가정하면, 일반적으로 조각별 지수 곡선 형태로 생성되는 투과율 곡선을 사용하여 문제를 단순화할 수 있습니다(대부분의 경우 시각적인 차이가 크지 않음).

첫 번째 및 마지막 노드는 매우 중요한 시각적 단서를 제공하므로 압축/제거되지 않습니다. 마지막 노드는 볼륨 뒤에 있는 모든 수신기에 전송되는 섀도우 정보를 인코딩하기 때문에 매우 중요합니다. 예를 들어, 테이블 위의 담배 연기로 인해 드리워진 그림자는 항상 정확합니다(압축 아티팩트 없음). 노드가 제거되면 나머지 노드의 위치는 원래 곡선(깊은 그림자 맵)에 더 잘 맞도록 업데이트되지 않습니다. 실제로 12번의 삽입 압축 반복을 통해 노드 위치를 업데이트하면 노드가 압축 평면에서 무작위 이동을 수행할 때 예측할 수 없는 결과가 발생할 수 있습니다.

DirectX 11 기반 구현은 스트리밍 단순성을 위해 설계된 알고리즘을 사용하지만 동일한 픽셀에 매핑된 조각을 실행하면 현재 픽셀 셰이더에서 사용할 수 없는 구조에 대한 데이터 경합 및 원자 RMW 작업이 발생합니다. 두 가지 구현 버전이 있습니다.
속도는 느리지만 메모리가 고정된 컴퓨팅 셰이더를 기반으로 하는 입자용 소프트웨어 파이프라인 프로토타입은 최적화 작업이 거의 없으며 가변 메모리 구현보다 약 2배 느립니다.
픽셀 셰이더를 기반으로 속도는 빠르지만 가변 메모리를 사용합니다.

AVSM의 성능 측면은 다음과 같습니다. 경쟁력 있는 성능, 더 높은 이미지 품질, 섀도우 조회가 지배적입니다. 일반적으로 AVSM 관련 렌더링 시간의 30% 미만이 삽입 코드에 소비되며 DSM은 AVSM보다 20-40배 느립니다.

요약하면, AVSM의 장점은 적응형 샘플링을 통해 이미지 품질을 향상시키고, 주기적인 샘플링 또는 가시성 함수군 확장을 기반으로 하는 방법의 일반적인 함정을 피하고, 고정되어 사용하기 쉽고, 불투명체 유형 및 공간 분포에 대한 사전 지식이 필요하지 않으며, 속도와 저장을 위해 이미지 품질을 쉽게 교환할 수 있다는 것입니다. 단점은 빠른 고정 메모리 구현을 위해서는 프레임 버퍼에 대한 읽기-수정-쓰기 작업 지원을 추가하기 위해 그래픽 하드웨어가 필요하다는 것입니다.
Direct3D 11을 사용한 픽셀별 연결 목록은 DX11을 기반으로 하는 픽셀별 연결 목록의 특성, 구현, 최적화 및 적용을 소개합니다.
연결리스트(Linked List)는 기존 실시간 그래픽스 API로는 효율적으로 구현하기 어려웠던 프로그래밍에 유용한 데이터 구조이다. DX11을 사용하면 연결된 목록, 픽셀별 연결된 목록, 동일한 화면 위치에 속하는 모든 픽셀의 연결된 목록 모음을 효율적으로 생성하고 구문 분석할 수 있습니다. 연결 목록에는 두 단계가 포함됩니다.
- 연결리스트 생성. 전달된 조각을 연결된 목록에 저장합니다.
"조각 및 링크" 버퍼에는 저장을 위한 모든 조각의 데이터와 링크가 포함되어 있습니다. 모든 조각을 저장할 만큼 충분히 커야 합니다. 카운터를 사용하여 생성을 지원합니다. UAV 보기에서 D3D11_BUFFER_UAV_FLAG_COUNTER 플래그를 사용합니다. 성명은 다음과 같습니다 :
struct FragmentAndLinkBuffer_STRUCT
{
FragmentData_STRUCT FragmentData; // Fragment data
uint uNext; // Link to next fragment
};
RWStructuredBuffer <FragmentAndLinkBuffer_STRUCT> FLBuffer;"시작 오프셋" 버퍼에는 각 픽셀 위치에 작성된 마지막 조각의 오프셋이 포함됩니다. 화면 크기는 너비 높이 sizeof(UINT32)이며 마법 값(예: -1)으로 초기화됩니다. 마법 값은 더 이상 조각이 저장되지 않음을 의미합니다(예: 목록의 끝). 성명은 다음과 같습니다 :
RWByteAddressBuffer StartOffsetBuffer;연결된 목록이 생성되면 아직 색상 렌더링 대상 바인딩이나 렌더링이 없으며 LL에 저장됩니다. 필요한 경우 깊이 버퍼를 바인딩합니다. OIT에서는 나중에 필요하며 UAV를 입력/출력으로 바인딩합니다(StartOffsetBuffer(R/W), FragmentAndLinkBuffer(W)).

픽셀별 연결 목록 생성 다이어그램. 그림의 노란색 삼각형은 시작 오프셋 버퍼의 두 픽셀을 차지하고 각 픽셀은 조각 및 링크 버퍼의 위치를 가리킵니다. 카운터는 누적되고 녹색 및 주황색 픽셀은 노란색 이전에 처리 및 저장되었습니다.
링크 생성 코드는 다음과 같습니다.
float PS_StoreFragments(PS_INPUT input) : SV_Target
{
// 계산/산출(Calculate)데이터 (컬러 、뎁스 )。
FragmentData_STRUCT FragmentData = ComputeFragment();
// 현재(Current)픽셀(Pixel)추가(Add)。
uint uPixelCount = FLBuffer.IncrementCounter();
// StartOffsetBuffer 내에서 。
uint vPos = uint(input.vPos);
uint uStartOffsetAddress= 4 * ( (SCREEN_WIDTH*vPos.y) + vPos.x );
uint uOldStartOffset;
StartOffsetBuffer.InterlockedExchange(uStartOffsetAddress, uPixelCount, uOldStartOffset);
// 및 버퍼 내에서 추가(Add)의 개 。
FragmentAndLinkBuffer_STRUCT Element;
Element.FragmentData = FragmentData;
Element.uNext = uOldStartOffset;
FLBuffer[uPixelCount] = Element;
}- 연결리스트에서 렌더링합니다. 연결 목록 순회 및 저장소 조각 처리. 픽셀을 렌더링하는 단계:
- "시작 오프셋" 버퍼와 "조각 및 링크" 버퍼를 SRV로 바인딩합니다.
Buffer<uint> StartOffsetBufferSRV;
StructuredBuffer<FragmentAndLinkBuffer_STRUCT>
FLBufferSRV;전체 화면 쿼드를 렌더링합니다.
각 픽셀에 대해 연결된 목록을 구문 분석하고 이 화면 위치에 대한 조각을 검색합니다.

위 그림은 라인 2의 2번째 위치에서 유효한 데이터를 검색하고, Start Offset Buffer를 기준으로 Fragment 및 Link Buffer 데이터를 가져옵니다.

Fragment and Link Buffer가 위 그림의 노란색 픽셀의 데이터를 획득하면 해당 픽셀에 다른 데이터(주황색)가 있음을 발견하므로 인덱스에 따라 다음 픽셀 데이터를 읽습니다.
- 필요에 따라 조각 목록을 처리합니다. 정렬, 최대값 찾기 등과 같은 알고리즘에 따라 다릅니다.

픽셀 연결 리스트의 모든 데이터를 읽은 후 필요에 따라 조각 리스트를 처리합니다. 그림은 평균 픽셀 색상을 보여줍니다.
float4 PS_RenderFragments(PS_INPUT input) : SV_Target
{
// 계산/산출(Calculate)UINT정렬 의 버퍼
uint vPos = uint(input.vPos);
uint uStartOffsetAddress = SCREEN_WIDTH*vPos.y + vPos.x;
// 페치/가져오기(Fetch)현재(Current)픽셀(Pixel)의 개 의
uint uOffset = StartOffsetBufferSRV.Load(uStartOffsetAddress);
// 위치 의 테이블
float4 FinalColor=float4(0,0,0,0);
while (uOffset!=0xFFFFFFFF) // 0xFFFFFFFF는
{
// 현재(Current)픽셀(Pixel)
Element=FLBufferSRV[uOffset];
// 에 따라 처리(Process)픽셀(Pixel)
ProcessPixel(Element, FinalColor);
// 개
uOffset = Element.uNext;
}
return (FinalColor);
}OIT(Order Independent Transparency)는 픽셀별 연결 목록을 통해 구현될 수 있으며, 투명 조각을 PPLL에 저장하고, 렌더링 단계에서는 픽셀을 뒤에서 앞으로 정렬하고 픽셀 셰이더에서 수동으로 혼합하며, 혼합 모드는 픽셀별로 고유할 수 있습니다! MSAA에서 지원하는 특수 사례입니다.
연결된 목록 구조는 UAV에 쓰거나 읽는 데이터의 양을 줄여 성능을 최적화합니다(예: float4 색상 대신 단위). OIT의 데이터 구조 예:
struct FragmentAndLinkBuffer_STRUCT
{
uint uPixelColor; // 의 픽셀(Pixel)컬러
uint uDepth; // 픽셀(Pixel)뎁스
uint uNext; // 개
};16비트 색상(565) + 16비트 깊이, 성능/메모리/품질 절충을 사용하여 색상과 깊이를 동일한 단위(동일한 알파인 경우)로 묶는 것도 가능합니다.
Linked List에서 픽셀 셰이더를 만들기 전에 보이는 조각만 사용하고 [earlylengthstencil]을 사용하여 깊이 테스트를 통과한 투명한 조각(즉, 보이는 조각)만 저장되도록 하여 성능과 렌더링 정확성을 절약할 수 있습니다!
[earlydepthstencil]
float PS_StoreFragments(PS_INPUT input) : SV_Target
{
(...)
}픽셀 정렬, 내부 정렬에는 연결된 목록에 대한 R/W 액세스가 필요하며 희소 메모리 액세스 = 느립니다! 더 나은 접근 방식은 모든 픽셀을 임시 레지스터 배열에 복사한 다음 정렬하는 것입니다. 임시 배열 선언은 화면 좌표당 픽셀 수에 대한 엄격한 제한을 의미하며 이는 성능에 대한 절충이 필요합니다. 구체적인 정렬 프로세스는 다음 그림 세트에 나와 있습니다.





// 저장(Store)픽셀(Pixel)로써 정렬
(...)
static uint2 SortedPixels[MAX_SORTED_PIXELS];
// Parse linked list for all pixels at this position
// and store them into temp array for later sorting
int nNumPixels=0;
while (uOffset!=0xFFFFFFFF)
{
// Retrieve pixel at current offset
Element=FLBufferSRV[uOffset];
// Copy pixel data into temp array
SortedPixels[nNumPixels++]=
uint2(Element.uPixelColor, Element.uDepth);
// Retrieve next offset
[flatten]uOffset = (nNumPixels>=MAX_SORTED_PIXELS) ?
0xFFFFFFFF : Element.uNext;
}
// Sort pixels in-place
SortPixelsInPlace(SortedPixels, nNumPixels);
(...)
// PS 내에서 의 픽셀(Pixel)블렌딩(Blending)
(...)
// Retrieve current color from background texture
float4 vCurrentColor=BackgroundTexture.Load(int3(vPos.xy, 0));
// Rendering pixels using SRCALPHA-INVSRCALPHA blending
for (int k=0; k<nNumPixels; k++)
{
// Retrieve next unblended furthermost pixel
float4 vPixColor= UnpackFromUint(SortedPixels[k].x);
// Manual blending between current fragment and previous one
vCurrentColor.xyz= lerp(vCurrentColor.xyz, vPixColor.xyz,
vPixColor.w);
}
// Return manually-blended color
return vCurrentColor;MSAA를 지원하는 픽셀별 연결 목록을 통해 OIT를 구현할 때 단일 샘플을 연결 목록에 저장하는 데 많은 메모리가 필요하면 성능이 저하됩니다! 해결책은 이전과 같이 투명 픽셀을 PPLL에 저장하되 샘플 적용 범위 데이터도 포함하는 것입니다. MSAA 모드만큼 많은 비트가 필요하며 PS 구조에서 SV_COVERAGE를 선언합니다.
struct PS_INPUT
{
float3 vNormal : NORMAL;
float2 vTex : TEXCOORD;
float4 vPos : SV_POSITION;
// 픽셀(Pixel)데이터
uint uCoverage : SV_COVERAGE;
}연결된 목록 구조는 이전과 거의 동일하며 깊이는 이제 24비트로 압축되고 8비트는 적용 범위를 저장하는 데 사용됩니다.
struct FragmentAndLinkBuffer_STRUCT
{
uint uPixelColor; // Packed pixel color
uint uDepthAndCoverage; // Depth + coverage
uint uNext; // Address of next link
};샘플 적용 범위의 예는 다음과 같습니다. 세 번째 샘플이 다루어지며, 이때 uCoverage = 0x04(바이너리 0100)입니다.

깊이 및 적용 범위 데이터가 압축되어 저장됩니다.
Element.uDepthAndCoverage = ( In.vPos.z*(2^24-1) << 8 ) | In.uCoverage;렌더링 단계에서는 단일 샘플을 작성할 수 있어야 하므로 PS는 샘플링 빈도로 실행됩니다. 입력 구조에서 SV_SAMPLEINDEX를 선언하고 연결된 목록을 구문 분석한 후 나중에 정렬하기 위해 픽셀을 임시 배열에 저장하면 됩니다. 이는 MSAA가 아닌 경우와 유사합니다. 단, 적용 범위 데이터가 래스터라이제이션되는 샘플 인덱스와 일치할 때만 샘플이 저장된다는 점이 다릅니다. 렌더링 코드는 다음과 같습니다.
static uint2 SortedPixels[MAX_SORTED_PIXELS];
// Parse linked list for all pixels at this position
// and store them into temp array for later sorting
int nNumPixels=0;
while (uOffset != 0xFFFFFFFF)
{
// Retrieve pixel at current offset
Element=FLBufferSRV[uOffset];
// Retrieve pixel coverage from linked list element
uint uCoverage=UnpackCoverage(Element.uDepthAndCoverage);
if ( uCoverage & (1<<In.uSampleIndex) )
{
// Coverage matches current sample so copy pixel
SortedPixels[nNumPixels++]=Element;
}
// Retrieve next offset
[flatten]uOffset = (nNumPixels>=MAX_SORTED_PIXELS) ?
0xFFFFFFFF : Element.uNext;
}GPU를 사용한 실시간 텍스처 압축에서는 GPU를 사용하여 현재 콘솔과 DirectX 10.1 비디오 카드에서 DXT 텍스처 압축을 수행하는 방법을 설명합니다. 각 플랫폼의 구현 세부 사항과 최적화를 다루면서 GPU 컴퓨팅 API나 비트별 수학 연산의 존재에 의존하지 않는 방법을 제안합니다.
GPU 압축을 사용하는 이유는 게임이 런타임 생성 콘텐츠(하이브리드 맵, 동적 큐브맵, 사용자 생성 콘텐츠)를 더 많이 사용하고 CPU 압축이 느리고 추가 동기화 및 대기 시간이 필요하기 때문입니다. 아래 그림의 성능 비교는 실시간 DXT 압축 용지의 CPU 성능 데이터에서 나온 것입니다.

DXT1/BC1은 4x4 텍셀을 나타내는 64비트 블록으로, 4개의 색상 값, 2개의 저장 값 및 2개의 보간이 있습니다.

색상 색인을 위한 의사 코드는 다음과 같습니다.
Index00 = color_0;
Index01 = color_1;
Index10 = 2/3 * color_0 + 1/3 * color_1;
Index11 = 1/3 * color_0 + 2/3 * color_1;
if (color_1 > color_0)
{
Index 10 = 1/2 * color_0 + 1/2 * color_1;
Index 11 = “Transparent”;
}DXT 압축의 기본 단계:
- 4x4 텍셀 그리드를 얻으세요. 코드는 다음과 같습니다:
float2 texel_size = (1.0f / texture_size);
texcoord -= texel_size * 2;
float4 colors[16];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
float2 uv = texcoord + float2(j, i) * texel_size;
colors[i*4+j] = uv;
}
}저장 색상으로 사용하려는 색상을 찾으세요. 이 작업은 매우 비쌀 수 있지만 끝점 색상을 찾는 몇 가지 방법이 나중에 언급되거나 매우 저렴합니다! 끝점 값을 설정할 때 Alpha에 주의해야 합니다.
각 4x4 텍셀을 가장 적절한 색상과 일치시킵니다. 텍셀 인덱스를 찾는 코드는 다음과 같습니다.
float3 color_line = endpoints[1] - endpoints[0];
float color_line_len = length(color_line);
color_line = normalize(color_line);
int2 indices = 0;
for(int i=0; i<8; i++)
{
int index = 0;
float i_val = dot(samples[i] - endpoints[0], color_line) / color_line_len;
float3 select = i_val.xxx > float3(1.0/6.0, 1.0/2.0, 5.0/6.0);
index = dot(select, float3(2, 1, -2));
indices.x += index * pow(2, i*2);
} 다음 8픽셀에 대해 반복합니다.
- 블록의 이진 표현을 만듭니다.
dxt_block.r = max(color_0_565, color_1_565);
dxt_block.g = min(color_0_565, color_1_565);
dxt_block.b = indices.x;
dxt_block.a = indices.y;
return dxt_block;-결과를 텍스처에 넣습니다. 방법은 플랫폼에 따라 다르며, 렌더링 대상은 16:16:16:16의 부호 없는 짧은 형식을 사용하여 소스 크기의 1/4, 1024x1024 소스 = 256x256 대상이어야 합니다.
디퓨즈맵의 런타임 압축과 오프라인 압축 비교 및 색상 차이는 다음과 같습니다.


성능을 조정하기 위해 할 수 있는 일이 있습니다. 셰이더 컴파일러는 똑똑하지만 완벽하지는 않습니다. 언롤링과 루핑의 성능을 테스트하고, 대상 형식에 대한 변형 셰이더를 생성하고, 2개의 구성 요소만 사용하면 노멀 맵이 더 저렴합니다. 노멀맵의 런타임 압축과 오프라인 압축 비교 및 색상 차이는 다음과 같습니다.


[DDOF(Optimized Diffusion Depth Of Field Solver)](http://www.klayge.org/material/4_2/DoF/An Optimized Diffusion Depth of Field Solver.pdf)는 CoC 뎁스 오브 필드(DoF)에 대한 몇 가지 깊이 최적화 기술을 공유합니다. DOF의 솔루션에는 삼중대각 시스템(아래)이 포함됩니다. 여기서 주황색은 CoC에서 발생하는 각 픽셀의 입력 행/열이고, 녹색은 흐림이 생성되는 행/열이고, 빨간색은 입력 이미지의 행/열입니다.

기사에서 언급한 이전 솔버(Solver)에는 하이브리드 GDC2010 솔버와 순환 축소(CR) 솔버가 포함됩니다. 바닐라 CR 솔버의 기능은 다음과 같습니다.

그러나 위 그림의 크기 1 단계에서 중지하면 병렬화가 방해되고 성능 저하가 발생합니다. 합리적인 크기에서 중지한 다음 충분히 큰 병렬 작업 부하로 Y를 풀 수 있습니다.

메모리 최적화 측면에서 rgba32f를 rgba16f로 변경할 수 있습니다(명백한 결함 없음). 또한 위 그림의 abc 텍스처는 abc 구성 프로세스를 건너뛰고 첫 번째 감소 과정에서 즉석에서 abc를 계산할 수 있는 솔버에서 사용하는 가장 큰 표면이기 때문에 다시 한 번 많은 메모리를 절약합니다. (아래 사진)

첫 번째 감소 후의 텍스처는 상당한 양의 메모리를 절약하게 되며, 감소의 4개 채널은 특수한 교체 과정을 통해 1~4개를 대체하여 1개의 특수 감소 채널로 줄일 수 있습니다.

DX11에서는 abc와 X를 rgba_uint 텍스처로 압축할 수 있으며 SM5 데이터 패키징을 사용할 수 있습니다.

DX11 메모리 최적화는 또한 솔버의 수평 및 수직 통과를 가능하게 하며, 저해상도 RT 체인은 두 번 표시되어야 하고, 수평 축소/교체 체인과 수직 축소/교체 체인이 필요합니다. UAV를 사용하면 수평 체인의 데이터를 수직 체인에 재사용할 수 있으며 개념 증명 구현을 통해 이것이 잘 작동하지만 런타임 성능에 상당한 영향을 미치는 것으로 나타났습니다(~40% 프레임 속도 감소). 메모리가 이미 부족하므로 RT를 유지하고 메모리에 정말로 관심이 있는 경우에만 사용하십시오.
위의 방법으로 최적화한 결과 4:1 Reduction + SM5 Packing 방법이 최고의 성능을 달성하고 가장 낮은 메모리를 차지했습니다.

Battlefield 3 및 Need For Speed의 5가지 렌더링 아이디어는 Frostbite 2 엔진의 5가지 렌더링 기술, 즉 분리 가능한 보케 DOF, Hi-Z//Z-Cull, 크로마 서브샘플링 이미지 처리, 타일링 기반 디퍼드 렌더링, 시간적으로 안정적인 스크린 스페이스 앰비언트 오클루전(SSAO)을 도입합니다.
분리 가능한 Bokeh DOF의 퍼지 프로세스에는 여러 가지 방법이 있습니다.
가우시안 블러. DX9 게임에서 흔히 볼 수 있습니다.
2D 영역 샘플링. 텍스처 탭 폭발로 인해 커널 크기가 제한됩니다.
GS 확장 포인트 스프라이트. Heavy fill rate, CryEngine3 및 UE3가 취한 접근 방식입니다.
이미지 공간의 모든 흐림은

육각형 블러는 육각형을 3개의 마름모로 분해할 수 있으며 각 마름모는 별도의 블러로 계산할 수 있으며 총 7개의 패스(모양 3개 × 블러 2개 + 조합 1개)에 대해 계산할 수 있습니다.

분리형 필터를 사용한 육각형 블러는 있으나 7채널, 6블러는 경쟁력이 없어 줄여야 합니다.
아래 그림을 보면 총 2개의 채널만 필요하지만 채널 1은 2개의 MRT를 출력해야 하고, 채널 2는 2개의 MRT를 읽어야 함을 보여줍니다. 이제 총 5개의 블러가 1개로 줄어들고 최종 결합된 채널은 채널 2의 일부가 됩니다.

아래에 표시된 방법은 채널 1에서 평소와 같이 상향 블러를 MRT0에 출력하지만 MRT1로 출력하기 전에 왼쪽 하단 블러의 결과에 추가하기도 합니다. 채널 2에서는 다이아몬드 2와 3 모두에 철저한 블러가 실행됩니다. 블러는 1번만 필요합니다! !

흐림 효과는 다음과 같습니다.

가우시안과 육각형의 비교: 가우시안에는 총 2개의 블러가 있습니다. Hexagon에는 2개 채널(3개 해상도), 총 4개의 블러가 있지만 각 블러에는 탭 수의 절반만 필요하므로 탭 수가 동일하더라도 각 탭은 동일하게 기여하므로(가우시안의 경우 다름) 주어진 미적 필터의 커널 너비를 충족하는 데 더 적은 탭이 필요합니다.
동일한 가중치의 흐림이 있기 때문에 여러 채널을 언더샘플링으로 채우는 반복 최적화를 흐림에 사용할 수 있습니다. 이중 반복 블러에는 총 5개의 채널과 8개의 세미 블러가 필요합니다.

의사 산란 필터, 적절한 보케는 흐림 효과가 이웃에게 분산되어야 합니다. 그러나 픽셀 셰이더는 결과를 수집하기 위한 것이며 결과를 분산시킬 수는 없습니다. 일반적인 흐림 기본 필터 커널은 픽셀 CoC인 반면, 기본값은 큰 CoC를 사용하고 샘플링된 텍셀의 CoC를 기반으로 거부하는 것입니다. 추가 방법을 사용하면 색상 유출 아티팩트를 방지하고 부드러운 그라데이션을 선명하게 할 수 있습니다.
이 기사에서는 특히 X360에 대한 Hi-Z/Z의 역방향 재로딩 기술을 언급합니다. 기존 깊이 버퍼에 렌더링 대상의 중첩을 추가합니다. 초기 중첩 RT는 D3DHIZFUNC GREATER EQUAL이고 전체 화면 직사각형이 그려집니다(PS는 NULL로 설정되고 Zfun==Never). 이때 Hi-Z는 반전됩니다.

역 Hi-Z는 CSM 렌더링에 사용됩니다. 방향성 조명의 각 계단식은 월드 공간의 상자로 제한되며 상자 내부의 월드 공간 픽셀만 그림자 맵에 캐스팅되고 상자의 뒷면을 그리면 이러한 픽셀만 역 Z 테스트를 통과합니다. CSM에 완벽한 CSM은 둘러싸는 볼륨이 평면 근처에서 카메라를 교차하고 둘러싸도록 설계되었습니다. 비록 이후 캐스케이드의 경우는 아니지만 전면 캐스케이드를 포함합니다.

별도의 패스로 평가된 입력은 깊이 버퍼이며 방향성 광 채널에 대한 L8 마스크 텍스처 입력을 생성합니다. 태양과 카메라의 각도에서 영감을 받아 템플릿의 광원에 라벨 뒷면의 픽셀을 쓰면 이전에 전체 화면을 만들 수 있습니다. 잠재적인 1/4 해상도 양방향 업샘플링, 템플릿이 업데이트되어 처리된 픽셀을 나타냅니다.

역방향 Hi-Z 기반 CSM. 위에서 아래로 계단식 0부터 계단식 3까지입니다.
최소/최대 깊이를 사용하여 PCF 부드러운 그림자를 구현할 수도 있습니다(아래 그림). 구체적인 과정은 원문을 참고해주세요.

크로마 서브 샘플링은 새로운 아이디어가 아니며 이미 TV 방송에서 사용되고 있습니다. Jpeg/Mpeg 압축은 이미지를 휘도와 채도로 나눕니다. 전체 해상도만 사용하여 휘도를 저장하고(사람의 눈은 밝기에 더 민감하기 때문에) **낮은 해상도를 사용하여 채도를 저장합니다.

상단이 일반 사진이고, 다음 3장의 사진은 분해된 Y, U, V 성분 사진으로, Y는 밝기, U, V는 색차입니다.
후처리에는 많은 대역폭이 필요합니다. 데이터가 일반적인 형식으로 저장되면 GPU에 큰 부담과 병목 현상이 발생합니다. 반대로 Luma 방식을 사용하면 필요한 대역폭을 원본의 1/4로 줄일 수 있지만 색상에 대한 추가 처리가 필요하므로 1/4 해상도(원본 크기의 1/8)에서 2채널이 가능합니다.

색조 서브샘플링을 사용하면 셰이더 속도가 4배 더 빨라질 수 있나요? 대답은 '아니오'입니다. ALU에 의해 제한되기 때문입니다. 텍스처 유닛과 ALU는 4개의 구성 요소(예: float4)가 있는 SIMD용으로 설계되었으며, 1개의 구성 요소만 사용되며 4개의 밝기 값을 함께 패키징하여 처리해야 합니다.
4개의 루마 값을 얻으려면 1번의 텍스처 읽기만 필요하므로 1280x720 루마 버퍼는 320x720 ARGB 버퍼입니다. 압축된 버퍼로 이중선형 필터링을 수행하는 것은 올바르지 않습니다. DOTP 수평 필터링은 수동으로 사용해야 합니다.
Butterfly Packing 기술은 데이터를 패킹할 때 사용되며 각 사분면을 미러 주변의 이미지 중심점인 ARGB로 덮습니다. 이제 이중선형은 경계를 넘는 경우를 제외하고 유효합니다. 추가 혼합 및 재구성을 통해 스트립이 다시 그려집니다. 수평 방향은 R<-->g, B<-->A, 수직 방향은 R<-->B, G<-->A이며 방사형 블러가 유효합니다. 나비 포장 풀기 과정은 다음과 같습니다.

기사에서 언급한 TBDR 기술은 전통적인 렌더링 프로세스 외에도 GPGPU 클리핑을 사용합니다. 프로세스는 다음과 같습니다.
화면은 32x32 픽셀의 920개 타일로 나누어져 있습니다.
장면을 다운샘플링하고 720p에서 40x23(1픽셀 = 1타일)으로 나눕니다.
각 타일의 최소/최대 깊이를 찾습니다.
각 타일의 재료 배열을 찾아보세요.
다운샘플링은 다중 채널 및 MRT를 통해 수행됩니다.
다음 그림은 재료 분류의 예입니다. 장면에 기본 재질(빨간색), 피부색(녹색), 금속(파란색)의 3가지 재질이 있다고 가정합니다.

(수동 이중선형 탭을 통해) 다운샘플링할 때 재료는 최종 출력 색상으로 결합됩니다. 아래 이미지의 오른쪽에서 머리 주위의 다운샘플링이 빨간색과 녹색의 조합인 노란색을 생성하는 방법을 볼 수 있으며, 이는 자홍색으로 나타나는 파란색과 유사합니다.

몇 단계를 건너뛰면 다음 이미지를 얻을 수 있습니다. 이 이미지는 각 타일의 재료 조합을 정확하게 제공하는 40x23 텍스처입니다. 병렬 MRT에서는 최소/최대 깊이도 다운샘플링되어 저장됩니다. 이 정보를 사용하면 이제 GPU를 사용하여 광원 소스를 추려낼 수 있습니다. 카메라 프러스텀의 모든 조명과 각 타일(및 하늘)의 최소/최대 깊이와 배열(미니 프러스텀)이 이미 알려져 있기 때문입니다.

각 타일에 대해 미니 프러스텀를 구성합니다.
스카이 타일을 무시하는 셰이더의 조명 컬링.
자르기 결과를 텍스처에 저장합니다(열 == Light ID, 행 == 타일 ID).
실제로 4개의 광원(A-R-G-B)을 한번에 처리할 수 있습니다.
기여 결과를 CPU에서 다시 읽고 조명 계산을 준비합니다.
조명을 계산하는 의사코드는 다음과 같습니다.
// 텍스처(Texture)의 클리핑/클램핑(Clipping)결과 , CPU실행(Execute).
ParseCullingResultsTexture();
For each light type:
For each tile:
For each material permutation:
// 설정(Set)PS상수(Constant)의 라이팅 파라미터 .
RegroupAndSetLightParametersForPSConstants(...);
// 설정(Set)셰이딩 루프 .
SetupShaderLoopCounter(...);
// 을(를) 활용하여 개 드로우/렌더(Draw)호출(Call)누적 합산(Accumulate)렌더링(Render)(까지 의 HDR라이팅 버퍼 ).
RenderLights(...);시간 안정 SSAO는 기본적으로 디스크의 각 샘플링 지점에서 구의 깊이 범위를 곱한 점유 함수의 분석 적분인 선분 샘플링을 사용합니다. 모든 2D 샘플은 z 버퍼의 서로 다른 지점에 투영되므로 라인 샘플링도 더 효율적이고 안정적입니다. 반면 3D 공간에서 일반적인 무작위 포인트 샘플링 방법을 사용하면 두 포인트 샘플이 동일한 위치에 투영되어 샘플 수가 줄어들 수 있습니다.

SSAO 렌더링 프로세스에는 다음과 같이 작동하는 빠른 회색조 흐림도 포함됩니다.

Pre-Integrated Skin Shading에서는 SSS 및 다양한 근사 방법을 포함하여 피부 렌더링과 관련된 기술을 설명하고 런타임 효율성이 매우 높은 사전 통합 피부 렌더링을 제안하여 업계에 지대한 영향을 미쳤습니다. 이 기사에서는 먼저 이전에 연구된 몇 가지 근사 방법을 요약합니다.

TSD(Texture Space Diffusion)를 기반으로 하는 다양한 피부 렌더링 방법입니다.

빠른 지하 산란 방법.

스크린 공간 지하 산란.
그러나 위의 방법에는 모두 몇 가지 문제나 한계가 있습니다. 이 기사에서는 모든 입력이 텍스처/범프 맵(블러 채널 없음)에 로컬로 저장되는 간단한 픽셀 셰이더만 사용하는 것을 목표로 하는 사전 통합 스킨 셰이딩이 제안되었습니다. 주요 관찰: 산란은 모든 곳에서 발생하지 않으며 입사 조명(조명 그라데이션)의 변화 근처에서 발생합니다. 전략은 조명 그라데이션을 찾고 산란을 사전 통합하는 것입니다.

위 그림과 같이 텍스처 공간 확산의 여러 상황. 숫자 1의 영역은 입사광이 일정하고 확산이 필요하지 않음을 나타냅니다. 2번 영역은 작은 표면 범프이고 표면 곡률로 인해 강한 디퓨즈 감쇠가 발생합니다. 3번 영역은 주름이나 융기 등의 특징을 통해 확산됩니다. 4번의 빛이 그림자 속에서 산란되면서 독특한 피부 표현을 연출합니다.
위의 4가지 사항은 3가지 현안으로 요약될 수 있습니다.
- **표면 곡률.**사전 통합된 곡률 기반 BRDF.
일반적인 디퓨즈, 서라운드 조명 및 거리 감쇠 기능은 표면 곡률 조명 계산에 적용할 수 없습니다. 그러나 랩 조명을 기반으로 사전 블러링된 확산 BRDF 및 피부 윤곽을 사용하여 실제 피부 확산 프로파일을 기반으로 하지 않는 문제를 해결하고, 곡률 매개변수화된 BRDF를 사용하여 표면 곡률을 고려하지 않는 문제를 해결함으로써 개선이 이루어질 수 있습니다.
위의 분석 후에는 구(또는 링, 더 쉽게는)의 모든 지점에서 모든 디퓨즈을 수집하여 정기적인 디퓨즈 계산을 수행하고 특정 크기(또는 특정 곡률)의 구에 대한 산란을 정확하게 계산할 수 있습니다. 계산이 오프라인으로 수행되므로 결과만 기록되므로 비용이 많이 드는 기술을 사용할 수 있습니다. 확산 감소의 각 지점에 대해(아래 오른쪽 이미지는 법선과 광선 사이의 각도를 보여줍니다) 전체 구에서 산란된 모든 빛을 통합합니다. 이 단계는 매우 비용이 많이 들므로 나중에 사용할 수 있도록 이 값을 기록해 두십시오.

다음은 다양한 매개변수의 디퓨즈 사전 계산 결과입니다.

이제 정확한 피부 윤곽을 사용하여 다양한 표면 곡률에서 산란 모양을 캡처하므로 이 모든 데이터를

노멀 벡터의 변화율과 월드 공간의 위치 변화율 사이의 간단한 유사한 삼각형 관계를 사용하여 곡률의 1차 추정을 얻을 수 있음이 밝혀졌습니다. 이러한 미미한 변화는 미분 명령(아래 이미지, 왼쪽)을 사용하여 얻을 수 있습니다. 아래 오른쪽 이미지는 이를 머리 모델에 적용한 결과입니다. 참고: 이 작업은 곡률을 시각화하기 위해 수행되지만 확산 프로필에서 올바른 단위를 사용한 다음 조회 텍스처의 곡률 범위를 수정해야 합니다.

- **표면이 고르지 않습니다.**사전 통합된 굽힘 노멀.
BRDF는 매끄러운 표면에 적합합니다. 노멀 맵의 작은 범프는 어떻습니까? 조명은 작은 크기의 곡률 실패를 사용하여 여러 표면 범프를 통해 분산되어야 하며 지금은 법선에만 초점을 맞추고 있습니다.
노멀 맵을 사용하면 주변 지역을 샘플링할 수 있습니다(많은 샘플, 조명, 가중치 및 누적을 사용할 수 있음). 아니면 노멀 맵을 사전 필터링할 수 있나요? 사전 필터링된 도트
탄젠트는 조명 그라데이션을 적용하여 법선을 캡처하는 기술인 노멀 맵을 얻을 수 있습니다. 조명 색상에 따라 캡처 법선이 달라집니다. 아래 이미지는 4개의 노멀 맵을 사용하며, 각 맵은 빨간색, 녹색, 파란색 디퓨즈과 반사광을 각각 계산하는 데 사용됩니다.

이 기술을 사용하려면 캡처된 법선이 필요하지 않습니다. "실제" 노멀 맵(반사)으로 시작하고 R/G/B 피부 윤곽을 사용하여 새 노멀 맵을 사전 필터링합니다. 최적으로 R/G/B 및 반사의 4개 법선이 필요합니다. 보기에는 좋지만 메모리를 많이 차지합니다!
곡선 법선을 최적화하는 방법은 다음과 같습니다.
지오메트리와 반사 법선을 사용합니다(나머지는 혼합). 특정 예술에만 적합하며 노멀 맵에는 세부 사항(주름/모공)만 포함되어야 합니다.
일반 샘플 2개를 사용합니다(나머지 샘플을 혼합). 모든 아트의 경우 노멀 맵 1개, 샘플러 2개, 흐릿한 밉 임계값에서 차단된 샘플러 1개입니다.

좋은 해결책이 있습니다: 곡선이지만 매끄러운 표면(사전 통합된 BRDF), 평평하지만 울퉁불퉁한 표면(사전 통합된 노멀 맵). 그들은 서로를 보완하며, BRDF는 주 곡률(기하학), 주 표면의 넓은 산란에서 선택되고, 곡선 법선이 틈을 채워 국부적 세부 사항의 세밀한 산란을 제공합니다.
- **그림자.**사전 통합된 섀도우 반그림자.
상자 필터의 그림자인 매우 유사한 기술을 적용할 수 있다는 것이 밝혀졌습니다. 그림자 값이 주어지면 반그림자 흐림 기능을 반전하여 그림자 내의 위치를 찾습니다. (아래 사진)

폴오프 기능에 위치/거리가 있는 경우 기본적으로 산란을 위한 추가 공간을 남겨두는 새로운 폴오프 기능을 지정한 다음 피부 확산 프로파일을 사용하여 산란 효과를 그림자에 사전 통합할 수 있습니다.

아래 이미지는 그림자에 사전 통합된 결과입니다. 디퓨즈 계산과 유사하게 여기에는 2D 조회가 있습니다. 두 번째 차원은 월드 공간의 반그림자 크기를 나타내며, 표면의 경사나 그림자의 흐릿함으로 인해 크기가 달라질 수 있습니다. 이 폭은 빛의 표면 경사를 사용하거나 그림자 자체의 파생물을 사용하는 등 다양한 방법으로 계산할 수 있습니다. 디더링된 그림자 맵과 같은 이상한 것이 있으면 가장자리가 딱딱하지 않고 산란이 잘못될 수 있습니다. 또한 2D에서는 거리가 정확하지 않지만 모양이 중요합니다.

다음 두 그림은 텍스처 공간 확산과 사전 통합을 비교한 것입니다.


그림자는 효과 향상을 위해 PCF 및 VSM과 결합될 수도 있습니다. 아래 그림은 2의 거듭제곱으로 크기와 강도를 변경하는 효과 행렬입니다. 여기서 가로축은 크기이고 세로축은 강도입니다.

PS3의 Practical Occlusion Culling은 SPU 런타임, 오클루전 바디 생성, 디버깅 도구, 성능 최적화 등을 포함하여 PS3용 오클루전 컬링 기술을 공유합니다. PS3 게임 Killzone의 렌더링 파이프라인은 다음과 같습니다.

SPU, PPU 및 메모리 간의 협업 및 상호 작용은 다음과 같습니다.

오클루전 컬링(Occlusion Culling) 측면에서 계획은 다음과 같습니다.
오프라인으로 기하학적 폐색을 만듭니다.
SPU는 각 프레임마다 720p 깊이 버퍼로 폐색을 렌더링합니다.
래스터라이제이션를 위해 버퍼를 16픽셀 높이의 블록으로 분할합니다.
80x45(최대 16x16 필터)로 버퍼링된 다운샘플링.
장면을 탐색하는 동안 이 경계 상자를 테스트하세요.
정확성: 래스터라이제이션 + 깊이 테스트.
- 대략적: 일종의 일정한 시점 테스트입니다.
오클루전 컬링 단계를 추가하기 위한 파이프라인은 다음과 같습니다.


폐색 쿼리 작업:
(잘린) 뷰 프러스텀에서 폐색 몸체를 찾습니다.
폐색 볼륨은 나머지 드로어블을 식별하기 위해 마커 비트를 사용하는 일반 렌더링 기본 요소입니다.

차단기 설정 작업:
RSX 스타일의 버텍스 및 인덱스 배열을 디코딩합니다.
클리핑 + 투영 삼각형을 준비 영역으로 내보냅니다.
DMA 대기 시간을 숨기는 내부 파이프라인.

래스터라이제이션 작업:
라인당 래스터 작업을 시작합니다.
준비 영역에서 삼각형을 로드하려면 목록 DMA를 사용하세요.
LS의 삼각형을 640x16 깊이 부동 소수점 버퍼로 그립니다.
깊이 버퍼를 uint16으로 압축하여 저장합니다.

작업 필터링:
래스터라이제이션 완료 후 실행합니다.
대략적으로 선별된 데이터를 생성합니다. 쿼리 중에 작은 개체를 선별하는 데 사용됩니다.
거부 버퍼(인접 및 폐색 버퍼)를 다시 작성합니다.
폐색 쿼리 작업:
테스트는 2단계 계층 구조로 작동합니다. 객체는 kd-트리에 존재하며 여러 부분을 포함합니다.
부품 추출을 방지하기 위해 개체를 테스트합니다.
부품을 테스트하고 그리지 마십시오.
최종 쿼리 결과는 메인 메모리에 기록되어 표시 목록을 구성하는 데 사용됩니다.

자르기 속도 향상:
충분한 RSX 컬링을 얻으려면 구형 테스트를 사용해 보십시오.
모든 물체가 철저히 테스트되었는지 확인하십시오. 이는 최적화를 더욱 중요하게 만듭니다.
또한 이 기사에서는 조정의 각 단계에 대한 구현 세부 사항과 최적화 제안을 다룹니다. 원문을 클릭하시면 보실 수 있습니다.
폴리토프의 선형 함수에 대한 분석적 앤티앨리어싱에서는 폴리토프의 선형 함수를 기반으로 하는 특별한 분석적 앤티앨리어싱을 설명합니다.
샘플링은 컴퓨터 그래픽의 매우 일반적인 핵심 기술이며 널리 사용됩니다. 주요 사용 사례 중 하나는 일반 그리드로 데이터를 샘플링하는 것입니다.

일반 입력 그리드를 특정 방식으로 샘플링한 후 제한된 샘플 값을 사용하여 그리드를 재구성합니다. 이 기사에서는 원본 그리드에서 샘플링하는 영역만 다룹니다.
공간 고주파수를 가진 그림이 있는 것으로 알려져 있습니다.

다양한 필터를 사용하여 위 이미지를 절반 해상도로 다운샘플링합니다.

Box 필터와 Hat 필터 모두 약간의 문제가 있음을 알 수 있지만 Gaussian 필터가 가장 좋은 효과를 나타냅니다. 더 나은 샘플링을 위해 일반적으로 랜덤 지터가 추가됩니다.

분석 샘플링의 주요 프로세스 및 단계는 다음과 같습니다.

컨볼루션 공식과 다이어그램은 다음과 같습니다.


얻은 결과는 복잡한 장면의 앨리어스 없는 샘플링입니다.


요약하면, 이 문서에서는 메쉬의 선형 기능(예: 색상, 밀도...), 고차 방사형 필터 기능, 일반 및 비전통적인 샘플링 그리드를 허용하는 다각형 및 다면체의 분석적 앤티앨리어싱을 제시합니다.
Uncharted의 Water Technology는 Uncharted Sea의 수역 시뮬레이션, 구현 및 최적화를 공유했습니다. 물은 물과 상호 작용하는 작은 수역에서 큰 수역까지 다양한 형태로 나오며, 옷을 젖게 만들고 빠르게 움직이며 느리고 탐색하기 어렵습니다. 수역의 셰이딩 모델은 다음과 같습니다:

흐름 시뮬레이션 다이어그램은 다음과 같습니다.

흐름의 변위에 따라 각 꼭지점은 서로 다른 위상 Φ를 사용하여 원형 패턴으로 이동합니다.

바다는 렌더링이 어려웠고, 탁 트인 바다, 큰 파도(100m+), 보트와 바지선을 몰고 가는 파도, 애니메이션 루프를 고려했지만 사용하지 않았으며 수영도 가능했습니다.
절차적, 매개변수적, 결정적, LOD 등을 포함한 웨이브 시스템. 두 가지 유형의 웨이브가 있습니다. Gerstner 웨이브는 단순하지만 고주파 세부사항이 충분하지 않으며 높은 오버헤드 전에는 몇 가지만 사용할 수 있습니다. FFT 웨이브는 더 현실적이고 더 상세하며 저해상도 그리드의 타일링으로 인해 시각적 왜곡이 발생하여 아티스트가 스펙트럼을 제어하기가 더 어렵습니다.
파동 입자(Wave Particles), 점 소스에서 나오는 파동도 있습니다. 미지의 바다는 포인트 소스를 사용하지 않습니다. 대신, 환형 영역에 무작위로 분포됩니다. 입자는 열린 물의 혼란스러운 움직임과 유사합니다. 특정 속도 범위 내의 임의 위치와 속도는 타일링 가능한 벡터 변위 필드를 생성합니다. 웨이브 파티클은 아티스트의 직관적인 제어, 타일링 왜곡 없음, 빠른 속도를 특징으로 하며 SPU 벡터화에 적합합니다. 시간적 결정론, 입자를 이동할 필요가 없으며 새로운 위치가 초기 위치, 속도 및 시간에서 파생됩니다.
파동장은 4개의 거스트너 파동 + 파동 입자입니다(4번 사용).

흐름 그리드는 그리드의 흐름, 거품 및 진폭 승수를 인코딩합니다.

더 간단한 웨이브를 추가한 후:

세부 수준의 경우 물 메쉬, 화면 투영 메쉬 → 앨리어싱 왜곡, 준 투영 메쉬 → 큰 변위를 처리하는 여러 가지 방법이 있습니다.
불규칙한 지오메트리 클립맵은 지오메트리 클립맵: 중첩된 일반 그리드를 사용한 지형 렌더링을 기반으로 하며 물 렌더링으로 수정되었습니다. 링 레벨 T-조인트를 보호하기 위한 다양한 분할, 레벨 간 동적 블렌딩, SPU 활용도를 향상시키는 패치.



수역 자르기 작업 메커니즘. (일부 단계만 선택됨)
균열은 다양한 LOD 수준에서 물 메쉬 경계에 나타나며 수리가 필요합니다.


워터 그리드 패치는 제거되어야 하며, Frustum-bbox는 프러스텀 외부의 패치를 제거하기 위한 테스트에 사용됩니다.

채광창으로 장면을 조명할 때 프러스텀 경계 상자 테스트를 사용하여 뷰 프러스텀 외부의 패치를 제거하고 평면 및 경계 상자 테스트를 사용하여 채광창 외부의 패치를 제거합니다.

채광창 조명을 계산할 때 셰이더 폐기 작업은 로비 경계 상자 내의 클램핑 지점을 평가하는 데 사용되는 평면 클리핑(왼쪽)을 수행하기 위해 렌더링하는 데 사용됩니다(오른쪽).

떠 있는 물체의 경우 샘플링 지점과 위치 지정에 가장 적합한 평면 사이의 교차 영역에서 진폭이 곱해집니다. 교차 영역에서 연결된 개체, 샘플 지점 및 가장 잘 배치된 평면에 진폭이 곱해집니다.

그리드 컴퓨팅 중에 각 링에 대해 SPU 작업을 실행하여 패치(i % 3)를 처리합니다.
J1: (0,3,6,9,12,15)
J2: (1,4,7,10,13,[16])
J3: (2,5,8,11,14)링 수준 계산을 최소화하고 이중 버퍼링된 그리드 출력을 제공합니다.

각 작업을 통해 완벽하게 보이는 메쉬가 생성되므로 메쉬를 꿰맬 필요가 없습니다. 여러 메시로 구성된 바다의 최종 메시입니다. (아래 사진)

시간에 주의를 기울여야 합니다. 클리핑 다이어그램에는 특정 시간의 파동 입자가 필요합니다. 하나의 파동 입자가 작동하는 한 이 작업은 변위 메시를 생성합니다. 작업을 동기화하기 위해 웨이브 입자 작업이 메시 생성을 완료할 때까지 기다리도록 장벽이 설정됩니다. (아래 사진)

렌더링 효과 스크린샷:

게임용 그래픽 보석 - Avalanche Studios의 조사 결과에서는 파티클 클리핑, 병합된 인스턴스, 전화선 앤티앨리어싱, 2차 깊이 앤티앨리어싱 등 게임의 특수 렌더링 기술 중 일부를 설명합니다.
기사에서는 GPU가 점점 더 강력해지고 ALU가 증가하고 있다고 언급했습니다! TEX의 꽤 좋은 성장, BW(대역폭)의 약간 느린 속도, ROP(렌더링 출력 장치)의 빙하 속도:

ROP가 제한적인 경우 더 적은 수의 픽셀을 그리는 방법을 찾으십시오. 입자 가지치기의 경우 일반적인 ROP 집약적 사례에는 입자, 클라우드, 빌보드 및 그래픽 사용자 인터페이스 요소가 포함됩니다. 해결 방법: 저해상도 렌더 대상으로 렌더링하고 MSAA를 남용합니다. 이 기사의 해결책: 입자 다각형을 다듬어 낭비를 줄입니다. 파티클이 사용하는 그리드에는 알파=0 영역이 많이 포함되어 채우기 속도가 낭비되는 경우가 많습니다. 입자 그리드를 조정하여 낭비를 줄이세요. 자동화된 도구를 사용할 수 있습니다.

자르기 후에는 많은 채우기 속도, 더 많은 정점을 절약할 수 있으며 ⇒ 더 큰 절감 효과를 얻을 수 있지만 수확량이 감소하는 경우(아래) Just Cause 2는 구름에 4개의 정점을 사용하고 입자 효과에 8개의 정점을 사용합니다.

입자 클리핑에는 두 가지 방법이 있습니다.
수동 트리밍. 지루하지만 개념 증명은 Cloud Atlas와 함께 사용할 수 있습니다. 2배의 성능, 수십 개의 아틀라스 파티클 텍스처.
자동 도구. 텍스처, 알파 임계값, 버텍스 수를 입력하고 최적화된 닫힌 다각형을 출력합니다.
입자 클리핑 알고리즘:
알파 임계값.
볼록한 모양에 모든 단색 픽셀을 추가합니다. 잠재적인 각도 테스트를 통한 최적화.
헐 버텍스 수를 줄입니다. 가장 중요하지 않은 가장자리를 교체하고 선체 버텍스 수가 최대가 될 때까지 반복합니다.
무차별 대입은 모든 유효한 모서리의 순열을 탐색하고 가장 작은 면적을 가진 다각형을 선택합니다.

입자 클리핑 알고리즘 프로세스. 1: 원본 텍스처; 2: 임계값 텍스처; 3: 모든 단색 픽셀을 볼록한 가장자리에 추가합니다. 4: 볼록한 가장자리의 면적을 줄입니다. 5: 최종 4 꼭지점 다각형(60.16%); 6: 최종 6 꼭지점 다각형(53.94%); 7: 최종 8 꼭지점 다각형(51.90%).
입자 가지치기 관련 문제:
다각형이 원래 사변형을 넘어 확장됩니다. 일반 텍스처는 문제가 없습니다. CLAMP를 사용하세요. 인접한 아틀라스 타일로 분할하여 모든 껍질을 먼저 계산하고, 다른 껍질과 교차하는 솔루션을 거부하고, 유효한 솔루션이 없으면 정렬된 직사각형으로 되돌릴 수 있습니다.
성능. 무차별 대입으로 볼록 껍질 버텍스 수를 합리적으로 낮게 유지합니다.
필터. 픽셀의 네 모서리를 모두 추가하거나(더 빠르게) 하위 픽셀 알파 값을 보간합니다(정확함).
텍스처 가장자리에서 알파 != 0과 같은 "이상한" 텍스처를 처리합니다.
다음은 병합 인스턴싱입니다.
인스턴스화는 여러 그리기 호출을 사용하는 하나의 메시의 여러 인스턴스입니다. 병합은 버텍스 데이터가 중복된 다중 메시, 메시당 하나의 인스턴스입니다. 병합 인스턴스화는 정점이 중복되지 않는 단일 그리기 호출입니다. 인스턴스화와 병합 인스턴스화의 비교 코드는 다음과 같습니다.
// 인스턴스
for (int instance = 0; instance < instance_count; instance++)
for (int index = 0; index < index_count; index++)
VertexShader( VertexBuffer[IndexBuffer[index]], InstanceBuffer[instance] );
// 인스턴스
for (int vertex = 0; vertex < vertex_count; vertex++)
{
int instance = vertex / freq;
int instance_subindex = vertex % freq;
int indexbuffer_offset = InstanceBuffer[instance].IndexOffset;
int index = IndexBuffer[indexbuffer_offset + instance_subindex];
VertexShader( VertexBuffer[index], InstanceBuffer[instance] );
}이상한 크기의 메쉬를 병합하고, 공통 주파수를 선택하고, 필요에 따라 인스턴스 데이터를 복사하고, 필요에 따라 퇴화된 삼각형으로 채웁니다. 예 - Mesh0: 꼭지점 39개, Mesh1: 꼭지점 90개, 빈도 = 45 선택, 퇴화된 삼각형 2개(꼭지점 6개)로 Mesh0을 채웁니다.
Instances[] = {
( Mesh0, InstanceData[0] ),
( Mesh1, InstanceData[1] ),
( Mesh1 + 45, InstanceData[1] ) }다음으로 전화선 앤티앨리어싱에 대해 이야기해 보겠습니다. 톱니의 출처:
기하학적 가장자리. 주로 MSAA로 해결되는 포스트 프로세스 AA도 일반적으로 효과적이며 미세한 형상으로 분해됩니다.
색칠. 밉매핑, 연구/이해 부족, LEAN 매핑과 같은 실용적인 게임 팁을 통해 정렬이 해결되었습니다.
전화선은 일반적인 게임 콘텐츠이며 일반적으로 하위 픽셀 크기입니다. MSAA는 도움이 되지만 별로 도움이 되지 않으며 하위 샘플 크기에서 중단됩니다. 실제로 하위 픽셀 크기는 필요하지 않습니다!

전화선은 중심점, 노멀 및 반경으로 정의되는 긴 원통형 모양입니다. 하위 픽셀로 이동하는 것을 피하고 반경을 픽셀 크기의 절반으로 제한하고 반경 감소 비율로 페이드합니다.
// Compute view-space w
float w = dot(ViewProj[3], float4(In.Position.xyz, 1.0f));
// Compute what radius a pixel wide wire would have
float pixel_radius = w * PixelScale;
// Clamp radius to pixel size. Fade with reduction in radius vs original.
float radius = max(actual_radius, pixel_radius);
float fade = actual_radius / radius;
// Compute final position
float3 position = In.Position + radius * normalize(In.Normal);다음은 앤티앨리어싱의 두 번째 깊이입니다. 필터 AA 방법에는 다음이 포함됩니다.
- AA 처리: MLAA, SMAA, FXAA, DLAA.
-분석 방법: GPAA, GBAA, DEAA, SDAA.
깊이 버퍼 및 두 번째 깊이 버퍼인 깊이는 화면 공간에서 선형이며 가장자리 감지를 단순화하고 원래 형상을 예측할 수 있습니다. 두 가지 유형의 가장자리: 주름, 실루엣, 실루엣에는 두 번째 깊이 버퍼, 전면 컬링을 사용한 pre-z 패스 또는 뒷면 형상을 렌더링하는 대상에 대한 출력 깊이가 필요합니다.
먼저 주름을 시도하고, 깊이 경사를 보고, 교차점을 계산하고, 거리가 1픽셀 미만인 경우 유효하고, 거리가 1/2픽셀 미만인 경우 사용하고, 그렇지 않은 경우 실루엣을 시도해 보세요.

실루엣으로 시도해 보세요. 이웃 깊이는 쓸모가 없습니다. 두 번째 깊이를 보고 교차점을 계산하고 거리 < 절반 픽셀인 경우 사용하세요.

두 번째 깊이 AA 효과 비교(오른쪽 없이 왼쪽):

GPUView를 사용하여 DirectX 11을 이해하려면 GPU 분석 도구 GPUView를 사용하여 GPU의 작동 메커니즘, 원리 및 디버깅 프로세스를 설명합니다. 그래픽과 WDDM(Windows 디스플레이 드라이버 모델) 간의 계층적 관계는 아래 그림에 나와 있습니다.

GPU에 작업을 보내는 프로세스:

표준 DMA는 그래픽 시스템 상태 개체, 그리기 명령 및 리소스 할당에 대한 참조(텍스처, 버텍스 및 인덱스 버퍼, 렌더링 대상, 상수 버퍼)를 나타냅니다. GPUView는 DMA의 세부정보를 보고 컨텍스트와 대기열을 모니터링할 수 있습니다.

CPU 소프트웨어 컨텍스트 큐는 GPU 컨텍스트에 제출된 작업을 나타냅니다. 대기열은 시간에 따라 스택으로 표시됩니다. UMD가 작업을 제출하면 스택이 커집니다. GPU가 작업을 완료하면 스택이 축소됩니다.


GPU 하드웨어 컨텍스트 큐는 시간에 따라 스택으로 표시됩니다. 이 큐는 KMD를 통해 작업이 제출되면 늘어나고 GPU에서 개체가 완료되면 줄어듭니다. 간격은 CPU 측 병목 현상을 나타냅니다. 특정 대기열을 선택하여 대기 시간을 표시할 수도 있습니다.

페이징 버퍼 패킷: 결과적으로 페이징 작업(큰 텍스처일 수 있음)을 제출하는 이유는 일반적으로 DMA 버퍼를 준비하고 페이징 작업 후 DMA 패킷을 보기 위한 것입니다. 하드웨어 스레드의 경우 색상은 유휴 상태를 나타내고 간격은 작업을 나타냅니다.

스레드 실행의 경우 연한 파란색은 커널 모드를 나타내고 진한 파란색은 dxgkrnl(DX 커널)을 나타내며 빨간색은 KMD(커널 모드 드라이버)를 나타냅니다.

수직 동기화 상태를 확인할 수도 있습니다.

올바른 폐색 쿼리를 얻기 위한 지연된 획득 결과는 N 프레임입니다. 여기서 N = GPU 수입니다. 점프를 방지하려면 교합 볼륨을 인위적으로 팽창시켜야 할 수도 있습니다. 특히 MSAA 모드에서 저가형 하드웨어의 텍스처 해상도를 줄이기 위해 비디오 메모리 사용을 제어하기 위한 페이징을 피하고 동적 데이터 텍스처와 버텍스 버퍼를 너무 많이 사용하지 마십시오. 즉, GPU가 활성 상태인지 확인하고, CPU/GPU 상호 작용을 추적하고, 스레드를 추적하고, 다중 GPU 상호 작용을 모니터링하고, 도구 상자에 GPUView를 추가하세요.
Journey의 Sand Rendering은 Journey 게임의 모래와 사막 렌더링을 공유합니다.

모래 렌더링에는 선명화 밉, 이방성 마스크, 반짝이는 거울, 바다 거울, 확산 대비, 세부 높이 맵 등이 사용됩니다.

왼쪽에서 오른쪽으로 추가됨: 세부 높이 맵, 분산 대비, 바다 거울, 반짝이 거울, 이방성 마스크, 선명하게 밉, 최종 이미징.
카메라로부터의 거리가 변함에 따라 모래 알갱이의 효과가 바뀌고 기사에서는 디퓨즈도 Lambert를 사용하는 대신 수정되었습니다. Lambert에 비해 훨씬 더 높은 대비로 수정된 확산 음영:

왼쪽: 수정된 디퓨즈; 오른쪽: 램버트 디퓨즈.

왼쪽: 높이 맵; 오른쪽: 높이 세부정보 맵, 오른쪽 상단의 두 사진은 미세한 세부정보이고 오른쪽 하단의 두 사진은 거시적 세부정보입니다.
확장 가능한 고품질 모션 블러 및 앰비언트 오클루전(AO)은 확장 가능한 고품질 모션 블러 및 앰비언트 오클루전(AO)을 도입합니다.
확장성이 필요한 이유는 성능 제한이 다른 플랫폼 간에 효과를 공유할 수 있고, 다양한 아트 스타일에 맞는 게임을 공유할 수 있기 때문입니다. 이점은 시각적 일관성, 개발 시간 절약, 일관된 콘텐츠 요구 사항 및 "무료" 품질 향상입니다.
잠재적으로 확장 가능한 요소는 품질 손잡이입니다: 최대 반경, 샘플 수, 클램핑 입력; 해상도 독립성으로 픽셀 대신 표준화된 화면 단위를 허용합니다. 모듈식 기능, 정확성 및 속도; 추가 처리, 추가 채널, 반복 알고리즘.
기사에 제시된 계획은 저급 품질 디자인, 고급 디자인으로 확장, 품질과 성능 반복, 반복 간 충분한 시간 확보입니다.

모션 블러의 목표는 자산 독립적이고, 모든 지오메트리 유형과 일관되고, 장면 복잡성과 무관하며, G 버퍼 인코딩을 최소화하는 것입니다. 이러한 제한으로 인해 대부분의 기존 기술이 제거됩니다. 모션 블러를 가까이서:

핵심 문제: 클러스터로 표현해야 하는 자연 산란 효과는 개체가 해당 범위 밖에서 흐려져 투명도와 같은 효과를 생성합니다. 기사의 방법: 타일 확장 속도 사용, 객체 경계 외부 흐림 허용, 확장 속도에 따른 샘플링, 분산 -> 수집, 속도 및 깊이에 따라 샘플 혼합, 배경 추정. 구체적인 단계:
- 렌더링 속도. 화면 공간의 속도를 계산하고, 최대 흐림으로 고정하고, [0, 1]로 크기를 조정합니다.

청킹은 속도를 최대화합니다. NxN 다운샘플링, N=최대 흐림 반경, 진폭별로 최대값을 기록합니다.
이웃은 속도를 극대화합니다. 청크된 최대값을 입력하고, 3x3 박스 필터를 적용하여 중앙과 주변 청크의 크기별로 최대값을 찾습니다.

- 재구축. 중심 깊이
, 색상 , 중심 속도 , 인접 최대값 .

- 샘플링.
두 방향, 즉 , , 샘플을 계산하고 전경 또는 배경을 결정하고 중심과 비교합니다.

배경 또는 전경을 결정합니다.

대비 세부 사항. 흥미로운 사례: 배경 샘플
, 잠재적인 배경 추정, 전경 샘플 , 중심을 지나 이동할 수 있으며 두 샘플 모두 이동합니다( ). 즉, 흐릿한 것을 원합니다. 최종 세부 사항: 샘플 수집, 가중치 합계 비교, 색상 기여 합계 및 결과 정규화.

모션블러의 전반적인 과정.
다음으로 확장 가능한 AO에 대해 이야기해 보겠습니다.
AO는 조명, 접촉 및 그림자의 주름 그림자에 큰 이점을 제공합니다. 프로젝트의 제약 조건은 속도가 빠르고 표면을 인식하며 앨리어싱을 줄이는 것이었습니다.

핵심 문제는 두 가지 다른 알고리즘을 원하지 않고 시각적 일관성을 원한다는 것입니다. 해결책은 두 가지 요소, 즉 점에서 중심까지의 거리, 법선까지의 샘플 거리의 투영된 길이, 그리고 결과에 만족할 때까지 붕괴 기능을 실험하는 것의 기여도를 기반으로 더 적지만 더 높은 품질의 샘플을 갖는 것입니다. 이 AO의 단계는 다음과 같습니다.
위치를 재구성하기 위해 중앙의 깊이와 법선을 샘플링합니다.
샘플링 속성. 샘플링 위치, 샘플링 깊이 및 재구성 위치를 선택합니다.

ng)
- 샘플 기여. 𝑣 ⃗를 계산하고, 🌺𝑣 ⃗ │을 계산하고, 𝑣 ⃗⋅𝑛 ̂을 계산하고, 반경 r을 기준으로 감쇠를 적용합니다.


12.png)
- 전체 폐색. 기여도를 집계하고 정규화합니다.

여기서: 𝑠𝑐𝑎𝑙𝑒 = 아티스트 조정 기여 척도, 𝑆 = 샘플 수.
- 다양한 법선을 샘플링하는 것도 AO에 큰 영향을 미칩니다. 다음 그림은 GBuffer 법선과 파생 법선의 사용을 보여줍니다.

- 흐릿한 결과. 깊이 인식 양면 흐림, 부드럽게 하는 효과, 패턴을 숨기는 넓은 필터, 그림자와 결합하여 비용 절감. 최종 AO:

확장 및 구현 가능:
확장성을 고려하여 설계되었습니다. 반경을 늘리고, 폴오프 기능을 변경하고, 접촉 그림자를 강조하고, 효과를 더 넓히고, 응용 프로그램을 변경하고, 모든 것을 조절하고, 환경을 조절합니다.
품질 확장성. 반경을 늘리고, 샘플 수를 늘리고, 샘플링 모드를 개선하고, 흐림 효과를 더 넓게 만듭니다.
현재 구현: 전체 해상도 4탭, 나선형 주위 샘플링, 임의 벡터 주위 회전, 미러 탭 사용, 반경을 최대 20픽셀로 제한, 수학을 전치하여 한 번에 계산, 흐림을 위해 블루/알파 깊이 인코딩.
DX11 구현: 9개 샘플, 절차적 나선형 샘플링 모드, 약간의 노이즈 발생, 반경 클램핑 없음, 클램핑되지 않은 반경이 있는 밉 깊이, 흐림을 위해 블루/알파로 인코딩된 깊이.

분리 가능한 하위 표면 산란(Separable Subsurface Scattering)은 당시 블리자드에서 근무하던 Jorge Jimenez와 다른 사람들이 발표한 피부 렌더링 및 눈 렌더링이었습니다. 피부 모델링, SSS, SSSS, 안구 렌더링 기술에 대해 자세히 설명했습니다. 피부의 경우 확산 곡선은 다음과 같습니다.

여러 가우스 함수를 사용하여 피부의 표면 아래 산란을 맞춥니다.

모든 신호는 푸리에, 고속 푸리에(FFT), 구면 고조파(SH) 및 확산 곡선 등과 같은 여러 유리항으로 피팅되고 재구성될 수 있습니다.
분리 가능한 매개변수화된 프로파일과 최적화된 공식은 다음과 같습니다.

반투명은 빛이 물체의 얇은 부분 내부로 이동할 때 발생하며 빛이 더 멀리 이동할수록 감쇠가 더 심해집니다. 즉, 아래 이미지의 첫 번째 지점이 두 번째 지점보다 덜 반투명합니다.

거리 외에 또 다른 요인은 물체의 뒤쪽에 도달하는 빛이지만 안타깝게도 화면 공간 방식을 사용하기 때문에 이 정보를 사용할 수 없습니다(아래 이미지의 빨간색 원).

관찰: 뒷면 정보는 알려져 있지 않으며, 인간 피부의 반투명성은 고주파수 세부 사항을 숨기고, 인간 피부의 알베도는 크게 변하지 않습니다. 가설: 반전된 전면 법선을 후면 법선으로 사용할 수 있고 전면 알베도 값을 후면 알베도 값으로 사용할 수 있습니다(아래 이미지).

이러한 가정을 통해 모든 수학은 아래 이미지의 빨간색 원에 표시된 것으로 축소될 수 있으며, 이는 간단한 텍스처로 미리 계산될 수 있습니다.

미리 계산된 텍스처 효과는 다음과 같습니다.

float scale = 2e4 * (1.0 - translucency) / sssWidth;
float4 shrinkedPos = float4(worldPosition - 0.005 * worldNormal, 1.0);
// 을(를) 활용하여 그림자(Shadow),계산/산출(Calculate)의 거리.
float4 shadowPosition = mul(shrinkedPos, lightViewProjection);
float d1 = shadowMap.Sample(LinearSampler, // 'd1' has a range of 0..1 shadowPosition.xy / shadowPosition.w);
float d2 = shadowPosition.z; // 'd2' has a range of 0..'lightFarPlane'
d1 *= lightFarPlane; // So we scale 'd1' accordingly:
float d = scale * abs(d1 - d2);
// 을(를) 활용하여 의 방정식 계산/산출(Calculate)개 거리의 컬러 .
float dd = -d * d;
float3 profile = float3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
float3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
float3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
float3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
float3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
float3(0.078, 0.0, 0.0) * exp(dd / 7.41);
// ,을(를) 활용하여 라이팅 (wrap lighting), 반투명(Translucent), 의 포인트 포인트 .
return profile * saturate((0.3 + dot(light, -worldNormal)) / 1.3);
위의 광자 매핑과 전송 근사치 비교.
이 피부 반투명 기술은 직접 조명에서 작동하지만 안타깝게도 주변 조명의 반투명도를 시뮬레이션하지 않습니다. 아래 사진에는 왜 귀에 빛이 없나요? 아 코에 있구나...

또한 아래 그림의 음영 부분에도 빛샘 현상이 발생합니다.

직접광의 경우 일반적인 그림자 매핑을 사용하여 빛이 물체를 얼마나 멀리 통과했는지 알 수 있습니다. 하지만 주변광의 경우에는 주변광이 특정 방향에서 오는 것이 아니기 때문에 이 정보를 알 수 없습니다.

작동하는 해결책은 법선을 반전시키고 반구의 각 방향으로 광선을 투사하고 평균을 취하는 것입니다.
그 중

왼쪽: 전송 없음; 오른쪽: 전송이 사용되었습니다.
사용자 유도 투과율을 사용할 수 있는 그림자 매핑의 단점도 있습니다.

위: 귀, 코, 눈꺼풀 등 효과의 정도와 방향은 아티스트가 선택합니다. 하단: 특정 방향을 따라 각 구의 두께를 미리 계산하는 데 사용됩니다. 특히 10도 원뿔의 평균 두께를 계산합니다.
이 기사에서는 또한 많은 세부 사항을 포함하여 안구 렌더링에 대해 자세히 설명합니다. 원본 기사 또는 작성자가 작성한 다른 기사 시리즈를 클릭할 수 있습니다.
언리얼 엔진의 초현실적 휴먼 렌더링 기술 분석 1부 - 개요 및 피부 렌더링
언리얼 엔진의 초현실적 휴먼 렌더링 기술 분석 2부 - 안구 렌더링
언리얼 엔진의 초현실적 휴먼 렌더링 기술 분석 3부 - 헤어 렌더링 등
Battlefield 3의 지형: 현대적이고 완벽하며 확장 가능한 시스템에서는 확장성, 작업 흐름, CPU 및 GPU 성능, 절차적 가상 텍스처, 데이터 흐름, 견고성, 절차적 메시 생성 등을 포함한 Frostbite의 지형 시스템에 대해 설명합니다.


지형은 높이 필드, 셰이더 스플래시 마스크, 컬러맵(셰이더 스플래시 위에 오버레이로 사용됨), 물리 재료, 파괴 깊이 마스크, 반사광을 위한 알베도 맵, 추가 마스크 패스 등 여러 래스터 자산을 사용합니다.
Frostbite의 확장성 정의: 모든 시각적 거리(0.06m ~ 30000m), 모든 세부 수준(0.0001m 이하), 모든 속도(슈퍼카 및 제트기). 주요 관찰: 모든 것은 계층 구조에 관한 것입니다! 계층 구조를 일관되게 사용하면 "무료" 확장성이 제공됩니다. 계층은 지형 렌더링에 있어 낯선 것이 아니며 Frostbite 접근 방식은 모든 공간 표현에 대한 Flight Simulator의 쿼드트리 계층과 유사합니다!
쿼드트리 노드의 페이로드는 상대적으로 복잡하며 완전히 로드되거나 부분적으로 로드될 수도 있고, LOD 로드 또는 뷰 관련 로드일 수도 있습니다.
GPU 최적화: 셰이더 스퍼터링을 사용하는 절차적 가상 텍스처를 통해 아티스트는 매우 느린 렌더링(10-20ms)으로 아름다운 지형을 만들 수 있습니다. 셰이더 스퍼터링은 보기 거리에서 확장 가능하지 않으며 여러 패스를 감당할 수 없습니다. 텍스처로 스퍼터링하고 프레임 간 일관성(성능)을 활용하여 여러 번 렌더링할 수 있으며(확장성) 텍스처가 포함된 전체 화면을 렌더링하는 데 2.5-3ms가 걸립니다(PS3).
가상 텍스처 키 값: 미터당 32개 샘플, 2개의 픽셀 테두리와 통합된 256x256 타일, 아틀라스에 저장, 기본 크기는 4k x 2k, 2개의 DXT5 텍스처:

매우 크며, 쉽게 최대 1M x 1M(= 1Tpixel)까지 가능합니다! 일반적인 가상 텍스처는 64k x 64k입니다.
간접 텍스처 형식: RGBA8, 가상 텍스처 타일 아틀라스에 대한 인덱스, 하나의 타일이 여러 간접 샘플을 덮는 저해상도 영역에 대한 배율 인자, CLOD 그라데이션 인자: 새로 합성된 타일의 페이드 인을 부드럽게 하는 데 사용(페이드 인 타일), 이미 아틀라스에 있고 간접 밉을 사용하여 얻은 이전 LOD(페이드 인 타일), CLOD 인자는 프레임마다 업데이트됩니다.
Teratexture의 간접 텍스처는 쉽게 4k x 4k에 도달할 수 있는데, 이는 엄청납니다! 4k 간접 텍스처를 6개의 64x64 클립맵 레이어로 대체하는 초기 가상 텍스처 구현인 Clipmap의 간접 텍스처를 사용하세요.

클립맵 간접 텍스처: 각 그리기 호출은 CPU의 클립 맵 수준을 확인하고, 추가 픽셀 셰이더 로직을 방지하고, 각 64x64 맵에 자체 밉 체인이 필요하며, 텍스처 공간은 월드 공간(지형 문제 아님)으로 대략 구성되어야 하며, 보다 일반적인 사용 사례에는 여러 기존 가상 텍스처를 사용하는 것이 더 나을 수 있습니다.
타일 구성: 타일은 GPU에서 합성되고 GPU 또는 SPU에서 압축됩니다. 이점(디스크에서 스트리밍하는 것과 비교): 작은 디스크 공간 - 데이터 증폭, 소스 래스터 데이터가 약 1000배 증폭됩니다. 짧은 대기 시간: 타일이 다음 프레임을 사용할 준비가 되었습니다. 동적 업데이트: 파괴, 실시간 편집, 효율적인 워크플로우: 아티스트가 수백 평방 킬로미터에 걸쳐 모든 조약돌을 칠할 필요가 없습니다.
지형은 데이터 스트리밍도 가능하게 합니다. 먼저 스트리밍의 기본을 이해해 봅시다. 스트리밍 단위: 래스터 타일(노드 페이로드라고도 함), 높이 필드를 포함한 일반적인 타일 크기: 133x133x2바이트, 마스크: 66x66x1바이트 x 페이로드당 0-50타일, 색상: 264x264x0.5바이트. 고정 크기 타일 풀(아틀라스), 일반적인 아틀라스 크기, 높이 필드 포함: 2048x2048, 마스크: 2048x1024, 색상: 2048x2048.
스트리밍 모드:
느린 게임을 위한 청크별(무료) 스트리밍.
타일 번들(푸시 기반이라고도 함) 스트리밍은 더 빠른 게임 플레이를 위해 레이아웃과 관련된 타일을 번들로 묶고, 레이아웃은 지형 해상도를 기반으로 합니다.
혼합 흐름(가장 일반적), 선택한 생성 지점 및 전환에 사용되는 번들이 나머지를 채우는 자유 흐름입니다.
레벨에 있는 모든 데이터의 레이아웃, 생성 지점에 로드된 데이터의 하위 세트, 지형 해상도 레이아웃 정의 하위 세트, 사용자가 레벨을 진행하면서 로드(및 언로드)되는 하위 세트입니다.

요약하자면, Frostbite 2는 강력하고 유능한 지형 시스템을 갖추고 있습니다: 하이트 필드, 그림자, 데칼, 물, 지형 장식, 대부분의 측면이 잘 확장됩니다: 보기 거리, 데이터 해상도, 장식 밀도 및 거리, 원활한 작업 흐름, 게임 내 편집, 다양한 도구, 우수한 성능(CPU, GPU, 메모리), 병렬화, 스트리밍, 절차적 가상 텍스처.
불완전한 데이터를 기반으로 한 로딩은 Fuse 게임을 구동하는 Insomniac Games의 새로운 엔진에 데이터 로딩 인프라를 도입합니다. 이 강연에서는 Insomniac Games가 어떻게 소스 코드 관리 및 구조화된 자산 파일을 개선하여 도구 반복 속도를 희생하지 않고 광학 미디어에 대한 빠른 로드 시간을 달성했는지 자세히 설명합니다. 또한 무차별 GPU 컴퓨팅 성능을 사용하여 최종 레이아웃을 계산하는 파일 복사를 위한 새로운 디스크 레이아웃 방법을 소개합니다.
데이터 구성은 백그라운드에서 자동으로 구축됩니다. 대부분의 자산은 소스와 출력 비율이 1:1입니다. 전역 종속성 보기가 없습니다. 목표는 하나의 자산 변경에 대해 하나의 파일만 재구성하는 것입니다. 런타임 데이터 연결, 간단한 빌드 시스템의 어두운 면, "지금 구입하고 나중에 지불하십시오!", 느슨한 파일 로딩, I/O 및 종속성 감지가 동기식으로 실행됩니다. 느슨한 로딩 흐름도는 다음과 같습니다.

느슨한 로딩의 이점은 모든 자산을 언제든지 로드할 수 있고 프로토타입 제작에 적합하며 자산은 RAM에 한 번만 저장되고 참조 횟수가 계산되며 런타임 시 자산을 쉽게 다시 로드할 수 있다는 것입니다. 로딩 목록을 빌드할 때 백그라운드 최적화 작업은 빌드 시스템이 유휴 상태일 때만 실행됩니다. 게임을 실행하는 데 데이터가 필요하지 않습니다. 전적으로 스캐닝에 의존하여 생성되며 대량의 데이터를 크롤링해야 합니다.

목록 로드 결과: DVD의 전체 레벨 목록 로드: 1분, 개발 중 HTTP 로드 가속: 약 50%! 출시를 위해서는 또 다른 2-3배 DVD 가속이 필요합니다. 좋습니다. I/O 파이프라인의 지연이 사라졌습니다. 나쁜 점은 여전히 제한된 검색입니다!
이 기사에서는 리소스 중복 제거 기술도 언급합니다.


에피폴라 샘플링 및 1D 최소/최대 이진 트리를 사용한 광산란 효과의 실제 구현에서는 참여 매체에서 광산란 효과의 실제 구현을 설명합니다. 이는 에피폴라 샘플링과 1D 최소/최대 이진 트리를 결합하고 점 광원으로 인한 산란 적분에 대한 새롭고 간단하며 효율적인 반분석 솔루션을 활용하는 기술입니다. 이 기술에는 품질을 성능으로 바꿀 수 있는 많은 매개변수가 있으므로 광범위한 하드웨어에 적합합니다. 내부 산란 적분은 다음과 같이 도출됩니다.



레일리 산란과 미에 산란 및 이들의 조합 효과는 다음과 같습니다.

볼륨 섀도우 계산 프로세스:


방사형 샘플링(에피폴라 샘플링):


구현 개요:

깊이 버퍼에서 카메라 공간 z 좌표를 재구성합니다. 깊이는 비선형이고 z 좌표는 안전하게 보간될 수 있기 때문에 필요한 작업입니다.
각 커널 슬라이스의 진입점과 종료점을 포함하는 1D 텍스처를 계산합니다.
이 텍스처는 카메라 공간 z와 함께 좌표 텍스처와 카메라 공간 z를 극좌표로 렌더링하는 데 사용됩니다. 이 단계에서는 유효한 샘플을 표시하기 위해 깊이 스텐실 버퍼도 설정됩니다.
깊이 중단을 감지하고 보간된 소스 텍스처를 계산합니다.
위에서 계산된 슬라이스 원점과 방향을 포함하는 또 다른 1D 텍스처를 렌더링합니다.

원본 그림자 맵, 방향 및 원점 텍스처는 각 에피폴라 슬라이스에 대한 1D 최소/최대 이진 트리를 구축하는 데 사용됩니다.
템플릿에 레이 행진 샘플을 표시하고 각 샘플에 대해 1D 최소/최대 최적화로 레이 행진 알고리즘을 수행합니다.

보간된 소스 텍스처를 사용하여 초기 내부 산란을 보간합니다.
내부 산란은 양측 가중치를 계산하기 위해 에피폴라 및 직사각형 카메라 공간 z-텍스처를 사용하여 극좌표에서 직사각형 좌표로 변환됩니다. 이 단계에서는 극좌표에서 보간할 수 없는 픽셀이 템플릿에 표시됩니다.

- 마지막으로 템플릿에 표시된 픽셀에 대해 산점 내 복구 프로세스가 수행됩니다. 이 단계에서는 1차원 최소/최대 최적화가 사용되지 않습니다.

빔 효과 비교. 왼쪽 위: Brute Force의 참조 이미지; 오른쪽 상단: 고품질; 왼쪽 아래: 균형 잡힌; 오른쪽 아래: 고성능.
CryENGINE 3의 그래픽 젬(Graphics Gems)에서는 2013년 CryEngine 3의 특수 렌더링 기술 중 일부(주로 앤티앨리어싱 및 포스트 프로세스)에 대해 설명합니다.
앤티앨리어싱\지연 MSAA 검토: 문제는 다중 채널 + 다중 샘플링 RT의 읽기/쓰기에 있습니다. DX10.1은 SV_SampleIndex/SV_Coverage 시스템 값 의미 체계를 도입하여 다중 채널별로 픽셀/샘플링 주파수 채널의 해상도를 허용합니다. SV_SampleIndex는 각 하위 샘플에 대해 픽셀 셰이더를 강제로 실행하고 현재 실행된 하위 샘플의 인덱스를 제공합니다. 인덱스는 Multisampled RT에서 하위 샘플을 얻는 데 사용될 수 있습니다(예: FooMS.Load(UnnormScreenCoord, nSampleIndex)). SV_Coverage는 래스터 단계에서 픽셀 셰이더가 적용하는 하위 샘플을 나타냅니다. 사용자 정의 적용 범위 마스크의 하위 샘플 적용 범위를 수정할 수도 있습니다. DX 11.0 Compute Tiled를 기반으로 한 디퍼드 렌더링/조명 MSAA는 MSAA 태그가 지정된 하위 샘플을 반복하여 더 간단합니다.
지연된 MSAA에 대한 참고 사항: 간단한 이론, 번거로운 실습 및 적어도 복잡한 지연된 렌더러의 경우 MSAA에 적합하지 않은 코드가 빠르게 축적됩니다. MSAA를 고려하지 않고 새로운 기술을 추가했기 때문에 기존의 틀을 깨는 것입니다. 비록 그것이 여전히 작동하더라도 말이죠. MSAA에 적합하지 않은 기술은 흰색/어두운 윤곽선 또는 AA가 전혀 없는 등의 시각적 왜곡을 유발하므로 이를 정확하게 찾아 수정해야 하는 경우가 많습니다. 지연된 MSAA를 지원하도록 렌더러를 조정하는 것은 작업량이 많고 매우 까다롭습니다.
MSAA 및 샘플별 마스크의 지연된 사용자 지정 구문 분석: 조명/기타 MSAA 관련 채널과 같은 픽셀 주파수 채널에 대해 G-버퍼 사후 처리, 사용자 지정 MSAA 구문 분석 수행, 샘플 0 사전 구문 분석. 동일한 채널에 하위 샘플 마스크를 생성하고(샘플의 유사성과 일치하지 않는 경우 플래그를 비교) MSAA가 필요하지 않은 영역을 중복 처리하게 되므로 기본 SV_COVERAGE를 사용하지 마십시오.

MSAA의 스텐실 일괄 처리 지연: 일반 스텐실 버퍼를 사용하여 각 샘플 스텐실 마스크 배치, 스텐실 버퍼에서 1비트 예약, 하위 샘플 마스크 업데이트 사용, 개별 픽셀 대신 전체 쿼드 픽셀 표시 -> 스텐실 선별 효율성 개선, 스텐실 읽기/쓰기 비트 마스크를 사용하여 샘플별 비트 적용 범위 방지, StencilWriteMask = 0x7F, 스텐실 지우기가 발생할 때마다 재개. 템플릿의 과도한 사용으로 인해 달성할 수 없습니까? 클리핑/폐기를 사용할 수 있으며, 추가 오버헤드는 각 샘플 템플릿에 대해 읽은 추가 텍스처에서도 발생합니다.
지연된 MSAA의 픽셀 및 샘플 주파수 패스: 픽셀 주파수 패스는 템플릿 읽기 마스크를 각 픽셀 영역(0x80)의 예약된 비트로 설정하고, 사전 구문 분석된(멀티샘플링되지 않은) 대상 SRV를 바인딩하고, 렌더링 패스를 정상적으로 실행합니다.

샘플 주파수 패스는 템플릿 읽기 마스크를 각 샘플 영역(0x80)의 예약된 비트로 설정하고, 멀티샘플 대상 SRV를 바인딩하고, SV_SAMPLEINDEX를 통해 현재 하위 샘플을 인덱싱하고, 평소대로 렌더링 패스를 실행합니다.

MSAA SSAA의 지연된 알파 테스트: 알파 테스트에는 해결 방법이 필요합니다. 기본 SV_Coverage는 삼각형 가장자리에서만 작동합니다. 자체 하위 샘플 적용 범위 마스크를 만듭니다. 현재 하위 샘플이 알파 테스트를 사용하는지 확인하고 비트를 설정하십시오.
static const float2 vMSAAOffsets[2] = {float2(0.25, 0.25),float2(-0.25,-0.25)};
const float2 vDDX = ddx(vTexCoord.xy);
const float2 vDDY = ddy(vTexCoord.xy);
[unroll] for(int s = 0; s < nSampleCount; ++s)
{
float2 vTexOffset = vMSAAOffsets[s].x * vDDX + (vMSAAOffsets[s].y * vDDY);
float fAlpha = tex2D(DiffuseSmp, vTexCoord + vTexOffset).w;
uCoverageMask |= ((fAlpha-fAlphaRef) >= 0)? (uint(0x1)<<i) : 0;
}
지연된 MSAA에 대한 성능 최적화: 지연된 계단식 태양 그림자 맵, 평소와 같이 픽셀 셰이더로 그림자를 렌더링하고 지연된 셰이딩 조합 중에 양방향 업샘플링을 사용합니다. 깊이에 접근하기 위한 불투명하지 않은 기술(예: 부드러운 입자) 실제 시나리오에서는 샘플별 접근 방식이 상당히 느립니다. 대부분의 경우 Max Depth를 사용하는 것이 좋으며 N배 더 빠릅니다. 많은 게임에서 사용되는 방법: 알파 테스트 슈퍼샘플링을 건너뛰고, 대신 알파 적용 범위를 사용하고, 알파 테스트 AA도 사용하지 않고(형태학적 AA가 이를 처리하도록 함), MSAA를 사용하여 불투명하게만 렌더링한 다음 MSAA 없이 투명하게 렌더링하고, HDR 렌더링을 가정합니다. 톤매핑은 구문 분석 후 암시적으로 수행되며 결과적으로 고대비 영역의 세부 정보가 손실됩니다.
지연된 MSAA를 통한 MSAA 친화성: 아래 이미지에서 눈에 띄는 MSAA 효과가 없거나 눈에 띄는 밝은/어두운 윤곽선이 없음을 알 수 있습니다.

수리 후 효과는 다음과 같습니다.

지연된 MSAA 검토: 다중 샘플링된 RT에 액세스 및/또는 렌더링합니까? 그런 다음 올바른 하위 샘플에 액세스하고 출력하는 데 주의를 기울여야 합니다. 일반적으로 항상 대역폭을 최소화하고, 바닐라 지연 조명을 피하고, 전체 지연, 블렌딩 또는 지연 건너뛰기 우선 순위를 지정하도록 노력해야 합니다. 지연되는 경우 경량 GBuffer를 선호하세요. GBuffer에 대상을 추가할 때마다 데이터 내보내기 오버헤드가 발생합니다. NV/AMD(GCN): 내보내기 비용 = 비용(RT0) + 비용(RT1)..., AMD(기존 하드웨어): 내보내기 비용 = (RT 수) * (가장 느린 RT), 고정밀 형식은 GCN의 이중선형 필터링 모드에서 절반 속도 샘플링 비용이며 조명/일부 hdr 사후 처리의 경우: 대부분의 경우 32비트 R11G11B10F 형식이면 충분합니다.
안티앨리어싱 + 4K 해상도에 MSAA가 필요합니까? 아래 그림은 고압축 4K와 원본 4K를 비교한 것입니다.

앤티앨리어싱/더 나은(그리고 더 빠른) AA 추구: 2011년: FXAA, MLAA, SMAA, SRAA, DEAA, GBAA, DLAA, ETC AA 및 "실시간 앤티앨리어싱을 위한 필터링 방법"과 같은 대체 AA 모드(및 명명된 조합)의 호황기였습니다. 음영처리된 앤티앨리어싱: "Mip 매핑된 노멀 맵", LEAN, CLEAN 등
임시 SSAA, SMAA 2TX, 4X 검토: 형태학적 AA + MSAA + 임시 SSAA 조합, 균형 잡힌 비용/품질 절충, 기술이 서로 보완, 임시 구성 요소는 2개의 하위 픽셀 버퍼를 사용하고, 프레임당 2x SSAA에 대한 하위 픽셀 디더를 추가하고, 이전 프레임을 재투영하고 현재 프레임과 현재 프레임을 혼합합니다. 속도 길이에 따라 가중치가 부여된 이전 프레임은 이미지 선명도와 합리적인 시간적 안정성을 유지합니다.


시간적 AA/일반적인 견고성 결함: 불투명한 기하학적 정보에 대한 의존, 신호(색상) 변경 또는 투명성을 처리할 수 없음. 올바른 결과를 얻으려면 모든 불투명 형상이 속도를 내보내야 합니다. 부정적인 경우: 알파 혼합 표면(예: 입자), 조명/그림자/반사/uv 애니메이션/등, AA가 해결되기 전의 분산 및 유사한 포스트 프로세스. 투명도, 조명, 그림자 등의 고스팅과 같이 산란을 일으킬 수 있는 오류. 실루엣은 산란 및 유사한 포스트 프로세스(예: 블룸)에서 나타날 수 있습니다. 다중 GPU를 위한 가장 간단한 솔루션: 강제 리소스 동기화, NVIDIA는 NVAPI를 통해 드라이버 힌트를 노출하여 리소스 동기화를 강제하는 솔루션은 NVIDIA의 TXAA에서 사용하는 솔루션입니다.
SMAA 1TX/A 더욱 강력한 시간적 AA: 개념: 신호 변화만 추적하고 기하학적 정보에 의존하지 않으며 시간적 안정성을 높입니다. TXAA와 같은 누적 버퍼에 여러 프레임을 누적하고 누적 버퍼를 다시 투영합니다. 가중치: 누적 버퍼 매핑, 현재 프레임 주변 색상 범위에 버퍼 색상, 고주파/저주파 영역에 대해 서로 다른 가중치(명확성을 유지하기 위해).


float3 cM = tex2D(tex0, tc.xy);
float3 cAcc = tex2D(tex0, reproj_tc.xy);
float3 cTL = tex2D(tex0, tc0.xy);
float3 cTR = tex2D(tex0, tc0.zw);
float3 cBL = tex2D(tex0, tc1.xy);
float3 cBR = tex2D(tex0, tc1.zw);
float3 cMax = max(cTL, max(cTR, max(cBL, cBR)));
float3 cMin = min(cTL, min(cTR, min(cBL, cBR)));
float3 wk = abs((cTL+cTR+cBL+cBR)*0.25-cM);
return lerp(cM, clamp(cAcc, cMin, cMax), saturate(rcp(lerp(kl, kh, wk)));이 기사에서는 Bokeh DOF 및 모션 블러와 같은 일부 후처리도 다룹니다.

다양한 DOF 가중치의 효과.

모션 블러를 위한 재구성 필터.
요약하자면, 이 기사에서는 실질적인 MSAA 세부 사항, 해야 할 일과 하지 말아야 할 일을 설명합니다. SMAA 1TX는 단 4개의 추가 텍스처 작업과 한 쌍의 ALU를 갖춘 더욱 강력한 TAA입니다. 합리적이고 성능이 좋은 DOF 재구성 필터, 분리 가능한 유연한 필터, 모든 보케 커널 모양이 가능합니다. 첫 번째 패스: 0.426ms, 두 번째 패스: 0.094ms, 총 0.52ms의 재구성 필터를 사용합니다. 개선된 합리적인 모션 블러 재구성 필터, 분리 가능, 첫 번째 패스: 0.236ms, 두 번째 패스: 0.236ms, 총 0.472ms의 재구성 필터를 사용합니다.
Oceans on a Shoestring: Shape Representation, Meshing and Shading은 해양 렌더링을 위한 새로운 기술, 기존 표현에 대한 많은 간단한 개선, 효율적인 높이 쿼리를 허용하는 새로운 절차적 표현, 앨리어싱을 크게 줄이는 새로운 "고정 메시" 메싱 기술을 도입합니다. 물론 표면 채색 경험도 있습니다.

해양 셰이딩에는 모양, 그리드 및 셰이딩이라는 세 가지 주요 기술이 포함됩니다.
모양 측면에서 푸리에 합성이 사용됩니다. 파도의 주파수 구성요소에 대한 여러 알려진 모델, 푸리에 변환을 사용하여 원하는 스펙트럼으로 표면을 합성할 수 있습니다. FFT는 변위 맵 세트, 64프레임의 루프 애니메이션, 64x64 공간 해상도, 8비트 고정 소수점 값, 위치 및 법선에 대해 1.5mb, 파도 세트에 대해 합산하여 오프라인으로 미리 계산됩니다.

파도 입자는 물 표면에서 움직이는 "물방울"을 시뮬레이션하는 데에도 사용되어 색상에 대한 표면 높이와 거품 값을 제공합니다. 자유롭게 움직일 수도 있고 떠다니는 물체에 묶일 수도 있습니다. Smoothstep을 입자 코어로 사용하면 매개변수를 오프셋하여 잔물결을 얻을 수 있습니다.

균일한 그리드에 쿼리하고, 업데이트 후 그리드에 활성 입자를 쓰고, 그리드의 간단한 루프에 잔물결을 래스터라이제이션하기 위한 세계 축 정렬입니다.
또한 모양은 제한된 수의 샘플과 함께 LOD를 사용하며, 특히 CPU에서 메시를 생성할 때 뷰에 따라 명확하지 않은 모양을 방지합니다. 절차적 – 더 작은 파장 생략, 푸리에 합성 – 감소, 파동 입자 – 감소.
요약하자면, 모양을 설명하는 방법에는 여러 가지가 있으며, 본 논문에서 찾은 방법은 표현력이 풍부하고 상대적으로 빠르고 구현하기 쉽습니다.
메시의 경우, 클립맵의 경우 서로 다른 해상도의 메시가 함께 연결되어 사전 제작 중에 제거됩니다. 앞으로도 그럴 수 있을 것이다.
투영된 메시는 간단하고 효율적이며 뷰가 조정되고 정점이 카메라와 함께 이동하며 보간 오류가 생생하고 분명해집니다. 스크린 공간과 월드 공간의 비교는 다음과 같습니다.

정점을 고정된 상태로 유지할 수 있으면 보간 오류를 고정할 수 있으며 이는 Polar Meshing을 통해 수행할 수 있습니다.

일반 투영 그리드와 극좌표 그리드의 비교 차트입니다.

파동의 극좌표 중첩과 다양한 변형을 거친 격자 모양.
이는 명백한 왜곡을 크게 줄일 수 있고 오버헤드가 낮으며 구현하기가 상대적으로 쉽습니다.
컬러링 측면에서는 폼, 글리터, 지하 산란, 어두운/밝은 색상이 추가되고, 포물선형 파동이 도입되고, 파동 입자가 "잔물결 입자"로 확장되어 짧은 시간 내에 시각적, 디자인적 목표를 충족하는 형태 묘사의 조합을 제시합니다.

픽셀 동기화: 새로운 데이터 구조로 오래된 그래픽 문제 해결픽셀 동기화의 배경, 기술, 최적화 및 기타 내용.
프로그래밍 가능한 셰이더는 수많은 새로운 렌더링 기술의 개발을 주도하면서 엄청난 영향을 미쳤으며 계속해서 영향을 미치고 있습니다. 파이프라인 백엔드는 아직 프로그래밍할 수 없으며 고정 메뉴에서만 색상, z 및 스텐실 작업을 주문할 수 있지만 매우 빠르고 전력 효율적입니다. 프로그래밍 가능한 새 백엔드를 추가하시겠습니까? 고정 기능 하드웨어와 공존하고 각각의 장점을 활용하세요. 프로그래밍 가능한 백엔드를 통해 DX11/OGL 4.2는 픽셀 셰이더에서 임의의 읽기 및 쓰기 메모리 작업을 활성화할 수 있지만 동일한 픽셀에 매핑된 조각으로 인해 데이터 경합이 발생할 수 있습니다.

조각은 순서에 맞지 않게 색상이 지정될 수 있으며 순서 종속 알고리즘은 지원되지 않습니다.

Haswell은 조각 간의 종속성을 감지하고, 데이터 경쟁을 피하고, R/M/W 메모리 작업의 원래 제출 순서를 보장할 수 있습니다.

픽셀 동기화: R/W 메모리 액세스 순서 지정(즉, 알파 블렌딩과 동일한 순서)을 가능하게 하는 픽셀/조각 셰이더에 대한 간단한 확장은 셰이더에서 IntelExt_BeginPixelOrdering() 함수 호출 중 하나일 뿐입니다. 대부분의 경우 성능에 거의 영향을 주지 않는 매우 우수한 성능, R/W 메모리 액세스는 전체 SoC 캐시 계층 구조에서 지원됩니다. 픽셀 셰이더에서 프레임 버퍼를 다시 읽는 것보다 더 강력하며 MSAA에서 분리된 모든 크기/유형/치수(복셀 포함)의 데이터 구조를 구축하고 액세스하며 픽셀당 및/또는 샘플당 데이터 구조를 사용할 수 있습니다.


일부 프로그래밍 가능한 블렌딩 애플리케이션: 새로운 블렌딩 연산자, 비선형 색상 공간, 단일 인코딩 등(예: RGBE, LogLuv 등), 지연된 셰이더 블렌딩(예: 노멀과 기타 재질 속성을 혼합하여 데칼을 적용합니다.
K-버퍼: Z-버퍼를 일반화한 것으로 N개의 이미지 레이어를 한 번에 렌더링합니다. 수많은 응용 분야: 깊이 제거 구조적 솔리드 기하학, 뎁스 오브 필드(DoF) 및 모션 블러, 볼륨 렌더링...

성능 팁: 큰 버퍼를 지우지 말고 작은 버퍼를 지우고 투명 마스크로 사용하십시오.

데이터 구조가 작을수록 성능이 향상되고, 데이터 압축/압축 해제에 더 많은 명령을 사용하고, 데이터 구조 크기와 압축/압축 해제 코드의 양이 균형을 이루고, 1D 구조화된 버퍼를 타일로 지정하여 1x2, 2x2(2D 텍스처), 2x2x2(복셀) 등과 같은 데이터의 지역성을 더 잘 활용하고, 셰이더의 후반부에 동기화 지점을 우선적으로 삽입하고, 동일한 픽셀에 매핑된 셰이딩 조각의 가능성을 높입니다. 동시에. 결과: 더 나은 성능을 위해 가능할 때마다 하드웨어 z 테스트를 사용하십시오(Hi-Z는 빠릅니다!).
요약하자면, 프로그래밍 가능한 셰이딩은 파이프라인의 끝부분을 건드리지 않고도 실시간 렌더링에 혁신을 가져옵니다. 픽셀 동기화는 3D 파이프라인에 새로운 생명을 불어넣는 새로운 접근 방식입니다. 렌더링 문제를 더 잘 해결하는 픽셀별 데이터 구조를 선택하십시오. 스트리밍 방식으로 데이터를 구축하기 위해 형상을 그립니다. 데이터를 활용하고 결과를 즐겨보세요. 이제 DX11+ 확장을 사용할 수 있으며 OpenGL 확장이 개발 중입니다.
REDengine 3 캐릭터 파이프라인은 The Witcher 2 제작에 사용된 캐릭터 파이프라인의 개요를 제공하고, 사용된 문제와 솔루션을 자세히 설명하고, 사용된 셰이더 탐색, 아티스트를 위한 예산 설정, 특히 컷신에서 캐릭터 조명의 특징, 그리고 마지막으로 이러한 캐릭터를 진정으로 믿을 수 있게 만드는 애니메이션과 흉내를 제공합니다. 또한 이 기사에서는 DX11 및 Forward+ 렌더링을 활용하여 헤어 시뮬레이션 및 렌더링, 피부 셰이딩, 완전히 수정된 시뮬레이션 애니메이션 시스템 등 더 나은 결과를 얻는 새로운 시스템을 소개합니다. 또한 애니메이션이 모션 캡처 스튜디오에서 게임으로 어떻게 전달되는지, 그리고 괴물과 동물을 애니메이션화하는 방법에 대해 자세히 설명합니다. 또한 캐릭터를 위해 특별히 제작된 수많은 기능을 사용하여 일관된 조명 및 환경 시스템을 만드는 것이 어렵다는 점에 대해서도 설명합니다.

고급 Linux 게임 프로그래밍에서는 시스템 구축 개선, 신호 처리, 메모리 디버깅 및 OpenGL 디버깅 기술을 포함하여 Linux 시스템에서의 게임 프로그래밍 기술을 설명합니다. Unix 신호는 비동기 알림이며 소스는 프로세스 자체, 다른 프로세스, 사용자 또는 커널일 수 있습니다. 인터럽트와 마찬가지로 첫 번째 비원자적 작업에서 핸들러로 점프합니다.

시스템은 일반적으로 Windows 용어로 코어, 코어 ≒ 미니 덤프를 종료 및/또는 덤프하지만 매핑된 전체 주소 범위(RLIMIT_core 바이트로 잘림)를 덤프하는 기본 처리기를 설치합니다. 사용자 정의 핸들러를 지정하고 핸들러를 가져오거나 설정할 수 있습니다. void handler(int, siginfo_t , void); 시그액션을 통해. sigaction() 호출에는 SAU_SIGINFO 플래그가 필요합니다. 신호는 중첩될 수 있지만 기본 프로그램과 공유할 수는 없습니다.

비동기 안전하지 않은/재진입이 불가능한 함수를 호출할 수 없습니다.
Valgrind는 Linux 시스템의 메모리 디버깅 도구입니다. 동적 런타임 분석 프레임워크, 동적 재컴파일, 기계어 코드 → IR → 도구 → 기계어 코드가 있습니다. 성능은 일반적으로 수정되지 않은 코드의 25-20%입니다. 그 안에는 "원격" 디버깅을 위한 gdbserver, 모든 오류에 대한 SIGTRAP(중단점), 무제한 메모리 체크포인트가 있습니다!
OpenGL 디버깅의 경우 오래된 방법은 OpenGL을 호출할 때마다 glGetError()를 호출하고, 8개 중 오류 코드를 가져오고, 설명서에서 호출을 찾아 이 특정 오류가 이 특정 컨텍스트에서 무엇을 의미하는지 확인하는 것입니다. 그런 다음 실제로 무슨 일이 일어나고 있는지, GLTEXAGE*()에서 유효하지 않은 GL 값의 6가지 가능한 원인을 확인하세요! 보통 디버거를 붙이고 장면을 재생하는데... 안타깝네요!
디버그 콜백을 사용하면 glGetError()를 다시 호출할 필요가 없습니다! 운전자가 제공하는 성능 팁을 포함하여 더 자세한 정보를 제공하고 다양한 운전자의 의견을 확인할 수 있습니다. 디버깅 OpenGL 컨텍스트(GLX_context_debug_BIT_ARB)가 없으면 적용되지 않을 수 있습니다. 다음 중 하나에 의해 제공됨(ABI 호환): GL_KHR_debug[OPENGL02], GL_ARB_debug_output[OPENGL03]. 다양한 GPU 공급업체 지원 표는 다음과 같습니다.


버퍼 메모리 유형, 사용되지 않은 밉 수준과 같은 중요한 성능 정보에 대한 자세한 정보(필터링)(glDebugMessageControl_ARB), 쿼리 11(GL_DONT_CARE)을 제어할 수 있습니다.
API 호출 추적을 사용하면 응용 프로그램 실행 추적을 기록하고, 추적을 재생 및 확인하고, 특정 호출에서 OpenGL 상태를 찾고, 상태 변수, 리소스 및 개체(텍스처, 셰이더, 버퍼 등)를 검사할 수 있습니다. apitrace 또는 VOGL을 사용합니다.
또한, gcc multilib는 32/64비트 교차 컴파일을 위한 전제 조건이며, Clang과 gcc 사이를 전환하는 것은 쉽고 유용하며, gold를 사용하면 링크 시간을 크게 향상시킬 수 있습니다. gdb 인덱스를 캐싱하면 디버깅 환경이 향상될 수 있으며 충돌 처리는 쉽지만 올바르게 처리하기는 어렵습니다. Valgrind는 메모리 디버깅에 큰 도움이 되며 사용자 정의 할당자를 사용하는 경우에도 일부 확장을 사용하면 OpenGL 디버깅 환경을 크게 향상시킬 수 있습니다.
2014년, Xbox One 및 PS4에서 컴퓨팅 셰이더의 효율적인 사용에서는 GPU 기반 천 시뮬레이션, 셰이더, 최적화 기술 등과 같은 콘솔 플랫폼에서 컴퓨팅 셰이더의 특성, 적용 및 최적화에 대해 설명했습니다. CPU에서 GPU로 전환을 시도하는 주요 이유 중 하나는 당시 콘솔 GPU의 최고 성능이 CPU의 15~23배였다는 것입니다.

첫 번째 계획에서는 다음 방법을 채택했습니다.

그러나 Dispatch가 너무 많으면 병목 현상은 여전히 CPU입니다. 더 나은 성능을 위해 여러 천 항목을 병합하려면 모든 천이 동일한 속성을 가져야 합니다. 새로운 접근 방식은 전체 천을 시뮬레이션하는 하나의 거대한 컴퓨팅 셰이더, 셰이더 내의 동기화 지점, 50개 이상의 "디스패치"를 사용하고 단일 "디스패치"를 사용하여 여러 천 항목(최대 32개)을 시뮬레이션하는 것입니다. 병렬화는 다음과 같습니다.

우수한 성능을 위해 순차 읽기를 보장합니다. 병합 = 16개 읽기 대신 1개 읽기, 즉 AoS(구조 배열) 대신 SoA(구조 배열)를 사용합니다.

셰이더 최적화 측면에서 일반적인 규칙은 병목 현상 = 메모리 대역폭이며 데이터 압축을 사용할 수 있습니다.

로컬 데이터 저장소(로컬 공유 메모리라고도 함)를 사용합니다.

로컬 데이터 메모리에 정점을 저장합니다.

가장 많은 대기 시간을 숨기려면 256개 또는 512개의 스레드가 있는 더 큰 스레드 그룹을 사용하십시오.


저지연 클라우드 게이밍 솔루션으로의 손쉬운 경로에서는 AMD의 GPU 기반 클라우드 렌더링 프레임워크 RapidFire의 기능, 아키텍처 및 기술을 설명합니다. RapidFire는 낮은 대기 시간, 고화질 이미지 품질, 멀티 스트림, 가상화 지원, 고해상도, 협업, 가상 데스크탑, 적응형 네트워크 환경을 특징으로 하며 서버, 네트워크, 클라이언트, UI 및 기타 구성 요소를 제공합니다. 렌더링 아키텍처는 다음과 같습니다.

데이터 흐름 개요:

클라이언트 데이터 흐름:

클라이언트 구성 요소의 초기화 및 루프:

LEAP DIRECT 게임 플랫폼 - RAPIDFIRE를 사용하여 클라우드 게임을 유연하게 코딩:

체적 안개(Volumetric Fog): 대기 산란에 대한 통합 컴퓨팅 셰이더 기반 솔루션은 대기 산란, 기존 게임 솔루션, 알고리즘 개요, 구현 세부 사항 등에 대한 소개를 공유합니다. 대기 산란에는 하늘 색상, 안개, 구름, 예수 빛, 광선 및 체적 그림자와 같은 시각 효과가 포함됩니다. 각 효과는 다양한 렌더링 기술에 해당합니다. 대기 산란에는 복잡한 유형의 산란이 포함됩니다. 해당 모델과 공식은 다음과 같이 설명됩니다.




게임 내 근사 방법:
분석 솔루션(간단한 중간 밀도 기능).
빌보드/입자 기반.
후처리를 기준으로 합니다.
레이 여행.
2D 레이 행진은 다음과 같은 이유로 이 기사에서 사용되지 않습니다. 일반적으로 물리적 기반이 아니며, GPU를 사용한 루핑의 병렬성이 낮고, 샘플이 병렬이 아닌 순차적으로 계산되고, 에피폴라 샘플링과 같은 솔루션이 제한되고, 중간 밀도의 변화가 없으며, 다중 광원이 없고, 전방 셰이딩과 호환되지 않으며, 단일 레이어 효과, 정보가 깊이에 저장되고, 가장자리 왜곡이 적습니다.
Light Propagation Volumes에서 영감을 받아 복셀화된 3D 그리드 방식이 채택되었습니다. 알고리즘 개요:

중간 저장소로서의 체적 텍스처.
컴퓨팅 셰이더 및 UAV를 사용한 효율적인 레이 트레이싱 및 쓰기.
일반적인 산란 단계를 분리합니다. 중간 밀도 추정, 산란광 계산, 광선 이동 및 응용 효과에 참여합니다.
알고리즘 세부정보:

3D 텍스처 레이아웃:

렌더링 효과:

스크립팅 파티클은 스크립트 파티클의 특성, 구현 및 최적화에 대해 설명합니다. 스크립트된 입자의 장점은 더 많은 유연성, 빠른 반복 및 아티스트 제어입니다.

유연성 및 성능: 스크립팅은 훌륭하지만 JIT를 사용해도 고성능 작업에는 너무 느립니다. 일부 고성능 영역에서는 입자 시뮬레이션, 바람 시뮬레이션(및 기타 벡터 필드 효과), 사운드 처리 등과 같은 유연성이 향상되면 이점을 얻을 수 있습니다. 이러한 영역에 대해 스크립트를 어떻게 작동시키나요? 스크립트 번역이 느린 이유는 무엇입니까? 아래 코드 중 일부는 동일합니다. 동일한 기계 명령어와 네이티브 코드 대신 바이트코드를 사용하는 데 따른 일부 오버헤드가 있습니다.

DATA WIDE VIRTUAL MACHINE: 여러 데이터 항목에 대한 각 명령을 실행하고 디코딩 및 분기 비용을 상각하며 바이트코드가 네이티브 코드만큼 빠릅니까? 레지스터에 데이터를 보관할 방법이 없으며 더 많은 로드 및 저장, 더 많은 캐시 접촉이 발생합니다. 주기 순서는 다음과 같습니다.

처리 과정:
Vector4 명령어 추상화를 기반으로 구축되었습니다.
입출력 데이터는 채널(SIMD 벡터 배열)입니다.
바이트코드에는 채널에서 작동하기 위한 지침이 포함되어 있습니다: pos = ADD pos move.
명령어를 해독한 후 인터프리터는 이를 한 번에 n개의 객체에 적용합니다.

Vector4 *a = (decode channel ref);
const Vector4 *b = (decode channel ref);
const Vector4 *c = (decode channel ref);
Vector4 *ae = a + n;
// 루프 로써 n。
while (a < ae)
{
*a = *b + *c;
++a; ++b; ++c;
}또한 상수와 임시 변수는 바이트코드에서 특별히 처리되고 최적화됩니다. 개요는 다음과 같습니다.
- 오프라인 무대. 데이터 컴파일러는 코드를 구문 분석합니다: pos = pos + vel * delta_time, 바이트코드를 생성하고 필요한 경우 임시 변수를 도입합니다.
r0 = MUL vel (0.0 0.0 0.0 0.0)delta_time
pos = ADD pos r0바이트코드가 최적화되었습니다(임시 변수가 제거됨).
- 런타임. 바이트코드로 상수를 패킹하고 명령어를 실행합니다.
요약하면, "Data Range Interpreter" 모델은 고성능, 스크립트 가능, 완전히 구성 가능한 동작, 완전히 동적을 달성하기 위한 실행 가능한 솔루션입니다. 엔진을 다시 컴파일하지 않고도 신속하게 다시 로드할 수 있으며 기존 수정자 스택 솔루션에 비해 18%의 오버헤드가 있고(네이티브에 비해 34%) AVX 지원 스크립트 솔루션은 기본 솔루션보다 빠릅니다. 앞으로는 구성요소당 하나의 채널(위치 x, 위치 y, 위치 z), 더 많은 백엔드: JIT 컴파일러, GPU 컴퓨팅, SPU...
우연히도 계산 기반 GPU 입자 시스템에는 충돌, 정렬, 블록 렌더링 등을 포함하여 입자를 가속화하기 위해 계산 셰이더를 사용하는 기술을 설명하는 GPU 입자도 포함됩니다. GPU를 사용하는 이유는 고도의 병렬 작업 부하를 위해 CPU를 게임 코드 수행 및 계산 활용에 활용하기 위한 것입니다. 입자의 데이터 구조에는 입자 속성(위치, 속도, 연령, 색상 등), 정렬 목록(일련번호, 거리), 파괴 목록(일련번호)이 포함됩니다. 계산된 음영을 방출하고 시뮬레이션하기 위한 데이터 흐름은 다음과 같습니다.


충돌은 프리미티브, 높이 필드, 복셀 데이터, 깊이 버퍼 등을 사용합니다. 깊이 버퍼 충돌 시 입자를 화면 공간에 투영하고, 깊이 버퍼에서 Z를 읽고, 뷰 공간 입자 위치를 Z 버퍼 값의 뷰 공간 위치와 비교하고, 두께 값을 사용합니다.

깊이 버퍼 충돌 응답, G 버퍼의 법선을 사용하거나 깊이 버퍼를 여러 번 클릭하여 깊이 불연속성에 주의합니다. 올바른 알파 블렌딩을 위해 정렬하고, 추가 블렌딩은 효과를 포화시키고, 이중 정렬은 GPU에서 훌륭하게 병렬화됩니다.
for( subArraySize=2; subArraySize<ArraySize; subArraySize*=2) // subArraySize == 4
{
for( compareDist=subArraySize/2; compareDist>0; compareDist/=2) // compareDist == 1
{
// Begin: GPU part of the sort
for each element n
n = selectBitonic(n, n^compareDist);
// End: GPU part of the sort
}
}
래스터라이제이션: DrawIndexedIndirectInstanced() 또는 DrawIndirectInstanced(), VertexId = 입자 인덱스(또는 VS 게시판의 경우 VertexId/4), 1개 인스턴스. 큰 입자를 오버그리면 게임 디자인이 텍스처 주위에 다각형 광고판을 사용하는 것으로 제한됩니다. 절반 크기 버퍼로 렌더링, 정렬 문제, 왜곡.
타일별 바이토닉 정렬: 각 스레드가 눈에 보이는 입자를 추가하기 때문에 입자는 임의의 순서로 LDS에 추가되므로 정렬해야 합니다. 전체 목록이 아닌 타일 내에서만 입자를 정렬합니다. 타일 렌더링(1스레드 = 1픽셀):
누적된 색상을 float4(0,0,0,0)으로 설정합니다.
타일의 각 입자에 대해(뒤에서 앞으로):
입자 기여도를 평가합니다.
반경 확인.
텍스처 조회.
선택적인 일반 생산 및 조명.
수동 혼합.
색상 = (srcA x srcCol) + (invSrcA x destCol).
알파 = srcA + ( invSrcA x destA ).
화면 크기 UAV를 작성합니다.
타일 렌더링(향상된 버전):
누적된 색상을 float4(0,0,0,0)으로 설정합니다.
타일의 각 입자에 대해(앞에서 뒤로):
입자 기여도를 평가합니다.
- 수동으로 섞으세요.
색상 = ( srcA x srcCol ) + ( invSrcA x destCol )
알파 = srcA + ( invSrcA x destA )
if ( 누적 알파 > 임계값 )
누적 알파 = 1 및 보석금
- 화면 크기의 UAV를 작성합니다.
러프 컬링:
입자를 8x8에 배치합니다.
UAV0은 오프셋을 사용하여 배열을 여러 부분으로 분할하는 인덱싱에 사용됩니다.
UAV1은 각 bin의 입자 수를 저장하는 데 사용됩니다. Bin당 요소 1개, InterlockedAdd()를 사용하여 카운터를 누적합니다.
각 살아있는 입자에 대해:
각 저장소에 대해 다음을 수행합니다.
상자의 프러스텀 평면을 기반으로 입자를 테스트합니다.
쓸 슬롯을 얻기 위해 UAV1에 카운터를 축적합니다.
UAV0에 입자 인덱스를 추가했습니다.
성능 비교:

결론: 입자 시뮬레이션, 깊이 버퍼 충돌, 올바른 혼합을 통한 이중 정렬을 위한 계산 활용. 타일 렌더링은 래스터라이제이션보다 빠르고 심각한 오버드로를 해결하는 데 적합하며 동작을 더 예측 가능하게 합니다. 향후 작업은 볼륨 추적, OIT에 임의의 형상을 추가하는 것입니다.
REDengine 3의 랜드스케이프 생성 및 렌더링에서는 Witcher 시리즈에 사용된 엔진인 REDengine의 지형 시스템 생성 파이프라인 및 렌더링 프로세스를 설명합니다.
REDengine 엔진의 목표는 16k 이상의 해상도, 0.5미터 미만의 버텍스 간격, 다양한 풍경 특징, 상대적으로 작은 팀이 그려서 채우는 동굴 메시 배치를 위한 지형 구멍, World Machine에서 생성하고 가져오는 지형 모양을 지원하는 것입니다. 텍스처, 혼합 재료, 경사 기반, 픽셀 단위, 지형에서 그림자를 표시해야 함, 평균 "풍경" 이상의 광범위한 복사-붙여넣기 기능 측면에서 큰 기대가 있습니다.
지형/스트리밍: 텍스처 배열을 사용하는 스트리밍 영역이 있는 메모리 내 클립맵입니다. Novigrad의 작업 설정: 46x46 타일, 각각 512x512(230k+), 창 해상도 = 1024x1024, 5개의 클립맵 레벨, 내부 버텍스 간격 = ~0.37cm, ~74km2.

지형/클립맵: 스트리밍 클립맵 3개: 높이 맵(16비트 unorm), 제어 맵(16비트 단위), 색상(32비트, 감소된 해상도, 163842 높이 데이터 세트의 경우 40962). 3개의 런타임 생성 클립맵: 수직 오류(64x64의 일반적인 경우), 노멀(선택 사항), 지형 음영.
지형/테셀레이션: Gpu Pro 3 기사에서 영감을 받아 유사한 기술이 클립맵에 적용되었으며 삼각형 수는 여전히 매우 좋습니다. 특히 콘솔 GPU의 경우 최대 테셀레이션 인수가 8 또는 16일 때 최상의 결과가 나옵니다.
수직 오류 맵 생성: 각 테셀레이션 블록 [x, y]에 대해(1 제어점 = 1 테셀레이션 블록):

소프트웨어 테셀레이션: 하드웨어 테셀레이션에 의존하기 전에 쿼드트리 수준에서 단순화하기 위해 오류 맵을 다운샘플링하여 최소 테셀레이션 블록의 조밀한 메시로 넓은 영역을 렌더링하는 것을 방지합니다.
텍스처 대상: 거의 노력하지 않고 설득력 있는 전경을 확보한 후 실제 작업이 시작됩니다. 클로즈업에 아름다운 재질을 통합하고 UV 브러시만 사용하여 오프라인으로 텍스처 크기를 수동으로 조정합니다. 구현하기 쉬움: 재료 흐름이 없고 텍스처 배열이 하나만 있습니다(둘 다 노멀 맵 포함).
지형은 삼면 매핑을 사용하고, 오버레이 텍스처에는 삼면 맵이 없으며, 삼면 맵이 있는 배경 텍스처 샘플의 경우 작동하는 평면을 선택하고(텍스처 가져오기보다 분기 선호) 혼합 영역을 최대한 조이되 아티팩트를 피하세요. 혼합 영역은 다음과 같이 축소됩니다.


지형 그림자 클립맵은 그림자의 최대 높이를 저장하고, 클립맵을 스트리밍하거나 시간을 변경할 때 업데이트하며, 그림자 깜박임을 방지하기 위해 클립맵 계산과 긴밀하게 결합되어야 합니다. 이를 통해 여러 개의 거대한 메시가 지형 그림자를 투사할 수 있습니다.

지형 셰이딩 알고리즘:
포장된 지형 깊이 - 태양의 관점.
각 텍스처에 렌더링된 그림자 조각 클립맵:
각 텍셀에 대해 다음을 수행합니다.
해당 높이 텍스처에서 월드 공간 위치(wsPos)를 계산합니다.
For i=0 to n: // n=13이면 좋은 결과가 나옵니다.
wsPos를 태양 공간 위치로 변환합니다.
태양의 공간 위치의 z값과 pt.1 텍스처에서 얻은 z값을 비교합니다.
위치가 가려지면 wsPos.z += step, step이 반으로 줄어듭니다.
wsPos.z -= 위치가 가려지지 않은 경우 단계.
지형 그림자 맵의 마지막 z 구성 요소 값을 다시 그립니다.
또한 식생은 복잡한 생성 알고리즘과 툴체인을 사용합니다. 렌더링은 다음과 같습니다.

얼굴 스캔부터 얼굴 애니메이션까지 차세대 캐릭터에서는 고품질 가상 캐릭터의 제작 과정, 관련 도구 체인 및 기술을 설명합니다. 기사에서 제안하는 워크플로우는 다음과 같습니다.
1. 배우를 스캔하세요.
스캐닝 단계에서는 사진 매트릭스를 사용합니다.

**2. 원본 스캔을 정렬된 혼합 모양으로 처리합니다.**BlendShape 스캐닝 프로세스 개요:
지점에 로케이터를 배치합니다.
스캔을 위해 그리드를 래핑합니다.
관절을 지점으로 이동합니다.
스캔에서 가장 가까운 지점을 일치시킵니다.
안심하다.
반복하다.
헤더 내보내기.
투영된 텍스처.
광학 흐름, 곡률 및 고주파 디퓨즈를 반복적으로 적용합니다.
메시에 광학 흐름 결과를 다시 적용합니다.
마치다.
위 프로세스에서는 텍스처 투영, 표현식, 기본 메쉬 등과 같은 많은 추가 세부 사항을 처리해야 합니다.
3. 블렌드셰이프 텍스처를 압축하여 실시간 재생을 구현합니다.
다양한 확산 텍스처(70개), Tiger Woods에는 수천 개가 더 있습니다.
PCA 가이드: 실제로는 오프셋입니다. 아래 그림은 왼쪽부터 오른쪽으로 스마일, 중립, 스마일 오프셋(스마일 중립)입니다.

재구축할 때 Final = w0img0 + w1img1 + w2img2 + … + w11img11, 애니메이션을 적용하려면 가중치(셰이더 상수)만 변경하면 됩니다.

주성분 분석 계산: SVD(Singular Value Decomposition)를 사용할 수 있습니다. SVD는 210개의 열을 모두 해결한 다음 처음 12개를 제외한 모든 열을 잘라냅니다.
PCA 알고리즘은 http://en.wikipedia.org/wiki/Principal_comComponent_analytic을 참조하세요.
4. mocap을 사용하여 블렌드 셰이프를 구동합니다.
관절 애니메이션과 일치하는 모양의 가중치를 찾습니다.

5. 스킨 셰이딩 렌더링을 사용합니다.
렌더링에 사용되는 기술에는 Skin SSS, SHAO(구형 고조파 포함 AO), 적응형 테셀레이션, 눈, 치아 등이 포함됩니다.

왼쪽부터: 그림자 없음, SHAO, 그림자, SHAO + 그림자.
하이브리드 재구성 안티 앨리어싱은 Far Cry 4의 하이브리드 재구성 안티 앨리어싱 기술 HRAA에 대해 이야기합니다. HRAA는 시간적 안정성, 고품질 가장자리 디앨리어싱, 4x RGSS에 필적하는 슈퍼샘플링, 1샘플/픽셀 셰이딩 비용, 1080p 해상도에서 PS4/X1의 최대 1ms 성능을 목표로 합니다. HRAA 개요: 안정적인 가장자리 앤티앨리어싱, 임시 오버샘플링, 템포럴 안티앨리어싱(TAA). 안정적인 가장자리 앤티앨리어싱에는 다음이 포함됩니다.
- 형태 : SMAA[히메네즈 11], FXAA[로테스 09]
장점: 정적 장면에서 가장 높은 인지 품질, 모든 동작 캡처, 손쉬운 통합, 래스터라이제이션된 데이터 사용.
단점: 1080p(PS4/X1)에서 1.0~1.5ms, 시간이 불안정하고 움직임이 흔들립니다. 부분적인 해결책: 더 비싼 SMAAx4.
에지 AA 분석: GBAA [Persson 11], DEAA [Malan 10]
장점: 기본 진실에 가까운 최고의 에지 품질, 안정적인 타이밍, 알파 테스트로 확장(SDF를 사용한 최상의 결과), 1080p에서 0.3ms의 빠른 속도(PS4/X1).
- 단점: 복잡한 통합, G-버퍼 셰이더 출력당 가장자리로부터의 거리, 기하학 셰이더/직접 버텍스 액세스[Drobot 14], 래스터라이제이션 문제가 있음, 래스터라이제이션 순서에 따라 다름, 콘텐츠에 따라 다름, 과도한 테셀레이션으로 인해 AA가 크게 꺼지고 교차하는 삼각형이 없음.

상단: 가장자리까지의 거리 시각화, 색상 인코딩 1비트 방향(X,Y), 부호 값 인코딩 4비트 거리. 중간: 1x 중심 래스터라이제이션 결과. 하단: 분석 구문 분석 결과. 오른쪽 가장자리는 완전히 앤티앨리어싱되었습니다. 중간 부분에는 래스터라이제이션 오류 및 하위 픽셀 삼각형(여러 삼각형이 교차하는 위치)으로 인해 잘못된 가장자리가 표시됩니다.
- MSAA.
장점: 표본 크기가 커질수록 기본 진리에 수렴하고 하위 픽셀 문제를 해결합니다.
- 단점: 메모리 사용량은 샘플링 볼륨과 선형적으로 관련되며, 그리드 렌더링 시간은 샘플링 볼륨에 따라 변경되고, 디퍼드 렌더링(Deferred Shading)의 복잡한 통합이 발생합니다.

2.png)
- EQAA/CSAA. GPU는 저렴한 커버리지 샘플의 지원을 받아 색상/깊이 조각에서 커버리지 샘플을 분리할 수 있습니다. MSAA=EQAA입니다.

- 보장 기준: Coverage Reconstruction AA(CRAA). 최저 비용을 위해 다른 커버리지 샘플과 함께 색상 조각을 사용하고 커버리지에서 최종 이미지를 재구성하며 샘플에 직접 액세스할 수 있는 하드웨어가 필요합니다. 이어서 AMD GCN 아키텍처를 기반으로 한 시연이 이어집니다. 다른 IHV도 커버리지 샘플링을 지원합니다.
FMASK: 샘플과 색상 조각 간의 연관 테이블을 저장하는 색상 버퍼와 연관된 조각 압축 버퍼입니다. 각 픽셀에 대해 각 샘플에 대해 연관된 조각의 비트 인덱스를 저장합니다. 픽셀당([1, 2, 4, 8, 16개 샘플] [색상 인덱스의 경우 1, 2, 4비트] + UNKNOWN 플래그의 경우 1비트):
4-sample/2-fragment = 4 * 2 = 8 bit
8-sample/1-fragment = 8 * 1 = 8 bit
16-sample/8-frag = 16 * 4 = 64 bit아래 그림을 바탕으로 구체적인 예를 들어보겠습니다.

위 이미지 상단: 샘플 0과 1이 고정되어 있습니다. 깊이 테스트를 위한 자체 깊이 조각이 있습니다. 위 이미지 중간: 파란색 삼각형이 앵커 샘플 0에 도달합니다. 파란색은 색상 조각의 시퀀스 번호 0에 추가됩니다. 위 이미지 하단: 파란색 삼각형으로 덮인 FMask 샘플은 색상 조각의 시퀀스 번호 0과 연결됩니다.
CRAA 설정: MRT 설정: 색상/깊이 1F xS, 파이프라인: Gbuffer 렌더링, 조명, CRAA 분석. 8x CRAA의 샘플 분석:
- 미지의 각 샘플에 대해:
샘플링 위치를 가져옵니다.
샘플 위치를 벡터로 처리합니다.
함께 추가되었습니다.
합계는 픽셀을 반면으로 나누는 대략적인 공식을 정의합니다.
반평면 방향(수직/수평)을 계산합니다.
반평면 경사를 계산합니다.
방향과 기울기(위/아래, 왼쪽/오른쪽)에서 알 수 없는 조각을 추론합니다.
해결된 픽셀 = 색상 조각 적용 범위 + (1-범위) 추론된 조각.

8xCRAA 결과는 여러 삼각형 교차점이 포함된 픽셀을 제외하고 8xMSAA와 유사합니다. 이 복잡한 경우 단일 모서리 추정으로는 모서리를 올바르게 해결할 수 없습니다. 가시적인 왜곡은 분석 방법과 유사합니다.
8xCRAA LUT: 하위 픽셀 아티팩트는 어떻습니까? 제거될 수 있나요? ALU를 제거하고 대역폭에 의해서만 제한될 수 있습니까? 해결 방법: LUT를 미리 계산하여 인접한 픽셀 가중치를 저장하고 전체 이웃, 픽셀을 통과하는 여러 가장자리/삼각형을 사용합니다.

8xCRAA LUT 효과 비교:

시간적 슈퍼샘플링: Killzone: Shadow Fall [Valient14]을 기반으로 데이터에 대해 현재 프레임과 이전 프레임(2개 샘플)을 사용하고 색상 흐름 테스트에 N-2 프레임을 사용하며 N-1 샘플은 N번째 프레임과 N-1번째 프레임 사이의 모션 흐름이 일관되고 N번째 프레임과 N-2번째 프레임 사이의 색상 흐름이 일관되는 경우에만 유효합니다(N-2와 N은 동일한 하위 픽셀 지터를 가짐).

성능상의 이유로 => 더 작은 창 => 더 보수적으로 3x3 이웃, 절대 차이의 합을 사용하여 테스트되었습니다. GCN은 하드웨어 가속(SAD, QSAD, MQSAD, 압축 보간)을 제공합니다.

N-1 샘플이 기하학적 메트릭을 따르지 않으면 보간은 N부터 시작됩니다. N-1 샘플이 색상 메트릭을 따르지 않으면 N-1 샘플은 N 색상 경계 상자로 제한되므로 안정성이 향상되고 새로운 정보가 제공됩니다. 다양한 샘플링 모드의 효과는 다음과 같이 비교됩니다.

ng)
왼쪽에서 오른쪽으로: 1x, FLIPQUAD, 4xRG.
FLIPQUAD 샘플링 모드: [AMD 13] AMD_framebuffer_sample_positions, 2xMSAA – 설정이 쉽고 동일한 비용으로 품질이 quincunx [Laine 06]보다 훨씬 높습니다. 다음 그림은 다양한 샘플링 모드와 오류 표입니다.

FLIPQUAD 모드의 시간 다이어그램은 다음과 같습니다.

패턴을 반으로 분할하면 프레임 A(파란색)가 부분적으로 렌더링되고 프레임 B(빨간색)가 나중에 렌더링됩니다. 쿼드 내에서 픽셀 단위로 구문 분석되어야 하며 프레임에 따라 X축 또는 Y축에서 편리하게 블렌딩되어야 합니다. Pixel0 = avg(BLUE(0,1), RED(0,2)).
TAA: 기록 인덱스 버퍼는 갑작스러운 시각적 변화(깜박임)를 상쇄하고 새로운 "중요한" 데이터를 최대한 많이 축적하며 빈도 기반 수용 지표를 사용합니다. 새 데이터의 이웃(3x3 창)에 대해 작업하면 평균에 가까운 과거 샘플은 새로운 정보를 가져오지 않으며, 멀리 있는 과거 샘플은 더 많은 정보를 가져오며, 너무 멀리 있는 과거 샘플은 일종의 변동이 될 수 있습니다. 로컬 최소값/최대값을 소프트 경계로 사용합니다.

HRAA의 최종 구현:
- 일시적으로 안정적인 가장자리 앤티앨리어싱.
SMAA(노멀 + 깊이 + 루마 예측 임계값)
CRAA
AEAA(GBAA)
TAA와 결합된 일시적 FLIPQUAD 재구성.
TFQ+TAA
Far Cry 4의 HRAA 최종 구현:
일시적으로 안정적인 가장자리 앤티앨리어싱. 당연한 선택은 아닙니다.
알파 테스트에서 SMAA+AEAA. 가장 안정적이고 합리적인 성능.
알파 테스트에서 CRAA+AEAA. 최고의 성능, 일부 콘텐츠 문제.
그 효과와 성능을 비교하면 다음과 같습니다.




Reflection System in Thief에서는 기본 알고리즘, 반사 시스템 개요, SSR, IBR, 광택 반사, 반사 파이프라인, 로컬 큐브 맵 반사, 아트 파이프라인 등을 포함하여 게임 "Thief" 엔진의 반사 시스템에 대해 설명합니다.
Thief 반사 시스템의 기본 알고리즘: 평면 반사, 큐브 맵 반사, 이미지 기반 반사, 스크린 스페이스 리플렉션(SSR), 로컬 큐브 매핑, 평면의 이미지 프록시, 범프 평면 반사, Hi-Z 스크린 스페이스 리플렉션(SSR) 등.
반사 시스템 사양: 차세대 플랫폼(PC/PS4/X1)에서 5밀리초 미만, 다층 반사 표면, 인체의 매우 역동적인 물체, 준수평 표면이 주요 랜드마크를 포착해야 합니다.
해결책: 다층 반사 시스템. 각 레이어는 특정 기능, 큐브맵(로컬 + 글로벌), 이미지 기반 반사(IBR), 스크린 스페이스 리플렉션(SSR) 캡처를 담당합니다. SSR(스크린 스페이스 리플렉션(SSR))의 단계는 아래 그림에서 빨간색 화살표로 표시됩니다.

SSR 최적화: 정상은 대략 (0,0,1)이고, 범프는 사후 처리이며, 더 나은 메모리 집계입니다. 각 DRAM 버스트에 더 유용한 데이터, Early Out을 사용하고 반사가 낮을 때 종료합니다.
// 로써 코드 【】?
...
float4 res = 0;
//Early out
if (reflectionFactor < epsilon)
{
return res;
}
...
res = tex2D(...);
...
// 보정/수정(Fix)
...
float4 res = 0;
// Early out
[branch] // X4121:그래디언트(Gradient)의 필수: 까지 ,로써 분기 (divergence)
if (reflectionFactor < epsilon)
{
return res;
}
...
res = tex2Dlod(...); // 을(를) 활용하여 그래디언트(Gradient) 및 분기 !:tex2D는 그래디언트(Gradient)。
...첫 번째 깊이 버퍼 교차점에서 종료:

만약 및 반사(Reflection)의 포인트 > 0,이면 현재(Current)image의 프레넬(Fresnel)계수,로써 . 거리
절반 해상도로 렌더링하고 훨씬 더 빠르며 포스트 프로세스 중에 고주파수 데이터를 재구성하고 최악의 경우 타이밍(전체 화면)은 약 1.0~1.5ms이지만 실제 지도에서는 달성하기가 정말 어렵습니다!
IBR(이미지 기반 반사)의 경우 UE3가 잘 작동하지만 Thief는 프레임당 50개의 IBR 프록시, Full HD의 경우 8~10ms가 필요합니다. 여전히 유용한 절반 해상도 IBR 룸: IBR을 특정 수준으로 배치하고 내려다볼 때 IBR 반사를 제한합니다.
IBR 타일 렌더링의 경우 화면이 수직 타일로 분할되고, 프록시 AABB 투영이 계산되어 수직 가장자리를 화면과의 교차점까지 확장하며, 영향을 받는 타일에 프록시가 추가됩니다.

광택 반사의 경우 반사 광선은 반사판과 반사 물체 사이의 거리에 따라 매끄러운 표면에서 발산됩니다. 4mm 정확도로 2바이트로 압축된 출력 반사 거리는 정렬(따라서 높은 정확도), 거리 확대, DOF 방법과 유사한 문제, 블러 존재(2채널 가우스)에도 사용할 수 있습니다.
SSR, IBR 블렌딩: SSR의 알파는 높이, 추적 정확도(깊이 델타), 표면 레벨, 화면을 떠나는 광선, 카메라로 돌아오는 광선 등 여러 요소에 따라 달라집니다. "SSR을 원하지 않기 때문에" IBR이 먼저 병합되고 큐브맵이 이어지며 블렌딩은 sRGB에서 수행되지만 PS4에서는 RGBA16F를 사용합니다. 일반적으로 SSR은 더 가깝고 일부 객체(불)는 예외이며 거리를 사용하여 IBR 셰이더에서 정렬됩니다.

IBR 정렬 중 왼쪽 사진은 정렬되지 않았으며, 오른쪽 사진은 정렬되어 있어서 정확한 불꽃 반사가 있습니다.
반사 범프: 추적 프로세스 중에 법선이 고정됩니다. 절반 해상도로 인해 고주파수 정보가 손실됩니다. 이는 굴절 렌더링 알고리즘과 유사하며 모든 보조 단계의 시간은 약 2밀리초로 설정됩니다.
아트 파이프라인 측면에서 현지화된 큐브 그래프 파이프라인은 다음과 같습니다.

모든 SKU에 사용되는 기본 큐브맵, 볼륨 구성, 캡처된 객체의 속성 설정, 볼륨 맵 구성 과정, 큐브맵 저장 및 조립, 큐브맵을 메시에 할당하고 최종 결과를 얻습니다.
IBR 생성 파이프라인: IBR 반사(예: 웅덩이)를 위한 후보 영역 식별, 주요 랜드마크에 대한 평면 생성, 평면에 구워진 조명 장면, 평면 위치 및 조명 조정(필요한 경우 평면 추가), 숨기기 및 다른 영역으로 이동.
요약하면, 실시간 반사는 해결된 문제가 아니며, SSR에는 폴백이 필요하고, 다중 레이어 솔루션이 사용되고/사용되며, 대역폭을 절약하기 위해 혼합 해상도 렌더링이 사용됩니다.
Call of Duty: Ghosts의 테셀레이션에서는 COD의 테셀레이션 기술을 자세히 설명합니다. 표면 테셀레이션의 구현은 오프라인 전역 표면 테셀레이션, 런타임 전역 표면 테셀레이션, 기능 적응형 표면 테셀레이션의 세 단계로 나눌 수 있습니다.

세분화 프로세스에서는 불규칙한 표면이 생성되어 메쉬에 균열이 생기고 불규칙한 가장자리에 전환점을 삽입해야 합니다.

화면 공간 적응의 알고리즘 과정과 상징적 의미는 다음과 같습니다.

모서리 외삽과 모서리 외삽은 다음과 같습니다.


Compute 셰이더를 Hull 셰이더로 사용할 수 있습니다.

HLSL 대신 어셈블리를 직접 사용하면 성능이 크게 향상될 수 있습니다.

또한 Wave 사용량(CP/클록, 클록/웨이브) 및 지연에 대한 자세한 통계도 작성됩니다.

언리얼 엔진의 Brian Karis가 고품질 시간적 슈퍼샘플링을 통해 UE의 시간적 안티앨리어싱(TAA)의 기술, 구현, 문제 및 최적화를 설명했습니다.
기사에서 Brian Karis는 MSAA, 공간 필터링(MLAA, FXAA, SMAA 등) 및 Specular Lobe 필터링(Toksvig, LEAN, vMF 등)을 비교한 결과 모두 어느 정도 문제가 있거나 정보가 부족하다는 사실을 발견하고 최종적으로 Temporal Anti-Aliasing TAA를 선택했습니다.
TAA는 여러 프레임에 걸쳐 샘플을 배포합니다. Brian Karis는 과거 SSAO 및 SSR과 같이 공간 필터링을 고품질의 저렴한 필터링으로 대체하여 큰 성공을 거두었습니다. 슈퍼샘플링에도 적용되나요?
TAA에는 디더링, 샘플링 모드, 이동 평균 등과 같은 기술적인 사항이 포함됩니다. 평균 시점의 경우 톤매핑 이전 또는 이후일 수 있습니다. 물리적으로 정확한 위치, 밝은 값이 지배적인 톤매핑 이전에는 앨리어싱 심각도가 샘플 수에 의해 제한됩니다. 톤매핑 후 모든 포스트 프로세스 필터가 깜박이며 앨리어싱 입력 → 앨리어싱 출력이 됩니다.

간단한 톤매핑 솔루션:
블렌드 톤매핑 전후: 모든 포스트 프로세스, 톤 맵 입력, 누적 샘플, 반전 톤 맵 출력 전에 적용됩니다.
톤매핑 후 AA와 동일한 품질.
포스트 프로세스 체인에 앤티앨리어싱 입력을 제공하여 더 이상 깜박이는 블룸이 없습니다.
더 나은 톤매핑 솔루션:
톤매핑은 밝은 픽셀의 채도를 낮춥니다.
대신, 루마 기반 가중치 샘플링은 기준 진실에 지각적으로 더 가까운 채도를 보존합니다.
가중치를 저장하고 가중치를 다시 도출할 필요가 없으므로 GPR이 절약됩니다.
재구성 필터는 박스 필터링(움직이는 동안 불안정함), PRMan 앤티앨리어싱 가이드 및 가우시안 피팅 Blackman Harris 3.3(약 2픽셀 너비 지원)입니다.

재투영: 현재 픽셀의 기록이 화면의 다른 곳에 있을 수도 있고 전혀 존재하지 않을 수도 있습니다. 모션 블러와 동일한 속도 버퍼를 사용하여 계산되고 지터 제거를 기억합니다.
속도 정확도: 모든 것에는 속도(모션 벡터)가 필요하며, 올바른 속도가 없는 모션은 흐릿해집니다. 정확성이 중요하며 작은 부정확성으로 인해 정지 이미지, 16:16 RG 속도 버퍼에 줄무늬가 남을 수 있습니다. 까다로운 것은 절차적 애니메이션, 롤링 텍스처, 거의 불투명한 반투명 개체입니다.
가장자리 이동: 윤곽선 가장자리를 이동하면 AA가 손실됩니다. 부드러운 앤티앨리어싱된 가장자리는 개체와 함께 움직이지 않습니다. 실제로 속도 버퍼의 들쭉날쭉한 마스크입니다. 속도가 확장되고 가장 높은 속도가 먼저 적용됩니다.
TAA의 가장 큰 문제점 중 하나는 고스팅(Ghosting)입니다(아래 그림). 해결책은 심층 비교를 사용하는 것입니다. 모든 샘플의 깊이가 동일하지는 않습니다. 속도에 따라 가중치가 부여되나요? 음영 변경 및 반투명도가 효과가 없게 됩니다.

이웃 클램핑을 사용하면 현재 프레임의 로컬 이웃으로 기록을 제한할 수 있습니다. 결과는 최소/최대 3x3 이웃 클램핑으로 이웃이 혼합된 것이라고 가정합니다.

그러나 이웃 차단에는 결함이 있습니다.

기본적인 이웃 차단 대 레드 히스토리. 많은 아티팩트가 있습니다. 가장 눈에 띄는 것은 모든 가장자리에 빨간색 고스팅이 있으며, 더 미묘하게는 이미지가 저해상도처럼 보입니다.
YCoCg 색상 공간을 사용하여 상자로 변경할 수 있습니다. 최소 및 최대의 기준은 RGB 공간의 AABB로 간주될 수 있으며 상자의 방향은 밝기 방향으로 위치할 수 있습니다(밝기는 로컬 대비가 높지만 채도는 일반적으로 그렇지 않기 때문입니다).

클램프 대신 클립 사용: 기록과 이웃 평균의 혼합으로 제한하고 선분을 직육면체로 클립하면 클램핑과 마찬가지로 색상이 상자 모서리에 뭉치지 않습니다.


기본 버전과 YCoCg 버전 비교.
반투명의 경우 반투명은 시간적(단일 기록 및 속도)에 적합하지 않으며 이상적으로는 반투명도를 별도로 렌더링하고 복합적으로 렌더링하며 깊이 버퍼 비교를 취소할 수 없습니다. 가능한 해결 방법: 4xMSAA 깊이 사전 통과, 음영 처리할 샘플을 선택합니다.
UE를 위한 반투명 솔루션: "반응형 AA" 머티리얼 플래그는 트랜스루센트 렌더링 시 템플릿을 설정하고, AA가 테스트 템플릿을 통과하고 최소한의 피드백을 사용합니다. 불행하게도 눈에 보이는 디더링을 방지하려면 >0 피드백이 필요합니다. 스파크와 같은 작은 입자에만 작동하며 나머지는 이웃이 처리합니다.


TAA는 가시성 샘플과 공간 필터링을 분리하는 방화벽과 같아서 깊이가 TAA를 관통하고 공간 필터링 단계에서 DOF에 의해 사용되는 것을 불가능하게 만듭니다.

또한, 반투명 단계 이후에는 특수 경로를 사용하여 DOF나 빔에 대한 데이터를 설정한 후 TAA를 별도로 실행한 후 공간 필터링 단계의 로직을 실행합니다.

깜박임: 카메라는 고정되어 있지만 일부 픽셀이 깜박이고 손실된 하위 픽셀 기능의 기록이 잘립니다. 일반적으로 관련 지터로 인해 수직 또는 수평 라인이 잘립니다. 차단은 순간적인 펄스이므로 톱니 모양의 깜박임이 발생합니다.

UE가 여러 번 시도한 후 최종 해결책은 이력이 차단에 가까워지면 혼합 계수를 줄이고, 차단 이벤트 이후에 이벤트별 메모리가 발생하며 추가 저장 공간이 필요하지 않다는 것입니다. 하지만 아직 완전히 해결된 것은 아니고 매우 어렵습니다! 여러 반대쪽 클램프를 해결할 수 없습니다.
흐린 필터 커널: 밉맵이 모든 텍스처를 오프셋하고 슈퍼샘플링의 파생물이 잘못되었습니다. 대비가 낮으면 필터 커널 크기를 줄이십시오. 기술적으로는 별칭이지만 보기에는 좋습니다. 추가적인 사후 선명화 필터를 추가할 수 있습니다. Mitchell 4.0 필터는 1픽셀보다 큰 음의 로브 거리를 갖습니다.
흐린 재투영 확산: 왕복 오류 보상을 사용할 수 있지만 좋은 결과를 얻지 못하고 기록을 더 높은 해상도로 저장할 수 있지만 오버헤드가 많이 발생합니다. 외부 픽셀을 다시 투영할 때 필터 크기와 피드백을 줄입니다.
노이즈 필터링: 원래 목적이 아니며 부작용이 크며 SSR 및 SSAO에 사용됩니다. 무작위 샘플링은 추가 비용 없이 훌륭하게 작동하며 거의 완벽한 반사성, 단 16개의 광선 단계입니다.
더 많은 잠재적 응용 분야: 무작위 투명도, 단일 샘플 이방성 반사 IBL, 부드러운 그림자, 레이 캐스팅을 위한 단순화된 단계, 시차 폐색 매핑, 체적 조명, 경로 추적? 가상 현실?
향후 방향: 시공간 조합, 별도의 반투명도, 가시성 및 음영 처리 예제, 픽셀당 다양한 디더링, 사용자 정의 MSAA 샘플 배치, 보다 완벽한 모션 벡터, 반투명도, 모션 추정. 요약하자면, 시간적 슈퍼샘플링은 생산 준비가 완료된 고품질, 고성능이며 광범위한 지각 조정이 필요합니다. 자세한 내용은 7.4.5 TAA를 참조하세요.
Pixel Sync를 사용한 사실적인 클라우드 렌더링은 픽셀 동기화 기술을 사용하여 오류 클라우드를 효율적으로 시뮬레이션합니다. 구름을 시뮬레이션하는 데는 게시판, 레이 스테핑, 직접 볼륨 렌더링 등 세 가지 일반적인 기술이 있습니다. 각각에는 고유한 특성, 장점 및 단점이 있습니다. 입자 기반 방법의 제어를 레이마칭(Ray Marching) 및 슬라이싱 기술과 결합해 볼 수 있습니다. 주요 아이디어: 실제 3D 모양을 나타내는 체적 입자 사용, 물리적 기반 조명, 사전 계산 조명 및 기타 수량을 사용하여 런타임 시 비용이 많이 드는 계산 방지, 알파 블렌딩 대신 볼륨 인식 블렌딩 수행. 알고리즘 단계:
- 초기 단계. 구형 입자를 사용하여 구름을 모델링합니다.

미리 계산된 구름 밀도와 투명도를 추가합니다.
미리 계산된 광산란을 추가합니다.
광원 폐색을 증가시킵니다.
볼륨 인식 블렌딩이 추가되었습니다(픽셀 동기화를 통해 활성화됨).
빛 산란을 증가시킵니다.
미리 계산된 조명: 주요 아이디어는 단순한 모양에 대해 물리적 기반 조명을 미리 계산하여 이러한 단순한 모양으로 구름을 만드는 것입니다. 이제 입자라는 단어는 이러한 기본 모양(개별 작은 물방울이 아님)을 나타냅니다. 그런 다음 광학 깊이, 산란을 미리 계산한 다음 구름을 결합하고 빛 폐색을 계산하고 볼륨 인식 혼합을 추가합니다.

왼쪽: 전통적인 알파 블렌딩; 오른쪽: 볼륨 인식 블렌딩.
볼륨 인식 하이브리드 알고리즘의 세부 내용은 다음과 같습니다.


DirectX는 픽셀 셰이더 실행에 어떤 순서도 적용하지 않으며 순서는 출력 병합 단계 후반에 발생하며 두 스레드가 동일한 메모리를 읽고 수정하는 경우 결과를 예측할 수 없습니다. 픽셀 셰이더 순서는 다음을 보장합니다. 읽기, 수정 및 쓰기 작업이 보호됩니다. 즉, 다른 스레드가 메모리에 쓰기를 완료할 때까지 어떤 스레드도 메모리를 읽을 수 없습니다. 모든 메모리 액세스 작업은 렌더링을 위해 프리미티브가 제출되는 것과 동일한 순서로 발생합니다.

픽셀 동기화 전(위)과 후(아래) 비교.
// Enabling pixel shader ordering
#include "IntelExtensions.hlsl"
...
void YourPixelShader(...)
{
IntelExt_Init();
...
// 픽셀(Pixel)동기화 함수
IntelExt_BeginPixelShaderOrdering();
// Access UAV
}성능을 향상시키기 위해 입자는 저해상도 버퍼로 렌더링된 다음 양측 필터링을 수행하여 원래 해상도를 높이고 가장자리를 유지합니다. 입자는 카메라 중앙에 있는 그리드, 동심원 링을 사용하여 생성됩니다. 다음 고리의 입자는 내부 고리 크기의 두 배입니다. 각 셀에는 여러 층의 입자가 포함되어 있습니다. 각 셀의 입자 밀도와 크기는 노이즈 텍스처에 의해 결정됩니다.

입자 렌더링:
입자 분류. 파티클은 뒤에서 앞으로 순서로 렌더링되어야 하며, GPU에서 정렬하는 것은 매우 비용이 많이 들고, 셀은 CPU에서 정렬될 수 있으며 모든 셀에 실제 파티클이 포함되어 있는 것은 아닙니다. 해결 방법: 유효한 셀에 대해서만 입자를 출력하고, "흐름"을 사용하여 순서를 유지하고, 하나의 GS 스레드를 통해 32개의 입자를 처리합니다.
입자 처리. DispatchIndirect()를 사용하여 CS를 수행하여 각 유효 입자의 불투명도를 계산하고 DispatchIndirect()를 사용하여 CS를 수행하여 각 유효 입자의 가시성을 계산합니다.
광산란 기술과 통합: 광선을 기반으로 구름 밀도 텍스처가 렌더링됩니다. 광선 이동의 각 단계에서 점이 구름 위 또는 아래에 있는지 여부가 결정됩니다(구름의 높이가 일정하다고 가정). 점이 구름 아래에 있는 경우 구름의 폐색을 얻기 위해 구름 밀도 텍스처를 샘플링합니다. 화면 공간에서는 구름 투명도와 구름으로부터의 거리를 사용하여 시선을 따라 산란을 약화시킵니다.

Kingdom Come: Deliverance의 적응형 의류 시스템에는 적응형 의류 시스템이 포함됩니다. 의류 시뮬레이션에 대한 가능한 접근 방식: 모든 품목 유형에 대해 동일한 모양/메시, 메시 간 큰(안전한) 거리, 모든 조합의 수동 조정 및 하이브리드 방법. 기사의 접근 방식은 각각의 새 의상에 대한 추가 아티스트 입력 없이 매우 현실적입니다. 옷의 다층 소재를 구현하기 위해 투광 기술이 사용됩니다. 프로세스는 다음과 같습니다.
- 각 삼각형 메쉬 쌍에 대해:
각 삼각형에 대해 다음을 수행합니다.
N개의 무작위 샘플(중심 좌표)을 선택합니다. (아래 그림 a)
N개의 광선을 추적합니다. (아래 사진b)
교차점을 버텍스 가중치로 변환합니다. (아래 c)

효과는 다음과 같습니다.

Hitman의 사운드 전파는 사운드 전파 시스템을 구현하기 위한 Hitman의 음파 모델링 사용을 공유합니다.

사운드 시스템에는 전파 기하학, 폐색, 전파 경로, 차단 등의 내용과 시뮬레이션이 포함됩니다.

왼쪽부터 오른쪽으로: 전파 기하학, 전파 계산, 전파 경로.
통합 원격 측정, 게임 개발에서 빅 데이터를 위한 인프라 구축에서는 성능, 스파이크 감지, 로드 시간, 시작 시간, 컴파일 시간, 로그, 메모리 추적, 버퍼/풀 크기 추적, 사용된 자산/현지화 추적, 네트워크 복제 디버깅, 대역폭/지연 시간 측정 등 게임의 모든 측면에서 성능 감지 및 분석 통계를 위한 원격 측정 사용에 대해 설명합니다.
이 문서에 정의된 원격 측정은 측정값 및 기타 데이터를 원격 또는 액세스할 수 없는 지점에서 수집하고 모니터링을 위해 수신 장치로 전송하는 고도로 자동화된 통신 프로세스입니다. 적용 사례: 통계 데이터 수집, 이벤트, 상태 스냅샷, 현장 디버깅. 비통합 원격 측정 데이터와 통합 원격 측정 데이터의 프로세스는 다음과 같습니다.


이점은 더 간단한 도구, 교차 도메인 분석, 비통계 데이터에 대한 팀 전체 분석 및 더 쉬운 협업입니다.
Quick and Dirty: 2 경량 AI 아키텍처는 경량 AI 아키텍처를 설명합니다. AI 디자인의 목표는 인공 지능을 너무 많이 요구하는 것이 아니라 레벨 성공/실패, 사운드 이벤트, UI 작업, 특수 효과 등 이벤트를 트리거하는 방법입니다. 신속한 개발과 반복이 중요합니다! 단기적인 확장, 실험적인 게임 디자인.
트리거는 다음으로 구성됩니다: 여러 절이 될 수 있고 함께 사용할 수 있는 단일 부울 트리거 조건, 작업 목록 부울 절이 true가 되면 트리거가 실행되고, 트리거가 실행되면 각 작업이 순서대로 실행됩니다. 또한 이벤트 기반(대부분의 아키텍처와 달리)이며 폴링 또는 업데이트 주기가 없습니다(대부분).
## Play a hint after 20 seconds, but only once
playHint_1_8_moveCamera:
triggerCondition:
- and:
- delay:
- 20
- doOnce:
actions:
- playSound:
- ALVO36_Rover모듈식 설계, 절은 이벤트 핸들러, 이벤트 지속성, 타이밍 임계값(기본값: 667ms), 트리거된 경우 재설정 또는 시나리오 재설정(성공 또는 실패)입니다. 트리거 그룹은 트리거 조건을 신중하게 설계하고 모든 사람에게 (고정된) 우선순위를 부여하고 가장 높은 것을 취합니다. 전역 트리거(예: 충돌 실패, 프로그램 완료 실패), 레벨 초기화 => 일련의 작업. 아래 그림은 보다 복잡한 트리거 사례입니다.

Frostbite의 물리 기반 및 통합 체적 렌더링에서는 시각적 품질을 향상시키고 아트 방향을 더 자유롭게 만드는 Frostbite 엔진의 체적 렌더링 기술, 더 많은 물리적 볼륨 렌더링(의미 있는 재료 매개변수, 조명에서 재료 분리, 일관된 결과), 통합 체적 상호 작용, 결합된 조명, 일반 그림자 및 체적 그림자, 불투명도, 투명도 및 입자와 상호 작용할 수 있습니다.
볼륨을 렌더링할 때 Frostbite는 단일 산란으로 제한됩니다. 빛이 표면과 상호 작용할 때 카메라에 반사되는 빛의 양은 다음과 같은 방법으로 평가할 수 있습니다. BRDF이지만 파라메트릭 미디어가 있으면 상황이 더욱 복잡해지며 전송을 고려해야 합니다. 그런 다음 산란된 빛은 여러 샘플을 채취하여 뷰 광선을 따라 통합되어야 합니다. 또한 각 지점에서 관측점까지의 투과율을 고려하고 위상 함수, 일반 그림자 맵(불투명 개체의 경우) 및 체적 그림자 맵(참여 미디어 및 기타 체적 엔터티의 경우)을 고려하여 각 위치에서 산란된 빛을 통합해야 합니다.

Frostbite는 클립 공간 볼륨을 사용합니다: 프러스텀 정렬 3D 텍스처 [Wronski14], 월드 공간의 프러스텀 복셀 => Froxel. Frostbite는 타일 기반 디퍼드 라이팅으로, 컬링된 라이트 목록이 있는 16x16 블록입니다. 조명 타일의 볼륨 타일을 정렬하고 각 타일에 대해 선별된 조명 목록을 재사용합니다. 볼륨 타일은 더 작을 수 있습니다(8x8, 4x4 등). 해상도 정수 분할을 주의 깊게 수정합니다. 기본값: 8x8 볼륨 블록, 64 깊이 슬라이스.

데이터 흐름은 아래와 같습니다. 클립 공간 볼륨은 파이프라인의 여러 단계에서 데이터를 저장하는 데 사용됩니다. 머티리얼 속성은 먼저 미디어에 참여하는 엔터티로부터 복셀화됩니다. 그런 다음 장면의 광원과 이 재질 속성 볼륨을 사용하여 픽셀당 산란광 데이터를 생성할 수 있으며, 이는 일시적으로 업샘플링되어 품질을 향상시킬 수 있습니다. 마지막 단계는 렌더링할 데이터를 준비하는 통합 단계입니다.

이러한 종류의 볼륨 렌더링은 여러 개의 평행 조명과 점 광원을 결합할 수 있으며 최종 렌더링 효과는 다음과 같습니다.

입자 볼륨 음영 처리 및 다양한 샘플링 방법도 지원됩니다.

Horizon Zero Dawn의 실시간 체적 구름 풍경은 Horizon Zero Dawn 게임의 영화 및 TV 수준의 체적 렌더링과 구름 풍경을 설명합니다. Horizon의 세계는 열려 있고 플레이어는 먼 거리를 여행할 수 있으며 낮과 밤의 주기, 역동적인 날씨를 지원하고 산, 숲, 호수의 장엄한 풍경을 가지고 있으며 하늘도 풍경의 일부입니다.

이 기사에서는 모델링, 조명, 렌더링 및 최적화와 같은 측면에서 볼륨 클라우드 환경을 자세히 설명합니다. 모델링 시 다양한 구름 모양과 다양한 높이가 고려되었습니다.

좀 더 자세히 설명하면, 많은 실제 변수가 고려됩니다. 즉, 낮은 온도에서는 밀도가 증가하고, 고도에 따라 온도는 감소하며, 높은 밀도는 비나 눈으로 정착되고, 풍향은 고도에 따라 변하며, 지구에서 나오는 열로 인해 상승하고, 조밀한 영역이 상승하면서 원을 형성하고, 빛의 영역이 안개처럼 퍼지고, 대기 난류로 인해 구름이 더욱 왜곡됩니다. 모델링의 기술적 포인트에는 프랙탈 브라운 운동, 계층화된 베를린 주파수, 높이 변위, 프로그래밍된 구름, 아름다운 위스키 모양 등이 포함됩니다. 동적 노이즈 결과를 생성하기 위해 2개의 3D 텍스처와 1개의 2D 텍스처를 사용하는 등 다양한 노이즈 생성 기술이 시도되었습니다. 레이 스테퍼/샘플러를 사용하여 만든 사용자 정의 노이즈, 2가지 세부 수준(저주파 기본 구름 모양, 고주파 세부 정보 및 교란), Perlin, Worley 및 Curl 노이즈, 높이 신호 및 적용 범위 신호로 변조된 밀도, 날씨 시뮬레이션/사용자 입력에 의해 구동, 애니메이션 포함.
조명 모델은 외부 산란, 흡수, 내부 산란 등을 고려합니다.

사용된 조명 모델과 곡선은 다음과 같습니다.


렌더링하는 동안 주변 색상 기여는 높이를 추가하고, 직접 조명 색상 기여는 태양에서 나오며, 대기는 구름 깊이를 차단합니다. 샘플러는 클라우드에 있지 않는 한 단계당 64-128개의 단계 샘플, 6개의 조명 샘플, 특정 깊이에서 전체에서 낮은 오버헤드로 이동하는 조명 샘플을 사용하여 저렴한 작업을 수행합니다.
실시간 볼륨 렌더링을 위한 샘플링 방법에서도 볼륨 렌더링에 대해 설명하지만 초점은 샘플의 레이아웃과 이동을 제어하여 변동성을 크게 줄이는 샘플링 방법에 있습니다. 또한 근거리 품질을 유지하면서 다양한 효과를 렌더링하기 위해 샘플링 깊이를 조정하는 방법도 설명합니다. 아래의 샘플링 방식으로 전환하면 회전이나 스위핑 문제를 해결할 수 있습니다. 동적으로 조정할 수 있지만 곡률을 변경하면 샘플이 이동합니다. 두 구성 사이를 수정하면 작동할 수 있습니다.

수평 대류는 구별됩니다.

적응형 샘플링이 샘플링되었습니다.

최종 효과는 점프와 같은 아티팩트 없이 모든 카메라 움직임과 잘 일치할 수 있습니다.

Stochastic Screen-Space Reflections는 Frostbite 엔진의 무작위 래스터라이제이션된 반사 효과를 보여줍니다. 반사 효과에 대한 Frostbite의 요구 사항은 명확하고 흐릿한 반사, 접촉 경화, 스페큘러 반사 신장, 픽셀별 러프니스 및 법선입니다.

Frostbite의 접근 방식은 중요한 방향에서 표면을 샘플링하는 것부터 시작하지만 매우 적은 수의 광선만 방출합니다. 심지어 픽셀당 하나의 낮은 광선도 방출합니다.

가장 큰 차이점은 색상을 즉시 반환하는 대신 교차점이 거의 저장되지 않는다는 것입니다. 그런 다음 인접한 픽셀에서 이러한 교차점을 재사용하는 구문 분석 프로세스가 있습니다.

재사용하는 동안 대략적인 원뿔 맞춤을 사용하고 반사 거리를 고려하여 각 샘플에 대해 필요한 흐림 수준이 계산됩니다. 각 픽셀의 BRDF의 기여도를 신중하게 평가하여 노멀 번짐, 과도한 흐림 및 선명한 접점이 보존됩니다.

SSR의 알고리즘 흐름은 다음과 같습니다.

계층적 깊이 추적은 레이 트레이싱, 즉 최소 Z 피라미드의 스택 없는 광선 스테핑에 사용됩니다.

mip = 0;
while (level > -1)
step through current cell;
if (above Z plane) ++level;
if (below Z plane) --level;광선 재사용: 인접한 픽셀은 가시성이 다를 수 있는 유용한 광선을 방출하며 교차점 결과를 재사용하기 위해 동일한 것으로 가정할 수 있습니다.

로컬 BRDF를 원본 PDF로 나누고 레이 트레이싱 및 라이프 포인트로 반환된 가중치로 사용하면 이웃은 BRDF/PDF 비율이 급증하고 재사용하지 않는 것보다 더 나쁜 결과와 함께 크게 다른 속성을 가질 수 있습니다.

왼쪽: 1픽셀당 광선 1개 및 분석 샘플 1개(재사용 없음); 오른쪽: 1픽셀에 대한 1개의 광선과 4개의 분석 샘플(1개의 광선이 4픽셀에 재사용됨).
또한 분산을 줄이기 위해 Monte Carlo가 개선되었습니다.

R9.png)
그 중에는:
분자는 BRDF 가중치 이미지 기여도입니다.
분모는 BRDF 가중치의 정규화입니다.
FG는 사전 통합된 BRDF입니다.
의사코드:
result = 0.0
weightSum = 0.0
for pixel in neighborhood:
weight = localBrdf(pixel.hit) / pixel.hitPdf
result += color(pixel.hit) * weight
weightSum += weight
result /= weightSum다양한 매개변수의 효과는 다음과 같습니다.

희소 레이 트레이싱: 감소된 해상도 레이 트레이싱, 전체 해상도에서 여러 광선 재사용, 각 픽셀에는 BRDF에서 자동으로 파생되는 고유한 광선 혼합이 있으며, 픽셀당 노멀 및 거칠기를 보존하고, 가중치 정규화가 격차를 해소합니다.
시간적 재투영: G 버퍼 깊이를 따라 "스미어" 재투영하여 반사 깊이, 로컬 광선 평균, 적절한 반사 시차를 추가합니다.

14.4.4 렌더링 기술
14.4.4.1 추론된 조명
**IL(Inferred Lighting)**은 지연 조명의 변형으로 **Light Pre-Pass Rendering(Light Pre-Pass Rendering)**이라고도 합니다. 장면의 복잡성으로부터 조명을 분리하는 것은 손상을 처리하는 데 중요합니다. 추론 조명 = 라이트 프리패스++, 조정 가능한 조명 해상도, MSAA 지원, 알파 조명. 추론 조명에는 3개의 채널이 있습니다.
**1. 기하학적 채널.**조명에 필요한 GBuffer를 준비하세요.

Red Faction의 GBuffer 레이아웃은 다음과 같습니다:

GBuffer에는 일반(23bit), 스페큘러 반사 지수(7bit), 조명 유형(2bit)이 포함되어 있음을 알 수 있습니다.
**2. 조명 채널.**조명을 계산하세요.
각 가시 광원을 반복하고 장면에 대한 해당 광원의 기여도를 계산하고, 모든 광원의 기여도를 누적하고, 결과를 L-버퍼(조명 버퍼)라는 텍스처에 저장합니다.

조명을 계산하는 데 필요한 모든 정보는 광원과 G-버퍼에서 나옵니다.
조명 정보는 L-Buffer(64비트 HDR 텍스처, 아래 그림 참조)에 저장되고, Diffuse 성분은 RGB 채널에 저장되며, Specular 성분은 Full Color가 아닌 밝기 값으로 저장되며 밝기는 색상처럼 누적될 수 있습니다.

전체 RGB 반사 조명 색상이 필요한 경우 확산 조명 색상을 가져와서 사양에 대해 저장된 밝기로 크기 조정하면 실제 반사 조명 구성 요소에 허용 가능한 근사치가 제공됩니다.
**3. 자료 채널.**조명을 사용하세요.
L-버퍼의 조명 정보를 각 개체에 대해 정의된 나머지 재료(질감, 개체 색상, 반사, 방출 재료, 거리 안개, 톤매핑 등)와 결합하여 각 픽셀에 대한 최종 출력 색상을 최종 장면 출력으로 생성하는 재료 채널 셰이더를 사용하여 보이는 개체를 반복하고 다시 그립니다.

위는 조명을 추론하는 일반적인 과정이다. 다음으로 Red Faction의 차별화된 구현을 보여드리겠습니다. 이러한 머티리얼 채널 셰이더의 L-버퍼에서 조명을 합성하는 방법부터 시작해 보겠습니다.
조명을 합성할 때 간단한 일반 조명 프리패스 시스템 접근 방식은 픽셀이 G/L/M 채널 간에 완전히 일치하는 것입니다.

추론된 조명을 사용하면 형상/조명 패스가 머티리얼 패스보다 낮은 해상도를 사용할 수 있으므로 조명 해상도를 위아래로 조정하여 시각적 품질과 성능을 절충할 수 있습니다. 그러나 이 경우 L-Buffer 값을 직접 사용하려고 하면 처참하게 실패하게 됩니다. 낮은 해상도의 L-버퍼를 샘플링하면 모든 가장자리에서 값이 혼합되어 가벼운 번짐과 아티팩트가 발생합니다.

이 문제를 해결하는 방법을 이해하기 위해 특정 픽셀에서 정확히 무슨 일이 일어나고 있는지 살펴보겠습니다. 각 픽셀을 정사각형 색상 영역이 아닌 수학적 점으로 생각하면 수학을 이해하기가 더 쉽습니다.

저해상도 조명을 샘플링했습니다.
아래 이미지와 결합하면 색상이 지정되는 픽셀은 위쪽 개체(아래 이미지 왼쪽의 노란색)에 속하며, 이 4개의 조명 샘플(아래 이미지 중간)을 혼합하면 4개 샘플 중 3개가 아래쪽 개체에서 나오며 이는 최종 색상(아래 이미지 오른쪽)의 거의 80%입니다! 이 가장자리를 감지하고 수정할 수 있다면 어떨까요?

DSF(Discontinuity-Sensitive Filtering)를 사용하면 세 번째 G-버퍼를 사용하여 가장자리를 보존하면서 L-버퍼의 크기를 조정할 수 있습니다. DSF 데이터는 16비트 값입니다(8비트는 게임에서 할당한 개체 ID를 저장하고, 8비트는 그리드 데이터에 저장된 일반 그룹 ID를 저장합니다).

G-버퍼: DSF 데이터.
DSF의 프로세스는 다음과 같습니다.
머티리얼 채널 셰이더 내에서 현재 이 픽셀에서 어떤 객체를 그리고 있는지 알 수 있습니다. (왼쪽 아래 사진)
DSF ID 4개를 각각 비교하면 DSF는 L-Buffer 1:1로 매칭됩니다. (아래 사진)
DSF ID가 일치하지 않는 경우: 블렌딩 가중치를 0.0으로 설정하고 DO 일치 샘플을 조정하여 최대 1.0을 추가합니다. (아래 오른쪽 사진)

아래 사진의 윗줄은 DSF가 없고, 아랫줄은 DSF가 있습니다. 첫 번째 열의 대각선 가장자리와 통풍구 윤곽선 주변의 "계단" 아티팩트가 줄어들고, 두 번째 및 세 번째 열의 후드 및 덕트 가장자리 주변의 덩어리진 밝은 픽셀이 제거됩니다.

위 버전은 잘 작동하지만 셰이더에서 가중치 합계를 계산하는 8개의 텍스처 조회(4 DSF, 4 조명)로 인해 느릴 수 있습니다. 최적화: 대신 샘플 UV를 조정하고 조명 샘플이 하나만 있으면 하드웨어가 블렌딩을 수행합니다.

DSF 최적화 프로세스. 그림의 위쪽 두 샘플에는 일치하는 DSF ID가 있는 반면 아래쪽 두 샘플은 일치하지 않습니다. 이 경우 UV를 수직으로 조정하여 아래쪽 두 샘플을 혼합에서 제거할 수 있습니다. 일치하는 샘플의 패턴에 따라 UV는 이러한 방식으로 수직, 수평, 둘 다 또는 둘 다 조정될 수 있습니다.
DSF는 하드웨어 앤티앨리어싱(MSAA)뿐만 아니라 조명의 품질과 속도에 대한 더 강력한 제어 기능을 제공합니다. 하드웨어로 관리되는 픽셀당 여러 하위 샘플. LPP(Light Pre-Pass)는 MSAA, 하나의 조명 샘플 및 픽셀당 여러 하위 샘플을 처리하는 데 적합하지 않습니다. DSF를 사용하면 IL은 MSAA를 무료로 처리할 수 있습니다!
추론 조명은 투명도를 지원할 수 있지만 MSAA와 비슷한 문제가 있습니다. 즉, 픽셀당 L 버퍼 샘플이 하나만 있습니다. DSF ID가 다른 픽셀은 조명을 계산할 때 "숨겨지고" 무시될 수 있습니다. 이 사실을 활용하세요!
화면을 2x2 픽셀 블록(각 블록에 하나의 픽셀(알파))으로 나누고, 알파 픽셀은 서로 다른 DSF ID를 가지며, 불투명 재질은 자동으로 이러한 조명 샘플을 선별합니다.

Alpha는 L 버퍼의 각 2x2 블록을 하나의 단위로 처리하는 수정된 DSF를 사용하므로 하드웨어 필터링 최적화는 여기서 작동하지 않습니다.

서로 다른 블록 픽셀을 사용하면 최대 4개의 레이어가 가능합니다.

IL 투명 렌더링 효과는 다음과 같습니다.

불연속성 요약, MSAA 지원, 반투명도, 저해상도 조명을 지원하지 않습니다. 기본 아이디어: DSF ID가 해당 픽셀과 일치하는지 확인합니다. 그렇다면 완료된 것입니다. 일치하는 항목이 없으면 일치하는 이웃을 찾을 때까지 이웃을 확인합니다. 일반적으로 최대 4개의 이웃이 있습니다.

IL의 제한 사항과 문제는 다음과 같습니다.
알파 객체의 저해상도 조명. 가능한 경우 고주파 법선을 피하면서 불투명 조명의 전체 해상도를 1/4로 늘립니다.
헤어는 IL이 잘 못하는 부분이므로 헤어에 사용하는 것은 피해야 합니다!
알파 레이어링. 추가 레이어는 불투명한 조명의 품질을 저하시키며 충돌을 피하기 위해 레이어를 할당하는 것은 어렵습니다! 본질적으로 그래픽 셰이딩 문제인 RF:A는 알파 조명의 한 레이어만 사용합니다.
입자. 파티클은 제한된 알파 조명 레이어에서는 작동하지 않으며 파티클에서 조명이 가짜일 수 있습니다.
DSF는 표준 조명 사전 렌더링 패스 비용을 증가시킵니다. 조명 해상도를 낮추면 균형을 맞추는 데 도움이 되며, 불연속성 패치는 더 저렴한 옵션일 수 있습니다. RF:A는 다양한 해상도의 패치를 사용합니다. Xbox/PS3: 960x540, PC: 하드웨어 제한에 도달하고, SR3는 전체 DSF를 사용합니다: 1280x720 장면, 800x450 조명, 반투명 조명의 4개 레이어도 모두 사용합니다.
1년 후, 조명 및 단순화 Saints Row: The Third는 추론 조명의 최신 반복을 공유하고 몇 가지 새로운 최적화 및 기능을 추가합니다.
원본 추론 조명은 다양한 완전 동적 조명, 통합 알파 조명(포워드 렌더링 없음), 하드웨어 MSAA 지원(DX9에서도)을 지원합니다. 이를 바탕으로 이 문서에서는 빗방울 조명(IL 필요), 향상된 나뭇잎 지원(IL만 해당), 화면 공간 데칼(IL로 향상) 및 방사형 앰비언트 오클루전(AO)(RAO)(IL로 최적화)을 추가합니다.
빗방울 조명: 각 빗방울의 개별 픽셀을 GBuffer로 렌더링합니다. 조명 채널은 빗방울을 무료로 비춥니다. DSF는 빗방울 샘플을 자동으로 무시합니다. 빗방울은 조명 샘플을 찾습니다.
초목: 추론 조명은 DSF 비용을 제한하기 위해 장면 깊이 복잡성이 낮다고 가정합니다. 초목은 이 가정을 깨뜨립니다. 더 빠른 식생 DSF:

PS3 장면의 전체 DSF, GPU 시간: 35.7ms, 2개 샘플은 33.7ms(2ms 절약)입니다.
동적 데칼: 화면 공간 데칼은 DSF ID를 사용하여 데칼을 특정 개체로 제한하는 화면 공간에 적용되는 체적 데칼입니다. 기존 DSF ID는 잘못된 라벨링을 방지하기 위해 데칼 판별자로 사용됩니다.

화면 공간 데칼. 잘못된 데칼은 왼쪽에 있고 오른쪽의 기존 DSF ID를 사용하여 수정되었습니다.
방사형 앰비언트 오클루전(AO)(RAO): [Shanmugam & Arikan 2007]을 대략적으로 기반으로 하는 폐색 요소는 일반 광원과 마찬가지로 상자 또는 타원체까지의 거리와 법선을 기반으로 합니다. 폐색 인자는 조명을 조절하는 데 사용됩니다. 차량의 경우 작가는 몸체 가까이에 상자를 배치하고, 인간의 경우 타원체는 자동으로 발 아래에 배치됩니다.

RAO 효과 비교. 왼쪽에는 있고 오른쪽에는 없습니다.
14.4.4.2 GPU 기반 렌더링 파이프라인
GPU 기반 렌더링 파이프라인은 Ubisoft Montreal의 Ulrich Haar와 다른 사람들이 발표했으며, GPU 드라이버를 기반으로 한 새로운 렌더링 파이프라인과 Assassin's Creed의 응용 프로그램을 설명하여 Assassin's Creed의 장면 복잡성을 기하급수적으로 증가시켰습니다.

GPU 기반 렌더링 파이프라인에는 클러스터링, 즉 그리드 선을 클러스터로 분할하는 사용이 필요합니다. 클러스터에는 고정 토폴로지(64개 버텍스 스트립)가 있으며 고정 토폴로지에 맞게 모든 메시를 분할 및 재배열하고(변형 삼각형 삽입) 공유 버퍼에서 VS의 정점을 수동으로 검색하고 비직접 드로잉 인터페이스 DrawInstancedIndirect를 인스턴스화하며 GPU가 출력 클러스터 목록 및 드로잉 매개변수를 선별합니다.

단일 드로우콜의 메시 수 제한, 클러스터 경계에 따른 GPU 컬링, 더 빠른 버텍스 추출, 클러스터 깊이 정렬.
GPU 기반 렌더링 파이프라인의 개요는 다음과 같습니다.

CPU 측에서는 여전히 매우 거친 프러스텀 컬링이 수행되고 컬링되지 않은 모든 객체는 재질별로 함께 패킹됩니다. GPU에서는 인스턴스별 프러스텀 및 오클루전 컬링으로 시작한 다음 프러스텀 및 폐색 깊이를 기반으로 클러스터를 컬링하기 전에 클러스터 확장 단계를 수행합니다. 그런 다음 인덱스 버퍼가 압축됩니다. 압축 과정에서 일부 뒷삼각형이 제거되고 압축 결과가 멀티 드로우콜에 제공됩니다. 변형된 모든 개체는 파이프라인의 클러스터별 부분을 우회합니다.
CPU 쿼드트리 컬링, 변환, LOD 요소 등을 포함한 각 인스턴스의 데이터, GPU 링 버퍼에서 업데이트, 정적 인스턴스의 지속성. 재료, 렌더링 상태 등과 같은 비인스턴스 데이터를 기반으로 하는 Drawcall 해시 구성, 해시 기반 Drawcall 병합.

인스턴스 스트림에는 GPU 버퍼의 각 인스턴스에 대한 오프셋 목록이 포함되어 있어 GPU가 변환, 경계, 메시 등과 같은 정보에 액세스할 수 있습니다.

그런 다음 GPU는 이 정보를 사용하여 인스턴스 스트림을 프러스텀화하고 선별합니다. 컬링을 통과한 모든 인스턴스에 대해 클러스터 청크 목록이 방출됩니다.

(직접 클러스터 확장이 아닌) 클러스터 블록 확장의 중간 단계를 사용하면 그리드당 클러스터 수가 크게 다르기 때문에(1-1000), 즉석 클러스터 내보내기는 클러스터 블록당 최대 64개의 클러스터를 내보낼 수 있어 웨이브프론트 내의 GPU 스레드 간에 매우 불균형한 경우가 많습니다.

그런 다음 클러스터 컬링 단계에서는 인스턴스 변환과 각 클러스터의 경계를 사용하여 프러스텀 및 폐색을 기반으로 클러스터를 컬링합니다. 각 클러스터에 대해 미리 구운 삼각형 뒷면 컬링을 위한 뷰 종속 삼각형 마스크도 얻습니다. 선별된 클러스터를 사용하면 관련 인스턴스 드로우 콜 기본 번호에 대한 원자 연산을 수행하여 결정되는 삼각형 마스크와 인덱스 읽기 및 쓰기 오프셋으로 구성된 인덱스 압축 작업이 파생됩니다.

다음으로, 채워지지 않은 모든 클러스터의 인덱스 압축이 동적 인덱스 버퍼에서 발생합니다. 압축된 인덱스 버퍼의 공간은 CPU에 할당되므로 각 그리드 인스턴스에는 인덱스의 전체(채워지지 않은) 양을 할당해야 합니다. 압축된 인덱스 버퍼는 매우 작기 때문에(8mb) 하나의 렌더링 패스가 버퍼에 완전히 들어갈 수 없음을 의미하므로 인덱스 버퍼 압축과 멀티 드로우 렌더링이 인터리브될 수 있도록 큰 프로세스가 분할됩니다.

이 시점에서 인덱스 압축은 클러스터별 선별 및 삼각형 면 선별로 선별된 삼각형을 제거합니다. 각 인덱스 압축 계산 작업에서 하나의 웨이브프런트는 하나의 클러스터를 처리하고 각 스레드는 다른 스레드 및 웨이브프런트와 완전히 독립적으로 하나의 삼각형을 처리합니다. 클러스터 컬링 단계에서 생성된 삼각형 마스크와 입/출력 오프셋을 기반으로 각 스레드는 동적 인덱스 버퍼에 대한 출력 쓰기 위치를 독립적으로 계산하고 3개의 삼각형 인덱스를 복사합니다. 이 단계에는 5%-10%의 형상 렌더링이 필요합니다.

그런 다음 MultiDrawIndexInstancedIndirect 호출을 배치별로 사용하여 클러스터 컬링 중 원자적 작업을 사용하여 생성된 드로우콜 그룹을 렌더링합니다.

정적 삼각형 뒷면 컬링: 클러스터 중심 큐브맵 픽셀 프러스텀의 구운 삼각형 가시성, 카메라 기반 큐브맵 조회, 클러스터의 모든 삼각형을 보기 위해 64비트 가져오기. 큐브맵 면당 하나의 픽셀만 있고(삼각형당 6비트) 픽셀 프러스텀는 컬링 효율성을 높이기 위해 먼 거리에서 절단되며(베벨 모서리는 거짓 긍정을 제공할 수 있음) 삼각형의 10-30%가 컬링됩니다.

오클루전 깊이 생성: 최적의 오클루전 볼륨을 사용한 깊이 프리패스, 전체 해상도에서 High-Z 및 Early-Z 렌더링, 512x256으로 다운샘플링, 마지막 프레임 깊이의 재투영, GPU 컬링을 위한 깊이 계층 구조와 결합됩니다.

그림자 폐색 깊이 생성: 각 캐스케이드에 대해 카메라 깊이 재투영(~70us), 그림자 깊이 재투영(10us), GPU 컬링을 위한 깊이 계층 구조(30us).

카메라 깊이 재투영 프로세스는 다음과 같습니다.

왼쪽 위: 노란색 화살표는 태양의 방향을 나타내고 빨간색 선은 그림자 맵 캐스케이드의 범위를 나타내며 빨간색 개체는 그림자 캐스터이며 가능한 모든 수신기가 땅과 파란색 개체에 숨겨져 있으므로 유효한 수신기를 가질 수 없습니다.
오른쪽 상단: 밝은 노란색 영역은 전경 개체에 의해 생성된 수평선을 표시하며, 그 아래에는 그림자 수신기가 표시되지 않습니다. 이 지평선보다 더 멀리 있는 모든 그림자 캐스터는 제거될 수 있습니다. 오클루전 컬링을 위해서는 조명 공간의 노란색 영역 상단에 있는 빨간색 선의 깊이(즉, 노란색 화살표 방향)를 계산해야 합니다.
왼쪽 아래: 근거리 평면에서 카메라 깊이 값까지 확장하여 카메라 깊이의 각 픽셀에 대해 큐브를 렌더링하면 이미지에 노란색 큐브가 표시됩니다.
오른쪽 하단: 이제 녹색 선이 보입니다. 이는 빛 공간에서 큐브의 최대 깊이 렌더링이며 앞서 언급한 빨간색 선과 동일합니다. 분명히 카메라 깊이 이미지의 모든 픽셀에 대해 하나의 큐브를 렌더링하려면 너무 많은 큐브가 필요합니다. 대신 카메라 깊이의 각 16x16 타일에 대해 큐브를 렌더링하고 각 타일의 최대 깊이를 사용하십시오. 그러면 녹색 선은 빨간색 선의 보수적인 근사값이 됩니다. 라이트 공간에서 큐브를 렌더링할 때 최소 합계 크기인 1픽셀로 채우고 최대 섀도우 필터 크기를 고려하는 것이 중요합니다. 투명한 그림자 수신기가 없는 경우 평면 근처의 카메라가 아니라 각 타일의 최소 깊이에서 큐브를 돌출시킬 수 있습니다. 이러한 조건에서는 최대 다운샘플링 중에 원거리 평면도 거부되어 큐브 렌더링이 더 조밀해질 수 있습니다. 큐브를 렌더링할 때 픽셀 셰이더에서 직접 깊이를 출력하고 텍스처 좌표 보간기를 사용하여 픽셀 깊이를 파생시키는 것이 중요합니다. 고정 함수 파이프라인에서 제공하는 깊이는 빛 방향과 거의 평행한 삼각형에 비해 너무 부정확합니다.

건물의 그림자를 재투영합니다.
카메라 깊이 재투영: [Silvennoine12]와 유사하지만 안개로 인해 마스크가 유효하지 않습니다. 최소 깊이를 사용할 수 없으며 원거리 평면을 제외할 수 없습니다. 오버드로를 제거하기 위해 깊이를 전처리할 수 있는 64x64 픽셀 재투영.
얻은 결과는 다음과 같습니다. CPU의 드로우 콜이 1~2배 감소했으며, 이전 세대 Assassin's Creed의 약 75%, 개체 수가 약 10배 감소했습니다. GPU에서 삼각형(뒷면 + 클러스터 경계)의 20-40%를 컬링하고 전체 이득은 작습니다: 지오메트리 렌더링의 <10%, 그림자 삼각형의 30-80% 컬링. 진행 중인 작업: 더 많은 GPU 기반 정적 개체, 더 많은 배치 친화적인 데이터. 향후 작업: 언바운드 텍스처, DX12 및 Vulkan 기반.
또한 이 기사에서는 GPU 기반 렌더링의 가상 텍스처, 가상 지연 텍스처, MSAA 기술, 2단계 오클루전 컬링, 가상 섀도우 매핑 및 기타 기술을 공유합니다.
가상 텍스처의 주요 아이디어: 눈에 보이는 텍스처 데이터만 메모리, 가상 256k x 256k 텍셀 아틀라스, 128 x 128 텍셀 페이지, 8k x 8k 텍스처 페이지 캐시, 5레이어 텍스처 배열: DXT 압축(BC5/BC3)을 사용하여 알베도, 스페큘러 반사, 러프니스, 노멀 등 유지합니다.
뷰포트 = 단일 그리기 호출(x2), 다양한 버텍스 애니메이션 유형에 대한 동적 분기, 최신 GPU는 빠르며(2% 더 많은 비용), 클러스터링된 깊이 정렬은 깊이 전처리에 유사한 이득을 제공하고, 역 정렬을 위한 저렴한 OIT를 제공합니다.
추가 VT 이점: 복잡한 재료 블렌딩 및 데칼 렌더링 결과는 VT 페이지 캐시에 저장되며, 데이터 재사용은 텍스처 해상도 및 리소스 수와 관계없이 수백 프레임, 일정한 메모리 공간에 대한 비용을 분산시킵니다.
가상 지연 텍스처링: 오래된 아이디어: 텍셀 대신 UV를 G 버퍼에 저장[Auf.07], 주요 기능: VT 페이지 캐시 아틀라스에는 현재 표시되는 모든 텍스처 데이터가 포함되어 있으며, 8k x 8k 텍스처 아틀라스의 16+16비트 UV는 8 x 8 하위 픽셀 필터링 정확도를 제공합니다.

그라데이션 및 탄젠트 좌표 시스템: 이웃의 UV 거리를 감지하는 데 사용되는 화면 공간의 픽셀 그라데이션을 계산하고, 이웃을 찾을 수 없는 경우 이중선형을 사용하고, 32비트 쿼터니언으로 저장된 탄젠트 좌표 시스템[Frykholm09], 암시적 밉 및 VT.Page = UV.xy/128의 재질 ID입니다.
검토 및 장점: 64비트, 전체 채우기 속도, MRT 없음. 오버드로 오버헤드는 매우 낮으며 텍스처는 조명 CS로 연기됩니다. 쿼드 효율성은 덜 중요하며 가상 텍스처 페이지 ID 채널은 더 이상 필요하지 않습니다. 그라디언트 재구성 데이터는 실제 사실과 매우 유사합니다.

MSAA 팁: 핵심 관찰은 UV와 접선을 보간할 수 있다는 것입니다. 정렬된 그리드 4xMSAA 모드를 사용하여 장면을 2x2(540p)의 낮은 해상도로 렌더링할 수 있습니다. Texture2DMS.Load()를 사용하여 조명 계산 셰이더에서 각 샘플을 개별적으로 읽습니다.

1080P 재구성: 1080p를 LDS로 재구성하고 가장자리 픽셀이 완벽하게 재구성되며 MSAA는 양쪽에 대해 픽셀 셰이더를 실행합니다. 내부 픽셀의 보간된 UV 및 탄젠트, 품질이 좋고 차이점을 발견하기 어렵습니다.
2단계 오클루전 컬링: 로우 폴리 프록시 지오메트리를 위한 추가 오클루전 패스 없음, 깊이 버퍼 데이터를 기반으로 하는 정확한 WYSIWYG(보이는 대로 표시됨) 오클루전, HTILE 최소/최대 버퍼에서 생성된 깊이 피라미드, O(1) 오클루전 테스트(gather4).

1단계: 마지막 프레임의 깊이 피라미드를 사용하여 객체와 클러스터를 선별하고 보이는 객체를 렌더링합니다.
2단계: 깊이 피라미드를 새로 고치고, 선별된 객체와 클러스터를 테스트하고, 위음성 객체를 렌더링합니다.

이 컬링 방법은 이전 단계에서 GPU가 생성한 데이터에 대한 낮은 지연 시간 액세스가 필요하므로 GPU 기반 렌더링 없이는 불가능합니다. CPU가 프레임 중간에 앞뒤로 실행되면 GPU가 심각하게 정지됩니다. 아래 그림은 1080p에서의 Xbox One 성능 데이터입니다.

가상 섀도우 매핑: 128k x 128k 가상 섀도우 맵, 256 x 256 텍셀 페이지, Z 버퍼에서 필요한 섀도우 페이지 식별, GPU 기반 파이프라인을 사용하여 섀도우 페이지 제거, 모든 페이지를 한 번에 렌더링.

VSM 품질 및 성능: 측정된 모든 영역에서 1:1 그림자-화면 해상도에 가깝습니다. 복잡한 "희소" 장면에서는 SDSM보다 3.5배 빠르며 간단한 장면에서는 SDSM 및 CSM보다 약간 느립니다.
또한 GPU 드라이버는 DX12와 같은 차세대 그래픽 API와 더욱 완벽하게 통합될 수 있습니다.

14.4.4.3 적응형 가상 텍스처
Far Cry 4의 적응형 가상 텍스처 렌더링은 가상 텍스처, 지형, 적응형 가상 텍스처, 렌더링 문제 등에 대한 개요를 포함하여 2015년 Far Cry 4에서 사용된 적응형 가상 텍스처 기술을 공유합니다.
가상 텍스처의 원리는 가상 메모리와 유사하지만 GPU에서 구현됩니다. 아래 그림과 결합하면 가상 텍스처는 매우 큰 크기의 텍스처를 표현할 수 있습니다. 텍스처 데이터가 필요한 경우, 실제 물리 페이지 캐시 데이터를 얻기 위해 간접 텍스처 정보를 쿼리하기 위해 가상 텍스처의 좌표를 제공해야 합니다.

게임의 가상 텍스처는 메가 텍스처 또는 절차적 가상 텍스처일 수 있습니다. Mega Texture는 Rage의 id 소프트웨어(Waveren 2013)에 의해 개발되었으며, 텍스처 데이터는 디스크에 저장되고 필요에 따라 메모리로 전송됩니다. 런타임은 필요한 타일(페이지)을 결정하여 디스크에서 요청하며, 타일은 타일 캐시(물리적 텍스처 캐시)에 로드되고 페이지 테이블(간접 텍스처)이 업데이트됩니다. 절차적 가상 텍스처는 DICE의 Frostbite 엔진(Widmark 2012)에서 사용됩니다. 이 엔진은 런타임 시 지형 렌더링을 가상 텍스처로 분해합니다. 고도로 압축된 가상 텍스처는 디스크에서 사용할 수 없으며 누락된 페이지가 있는 가상 텍스처로 직접 렌더링됩니다, 프레임 간 일관성을 활용하여 지형 렌더링 비용을 줄이고, 지형 렌더링을 위한 강력한 GPU 최적화를 수행합니다.
Far Cry 4의 프로그래밍된 가상 텍스처 매개변수는 아래 그림에 나와 있습니다. 거대한 가상 텍스처는 512k x 512k, 간접 텍스처는 2k x 2k, 물리적 텍스처는 9k x 9k입니다. 가상 텍스처와 간접 텍스처에는 11개의 밉 레벨이 있습니다.

간접 텍스처의 형식은 다음과 같습니다. 항목 좌표(x, y): 각 항목은 가상 페이지를 나타냅니다. 항목 좌표 = 가상 페이지 좌표 / 가상 페이지 크기. 항목 콘텐츠 형식은 32비트 정수입니다. 여기서 PageOffsetX = 물리적 페이지 U 좌표/물리적 페이지 크기, PageOffsetY = 물리적 페이지 V 좌표/물리적 페이지 크기, Mip: 이 페이지의 Mip 매핑 수준, 디버깅: 디버깅 전용(예: 프레임 수 저장).

기존 가상 텍스처를 사용하는 경우 512K x 512K 가상 텍스처에는 10 x 10km의 세계에서 1천만 x 1천만 개의 가상 텍스처가 필요합니다! 또 다른 새로운 기술이 시급히 필요합니다.

이 새로운 기술은 절차적 가상 텍스처를 기반으로 하는 적응형 가상 텍스처입니다. 10x10KM 세계는 64x64미터 영역(섹터)으로 나뉩니다. 가까운 지형 영역: 가상 이미지가 가상 텍스처에 할당됩니다. 더 가까운 영역: 64K x 64K(64K/64미터 = 10텍셀/cm)와 같은 더 큰 가상 이미지. 추가 영역: 32K x 32K, 16K x 16K,…,1K x 1K와 같은 더 작은 가상 이미지.
가상 텍스처는 가상 텍스처의 모든 닫힌 영역에 할당됩니다. 여기서 아래 그림의 빨간색 영역은 시각적 가상 텍스처의 좁은 영역에 대한 가상 텍스처 할당이며, 색상이 지정된 각 사각형은 각 인근 영역에 대한 가상 텍스처를 나타냅니다.

아래 그림의 빨간색 사각형 2개는 카메라에 가장 가까운 파티션의 가상 텍스처를 나타내며 64k x64k에 이릅니다. 노란색은 카메라에서 약간 더 멀리 떨어져 있습니다(32k x32k). 근처의 모든 파티션이 할당될 때까지 계속됩니다.

카메라가 닫힐 때 가상 텍스처 크기를 늘리면 아래 이미지가 32k x 32k에서 64k x 64k로 늘어납니다.

카메라가 멀리 있으면 작업을 반대로 수행합니다.

업스케일링 과정에서 더 큰 가상 이미지가 가상 텍스처에 할당되고 이전 이미지는 제거됩니다. 지형 재료는 이미 물리 텍스처 캐시에 캐시된 추가 데칼과 혼합되어 오프셋되어 재사용됩니다! mip 1부터 mip 10까지의 모든 페이지에 대해 이전 이미지의 간접 텍스처 항목을 새 이미지에 복사하고 1 mip씩 위쪽으로 오프셋합니다.

그런 다음 새 가상 이미지에 대한 간접 텍스처의 모든 mip 1 항목을 업데이트합니다.

mip 0 페이지는 이전 이미지에서 렌더링되지 않으므로 특별한 처리가 필요합니다.

4개의 mip 0 페이지에는 해당 mip 1 페이지가 있으며, 이는 일시적으로 하위 수준 mip 페이지에 매핑됩니다. 이 프레임에서는 이미지가 흐릿하게 나타나고 올바른 업데이트 후에는 더 선명해집니다. 새 가상 이미지의 mip 0에 있는 모든 페이지에 대해 다음을 수행하십시오.

또한 간접 텍스처의 mip 0 페이지를 업데이트하고 간접 텍스처 항목의 내용을 복사해야 합니다.

가상 이미지를 축소할 때 가상 텍스처에 더 작은 가상 이미지를 할당하고 이전 이미지를 제거하여 가상 이미지를 확대하는 단계를 반대로 수행합니다.
직면한 과제에는 가상 페이지 ID 버퍼의 메모리 사용량 감소, 각 프레임의 렌더링 소비 제한, 대규모 데칼 생성, 이방성 필터링 및 삼선형 필터링 지원이 포함됩니다. 구체적인 접근 계획은 원문을 참조하고 여기에서는 무시하세요. 최종 성능 및 효과는 다음과 같습니다.


14.4.4.4 부호 있는 거리 필드
부호 있는 디스턴스 필드를 사용한 동적 오클루전은 언리얼 엔진이 방향성 디스턴스 필드를 사용하여 앰비언트 오클루전(AO) 효과를 효율적이고 고품질로 생성하는 방법을 보여줍니다.
영역 그림자, 하늘 폐색, 반사 그림자에 대해 부드럽고 정확하며 개별적인 가시성 쿼리가 필요한 동적으로 제작된 게임 장면의 범용 폐색에 대한 좋은 솔루션은 없습니다. 솔루션: 동적 장면의 전역 조명에 대한 빠른 근사에서 영감을 받은 가벼운 스테핑을 위한 서명된 거리 필드. 2011년 초에 Samaritan 데모(Unreal Engine 3)에서는 반사된 그림자, 모놀리식 텍스처 및 정적 장면에 SDF(Directed Distance Field) 광선 이동을 사용했는데, 이는 고급 하드웨어가 필요했습니다.

픽셀당 원뿔이 교차하는 모든 물체를 따라 이동하는 동적 스카이 오클루전 품질의 초기 프로토타입은 27개의 원뿔을 사용하고 작은 장면에서 단 2FPS로 실행되었습니다. GDC 2015 카이트 기술 시연에서는 이러한 방법을 사용하여 거대한 세계를 완전하게 역동적으로 조명하려면 980 GTX가 필요했습니다.

SDF 음영처리를 껐을 때(왼쪽)와 켰을 때(오른쪽) 비교.
현재 Fortnite는 역동적인 시간을 지원하고, 이러한 조명 방법을 사용하고, 많은 플레이어 빌드로 레벨을 절차적으로 생성하기 위해 개발 중입니다. 모두 PlayStation 4 레벨 하드웨어를 지원합니다. SDF는 각 점에서 가장 가까운 표면까지의 거리를 저장하고, 내부 영역은 음수 거리(부호 있음)를 저장하며, d=0인 등가곡면(레벨 세트)은 표면입니다. 부호 있는 거리는 표면 전체에 걸쳐 선형으로 보간되므로 그리드에도 불구하고 모든 표면 방향을 정확하게 나타냅니다. 광선 교차는 표면까지의 거리를 기준으로 빈 공간을 건너뜁니다. 광선이 교차하면 광선이 가려집니다. 영역 음영을 얻기 위해 원뿔 교차점을 자유롭게 근사화합니다.

SDF와 복셀 비교: + 임의 방향의 표면을 동일하게 표현, + 선형 보간, + 더 높은 유효 해상도, + 자체 교차를 피하기 위해 바이어스 감소, + 추적 시 공백 건너뛰기, + 사전 필터링 없이 대략적인 원뿔 교차점. 복셀은 표면 위치와 법선만 나타내며 추적을 통해서만 가시성을 얻을 수 있습니다. 기본적으로 SDF는 볼륨이 아닌 표면 표현이며 입사 조명과 가시성을 분리할 수 있는 경우에만 사용할 수 있어 모든 방향에서 부드럽고 정확한 가시성 추적을 제공합니다!
장면 표현: 무차별 대입으로 삼각형 레이 트레이싱을 수행하고 메시 SDF를 오프라인으로 생성하며 fp16 볼륨 텍스처에 저장합니다.

카메라 광선을 추적하고 단계를 시각화하는 것이 가능합니다.

내부/외부는 후면 광선 히트에 의해 결정되며 닫는 메시는 필요하지 않습니다.

부분 지지된 부분 폐색 볼륨은 완전한 교차를 가져오지 않는 양면 표면으로 처리되며 잎사귀에 유용합니다. 그러나 레이 스테핑은 비용이 많이 듭니다.

인스턴스 지원: 동일한 SDF 데이터, 다양한 변환, 현재 구현에서 균일한 크기 조정만 가능, 자산 크기 조정에 따른 기본 해상도 할당.

각도는 해상도에 따라 둥글게 처리되며 얇은 표면은 뿌리를 찾는 데 필요한 조건인 내부 네거티브 텍스처로만 표현할 수 있습니다.

빛이 이동할 때 디스턴스 필드 텍스처는 전역 장면 액세스에 사용됩니다.
지형 높이 필드, 높이 필드에서 계산된 대략적인 원뿔 교차점, 고해상도 높이 맵 재사용, 개별 채널 조합 결과. 현재 표현은 균일하지 않게 크기가 조정된 메시, 스킨 처리/동적으로 변형된 메시, 대규모 유기적 메시/체적 지형을 제외한 많은 게임 장면을 처리합니다. 가능한 대체 기본 요소: 분석 거리 함수, 희소 체적 SDF?
직접적인 그림자에 대한 충분한 해상도! 구형 광원 모양을 가진 방사형 조명(영역 그림자)은 조명의 경계에 개체를 교차하도록 컬링한 다음 타일과 개체 경계를 포함하는 조명 원뿔에서 타일을 스크린합니다. 구형 광원 모양의 방사형 광원에 대한 의사 코드:
Foreach intersecting object
Foreach sample step
DistanceToSurface = Sample SDF
Track min visibility (DistanceToSurface / ConeRadius)
Step along ray toward light by abs(DistanceToSurface)
Terminate if inside or exceeded max step count
Shadow = 1 - MinVisibility직접 그림자: 원뿔 폐색 휴리스틱, 거리 표면/원뿔 반경 = 1d 교차점,

방향성 조명: 최대 보기 거리에서 교차하는 객체를 선별한 다음 동일한 추적 커널을 사용하여 조명 공간 그리드에 들어갑니다. 버텍스 애니메이션은 표현할 수 없으므로 계단식 그림자 맵을 명확한 위치에 사용해야 합니다.

왼쪽: CSM; 오른쪽: CSM+SDF.
삼각형 LOD(빌보드)가 SDF와 일치하지 않으면 보수적인 깊이 쓰기를 사용하십시오.

직접 그림자에 SDF를 사용하는 이유: 선명한 접촉이 있는 영역 그림자, 제어 가능한 자체 그림자 왜곡 - 월드 공간 바이어스, 그림자 맵 앨리어싱 없음, 삼각형 수 독립적 성능, 객체 밀도 및 해상도(채널 수)에 따라 다름, 상당히 쉽게 다운샘플링 가능, 넓은 시야 지원 - CPU 비용 없음, 삼각형 LOD의 효율성에 따라 기존 그림자 맵(큐브맵/CSM)보다 30-50% 빠릅니다.
하늘 폐색 문제: SSAO는 소규모 화면 공간 결함에만 적합하며 중간 거리 폐색(10미터), 얇은 벽이 있는 건물에 대한 일반적인 솔루션을 원합니다. 단일 SDF 원뿔 추적은 부드러울 수 있습니다.

여러 개의 원뿔(예: 9)이 반구(법선을 향한 반구)를 덮고 min()을 사용하여 여러 개체의 폐색을 처리하며 폐색 거리가 제한됩니다(기본값은 10미터).

최소 폐색(구부러진 노멀)의 원뿔을 생성하며, 다른 방향 폐색 표현도 가능합니다. SH 확산 조명은 채광창에 적용되며, 대략적인 원뿔/원추 교차점을 사용하여 하늘 반사 반사에도 적합합니다.
하늘 폐색 최적화: 개체는 화면 타일 경계까지 컬링하는 데 영향을 줍니다. 각 타일에는 두 개의 깊이 경계와 두 개의 컬링 목록이 있으며 객체 SDF는 타일 경계를 추가로 컬링하는 데 사용됩니다.

GCN에서 래스터라이저를 사용한 타일 컬링은 타일 컴퓨팅 셰이더보다 빠르며 수천 개의 항목이 10에 도달할 때 가장 큰 이득을 얻습니다. 아마도 다른 많은 사용 사례(조명, 데칼, 반사 프로브)에 적용할 수 있으며 GCN의 시간은 0.4ms -> 0.2ms입니다.
타일 컬링 프로세스: 그리기 매개변수 버퍼 구축 – 프러스텀 컬링 출력, 경계 형상 그리기 – DrawIndexedInstancedIndirect, 픽셀 셰이더는 UAV에서 타일 교차 목록을 구축합니다. 각 크기의 1/8로 계산된 원뿔 추적, 심하게 앨리어싱됨, 추가 필터링 필요 없음, 절반 해상도로 필터링 수행, 형상 인식 양방향 업샘플링.

4x 시간적 슈퍼샘플링(4개의 지터 위치), 템포럴 안티앨리어싱(TAA)을 사용하여 정확한 픽셀 속도로 재투영, 깊이 제거, 거부된 픽셀을 불안정한 것으로 표시, 시간적으로 불안정한 영역의 공간 채우기.
객체 거리 필드를 샘플링하는 데는 비용이 많이 듭니다. 아래 그림의 흰색 = 200개 개체 효과. 해결책은 다음과 같습니다. 글로벌 디스턴스 필드로 합성합니다.

전역 거리 필드: 카메라 중심의 클립맵에 저장되며 4개의 클립맵이 사용됩니다. 각 클립맵의 크기는

전역 거리 필드는 지면 근처에서 정확하지 않으며 객체 SDF는 원뿔 시작 부분 근처에서 샘플링되고 나머지는 전역 SDF입니다.

글로벌 디스턴스 필드(Global Distance Field)는 객체 영향 중첩을 대폭 줄일 수 있습니다!

14.4.4.5 Destiny의 다중 스레드 렌더러 아키텍처
Destiny의 멀티스레드 렌더러 아키텍처는 Destiny 코어 렌더러 아키텍처, GPU 데이터 흐름에 대한 게임 시뮬레이션, 작업 및 로드 밸런싱 고려 사항, 지연 시간 감소 기술(입력 및 렌더링 지연 감소, GPU를 완전히 포화 상태로 유지), 복잡성 캡슐화 등을 포함하여 2015년 Destiny 엔진의 멀티스레드 렌더링 아키텍처를 설명합니다. 또한 여기에는 거친 병렬성, Destiny 렌더러 대상, 분리된 시뮬레이션 및 렌더링, 핵심 작업 부하와 같은 기술이 포함됩니다. 작업화, 데이터 기반 렌더링 제출 및 고급 최적화.
초기 Halo 엔진은 SOT(System on a Thread) 렌더링 파이프라인을 사용했습니다.


프레임 간의 타이밍 다이어그램은 다음과 같습니다.

스레드별 정적 로드 밸런싱은 작업 부하 분산이 이상적이지 않음을 의미하므로 시뮬레이션 및 렌더링 루프(가장 큰 작업 부하)에서 스레드의 활용률이 많이 나타나는 경향이 있지만 다른 스레드에서는 유휴 시간이 많이 나타납니다.

SOT의 단점은 교차 세대/교차 플랫폼 채택이 어렵고 이기종 플랫폼에 적합하지 않으며 동기화에는 게임 상태의 전체 이중 버퍼링이 필요하고 프런트 엔드의 높은 직렬화 가시성 비용, 잠재적인 GPU 유휴 버블이 있다는 점입니다. 장점은 편리한 데이터 액세스, 확장성, 쉽고 간단한 스레딩 모델, 시뮬레이션 및 렌더링의 파이프라인 병렬 실행입니다.
데스티니 엔진 시대에 렌더러의 목표는 뛰어난 시각 효과와 응답 속도, 복잡하고 생생하며 아름다운 세계, 다양한 환경을 갖춘 대규모 목적지 지형, 고품질 조명, 동적 시간, 실시간 그림자, 날씨 요인, 고해상도 렌더링 및 다양한 그래픽 기능을 갖춘 게임 출시였습니다. 플레이 가능한 시각적으로 훌륭하고 반응성이 뛰어난 게임을 출시하고 확장성을 유지하며 세대 간, 플랫폼 간을 막론하고 모든 플랫폼에서 견고한 성능을 발휘하세요. 최대 CPU 및 GPU 사용량으로 효율성을 유지하여 GPU 유휴를 방지할 수 있는 충분한 시간, 동적 로드 밸런싱 및 스마트 작업 일괄 처리를 통해 대기 시간을 낮게 유지하세요. 단순하게 유지하여 사람들이 멀티스레딩에 대한 걱정을 멈추고 멀티스레딩을 좋아하도록 하고, 짧은 시간 내에 멀티스레드 렌더링을 시작할 수 있도록 하십시오. 그러면 새로운 기능으로 인해 기존 작업이 거의 또는 전혀 변경되지 않을 것입니다. 렌더링에서 시뮬레이션을 분리하고 완전한 데이터 기반 렌더링 파이프라인을 생성합니다.
첫 번째는 게임 상태 순회를 렌더링에서 분리하는 것입니다. 게임 개체의 가시성 순회와 관계없이 가시성과 게임 개체를 분리하고, 가시성 결과를 기반으로 렌더링 작업 부하를 구동하고, 렌더링과 게임 개체를 분리합니다. 이러한 정적 데이터를 치워두세요. 렌더링 데이터는 게임 개체 데이터와 동일하지 않습니다. 객체의 수명 주기 동안 대부분의 렌더링 데이터는 정적입니다. 불변 렌더링 데이터는 렌더러에 캐시되며 등록 후에는 읽기 전용입니다. 프레임당 임시 렌더링 특정 데이터를 추출하고, 정적 데이터는 캐싱했으며, 프레임당 동적 데이터만 추출하고, 가시성 결과는 추출할 게임 상태를 정의하고, 가시적인 요소에 대한 데이터만 추출합니다. 아래 사진은 수정 전과 수정 후의 비교입니다.

다음은 객체 분리와 렌더링입니다. 각 시스템에서 별도로 표현됩니다: 객체 시스템(게임 측), 렌더링(렌더링 객체), 가시성(가시성 객체), 교차 레이어 통신을 위한 인터페이스 제공(엄격한 액세스 규칙을 사용하며 특정 게임 단계에서만, 자세한 설명은 아래 그림 참조).

)
1: 게임 개체의 각 구성 요소는 렌더러 측의 특정 렌더링 개체에 매핑됩니다. 새로운 게임 객체가 세계에 추가되면 렌더러에 등록됩니다. 게임 개체의 정적 렌더링 데이터는 렌더러에 캐시됩니다. 렌더링 개체는 나중에 사용하기 위해 게임 개체 핸들(동적 개체용)을 캐시할 수 있습니다.
2: 그런 다음 렌더러는 렌더링 개체의 핸들을 게임 개체에 반환하고 게임 개체는 이를 해당 렌더링 구성 요소에 캐시합니다.
3: 이 렌더 객체 핸들을 사용하여 게임 객체는 가시성 시스템에 등록되어 렌더 객체 핸들을 캐시하는 가시성 객체를 생성합니다. 이 렌더 객체 핸들은 원래 렌더 객체를 가리킵니다.
4: 그런 다음 가시성 개체 핸들을 게임 개체에 반환합니다. 이제 게임 개체를 숨기려면 이 개체의 가시성을 등록 취소하면 렌더링이 중지됩니다.
5: 렌더 객체는 가시성에 대해 아무것도 모릅니다. 오직 가시성만이 렌더 객체에 대해 알고 있습니다. 따라서 게임 객체 시스템, 가시성 및 렌더링 레이어를 분리함으로써 이제 게임 객체에 액세스하지 않고도 가시성 결과를 기반으로 렌더링 시스템을 구동할 수 있습니다. 동적 데이터 추출은 어떻습니까? .
프레임 패킷: 동적 프레임별 렌더링 데이터 저장. 모든 기능 렌더러 동적 데이터가 여기에 저장됩니다. 이는 완전히 상태 비저장이며 각 프레임이 사용된 후에 폐기됩니다. 총 점유율은 PS3 Xbox360에서 프레임당 1MB로 작으며 전체 게임 상태의 9%를 차지합니다.

뷰는 플레이어 뷰, 그림자 뷰, 오버헤드 뷰 등과 같이 프러스텀와 카메라의 조합과 동일합니다.

또한 뷰는 가시성, 추출, 준비, ..., 제출 등과 같은 렌더링 작업 체인 단위와도 동일합니다. 각 프레임 링 버퍼는 여러 프레임 패킷(일반적으로 UE와 같은 2개)을 포함할 수 있으며 각 프레임 패킷은 여러 뷰 패킷을 포함할 수 있습니다. 보기 패킷에는 보기와 관련된 모든 데이터가 포함됩니다. 각 보기의 작업 체인은 아래 그림의 오른쪽에 표시됩니다.

좌: 프레임 링 버퍼, 프레임 패키지, 뷰 패키지 간의 구조적 관계, 우: 작업 체인 및 각 뷰의 단계.
보기 작업 체인은 항상 프레임 콘텐츠와 독립적으로 실행되는 핵심 시스템 작업입니다. 데이터 기반 보기 작업 체인은 지정된 프레임의 콘텐츠를 기반으로 동적으로 생성됩니다.
보기 단계 결정: 프레임을 보존하고 패킷 보기, 중량 할당 없음, 힙 작업 등
가져오기 단계: 각 뷰에 대해 표시되는 렌더 목록을 계산하고 이를 가시성 링 버퍼(임시)에 저장합니다. 포함되는 단계는 다음과 같습니다.

뷰 체인 작업은 매우 효율적이고 압축(초소형), 캐시 일관성 표현이 가능하고 렌더링 섹션 일관성을 채우는 렌더링 노드에서 작동합니다. 배열입니다.실행(Execute),뷰(View) 내에서 할당(Allocate)렌더링(Render)포인트 。렌더링(Render)뷰(View)포인트 ,저장(Store)뷰(View)데이터 ,로써 할당(Allocate)데이터 (렌더링(Render)객체/오브젝트 타입/유형 ). 및 포인트 뷰(View) 내에서 의 데이터 ,의 데이터 ,데이터 :

이전 다이어그램으로 돌아가서, 다음 프레임에 대한 게임 틱의 잠금을 해제하기 전에 추출 단계를 완료해야 하므로 게임 시뮬레이션 지연 시간이 발생합니다.

가져오기 창 및 대기 시간: 프로그램에서 청크를 가져오면 게임 상태가 읽기용으로 잠기므로 가져오기가 대기 시간에 가장 큰 영향을 미치는 워크로드가 됩니다. 추출 창은 최적화되어야 하며 추출 창은 다음에 의해 결정됩니다.
모든 뷰의 가시성 계산, 게임 상태 데이터 추출, 가시성 계산은 CPU 작업입니다. 가시성을 추출 외부로 이동할 수 있나요? 플레이어 뷰의 정적 환경 가시성은 가장 어려운 작업입니다.

추출에서 가시성을 이동하면 지연 시간이 최신 세대 게임에서 약 4밀리초, 현세대 콘솔에서 약 2.5밀리초 감소했습니다.
추출: 최소한의 노력으로 동적 데이터를 복사하고, 복잡한 데이터 변환을 실행하지 않으며, 다음 게임 틱을 위해 게임 상태/시뮬레이션을 완료하고 잠금 해제합니다.
준비: 눈에 보이는 요소에 대해서만 준비 작업을 실행하고, 가능하면 LOD 기반 계산을 건너뛰고, 눈에 띄지 않는 콘텐츠는 계산하지 마세요.
준비되고 시뮬레이션된 프레임 시퀀스는 다음과 같습니다.

이제 시뮬레이션이 병렬로 실행되면 준비 단계를 수행하겠습니다. 추출과 마찬가지로 준비도 뷰 및 프레임 노드와 캐시된 렌더 객체 데이터를 반복하여 작동하고, 다양한 렌더 객체에 대한 준비 진입점을 실행합니다. 또한 준비는 각 준비 작업의 결과를 프레임 패킷에 기록합니다. 그러나 추출에는 한 가지 중요한 차이점이 있습니다. 즉, 렌더링 작업이 더 이상 게임 개체에 액세스할 수 없다는 것입니다. 준비 과정에서 아래 캐릭터(Raider)의 너덜너덜한 망토에 대해 천 시뮬레이션 작업이 실행되고, Raider가 플레이어와 충분히 가까울 경우 Raider의 손가락과 발가락 뼈에 대해 비결정적 애니메이션이 계산됩니다(이 작업은 플레이어와 충분히 가깝지 않으면 건너뜁니다). 또한 전투 프레임에 대해 일관된 LOD 공간을 유지하기 위해 수직 개수에 따라 연속 LOD 버킷에 배치됩니다.

이 작업 흐름은 각각 다음 작업 체인이 있는 다른 보기(예: 프레임에 총 3개의 보기가 있는 경우)에 대해 반복될 수 있습니다.

UE의 장면 렌더러 프로세스가 위에서 언급한 뷰 작업 체인과 매우 일치한다는 점은 언급할 가치가 있으며, 이는 UE도 이 병렬 렌더링 아키텍처를 사용한다는 것을 나타냅니다.
단순함 유지: 그래픽 기능 개발을 단순화하고, 렌더링 작업 부하를 투명하게 운영하며, 캐시 일관성을 보장하고 핵심 작업의 잠재적인 동기화를 보장합니다. 해결책: 기능적 추상화 및 캡슐화.
렌더링 기능: 렌더링 기능은 캐시 일관성 있는 데이터 표현, 데이터 관리 및 렌더링을 위한 코드 경로로 정의되는 그래픽 렌더링 단위입니다. 속성 렌더러의 인스턴스에 매핑될 수 있습니다. Destiny 속성 렌더러는 그래픽 속성이 매핑되는 방식(캐시된 데이터 표현을 사용한 객체 렌더링, 프레임 팩 렌더 노드 표현 및 각 단계의 작업 진입점)을 정의합니다. (아래 사진)

기능 렌더러 작업: 각 기능 렌더러는 각 단계에 대한 진입점 세트를 노출하고 데이터 액세스를 제한합니다. 해당 노드 상태 및 기능 렌더 개체 데이터만 읽고 프레임 패킷으로만 출력하며 모든 출력은 자동으로 이중 버퍼링됩니다. 코어 렌더러는 이러한 진입점을 사용하여 리프 기능에 영향을 주지 않고 각 단계에 대한 작업을 실행합니다. 리프 기능은 핵심 아키텍처가 작업 종속성 또는 로드 밸런싱 규칙을 재구성할 때 영향을 받지 않습니다.
다음은 인터페이스에서 제공하는 기능적 렌더러에 대한 모든 진입점 세트입니다. 당신은 그들의 이름을 이해하지 못할 수도 있지만 걱정하지 마십시오. 그들은 단지 시스템이 어떻게 작동하는지 이해하기를 원할 뿐입니다.

성능 및 메모리 최적화:
작업 빈도별로 데이터 및 작업 부하 구성: 뷰 전체, 렌더링 개체 전체에서 데이터 공유: 프레임 팩 메모리 절약, 성능 절약: 빈도당 한 번씩 값비싼 계산을 수행합니다.
핵심 아키텍처는 공유 요소에 대한 액세스 및 실행, 멀티스레드 액세스를 동기화합니다. 내부 루프를 강제로 잠그면 성능이 저하될 수 있습니다. 빠른 공유 렌더 노드 작업을 위해 사용자 정의 잠금 없는 기본 요소를 개발했습니다.
프레임당 작업을 추출하거나 준비할 때 프레임당 한 번 렌더러에 등록된 모든 객체에 고유한 프레임당 노드 인덱스의 잠금 없는 동기화 프리미티브(객체가 모든 보기에 표시되는 한).
각 게임 객체에 대한 작업을 추출하거나 준비할 때 여러 렌더 객체에 대한 워크로드 공유, 스킨 추출 및 준비/동적 AO 계산/순방향 조명 감지 계산/비결정적 애니메이션 해결, 객체 뼈대 해싱을 기반으로 하는 잠금 없는 동기화 프리미티브.

데이터 기반 제출 파이프라인 프레임 제출: 고급 제출 코드 실행 채널, 병렬 제출, 게임 상태 기반. 드물지만 비용이 많이 드는 전역 상태 설정: 렌더링 대상 작업(바인드, 지우기, 구문 분석, 압축 풀기), 전역 상태(프레임/뷰 레지스터). 각 채널은 해당 뷰에 대한 GPU 명령을 생성하는 간단한 크로스 플랫폼 API인 커밋 뷰 명령을 호출합니다. 각 제출 보기 지시문은 제출 보기 작업을 설정하며 작업 규칙은 플랫폼마다 다릅니다. 파이프라인 GPU는 다음과 같이 작동합니다.

궁극적으로 해야 할 일은 제출 보기 작업을 시작하는 방법과 상위 수준 제출 파이프라인에서 기능 제출 진입점을 파악하는 것입니다. 당신이 해야 할 일은 데칼 단계에 제출해야 할 표시 요소와 투명 단계에 제출해야 하는 요소를 구별하는 것입니다.

고급 커밋 제어: 단계별로 구성된 크로스 플랫폼 코드 경로: 1. 셰이딩 패스, 톤매핑/파싱 등과 같은 필수 패스; 2. 커밋 단계 커밋 지침.
// 단계 의 코드
generate_gbuffer_pass()
set_render_targets(depth_stencil, gbuffer_surfaces)
setup_viewport_parameters()
...
clear_viewport()
submit_render_stage_for_view(first_person_view, _render_stage_gbuffer_opaque);렌더링 단계 메커니즘: 런타임 제출 프로세스를 필터링하고, 런타임 셰이더 기술 관리를 제공하고, 적시에 올바른 기술을 선택하고, 표시 목록 필터링을 허용하고, 캐시 일관성과 빠른 반복을 위해 구축된 올바른 기술을 사용하여 올바른 프로세스에 제출할 올바른 메시 세트를 선택합니다.
렌더 단계: 각 렌더 객체는 등록 시 또는 런타임 중 언제든지 코어 렌더러에 단계를 등록하여 언제든지 렌더 단계를 구독할 수 있습니다. 각 뷰는 런타임 시 렌더링 단계를 구독할 수 있으며 표시 목록은 구독된 렌더링 단계로만 필터링됩니다.
여기서 렌더링 단계는 실제로 UE의 FMeshPassProcessor 및 해당 하위 클래스와 유사합니다. 자세한 내용은 언리얼 렌더링 시스템 분석(03) - 렌더링 메커니즘을 참조하세요.
렌더링 단계별로 보기 필터링: 렌더링 개체는 두 가지 조건이 충족되는 경우에만 제출됩니다. 보기는 지정된 단계를 지원하고 보기에는 해당 렌더링 단계를 구독하는 표시 노드가 포함됩니다.
단계별로 제출 노드 채우기: 렌더링 단계별로 표시되는 목록을 필터링합니다.
제출 노드를 단계별로 정렬: 투명 재료 등과 같은 일부 프로세스는 렌더링하기 전에 정렬해야 합니다. 각 단계는 각 렌더 단계에 대해 구성 가능한 콜백을 사용하여 준비 중에 순서가 지정되고, 각 렌더 노드는 런타임 시 각 단계에 대한 사용자 지정 경험적 방법을 계산합니다. 각 렌더 객체에는 작은 정렬 키를 기반으로 하는 인라인 빠른 정렬을 사용하여 하나 이상의 제출 노드가 있을 수 있습니다.
캐시 일관성: 모든 핵심 렌더러 작업은 경량 데이터 구조인 렌더 노드에서 작동합니다. 모든 핵심 워크로드에 대해 빠르고 캐시 일관성이 있는 정렬, 할당 및 탐색을 수행하고 데이터 복제를 줄여 긴밀한 반복 루프에서 더 빠른 캐시 액세스를 가능하게 합니다.

단계별 작업 제출 보기: 동적 로드 밸런싱 분할을 통해 단계별, 보기, 기능, 단계 세트 등과 같은 다양한 제출 리프 작업으로 구분됩니다. 각 기능 제출 진입점에 대해 렌더 노드 및 기능 렌더 객체 캐시와 같은 로컬 및 렌더 객체 데이터에만 액세스됩니다.
기능 렌더러 커밋 커널: 허용된 패스에 대해서만 기능 유형별로 정렬할 수 있는 각 기능에 대한 일관된 코드 경로입니다. 제출 보기 작업은 커널 프로세서에 최적화되어 있습니다.
렌더링 지터 및 지연 시간 감소: 멀티스레드 제출, CPU/GPU 로드 밸런싱, GPU 버블 감소, 효율적인 명령 버퍼 플러싱, 비동기 스와핑, 지터를 줄이기 위한 지연이 있는 자동 복구.
GPU 사용률: 궁극적인 목표는 GPU를 완전히 포화 상태로 유지하고 유휴 상태가 되지 않도록 하는 것입니다. 중요한 요소는 GPU 명령을 GPU로 새로 고치고, 드로우 콜을 실행하고, 명령 목록 명령을 실행하고, 대상 상태를 렌더링하고, 이전 프레임에 대한 GPU 작업이 완료되고 롤오버되는 데 걸리는 시간입니다.
GPU 유휴 추적: 카운터는 불규칙하지만 일부 플랫폼에서 사용할 수 있으며 모든 성능 및 활동 테스트에 대해 GPU 유휴 == GPU 부족을 추적하는 데 엔진이 사용되며, GPU 부족으로 인해 지연 시간이 더 높은 위치를 찾아내는 데 도움이 됩니다.

위 이미지는 많은 GPU 유휴 버블을 보여 주며, 이는 전체 렌더링 대기 시간을 증가시키는 GPU 부족 상태를 나타냅니다.
GPU 점유 유지: 멀티 스레드 제출, 효율적인 명령 버퍼 새로 고침 생성, 제출 작업 세분화된 로드 밸런싱, Vblank 동기화.
VBlank에 동기화: 간격을 놓치지 않고 뒤집을 준비가 되면 GPU 작업이 완료되도록 vblank 오프셋을 기반으로 계산합니다. 일부 콘솔에서는 전체 제어에 유용한 원시 vblank 이벤트 추적을 허용합니다. 다른 콘솔/PC는 수동 작업이 필요하지 않습니다. 별도의 스레드를 가동하고 Vblank 이벤트를 기다리면 됩니다. 크기 조정/전체 화면 이벤트를 게시할 때 렌더링 교착 상태에 유의하세요.
멀티 스레드 제출: 복잡한 주제이며 명령 버퍼를 GPU로 플러시할 때 모든 중요한 측면을 다룰 수 없습니다. 고급 커밋 스크립트는 보기별, 단계별로 명령 버퍼 커밋을 생성합니다. GPU는 명령이 생성될 때가 아니라 주로 명령 버퍼가 GPU에 플러시될 때 명령을 순차적으로 실행해야 합니다.
고급 렌더링 제출: 높은 수준, 고비용 렌더링 상태(목표 경계/삭제/해결됨)를 제출합니다. 렌더링 단계에 대한 뷰를 렌더링하기 위한 상위 수준 커밋 지시문을 제출하고(선택 사항: 추가 기능 필터링) 이를 이 레이어에서 작업하고 지시문에 대한 명령 버퍼를 생성합니다.
제출 작업 생성: 작업 N은 기능 또는 렌더링 상태별로 그룹화되어 노드를 함께 제출합니다. GPU 순차 실행을 위해 고급 제출 스크립트 작업에서 제출 작업 생성을 위한 명령 버퍼를 분할합니다. 각 기능별, 단계별, 보기별 제출 작업 == 명령 버퍼 1개.
작업 제출 및 GPU 점유: 가벼운 CPU가 GPU로 빠르게 플러시되어 시작되고 그 다음에는 대부분의 GPU 작업을 수행하는 중간 CPU 등을 포함하여 CPU와 GPU 로드의 최적의 균형이 필요합니다. 핵심 렌더러는 플랫폼별로 조정된 렌더링 특성 및 렌더링 단계 비용을 기준으로 제출된 작업을 정렬하는 메커니즘을 제공합니다.
동적 로드 밸런싱은 아래에서 다룹니다.
로드 밸런싱 렌더링 작업: 조잡한 접근 방식은 초기 구현을 너무 단순하게 만들 수 있습니다. 단계당 기능당 하나의 작업(추출/준비/제출), 워크로드가 크게 다릅니다. 예를 들어 환경/지형을 준비할 필요가 없으며 캐릭터 리깅, 스키닝 및 천은 너무 많은 오버헤드가 있는 무거운 작업입니다.
동적 로드 밸런싱: 각 기능은 각 단계에 대한 비용 함수를 제공합니다. 독립적으로 작동해야 합니까? 각 단계 {가져오기, 준비, 제출}의 엔터티 및 기능 비용을 기반으로 하는 핵심 시스템 일괄 처리, 프레임의 데이터를 기반으로 하는 자동 로드 밸런싱.
이기종 작업 실행: 각 기능은 지원하는 실행 단위를 지정하고 코어 렌더러는 SPU/PPU 예약과 같이 가용성에 따라 자동으로 예약합니다. 대부분은 추출에 사용되며 작업량이 많은 다른 단계는 PPU에서 작동합니다. 향후 다른 시스템으로 확장될 수 있습니다.
결과: 크로스 플랫폼이고 아키텍처 조정의 영향을 받지 않는 기능 코드를 사용하여 PlayStation 4, PlayStation 3, Xbox One 및 Xbox 360과 같은 여러 플랫폼에서 지연 시간이 짧고 효율적이며 확장성이 뛰어난 실행이 가능합니다. 렌더러의 멀티스레딩은 확장성과 동적 로드 밸런싱, 캐시 일관성 데이터 액세스, 과중한 작업 부하에도 불구하고 짧은 대기 시간을 가능하게 하는 이기종 지원을 통해 Destiny를 제공하는 데 핵심입니다. 데이터 기반 파이프라인 아키텍처는 그래픽 기능 생성을 위한 뛰어난 유연성을 제공하며 견고한 패키징은 개발 프로세스 전반에 걸쳐 광범위한 최적화를 허용합니다. 원래 설정된 목표를 달성하여 게임 상태 탐색을 출력에서 성공적으로 분리하고, 더 나은 CPU 및 GPU 활용도를 달성했으며, 데이터 기반 아키텍처를 통해 렌더링 알고리즘을 작업 및 데이터 병렬 워크로드로 분해했습니다.
문제는 각 플랫폼마다 작업 제출 세분성, 명령 버퍼 생성, 프로젝트 전반에 걸친 작업 오버헤드 비용의 지속적인 최적화 등 맞춤형 요구 사항이 있다는 것입니다.
Destiny의 핵심 엔진 아키텍처에서 얻은 교훈에서는 Destiny 엔진의 렌더링 아키텍처와 목표 달성 방법에 대해 설명합니다. 당시 데스티니 엔진에는 다음과 같은 많은 모듈이 있었습니다.

엔진이 지원하는 기능에는 작업 그래프 멀티스레딩, 크로스 플랫폼, 엔진 공유 및 신속한 재구성을 위한 계층적 코드 베이스, 게임 로직에서 분리된 게임 상태 및 리소스 수명 주기, 구성 요소화된 개체 시스템, 고급 기능 개발 지원, 게임플레이 반복을 위한 심층 스크립트를 작성하고 모든 콘텐츠를 빠르게 반복할 수 있는 사용자 정의 C# 편집기 제품군이 포함되며 이러한 기능의 약 60%를 제공합니다. 다음 그림은 다양한 시대와 수준에 따른 엔진 아키텍처의 진화를 보여줍니다.






14.4.5 개화기간 요약
2010년부터 2015년까지 요약하면 렌더링 엔진의 전반적인 특성은 다음과 같습니다.
DirectX 11 및 OpenGL 4.x의 그래픽 API는 많은 새로운 기능을 제공하여 게임 엔진과 애플리케이션을 플레이할 수 있는 넓은 공간을 제공합니다.
GPU 하드웨어 구조와 드라이버 레이어도 그래픽 API 개발에 적응하거나 이를 촉진하고 있습니다. 컴퓨팅 성능과 병렬성은 기하급수적으로 발전하고 있지만 IO 대역폭 병목 현상은 여전히 남아 있으며 ALU의 개선을 따라잡을 수 없습니다. GPU 기반 렌더링 파이프라인의 출현은 매우 복잡한 장면 렌더링을 위한 견고한 기반을 제공합니다.
멀티스레드 렌더링, 비동기 로딩, 작업자 스레드, 스레드 풀, DX11 멀티스레드 컨텍스트 등과 같은 멀티스레딩이 완전히 활용됩니다. 모두 구체적인 실시예입니다. SOA, 선형 배열, DirectCompute, 데이터 드라이버 등 멀티스레딩에 적응하고 병렬성을 향상시키는 기술과 데이터 구조도 전례 없이 사용되었습니다.
PBR, 지연 조명, 추론 조명, 블록 및 클러스터 조명뿐만 아니라 다양한 직접 조명, 간접 조명, 체적 조명 및 기타 기술과 같은 렌더링 기술도 빠르게 발전했습니다. 수많은 앤티앨리어싱 기술이 개발되었으며 대표적인 예로는 FXAA, TAA, SMAA 및 그 변형이 있습니다. 포스트 프로세스 기술도 크게 뒤지지 않으며 보다 현실적이고 효율적인 수많은 알고리즘이 뒤따랐습니다. 대표적인 대표적인 것이 DOF인데, 이는 많은 문서에서 볼 수 있다.
특수 소재도 날이 갈수록 진화하고, 피부, 머리카락, 눈, 옷, 자연 풍경(지형, 하늘, 대기, 광선, 날씨, 초목, 호수, 바닷물, 안개)을 예로 드는 문학이 확산되고 있습니다.
모바일 단말기의 지능화가 발전함에 따라 모바일 렌더링이 점점 성숙해지고 있습니다. 모바일 단말기 전용 GPU, 그래픽 API, 렌더링 엔진 등은 지속적으로 개선되어 완전한 생태계 체인을 형성하고 있습니다.
레이 트레이싱, VR, 웹 등의 신기술은 조용히 발전하고 있으며 후속 개발을 위한 좋은 시작과 기반을 마련하고 있습니다.
이 글은 아직 끝나지 않았으며 계속됩니다.
특별 지침
모든 참고문헌의 저자에게 감사드립니다. 일부 사진은 참고 자료와 인터넷에서 가져온 것이므로 삭제되었습니다.
이 시리즈의 기사는 저자가 직접 작성한 것이며 블로그에만 게시됩니다. 이 글의 링크를 공유하셔도 좋지만 무단 전재는 허용되지 않습니다!
계속되는 일련의 기사. 전체 목록을 보려면 콘텐츠 개요를 클릭하세요.
계속되는 일련의 기사. 전체 목록을 보려면 콘텐츠 개요를 클릭하세요.
계속되는 일련의 기사. 전체 목록을 보려면 콘텐츠 개요를 클릭하세요.
📚 참고 자료 및 공식 링크 (References)
- Unreal Engine Source
- Rendering and Graphics
- Materials
- Graphics Programming
- Unreal Engine 2 Documentation
- Unreal Engine 3 Documentation
- Game engine
- List of game engines
- Game Engine Architecture
- Game Engine Architecture Third Edition
- Game Engine Architecture Course
- Welcome to CS1950u!
- Game Engine Fundamentals
- Designing the Framework of a Parallel Game Engine
- 📖 GPU 하드웨어 아키텍처 및 작동 메커니즘에 대한 심층적인 이해
- 📖 얕은 것부터 깊은 것까지 PBR의 원리와 구현을 배워보세요.
- 📖 언리얼 엔진의 초현실적 휴먼 렌더링 기술 분석 1부 - 개요 및 피부 렌더링
- 📖 언리얼 엔진의 초현실적인 휴먼 렌더링 기술 분석 2부 - 안구 렌더링
- 📖 언리얼 엔진의 초현실적 휴먼 렌더링 기술 분석 3부 - 헤어 렌더링 등
- Playstation 2 Architecture
- Procedural Rendering on Playstation® 2
- Independent Game Development
- CryEngine Sandbox Far Cry Edition
- Information Visualisation utilising 3D Computer Game Engines
- Using Commonsense Reasoning in Video Games
- GeForce 6 series
- List of game engines
- 3D Game Engine Architecture
- 『:』12UE5
- Unreal Engine
- 언리얼 엔진(Unreal Engine)
- FROM ABSTRACT DATA MAPPING TO 3D PHOTOREALISM: UNDERSTANDING EMERGING INTERSECTIONS IN VISUALISATION PRACTICES AND TECHNIQUES
- Game Developer - October 2005
- Torque Tutorial #2
- Game Engine Tutorials:Chapter 1 - Introduction
- Unreal Engine 3 Technology
- Using the Source Engine for Serious Games
- Designing a Modern Rendering Engine
- Finding Next Gen – CryEngine 2
- CryENGINE 3 Game Development Beginner's Guide
- GPU overview Graphics and Game Engines
- 3dfx Interactive
- RIVA TNT
- DirectX
- Direct3D feature levels
- Feature levels in Direct3D
- High-Level Shader Language
- DirectX 3.0
- Microsoft Ships DirectX Version 3.0
- Microsoft Ships DirectX 5.0
- DirectX 5.0
- Microsoft's Official DirectX 6.0
- Multitexturing in DirectX 6
- Microsoft® DirectX® 7: What's New for Graphics
- GLFW
- OpenGL Related toolkits and APIs
- Nurien Mstar Online - (4minute - Huh) Bubble Item Mode
- GDM_April_2008(Game Developer)
- How To Go From PC to Cross Platform Development Without Killing Your Studio
- “A bit more Deferred” - CryEngine 3
- CryEngine
- Far Cry®
- CryENGINE 2
- Crysis 1 XBOX/PS3
- CryENGINE 3
- CryEngine Features
- The Matrix Awakens: An Unreal Engine 5 Experience
- Hitting 60Hz with the Unreal Engine: Inside the Tech of Mortal Kombat vs DC Universe
- Parallel Graphics in Frostbite – Current & Future
- Frostbite (game engine)
- EA Tech Blog
- irrlicht
- Practical techniques for managing Code and Assets in multiple cross platform titles
- Next-Gen Asset Streaming Using Runtime Statistics
- Light Pre-Pass Deferred Lighting: Latest Development
- The Next Mainstream Programming Language: A Game Developer’s Perspective
- An explanation of Doom 3’s repository-style architecture
- TerraForm3D Plasma Works 3D Engine & USGS Terrain Modeler
- Entity component system
- Entity Component Systems in Unity
- Entity Component System VS Entity Component
- Entities, components and systems
- Redefining Game Engine Architecture through Concurrency
- Tim Sweeney on the first version of the Unreal Editor
- Integrating Architecture Soar Workshop
- Ray Tracing for Games
- Modern Graphics Engine Design
- Ogre Golf
- Selecting the Best Open Source 3D Games Engines
- Theory, Design, and Preparation
- The Benefits of Multiple CPU Cores in Mobile Devices
- GAME ENGINES
- Development of a 3D Game Engine - OpenCommons
- Physically Based Shading Models for Film and Game Production
- Physically Based Shading at Disney
- Real Shading in Unreal Engine 4
- The Game Engine Space for Virtual Cultural Training
- Game Engines
- Quake III Arena Game Structures
- iOS and Android development with Unity3D
- The use cases that drive XNAT development
- Exploiting Game Engines For Fun & Profit
- GAME ENGINES: A 0-DAY’S TALE
- Comparison and evaluation of 3D mobile game engines
- Barotrauma
- Microsoft XNA
- Game Engines
- Game Engines-The Overview
- Multithreading for Gamedev Students
- A History of the Unity Game Engine
- A brief insight into BRTECH1
- CRYENGINE 5.3 - Getting Started Guide
- The architecture and evolution of computer game engines
- Designing a Modern GPU Interface
- Game Engine Programming
- DX12 & Vulkan Dawn of a New Generation of Graphics APIs
- GPU-Driven Rendering Pipelines
- Limitation to Innovation in the North American Console Video Game Industry 2001-2013: A Critical Analysis
- The 4+1 View Model of Architecture
- Architectural Blueprints—The “4+1” View Model of Software Architecture
- Serious Games Architectures and Engines
- Game Engine Solutions
- Remote exploitation of the Valve Source game engine
- Game Engines - Computer Science
- High quality mobile VR with Unreal Engine and Oculus
- The Report by the written by Amanda Wong funded by the July 2017
- Entity Component Systems & Data Oriented Design
- A Taxonomy of Game Engines and the Tools that Drive the Industry
- Torque 3D Documentation
- Comparative Study on Game Engines
- MOBILE GAME DEVELOPMENT
- Evaluation of CPU and Memory performance between Object-oriented Design and Data-oriented Design in Mobile games
- Efficient generation and rendering of tube geometry in Unreal Engine
- Global Illumination Based on Surfels
- Radiance Caching for real-time Global Illumination
- BigWorld
- Ubisoft Anvil
- Destiny Game Engine: Tiger
- Multithreading the Entire Destiny Engine
- Lessons from the Core Engine Architecture of Destiny
- Destiny 2: Tiger Engine Changes
- Destiny
- Destiny 2
- RE Engine
- Rockstar Advanced Game Engine
- NVIDIA DLSS
- OpenGL
- OpenGL ES
- Tone Reproduction and Physically Based Spectral Rendering
- A Framework for an R to OpenGL Interface for Interactive 3D graphics
- Beyond Finite State Machines Managing Complex, Intermixing Behavior Hierarchies
- Game Mobility Requires Code Portability
- Challenges in programming multiprocessor platforms
- Adding Spherical Harmonic Lighting to the Sushi Engine
- Real World Multithreading in PC Games Case Studies
- Speed up the 3D Application Production Pipeline
- New 3D Graphics Rendering Engine Architecture for Direct Tessellation of Spline Surfaces
- A realtime immersive application with realistic lighting: The Parthenon
- The Parthenon Demo: Preprocessing and Rea-Time Rendering Techniques for Large Datasets
- Rendering Gooey Materials with Multiple Layers
- Practical Parallax Occlusion Mapping For Highly Detailed Surface Rendering
- Real-time Atmospheric Effects in Games
- Shading in Valve’s Source Engine slide
- Shading in Valve’s Source Engine
- Ambient Aperture Lighting
- Fast Approximations for lighting of Dynamic Scenes
- An Analysis of Game Loop Architectures
- Exploiting Scalable Multi-Core Performance in Large Systems
- Ritual™ Entertainment: Next-Gen Effects on Direct3D® 10
- Feeding the Monster: Advanced Data Packaging for Consoles
- Best Practices in Game Development
- High-Performance Physics Solver Design for Next Generation Consoles
- Collaborative Soft Object Manipulation for Game Engine-Based Virtual Reality Surgery Simulators
- Introduction to Direct3D 10 Course
- Practical Global Illumination with Irradiance Caching
- General-Purpose Computation on Graphics Hardware
- GPUBench
- The Mobile 3D Ecosystem
- Advanced Real-Time Rendering in 3D Graphics and Games
- Frostbite Rendering Architecture and Real-time Procedural Shading & Texturing Techniques
- Saints Row Scheduler
- PCI Express
- The Delta3D Gaming and Simulation Engine: An Open Source Approach to Serious Games
- Software Requirement Specification Common Infrastructure Team
- Dragged Kicking and Screaming: Source Multicore
- OpenGL ES 2.0 : Start Developing Now
- Interactive Relighting with Dynamic BRDFs
- Advances in Real-Time Rendering in 3D Graphics and Games (SIGGRAPH 2008 Course)
- Advanced Virtual Texture Topics
- March of the Froblins: Simulation and rendering massive crowds of intelligent and detailed creatures on GPU
- Using wavelets with current and future hardware
- StarCraft II: Effects & Techniques
- The Intersection of Game Engines & GPUs: Current & Future
- Software Instrumentation of Computer and Video Games
- John Carmack Archive - Interviews
- UnrealScript: A Domain-Specific Language
- GPU evolution: Will Graphics Morph Into Compute?
- Introduction to the Direct3D 11 Graphics Pipeline
- Lighting and Material of HALO 3
- Snakes! On a seamless living world
- Threading Successes of Popular PC Games and Engines
- THQ/Gas Powered Games Supreme Commander and Supreme Commander: Forged Alliance
- Emergent Game Technologies: Gamebryo Element Engine
- Namco Bandai, EA Partner For Hellgate: London
- Project “Smoke” N-core engine experiment
- New Dog, Old Tricks: Running Halo 3 Without a Hard Drive
- Creating believable crowds in ASSASSIN'S CREED
- id Tech 5 Challenges - From Texture Virtualization to Massive Parallelization
- Building a Dynamic Lighting Engine for Velvet Assassin
- Techniques for Improving Large World and Terrain Streaming
- A Novel Multithreaded Rendering System based on a Deferred Approach
- Regressions in RT Rendering: LittleBigPlanet Post Mortem
- Meshless Deformations Based on Shape Matching
- sphere ambient occlusion - 2006
- Insomniac Physics
- State-Based Scripting in Uncharted 2: Among Thieves
- Zen of Multicore Rendering
- Star Ocean 4 - Flexible Shader Managment and Post-processing
- Light Propagation Volumes in CryEngine 3
- https://advances.realtimerendering.com/s2009/SIGGRAPH
- Precomputed Atmospheric Scattering
- Theory and Practice of Game Object Component Architecture
- Rendering Technology at Black Rock Studio
- NVIDIA Developer Tools for Graphics and PhysX
- Animated Wrinkle Maps
- Terrain Rendering in Frostbite Using Procedural Shader Splatting
- Spherical Harmonic Lighting: The Gritty Details
- Precomputed Radiance Transfer for Real-Time Rendering in Dynamic, Low-Frequency Lighting Environments
- A Gentle Introduction to Precomputed Radiance Transfer
- Spherical harmonics
- Tetris packing [Levy 02]
- Multi-Chart Geometry Images
- Direct3D 11.1 Features
- Direct3D 11.2 Features
- Vulkan
- Metal (API)
- Mantle (API)
- ADVANCED GRAPHICS ENGINE BASED ON THE NEW OPENGL FEATURES
- A High Dynamic Range Rendering Pipeline
- A Real Time Radiosity Architecture for Video Games
- Advanced Screenspace Antialiasing
- The Benefits of Multiple CPU Cores in Mobile Devices
- Direct3D 11 In-Depth Tutorial: Tessellation
- Real-time Diffuse Global Illumination in CryENGINE 3
- Future graphics in games
- Physically-Based Shading Models in Film and Game Production
- Crafting Physically Motivated Shading Models for Game Development
- Pre-computing Lighting in Games
- Direct3D 11 Performance Tips & Tricks
- Oit And Indirect Illumination Using Dx11 Linked Lists
- http://advances.realtimerendering.com/s2010/Hable-Uncharted2
- UFO Invasion: DX11 and Multicore to the Rescue
- CryENGINE 3: reaching the speed of light
- 레이 트레이싱(Ray Tracing):Regular Grid 및 3DDDA
- Destruction Masking in Frostbite 2 using Volume Distance Fields
- Sample Distribution Shadow Maps
- Shears - Squeeze the Juice Out of the CPUs: Post Mortem of a Data-Driven Scheduler
- Advanced Material Rendering
- Water and lightin underwater photography
- http://advances.realtimerendering.com/s2010/Ownby
- http://advances.realtimerendering.com/s2010/Salvi-AVSM
- DiRT2 DirectX 11 Technology
- What Is Ambient Occlusion? (SSAO, HBAO, HDAO And VXAO)
- HORIZON-BASED AMBIENT OCCLUSION PLUS (HBAO+)
- R-Trees -- Adapting out-of-core techniques to modern memory architectures
- Streaming Massive Environments from 0 to 200 MPH
- A Dynamic Component Architecture for High Performance Gameplay
- The Game Engine Space for Virtual Cultural Training: Requirements, Devices, Engines, Porting Strategies and a Future Outlook
- DirectCompute Performance on DX11 Hardware
- DirectCompute Optimizations and Best Practices
- Per-Pixel Linked Lists with Direct3D 11
- Texture Compression in Real-Time Using the GPU
- Reflection for Tools Development
- The Asset pipeline for Just Cause 2: Lessons learned
- Real-Time Order Independent Transparency and Indirect Illumination Using Direct3D 11
- Multi-Core Memory Management Technology in Mortal Kombat
- Mega Meshes - Modeling, Rendering and Lighting a World Made of 100 Billion Polygons
- Game Worlds from Polygon Soup: Visibility, Spatial Connectivity and Rendering
- Building a Multithreaded Web Based Game Engine Using HTML5, CSS3 and JavaScript
- Culling the Battlefield: Data Oriented Design in Practice
- Dynamic lighting in GOW3
- Firaxis LORE And other uses of D3D11
- DirectX 11 Rendering in Battlefield 3
- Secrets of CryENGINE 3 Graphics Technology
- Rendering in Cars 2
- http://www.klayge.org/material/4_2/DoF/An
- DX11 Performance Gems
- Lighting the Apocalypse: Rendering Techniques for RED FACTION: ARMAGEDDON
- Five Rendering Ideas from Battlefield 3 & Need For Speed
- 📖 UE Part 1에서 PBR 머티리얼 제작 가이드 - 색상 지식
- High Performance Post-Processing
- Separating Semantics from Rendering:A Scene Graph based Architecture for Graphics Applications
- Pre-Integrated Skin Shading
- Scaling the Pipeline
- Practical Occlusion Culling on PS3
- Putting the Plane Together Midair
- 『』기술
- Accelerating Rendering Pipelines Using Bidirectional Iterative Reprojection
- CSM Scrolling: An acceleration technique for the rendering of cascaded shadow maps
- Analytic Anti-Aliasing of Linear Functions on Polytopes
- iOS and Android Development with Unity3D
- http://twvideo01.ubm-us.net/o1/vault/gdc2012/slides/Programming
- Effects Techniques Used in Uncharted 3: Drake's Deception
- Cutting the Pipe: Achieving Sub-Second Iteration Times
- Mastering DirectX 11 with Unity
- Practical Physically Based Rendering in Real-time
- GPU Task-Parallelism: Primitives and Applications
- Beyond a simple physically based Blinn-Phong model in real-time
- Water Technology of Uncharted
- Geometry Clipmaps: Terrain Rendering Using Nested Regular Grids
- Graphics Gems for Games - Findings from Avalanche Studios
- New particle trimming tool
- Particle trimmer
- LEAN Mapping
- Forward Rendering Pipeline for Modern GPUs
- Using GPUView to Understand your DirectX 11
- Realtime global illumination and reflections in Dust 514
- Advanced Procedural Rendering with DirectX 11
- Survey of Physics Engines for Games
- http://advances.realtimerendering.com/s2012/Ubisoft/Rock-Solid
- Linear Efficient Anti-aliased Normal Mapping
- Sand Rendering in Journey
- Scalable High-Quality Motion Blur and Ambient Occlusion
- 📖 언리얼 엔진의 초현실적 휴먼 렌더링 기술 분석 1부 - 개요 및 피부 렌더링
- 📖 언리얼 엔진의 초현실적인 휴먼 렌더링 기술 분석 2부 - 안구 렌더링
- Bringing AAA Graphics to Mobile Platforms
- Deferred Radiance Transfer Volumes: Global Illumination in Far Cry 3
- The Technology Behind the “Unreal Engine 4 Elemental demo”
- Interactive Indirect Illumination Using Voxel-Based Cone Tracing
- Terrain in Battlefield 3: A Modern, Complete and Scalable System
- Practical Implementation of Light Scattering Effects Using Epipolar Sampling and 1D Min/Max Binary Trees
- Accelerate your Mobile Apps and Games for Android™ on ARM
- OpenGL ES 3.0 - Challenges and Opportunities
- An Architecture Approach for 3D Render Distribution using Mobile Devices in Real Time
- Destiny: From Mythic Science Fiction to Rendering in Real-Time
- Graphics Gems from CryENGINE 3
- Oceans on a Shoestring: Shape Representation, Meshing and Shading
- Practical Clustered Shading
- Clustered Deferred and Forward Shading
- Pixel Synchronization: Solving Old Graphics Problems with New Data Structures
- REDengine 3 Character Pipeline
- Virtual Reality Capabilities of Graphics Engines
- Efficient Usage of Compute Shaders on Xbox One and PS4
- Killzone Shadow Fall: Threading the Entity Update on PS4
- Developing Virtual Reality Experiences with the Oculus Rift
- Virtual Reality and Getting the Best from Your Next-Gen Engine
- Diving into VR World with Oculus
- Solving Visibility and Streaming in The Witcher 3: Wild Hunt with Umbra 3
- Volumetric Fog: Unified compute shader based solution to atmospheric scattering
- SCRIPTING PARTICLES
- Compute-Based GPU Particle Systems
- Multithreading for Gamedev Students
- Moving Frostbite to Physically Based Rendering 3.0
- 『』개발
- Landscape creation and rendering in REDengine 3
- Next-Gen Characters From Facial Scans to Facial Animation
- PCA
- Hybrid Reconstruction Anti Aliasing
- OpenGL ES 3.0 and Beyond: How To Deliver Desktop Graphics on Mobile Platforms
- Rendering in Codemasters’ GRID2 and beyond Achieving the ultimate graphics on both PC and tablet
- Real-time lighting via Light Linked List
- Authoring Tools Framework: Open Source from Sony's Worldwide Studios
- Introduction to PowerVR Ray Tracing
- Practical Techniques for Ray Tracing in Games
- Next Generation Post Processing in Call of Duty
- Concurrent Interactions in The Sims 4
- Crafting a Next-Gen Material Pipeline for The Order: 1886
- Reflection System in Thief
- Rendering Techniques in Ryse
- Tessellation in Call of Duty: Ghosts
- Achieving the Best Performance with Intel Graphics Tips, Tricks, and Clever Bits
- High Quality Temporal Supersampling
- Realistic Cloud Rendering Using Pixel Sync
- Calibrating Lighting and Materials in Far Cry 3
- Adaptive Clothing System in Kingdom Come: Deliverance
- Sound Propagation in Hitman
- Visual Effects in Star Citizen
- Adaptive Virtual Texture Rendering in Far Cry 4
- Rendering the World of Far Cry 4
- Assassin's Creed Identity: Create a Benchmark Mobile Game!
- D3D12 A new meaning for efficiency and performance
- PowerVR Graphics - Latest Developments and Future Plans
- Unified Telemetry, Building an Infrastructure for Big Data in Games Development
- Quick and Dirty: 2 Lightweight AI Architectures
- Dynamic Occlusion With Signed Distance Fields
- Fast Approximations for Global Illumination on Dynamic Scenes
- SIMD at Insomniac Games
- Frostbite on Mobile
- Destiny's Multi-threaded Renderer Architecture
- Lessons from the Core Engine Architecture of Destiny
- Parallelizing the Naughty Dog Engine Using Fibers
- Strategies for efficient authoring of content in Shadow of Mordor
- Multi-Scale Global Illumination in Quantum Break
- Physically-based & Unified Volumetric Rendering in Frostbite
- Piko: A Framework for Authoring Programmable Graphics Pipelines
- Rendering the Alternate History of The Order: 1886
- MSAA Resolve Filters
- Far Cry 4 and Assassin’s Creed Unity: Spicing Up PC Graphics with GameWorks
- The Real-Time Volumetric Cloudscapes of Horizon Zero Dawn
- Sampling Methods for Real-time Volume Rendering
- Stochastic Screen-Space Reflections
- Hybrid Ray-Traced Shadows
- Advancements in Tiled-Based Compute Rendering
- Advanced VR Rendering
- Authoring Realtime Volumetric Cloudscapes with the Decima Engine