본문 바로가기
Shader CG

2.7 Noise - 영혼이 빠져나감

by SimonLee 2023. 8. 28.

이번에 만들어볼 이펙트는 말로 설명하기가 어렵습니다.

일본 공포만화에서 볼법한 귀신같은 느낌이라

제목을 영혼이 빠져나감 이라고 적었습니다. ^^

 

영혼이 빠져나가는 듯한 효과

전 챕터에서 사용한 random 함수, 그리고  새로운 random2 함수 입니다.

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

vec2 random2(vec2 st){
    st = vec2( dot(st,vec2(127.1,311.7)),
              dot(st,vec2(269.5,183.3)) );
    return -1.0 + 2.0*fract(sin(st) * 43758.5453123);
}

기존 random 함수는 리턴타입이 float 인 반면, random2 함수는 리턴타입이 vec2 입니다.

dot 연산을 통해 2차원을 1차원으로 줄이는 과정을 st.x, st.y에 적용해서 2차원을 유지 했습니다.

계산된 st 값 특정 수로 곱하고 sin을 취하는 등 계산을 하고, 

마지막으로..

fract 함수의 결과의 소수부분에 2를 곱하고 -1을 하면 범위는 [0 ~ 1]이 됩니다.

-1.0 + 2.0 * fract ( ... ) 

... 부분에 customize 해서 본인들 만의 랜덤 함수를 만들어 봅시다.

 

전 챕터에서 사용한 noise 함수, 그리고 새로운 noise2 함수 입니다.

float noise(vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);
    vec2 u = f*f*(3.0-2.0*f);
    return mix( mix( random( i + vec2(0.0,0.0) ),
                     random( i + vec2(1.0,0.0) ), u.x),
                mix( random( i + vec2(0.0,1.0) ),
                     random( i + vec2(1.0,1.0) ), u.x), u.y);
}

float noise2(vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);
    vec2 u = f*f*(3.0-2.0*f);

    return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
                     dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
                mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
                     dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}

mix(

mix(

    dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
    dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ),

    u.x),
mix(

    dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
    dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ),

    u.x),

u.y);

.....................

 

메인함수 부분입니다.

float t = 4.;
st += noise(st * 5.) * t;
color = vec3(1.) * smoothstep(.13, .14, noise(st));
color += smoothstep(.15, .2, noise(st * 10.));
color -= smoothstep(.35, .4, noise(st * 10.));
gl_FragColor = vec4(1. -color, 1.0);

.......................

 

 

 

전체코드

// Author : SimonLee
// Title : Noise_4_ShowDevel
// 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);
}

vec2 random2(vec2 st){
    st = vec2( dot(st,vec2(127.1,311.7)),
              dot(st,vec2(269.5,183.3)) );
    return -1.0 + 2.0*fract(sin(st)*43758.5453123);
}

float noise(vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);

    vec2 u = f*f*(3.0-2.0*f);

    return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
                     dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
                mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
                     dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}

mat2 rotate2d(float angle){
    return mat2(cos(angle),-sin(angle),
                sin(angle),cos(angle));
}

float lines(in vec2 pos, float scale){
    pos *= scale;
    return smoothstep(0.0, 0.5, abs( ( sin (pos.x*3.1415) ) ) );
}


void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st.y *= u_resolution.y/u_resolution.x;	
    vec3 color = vec3(0.);
    
    
	float t = 4.;
    st += noise(st * 5.) * t;
	color = vec3(1.) * smoothstep(.13, .14, noise(st));
    color += smoothstep(.15, .2, noise(st * 10.));
    color -= smoothstep(.35, .4, noise(st * 10.));
    

    gl_FragColor = vec4(1. -color, 1.0);
}

'Shader CG' 카테고리의 다른 글

01. RayMarhcing - Rendering Sphere  (0) 2024.07.31
3D Scenes With Ray Marching  (0) 2024.06.27
2.6 나이테 Noise  (0) 2023.08.19
2.5 Gradient Noise  (0) 2023.08.17
2.4 Noise 함수 사용해보기  (0) 2023.08.12