본문 바로가기

Programming

Shadertoy - 2d 도형 그리기

shadertoy는 webgl 기반으로 GLSL shader를 가지고 놀 수 있는 사이트다.

매우 제한적인 데이터만 사용하여 fragment shader를 구현할 수 있는데, 많은 사람들이 수학을 통해 온 몸을 뒤틀면서 굉장한 결과물들을 자랑하고 있다. 수학은 정말 굉장하다!

나도 종잇장으로 세계를 만들어 보고 싶어 한번 가지고 놀아보기로 했다.

도형을 그리는 코드는 여기를 참고하였다.

1. uv 좌표 설정

vec2 uv = vec2(1.0, -1.0) * (fragCoord - 0.5 * iResolution.xy) / iResolution.y;

- 기본 좌표 방향을 ↘ 에서 ↗ 으로 바꿈

- 영점을 (0.5, 0.5)만큼 이동

- 캔버스의 종횡비를 보정

2. 원 그리기

float circle = 1.0 - smoothstep(size-smooth_range, size,length(uv));

- if ( length(uv) < r) then 1 or 0

-> 최적화를 위해 if 대신 glsl에서 제공하는 step함수 사용

-> 안티 앨리어싱이 적용되는 smoothstep사용

* smoothstep

lerp가 선형으로 보간하는 방법이라면, smoothstep은 Hermite 보간법을 사용한다.

여기에서는 예쁜 안티앨리어싱을 위해 사용했지만, 아무래도 값을 이쁘게 섞고 싶을때 유용한 함수인 것 같다!

linear(lerp) vs smoothstep

3. 사각형 그리기

vec2 square = 1.0-smoothstep(vec2(size-smooth_range),vec2(size),abs(uv));
vec3 square_color = vec3(square.x * square.y);

- circle 때처럼 smoothstep을 사용해서 그렸다.

4. 두 도형 합치기

vec3 color = vec3(0,0,0);
color += circle_color + square_color;

- 배경색을 검정으로 깔고

- (도형이 겹쳐지지 않도록 각각 offset을 적용했다) 원과 사각형을 더하여 그려준다

결과

야호!

나도 수학으로 그림을 그려냈다!