1// Compatibility #ifdefs needed for parameters 2#ifdef GL_ES 3#define COMPAT_PRECISION mediump 4#else 5#define COMPAT_PRECISION 6#endif 7 8// Parameter lines go here: 9#pragma parameter RETRO_PIXEL_SIZE "Retro Pixel Size" 0.84 0.0 1.0 0.01 10#ifdef PARAMETER_UNIFORM 11// All parameter floats need to have COMPAT_PRECISION in front of them 12uniform COMPAT_PRECISION float RETRO_PIXEL_SIZE; 13#else 14#define RETRO_PIXEL_SIZE 0.84 15#endif 16 17#if defined(VERTEX) 18 19#if __VERSION__ >= 130 20#define COMPAT_VARYING out 21#define COMPAT_ATTRIBUTE in 22#define COMPAT_TEXTURE texture 23#else 24#define COMPAT_VARYING varying 25#define COMPAT_ATTRIBUTE attribute 26#define COMPAT_TEXTURE texture2D 27#endif 28 29#ifdef GL_ES 30#define COMPAT_PRECISION mediump 31#else 32#define COMPAT_PRECISION 33#endif 34 35COMPAT_ATTRIBUTE vec4 VertexCoord; 36COMPAT_ATTRIBUTE vec4 COLOR; 37COMPAT_ATTRIBUTE vec4 TexCoord; 38COMPAT_VARYING vec4 COL0; 39COMPAT_VARYING vec4 TEX0; 40// out variables go here as COMPAT_VARYING whatever 41 42vec4 _oPosition1; 43uniform mat4 MVPMatrix; 44uniform COMPAT_PRECISION int FrameDirection; 45uniform COMPAT_PRECISION int FrameCount; 46uniform COMPAT_PRECISION vec2 OutputSize; 47uniform COMPAT_PRECISION vec2 TextureSize; 48uniform COMPAT_PRECISION vec2 InputSize; 49 50// compatibility #defines 51#define vTexCoord TEX0.xy 52#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 53#define OutSize vec4(OutputSize, 1.0 / OutputSize) 54 55void main() 56{ 57 gl_Position = MVPMatrix * VertexCoord; 58 TEX0.xy = VertexCoord.xy; 59// Paste vertex contents here: 60} 61 62#elif defined(FRAGMENT) 63 64#if __VERSION__ >= 130 65#define COMPAT_VARYING in 66#define COMPAT_TEXTURE texture 67out vec4 FragColor; 68#else 69#define COMPAT_VARYING varying 70#define FragColor gl_FragColor 71#define COMPAT_TEXTURE texture2D 72#endif 73 74#ifdef GL_ES 75#ifdef GL_FRAGMENT_PRECISION_HIGH 76precision highp float; 77#else 78precision mediump float; 79#endif 80#define COMPAT_PRECISION mediump 81#else 82#define COMPAT_PRECISION 83#endif 84 85uniform COMPAT_PRECISION int FrameDirection; 86uniform COMPAT_PRECISION int FrameCount; 87uniform COMPAT_PRECISION vec2 OutputSize; 88uniform COMPAT_PRECISION vec2 TextureSize; 89uniform COMPAT_PRECISION vec2 InputSize; 90uniform sampler2D Texture; 91COMPAT_VARYING vec4 TEX0; 92// in variables go here as COMPAT_VARYING whatever 93 94// compatibility #defines 95#define Source Texture 96#define vTexCoord TEX0.xy 97 98#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 99#define OutSize vec4(OutputSize, 1.0 / OutputSize) 100 101// delete all 'params.' or 'registers.' or whatever in the fragment 102float iGlobalTime = float(FrameCount)*0.025; 103vec2 iResolution = OutputSize.xy; 104 105/////////////////////////////////////////////////////////////////////////////// 106// // 107// GGGG IIIII AAA N N TTTTT PPPP AAA CCCC M M AAA N N // 108// G I A A NN N T P P A A C MM MM A A NN N // 109// G GG I AAAAA N N N T PPPP AAAAA C --- M M M AAAAA N N N // 110// G G I A A N NN T P A A C M M A A N NN // 111// GGGG IIIII A A N N T P A A CCCC M M A A N N // 112// // 113/////////////////////////////////////////////////////////////////////////////// 114 115// Parameters 116#define VOXEL_RESOLUTION 1.5 117#define VOXEL_LIGHTING 118#define SHADOW 119#define GROUND 120#define GHOST 121//#define MOUSE 122#define HSV2RGB_FAST 123 124#define CAMERA_FOCAL_LENGTH 2.0 125#define DELTA 0.01 126#define RAY_LENGTH_MAX 500.0 127#define RAY_STEP_MAX 100.0 128#define AMBIENT 0.2 129#define SPECULAR_POWER 2.0 130#define SPECULAR_INTENSITY 0.3 131#define SHADOW_LENGTH 150.0 132#define SHADOW_POWER 3.0 133#define FADE_POWER 1.0 134#define BACKGROUND 0.7 135#define GLOW 0.4 136#define GAMMA 0.8 137 138// Math constants 139#define PI 3.14159265359 140#define SQRT3 1.73205080757 141 142// Global variable to handle the glow effect 143float glowCounter; 144 145// PRNG (from https://www.shadertoy.com/view/4djSRW) 146float rand (in vec3 seed) { 147 seed = fract (seed * vec3 (5.3983, 5.4427, 6.9371)); 148 seed += dot (seed.yzx, seed.xyz + vec3 (21.5351, 14.3137, 15.3219)); 149 return fract (seed.x * seed.y * seed.z * 95.4337); 150} 151 152// Distance to the voxel 153float distVoxel (in vec3 p) { 154 155 // Update the glow counter 156 ++glowCounter; 157 158 // Rounded box 159 const float voxelRadius = 0.25; 160 return length (max (abs (p) - 0.5 + voxelRadius, 0.0)) - voxelRadius; 161} 162 163// Distance to the scene and color of the closest point 164vec2 distScene (in vec3 p, out vec3 P) { 165 166 // Update the glow counter 167 ++glowCounter; 168 169 // Scaling 170 p *= VOXEL_RESOLUTION; 171 172 // Velocity, period of the waves, spacing of the gums 173 float v = VOXEL_RESOLUTION * floor (iGlobalTime * 100.0 / VOXEL_RESOLUTION); 174 const float k1 = 0.05; 175 const float k2 = 60.0; 176 177 // Giant Pac-Man 178 float body = length (p); 179 body = max (body - 32.0, 27.0 - body); 180 float eyes = 6.0 - length (vec3 (abs (p.x) - 12.5, p.y - 19.5, p.z - 20.0)); 181 float mouthAngle = PI * (0.07 + 0.07 * cos (2.0 * v * PI / k2)); 182 float mouthTop = dot (p, vec3 (0.0, -cos (mouthAngle), sin (mouthAngle))) - 2.0; 183 mouthAngle *= 2.5; 184 float mouthBottom = dot (p, vec3 (0.0, cos (mouthAngle), sin (mouthAngle))); 185 float pacMan = max (max (body, eyes), min (mouthTop, mouthBottom)); 186 vec2 d = vec2 (pacMan, 0.13); 187 P = p; 188 189 // Gums 190 vec3 q = vec3 (p.xy, mod (p.z + v, k2) - k2 * 0.5); 191 float gum = max (length (q) - 6.0, -p.z); 192 if (gum < d.x) { 193 d = vec2 (gum, 0.35); 194 P = q; 195 } 196 197 // Ground 198 #ifdef GROUND 199 q = vec3 (p.xy, p.z + v); 200 float ground = (q.y + 50.0 + 14.0 * cos (q.x * k1) * cos (q.z * k1)) * 0.7; 201 if (ground < d.x) { 202 d = vec2 (ground, 0.55); 203 P = q; 204 } 205 #endif 206 207 // Ghost 208 #ifdef GHOST 209 v = VOXEL_RESOLUTION * floor ((130.0 + 60.0 * cos (iGlobalTime * 3.0)) / VOXEL_RESOLUTION); 210 q = vec3 (p.xy, p.z + v); 211 body = length (vec3 (q.x, max (q.y - 4.0, 0.0), q.z)); 212 body = max (body - 28.0, 22.0 - body); 213 eyes = 8.0 - length (vec3 (abs (q.x) - 12.0, q.y - 10.0, q.z - 22.0)); 214 float bottom = (q.y + 28.0 + 4.0 * cos (p.x * 0.4) * cos (p.z * 0.4)) * 0.7; 215 float ghost = max (max (body, eyes), -bottom); 216 if (ghost < d.x) { 217 d = vec2 (ghost, 0.76); 218 P = q; 219 } 220 #endif 221 222 // Scaling 223 d.x /= VOXEL_RESOLUTION; 224 return d; 225} 226 227// Distance to the (voxelized?) scene 228vec4 dist (inout vec3 p, in vec3 ray, in float voxelized, in float rayLengthMax) { 229 vec3 P = p; 230 vec2 d = vec2 (0.0, 0.0); 231 float rayLength = 0.0; 232 float rayLengthInVoxel = 0.0; 233 float rayLengthCheckVoxel = 0.0; 234 vec3 raySign = sign (ray); 235 vec3 rayDeltaVoxel = raySign / ray; 236 for (float rayStep = 0.0; rayStep < RAY_STEP_MAX; ++rayStep) { 237 if (rayLength < rayLengthInVoxel) { 238 d.x = distVoxel (fract (p + 0.5) - 0.5); 239 if (d.x < DELTA) { 240 break; 241 } 242 } else if (rayLength < rayLengthCheckVoxel) { 243 vec3 rayDelta = (0.5 - raySign * (fract (p + 0.5) - 0.5)) * rayDeltaVoxel; 244 float dNext = min (rayDelta.x, min (rayDelta.y, rayDelta.z)); 245 d = distScene (floor (p + 0.5), P); 246 if (d.x < 0.0) { 247 rayDelta = rayDeltaVoxel - rayDelta; 248 d.x = max (rayLengthInVoxel - rayLength, DELTA - min (rayDelta.x, min (rayDelta.y, rayDelta.z))); 249 rayLengthInVoxel = rayLength + dNext; 250 } else { 251 d.x = DELTA + dNext; 252 } 253 } else { 254 d = distScene (p, P); 255 if (voxelized > 0.5) { 256 if (d.x < SQRT3 * 0.5) { 257 rayLengthCheckVoxel = rayLength + abs (d.x) + SQRT3 * 0.5; 258 d.x = max (rayLengthInVoxel - rayLength + DELTA, d.x - SQRT3 * 0.5); 259 } 260 } else if (d.x < DELTA) { 261 break; 262 } 263 } 264 rayLength += d.x; 265 if (rayLength > rayLengthMax) { 266 break; 267 } 268 p += d.x * ray; 269 } 270 return vec4 (d, rayLength, rand (P)); 271} 272 273// Normal at a given point 274vec3 normal (in vec3 p, in float voxelized) { 275 vec2 h = vec2 (DELTA, -DELTA); 276 vec3 n; 277 if (voxelized > 0.5) { 278 p = fract (p + 0.5) - 0.5; 279 n = h.xxx * distVoxel (p + h.xxx) + 280 h.xyy * distVoxel (p + h.xyy) + 281 h.yxy * distVoxel (p + h.yxy) + 282 h.yyx * distVoxel (p + h.yyx); 283 } else { 284 n = h.xxx * distScene (p + h.xxx, n).x + 285 h.xyy * distScene (p + h.xyy, n).x + 286 h.yxy * distScene (p + h.yxy, n).x + 287 h.yyx * distScene (p + h.yyx, n).x; 288 } 289 return normalize (n); 290} 291 292// HSV to RGB 293vec3 hsv2rgb (in vec3 hsv) { 294 #ifdef HSV2RGB_SAFE 295 hsv.yz = clamp (hsv.yz, 0.0, 1.0); 296 #endif 297 #ifdef HSV2RGB_FAST 298 return hsv.z * (1.0 + 0.5 * hsv.y * (cos (2.0 * PI * (hsv.x + vec3 (0.0, 2.0 / 3.0, 1.0 / 3.0))) - 1.0)); 299 #else 300 return hsv.z * (1.0 + hsv.y * clamp (abs (fract (hsv.x + vec3 (0.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 2.0, -1.0, 0.0)); 301 #endif 302} 303 304// Main function 305void mainImage (out vec4 fragColor, in vec2 fragCoord) { 306 307 // Get the fragment 308 vec2 frag = (2.0 * fragCoord.xy - iResolution.xy) / iResolution.y; 309 310 // Define the rendering mode 311 float modeTiming = iGlobalTime * 0.234; 312 float modeAngle = PI * cos (iGlobalTime * 0.2); 313 modeAngle = dot (frag - vec2 (cos (iGlobalTime * 2.0), 0.0), vec2 (cos (modeAngle), sin (modeAngle))); 314 float modeVoxel = step (0.5, fract (modeTiming / (4.0 * PI))); 315 modeTiming = cos (modeTiming); 316 float mode3D = smoothstep (0.8, 0.5, modeTiming); 317 float modeSwitch = smoothstep (0.995, 1.0, modeTiming) + smoothstep (0.02, 0.0, abs (modeAngle)) * (1.0 - modeVoxel); 318 modeVoxel += step (0.0, modeAngle) * (1.0 - modeVoxel); 319 320 // Define the ray corresponding to this fragment 321 vec3 ray = normalize (vec3 (frag, mix (8.0, CAMERA_FOCAL_LENGTH, mode3D))); 322 323 // Compute the orientation of the camera 324 float yawAngle = PI * (1.2 + 0.2 * cos (iGlobalTime * 0.5)); 325 float pitchAngle = PI * (0.1 * cos (iGlobalTime * 0.3) - 0.05); 326 #ifdef MOUSE 327 yawAngle += 4.0 * PI * iMouse.x / iResolution.x; 328 pitchAngle += PI * 0.3 * (1.0 - iMouse.y / iResolution.y); 329 #endif 330 yawAngle = mix (PI * 1.5, yawAngle, mode3D); 331 pitchAngle *= mode3D; 332 333 float cosYaw = cos (yawAngle); 334 float sinYaw = sin (yawAngle); 335 float cosPitch = cos (pitchAngle); 336 float sinPitch = sin (pitchAngle); 337 338 mat3 cameraOrientation; 339 cameraOrientation [0] = vec3 (cosYaw, 0.0, -sinYaw); 340 cameraOrientation [1] = vec3 (sinYaw * sinPitch, cosPitch, cosYaw * sinPitch); 341 cameraOrientation [2] = vec3 (sinYaw * cosPitch, -sinPitch, cosYaw * cosPitch); 342 343 ray = cameraOrientation * ray; 344 345 // Compute the origin of the ray 346 float cameraDist = mix (300.0, 95.0 + 50.0 * cos (iGlobalTime * 0.8), mode3D); 347 vec3 origin = (vec3 (0.0, 0.0, 40.0 * sin (iGlobalTime * 0.2)) - cameraOrientation [2] * cameraDist) / VOXEL_RESOLUTION; 348 349 // Compute the distance to the scene 350 glowCounter = 0.0; 351 vec4 d = dist (origin, ray, modeVoxel, RAY_LENGTH_MAX / VOXEL_RESOLUTION); 352 353 // Set the background color 354 vec3 finalColor = hsv2rgb (vec3 (0.2 * ray.y + 0.4 * modeVoxel - 0.37, 1.0, mode3D * BACKGROUND)); 355 vec3 glowColor = GLOW * vec3 (1.0, 0.3, 0.0) * glowCounter / RAY_STEP_MAX; 356 if (d.x < DELTA) { 357 358 // Set the object color 359 vec3 color = hsv2rgb (vec3 (d.y + 0.1 * d.w * modeVoxel, 0.5 + 0.5 * modeVoxel, 1.0)); 360 361 // Lighting 362 vec3 l = normalize (mix (vec3 (1.0, 0.0, 0.0), vec3 (1.25 + cos (iGlobalTime * 0.2), 1.0, 1.0), mode3D)); 363 #ifdef VOXEL_LIGHTING 364 if (modeVoxel > 0.5) { 365 vec3 n = normal (floor (origin + 0.5), 0.0); 366 float diffuse = max (0.0, dot (n, l)); 367 float specular = pow (max (0.0, dot (reflect (ray, n), l)), SPECULAR_POWER) * SPECULAR_INTENSITY; 368 color = (AMBIENT + diffuse) * color + specular; 369 } 370 #endif 371 vec3 n = normal (origin, modeVoxel); 372 float diffuse = dot (n, l); 373 float specular; 374 if (diffuse < 0.0) { 375 diffuse = 0.0; 376 specular = 0.0; 377 } else { 378 specular = pow (max (0.0, dot (reflect (ray, n), l)), SPECULAR_POWER) * SPECULAR_INTENSITY; 379 #ifdef SHADOW 380 origin += n * DELTA * 2.0; 381 vec4 shadow = dist (origin, l, modeVoxel, SHADOW_LENGTH / VOXEL_RESOLUTION); 382 if (shadow.x < DELTA) { 383 shadow.z = pow (min (1.0, shadow.z * VOXEL_RESOLUTION / SHADOW_LENGTH), SHADOW_POWER); 384 diffuse *= shadow.z; 385 specular *= shadow.z; 386 } 387 #endif 388 } 389 color = (AMBIENT + diffuse) * color + specular; 390 391 // Fading 392 float fade = pow (max (0.0, 1.0 - d.z * VOXEL_RESOLUTION / RAY_LENGTH_MAX), FADE_POWER); 393 finalColor = mix (finalColor, color, fade); 394 } 395 396 // Set the fragment color 397 finalColor = mix (pow (finalColor, vec3 (GAMMA)) + glowColor, vec3 (1.0), modeSwitch); 398 fragColor = vec4 (finalColor, 1.0); 399} 400 401 void main(void) 402{ 403 //just some shit to wrap shadertoy's stuff 404 vec2 FragCoord = vTexCoord.xy*OutputSize.xy; 405 mainImage(FragColor,FragCoord); 406} 407#endif 408