유니티 마우스 클릭 이동 방법 – 오늘은 유니티 C# 스크립트를 이용하여 마우스 클릭에 의한 플레이어 캐릭터의 이동 및 회전을 구현해 보겠습니다. 다음은 결과물의 영상입니다.클릭 앤 무브 작동 영상

위와 같은 동작을 위해 필요한 유니티 C# 클래스는 단 하나입니다. ClickToMove.cs 라는 이름의 모노비헤이비어 기반의 클래스를 아래와 같은 방법으로 만든 뒤, 플레이어 캐릭터 역할을 하는 게임 오브젝트에 붙여 넣으면 바로 실행됩니다.

다음은 코드를 작성하는 방법에 대한 설명입니다.

ClickToMove 유니티 C# 스크립트 생성

우선 유니티에서 C# 스크립트를 하나 만들고 이름을 ClickToMove 라고 변경하였습니다. 이 스크립트에서는 Start() 메소드를 사용하지 않을 것이므로 Update() 를 제외하고는 일단 지웠습니다. (그냥 놔두셔도 물론 됩니다.)

필드 선언

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour{
    public float movementSpeed = 10f;
    public float rotationSpeed = 10f;
    private void Update(){
 
    }
}

제일 먼저 플레이어 캐릭터의 이동 속도 및 마우스 클릭 지점으로의 회전 속도를 지정하기 위한 변수 두 개를 선언하였습니다.  movementSpeed 는 이동 속도를, rotationSpeed 는 회전 속도를 나타냅니다. 각각 기본 값 10f 를 부여하였고, 이는 나중에 얼마든지 변경 가능합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour{
    public float movementSpeed = 10f;
    public float rotationSpeed = 10f;
    private Vector3 destinationPoint;
    private void Update(){ 
    }
}

다음으로 이동 목표 지점의 좌표를 저장할 변수 destinationPoint 를 선언하였습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
 
    public float movementSpeed = 10f;
 
 
    public float rotationSpeed = 10f;
 
 
    private Vector3 destinationPoint;
 
 
    private bool shouldMove = false;
 
 
    private void Update()
    {
  
    }
}

다음으로 플레이어 캐릭터의 움직임을 제어하기 위한 플래그(flag)로 부울 타입 변수인 shouldMove 를 추가하였습니다. 플레이어 캐릭터가 이동하다가 목표지점에 도달하면 멈춰야 하기 때문에 이를 제어하기 위한 것입니다.

목표 지점 위치 구하기

마우스 클릭 여부 확인

이제 마우스 클릭을 통해 이동 지점의 좌표를 구하는 부분을 만들어 보겠습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            
        }
    }
}

Input.GetMouseButtonDown(0)은 마우스 왼쪽 버튼 클릭 여부를 확인하는 방법입니다. 마우스 왼쪽 버튼을 클릭하면 true를 반환하고 클릭하지 않으면 false를 반환합니다.

if 조건문은 마우스 왼쪽 버튼이 클릭되었는지 확인합니다. 클릭하면 조건문이 참이 되어서, if 블록 내부의 코드가 실행됩니다. 클릭하지 않으면 거짓이 되므로 if 블록 내부의 코드가 실행되지 않습니다.

목표 지점 위치 구하기

이제 마우스 클릭을 기반으로 실제 3차원 월드 상에서의 목표 이동 지점을 구하는 코드를 작성해 보겠습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100f))
            {
                
            }
        }
 
    }
}

위의 코드는 3차원 월드 상에서의 마우스 클릭 지점을 구할 때, 일종의 패턴처럼 외워서 사용하시면 됩니다. 각 행의 의미는 다음과 같습니다.

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

이 명령문이 하는 일은 Ray 타입의 개체인 ray를 만드는 것입니다. 이렇게 만든 ray 는 다음 부분에서 마우스 클릭 지점을 구할 때 사용됩니다.

ray를 만들기 위해서는 Camera.main 개체의 ScreenPointToRay 메서드를 사용합니다. Camera.main 은 현재 씬(scene)에 존재하는 메인 카메라를 나타냅니다.

ScreenPointToRay 메서드는 Vector3를 매개 변수로 사용하며, 이 매개 변수는 화면상의 점(point)을 나타냅니다. 위의 코드에서는 Input.mousePosition이 매개 변수로 사용되었는데, 이 Input.mousePosition은 마우스 커서의 현재 (화면상의) 위치를 나타냅니다.

이렇게 마우스 커서의 화면상의 위치를 매개 변수로 전달하면, 이제 ScreenPointToRay 메서드는 메인 카메라의 위치에서 시작하여 화면의 포인트 방향으로 확장되는 광선(ray)을 생성합니다. 다음의 그림을 보시면 이해가 되실 겁니다.

위의 그림에서 플레이어의 눈(메인 카메라)로부터 2차원 화면상의 마우스 클릭 지점을 관통하는 광선(ray)이 쭉 나아가다가 3차원 월드상의 바닥에 충돌하고 있습니다. 위의 명령문에서 만들어 낸 Ray 개체가 가리키는 것이 그것이라고 이해하시면 됩니다.

RaycastHit 이해하기

이제 다음 코드를 보겠습니다.

RaycastHit hit;

이 코드는 Raycast 타입의 변수인 hit 를 선언하고 있습니다. RaycastHit 는 광선이 충돌하는 지점(3D 공간의 한 점)과 관련한 정보를 저장하는데 사용되는 데이터 구조(data structure)입니다.

if (Physics.Raycast(ray, out hit, 100f))

이 코드는 물리학(Physics) 클래스의 Raycast 메서드를 사용하여 레이캐스팅을 수행합니다. Raycast 메서드는 위의 코드에서 보시는 것처럼 세 가지 파라미터를 사용합니다.

  • 캐스팅할 광선을 나타내는 Ray 개체. 이 경우에는 앞에서 만들어 낸 ray 가 매개 변수로 전달됩니다.
  • RaycastHit. 즉, 광선이 충돌하는 지점에 대한 데이터 개체입니다. 이 경우에는 바로 위에서 구한 hit 가 매개 변수로 전달됩니다.
  • 광선이 도달할 수 있는 최대 거리를 나타내는 실수(float) 값. 이 경우 100f가 매개 변수로 전달되었습니다. 더 크거나 작은 숫자를 입력하셔도 되지만 너무 짧으면 래이캐스트로 인한 충돌 자체가 일어나지 않을 수 있으니 주의하시기 바랍니다.

Physics.Raycast 메서드는 광선(ray)이 충돌체를 가진 물체와 충돌하면 true를 반환하고 그렇지 않으면 false를 반환합니다. 위의 코드에서 충돌이 감지되면 if 조건문 블록 내부의 코드가 실행되고, 그렇지 않으면 if 블록 내부의 코드가 실행되지 않을 것입니다.

따라서 위와 같은 방법으로 마우스 클릭이 이동 목표 지점에 대한 유효한 정보를 가져 오는 지 여부를 알 수 있는 것입니다.

Physics.Raycast 메서드 사용

그럼 이제부터 조건문 내부 코드를 작성하도록 하겠습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100f))
            {
                destinationPoint = new Vector3(hit.point.x, transform.position.y, hit.point.z);
 
                shouldMove = true;
            }
        }
 
    }
}

만약 Physics.Raycast 메서드가 true 를 반환한다면, hit 라는 매개 변수에는 이제 충돌 지점에 대한 여러 가지 데이터가 자동으로 저장되게 됩니다. 따라서 이 hit 를 분석해서 목표 이동 지점을 파악할 수 있습니다.

destinationPoint = new Vector3(hit.point.x, transform.position.y, hit.point.z);

목표 이동 지점은 위와 같은 방식으로 hit 에 들어 있는 정보를 통해 생성해 낼 수 있습니다.

참고로 위의 코드에서는 Vector3 개체를 직접 만들었지만, 원래는 다음과 같이 hit.point 를 직접 대입하는 것이 정석입니다.

destinationPoint = hit.point;

