본문 바로가기
개발/Unity

유니티 - 절차적 메시의 양면 렌더링 (Double Sided Rendering with Procedural Mesh)

by 피로물든딸기 2022. 10. 30.
반응형

Unity 전체 링크

 

절차적 메시로 만든 결과를 아래에서 보면 메시가 사라진다.

 

평면의 양면 렌더링에서는 쉐이더에서 cull off를 설정하였다.

 

여기서는 메시를 한번 더 그리면 된다.

시계 방향으로 triangle을 만들어줄 때 정면에서 보이므로, 반시계 방향을 추가하면 된다.

정점은 그대로이므로 vertices 변경하지 않고 triangles만 넣으면 된다.

0 → 1 → 2 가 시계 방향이므로, 반시계 방향인 2 → 1 → 0을 배열에 추가하자. (1 → 0 → 2 등 모든 반시계 방향 가능)

triangles = new int[] { 0, 1, 2, 2, 1, 0 };

 

게임을 실행해서 확인해보면 양면으로 보이긴 하지만 까맣게 변하게 된다.

 

vertex에는 여러 정보가 있는데 vertex 3개로 두 개의 평면을 만들었기 때문에 생기는 현상이다.

따라서 중복되지만 vertex를 한 세트 더 만들고, triangles의 좌표도 수정한다. (반시계 방향 5 → 4 → 3)

    void setMeshData(float size)
    {
        float g = Mathf.Sqrt(3.0f) / 6.0f * size;
        vertices = new Vector3[] {
            new Vector3(-0.5f * size, 0, -g) + offset,
            new Vector3(0, 0, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset,
            new Vector3(0.5f * size, 0, -g) + offset,

            new Vector3(-0.5f * size, 0, -g) + offset,
            new Vector3(0, 0, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset,
            new Vector3(0.5f * size, 0, -g) + offset};

        triangles = new int[] { 0, 1, 2, 5, 4, 3};
    }

 

이제 게임을 실행해서 Procedural Mesh의 각도를 변경해보자. 

양면으로 렌더링이 된 것을 알 수 있다.

 

전체 코드는 아래와 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class ProceduralTriangle : MonoBehaviour
{
    public float size = 1.0f;
    public Vector3 offset = new Vector3(0, 0, 0);

    Mesh mesh;
    Vector3[] vertices;
    int[] triangles;

    void OnValidate()
    {
        if (mesh == null) return;

        if(size > 0 || offset.magnitude > 0)
        {
            setMeshData(size);
            createProceduralMesh();
        }
    }

    void Start()
    {
        mesh = GetComponent<MeshFilter>().mesh;

        setMeshData(size);
        createProceduralMesh();
    }

    void setMeshData(float size)
    {
        float g = Mathf.Sqrt(3.0f) / 6.0f * size;
        vertices = new Vector3[] {
            new Vector3(-0.5f * size, 0, -g) + offset,
            new Vector3(0, 0, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset,
            new Vector3(0.5f * size, 0, -g) + offset,

            new Vector3(-0.5f * size, 0, -g) + offset,
            new Vector3(0, 0, Mathf.Sqrt(3.0f) / 2.0f * size - g) + offset,
            new Vector3(0.5f * size, 0, -g) + offset};

        triangles = new int[] { 0, 1, 2, 5, 4, 3};
    }

    void createProceduralMesh()
    {
        mesh.Clear();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();

        Destroy(this.GetComponent<MeshCollider>());
        this.gameObject.AddComponent<MeshCollider>();
    }
}

 

위의 실행결과는 아래의 unitypackage에서 확인 가능하다.

ProceduralTriangle_DoubleSidedRendering.unitypackage
0.00MB

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글