├── README.md ├── Shader ├── 2DRes.frag ├── 2DScene.frag ├── 3DBloom.frag ├── 3DDOF.frag ├── 3DScene.frag ├── 3DScene_Bac.frag ├── 3DScene_raw.frag ├── Unite.frag ├── UniteProcess.frag ├── common.glsl ├── font.glsl └── params.glsl ├── Src ├── Face │ ├── F0_Sen.png │ ├── F1_Sen.png │ ├── F2_1_Sen.png │ ├── F3_Sen.png │ ├── F4_3_Sen.png │ └── F5_Sen.png └── Fonts │ └── Myrica_msdf.png └── pipeline.yaml /README.md: -------------------------------------------------------------------------------- 1 | # VJ-at-lambda-2023-06-10 2 | 3 | Use [sh4derjockey](https://github.com/slerpyyy/sh4der-jockey) 4 | 5 | [twitter](https://twitter.com/ymgmcmc/status/1666401630651293696) 6 | 7 | [youtube](https://youtu.be/iVjLUrviE9I) 8 | -------------------------------------------------------------------------------- /Shader/2DRes.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | #pragma include "Shader/common.glsl" 6 | #pragma include "Shader/params.glsl" 7 | #pragma include "Shader/font.glsl" 8 | 9 | uniform sampler2D Tex2DScene; 10 | uniform sampler2D Tex2DRes; 11 | 12 | vec2 uv2luv(vec2 uv) 13 | { 14 | return (uv - 0.5) * 1.5 + 0.5; 15 | } 16 | 17 | vec2 luv2uv(vec2 luv) 18 | { 19 | return (luv - 0.5) / 1.5 + 0.5; 20 | } 21 | 22 | vec4 tex(sampler2D ch, in vec2 q) 23 | { 24 | ivec2 p = ivec2(q); 25 | ivec2 r = ivec2(vec2(textureSize(ch, 0))); 26 | p = (p + r) % r; 27 | return texelFetch(ch, p, 0); 28 | } 29 | 30 | bool vecEQ(vec3 col) 31 | { 32 | const float eps = 1e-3; 33 | return (abs(col.r - col.g) < eps && abs(col.g - col.b) < eps && abs(col.b - col.r) < eps); 34 | } 35 | 36 | vec3 calcCol(vec2 uv) 37 | { 38 | vec2 luv = uv2luv(uv); 39 | // https://www.shadertoy.com/view/DtBXWG 40 | vec2 px = gl_FragCoord.xy; 41 | float k = 1. / resolution.y; 42 | // Uncomment to zoom (tracks mouse incorrectly) 43 | float sc = 0.6; 44 | //px = sc * (px - 0.5 * res) + 0.5 * res; 45 | vec4 col1 = tex(Tex2DScene, px); 46 | vec4 col2 = tex(Tex2DScene, px - vec2(5)); 47 | // Messy color stuff 48 | vec4 col = vec4(3. * col1.g - 1.2 * col2.r); 49 | if(col.g > 0.) 50 | col.rgb *= 0.8 + 0.2 * cos(2. * PI * (col.g + vec3(0, 1, 2) / 3.)); 51 | col = tanh(vec4(3.5, 1, 1, 1) * col); 52 | float ab = 2. * abs(col.g - col2.g); 53 | col = clamp(col, 0., 1.); 54 | col += vec4(pow(ab, 5.)); 55 | col = mix(col, vec4(1), 0.25 * (1. - col.r)); 56 | col = vec4(vec3(1.0 - col.r), 1.0); 57 | vec4 bcol = texture(Tex2DScene, uv); 58 | bool isRD = inUV(luv, vec2(0), vec2(1)) && (getMaster().Info2D.ID == 4); 59 | vec3 rescol = (isRD ? col : bcol).rgb; 60 | return saturate(rescol); 61 | } 62 | 63 | void main() 64 | { 65 | Master master = getMaster(); 66 | float LocalTime = master.Info2D.LocalTime; 67 | 68 | vec2 uv = gl_FragCoord.xy / resolution.xy; 69 | vec3 rescol = vec3(0); 70 | float slt = pow(1.0 / (1.0 + beatButton().y), 15.0); 71 | float llt = pow(1.0 / (1.0 + LocalTime), 4.0); 72 | float buv = texture(spectrum_raw, uv.y).r * 0.05 * slt; 73 | // float buv = texture(spectrum, uv.y).r * 0.1 * slt; 74 | vec3 vec = cyclicNoise(vec3(uv * 10.0, time)); 75 | vec.xy *= vec.z; 76 | float sh = 0.05 * llt; 77 | vec3 uvc = vec3(-sh, 0, sh); 78 | rescol.r += calcCol(uv + vec2(buv, 0) + vec.xy * uvc.r).r; 79 | rescol.g += calcCol(uv + vec2(buv, 0) + vec.xy * uvc.g).g; 80 | rescol.b += calcCol(uv + vec2(buv, 0) + vec.xy * uvc.b).b; 81 | if(isLive()) 82 | { 83 | SetAspect(resolution.xy, 2.5, true, false); 84 | SetAlign(Align_Center_Center); 85 | SetFontStyle(STYLE_OUTLINE); 86 | Stack_Char(C_C); 87 | Stack_Char(C_O); 88 | Stack_Char(C_D); 89 | Stack_Char(C_I); 90 | Stack_Char(C_N); 91 | Stack_Char(C_G); 92 | rescol += Render_Char(uv); 93 | 94 | vec2 fres = resolution.y / resolution.xy; 95 | vec2 w = vec2(0.01) * fres; 96 | float edge = 0.0; 97 | vec2 auv = abs(uv - 0.5) - vec2(0.25, 0.25); 98 | vec2 suv = uv - 0.5; 99 | edge += float((0.0 < auv.x || 0.0 < auv.y) && (auv.x < w.x && auv.y < w.y)); 100 | bool l0 = suv.y > suv.x, l1 = suv.y > -suv.x; 101 | float t0 = ((l0 == l1) ? uv.x / fres.x : uv.y / fres.y) * 50.0; 102 | float t1 = (l0 ? time : -time) * 2.5; 103 | edge *= float(fract(t0 + t1) < 0.5); 104 | rescol += edge; 105 | } 106 | 107 | vec2 suv = (uv - 0.5) * resolution.xy / resolution.y; 108 | vec2 asuv = abs(suv); 109 | float as = asuv.x + asuv.y; 110 | float asf = fract(as * 15.0); 111 | float ab = 1.0 / (1.0 + beatButton().y); 112 | float asi = (1.0 - pow(ab, 6.0)) * 1.5; 113 | rescol += float(int(beatButton().w + 0.5) % 8 == 0) * float(asf < 0.5) * pow(saturate(1.0 - abs(asi - as)), 4.0) * pow(ab, 6.0); 114 | rescol = saturate(rescol); 115 | 116 | // tlansition merge 117 | vec3 backcol = texture(Tex2DRes, uv).rgb; 118 | float lt = remapc(LocalTime, 0.0, TransitionTime, 0.0, 1.0); 119 | lt = pow(lt, 3.0); 120 | float mixa = mix(0.1, 1.0, lt); 121 | rescol = mix(backcol, rescol, mixa); 122 | 123 | outColor = vec4(rescol, 1.0); 124 | } -------------------------------------------------------------------------------- /Shader/2DScene.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | #pragma include "Shader/params.glsl" 6 | #pragma include "Shader/font.glsl" 7 | 8 | uniform sampler2D Tex2DScene; 9 | 10 | float GlobalTime; 11 | float LocalTime; 12 | 13 | vec2 uv2luv(vec2 uv) 14 | { 15 | return (uv - 0.5) * 1.5 + 0.5; 16 | } 17 | 18 | vec2 luv2uv(vec2 luv) 19 | { 20 | return (luv - 0.5) / 1.5 + 0.5; 21 | } 22 | 23 | /* 24 | time:ランダムな漢字が現れる 25 | fft:? 26 | */ 27 | vec3 layer0(vec2 uv, vec2 res) 28 | { 29 | SetAspect(res.xy, 12.0, true, false); 30 | SetAlign(Align_Center_Center); 31 | 32 | const float freq = 20.0; 33 | float seedx = floor(GlobalTime * freq) / freq; 34 | // float seedx = floor(high_smooth_integrated.r * 0.05 * freq) / freq; 35 | 36 | SetFontStyle(STYLE_NORMAL); 37 | 38 | float ch = 0.0; 39 | for(int i = 0; i < 6; i++) 40 | { 41 | vec2 seed = vec2(seedx, i); 42 | int chid = getRandomChar(seed); 43 | Stack_Char(chid); 44 | } 45 | ch += Render_Char(uv); 46 | 47 | return vec3(saturate(ch)); 48 | } 49 | 50 | /* 51 | time:Lambdaを表示 52 | fft:? 53 | */ 54 | vec3 layer1(vec2 uv, vec2 res) 55 | { 56 | vec2 nuv = uv; 57 | SetAspect(res.xy, 6.0, true, false); 58 | SetAlign(Align_Center_Center); 59 | 60 | const int[6] lambda = int[6](C_L, C_A, C_M, C_B, C_D, C_A); 61 | int tim = int(LocalTime * 16.0); 62 | int line = 24; 63 | float ch = 0.0; 64 | 65 | nuv.y = fract(nuv.y + float(max(0, tim - line)) / 24.0); 66 | 67 | SetFontStyle(STYLE_BOLD); 68 | for(int i = 0; i < 6; i++) 69 | { 70 | int chid = lambda[i]; 71 | Stack_Char(chid); 72 | } 73 | ch += Render_Char(nuv); 74 | nuv.y = fract(nuv.y + 1.0 / 24.0); 75 | 76 | SetFontStyle(STYLE_OUTLINE); 77 | int maxch = min(tim * 6, line * 6); 78 | for(int i = 0; i < maxch; i++) 79 | { 80 | int id = i % 6; 81 | Stack_Char(lambda[id]); 82 | if(id == 5) 83 | { 84 | ch += Render_Char(nuv); 85 | nuv.y = fract(nuv.y + 1.0 / 24.0); 86 | } 87 | } 88 | ch = saturate(ch); 89 | 90 | float ismove = float(frame_count % 8 == 0); 91 | float bac = texture2D(Tex2DScene, luv2uv(uv + ismove * vec2(36.0, 0) / resolution.x)).r; 92 | bac *= ismove > 0.5 ? 0.7 : 1.0; 93 | // TODO: replace with fft 94 | bool fftb = hash11(float(tim)) > 0.3; 95 | ch = fftb ? (bac + ismove * ch) : fract(tan(bac + ismove * ch)); 96 | 97 | return vec3(saturate(ch)); 98 | } 99 | // 16*9 = 144 100 | vec3 layer2(vec2 uv, vec2 res) 101 | { 102 | vec2 nuv = uv; 103 | float ltime = LocalTime * 0.5; 104 | 105 | // TODO: replace with fft 106 | // bool fftb = hash11(floor(LocalTime * 16.0)) > 0.5; 107 | bool fftb = high.r > 0.5; 108 | ltime = (ltime > 2.0 && fftb) ? 1.0 : ltime; 109 | 110 | // nuv.y -= floor(max(0.0, ltime) / 9.0 * 2.0 * 32.0) / 32.0; 111 | 112 | nuv.y = 1.0 - nuv.y; 113 | vec2 ires = res / res.x * 32.0; 114 | nuv = nuv * ires; 115 | vec2 iuv = floor(nuv); 116 | 117 | for(int i = 0; i < 4; i++) 118 | { 119 | vec2 cuv = (iuv + 0.5) / ires; 120 | if(hash12(cuv) > 0.6) 121 | { 122 | break; 123 | } 124 | nuv *= 0.5; 125 | iuv = floor(nuv); 126 | } 127 | 128 | float id = (iuv.x + iuv.y * 16.0) / 144.0; 129 | float c0, c1, c2; 130 | SetAspect(res.xy, 1.5, true, false); 131 | SetAlign(Align_Center_Center); 132 | SetFontStyle(STYLE_BOLD); 133 | Stack_Char(223); 134 | c0 = 1.0 - Render_Char(uv); 135 | 136 | SetAspect(res.xy, 1.5, true, false); 137 | SetAlign(Align_Center_Center); 138 | SetFontStyle(STYLE_NORMAL); 139 | Stack_Char(223); 140 | c1 = Render_Char(uv); 141 | 142 | SetAspect(res.xy, 1.5, true, false); 143 | SetAlign(Align_Center_Center); 144 | SetFontStyle(STYLE_THIN); 145 | Stack_Char(223); 146 | c2 = Render_Char(uv); 147 | 148 | float bac = texture2D(Tex2DScene, luv2uv(uv)).r; 149 | 150 | if(id > ltime) 151 | { 152 | return vec3(saturate(c1) * 0.2 + bac * 0.8); 153 | } 154 | 155 | vec2 fuv = fract(nuv); 156 | fuv.y = 1.0 - fuv.y; 157 | 158 | float ch = 0.0; 159 | SetAspect(vec2(1), 0.8, true, false); 160 | SetAlign(Align_Center_Center); 161 | SetFontStyle(STYLE_BOLD); 162 | Stack_Char(223); 163 | ch += Render_Char(fuv); 164 | 165 | vec2 auv = abs(fuv - 0.5) - 0.45; 166 | float eh = 0.03; 167 | // ch += float((0.0 < auv.x || 0.0 < auv.y) && (auv.x < eh && auv.y < eh)); 168 | ch = saturate(ch); 169 | 170 | vec2 cen; 171 | vec3 ha3 = hash31(id); 172 | float ha = ha3.x; 173 | if(ha < 0.2) 174 | { 175 | cen = vec2(0); 176 | } 177 | else if(ha < 0.4) 178 | { 179 | cen = vec2(1, 0); 180 | } 181 | else if(ha < 0.6) 182 | { 183 | cen = vec2(1, 1); 184 | } 185 | else if(ha < 0.9) 186 | { 187 | cen = vec2(0, 1); 188 | } 189 | else 190 | { 191 | cen = vec2(0.5); 192 | } 193 | float ln = length(fuv - cen) * 5.5; 194 | float cir = float(fract(ln) < 0.5 && ln < 2.5 + floor(ha3.y * 5.0) * 0.5); 195 | 196 | SetAspect(vec2(1), 0.8, true, false); 197 | SetAlign(Align_Center_Center); 198 | SetFontStyle(STYLE_BOLD); 199 | Stack_Char(223); 200 | cir = saturate(cir - Render_Char(fuv)); 201 | 202 | ch = saturate(ch + cir); 203 | // bool fftb2 = hash12(vec2(id, floor(LocalTime * 16.0))) > 0.8; 204 | bool fftb2 = mid.r > 0.5; 205 | ch += (1.0 - 2.0 * ch) * float(ha3.z < 0.1) * float(fftb2); 206 | 207 | ch *= c0; 208 | // ch += c1; 209 | // ch -= c2; 210 | return vec3(saturate(ch) * 0.2 + bac * 0.8); 211 | } 212 | 213 | vec3 layer3(vec2 uv, vec2 res) 214 | { 215 | float ltime = LocalTime * 2.0; 216 | // float fr = fract(ltime); 217 | // float fl = floor(ltime); 218 | ltime = ltime + sin(ltime * TAU) / TAU; 219 | // ltime = fl + pow(fr, 2.0); 220 | 221 | vec2 cuv = uv; 222 | vec2 nuv = uv; 223 | 224 | cuv.y *= res.y / res.x; 225 | vec3 no = cyclicNoise(vec3(cuv * 5.0, ltime * 0.5)) + 1.0; 226 | float flux = dot(vec3(1), no) / 8.0; 227 | flux = clamp((flux - 0.5) * 2.0 + 0.5, 0.0, 1.0); 228 | 229 | const int[4] fluxc = int[4](C_F, C_L, C_U, C_X); 230 | float ch = 0.0; 231 | 232 | SetAspect(res.xy, 10.0, true, false); 233 | SetAlign(Align_Center_Center); 234 | SetFontStyle(STYLE_OUTLINE); 235 | Stack_Char(fluxc[0]); 236 | Stack_Char(fluxc[1]); 237 | Stack_Char(fluxc[2]); 238 | Stack_Char(fluxc[3]); 239 | 240 | float lh = 0.5 - Char_Size.y * 0.5, rh = 0.5 + Char_Size.y * 0.43; 241 | nuv.y = remapc(nuv.y, lh, rh, lh, rh); 242 | ch += Render_Char(nuv); 243 | 244 | SetAspect(res.xy, 10.0, true, false); 245 | SetAlign(Align_Center_Center); 246 | SetFontStyle(STYLE_BOLD); 247 | Stack_Char(fluxc[0]); 248 | Stack_Char(fluxc[1]); 249 | Stack_Char(fluxc[2]); 250 | Stack_Char(fluxc[3]); 251 | Print_Return(0.26); 252 | ch += Render_Char(nuv) * float(Font_Anchor.y + Char_Size.y * 0.46 > nuv.y); 253 | 254 | Stack_Char(fluxc[0]); 255 | Stack_Char(fluxc[1]); 256 | Stack_Char(fluxc[2]); 257 | Stack_Char(fluxc[3]); 258 | Print_Return(-0.26 * 2.0); 259 | ch += Render_Char(nuv) * float(Font_Anchor.y + Char_Size.y * 0.46 < nuv.y); 260 | 261 | ch *= float(abs(uv.y - 0.5) < ltime / 4.0 / 2.0); 262 | 263 | ch += mix(flux, (1.0 - 2.0 * ch) * flux, saturate(abs(uv.y - 0.5) * 4.0)); 264 | ch = saturate(ch); 265 | 266 | vec2 auv = abs(uv - 0.5); 267 | bool auvin = auv.x < 0.1 && auv.y < 0.45; 268 | ch *= float(auvin); 269 | 270 | vec2 fuv = uv; 271 | SetAspect(res.xy, 12.0, true, false); 272 | SetAlign(Align_Left_Bottom); 273 | SetFontStyle(STYLE_OUTLINE_ITALIC); 274 | for(int i = 0; i < 72; i++) 275 | { 276 | Stack_Char(fluxc[i % 4]); 277 | } 278 | float fuvyi = fuv.y * 16.0; 279 | fuv.y = fract(fuvyi) / 16.0; 280 | 281 | fuv.x += (Char_Size.x * SPACE_H * 2.0) * (int(fuvyi) % 2 == 0 ? 2.0 : 1.0); 282 | float bch = Render_Char(fuv); 283 | bch += (1.0 - 2.0 * bch) * float(int(fuvyi) % 4 == 0); 284 | 285 | bch *= float(!auvin); 286 | float bot = floor(16.0 - mod(ltime, 8.0) * 4.0); 287 | float top = floor(32.0 - mod(ltime, 8.0) * 4.0); 288 | bch *= float(bot < fuvyi && fuvyi < top); 289 | 290 | ch = saturate(ch + bch); 291 | return vec3(ch); 292 | } 293 | 294 | vec3 layer4(vec2 uv, vec2 res) 295 | { 296 | float ch = 0.0; 297 | float ltime = LocalTime * 0.5; 298 | vec2 auv = pow(saturate(2.0 * (0.5 - abs(uv - 0.5))), vec2(0.5)); 299 | vec2 namp = vec2(0.05, 0.1) * auv.x * auv.y; 300 | vec2 n = vec2(snoise(vec3(uv * 2.0, ltime)), snoise(vec3(ltime, uv * 2.0))) - 0.5; 301 | vec2 nuv = namp * n; 302 | uv += nuv; 303 | SetAspect(res.xy, 8.0, true, true); 304 | SetAlign(Align_Left_Bottom); 305 | SetFontStyle(STYLE_OUTLINE); 306 | Stack_Char(C_W); 307 | Stack_Char(C_A); 308 | Stack_Char(C_V); 309 | Stack_Char(C_E); 310 | uv.x = mod(uv.x, 1.0 / 10.0); 311 | uv.y = mod(uv.y, 1.0 / 14.0); 312 | ch += float(uv.y < 0.002); 313 | uv.y += Char_Size.y * 0.45; 314 | ch += Render_Char(uv); 315 | 316 | return vec3(ch); 317 | } 318 | 319 | vec2 _gRes; 320 | // sampler2D gChannel; // Error: sampler2Ds must be uniform 321 | // uniform sampler2D gChannel; 322 | 323 | vec4 _sample1(sampler2D channel, vec2 uv, float i, float j) 324 | { 325 | vec2 px = 1. / _gRes; 326 | vec2 r = vec2(i, j); 327 | 328 | return texture(channel, uv + px * r); 329 | } 330 | 331 | vec2 _diffuse(sampler2D channel, vec2 p) 332 | { 333 | vec4 diagonals = _sample1(channel, p, 1., 1.) + _sample1(channel, p, 1., -1.) + _sample1(channel, p, -1., -1.) + _sample1(channel, p, -1., 1.); 334 | vec4 sides = _sample1(channel, p, 1., 0.) + _sample1(channel, p, 0., -1.) + _sample1(channel, p, -1., 0.) + _sample1(channel, p, 0., 1.); 335 | vec4 center = _sample1(channel, p, 0., 0.); 336 | return (diagonals * 0.05 + sides * 0.20 - center).xy; 337 | //return (diagonals + sides * 2. - center * 12.).xy / 21.; 338 | } 339 | 340 | vec3 _render(vec2 res, sampler2D channel, vec2 uv) 341 | { 342 | _gRes = res; 343 | // gChannel = channel; // l-value required (can't modify a uniform "gChannel") 344 | vec3 col = vec3(0.0); 345 | vec2 diff_rate = vec2(1.025, 0.302); 346 | float feed = 0.031; 347 | float kill = 0.056; 348 | float dt = 1.0; 349 | 350 | vec2 ab = _sample1(channel, uv, 0., 0.).xy; 351 | vec2 delta_ab = diff_rate * _diffuse(channel, uv).xy; 352 | float reaction = ab.x * ab.y * ab.y; 353 | delta_ab += vec2(-1., 1.) * reaction; 354 | delta_ab += vec2(feed * (1. - ab.x), -(kill + feed) * ab.y); 355 | col.xy = clamp(ab + delta_ab, 0., 1.); 356 | 357 | return vec3(col.x, col.y, 0.0); 358 | } 359 | 360 | vec3 layer5(vec2 uv, vec2 res) 361 | { 362 | vec3 col = vec3(0); 363 | vec2 guv = luv2uv(uv); 364 | float ch = texture(Tex2DScene, guv).y; 365 | // col = (LocalTime < 0.1 ? vec3(1, length(uv - 0.5) < 0.2, 0) : _render(res, Tex2DScene, guv)); 366 | col = (LocalTime < 0.1 ? vec3(1, ch, 0) : _render(res, Tex2DScene, guv)); 367 | 368 | float ltime = floor(GlobalTime * 5.0); 369 | float stmp = 0.0; 370 | vec2 seed = vec2(42.0, ltime); 371 | uv += (hash22(seed) - 0.5) * 0.9; 372 | float size = 3.0 + 5.0 * hash12(seed.yx); 373 | SetAspect(res.xy, size, true, false); 374 | SetAlign(Align_Center_Center); 375 | SetFontStyle(STYLE_THIN); 376 | Stack_Char(hash12(seed + 42.0) < 0.1 ? 223 : getRandomChar(seed)); 377 | stmp += Render_Char(uv); 378 | 379 | col.g += stmp; 380 | return col; 381 | } 382 | 383 | vec3 layer(int id, vec2 uv, vec2 res) 384 | { 385 | if(id == 0) 386 | { 387 | return layer0(uv, res); 388 | } 389 | else if(id == 1) 390 | { 391 | return layer1(uv, res); 392 | } 393 | // else if(id == 2) 394 | // { 395 | // return layer2(uv, res); 396 | // } 397 | else if(id == 2) 398 | { 399 | return layer3(uv, res); 400 | } 401 | else if(id == 3) 402 | { 403 | return layer4(uv, res); 404 | } 405 | else if(id == 4) 406 | { 407 | return layer5(uv, res); 408 | } 409 | else 410 | { 411 | return layer0(uv, res); 412 | } 413 | } 414 | 415 | vec3 overlay(int id, vec2 uv, vec2 res) 416 | { 417 | float sen = 0.0; 418 | vec2 luv = uv2luv(uv); 419 | vec2 fasp = res / res.y; 420 | vec2 luvd = (abs(luv - 0.5) - 0.5) * fasp; 421 | float w = 1e-3; 422 | sen += float(luvd.x < w && luvd.y < w); 423 | vec2 suv = remap(uv, vec2(1.0 / 3.0 + 0.5, 0.5 - 1.0 / 3.0), vec2(1.0, 1.0 / 3.0 + 0.5), vec2(0.0), vec2(1.0)); 424 | vec2 fasp2 = vec2(1, 4) / 6.0 * fasp; 425 | vec2 asuv = (abs(suv - 0.5) - 0.4) * fasp2; 426 | vec2 asuv2 = abs(asuv); 427 | float w2 = 2e-2; 428 | sen += float((0.0 < asuv.x && asuv.x < w) || (0.0 < asuv.y && asuv.y < w)) * float((asuv2.x < w2 && asuv2.y < w2)); 429 | 430 | vec2 guv = (suv - vec2(0.5, 0.7)) * fasp2; 431 | float l0 = length(guv) * 40.0; 432 | float lf = fract(l0); 433 | float li = floor(l0) + 1.0; 434 | float a0 = (atan(guv.y, guv.x) + PI) / TAU; 435 | float sda = fract(LocalTime * 0.25); 436 | sen += saturate(float(lf < 0.5) * float(l0 < 4.0) * float(mod(a0 + li * sda, 1.0) < 0.5)); 437 | 438 | vec2 guv2 = suv * fasp2 * 52.5 + vec2(0.25, 0); 439 | vec2 guv2f = fract(guv2); 440 | vec2 guv2i = floor(guv2); 441 | vec2 aguv2f = abs(guv2f - 0.5); 442 | int idy = int(fract(-LocalTime * 0.5) * 29.0) + 3; 443 | float blc = float(int(guv2i.x) > 1 && int(guv2i.x) < 14) * float(int(guv2i.y) == idy) * float(aguv2f.x < 0.5 && aguv2f.y < 0.5); 444 | SetAspect(vec2(1), 1.0); 445 | SetAlign(Align_Center_Center); 446 | SetFontStyle(STYLE_BOLD); 447 | Stack_Char(getRandomChar(vec2(guv2i.x, idy))); 448 | sen += blc * (1.0 - Render_Char(guv2f)); 449 | 450 | float spec = texture(spectrum, remap(suv.x, 0.1, 0.9, 0.0, 1.0)).r; 451 | sen += spec * float(inUV(suv, vec2(0.1, 0.1), vec2(0.9, 0.9))); 452 | // sen += (1.0 - 2.0 * sen) * float(fract((suv.y - suv.x * 0.5) * 15.0) < 0.5) * float(inUV(suv, vec2(0.6, 0.1), vec2(0.9, 0.9))); 453 | sen += (1.0 - 2.0 * sen) * float(inUV(suv, vec2(0.6, 0.1), vec2(0.9, 0.9))); 454 | 455 | SetAspect(fasp2, 32.0); 456 | SetAlign(Align_Left_Bottom); 457 | // SetFontStyle(STYLE_THIN); 458 | suv.y -= Char_Size.y * 8.0; 459 | suv.x -= Char_Size.x * 3.0; 460 | 461 | Stack_Char(C_I); 462 | Stack_Char(C_D); 463 | Stack_Char(C_minus); 464 | Stack_Char(C_space); 465 | Stack_Number(id); 466 | sen += Render_Char(suv); 467 | Print_Return(1.0); 468 | Stack_Char(C_F); 469 | Stack_Char(C_space); 470 | Stack_Char(C_minus); 471 | Stack_Char(C_space); 472 | Stack_Number(frame_count); 473 | sen += Render_Char(suv); 474 | Print_Return(1.0); 475 | Stack_Char(C_F); 476 | Stack_Char(C_P); 477 | Stack_Char(C_minus); 478 | Stack_Char(C_space); 479 | Stack_Number(1.0 / time_delta); 480 | sen += Render_Char(suv); 481 | Print_Return(1.0); 482 | Stack_Char(C_L); 483 | Stack_Char(C_T); 484 | Stack_Char(C_minus); 485 | Stack_Char(C_space); 486 | Stack_Number(LocalTime); 487 | sen += Render_Char(suv); 488 | Print_Return(1.0); 489 | Stack_Char(C_G); 490 | Stack_Char(C_T); 491 | Stack_Char(C_minus); 492 | Stack_Char(C_space); 493 | Stack_Number(GlobalTime); 494 | sen += Render_Char(suv); 495 | 496 | float left = 0.0; 497 | vec2 leuv = remap(uv, vec2(0.0, 0.5 - 1.0 / 3.0), vec2(0.5 - 1.0 / 3.0, 1.0 / 3.0 + 0.5), vec2(0.0), vec2(1.0)); 498 | float lmask = float(inUV(leuv, vec2(0.1), vec2(0.7, 0.6))); 499 | vec2 leuvs = (leuv - 0.5) * vec2(1, 2) * 0.1; 500 | vec3 _a, _b; 501 | float don = (lmask > 0.5 ? domainWarping(vec3(leuvs, snoise(vec3(leuvs + id, GlobalTime * 0.05))), _a, _b) : 1.0); 502 | left += float(don < 0.02); 503 | vec2 leuv2 = fract(uv * fasp * 40.0); 504 | float w3 = w * 40.0; 505 | float lmask2 = float(inUV(1.0 - leuv, vec2(0.1), vec2(0.7, 0.6))); 506 | left += (1.0 - lmask) * lmask2 * float(leuv2.x < w3 || leuv2.y < w3); 507 | SetAspect(fasp2.yx, 3.0); 508 | SetAlign(Align_Right_Top); 509 | SetFontStyle(STYLE_OUTLINE_ITALIC); 510 | vec2 cleuv = vec2(1.0 - leuv.y, leuv.x); 511 | cleuv.x += Char_Size.x * SPACE_H; 512 | // cleuv.y += Char_Size.y * SPACE_H; 513 | Stack_Char(C_2); 514 | Stack_Char(C_D); 515 | Stack_Char(C_I); 516 | Stack_Char(C_M); 517 | Stack_Char(C_E); 518 | Stack_Char(C_N); 519 | Stack_Char(C_S); 520 | Stack_Char(C_I); 521 | Stack_Char(C_O); 522 | Stack_Char(C_N); 523 | left += Render_Char(cleuv); 524 | float hlch = 0.0; 525 | SetAspect(fasp2.yx, 10.0); 526 | SetAlign(Align_Right_Top); 527 | SetFontStyle(STYLE_NORMAL); 528 | // SetFontStyle(STYLE_BOLD); 529 | cleuv = vec2(leuv.y, 1.0 - leuv.x); 530 | cleuv.x += Char_Size.x * SPACE_H * 6.0; 531 | cleuv.y += Char_Size.y * SPACE_H * 3.0; 532 | Stack_Char(C_S); 533 | Stack_Char(C_Y); 534 | Stack_Char(C_S); 535 | Stack_Char(C_T); 536 | Stack_Char(C_E); 537 | Stack_Char(C_M); 538 | Stack_Char(C_minus); 539 | Stack_Char(C_M); 540 | Stack_Char(C_O); 541 | Stack_Char(C_N); 542 | Stack_Char(C_O); 543 | Stack_Char(C_left); 544 | Stack_Char(C_S); 545 | Stack_Char(C_P); 546 | Stack_Char(C_A); 547 | Stack_Char(C_C); 548 | Stack_Char(C_E); 549 | Stack_Char(C_right); 550 | hlch += Render_Char(cleuv); 551 | left += hlch; 552 | // left += float(inUV(leuv, vec2(0.1, 0.6), vec2(0.3, 0.9))) - hlch; 553 | 554 | const int LAYER_COUNT = 5; 555 | float ch = 0.0; 556 | const float chspeed = 0.1; 557 | vec2 cuv = uv; 558 | const int[16] text0 = int[16](C_M, C_E, C_A, C_N, C_I, C_N, C_G, C_L, C_E, C_S, C_S, 0, 0, 0, 0, 0); 559 | const int[16] text1 = int[16](C_Y, C_O, C_U, C_space, C_A, C_R, C_E, C_space, C_H, C_E, C_R, C_E, 0, 0, 0, 0); 560 | // const int[16] text2 = int[16](C_Q, C_U, C_A, C_D, C_T, C_R, C_E, C_E, C_space, C_D, C_I, C_V, C_I, C_D, C_E, 0); 561 | const int[16] text3 = int[16](C_F, C_L, C_U, C_X, C_space, C_space, C_space, C_space, C_F, C_L, C_U, C_X, C_space, C_space, C_space, C_space); 562 | const int[16] text4 = int[16](C_W, C_A, C_V, C_E, C_space, C_space, C_space, C_space, C_W, C_A, C_V, C_E, C_space, C_space, C_space, C_space); 563 | const int[16] text5 = int[16](C_R, C_D, C_space, C_minus, C_space, C_S, C_Y, C_S, C_T, C_E, C_M, 0, 0, 0, 0, 0); 564 | // const int[LAYER_COUNT][16] texts = int[LAYER_COUNT][16](text0, text1, text2, text3, text4, text5); 565 | const int[LAYER_COUNT][16] texts = int[LAYER_COUNT][16](text0, text1, text3, text4, text5); 566 | 567 | SetAspect(res.xy, 3.0); 568 | SetAlign(Align_Left_Top); 569 | if(cuv.y > 0.5) 570 | { 571 | SetFontStyle(STYLE_OUTLINE); 572 | cuv.x = fract(cuv.x + GlobalTime * chspeed); 573 | } 574 | else 575 | { 576 | SetFontStyle(STYLE_BOLD); 577 | cuv.x = fract(cuv.x - GlobalTime * chspeed); 578 | } 579 | 580 | for(int i = 0; i < 16; i++) 581 | { 582 | Stack_Char(texts[id % LAYER_COUNT][i]); 583 | // Stack_Number((i + int(LocalTime)) % 4); 584 | } 585 | // fold 586 | cuv.y = abs(cuv.y - 0.5) + 0.5; 587 | ch += Render_Char(cuv); 588 | 589 | float mark = 0.0; 590 | vec2 muv = uv * fasp * 20.0 + 0.25; 591 | vec2 muvf = fract(muv); 592 | vec2 muvi = floor(muv); 593 | float mtime = floor(LocalTime * 16.0); 594 | float ma = 0.0; 595 | vec2 amuvf = abs(muvf - 0.5); 596 | vec2 aamuvf = abs(amuvf - 0.25); 597 | float mw = 1e-2; 598 | mark += float((amuvf.x < mw) || (amuvf.y < mw)); 599 | mark *= float(hash13(vec3(muvi, mtime)) < 0.01); 600 | 601 | float col = saturate(sen + left + ch + mark); 602 | return vec3(col); 603 | } 604 | 605 | float layermask(vec2 uv) 606 | { 607 | uv = abs(uv - 0.5); 608 | return float(uv.x < 0.5 && uv.y < 0.5); 609 | } 610 | 611 | vec3 uniteLayer(float sht) 612 | { 613 | Master master = getMaster(); 614 | GlobalTime = master.GlobalTime + sht; 615 | LocalTime = master.Info2D.LocalTime + sht; 616 | 617 | vec2 uv = gl_FragCoord.xy / resolution.xy; 618 | vec2 luv = uv2luv(uv); 619 | vec3 col = vec3(0); 620 | int layerID = master.Info2D.ID; 621 | col = (layermask(luv) > 0.5 ? layer(layerID, luv, resolution.xy) : col); 622 | col = (layermask(luv) < 0.5 ? overlay(layerID, uv, resolution.xy) : col); 623 | col = saturate(col); 624 | return col; 625 | } 626 | 627 | void main() 628 | { 629 | // float sht = pow(1.0 / (1.0 + beatButton().y), 10.0) * 0.5; 630 | // vec3 col = uniteLayer(-sht); 631 | vec3 col = uniteLayer(0.0); 632 | outColor = vec4(col, 1.0); 633 | } -------------------------------------------------------------------------------- /Shader/3DBloom.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | #pragma include "Shader/params.glsl" 6 | #pragma include "Shader/common.glsl" 7 | 8 | uniform sampler2D Tex3DDOF; 9 | uniform sampler2D Tex3DRes; 10 | 11 | float getLuma(vec3 color) 12 | { 13 | const vec3 lumaWeights = vec3(0.299, 0.587, 0.114); 14 | return dot(color, lumaWeights); 15 | } 16 | 17 | float gaussian(float x) 18 | { 19 | const float sigma = 5.0; 20 | return exp(-(x * x) / (2.0 * sigma * sigma)); 21 | } 22 | 23 | vec3 getBloom(vec2 uv, float threshold) 24 | { 25 | vec3 col = vec3(0); 26 | float total = 0.0; 27 | const int MAX_BLUR_SIZE = 4; 28 | float rangefactor = 4.0; 29 | for(int x = -MAX_BLUR_SIZE; x < MAX_BLUR_SIZE; x++) 30 | { 31 | for(int y = -MAX_BLUR_SIZE; y < MAX_BLUR_SIZE; y++) 32 | { 33 | vec2 offset = vec2(x, y); 34 | float weight = gaussian(length(offset)); 35 | offset *= rangefactor; 36 | vec3 up = max(vec3(0), texture(Tex3DDOF, uv + offset / resolution.xy, rangefactor).rgb - threshold); 37 | col += up * weight; 38 | total += weight; 39 | } 40 | } 41 | return saturate(col / total); 42 | } 43 | 44 | void main() 45 | { 46 | if(is2D()) 47 | { 48 | outColor = vec4(0); 49 | return; 50 | } 51 | 52 | bool Bloom = true; 53 | float threshold = 0.0; 54 | float tone = 1.0; 55 | // float ins = 0.15; 56 | float ins = 0.1 + pow(1.0 / (1.0 + beatButton().y), 10.0); 57 | 58 | vec2 fragCoord = gl_FragCoord.xy; 59 | vec2 uv = fragCoord / resolution.xy; 60 | vec3 col = texture(Tex3DDOF, uv).rgb; 61 | if(Bloom) 62 | { 63 | col = col * tone + getBloom(uv, threshold) * ins; 64 | } 65 | col = saturate(col); 66 | 67 | // do motion blur? 68 | float ins2 = 0.5; 69 | vec3 bac = texture(Tex3DRes, uv).rgb; 70 | col = mix(col, bac, ins2); 71 | 72 | outColor = vec4(col, 1); 73 | } -------------------------------------------------------------------------------- /Shader/3DDOF.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | #pragma include "Shader/params.glsl" 6 | #pragma include "Shader/common.glsl" 7 | 8 | uniform sampler2D Tex3DScene; 9 | 10 | const float GOLDEN_ANGLE = 2.39996323; 11 | const float MAX_BLUR_SIZE = 6.0; 12 | const float RAD_SCALE = 0.5; // Smaller = nicer blur, larger = faster 13 | 14 | float getBlurSize(float depth, float focusPoint, float focusScale) 15 | { 16 | float coc = clamp((1.0 / focusPoint - 1.0 / depth) * focusScale, -1.0, 1.0); 17 | return abs(coc) * MAX_BLUR_SIZE; 18 | } 19 | 20 | float getFocusPoint() 21 | { 22 | float point = 0.0; 23 | const float w = 0.05; 24 | const vec2 cen = vec2(0.5); 25 | const vec2 p0 = cen; 26 | const vec2 p1 = cen + vec2(0, w); 27 | const vec2 p2 = cen + vec2(w, 0); 28 | const vec2 p3 = cen + vec2(0, -w); 29 | const vec2 p4 = cen + vec2(-w, 0); 30 | point += texture(Tex3DScene, p0, 2.0).a; 31 | point += texture(Tex3DScene, p1, 2.0).a; 32 | point += texture(Tex3DScene, p2, 2.0).a; 33 | point += texture(Tex3DScene, p3, 2.0).a; 34 | point += texture(Tex3DScene, p4, 2.0).a; 35 | point /= 5.0; 36 | return point; 37 | } 38 | 39 | vec3 depthOfField(vec2 uv, float focusScale, vec2 uPixelSize) 40 | { 41 | vec4 tex = texture(Tex3DScene, uv); 42 | float centerDepth = tex.a; 43 | float focusPoint = getFocusPoint(); 44 | float centerSize = getBlurSize(centerDepth, focusPoint, focusScale); 45 | vec3 color = tex.rgb; 46 | 47 | float tot = 1.0; 48 | float radius = RAD_SCALE; 49 | for(float ang = 0.0; radius < MAX_BLUR_SIZE; ang += GOLDEN_ANGLE) 50 | { 51 | vec2 tc = uv + vec2(cos(ang), sin(ang)) * uPixelSize * radius; 52 | tex = texture(Tex3DScene, tc); 53 | vec3 sampleColor = tex.rgb; 54 | float sampleDepth = tex.a; 55 | float sampleSize = getBlurSize(sampleDepth, focusPoint, focusScale); 56 | if(sampleDepth > centerDepth) 57 | sampleSize = clamp(sampleSize, 0.0, centerSize * 2.0); 58 | float m = smoothstep(radius - 0.5, radius + 0.5, sampleSize); 59 | color += mix(color / tot, sampleColor, m); 60 | tot += 1.0; 61 | radius += RAD_SCALE / radius; 62 | } 63 | return color /= tot; 64 | } 65 | 66 | void main() 67 | { 68 | if(is2D()) 69 | { 70 | outColor = vec4(0); 71 | return; 72 | } 73 | 74 | bool DOF = true; 75 | // TODO: 76 | float focusScale = 3.0; 77 | 78 | vec2 fragCoord = gl_FragCoord.xy; 79 | vec2 uv = fragCoord / resolution.xy; 80 | vec3 col = texture(Tex3DScene, uv).rgb; 81 | if(DOF) 82 | { 83 | col = depthOfField(uv, focusScale, 1.0 / resolution.xy); 84 | } 85 | outColor = vec4(col, 1); 86 | } -------------------------------------------------------------------------------- /Shader/3DScene.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | // #define DEBUG 6 | // #define TAA 7 | // Dont touch---------------------------------------------------------------------------------- 8 | 9 | // Include---------------------------------------------------------------------------------- 10 | #pragma include "Shader/params.glsl" 11 | #pragma include "Shader/font.glsl" 12 | 13 | #define LoopMax 256 14 | #define DistMin 1e-3 15 | #define LenMax 1000.0 16 | #define NormalEPS 1e-3 17 | 18 | #define iTime time 19 | #define iResolution resolution 20 | 21 | // Global---------------------------------------------------------------------------------- 22 | float GlobalTime; 23 | int MatID; 24 | vec3 CP; 25 | 26 | struct Mat 27 | { 28 | int mat;// 0:Emission,1:Standard 29 | vec3 color; 30 | float roughness; 31 | float metallic; 32 | vec3 nmap;// just normalize(normal + nmap) 33 | }; 34 | #define EMISSION 0 35 | #define STANDARD 1 36 | #define Mat() Mat(EMISSION,vec3(0),0.0,0.0,vec3(0)) 37 | #define MAT_SKY Mat() 38 | 39 | struct SubdivResult 40 | { 41 | int depth; 42 | vec3 size; 43 | vec3 cell; 44 | vec3 hash; 45 | }; 46 | struct GridResult 47 | { 48 | SubdivResult subdiv; 49 | vec3 normal;// maybe not use 50 | float d; 51 | }; 52 | 53 | // last grid result 54 | GridResult GRes; 55 | 56 | uniform sampler2D Tex3DScene; 57 | uniform sampler2D Tex2DRes; 58 | 59 | // SDF------------------------------------------------------------------------------------- 60 | float sdBox(vec3 p, vec3 b) 61 | { 62 | vec3 q = abs(p) - b; 63 | return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0); 64 | } 65 | float sdBox(vec3 p, float s) 66 | { 67 | return sdBox(p, vec3(s)); 68 | } 69 | 70 | float sdSphere(vec3 p, float s) 71 | { 72 | return length(p) - s; 73 | } 74 | 75 | float sdPlane(vec3 p, vec3 n, float h) 76 | { 77 | return dot(p, n) + h; 78 | } 79 | 80 | float sdCapsule(vec3 p, vec3 a, vec3 b, float r) 81 | { 82 | vec3 pa = p - a, ba = b - a; 83 | float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); 84 | return length(pa - ba * h) - r; 85 | } 86 | 87 | // SDF Modifier---------------------------------------------------------------------------- 88 | 89 | mat2 rot(float a) 90 | { 91 | float c = cos(a), s = sin(a); 92 | return mat2(c, -s, s, c); 93 | } 94 | 95 | vec2 pmod(vec2 p, float n) 96 | { 97 | float a = mod(atan(p.y, p.x), TAU / n) - .5 * TAU / n; 98 | return length(p) * vec2(sin(a), cos(a)); 99 | } 100 | 101 | vec3 bfold(vec3 p) 102 | { 103 | if(p.x < p.y) 104 | p.xy = p.yx; 105 | if(p.x < p.z) 106 | p.xz = p.zx; 107 | if(p.y < p.z) 108 | p.yz = p.zy; 109 | return p; 110 | } 111 | 112 | void rotCenter(inout vec3 p, inout vec3 rd) 113 | { 114 | vec4 but = beatButton(); 115 | int bcount = int(but.w + 0.5); 116 | float blt = pow(1.0 / (1.0 + but.y), 10.0); 117 | vec2 rto = hash21(float(bcount) * 42.0) * 180.0; 118 | vec2 rfrom = hash21(float(bcount - 1) * 42.0) * 180.0; 119 | vec2 rot2 = mix(rfrom, rto, blt); 120 | p.xz = rot2d(p.xz, rot2.x); 121 | p.xy = rot2d(p.xy, rot2.y); 122 | rd.xz = rot2d(rd.xz, rot2.x); 123 | rd.xy = rot2d(rd.xy, rot2.y); 124 | } 125 | 126 | // LIVE CODING SPACE vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 127 | 128 | // bool ENABLE_CENTER = true; 129 | bool ENABLE_CENTER = (int(beatButton().w + 0.5) % 2 == 0); 130 | 131 | vec4 BTN = beatButton(); 132 | float BC = BTN.w; 133 | float BT = pow(1.0 / (1.0 + BTN.y), 5.0); 134 | int FID = 0; 135 | 136 | float city(vec3 p) 137 | { 138 | float s=p.y=1.0-abs(p.y),k=10.0; 139 | int id=0; 140 | for(int i=0;i<10;i++) 141 | { 142 | p.xz*=rot(PI*0.25); 143 | p=k*sliders[1]-abs(mod(p,2.0*k)-k); 144 | k*=0.5; 145 | float d=vmin(p); 146 | if(s d ? (d = dt, mid): id)), mid++ 373 | int id = -1, mid = 0; 374 | 375 | float dt, d = LenMax; 376 | opSDFMin(room(p)); 377 | opSDFMin(screen(p)); 378 | if(ENABLE_CENTER) 379 | { 380 | opSDFMin(center(p, rd)); 381 | } 382 | else 383 | { 384 | opSDFMin(hoge(p)); 385 | } 386 | opSDFMin(pillar(p)); 387 | opSDFMin(dai(p)); 388 | opSDFMin(sphere(p)); 389 | 390 | MatID = id; 391 | return d; 392 | } 393 | 394 | vec3 getNormal(vec3 p, vec3 rd) 395 | { 396 | const float h = NormalEPS; 397 | const vec2 k = vec2(1, -1); 398 | return normalize(k.xyy * sdf(p + k.xyy * h, rd) + k.yyx * sdf(p + k.yyx * h, rd) + k.yxy * sdf(p + k.yxy * h, rd) + k.xxx * sdf(p + k.xxx * h, rd)); 399 | } 400 | 401 | // Material-------------------------------------------------------------------------------- 402 | 403 | /* 404 | struct Mat 405 | { 406 | int mat;// 0:Emission,1:Standard 407 | vec3 color; 408 | float roughness; 409 | float metallic; 410 | vec3 nmap;// just normalize(normal + nmap) 411 | }; 412 | */ 413 | Mat roomMat(vec3 p) 414 | { 415 | Mat res = Mat(); 416 | res.mat = STANDARD; 417 | res.metallic = 0.9; 418 | res.roughness = 0.5; 419 | float freq = 4.0; 420 | vec3 np = p * freq; 421 | float _time = GlobalTime * 0.5; 422 | vec2 rnd0 = vec2(snoise(np + vec3(0, -_time, 0)), snoise(vec3(np.yz + 42.0, _time))); 423 | res.nmap = randomSphereDir(rnd0) * 0.05; 424 | res.color = vec3(1); 425 | return res; 426 | } 427 | 428 | Mat screenMat(vec3 p) 429 | { 430 | Mat res = Mat(); 431 | res.mat = EMISSION; 432 | 433 | float a = atan(p.x, p.z) + PI + PI / 4.0; 434 | float len = length(p.xz); 435 | a = mod(a, PI * 0.5) + PI / 4.0; 436 | p.xz = len * vec2(cos(a), sin(a)); 437 | 438 | const float x = 3.5; 439 | const float y = x * 9.0 / 16.0; 440 | vec2 edge = vec2(x, y); 441 | 442 | vec2 uv = remapc(p.xy, -edge, edge, vec2(0), vec2(1)); 443 | uv.x = 1.0 - uv.x; 444 | res.color = texture(Tex2DRes, uv).rgb; 445 | return res; 446 | } 447 | 448 | // TODO:change material via GRes 449 | /* 450 | struct SubdivResult 451 | { 452 | int depth; 453 | vec3 size; 454 | vec3 cell; 455 | vec3 hash; 456 | }; 457 | struct GridResult 458 | { 459 | SubdivResult subdiv; 460 | vec3 normal;// maybe not use 461 | float d; 462 | }; 463 | */ 464 | 465 | // TODO:poor 466 | Mat centerMat(vec3 p, vec3 rd) 467 | { 468 | rotCenter(p, rd); 469 | // is this poor? 470 | const int num = 3; 471 | Mat[num] mats = Mat[num](Mat(), Mat(), Mat()); 472 | mats[0].mat = EMISSION; 473 | mats[0].metallic = 0.0; 474 | mats[0].color = vec3(1.0, 0.1, 0.1); 475 | 476 | mats[1].mat = EMISSION; 477 | mats[1].metallic = 0.0; 478 | mats[1].color = vec3(1.0); 479 | 480 | mats[2].mat = STANDARD; 481 | mats[2].metallic = 1.0; 482 | mats[2].roughness = 0.0; 483 | mats[2].color = vec3(1.0); 484 | 485 | // rot 486 | vec4 but = beatButton(); 487 | int bcount = int(but.w + 0.5); 488 | float blt = pow(1.0 / (1.0 + but.y), 10.0); 489 | 490 | vec4 seed4 = vec4(GRes.subdiv.cell * 42.0, but.w); 491 | vec4 hash4 = hash44(seed4); 492 | int id = int(hash4.x * float(num)) % num; 493 | Mat mat = mats[id]; 494 | 495 | mat.color = (hash11(but.w) < 0.8 ? vec3(mat.color.r) : vec3(mat.color.r, 0.1, 0.1)); 496 | 497 | vec2 uv; 498 | int uvi = 0; 499 | float amp = 1.0; 500 | vec3 cell = GRes.subdiv.cell; 501 | vec3 size = GRes.subdiv.size; 502 | vec3 pc = clamp((p - cell) / size, -1.0, 1.0); 503 | const ivec3 order = ivec3(0, 2, 1); 504 | for(int i = 0; i < 3; i++) 505 | { 506 | int oi = order[i]; 507 | float ni = GRes.normal[oi]; 508 | if(abs(ni) < 0.5) 509 | { 510 | uv[uvi++] = pc[oi]; 511 | } 512 | else 513 | { 514 | amp = sign(ni); 515 | } 516 | } 517 | 518 | uv = clamp(uv * 0.5 + 0.5, 0.0, 1.0); 519 | uv = (hash4.y < 0.5 ? uv : uv.yx); 520 | uv.x = fract(uv.x + blt * 0.5); 521 | 522 | SetAspect(vec2(1), 1.5, true, false); 523 | SetAlign(Align_Center_Center); 524 | SetFontStyle(STYLE_BOLD); 525 | Stack_Char((hash11(but.w * 4.2 + .42) < 0.1) ? 223 : getRandomKanji(hash4.xy * 42.0)); 526 | // Stack_Char(getRandomChar(hash4.xy * 42.0)); 527 | // Stack_Char(223); 528 | float ch = Render_Char(uv); 529 | ch = (hash4.z < 0.5) ? 1.0 - ch : ch; 530 | ch = (hash4.w < 0.3) ? ch * float(fract((uv.x + uv.y + GlobalTime * 0.1 + blt) * 8.0) < 0.5) : ch; 531 | 532 | bool isemi = (mats[id].mat == EMISSION) && (ch > 0.1); 533 | mat.mat = (isemi ? EMISSION : STANDARD); 534 | mat.nmap = hash4.xyz * ch; 535 | return mat; 536 | } 537 | 538 | Mat pillarMat(vec3 p) 539 | { 540 | Mat res = Mat(); 541 | res.mat = STANDARD; 542 | res.color = vec3(1.0); 543 | res.metallic = 0.9; 544 | res.roughness = 0.5; 545 | return res; 546 | } 547 | 548 | Mat daiMat(vec3 p) 549 | { 550 | Mat res = Mat(); 551 | res.mat = STANDARD; 552 | res.color = vec3(1.0); 553 | res.metallic = 0.5; 554 | res.roughness = 0.5; 555 | return res; 556 | } 557 | 558 | Mat sphereMat(vec3 p) 559 | { 560 | Mat res = Mat(); 561 | res.mat = STANDARD; 562 | res.color = vec3(1.0); 563 | res.metallic = 1.0; 564 | res.roughness = 0.5; 565 | return res; 566 | } 567 | 568 | Mat mat(vec3 p, vec3 rd) 569 | { 570 | #define ifMat(mat) if(MatID == mid++)return mat 571 | int mid = 0; 572 | 573 | ifMat(roomMat(p)); 574 | ifMat(screenMat(p)); 575 | if(ENABLE_CENTER) 576 | { 577 | ifMat(centerMat(p, rd)); 578 | } 579 | else 580 | { 581 | ifMat(lambdaMat(p)); 582 | } 583 | ifMat(pillarMat(p)); 584 | ifMat(daiMat(p)); 585 | ifMat(sphereMat(p)); 586 | 587 | return Mat(); 588 | } 589 | 590 | // Lights---------------------------------------------------------------------------- 591 | 592 | float Fd_Burley(float ndotv, float ndotl, float ldoth, float roughness) 593 | { 594 | float fd90 = 0.5 + 2.0 * ldoth * ldoth * roughness; 595 | float lightScatter = (1.0 + (fd90 - 1.0) * pow(1.0 - ndotl, 5.0)); 596 | float viewScatter = (1.0 + (fd90 - 1.0) * pow(1.0 - ndotv, 5.0)); 597 | float diffuse = lightScatter * viewScatter; 598 | return diffuse; 599 | } 600 | float V_SmithGGXCorrelated(float ndotl, float ndotv, float alpha) 601 | { 602 | float lambdaV = ndotl * (ndotv * (1.0 - alpha) + alpha); 603 | float lambdaL = ndotv * (ndotl * (1.0 - alpha) + alpha); 604 | return 0.5 / (lambdaV + lambdaL + 0.0001); 605 | } 606 | float D_GGX(float perceptualRoughness, float ndoth, vec3 normal, vec3 halfDir) 607 | { 608 | vec3 ncrossh = cross(normal, halfDir); 609 | float a = ndoth * perceptualRoughness; 610 | float k = perceptualRoughness / (dot(ncrossh, ncrossh) + a * a); 611 | float d = k * k / PI; 612 | return min(d, 65504.0); 613 | } 614 | #define _DielectricF0 0.04 615 | vec3 F_Schlick(vec3 f0, float cos) 616 | { 617 | return f0 + (1.0 - f0) * pow(1.0 - cos, 5.0); 618 | } 619 | // vec3 BRDF(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor, vec3 indirectDiffuse, vec3 indirectSpecular) 620 | // { 621 | // vec3 halfDir = normalize(lightDir + viewDir); 622 | // float ndotv = abs(dot(normal, viewDir)); 623 | // float ndotl = max(0, dot(normal, lightDir)); 624 | // float ndoth = max(0, dot(normal, halfDir)); 625 | // float ldoth = max(0, dot(lightDir, halfDir)); 626 | // float reflectivity = mix(_DielectricF0, 1, metallic); 627 | // vec3 f0 = mix(_DielectricF0, albedo, metallic); 628 | // float diffuseTerm = Fd_Burley(ndotv, ndotl, ldoth, perceptualRoughness) * ndotl; 629 | // vec3 diffuse = albedo * (1 - reflectivity) * lightColor * diffuseTerm; // Indirect Diffuse 630 | // diffuse += albedo * (1 - reflectivity) * indirectDiffuse; 631 | 632 | // float alpha = perceptualRoughness * perceptualRoughness; 633 | // float V = V_SmithGGXCorrelated(ndotl, ndotv, alpha); 634 | // float D = D_GGX(perceptualRoughness, ndotv, normal, halfDir); 635 | // vec3 F = F_Schlick(f0, ldoth); 636 | // vec3 specular = V * D * F * ndotl * lightColor; 637 | // specular *= PI;// maybe not needed? 638 | // specular = max(0, specular); // Indirect Specular 639 | // float surfaceReduction = 1.0 / (alpha * alpha + 1.0); 640 | // float f90 = saturate((1 - perceptualRoughness) + reflectivity); 641 | // specular += surfaceReduction * indirectSpecular * mix(f0, f90, pow(1 - ndotv, 5)); 642 | // vec3 color = diffuse + specular; 643 | // return color; 644 | // } 645 | 646 | vec3 BDRF_Indirect(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 indirectDiffuse, vec3 indirectSpecular) 647 | { 648 | float ndotv = abs(dot(normal, viewDir)); 649 | float reflectivity = mix(_DielectricF0, 1.0, metallic); 650 | vec3 diffuse = albedo * (1.0 - reflectivity) * indirectDiffuse; 651 | 652 | float alpha = perceptualRoughness * perceptualRoughness; 653 | float surfaceReduction = 1.0 / (alpha * alpha + 1.0); 654 | vec3 f0 = mix(vec3(_DielectricF0), albedo, metallic); 655 | float f90 = saturate((1.0 - perceptualRoughness) + reflectivity); 656 | vec3 specular = surfaceReduction * indirectSpecular * mix(f0, vec3(f90), pow(1.0 - ndotv, 5.0)); 657 | 658 | vec3 color = diffuse + specular; 659 | return color; 660 | } 661 | 662 | vec3 BDRF_Direct(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor) 663 | { 664 | vec3 halfDir = normalize(lightDir + viewDir); 665 | float ndotv = abs(dot(normal, viewDir)); 666 | float ndotl = max(0.0, dot(normal, lightDir)); 667 | float ndoth = max(0.0, dot(normal, halfDir)); 668 | float ldoth = max(0.0, dot(lightDir, halfDir)); 669 | float reflectivity = mix(_DielectricF0, 1.0, metallic); 670 | vec3 f0 = mix(vec3(_DielectricF0), albedo, metallic); 671 | float diffuseTerm = Fd_Burley(ndotv, ndotl, ldoth, perceptualRoughness) * ndotl; 672 | vec3 diffuse = albedo * (1.0 - reflectivity) * lightColor * diffuseTerm; // Indirect Diffuse 673 | 674 | float alpha = perceptualRoughness * perceptualRoughness; 675 | float V = V_SmithGGXCorrelated(ndotl, ndotv, alpha); 676 | float D = D_GGX(perceptualRoughness, ndotv, normal, halfDir); 677 | vec3 F = F_Schlick(f0, ldoth); 678 | vec3 specular = V * D * F * ndotl * lightColor; 679 | specular *= PI;// maybe not needed? 680 | specular = max(vec3(0), specular); // Indirect Specular 681 | 682 | vec3 color = diffuse + specular; 683 | return color; 684 | } 685 | 686 | // for indirectDiffuse 687 | vec3 getAmbientColor() 688 | { 689 | return vec3(0.1); 690 | } 691 | 692 | #define LightCount 2 693 | // 0:screen 694 | // 1:center 695 | 696 | float lightSDF(vec3 p, vec3 rd, int id) 697 | { 698 | #define ifLightSDF(sdf) if(id == mid++)return sdf 699 | int mid = 0; 700 | 701 | ifLightSDF(screen(p)); 702 | if(ENABLE_CENTER) 703 | { 704 | ifLightSDF(center(p, rd)); 705 | } 706 | else 707 | { 708 | ifLightSDF(hoge(p)); 709 | } 710 | 711 | return LenMax; 712 | } 713 | 714 | // only for emission material 715 | vec3 lightCol(vec3 p, vec3 rd, int id) 716 | { 717 | #define ifLightColor(matFunc) if(id == mid++)return (tmpmat = matFunc).color*float(tmpmat.mat==EMISSION) 718 | Mat tmpmat = Mat(); 719 | int mid = 0; 720 | 721 | ifLightColor(screenMat(p)); 722 | if(ENABLE_CENTER) 723 | { 724 | ifLightColor(centerMat(p, rd)); 725 | } 726 | else 727 | { 728 | ifLightColor(lambdaMat(p)); 729 | } 730 | 731 | return vec3(0); 732 | } 733 | 734 | vec3 lightDirection(vec3 p, vec3 rd, int id) 735 | { 736 | const float h = NormalEPS; 737 | const vec2 k = vec2(1, -1); 738 | return -normalize(k.xyy * lightSDF(p + k.xyy * h, rd, id) + k.yyx * lightSDF(p + k.yyx * h, rd, id) + k.yxy * lightSDF(p + k.yxy * h, rd, id) + k.xxx * lightSDF(p + k.xxx * h, rd, id)); 739 | } 740 | 741 | float lightAttenuation(float dist) 742 | { 743 | const float lightRange = 5.0; 744 | dist = max(dist, 0.0); 745 | return pow(clamp(1.0 - (1.0 / lightRange) * dist, 0.0, 1.0), 2.0); 746 | } 747 | 748 | // do approximate light 749 | #define LightSample 8 750 | void calcLight(int id, vec3 rp, out vec3 lightRp, out vec3 lightDir, out vec3 lightColor) 751 | { 752 | const float maxdiff = 0.25; 753 | const float distFactor = 0.5; 754 | 755 | float attsum = 0.0; 756 | vec3 colsum = vec3(0); 757 | vec3 rd, ro; 758 | rd = vec3(0, 1, 0); 759 | ro = rp; 760 | // lightDir = lightDirection(rp, rd, id); 761 | 762 | for(int j = 0; j < LightSample; j++) 763 | { 764 | rd = lightDirection(rp, rd, id); 765 | float diff = clamp(1.0 - float(j) / float(LightSample), 0.0, 1.0) * maxdiff; 766 | // j,rd,id 767 | vec2 rnd = hash23(vec3(float(j) + GlobalTime, hash13(rp * 42.0) * 42.0, float(id) * 42.0)); 768 | rd = normalize(rd + diff * randomSphereDir(rnd)); 769 | float dist = lightSDF(rp, rd, id); 770 | vec3 col = lightCol(rp, rd, id); 771 | float att = lightAttenuation(dist); 772 | // weight 773 | colsum += col * att; 774 | attsum += att; 775 | rp += rd * dist * distFactor; 776 | } 777 | lightRp = rp; 778 | lightDir = normalize(lightRp - ro); 779 | lightColor = colsum / attsum; 780 | float len = length(lightRp - ro); 781 | lightColor *= lightAttenuation(len); 782 | } 783 | 784 | float calcAO(vec3 p, vec3 rd, vec3 n, float d) 785 | { 786 | return clamp(sdf(p + n * d, rd) / d, 0., 1.); 787 | } 788 | 789 | // Tracer---------------------------------------------------------------------------- 790 | 791 | Mat calcIntersect(vec3 rd, vec3 ro, out vec3 rp, out float dist, out float len) 792 | { 793 | len = 0.0; 794 | rp = ro; 795 | for(int i; i < LoopMax; i++) 796 | { 797 | dist = sdf(rp, rd); 798 | len += dist; 799 | rp = ro + rd * len; 800 | if(dist < DistMin) 801 | { 802 | return mat(rp, rd); 803 | } 804 | } 805 | // return mat(rp, rd); 806 | return MAT_SKY; 807 | } 808 | 809 | vec4 tracer(vec3 rd, vec3 ro) 810 | { 811 | // first raycast 812 | vec3 rp; 813 | float dist, len; 814 | Mat mat = calcIntersect(rd, ro, rp, dist, len); 815 | if(mat.mat == EMISSION) 816 | { 817 | return vec4(mat.color * 3.0, length(rp - ro)); 818 | } 819 | 820 | // shading 821 | vec3 normal = normalize(getNormal(rp, rd) + mat.nmap); 822 | vec3 nrp = rp + normal * DistMin * 10.0; 823 | // indirect light 824 | vec3 indirectDiffuse = getAmbientColor(); 825 | vec3 ro_s = nrp; 826 | vec3 rd_s = reflect(rd, normal); 827 | vec3 rp_s; 828 | float dist_s, len_s; 829 | Mat mat_s = calcIntersect(rd_s, ro_s, rp_s, dist_s, len_s); 830 | vec3 indirectSpecular = mat_s.color * float(mat_s.mat == EMISSION); 831 | // bdrf 832 | vec3 indirect = BDRF_Indirect(mat.color, mat.metallic, mat.roughness, normal, rd, indirectDiffuse, indirectSpecular); 833 | vec3 direct = vec3(0); 834 | int lcount = (ENABLE_CENTER ? LightCount : LightCount - 1); 835 | for(int i = 0; i < LightCount; i++) 836 | { 837 | // direct light 838 | vec3 lightRp, lightDir, lightColor; 839 | calcLight(i, nrp, lightRp, lightDir, lightColor); 840 | // direct += lightDir; 841 | direct += BDRF_Direct(mat.color, mat.metallic, mat.roughness, normal, rd, lightDir, lightColor); 842 | } 843 | vec3 color = indirect + direct * 1.5; 844 | // vec3 color = direct; 845 | // some post process 846 | float ao = calcAO(rp, rd, normal, 0.1); 847 | color *= ao; 848 | color = clamp(color, 0.0, 1.0); 849 | return vec4(color, length(rp - ro)); 850 | } 851 | 852 | // Root---------------------------------------------------------------------------- 853 | void setParameters(vec2 coord) 854 | { 855 | GlobalTime = time; 856 | #ifdef TAA 857 | GlobalTime += (hash12(hash23(vec3(GlobalTime, coord)))) * 0.005; 858 | #endif 859 | } 860 | 861 | void getUVandSeed(out vec2 uv, out vec2 suv, out float seed, inout vec2 fragCoord) 862 | { 863 | // CRT 864 | uv = fragCoord / iResolution.xy; 865 | vec2 taa = vec2(0); 866 | #ifdef TAA 867 | taa = hash23(vec3(GlobalTime, fragCoord)) - 0.5; 868 | #endif 869 | seed = hash12(taa * 42.0 - 0.42) * 42.0; 870 | suv = (2.0 * (fragCoord + taa) - iResolution.xy) / min(iResolution.x, iResolution.y); 871 | } 872 | 873 | void getRORD(out vec3 ro, out vec3 rd, out vec3 dir, vec2 suv) 874 | { 875 | // Parameter 876 | float fov; 877 | vec3 ta; 878 | float fisheye = 0.0; 879 | bool pars = true; 880 | float ortho = 2.5; 881 | 882 | vec3 trd, tro; 883 | float ttime = GlobalTime * 0.005; 884 | vec3 tseed = vec3(ttime, ttime + 42.42, -ttime + 42.42); 885 | float tins = domainWarping(tseed, trd, tro); 886 | tro = normalize(tro - 0.5); 887 | tro *= 0.25; 888 | float troins = 1.0; 889 | 890 | // sequence 891 | int sid = int(cameraButton().w + 0.5) % 4; 892 | if(sid == 0) 893 | { 894 | fov = 90.0; 895 | ro = vec3(0, 0, -3.0); 896 | ro.xz = rot2d(ro.xz, GlobalTime * 5.0); 897 | ta = vec3(0, 0, 0); 898 | } 899 | else if(sid == 1) 900 | { 901 | fov = 90.0; 902 | fisheye = 1.0; 903 | ro = vec3(-3.5, -1.5, -3.5 + 7.0 * fract(GlobalTime * 0.05)); 904 | ta = vec3(0, -0.5, 0); 905 | } 906 | else if(sid == 2) 907 | { 908 | pars = false; 909 | fov = 90.0; 910 | ro = vec3(0, -0.5, -2.75); 911 | ro.xz = rot2d(ro.xz, GlobalTime * 5.0); 912 | ta = vec3(0, 0, 0); 913 | } 914 | else 915 | { 916 | troins = 3.0; 917 | fov = 100.0; 918 | fisheye = 0.5; 919 | ro = vec3(0, 0, -3.0); 920 | ta = vec3(0, 0, 0); 921 | } 922 | 923 | // calc dir 924 | dir = normalize(ta - ro); 925 | 926 | // tebure 927 | ro = ro + tro * troins; 928 | 929 | // calc rd 930 | float cr = 0.0; 931 | vec3 cw = normalize(dir); 932 | vec3 cp = vec3(sin(cr), cos(cr), 0.0); 933 | vec3 cu = normalize(cross(cw, cp)); 934 | vec3 cv = normalize(cross(cu, cw)); 935 | float zf = 1.0 / tan(fov * PI / 360.0); 936 | zf -= zf * length(suv) * fisheye; 937 | if(pars) 938 | { 939 | rd = normalize(-cu * suv.x + cv * suv.y + cw * zf); 940 | } 941 | else 942 | { 943 | rd = dir; 944 | ro += suv.x * cu * ortho + suv.y * cv * ortho; 945 | } 946 | } 947 | 948 | void main() 949 | { 950 | if(is2D()) 951 | { 952 | outColor = vec4(0); 953 | return; 954 | } 955 | 956 | vec2 fragCoord = gl_FragCoord.xy; 957 | 958 | // Set some parameters 959 | setParameters(fragCoord); 960 | 961 | // Get UV and Seed 962 | float seed; 963 | vec2 uv, suv; 964 | getUVandSeed(uv, suv, seed, fragCoord); 965 | 966 | // Camera 967 | vec3 ro, rd, dir; 968 | getRORD(ro, rd, dir, suv); 969 | CP = ro; 970 | 971 | // Tracer 972 | vec4 col = tracer(rd, ro); 973 | 974 | #ifdef TAA 975 | const float bl = 0.5; 976 | col = texture(Tex3DScene, uv) * bl + col * bl; 977 | #endif 978 | 979 | // Output 980 | outColor = col; 981 | 982 | // Debug for some value printf 983 | #ifdef DEBUG 984 | float debugCh = 0.0; 985 | SetAspect(iResolution.xy, 24.0); 986 | SetAlign(Align_Left_Top); 987 | // OffSetAnchor(vec2(0,0)); 988 | // ro 989 | Stack_Char(C_R); 990 | Stack_Char(C_O); 991 | Stack_Char(C_comma); 992 | Stack_Char(C_x); 993 | Stack_Char(C_colon); 994 | Stack_Sign(ro.x); 995 | Stack_Number(ro.x); 996 | debugCh += Render_Char(uv); 997 | Print_Return(); 998 | 999 | // debugCh += Print_Char(uv, C_R); 1000 | // debugCh += Print_Char(uv, C_O); 1001 | // debugCh += Print_Char(uv, C_comma); 1002 | // debugCh += Print_Char(uv, C_x); 1003 | // debugCh += Print_Char(uv, C_colon); 1004 | // debugCh += Print_Sign(uv, ro.x); 1005 | // debugCh += Print_Number(uv, ro.x); 1006 | 1007 | Stack_Char(C_R); 1008 | Stack_Char(C_O); 1009 | Stack_Char(C_comma); 1010 | Stack_Char(C_y); 1011 | Stack_Char(C_colon); 1012 | Stack_Sign(ro.y); 1013 | Stack_Number(ro.y); 1014 | debugCh += Render_Char(uv); 1015 | Print_Return(); 1016 | Stack_Char(C_R); 1017 | Stack_Char(C_O); 1018 | Stack_Char(C_comma); 1019 | Stack_Char(C_z); 1020 | Stack_Char(C_colon); 1021 | Stack_Sign(ro.z); 1022 | Stack_Number(ro.z); 1023 | debugCh += Render_Char(uv); 1024 | Print_Return(); 1025 | // dir 1026 | Stack_Char(C_D); 1027 | Stack_Char(C_I); 1028 | Stack_Char(C_comma); 1029 | Stack_Char(C_x); 1030 | Stack_Char(C_colon); 1031 | Stack_Sign(dir.x); 1032 | Stack_Number(dir.x); 1033 | debugCh += Render_Char(uv); 1034 | Print_Return(); 1035 | Stack_Char(C_D); 1036 | Stack_Char(C_I); 1037 | Stack_Char(C_comma); 1038 | Stack_Char(C_y); 1039 | Stack_Char(C_colon); 1040 | Stack_Sign(dir.y); 1041 | Stack_Number(dir.y); 1042 | debugCh += Render_Char(uv); 1043 | Print_Return(); 1044 | Stack_Char(C_D); 1045 | Stack_Char(C_I); 1046 | Stack_Char(C_comma); 1047 | Stack_Char(C_z); 1048 | Stack_Char(C_colon); 1049 | Stack_Sign(dir.z); 1050 | Stack_Number(dir.z); 1051 | debugCh += Render_Char(uv); 1052 | Print_Return(); 1053 | 1054 | // SetAspect(iResolution.xy, 4.0); 1055 | // SetAlign(Align_Center_Center); 1056 | // Stack_Char(C_0); 1057 | // Stack_Char(C_g); 1058 | // debugCh += Render_Char(uv); 1059 | 1060 | debugCh = clamp(debugCh, 0.0, 1.0); 1061 | outColor.rgb += debugCh; 1062 | // outColor.rgb -= 10.0 * vec3(abs(uv.y - 0.5) < 0.001 || abs(uv.x - 0.5) < 0.001, 0, 0); 1063 | #endif 1064 | 1065 | // clamp 1066 | // outColor.rgb = clamp(outColor.rgb, 0.0, 1.0); 1067 | } -------------------------------------------------------------------------------- /Shader/3DScene_Bac.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | // #define DEBUG 6 | // #define TAA 7 | // Dont touch---------------------------------------------------------------------------------- 8 | 9 | // Include---------------------------------------------------------------------------------- 10 | #pragma include "Shader/params.glsl" 11 | #pragma include "Shader/font.glsl" 12 | 13 | #define LoopMax 256 14 | #define DistMin 1e-3 15 | #define LenMax 1000.0 16 | #define NormalEPS 1e-3 17 | 18 | #define iTime time 19 | #define iResolution resolution 20 | 21 | // Global---------------------------------------------------------------------------------- 22 | float GlobalTime; 23 | int MatID; 24 | vec3 CP; 25 | 26 | struct Mat 27 | { 28 | int mat;// 0:Emission,1:Standard 29 | vec3 color; 30 | float roughness; 31 | float metallic; 32 | vec3 nmap;// just normalize(normal + nmap) 33 | }; 34 | #define EMISSION 0 35 | #define STANDARD 1 36 | #define Mat() Mat(EMISSION,vec3(0),0.0,0.0,vec3(0)) 37 | #define MAT_SKY Mat() 38 | 39 | struct SubdivResult 40 | { 41 | int depth; 42 | vec3 size; 43 | vec3 cell; 44 | vec3 hash; 45 | }; 46 | struct GridResult 47 | { 48 | SubdivResult subdiv; 49 | vec3 normal;// maybe not use 50 | float d; 51 | }; 52 | 53 | // last grid result 54 | GridResult GRes; 55 | 56 | uniform sampler2D Tex3DScene; 57 | uniform sampler2D Tex2DRes; 58 | 59 | // SDF------------------------------------------------------------------------------------- 60 | float sdBox(vec3 p, vec3 b) 61 | { 62 | vec3 q = abs(p) - b; 63 | return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0); 64 | } 65 | float sdBox(vec3 p, float s) 66 | { 67 | return sdBox(p, vec3(s)); 68 | } 69 | 70 | float sdSphere(vec3 p, float s) 71 | { 72 | return length(p) - s; 73 | } 74 | 75 | float sdPlane(vec3 p, vec3 n, float h) 76 | { 77 | return dot(p, n) + h; 78 | } 79 | 80 | float sdCapsule(vec3 p, vec3 a, vec3 b, float r) 81 | { 82 | vec3 pa = p - a, ba = b - a; 83 | float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); 84 | return length(pa - ba * h) - r; 85 | } 86 | 87 | // SDF Modifier---------------------------------------------------------------------------- 88 | 89 | mat2 rot(float a) 90 | { 91 | float c = cos(a), s = sin(a); 92 | return mat2(c, -s, s, c); 93 | } 94 | 95 | vec2 pmod(vec2 p, float n) 96 | { 97 | float a = mod(atan(p.y, p.x), TAU / n) - .5 * TAU / n; 98 | return length(p) * vec2(sin(a), cos(a)); 99 | } 100 | 101 | vec3 bfold(vec3 p) 102 | { 103 | if(p.x < p.y) 104 | p.xy = p.yx; 105 | if(p.x < p.z) 106 | p.xz = p.zx; 107 | if(p.y < p.z) 108 | p.yz = p.zy; 109 | return p; 110 | } 111 | 112 | void rotCenter(inout vec3 p, inout vec3 rd) 113 | { 114 | vec4 but = beatButton(); 115 | int bcount = int(but.w + 0.5); 116 | float blt = pow(1.0 / (1.0 + but.y), 10.0); 117 | vec2 rto = hash21(float(bcount) * 42.0) * 180.0; 118 | vec2 rfrom = hash21(float(bcount - 1) * 42.0) * 180.0; 119 | vec2 rot2 = mix(rfrom, rto, blt); 120 | p.xz = rot2d(p.xz, rot2.x); 121 | p.xy = rot2d(p.xy, rot2.y); 122 | rd.xz = rot2d(rd.xz, rot2.x); 123 | rd.xy = rot2d(rd.xy, rot2.y); 124 | } 125 | 126 | // LIVE CODING SPACE vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 127 | 128 | // bool ENABLE_CENTER = true; 129 | bool ENABLE_CENTER = (int(beatButton().w + 0.5) % 2 == 0); 130 | 131 | vec4 BTN = beatButton(); 132 | float BC = BTN.w; 133 | float BT = pow(1.0 / (1.0 + BTN.y), 5.0); 134 | int FID = 0; 135 | 136 | float city(vec3 p) 137 | { 138 | float s = p.y = 1.0 - abs(p.y), k = 10.0; 139 | int id = 0; 140 | for(int i = 0; i < 10; i++) 141 | { 142 | p.xz *= rot(PI * 0.25); 143 | p = k * sliders[1] - abs(mod(p, 2.0 * k) - k); 144 | k *= 0.5; 145 | float d = vmin(p); 146 | if(s < d) 147 | { 148 | id = i; 149 | } 150 | s = max(s, d); 151 | } 152 | FID = id; 153 | return s; 154 | } 155 | 156 | float sdf(vec3 p) 157 | { 158 | float d = LenMax; 159 | 160 | d = city(p); 161 | d = max(d, sdBox(p, 5.0)); 162 | d = max(d, -sdBox(p, 1.5)); 163 | d = max(d, -sdBox(p - CP, 0.2)); 164 | return d; 165 | } 166 | 167 | float origin(vec3 p) 168 | { 169 | vec3 _d; 170 | rotCenter(p, _d); 171 | return sdBox(p, 1.0 - DistMin); 172 | } 173 | 174 | float lambda(vec3 p) 175 | { 176 | // return origin(p); 177 | float d = LenMax; 178 | d = min(origin(p), sdf(p)); 179 | return d; 180 | } 181 | 182 | Mat lambdaMat(vec3 p) 183 | { 184 | Mat mat = Mat(); 185 | int b = int(BC * 0.5 + 0.5) % 10; 186 | mat.mat = (FID == b) ? EMISSION : STANDARD; 187 | mat.color = vec3(1.0); 188 | mat.metallic = 0.5; 189 | return mat; 190 | } 191 | 192 | // LIVE CODING SPACE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 193 | 194 | SubdivResult subdivision(vec3 p) 195 | { 196 | SubdivResult result; 197 | vec3 bsize = vec3(0.5); 198 | float th = 0.5; 199 | float dh = hash13(hash31(beatButton().w) * 42.0); 200 | int depth = 1 + int(dh * 3.0); 201 | 202 | result.size = bsize; 203 | result.depth = 0; 204 | for(int i = 0; i < depth; i++) 205 | { 206 | result.cell = (floor(p / result.size) + 0.5) * result.size; 207 | result.hash = hash33(vec3(hash23(result.cell), beatButton().w) * 42.0); 208 | if(i == depth - 1 || result.hash.x < th) 209 | { 210 | break; 211 | } 212 | result.size *= 0.5; 213 | result.depth++; 214 | } 215 | 216 | return result; 217 | } 218 | 219 | GridResult gridTraversal(vec3 rp, vec3 rd) 220 | { 221 | GridResult result; 222 | result.subdiv = subdivision(rp); 223 | vec3 src = -(rp - result.subdiv.cell) / rd; 224 | vec3 dst = abs(0.5 * result.subdiv.size / rd); 225 | vec3 bd = src + dst; 226 | vec3 bn = src - dst; 227 | result.d = min(min(bd.x, bd.y), bd.z); 228 | result.normal = -sign(rd) * step(bn.yzx, bn.xyz) * step(bn.zxy, bn.xyz); 229 | return result; 230 | } 231 | 232 | float gridSDF(vec3 p) 233 | { 234 | float d = LenMax; 235 | d = min(d, sdBox(p, vec3(1.0))); 236 | return d; 237 | } 238 | 239 | float gridBox(vec3 p, vec3 rd) 240 | { 241 | const float th = 0.5; 242 | vec3 bsize = vec3(0.5); 243 | GridResult result = gridTraversal(p, rd); 244 | GRes = result; 245 | // std sdf 246 | vec3 scale = 4.0 * bsize / result.subdiv.size; 247 | vec3 cp = (p - result.subdiv.cell) * scale; 248 | float sdfscale = 1.0 / max(scale.x, max(scale.y, scale.z)); 249 | float d = result.d; 250 | d = min(d, gridSDF(cp)); 251 | d *= sdfscale; 252 | // exist 253 | bool exist = result.subdiv.hash.y < th; 254 | d = exist ? d : result.d; 255 | d += DistMin * 1.0;// TODO:maybe 1.0 for just box 256 | return d; 257 | } 258 | 259 | float room(vec3 p) 260 | { 261 | return -sdBox(p, vec3(4.1, 2, 4.1)); 262 | } 263 | 264 | float screenID(vec3 p, int id) 265 | { 266 | p.xz = rot2d(p.xz, float(id) * 90.0); 267 | const float x = 3.5; 268 | const float y = x * 9.0 / 16.0; 269 | vec2 edge = vec2(x, y); 270 | 271 | float d0 = sdBox(p, vec3(x, y, 4.0)); 272 | float d1 = sdPlane(p, vec3(0, 0, -1), 4.0); 273 | return max(d0, d1); 274 | } 275 | 276 | float screen(vec3 p) 277 | { 278 | float d = LenMax; 279 | for(int i = 0; i < 4; i++) 280 | { 281 | d = min(d, screenID(p, i)); 282 | } 283 | return d; 284 | } 285 | 286 | #define ENABLE_ROTATE false 287 | float hoge(vec3 p) 288 | { 289 | vec3 _d; 290 | if(ENABLE_ROTATE) 291 | { 292 | rotCenter(p, _d); 293 | } 294 | return lambda(p); 295 | } 296 | 297 | float modifire(vec3 p, vec3 rp) 298 | { 299 | // if(ENABLE_ROTATE) 300 | // { 301 | // return hoge(rp); 302 | // } 303 | // else 304 | // { 305 | // return hoge(p); 306 | // } 307 | return hoge(p); 308 | } 309 | 310 | float center(vec3 p, vec3 rd) 311 | { 312 | float d = LenMax; 313 | vec3 np = p, nrd = rd; 314 | rotCenter(np, nrd); 315 | d = min(d, gridBox(np, nrd)); 316 | d = max(d, modifire(p, np)); 317 | return d; 318 | } 319 | 320 | float pillarR(vec3 p) 321 | { 322 | // round 323 | float size = 0.1; 324 | p.xz = abs(p.xz); 325 | p -= vec3(1.5, 0, 1.5); 326 | p.xz = rot2d(p.xz, (p.y - GlobalTime * 0.5) * 60.0); 327 | return sdBox(p, vec3(size, 3, size)); 328 | } 329 | 330 | // https://www.shadertoy.com/view/ttB3DV 331 | float profileSquare(vec2 p, vec2 dim) 332 | { 333 | vec2 d = abs(p) - dim; 334 | return length(max(d, vec2(0))) + min(max(d.x, d.y), 0.0); 335 | } 336 | vec3 closestPointOnCylinder(vec3 p, vec2 dim) 337 | { 338 | return vec3(normalize(p.xy) * dim.x, clamp(p.z, -dim.y / 2.0, dim.y / 2.0)); 339 | } 340 | float pillarT(vec3 p) 341 | { 342 | p = p.xzy; 343 | float radius = 2.0; 344 | float height = 4.0; 345 | float coils = PI; 346 | float freq = 1.0; 347 | vec3 pc = closestPointOnCylinder(p, vec2(radius, height)); 348 | float distToCyl = distance(p, pc); 349 | float distToCoil = asin(sin(p.z * coils + freq * atan(p.x, p.y) - GlobalTime * 0.5)) / coils; 350 | vec2 springCoords = vec2(distToCyl, distToCoil); 351 | float profile = profileSquare(springCoords, vec2(0.05)) - 0.02; 352 | return profile * (max(radius / 2.0 - abs(length(p.xy) - radius), 0.0) * 0.3 + 0.7); 353 | } 354 | 355 | float pillar(vec3 p) 356 | { 357 | return pillarR(p); 358 | } 359 | 360 | float dai(vec3 p) 361 | { 362 | float d = LenMax; 363 | float h = 0.25; 364 | p.y = abs(p.y); 365 | d = min(d, sdBox(p - vec3(0, 2.0 - 0.5 * h, 0), vec3(2.0, 0.5 * h, 2.0)) - 0.05); 366 | return d; 367 | } 368 | 369 | float sphere(vec3 p) 370 | { 371 | float d = LenMax; 372 | p.xz = abs(p.xz); 373 | d = sdSphere(p - vec3(2 - 0.15, -2 + 0.25 + 0.3, 2 - 0.15), 0.25); 374 | return d; 375 | } 376 | 377 | float sdf(vec3 p, vec3 rd) 378 | { 379 | #define opSDFMin(sdf) (id = ((dt = sdf) < d ? (d = dt, mid): id)), mid++ 380 | #define opSDFMax(sdf) (id = ((dt = sdf) > d ? (d = dt, mid): id)), mid++ 381 | int id = -1, mid = 0; 382 | 383 | float dt, d = LenMax; 384 | opSDFMin(room(p)); 385 | opSDFMin(screen(p)); 386 | if(ENABLE_CENTER) 387 | { 388 | opSDFMin(center(p, rd)); 389 | } 390 | else 391 | { 392 | opSDFMin(hoge(p)); 393 | } 394 | opSDFMin(pillar(p)); 395 | opSDFMin(dai(p)); 396 | opSDFMin(sphere(p)); 397 | 398 | MatID = id; 399 | return d; 400 | } 401 | 402 | vec3 getNormal(vec3 p, vec3 rd) 403 | { 404 | const float h = NormalEPS; 405 | const vec2 k = vec2(1, -1); 406 | return normalize(k.xyy * sdf(p + k.xyy * h, rd) + k.yyx * sdf(p + k.yyx * h, rd) + k.yxy * sdf(p + k.yxy * h, rd) + k.xxx * sdf(p + k.xxx * h, rd)); 407 | } 408 | 409 | // Material-------------------------------------------------------------------------------- 410 | 411 | /* 412 | struct Mat 413 | { 414 | int mat;// 0:Emission,1:Standard 415 | vec3 color; 416 | float roughness; 417 | float metallic; 418 | vec3 nmap;// just normalize(normal + nmap) 419 | }; 420 | */ 421 | Mat roomMat(vec3 p) 422 | { 423 | Mat res = Mat(); 424 | res.mat = STANDARD; 425 | res.metallic = 0.9; 426 | res.roughness = 0.5; 427 | float freq = 4.0; 428 | vec3 np = p * freq; 429 | float _time = GlobalTime * 0.5; 430 | vec2 rnd0 = vec2(snoise(np + vec3(0, -_time, 0)), snoise(vec3(np.yz + 42.0, _time))); 431 | res.nmap = randomSphereDir(rnd0) * 0.05; 432 | res.color = vec3(1); 433 | return res; 434 | } 435 | 436 | Mat screenMat(vec3 p) 437 | { 438 | Mat res = Mat(); 439 | res.mat = EMISSION; 440 | 441 | float a = atan(p.x, p.z) + PI + PI / 4.0; 442 | float len = length(p.xz); 443 | a = mod(a, PI * 0.5) + PI / 4.0; 444 | p.xz = len * vec2(cos(a), sin(a)); 445 | 446 | const float x = 3.5; 447 | const float y = x * 9.0 / 16.0; 448 | vec2 edge = vec2(x, y); 449 | 450 | vec2 uv = remapc(p.xy, -edge, edge, vec2(0), vec2(1)); 451 | uv.x = 1.0 - uv.x; 452 | res.color = texture(Tex2DRes, uv).rgb; 453 | return res; 454 | } 455 | 456 | // TODO:change material via GRes 457 | /* 458 | struct SubdivResult 459 | { 460 | int depth; 461 | vec3 size; 462 | vec3 cell; 463 | vec3 hash; 464 | }; 465 | struct GridResult 466 | { 467 | SubdivResult subdiv; 468 | vec3 normal;// maybe not use 469 | float d; 470 | }; 471 | */ 472 | 473 | // TODO:poor 474 | Mat centerMat(vec3 p, vec3 rd) 475 | { 476 | rotCenter(p, rd); 477 | // is this poor? 478 | const int num = 3; 479 | Mat[num] mats = Mat[num](Mat(), Mat(), Mat()); 480 | mats[0].mat = EMISSION; 481 | mats[0].metallic = 0.0; 482 | mats[0].color = vec3(1.0, 0.1, 0.1); 483 | 484 | mats[1].mat = EMISSION; 485 | mats[1].metallic = 0.0; 486 | mats[1].color = vec3(1.0); 487 | 488 | mats[2].mat = STANDARD; 489 | mats[2].metallic = 1.0; 490 | mats[2].roughness = 0.0; 491 | mats[2].color = vec3(1.0); 492 | 493 | // rot 494 | vec4 but = beatButton(); 495 | int bcount = int(but.w + 0.5); 496 | float blt = pow(1.0 / (1.0 + but.y), 10.0); 497 | 498 | vec4 seed4 = vec4(GRes.subdiv.cell * 42.0, but.w); 499 | vec4 hash4 = hash44(seed4); 500 | int id = int(hash4.x * float(num)) % num; 501 | Mat mat = mats[id]; 502 | 503 | mat.color = (hash11(but.w) < 0.8 ? vec3(mat.color.r) : vec3(mat.color.r, 0.1, 0.1)); 504 | 505 | vec2 uv; 506 | int uvi = 0; 507 | float amp = 1.0; 508 | vec3 cell = GRes.subdiv.cell; 509 | vec3 size = GRes.subdiv.size; 510 | vec3 pc = clamp((p - cell) / size, -1.0, 1.0); 511 | const ivec3 order = ivec3(0, 2, 1); 512 | for(int i = 0; i < 3; i++) 513 | { 514 | int oi = order[i]; 515 | float ni = GRes.normal[oi]; 516 | if(abs(ni) < 0.5) 517 | { 518 | uv[uvi++] = pc[oi]; 519 | } 520 | else 521 | { 522 | amp = sign(ni); 523 | } 524 | } 525 | 526 | uv = clamp(uv * 0.5 + 0.5, 0.0, 1.0); 527 | uv = (hash4.y < 0.5 ? uv : uv.yx); 528 | uv.x = fract(uv.x + blt * 0.5); 529 | 530 | SetAspect(vec2(1), 1.5, true, false); 531 | SetAlign(Align_Center_Center); 532 | SetFontStyle(STYLE_BOLD); 533 | Stack_Char((hash11(but.w * 4.2 + .42) < 0.1) ? 223 : getRandomKanji(hash4.xy * 42.0)); 534 | // Stack_Char(getRandomChar(hash4.xy * 42.0)); 535 | // Stack_Char(223); 536 | float ch = Render_Char(uv); 537 | ch = (hash4.z < 0.5) ? 1.0 - ch : ch; 538 | ch = (hash4.w < 0.3) ? ch * float(fract((uv.x + uv.y + GlobalTime * 0.1 + blt) * 8.0) < 0.5) : ch; 539 | 540 | bool isemi = (mats[id].mat == EMISSION) && (ch > 0.1); 541 | mat.mat = (isemi ? EMISSION : STANDARD); 542 | mat.nmap = hash4.xyz * ch; 543 | return mat; 544 | } 545 | 546 | Mat pillarMat(vec3 p) 547 | { 548 | Mat res = Mat(); 549 | res.mat = STANDARD; 550 | res.color = vec3(1.0); 551 | res.metallic = 0.9; 552 | res.roughness = 0.5; 553 | return res; 554 | } 555 | 556 | Mat daiMat(vec3 p) 557 | { 558 | Mat res = Mat(); 559 | res.mat = STANDARD; 560 | res.color = vec3(1.0); 561 | res.metallic = 0.5; 562 | res.roughness = 0.5; 563 | return res; 564 | } 565 | 566 | Mat sphereMat(vec3 p) 567 | { 568 | Mat res = Mat(); 569 | res.mat = STANDARD; 570 | res.color = vec3(1.0); 571 | res.metallic = 1.0; 572 | res.roughness = 0.5; 573 | return res; 574 | } 575 | 576 | Mat mat(vec3 p, vec3 rd) 577 | { 578 | #define ifMat(mat) if(MatID == mid++)return mat 579 | int mid = 0; 580 | 581 | ifMat(roomMat(p)); 582 | ifMat(screenMat(p)); 583 | if(ENABLE_CENTER) 584 | { 585 | ifMat(centerMat(p, rd)); 586 | } 587 | else 588 | { 589 | ifMat(lambdaMat(p)); 590 | } 591 | ifMat(pillarMat(p)); 592 | ifMat(daiMat(p)); 593 | ifMat(sphereMat(p)); 594 | 595 | return Mat(); 596 | } 597 | 598 | // Lights---------------------------------------------------------------------------- 599 | 600 | float Fd_Burley(float ndotv, float ndotl, float ldoth, float roughness) 601 | { 602 | float fd90 = 0.5 + 2.0 * ldoth * ldoth * roughness; 603 | float lightScatter = (1.0 + (fd90 - 1.0) * pow(1.0 - ndotl, 5.0)); 604 | float viewScatter = (1.0 + (fd90 - 1.0) * pow(1.0 - ndotv, 5.0)); 605 | float diffuse = lightScatter * viewScatter; 606 | return diffuse; 607 | } 608 | float V_SmithGGXCorrelated(float ndotl, float ndotv, float alpha) 609 | { 610 | float lambdaV = ndotl * (ndotv * (1.0 - alpha) + alpha); 611 | float lambdaL = ndotv * (ndotl * (1.0 - alpha) + alpha); 612 | return 0.5 / (lambdaV + lambdaL + 0.0001); 613 | } 614 | float D_GGX(float perceptualRoughness, float ndoth, vec3 normal, vec3 halfDir) 615 | { 616 | vec3 ncrossh = cross(normal, halfDir); 617 | float a = ndoth * perceptualRoughness; 618 | float k = perceptualRoughness / (dot(ncrossh, ncrossh) + a * a); 619 | float d = k * k / PI; 620 | return min(d, 65504.0); 621 | } 622 | #define _DielectricF0 0.04 623 | vec3 F_Schlick(vec3 f0, float cos) 624 | { 625 | return f0 + (1.0 - f0) * pow(1.0 - cos, 5.0); 626 | } 627 | // vec3 BRDF(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor, vec3 indirectDiffuse, vec3 indirectSpecular) 628 | // { 629 | // vec3 halfDir = normalize(lightDir + viewDir); 630 | // float ndotv = abs(dot(normal, viewDir)); 631 | // float ndotl = max(0, dot(normal, lightDir)); 632 | // float ndoth = max(0, dot(normal, halfDir)); 633 | // float ldoth = max(0, dot(lightDir, halfDir)); 634 | // float reflectivity = mix(_DielectricF0, 1, metallic); 635 | // vec3 f0 = mix(_DielectricF0, albedo, metallic); 636 | // float diffuseTerm = Fd_Burley(ndotv, ndotl, ldoth, perceptualRoughness) * ndotl; 637 | // vec3 diffuse = albedo * (1 - reflectivity) * lightColor * diffuseTerm; // Indirect Diffuse 638 | // diffuse += albedo * (1 - reflectivity) * indirectDiffuse; 639 | 640 | // float alpha = perceptualRoughness * perceptualRoughness; 641 | // float V = V_SmithGGXCorrelated(ndotl, ndotv, alpha); 642 | // float D = D_GGX(perceptualRoughness, ndotv, normal, halfDir); 643 | // vec3 F = F_Schlick(f0, ldoth); 644 | // vec3 specular = V * D * F * ndotl * lightColor; 645 | // specular *= PI;// maybe not needed? 646 | // specular = max(0, specular); // Indirect Specular 647 | // float surfaceReduction = 1.0 / (alpha * alpha + 1.0); 648 | // float f90 = saturate((1 - perceptualRoughness) + reflectivity); 649 | // specular += surfaceReduction * indirectSpecular * mix(f0, f90, pow(1 - ndotv, 5)); 650 | // vec3 color = diffuse + specular; 651 | // return color; 652 | // } 653 | 654 | vec3 BDRF_Indirect(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 indirectDiffuse, vec3 indirectSpecular) 655 | { 656 | float ndotv = abs(dot(normal, viewDir)); 657 | float reflectivity = mix(_DielectricF0, 1.0, metallic); 658 | vec3 diffuse = albedo * (1.0 - reflectivity) * indirectDiffuse; 659 | 660 | float alpha = perceptualRoughness * perceptualRoughness; 661 | float surfaceReduction = 1.0 / (alpha * alpha + 1.0); 662 | vec3 f0 = mix(vec3(_DielectricF0), albedo, metallic); 663 | float f90 = saturate((1.0 - perceptualRoughness) + reflectivity); 664 | vec3 specular = surfaceReduction * indirectSpecular * mix(f0, vec3(f90), pow(1.0 - ndotv, 5.0)); 665 | 666 | vec3 color = diffuse + specular; 667 | return color; 668 | } 669 | 670 | vec3 BDRF_Direct(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor) 671 | { 672 | vec3 halfDir = normalize(lightDir + viewDir); 673 | float ndotv = abs(dot(normal, viewDir)); 674 | float ndotl = max(0.0, dot(normal, lightDir)); 675 | float ndoth = max(0.0, dot(normal, halfDir)); 676 | float ldoth = max(0.0, dot(lightDir, halfDir)); 677 | float reflectivity = mix(_DielectricF0, 1.0, metallic); 678 | vec3 f0 = mix(vec3(_DielectricF0), albedo, metallic); 679 | float diffuseTerm = Fd_Burley(ndotv, ndotl, ldoth, perceptualRoughness) * ndotl; 680 | vec3 diffuse = albedo * (1.0 - reflectivity) * lightColor * diffuseTerm; // Indirect Diffuse 681 | 682 | float alpha = perceptualRoughness * perceptualRoughness; 683 | float V = V_SmithGGXCorrelated(ndotl, ndotv, alpha); 684 | float D = D_GGX(perceptualRoughness, ndotv, normal, halfDir); 685 | vec3 F = F_Schlick(f0, ldoth); 686 | vec3 specular = V * D * F * ndotl * lightColor; 687 | specular *= PI;// maybe not needed? 688 | specular = max(vec3(0), specular); // Indirect Specular 689 | 690 | vec3 color = diffuse + specular; 691 | return color; 692 | } 693 | 694 | // for indirectDiffuse 695 | vec3 getAmbientColor() 696 | { 697 | return vec3(0.1); 698 | } 699 | 700 | #define LightCount 2 701 | // 0:screen 702 | // 1:center 703 | 704 | float lightSDF(vec3 p, vec3 rd, int id) 705 | { 706 | #define ifLightSDF(sdf) if(id == mid++)return sdf 707 | int mid = 0; 708 | 709 | ifLightSDF(screen(p)); 710 | if(ENABLE_CENTER) 711 | { 712 | ifLightSDF(center(p, rd)); 713 | } 714 | else 715 | { 716 | ifLightSDF(hoge(p)); 717 | } 718 | 719 | return LenMax; 720 | } 721 | 722 | // only for emission material 723 | vec3 lightCol(vec3 p, vec3 rd, int id) 724 | { 725 | #define ifLightColor(matFunc) if(id == mid++)return (tmpmat = matFunc).color*float(tmpmat.mat==EMISSION) 726 | Mat tmpmat = Mat(); 727 | int mid = 0; 728 | 729 | ifLightColor(screenMat(p)); 730 | if(ENABLE_CENTER) 731 | { 732 | ifLightColor(centerMat(p, rd)); 733 | } 734 | else 735 | { 736 | ifLightColor(lambdaMat(p)); 737 | } 738 | 739 | return vec3(0); 740 | } 741 | 742 | vec3 lightDirection(vec3 p, vec3 rd, int id) 743 | { 744 | const float h = NormalEPS; 745 | const vec2 k = vec2(1, -1); 746 | return -normalize(k.xyy * lightSDF(p + k.xyy * h, rd, id) + k.yyx * lightSDF(p + k.yyx * h, rd, id) + k.yxy * lightSDF(p + k.yxy * h, rd, id) + k.xxx * lightSDF(p + k.xxx * h, rd, id)); 747 | } 748 | 749 | float lightAttenuation(float dist) 750 | { 751 | const float lightRange = 5.0; 752 | dist = max(dist, 0.0); 753 | return pow(clamp(1.0 - (1.0 / lightRange) * dist, 0.0, 1.0), 2.0); 754 | } 755 | 756 | // do approximate light 757 | #define LightSample 8 758 | void calcLight(int id, vec3 rp, out vec3 lightRp, out vec3 lightDir, out vec3 lightColor) 759 | { 760 | const float maxdiff = 0.25; 761 | const float distFactor = 0.5; 762 | 763 | float attsum = 0.0; 764 | vec3 colsum = vec3(0); 765 | vec3 rd, ro; 766 | rd = vec3(0, 1, 0); 767 | ro = rp; 768 | // lightDir = lightDirection(rp, rd, id); 769 | 770 | for(int j = 0; j < LightSample; j++) 771 | { 772 | rd = lightDirection(rp, rd, id); 773 | float diff = clamp(1.0 - float(j) / float(LightSample), 0.0, 1.0) * maxdiff; 774 | // j,rd,id 775 | vec2 rnd = hash23(vec3(float(j) + GlobalTime, hash13(rp * 42.0) * 42.0, float(id) * 42.0)); 776 | rd = normalize(rd + diff * randomSphereDir(rnd)); 777 | float dist = lightSDF(rp, rd, id); 778 | vec3 col = lightCol(rp, rd, id); 779 | float att = lightAttenuation(dist); 780 | // weight 781 | colsum += col * att; 782 | attsum += att; 783 | rp += rd * dist * distFactor; 784 | } 785 | lightRp = rp; 786 | lightDir = normalize(lightRp - ro); 787 | lightColor = colsum / attsum; 788 | float len = length(lightRp - ro); 789 | lightColor *= lightAttenuation(len); 790 | } 791 | 792 | float calcAO(vec3 p, vec3 rd, vec3 n, float d) 793 | { 794 | return clamp(sdf(p + n * d, rd) / d, 0., 1.); 795 | } 796 | 797 | // Tracer---------------------------------------------------------------------------- 798 | 799 | Mat calcIntersect(vec3 rd, vec3 ro, out vec3 rp, out float dist, out float len) 800 | { 801 | len = 0.0; 802 | rp = ro; 803 | for(int i; i < LoopMax; i++) 804 | { 805 | dist = sdf(rp, rd); 806 | len += dist; 807 | rp = ro + rd * len; 808 | if(dist < DistMin) 809 | { 810 | return mat(rp, rd); 811 | } 812 | } 813 | // return mat(rp, rd); 814 | return MAT_SKY; 815 | } 816 | 817 | vec4 tracer(vec3 rd, vec3 ro) 818 | { 819 | // first raycast 820 | vec3 rp; 821 | float dist, len; 822 | Mat mat = calcIntersect(rd, ro, rp, dist, len); 823 | if(mat.mat == EMISSION) 824 | { 825 | return vec4(mat.color * 3.0, length(rp - ro)); 826 | } 827 | 828 | // shading 829 | vec3 normal = normalize(getNormal(rp, rd) + mat.nmap); 830 | vec3 nrp = rp + normal * DistMin * 10.0; 831 | // indirect light 832 | vec3 indirectDiffuse = getAmbientColor(); 833 | vec3 ro_s = nrp; 834 | vec3 rd_s = reflect(rd, normal); 835 | vec3 rp_s; 836 | float dist_s, len_s; 837 | Mat mat_s = calcIntersect(rd_s, ro_s, rp_s, dist_s, len_s); 838 | vec3 indirectSpecular = mat_s.color * float(mat_s.mat == EMISSION); 839 | // bdrf 840 | vec3 indirect = BDRF_Indirect(mat.color, mat.metallic, mat.roughness, normal, rd, indirectDiffuse, indirectSpecular); 841 | vec3 direct = vec3(0); 842 | int lcount = (ENABLE_CENTER ? LightCount : LightCount - 1); 843 | for(int i = 0; i < LightCount; i++) 844 | { 845 | // direct light 846 | vec3 lightRp, lightDir, lightColor; 847 | calcLight(i, nrp, lightRp, lightDir, lightColor); 848 | // direct += lightDir; 849 | direct += BDRF_Direct(mat.color, mat.metallic, mat.roughness, normal, rd, lightDir, lightColor); 850 | } 851 | vec3 color = indirect + direct * 1.5; 852 | // vec3 color = direct; 853 | // some post process 854 | float ao = calcAO(rp, rd, normal, 0.1); 855 | color *= ao; 856 | color = clamp(color, 0.0, 1.0); 857 | return vec4(color, length(rp - ro)); 858 | } 859 | 860 | // Root---------------------------------------------------------------------------- 861 | void setParameters(vec2 coord) 862 | { 863 | GlobalTime = time; 864 | #ifdef TAA 865 | GlobalTime += (hash12(hash23(vec3(GlobalTime, coord)))) * 0.005; 866 | #endif 867 | } 868 | 869 | void getUVandSeed(out vec2 uv, out vec2 suv, out float seed, inout vec2 fragCoord) 870 | { 871 | // CRT 872 | uv = fragCoord / iResolution.xy; 873 | vec2 taa = vec2(0); 874 | #ifdef TAA 875 | taa = hash23(vec3(GlobalTime, fragCoord)) - 0.5; 876 | #endif 877 | seed = hash12(taa * 42.0 - 0.42) * 42.0; 878 | suv = (2.0 * (fragCoord + taa) - iResolution.xy) / min(iResolution.x, iResolution.y); 879 | } 880 | 881 | void getRORD(out vec3 ro, out vec3 rd, out vec3 dir, vec2 suv) 882 | { 883 | // Parameter 884 | float fov; 885 | vec3 ta; 886 | float fisheye = 0.0; 887 | bool pars = true; 888 | float ortho = 2.5; 889 | 890 | vec3 trd, tro; 891 | float ttime = GlobalTime * 0.005; 892 | vec3 tseed = vec3(ttime, ttime + 42.42, -ttime + 42.42); 893 | float tins = domainWarping(tseed, trd, tro); 894 | tro = normalize(tro - 0.5); 895 | tro *= 0.25; 896 | float troins = 1.0; 897 | 898 | // sequence 899 | int sid = int(cameraButton().w + 0.5) % 4; 900 | if(sid == 0) 901 | { 902 | fov = 90.0; 903 | ro = vec3(0, 0, -3.0); 904 | ro.xz = rot2d(ro.xz, GlobalTime * 5.0); 905 | ta = vec3(0, 0, 0); 906 | } 907 | else if(sid == 1) 908 | { 909 | fov = 90.0; 910 | fisheye = 1.0; 911 | ro = vec3(-3.5, -1.5, -3.5 + 7.0 * fract(GlobalTime * 0.05)); 912 | ta = vec3(0, -0.5, 0); 913 | } 914 | else if(sid == 2) 915 | { 916 | pars = false; 917 | fov = 90.0; 918 | ro = vec3(0, -0.5, -2.75); 919 | ro.xz = rot2d(ro.xz, GlobalTime * 5.0); 920 | ta = vec3(0, 0, 0); 921 | } 922 | else 923 | { 924 | troins = 3.0; 925 | fov = 100.0; 926 | fisheye = 0.5; 927 | ro = vec3(0, 0, -3.0); 928 | ta = vec3(0, 0, 0); 929 | } 930 | 931 | // calc dir 932 | dir = normalize(ta - ro); 933 | 934 | // tebure 935 | ro = ro + tro * troins; 936 | 937 | // calc rd 938 | float cr = 0.0; 939 | vec3 cw = normalize(dir); 940 | vec3 cp = vec3(sin(cr), cos(cr), 0.0); 941 | vec3 cu = normalize(cross(cw, cp)); 942 | vec3 cv = normalize(cross(cu, cw)); 943 | float zf = 1.0 / tan(fov * PI / 360.0); 944 | zf -= zf * length(suv) * fisheye; 945 | if(pars) 946 | { 947 | rd = normalize(-cu * suv.x + cv * suv.y + cw * zf); 948 | } 949 | else 950 | { 951 | rd = dir; 952 | ro += suv.x * cu * ortho + suv.y * cv * ortho; 953 | } 954 | } 955 | 956 | void main() 957 | { 958 | if(is2D()) 959 | { 960 | outColor = vec4(0); 961 | return; 962 | } 963 | 964 | vec2 fragCoord = gl_FragCoord.xy; 965 | 966 | // Set some parameters 967 | setParameters(fragCoord); 968 | 969 | // Get UV and Seed 970 | float seed; 971 | vec2 uv, suv; 972 | getUVandSeed(uv, suv, seed, fragCoord); 973 | 974 | // Camera 975 | vec3 ro, rd, dir; 976 | getRORD(ro, rd, dir, suv); 977 | CP = ro; 978 | 979 | // Tracer 980 | vec4 col = tracer(rd, ro); 981 | 982 | #ifdef TAA 983 | const float bl = 0.5; 984 | col = texture(Tex3DScene, uv) * bl + col * bl; 985 | #endif 986 | 987 | // Output 988 | outColor = col; 989 | 990 | // Debug for some value printf 991 | #ifdef DEBUG 992 | float debugCh = 0.0; 993 | SetAspect(iResolution.xy, 24.0); 994 | SetAlign(Align_Left_Top); 995 | // OffSetAnchor(vec2(0,0)); 996 | // ro 997 | Stack_Char(C_R); 998 | Stack_Char(C_O); 999 | Stack_Char(C_comma); 1000 | Stack_Char(C_x); 1001 | Stack_Char(C_colon); 1002 | Stack_Sign(ro.x); 1003 | Stack_Number(ro.x); 1004 | debugCh += Render_Char(uv); 1005 | Print_Return(); 1006 | 1007 | // debugCh += Print_Char(uv, C_R); 1008 | // debugCh += Print_Char(uv, C_O); 1009 | // debugCh += Print_Char(uv, C_comma); 1010 | // debugCh += Print_Char(uv, C_x); 1011 | // debugCh += Print_Char(uv, C_colon); 1012 | // debugCh += Print_Sign(uv, ro.x); 1013 | // debugCh += Print_Number(uv, ro.x); 1014 | 1015 | Stack_Char(C_R); 1016 | Stack_Char(C_O); 1017 | Stack_Char(C_comma); 1018 | Stack_Char(C_y); 1019 | Stack_Char(C_colon); 1020 | Stack_Sign(ro.y); 1021 | Stack_Number(ro.y); 1022 | debugCh += Render_Char(uv); 1023 | Print_Return(); 1024 | Stack_Char(C_R); 1025 | Stack_Char(C_O); 1026 | Stack_Char(C_comma); 1027 | Stack_Char(C_z); 1028 | Stack_Char(C_colon); 1029 | Stack_Sign(ro.z); 1030 | Stack_Number(ro.z); 1031 | debugCh += Render_Char(uv); 1032 | Print_Return(); 1033 | // dir 1034 | Stack_Char(C_D); 1035 | Stack_Char(C_I); 1036 | Stack_Char(C_comma); 1037 | Stack_Char(C_x); 1038 | Stack_Char(C_colon); 1039 | Stack_Sign(dir.x); 1040 | Stack_Number(dir.x); 1041 | debugCh += Render_Char(uv); 1042 | Print_Return(); 1043 | Stack_Char(C_D); 1044 | Stack_Char(C_I); 1045 | Stack_Char(C_comma); 1046 | Stack_Char(C_y); 1047 | Stack_Char(C_colon); 1048 | Stack_Sign(dir.y); 1049 | Stack_Number(dir.y); 1050 | debugCh += Render_Char(uv); 1051 | Print_Return(); 1052 | Stack_Char(C_D); 1053 | Stack_Char(C_I); 1054 | Stack_Char(C_comma); 1055 | Stack_Char(C_z); 1056 | Stack_Char(C_colon); 1057 | Stack_Sign(dir.z); 1058 | Stack_Number(dir.z); 1059 | debugCh += Render_Char(uv); 1060 | Print_Return(); 1061 | 1062 | // SetAspect(iResolution.xy, 4.0); 1063 | // SetAlign(Align_Center_Center); 1064 | // Stack_Char(C_0); 1065 | // Stack_Char(C_g); 1066 | // debugCh += Render_Char(uv); 1067 | 1068 | debugCh = clamp(debugCh, 0.0, 1.0); 1069 | outColor.rgb += debugCh; 1070 | // outColor.rgb -= 10.0 * vec3(abs(uv.y - 0.5) < 0.001 || abs(uv.x - 0.5) < 0.001, 0, 0); 1071 | #endif 1072 | 1073 | // clamp 1074 | // outColor.rgb = clamp(outColor.rgb, 0.0, 1.0); 1075 | } -------------------------------------------------------------------------------- /Shader/3DScene_raw.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | // #define DEBUG 6 | // #define TAA 7 | // Dont touch---------------------------------------------------------------------------------- 8 | 9 | // Include---------------------------------------------------------------------------------- 10 | #pragma include "Shader/params.glsl" 11 | #pragma include "Shader/font.glsl" 12 | 13 | #define LoopMax 256 14 | #define DistMin 1e-3 15 | #define LenMax 1000.0 16 | #define NormalEPS 1e-3 17 | 18 | #define iTime time 19 | #define iResolution resolution 20 | 21 | // Global---------------------------------------------------------------------------------- 22 | float GlobalTime; 23 | int MatID; 24 | vec3 CP; 25 | 26 | struct Mat 27 | { 28 | int mat;// 0:Emission,1:Standard 29 | vec3 color; 30 | float roughness; 31 | float metallic; 32 | vec3 nmap;// just normalize(normal + nmap) 33 | }; 34 | #define EMISSION 0 35 | #define STANDARD 1 36 | #define Mat() Mat(EMISSION,vec3(0),0.0,0.0,vec3(0)) 37 | #define MAT_SKY Mat() 38 | 39 | struct SubdivResult 40 | { 41 | int depth; 42 | vec3 size; 43 | vec3 cell; 44 | vec3 hash; 45 | }; 46 | struct GridResult 47 | { 48 | SubdivResult subdiv; 49 | vec3 normal;// maybe not use 50 | float d; 51 | }; 52 | 53 | // last grid result 54 | GridResult GRes; 55 | 56 | uniform sampler2D Tex3DScene; 57 | uniform sampler2D Tex2DRes; 58 | 59 | // SDF------------------------------------------------------------------------------------- 60 | float sdBox(vec3 p, vec3 b) 61 | { 62 | vec3 q = abs(p) - b; 63 | return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0); 64 | } 65 | float sdBox(vec3 p, float s) 66 | { 67 | return sdBox(p, vec3(s)); 68 | } 69 | 70 | float sdSphere(vec3 p, float s) 71 | { 72 | return length(p) - s; 73 | } 74 | 75 | float sdPlane(vec3 p, vec3 n, float h) 76 | { 77 | return dot(p, n) + h; 78 | } 79 | 80 | float sdCapsule(vec3 p, vec3 a, vec3 b, float r) 81 | { 82 | vec3 pa = p - a, ba = b - a; 83 | float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); 84 | return length(pa - ba * h) - r; 85 | } 86 | 87 | // SDF Modifier---------------------------------------------------------------------------- 88 | 89 | mat2 rot(float a) 90 | { 91 | float c = cos(a), s = sin(a); 92 | return mat2(c, -s, s, c); 93 | } 94 | 95 | vec2 pmod(vec2 p, float n) 96 | { 97 | float a = mod(atan(p.y, p.x), TAU / n) - .5 * TAU / n; 98 | return length(p) * vec2(sin(a), cos(a)); 99 | } 100 | 101 | vec3 bfold(vec3 p) 102 | { 103 | if(p.x < p.y) 104 | p.xy = p.yx; 105 | if(p.x < p.z) 106 | p.xz = p.zx; 107 | if(p.y < p.z) 108 | p.yz = p.zy; 109 | return p; 110 | } 111 | 112 | void rotCenter(inout vec3 p, inout vec3 rd) 113 | { 114 | vec4 but = beatButton(); 115 | int bcount = int(but.w + 0.5); 116 | float blt = pow(1.0 / (1.0 + but.y), 10.0); 117 | vec2 rto = hash21(float(bcount) * 42.0) * 180.0; 118 | vec2 rfrom = hash21(float(bcount - 1) * 42.0) * 180.0; 119 | vec2 rot2 = mix(rfrom, rto, blt); 120 | p.xz = rot2d(p.xz, rot2.x); 121 | p.xy = rot2d(p.xy, rot2.y); 122 | rd.xz = rot2d(rd.xz, rot2.x); 123 | rd.xy = rot2d(rd.xy, rot2.y); 124 | } 125 | 126 | // LIVE CODING SPACE vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 127 | 128 | bool ENABLE_CENTER = true; 129 | // bool ENABLE_CENTER = (int(beatButton().w + 0.5) % 2 == 0); 130 | 131 | vec4 BTN = beatButton(); 132 | float BC = BTN.w; 133 | float BT = pow(1.0 / (1.0 + BTN.y), 5.0); 134 | int FID = 0; 135 | 136 | float origin(vec3 p) 137 | { 138 | vec3 _d; 139 | rotCenter(p, _d); 140 | return sdBox(p, 1.0 - DistMin); 141 | } 142 | 143 | float lambda(vec3 p) 144 | { 145 | return origin(p); 146 | } 147 | 148 | Mat lambdaMat(vec3 p) 149 | { 150 | Mat mat = Mat(); 151 | mat.mat = STANDARD; 152 | mat.color = vec3(1.0); 153 | mat.metallic = 0.5; 154 | return mat; 155 | } 156 | 157 | // LIVE CODING SPACE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 158 | 159 | SubdivResult subdivision(vec3 p) 160 | { 161 | SubdivResult result; 162 | vec3 bsize = vec3(0.5); 163 | float th = 0.5; 164 | float dh = hash13(hash31(beatButton().w) * 42.0); 165 | int depth = 1 + int(dh * 3.0); 166 | 167 | result.size = bsize; 168 | result.depth = 0; 169 | for(int i = 0; i < depth; i++) 170 | { 171 | result.cell = (floor(p / result.size) + 0.5) * result.size; 172 | result.hash = hash33(vec3(hash23(result.cell), beatButton().w) * 42.0); 173 | if(i == depth - 1 || result.hash.x < th) 174 | { 175 | break; 176 | } 177 | result.size *= 0.5; 178 | result.depth++; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | GridResult gridTraversal(vec3 rp, vec3 rd) 185 | { 186 | GridResult result; 187 | result.subdiv = subdivision(rp); 188 | vec3 src = -(rp - result.subdiv.cell) / rd; 189 | vec3 dst = abs(0.5 * result.subdiv.size / rd); 190 | vec3 bd = src + dst; 191 | vec3 bn = src - dst; 192 | result.d = min(min(bd.x, bd.y), bd.z); 193 | result.normal = -sign(rd) * step(bn.yzx, bn.xyz) * step(bn.zxy, bn.xyz); 194 | return result; 195 | } 196 | 197 | float gridSDF(vec3 p) 198 | { 199 | float d = LenMax; 200 | d = min(d, sdBox(p, vec3(1.0))); 201 | return d; 202 | } 203 | 204 | float gridBox(vec3 p, vec3 rd) 205 | { 206 | const float th = 0.5; 207 | vec3 bsize = vec3(0.5); 208 | GridResult result = gridTraversal(p, rd); 209 | GRes = result; 210 | // std sdf 211 | vec3 scale = 4.0 * bsize / result.subdiv.size; 212 | vec3 cp = (p - result.subdiv.cell) * scale; 213 | float sdfscale = 1.0 / max(scale.x, max(scale.y, scale.z)); 214 | float d = result.d; 215 | d = min(d, gridSDF(cp)); 216 | d *= sdfscale; 217 | // exist 218 | bool exist = result.subdiv.hash.y < th; 219 | d = exist ? d : result.d; 220 | d += DistMin * 1.0;// TODO:maybe 1.0 for just box 221 | return d; 222 | } 223 | 224 | float room(vec3 p) 225 | { 226 | return -sdBox(p, vec3(4.1, 2, 4.1)); 227 | } 228 | 229 | float screenID(vec3 p, int id) 230 | { 231 | p.xz = rot2d(p.xz, float(id) * 90.0); 232 | const float x = 3.5; 233 | const float y = x * 9.0 / 16.0; 234 | vec2 edge = vec2(x, y); 235 | 236 | float d0 = sdBox(p, vec3(x, y, 4.0)); 237 | float d1 = sdPlane(p, vec3(0, 0, -1), 4.0); 238 | return max(d0, d1); 239 | } 240 | 241 | float screen(vec3 p) 242 | { 243 | float d = LenMax; 244 | for(int i = 0; i < 4; i++) 245 | { 246 | d = min(d, screenID(p, i)); 247 | } 248 | return d; 249 | } 250 | 251 | #define ENABLE_ROTATE false 252 | float hoge(vec3 p) 253 | { 254 | vec3 _d; 255 | if(ENABLE_ROTATE) 256 | { 257 | rotCenter(p, _d); 258 | } 259 | return lambda(p); 260 | } 261 | 262 | float modifire(vec3 p, vec3 rp) 263 | { 264 | // if(ENABLE_ROTATE) 265 | // { 266 | // return hoge(rp); 267 | // } 268 | // else 269 | // { 270 | // return hoge(p); 271 | // } 272 | return hoge(p); 273 | } 274 | 275 | float center(vec3 p, vec3 rd) 276 | { 277 | float d = LenMax; 278 | vec3 np = p, nrd = rd; 279 | rotCenter(np, nrd); 280 | d = min(d, gridBox(np, nrd)); 281 | d = max(d, modifire(p, np)); 282 | return d; 283 | } 284 | 285 | float pillarR(vec3 p) 286 | { 287 | // round 288 | float size = 0.1; 289 | p.xz = abs(p.xz); 290 | p -= vec3(1.5, 0, 1.5); 291 | p.xz = rot2d(p.xz, (p.y - GlobalTime * 0.5) * 60.0); 292 | return sdBox(p, vec3(size, 3, size)); 293 | } 294 | 295 | // https://www.shadertoy.com/view/ttB3DV 296 | float profileSquare(vec2 p, vec2 dim) 297 | { 298 | vec2 d = abs(p) - dim; 299 | return length(max(d, vec2(0))) + min(max(d.x, d.y), 0.0); 300 | } 301 | vec3 closestPointOnCylinder(vec3 p, vec2 dim) 302 | { 303 | return vec3(normalize(p.xy) * dim.x, clamp(p.z, -dim.y / 2.0, dim.y / 2.0)); 304 | } 305 | float pillarT(vec3 p) 306 | { 307 | p = p.xzy; 308 | float radius = 2.0; 309 | float height = 4.0; 310 | float coils = PI; 311 | float freq = 1.0; 312 | vec3 pc = closestPointOnCylinder(p, vec2(radius, height)); 313 | float distToCyl = distance(p, pc); 314 | float distToCoil = asin(sin(p.z * coils + freq * atan(p.x, p.y) - GlobalTime * 0.5)) / coils; 315 | vec2 springCoords = vec2(distToCyl, distToCoil); 316 | float profile = profileSquare(springCoords, vec2(0.05)) - 0.02; 317 | return profile * (max(radius / 2.0 - abs(length(p.xy) - radius), 0.0) * 0.3 + 0.7); 318 | } 319 | 320 | float pillar(vec3 p) 321 | { 322 | return pillarR(p); 323 | } 324 | 325 | float dai(vec3 p) 326 | { 327 | float d = LenMax; 328 | float h = 0.25; 329 | p.y = abs(p.y); 330 | d = min(d, sdBox(p - vec3(0, 2.0 - 0.5 * h, 0), vec3(2.0, 0.5 * h, 2.0)) - 0.05); 331 | return d; 332 | } 333 | 334 | float sphere(vec3 p) 335 | { 336 | float d = LenMax; 337 | p.xz = abs(p.xz); 338 | d = sdSphere(p - vec3(2 - 0.15, -2 + 0.25 + 0.3, 2 - 0.15), 0.25); 339 | return d; 340 | } 341 | 342 | float sdf(vec3 p, vec3 rd) 343 | { 344 | #define opSDFMin(sdf) (id = ((dt = sdf) < d ? (d = dt, mid): id)), mid++ 345 | #define opSDFMax(sdf) (id = ((dt = sdf) > d ? (d = dt, mid): id)), mid++ 346 | int id = -1, mid = 0; 347 | 348 | float dt, d = LenMax; 349 | opSDFMin(room(p)); 350 | opSDFMin(screen(p)); 351 | if(ENABLE_CENTER) 352 | { 353 | opSDFMin(center(p, rd)); 354 | } 355 | else 356 | { 357 | opSDFMin(hoge(p)); 358 | } 359 | opSDFMin(pillar(p)); 360 | opSDFMin(dai(p)); 361 | opSDFMin(sphere(p)); 362 | 363 | MatID = id; 364 | return d; 365 | } 366 | 367 | vec3 getNormal(vec3 p, vec3 rd) 368 | { 369 | const float h = NormalEPS; 370 | const vec2 k = vec2(1, -1); 371 | return normalize(k.xyy * sdf(p + k.xyy * h, rd) + k.yyx * sdf(p + k.yyx * h, rd) + k.yxy * sdf(p + k.yxy * h, rd) + k.xxx * sdf(p + k.xxx * h, rd)); 372 | } 373 | 374 | // Material-------------------------------------------------------------------------------- 375 | 376 | /* 377 | struct Mat 378 | { 379 | int mat;// 0:Emission,1:Standard 380 | vec3 color; 381 | float roughness; 382 | float metallic; 383 | vec3 nmap;// just normalize(normal + nmap) 384 | }; 385 | */ 386 | Mat roomMat(vec3 p) 387 | { 388 | Mat res = Mat(); 389 | res.mat = STANDARD; 390 | res.metallic = 0.9; 391 | res.roughness = 0.5; 392 | float freq = 4.0; 393 | vec3 np = p * freq; 394 | float _time = GlobalTime * 0.5; 395 | vec2 rnd0 = vec2(snoise(np + vec3(0, -_time, 0)), snoise(vec3(np.yz + 42.0, _time))); 396 | res.nmap = randomSphereDir(rnd0) * 0.05; 397 | res.color = vec3(1); 398 | return res; 399 | } 400 | 401 | Mat screenMat(vec3 p) 402 | { 403 | Mat res = Mat(); 404 | res.mat = EMISSION; 405 | 406 | float a = atan(p.x, p.z) + PI + PI / 4.0; 407 | float len = length(p.xz); 408 | a = mod(a, PI * 0.5) + PI / 4.0; 409 | p.xz = len * vec2(cos(a), sin(a)); 410 | 411 | const float x = 3.5; 412 | const float y = x * 9.0 / 16.0; 413 | vec2 edge = vec2(x, y); 414 | 415 | vec2 uv = remapc(p.xy, -edge, edge, vec2(0), vec2(1)); 416 | uv.x = 1.0 - uv.x; 417 | res.color = texture(Tex2DRes, uv).rgb; 418 | return res; 419 | } 420 | 421 | // TODO:change material via GRes 422 | /* 423 | struct SubdivResult 424 | { 425 | int depth; 426 | vec3 size; 427 | vec3 cell; 428 | vec3 hash; 429 | }; 430 | struct GridResult 431 | { 432 | SubdivResult subdiv; 433 | vec3 normal;// maybe not use 434 | float d; 435 | }; 436 | */ 437 | 438 | // TODO:poor 439 | Mat centerMat(vec3 p, vec3 rd) 440 | { 441 | rotCenter(p, rd); 442 | // is this poor? 443 | const int num = 3; 444 | Mat[num] mats = Mat[num](Mat(), Mat(), Mat()); 445 | mats[0].mat = EMISSION; 446 | mats[0].metallic = 0.0; 447 | mats[0].color = vec3(1.0, 0.1, 0.1); 448 | 449 | mats[1].mat = EMISSION; 450 | mats[1].metallic = 0.0; 451 | mats[1].color = vec3(1.0); 452 | 453 | mats[2].mat = STANDARD; 454 | mats[2].metallic = 1.0; 455 | mats[2].roughness = 0.0; 456 | mats[2].color = vec3(1.0); 457 | 458 | // rot 459 | vec4 but = beatButton(); 460 | int bcount = int(but.w + 0.5); 461 | float blt = pow(1.0 / (1.0 + but.y), 10.0); 462 | 463 | vec4 seed4 = vec4(GRes.subdiv.cell * 42.0, but.w); 464 | vec4 hash4 = hash44(seed4); 465 | int id = int(hash4.x * float(num)) % num; 466 | Mat mat = mats[id]; 467 | 468 | mat.color = (hash11(but.w) < 0.8 ? vec3(mat.color.r) : vec3(mat.color.r, 0.1, 0.1)); 469 | 470 | vec2 uv; 471 | int uvi = 0; 472 | float amp = 1.0; 473 | vec3 cell = GRes.subdiv.cell; 474 | vec3 size = GRes.subdiv.size; 475 | vec3 pc = clamp((p - cell) / size, -1.0, 1.0); 476 | const ivec3 order = ivec3(0, 2, 1); 477 | for(int i = 0; i < 3; i++) 478 | { 479 | int oi = order[i]; 480 | float ni = GRes.normal[oi]; 481 | if(abs(ni) < 0.5) 482 | { 483 | uv[uvi++] = pc[oi]; 484 | } 485 | else 486 | { 487 | amp = sign(ni); 488 | } 489 | } 490 | 491 | uv = clamp(uv * 0.5 + 0.5, 0.0, 1.0); 492 | uv = (hash4.y < 0.5 ? uv : uv.yx); 493 | uv.x = fract(uv.x + blt * 0.5); 494 | 495 | SetAspect(vec2(1), 1.5, true, false); 496 | SetAlign(Align_Center_Center); 497 | SetFontStyle(STYLE_BOLD); 498 | Stack_Char((hash11(but.w * 4.2 + .42) < 0.1) ? 223 : getRandomKanji(hash4.xy * 42.0)); 499 | // Stack_Char(getRandomChar(hash4.xy * 42.0)); 500 | // Stack_Char(223); 501 | float ch = Render_Char(uv); 502 | ch = (hash4.z < 0.5) ? 1.0 - ch : ch; 503 | ch = (hash4.w < 0.3) ? ch * float(fract((uv.x + uv.y + GlobalTime * 0.1 + blt) * 8.0) < 0.5) : ch; 504 | 505 | bool isemi = (mats[id].mat == EMISSION) && (ch > 0.1); 506 | mat.mat = (isemi ? EMISSION : STANDARD); 507 | mat.nmap = hash4.xyz * ch; 508 | return mat; 509 | } 510 | 511 | Mat pillarMat(vec3 p) 512 | { 513 | Mat res = Mat(); 514 | res.mat = STANDARD; 515 | res.color = vec3(1.0); 516 | res.metallic = 0.9; 517 | res.roughness = 0.5; 518 | return res; 519 | } 520 | 521 | Mat daiMat(vec3 p) 522 | { 523 | Mat res = Mat(); 524 | res.mat = STANDARD; 525 | res.color = vec3(1.0); 526 | res.metallic = 0.5; 527 | res.roughness = 0.5; 528 | return res; 529 | } 530 | 531 | Mat sphereMat(vec3 p) 532 | { 533 | Mat res = Mat(); 534 | res.mat = STANDARD; 535 | res.color = vec3(1.0); 536 | res.metallic = 1.0; 537 | res.roughness = 0.5; 538 | return res; 539 | } 540 | 541 | Mat mat(vec3 p, vec3 rd) 542 | { 543 | #define ifMat(mat) if(MatID == mid++)return mat 544 | int mid = 0; 545 | 546 | ifMat(roomMat(p)); 547 | ifMat(screenMat(p)); 548 | if(ENABLE_CENTER) 549 | { 550 | ifMat(centerMat(p, rd)); 551 | } 552 | else 553 | { 554 | ifMat(lambdaMat(p)); 555 | } 556 | ifMat(pillarMat(p)); 557 | ifMat(daiMat(p)); 558 | ifMat(sphereMat(p)); 559 | 560 | return Mat(); 561 | } 562 | 563 | // Lights---------------------------------------------------------------------------- 564 | 565 | float Fd_Burley(float ndotv, float ndotl, float ldoth, float roughness) 566 | { 567 | float fd90 = 0.5 + 2.0 * ldoth * ldoth * roughness; 568 | float lightScatter = (1.0 + (fd90 - 1.0) * pow(1.0 - ndotl, 5.0)); 569 | float viewScatter = (1.0 + (fd90 - 1.0) * pow(1.0 - ndotv, 5.0)); 570 | float diffuse = lightScatter * viewScatter; 571 | return diffuse; 572 | } 573 | float V_SmithGGXCorrelated(float ndotl, float ndotv, float alpha) 574 | { 575 | float lambdaV = ndotl * (ndotv * (1.0 - alpha) + alpha); 576 | float lambdaL = ndotv * (ndotl * (1.0 - alpha) + alpha); 577 | return 0.5 / (lambdaV + lambdaL + 0.0001); 578 | } 579 | float D_GGX(float perceptualRoughness, float ndoth, vec3 normal, vec3 halfDir) 580 | { 581 | vec3 ncrossh = cross(normal, halfDir); 582 | float a = ndoth * perceptualRoughness; 583 | float k = perceptualRoughness / (dot(ncrossh, ncrossh) + a * a); 584 | float d = k * k / PI; 585 | return min(d, 65504.0); 586 | } 587 | #define _DielectricF0 0.04 588 | vec3 F_Schlick(vec3 f0, float cos) 589 | { 590 | return f0 + (1.0 - f0) * pow(1.0 - cos, 5.0); 591 | } 592 | // vec3 BRDF(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor, vec3 indirectDiffuse, vec3 indirectSpecular) 593 | // { 594 | // vec3 halfDir = normalize(lightDir + viewDir); 595 | // float ndotv = abs(dot(normal, viewDir)); 596 | // float ndotl = max(0, dot(normal, lightDir)); 597 | // float ndoth = max(0, dot(normal, halfDir)); 598 | // float ldoth = max(0, dot(lightDir, halfDir)); 599 | // float reflectivity = mix(_DielectricF0, 1, metallic); 600 | // vec3 f0 = mix(_DielectricF0, albedo, metallic); 601 | // float diffuseTerm = Fd_Burley(ndotv, ndotl, ldoth, perceptualRoughness) * ndotl; 602 | // vec3 diffuse = albedo * (1 - reflectivity) * lightColor * diffuseTerm; // Indirect Diffuse 603 | // diffuse += albedo * (1 - reflectivity) * indirectDiffuse; 604 | 605 | // float alpha = perceptualRoughness * perceptualRoughness; 606 | // float V = V_SmithGGXCorrelated(ndotl, ndotv, alpha); 607 | // float D = D_GGX(perceptualRoughness, ndotv, normal, halfDir); 608 | // vec3 F = F_Schlick(f0, ldoth); 609 | // vec3 specular = V * D * F * ndotl * lightColor; 610 | // specular *= PI;// maybe not needed? 611 | // specular = max(0, specular); // Indirect Specular 612 | // float surfaceReduction = 1.0 / (alpha * alpha + 1.0); 613 | // float f90 = saturate((1 - perceptualRoughness) + reflectivity); 614 | // specular += surfaceReduction * indirectSpecular * mix(f0, f90, pow(1 - ndotv, 5)); 615 | // vec3 color = diffuse + specular; 616 | // return color; 617 | // } 618 | 619 | vec3 BDRF_Indirect(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 indirectDiffuse, vec3 indirectSpecular) 620 | { 621 | float ndotv = abs(dot(normal, viewDir)); 622 | float reflectivity = mix(_DielectricF0, 1.0, metallic); 623 | vec3 diffuse = albedo * (1.0 - reflectivity) * indirectDiffuse; 624 | 625 | float alpha = perceptualRoughness * perceptualRoughness; 626 | float surfaceReduction = 1.0 / (alpha * alpha + 1.0); 627 | vec3 f0 = mix(vec3(_DielectricF0), albedo, metallic); 628 | float f90 = saturate((1.0 - perceptualRoughness) + reflectivity); 629 | vec3 specular = surfaceReduction * indirectSpecular * mix(f0, vec3(f90), pow(1.0 - ndotv, 5.0)); 630 | 631 | vec3 color = diffuse + specular; 632 | return color; 633 | } 634 | 635 | vec3 BDRF_Direct(vec3 albedo, float metallic, float perceptualRoughness, vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor) 636 | { 637 | vec3 halfDir = normalize(lightDir + viewDir); 638 | float ndotv = abs(dot(normal, viewDir)); 639 | float ndotl = max(0.0, dot(normal, lightDir)); 640 | float ndoth = max(0.0, dot(normal, halfDir)); 641 | float ldoth = max(0.0, dot(lightDir, halfDir)); 642 | float reflectivity = mix(_DielectricF0, 1.0, metallic); 643 | vec3 f0 = mix(vec3(_DielectricF0), albedo, metallic); 644 | float diffuseTerm = Fd_Burley(ndotv, ndotl, ldoth, perceptualRoughness) * ndotl; 645 | vec3 diffuse = albedo * (1.0 - reflectivity) * lightColor * diffuseTerm; // Indirect Diffuse 646 | 647 | float alpha = perceptualRoughness * perceptualRoughness; 648 | float V = V_SmithGGXCorrelated(ndotl, ndotv, alpha); 649 | float D = D_GGX(perceptualRoughness, ndotv, normal, halfDir); 650 | vec3 F = F_Schlick(f0, ldoth); 651 | vec3 specular = V * D * F * ndotl * lightColor; 652 | specular *= PI;// maybe not needed? 653 | specular = max(vec3(0), specular); // Indirect Specular 654 | 655 | vec3 color = diffuse + specular; 656 | return color; 657 | } 658 | 659 | // for indirectDiffuse 660 | vec3 getAmbientColor() 661 | { 662 | return vec3(0.1); 663 | } 664 | 665 | #define LightCount 2 666 | // 0:screen 667 | // 1:center 668 | 669 | float lightSDF(vec3 p, vec3 rd, int id) 670 | { 671 | #define ifLightSDF(sdf) if(id == mid++)return sdf 672 | int mid = 0; 673 | 674 | ifLightSDF(screen(p)); 675 | if(ENABLE_CENTER) 676 | { 677 | ifLightSDF(center(p, rd)); 678 | } 679 | else 680 | { 681 | ifLightSDF(hoge(p)); 682 | } 683 | 684 | return LenMax; 685 | } 686 | 687 | // only for emission material 688 | vec3 lightCol(vec3 p, vec3 rd, int id) 689 | { 690 | #define ifLightColor(matFunc) if(id == mid++)return (tmpmat = matFunc).color*float(tmpmat.mat==EMISSION) 691 | Mat tmpmat = Mat(); 692 | int mid = 0; 693 | 694 | ifLightColor(screenMat(p)); 695 | if(ENABLE_CENTER) 696 | { 697 | ifLightColor(centerMat(p, rd)); 698 | } 699 | else 700 | { 701 | ifLightColor(lambdaMat(p)); 702 | } 703 | 704 | return vec3(0); 705 | } 706 | 707 | vec3 lightDirection(vec3 p, vec3 rd, int id) 708 | { 709 | const float h = NormalEPS; 710 | const vec2 k = vec2(1, -1); 711 | return -normalize(k.xyy * lightSDF(p + k.xyy * h, rd, id) + k.yyx * lightSDF(p + k.yyx * h, rd, id) + k.yxy * lightSDF(p + k.yxy * h, rd, id) + k.xxx * lightSDF(p + k.xxx * h, rd, id)); 712 | } 713 | 714 | float lightAttenuation(float dist) 715 | { 716 | const float lightRange = 5.0; 717 | dist = max(dist, 0.0); 718 | return pow(clamp(1.0 - (1.0 / lightRange) * dist, 0.0, 1.0), 2.0); 719 | } 720 | 721 | // do approximate light 722 | #define LightSample 8 723 | void calcLight(int id, vec3 rp, out vec3 lightRp, out vec3 lightDir, out vec3 lightColor) 724 | { 725 | const float maxdiff = 0.25; 726 | const float distFactor = 0.5; 727 | 728 | float attsum = 0.0; 729 | vec3 colsum = vec3(0); 730 | vec3 rd, ro; 731 | rd = vec3(0, 1, 0); 732 | ro = rp; 733 | // lightDir = lightDirection(rp, rd, id); 734 | 735 | for(int j = 0; j < LightSample; j++) 736 | { 737 | rd = lightDirection(rp, rd, id); 738 | float diff = clamp(1.0 - float(j) / float(LightSample), 0.0, 1.0) * maxdiff; 739 | // j,rd,id 740 | vec2 rnd = hash23(vec3(float(j) + GlobalTime, hash13(rp * 42.0) * 42.0, float(id) * 42.0)); 741 | rd = normalize(rd + diff * randomSphereDir(rnd)); 742 | float dist = lightSDF(rp, rd, id); 743 | vec3 col = lightCol(rp, rd, id); 744 | float att = lightAttenuation(dist); 745 | // weight 746 | colsum += col * att; 747 | attsum += att; 748 | rp += rd * dist * distFactor; 749 | } 750 | lightRp = rp; 751 | lightDir = normalize(lightRp - ro); 752 | lightColor = colsum / attsum; 753 | float len = length(lightRp - ro); 754 | lightColor *= lightAttenuation(len); 755 | } 756 | 757 | float calcAO(vec3 p, vec3 rd, vec3 n, float d) 758 | { 759 | return clamp(sdf(p + n * d, rd) / d, 0., 1.); 760 | } 761 | 762 | // Tracer---------------------------------------------------------------------------- 763 | 764 | Mat calcIntersect(vec3 rd, vec3 ro, out vec3 rp, out float dist, out float len) 765 | { 766 | len = 0.0; 767 | rp = ro; 768 | for(int i; i < LoopMax; i++) 769 | { 770 | dist = sdf(rp, rd); 771 | len += dist; 772 | rp = ro + rd * len; 773 | if(dist < DistMin) 774 | { 775 | return mat(rp, rd); 776 | } 777 | } 778 | // return mat(rp, rd); 779 | return MAT_SKY; 780 | } 781 | 782 | vec4 tracer(vec3 rd, vec3 ro) 783 | { 784 | // first raycast 785 | vec3 rp; 786 | float dist, len; 787 | Mat mat = calcIntersect(rd, ro, rp, dist, len); 788 | if(mat.mat == EMISSION) 789 | { 790 | return vec4(mat.color * 3.0, length(rp - ro)); 791 | } 792 | 793 | // shading 794 | vec3 normal = normalize(getNormal(rp, rd) + mat.nmap); 795 | vec3 nrp = rp + normal * DistMin * 10.0; 796 | // indirect light 797 | vec3 indirectDiffuse = getAmbientColor(); 798 | vec3 ro_s = nrp; 799 | vec3 rd_s = reflect(rd, normal); 800 | vec3 rp_s; 801 | float dist_s, len_s; 802 | Mat mat_s = calcIntersect(rd_s, ro_s, rp_s, dist_s, len_s); 803 | vec3 indirectSpecular = mat_s.color * float(mat_s.mat == EMISSION); 804 | // bdrf 805 | vec3 indirect = BDRF_Indirect(mat.color, mat.metallic, mat.roughness, normal, rd, indirectDiffuse, indirectSpecular); 806 | vec3 direct = vec3(0); 807 | int lcount = (ENABLE_CENTER ? LightCount : LightCount - 1); 808 | for(int i = 0; i < LightCount; i++) 809 | { 810 | // direct light 811 | vec3 lightRp, lightDir, lightColor; 812 | calcLight(i, nrp, lightRp, lightDir, lightColor); 813 | // direct += lightDir; 814 | direct += BDRF_Direct(mat.color, mat.metallic, mat.roughness, normal, rd, lightDir, lightColor); 815 | } 816 | vec3 color = indirect + direct * 1.5; 817 | // vec3 color = direct; 818 | // some post process 819 | float ao = calcAO(rp, rd, normal, 0.1); 820 | color *= ao; 821 | color = clamp(color, 0.0, 1.0); 822 | return vec4(color, length(rp - ro)); 823 | } 824 | 825 | // Root---------------------------------------------------------------------------- 826 | void setParameters(vec2 coord) 827 | { 828 | GlobalTime = time; 829 | #ifdef TAA 830 | GlobalTime += (hash12(hash23(vec3(GlobalTime, coord)))) * 0.005; 831 | #endif 832 | } 833 | 834 | void getUVandSeed(out vec2 uv, out vec2 suv, out float seed, inout vec2 fragCoord) 835 | { 836 | // CRT 837 | uv = fragCoord / iResolution.xy; 838 | vec2 taa = vec2(0); 839 | #ifdef TAA 840 | taa = hash23(vec3(GlobalTime, fragCoord)) - 0.5; 841 | #endif 842 | seed = hash12(taa * 42.0 - 0.42) * 42.0; 843 | suv = (2.0 * (fragCoord + taa) - iResolution.xy) / min(iResolution.x, iResolution.y); 844 | } 845 | 846 | void getRORD(out vec3 ro, out vec3 rd, out vec3 dir, vec2 suv) 847 | { 848 | // Parameter 849 | float fov; 850 | vec3 ta; 851 | float fisheye = 0.0; 852 | bool pars = true; 853 | float ortho = 2.5; 854 | 855 | vec3 trd, tro; 856 | float ttime = GlobalTime * 0.005; 857 | vec3 tseed = vec3(ttime, ttime + 42.42, -ttime + 42.42); 858 | float tins = domainWarping(tseed, trd, tro); 859 | tro = normalize(tro - 0.5); 860 | tro *= 0.25; 861 | float troins = 1.0; 862 | 863 | // sequence 864 | int sid = int(cameraButton().w + 0.5) % 4; 865 | if(sid == 0) 866 | { 867 | fov = 90.0; 868 | ro = vec3(0, 0, -3.0); 869 | ro.xz = rot2d(ro.xz, GlobalTime * 5.0); 870 | ta = vec3(0, 0, 0); 871 | } 872 | else if(sid == 1) 873 | { 874 | fov = 90.0; 875 | fisheye = 1.0; 876 | ro = vec3(-3.5, -1.5, -3.5 + 7.0 * fract(GlobalTime * 0.05)); 877 | ta = vec3(0, -0.5, 0); 878 | } 879 | else if(sid == 2) 880 | { 881 | pars = false; 882 | fov = 90.0; 883 | ro = vec3(0, -0.5, -2.75); 884 | ro.xz = rot2d(ro.xz, GlobalTime * 5.0); 885 | ta = vec3(0, 0, 0); 886 | } 887 | else 888 | { 889 | troins = 3.0; 890 | fov = 100.0; 891 | fisheye = 0.5; 892 | ro = vec3(0, 0, -3.0); 893 | ta = vec3(0, 0, 0); 894 | } 895 | 896 | // calc dir 897 | dir = normalize(ta - ro); 898 | 899 | // tebure 900 | ro = ro + tro * troins; 901 | 902 | // calc rd 903 | float cr = 0.0; 904 | vec3 cw = normalize(dir); 905 | vec3 cp = vec3(sin(cr), cos(cr), 0.0); 906 | vec3 cu = normalize(cross(cw, cp)); 907 | vec3 cv = normalize(cross(cu, cw)); 908 | float zf = 1.0 / tan(fov * PI / 360.0); 909 | zf -= zf * length(suv) * fisheye; 910 | if(pars) 911 | { 912 | rd = normalize(-cu * suv.x + cv * suv.y + cw * zf); 913 | } 914 | else 915 | { 916 | rd = dir; 917 | ro += suv.x * cu * ortho + suv.y * cv * ortho; 918 | } 919 | } 920 | 921 | void main() 922 | { 923 | if(is2D()) 924 | { 925 | outColor = vec4(0); 926 | return; 927 | } 928 | 929 | vec2 fragCoord = gl_FragCoord.xy; 930 | 931 | // Set some parameters 932 | setParameters(fragCoord); 933 | 934 | // Get UV and Seed 935 | float seed; 936 | vec2 uv, suv; 937 | getUVandSeed(uv, suv, seed, fragCoord); 938 | 939 | // Camera 940 | vec3 ro, rd, dir; 941 | getRORD(ro, rd, dir, suv); 942 | CP = ro; 943 | 944 | // Tracer 945 | vec4 col = tracer(rd, ro); 946 | 947 | #ifdef TAA 948 | const float bl = 0.5; 949 | col = texture(Tex3DScene, uv) * bl + col * bl; 950 | #endif 951 | 952 | // Output 953 | outColor = col; 954 | 955 | // Debug for some value printf 956 | #ifdef DEBUG 957 | float debugCh = 0.0; 958 | SetAspect(iResolution.xy, 24.0); 959 | SetAlign(Align_Left_Top); 960 | // OffSetAnchor(vec2(0,0)); 961 | // ro 962 | Stack_Char(C_R); 963 | Stack_Char(C_O); 964 | Stack_Char(C_comma); 965 | Stack_Char(C_x); 966 | Stack_Char(C_colon); 967 | Stack_Sign(ro.x); 968 | Stack_Number(ro.x); 969 | debugCh += Render_Char(uv); 970 | Print_Return(); 971 | 972 | // debugCh += Print_Char(uv, C_R); 973 | // debugCh += Print_Char(uv, C_O); 974 | // debugCh += Print_Char(uv, C_comma); 975 | // debugCh += Print_Char(uv, C_x); 976 | // debugCh += Print_Char(uv, C_colon); 977 | // debugCh += Print_Sign(uv, ro.x); 978 | // debugCh += Print_Number(uv, ro.x); 979 | 980 | Stack_Char(C_R); 981 | Stack_Char(C_O); 982 | Stack_Char(C_comma); 983 | Stack_Char(C_y); 984 | Stack_Char(C_colon); 985 | Stack_Sign(ro.y); 986 | Stack_Number(ro.y); 987 | debugCh += Render_Char(uv); 988 | Print_Return(); 989 | Stack_Char(C_R); 990 | Stack_Char(C_O); 991 | Stack_Char(C_comma); 992 | Stack_Char(C_z); 993 | Stack_Char(C_colon); 994 | Stack_Sign(ro.z); 995 | Stack_Number(ro.z); 996 | debugCh += Render_Char(uv); 997 | Print_Return(); 998 | // dir 999 | Stack_Char(C_D); 1000 | Stack_Char(C_I); 1001 | Stack_Char(C_comma); 1002 | Stack_Char(C_x); 1003 | Stack_Char(C_colon); 1004 | Stack_Sign(dir.x); 1005 | Stack_Number(dir.x); 1006 | debugCh += Render_Char(uv); 1007 | Print_Return(); 1008 | Stack_Char(C_D); 1009 | Stack_Char(C_I); 1010 | Stack_Char(C_comma); 1011 | Stack_Char(C_y); 1012 | Stack_Char(C_colon); 1013 | Stack_Sign(dir.y); 1014 | Stack_Number(dir.y); 1015 | debugCh += Render_Char(uv); 1016 | Print_Return(); 1017 | Stack_Char(C_D); 1018 | Stack_Char(C_I); 1019 | Stack_Char(C_comma); 1020 | Stack_Char(C_z); 1021 | Stack_Char(C_colon); 1022 | Stack_Sign(dir.z); 1023 | Stack_Number(dir.z); 1024 | debugCh += Render_Char(uv); 1025 | Print_Return(); 1026 | 1027 | // SetAspect(iResolution.xy, 4.0); 1028 | // SetAlign(Align_Center_Center); 1029 | // Stack_Char(C_0); 1030 | // Stack_Char(C_g); 1031 | // debugCh += Render_Char(uv); 1032 | 1033 | debugCh = clamp(debugCh, 0.0, 1.0); 1034 | outColor.rgb += debugCh; 1035 | // outColor.rgb -= 10.0 * vec3(abs(uv.y - 0.5) < 0.001 || abs(uv.x - 0.5) < 0.001, 0, 0); 1036 | #endif 1037 | 1038 | // clamp 1039 | // outColor.rgb = clamp(outColor.rgb, 0.0, 1.0); 1040 | } -------------------------------------------------------------------------------- /Shader/Unite.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | #pragma include "Shader/common.glsl" 6 | #pragma include "Shader/params.glsl" 7 | 8 | uniform sampler2D TexUniteProcess; 9 | 10 | vec3 tex(vec2 uv, vec2 suv) 11 | { 12 | vec3 col; 13 | vec2 sh = suv * 0.0015 * sliders[0]; 14 | col.r = texture(TexUniteProcess, uv - sh).r; 15 | col.g = texture(TexUniteProcess, uv).g; 16 | col.b = texture(TexUniteProcess, uv + sh).b; 17 | return col; 18 | } 19 | 20 | void main() 21 | { 22 | vec2 uv = gl_FragCoord.xy / resolution.xy; 23 | vec2 suv = (gl_FragCoord.xy * 2.0 - resolution.xy) / resolution.y; 24 | vec3 col = tex(uv, suv), bcol = col; 25 | // https://www.shadertoy.com/view/ss3SD8 26 | col = pow(col, vec3(0.5)); 27 | col *= 1.0 - 0.4 * length(suv); 28 | col = vec3(smoothstep(0.1, 1.1, col.x), smoothstep(0.0, 1.0, col.y), smoothstep(-0.1, 0.9, col.z)); 29 | col = saturate(col); 30 | col = mix(bcol, col, sliders[0]); 31 | outColor = vec4(col, 1); 32 | } -------------------------------------------------------------------------------- /Shader/UniteProcess.frag: -------------------------------------------------------------------------------- 1 | #version 440 2 | 3 | out vec4 outColor; 4 | 5 | #pragma include "Shader/common.glsl" 6 | #pragma include "Shader/params.glsl" 7 | #pragma include "Shader/font.glsl" 8 | 9 | uniform sampler2D Tex2DRes; 10 | uniform sampler2D Tex3DRes; 11 | uniform sampler2D TexUniteProcess; 12 | 13 | float GlobalTime; 14 | float LocalTime; 15 | int ID; 16 | 17 | vec3 pass(vec2 uv) 18 | { 19 | return (is2D() ? texture(Tex2DRes, uv).rgb : texture(Tex3DRes, uv).rgb); 20 | } 21 | 22 | vec3 back(vec2 uv) 23 | { 24 | return texture(TexUniteProcess, uv).rgb; 25 | } 26 | 27 | // Life Game 28 | 29 | float lifegame(float center, float sum) 30 | { 31 | if(center > 0.5) 32 | { 33 | if(sum < 1.5 || sum > 3.5) 34 | { 35 | center = 0.0; 36 | } 37 | else 38 | { 39 | center = 1.0; 40 | } 41 | } 42 | else 43 | { 44 | if(abs(sum - 3.0) < 0.5) 45 | { 46 | center = 1.0; 47 | } 48 | else 49 | { 50 | center = 0.0; 51 | } 52 | } 53 | return center; 54 | } 55 | 56 | vec3 process1(vec2 uv) 57 | { 58 | #define UOWNSCALE(_uv) (floor(_uv/cellSize+0.5)*cellSize) 59 | // pre 60 | float ch = 0.0; 61 | SetAspect(resolution.xy, 3.0, true, false); 62 | SetAlign(Align_Center_Center); 63 | SetFontStyle(STYLE_BOLD); 64 | // SetFontStyle(STYLE_OUTLINE); 65 | Stack_Char(C_L); 66 | Stack_Char(C_I); 67 | Stack_Char(C_F); 68 | Stack_Char(C_E); 69 | ch += Render_Char(uv); 70 | if(LocalTime < TransitionTime) 71 | { 72 | return vec3(ch) + back(uv); 73 | } 74 | 75 | if(frame_count % 3 != 0) 76 | { 77 | return back(uv); 78 | } 79 | // main 80 | const vec2[8] offsets = vec2[8](vec2(-1.0, -1.0), vec2(0.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 0.0), vec2(1.0, 0.0), vec2(-1.0, 1.0), vec2(0.0, 1.0), vec2(1.0, 1.0)); 81 | 82 | vec2 cellSize = 4.0 / resolution.xy; 83 | vec3 sum = vec3(0); 84 | for(int i = 0; i < 8; i++) 85 | { 86 | vec2 offset = offsets[i]; 87 | vec2 pos = uv + offset * cellSize; 88 | // sum += texture(TexUniteProcess, pos).r > 0.001 ? 1.0 : 0.0; 89 | sum += texture(TexUniteProcess, UOWNSCALE(pos)).rgb; 90 | } 91 | // float center = texture(TexUniteProcess, uv).r > 0.001 ? 1.0 : 0.0; 92 | vec3 center = texture(TexUniteProcess, UOWNSCALE(uv)).rgb; 93 | vec3 col = vec3(0.0); 94 | col.r += lifegame(center.r, sum.r); 95 | col += lifegame(center.b, sum.b); 96 | col += (LocalTime < TransitionTime + 0.01 ? ch : 0.0); 97 | return col; 98 | } 99 | 100 | //https://www.shadertoy.com/view/ftlfD8 101 | //pixel XOR Sorting 4x by Kastorp 102 | //sorting network https://www.shadertoy.com/view/XsXGDX 103 | 104 | #define D 4 //if FPS<60, use D=2 105 | #define COMP(a,b) length(a.xyz)2 115 | SW(4, 5); 116 | SW(6, 7); 117 | SW(4, 6); 118 | SW(5, 7); 119 | SW(5, 6); 120 | SW(0, 4); 121 | SW(1, 5); 122 | SW(1, 4); 123 | SW(2, 6); 124 | SW(3, 7); 125 | SW(3, 6); 126 | SW(2, 4); 127 | SW(3, 5); 128 | SW(3, 4); 129 | #endif 130 | return v; 131 | } 132 | 133 | /* 134 | vec3 process2(vec2 uv,vec2 anc,vec2 size) 135 | { 136 | // pre 137 | float ch = 0.0; 138 | SetAspect(resolution.xy, 3.0, true, false); 139 | SetAlign(Align_Center_Center); 140 | SetFontStyle(STYLE_BOLD); 141 | // SetFontStyle(STYLE_OUTLINE); 142 | Stack_Char(C_P); 143 | Stack_Char(C_I); 144 | Stack_Char(C_X); 145 | Stack_Char(C_E); 146 | Stack_Char(C_L); 147 | ch += Render_Char(uv); 148 | if(LocalTime < TransitionTime) 149 | { 150 | return vec3(ch) + back(uv); 151 | } 152 | 153 | // main 154 | vec2 RR = resolution.xy; 155 | vec2 U = gl_FragCoord.xy; 156 | vec3 O = vec3(0); 157 | int iFrame = frame_count; 158 | 159 | // if(iFrame < 20 || texelFetch(TexUniteProcess, ivec2(RR - 1.), 0) == vec4(0.)) 160 | // { 161 | // return texture(TexUniteProcess, U / RR).xyz; 162 | // } ?? 163 | 164 | float t = 1.; 165 | 166 | ivec2 R = ivec2(RR); 167 | int l = int(log2(RR.x * RR.y)) - 2, z = (iFrame / 2) % l, zz = 1 << z, ii = (int(U.x) + int(U.y) * R.x), i = ii / zz, s = ((i & D) / D == (iFrame & 1)) ? 0 : 1, m = s * D + (i & (D - 1)), h = min(i - (i & (D - 1)), i - (i & (D - 1)) - s * D); 168 | 169 | vec3[2 * D] P; 170 | for(int k = 0; k < 2 * D; k++) 171 | { 172 | int j = (h + k) * zz + (ii % zz); 173 | // P[k] = texelFetch(TexUniteProcess, ivec2(j % R.x, j / R.x), 0).xyz * t; 174 | P[k] = texelFetch(TexUniteProcess, ivec2(U.x, j / R.x), 0).xyz * t; 175 | } 176 | 177 | if(h >= 0 && (h + D) * zz < ((R.x * R.y) & ((1 << 24) - D * zz))) 178 | O = sort(P)[m]; 179 | else 180 | O = P[m]; 181 | 182 | return O; 183 | } 184 | */ 185 | 186 | vec3 process2(vec2 uv, vec2 anc, vec2 size) 187 | { 188 | // pre 189 | float ch = 0.0; 190 | SetAspect(resolution.xy, 3.0, true, false); 191 | SetAlign(Align_Center_Center); 192 | SetFontStyle(STYLE_BOLD); 193 | // SetFontStyle(STYLE_OUTLINE); 194 | Stack_Char(C_P); 195 | Stack_Char(C_I); 196 | Stack_Char(C_X); 197 | Stack_Char(C_E); 198 | Stack_Char(C_L); 199 | ch += Render_Char(uv); 200 | if(LocalTime < TransitionTime) 201 | { 202 | return vec3(ch) + back(uv); 203 | } 204 | 205 | // main 206 | vec2 RR = size * resolution.xy - 5.0; 207 | vec2 U = (uv - anc) * resolution.xy; 208 | vec3 O = vec3(0); 209 | ivec2 UD = ivec2(anc * resolution.xy + 0.5); 210 | int iFrame = frame_count; 211 | 212 | // if(iFrame < 20 || texelFetch(TexUniteProcess, ivec2(RR - 1.), 0) == vec4(0.)) 213 | // { 214 | // return texture(TexUniteProcess, U / RR).xyz; 215 | // } ?? 216 | 217 | float t = 1.; 218 | 219 | ivec2 R = ivec2(RR); 220 | int l = int(log2(RR.x * RR.y)) - 2, z = (iFrame / 2) % l, zz = 1 << z, ii = (int(U.x) + int(U.y) * R.x), i = ii / zz, s = ((i & D) / D == (iFrame & 1)) ? 0 : 1, m = s * D + (i & (D - 1)), h = min(i - (i & (D - 1)), i - (i & (D - 1)) - s * D); 221 | 222 | vec3[2 * D] P; 223 | for(int k = 0; k < 2 * D; k++) 224 | { 225 | int j = (h + k) * zz + (ii % zz); 226 | ivec2 iuv = ivec2(U.x, j / R.x) + UD; 227 | // P[k] = texelFetch(TexUniteProcess, ivec2(j % R.x, j / R.x), 0).xyz * t; 228 | P[k] = texelFetch(TexUniteProcess, iuv, 0).xyz * t; 229 | } 230 | 231 | if(h >= 0 && (h + D) * zz < ((R.x * R.y) & ((1 << 24) - D * zz))) 232 | O = sort(P)[m]; 233 | else 234 | O = P[m]; 235 | 236 | return O; 237 | } 238 | 239 | vec2 fold(vec2 p, vec2 v) 240 | { 241 | float g = dot(p, v); 242 | return (p - (g - abs(g)) * v) * vec2(sign(g), 1); 243 | } 244 | vec2 pmod(vec2 p, float n) 245 | { 246 | float a = mod(atan(p.y, p.x), TAU / n) - .5 * TAU / n; 247 | return length(p) * vec2(sin(a), cos(a)); 248 | } 249 | vec2 rot(vec2 p, float a) 250 | { 251 | return p * mat2(cos(a), sin(a), -sin(a), cos(a)); 252 | } 253 | 254 | vec2 uvfold(vec2 uv, vec3 seed, float ins) 255 | { 256 | vec2 ha = hash22(seed.xy); 257 | float a = (ha.x - 0.5) * PI * ins + PI * float(ha.y < 0.5); 258 | vec2 v = normalize(vec2(cos(a), sin(a))); 259 | vec2 off = (hash22(seed.yx) - 0.5) * ins; 260 | uv -= off; 261 | uv = fold(uv, v); 262 | uv += off; 263 | return uv; 264 | } 265 | 266 | vec2 uvshrink(vec2 uv, vec3 seed, float ins) 267 | { 268 | vec2 ha = hash22(seed.xy); 269 | float ex = mix(0.7, 1.5, ha.x); 270 | ex = mix(1.0, ex, ins); 271 | uv *= ex; 272 | return uv; 273 | } 274 | 275 | vec3 process3(vec2 uv) 276 | { 277 | // uv 278 | vec2 res = resolution.xy / resolution.y; 279 | vec2 nuv = (uv * 2.0 - 1.0) * res; 280 | int count = 8; 281 | vec4 but = beatButton(); 282 | vec2 buv = vec2(1); 283 | for(int i = 0; i < count; i++) 284 | { 285 | // float lt = LocalTime * 2.0 + float(i); 286 | // float li = floor(lt); 287 | // float lf = fract(lt); 288 | // lf = pow(smoothstep(0.0, 1.0, lf), 0.1); 289 | float lt = float(i + int(but.w + 0.5)); 290 | float li = floor(lt); 291 | float lf = 1.0 - pow(1.0 / (1.0 + but.y), 15.0); 292 | 293 | vec3 s3 = hash31(li) * 42.0; 294 | float ins = ((i == 0) ? 1.0 - lf : (i == count - 1) ? lf : 1.0); 295 | float th = hash13(s3.yzx); 296 | if(th < 0.7) 297 | { 298 | nuv = uvfold(nuv, s3, ins); 299 | } 300 | // else if(th < 0.75) 301 | else 302 | { 303 | nuv = uvshrink(nuv, s3, ins); 304 | buv = uvshrink(buv, s3, ins); 305 | } 306 | // else 307 | // { 308 | // nuv = nuv; 309 | // } 310 | // nuv = clamp(nuv, -res, res); 311 | } 312 | nuv = (nuv / res + 1.0) * 0.5; 313 | // nuv = buv.x > 1.5 ? fract(nuv) : nuv; 314 | nuv = (is2D() ? nuv : fract(nuv)); 315 | 316 | // pre 317 | float ch = 0.0; 318 | SetAspect(resolution.xy, 3.0, true, false); 319 | SetAlign(Align_Center_Center); 320 | SetFontStyle(STYLE_BOLD); 321 | Stack_Char(C_G); 322 | Stack_Char(C_L); 323 | Stack_Char(C_I); 324 | Stack_Char(C_T); 325 | Stack_Char(C_C); 326 | Stack_Char(C_H); 327 | ch += Render_Char(uv); 328 | if(LocalTime < TransitionTime) 329 | { 330 | return vec3(ch) + back(uv); 331 | } 332 | 333 | ch = 0.0; 334 | SetAspect(resolution.xy, 3.0, true, false); 335 | SetAlign(Align_Center_Center); 336 | SetFontStyle(STYLE_BOLD); 337 | Stack_Char(C_G); 338 | Stack_Char(C_L); 339 | Stack_Char(C_I); 340 | Stack_Char(C_T); 341 | Stack_Char(C_C); 342 | Stack_Char(C_H); 343 | ch += Render_Char(nuv); 344 | // main 345 | return vec3(ch) + pass(nuv); 346 | } 347 | 348 | vec3 spectrum_offset(float t) 349 | { 350 | float t0 = 3.0 * t - 1.5; 351 | return clamp(vec3(-t0, 1.0 - abs(t0), t0), 0.0, 1.0); 352 | } 353 | // RGB Shift 354 | vec3 process5(vec2 uv, vec3 s3) 355 | { 356 | vec3 seed = vec3(s3.xy + GlobalTime * 0.3, float(uv.y * 42.0 + s3.z)); 357 | float ofs = (snoise(seed)) * 0.006; 358 | vec2 ofs2 = (hash13(s3.zyx) < 0.5 ? vec2(ofs, 0.0) : vec2(0.0, ofs)); 359 | 360 | // https://www.shadertoy.com/view/lsfGD2 361 | const int NUM_SAMPLES = 10; 362 | const float RCP_NUM_SAMPLES_F = 1.0 / float(NUM_SAMPLES); 363 | vec3 sum = vec3(0.0); 364 | vec3 wsum = vec3(0.0); 365 | for(int i = 0; i < NUM_SAMPLES; ++i) 366 | { 367 | float t = float(i) * RCP_NUM_SAMPLES_F; 368 | uv = saturate(uv + ofs2 * t); 369 | vec3 samplecol = pass(uv); 370 | vec3 s = spectrum_offset(t); 371 | samplecol = samplecol * s; 372 | sum += samplecol; 373 | wsum += s; 374 | } 375 | sum /= wsum; 376 | 377 | return sum.rgb; 378 | } 379 | 380 | const float kernel[9] = float[9](-1., -1., -1., -1., 8., -1., -1., -1., -1.); 381 | // laplacian filter 382 | vec3 process6(vec2 uv, vec3 s3) 383 | { 384 | vec2 p = 1.0 / resolution.xy; 385 | vec3 edge = vec3(0); 386 | for(int i = 0; i < 9; i++) 387 | { 388 | vec2 d = vec2(i % 3, i / 3) - 1.0; 389 | edge += kernel[i] * pass(uv + d * p); 390 | } 391 | return edge; 392 | } 393 | 394 | uniform sampler2D TexF0; 395 | uniform sampler2D TexF1; 396 | uniform sampler2D TexF2; 397 | uniform sampler2D TexF3; 398 | uniform sampler2D TexF4; 399 | uniform sampler2D TexF5; 400 | 401 | vec3 face(vec2 uv, int id) 402 | { 403 | id %= 6; 404 | if(id == 0) 405 | { 406 | return texture(TexF0, uv).rgb; 407 | } 408 | else if(id == 1) 409 | { 410 | return texture(TexF1, uv).rgb; 411 | } 412 | else if(id == 2) 413 | { 414 | return texture(TexF2, uv).rgb; 415 | } 416 | else if(id == 3) 417 | { 418 | return texture(TexF3, uv).rgb; 419 | } 420 | else if(id == 4) 421 | { 422 | return texture(TexF4, uv).rgb; 423 | } 424 | else 425 | { 426 | return texture(TexF5, uv).rgb; 427 | } 428 | } 429 | 430 | vec3 process7(vec2 uv, vec2 anc, vec2 size, vec3 s3) 431 | { 432 | vec3 edge1 = process6(uv, s3); 433 | uv = (uv - anc) / size; 434 | int id = int(hash13(s3.yzx) * 6.0) % 6; 435 | vec2 p = 0.5 / size.x / resolution.xy; 436 | vec3 edge2 = (1.0 - face(uv, id)); 437 | edge2 += (1.0 - face(uv + vec2(p.x, 0.0), id)); 438 | edge2 += (1.0 - face(uv + vec2(-p.x, 0.0), id)); 439 | edge2 += (1.0 - face(uv + vec2(0.0, p.y), id)); 440 | edge2 += (1.0 - face(uv + vec2(0.0, -p.y), id)); 441 | edge2 *= 0.4; 442 | return edge2 + edge1 * 0.1; 443 | } 444 | 445 | float gaussian(float x) 446 | { 447 | const float sigma = 5.0; 448 | return exp(-(x * x) / (2.0 * sigma * sigma)); 449 | } 450 | vec3 process8(vec2 uv, vec3 s3) 451 | { 452 | vec3 col = vec3(0); 453 | vec2 p = 1.0 / resolution.xy; 454 | float total = 0.0; 455 | const int MAX_BLUR_SIZE = 3; 456 | float rangefactor = 1.0; 457 | for(int x = -MAX_BLUR_SIZE; x < MAX_BLUR_SIZE; x++) 458 | { 459 | for(int y = -MAX_BLUR_SIZE; y < MAX_BLUR_SIZE; y++) 460 | { 461 | vec2 offset = vec2(x, y); 462 | float weight = gaussian(length(offset)); 463 | offset *= rangefactor; 464 | col += pass(uv + offset * p) * weight; 465 | total += weight; 466 | } 467 | } 468 | return saturate(col / total); 469 | } 470 | 471 | vec3 process4(vec2 uv) 472 | { 473 | // pre 474 | float ch = 0.0; 475 | SetAspect(resolution.xy, 3.0, true, false); 476 | SetAlign(Align_Center_Center); 477 | SetFontStyle(STYLE_BOLD); 478 | // SetFontStyle(STYLE_OUTLINE); 479 | Stack_Char(C_W); 480 | Stack_Char(C_I); 481 | Stack_Char(C_N); 482 | Stack_Char(C_D); 483 | Stack_Char(C_O); 484 | Stack_Char(C_W); 485 | ch += Render_Char(uv); 486 | if(LocalTime < TransitionTime) 487 | { 488 | return vec3(ch) + back(uv); 489 | } 490 | 491 | vec4 but = beatButton(); 492 | bool iswin = false; 493 | int uvid = -1; 494 | vec3 uvs3; 495 | vec2 uvanc; 496 | vec2 uvsize; 497 | int idcount = 8; 498 | int maxcount = 16; 499 | float edge = 0.0; 500 | vec2 fres = resolution.xy / resolution.y; 501 | vec2 w = vec2(1e-3) / fres; 502 | for(int i = 0; i < maxcount; i++) 503 | { 504 | float lt = float(i + int(but.w + 0.5)); 505 | float li = floor(lt); 506 | float lf = 1.0 - pow(1.0 / (1.0 + but.y), 15.0); 507 | 508 | vec3 s3 = hash31(float(i + int(but.w + 0.5))) * 42.0; 509 | float ins = ((i == 0) ? 1.0 - lf : (i == maxcount - 1) ? lf : 1.0); 510 | 511 | float area = mix(0.05, 0.2, hash12(s3.xy)); 512 | float xraito = mix(0.3, 0.7, hash12(s3.yz)); 513 | float yraito = 1.0 - xraito; 514 | float xsize = sqrt(area * xraito / yraito); 515 | float ysize = area / xsize; 516 | vec2 size = vec2(xsize, ysize) * ins; 517 | int id = int(hash12(s3.zx) * float(idcount)) % idcount; 518 | if(id == 7) 519 | { 520 | float siz = (size.x + size.y) * 0.5; 521 | size = vec2(siz) / fres; 522 | } 523 | vec2 anc = hash22(s3.yx) * (1.0 - size); 524 | 525 | bool inuv = inUV(uv, anc, anc + size); 526 | if(inuv) 527 | { 528 | iswin = true; 529 | bool isedge = inuv && ((uv.x < anc.x + w.x || uv.x > anc.x + size.x - w.x) || (uv.y < anc.y + w.y || uv.y > anc.y + size.y - w.y)); 530 | uvid = id; 531 | edge = (isedge ? 1.0 : 0.0); 532 | uvs3 = s3; 533 | uvanc = anc; 534 | uvsize = size; 535 | } 536 | } 537 | 538 | vec3 col; 539 | if(uvid == 0) 540 | { 541 | // life 542 | col = process8(uv, uvs3); 543 | } 544 | if(uvid == 1) 545 | { 546 | // life 547 | col = process1(uv); 548 | } 549 | else if(uvid == 2) 550 | { 551 | // pixel 552 | col = process2(uv, uvanc, uvsize); 553 | } 554 | else if(uvid == 3) 555 | { 556 | // ifs 557 | col = process3(uv); 558 | } 559 | else if(4 <= uvid && uvid < 6) 560 | { 561 | if(iswin) 562 | { 563 | // inv 564 | uv.x = (hash12(uvs3.xz) < 0.5) ? (uvanc.x * 2.0 + uvsize.x - uv.x) : uv.x; 565 | uv.y = (hash12(uvs3.yz) < 0.5) ? (uvanc.y * 2.0 + uvsize.y - uv.y) : uv.y; 566 | } 567 | col = process5(uv, uvs3); 568 | } 569 | else if(uvid == 6) 570 | { 571 | if(iswin) 572 | { 573 | // inv 574 | uv.x = (hash12(uvs3.xz) < 0.5) ? (uvanc.x * 2.0 + uvsize.x - uv.x) : uv.x; 575 | uv.y = (hash12(uvs3.yz) < 0.5) ? (uvanc.y * 2.0 + uvsize.y - uv.y) : uv.y; 576 | } 577 | // kernel 578 | col = process6(uv, uvs3); 579 | } 580 | else if(uvid == 7) 581 | { 582 | // face 583 | col = process7(uv, uvanc, uvsize, uvs3); 584 | } 585 | else 586 | { 587 | // 0-1 588 | if(iswin) 589 | { 590 | // inv 591 | uv.x = (hash12(uvs3.xz) < 0.5) ? (uvanc.x * 2.0 + uvsize.x - uv.x) : uv.x; 592 | uv.y = (hash12(uvs3.yz) < 0.5) ? (uvanc.y * 2.0 + uvsize.y - uv.y) : uv.y; 593 | } 594 | 595 | col = pass(uv); 596 | } 597 | 598 | return col + edge; 599 | } 600 | 601 | vec3 process(vec2 uv, vec3 col) 602 | { 603 | if(ID == 1) 604 | { 605 | col = process3(uv); 606 | } 607 | else if(ID == 2) 608 | { 609 | col = process4(uv); 610 | } 611 | return col; 612 | } 613 | 614 | void main() 615 | { 616 | Master master = getMaster(); 617 | GlobalTime = master.GlobalTime; 618 | LocalTime = master.InfoUnite.LocalTime; 619 | ID = master.InfoUnite.ID; 620 | 621 | vec2 uv = gl_FragCoord.xy / resolution.xy; 622 | vec3 pcol = pass(uv); 623 | vec3 col = process(uv, pcol); 624 | col = saturate(col); 625 | 626 | // tlansition merge 627 | vec3 bcol = back(uv); 628 | // float mixa = remapc(LocalTime, 0.0, TransitionTime, 0.0, 1.0); 629 | float lt = remapc(LocalTime, 0.0, TransitionTime, 0.0, 1.0); 630 | lt = pow(lt, 3.0); 631 | float mixa = mix(0.1, 1.0, lt); 632 | col = mix(bcol, col, mixa); 633 | col = saturate(col); 634 | 635 | outColor = vec4(col, 1.0); 636 | } -------------------------------------------------------------------------------- /Shader/common.glsl: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_GLSL 2 | #define COMMON_GLSL 3 | 4 | #define PI 3.1415926535897932384626433832795 5 | #define TAU 6.283185307179586476925286766559 6 | 7 | #define remap(x,a,b,c,d) ((((x)-(a))/((b)-(a)))*((d)-(c))+(c)) 8 | #define remapc(x,a,b,c,d) clamp(remap(x,a,b,c,d),min(c,d),max(c,d)) 9 | 10 | #ifndef saturate 11 | #define saturate(x) clamp(x,0.0,1.0) 12 | #endif 13 | 14 | // Hash without Sine by David Hoskins. 15 | // https://www.shadertoy.com/view/4djSRW 16 | // 1 out, 1 in... 17 | float hash11(float p) 18 | { 19 | p = fract(p * .1031); 20 | p *= p + 33.33; 21 | p *= p + p; 22 | return fract(p); 23 | } 24 | // 1 out, 2 in... 25 | float hash12(vec2 p) 26 | { 27 | vec3 p3 = fract(vec3(p.xyx) * .1031); 28 | p3 += dot(p3, p3.yzx + 33.33); 29 | return fract((p3.x + p3.y) * p3.z); 30 | } 31 | // 1 out, 3 in... 32 | float hash13(vec3 p3) 33 | { 34 | p3 = fract(p3 * .1031); 35 | p3 += dot(p3, p3.zyx + 31.32); 36 | return fract((p3.x + p3.y) * p3.z); 37 | } 38 | // 1 out 4 in... 39 | float hash14(vec4 p4) 40 | { 41 | p4 = fract(p4 * vec4(.1031, .1030, .0973, .1099)); 42 | p4 += dot(p4, p4.wzxy + 33.33); 43 | return fract((p4.x + p4.y) * (p4.z + p4.w)); 44 | } 45 | // 2 out, 1 in... 46 | vec2 hash21(float p) 47 | { 48 | vec3 p3 = fract(vec3(p) * vec3(.1031, .1030, .0973)); 49 | p3 += dot(p3, p3.yzx + 33.33); 50 | return fract((p3.xx + p3.yz) * p3.zy); 51 | } 52 | /// 2 out, 2 in... 53 | vec2 hash22(vec2 p) 54 | { 55 | vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973)); 56 | p3 += dot(p3, p3.yzx + 33.33); 57 | return fract((p3.xx + p3.yz) * p3.zy); 58 | } 59 | /// 2 out, 3 in... 60 | vec2 hash23(vec3 p3) 61 | { 62 | p3 = fract(p3 * vec3(.1031, .1030, .0973)); 63 | p3 += dot(p3, p3.yzx + 33.33); 64 | return fract((p3.xx + p3.yz) * p3.zy); 65 | } 66 | // 3 out, 1 in... 67 | vec3 hash31(float p) 68 | { 69 | vec3 p3 = fract(vec3(p) * vec3(.1031, .1030, .0973)); 70 | p3 += dot(p3, p3.yzx + 33.33); 71 | return fract((p3.xxy + p3.yzz) * p3.zyx); 72 | } 73 | 74 | /// 3 out, 2 in... 75 | vec3 hash32(vec2 p) 76 | { 77 | vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973)); 78 | p3 += dot(p3, p3.yxz + 33.33); 79 | return fract((p3.xxy + p3.yzz) * p3.zyx); 80 | } 81 | /// 3 out, 3 in... 82 | vec3 hash33(vec3 p3) 83 | { 84 | p3 = fract(p3 * vec3(.1031, .1030, .0973)); 85 | p3 += dot(p3, p3.yxz + 33.33); 86 | return fract((p3.xxy + p3.yxx) * p3.zyx); 87 | 88 | } 89 | // 4 out, 1 in... 90 | vec4 hash41(float p) 91 | { 92 | vec4 p4 = fract(vec4(p) * vec4(.1031, .1030, .0973, .1099)); 93 | p4 += dot(p4, p4.wzxy + 33.33); 94 | return fract((p4.xxyz + p4.yzzw) * p4.zywx); 95 | 96 | } 97 | // 4 out, 2 in... 98 | vec4 hash42(vec2 p) 99 | { 100 | vec4 p4 = fract(vec4(p.xyxy) * vec4(.1031, .1030, .0973, .1099)); 101 | p4 += dot(p4, p4.wzxy + 33.33); 102 | return fract((p4.xxyz + p4.yzzw) * p4.zywx); 103 | 104 | } 105 | // 4 out, 3 in... 106 | vec4 hash43(vec3 p) 107 | { 108 | vec4 p4 = fract(vec4(p.xyzx) * vec4(.1031, .1030, .0973, .1099)); 109 | p4 += dot(p4, p4.wzxy + 33.33); 110 | return fract((p4.xxyz + p4.yzzw) * p4.zywx); 111 | } 112 | // 4 out, 4 in... 113 | vec4 hash44(vec4 p4) 114 | { 115 | p4 = fract(p4 * vec4(.1031, .1030, .0973, .1099)); 116 | p4 += dot(p4, p4.wzxy + 33.33); 117 | return fract((p4.xxyz + p4.yzzw) * p4.zywx); 118 | } 119 | 120 | // Simplex 3D Noise 121 | // by Ian McEwan, Ashima Arts 122 | // 123 | vec4 permute(vec4 x) 124 | { 125 | return mod(((x * 34.0) + 1.0) * x, 289.0); 126 | } 127 | vec4 taylorInvSqrt(vec4 r) 128 | { 129 | return 1.79284291400159 - 0.85373472095314 * r; 130 | } 131 | 132 | float snoise(vec3 v) 133 | { 134 | const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0); 135 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 136 | 137 | // First corner 138 | vec3 i = floor(v + dot(v, C.yyy)); 139 | vec3 x0 = v - i + dot(i, C.xxx); 140 | 141 | // Other corners 142 | vec3 g = step(x0.yzx, x0.xyz); 143 | vec3 l = 1.0 - g; 144 | vec3 i1 = min(g.xyz, l.zxy); 145 | vec3 i2 = max(g.xyz, l.zxy); 146 | 147 | // x0 = x0 - 0. + 0.0 * C 148 | vec3 x1 = x0 - i1 + 1.0 * C.xxx; 149 | vec3 x2 = x0 - i2 + 2.0 * C.xxx; 150 | vec3 x3 = x0 - 1. + 3.0 * C.xxx; 151 | 152 | // Permutations 153 | i = mod(i, 289.0); 154 | vec4 p = permute(permute(permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y + vec4(0.0, i1.y, i2.y, 1.0)) + i.x + vec4(0.0, i1.x, i2.x, 1.0)); 155 | 156 | // Gradients 157 | // ( N*N points uniformly over a square, mapped onto an octahedron.) 158 | float n_ = 1.0 / 7.0; // N=7 159 | vec3 ns = n_ * D.wyz - D.xzx; 160 | 161 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,N*N) 162 | 163 | vec4 x_ = floor(j * ns.z); 164 | vec4 y_ = floor(j - 7.0 * x_); // mod(j,N) 165 | 166 | vec4 x = x_ * ns.x + ns.yyyy; 167 | vec4 y = y_ * ns.x + ns.yyyy; 168 | vec4 h = 1.0 - abs(x) - abs(y); 169 | 170 | vec4 b0 = vec4(x.xy, y.xy); 171 | vec4 b1 = vec4(x.zw, y.zw); 172 | 173 | vec4 s0 = floor(b0) * 2.0 + 1.0; 174 | vec4 s1 = floor(b1) * 2.0 + 1.0; 175 | vec4 sh = -step(h, vec4(0.0)); 176 | 177 | vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy; 178 | vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww; 179 | 180 | vec3 p0 = vec3(a0.xy, h.x); 181 | vec3 p1 = vec3(a0.zw, h.y); 182 | vec3 p2 = vec3(a1.xy, h.z); 183 | vec3 p3 = vec3(a1.zw, h.w); 184 | 185 | //Normalise gradients 186 | vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); 187 | p0 *= norm.x; 188 | p1 *= norm.y; 189 | p2 *= norm.z; 190 | p3 *= norm.w; 191 | 192 | // Mix final noise value 193 | vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0); 194 | m = m * m; 195 | return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); 196 | } 197 | // hemisphere hash function based on a hash by Slerpy 198 | vec3 hashHs(vec3 n, vec3 seed) 199 | { 200 | vec2 h = hash23(seed); 201 | float a = h.x * 2. - 1.; 202 | float b = TAU * h.y * 2. - 1.; 203 | float c = sqrt(1. - a * a); 204 | vec3 r = vec3(c * cos(b), a, c * sin(b)); 205 | return r; 206 | } 207 | 208 | /** 209 | * hash function 210 | */ 211 | uvec3 pcg3d(uvec3 s) 212 | { 213 | s = s * 108137495u + 42985068u; 214 | s.x += s.y * s.z; 215 | s.y += s.z * s.x; 216 | s.z += s.x * s.y; 217 | s ^= s >> 16; 218 | s.x += s.y * s.z; 219 | s.y += s.z * s.x; 220 | s.z += s.x * s.y; 221 | return s; 222 | } 223 | 224 | /** 225 | * pcg3d but float 226 | */ 227 | vec3 pcg3df(vec3 s) 228 | { 229 | uvec3 r = pcg3d(floatBitsToUint(s)); 230 | return vec3(r) / float(0xffffffffu); 231 | } 232 | 233 | // https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 234 | #define NUM_OCTAVES 5 235 | float fbm(vec3 x) 236 | { 237 | float v = 0.0; 238 | float a = 0.5; 239 | vec3 shift = vec3(100); 240 | for(int i = 0; i < NUM_OCTAVES; ++i) 241 | { 242 | v += a * snoise(x); 243 | x = x * 2.0 + shift; 244 | a *= 0.5; 245 | } 246 | return v; 247 | } 248 | 249 | // https://iquilezles.org/articles/warp/ 250 | float domainWarping(vec3 p, out vec3 q, out vec3 r) 251 | { 252 | vec3 s0 = vec3(0.2, 4.2, 3.1) * 0.5; 253 | vec3 s1 = vec3(1.7, 9.2, 2.3) * 0.5; 254 | vec3 s2 = vec3(8.3, 2.8, 9.8) * 0.5; 255 | q = vec3(fbm(p + s0), fbm(p + s1), fbm(p + s2)); 256 | 257 | vec3 s3 = vec3(4.7, 1.5, 0.9) * 0.5; 258 | vec3 s4 = vec3(4.1, 2.9, 5.6) * 0.5; 259 | vec3 s5 = vec3(6.3, 7.9, 2.5) * 0.5; 260 | vec3 l = p + 4.0 * q; 261 | r = vec3(fbm(l + s3), fbm(l + s4), fbm(l + s5)); 262 | 263 | return fbm(p + 4.0 * r); 264 | } 265 | 266 | float deg2rad(float deg) 267 | { 268 | return deg * PI / 180.0; 269 | } 270 | 271 | float rad2deg(float rad) 272 | { 273 | return rad * 180.0 / PI; 274 | } 275 | 276 | vec2 rot2d(vec2 p, float a) 277 | { 278 | a *= PI / 180.0; 279 | float c = cos(a); 280 | float s = sin(a); 281 | return vec2(c * p.x - s * p.y, s * p.x + c * p.y); 282 | } 283 | 284 | vec3 randomSphereDir(vec2 rnd) 285 | { 286 | float s = rnd.x * PI * 2.; 287 | float t = rnd.y * 2. - 1.; 288 | return vec3(sin(s), cos(s), t) / sqrt(1.0 + t * t); 289 | } 290 | 291 | mat3 getOrthogonalBasis(vec3 z) 292 | { 293 | z = normalize(z); 294 | vec3 up = abs(z.y) < 0.99 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, 0.0, 1.0); 295 | vec3 x = normalize(cross(up, z)); 296 | return mat3(x, cross(z, x), z); 297 | } 298 | // 2.0 299 | vec3 cyclicNoise(vec3 p, float pump = 2.0) 300 | { 301 | vec4 sum = vec4(0.0); 302 | mat3 basis = getOrthogonalBasis(vec3(-1.0, 2.0, -3.0)); 303 | for(int i = 0; i < 10; i++) 304 | { 305 | p *= basis; 306 | p += sin(p.yzx); 307 | sum += vec4(cross(cos(p), sin(p.zxy)), 1.0); 308 | sum *= pump; 309 | p *= 2.0; 310 | } 311 | return sum.xyz / sum.w; 312 | } 313 | 314 | bool inUV(vec2 uv, vec2 uv_min, vec2 uv_max) 315 | { 316 | return all(greaterThanEqual(uv, uv_min)) && all(lessThanEqual(uv, uv_max)); 317 | } 318 | 319 | float vmin(vec2 v) 320 | { 321 | return min(v.x, v.y); 322 | } 323 | float vmin(vec3 v) 324 | { 325 | return min(v.x, min(v.y, v.z)); 326 | } 327 | float vmin(vec4 v) 328 | { 329 | return min(v.x, min(v.y, min(v.z, v.w))); 330 | } 331 | 332 | float vmax(vec2 v) 333 | { 334 | return max(v.x, v.y); 335 | } 336 | float vmax(vec3 v) 337 | { 338 | return max(v.x, max(v.y, v.z)); 339 | } 340 | float vmax(vec4 v) 341 | { 342 | return max(v.x, max(v.y, max(v.z, v.w))); 343 | } 344 | #endif -------------------------------------------------------------------------------- /Shader/font.glsl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef FONT_GLSL 3 | #define FONT_GLSL 4 | 5 | #include "Shader/common.glsl" 6 | // Chars Area ------------------------------------------------------------------------------ 7 | 8 | #define C_0 16 9 | #define C_1 17 10 | #define C_2 18 11 | #define C_3 19 12 | #define C_4 20 13 | #define C_5 21 14 | #define C_6 22 15 | #define C_7 23 16 | #define C_8 24 17 | #define C_9 25 18 | 19 | #define C_a 65 20 | #define C_b 66 21 | #define C_c 67 22 | #define C_d 68 23 | #define C_e 69 24 | #define C_f 70 25 | #define C_g 71 26 | #define C_h 72 27 | #define C_i 73 28 | #define C_j 74 29 | #define C_k 75 30 | #define C_l 76 31 | #define C_m 77 32 | #define C_n 78 33 | #define C_o 79 34 | #define C_p 80 35 | #define C_q 81 36 | #define C_r 82 37 | #define C_s 83 38 | #define C_t 84 39 | #define C_u 85 40 | #define C_v 86 41 | #define C_w 87 42 | #define C_x 88 43 | #define C_y 89 44 | #define C_z 90 45 | 46 | #define C_A 33 47 | #define C_B 34 48 | #define C_C 35 49 | #define C_D 36 50 | #define C_E 37 51 | #define C_F 38 52 | #define C_G 39 53 | #define C_H 40 54 | #define C_I 41 55 | #define C_J 42 56 | #define C_K 43 57 | #define C_L 44 58 | #define C_M 45 59 | #define C_N 46 60 | #define C_O 47 61 | #define C_P 48 62 | #define C_Q 49 63 | #define C_R 50 64 | #define C_S 51 65 | #define C_T 52 66 | #define C_U 53 67 | #define C_V 54 68 | #define C_W 55 69 | #define C_X 56 70 | #define C_Y 57 71 | #define C_Z 58 72 | 73 | #define C_space 0 74 | #define C_left 8 75 | #define C_right 9 76 | #define C_ast 10 77 | #define C_plus 11 78 | #define C_minus 13 79 | #define C_slash 15 80 | #define C_equal 29 81 | #define C_comma 14 82 | #define C_colon 26 83 | #define C_que 31 84 | 85 | // Chars Area ------------------------------------------------------------------------------ 86 | 87 | uniform sampler2D TexFont; 88 | #define TexFont_RES ivec2(68, 68) 89 | #define Font_Size ivec2(84, 84) 90 | #define Font_Baseline ivec2(-18, 24) 91 | #define Char_List_Max 72 92 | int Char_List_Index = 0; 93 | int[Char_List_Max] Char_List; 94 | 95 | #define SPACE_F 0.7 96 | #define SPACE_H 0.35 97 | float GetSpace(int c) 98 | { 99 | bool isH = (0 <= c && c <= 94) || (7073 <= c && c <= 7130); 100 | return (isH ? SPACE_H : SPACE_F) * float(c >= 0); 101 | } 102 | 103 | int Font_Style = 0; 104 | #define STYLE_NORMAL 0 105 | #define STYLE_BOLD 1 106 | #define STYLE_ITALIC 2 107 | #define STYLE_OUTLINE 3 108 | #define STYLE_THIN 4 109 | #define STYLE_OUTLINE_ITALIC 5 110 | void SetFontStyle(int style) 111 | { 112 | Font_Style = style; 113 | } 114 | 115 | vec2 Char_Size; 116 | vec2 UV_Offset = vec2(0); 117 | void SetAspect(vec2 resol, float div, bool fitWidth = true, bool fitBaseLine = true) 118 | { 119 | float width = resol.x; 120 | float height = resol.y; 121 | Char_Size = vec2(1.0 / div); 122 | if(!fitWidth) 123 | { 124 | Char_Size.y *= (width / height); 125 | } 126 | else 127 | { 128 | Char_Size.x *= (height / width); 129 | } 130 | // baseline offset 131 | vec2 base = Char_Size * vec2(Font_Baseline) / vec2(Font_Size); 132 | if(!fitBaseLine) 133 | { 134 | base.y = 0.0; 135 | } 136 | UV_Offset = vec2(-base.x, -base.y); 137 | } 138 | 139 | #define Align_Left_Bottom 0 140 | #define Align_Left_Center 1 141 | #define Align_Left_Top 2 142 | #define Align_Center_Bottom 3 143 | #define Align_Center_Center 4 144 | #define Align_Center_Top 5 145 | #define Align_Right_Bottom 6 146 | #define Align_Right_Center 7 147 | #define Align_Right_Top 8 148 | vec2 Origin_Font_Anchor; 149 | vec2 Font_Anchor; 150 | int Current_Align; 151 | 152 | void _SetAlignOffSetX(float offset) 153 | { 154 | vec2 anchor; 155 | if(Current_Align == Align_Left_Bottom) 156 | { 157 | anchor = vec2(0.0, 0.0) + vec2(0.0, 0.0) * Char_Size; 158 | } 159 | else if(Current_Align == Align_Left_Center) 160 | { 161 | anchor = vec2(0.0, 0.5) + vec2(0.0, -0.5) * Char_Size; 162 | } 163 | else if(Current_Align == Align_Left_Top) 164 | { 165 | anchor = vec2(0.0, 1.0) + vec2(0.0, -1.0) * Char_Size; 166 | } 167 | else if(Current_Align == Align_Center_Bottom) 168 | { 169 | anchor = vec2(0.5, 0.0) + vec2(-(offset) * 0.5, 0.0) * Char_Size; 170 | } 171 | else if(Current_Align == Align_Center_Center) 172 | { 173 | anchor = vec2(0.5, 0.5) + vec2(-(offset) * 0.5, -0.5) * Char_Size; 174 | } 175 | else if(Current_Align == Align_Center_Top) 176 | { 177 | anchor = vec2(0.5, 1.0) + vec2(-(offset) * 0.5, -1.0) * Char_Size; 178 | } 179 | else if(Current_Align == Align_Right_Bottom) 180 | { 181 | anchor = vec2(1.0, 0.0) + vec2(-offset, 0.0) * Char_Size; 182 | } 183 | else if(Current_Align == Align_Right_Center) 184 | { 185 | anchor = vec2(1.0, 0.5) + vec2(-offset, -0.5) * Char_Size; 186 | } 187 | else if(Current_Align == Align_Right_Top) 188 | { 189 | anchor = vec2(1.0, 1.0) + vec2(-offset, -1.0) * Char_Size; 190 | } 191 | else 192 | { 193 | anchor = vec2(0.0, 0.0); 194 | } 195 | Font_Anchor.x = anchor.x; 196 | } 197 | 198 | void SetAlign(int align, float size = 0.0, float space = SPACE_F) 199 | { 200 | float xoffset = size * space; 201 | if(align == Align_Left_Bottom) 202 | { 203 | Font_Anchor = vec2(0.0, 0.0) + vec2(0.0, 0.0) * Char_Size; 204 | } 205 | else if(align == Align_Left_Center) 206 | { 207 | Font_Anchor = vec2(0.0, 0.5) + vec2(0.0, -0.5) * Char_Size; 208 | } 209 | else if(align == Align_Left_Top) 210 | { 211 | Font_Anchor = vec2(0.0, 1.0) + vec2(0.0, -1.0) * Char_Size; 212 | } 213 | else if(align == Align_Center_Bottom) 214 | { 215 | Font_Anchor = vec2(0.5, 0.0) + vec2(-(xoffset) * 0.5, 0.0) * Char_Size; 216 | } 217 | else if(align == Align_Center_Center) 218 | { 219 | Font_Anchor = vec2(0.5, 0.5) + vec2(-(xoffset) * 0.5, -0.5) * Char_Size; 220 | } 221 | else if(align == Align_Center_Top) 222 | { 223 | Font_Anchor = vec2(0.5, 1.0) + vec2(-(xoffset) * 0.5, -1.0) * Char_Size; 224 | } 225 | else if(align == Align_Right_Bottom) 226 | { 227 | Font_Anchor = vec2(1.0, 0.0) + vec2(-xoffset, 0.0) * Char_Size; 228 | } 229 | else if(align == Align_Right_Center) 230 | { 231 | Font_Anchor = vec2(1.0, 0.5) + vec2(-xoffset, -0.5) * Char_Size; 232 | } 233 | else if(align == Align_Right_Top) 234 | { 235 | Font_Anchor = vec2(1.0, 1.0) + vec2(-xoffset, -1.0) * Char_Size; 236 | } 237 | else 238 | { 239 | Font_Anchor = vec2(0.0, 0.0); 240 | } 241 | Origin_Font_Anchor = Font_Anchor; 242 | Current_Align = align; 243 | } 244 | 245 | void OffSetAnchor(vec2 offset) 246 | { 247 | Font_Anchor += offset * Char_Size; 248 | } 249 | 250 | float _median(float r, float g, float b) 251 | { 252 | return max(min(r, g), min(max(r, g), b)); 253 | } 254 | float Print_Char(vec2 uv, int id) 255 | { 256 | if(id < 0) 257 | return 0.0; 258 | uv += UV_Offset; 259 | vec2 uv0 = Font_Anchor, uv1 = Font_Anchor + Char_Size; 260 | bool isIn = all(greaterThanEqual(uv, uv0)) && all(lessThan(uv, uv1)); 261 | vec2 uv2 = remap(uv, uv0, uv1, vec2(0), vec2(1)); 262 | vec2 uv3 = uv2 / vec2(TexFont_RES) + vec2(id % TexFont_RES.x, id / TexFont_RES.x) / vec2(TexFont_RES); 263 | vec4 col = isIn ? texture(TexFont, uv3) : vec4(0); 264 | // float dist = _median(col.r, col.g, col.b) - 0.5; 265 | float dist = _median(col.r, col.g, col.b); 266 | if(Font_Style == STYLE_BOLD || Font_Style == STYLE_OUTLINE || Font_Style == STYLE_OUTLINE_ITALIC) 267 | { 268 | dist -= 0.3; 269 | } 270 | else if(Font_Style == STYLE_ITALIC || Font_Style == STYLE_THIN) 271 | { 272 | dist -= 0.6; 273 | } 274 | else 275 | { 276 | dist -= 0.5; 277 | } 278 | float sig = fwidth(dist); 279 | float c = smoothstep(-sig, sig, dist) * col.a * float(id != 0); 280 | if(Font_Style == STYLE_OUTLINE || Font_Style == STYLE_OUTLINE_ITALIC) 281 | { 282 | dist -= 0.2; 283 | sig = fwidth(dist); 284 | c -= smoothstep(-sig, sig, dist) * col.a * float(id != 0); 285 | } 286 | // float c = clamp(dist + 0.5, 0.0, 1.0) * col.a; 287 | Font_Anchor.x += Char_Size.x * GetSpace(id); 288 | return c; 289 | } 290 | 291 | void Stack_Char(int id) 292 | { 293 | if(Char_List_Index < Char_List_Max) 294 | { 295 | Char_List[Char_List_Index] = id; 296 | Char_List_Index++; 297 | } 298 | } 299 | 300 | float Render_Char(vec2 uv) 301 | { 302 | if(Font_Style == STYLE_ITALIC || Font_Style == STYLE_OUTLINE_ITALIC) 303 | { 304 | uv.x -= ((uv.y - Font_Anchor.y) / Char_Size.y) * Char_Size.x * 0.4; 305 | } 306 | 307 | float xoffset = 0.0; 308 | for(int i = 0; i < Char_List_Index; i++) 309 | { 310 | xoffset += GetSpace(Char_List[i]); 311 | } 312 | _SetAlignOffSetX(xoffset); 313 | 314 | float c = 0.0; 315 | for(int i = 0; i < Char_List_Index; i++) 316 | { 317 | c += Print_Char(uv, Char_List[i]); 318 | } 319 | Char_List_Index = 0; 320 | return c; 321 | } 322 | 323 | int pow10(int y) 324 | { 325 | int r = 1; 326 | for(int i = 0; i < y; i++) 327 | { 328 | r *= 10; 329 | } 330 | return r; 331 | } 332 | 333 | int log10(int x) 334 | { 335 | int r = 0; 336 | while(x > 0) 337 | { 338 | x /= 10; 339 | r++; 340 | } 341 | return r; 342 | } 343 | 344 | float Print_Sign(vec2 uv, int value) 345 | { 346 | float c = (value < 0 ? Print_Char(uv, C_minus) : Print_Char(uv, C_space)); 347 | return c; 348 | } 349 | void Stack_Sign(int value) 350 | { 351 | int id = (value < 0 ? C_minus : C_space); 352 | Stack_Char(id); 353 | } 354 | 355 | float Print_Sign(vec2 uv, float value) 356 | { 357 | float c = (value < 0.0 ? Print_Char(uv, C_minus) : Print_Char(uv, C_space)); 358 | return c; 359 | } 360 | void Stack_Sign(float value) 361 | { 362 | int id = (value < 0.0 ? C_minus : C_space); 363 | Stack_Char(id); 364 | } 365 | 366 | float Print_Number(vec2 uv, int value, int digit = - 1) 367 | { 368 | float c = 0.0; 369 | value = abs(value); 370 | if(value == 0) 371 | return Print_Char(uv, C_0); 372 | digit = (digit < 0 ? log10(value) : digit); 373 | int p10 = pow10(digit - 1); 374 | for(int i = 0; i < digit; i++) 375 | { 376 | int v = value / p10; 377 | value -= v * p10; 378 | p10 /= 10; 379 | c += Print_Char(uv, v + C_0); 380 | } 381 | return c; 382 | } 383 | void Stack_Number(int value, int digit = - 1) 384 | { 385 | value = abs(value); 386 | if(value == 0) 387 | Stack_Char(C_0); 388 | digit = (digit < 0 ? log10(value) : digit); 389 | int p10 = pow10(digit - 1); 390 | for(int i = 0; i < digit; i++) 391 | { 392 | int v = value / p10; 393 | value -= v * p10; 394 | p10 /= 10; 395 | Stack_Char(v + C_0); 396 | } 397 | } 398 | 399 | float Print_Number(vec2 uv, float value, int fdigit = 3, int idigit = - 1) 400 | { 401 | float c = 0.0; 402 | value = abs(value); 403 | int v = int(value); 404 | c += Print_Number(uv, v, idigit); 405 | if(fdigit < 1) 406 | return c; 407 | c += Print_Char(uv, C_comma); 408 | value -= v; 409 | for(int i = 0; i < fdigit; i++) 410 | { 411 | value *= 10.0; 412 | v = int(value); 413 | value -= v; 414 | c += Print_Char(uv, v + C_0); 415 | } 416 | return c; 417 | } 418 | void Stack_Number(float value, int fdigit = 3, int idigit = - 1) 419 | { 420 | value = abs(value); 421 | int v = int(value); 422 | Stack_Number(v, idigit); 423 | if(fdigit < 1) 424 | return; 425 | Stack_Char(C_comma); 426 | value -= v; 427 | for(int i = 0; i < fdigit; i++) 428 | { 429 | value *= 10.0; 430 | v = int(value); 431 | value -= v; 432 | Stack_Char(v + C_0); 433 | } 434 | } 435 | 436 | void Print_Return(float space = 1.0) 437 | { 438 | Font_Anchor.x = Origin_Font_Anchor.x; 439 | Font_Anchor.y -= Char_Size.y * space; 440 | } 441 | 442 | int getRandomChar(vec2 seed) 443 | { 444 | // const int kanji_min = 650, kanji_max = 4399; 445 | const int kanji_min = 0, kanji_max = 4600; 446 | return int(float(kanji_max - kanji_min) * hash12(seed)) + kanji_min; 447 | } 448 | 449 | int getRandomKanji(vec2 seed) 450 | { 451 | const int kanji_min = 650, kanji_max = 4399; 452 | // const int kanji_min = 0, kanji_max = 4600; 453 | return int(float(kanji_max - kanji_min) * hash12(seed)) + kanji_min; 454 | } 455 | 456 | #endif -------------------------------------------------------------------------------- /Shader/params.glsl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef PARAMS_GLSL 3 | #define PARAMS_GLSL 4 | 5 | // ターゲットの解像度 6 | uniform vec4 resolution; // vec4(x, y, x/y, y/x) 7 | 8 | // ステージのインデックス 9 | // 同じシェーダーを複数回実行する場合に便利かもしれません 10 | uniform int pass_index; 11 | 12 | // プログラム起動時からの秒数 13 | uniform float time; 14 | 15 | // 前フレームからの経過時間 16 | uniform float time_delta; 17 | 18 | // beat == time * BPM / 60 19 | // BPMはコントロールパネルから設定できます。 20 | uniform float beat; 21 | 22 | // コントロールパネルにあるスライダーの値に対応します 23 | uniform float sliders[32]; 24 | 25 | // コントロールパネルにあるボタンに対応します 26 | // buttons[i] = vec4(intensity, since_last_on, since_last_off, count); 27 | // intensity: NoteOnのvelocityとPolyphonicKeyPressureの値が書き込まれます 28 | // since_last_on: 直近の NoteOn からの経過秒数 29 | // since_last_off: 直近の NoteOff からの経過秒数 30 | // count: NoteOnが何回発行されたかを数え上げる整数値 31 | uniform vec4 buttons[32]; 32 | 33 | // 32x32x32の乱数テキスチャ。 34 | // パイプラインが読み込まれるたびに再計算されるので 35 | //  コンパイルなどを走らせるとテキスチャの中身が変わります。 36 | uniform sampler3D noise; 37 | 38 | // プログラム開始からのフレーム数 39 | uniform int frame_count; 40 | 41 | // オーディオ入力デバイスからの生サンプル. 42 | // r には左チャンネル (モノラルの場合は唯一) の情報が入ります 43 | // g には右チャンネルの情報が入ります 44 | uniform sampler1D samples; 45 | 46 | // 生FFT情報 47 | // r/g は上記と同じく 48 | uniform sampler1D spectrum_raw; 49 | 50 | // "いい感じ"なFFT、EQをかけたり音階にゆるく対応しています。 51 | // r/g は上記の同じく 52 | uniform sampler1D spectrum; 53 | uniform sampler1D spectrum_smooth; 54 | uniform sampler1D spectrum_integrated; 55 | uniform sampler1D spectrum_smooth_integrated; 56 | 57 | // Bass/Mid/High 58 | uniform vec3 bass; 59 | uniform vec3 bass_smooth; 60 | uniform vec3 bass_integrated; 61 | uniform vec3 bass_smooth_integrated; 62 | 63 | uniform vec3 mid; 64 | uniform vec3 mid_smooth; 65 | uniform vec3 mid_integrated; 66 | uniform vec3 mid_smooth_integrated; 67 | 68 | uniform vec3 high; 69 | uniform vec3 high_smooth; 70 | uniform vec3 high_integrated; 71 | uniform vec3 high_smooth_integrated; 72 | 73 | // 現在の音量, 全サンプルのRMSで計算されてます 74 | // r には左右の平均値、モノラルの場合は音量が入ります 75 | // g には左チャンネルの音量が入ります 76 | // b には右チャンネルの音量が入ります 77 | uniform vec3 volume; 78 | uniform vec3 volume_integrated; 79 | 80 | #define god ((bass.r + 0.1) * (mid.r + 0.1) * (high.r + 0.1)) 81 | #define god_smooth ((bass_smooth.r + 0.1) * (mid_smooth.r + 0.1) * (high_smooth.r + 0.1)) 82 | #define god_integrated (bass_integrated.r + mid_integrated.r + high_integrated.r) 83 | #define god_smooth_integrated (bass_smooth_integrated.r + mid_smooth_integrated.r + high_smooth_integrated.r) 84 | 85 | struct Info 86 | { 87 | float LocalTime; 88 | int ID; 89 | }; 90 | 91 | struct Master 92 | { 93 | float GlobalTime; 94 | Info Info2D; 95 | Info Info3D; 96 | Info InfoUnite; 97 | }; 98 | 99 | /* 100 | 0~4: 2D 101 | 16~19: Unite 102 | 28 : Live 103 | 29 : camera 104 | 30 : Beat 105 | 31: 2D-3D switch 106 | */ 107 | 108 | Info getInfo(int sh, int count) 109 | { 110 | Info info; 111 | int id = 0; 112 | float mint = 1e9; 113 | for(int i = 0; i < count; i++) 114 | { 115 | int tid = i + sh; 116 | if(buttons[tid].y < mint) 117 | { 118 | mint = buttons[tid].y; 119 | id = i; 120 | } 121 | } 122 | info.LocalTime = mint; 123 | info.ID = id; 124 | return info; 125 | } 126 | 127 | Info getInfo2D() 128 | { 129 | return getInfo(0, 5); 130 | } 131 | 132 | Info getInfoUnite() 133 | { 134 | return getInfo(16, 4); 135 | } 136 | 137 | Info getInfo3D() 138 | { 139 | return getInfo(10, 1); 140 | } 141 | 142 | Master getMaster() 143 | { 144 | Master master; 145 | master.GlobalTime = time; 146 | master.Info2D = getInfo2D(); 147 | master.Info3D = getInfo3D(); 148 | master.InfoUnite = getInfoUnite(); 149 | return master; 150 | } 151 | 152 | bool is2D() 153 | { 154 | return (int(buttons[31].w + 0.5) % 2 != 0); 155 | } 156 | 157 | bool isLive() 158 | { 159 | return (int(buttons[28].w + 0.5) % 2 != 0); 160 | } 161 | 162 | vec4 beatButton() 163 | { 164 | return buttons[30]; 165 | } 166 | 167 | vec4 cameraButton() 168 | { 169 | return buttons[29]; 170 | } 171 | 172 | float parameter() 173 | { 174 | return sliders[0]; 175 | } 176 | 177 | #define TransitionTime 0.5 178 | 179 | #endif -------------------------------------------------------------------------------- /Src/Face/F0_Sen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Face/F0_Sen.png -------------------------------------------------------------------------------- /Src/Face/F1_Sen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Face/F1_Sen.png -------------------------------------------------------------------------------- /Src/Face/F2_1_Sen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Face/F2_1_Sen.png -------------------------------------------------------------------------------- /Src/Face/F3_Sen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Face/F3_Sen.png -------------------------------------------------------------------------------- /Src/Face/F4_3_Sen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Face/F4_3_Sen.png -------------------------------------------------------------------------------- /Src/Face/F5_Sen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Face/F5_Sen.png -------------------------------------------------------------------------------- /Src/Fonts/Myrica_msdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Forenard/VJ-at-lambda-2023-06-10/27d17f9d52f987797f90d2a022f4882ea65cc579/Src/Fonts/Myrica_msdf.png -------------------------------------------------------------------------------- /pipeline.yaml: -------------------------------------------------------------------------------- 1 | stages: 2 | - fs: "Shader/2DScene.frag" 3 | target: "Tex2DScene" 4 | wrap_mode: repeat 5 | float: true 6 | - fs: "Shader/2DRes.frag" 7 | target: "Tex2DRes" 8 | - fs: "Shader/3DScene.frag" 9 | target: "Tex3DScene" 10 | float: true 11 | mipmap: true 12 | - fs: "Shader/3DDOF.frag" 13 | target: "Tex3DDOF" 14 | float: true 15 | mipmap: true 16 | - fs: "Shader/3DBloom.frag" 17 | target: "Tex3DRes" 18 | wrap: clamp 19 | - fs: "Shader/UniteProcess.frag" 20 | target: "TexUniteProcess" 21 | float: true 22 | wrap: clamp 23 | filter: nearest 24 | - fs: "Shader/Unite.frag" 25 | 26 | images: 27 | - path: "Src/Fonts/Myrica_msdf.png" 28 | name: "TexFont" 29 | - path: "Src/Face/F0_Sen.png" 30 | name: "TexF0" 31 | - path: "Src/Face/F1_Sen.png" 32 | name: "TexF1" 33 | - path: "Src/Face/F2_1_Sen.png" 34 | name: "TexF2" 35 | - path: "Src/Face/F3_Sen.png" 36 | name: "TexF3" 37 | - path: "Src/Face/F4_3_Sen.png" 38 | name: "TexF4" 39 | - path: "Src/Face/F5_Sen.png" 40 | name: "TexF5" --------------------------------------------------------------------------------