본문 바로가기
Shader CG

기초 2. 블렌딩 해보자

by SimonLee 2023. 7. 5.

이전 단계에서는 화면에 파랑색을 표시 했습니다.

 

다시 복습하면

작성한 Shader를 보기 위해서는 다음 과정을 거칩니다.

Shader 작성 -> 매터리얼에 작성한 Shader 선택 -> Quad 오브젝트에 매터리얼 등록

-> Quad 오브젝트를 Scene 배치 -> 카메라를 Orthographic 으로 수정.

 

------------------------------------------------------------------------------------------

이번에는 쿼드의 색상을 계속 변하도록 만들어 봅시다.

------------------------------------------------------------------------------------------

 

fixed3 structure x,y,z에 대응하는 값들을 다음과 같이 세팅해봅시다.

x: (sin(_Time.y) + 1) / 2

y : 0

z : (cos(_Time.y) + 1) / 2

 

sin, cos 함수는 -1 ~ 1의 Range를 가지고 있으므로 + 1을 하고 2로 나누어 주면

0 ~ 1 Range를 가지게 됩니다.

 

fragment shader의 리턴값은 fixed4 type 입니다.

(x,y,z,w) 해당되는 값은 RGBA 값 입니다.

x : 빨강, z : 파랑 값이 0 ~ 1로 변하게 되므로, 색의 변화는 빨강 계열 <--> 파랑 계열로 변화가 일어날 것 입니다.

 

Shader "SimonLee/Shader2Unlit"
{
    Properties
    {
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag

            #include "UnityCG.cginc"

            fixed4 frag(v2f_img i) : SV_Target
            {
                fixed3 color = fixed3((sin(_Time.y) + 1) / 2, 0, (cos(_Time.y) + 1) / 2);
                
                return fixed4(color, 1).gbra;
            }
            ENDCG
        }
    }
}

 

fixed(color, 1) 뒤에 붙은 gbra는 뭘까요 ?

rgba순서를 gbra로 바꾼 다는 의미 입니다.

fixed4 원소의 (x, y, z, w) 순서가 (y, z, x, w)로 변화가 됩니다.

 

결과 Unity 화면

 

RenderType 경우는 투명이 아니면 Opaque를 사용을 합니다.

그 밖에 여러 type이 존재하는데 아래 공식문서를 참조 합시다.

https://docs.unity3d.com/kr/530/Manual/SL-ShaderReplacement.html

 

대체 셰이더로 렌더링 - Unity 매뉴얼

일부 렌더링 효과를 위해 다른 셰이더로 씬을 렌더링해야 하는 경우가 있습니다. 예를 들어, 에지 감지를 제대로 하려면 표면 방향 차이를 감지할 수 있도록 씬 노멀이 있는 텍스처가 필요합니

docs.unity3d.com

 

------------------------------------------------------------------------------------------

이번에는 색상을 인자로 받아서 블렌딩 해봅시다.

------------------------------------------------------------------------------------------

Properties 항목에는 인자로 받을 놈들을 넣어 줍시다.

우리는 블렌딩할 색상 A, B를 입력으로 넣습니다.

 

자세한 건 아래 문서를 참고하시고요

https://docs.unity3d.com/kr/530/Manual/SL-Properties.html

 

ShaderLab: 프로퍼티(Properties) - Unity 매뉴얼

셰이더는 Unity의 머티리얼 인스펙터에서 아티스트의 설정을 위한 파라미터 리스트를 정의할 수 있습니다. 셰이더 파일의 프로퍼티 블록이 이를 정의합니다.

docs.unity3d.com

Unity에서는 밑줄 표시로 셰이더 프로퍼티 이름을 시작하는 것이 일반적이라네요.

 

프로퍼티에 등록을 했으면 CG Shader 에서 선언을 해야 사용할수 있습니다.

fixed4 _ColorA, fixed4 _ColorB로 선언을 했습니다.

 

블렌딩을 할때 lerp 함수를 사용했네요

lerp 함수는 (Source, Destination, delta)로 구성되어 있습니다.

delta 값은 0 ~ 1의 범위를 가지며  (Source * delta) + (Destination * ( 1- delta)) 계산됩니다.

쉽게 말해서

0이면 Source에 가깝고, 1이면 Destination에 가깝습니다.

 

delta 값은 i.uv.x를 사용했고, 이는 v2f_img라는 type을 사용하는데

struct v2f_img
{
    float4 pos : SV_POSITION;
    half2 uv : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
    UNITY_VERTEX_OUTPUT_STEREO
};

