본문 바로가기
셰이더 (Shader)/The Art of Code

[GLSL] Starfield - 4 : 별 깊이감, 움직임 추가

by Minkyu Lee 2023. 4. 8.

#define NUM_LAYERS 6.0

mat2 Rot(float a) {
    float s = sin(a), c = cos(a) ;
    return mat2(c, -s, s, c) ;
}

float Star(vec2 uv, float flare) {
    float d = length(uv) ;
    float m = 0.02/d ; 
    m*= 1.0 ;
    // 십자 레이
    float rays = max(0.0, 1.0-abs(uv.x*uv.y*1000.0)) ;
    m += rays * flare ;
    
    // 대각선 레이
    uv *= Rot(3.1415/4.0) ;
    rays = max(0.0, 1.0-abs(uv.x*uv.y*1000.0)) ;
    m += rays * 0.3 * flare ;
    
    m *= smoothstep(1.0, 0.1, d) ;
    return m ;
}

float Hash21(vec2 p) 
{
    p = fract(p*vec2(123.34, 456.21) ) ;
    p += dot(p, p+45.32) ;
    return fract(p.x*p.y) ; 
}

vec3 StarLayer(vec2 uv) {
    vec3 col = vec3(0.0);
    vec2 gv = fract(uv)-0.5 ;
    vec2 id = floor(uv) ;
    
    for(int y=-1; y<=1; y++) {
        for(int x=-1 ; x<=1; x++) {
            vec2 offs = vec2(x, y) ;
            float n = Hash21(id+offs) ; // random 0~1
            
            float size = fract(n*345.32) ;
            float star = Star(gv-offs-vec2(n, fract(n*34.0))+0.5, smoothstep(0.9,0.1,size)*0.6);
            vec3 color = sin(vec3(0.2, 0.3, 0.9)*fract(n*2345.2)*6.2831)*0.5+0.5 ;
            color *= vec3(1.0, 0.5, 1.0+size) ; // 사이즈가 클수록 블루톤
            col += star * size * color ;
        }
    }
    return col ;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (fragCoord-0.5*iResolution.xy)/iResolution.y ; 
    uv *= 3.0;
    float t = iTime*0.1;
    vec3 col = vec3(0.0);
    for(float i=0.0; i<1.0; i+=1.0/NUM_LAYERS) {
        float depth = fract(i+t); // i는 시작값, t는 키값
        float fade = depth;
        float scale = mix(10.0, 0.5, depth) ; // depth가 0이면 10.0, 1이면 0.5 scale을 가진다.
        float offset = i*453.2;
        col += StarLayer(uv*scale+offset)*fade;
    }
    fragColor = vec4(col,1.0);
}

// 별 여러개 쌓아서 깊이감 추가

반복문을 사용한다.

uv를 곱하기하여 크기를 조절한다.

uv 크기 조절시 time값을 이용해 애니메이션을 주어 별이 이동한다.

 

uv에 곱하기 값이 클수록 별이 많아지고 작아진다.

멀리있는 것처럼 보인다.

 

작을수록 별이 적어지고 커진다.

가까이 있는 것처럼 보인다.

 

// 핵심

쉽게 말해 uv를 이용한 깊이감 페이크다.

 

// 문제점

하지만 별이 가까이 오고나서 팍하고 사라지는 문제가 있다.

이는 다음 단계에서 해결한다.

댓글