내일배움캠프 - TIL/내일배움캠프 - TIL

내일배움캠프 23일차 - Unity 3D 상에서 Plane 생성 시 위로 이동하면 안보이는 이슈

rudals4469 2025. 5. 20. 21:06

오늘은 정말 미스테리 한 이슈를 하나 발견해서 정리를 해볼 까 한다.

 

내가 유니티 3D 환경에서 Plane으로 오브젝트를 만들고 그 오브젝트를 포인트 사이를 왔다 갔다하는 로직을 만들어보았는데,

이때 플레인이 위아래로 움직일 시 특정 높이 이상으로 올라가면 보이지 않는 문제가 있었다.

 

최하단의 Plane Object
올라간 상태의 Plane Object

 

위의 사진들을 비교하면 밑에 있을 땐 보이지만 조금만 올라가도 그림자만 보이고 보이지 않는 문제가 생겼다.

단순이 게임 창에서 올라간 게 아니라 일정 높이 이상으로 올라가면 게임 창에서 보이지 않게 되는 문제다.

 

구글링을 해봐도 나오는 내용도 없어서 튜터님께 질문하러 갔는데

 

유니티는 3D 상에서 평면 도형은 한 쪽만 렌더링 하는 문제라고 하신다.

이를 해결 하기 위해서는 쉐이더를 직접 만들어서 Cull off 시켜 주면 된다고 하신다.

 

사실 쉐이더는 정말 건들어 본 적이 없어 어떻게 해야 하나 싶었는데 튜터님이 아직 힘든 내용일 꺼라 쉐이더를 하나 직접 코딩하셔서 주셨다.

 

 

Shader "Custom/ExplicitDoubleSided"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        Pass
        {
            Cull Off // 컬링 비활성화
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"
            
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };
            
            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float3 worldNormal : TEXCOORD1;
                float3 worldPos : TEXCOORD2;
            };
            
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;
            half _Glossiness;
            half _Metallic;
            
            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {
                // 알베도 텍스처
                fixed4 col = tex2D(_MainTex, i.uv) * _Color;
                
                // 기본 디퓨즈 라이팅
                float3 worldNormal = normalize(i.worldNormal);
                float nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
                float3 diffuse = nl * _LightColor0.rgb;
                float3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
                col.rgb *= diffuse + ambient;
                
                return col;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

 

사실다 볼 필요는 없고 저 위의  Cull Off만 해주면 된다고 하신다. (사실 그 전에 따른 쉐이더파일에서 했는데 안되서 튜터님이 직접 쓰시던거 주신거다.)

 

cull 옵션은 아래와 같다.

cull back 앞면만 렌더링 한다. 쉐이더에 아무것도 적혀있지 않으면 cull back이 기본이다.
cull front 뒷면만 렌더링 한다. 노멀을 뒤집는 것은 아니다.
cull off 양면을 렌더링한다. 

 

사실 이 내용이 아직 이해가 잘 안된다.

 

내 식으로 해결을 하면 

1. 그냥 평면도형으로 만들 지 말고 큐브 처럼 입체 도형으로 만든다.

2. 그냥 나중에 배울 URP를 사용하면 저절로 해결될 문제라고 한다.