GLSL을 통해 Halftone 효과를 구현한 이미지 입니다.
위 이미지에 보이는 하프톤 효과를 셰이더를 통해 구현해봅시다.
기본적으로 threejs를 사용합니다.
https://github.com/deeean/threejs-playground
해당 레포를 클론 하고
yarn
yarn dev
위 명령어를 입력하여 개발서버를 띄우고 접속합니다.
이런 화면이 나오면 성공입니다.
이제 /src/entities/Plane/Plane.frag
파일로 들어가서
varying vec2 vUv;
uniform float time;
uniform sampler2D channel0;
void main() {
vec2 st = vUv;
float pixels = 20.0;
gl_FragColor = texture2D(channel0, floor(st * pixels) / pixels);
}
위와 같이 입력해 줍니다.
과일 사진이 이렇게 모자이크가 들어간 상태로 보입니다.
왜 이렇게 그려지는지 생각해봅시다.
floor(st * pixels) / pixels
이 부분을 설명하겠습니다.
pixels는 일단 10이라고 가정합니다.
st라는 vec2변수는 x, y가 0 ~ 1 소수점으로 된 좌표값입니다.
st * 10 을 한다고 생각해보면
0 ~ 10 까지 소수점을 지나서 도달하게됩니다.
floor 내림 하면 0, 1, 2, 3 ... 10 이렇게 소수점이 사라지고
다시 st / 10.0 을 하면 0, 0.1, 0.2, 0.3 ... 1.0 이런식으로 텍스쳐를 그리기때문에
모자이크가 된것입니다.
모자이크된 색상은 다른 변수에 저장해두고
이제 하프톤을 만들기위해 원을 하나 그려봅시다.
varying vec2 vUv;
uniform float time;
uniform sampler2D channel0;
void main() {
vec2 st = vUv;
float pixels = 20.0;
vec4 mosaicCol = texture2D(channel0, floor(st * pixels) / pixels);
float dist = distance(st, vec2(0.5));
dist = step(dist, 0.5);
gl_FragColor = vec4(vec3(1.0), dist);
}
이전 글과 같은 방법으로 원을 그렸습니다.
이제 모자이크 픽셀수만큼 원을 반복해봅시다.
varying vec2 vUv;
uniform float time;
uniform sampler2D channel0;
void main() {
vec2 st = vUv;
float pixels = 20.0;
vec4 mosaicCol = texture2D(channel0, floor(st * pixels) / pixels);
float dist = distance(fract(st * pixels), vec2(0.5));
dist = step(dist, 0.5);
gl_FragColor = vec4(vec3(1.0), dist);
}
이렇게 입력해줍니다.
원이 20 x 20 배열로 그려졌습니다.
왜 원이 여러 개가 그려졌는지 생각해 봅시다.
fract라는 함수는 소수점만 취하는 함수인데
ex) 10.2 -> 0.2 이런식으로 작동합니다.
위에서 st라는 vec2변수는 x, y가 0 ~ 1 소수점으로 된 좌표값이라고 했습니다.
이를 pixels만큼 곱했습니다.
그러면 0 ~ 20까지 소수점을 포함해서 값이 증가하고
fract를 통해 소수점만 취했습니다.
0 ~ 1, 0 ~ 1, 0 ~ 1 ... 이 20번 반복되기때문에 원이 여러 개가 그려지는 것입니다.
이제 아까 만들어둔 모자이크를 곱해줍시다.
varying vec2 vUv;
uniform float time;
uniform sampler2D channel0;
void main() {
vec2 st = vUv;
float pixels = 20.0;
vec4 mosaicCol = texture2D(channel0, floor(st * pixels) / pixels);
float dist = distance(fract(st * pixels), vec2(0.5));
dist = step(dist, 0.5);
gl_FragColor = vec4(vec3(1.0), dist) * mosaicCol;
}
이렇게 하프톤 효과를 아주 쉽게 만들수있습니다.
위에 pixels 라는 변수의 값을 100으로 변경하면
간단하게 원의 개수를 늘릴 수 있습니다.
여기까지 하프톤 효과를 만들어보았습니다
셰이더는 색상들을 겹치고 빼서 원하는 결과를 만들어낸다고 생각하면 쉽고 재미있습니다.
현재 WE-AR에서 채용을 진행하고있습니다.
아래 링크를 통해 많은 지원 부탁드립니다.
포스팅들 너무 재밌게 보고 있습니다! 아직은 초보 개발자이지만 조만간 이런 멋진 것들을 구현해 낼 수 있겠죠?! 다음 재미나고 멋진 포스팅도 기대하겠습니다! 존버!