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/*-------------------------------------------------------------------------------------- 106License CC0 - http://creativecommons.org/publicdomain/zero/1.0/ 107To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. 108---------------------------------------------------------------------------------------- 109-Otavio Good 110*/ 111 112// The noise function in this was inspired by IQ's "Terrain Tubes" shader. I never really figured out 113// his function completely, so I'm not sure of the exact similarities. It's nice though because it 114// works the same on all computers (I think). It's not based on a hash that changes from computer to 115// computer. That means I can finally rely on the terrain being the same and make a camera path. :) 116// It's also a much faster noise function, although it can look a bit repetitive. 117 118#define MOTION_BLUR 119#define MOVING_SUN 120 121float Hash2d(vec2 uv) 122{ 123 float f = uv.x + uv.y * 47.0; 124 return fract(cos(f*3.333)*100003.9); 125} 126float Hash3d(vec3 uv) 127{ 128 float f = uv.x + uv.y * 37.0 + uv.z * 521.0; 129 return fract(cos(f*3.333)*100003.9); 130} 131 132float PI=3.14159265; 133 134vec3 saturate(vec3 a) { return clamp(a, 0.0, 1.0); } 135vec2 saturate(vec2 a) { return clamp(a, 0.0, 1.0); } 136float saturate(float a) { return clamp(a, 0.0, 1.0); } 137 138vec3 RotateX(vec3 v, float rad) 139{ 140 float cos = cos(rad); 141 float sin = sin(rad); 142 //if (RIGHT_HANDED_COORD) 143 return vec3(v.x, cos * v.y + sin * v.z, -sin * v.y + cos * v.z); 144 //else return new float3(x, cos * y - sin * z, sin * y + cos * z); 145} 146vec3 RotateY(vec3 v, float rad) 147{ 148 float cos = cos(rad); 149 float sin = sin(rad); 150 //if (RIGHT_HANDED_COORD) 151 return vec3(cos * v.x - sin * v.z, v.y, sin * v.x + cos * v.z); 152 //else return new float3(cos * x + sin * z, y, -sin * x + cos * z); 153} 154vec3 RotateZ(vec3 v, float rad) 155{ 156 float cos = cos(rad); 157 float sin = sin(rad); 158 //if (RIGHT_HANDED_COORD) 159 return vec3(cos * v.x + sin * v.y, -sin * v.x + cos * v.y, v.z); 160} 161 162 163// This function basically is a procedural environment map that makes the sun 164vec3 sunCol = vec3(258.0, 208.0, 100.0) / 4255.0;//unfortunately, i seem to have 2 different sun colors. :( 165vec3 GetSunColorReflection(vec3 rayDir, vec3 sunDir) 166{ 167 vec3 localRay = normalize(rayDir); 168 float dist = 1.0 - (dot(localRay, sunDir) * 0.5 + 0.5); 169 float sunIntensity = 0.015 / dist; 170 sunIntensity = pow(sunIntensity, 0.3)*100.0; 171 172 sunIntensity += exp(-dist*12.0)*300.0; 173 sunIntensity = min(sunIntensity, 40000.0); 174 return sunCol * sunIntensity*0.0425; 175} 176vec3 GetSunColorSmall(vec3 rayDir, vec3 sunDir) 177{ 178 vec3 localRay = normalize(rayDir); 179 float dist = 1.0 - (dot(localRay, sunDir) * 0.5 + 0.5); 180 float sunIntensity = 0.05 / dist; 181 sunIntensity += exp(-dist*12.0)*300.0; 182 sunIntensity = min(sunIntensity, 40000.0); 183 return sunCol * sunIntensity*0.025; 184} 185 186// This is a spline used for the camera path 187vec4 CatmullRom(vec4 p0, vec4 p1, vec4 p2, vec4 p3, float t) 188{ 189 float t2 = t*t; 190 float t3 = t*t*t; 191 return 0.5 *((2.0 * p1) + 192 (-p0 + p2) * t + 193 (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 + 194 (-p0 + 3.0 * p1- 3.0 * p2 + p3) * t3); 195} 196 197// This spiral noise works by successively adding and rotating sin waves while increasing frequency. 198// It should work the same on all computers since it's not based on a hash function like some other noises. 199// It can be much faster than other noise functions if you're ok with some repetition. 200const float nudge = 0.739513; // size of perpendicular vector 201float normalizer = 1.0 / sqrt(1.0 + nudge*nudge); // pythagorean theorem on that perpendicular to maintain scale 202float SpiralNoiseC(vec3 p) 203{ 204 float n = 0.0; // noise amount 205 float iter = 1.0; 206 for (int i = 0; i < 8; i++) 207 { 208 // add sin and cos scaled inverse with the frequency 209 n += -abs(sin(p.y*iter) + cos(p.x*iter)) / iter; // abs for a ridged look 210 // rotate by adding perpendicular and scaling down 211 p.xy += vec2(p.y, -p.x) * nudge; 212 p.xy *= normalizer; 213 // rotate on other axis 214 p.xz += vec2(p.z, -p.x) * nudge; 215 p.xz *= normalizer; 216 // increase the frequency 217 iter *= 1.733733; 218 } 219 return n; 220} 221float SpiralNoiseD(vec3 p) 222{ 223 float n = 0.0; 224 float iter = 1.0; 225 for (int i = 0; i < 6; i++) 226 { 227 n += abs(sin(p.y*iter) + cos(p.x*iter)) / iter; // abs for a ridged look 228 p.xy += vec2(p.y, -p.x) * nudge; 229 p.xy *= normalizer; 230 p.xz += vec2(p.z, -p.x) * nudge; 231 p.xz *= normalizer; 232 iter *= 1.733733; 233 } 234 return n; 235} 236float SpiralNoise3D(vec3 p) 237{ 238 float n = 0.0; 239 float iter = 1.0; 240 for (int i = 0; i < 5; i++) 241 { 242 n += (sin(p.y*iter) + cos(p.x*iter)) / iter; 243 //p.xy += vec2(p.y, -p.x) * nudge; 244 //p.xy *= normalizer; 245 p.xz += vec2(p.z, -p.x) * nudge; 246 p.xz *= normalizer; 247 iter *= 1.33733; 248 } 249 return n; 250} 251 252// These are the xyz camera positions and a left/right facing angle relative to the path line 253// I think webgl glsl can only access arrays using a constant, so I'm writing all these out. 254// Someone please tell me if I'm wrong. 255vec4 c00 = vec4(3.5, 2.0, 13.1, 0.0); // start point 256vec4 c01 = vec4(12.5, 2.2, 17.0, 0.0); // run up to canyon 2 before hole in large rock face 257vec4 c02 = vec4(21.5, 4.0, 8.1, 0.0); // canyon 2 before hole in large rock face 258vec4 c03 = vec4(21.0, 5.0, 1.1, -0.5); // before hole in large rock face 259vec4 c04 = vec4(17.8, 5.4, -0.2, 0.0); // hole in large rock face 260vec4 c05 = vec4(14.7, 2.5, 1.4, 0.0); // after hole in large rock face 261vec4 c06 = vec4(7.9, 2.3, -2.1, 0.0); 262vec4 c07 = vec4(0.5, -0.7, -3.5, 1.0); 263vec4 c08 = vec4(-3.0, -1.0, -3.5, 1.3); 264vec4 c09 = vec4(-3.5, -1.0, 4.0, 1.3); 265vec4 c10 = vec4(3.0, -0.7, 3.3, 0.8); 266vec4 c11 = vec4(3.5, -1.0, -4.75, 0.0); 267vec4 c12 = vec4(-6.0, -0.2, 1.0, 3.14); 268vec4 c13 = vec4(-6.0, -1.0, 5.5, 0.0); 269 270vec4 cXX = vec4(0.0, 3.0, 0.0, 0.0); 271 272float camPathOffset = 0.0; // where to start on the camera path - parametric t var for catmull-rom spline 273vec3 camPos = vec3(0.0), camFacing; 274vec3 camLookat=vec3(0,0.0,0); 275float waterLevel = 1.5; 276// from a time t, this finds where in the camera path you are. 277// It uses Catmull-Rom splines 278vec4 CamPos(float t) 279{ 280 t = mod(t, 14.0); // repeat after 14 time units 281 float bigTime = floor(t); 282 float smallTime = fract(t); 283 // Can't do arrays right, so write this all out. 284 if (bigTime == 0.0) return CatmullRom(c00, c01, c02, c03, smallTime); 285 if (bigTime == 1.0) return CatmullRom(c01, c02, c03, c04, smallTime); 286 if (bigTime == 2.0) return CatmullRom(c02, c03, c04, c05, smallTime); 287 if (bigTime == 3.0) return CatmullRom(c03, c04, c05, c06, smallTime); 288 if (bigTime == 4.0) return CatmullRom(c04, c05, c06, c07, smallTime); 289 if (bigTime == 5.0) return CatmullRom(c05, c06, c07, c08, smallTime); 290 if (bigTime == 6.0) return CatmullRom(c06, c07, c08, c09, smallTime); 291 292 if (bigTime == 7.0) return CatmullRom(c07, c08, c09, c10, smallTime); 293 if (bigTime == 8.0) return CatmullRom(c08, c09, c10, c11, smallTime); 294 if (bigTime == 9.0) return CatmullRom(c09, c10, c11, c12, smallTime); 295 if (bigTime == 10.0) return CatmullRom(c10, c11, c12, c13, smallTime); 296 if (bigTime == 11.0) return CatmullRom(c11, c12, c13, c00, smallTime); 297 if (bigTime == 12.0) return CatmullRom(c12, c13, c00, c01, smallTime); 298 if (bigTime == 13.0) return CatmullRom(c13, c00, c01, c02, smallTime); 299 return vec4(0.0); 300} 301 302float DistanceToObject(vec3 p) 303{ 304 float final = p.y + 4.5; 305 final -= SpiralNoiseC(p.xyz); // mid-range noise 306 final += SpiralNoiseC(p.zxy*0.123+100.0)*3.0; // large scale terrain features 307 final -= SpiralNoise3D(p); // more large scale features, but 3d, so not just a height map. 308 final -= SpiralNoise3D(p*49.0)*0.0625*0.125; // small scale noise for variation 309 final = min(final, length(p) - 1.99); // sphere in center 310 final = min(final, p.y + waterLevel); // water 311 //final = min(final, length(p-camLookat) - 0.3); 312 return final; 313} 314 315void mainImage( out vec4 fragColor, in vec2 fragCoord ) 316{ 317 // ---------------- First, set up the camera rays for ray marching ---------------- 318 vec2 uv = fragCoord.xy/iResolution.xy * 2.0 - 1.0; 319 320 // Camera up vector. 321 vec3 camUp=vec3(0,1,0); // vuv 322 323 // Camera lookat. 324 camLookat=vec3(0,0.0,0); // vrp 325 326/* if (iGlobalTime == 0.0) // for debugging with manual camera 327 { 328 camPos = cXX.xyz; 329 camLookat = vec3(0.0)*cXX.xyz; 330 }*/ 331 332 // debugging camera 333#ifdef MOUSE 334 float mx=iMouse.x/iResolution.x*PI*2.0;// + iGlobalTime * 0.1; 335 float my=-iMouse.y/iResolution.y*10.0;// + sin(iGlobalTime * 0.3)*0.2+0.2;//*PI/2.01; 336#else 337 float mx=0.0/iResolution.x*PI*2.0;// + iGlobalTime * 0.1; 338 float my=-0.0/iResolution.y*10.0;// + sin(iGlobalTime * 0.3)*0.2+0.2;//*PI/2.01; 339#endif 340 camPos += vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(5.2); // prp 341 342 // set time for moving camera along path 343 float timeLine = iGlobalTime*0.2 + camPathOffset; 344 camFacing = camLookat + camPos; 345 // without this if condition, the mac doesn't work. mysterious. :( 346 if (iGlobalTime != -1.0) 347 { 348 vec4 catmullA = CamPos(timeLine); 349 // get a smoother derivative even though the spline is not C2 continuous. 350 // Also look ahead a bit so the camera leads the motion 351 vec4 catmullB = CamPos(timeLine + 0.3); 352#ifdef MOTION_BLUR 353 vec4 catmullC = CamPos(timeLine + 0.004); // adjust for camera motion blur 354 vec4 catmullBlur = mix(catmullA, catmullC, Hash2d(uv)); // motion blur along camera path 355 camPos = catmullBlur.xyz; 356 // face camera along derivate of motion path 357 camFacing = normalize(catmullB.xyz - catmullA.xyz); 358 // rotate camera based on w component of camera path vectors 359 camFacing = RotateY(camFacing, -catmullBlur.w); 360#else 361 camPos = catmullA.xyz; 362 // face camera along derivate of motion path 363 camFacing = normalize(catmullB.xyz - catmullA.xyz); 364 // rotate camera based on w component of camera path vectors 365 camFacing = RotateY(camFacing, -catmullA.w); 366#endif 367 camFacing = RotateY(camFacing, -mx); 368 camLookat = camPos + camFacing; 369 } 370 371 372 // add randomness to camera for depth-of-field look close up. 373 //camPos += vec3(Hash2d(uv)*0.91, Hash2d(uv+37.0), Hash2d(uv+47.0))*0.01; 374 375 // Camera setup. 376 vec3 camVec=normalize(camLookat - camPos);//vpn 377 vec3 sideNorm=normalize(cross(camUp, camVec)); // u 378 vec3 upNorm=cross(camVec, sideNorm);//v 379 vec3 worldFacing=(camPos + camVec);//vcv 380 vec3 worldPix = worldFacing + uv.x * sideNorm * (iResolution.x/iResolution.y) + uv.y * upNorm;//scrCoord 381 vec3 relVec = normalize(worldPix - camPos);//scp 382 383 // -------------------------------------------------------------------------------- 384 float dist = 0.05; 385 float t = 0.0; 386 float inc = 0.02; 387 float maxDepth = 110.0; 388 vec3 pos = vec3(0,0,0); 389 // ray marching time 390 for (int i = 0; i < 200; i++) // This is the count of the max times the ray actually marches. 391 { 392 if ((t > maxDepth) || (abs(dist) < 0.0075)) break; 393 pos = camPos + relVec * t; 394 // ******************************************************* 395 // This is _the_ function that defines the "distance field". 396 // It's really what makes the scene geometry. 397 // ******************************************************* 398 dist = DistanceToObject(pos); 399 t += dist * 0.25; // because deformations mess up distance function. 400 } 401 402 // -------------------------------------------------------------------------------- 403 // Now that we have done our ray marching, let's put some color on this geometry. 404 405#ifdef MOVING_SUN 406 vec3 sunDir = normalize(vec3(sin(iGlobalTime*0.047-1.5), cos(iGlobalTime*0.047-1.5), -0.5)); 407#else 408 vec3 sunDir = normalize(vec3(0.93, 1.0, -1.5)); 409#endif 410 // This makes the sky fade at sunset 411 float skyMultiplier = saturate(sunDir.y+0.7); 412 vec3 finalColor = vec3(0.0); 413 414 // If a ray actually hit the object, let's light it. 415 if (abs(dist) < 0.75) 416 //if (t <= maxDepth) 417 { 418 // calculate the normal from the distance field. The distance field is a volume, so if you 419 // sample the current point and neighboring points, you can use the difference to get 420 // the normal. 421 vec3 smallVec = vec3(0.005, 0, 0); 422 vec3 normal = vec3(dist - DistanceToObject(pos - smallVec.xyy), 423 dist - DistanceToObject(pos - smallVec.yxy), 424 dist - DistanceToObject(pos - smallVec.yyx)); 425 426 /*if (pos.y <= waterLevel-2.995) // water waves? 427 { 428 normal += SpiralNoise3D(pos*32.0+vec3(iGlobalTime*8.0,0.0,0.0))*0.0001; 429 normal += SpiralNoise3D(pos*27.0+vec3(0.0,0.0, iGlobalTime* 10.333))*0.0001; 430 normal += SpiralNoiseD(pos*37.0+vec3(0.0,iGlobalTime* 14.333,0.0))*0.0002; 431 }*/ 432 normal = normalize(normal); 433 434 // calculate 2 ambient occlusion values. One for global stuff and one 435 // for local stuff - so the green sphere light source can also have ambient. 436 float ambientS = 1.0; 437 //ambient *= saturate(DistanceToObject(pos + normal * 0.1)*10.0); 438 ambientS *= saturate(DistanceToObject(pos + normal * 0.2)*5.0); 439 ambientS *= saturate(DistanceToObject(pos + normal * 0.4)*2.5); 440 ambientS *= saturate(DistanceToObject(pos + normal * 0.8)*1.25); 441 float ambient = ambientS * saturate(DistanceToObject(pos + normal * 1.6)*1.25*0.5); 442 ambient *= saturate(DistanceToObject(pos + normal * 3.2)*1.25*0.25); 443 ambient *= saturate(DistanceToObject(pos + normal * 6.4)*1.25*0.125); 444 //ambient = max(0.05, pow(ambient, 0.3)); // tone down ambient with a pow and min clamp it. 445 ambient = saturate(ambient); 446 447 // Trace a ray toward the sun for sun shadows 448 float sunShadow = 1.0; 449 float iter = 0.2; 450 for (int i = 0; i < 10; i++) 451 { 452 float tempDist = DistanceToObject(pos + sunDir * iter); 453 sunShadow *= saturate(tempDist*10.0); 454 if (tempDist <= 0.0) break; 455 iter *= 1.5; // constant is more reliable than distance-based 456 //iter += max(0.2, tempDist)*1.2; 457 } 458 float sunSet = saturate(sunDir.y*4.0); // sunset dims the sun 459 sunShadow = saturate(sunShadow) * sunSet; 460 461 // calculate the reflection vector for highlights 462 vec3 ref = reflect(relVec, normal); 463 464 // pulse the ball light source 465 vec3 ballGlow = vec3(0.1, 0.97, 0.1) * abs(SpiralNoise3D(vec3(iGlobalTime*1.3))); 466 467 // ------ Calculate texture color of the rock ------ 468 // basic orange and white blended together with noise 469 vec3 texColor = mix(vec3(0.95, 1.0, 1.0), vec3(0.9, 0.7, 0.5), pow(abs(SpiralNoise3D(pos*1.0)-1.0), 0.6) ); 470 // make the undersides darker greenish 471 texColor = mix(vec3(0.2, 0.2, 0.1), texColor, saturate(normal.y)); 472 // fade to reddish/orange closer to the water level 473 texColor = mix(texColor, vec3(0.64, 0.2, 0.1) , saturate(-0.4-pos.y)); 474 // some more variation to the color vertically 475 texColor = mix(texColor, vec3(0.2, 0.13, 0.02) , pow(saturate(pos.y*0.125+0.5), 2.0)); 476 // give the rock a stratified, layered look 477 float rockLayers = abs(cos(pos.y*1.5+ SpiralNoiseD(pos*vec3(1.0, 2.0, 1.0)*4.0)*0.2 )); 478 texColor += vec3(0.7, 0.4, 0.3)*(1.0-pow(rockLayers, 0.3)); 479 480 // make the water orange. I'm trying for that "nickel tailings" look. 481 texColor = mix(texColor, vec3(1.4, 0.15, 0.05) + SpiralNoise3D(pos)*0.025, saturate((-pos.y-1.45)*17.0)); 482 // make the sphere white 483 if (length(pos) <= 2.01) texColor = vec3(1.0); 484 // don't let it get too saturated or dark 485 texColor = max(texColor, 0.05); 486 487 // ------ Calculate lighting color ------ 488 // Start with sun color, standard lighting equation, and shadow 489 vec3 lightColor = vec3(1.0, 0.75, 0.75) * saturate(dot(sunDir, normal)) * sunShadow*1.5; 490 // sky color, hemisphere light equation approximation, anbient occlusion, sunset multiplier 491 lightColor += vec3(1.0,0.3,0.6) * ( dot(sunDir, normal) * 0.5 + 0.5 ) * ambient * 0.25 * skyMultiplier; 492 // Make the ball cast light. Distance to the 4th light falloff looked best. Use local ambient occlusion. 493 float lp = length(pos) - 1.0; 494 lightColor += ambientS*(ballGlow*1.2 * saturate(dot(normal, -pos)*0.5+0.5) / (lp*lp*lp*lp)); 495 496 // finally, apply the light to the texture. 497 finalColor = texColor * lightColor; 498 499 // Make the water reflect the sun (leaving out sky reflection for no good reason) 500 vec3 refColor = GetSunColorReflection(ref, sunDir)*0.68; 501 finalColor += refColor * sunShadow * saturate(normal.y*normal.y) * saturate(-(pos.y+1.35)*16.0); 502 503 // make the ball itself glow 504 finalColor += pow(saturate(1.0 - length(pos)*0.4925), 0.65) * ballGlow*6.1; 505 // fog that fades to reddish plus the sun color so that fog is brightest towards sun 506 finalColor = mix(vec3(1.0, 0.41, 0.41)*skyMultiplier + min(vec3(0.25),GetSunColorSmall(relVec, sunDir))*2.0*sunSet, finalColor, exp(-t*0.03)); 507 } 508 else 509 { 510 // Our ray trace hit nothing, so draw sky. 511 // fade the sky color, multiply sunset dimming 512 finalColor = mix(vec3(1.0, 0.5, 0.5), vec3(0.40, 0.25, 0.91), saturate(relVec.y))*skyMultiplier; 513 // add the sun 514 finalColor += GetSunColorSmall(relVec, sunDir);// + vec3(0.1, 0.1, 0.1); 515 } 516 517 //finalColor = vec3(Hash2d(uv)*0.91, Hash2d(uv+47.0)*0.91, 0.0); 518 // vignette? 519 finalColor *= vec3(1.0) * saturate(1.0 - length(uv/2.5)); 520 finalColor *= 1.3; 521 522 // output the final color with sqrt for "gamma correction" 523 fragColor = vec4(sqrt(clamp(finalColor, 0.0, 1.0)),1.0); 524} 525 526void main(void) 527{ 528 //just some shit to wrap shadertoy's stuff 529 vec2 FragCoord = vTexCoord.xy*OutputSize.xy; 530 mainImage(FragColor,FragCoord); 531} 532#endif 533