본문 바로가기
College Study/GLSL

[GLSL] Atan

by 2den 2022. 1. 5.
728x90

 

 


As you probably know there are different ways to organize color besides by red, green and blue channels.

HSB stands for Hue, Saturation and Brightness (or Value) and is a more intuitive and useful organization of colors.

source:  https://yeun.github.io/
#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);
}
 

With the functions 'rgb2hsb' and 'hsb2rgb' above, conversion between rgb and hsb is easier. As mentioned by the comments, the x value is mapped to the hue and the y to the brightness.

#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;    // line 22
    vec3 color = vec3(0.0);

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

    // 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));    // line 32

    gl_FragColor = vec4(color,1.0);    // line 34
}
 

See the lines in the main function. Line 22 normalizes the coordinates of the pixels to 0.0 to 1.0. Also initialize the color variable to be output to vec3 value of 0.0. Line 26 changes all coordinate values from 0.5 to -0.5 by subtracting the st coordinate value from (0.5, 0.5). Then (0.0, 0.0) the origin will be centered on the screen. The angle between the coordinates and the origin (0 ~ pi, 0 ~ -pi) is assigned to the angle variable through the atan function, and the length function finds the distance to the origin, multiplies it by 2, and assigns it to the radius variable. The region with the shortest distance from the origin to the edge has a radius of 0 to 1. Line 32 divides the angle by 2pi, adds 0.5, normalizes to 0-1, and sets the hue. I set the radius to saturation (1.0 over 1.0). Then the value is set to 1.0, and the colors below are printed.

 

 

728x90

'College Study > GLSL' 카테고리의 다른 글

[GLSL] Rectangle  (0) 2022.01.05
[GLSL] Qualifier  (0) 2022.01.05
[GLSL] Mix  (0) 2022.01.05
[GLSL] Color  (0) 2022.01.05
[GLSL] Gain  (0) 2022.01.05

댓글