book/23-cn-subculture-shader-rendering-deep-dive.md

N/A

23. 중국 최신 서브컬쳐 게임 Shader Rendering Deep Dive

공개된 기술 인터뷰/공식 공지(2024-2026)를 바탕으로 중국 최신 서브컬쳐 게임의 렌더링 패턴을 추출하고 Unity 6.3(6000.3) / URP 17.3.0에서 구현 가능한 심화 셰이더 구조로 정리한다

23. 중국 최신 서브컬쳐 게임 Shader Rendering Deep Dive (Unity 6.3 / URP 17.3.0)

이 문서는 “중국 최신 서브컬쳐 게임의 비주얼 감각”을 URP에서 구현 가능한 셰이더 아키텍처로 옮기기 위한 심화 가이드입니다.

신규 심화 시리즈(28~48) 안내

기존 23~27장을 유지한 상태에서, 별도 독립 시리즈로 28~48장을 추가했습니다.

분량을 분리한 확장 문서(2026-02-18 업데이트):

핵심 원칙:

  • 특정 게임의 내부 코드를 역공학/복제하지 않는다.
  • 공개된 기술 발표/공식 공지에서 확인 가능한 사실만 기반으로 삼는다.
  • 구현은 URP 계약(Forward/Deferred/DepthNormals/MotionVectors)을 지키는 방식으로 설계한다.

기준 시점: 2026-02-18

23.0 최신 타이틀 스냅샷(공개 정보 기준)

타이틀 공개 상태(절대 날짜) 공개 기술 단서(요약) 이 챕터에서 가져오는 설계 포인트
Wuthering Waves 공식 Release Trailer 설명 기준 글로벌 런치: 2024-05-22(PT) Unreal Engine 인터뷰에서 모바일 deferred one-pass, SSR/GTAO 리프로젝션, 캐릭터 독립 조명 파이프라인, 얼굴 그림자 텍스처, 빌보드/임포스터 식생 최적화 언급 캐릭터-배경 분리 조명, 리프로젝션 친화 셰이더, 대규모 필드 최적화
Infinity Nikki 공식 FAQ 기준 출시: 2024-12-05 10:00(UTC+8) Unreal Engine 인터뷰에서 OIT 재구성, Virtual Heightfield Mesh + VT 최적화, 주얼리 머티리얼(큐브맵/굴절), 수백만 식생 GPU-driven 최적화. Silicon Studio 발표에서 Enlighten GI 파트너십 확인 투명/의상 처리, 액세서리 하이라이트, 대규모 월드에서의 GI/성능 균형
Zenless Zone Zero PS5 버전 출시 공지: 2024-07-04. Xbox 버전 발표 글: 2025-06-06 Xbox Wire 글에서 DXR 반사, HDR, 네이티브 4K/60FPS 언급 서브컬쳐 스타일 + 하이엔드 플랫폼 반사/톤 대응
Arknights: Endfield 공식 공지 기준 글로벌 출시: 2026-01-22 11:00(UTC+8) 테크니컬 테스트 공지에서 테스트 빌드/비주얼 변경 가능성 명시 라이브 이전 단계에서 셰이더 품질축/검증 루틴을 먼저 고정

중요
아래 기술 설계는 “공개된 특징 + URP 실무 패턴”의 결합입니다.
특정 타이틀의 내부 파이프라인을 단정하지 않고, 재현 가능한 형태로 추상화합니다.

23.1 서브컬쳐 셰이더 품질축(아트 피드백이 빨라지는 기준)

중국 최신 서브컬쳐 타이틀을 따라갈 때, 품질은 보통 아래 8축에서 결정됩니다.

  1. 얼굴 가독성: 광원 각도 변화에서도 눈/코/입 명암이 의도대로 유지되는가
  2. 헤어 하이라이트 방향성: 카메라/광원 이동 시 “가닥 결”이 살아있는가
  3. 의상 재질 분리감: 천/가죽/금속/보석이 한 화면에서 명확히 분리되는가
  4. 배경 대비 캐릭터 우선순위: 복잡한 월드에서도 캐릭터가 묻히지 않는가
  5. 야간/네온 장면 안정성: 과포화/밴딩/플리커 없이 스타일이 유지되는가
  6. 반투명 안정성: 머리카락/레이스/장식의 정렬 아티팩트가 허용 가능한가
  7. 시간축 안정성(Temporal): TAA/모션블러 환경에서 잔상/노이즈가 통제되는가
  8. 멀티플랫폼 일관성: 모바일~콘솔까지 룩이 크게 붕괴하지 않는가

23.2 URP 기준 전체 렌더링 계약(이 챕터의 기본 뼈대)

서브컬쳐 셰이더도 결국 URP 계약 위에서 돌아갑니다.

  • Forward 기반: UniversalForward, ShadowCaster, DepthOnly, Meta
  • 화면기반 효과 사용 시: DepthNormals
  • TAA/모션블러/리프로젝션: MotionVectors (+ XR이면 XRMotionVectors)
  • Deferred 프로젝트: UniversalGBuffer 추가