하지만 우리의 경우에는 y 값을 hit.point의 y 좌표가 아닌, 플레이어 캐릭터 게임 오브젝트의 y 좌표인 transform.position.y 를 이용했습니다. 그 이유는 현재 플레이어 캐릭터가 지면에 닿아 있지 않고, 지면에서 약간 위에 떠 있기 때문에 이 고도를 유지하기 위해서 그런 것입니다.

만약에 여러분의 캐릭터가 위와 달리 지면에 붙어 있다면, destinationPoint = hit.point; 라고 하셔도 무방합니다.

움직임과 관련한 플래그

이제 다음 코드를 보겠습니다.

shouldMove = true;

이 코드의 의미는 명확합니다. shouldMove 플래그를 true로 설정하여 개체가 대상 지점을 향해 이동을 시작할 수 있도록 허용하는 것입니다. 이 값이 나중에 false 로 변하면, 다시 말해서 플레이어 캐릭터가 목표지점에 도달하게 되면 더 이상 이동을 허용하지 말아야 합니다. 이에 대해서는 이후의 코드에서 확인하실 수 있을 것입니다.

이제 목표 이동 지점을 구했으니 다음으로 해야 할 일은 캐릭터를 해당 지점을 향해 회전시키고, 지정된 속도에 맞춰 이동시켜야 합니다. 이를 위한 코드를 추가해 보겠습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100f))
            {
                destinationPoint = new Vector3(hit.point.x, transform.position.y, hit.point.z);
 
                shouldMove = true;
            }
        }
 
        if (shouldMove)
        {
            
        }
    }
}

이제부터의 코드는 플레이어 캐릭터의 이동이 허용된 경우에만 의미가 있습니다. 따라서 위와 같이 조건문을 만든 것입니다. 이제 이 안에 회전과 관련된 코드를 먼저 작성해 넣겠습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100f))
            {
                destinationPoint = new Vector3(hit.point.x, transform.position.y, hit.point.z);
 
                shouldMove = true;
            }
        }
 
        if (shouldMove)
        {
            Quaternion targetRotation = Quaternion.LookRotation(destinationPoint - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);            
        }
    }
}

캐릭터의 회전과 관련한 이 코드 블록도 하나의 패턴으로 암기해서 사용하시는 것이 좋습니다. 처음에는 원리를 이해하기 어려워도 반복해서 사용하다 보면 자신도 모르게 의미를 이해하게 될 것입니다. 일단 각각의 코드에 대해 설명 드리겠습니다.

Quaternion targetRotation = Quaternion.LookRotation(destinationPoint - transform.position);

이 명령문은 개체가 대상 지점을 바라보기 위해 얼마만큼 회전해야 하는지를 계산합니다. Quaternion.LookRotation 매서드는 매개 변수로 정면 방향(forward direction)을 받습니다. 플레이어 캐릭터의 현재 위치에서 목표 지점을 바라보기 위한 정면 방향은 destinationPoint에서 캐릭터 개체의 현재 위치(transform.position)를 빼면 구할 수 있습니다.

이렇게 해서 구한 회전 값을 Quaternion 타입의 변수인 targetRotation 에 저장하면 됩니다.

부드러운 회전 구현

그럼 다음 코드를 보겠습니다.

transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

이 코드는 바로 위에서 계산한 목표 회전 값을 향해 개체를 부드럽게 회전시키는 일을 합니다. 이를 위해서는 Quaternion 클래스의 Slerp(구면 선형 보간) 메서드를 사용합니다.

Quaternion.Slerp() 매서드는 개체의 현재 회전(transform.rotation), 목표 회전(targetRotation) 및 회전 속도(rotationSpeed)를 매개 변수로 받습니다. (이 때 Time.deltaTime 값을 회전 속도에 곱하면 게임의 프레임 속도에 관계없이 일정한 속도로 회전할 수 있습니다.)

그리고 이렇게 얻어진 매 프레임 당 캐릭터가 회전할 목표 값을 transform.rotation 에 할당하면 됩니다. 여기까지 코드를 작성하고 실행하면 캐릭터가 이동은 못해도 회전은 잘 수행하게 될 것입니다.

마우스를 클릭하면 회전한다

캐릭터 이동 구현

이제 마지막으로 이동 부분을 작성하도록 하겠습니다. 지금까지 작성한 코드에 다음과 같은 명령문을 추가합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100f))
            {
                destinationPoint = new Vector3(hit.point.x, transform.position.y, hit.point.z);
 
                shouldMove = true;
            }
        }
 
        if (shouldMove)
        {
            Quaternion targetRotation = Quaternion.LookRotation(destinationPoint - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
 
            transform.position = Vector3.MoveTowards(transform.position, destinationPoint, movementSpeed * Time.deltaTime);
 
        }
    }
}

이 코드는 플레이어 캐릭터 개체를 앞에서 구한 목표 지점을 향해 이동시킵니다.

Vector3.MoveTowards() 메서드에 개체의 현재 위치(transform.position), 목표 지점(destinationPoint) 및 ‘이동 속도(movementSpeed) 곱하기 Time.deltaTime’의 세 가지 매개 변수를 전달하면 각 프레임당 개체가 얼마나 이동해야 원하는 속도로 목표 지점에 도달할 수 있을 지를 알 수 있습니다. 이렇게 구한 값을 다시 플레이어 캐릭터 개체의 transform.position 에 할당하면 됩니다.

목표 지점 도달 처리

이 코드를 추가하고 게임을 실행하면 마우스 클릭을 통해 캐릭터를 목표 지점으로 이동시킬 수 있습니다. 하지만 목표 지점에서 멈추지 않고 계속 움직이게 됩니다. 정지와 관련된 코드를 작성하지 않았기 때문입니다.

따라서 다음과 같은 코드를 추가함으로써 이 문제를 해결할 수 있습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ClickToMove : MonoBehaviour
{
    public float movementSpeed = 10f;
 
    public float rotationSpeed = 10f;
 
    private Vector3 destinationPoint;
 
    private bool shouldMove = false;
 
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100f))
            {
                destinationPoint = new Vector3(hit.point.x, transform.position.y, hit.point.z);
 
                shouldMove = true;
            }
        }
 
        if (shouldMove)
        {
            Quaternion targetRotation = Quaternion.LookRotation(destinationPoint - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
 
            transform.position = Vector3.MoveTowards(transform.position, destinationPoint, movementSpeed * Time.deltaTime);
 
            if (transform.position == destinationPoint)
            {
                shouldMove = false;
            }
        }
    }
}

이 코드는 개체의 위치가 대상 지점과 동일한지 여부를 확인합니다. 만약 그럴 경우, 이동 플래그가 false로 설정되고 플레이어 캐릭터 개체는 이동을 멈추게 됩니다.

위 코드에서 보완해야 할 부분

참고로 이 부분은 자칫 문제를 야기할 수도 있습니다. 예를 들어 게임의 프레임이 낮을 경우(너무 느릴 경우) 자칫 위의 조건문 (==)이 참인 순간을 지나쳐 버릴 수 있습니다.

이런 경우를 대비하기 위해 플레이어 캐릭터의 현재 위치와 목표 지점까지의 거리를 계산해서, 거리가 예를 들어 1미터 이상 떨어졌을 때만 이동하고, 그 보다 줄어들면 멈추게 하는 방법으로 코드를 변경할 수도 있습니다. 이 부분은 여러분이 직접 해 보시기 바랍니다.

지금까지 작성한 ClickToMove 스크립트는 어떤 게임 오브젝트에 붙여도 작동됩니다. 위의 안내에 따라 스크립트를 작성하고 확장, 변형시켜 보시기 바랍니다. 꽤 재미 있는 유니티 C# 스크립트 공부가 될 것입니다.

 

