[유니티] 절차적 지형 생성 1 - Perlin noise를 이용한 지형 생성

11752 단어 PCG유니티UnityPCG

펄린 노이즈를 이용해서 지형 생성

이전 포스팅에서 학습한 Perlin noise를 이용하여 Height 값에 따라 블록을 배치한 모습

겉보기엔 괜찮은 지형이 생성되었으나 메모리 낭비가 너무 심하다.

큐브를 생성한 다음 측정한 FPS

아무것도 하지 않았지만 FPS가 약 20으로 현저히 낮은 수치를 기록하고있다.

FPS가 낮은 이유는 큐브 오브젝트가 6면을 모두 메쉬로 채우기 때문인데 이를 해결하기 위해서는 보이지 않는 면을 컬링해야한다.


메쉬 생성

Instantiate(cube, new Vector3(x, y, z), Quaternion.identity);
기존의 큐브를 생성하는 코드를 지우고 아래의 메쉬를 생성하는 코드로 바꿔주었다.

Vector3[] vertices = {
    new Vector3 (0, 0, 0),
    new Vector3 (1, 0, 0),
    new Vector3 (1, 1, 0),
    new Vector3 (0, 1, 0),
    new Vector3 (0, 1, 1),
    new Vector3 (1, 1, 1),
    new Vector3 (1, 0, 1),
    new Vector3 (0, 0, 1),
};
int[] triangles = {
    0, 2, 1, //face front
    0, 3, 2,
    2, 3, 4, //face top
    2, 4, 5,
    1, 2, 5, //face right
    1, 5, 6,
    0, 7, 4, //face left
    0, 4, 3,
    5, 4, 7, //face back
    5, 7, 6,
    0, 6, 7, //face bottom
    0, 1, 6
};
Mesh mesh = GetComponent<MeshFilter>().mesh;

그리고 주변에 메쉬와 붙어있는 오브젝트가 있는지 확인하여 오브젝트가 없는 경우에만 메쉬를 생성하게끔 만들었다.

FPS가 75로 많이 올랐으나 여기서 한 단계 더 나아가서 각각의 메쉬들을 하나의 메쉬로 합치면 FPS를 더 높일 수 있다.


메쉬 합치기

각각의 메쉬들을 하나로 합치기 위해 유니티에서 제공하는 CombineInstance 기능을 사용한다.

CombineInstance[] combine = new CombineInstance[meshFilters.Length];

    for (int i = 0; i < meshFilters.Length; i++)
    {
        combine[i].mesh = meshFilters[i].sharedMesh;
        combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
        meshFilters[i].gameObject.SetActive(false);
    }
meshFilter.mesh.CombineMeshes(combine);

자식 개체에서 메쉬를 가져와 CombineInstance 배열에 추가하고 CombineMeshed 함수를 이용해 하나의 메쉬로 합쳐주었다.

이러한 최적화 과정을 거치면 처음 큐브 오브젝트와 비교했을 때 상당히 높아진 FPS 수치를 확인할 수 있다.


최종 결과


참고한 사이트

https://minpro-tech.tistory.com/68
https://youtu.be/Nj8gt_92c-M
https://bbtarzan12.github.io/Voxel-Part-1/
https://ordinarybk.tistory.com/entry/Unity3D-%EC%B5%9C%EC%A0%81%ED%99%94%EB%A5%BC-%EC%9C%84%ED%95%9C-CombineMesh

좋은 웹페이지 즐겨찾기