관련 상세 계약:

23.3 아키텍처: Stylized-PBR Bridge

서브컬쳐 룩을 안정적으로 유지하려면 “완전 toon” 또는 “완전 PBR” 한쪽 극단보다, 아래 브리지 구조가 실무에서 유리합니다.

Parse error on line 1:
flowchart TD  A[Mat
^
Expecting 'NEWLINE', 'SPACE', 'GRAPH', got 'ALPHA'

핵심 아이디어:

  • 물리 기반 입력(노말, 거칠기, AO)은 유지한다.
  • 최종 라이트 전달 함수(램프, 스텝, 림, 페이스 SDF)는 아트 주도적으로 교체한다.
  • 시간축 안정성을 위해 노이즈/디더 패턴은 프레임 안정형으로 설계한다.

23.4 핵심 셰이딩 함수(URP/HLSL 실전 골격)

아래 코드는 “서브컬쳐 하이브리드 조명”의 최소 골격입니다.

HLSL
struct SubcultureParams
{
    half rampWeight;          // 0 = PBR diffuse, 1 = stylized ramp
    half specStylizeWeight;   // 0 = GGX, 1 = hard spec
    half rimPower;
    half rimIntensity;
    half shadowLift;          // 그림자 영역 들어올림
};

half EvalRamp(half ndl, TEXTURE2D_PARAM(rampTex, rampSmp))
{
    half2 uv = half2(saturate(ndl), 0.5h);
    return SAMPLE_TEXTURE2D(rampTex, rampSmp, uv).r;
}

half3 EvalHybridDiffuse(half3 baseColor, half ndl, half ao, SubcultureParams p,
                        TEXTURE2D_PARAM(rampTex, rampSmp))
{
    half pbr = saturate(ndl) * ao;
    half toon = EvalRamp(ndl, TEXTURE2D_ARGS(rampTex, rampSmp));
    half lit = lerp(pbr, toon, p.rampWeight);
    lit = max(lit, p.shadowLift);
    return baseColor * lit;
}

half EvalStylizedSpec(half3 N, half3 V, half3 L, half smoothness, SubcultureParams p)
{
    half3 H = normalize(L + V);
    half ndh = saturate(dot(N, H));
    half ggxLike = pow(ndh, lerp(16.0h, 128.0h, smoothness));
    half hardSpec = smoothstep(0.75h, 0.9h, ndh);
    return lerp(ggxLike, hardSpec, p.specStylizeWeight);
}

half3 EvalRim(half3 N, half3 V, half3 rimColor, SubcultureParams p)
{
    half fres = pow(1.0h - saturate(dot(N, V)), p.rimPower);
    return rimColor * fres * p.rimIntensity;
}

실무 팁:

  • shadowLift를 0보다 조금 올리면 얼굴/의상의 암부 뭉침이 줄어든다.
  • 스페큘러는 “강도”보다 “형태”를 먼저 잡아야 서브컬쳐 룩이 안정된다.

23.5 얼굴 셰이더: SDF/마스크 기반 제어

얼굴은 일반 PBR보다 별도 계약을 두는 편이 안정적입니다.

23.5.1 얼굴 명암 최소 패턴

HLSL
// _FaceShadowTex: 좌우 비대칭을 포함한 얼굴 음영 마스크/SDF
half EvalFaceLit(half2 faceUV, half3 headForwardWS, half3 headRightWS, half3 lightDirWS)
{
    half mask = SAMPLE_TEXTURE2D(_FaceShadowTex, sampler_FaceShadowTex, faceUV).r;

    // 얼굴 로컬 축 기준 광원 방향성 투영
    half front = dot(headForwardWS, lightDirWS); // 정면/역광
    half side  = dot(headRightWS,   lightDirWS); // 좌/우 편차

    // 아트 파라미터로 임계값을 제어
    half threshold = saturate(_FaceShadowBias + front * _FaceShadowFrontScale + abs(side) * _FaceShadowSideScale);
    return step(threshold, mask);
}

23.5.2 필수 안정화

  • 헤드 로컬 축 기준으로 계산(월드 축 고정 금지)
  • 미러 UV 캐릭터는 좌우 반전 케이스를 별도 체크
  • 얼굴 전용 스무딩/노멀 보정을 헤어/의상과 분리

23.6 헤어 셰이더: 이중 하이라이트 + 가닥 방향

헤어는 “투명도”보다 “방향성 하이라이트”가 우선입니다.

HLSL
half EvalHairLobe(half3 T, half3 V, half3 L, half shift, half power)
{
    half3 H = normalize(V + L);
    half th = dot(normalize(T + shift * H), H);
    return pow(saturate(th * 0.5h + 0.5h), power);
}

half3 EvalHairSpec(half3 tangentWS, half3 V, half3 L)
{
    half lobe1 = EvalHairLobe(tangentWS, V, L, _HairShift1, _HairPower1);
    half lobe2 = EvalHairLobe(tangentWS, V, L, _HairShift2, _HairPower2);
    return _HairSpecColor1.rgb * lobe1 + _HairSpecColor2.rgb * lobe2;
}

권장:

  • 밝은 밴드 1개 + 얇은 보조 밴드 1개(이중 로브)
  • 가닥 흐름(탱전트 맵/버텍스 탱전트)을 하이라이트 계산의 1급 입력으로 사용

23.7 반투명/장식 재질: OIT와 보석 표현

공개 자료에서 Infinity Nikki는 OIT 및 주얼리 재질(큐브맵/굴절) 최적화를 명시했습니다.
URP에서도 아래 방식으로 재현할 수 있습니다.

23.7.1 Weighted Blended OIT(개념)

HLSL
// 개념식
accumColor += src.rgb * src.a * weight;
accumAlpha += src.a * weight;
final.rgb = accumColor / max(accumAlpha, 1e-4);
final.a   = saturate(accumAlpha);

적용 순서:

  1. 반투명 전용 누적 RT 구성(RenderGraph)
  2. 반투명 오브젝트를 OIT pass로 누적
  3. 합성 pass에서 카메라 컬러와 결합

23.7.2 보석/액세서리 표현

  • 큐브맵 반사 + 뷰 의존 프레넬
  • 얇은 가짜 굴절(offset 샘플)로 광택 강조
  • 캐릭터 조명과 분리된 하이라이트 강도 보정 슬롯 제공

23.8 캐릭터-배경 분리 조명(서브컬쳐에서 매우 중요)

Wuthering Waves 공개 인터뷰의 “독립 캐릭터 조명 파이프라인” 단서를 URP에서 구현하면 보통 아래 구조가 됩니다.

  1. 캐릭터를 Rendering Layer 또는 stencil로 마스킹
  2. 캐릭터 전용 조명 보정(암부 리프트/림/스페큘러 스케일) 적용
  3. 배경은 물리 기반을 더 유지하고 캐릭터는 스타일 보정 강도를 높임

간단한 후처리 측 골격:

C#
// RendererFeature 개념 코드
// 1) CharacterMask pass
// 2) ColorGrade pass(scene LUT)
// 3) CharacterSelectiveGrade pass(character LUT + mask)

이 구조를 쓰면 “월드 톤은 유지하면서 캐릭터만 읽기 좋게” 만들기 쉽습니다.

23.9 Deferred vs Forward 선택 매트릭스(서브컬쳐 프로젝트용)

프로젝트 조건 권장
오픈월드 + 복수 화면효과(SSR/GTAO/리프로젝션) + 많은 불투명 재질 Opaque는 Deferred, 투명/헤어/특수는 Forward
모바일 비중 높고 재질 수 제한적 Forward+ 중심 + 필요한 효과만 선택적 활성화
2D/3D 혼합 서브컬쳐 UI·연출 비중 큼 Forward 기반으로 단순화, 캐릭터 전용 보정 pass 강화

결정 전에 반드시 확인:

23.10 변형(Variant)과 성능 운영

서브컬쳐 셰이더는 기능이 늘면서 variant 폭발이 쉽게 발생합니다.

운영 규칙:

  1. 기능을 “캐릭터 핵심/상황별/디버그” 3등급으로 분류
  2. 핵심 외 키워드는 material-local(shader_feature_local) 우선
  3. 모바일 tier에서는 얼굴/헤어/의상 중 비용 높은 항목부터 스케일 다운
  4. MotionVectors/DepthNormals는 “품질 옵션”이 아니라 “기능 계약”으로 취급

23.11 구현 순서(권장 스프린트)

  1. Pass 계약 고정: Forward/Shadow/Depth/DepthNormals/MotionVectors
  2. 하이브리드 조명 도입: Ramp + Spec + Rim
  3. 얼굴 셰이더 분리: Face SDF/마스크
  4. 헤어 2로브 하이라이트: 탱전트 기반
  5. 반투명/OIT 적용: 의상/장식
  6. 캐릭터-배경 분리 보정: 마스크 + 선택적 LUT
  7. Temporal 검증: TAA/모션블러에서 고스팅/플리커 점검
  8. 멀티플랫폼 튜닝: 품질 tier별 키워드/RT 비용 최적화

23.12 디버깅 체크리스트(서브컬쳐 전용)

  • 얼굴 명암이 광원 회전에 따라 튀면:
    • 얼굴 로컬 축 계산, SDF 임계값, 노말 보정 순서 점검
  • 헤어가 플라스틱처럼 보이면:
    • 이중 로브의 폭/강도 분리, 탱전트 입력 정확도 점검
  • 반투명 장식이 깜빡이면:
    • OIT 누적/합성 순서, depth write/test 상태 점검
  • TAA에서 외곽선/하이라이트가 번지면:
    • MotionVectors pass 소비 여부, 하이라이트 임계값 완화 점검
  • 야간 네온에서 피부가 뜨면:
    • 캐릭터 전용 LUT 강도와 shadowLift 상한점검

23.13 공개 소스(작성 근거)