https://cjwoov.tistory.com/18#:~:text=%5BUnity%5D%20%EB%A7%88%EC%9A%B0%EC%8A%A4%20%ED%81%B4%EB%A6%AD%ED%95%9C%20%EC%A7%80%EC%A0%90%EC%9C%BC%EB%A1%9C%20%EC%BA%90%EB%A6%AD%ED%84%B0%20%EC%9D%B4%EB%8F%99%EC%8B%9C%ED%82%A4%EA%B8%B0%201%20Control.cs%3A,%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%202%20Behavior.cs%3A%20%EC%8B%A4%EC%A0%9C%20%EC%BA%90%EB%A6%AD%ED%84%B0%EC%9D%98%20%ED%96%89%EB%8F%99%EC%9D%84%20%EB%8B%B4%EB%8B%B9%ED%95%98%EB%8A%94%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8

'유니티스크립팅 > 유니티팁' 카테고리의 다른 글

게임 오브젝트를 찾는 Find 메서드  (0) 2023.05.24
알아두면 편리한 기능  (0) 2023.03.04

라이트매핑은 정적이므로 동적으로 움직이는 객체에는 적용할 수 없다. 물론 실시간 조명의 Culling Mask를 사용해 주인공에게만 조명 효과를 부여할 수 있지만 라이팅매핑이 적용된 간접광원 또는 그림자영역에 들어갔을때 밝은 조명이 비치는 부자연 스러운 장면이 연출된다.

이를 개선하기 위해 유니티는 라이트 프로브(Light Probes)라는 기능을 제공한다. 라이트프로브는 스테이지 조명이 있는 곳 주변에 라이트 프로브를 배치하고 라이트맵을 베이크할때 해당 라이트프로브에 주변부의 광원 데이터를 미리 저장해 둔다. 저장된 광원데이터는 실행시 근처를 지나치는 동적 객체에 광원 데이터를 전달해 해당 객체의 색상과 보간시켜 마치 실시간 조명과 같은 효과를 내는 방식이다.

 

Light Probe Group

라이트 프로브를 만들어 주인공을 밝게 만들어보다 하이라키뷰의 _STAGE를 선택해 메뉴에서 [Light]->[Light Probe Group]을 선택해 Light Probe Group를 생성한다. _STABE하위에 생성한 Light Probe Group의 Position이 (0,0,0)인지 다시한번 확인한다.

Light Probe는 바닥위에 위치해야 효과를 낼수 있다 따라서 Y를  1.2로 설정해 라이트프로브가 모두 바닥위에 배치되도록한다.

Edit Light Probes를 클릭하면 4개의 버튼이 나타나고 Select All 버튼을 클릭하면 라이트 프로브가 파란색으로 바낀다.

Duplicate Selected를 클릭하면 변화가 없어 보이지만 복사가 되었다 Transform축을 클릭해 이동한다.

Selected All - duplicate Selected를 반복해 Floor를 채워보자

Lighting 뷰에서 베이크 해보면 이제 Player가 Point Light색에 따라 변화하는 걸 알수 있다.

 

Anchor Override

라이트 프로브는 Player가 근접한 4개의 라이트 프로브에서 베이크된 조명값을 전달한다. 

Anchor Override기능을 이용해 보간되는 위치를 설정할 수 있다. 이 속성에 원하는 위치를 연결하면 그 위치부터 텍스처 색상이 보간되기 시작한다. 하이라키뷰의 Player를 선택하고 head를 열어 놓고 slade_mesh 3개를 선택하고 인스펙터의 Anchor Override 에 연결해준다

 

'유니티게임강좌 > 라이트매핑' 카테고리의 다른 글

[라이트매핑] 라이트매핑  (0) 2023.03.20
[라이트매핑] 광원 타입  (0) 2023.03.19

라이트매핑은 조명효과를 텍스처로 미리 만드는 과정을 말한다. 이 텍스처를 라이트맵이라고 하고 이과정을 Bake한다고 한다. 라이트맵은 실시간 렌더링화면과 오버레이돼 믹싱된다.

 

 Generate Lightmap UVs 옵션

외부에서 임포트된 모델은 Models  탭에서 Generate Lightmap UVs속성을 체크해야 라이트매핑 효과가 적용된다.

05.Models/Stair폴더의 Stair모델을 선택하고 인스펙터뷰에서 Model탭을 누르고 아래 Generate Lightmap UVs를 체크하고 Apply한다.

 

 

Contribute GI 플러그

라이트매핑을 하려면 라이트매퍼에 그 대상을 알려줘야 한다. 따라서 Barrel, Floor, Wall, Stair를 선택하고 인스펙터뷰의 Static 플래그 중 Contribute GI를 체크해야한다. 프로젝트뷰 프리팹폴더에서 처리한다.

Barrel은 동적장애물 처리를 했기때문에 Contrubute GI만 선택하고 나머지 Floor, Wall,Stair등은 Navigation Static도 선택한다. Contribute GI를 선택하지 않으면 라이트매핑 대상에서 제외된다.

라이팅뷰

메뉴에서 Window>Rendering>Lighting을 선택해 라이팅 뷰를 열고 Scene탭을 클릭한다. 라이팅뷰는 4개의 영역으로 분리돼 있으며 라이팅매핑을 위한 다양한 속성을 제공한다. 먼저 Scene탭의 속성은 다음과 같다.

한번도 라이트맵을 베이킹하지 않았다면 모든 섹션이 비활성화 되어 있습니다 .[New Lighting Settings]버튼을 클릭해 새로운 라이팅 세팅을 생성한다. 생성한 라이팅 섹션의 이름을 씬이름과 동일하게 Play라고 지정한다.

아래 Auto Generate속성을 체크하면 라이트맵을 백그라운드로 베이크한다. 씬뷰에 새로운 모델 또는 조명을 변경하면 라이트매퍼가 다시 베이크작업을 시작한다. 이때 오른쪽 아래 있는 상태바에 베이크 과정이 표시된다. 라이트맵은 캐시에 저장되는데 캐시는 실행파일에 포함되지 않으므로 실행파일과 함께 배포하려면 반드시 Auto Generate 옵션을 끄고 수동으로 베이크한다.

Progressive 라이트매퍼

Progressive 라이트매퍼는 경로추적기반의 라이트매퍼로서 라이트맵과 라이트프로브를 점진적으로 베이크하는 기능을 제공한다. 또한,  Progressive GPU라이트매퍼는 GPU의 그래픽 가속 기능을 이용해 좀 더 빠르게 라이트 매핑을 할 수 있다. 기존 Enlighten 라이트매퍼는 베이크가 완료전까지는 결과물을 볼수 없으나 Progressive 라이트 매퍼는 대략적인 결과물을 바로 보여준다. 

 

라이팅뷰의 Environment

라이트맵을 수동으로 베이크해보자. 씬뷰에 있는 Directional Light는 Realtime조명으로 씬을 전체적으로 비췄던 조명이다. 라이트맵의 결과물을 확인하기 쉽게 이걸 잠시 비활성화한다.

조명을 비활성화해도 희미하게 보이는데 Skybox의 하늘빛이 환경 광원으로 작용하고 있다. 환경광원은 Ambient Light라고도 한다. 바닥에도 반사광이 표시된다. 

라이트뷰를 열어 Environment탭을 선택해 보면 Source가 Skybox로 되어 있어서 그렇고  Intensity Multiplier를 2로 변경하면 좀더 밝아진다.

어둡게 하기위해 Soruce를 color로 바꾸고 검정색을 선택한다.

Environment Reflection속성은 3D 모델 표면에 반사 광원의 효과를 설정하는 옵션이다. 기본값인 Skybox의 빛을 Floor에 비추고 있다. Source를 Custom으로 변경하거나 반사율을 나타내는 Intensity Multiplier속성을 0으로 설정하면 바닥이 어둡게 된다.

Baked 라이트매핑

Baked 라이트매핑을 위해 먼저 라이팅뷰의 [Scene]탭으로 이동한 다음 Realtime Lighting 섹션에서 Realtime Global Illumination 속성을 언체크한다. 이 기능은 전역조명을 실시간 계산해서 반영하는것으로 게임용 PC에서 적합하다.

