1#version 330 2 3// Compatibility #ifdefs needed for parameters 4#ifdef GL_ES 5#define COMPAT_PRECISION mediump 6#else 7#define COMPAT_PRECISION 8#endif 9 10// Parameter lines go here: 11#pragma parameter RETRO_PIXEL_SIZE "Retro Pixel Size" 0.84 0.0 1.0 0.01 12#ifdef PARAMETER_UNIFORM 13// All parameter floats need to have COMPAT_PRECISION in front of them 14uniform COMPAT_PRECISION float RETRO_PIXEL_SIZE; 15#else 16#define RETRO_PIXEL_SIZE 0.84 17#endif 18 19#if defined(VERTEX) 20 21#if __VERSION__ >= 130 22#define COMPAT_VARYING out 23#define COMPAT_ATTRIBUTE in 24#define COMPAT_TEXTURE texture 25#else 26#define COMPAT_VARYING varying 27#define COMPAT_ATTRIBUTE attribute 28#define COMPAT_TEXTURE texture2D 29#endif 30 31#ifdef GL_ES 32#define COMPAT_PRECISION mediump 33#else 34#define COMPAT_PRECISION 35#endif 36 37COMPAT_ATTRIBUTE vec4 VertexCoord; 38COMPAT_ATTRIBUTE vec4 COLOR; 39COMPAT_ATTRIBUTE vec4 TexCoord; 40COMPAT_VARYING vec4 COL0; 41COMPAT_VARYING vec4 TEX0; 42// out variables go here as COMPAT_VARYING whatever 43 44vec4 _oPosition1; 45uniform mat4 MVPMatrix; 46uniform COMPAT_PRECISION int FrameDirection; 47uniform COMPAT_PRECISION int FrameCount; 48uniform COMPAT_PRECISION vec2 OutputSize; 49uniform COMPAT_PRECISION vec2 TextureSize; 50uniform COMPAT_PRECISION vec2 InputSize; 51 52// compatibility #defines 53#define vTexCoord TEX0.xy 54#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 55#define OutSize vec4(OutputSize, 1.0 / OutputSize) 56 57void main() 58{ 59 gl_Position = MVPMatrix * VertexCoord; 60 TEX0.xy = VertexCoord.xy; 61// Paste vertex contents here: 62} 63 64#elif defined(FRAGMENT) 65 66#if __VERSION__ >= 130 67#define COMPAT_VARYING in 68#define COMPAT_TEXTURE texture 69out vec4 FragColor; 70#else 71#define COMPAT_VARYING varying 72#define FragColor gl_FragColor 73#define COMPAT_TEXTURE texture2D 74#endif 75 76#ifdef GL_ES 77#ifdef GL_FRAGMENT_PRECISION_HIGH 78precision highp float; 79#else 80precision mediump float; 81#endif 82#define COMPAT_PRECISION mediump 83#else 84#define COMPAT_PRECISION 85#endif 86 87uniform COMPAT_PRECISION int FrameDirection; 88uniform COMPAT_PRECISION int FrameCount; 89uniform COMPAT_PRECISION vec2 OutputSize; 90uniform COMPAT_PRECISION vec2 TextureSize; 91uniform COMPAT_PRECISION vec2 InputSize; 92uniform sampler2D Texture; 93COMPAT_VARYING vec4 TEX0; 94// in variables go here as COMPAT_VARYING whatever 95 96// compatibility #defines 97#define Source Texture 98#define vTexCoord TEX0.xy 99 100#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 101#define OutSize vec4(OutputSize, 1.0 / OutputSize) 102 103// delete all 'params.' or 'registers.' or whatever in the fragment 104float iGlobalTime = float(FrameCount)*0.025; 105vec2 iResolution = OutputSize.xy; 106 107// Mountain Peak - TDM - 2014-09-26 108// https://www.shadertoy.com/view/llK3WR 109 110// Terrain with procedural hydraulic erosion. 111 112// "Mountain Peak" by Alexander Alekseev aka TDM - 2014 113// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 114 115#define WIND 116 117const int NUM_STEPS = 38; 118const int NUM_STEPS_VOLUME = 10; 119const float STRIDE = 0.75; 120const float STRIDE_VOLUME = 1.0; 121const float PI = 3.1415; 122const float EPSILON = 1e-3; 123 124// terrain 125const int ITER_GEOMETRY = 4; 126const int ITER_FRAGMENT = 7; 127 128const float TERR_HEIGHT = 12.0; 129const float TERR_WARP = 0.7; 130const float TERR_OCTAVE_AMP = 0.55; 131const float TERR_OCTAVE_FREQ = 2.5; 132const float TERR_MULTIFRACT = 0.27; 133const float TERR_CHOPPY = 1.9; 134const float TERR_FREQ = 0.24; 135const vec2 TERR_OFFSET = vec2(13.5,15.); 136 137const vec3 SKY_COLOR = vec3(0.5,0.59,0.75) * 0.6; 138const vec3 SUN_COLOR = vec3(1.,1.,0.98) * 0.75; 139const vec3 COLOR_SNOW = vec3(1.0,1.0,1.1) * 2.0; 140const vec3 COLOR_ROCK = vec3(0.0,0.1,0.1); 141vec3 light = normalize(vec3(1.0,1.0,-0.3)); 142 143// math 144mat3 fromEuler(vec3 ang) { 145 vec2 a1 = vec2(sin(ang.x),cos(ang.x)); 146 vec2 a2 = vec2(sin(ang.y),cos(ang.y)); 147 vec2 a3 = vec2(sin(ang.z),cos(ang.z)); 148 mat3 m; 149 m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x); 150 m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x); 151 m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y); 152 return m; 153} 154float saturate(float x) { return clamp(x,0.,1.); } 155 156/*float hash(vec2 p) { 157 float h = dot(p,vec2(127.1,311.7)); 158 return fract(sin(h)*43758.5453123); 159}*/ 160float hash(vec2 p) { 161 uint n = floatBitsToUint(p.x * 122.0 + p.y); 162 n = (n << 13U) ^ n; 163 n = n * (n * n * 15731U + 789221U) + 1376312589U; 164 return uintBitsToFloat( (n>>9U) | 0x3f800000U ) - 1.0; 165} 166 167float hash3(vec3 p) { 168 return fract(sin(p.x*p.y*p.z)*347624.531834); 169} 170 171// 3d noise 172float noise_3(in vec3 p) { 173 vec3 i = floor( p ); 174 vec3 f = fract( p ); 175 vec3 u = f*f*(3.0-2.0*f); 176 177 float a = hash3( i + vec3(0.0,0.0,0.0) ); 178 float b = hash3( i + vec3(1.0,0.0,0.0) ); 179 float c = hash3( i + vec3(0.0,1.0,0.0) ); 180 float d = hash3( i + vec3(1.0,1.0,0.0) ); 181 float v1 = mix(mix(a,b,u.x), mix(c,d,u.x), u.y); 182 183 a = hash3( i + vec3(0.0,0.0,1.0) ); 184 b = hash3( i + vec3(1.0,0.0,1.0) ); 185 c = hash3( i + vec3(0.0,1.0,1.0) ); 186 d = hash3( i + vec3(1.0,1.0,1.0) ); 187 float v2 = mix(mix(a,b,u.x), mix(c,d,u.x), u.y); 188 189 return abs(mix(v1,v2,u.z)); 190} 191 192// noise with analytical derivatives (thanks to iq) 193vec3 noise_deriv(in vec2 p) { 194 vec2 i = floor( p ); 195 vec2 f = fract( p ); 196 vec2 u = f*f*(3.0-2.0*f); 197 198 float a = hash( i + vec2(0.0,0.0) ); 199 float b = hash( i + vec2(1.0,0.0) ); 200 float c = hash( i + vec2(0.0,1.0) ); 201 float d = hash( i + vec2(1.0,1.0) ); 202 float h1 = mix(a,b,u.x); 203 float h2 = mix(c,d,u.x); 204 205 return vec3(abs(mix(h1,h2,u.y)), 206 6.0*f*(1.0-f)*(vec2(b-a,c-a)+(a-b-c+d)*u.yx)); 207} 208 209// lighting 210float diffuse(vec3 n,vec3 l,float p) { return pow(max(dot(n,l),0.0),p); } 211float specular(vec3 n,vec3 l,vec3 e,float s) { 212 float nrm = (s + 8.0) / (3.1415 * 8.0); 213 return pow(max(dot(reflect(e,n),l),0.0),s) * nrm; 214} 215 216// terrain 217vec3 octave(vec2 uv) { 218 vec3 n = noise_deriv(uv); 219 return vec3(pow(n.x,TERR_CHOPPY), n.y, n.z); 220} 221 222float map(vec3 p) { 223 float frq = TERR_FREQ; 224 float amp = 1.0; 225 vec2 uv = p.xz * frq + TERR_OFFSET; 226 vec2 dsum = vec2(0.0); 227 228 float h = 0.0; 229 for(int i = 0; i < ITER_GEOMETRY; i++) { 230 vec3 n = octave((uv - dsum * TERR_WARP) * frq); 231 h += n.x * amp; 232 233 dsum += n.yz * (n.x*2.0-1.0) * amp; 234 frq *= TERR_OCTAVE_FREQ; 235 amp *= TERR_OCTAVE_AMP; 236 amp *= pow(n.x,TERR_MULTIFRACT); 237 } 238 h *= TERR_HEIGHT / (1.0 + dot(p.xz,p.xz) * 1e-3); 239 return p.y - h; 240} 241float map_detailed(vec3 p) { 242 float frq = TERR_FREQ; 243 float amp = 1.0; 244 vec2 uv = p.xz * frq + TERR_OFFSET; 245 vec2 dsum = vec2(0.0); 246 247 float h = 0.0; 248 for(int i = 0; i < ITER_FRAGMENT; i++) { 249 vec3 n = octave((uv - dsum * TERR_WARP) * frq); 250 h += n.x * amp; 251 252 dsum += n.yz * (n.x*2.0-1.0) * amp; 253 frq *= TERR_OCTAVE_FREQ; 254 amp *= TERR_OCTAVE_AMP; 255 amp *= pow(n.x,TERR_MULTIFRACT); 256 } 257 h *= TERR_HEIGHT / (1.0 + dot(p.xz,p.xz) * 1e-3); 258 return p.y - h; 259} 260float map_noise(vec3 p) { 261 p *= 0.5; 262 float ret = noise_3(p); 263 ret += noise_3(p * 2.0) * 0.5; 264 ret = (ret - 1.0) * 5.0; 265 return saturate(ret * 0.5 + 0.5); 266} 267 268// tracing 269vec3 getNormal(vec3 p, float eps) { 270 vec3 n; 271 n.y = map_detailed(p); 272 n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y; 273 n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y; 274 n.y = eps; 275 return normalize(n); 276} 277 278float hftracing(vec3 ori, vec3 dir, out vec3 p, out float t) { 279 float d = 0.0; 280 t = 0.0; 281 for(int i = 0; i < NUM_STEPS; i++) { 282 p = ori + dir * t; 283 d = map(p); 284 if(d < 0.0) break; 285 t += d*0.6; 286 } 287 return d; 288} 289 290float volume_tracing(vec3 ori, vec3 dir, float maxt) { 291 float d = 0.0; 292 float t = 0.0; 293 float count = 0.0; 294 for(int i = 0; i < NUM_STEPS_VOLUME; i++) { 295 vec3 p = ori + dir * t; 296 d += map_noise(p); 297 if(t >= maxt) break; 298 t += STRIDE_VOLUME; 299 count += 1.0; 300 } 301 return d / count; 302} 303 304// color 305vec3 sky_color(vec3 e) { 306 e.y = max(e.y,0.0); 307 vec3 ret; 308 ret.x = pow(1.0-e.y,3.0); 309 ret.y = pow(1.0-e.y, 1.2); 310 ret.z = 0.7+(1.0-e.y)*0.3; 311 return ret; 312} 313vec3 terr_color(in vec3 p, in vec3 n, in vec3 eye, in vec3 dist) { 314 float slope = 1.0-dot(n,vec3(0.,1.,0.)); 315 vec3 ret = mix(COLOR_SNOW,COLOR_ROCK,smoothstep(0.0,0.2,slope*slope)); 316 ret = mix(ret,COLOR_SNOW,saturate(smoothstep(0.6,0.8,slope+(p.y-TERR_HEIGHT*0.5)*0.05))); 317 return ret; 318} 319 320// main 321void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 322 vec2 uv = fragCoord.xy / iResolution.xy; 323 uv = uv * 2.0 - 1.0; 324 uv.x *= iResolution.x / iResolution.y; 325 float time = iGlobalTime * 0.1; 326 327 // ray 328#ifdef MOUSE 329 vec3 ang = vec3(sin(time*6.0)*0.1,0.1,-time + iMouse.x*0.01); 330#else 331 vec3 ang = vec3(sin(time*6.0)*0.1,0.1,-time + 0.0*0.01); 332#endif 333 mat3 rot = fromEuler(ang); 334 335 vec3 ori = vec3(0.0,5.0,40.0); 336 vec3 dir = normalize(vec3(uv.xy,-2.0)); 337 dir.z += length(uv) * 0.12; 338 dir = normalize(dir) * rot; 339 ori = ori * rot; 340 ori.y -= map(ori) * 0.75 - 3.0; 341 342 // tracing 343 vec3 p; 344 float t; 345 float dens = hftracing(ori,dir,p,t); 346 vec3 dist = p - ori; 347 vec3 n = getNormal(p, dot(dist,dist)* (1e-1 / iResolution.x)); 348 349 // terrain 350 vec3 color = terr_color(p,n,dir,dist) * SKY_COLOR; 351 color += vec3(diffuse(n,light,2.0) * SUN_COLOR); 352 color += vec3(specular(n,light,dir,20.0) * SUN_COLOR*0.4); 353 354 // fog 355 vec3 fog = sky_color(vec3(dir.x,0.,dir.z)); 356 color = mix(color,fog,saturate(min(length(dist)*0.018, dot(p.xz,p.xz)*0.001))); 357 358 // sky 359 color = mix(sky_color(dir),color,step(dens,4.0)); 360 color += pow(max(dot(dir,light),0.0),3.0)*0.3; 361 362 // wind 363#ifdef WIND 364 float wind = volume_tracing(ori,dir,t) * saturate(1.8 - p.y * 0.2); 365 color = mix(color,fog, wind * 1.6); 366#endif 367 368 // post 369 color = (1.0 - exp(-color)) * 1.5; 370 color = pow(color,vec3(0.85)); 371 fragColor = vec4(color,1.0); 372} 373 374void main(void) 375{ 376 //just some shit to wrap shadertoy's stuff 377 vec2 FragCoord = vTexCoord.xy*OutputSize.xy; 378 mainImage(FragColor,FragCoord); 379} 380#endif 381