카테고리 없음

내일배움캠프 36일차 TIL 유니티 3D 팀프로젝트 - Zomvid 19(3)

joseph2518 2024. 11. 4. 21:39

20241104 / Unity_6차  9주차 월요일

 

 

저번에 했던 Skybox에 이어서...

 

환경 변화요소는 2가지가 있다.

 

낮과 밤, 그리고 날씨다.

 

Skybox는 서서히 변해야 한다. 그런데 낮과 밤이 바뀌는 동안 날씨가 바뀔 수도 있도록 하고 싶었다.

 

가지고 있는 Skybox는 맑은 낮, 맑은 밤, 구름낀 낮, 구름낀 밤이다.

 

낮에서 밤으로 변하는 동안 날씨가 맑음에서 흐림으로 전환되기 시작한다면

Skybox는 맑은 낮, 맑은 밤, 흐린 밤이 혼재된 상태가 된다.

 

물론 두 개 이상의 트랜지션이 공존하지 않게 하면 되지만 아이디어가 있다면 부딪쳐 보기로 했다.

private void DayNightTransition()
{
    if (dayNightTransition == false)
    {
        if (isTargetNight == false && WorldTimeHour > 0.8 - weatherTransitionTime / 2)
        {
            Debug.Log("저녁되기 시작");
            dayNightTransition = true;
            isTargetNight = true;
            startDayTransitionTime = WorldTime;

            if (weatherTransition == false)
            {
                targetWeatherOption1 = GetWeatherOption(isTargetNight, targetWeather);
                startTransitionTime1 = WorldTime;
            }
            else
            {
                targetWeatherOption2 = GetWeatherOption(isTargetNight, targetWeather);
                startTransitionTime2 = WorldTime;
            }
        }
        else if (isTargetNight == true && WorldTimeHour > 0.2 - weatherTransitionTime / 2 && WorldTimeHour < 0.5)
        {
            Debug.Log($"아침되기 시작");
            dayNightTransition = true;
            isTargetNight = false;
            startDayTransitionTime = WorldTime;

            if (weatherTransition == false)
            {
                targetWeatherOption1 = GetWeatherOption(isTargetNight, targetWeather);
                startTransitionTime1 = WorldTime;
            }
            else
            {
                targetWeatherOption2 = GetWeatherOption(isTargetNight, targetWeather);
                startTransitionTime2 = WorldTime;
            }
        }
    }
    else
    {
        if (WorldTime > startDayTransitionTime + weatherTransitionTime)
        {
            Debug.Log("낮밤 전환 끝");
            dayNightTransition = false;

            currentWeatherOption = targetWeatherOption1;
            targetWeatherOption1 = targetWeatherOption2;

            startTransitionTime1 = startTransitionTime2;
        }
    }
}

private void WeatherTransition()
{
    if (WorldTime >= targetWeatherTime)
    {
        CurrentWeather = targetWeather;
    }

    if (weatherTransition == false)
    {
        if (WorldTime > targetWeatherTime - weatherTransitionTime / 2)
        {
            Debug.Log("날씨 변경 시작");
            weatherTransition = true;
            targetWeather = reservedWeather;
            startWeatherTransitionTime = WorldTime;

            if (dayNightTransition == false)
            {
                targetWeatherOption1 = GetWeatherOption(isTargetNight, targetWeather);
                startTransitionTime1 = WorldTime;
            }
            else
            {
                targetWeatherOption2 = GetWeatherOption(isTargetNight, targetWeather);
                startTransitionTime2 = WorldTime;
            }
        }
    }
    else
    {
        if (WorldTime > targetWeatherTime + weatherTransitionTime / 2)
        {
            Debug.Log("날씨 전환 끝");
            weatherTransition = false;
            targetWeatherTime = float.MaxValue;

            currentWeatherOption = targetWeatherOption1;
            targetWeatherOption1 = targetWeatherOption2;

            startTransitionTime1 = startTransitionTime2;

            ReserveNextWeather(); // 다음 날씨 예약
        }
    }
}

 

낮밤, 그리고 날씨 중 먼저 시작된 트랜지션이 targetWeatherOption1을 차지하게 된다.

 

그리고 첫번째 트랜지션이 끝나면 currentWeatherOption은 targetWeatherOption1으로,

targetWeatherOption1은 targetWeatherOption2로 밀어쓰기 한다.

 

스카이박스도 3개가 혼재되면 머테리얼은 3개, lerp값은 2개여야 하기 때문에 셰이더 코드도 변경했다.

Shader "Custom/BlendPanoramicSkybox"
{
    Properties
    {
        _Tex1 ("Panorama Texture 1", 2D) = "white" {}
        _Tex2 ("Panorama Texture 2", 2D) = "white" {}
        _Tex3 ("Panorama Texture 3", 2D) = "white" {}
        _Exposure1 ("Exposure 1", Range(0, 5)) = 1.0
        _Exposure2 ("Exposure 2", Range(0, 5)) = 1.0
        _Exposure3 ("Exposure 3", Range(0, 5)) = 1.0
        _Blend ("Blend Factor", Range(0, 1)) = 0.5
        _Blend2 ("Blend Factor 2", Range(0, 1)) = 0.0
    }
    SubShader
    {
        Tags { "Queue" = "Background" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD0;
            };

            sampler2D _Tex1;
            sampler2D _Tex2;
            sampler2D _Tex3;
            float _Exposure1;
            float _Exposure2;
            float _Exposure3;
            float _Blend;
            float _Blend2;

            v2f vert (appdata_t v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float theta = atan2(i.worldPos.z, i.worldPos.x);
                float phi = acos(i.worldPos.y / length(i.worldPos));
                
                float2 uv;
                uv.x = - (theta / (2.0 * UNITY_PI)) + 0.5;
                uv.y = 1.0 - (phi / UNITY_PI); // v 좌표 반전

                fixed4 col1 = tex2D(_Tex1, uv) * _Exposure1;
                fixed4 col2 = tex2D(_Tex2, uv) * _Exposure2;
                fixed4 col3 = tex2D(_Tex3, uv) * _Exposure3;

                // 두 텍스처를 먼저 혼합
                fixed4 blendedColor = lerp(col1, col2, _Blend);

                // _Blend2 값이 0이 아니면 세 번째 텍스처를 추가로 혼합
                if (_Blend2 != 0.0)
                {
                    blendedColor = lerp(blendedColor, col3, _Blend2);
                }

                return blendedColor;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}