본문 바로가기
튜터리얼_스터디

(HLSL)아티스트를 위한 URP 셰이더 Shader #10 - 버텍스 칼라 출력

by 대마왕J 2021. 10. 17.
더보기
안내 
여기 나오는 내용은 유니티 쉐이더 스타트업에 나오는 예제를 최신 URP에 맞추어 예제를 번역한 내용입니다. 
때문에 이론적 내용이 상당히 간략하거나 불친절하며, 예제에 대한 설명도 축약되어 있기 때문에
책과 같이 보시는 것을 추천하는 바입니다.

자 이번엔 버텍스 칼라 출력입니다. 
버텍스 칼라 그리는거야.. 맥스나 블렌더같은 3D 툴에서 그리면 되는데...

 

...귀찮잖아요 

 

뭐 요즘 게임 엔진에는 버텍스 칼라쯤은 자기가 그리는 기능도 가지고 있고 말이니까요 이럴땐 PolyBrush가 제격이죠 

빨강으로 카와이하게 그려줄께요 

뭐야 안 보이잖아... 

 

후후후 버텍스 칼라는 그렇게 쉬운 녀석이 아니니까요 (사실 쉬움)

일단 버텍스 칼라가 보이도록 만들어 줘야 합니다. (사실 오늘은 이게 다임)

 


1. 버텍스 칼라 보이기 

우선 새 셰이더에서 시작해 줄께요.  늘 그렇듯이. 

URPUnlitShaderBasic.shader
0.00MB

다운로드 안하고 직접 새로 만들어 보고 싶으신 분은 이걸 참고 하시면 되고요 

텍스쳐 한 장이 출력되는 기본 셰이더입니다. 

더보기
Shader "URPUnlitShaderBasic"
{
    Properties
    {
        _BaseMap("BaseMap",2D) = "white"{}
    }

    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS   : POSITION;
                float2 uv           : TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionHCS  : SV_POSITION;
                float2 uv           : TEXCOORD0;
            };

            TEXTURE2D(_BaseMap);
            SAMPLER(sampler_BaseMap);

            CBUFFER_START(UnityPerMaterial)
                float4 _BaseMap_ST;
            CBUFFER_END

            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = IN.uv;
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, TRANSFORM_TEX(IN.uv, _BaseMap));
                return color;
            }
            ENDHLSL
        }
    }
}

 

그리고 메터리얼을 만들고 만든 셰이더를 Plane 에 적용시켜 주고요 

셰이더그래프에서는 VertexColor 노드를 꺼내서 연결해 주기만 하면 끝났지만, 
코드로 하면 아무래도 좀 더 정통이다 보니까 과정이 있지요 

뭐 그래도 번거롭진 않은 편입니다. 

struct Attributes
  {
  float4 positionOS   : POSITION;
  float2 uv           : TEXCOORD0;
  float4 color        : COLOR; //버텍스 칼라 받아오기 
  };

struct Varyings
  {
  float4 positionHCS  : SV_POSITION;
  float2 uv           : TEXCOORD0;
  float4 color        : COLOR; //버텍스 칼라 출력하기 = 
  };

프리미티브 데이터에서 받아오는 Attributes 에서 버텍스칼라 color를 받아오게 하고, (이걸 버텍스 셰이더에서 쓰겠죠)
버텍스 셰이더에서 픽셀셰이더로 넘겨주는 구조체인  Varyings 에도 똑같이 color를 넘겨주면 됩니다. 

그리고 버텍스 셰이더에서는 Attributes 에서 받은걸 Varyings 로 넘기기만 하면 끝. 

Varyings vert(Attributes IN)
  {
  Varyings OUT;
  OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
  OUT.uv = IN.uv;
  OUT.color = IN.color; //Attributes 에서 받아서 Varyings로 토-스
  return OUT;
  }

그럼 다시 픽셀셰이더에서 이 버텍스 칼라를 받아와서 (Varyings로 부터) 
출력만 하면 된다 이말이죠 

half4 frag(Varyings IN) : SV_Target
  {
  half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, TRANSFORM_TEX(IN.uv, _BaseMap));

  half4 vcolor = IN.color;//버텍스 칼라를 받아와서
  return vcolor;//버텍스 칼라를 출력
  }

그러면 아주 잘 작동됩니다. 뭐 기본적인거니 쉽게 하실 수 있겠죠?

 후후후 겁나 간단. 가끔 이렇게 날로 먹을 때도 있어야지요

물론 이걸 응용해서 텍스쳐와 버텍스 칼라를 곱해준다던가 한다면, 밋밋한 지형에 색을 은근하게 넣어준다던가,

그림자를 쓸 수 없는 상황에서 은근하게 그림자를 그려준다던가 하는 짓도 할 수 있습니다
코드는 대충 이정도면 되겠지요

half4 frag(Varyings IN) : SV_Target
  {
  half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, TRANSFORM_TEX(IN.uv, _BaseMap));

  half4 vcolor = IN.color;//버텍스 칼라를 받아와서
  return color * vcolor;// 텍스쳐와 버텍스 칼라를 곱해서 출력
  }

오오 잘 되는군요.

책에서 소개하는 이 다음 내용은 아마도 터레인과 같은 텍스쳐 스플레팅을 구현해 보는 것이었겠죠? 
네 그건 다음 글에 이어서 할께요 

오늘 코드는 굉장히 간단했는데요. 그래요 날로 먹는 날도 있어야지요. 
이게 양이 중요한게 아니라 꾸준히 하는게 중요한거예요 

왜 뭐 왜 왜 뭐 뭐 뭐
VertexColor.shader
0.00MB

오늘의 풀 코드는 위와 같습니다. 
코드로 그냥 보고 싶으신 분은 아래쪽.

더보기
Shader "URPUnlitShaderVertexColor"
{
    Properties
    {
        _BaseMap("BaseMap",2D) = "white"{}
    }

    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS   : POSITION;
                float2 uv           : TEXCOORD0;
                float4 color        : COLOR; //버텍스 칼라 받아오기 
            };

            struct Varyings
            {
                float4 positionHCS  : SV_POSITION;
                float2 uv           : TEXCOORD0;
                float4 color        : COLOR; //버텍스 칼라 출력하기 = 
            };

            TEXTURE2D(_BaseMap);
            SAMPLER(sampler_BaseMap);

            CBUFFER_START(UnityPerMaterial)
                float4 _BaseMap_ST;
            CBUFFER_END

            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = IN.uv;
                OUT.color = IN.color; //Attributes 에서 받아서 Varyings로 토-스
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, TRANSFORM_TEX(IN.uv, _BaseMap));

                half4 vcolor = IN.color;//버텍스 칼라를 받아와서
                return color * vcolor;// 텍스쳐와 버텍스 칼라를 곱해서 출력
            }
            ENDHLSL
        }
    }
}

블로그 주인장에게 커피값을 후원할 수 있습니다! 

 

 

반응형

댓글