ffmpeg通过OpenGL给视频添加 烟花特效
效果如下:
直接贴代码, 这里代码也是基于 shadertoy, 在原代码上做了一些修改:
uniform sampler2D texture;
uniform float u_time;
uniform vec2 u_resolution;
vec2 hash21(float p)
{
vec3 p3 = fract(vec3(p) * vec3(.1031, .1030, .0973));
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.xx+p3.yz)*p3.zy);
}
vec3 hash31(float p) {
vec3 p2 = fract(p * vec3(5.3983, 5.4427, 6.9371));
p2 += dot(p2.zxy, p2.xyz + vec3(21.5351, 14.3137, 15.3219));
return fract(vec3(p2.x * p2.y * 95.4337, p2.y * p2.z * 97.597, p2.z * p2.x * 93.8365));
}
vec2 dir(float id){
vec2 h = hash21(id);
h.y*=2.*acos(-1.);
return h.x*vec2(cos(h.y),sin(h.y));
}
#define PARTICLES_MIN 20.
#define PARTICLES_MAX 200.
float bang(vec2 uv, float t,float id){
float o = 0.;
if(t<=0.){
return .04/dot(uv,uv);
}
float s = (sqrt(t)+t*exp2(-t/.125)*.8)*10.;
float brightness = sqrt(1.-t)*.015*(step(.0001,t)*.9+.1);
float blinkI = exp2(-t/.125);
float PARTICLES = PARTICLES_MIN+(PARTICLES_MAX-PARTICLES_MIN)*fract(cos(id)*45241.45);
for(float i=0.; i<20.0; i++){
vec2 d = dir(i+.012*id);
vec2 p = d*s;
vec2 h = hash21(5.33345*i+.015*id);
float blink = mix(cos((t+h.x)*10.*(2.+h.y)+h.x*h.y*10.)*.3+.7,1.,blinkI);
o+=blink*brightness/dot(uv-p,uv-p);
}
return o;
}
const float ExT = 1./4.;
#define duration 2.2
float firework(vec2 uv,float t,float id){
if(id<1.)return 0.;
vec2 h = hash21(id*5.645)*2.-1.;
vec2 offset = vec2(h.x*.1,0.);
h.y=h.y*.95;
h.y*=abs(h.y);
vec2 di = vec2(h.y,sqrt(1.-h.y*h.y));
float thrust = sqrt(min(t,ExT)/ExT)*25.;
vec2 p = offset+duration*(di*thrust+vec2(0.,-9.81)*t)*t;
return sqrt(1.-t)*bang(uv-p,max(0.,(t-ExT)/(1.-ExT)),id);
}
#define NUM_ROCKETS 3.
void main()
{
vec2 uv = gl_FragCoord.xy/u_resolution.xy;
gl_FragColor =texture2D(texture, uv);
uv = (2.*gl_FragCoord.xy-u_resolution.xy*vec2(1.,0.))/u_resolution.y;
float time = .75*u_time;
float t = time/duration;
//uv.y-=.65;
uv*=35.;
float m = 1.;
float d =0.;
for(float i = 0.;i<ceil(NUM_ROCKETS);i++){
float T = 1.+t+i/NUM_ROCKETS;
float id = floor(T)-i/NUM_ROCKETS; //should give a unique integer for each rocket
vec3 color = hash31(id*.75645);
color/=max(color.r,max(color.g,color.b));//making colors as bright as possible
gl_FragColor += vec4(firework(uv,fract(T),id)*color,0.0);
}
}