본문 바로가기
유니티/Shader Study

URP Shader Study #9 - UV 정보를 픽셀 셰이더에 출력, Texture Splatting

by witn331ss 2023. 12. 3.

Frame Debugger

 

실제 Transparent는 뎁스버퍼에 쓰지 않는다.

 

Depth PrePass 라고 반투명을 뎁스 프리패스에 한번 더 그리는 명령어가 있는데

urp는 아직 지원을 안하고 있다.

 

..

 

 

UV 정보를 픽셀 셰이더에 출력

 

버텍스 버퍼에 uv를 선언해준다 (보간기에도 동일)
                float2 uv : TEXCOORD0;
                
버텍스 버퍼에 선언한 UV를 읽어와서 버텍스 셰이더에 맵핑해준다
            o.uv = v.uv.xy;

이제 픽셀셰이더에서 볼 수 있게끔 호출해주자
   				 float4 Color = float4(i.uv.x, i.uv.y, 0, 1);
                return Color;

 

z값은 필요없으니 0

alpha 값은 보여야하니 1

 

 

자 이걸 UV값중 U만 표현하다고 하면 어떤식으로 해야할까?

 

바로 픽셀 셰이더 레벨에서 i의 uv.x 만 가져오면 되는 것이다.

 

                float4 Color = i.uv.x;

 

 

 

감마커렉션을 한번 알아 볼 것인데 먼저 다음과 같이 작성해주자

        half4 frag(VertexOutput i) : SV_Target
        {

            float4 color = color;
            if (i.uv.y > 0.5) // Y가 0.5보다클때 즉, V값을 기준으로 반을 가른다는 소리임
            {
                color = pow(i.uv.x, 2.2); // 2.2(감마)만큼 X를 거듭제곱 시킨다
            }
            else // Y가 0.5보다 작을 때 
            {
                color = i.uv.x; // 그냥 uv.x를 출력한다
            }
            return color;
        	}

 

 

위는 우리가 보통 알고있는 자연스러운 그라데이션이고

아래는 수학의 값으로써 0부터 1이다.

 

https://www.slideshare.net/jpcorp/ss-96115075

 

감마가 어디감마

감마가 어디감마 - Download as a PDF or view online for free

www.slideshare.net

대마왕님의 감마설명인데 한번 쯤 읽어봄직하다.

 

 

방금 코드는 삼항 연산자로 간략화 할 수 있다.

근데 이건 가독성의 차이지 코드 컴파일링 하면 비용은 똑같이 든다

   float4 color = i.uv.y > 0.5 ? pow(i.uv.x, 2.2) : i.uv.x;
   // 조건문 ? 참(True)일 때 실행값 : 거짓(False)일때 실행값 ;
            return color;

https://illu.tistory.com/1442

 

Unity Shader에서 if문 사용과 삼항 연산자 사용에서의 compile 코드 비교.

참고 : blog.hybrid3d.dev/2020-12-21-reason-for-slow-of-if-statement-in-shader 쉐이더에서 IF 문이 느린 이유 개요 쉐이더에서 if 문이 성능에 좋지 않다는 것은 프로그래머가 아니더라도 많이들 알고 있는 사실이

illu.tistory.com

해당 블로그에 설명이 되어있으니 참고하면 좋다.

 

 

비교연산자 참고

 

쉐이더에서 많이 쓰이는 연산자는

*= 같이 곱하고 대입하는 것을 많이 쓴다.

+= 같은 더하고 대입하는 것도 사용

 

비교연산자는 특별한 상황에서 사용된다고 생각하면 좋다.

 

 

Texture Splatting

두장의 텍스쳐를 아씨발 샘플러 텍스쳐 씨발 진짜

 

이런식으로 텍스쳐 2D와 샘플러의 이름을 맞춰야하는걸 3시간동안 대가리 부딫히다가 알게됨;;;

 

하여튼 문제가 있는 분들이 본다면 한번 체크해보시고..

 

다시 이어서 하겠음..

 

 

프로퍼티스
           _Texture2D_01("Texture2D_01", 2D) = "white" {}
           _Texture2D_02("Texture2D_02", 2D) = "white" {}
           

버텍스 버퍼레벨 

                float2 uv : TEXCOORD0;

보간기

            float2 uv  : TEXCOORD0;
            float2 uv2 : TEXCOORD1;


함수지정 
            float4 _Texture2D_01_ST, _Texture2D_02_ST;
            Texture2D _Texture2D_01, _Texture2D_02;

            SamplerState sampler_Texture2D_01;
            // 진짜 반드시 텍스쳐 '이름'이랑 '샘플러_이름'은 맞춰라..
            
버텍스셰이더
            o.uv = v.uv.xy * _Texture2D_01_ST.xy + _Texture2D_01_ST.zw;
            o.uv2 = v.uv.xy * _Texture2D_02_ST.xy + _Texture2D_02_ST.zw;


픽셀 셰이더
            float4 Texture01 = _Texture2D_01.Sample(sampler_Texture2D_01, i.uv);
            float4 Texture02 = _Texture2D_02.Sample(sampler_Texture2D_01, i.uv);

            float4 color = lerp(Texture01, Texture02, i.uv.x);

 

 

섞인다 섞여!!!!!!!

 

 

마스크 텍스쳐를 사용한 텍스쳐 블렌딩

두 장의 텍스쳐를 마스크 텍스쳐를 이용해 더하는 방식이다.

이 경우에는 RGBA채널을 사용하는 마스크에서 각 색 영역이 중복이 없어야지 깔끔하게 나온다

 

프로퍼티스

    _MaskTex("Mask Texure", 2D) = "white" {}


픽셀셰이더를 이렇게 변경

 half4 frag(VertexOutput i) : SV_Target
        {
            float4 Texture01 = _Texture2D_01.Sample(sampler_Texture2D_01, i.uv);
            float4 Texture02 = _Texture2D_02.Sample(sampler_Texture2D_01, i.uv);

            float mask = _Texture2D_01.Sample(sampler_Texture2D_01, i.uv);
            //Texture01번의 정보를 활용

            float4 color = lerp(Texture01, Texture02, mask.r); 
           //Texture01의 R부분을 마스킹 한다


                return color;
       	
        	}

 

그럼 이렇게 된다.