Mixed Lighting - Baked Global Illumination을 체크하고 Lighting Mode는 Subtractive로 설정해 라이트맵과 라이트프로브, 그림자를 모두 하나의 라이트맵에 베이크한다.

조명을 여러개 배치하기 위해 하이라키뷰의 _STAGE를 선택하고  Point Light를 차일드로 추가한다. Point Light속성은 intensity는 10으로 다음 표과 같이 설정한다. 조명의높이는 주인공의 키 높이 정도로 Y:2정도로 올려서 스테이지에 배치한다.  10개정도  카피해서 배치한후. 색은 R G B 원색으로 각각 바꿔준다.

AutoGenerate 기능이 켜져있기 대문에 조명을 추가하면 바로바로 라이트맵을 베이크하기 시작하고 시간이 지나면서 품질이 좋와진다. 대신 AutoGenerate 기능이 켜져있어 조명을 추가할때마다 엄청 부하가 먹는다 

 

라이트맵 베이크

라이트맵을 캐시가 아닌 텍스처파일로 베이크하려면 백그라운드기능을 꺼야한다 .라이트뷰 Auto Generate 옵션을 언체크한다.

Generate Lighting을 클릭하면 열심히 렌더링한다 제대로 조명이 안나온다면 오브젝트의 Static에 GI가 체크되어 있는지 확인해본다

Lighting 뷰의 [Baked Lightmaps]탭을 누르면 라이트맵을 확인할 수 있다. 포토샵에서 편집이 가능하다.

L

Area Light

_Stage 오브젝트의 자식으로 Area Light를 하나 만들고 벽쪽으로 배치하고 다음과 같이 길게 만들어 본다. Area Light는 유일하게 실시간 라이트가 아니다. 베이크후 효과를 볼 수 있다.

 

Realtime Lighting

이 섹션에는 인라이튼 실시간 전역 조명 시스템과 관련된 설정이 포함되어 있습니다.

프로퍼티기능

Realtime Global Illumination 이 체크박스를 선택하면 Unity는 이 조명 설정 에셋을 사용하는 씬에서 인라이튼 실시간 전역 조명 시스템을 활성화합니다.
Realtime Environment Lighting 인라이튼 실시간 전역 조명 시스템을 사용하여 주변광을 실시간으로 계산하고 업데이트하려면 이 프로퍼티를 활성화합니다.

이 프로퍼티는 씬에서 인라이튼 실시간 전역 조명  베이크된 전역 조명이 모두 활성화된 경우에만 사용할 수 있습니다.

 

Mixed Lighting

이 섹션에는 조명 설정 에셋을 사용하는 씬 내 베이크된 광원  혼합 광원의 동작에 영향을 주는 설정이 나와 있습니다.

프로퍼티:기능:

Baked Global Illumination 이 설정을 활성화하면 Unity는 이 조명 설정 에셋을 사용하는 씬에 대해 베이크된 전역 조명 시스템을 활성화합니다. 이 설정을 비활성화하면 Unity는 이 조명 설정 에셋을 사용하는 씬에 대해 베이크된 전역 조명 시스템을 비활성화합니다.

베이크된 전역 조명 시스템을 활성화하면 Unity는 라이트매핑의 경우에만 씬에서 베이크된 광원을 사용하고, 혼합 광원은 Lighting Mode 설정에 따라 동작합니다. 베이크된 전역 조명 시스템을 비활성화하면 Unity는 씬의 모든 베이크된 광원과 혼합 광원이 실시간 광원처럼 동작하도록 강제로 지정합니다.
Lighting Mode Unity가 이 조명 설정 에셋을 사용하는 씬 내 모든 혼합 광원에 사용할 조명 모드를 지정합니다.

조명 모드를 변경하면 이 조명 설정 에셋을 사용하는 씬의 조명 데이터를 다시 베이크해야 합니다.
  Baked Indirect 이 조명 설정 에셋을 사용하는 씬 내 모든 혼합 광원에 Baked Indirect 조명 모드를 사용합니다.
  Subtractive 이 조명 설정 애셋을 사용하는 씬의 모든 혼합 조명에 대해 서브트랙티브 조명 모드를 사용합니다.

  Shadowmask 이 조명 설정 애셋을 사용하는 씬의 모든 혼합 조명에 대해 섀도우 마스크 조명 모드를 사용합니다.

 

Lightmapping Settings

프로퍼티기능

Lightmap Resolution 라이트맵에 사용할 단위당 텍셀 수를 지정합니다. 이 값을 높게 설정하면 라이트맵 품질이 개선되지만 베이크 시간도 늘어납니다. 이 값을 두 배로 늘리면 라이트맵의 높이와 너비가 모두 2배가 되기 때문에 텍셀 수는 4배로 증가합니다. 조명 창의 통계 영역에서 Occupied texels 수를 확인할 수 있습니다.
Lightmap Padding 베이크된 라이트맵의 개별 셰이프 간 간격을 텍셀 단위로 결정합니다. 기본값은 2입니다.
Max Lightmap Size 개별로 포함된 게임 오브젝트 영역을 통합하는 전체 라이트맵 텍스처의 크기(픽셀 단위)를 지정합니다. 기본값은 1024입니다.
Lightmap compression 에디터가 라이트맵에 사용하는 압축 수준입니다.
- None: 라이트맵을 압축하지 않습니다.
- Low Quality: 보통 품질보다 메모리와 저장 공간을 덜 사용하지만 시각적 결함이 발생할 수도 있습니다.
- Normal Quality: 메모리 사용량과 화질 사이의 균형을 유지합니다.
- High Quality: 보통 품질보다 더 많은 메모리와 저장 공간이 필요하지만 더 나은 시각적 결과를 제공합니다.
Ambient Occlusion 베이크된 앰비언트 오클루전에서 상대 표면 밝기를 제어할 수 있습니다. 이것은 조명을 베이크하는데 사용하는 라이트매퍼에 의해 계산된 간접 조명에만 적용됩니다. 기본적으로 활성화되어 있습니다. 앰비언트 오클루전이 활성화되면 최대 거리, 간접 조정, 직접 조정의 세 가지 설정이 노출됩니다. 세 가지 설정 모두 값이 높을수록 오클루전된 영역과 조명을 완전히 받은 영역 간의 콘트라스트가 더욱 증가합니다.
Max Distance 오브젝트에 오클루전을 적용할지 결정하기 위해 조명 시스템에서 광선을 투사하는 거리를 지정합니다. 값이 높을수록 더 긴 광선이 생성되고 라이트맵에 그림자가 더 많이 추가되는 한편, 값이 낮을수록 오브젝트가 서로 매우 가까이에 있는 경우에만 그림자를 추가하는 더 짧은 광선이 생성됩니다. 값을 0으로 설정하면 최대 거리가 없는 무한하게 긴 광선이 투사됩니다. 기본값은 1입니다.
Indirect Contribution 최종 라이트맵의 오브젝트에서 바운스되고 방출되는 간접 주변광의 밝기를 스케일합니다. 0과 10 사이의 값으로 기본값은 1입니다. 값이 1보다 작으면 강도가 감소하고 값이 1보다 크면 증가합니다.
Direct Contribution 직접광의 밝기를 스케일합니다. 0과 10사이의 값으로 기본값은 0입니다. 값이 높을수록 에디터가 직접 조명에 적용하는 콘트라스트가 증가합니다.
Directional Mode 오브젝트 표면의 각 포인트에서 가장 우세하게 비추는 광원의 특성에 관한 정보를 저장할 수 있는 라이트맵을 활성화합니다. 자세한 내용은 방향성 라이트매핑을 참조하십시오. 기본 모드는 Directional입니다.
Directional Directional 모드에서 Unity는 광원에서 비추는 우세한 방향을 저장하는 두 번째 라이트맵을 생성합니다. 이를 통해 디퓨즈 노멀 매핑된 머티리얼을 전역 조명 시스템과 연동할 수 있습니다. 셰이더는 렌더링하는 동안 두 개의 라이트맵 텍스처를 샘플링합니다. 결과적으로 방향성 모드는 추가 라이트맵 데이터를 위해 비방향성 모드보다 약 2배의 비디오 메모리를 필요로 합니다. 추가 방향성 텍스처를 생성하면 베이킹 성능에 영향을 줍니다. 방향 라이트맵은 SM2.0 하드웨어에서 또는 GLES2.0을 사용할 때 디코드할 수 없습니다.
Non-directional Non-directional 모드 라이트맵에는하나의 텍스처만 포함됩니다. 결과적으로 방향 라이트맵보다 비디오 메모리와 저장 공간이 적게 필요하며 셰이더에서 더 빠르게 디코드할 수 있습니다. 이러한 최적화는 화질을 저하합니다.
Indirect Intensity 실시간 및 베이크된 라이트맵에 저장되는 간접광의 밝기를 결정합니다. 0과 5 사이의 값입니다. 값을 1보다 크게 설정하면 간접광의 강도가 증가하고, 값을 1보다 작게 설정하면 간접광의 강도가 감소합니다. 기본값은 1입니다.
Albedo Boost Unity가 표면 사이에서 바운스하는 광원의 양을 지정합니다. 이 값은 1에서 10 사이입니다. 이 값을 높게 설정할수록 간접광 계산을 위해 알베도 값을 흰색으로 끌어옵니다. 기본값은 1이며 물리적으로 정확합니다.
Lightmap Parameters 라이트맵 파라미터 에셋은 베이크된 전역 조명과 관련된 설정 값을 저장합니다. 에디터는 선택할 수 있는 몇 가지 기본 라이트맵 파라미터 에셋을 제공하지만 Create New 옵션을 사용하여 자체 라이트맵 파라미터 파일을 만들 수도 있습니다. 자세한 내용은 라이트맵 파라미터를 참조하십시오. 기본값은 Default-Medium입니다. 옵션은 Default-Medium, Default-HighResolution, Default-LowResolution 및 Default-VeryLowResolution입니다.

