본문 바로가기
Shader CG

1.6 도형 - 라인 그려보기

by SimonLee 2023. 7. 20.

라인도 대각선 방향으로된 사각형의 영역이라고 생각하시면 됩니다.

 

사각형의 경우 렌더링 방법은

좌측하단 꼭지점과 우측 상단 꼭지점을 기준으로 영역을 지정하고,

좌측하단 꼭지점 영역 - 우측상단 꼭지점 영역으로 구했습니다.

 

모르시는 분 아래 포스팅 참조!

https://graphicsimon.tistory.com/12

 

5. Draw Rectangle - 1

지난 시간 원에 이어서 사각형을 렌더링 해봅시다. 결국은 동일한 원리 이지만, 이해를 돕기 위해 2가지 방법을 설명 드립니다. 사각형을 렌더링 함수를 rect라고 정의 하겠습니다. 함수의 인자는

graphicsimon.tistory.com

사각형의 경우 좌측하단 꼭지점이 (-0.2, -0.2)라고 하면

개념적으로 y = -0.2, x = -0.2라는 두 직선을 그어서 영역을 생각해 봅시다.

그래서 우리는 해당 꼭지점을 기준으로 우측 영역 선택되도록 계산을 했었습니다.

사각형 렌더링할때 영역

직선의 경우는 방정식은 y = x 를 떠올릴수 있을 것 입니다.

픽셀이 칠해지는 부분은 항상 x와 y의 값이 같아야 합니다.

선이 너무 얇으면 보이지 않으니, 위 아래로 몇픽셀씩 영역이 같이 잡히게 하면 됩니다.

 

쉬운것 부터 생각해봅시다.

x = y 영역

위 그림에서 A, B, C 점은 x좌표가 0으로 동일하고 y값만 다릅니다.

B지점의 영역만 선택하고 싶다고 하면 step(x, y) 하면 됩니다.

x 값이 y보다 큰놈만 1을 리턴하기 때문이지요.

float Line(float x, float y, float line_width) 
{                
    return step(x, y);
}

step(x, y)

 

 

직선을 렌더링 하기 위해 2개의 방정식이 필요합니다.

y = x - 0.5 그래프와 y = x + 0.5 그래프 두개를 그려보면 아래와 같습니다.

사각형 영역 구하는 것과 비슷합니다.

 

y = x + 0.5, y = x - 0.5 영역

1은 빨강색이 영역, 0은 검은색이 영역 입니다.

 

y = x - 0.5 그래프에서

아래 영역을 0, 위 영역을 1로 만드는 식은 다음과 같습니다.

= step(x - 0.5, y)

y = x + 0.5 그래프에서

아래 영역을 0, 위 영역을 1로 만드는 식은 다음과 같습니다.

= step(x + 0.5, y)

위 그림 영역에서 아래 영역의 그림을 빼주게 되면 우리가 원하는 선분의 영역이 나옵니다.

= step(x - 0.5, y) - step(x + 0.5, y)

여기서 0.5를 line_width 변수로 두어서 아래 Line 함수처럼 만들수 있습니다.

float Line(float x, float y, float line_width) 
{                
	return step(x - line_width, y) - step(x + line_width, y);
}

Line 결과

 

이번에는 smoothstep을 적용 하여 라인의 바깥쪽을 블러 효과처럼 부드럽게 해봅시다.

step 적용한 공식에서 조금 만 더 생각해보면 됩니다.

 

요구사항은 다음과 같습니다.

y = x + 0.5 에서 y = x + 0.6 그래프 사이를 블러링 하고싶고,

y = x - 0.5 에서 y = x - 0.6 그래프 사이를 블러링 하고 싶습니다.

= smoothstep(x - 0.6, x - 0.5, y) - smoothstep(x + 0.5, x + 0.6, y) 

 

영역을 구해봅시다.

x-0.6 보다 작은 부분 0

x-0.5 ~ x-0.6 보간 부분 0 ~ 1

x-0.5 보다 큰 부분 1

x + 0.5 보다 작은 부분 0

x + 0.5 ~ x + 0.6 : 보간 부분 0 ~ 1

x + 0.6 보다 큰 부분 1

 

위 두부분을 역시 빼주면 됩니다.

나머지는 동일하고 보간 영역이 바깥쪽에는 픽셀들이 0 값에 가깝다가 안쪽 영역에는 점차적으로 1이 됩니다.

 

여기서 블러링 되는 영역을 thick 변수로 표현을 해서 아래 line 함수로 나타내었습니다.

float Line(float2 pos, float line_width, float thick) 
{
    return smoothstep(pos.x - line_width - thick, pos.x - line_width, pos.y) -
        smoothstep(pos.x + line_width, pos.x + line_width + thick, pos.y);
}

smooth step 사용한 결과

Shader "Simonlee/Shader16Unlit"
{
    Properties
    {
        _Color("Color", Color) = (1.0,1.0,1.0,1.0)
        _LineWidth("Line Width", Float) = 0.01
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv: TEXCOORD0;
                float4 position: TEXCOORD1;
                float4 screenPos: TEXCOORD2;
            };
            
            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.position = v.vertex;
                o.uv = v.texcoord;
                o.screenPos = ComputeScreenPos(o.vertex);
                return o;
            }
           
            fixed4 _Color;
            float _LineWidth;
            
            float Line(float2 pos, float thick) {
                return smoothstep(pos.x - thick, pos.x, pos.y) -
                    smoothstep(pos.x, pos.x + thick, pos.y);
            }

            float Line(float x, float y, float line_width) {                
                return step(x - line_width, y) - step(x + line_width, y);
            }

            float Line(float x, float y) {                
                return step(x , y);
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float2 uv = i.screenPos.xy / i.screenPos.w;
            	float2 pos = i.position.xy * 2;
                //fixed3 color = _Color * Line(pos.x, pos.y, _LineWidth);
                fixed3 color = _Color * Line(pos.x, pos.y);

                return fixed4(color, 1.0);
            }
            ENDCG
        }
    }
}

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

2.2 Noise 모자이크 효과  (0) 2023.08.09
2.1 Noise TV 화면 만들어보기  (0) 2023.08.06
1.5 도형 - Draw Circle 심화  (2) 2023.07.18
1.4 도형 - 타일링  (0) 2023.07.13
1.3 도형 - Rotation & Scailing Rect  (0) 2023.07.11