중국 엔지니어가 포팅 후 테스트 한 영상이다.
아무튼 관련 해서 유니티 엔진을 사용하는 고객사가 있기 때문에 2025년 3분기에 진행 할 내용들을 정리 해 봤다.
1. PBR 구현의 정확성 개선 방안
에너지 보존 검증: 언급된 에너지 보존 원칙이 핵심인데, 실제 구현에서 다음을 추가로 고려하면 좋을 것 같습니다:
Multi-scattering compensation 추가
높은 roughness에서 에너지 손실을 보정하는 것이 중요합니다. Heitz et al.의 연구에 따르면 단일 산란 모델은 roughness가 증가할수록 최대 40%의 에너지를 잃을 수 있습니다. 이를 해결하기 위한 방법:
// Fdez-Agüera의 에너지 보존 BRDF 구현 예시
vec3 Fr = max(vec3_splat(1.0 - roughness), F0) - F0;
vec3 k_S = F0 + Fr * pow(1.0 - NoV, 5.0);
vec3 FssEss = k_S * f_ab.x + f_ab.y; // f_ab는 사전 계산된 LUT
- Energy Compensation LUT: Kulla-Conty 방식의 2D/3D LUT 사용 고려
- Analytical Approximation: 실시간 성능을 위해 Davide Sforza의 분석적 근사법 활용
White Furnace Test
Enterprise PBR 모델에서 제시한 검증 방법
- Uniform 환경광(모든 방향에서 1.0)에서 albedo 1.0일 때 완전 백색 출력 확인
- 에너지 보존 위반 시 시각적으로 어두워지는 문제 발생
2. 환경광 반사 품질 개선
Unity와 UE의 반사 품질 차이점에 대한 구체적 개선 방안:
Importance Sampling 구현
Epic Games의 접근법을 Unity에 적용:
// Hammersley 시퀀스를 이용한 중요도 샘플링
vec2 Hammersley(uint i, uint N) {
float E1 = fract((float)i / (float)N);
float E2 = float(ReverseBits32(i)) * 2.3283064365386963e-10;
return vec2(E1, E2);
}
// GGX 중요도 샘플링
vec3 ImportanceSampleGGX(vec2 Xi, float roughness, vec3 N) {
float a = roughness * roughness;
float phi = 2.0 * PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
// ... tangent space to world space 변환
}
Split-sum Approximation 개선
Brian Karis의 방법론
- Pre-filtered environment map: 각 mip 레벨별로 다른 roughness 적용
- BRDF Integration LUT: 16비트 정밀도 사용 권장
3. Unity 6 + Rendering Graph 활용
Unity 6의 새로운 기능들을 활용한 최적화
Deferred+ 렌더링
- Cluster-based light culling: 타일 기반 대신 3D 클러스터 사용
- GPU Resident Drawer 통합: BatchRendererGroup API 자동 활용
- 성능 향상: 많은 광원이 있는 씬에서 Forward+ 대비 개선
GPU Resident Drawer
실제 테스트 결과
- CPU 워크로드 50% 감소 (대규모 복잡한 씬)
- Draw call 대폭 감소: 35,000개 오브젝트에서 128개로 감소
- 메모리 오버헤드: 약 100MB 증가
- GPU Occlusion Culling: 이전 프레임의 depth buffer 활용
설정 방법:
// GPU Resident Drawer 활성화 확인
using UnityEngine.Rendering;
public class GPUResidentDrawerChecker : MonoBehaviour {
void Start() {
if (GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset urpAsset) {
bool isEnabled = urpAsset.gpuResidentDrawerMode ==
GPUResidentDrawerMode.InstancedDrawing;
Debug.Log("GPU Resident Drawer: " + isEnabled);
}
}
}
4. SubsurfaceProfile 최적화
Separable SSS 구현
Jorge Jimenez의 Separable SSS 기법
주요 특징:
- 2-pass screen-space convolution: 기존 12-pass 대신 2-pass로 처리
- 실행 시간: 프레임당 0.5ms 미만
- 샘플링: Jittering 전략으로 픽셀당 7개 샘플만 필요
// Separable SSS 커널 적용
float4 SSSSBlurPS(float2 texcoord : TEXCOORD0,
float2 pixcoord : VPOS) : COLOR0 {
// 첫 번째 패스: 수평 블러
// 두 번째 패스: 수직 블러
float sssWidth = subsurfaceProfile.scatterDistance;
// Jittered sampling으로 aliasing 감소
float2 offset = getJitteredOffset(pixcoord);
// 가우시안 커널 대신 profile 기반 커널 사용
return performSeparableConvolution(texcoord, offset, sssWidth);
}
Transmission LUT 캐싱
- 사전 계산: 다양한 thickness 값에 대한 투과율 저장
- 실시간 lookup: thickness map과 결합하여 사용
5. 성능 최적화 제안
Shader Variant 최소화
// shader_feature 사용 예시
#pragma shader_feature_local _ANISOTROPY
#pragma shader_feature_local _CLEARCOAT
#pragma shader_feature_local _SUBSURFACE
// 조건부 컴파일로 불필요한 계산 제거
#ifdef _ANISOTROPY
// Anisotropic GGX 계산
#else
// 기본 GGX 계산
#endif
Mobile 최적화
- Half precision 적극 활용:
half3 color = half3(0, 0, 0);
half roughness = saturate(half(_Roughness));
half metallic = saturate(half(_Metallic));
- Simplified BRDF 모델 옵션 제공:
#if defined(SHADER_API_MOBILE)
// Mobile용 간소화된 BRDF
half3 brdf = SimplifiedGGX(N, V, L, roughness);
#else
// Desktop용 전체 BRDF
half3 brdf = BRDF_GGX(N, V, L, roughness, F0);
#endif
6. Hair 셰이딩 개선
Marschner 모델 구현에 추가로:
- Dual scattering approximation: 더 사실적인 금발/밝은 색 머리카락
- Azimuthal roughness: TT lobe의 glint 효과 개선
7. 검증 도구 개선
픽셀 단위 비교를 위한 추가 도구:
- A/B test viewer: Unity 내에서 UE 결과와 실시간 비교
- Difference visualization: 차이를 heat map으로 시각화
- Component-wise debugging: Diffuse/Specular/Transmission 각각 독립적 검증
8. ASE 대안 고려
ASE 의존성을 줄이기 위해:
- Shader Graph Custom Function Node 활용
- Better Shaders 같은 더 가벼운 대안 고려
- 핵심 로직을 독립적인 .hlsl 라이브러리로 분리
'UNITY3D' 카테고리의 다른 글
Unity 6.2.1 HDRP vs URP 셰이더 코드 비교 연구 (1) | 2025.09.07 |
---|---|
MagicaCloth2 Dynamic Optimizer (0) | 2025.07.22 |
고객사와 함께 읽는 울티밋 가이드 프로파일링 유니티 (4) | 2025.07.08 |
DirectBRDF_DualLobeSpecular (1) | 2025.06.20 |
유니티 6.1 인스턴싱 로컬 키워드 추가 리스트. (0) | 2025.06.04 |