'유니티게임강좌 > 라이트매핑' 카테고리의 다른 글

[라이트매핑] 라이트 프로브  (2) 2023.03.20
[라이트매핑] 광원 타입  (0) 2023.03.19

라이트매핑

라이트매핑은 씬의 표면 밝기를 미리 계산하고 계산 결과를 나중에 사용하기 위해 라이트맵이라고 불리는 텍스처에 저장하는 프로세스입니다.

왼쪽: 라이트맵이 적용된 간단한 씬. 오른쪽: Unity가 생성한 라이트맵 텍스처. 그림자 및 광원 정보가 모두 캡처됩니다.

라이트맵에는 직접광과 간접광이 모두 포함될 수 있습니다. 이 조명 텍스처는 오브젝트의 머티리얼과 연결된 셰이더에서 컬러(알베도) 및 릴리프(노멀) 같은 표면 정보와 함께 사용될 수 있습니다.

라이트맵에 베이크된 데이터는 런타임 시 변경할 수 없습니다. 실시간 광원은 라이트맵이 적용된 씬 위에 오버레이시켜 추가적으로 사용할 수 있지만, 라이트맵 자체를 대화식으로 변경할 수 없습니다.

이 방식을 사용할 경우 게임플레이 시에 광원을 실시간으로 움직일 수 있는 유용성을 잠재적인 성능 향상과 맞바꾸는 것이므로, 모바일 플랫폼처럼 성능이 낮은 하드웨어에 적합합니다.

Unity는 라이트맵 생성을 위해 다음의 라이트매퍼를 제공합니다.

 

인라이튼 베이크된 전역 조명을 사용한 라이트매핑 - Unity 매뉴얼

인라이튼 베이크된 전역 조명은 사전 계산된 실시간 전역 조명 데이터에 기반하여 간접 조명을 생성합니다. 이렇게 하면 씬의 조명을 변경한 후 새로운 라이트맵을 매우 빠르게 생성하는 장점

docs.unity3d.com

인라이튼 베이크된 전역 조명을 사용한 라이트매핑

인라이튼 베이크된 전역 조명은 사전 계산된 실시간 전역 조명 데이터에 기반하여 간접 조명을 생성합니다. 이렇게 하면 씬의 조명을 변경한 후 새로운 라이트맵을 매우 빠르게 생성하는 장점이 있습니다. 그러나 인라이튼 베이크된 전역 조명은 프로그레시브 라이트매퍼보다 UV 레이아웃 제한이 더 많습니다.

인라이튼 베이크된 전역 조명은 지원 중단 예정입니다.(인라이튼 실시간 전역 조명은 계속 지원합니다.)

렌더 파이프라인 지원

렌더 파이프라인의 인라이튼 베이크된 전역 조명 지원에 대한 자세한 내용은 렌더 파이프라인 기능 비교를 참조하십시오.

인라이튼 라이트매퍼 사용

인라이튼 베이크된 전역 조명을 사용하려면 Window > Rendering > Lighting에서 Lightmapping Settings로 이동한 후 Lightmapper Enlighten으로 설정합니다.

LightingSettings API를 사용하여 스크립트를 통해 이 창에서 사용할 수 있는 많은 기능을 수행할 수 있습니다.

다음 프로퍼티는 인라이튼에만 해당됩니다. 이것을 노출시키려면 Lightmapper control에서 Enlighten을 선택합니다.

프로퍼티:기능:

Final Gather 베이크된 라이트맵과 동일한 해상도로 전역 조명 최종 광원 바운스를 계산합니다. 이렇게 하면 화질이 향상되지만 조명 베이크 시간이 늘어납니다. Final Gather가 활성화되면 Ray Count 및 Denoising 설정이 노출됩니다.
Indirect Resolution 이 설정을 사용하면 라이트매퍼가 간접 조명 계산에 사용하는 샘플 수를 지정할 수 있습니다. 값이 높을수록 라이트맵 품질이 향상되지만, 그만큼 베이크하는 데 걸리는 시간이 증가합니다.
  Ray Count 최종 수집 포인트마다 라이트매퍼가 방출하는 광선의 수를 지정합니다.
  Denoising 최종 수집 출력에 노이즈 제거 필터를 적용합니다.

기본 환경 기여 비활성화

Unity는 자동으로 앰비언트 프로브 기본 반사 프로브를 생성하여 환경 조명이 기본적으로 씬과 씬의 게임 오브젝트에 영향을 주도록 합니다.

라이트맵과 라이트 프로브를 수동으로 생성하지 않은 게임 오브젝트 또는 씬의 조명 결과에서 환경 기여를 비활성화하려면 기본 반사 프로브와 앰비언트 프로브를 비활성화합니다. 자세한 내용은 [SkyManager 비활성화]를 참조하십시오.

라이트매핑: 시작하기

씬 준비 및 라이트맵 베이킹

Unity 에디터 메뉴에서 Window > Rendering > Lighting 을 선택하여 Lighting 창을 엽니다. 라이트맵을 적용할 메시를 검토하여 라이트맵에 적합한 UV가 있는지 확인합니다. 메시 임포트 설정을 열고 Generate Lightmap UVs 설정을 활성화하면 가장 쉽게 확인할 수 있습니다.

다음, 라이트맵 해상도를 설정하기 위해 라이트맵 설정(Lightmapping Settings) 섹션으로 이동하여 라이트맵 해상도(Lightmap Resolution) 값을 조정합니다.

라이트맵에 포함되려면 렌더러가 다음 조건을 충족해야 합니다.

  • Mesh Renderer 또는 Terrain 컴포넌트가 있습니다.
  • Contribute GI로 표시되어 있습니다.
  • 빌트인 Unity 머티리얼, 스탠다드 셰이더 또는 메타 패스가 포함된 셰이더를 사용합니다.

광원 탐색기에서 광원에 대한 설정을 조정할 수 있습니다. 광원 탐색기를 열려면 Window > Rendering > Light Explorer로 이동합니다.

