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// Wolfenstein. Created by Reinder Nijhoff 2013 106// @reindernijhoff 107 108#define NUM_MATERIALS 3 109#define NUM_OBJECTS 1 110#define SECONDS_IN_ROOM 3. 111#define ROOM_SIZE 10. 112#define MAXSTEPS 17 113#define MATERIAL_DOOR 200 114#define MATERIAL_DOORWAY 201 115 116#define COL(r,g,b) vec3(r/255.,g/255.,b/255.) 117 118#define time (iGlobalTime+40.) 119vec3 rdcenter; 120 121//---------------------------------------------------------------------- 122// Math functions 123 124float hash( const float n ) { 125 return fract(sin(n*14.1234512)*51231.545341231); 126} 127float hash( const vec2 x ) { 128 float n = dot( x, vec2(14.1432,1131.15532) ); 129 return fract(sin(n)*51231.545341231); 130} 131float crossp( const vec2 a, const vec2 b ) { return a.x*b.y - a.y*b.x; } 132vec3 rotate(vec3 r, float v){ return vec3(r.x*cos(v)+r.z*sin(v),r.y,r.z*cos(v)-r.x*sin(v));} 133bool intersectSegment(const vec3 ro, const vec3 rd, const vec2 a, const vec2 b, out float dist, out float u) { 134 vec2 p = ro.xz; vec2 r = rd.xz; 135 vec2 q = a-p; vec2 s = b-a; 136 float rCrossS = crossp(r, s); 137 138 if( rCrossS == 0.){ 139 return false; 140 } else { 141 dist = crossp(q, s) / rCrossS; 142 u = crossp(q, r) / rCrossS; 143 144 if(0. <= dist && 0. <= u && u <= 1.){ 145 return true; 146 } else { 147 return false; 148 } 149 } 150} 151 152//---------------------------------------------------------------------- 153// Material helper functions 154 155float onCircle( const vec2 c, const vec2 centre, const float radius ) { 156 return clamp( 4.*(radius - distance(c,centre)), 0., 1. ); 157} 158float onCircleLine( const vec2 c, const vec2 centre, const float radius ) { 159 return clamp( 1.-1.5*abs(radius - distance(c,centre)), 0., 1. ); 160} 161float onLine( const float c, const float b ) { 162 return clamp( 1.-abs(b-c), 0., 1. ); 163} 164float onBand( const float c, const float mi, const float ma ) { 165 return clamp( (ma-c+1.), 0., 1. )*clamp( (c-mi+1.), 0., 1. ); 166} 167float onLineSegmentX( const vec2 c, const float b, const float mi, const float ma ) { 168 return onLine( c.x, b )*onBand( c.y, mi, ma ); 169} 170float onLineSegmentY( const vec2 c, const float b, const float mi, const float ma ) { 171 return onLine( c.y, b )*onBand( c.x, mi, ma ); 172} 173float onRect( const vec2 c, const vec2 lt, const vec2 rb ) { 174 return onBand( c.x, lt.x, rb.x )*onBand( c.y, lt.y, rb.y ); 175} 176vec3 addBevel( const vec2 c, const vec2 lt, const vec2 rb, const float size, const float strength, const float lil, const float lit, const vec3 col ) { 177 float xl = clamp( (c.x-lt.x)/size, 0., 1. ); 178 float xr = clamp( (rb.x-c.x)/size, 0., 1. ); 179 float yt = clamp( (c.y-lt.y)/size, 0., 1. ); 180 float yb = clamp( (rb.y-c.y)/size, 0., 1. ); 181 182 return mix( col, col*clamp(1.0+strength*(lil*(xl-xr)+lit*(yb-yt)), 0., 2.), onRect( c, lt, rb ) ); 183} 184vec3 addKnob( const vec2 c, const vec2 centre, const float radius, const float strength, const vec3 col ) { 185 vec2 lv = normalize( centre-c ); 186 return mix( col, col*(1.0+strength*dot(lv,vec2(-0.7071,0.7071))), onCircle(c, centre, radius ) ); 187} 188float stepeq( float a, float b ) { 189 return step( a, b )*step( b, a ); 190} 191//---------------------------------------------------------------------- 192// Generate materials! 193 194void getMaterialColor( const int material, in vec2 uv, const float decorationHash, out vec3 col ) { 195 vec3 fgcol; 196 197 uv = floor( mod(uv+64., vec2(64.)) ); 198 vec2 uvs = uv / 64.; 199 200 // basecolor 201 vec3 basecol = vec3( mix(55./255.,84./255.,uvs.y ) ); 202 float br = hash(uv); 203 col = basecol; 204// grey bricks 205 if( material == 0 || material == 1 ) { 206 vec2 buv = vec2( mod(uv.x+1. + (floor((uv.y+1.) / 16.) * 16.), 32.) , mod( uv.y+1., 16.) ); 207 float bbr = mix( 190./255., 91./255., (buv.y)/14. ) + 0.05*br; 208 if ( buv.x < 2. || buv.y < 2.) { 209 bbr = 72./255.; 210 } 211 col = vec3(bbr*0.95); 212 col = addBevel( buv, vec2(1.,1.), vec2( 31.5, 15.), 2., 0.35, 1., 1., col); 213 // blue wall 214 if( material == 1 ) { 215 col *= 1.3*COL(11.,50.,209.); 216 col = mix( col, COL(2.,15.,86.), onBand(uv.y,14.,49.)); 217 col = mix( col, COL(9.,44.,185.)*(0.9+0.1*br), onBand(uv.y,16.,47.)); 218 col = mix( col, COL(3.,25.,122.), onBand(uv.y,21.,42.)); 219 col = addBevel( uv, vec2(-1.,16.), vec2( 65., 21.), 1., 0.35, 1., 1., col); 220 col = addBevel( uv, vec2(-1.,43.), vec2( 65., 48.), 1., 0.35, 1., 1., col); 221 222 col = mix( col, COL(2.,11.,74.), onRect(uv, vec2(22.,22.), vec2(42.,42.))); 223 col = mix( col, COL(9.,44.,185.)*(0.95+0.1*br), onRect(uv, vec2(22.,23.), vec2(42.,40.))); 224 col = addBevel( uv, vec2(22.,23.), vec2(42.,40.), 1., 0.2, -1., 1., col); 225 col = mix( col, mix(COL(2.,11.,74.), COL(3.,25.,122.), (uv.x-26.)/3.), onRect(uv, vec2(26.,23.), vec2(29.,29.))); 226 col = mix( col, mix(COL(2.,11.,74.), COL(3.,25.,122.), (uv.y-34.)/2.), onRect(uv, vec2(22.,34.), vec2(29.,36.))); 227 col = mix( col, mix(COL(2.,11.,74.), COL(3.,25.,122.), (uv.y-27.)/2.), onRect(uv, vec2(35.,27.), vec2(42.,29.))); 228 col = mix( col, mix(COL(2.,11.,74.), COL(3.,25.,122.), (uv.y-34.)/8.), onRect(uv, vec2(35.,34.), vec2(38.,42.))); 229 } 230 } 231// wooden wall 232 else if( material == 2 ) { 233 float mx = mod( uv.x, 64./5. ); 234 float h1 = hash( floor(uv.x/(64./5.)) ); 235 float h2 = hash( 1.+1431.16*floor(uv.x/(64./5.)) ); 236 col = mix( COL(115.,75.,43.),COL( 71.,56.,26.), smoothstep( 0.2, 1., (0.7+h2)*abs(mod( h2-uv.y*(0.05+0.1*h2)+(1.+h1+h2)*sin(mx*(0.1+0.2*h2)), 2. )-1.) ) ); 237 238 col = mix( col, mix(COL(40.,31.,13.), COL(142.,91.,56.), (uv.x)/2.), step(uv.x,2.) ); 239 col = mix( col, mix(COL(40.,31.,13.), COL(142.,91.,56.), (uv.x-10.)/2.), step(10.,uv.x)*step(uv.x,12.) ); 240 col = mix( col, mix(COL(40.,31.,13.), COL(142.,91.,56.), (uv.x-26.)/2.), step(26.,uv.x)*step(uv.x,28.) ); 241 col = mix( col, mix(COL(40.,31.,13.), COL(142.,91.,56.), (uv.x-40.)/2.), step(40.,uv.x)*step(uv.x,42.) ); 242 col = mix( col, mix(COL(40.,31.,13.), COL(142.,91.,56.), (uv.x-54.)/2.), step(54.,uv.x)*step(uv.x,56.) ); 243 244 col = mix( col, mix(COL(83.,60.,31.), COL(142.,91.,56.), (uv.x- 8.)), step( 8.,uv.x)*step(uv.x,9.) ); 245 col = mix( col, mix(COL(83.,60.,31.), COL(142.,91.,56.), (uv.x-24.)), step(24.,uv.x)*step(uv.x,25.) ); 246 col = mix( col, mix(COL(83.,60.,31.), COL(142.,91.,56.), (uv.x-38.)), step(38.,uv.x)*step(uv.x,39.) ); 247 col = mix( col, mix(COL(83.,60.,31.), COL(142.,91.,56.), (uv.x-52.)), step(52.,uv.x)*step(uv.x,53.) ); 248 col = mix( col, mix(COL(83.,60.,31.), COL(142.,91.,56.), (uv.x-62.)), step(62.,uv.x) ); 249 250 col = mix( col, mix(COL(40.,31.,13.), COL(142.,91.,56.), (uv.y)/2.), step(uv.y,2.) ); 251 col *= 1.-0.3*stepeq(uv.y,3.); 252 } 253// door 254 else if( material == MATERIAL_DOOR ) { 255 fgcol = COL(44., 176., 175.)*(0.95+0.15*sin(-0.25+ 4.*((-0.9-uvs.y)/(1.3-0.8*uvs.x)) ) ); 256 fgcol = addBevel( uv, vec2(-1.,1.), vec2(62.,66.), 2., 0.4, -1., -1., fgcol); 257 fgcol = addBevel( uv, vec2( 6.,6.), vec2(57.,57.), 2.25, 0.5, -1., -1., fgcol); 258 fgcol = mix( addKnob( mod( uv, vec2(8.) ), vec2(3.5), 1.65, 0.5, fgcol ), fgcol, onRect( uv, vec2( 6.,6.), vec2(57.,57.)) ) ; 259 260 //knob 261 fgcol *= 1.-0.2*onRect( uv, vec2( 13.5, 28.5 ), vec2( 22.5, 44.5 ) ); 262 fgcol = mix( fgcol, mix( COL(44.,44.,44.),COL(152.,152.,152.), ((uv.x+(43.-uv.y)-15.)/25. ) ), onRect( uv, vec2( 15., 27. ), vec2( 24., 43. ) ) ); 263 fgcol = addBevel( uv, vec2( 15., 27. ), vec2( 24., 43. ), 1., 0.45, 1., 1., fgcol); 264 fgcol = mix( fgcol, addKnob( mod( uv, vec2(6.) ), vec2(4.25,5.5), 1.15, 0.75, fgcol ), onRect( uv, vec2( 15., 27. ), vec2( 24., 43. ) ) ) ; 265 266 fgcol *= 1.-0.5*onRect( uv, vec2( 16.5, 33.5 ), vec2( 20.5, 38.5 ) ); 267 fgcol = mix( fgcol, mix( COL(88.,84.,11.),COL(251.,242.,53.), ((uv.x+(37.-uv.y)-18.)/7. ) ), onRect( uv, vec2( 18., 33. ), vec2( 21., 37. ) ) ); 268 fgcol = mix( fgcol, COL(0.,0.,0.), onRect( uv, vec2( 19., 34. ), vec2( 20., 35.7 ) ) ); 269 270 fgcol *= 1.-0.2*onRect( uv, vec2( 6.5, 29.5 ), vec2( 10.5, 41.5 ) ); 271 fgcol = mix( fgcol, mix( COL(88.,84.,11.),COL(251.,242.,53.), ((uv.x+(40.-uv.y)-9.)/13. ) ), onRect( uv, vec2( 9., 29. ), vec2( 11., 40. ) ) ); 272 fgcol = addBevel( uv, vec2( 9., 29. ), vec2( 11., 40. ), 0.75, 0.5, 1., 1., fgcol); 273 274 col = mix( basecol, fgcol, onRect( uv, vec2(1.,1.), vec2(62.,62.) ) ); 275 } 276// doorway 277 else if( material == MATERIAL_DOORWAY ) { 278 fgcol = COL(44., 176., 175.)*(0.95+0.15*sin(-0.25+ 4.*((-0.9-uvs.y)/(1.3-0.8*uvs.x)) ) ); 279 vec2 uvhx = vec2( 32.-abs(uv.x-32.), uv.y ); 280 fgcol = addBevel( uvhx, vec2(-1.,1.), vec2(28.,66.), 2., 0.4, -1., -1., fgcol); 281 fgcol = addBevel( uvhx, vec2( 6.,6.), vec2(23.,57.), 2.25, 0.5, -1., -1., fgcol); 282 fgcol = mix( addKnob( vec2( mod( uvhx.x, 22. ), mod( uvhx.y, 28. )), vec2(3.5), 1.65, 0.5, fgcol ), fgcol, onRect( uvhx, vec2( 6.,6.), vec2(24.,57.)) ) ; 283 fgcol = mix( fgcol, vec3(0.), onRect( uv, vec2( 29., 1.), vec2( 35., 63.) ) ); 284 col = mix( basecol, fgcol, onRect( uv, vec2(1.,1.), vec2(62.,62.) ) ); 285 } 286 287// prison door 288 if( decorationHash > 0.93 && material < (NUM_MATERIALS+1) ) { 289 vec4 prisoncoords = vec4(12.,14.,52.,62.); 290 // shadow 291 col *= 1.-0.5*onRect( uv, vec2( 11., 13. ), vec2( 53., 63. ) ); 292 // hinge 293 col = mix( col, COL(72.,72.,72.), stepeq(uv.x, 53.)*step( mod(uv.y+2.,25.), 5.)*step(13.,uv.y) ); 294 col = mix( col, COL(100.,100.,100.), stepeq(uv.x, 53.)*step( mod(uv.y+1.,25.), 3.)*step(13.,uv.y) ); 295 296 vec3 pcol = vec3(0.)+COL(100.,100.,100.)*step( mod(uv.x-4., 7.), 0. ); 297 pcol += COL(55.,55.,55.)*step( mod(uv.x-5., 7.), 0. ); 298 pcol = addBevel(uv, vec2(0.,17.), vec2(63.,70.), 3., 0.8, 0., -1., pcol); 299 pcol = addBevel(uv, vec2(0.,45.), vec2(22.,70.), 3., 0.8, 0., -1., pcol); 300 301 fgcol = COL(72.,72.,72.); 302 fgcol = addBevel(uv, prisoncoords.xy, prisoncoords.zw+vec2(1.,1.), 1., 0.5, -1., 1., fgcol ); 303 fgcol = addBevel(uv, prisoncoords.xy+vec2(3.,3.), prisoncoords.zw-vec2(2.,1.), 1., 0.5, 1., -1., fgcol ); 304 fgcol = mix( fgcol, pcol, onRect( uv, prisoncoords.xy+vec2(3.,3.), prisoncoords.zw-vec2(3.,2.) ) ); 305 fgcol = mix( fgcol, COL(72.,72.,72.), onRect( uv, vec2(15.,32.5), vec2(21.,44.) ) ); 306 307 fgcol = mix( fgcol, mix( COL(0.,0.,0.), COL(43.,43.,43.), (uv.y-37.) ), stepeq(uv.x, 15.)*step(37.,uv.y)*step(uv.y,38.) ); 308 fgcol = mix( fgcol, mix( COL(0.,0.,0.), COL(43.,43.,43.), (uv.y-37.)/3. ), stepeq(uv.x, 17.)*step(37.,uv.y)*step(uv.y,40.) ); 309 fgcol = mix( fgcol, COL(43.,43.,43.), stepeq(uv.x, 18.)*step(37.,uv.y)*step(uv.y,41.) ); 310 fgcol = mix( fgcol, mix( COL(0.,0.,0.), COL(100.,100.,100.), (uv.y-37.)/3. ), stepeq(uv.x, 18.)*step(36.,uv.y)*step(uv.y,40.) ); 311 fgcol = mix( fgcol, COL(43.,43.,43.), stepeq(uv.x, 19.)*step(37.,uv.y)*step(uv.y,40.) ); 312 313 fgcol = mix( fgcol, mix( COL(84.,84.,84.), COL(108.,108.,108.), (uv.x-15.)/2. ), stepeq(uv.y, 32.)*step(15.,uv.x)*step(uv.x,17.) ); 314 fgcol = mix( fgcol, COL(81.,81.,81.), stepeq(uv.y, 32.)*step(20.,uv.x)*step(uv.x,21.) ); 315 316 col = mix( col, fgcol, onRect( uv, prisoncoords.xy, prisoncoords.zw ) ); 317 } 318// flag 319 else if( decorationHash > 0.63 && material < (NUM_MATERIALS+1) ) { 320 vec2 uvc = uv-vec2(32.,30.); 321 322 // shadow 323 vec4 shadowcoords = vec4( 14., 7., 324 54., max( 56. + sin( uv.x*0.32-1. ),56.) ); 325 col *= 1.-0.3*onRect( uv, vec2( 6., 6. ), vec2( 61., 7. ) ); 326 col *= 1.-0.3*clamp( 0.25*(56.-uv.x), 0., 1.)*onRect( uv, shadowcoords.xy, shadowcoords.zw ); 327 328 // rod 329 col = mix( col, COL(250.,167.,98.), onLineSegmentX( vec2( abs(uv.x-32.), uv.y ), 26., 4., 6.5 ) ); 330 col = mix( col, COL(251.,242.,53.), onLineSegmentY( uv, 5., 4., 60. ) ); 331 col = mix( col, COL(155.,76.,17.), onLineSegmentY( uv, 6., 4., 60. ) ); 332 col = mix( col, COL(202.,96.,25.), onLineSegmentY( vec2( abs(uv.x-32.), uv.y ), 6., 26., 28. ) ); 333 col = mix( col, COL(251.,242.,53.), onLineSegmentX( vec2( abs(uv.x-32.), uv.y ), 25., 3., 7. ) ); 334 col = mix( col, COL(252.,252.,217.), onLineSegmentX( vec2( abs(uv.x-32.), uv.y ), 25., 4.3, 5.5 ) ); 335 col = mix( col, COL(252.,252.,217.), onLineSegmentX( vec2( abs(uv.x-32.), uv.y ), 26., 5.3, 5.5 ) ); 336 col = mix( col, COL(0.,0.,0.), onLineSegmentY( vec2( abs(uv.x-32.), uv.y ), 6., 18.3, 19.5 ) ); 337 338 // flag 339 vec4 flagcoords = vec4( 13., min( 9.5 - pow(5.5* (uvs.x-0.5), 2.), 9. ), 340 51., max( 55. + sin( uv.x*0.4+2.7 ),55.) ); 341 342 fgcol = COL(249.,41.,27.); 343 344 fgcol = mix( fgcol, COL(255.,255.,255.), onBand( min(abs(uvc.x), abs(uvc.y)), 2., 4. ) ); 345 fgcol = mix( fgcol, COL(72.,72.,72.), onLine( min(abs(uvc.x), abs(uvc.y)), 3. ) ); 346 347 fgcol = mix( fgcol, COL(255.,255.,255.), onCircle( uv, vec2(32.,30.), 12.5 ) ); 348 fgcol = mix( fgcol, COL(0.,0.,0.), onCircleLine( uv, vec2(32.,30.), 11. ) ); 349 fgcol = mix( fgcol, COL(0.,0.,0.), onCircleLine( uv, vec2(32.,30.), 9. ) ); 350 351 vec2 uvr = vec2( (uvc.x-uvc.y)*0.7071, (uvc.y+uvc.x)*0.7071)*sign( uvc.x+0.5 ); 352 fgcol = mix( fgcol, COL(72.,72.,72.), onRect( uvr, vec2(-1.,-1.), vec2(1.,4.) ) ); 353 fgcol = mix( fgcol, COL(72.,72.,72.), onRect( uvr, vec2(-4.2, 4.2), vec2(1.,6.15) ) ); 354 fgcol = mix( fgcol, COL(72.,72.,72.), onRect( uvr, vec2(-1.,-1.), vec2(4.,1.) ) ); 355 fgcol = mix( fgcol, COL(72.,72.,72.), onRect( uvr, vec2( 4.2,-1.), vec2(6.15,4.2) ) ); 356 357 fgcol *= (0.8+0.2*sin( uv.x*0.4+2.7 )); 358 fgcol *= (0.8+0.2*clamp( 0.5*(uv.y-7.), 0., 1.)); 359 360 // mix flag on background 361 col = mix( col, fgcol, onRect( uv, flagcoords.xy, flagcoords.zw ) ); 362 } 363 364// fake 8-bit color palette and dithering 365 col = floor( (col+0.5*mod(uv.x+uv.y,2.)/32.)*32.)/32.; 366} 367bool getObjectColor( const int object, in vec2 uv, inout vec3 icol ) { 368 uv = floor( mod(uv, vec2(64.)) ); 369 vec2 uvs = uv / 64.; 370 vec3 col = vec3(20./255.); 371 float d; 372 373// only a lamp for now 374 375 // lamp top 376 d = distance( uv*vec2(1.,2.), vec2(28.1, 5.8)*vec2(1.,2.) ); 377 col = mix( col, mix( COL(41.,250.,46.), COL(13.,99.,12.), clamp( d/8.-0.2, 0., 1.) ), 378 onCircle(uv, vec2(31.,13.6), 11.7 )*step( uv.y, 6. )); 379 col = mix( col, COL(9.,75.,6.), onCircleLine( uv, vec2(31.,14.), 11.6 ) * 380 step( length(uv-vec2(31.,13.6)), 11.7 )*step( uv.y, 6. ) ); 381 col = mix( col, COL(100.,100.,100.), onLine( abs(uv.x-31.), 1. )*step( uv.y, 1. ) ); 382 col = mix( col, COL(140.,140.,140.), onLine( abs(uv.x-31.), 0.25 )*step( uv.y, 1. )*step( 1., uv.y ) ); 383 384 // lamp bottom 385 d = distance( uv*vec2(1.,2.), vec2(30.5, 6.5)*vec2(1.,2.) ); 386 col = mix( col, mix( COL(41.,250.,46.), COL(13.,99.,12.), clamp( abs(uv.x-31.)/4.-1.25, 0., 1. )), step( abs(uv.x-31.), 9. )*stepeq( uv.y, 7.) ); 387 col = mix( col, mix( COL(41.,250.,46.), COL(16.,123.,17.), clamp( abs(uv.x-31.)/4.-1.25, 0., 1. )), step( abs(uv.x-31.), 9. )*stepeq( uv.y, 8.) ); 388 col = mix( col, mix( COL(133.,250.,130.), COL(22.,150.,23.), clamp( abs(uv.x-31.)/4.-0.75, 0., 1. )), step( abs(uv.x-31.), 7. )*stepeq( uv.y, 9.) ); 389 390 col = mix( col, mix( COL(255.,251.,187.), col, clamp( d/4.5-0.6, 0., 1.) ), 391 onCircle(uv, vec2(31.,1.), 10.2 )*step( uv.y, 8. )*step( 7., uv.y )); 392 col = mix( col, mix( COL(255.,255.,255.), col, clamp( d/4.-0.7, 0., 1.) ), 393 onCircle(uv, vec2(31.,1.), 7.2 )*step( uv.y, 8. )*step( 7., uv.y )); 394 395 // floor 396 d = distance( vec2(mod(uv.x, 32.),uv.y)*vec2(1.5,30./3.), vec2(16., 61.5)*vec2(1.5,30./3.) ); 397 col = mix( col, mix( COL(168.,168.,168.), COL(124.,124.,124.), clamp(d/15.-0.5, 0., 1.) ), step(d,24.5)); 398 col = mix( col, mix( COL(124.,124.,124.), COL(140.,140.,140.), clamp((uv.y-59.)/1., 0., 1.)), step(59.,uv.y)*step(uv.x, 57.)*step(7.,uv.x)); 399 col = mix( col, mix( COL(168.,168.,168.), COL(124.,124.,124.), clamp(abs(32.-uv.x)/10.-2., 0., 1.)), step(uv.y, 62.)*step(62.,uv.y)*step(uv.x, 61.)*step(3.,uv.x)); 400 col = mix( col, mix( COL(152.,152.,152.), COL(124.,124.,124.), clamp(abs(32.-uv.x)/10.-2.25, 0., 1.)), step(uv.y, 61.)*step(61.,uv.y)*step(uv.x, 59.)*step(5.,uv.x)); 401 402 col = floor( (col)*32.)/32.; 403 if( any(notEqual(col, vec3(floor((20./255.)*32.)/32.))) ) { 404 icol = col; 405 return true; 406 } 407 return false; 408} 409 410//---------------------------------------------------------------------- 411// Proocedural MAP functions 412 413bool isWall( const vec2 vos ) { 414 return vos.y<0.4*ROOM_SIZE || vos.y>2.75*ROOM_SIZE || any( equal( mod( vos, vec2( ROOM_SIZE ) ), vec2(0.,0.) ) ); 415} 416bool isDoor( const vec2 vos ) { 417 return isWall(vos) && ((hash(vos)>0.75 && any( equal( mod( vos, vec2( ROOM_SIZE*0.5 ) ), vec2(2.) ) )) 418 || any( equal( mod( vos, vec2( ROOM_SIZE ) ), vec2(ROOM_SIZE*0.5) ) )); 419} 420bool isObject( const vec2 vos ) { 421 return hash( vos*10. ) > 0.95; 422} 423bool map( const vec2 vos ) { 424 return isObject( vos ) || isWall( vos ); 425} 426 427//---------------------------------------------------------------------- 428// Render MAP functions 429 430bool intersectSprite( const vec3 ro, const vec3 rd, const vec3 vos, const vec3 nor, out vec2 uv ) { 431 float dist, u; 432 vec2 a = vos.xz + nor.zx*vec2(-0.5,0.5) + vec2(0.5, 0.5); 433 vec2 b = vos.xz - nor.zx*vec2(-0.5,0.5) + vec2(0.5, 0.5); 434 if( intersectSegment( ro, rd, a, b, dist, u) ) { 435 uv.x = u; uv.y = 1.-(ro+dist*rd).y; 436 if( sign(nor.x)<0. ) uv.x = 1.-uv.x; 437 return uv.y>0.&&uv.y<1.; 438 } 439 return false; 440} 441int getMaterialId( const vec2 vos ) { 442 return int( mod( 521.21 * hash( floor((vos-vec2(0.5))/ROOM_SIZE ) ), float(NUM_MATERIALS)) ); 443} 444bool getColorForPosition( const vec3 ro, const vec3 rd, const vec3 vos, const vec3 pos, const vec3 nor, inout vec3 col ) { 445 vec2 uv; 446 447 if( isWall( vos.xz ) ) { 448 if( isDoor( vos.xz ) ) { 449 if( intersectSprite( ro, rd, vos+nor*0.03, nor, uv ) ) { 450 // open the door 451 uv.x -= clamp( 2.-0.75*distance( ro.xz, vos.xz+vec2(0.5) ), 0., 1.); 452 if( uv.x > 0. ) { 453 getMaterialColor( MATERIAL_DOOR, uv*64., 0., col ); 454 return true; 455 } 456 } 457 return false; 458 } 459 // a wall is hit 460 if( pos.y <= 1. && pos.y >= 0. ) { 461 vec2 mpos = vec2( dot(vec3(-nor.z,0.0,nor.x),pos), -pos.y ); 462 float sha = 0.6 + 0.4*abs(nor.z); 463 getMaterialColor( isDoor( vos.xz+nor.xz )?MATERIAL_DOORWAY:getMaterialId(vos.xz), mpos*64., hash( vos.xz ), col ); 464 col *= sha; 465 return true; 466 } 467 return true; 468 } 469 if( isObject( vos.xz ) && !isWall( vos.xz+vec2(1.,0.) ) && !isWall( vos.xz+vec2(-1.,0.) ) 470 && !isWall( vos.xz+vec2(0.,-1.) ) && !isWall( vos.xz+vec2(0.,1.) ) && 471 intersectSprite( ro, rd, vos, rdcenter, uv ) ) { 472 return getObjectColor( 0, uv*64., col ); 473 } 474 return false; 475} 476 477bool castRay( const vec3 ro, const vec3 rd, inout vec3 col ) { 478 vec3 pos = floor(ro); 479 vec3 ri = 1.0/rd; 480 vec3 rs = sign(rd); 481 vec3 dis = (pos-ro + 0.5 + rs*0.5) * ri; 482 483 float res = 0.0; 484 vec3 mm = vec3(0.0); 485 bool hit = false; 486 487 for( int i=0; i<MAXSTEPS; i++ ) { 488 if( hit ) continue; 489 490 mm = step(dis.xyz, dis.zyx); 491 dis += mm * rs * ri; 492 pos += mm * rs; 493 494 if( map(pos.xz) ) { 495 vec3 mini = (pos-ro + 0.5 - 0.5*vec3(rs))*ri; 496 float t = max ( mini.x, mini.z ); 497 hit = getColorForPosition( ro, rd, pos, ro+rd*t, -mm*sign(rd), col ); 498 } 499 } 500 return hit; 501} 502 503//---------------------------------------------------------------------- 504// Some really ugly code 505 506#define CCOS(a) cos(clamp(a,0.,1.)*1.57079632679) 507#define CSIN(a) sin(clamp(a,0.,1.)*1.57079632679) 508vec3 path( const float t ) { 509 float tmod = mod( t/SECONDS_IN_ROOM, 8. ); 510 float tfloor = floor( tmod ); 511 512 vec3 pos = vec3( 4.*ROOM_SIZE*floor(t/(SECONDS_IN_ROOM*8.))+0.5, 0.5, 0.5*ROOM_SIZE+0.5 ); 513 return pos + ROOM_SIZE*vec3( 514 clamp(tmod,0.,1.)+clamp(tmod-4.,0.,1.)+0.5*(2.+CSIN(tmod-1.)-CCOS(tmod-3.)+CSIN(tmod-5.)-CCOS(tmod-7.)), 0., 515 clamp(tmod-2.,0.,1.)-clamp(tmod-6.,0.,1.)+0.5*(-CCOS(tmod-1.)+CSIN(tmod-3.)+CCOS(tmod-5.)-CSIN(tmod-7.)) ); 516} 517 518 519//---------------------------------------------------------------------- 520// Main 521 522void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 523 vec2 q = fragCoord.xy / iResolution.xy; 524 vec2 p = -1.0 + 2.0*q; 525 p.x *= iResolution.x/ iResolution.y; 526 527 vec3 ro = path( time ); 528 vec3 ta = path( time+0.1 ); 529 530 rdcenter = rotate( normalize( ta - ro), 0.3*cos(time*0.75) ); 531 vec3 uu = normalize(cross( vec3(0.,1.,0.), rdcenter )); 532 vec3 vv = normalize(cross(rdcenter,uu)); 533 vec3 rd = normalize( p.x*uu + p.y*vv + 2.5*rdcenter ); 534 535 vec3 col = rd.y>0.?vec3(56./255.):vec3(112./255.); 536 castRay( ro, rd, col ); 537 538 fragColor = vec4( col, 1.0 ); 539} 540 541 void main(void) 542{ 543 //just some shit to wrap shadertoy's stuff 544 vec2 FragCoord = vTexCoord.xy*OutputSize.xy; 545 mainImage(FragColor,FragCoord); 546} 547#endif 548