본문 바로가기
Shader CG

1.4 도형 - 타일링

by SimonLee 2023. 7. 13.

타일링을 해봅시다

타일링이라고 함은 특정 모양의 여러개의 타일들이 일정한 간격으로 배치가 되는 것을 의미 합니다.

우리는 사각형을 만드는 것을 배웠으니, 사각형 모양으로 여러개를 반복해서 렌더링 할 것입니다.

 

아래 타일링을 적용하는 코드는 아래 한 줄 입니다.

float2 pos = frac(i.position.xy * _TileCount);

원리는 다음과 같습니다.

frac 함수는 분위수 부분을 반환합니다.

frac(x) + floor(x) = x 로 정의 됩니다.

frac(x)는 분수 부분을 리턴합니다.

 

예를 들어

1) 11.43경우, floor는 11, frac은 0.43 입니다.

2) -1.4 음수 경우 = floor는 -2, frac은 0.6 입니다.

 

UnityObjectToClipPos 함수로 인하여,  i.position.xy 범위는 -0.5 ~ 0.5 입니다.

unity clip space 좌표계

 

중심이 (0, 0)에 가로, 세로길이가 0.4인 정사각형이 있다고 생각해봅시다.

 

그 정사각형의 position에 frac 함수를 넣어 봅시다.

pos = frac(pos);

결과는 1사분면만 그려지게 됩니다.

 

그 이유는 아래 그림의 C점을 예를 들면, 

X좌표 -0.1의 frac 값이 0.9가 되어서 X좌표의 픽셀값은 실제로 가져오는 곳은 (0.9, 0.1) 입니다.

해당 좌표는 이미 좌표계를 벗어나 있지요.

 

그래서 음수인 값이 하나라도 있으면 대부분 사각형을 벗어난 부분의 픽셀값을 가져오기 때문에

C, D, E 영역이 전부 그려지지 않게 됩니다.

 

잘 이해가 안되신 분들은 그려가면서 이해하셔야 합니다 =ㅠ=

frac(position)

 frac() 함수를 사용해서 타일링을 할때는,

음수좌표의 경우 예상하기가 어렵기 때문에 양수 좌표계 (0 ~ 1)인 Uv좌표를 이용합니다.

 

이렇게 없어지는 영역 문제를 없애기 위해,

먼저 정사각형의 중심을 원점에서 (0.5, 0.5)로 이동해 봅시다.

그렇게 되면 사각형의 모든 픽셀이 전부 양의 값을 가지게 되겠지요

 

 

그리고 그 다음에

position 값에 * TileCount (6) 를 곱해주면,

pos = frac(pos * 6 );

 

구간이 나누어지는 효과가 발생합니다.

r계

Tile 반복횟수를 좌표에 곱하게 되면, 정수 범위가 커지게 됩니다.

(0.3, 0.3) 좌표는 (1.8, 1.8) 되고, (0.9, 0.9) 좌표는 (5.4, 5.4) 가 됩니다.

즉 정수 6보다 작은 값으로 좌표가 구성이 됩니다.

6을 곱한 좌표 값에서 frac을 통해서 정수를 제거가 되면,

(0.3, 0.3) 좌표는 (0.8, 0.8) 되고, (0.9, 0.9) 좌표는 (0.4, 0.4) 가 됩니다.

 

 

정리하면 6개의 구간이 생기고 position 값은 각 구간마다 0 ~ 1 값을 가지게 된다.

Tiling 결과

 

Shader "SimonLee/Shader12Unlit"
{
    Properties
    {
        _Color("Square Color", Color) = (1.0,1.0,0,1.0)
        _Size("Size", Float) = 0.3
        _Anchor("Anchor", Vector) = (0.15, 0.15, 0.1, 0.3)
        _TileCount("TileCount", Int) = 6
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc" 

            fixed4 _Color;
            float _Size;
            float4 _Anchor;
            float _TileCount;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 position : TEXCOORD1;
            };

            v2f vert(appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.position = v.vertex;
                return o;
            }

            float rect(float2 pt, float2 anchor, float2 size, float2 center){
                float2 p = pt - center;
                float2 halfsize = size/2.0;
                float horz = step(-halfsize.x - anchor.x, p.x) - step(halfsize.x - anchor.x, p.x);
                float vert = step(-halfsize.y - anchor.y, p.y) - step(halfsize.y - anchor.y, p.y);
                return horz*vert;
            }

            float2x2 getRotationMatrix(float theta){
                float s = sin(theta);
                float c = cos(theta);
                return float2x2(c, -s, s, c);
            }

            float2x2 getScaleMatrix(float scale){
                return float2x2(scale,0,0,scale);
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                float2 center = _Anchor.zw;
                float2 pos = frac(i.position.xy * _TileCount);
                //float2 pos = i.position.xy;
                
                float2x2 matr = getRotationMatrix(_Time.y);
                float2x2 mats = getScaleMatrix((sin(_Time.y) + 1)/3 + 0.5);
                float2x2 mat = mul(matr, mats);
                
                float2 pt = mul(mat, pos - center) + center;
                  
                float3 color = _Color * rect(pt, _Anchor.xy, float2(_Size, _Size), center);
                
                return fixed4(color, 1.0);
            }
            ENDCG
        }
    }
}

 

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

1.6 도형 - 라인 그려보기  (0) 2023.07.20
1.5 도형 - Draw Circle 심화  (2) 2023.07.18
1.3 도형 - Rotation & Scailing Rect  (0) 2023.07.11
1.2 도형 - Draw Rectangle - 2  (0) 2023.07.09
1.2 도형 - Draw Rectangle - 1  (0) 2023.07.09