씬의 라이트맵을 생성하는 방법:

  1. Lighting 창(메뉴: Window > Rendering > Lighting)을 엽니다.
  2. Lighting 창의 Scene 탭 하단에서 Generate Lighting 을 선택합니다(또는 Auto Generate 가 활성화되어 있는지 확인합니다).
  3. Unity 에디터 상태 표시줄의 오른쪽 하단에 진행 표시줄이 나타납니다.

라이트매핑이 완료되면 Unity의 씬 뷰와 게임 뷰가 자동으로 업데이트되며 Lighting 창의 Baked Lightmaps 탭으로 이동하여 결과가 적용된 라이트맵을 볼 수 있습니다.

조명을 수동으로 생성하면 조명 데이터 에셋, 베이크된 라이트맵, 반사 프로브 Assets 폴더에 추가됩니다.

 

라이트맵 파라미터 에셋

라이트맵 파라미터 에셋에는 Unity의 조명 기능을 제어하는 파라미터 값 세트가 들어 있습니다. 이러한 에셋을 사용하면 다양한 조명 값 세트를 정의하고 저장하여 다양한 상황에서 사용할 수 있습니다.

라이트맵 파라미터 에셋을 사용하면 다양한 게임 오브젝트 타입이나 여러 플랫폼과 여러 씬 타입(예: 실내 또는 야외 씬)에 최적화된 프리셋을 빨리 만들 수 있습니다.

라이트맵 파라미터 에셋 생성

새 라이트맵 파라미터 에셋을 생성하려면 프로젝트 창에서 마우스 오른쪽 버튼을 클릭하고 생성(Create) > 새 파라미터 에셋(New Parameters Asset) 으로 이동합니다. Unity는 프로젝트 폴더에 생성된 에셋을 저장합니다.

프로퍼티

프로젝트 창에서 라이트맵 파라미터 에셋을 클릭하면 해당 에셋에 정의된 값이 인스펙터 창에 표시됩니다. 아래 표에는 각 파라미터와 해당 설명이 나열되어 있습니다.

실시간 GI

이 파라미터는 인라이튼 실시간 전역 조명을 설정합니다.

렌더 파이프라인의 인라이튼 실시간 전역 조명 지원에 대한 자세한 내용은 렌더 파이프라인 기능 비교를 참조하십시오.

프로퍼티기능

Resolution 이 값은 라이팅 창의 Scene 탭(메뉴: Window > Rendering > Lighting > Scene)에 있는 Realtime Resolution 값을 조정하여 라이트맵의 최종 해상도를 단위 거리당 텍셀 수로 표시합니다.
Cluster Resolution 클러스터 해상도(광원 바운스가 내부적으로 계산되는 해상도) 대 최종 라이트맵 해상도의 비율입니다. 자세한 내용은 씬 뷰에서 GI 시각화 문서를 참조하십시오.
Irradiance Budget 값은 라이트맵의 각 텍셀에 광원을 비추는 데 사용되는 유입 광원 데이터의 정밀도를 결정합니다. 각 텍셀의 조명은 텍셀 포지션에서 씬의 “뷰”를 샘플링하여 얻습니다. 복사 조도의 계산 정밀도 값이 낮을수록 샘플이 더 흐릿합니다. 값이 높을수록 샘플의 선명도가 높아집니다. 복사도 값이 높을수록 조명이 개선되지만, 런타임 메모리 사용량이 증가하고 CPU 사용량도 증가할 수 있습니다.
Irradiance Quality 슬라이더를 사용해 캐스트되고 주어진 출력 라이트맵 텍셀에 영향을 미치는 클러스터를 계산하는 데 사용되는 레이의 수를 정의합니다. 값이 높을수록 라이트맵이 시각적으로 개선되지만, Unity 에디터에서 미리 계산하는 시간이 늘어납니다. 이 값은 런타임 성능에 영향을 미치지 않습니다.
Modelling Tolerance 값은 광원이 메시 지오메트리를 통과할 수 있는 틈새의 최소 크기를 설정합니다. 환경에서 광원이 더 작은 틈새를 통과할 수 있게 하려면 이 값을 더 낮게 설정해야 합니다.
Edge Stitching 활성화할 경우, 프로퍼티는 불필요한 시각적 결함을 방지하기 위해 라이트맵의 UV 차트를 완벽하게 결합해야 함을 나타냅니다.
Is Transparent 활성화하면 오브젝트가 전역 조명 계산 중에 투명하게 표시됩니다. 후면은 계산에 포함되지 않고, 광원이 표면을 통해 지나갑니다. 보이지 않는 이미시브 표면에 유용합니다.
System Tag 라이트맵 텍스처가 “시스템”이라는 동일한 라이트맵 아틀라스에 결합된 오브젝트 그룹입니다. Unity 에디터는 모든 라이트맵이 아틀라스 하나에 들어가지 않는 경우 추가 시스템과 각각의 아틀라스를 함께 정의합니다. 하지만 때로는 (예를 들어 서로 다른 룸 안에 있는 오브젝트가 룸당 시스템 하나로 그룹화되게 하기 위해) 별도의 시스템을 직접 정의하면 유용합니다. System Tag 번호를 변경하여 새로운 시스템과 라이트맵을 강제로 만들 수 있습니다. 태그의 정확한 숫자 시퀀스 값은 중요하지 않습니다.

베이크된 GI

이 파라미터는 라이트매핑을 설정합니다.

렌더 파이프라인의 라이트매핑 지원에 대한 자세한 내용은 렌더 파이프라인 기능 비교를 참조하십시오.

프로퍼티기능

  인라이튼 베이크된 전역 조명 프로그레시브 라이트매퍼(Progressive Lightmapper)
