Unity 전체 링크
셰이딩 모드를 Shaded Wireframe으로 설정하자.
그리고 쿼드를 생성하면 쿼드를 만들고 있는 Wireframe이 보인다.
모든 메쉬는 삼각형의 집합으로 구성되어 있는데,
컴퓨터 그래픽이 삼각형의 모서리에 있는 꼭짓점에서 작업을 하기 때문이다.
이제 쿼드를 절차적 메시로 만들어보자.
참고로 쿼드의 정점의 개수는 6개가 아닌 4개다.
즉, 삼각형 2개를 만드는 것과 쿼드 1개를 만드는 것은 다르다.
정점이 6개인 Quad와 정점이 4개인 Quad의 차이점을 알아보자.
정점이 6개인 쿼드와 4개인 쿼드 만들기
절차적 메시로 삼각형을 만들 수 있으니 좌표를 적절히 변경하여 아래의 쿼드를 만들자.
실제 쿼드처럼 중심 좌표에 기즈모가 생기도록 좌표를 조절하였다.
void setMeshData()
{
vertices = new Vector3[] {
new Vector3(-0.5f, 0.5f, 0),
new Vector3(0.5f, 0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
new Vector3(0.5f, 0.5f, 0),
new Vector3(0.5f, -0.5f, 0),
};
triangles = new int[] { 0, 1, 2, 3, 4, 5 };
}
vertices와 triangles를 아래처럼 바꾸면 4개의 정점으로 쿼드를 만든다.
void setMeshData()
{
vertices = new Vector3[] {
new Vector3(-0.5f, 0.5f, 0),
new Vector3(0.5f, 0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
new Vector3(0.5f, -0.5f, 0),
};
triangles = new int[] { 0, 1, 2, 2, 1, 3 };
}
좌표가 아래와 같은 순서대로 만들어졌으므로 triangles에 시계 방향인 0 → 1 → 2 와 2 → 1 → 3으로 넣어준다.
참고로 정점이 4개라고 해서 아래와 같이 triangles에 넣으면 안된다.
triangles = new int[] { 0, 1, 2, 3 };
아래의 에러가 발생하며, triangles의 배열 크기는 반드시 3의 배수여야 한다.
→ Failed setting triangles. The number of supplied triangle indices must be a multiple of 3.
이제 게임을 실행해보자.
순서대로 6개의 정점, 4개의 정점, 유니티 Quad지만 별 차이가 없어보인다.
Z 좌표 변경하기
두 쿼드의 차이를 구분하기 위해 빈 오브젝트에 ChangeZValue를 추가한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeZValue : MonoBehaviour
{
public float zValue;
public static ChangeZValue Instance;
void Awake()
{
Instance = this;
}
}
그리고 ProceduralQuad6, 4의 Start에 있는 코드를 Update로 분리한다.
void Start()
{
mesh = GetComponent<MeshFilter>().mesh;
}
void Update()
{
setMeshData();
createProceduralMesh();
}
그리고 각 스크립트의 verteces의 첫번째 원소에 0을 zValue로 수정한다.
vertices = new Vector3[] {
new Vector3(-0.5f, 0.5f, ChangeZValue.Instance.zValue),
게임을 실행하고 z 좌표를 변경해보자.
왼쪽의 Quad6는 빛에 의한 연산이 각각의 삼각형에 적용되고, Quad4는 그라데이션이 나타나게 된다.
즉, 정점의 좌표 vertices와 triangles에 어떻게 넣어주냐에 따라 유니티가 노멀을 계산하는 방법이 다르다.
각 정점은 하나의 정보만 가질 수 있으므로 Quad4는 그라데이션이 적용되는 반면,
Quad6은 각각의 정점에서 노멀을 계산하므로 회색 면과 흰색 면이 나뉜다.
유니티에서 제공하는 쿼드는 정점이 4개이므로 vertices가 공유되고 있을 것이다.
전체 코드는 아래와 같다.
ProceduralQuad6.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class ProceduralQuad6 : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
void Start()
{
mesh = GetComponent<MeshFilter>().mesh;
}
void Update()
{
setMeshData();
createProceduralMesh();
}
void setMeshData()
{
vertices = new Vector3[] {
new Vector3(-0.5f, 0.5f, ChangeZValue.Instance.zValue),
new Vector3(0.5f, 0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
new Vector3(0.5f, 0.5f, 0),
new Vector3(0.5f, -0.5f, 0),
};
triangles = new int[] { 0, 1, 2, 3, 4, 5 };
}
void createProceduralMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
ProceduralQuad4.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class ProceduralQuad4 : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
void Start()
{
mesh = GetComponent<MeshFilter>().mesh;
}
void Update()
{
setMeshData();
createProceduralMesh();
}
void setMeshData()
{
vertices = new Vector3[] {
new Vector3(-0.5f, 0.5f, ChangeZValue.Instance.zValue),
new Vector3(0.5f, 0.5f, 0),
new Vector3(-0.5f, -0.5f, 0),
new Vector3(0.5f, -0.5f, 0),
};
triangles = new int[] { 0, 1, 2, 2, 1, 3 };
}
void createProceduralMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
ChangeZValue.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeZValue : MonoBehaviour
{
public float zValue;
public static ChangeZValue Instance;
void Awake()
{
Instance = this;
}
}
위의 실행결과는 아래의 unitypackage에서 확인 가능하다.
Unity Plus:
Unity Pro:
Unity 프리미엄 학습:
댓글