学祭(DDP2023)で使ったシェーダー
ソース
code:bg.frag
precision highp float;
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
vec3 tinv(vec3 p) {
return vec3(p.x, -p.yz) / dot(p,p); //転置
}
vec4 ot;
float g = 0.65;
vec3 CSize = vec3(1.28);
vec3 C1 = vec3(1.);
vec3 C = vec3(1.);
const int MaxIter = 10;
float zoom = 2.0;
float map(vec3 p) {
float dr = 1.0;
p = p.yxz;
ot = vec4(1000.);
C = p * .25;
for (int i=0; i<MaxIter;i++) {
//立体
p = clamp(p, -CSize, CSize)*2.0 - p;
float r2 = dot(p,p);
if(r2 > (1.1 + cos(time + length(p)*10.))*2.) continue;
ot = min(ot, vec4(abs(p),r2));
dr= dr/r2/g;
p = tinv(g*(p)) + C;
}
return .16*abs(p.x)/dr;
return .2*length(p)/dr*log(length(p));
}
float trace(in vec3 ro, in vec3 rd) {
float maxd = 10.;
float precis = 0.005;
float h = precis * 2.0;
float t = 0.0;
for (int i = 0; i < 100; i++) {
if(t > maxd || h<precis*(.1 + t)) continue;
//break;
t += h;
h = map(ro + rd*t);
}
if (t > maxd) t = -1.0;
return t;
}
//法線の計算
vec3 calcNormal(in vec3 pos) {
vec3 eps = vec3(.005, 0.0, 0.0);
vec3 nor;
nor.x = map(pos + eps.xyy) - map(pos - eps.xyy);
nor.y = map(pos + eps.yxy) - map(pos - eps.yxy);
nor.z = map(pos + eps.yyx) - map(pos - eps.yyx);
return normalize(nor);
}
void main(void) {
float igt = 1.2425*time;
vec4 iMouse = vec4(mouse, 0.0, 1.0);
vec2 p = -1.0 + 2.0*gl_FragCoord.xy/resolution;
p.x *= resolution.x/resolution.y;
vec2 m = vec2(-.5)*6.28;
if (iMouse.z > 0.0)m = iMouse.xy/resolution-.5*6.28;
m += .5*vec2(sin(0.15*igt), cos(0.09*igt)) +.3;
//カメラ
vec3 ta = vec3(0.,0.5,0.);
vec3 ro = ta - .9*zoom*vec3(cos(time*0.1), -0.75 + 0.1*cos(time*0.1), sin(time*0.1));
vec3 cw = normalize(ta - ro);
vec3 cp = vec3(0., 100., 25.);
vec3 cu = normalize(cross(cw, cp));
vec3 cv = normalize(cross(cu, cw));
vec3 rd = normalize(p.x*cu + p.y*cv + 2.*cw);
vec3 col = vec3(0.5 + 1.*sin(time)*cos(time), 0.5 + 0.5*sin(time)*cos(time), 0.5 + 0.5*cos(time));
//トレーシング
float t = trace(ro, rd);
if (t > 0.) {
vec3 pos = ro + t*rd;
vec3 nor = calcNormal(pos);
//ライティング
vec3 light1 = vec3(0.577, 0.577, -0.577);
vec3 light2 = vec3(-0.707, 0.707,0.0);
float key = clamp(dot(light1, nor), 0.0, 1.0);
float bac = clamp(0.5 + 0.5*dot(light2, nor), 0.0, 1.0);
float amb = (0.5+.5*nor.y);
float ao = pow(clamp(ot.w*5.0, 0.2, 1.0), 1.2);
vec3 brdf = vec3(ao)*(.4*amb + key + .2*bac);
//マテリアル
vec3 rgb = vec3(1.0);
rgb = (5.*abs(sin(2. + (vec3(.5*ot.w, ot.y*ot.y, 2. -5.*ot.w)))) + 10.*sin(vec3(-0.2, -0.6, 0.8) + 2.3 + ot.x*22.5))*.85 + .15;
rgb.gbr = mix(rgb, rgb.bgr + vec3(0.3, 0.1, -.2) ,0.5 + .5*sin(15.*ot.w));
//色調補正
col = mix(vec3(0.75,1.,1.),rgb*brdf,exp(-0.8*t));
}
gl_FragColor=vec4(col,1.0);
}
VJ環境についての小話
GLSL sandbox + OBS
素材を用意するのが面倒だったため、ひとつの素材にOBSのエフェクト類で情報を増やして誤魔化してます
OBSのeffect hotkeys?というプラグインを使いトグル制御してみたのですが、何気DJにタイミングを合わすのがムズイ
https://scrapbox.io/files/65681640cf89a900225a0c2f.png
https://scrapbox.io/files/6568160c0fdc2c0024236af9.png
https://scrapbox.io/files/6568160f07951c0023e40e3c.png