Unity Grass Instancer
요약
본 문서는 Unity 환경에서 C# 스크립트와 셰이더를 활용하여 GPU 인스턴싱 방식으로 잔디(또는 기타 메쉬)를 효율적으로 렌더링하는 방법을 설명합니다. 단순 인스턴싱부터 오클루전/프리즘 컬링, 무한 잔디 렌더링에 이르기까지 다양한 성능 최적화 접근 방식을 단계별로 제시하고 있습니다.
핵심 포인트
- GPU 인스턴싱을 활용하여 대규모 메쉬(잔디)를 효율적으로 렌더링합니다.
- 프리즘 컬링, 청킹, 오클루전 컬링 등 여러 최적화 기법이 포함되어 성능 향상을 추구합니다.
- Unity의 다양한 렌더 파이프라인(URP/HDRP)에서 사용 가능하며, 스크립트와 셰이더 설정이 필요합니다.
- 무한 잔디 렌더링 기능을 구현하여 넓은 영역에 걸쳐 자연스러운 표현을 지원합니다.
Unity Grass Instancer
C# 스크립트와 셰이더를 포함하여 GPU 인스턴싱(instanced) 잔디(또는 다른 메쉬)
Unity 2020.3.4f1 및 HDRP 10.4.0으로 제작됨
Unity 2022.3.40f1 및 URP 14.0.11 | Unity 6 및 URP 17.0.3에서도 테스트 완료

비디오 시연:
프로젝트는 6가지 접근 방식을 포함합니다
(단계가 올라갈수록 성능 향상)
- (구버전)
DrawMeshInstanced및DrawMeshInstancedIndirect를 사용한 단순 인스턴싱 렌더링, 최적화 없음 (자세히 읽기) - 프리즘 컬링(Frustum culled) 접근 방식 (자세히 읽기)
- 청킹(chunking)을 사용한 프리즘 컬링 접근 방식 (자세히 읽기)
- 프리즘 컬링 및 청킹을 사용한 오클루전 컬링(Occlusion culled) 접근 방식 (자세히 읽기)
- 모든 다른 방식을 확장하는 고성능 접근 방식 (자세히 읽기)
- 무한 잔디 렌더링 (자세히 읽기)
요구 사항
- 모든 렌더 파이프라인 (URP 및 단순 HDRP 셰이더만 제공)
- 지형(terrain)
- SRP Batcher 비활성화 필요
- 머티리얼에서 GPU 인스턴싱 활성화

설정
- 원하는 접근 방식의 3D 모델과 스크립트를 프로젝트로 드래그합니다.
- 임포트 설정에서 3D 모델의
스케일 팩터(scale factor)를100으로 조정합니다. - 새 머티리얼을 생성하고 셰이더를 할당합니다.
- 스크립트를 빈 게임 오브젝트에 부착합니다.
- 드로우 기즈모(draw gizmos) 활성화
- 지형의 중앙에 위치시킵니다.
- 지형 크기에 맞게 범위를 구성합니다.
Scene Setup
중요 설정 (Important settings)
참고: 모든 접근 방식에 적용되는 설정은 아닙니다.
Instances- 인스턴스화될 수 있는 잔디 잎의 양입니다. 2의 거듭제곱(powers of 2)과 함께 사용할 때 가장 좋습니다.True instance count- 스크립트에 의해 설정됩니다. 일부는 건너뛸 수 있으므로 실제 인스턴스의 총 개수를 포함합니다. 예를 들어 지형이 너무 가파른 경우입니다.Visible instance count- 스크립트에 의해 설정됩니다. 현재 보이는, 즉 렌더링되고 있는 인스턴스의 양을 포함합니다.Scale min and scale max- 각 잔디 잎에 무작위 크기를 생성하는 데 사용됩니다.Ground layer- 지형의 레이어입니다.Chunk size- 청크의 크기(미터)입니다. 2의 거듭제곱과 함께 사용할 때 가장 좋습니다.Threads chunk render- 컴퓨트 셰이더에 설정된 스레드 그룹의 양입니다. 이 설정과 일치해야 합니다. 이 역시 2의 거듭제곱과 함께 사용할 때 가장 좋습니다.Depth bias- 샘플링된 깊이 텍스처에서 빼질 값입니다. 가려진(occluded) 청크의 컬링을 미세 조정하는 데 사용됩니다.
FAQ
인스턴스가 보이지 않아요? (Why can't I see any instances?)
여러 가지 이유가 있을 수 있습니다.
먼저 요구 사항 및 설정 섹션을 확인하세요.
메시(mesh)가 올바르게 스케일링되었는지 확인합니다.
임포트 설정에서 스케일 팩터를 필요에 맞게 조정하거나, 제공된 3D 모델을 사용하는 경우 100을 사용하십시오.
메시가 올바르게 배치되거나 회전되지 않았을 수도 있습니다:
모든 인스턴스가 보이지 않거나 검은색인 이유는 무엇인가요?
이것은 오브젝트를 수동으로 재질과 함께 배치했기 때문에 발생할 수 있습니다. 이는 셰이더가 렌더링을 위해 DrawMeshInstanced 및 DrawMeshinstancedIndirect 호출을 통해서만 제공되는 인스턴스 ID(instance ID)와 필요로 하기 때문에 작동하지 않습니다. 또한, 모든 인스턴스의 데이터를 포함하는 _trsBuffer는 시작 시에만 초기화되며 렌더링에 필요합니다.
또 다른 이유는 셰이더가 사용자의 렌더 파이프라인과 호환되지 않기 때문일 수 있습니다. 현재 저는 URP용 셰이더와 HDRP용 셰이더그래프만 제공합니다. HDRP 셰이더그래프는 인스턴스 ID 노드가 이전 버전에는 존재하지 않기 때문에 Unity 2021.2 이상에서만 작동합니다.
더 많은 문제가 있다면, 여기에 Github에 이슈를 열어주세요.
다음 작업/TODOs
- HDRP용 새 셰이더
- 기본 렌더 파이프라인용 새 셰이더
- README 파일 개선
자료
- 이 프로젝트는 GPU 인스턴싱(GPU instancing)에 대한 멋진 비디오를 보고 시작했습니다:
- Acerola의 유튜브 채널에서 잔디 렌더링에 대한 많은 정보를 찾았습니다: https://www.youtube.com/c/Acerola_t
- 저는 또한 제 쇼케이스에 그의 3D 모델을 사용하고 있습니다.
용어집 (제가 자주 사용하는 용어들)
TRS: 변환(Transformation), 회전(rotation) 및 크기(scale) 행렬._trsBuffer: 인스턴스들의 모든TRS 행렬을 담고 있으며, 셰이더 내부에서 배열처럼 접근할 수 있는 컴퓨트 버퍼_argsBuffer:DrawMeshInstancedIndirect를 위해 어떤 메시와 몇 개를 렌더링해야 하는지에 대한 정보를 담는 버퍼batch:DrawMeshInstanced를 위한변환 행렬들의 모음
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub GameDev의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기