Blur Radius 텍셀에서 사후 처리 중에 직접 조명에 적용되는 블러 필터의 반지름입니다. 반지름은 본질적으로 인접 텍셀 거리의 평균입니다. 반지름이 클수록 블러 효과가 더 많이 제공됩니다. 블러 레벨이 높을수록 시각적 결함이 감소하지만 섀도우의 가장자리가 부드러워지는 경향이 있습니다. 프로그레시브 라이트매퍼를 사용하는 경우 블러 반지름(Blur Radius) 은 이용할 수 없습니다.
안티앨리어싱 샘플(Anti-aliasing Samples) 적용되는 안티앨리어싱(“블록 모양”의 결함 감소) 정도입니다. 숫자가 높을수록 품질이 향상되고 베이크 시간이 늘어납니다. 앨리어싱을 줄이기 위해 텍셀을 슈퍼샘플링하는 횟수입니다. [1;3] 샘플은 슈퍼샘플링을 비활성화하고, [4;8] 샘플은 2x 슈퍼샘플링을 제공하고, [9;256] 샘플은 4x 슈퍼샘플링을 제공합니다. 주로 포지션과 노멀 버퍼에 사용되는 메모리 양에 영향을 미칩니다. (2x 시 메모리가 4배 더 많이 사용되고, 4x 시 메모리가 16배 더 많이 사용됩니다.)
Direct Light Quality 직접 조명을 측정하는 데 사용되는 레이의 수입니다. 레이 수가 많을수록 더 정확하고 부드러운 섀도우가 생성되지만 베이크 시간이 늘어납니다. 프로그레시브 라이트매퍼를 사용하는 경우 직접광 품질(Direct Light Quality) 은 이용할 수 없습니다.
Backface Tolerance 때로는 메시 구조로 인해 일부 텍셀에 후면 방향 지오메트리가 포함된 “뷰”가 있을 수 있습니다. 후면에서 유입되는 광원은 씬에서 무의미하므로, 프로퍼티를 통해 텍셀을 유효한 것으로 간주하기 위해서는 전체 광원 중 전면 지오메트리에서 나온 광원이 얼마나 되어야 하는지를 나타내는 백분율의 임계값을 선택할 수 있습니다. 유효하지 않은 텍셀은 인접 텍셀의 값으로부터 조명이 어림됩니다. 값을 낮추면 후면에서 유입되는 광원으로 인해 발생하는 조명 문제를 해결할 수 있습니다. 출력 텍셀에서 투사된 광선이 유효한 것으로 간주되기 위해 전면에 닿아야 하는 광선의 비율입니다. 텍셀에서 투사된 광선 중에 후면에 닿는 광선이 너무 많으면(텍셀이 어떤 지오메트리 안에 있음) 텍셀을 무효화할 수 있습니다. 이 경우 주위 텍셀에서 유효한 값을 복제하여 결함을 방지합니다. 예를 들어 후면 허용치를 0.0으로 설정하면, 텍셀에서 후면만 보일 때에만 텍셀이 거부됩니다. 후면 허용치를 1.0으로 설정하면, 후면에 닿는 광선이 하나만 있어도 광선 원점이 거부됩니다. 베이크된 텍셀 유효성(Baked Texel Validity) 씬 뷰 모드에서 유효한 텍셀은 녹색으로, 유효하지 않은 텍셀은 빨간색으로 나타납니다. 씬에 단면 메시가 있는 경우 이 기능을 영(0)으로 설정하여 비활성화하는 것이 좋습니다. 나중에 Unity 에디터에서 양면 플래그를 추가하여 이 문제를 해결할 수 있습니다.
Pushoff 모델링 유닛에서 레이 트레이스를 시작하기 전에 표면 지오메트리에서 밀어낼 거리입니다. 모든 베이크된 라이트맵에 적용되므로 직접광, 간접광 및 AO에 영향을 미칩니다. Pushoff는 원치 않는 AO나 섀도우를 없애는 데 유용합니다. 이 설정은 오브젝트 표면에 오브젝트 자체의 섀도우가 생겨 분명한 소스 없이 표면에 얼룩진 섀도우 패턴이 나타나는 문제를 해결하는 데 사용합니다. 이 설정을 사용하여 미세한 디테일을 정확하게 레이 트레이스할 수 있을 만큼 부동 소수점 정밀도가 충분히 높지 않은 경우에 큰 오브젝트에서 원치 않는 결함을 제거할 수도 있습니다. 레이트레이싱을 위해 노멀을 따라 레이 원점을 밀어서 지오메트리에서 멀리 떨어트릴 거리(모델링 단위)입니다. 모든 베이크된 라이트맵에 적용되므로 직접광, 간접광, 베이크된 앰비언트 오클루전에 영향을 미칩니다. 원치 않는 오클루전/그림자를 없애는 데 유용합니다.
Baked Tag 위의 시스템 태그(System Tag) 프로퍼티와 유사하며, 오브젝트 집합을 별도의 베이크된 라이트맵으로 그룹화하는 데 사용할 수 있습니다. 시스템 태그와 마찬가지로, 정확한 숫자 값은 중요하지 않습니다. 베이크된 태그 값이 서로 다른 오브젝트는 절대로 같은 아틀라스 안에 포함되지 않습니다. 하지만 태그가 같은 오브젝트가 라이트맵 하나에 들어가지 않을 수 있으므로 같은 아틀라스에 포함된다는 보장은 없습니다(예는 아래 이미지 A 참조). 멀티씬 베이크 API를 사용하는 경우 그룹화가 자동으로 수행되므로 이 프로퍼티를 설정하지 않아도 됩니다. 베이크된 태그(Baked Tag) 를 사용하여 아틀라스 잠금(Lock Atlas) 옵션의 일부 동작을 모사할 수 있습니다. 자세한 내용은 아래의 베이크된 태그: 세부 정보를 참조하십시오.
Limit Lightmap Count Limit Lightmap Count 는 인라이튼 베이크된 전역 조명을 사용할 때는 제공되지 않습니다. Limit Lightmap Count는 동일한 베이크된 전역 조명 설정을 가진 게임 오브젝트를 패킹할 때 Unity가 사용할 수 있는 최대 라이트 맵 수를 적용합니다. Limit Lightmap Count를 활성화하면 아래에 Max Lightmaps라는 이름의 설정이 나타납니다. 이 설정을 사용하여 Unity가 사용할 수 있는 최대 라이트 맵 수를 설정하십시오.

Unity는 게임 오브젝트들이 동일한 Anti-aliasing Samples, Pushoff, Baked Tag  Backface Tolerance 값을 가진 경우 동일한 베이크된 전역 조명 설정을 사용한다고 간주합니다. 즉 Unity가 다른 라이트맵 파라미터 에셋과 연결된 게임 오브젝트들을 함께 패킹할 수 있습니다. 게임 오브젝트를 패킹하기 위해 Unity는 모든 게임 오브젝트가 지정된 라이트맵 수 안에 들어갈 때까지 UV 레이아웃을 점차적으로 스케일다운합니다. 라이트매퍼 설정은 이러한 라이트맵의 크기를 정의합니다. 이 프로세스는 게임 오브젝트의 라이트맵 해상도를 떨어뜨릴 수 있습니다.

 

베이크된 태그: 세부 정보

 

위 두 이미지에는 동일한 씬에 대한 두 가지 뷰가 나와 있습니다.

  1. 위: 모든 게임 오브젝트의 Baked Tag 가 같으므로 모두 하나의 아틀라스에 있습니다.
  2. 아래: 한 게임 오브젝트에 다른 Baked Tag 가 할당되어 있어 두 번째 라이트맵으로 들어갑니다.

베이크된 AO

이 파라미터는 베이크된 앰비언트 오클루전을 설정합니다.

프로퍼티기능

Quality 베이크된 앰비언트 오클루전(AO) 측정 시에 캐스트되는 레이의 수입니다. 레이 수가 많을수록 AO 품질이 향상되지만 베이크 시간도 늘어납니다.
안티앨리어싱 샘플(Anti-aliasing Samples) AO 안티앨리어싱을 수행할 때 사용할 샘플 수입니다. 샘플 수가 많을수록 AO 품질이 향상되지만 베이크 시간도 늘어납니다.

일반 GI

프로퍼티기능

Backface Tolerance 출력 텍셀에서 투사된 광선이 조명 시스템에서 사용 가능한 것으로 간주되기 위해 전면에 닿아야 하는 광선의 비율입니다. 이를 통해 Unity는 후면에 닿는 광선이 너무 많은 경우(예: 텍셀이 일부 지오메트리 내에 있는 경우) 텍셀을 무효화할 수 있습니다. 조명 시스템은 주위 텍셀에서 유효한 값을 복제하여 의도치 않은 결함을 방지합니다.

후면 허용치(Backface Tolerance) 를 0.0으로 설정하면 조명 시스템은 후면만 보일 때만 텍셀을 리젝트합니다. 1.0으로 설정하면 조명 시스템은 후면에 닿는 광선이 하나만 있어도 광선 원점을 리젝트합니다.

라이트맵 파라미터 에셋 할당(Assigning Lightmap Parameters Assets)

씬(Scenes)

전체 씬에 라이트맵 파라미터 에셋을 할당하려면 다음 단계를 따르십시오.

  1. 조명 창(Window > Rendering > Lighting)을 엽니다.
  2. Scene 탭을 클릭합니다.
  3. Lightingmapping Settings 로 이동합니다.
  4. Lightmap Parameters 드롭다운을 사용하여 디폴트 라이트맵 파라미터 에셋을 할당합니다. 드롭다운 리스트에는 사용 가능한 라이트맵 파라미터 에셋이 모두 나열됩니다.

게임 오브젝트(GameObject)

라이트맵 파라미터 에셋을 단일 게임 오브젝트에 할당하려면 게임 오브젝트에 Mesh Renderer 또는 Terrain 컴포넌트가 연결되어 있어야 합니다.

