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// Xafer - 2017-04-30 106// https://www.shadertoy.com/view/4dlyzl 107 108// Reflections, refractions, lights such 109 110#define NEAR 0.01 111#define FAR 12.0 112 113#define STEP_SIZE 0.1 114#define MAX_ITER 300 115#define MAX_CYCLES 2 116#define DELTA 0.01 117#define A_SPEED 0.3 118#define CAM_DIST 3.3 119 120#define RECAST_MAX 5 121 122#define GLOW_POWER 6.0 123#define GLOW_COLOR vec3(0.2,0.4,0.4) 124#define GRASS_SIZE vec2(0.005,0.4) 125 126#define SKY_COLOR vec3(0.1,0.3,0.4) 127 128 129//Structures 130 131struct Light 132{ 133 vec3 pos; 134 vec3 color; 135 float radius; 136 float intensity; 137}; 138 139struct lComp 140{ 141 vec3 specular; 142 float specularIntensity; 143 vec3 diffuse; 144}; 145 146struct Ray 147{ 148 vec3 pos; 149 vec3 dir; 150 float dist; 151 float near; 152}; 153 154struct Material 155{ 156 vec3 color; 157 float specular; 158 float diffuse;// 159 float ambient;//Ambient light factor 160 float refl;//How reflective is a surface 161 float refr;//Refraction index 162 float opacity;//For refractions 163}; 164 165 166//Signed Distance Functions 167 168float sdSphere(vec3 p) 169{ 170 return length(p) - 1.0; 171} 172 173float sdPlane(vec3 p) 174{ 175 return -p.y; 176} 177 178float sdBox( vec3 p) 179{ 180 vec3 d = abs(p) - vec3(1.0); 181 return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); 182} 183 184float opAdd(float d1, float d2) 185{ 186 return min(d1,d2); 187} 188 189float opSub(float d1, float d2) 190{ 191 return max(-d1,d2); 192} 193 194float opInter(float d1, float d2) 195{ 196 return max(d1,d2); 197} 198 199 200//Combinations 201 202float walls(vec3 p) 203{ 204 p.y -= 1.0; 205 p.y * 2.0; 206 207 vec3 p2 = p; 208 vec3 p3 = p; 209 210 float width = 0.1; 211 vec2 dist = vec2(5.0); 212 213 p2.xz = mod(p2.xz,dist)-(dist/2.0); 214 p2.x /= width; 215 p2.z /= 2.0; 216 217 p3.xz = mod(p3.xz,dist)-(dist/2.0); 218 p3.z /= width; 219 p3.x /= 2.0; 220 221 float env = opAdd(sdPlane(p),opAdd(sdBox(p2),sdBox(p3))); 222 223 env = opSub(max(-p.y - 0.3, p.y + 0.2),max(env,sdSphere(p/(CAM_DIST-0.4)))); 224 225 env = opAdd(env,sdSphere(p/0.7 + vec3(0,0.5,0))); 226 227 return opSub(sdSphere(p),env); 228} 229 230float map(vec3 pos, float factor) 231{ 232 return walls(pos); 233} 234 235float map(vec3 pos) 236{ 237 return map(pos,0.0); 238} 239 240//Environment propreties 241 242vec3 getNormal(vec3 p) 243{ 244 vec2 delta = vec2 (DELTA, 0.0); 245 vec3 normal = normalize (vec3 ( 246 map (p + delta.xyy) - map (p - delta.xyy), 247 map (p + delta.yxy) - map (p - delta.yxy), 248 map (p + delta.yyx) - map (p - delta.yyx))); 249 250 return normalize(normal); 251} 252 253 254 255Material getMaterial(vec3 pos) 256{ 257 Material mat; 258 mat.color = vec3(sin(pos.y),cos(pos.x),sin(pos.z))/2.0 + 0.5; 259 mat.refl = 0.0; 260 mat.refr = 0.8; 261 mat.opacity = 0.7; 262 263 mat.color = mix(mat.color,getNormal(pos),0.2); 264 265 return mat; 266} 267 268//RayMarching 269 270Ray march(Ray ray, int iterations) 271{ 272 float n = 1.0 / min(iResolution.x, iResolution.y); 273 274 for(int i = 0; i < iterations; i++) 275 { 276 ray.near = map(ray.pos,sqrt(ray.dist)*n); 277 278 if(ray.near < DELTA || ray.dist > FAR) 279 break; 280 281 float n = ray.near * STEP_SIZE; 282 ray.pos += ray.dir * n; 283 ray.dist += n; 284 } 285 286 return ray; 287} 288 289lComp getLighting(Ray ray) 290{ 291 lComp lightComposition; 292 293 //Looping through lights 294 Light light; 295 light.radius = 3.5; 296 light.intensity = 1.0; 297 light.pos = vec3(0,-1,0); 298 light.color = vec3(1.0,0.8,0.6); 299 300 float specular; 301 float diffuse; 302 303 vec3 rayPos = ray.pos; 304 vec3 dir = light.pos - ray.pos; 305 float lDist = length(dir); 306 307 dir = normalize(dir); 308 309 rayPos += DELTA*dir; 310 311 float near = 0.0; 312 float dist = 0.0; 313 314 float l; 315 316 for(int i =0 ; i < MAX_ITER;i++) 317 { 318 near = map(rayPos); 319 l = length(rayPos-light.pos); 320 if(near < DELTA || dist > lDist) 321 break; 322 323 float n = abs(near * 0.1); 324 325 rayPos += n*dir; 326 dist += n; 327 } 328 329 if(near < DELTA) 330 diffuse = 0.0; 331 else if(dist > lDist) 332 { 333 diffuse = max(0.0,1.0 - (lDist/light.radius)); 334 specular = dot(reflect(ray.dir,getNormal(ray.pos)),dir)/2.0 + 0.5; 335 specular = -cos(specular*3.1416)/2.0 + 0.5; 336 specular = pow(specular,lDist*lDist); 337 //if(specular > 0.9); 338 // specular /= 20.0; 339 } 340 341 vec3 normal = getNormal(ray.pos); 342 343 lightComposition.diffuse = mix(SKY_COLOR, light.color, diffuse); 344 lightComposition.specular = light.color; 345 lightComposition.specularIntensity = specular; 346 347 return lightComposition; 348} 349 350//Marching through refractions 351 352vec3 getRefraction(Ray ray) 353{ 354 vec3 color; 355 float colorFactor; 356 357 float intensity = 1.0; 358 Material mat = getMaterial(ray.pos);; 359 360 for(int i = 0; i < MAX_CYCLES; i++) 361 { 362 vec3 normal = getNormal(ray.pos); 363 ray.dir = refract(ray.dir, normal, mat.refr); 364 365 vec3 m = ray.dir*DELTA*2.0; 366 367 int inside = 0; 368 369 for(int j = 0; j < MAX_ITER && (ray.near < DELTA || inside == 1); j++) 370 { 371 ray.pos += m; 372 ray.dist += DELTA*2.0; 373 ray.near = map(ray.pos); 374 } 375 376 ray.dir = refract(ray.dir,normal,mat.refr); 377 ray = march(ray,MAX_ITER); 378 379 if(ray.near > DELTA || ray.dist > FAR) 380 { 381 color += SKY_COLOR*intensity; 382 colorFactor += intensity; 383 break; 384 } 385 386 lComp lightComposition = getLighting(ray); 387 388 mat = getMaterial(ray.pos); 389 390 vec3 col = mix(mat.color * lightComposition.diffuse,lightComposition.specular, lightComposition.specularIntensity); 391 392 color += mix(col,SKY_COLOR,ray.dist/FAR)*intensity; 393 colorFactor += intensity; 394 395 intensity *= 1.0 - mat.opacity; 396 } 397 398 return color/colorFactor; 399} 400 401//Marching through reflections 402 403vec3 getReflection(Ray ray) 404{ 405 vec3 color; 406 float colorFactor; 407 408 float intensity = 1.0; 409 410 for(int i = 0; i < MAX_CYCLES; i++) 411 { 412 vec3 normal = getNormal(ray.pos); 413 ray.dir = reflect(ray.dir,normal); 414 ray.pos += ray.dir * DELTA; 415 416 ray = march(ray, MAX_ITER); 417 418 Material mat = getMaterial(ray.pos); 419 420 intensity *= mat.refl; 421 422 lComp lightComposition = getLighting(ray); 423 424 vec3 col = mix(mat.color * lightComposition.diffuse, lightComposition.specular, lightComposition.specularIntensity); 425 426 color += mix(col,SKY_COLOR,ray.dist/FAR)*intensity; 427 colorFactor += intensity; 428 } 429 430 return color/colorFactor; 431} 432 433//Getting the color at the specified point 434 435vec3 getColor(Ray ray) 436{ 437 438 vec3 color; 439 vec3 normal = getNormal(ray.pos); 440 441 if(ray.dist > FAR) 442 { 443 color = SKY_COLOR; 444 } 445 else if(ray.near <= DELTA) 446 { 447 Material mat = getMaterial(ray.pos); 448 449 color = mat.color; 450 451 lComp lightComposition = getLighting(ray); 452 color *= lightComposition.diffuse; 453 454 if(mat.refr > 0.0) 455 color = mix(getRefraction(ray),color,mat.opacity); 456 457 if(mat.refl > 0.0) 458 color = mix(color,getReflection(ray),mat.refl); 459 460 color = mix(color, lightComposition.specular, lightComposition.specularIntensity); 461 462 color = mix(color, SKY_COLOR , ray.dist/FAR); 463 color = mix(color, SKY_COLOR , dot(ray.dir,normal)/2.0 + 0.5); 464 } 465 466 return color; 467} 468 469vec3 castRay(vec3 origin, vec3 direction) 470{ 471 //Generating ray 472 Ray ray; 473 ray.pos = origin; 474 ray.dir = direction; 475 ray.dist = 0.0; 476 477 //Move the ray to a surface up to far distance 478 ray = march(ray, MAX_ITER*2); 479 480 return getColor(ray); 481} 482 483//Initialisation 484 485void mainImage( out vec4 fragColor, in vec2 fragCoord ) 486{ 487 488 //Setting up screen-correct uv 489 vec2 uv = ( fragCoord.xy / iResolution.xy ) * 2.0 - vec2( 1 ); 490 uv.x *= iResolution.x/iResolution.y; 491 492 //Setting up rotation 493 float sa = sin( iGlobalTime * A_SPEED ); 494 float ca = cos( iGlobalTime * A_SPEED ); 495 496 float cDist = CAM_DIST + sin(iGlobalTime * A_SPEED); 497 498 //Creating ray 499 vec3 or = vec3(sa*cDist,0.5,-ca*cDist); 500 vec3 di = -normalize(vec3(uv.x,uv.y,-1.0)); 501 502 //Rotating orientation 503 mat3 r; 504 r[0] = vec3(ca,0,sa); 505 r[1] = vec3(0,1,0); 506 r[2] = vec3(-sa,0,ca); 507 di = r*di; 508 509 vec3 color = castRay(or,di); 510 511 fragColor = vec4(color,1); 512} 513 514 void main(void) 515{ 516 //just some shit to wrap shadertoy's stuff 517 vec2 FragCoord = vTexCoord.xy*OutputSize.xy; 518 mainImage(FragColor,FragCoord); 519} 520#endif 521