v2f_img sturct에 두번째 원소에 uv 가 있습니다.

uv는 Texture Cordinates 입니다.

Texture Coordinates는 0 ~ 1의 범위를 가지고 Texture에서 색상을 샘플링 할때 사용됩니다.

 

현재 Unity Quad 오브젝트를 사용하고 있습니다.

Quad 오브젝트의 4개의 꼭지점에 해당하는 UV 값이 지정이 되어 있습니다.

위 값들은 래스터 라이제이션에서 보간되어 각 프래그먼트마다 보간된 UV값을 가지고 있습니다.

이 보간된 UV중 첫번째 원소 x값도 역시 0 ~ 1 범위를 가지고 있습니다.

Quad 오브젝트 각 픽셀의 x값이 커짐에 따라 uv.x도 같이 커지기 때문에, 

오른쪽으로 갈수록 ColorB의 색상과 가까워 집니다.

 

Shader "SimonLee/Shader4Unlit"
{
    Properties
    {
        _ColorA("Color A", Color) = (1,0,0,1)
        _ColorB("Color B", Color) = (0,0,1,1) 
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag

            #include "UnityCG.cginc"

            fixed4 _ColorA;
            fixed4 _ColorB;

            fixed4 frag(v2f_img i) : SV_Target
            {
                float delta = i.uv.x;
                fixed3 color = lerp(_ColorA, _ColorB, delta);
                return fixed4(color, 1.0);
            }
            ENDCG
        }
    }
}

 

 

Unity 결과 화면

 

 

------------------------------------------------------------------------------------------

마지막 예제 입니다. 

또다른 블렌딩 예제입니다.

------------------------------------------------------------------------------------------

이번에는 Vertex Shader도 정의해 봅시다.

vert라는 함수가 Vertex Shader 입니다.

아래 보면 Vertex Shader에서 Framgment Shader로 보간을 할 정보를 넘겨주는데, 

v2f 구조체에서 vertex, position,  uv 입니다.

 

VertexShader에서 해야하는 일중 하나가 로컬스페이스 좌표를 클립스페이스로 옮겨주어야 합니다.

이를 위해 내부 함수인 UnityObjectToClipPos() 함수를 사용합니다.

좌표계 -0.5 ~ 0.5 범위를 가지게 됩니다.

여기서 좌표값에 2를 곱하게 되면 ,

좌표계 -1 ~ 1의 범위를 가지게 됩니다.

 

Saturate 함수는 0 ~ 1 범위로 만들어 줍니다. 

0 보다 작으면 0, 1보다 크면 1, 중간 값이면 그대로 값을 취합니다. 

 

그림을 그려보면 다음과 같습니다.

클립 스페이스에서 사용한 position에 해당하는 좌표는 검은색이고, saturate 통해 변경된 값은 파랑색으로 표시했습니다.

검은색 영역은 R, G에 해당하는 영역이 (0, 0) 이고

빨강색 영역은 R, G ( 1, 0 ), 초록색 영역은 R, G ( 0, 1 ) , 노랑색은 (1, 1) 입니다.

 

여기서 0에 해당하는 영역은 saturate에 의해 확실하게 0 인 반면에,

1이라고 쓴 영역은 0 ~ 1에 해당하는 값을 가졌기에 경계가 스무스하게 블렌딩 된것을 확인할 수 있습니다. ^^

Shader "SimonLee/Shader5Unlit"
{
    Properties
    {
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct v2f {
                float4 vertex: SV_POSITION;
                float4 position: TEXCOORD1;
                float2 uv: TEXCOORD0;
            };
            
            v2f vert(appdata_base v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.position = v.vertex;
                o.uv = v.texcoord;
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 color = saturate(i.position * 2);
                return fixed4(color, 1.0);
            }
            ENDCG
        }
    }
}

 

참고 사이트

CG API

https://developer.download.nvidia.com/cg/index_stdlib.html

 

Cg Standard Library Documentation

 

developer.download.nvidia.com

예제 가져온 곳

https://niklever.com/courses

'Shader CG' 카테고리의 다른 글

1.2 도형 - Draw Rectangle - 1  (0) 2023.07.09
1.1 도형 - draw Circle  (0) 2023.07.09
기초 3. 블렌딩 해보자 (step, smoothstep)  (0) 2023.07.06
기초 1. Shader 배워보자.  (0) 2023.07.05
기초 2. 기본 색상 출력 해보기  (0) 2023.06.28