EasyCastleUNITY

2023/08/30 필기 (Light 관련 및 씬 비동기 전환) 본문

개인 필기

2023/08/30 필기 (Light 관련 및 씬 비동기 전환)

EasyCastleT 2023. 8. 30. 12:35

라이트 매핑 

씬에 배치된 모든 3D 모델에 영향을 미치는 직접 조명, 간접 조명 및 그림자의 효과를 텍스처로 미리 만드는 과정 

 

많은 3D 모델이 배치되어 있는 경우, 베이크 시간이 길어지고, 메모리를 많이 사용한다는 단점이 있다. 

 

UV 매핑

https://en.wikipedia.org/wiki/UV_mapping

 

UV mapping - Wikipedia

From Wikipedia, the free encyclopedia Process of projecting a 3D model's surface to a 2D image for texture mapping The application of a texture in the UV space related to the effect in 3D. A representation of the UV mapping of a cube. The flattened cube ne

en.wikipedia.org

2차원 그림을 3차원 모델로 만드는 모델링 프로세스

어느 것이든 normalized 되어 있는 것이 특징 -> 모델의 크기가 달라질 수 있기에,어느 모델이든 대응 될수 있도록 하기 위함

 

위에서 언급한 라이트 매핑을 적용하려면 uv를 가지고 있어야 한다. 

 

Contribute GI 플래그

또한 유니티에서 라이트 매핑 대상이 되려면

Contribute GI 플래그를 체크해야한다 

 

 

 

 

 

 

 

 

 

 

직접광원을 제거 해도 보이는 이유 -> 환경광이 남아있기 때문에(Ambient Light)

환경광원을 어떤 것으로 할 것인지

결정하는 속성

Intensity Multiplier -> 환경광원의 조도를 결정

 

 

 

 

ambient occlusion

https://namu.wiki/w/Ambient%20Occlusion

 

Ambient Occlusion - 나무위키

이 저작물은 CC BY-NC-SA 2.0 KR에 따라 이용할 수 있습니다. (단, 라이선스가 명시된 일부 문서 및 삽화 제외) 기여하신 문서의 저작권은 각 기여자에게 있으며, 각 기여자는 기여하신 부분의 저작권

namu.wiki

쉽게 말해서 어두운 곳은 더 어둡게 하는 역할을 한다.

 

라이트 매핑은 정적인 개체들만을 대상으로 한다. 그렇기에 움직이는 오브젝트들은 빛에 영향을 받지 못하게 된다.

 

옆에 사진은 정적이기에, 오브젝트를 옮겼음에도 불구하고

그 자리의 그대로 그림자가 있는 것을 보여주는 사진이다. 

 

 

 

 

 

이러한 점을 개선하기 위해 나온게, Light Probes 기능이다. 

주변의 광원에 대한 정보를 bake 할때 미리 저장해 놓고, 이 데이터를 동적 객체에 데이터를 전달해 

이 객체의 색상을 보간시켜 실시간 조명과 같은 효과는 내는 방식이다.

 

씬 분리하고 합치기

LoadSceneMode.Single: 기존에 로드된 씬을 모두 삭제한 후 새로운 씬을 로드한다. 

LoadSceneMode.Additive: 기존 씬을 삭제하지 않고 추가해서 새로운 씬을 로드한다.

동기로 씬로드 및 비동기로 씬로드 

동기 씬로드

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

public class App : MonoBehaviour
{
    private void Awake()
    {
        DontDestroyOnLoad(this.gameObject);  
    }
    private void Start()
    {
        //동기로 씬 로드
        SceneManager.LoadScene("Title");
        var titleMain = GameObject.FindAnyObjectByType<TitleMain>();
        Debug.Log(titleMain); //null 
        titleMain.Init();
        //비동기로 씬 로드
        //AsyncOperation이라는 타입의 값을 반환하고 있음
        //AsyncOperation oper= SceneManager.LoadSceneAsync("Title");
        ////로드가 완료되면, 뒤에 메서드를 실행, 비동기이기에 언제 로드가 완료될지 모르기에 가능
        //oper.completed += OnTitleSceneLoadComplete;
    }

    private void OnTitleSceneLoadComplete(AsyncOperation operation)
    {
        Debug.Log("로드 완료");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TitleMain : MonoBehaviour
{
    private void Awake()
    {
        Debug.Log("[TitleMain] awake");
    }
    private void OnEnable()
    {
        Debug.Log("[TitleMain] OnEnable");
    }
    private void Start()
    {
        Debug.Log("[TitleMain] start");
    }
    public void Init()
    {
        Debug.Log("[TitleMain] init");
    }
}

오브젝트를 찾지 못하고 있는 모습

비동기 로드 

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

public class App : MonoBehaviour
{
    private string version = "1.0";
    private void Awake()
    {
        DontDestroyOnLoad(this.gameObject);
    }

    private void Start()
    {
        //비동기 
        AsyncOperation oper = SceneManager.LoadSceneAsync("TitleScene");
        oper.completed += OnLoadCompleteTitleScene;
    }

    private void OnLoadCompleteTitleScene(AsyncOperation obj)
    {
        Debug.Log("Title씬 로드 완료");
        TitleMain titleMain = GameObject.FindObjectOfType<TitleMain>();
        titleMain.onChangeScene = (nickname) => {
            this.LoadGameScene(nickname);
        };
        Debug.LogFormat("titleMain: {0}", titleMain);
        titleMain.Init(this.version);
    }

    private void LoadGameScene(string nickname)
    {
        //비동기 로드 
        AsyncOperation oper = SceneManager.LoadSceneAsync("GameScene");
        oper.completed += (ao) => {
            GameMain gameMain = GameObject.FindObjectOfType<GameMain>();
            gameMain.Init(nickname);
        };

    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class TitleMain : MonoBehaviour
{
    [SerializeField]
    private Button btn;
    public System.Action<string> onChangeScene;

    private void Awake()
    {
        Debug.Log("[TitleMain] Awake");
    }

    private void OnEnable()
    {
        Debug.Log("[TitleMain] OnEnable");
    }

    private void Start()
    {
        Debug.Log("[TitleMain] Start");
    }

    public void Init(string version)
    {
        Debug.Log("[TitleMain] <color=yellow>Init</color>");
        Debug.LogFormat("version: {0}", version);

        this.btn.onClick.AddListener(() => {
            this.onChangeScene("홍길동");
        });
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameMain : MonoBehaviour
{
    private void Awake()
    {
        Debug.Log("[GameMain] Awake");
    }

    private void OnEnable()
    {
        Debug.Log("[GameMain] OnEnable");
    }

    private void Start()
    {
        Debug.Log("[GameMain] Start");
    }

    public void Init(string nickname)
    {
        Debug.LogFormat("[GameMain] <color=yellow>Init</color> : {0}", nickname);
    }
}

제대로 찾는 모습을 볼 수 있다.

 

'개인 필기' 카테고리의 다른 글

유니티 쉐이더  (0) 2023.08.31
2023/08/31 개인필기 (Occulusion Culling,Input System)  (0) 2023.08.31
2023/08/29 필기  (0) 2023.08.29
2023/08/28 필기 (오브젝트 풀링 내용 포함)  (0) 2023.08.28
2023/08/22 필기  (0) 2023.08.22