momodudu.zip
#1 ShaderToy - 기본 예제 본문
쉐이더 공부를 어떻게 하면 좀 더 직관적으로 할 수 있을까.. 라는 생각을 하던차에 아래와 같이 아주 유용한 사이트를 찾았다.
WebGL 기반으로 Shader를 직접 한줄한줄 수정하면 바로 옆에서 결과가 뜨는 사이트이다.
C++개발자가 자기 필요에 의해서 web을 배우고 만든 사이트라는데... 대단하다.
여담이지만 진짜 존경한다... 나는 web필요성을 절실히 느끼고 있음에도 게으르게 살고있는데ㅠ 반성해본다..
기본 프로젝트 생성시 뜨는 예제다.
나처럼 다양하고 복잡한 fragement shader를 만질일이 없었던 뵹아리 그래픽스 개발자에겐 아주 좋은 사이트인듯하다.
먼저, 처음 만들었을때 기본으로 제공되는 코드에 대해 분석해보고자 한다.
기본으로 제공되는 input값. uniform 형태다.
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
fragColor = vec4(col,1.0);
}
out으로 fragColor, 즉 하나의 픽셀값이 출력되게 될 것이고 in으로 fragCoord가 전달된다.
여기서 fragCoord는 출력되는 view상의 fragment의 좌표값이라고 보면 된다.
resoultion은 출력되는 view의 크기다. 즉 위 코드에서 vec2 uv값은 화면 내 [0,1]의 정규화 좌표라고 생각하면 된다.
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Output to screen
fragColor = vec4(uv.x,0.0,0.0,1.0);
}
좌표가 어떻게 이루어지는지 보기 위해 짠 테스트 코드다.
정규화 좌표 uv의 x값을 fragment color R값에 넣었다. 즉, 오른쪽으로 갈수록 빨갛게 되는걸 보면 왼쪽->오른쪽 방향으로 1.0에 가까워짐을 알 수 있다.
반대로 uv의 y값을 R에 넣어보면 아래쪽으로 갈수록 까맣다는걸 알 수 있다.
즉, 좌하단이 (0,0) 우상단이(1,1)인 정규화 좌표계라고 보면 된다. 그래서 fragCoord값 역시 좌하단이 원점인 좌표계라고 볼 수 있다.
이제 좌표계 구성에 대해서 알아봤으니, 다시 기본 예제로 돌아가서
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
fragColor = vec4(col,1.0);
}
샘플코드에서 설정한 col값이 무엇인지 알아보자. 수식만봐서는 눈에 안들어오니까, 일단 그래프로 그려본다.
위 그래프 그리는 사이트는 예전에 회사에서 일 할 때 bezierCurve관련해서 그래프를 보고싶어서 찾았던 사이트인데, 유용하다. 복잡한 수식에 대한 그래프를 쉽게 그려볼 수 있어서 좋은 사이트임.
cos은 기본적으로 [-1,1]의 값이므로 앞에 0.5를 곱해줬으니 [-0.5,0.5] 사잇값이 될 것이다.
그리고 cos 안에 들어가는 x변수로 iTime이 있는데, 이거는 계속해서 변하는 변수다.
즉, cos(x)의 x로 iTime만을 넣으면 위 그래프처럼 [-0.5,0.5]사이값을 왔다갔다 할 것이다.
즉, 모든 fragment에 대해서 uniform하게 [-0.5,0.5]사이를 왔다갔다 할 것이다.
cos안에 uv.xyx대신에 vec(1,1,1)같은것을 넣어보고 비교를 해보면 색이 변하는게 다르게 느껴질 것이다.
이 예제에서는 각 fragment에 대해서 다르게 변하도록 일종의 offset을 준 것이다.
음.. 간단하게 예를 들어서, uv가 우상단인 (1,1)이라고 치면 해당 픽셀값은
0.5+0.5*cos(iTime+vec(1,1,1)+vec(0,2,4)) = 0.5+0.5*cos(iTime+vec(1,3,5)) 가 될것이다.
즉 각각의 RGB값은 아래와 같이 이루어 질거라고 보면 된다.
즉, fragment 정규화 좌표 우상단 (1,1)은 위와 같이 RGB가 변한다고 보면 된다.
이건 한 픽셀에 해당하는것이다, 즉 각 fragment별로 x값의 offset이 조금씩 있을 뿐.
아주 간단한 예젠데 fragmentCoord 좌표계랑 픽셀 출력에 대한 개념을 이해하기에 아주 좋은 예제다.ㅎㅎ
fragColor값에 uv의 xy값을 대충 넣어가면서 보면 픽셀 출력에 대한 개념이 좀 잡힐것 같다.
여긴 참 좋은데, 아쉬운게 약간 단계별로? 난이도별로 나눠놓은게 없다. 그냥 굇수들이 장난쳐놓은거 자랑해놓는 곳 같은 느낌..나같은 양민은 쉬운 예제부터 하나하나 파나가야된다 ㅠㅠ
'Graphics > ShaderToy' 카테고리의 다른 글
#3 ShaderToy - 원을 이용한 간단한 예제(Smile) (0) | 2019.09.16 |
---|---|
#2 ShaderToy - 원 그리기 (0) | 2019.09.16 |