개발/Shader / / 2023. 2. 22. 17:39

GLSL - color와 atan 함수

반응형

https://thebookofshaders.com/06/

 

The Book of Shaders

Gentle step-by-step guide through the abstract and complex universe of Fragment Shaders.

thebookofshaders.com

 

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;

vec3 rgb2hsb( in vec3 c ){
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz),
                 vec4(c.gb, K.xy),
                 step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r),
                 vec4(c.r, p.yzx),
                 step(p.x, c.r));
    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),
                d / (q.x + e),
                q.x);
}

//  Function from Iñigo Quiles
//  https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb( in vec3 c ){
    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
                             6.0)-3.0)-1.0,
                     0.0,
                     1.0 );
    rgb = rgb*rgb*(3.0-2.0*rgb);
    return c.z * mix(vec3(1.0), rgb, c.y);
}

void main(){
    vec2 st = gl_FragCoord.xy/u_resolution;
    vec3 color = vec3(0.0);

    // We map x (0.0 - 1.0) to the hue (0.0 - 1.0)
    // And the y (0.0 - 1.0) to the brightness
    color = hsb2rgb(vec3(st.x,1.0,st.y));

    gl_FragColor = vec4(color,1.0);
}

위 코드를 보면 rgb2hsb와 hsb2rgb라는 함수가 있다. 이는 색상을 표현하는 색상 모델 사이를 변환시키는 함수이다. 

main함수에서 hsb2rgb함수를 호출하는 매개변수를 보면 vec3를 통해 h값에 st.x좌표로 x좌표에 따라서 hue값을 변경하고, Saturation값은 1.0으로 고정, Brightness값은 st.y좌표로 y값에 따라서 밝기를 조절한다.

 

 

#ifdef GL_ES
precision mediump float;
#endif

#define TWO_PI 6.28318530718

uniform vec2 u_resolution;
uniform float u_time;

//  Function from Iñigo Quiles
//  https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb( in vec3 c ){
    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
                             6.0)-3.0)-1.0,
                     0.0,
                     1.0 );
    rgb = rgb*rgb*(3.0-2.0*rgb);
    return c.z * mix( vec3(1.0), rgb, c.y);
}

void main(){
    vec2 st = gl_FragCoord.xy/u_resolution;
    vec3 color = vec3(0.0);

    // Use polar coordinates instead of cartesian
    vec2 toCenter = vec2(0.5)-st;
    float angle = atan(toCenter.y,toCenter.x);
    float radius = length(toCenter)*2.0;

    // Map the angle (-PI to PI) to the Hue (from 0 to 1)
    // and the Saturation to the radius
    color = hsb2rgb(vec3((angle/TWO_PI)+0.5,radius,1.0));

    gl_FragColor = vec4(color,1.0);
}

위 코드에서 각도를 구할 때 atan() 를 사용하게 된다. 

 

arctan은 위 그림처럼 시계방향으로 값이 이동할 수록 PI에 가까워 지고, 반시계방향으로 값이 이동할 수록 -PI에 가까워 진다.

 

 

#ifdef GL_ES
precision mediump float;
#endif

#define TWO_PI 6.28318530718
#define PI 3.141592

uniform vec2 u_resolution;
uniform float u_time;

//  Function from Iñigo Quiles
//  https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb( in vec3 c ){
    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
                             6.0)-3.0)-1.0,
                     0.0,
                     1.0 );
    rgb = rgb*rgb*(3.0-2.0*rgb);
    return c.z * mix( vec3(1.0), rgb, c.y);
}

void main(){
    vec2 coord = gl_FragCoord.xy/u_resolution;
    coord = coord * 2. - 1.; // 각각 해상도의 좌표값을 1 또는 -1로 간추려지게 만들기 위한 계산
    
    float rotate = 2.0;
    float frequency = 2.0;
    
    float angle = atan(coord.y, coord.x);
    angle += PI + u_time * rotate;
    angle /= 2. * PI;
    angle *= (1. + frequency);
    
    float dist = length(coord); // distance()와는 달리 length()는 원점에서부터의 거리이다.
    
    vec3 color = hsb2rgb(vec3(angle, dist, 1.));
    
    gl_FragColor = vec4(color, 1.0);
}

위와 같이 같은 동작방식의 코드를 재작성해보았다.

좌표의 각 끝점을 1 또는 -1로만 표현하도록 coord에 계산식을 더하였고, atan()을 이용해서 각 위치에 따라 각도를 본래 -PI ~ PI에서 0~2PI로 표현하도록 PI를 더하였다.

length()를 이용해서 원점으로부터의 거리로 Saturation값을 지정하고, 각도에 따라 Hue값을 지정하게 하였다.

distance()라는 함수도 있지만, 원점으로부터의 길이를 구하므로 length를 사용하였다.

https://thebookofshaders.com/glossary/?search=length 

 

The Book of Shaders

Gentle step-by-step guide through the abstract and complex universe of Fragment Shaders.

thebookofshaders.com

https://thebookofshaders.com/glossary/?search=distance 

 

The Book of Shaders

Gentle step-by-step guide through the abstract and complex universe of Fragment Shaders.

thebookofshaders.com

 

rotate를 이용해서 angle에 값을 더하여 회전하는 각도에 영향을 주었고, frequency를 이용해서 angle에 값을 곱하여 Hue 색상의 주기에 영향을 주었다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유