개발/Shader / / 2023. 3. 15. 19:07

GLSL - Random Noise 랜덤 노이즈

반응형

https://thebookofshaders.com/10/

 

The Book of Shaders

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

thebookofshaders.com

※ 다음 페이지를 참고하여 공부한 게시물입니다.

https://www.opentutorials.org/module/3659/24667

 

18. Random1 - GLSL / Shader

18. Random1 2019-04-19 01:52:20 보충 URL

www.opentutorials.org

 

Random Noise

위 fract()와 sin을 이용하여 랜덤 함수를 만들 수 있다. 이 값이 100000을 넘어가는 경우를 아래 rand()함수라고 정의한다.

 

이 rand() 함수의 값 분포는 rand() 함수에 변형을 가하여 분포의 형태를 바꿀 수 가 있는데,

 

일반적인 rand() 함수의 분포는 이렇고

 

rand(x) * rand(x)의 경우 분포가 0에 더 가까워졌다. rand()로 나올 수 있는 값은 0~1 사이이므로 거듭제곱할 경우 0에 가까워진다.

 

반대로 제곱근을 씌우면 분포는 1에 가까워진다.

 

pow를 사용하여 5배 거듭제곱을 하게 되면, 2배로 거듭제곱한 것보다 훨씬 더 분포가 0에 가깝게 나온다.

 

 

// Author @patriciogv - 2015
// http://patriciogonzalezvivo.com

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float random (vec2 st) {
    return fract(sin(dot(st.xy,
                         vec2(12.9898,78.233)))*
        43758.5453123);
}

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

    float rnd = random( st );

    gl_FragColor = vec4(vec3(rnd),1.0);
}

위와 같은 노이즈를 만드는 코드를 알아보자.

 

 

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float random(float);
float random(vec2);

void main() {
    vec2 coord = gl_FragCoord.xy/u_resolution.xy;
    coord.x *= u_resolution.x / u_resolution.y;
    
    vec3 col = vec3(random(coord));
    gl_FragColor = vec4(col,1.0);
}

float random (float f) {
    float y = fract(sin(f * 712.5568) *7894.12379);
    return y;
}

float random(vec2 v2){
    float f = dot(v2, vec2(0.800,0.610));
    float y = fract(sin(f*123.691)*34634.12312);
    return y;
}

각 좌표에 대해서 vec2의 형태로 받은 픽셀 좌표들을 dot를 이용해서 scalar값으로 만든다. 이 스칼라 값을 fract(sin())에 넣음으로써 랜덤값을 생성하고, 상당히 큰 숫자를 곱해서 랜덤 노이즈를 생성한다.

 

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float random(float);
float random(vec2);

void main() {
    vec2 coord = gl_FragCoord.xy/u_resolution.xy;
    coord.x *= u_resolution.x / u_resolution.y;
    
    coord *= 10.;
    
    vec2 ci = floor(coord);
    vec2 cf = coord - ci;
    
    vec3 col = vec3(random(ci));
    gl_FragColor = vec4(col,1.0);
}

float random (float f) {
    float y = fract(sin(f * 712.5568) *7894.12379);
    return y;
}

float random(vec2 v2){
    float f = dot(v2, vec2(0.800,0.610));
    float y = fract(sin(f*123.691)*34634.12312);
    return y;
}

이렇게 특정 범위의 랜덤값은 일치시켜서 모자이크를 생성할 수 도 있는데,

 

coord좌표의 값을 곱하여 배수하고, floor를 이용해서 정수부분만을 가지고 랜덤 값을 만들면, 정수 범위로 나누어지는 칸은 같은 색을 가지게 되어 모자이크 형태가 된다.

 

 

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