환경 준비

예제

#version 330
out vec4 outputColor;
in vec2 UV;

uniform vec2 resolution; // image resolution
uniform float timer; // 0 --> 1
uniform float loop_timer; // 0 --> 1 --> 0

uniform sampler2D VIDEO;

#define PI 3.14159265

vec2 rotate(vec2 p, float a){
    return vec2(
        p.x * cos(a) - p.y * sin(a),
        p.x * sin(a) + p.y * cos(a)
    );
}

float sd_circle(vec2 p, float r){
    return length(p) - r;
}

float sd_ring(vec2 p, float r, float w){
    float ring = length(p)-r;
    ring = abs(ring)-w;
    return ring;
}

float sd_box(vec2 p, vec2 w){
    float box = max(
        abs(p.x)-w.x,
        abs(p.y)-w.y
    );
    return box;
}

float sd_line(vec2 p, vec2 a, vec2 b, float w){
    vec2 ba = b - a;
    vec2 pa = p - a;
    vec2 dr = normalize(ba);
    float dt = dot(dr, pa);
    vec2 h = a + dr * dt;

    float dst = length(p-h) - w;

    if(dt <= .0){
        dst = length(p-a) - w;
    }

    if(dt >= length(ba)){
        dst = length(p-b) - w;
    }

    return dst;
}

void main(){
    vec2 uv = UV;
    vec2 rs = resolution;
    vec2 rs_sc = rs/min(rs.y, rs.x);
    uv = (uv - .5) * rs_sc;

    float circle = sd_circle(uv, .3 - .1 * loop_timer);
    float circle_sh = 1.-smoothstep(.0, .003, circle);

    float ring = sd_ring(uv, .4 + .1 * loop_timer, .01);
    float ring_sh = 1.-smoothstep(.0, .003, ring);

    //uv = rotate(uv, timer * 2. * PI);
    float box = sd_box(uv, vec2(.1));
    float box_sh = 1.-smoothstep(.0, .003, box);

    //uv = rotate(uv, loop_timer * 2. * PI);
    float line = sd_line(uv, vec2(.0,.45), vec2(.0,-.45), .01);
    float line_sh = 1.-smoothstep(.0, .003, line);

    vec3 col = vec3(1.);
    col = mix(col, vec3(0.), circle_sh);
    col = mix(col, vec3(1.,.0,0.), ring_sh);
    col = mix(col, vec3(.0,.0,1.), box_sh);
    col = mix(col, vec3(.0,.5,.0), line_sh);
    
    vec2 sc = vec2(50.);
    vec2 iuv = floor(uv*sc);
    vec2 fuv = fract(uv*sc)-.5;

    vec2 tc = iuv/sc;
    tc = (tc/rs_sc)+.5;
    vec4 ovsamp = texture(VIDEO, UV);
    vec4 vsamp = texture(VIDEO, tc);
    col.rgb = ovsamp.rgb;

    float pl = length(vsamp.rgb)/length(vec3(1.));
    float rad = .3*(1.-pl);
    float circle2 = sd_circle(fuv, rad);
    float circle_sh2 = 1.-smoothstep(.0,.01,circle2);

    col = mix(col, vec3(.1,1.,.1), circle_sh2);

    outputColor = vec4(col, 1.);
}
from chgnhyk import FBO, ClipRenderer, load_shader
from moderngl import create_context
from pathlib import Path

work_path = Path(__file__).parent
sample_folder = work_path.joinpath("sample/")
shader_folder = work_path.joinpath("shader/")
video_folder = work_path.joinpath("video/")

CTX = create_context(
    require = (330), 
    standalone = True)
SIZE = (1080, 1080)

scene = FBO(
    ctx = CTX, 
    size = SIZE, 
    shader = load_shader(shader_folder.joinpath("scene.glsl"))
    )

clip = ClipRenderer(duration = 2, fps = 30)
clip.addFBOPass("scene", scene)
clip.addVideo(video_folder.joinpath("test.mp4"), "VIDEO", 6)

# render!
clip.render_frame_sample(clip.duration * 0)
clip.extractImage(sample_folder.joinpath(f"test_{clip.t}.jpg"))

vid = clip.render()
vid.write_videofile(str(sample_folder.joinpath("test.mp4")), fps = clip.fps)
# render end

clip.release()
CTX.release()
#version 330
out vec4 outputColor;
in vec2 UV;

uniform sampler2D bckbuffer;
uniform vec2 resolution;
uniform sampler2D VIDEO;
uniform vec2 VIDEO_res;

uniform float timer;
uniform float loop_timer;
uniform float duration;

#define PI 3.14159265

float rand(vec3 p){
    float sd1 = dot(p, vec3(31.3131,23.2323,17.1717));
    float sd2 = dot(p, vec3(13.1313,15.1515,19.1919));
    float sv = sin(sd1) + sin(sd2);
    return fract(sv * 45678.654321);
}

vec2 rotate(vec2 p, float a){
    return vec2(
        p.x * cos(a) - p.y * sin(a),
        p.x * sin(a) + p.y * cos(a)
    );
}

float sd_segment(vec2 p, vec2 a, vec2 b, float w){
    vec2 ba = b - a;
    vec2 pa = p - a;
    vec2 dr = normalize(ba);
    float l = length(ba);

    float dt = dot(pa, dr);
    vec2 h = a + dt * dr;

    float dst = length(h-p)-w;
    if(dt <= .0){
        dst = length(p-a)-w;
    }

    if(dt >= l){
        dst = length(p-b)-w;
    }

    return dst;
}

void main() {
    vec2 uv = UV;
    vec2 rs = resolution;
    uv = (uv-.5);
    uv *= rs/rs.y;

    vec2 sc = vec2(40.);
    
    vec2 iuv = floor(uv*sc);
    if(mod(iuv.y,2.) == .0){
        uv.x -= .5/sc.x;
    }
    iuv = floor(uv*sc);
    vec2 fuv = fract(uv*sc)-.5;
    vec2 vtc = (iuv/sc)*rs.y/rs + .5;
    vec4 vsamp = texture(VIDEO, vtc);
    vec4 ovsamp = texture(VIDEO, UV);

    float h = length(vsamp.rgb)/length(vec3(1.));
    h = floor(h * 8.)/8.;
    fuv = rotate(fuv, h * PI * 2.);
    float sh = sd_segment(fuv, vec2(-.4,.0), vec2(.4,.0), .02);
    sh = 1.-smoothstep(.0,.001 * sc.x,sh);

    vec3 col;
    col = mix(vsamp.rgb, vec3(.1,1.,.1), sh);
    outputColor = vec4(col, 1.);
}