라이트맵 파라미터 에셋을 Mesh Renderer 컴포넌트에 할당하려면 다음 단계를 따르십시오.

  1. 인스펙터에서 Mesh Renderer > Lighting으로 이동합니다.
  2. Contribute Global Illumination 을 활성화합니다.
  3. Mesh Renderer 컴포넌트에서 Lightmapping > Lightmap Parameters로 이동합니다.
  4. 메뉴에서 옵션을 선택합니다. Scene Default Parameter 를 선택하여 전체 씬에 할당된 동일한 라이트맵 파라미터 에셋을 사용합니다.

라이트맵 파라미터 에셋을 Terrain 컴포넌트에 할당하려면 다음 단계를 따르십시오.

  1. 인스펙터에서 Terrain > Terrain Settings > Lighting으로 이동합니다.
  2. Contribute Global Illumination 을 활성화합니다.
  3. Terrain Settings에서 Lightmapping > Lightmap Parameters로 이동합니다.
  4. 메뉴에서 옵션을 선택합니다. Scene Default Parameter 를 선택하여 전체 씬에 할당된 동일한 라이트맵 파라미터 에셋을 사용합니다.

라이트맵 UV

일반적으로 UV라고 불리는 텍스처 좌표는 지오메트리 주위에 텍스처를 “래핑”하는 방법을 말합니다. 라이트맵은 텍스처이므로 Unity에서 씬을 올바르게 사용하려면 UV가 필요합니다.

이 섹션에서는 다음의 정보를 제공합니다.

페이지설명

라이트맵 UV 소개 베이크된 전역 조명 시스템과 실시간 전역 조명 시스템의 라이트맵 UV에 대한 정보를 소개합니다.
라이트맵 UV 생성 직접 라이트맵 UV를 제공하거나 Unity에서 자동으로 생성하도록 하는 방법.
라이트맵 UV 시각화 Unity에서 사용 중인 라이트맵 UV를 보는 방법.
라이트맵 UV 오버랩 해결 라이트맵 UV의 일반적인 문제를 해결하는 방법.

https://docs.unity3d.com/kr/2021.3/Manual/LightingOverview.html

 

조명 - Unity 매뉴얼

Unity에서 다양한 아트 스타일에 적합한 사실적인 조명을 구현할 수 있습니다.

docs.unity3d.com

 

광원 모드

이 페이지는 Light 컴포넌트 Mode 프로퍼티에 대한 정보를 제공합니다. 광원의 Mode 프로퍼티가 해당 목적을 정의합니다.

제공되는 모드는 다음과 같습니다.

  • Baked: Unity는 런타임 전에 베이트된 광원에서 조명을 미리 계산하고, 런타임 조명 계산에는 이를 포함하지 않습니다. 자세한 내용은 베이크된 광원을 참조하십시오.
  • Realtime: Unity는 런타임 시점에 프레임마다 실시간 광원의 조명을 계산하고 업데이트합니다. 실시간 광원에 대한 계산은 미리 수행하지 않습니다. 자세한 내용은 실시간 광원을 참조하십시오.
  • Mixed: Unity가 일부 혼합 광원의 계산을 미리 수행하거나 런타임 시점에 수행합니다. 자세한 내용은 혼합 광원을 참조하십시오.

광원 모드: Realtime

이 페이지에서는 Mode 프로퍼티를 Realtime으로 설정했을 때 Light 컴포넌트의 동작을 설명합니다. 이를 실시간 광원이라고도 합니다.

Unity는 실시간 광원에 대한 조명 계산을 런타임 시점에 프레임당 한 번 수행합니다. 런타임 시점에 실시간 광원의 프로퍼티를 변경하여 깜박이는 전구, 어두운 방을 통과하는 횃불 등과 같은 효과를 구현할 수 있습니다.

실시간 광원은 캐릭터나 움직이는 지오메트리에 조명을 비추고 그림자를 드리울 때 유용합니다.

실시간 광원 동작

  • 실시간 광원은 섀도우 거리까지 그림자를 드리웁니다.
  • 기본적으로 실시간 광원은 씬에 실시간 직접 조명만 제공합니다. 빌트인 렌더 파이프라인을 사용 중이고 프로젝트에서 인라이튼 실시간 전역 조명을 활성화하면 실시간 광원도 씬에 실시간 간접 조명을 제공합니다.

실시간 광원의 제한 사항

  • 실시간 광원에 대한 런타임 계산을 수행할 경우 복잡한 씬이나 저사양 하드웨어에서 성능 부하가 심할 수 있습니다.
  • 실시간 광원은 기본적으로 씬에 직접 조명만 제공하므로, 그림자가 완전히 검게 표시되고 컬러 바운스 같은 간접 조명 효과가 없습니다. 이로 인해 씬에 비사실적인 조명이 생길 수 있습니다.

광원 모드: Mixed

이 페이지에서는 Mode 프로퍼티를 Mixed로 설정했을 때 Light 컴포넌트의 동작을 설명합니다. 이를 혼합 광원이라고도 합니다.

혼합 조명은 실시간 조명과 베이크된 조명 요소를 결합합니다. 혼합 광원을 사용하여 동적 그림자를 동일한 광원의 베이크된 조명과 결합하거나 광원이 직접 실시간 조명과 베이크된 간접 조명에 기여하도록 하려는 경우에 사용할 수 있습니다.

혼합 광원을 사용하려면 먼저 실시간 광원 베이크된 광원의 이점과 제한 사항을 이해해야 합니다.

혼합 광원 동작

  • 씬에 있는 모든 혼합 광원의 동작은 라이팅 창의 Lighting Mode 설정에 따라 다릅니다. 각 조명 모드는 저마다 매우 다른 성능 특성과 다양한 수준의 시각적 정확도를 제공합니다. 자세한 내용은 조명 모드를 참조하십시오.
  • 혼합 광원의 프로퍼티는 런타임 시점에 변경할 수 있습니다. 이렇게 하면 실시간 조명은 업데이트되지만, 베이크된 조명은 업데이트되지 않습니다. 원치 않는 시각 효과가 발생하지 않도록 주의하십시오.

혼합 광원의 제한 사항

  • 혼합 광원의 성능 소모는 조명 모드에 따라 상당히 다릅니다. 그러나 혼합 광원은 항상 최소한 일부 실시간 조명과 일부 베이크된 조명을 결합하기 때문에 혼합 광원에는 항상 완전히 베이크된 조명보다 더 많은 런타임 계산이 필요하고 완전 실시간 조명보다 더 많은 메모리 사용량이 필요합니다.

광원 모드: Baked

이 페이지에서는 Mode 프로퍼티를 Baked로 설정했을 때 Light 컴포넌트의 동작을 설명합니다. 이를 베이크된 광원이라고도 합니다.

Unity는 Unity 에디터에서 베이크된 광원에 대한 계산을 수행하고 그 결과를 디스크에 조명 데이터로 저장합니다. 이러한 프로세스를 베이크라고 합니다. 런타임 시점에 Unity는 베이크된 조명 데이터를 로드하여 씬에 조명을 적용하기 위해 사용합니다. 복잡한 계산이 미리 수행되므로 베이크된 광원은 런타임 시점에 셰이딩 부하를 줄이고 그림자의 렌더링 부하도 낮춥니다.

베이크된 광원은 런타임 시점에 변하지 않는 요소(예: 풍경)에 조명을 적용할 때 유용합니다.

베이크된 광원 동작

  • Unity는 직접 조명과 간접 조명 모두를 베이크된 광원에서 라이트맵으로 베이크합니다. 라이트맵 사용에 대한 자세한 내용은 라이트매핑을 참조하십시오.
  • Unity는 직접 조명과 간접 조명 모두를 베이크된 광원에서 라이트 프로브로 베이크합니다. 라이트 프로브 사용에 대한 자세한 내용은 라이트 프로브를 참조하십시오.

베이크된 광원의 제한 사항

  • 베이크된 광원의 프로퍼티는 런타임 시점에 변경할 수 없습니다.
  • 베이크된 광원은 스페큘러 조명에 기여하지 않습니다.
  • 동적 게임 오브젝트는 베이크된 광원으로부터 광원이나 그림자를 받지 않습니다.

+ Recent posts