Z Buffer

2022. 7. 25. 15:03Public/Graphics

가장 먼저 그려지는 건 배경일까 ? 캐릭터일까?

이펙트일까? UI 일까 ?

답은 그려지는 순서는 제멋대로이다. 특정한 명령이나 그룹핑에 따라서 그리는 순서를 조정할 수 있지만

간단하게 "계산이 다 끝난 녀석을 그린다" 이다.

그러니 어느것이 먼저 그려졌는지 알 수 없다.

 

검은색 공이 먼저 그려졌는지 , 뒤에 있는 하얀색 큐브가 먼저 그려졌는지 알 수 없다

 

"일단 순서는 상관없이 그린다" 라는 대전제로 시작하겠습니다.

 

 

뒤에 있는 오브젝트가 먼저 그려지고 앞에 있는 오브젝트가 그려질 때

뒤에 있는 하얀색 큐브와 앞에 있는 검은색 공이 있습니다.

 

뒤에 있는 하얀색 큐브가 먼저 그려지고 앞에 있는 검은색 공이 뒤에 그려지면 문제 없이 그려집니다.

그냥 그려진 큐브 위에다가 검은색 공을 덧그리면 되니까요.

이것을 '오버드로우(OverDraw)'라고 합니다.

 

문제는 앞에 있는 오브젝트가 먼저 그려지고 뒤에 있는 오브젝트가 그려질때 입니다.

앞에 있는 오브젝트가 먼저 그려지고 뒤에 있는 오브젝트가 그려질 때

 

앞뒤를 판정하는 정보가 없다면 나중에 그려진 '뒤에 있는 오브젝트'가 앞의 오브젝트를 덮어버립니다.

뒤에 그려졌으니까요. 이럴경우에는 문제가 생깁니다.

예시 이미지

이문제를 피하기 위해서는 "네 앞에 이미 그려진 녀석이 있어!" 라는 정보가 있어야 그부분을 피해서 그립니다.

바로 이 정보를 Z  버퍼(Z Buffer)라고 부릅니다.

다시 한번 정리하자면 

"앞뒤 판정을 위해서, 각 픽셀마다 카메라를 기준으로 가장 가까운 오브젝트의 깊이값이 저장되어 있는 데이터 시트가 필요합니다." 라는 말이 되고 이 값은 1.000 ~ 0.000의 숫자로 나타낼 수 있습니다.

그리고 이 '깊이 값'을 각 픽셀별로 그려놓은 그림이 바로 Z버퍼 입니다.

 

Shader "Custom/0725Depth"
{
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert noambient noshadow

        #pragma target 3.0


        sampler2D _CameraDepthTexture;
        struct Input
        {            
            float4 screenPos;
        };        

        void surf (Input IN, inout SurfaceOutput o)
        {            
            float2 sPos = float2(IN.screenPos.x, IN.screenPos.y) / IN.screenPos.w;
            float4 Depth = tex2D(_CameraDepthTexture, sPos);
            o.Emission = Depth.r;
            o.Alpha = 1;
        }
        ENDCG
    }
    FallBack "Diffuse"
}