라인도 대각선 방향으로된 사각형의 영역이라고 생각하시면 됩니다.
사각형의 경우 렌더링 방법은
좌측하단 꼭지점과 우측 상단 꼭지점을 기준으로 영역을 지정하고,
좌측하단 꼭지점 영역 - 우측상단 꼭지점 영역으로 구했습니다.
모르시는 분 아래 포스팅 참조!
https://graphicsimon.tistory.com/12
사각형의 경우 좌측하단 꼭지점이 (-0.2, -0.2)라고 하면
개념적으로 y = -0.2, x = -0.2라는 두 직선을 그어서 영역을 생각해 봅시다.
그래서 우리는 해당 꼭지점을 기준으로 우측 영역 선택되도록 계산을 했었습니다.
직선의 경우는 방정식은 y = x 를 떠올릴수 있을 것 입니다.
픽셀이 칠해지는 부분은 항상 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);
}
직선을 렌더링 하기 위해 2개의 방정식이 필요합니다.
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);
}
이번에는 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);
}
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 |