Cascade Shadow Map 해상도 상향
ChosenPros
- 기존 파이프라인 그대로, 구현 비용 적음
Cons
- 메모리·대역폭 비용 증가, 캐릭터당 텍셀 보장 안 됨, 전체 씬 영향




로비 16명 한정 고품질 캐릭터 그림자 — Atlas 슬롯 + 마스크 방식으로 모바일 1024 해상도에서 실루엣 가독성을 확보.
URP 기본 캐스케이드 섀도우맵은 화면 전체를 한 장에 담아 캐릭터 1명당 할당되는 텍셀이 매우 적습니다. 그림자만의 영역을 분리해 캐릭터당 텍셀을 보장할 필요가 있었습니다.
Pros
Cons
Pros
Cons
Pros
Cons
Why Cascade Shadow Map 해상도 상향: 로비는 캐릭터가 단일 평면 위에 있어 깊이 비교가 주는 이점이 작은 반면, 16-bit depth + 256² 슬롯에서 acne·bias 튜닝 비용이 큽니다. 깊이 비교 자체를 제거하고 normalWS.y 기반 SlopeFade로 천장·벽 영향만 차단했습니다
RendererFeature가 BeforeRenderingOpaques 시점에 1024 atlas RT를 클리어하고 16개 슬롯에 각 캐스터 메쉬를 depth-only로 렌더링합니다. 캐스터별 union bounds 8 corner를 view space로 변환해 tight orthographic AABB를 만들어 슬롯 텍셀을 빠듯이 채웁니다. 리시버 셰이더는 _CharacterShadowVP[i]로 worldPos를 슬롯 UV로 변환하고, 클리어 값이 아닌 픽셀을 그림자로 판정합니다.
diagram: /images/projects/ovensmash/character-shadow-atlas/architecture.svg
diagram caption: Caster → Manager → AtlasPass → 글로벌 → Receiver Shader
캐릭터 루트에 부착하는 MonoBehaviour. 자식 SkinnedMeshRenderer만 자동 수집해 union bounds를 계산합니다. 본 애니메이션 때문에 bounds가 매 프레임 출렁이는 '펌핑'을 막기 위해 extents에 히스테리시스(확장 즉시 / 축소 lerp)를 적용하고, center는 즉시 추적해 이동 응답성은 유지했습니다.
CharacterShadowCaster.GetUnionBounds의 히스테리시스 부분 (Vector3.Max 후 Vector3.Lerp).씬 싱글톤이 캐스터를 Player/NPC로 분리 등록하고, 매 프레임 Player 전원 → 카메라 거리순 NPC 순서로 최대 16명을 선별합니다. 도메인 리로드 후 static 참조가 끊긴 경우 씬에서 재수집하는 복구 경로도 두었습니다.
이전 버전은 라이트 기울기로부터 그림자 수평 드리움 거리를 추정해 frustum을 정사각형 r로 키웠습니다. 이번에는 bounds 8 corner를 view space로 변환해 tight orthographic AABB(xMin/xMax/yMin/yMax)를 직접 계산하도록 바꿔, 같은 256² 슬롯 안에서 캐릭터 실루엣이 차지하는 텍셀을 최대화했습니다.
ComputeMatrices의 8-corner 루프와 Matrix4x4.Ortho(xMin, xMax, yMin, yMax, near, far).기존 깊이 비교(coord.z vs stored + bias)를 폐기하고 "아틀라스에 캐스터가 그려진 픽셀 = 그림자"로 단순화했습니다. reversed Z에서는 clear=0이므로 stored > 0이면 hit. _CharShadowBias 파라미터가 사라지고, normalWS.y 기반 SlopeFade로 천장·벽에 그림자가 새는 것을 막습니다.
EvalCharacterShadow의 stored 샘플링 + UNITY_REVERSED_Z 분기 hit 판정.


같은 텍스쳐 해상도로 그림자 퀄리티 보완