Advertisement
Guest User

Untitled

a guest
Feb 24th, 2018
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 45.16 KB | None | 0 0
  1. // Planet Shadertoy. Created by Reinder Nijhoff 2015
  2. // @reindernijhoff
  3. //
  4. // https://www.shadertoy.com/view/4tjGRh
  5. //
  6.  
  7. //#define HIGH_QUALITY
  8. //#define MED_QUALITY
  9. //#define LOW_QUALITY
  10. #define VERY_LOW_QUALITY
  11.  
  12. const float PI = 3.14159265359;
  13. const float DEG_TO_RAD = (PI / 180.0);
  14. const float MAX = 10000.0;
  15.  
  16. const float EARTH_RADIUS = 1000.;
  17. const float EARTH_ATMOSPHERE = 5.;
  18. const float EARTH_CLOUDS = 1.;
  19.  
  20. const float RING_INNER_RADIUS = 1500.;
  21. const float RING_OUTER_RADIUS = 2300.;
  22. const float RING_HEIGHT = 2.;
  23.  
  24. #ifdef HIGH_QUALITY
  25. const int SEA_NUM_STEPS = 7;
  26. const int TERRAIN_NUM_STEPS = 140;
  27. const int ASTEROID_NUM_STEPS = 11;
  28. const int ASTEROID_NUM_BOOL_SUB = 7;
  29. const int RING_VOXEL_STEPS = 25;
  30. const float ASTEROID_MAX_DISTANCE = 1.1;
  31. const int FBM_STEPS = 4;
  32. const int ATMOSPHERE_NUM_OUT_SCATTER = 5;
  33. const int ATMOSPHERE_NUM_IN_SCATTER = 7;
  34.  
  35. #define DISPLAY_LLAMEL
  36. #define DISPLAY_CLOUDS
  37. #define DISPLAY_CLOUDS_DETAIL
  38. #define DISPLAY_TERRAIN_DETAIL
  39. #endif
  40.  
  41. #ifdef MED_QUALITY
  42. const int SEA_NUM_STEPS = 6;
  43. const int TERRAIN_NUM_STEPS = 100;
  44. const int ASTEROID_NUM_STEPS = 10;
  45. const int ASTEROID_NUM_BOOL_SUB = 6;
  46. const int RING_VOXEL_STEPS = 24;
  47. const float ASTEROID_MAX_DISTANCE = 1.;
  48. const int FBM_STEPS = 4;
  49. const int ATMOSPHERE_NUM_OUT_SCATTER = 4;
  50. const int ATMOSPHERE_NUM_IN_SCATTER = 6;
  51. #define DISPLAY_CLOUDS
  52. #define DISPLAY_TERRAIN_DETAIL
  53. #define DISPLAY_CLOUDS_DETAIL
  54. #endif
  55.  
  56. #ifdef LOW_QUALITY
  57. const int SEA_NUM_STEPS = 5;
  58. const int TERRAIN_NUM_STEPS = 75;
  59. const int ASTEROID_NUM_STEPS = 9;
  60. const int ASTEROID_NUM_BOOL_SUB = 5;
  61. const int RING_VOXEL_STEPS = 20;
  62. const float ASTEROID_MAX_DISTANCE = .85;
  63. const int FBM_STEPS = 3;
  64. const int ATMOSPHERE_NUM_OUT_SCATTER = 3;
  65. const int ATMOSPHERE_NUM_IN_SCATTER = 5;
  66. #endif
  67.  
  68. #ifdef VERY_LOW_QUALITY
  69. const int SEA_NUM_STEPS = 4;
  70. const int TERRAIN_NUM_STEPS = 60;
  71. const int ASTEROID_NUM_STEPS = 7;
  72. const int ASTEROID_NUM_BOOL_SUB = 4;
  73. const int RING_VOXEL_STEPS = 16;
  74. const float ASTEROID_MAX_DISTANCE = .67;
  75. const int FBM_STEPS = 3;
  76. const int ATMOSPHERE_NUM_OUT_SCATTER = 2;
  77. const int ATMOSPHERE_NUM_IN_SCATTER = 4;
  78. #define HIDE_TERRAIN
  79. #endif
  80.  
  81. const vec3 SUN_DIRECTION = vec3( .940721, .28221626, .18814417 );
  82. const vec3 SUN_COLOR = vec3(.3, .21, .165);
  83.  
  84. float time;
  85.  
  86. //-----------------------------------------------------
  87. // Noise functions
  88. //-----------------------------------------------------
  89.  
  90. float hash( const in float n ) {
  91. return fract(sin(n)*43758.5453123);
  92. }
  93. float hash( const in vec2 p ) {
  94. float h = dot(p,vec2(127.1,311.7));
  95. return fract(sin(h)*43758.5453123);
  96. }
  97. float hash( const in vec3 p ) {
  98. float h = dot(p,vec3(127.1,311.7,758.5453123));
  99. return fract(sin(h)*43758.5453123);
  100. }
  101. vec3 hash31( const in float p) {
  102. vec3 h = vec3(1275.231,4461.7,7182.423) * p;
  103. return fract(sin(h)*43758.543123);
  104. }
  105. vec3 hash33( const in vec3 p) {
  106. return vec3( hash(p), hash(p.zyx), hash(p.yxz) );
  107. }
  108.  
  109. float noise( const in float p ) {
  110. float i = floor( p );
  111. float f = fract( p );
  112. float u = f*f*(3.0-2.0*f);
  113. return -1.0+2.0* mix( hash( i + 0. ), hash( i + 1. ), u);
  114. }
  115.  
  116. float noise( const in vec2 p ) {
  117. vec2 i = floor( p );
  118. vec2 f = fract( p );
  119. vec2 u = f*f*(3.0-2.0*f);
  120. return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),
  121. hash( i + vec2(1.0,0.0) ), u.x),
  122. mix( hash( i + vec2(0.0,1.0) ),
  123. hash( i + vec2(1.0,1.0) ), u.x), u.y);
  124. }
  125. float noise( const in vec3 x ) {
  126. vec3 p = floor(x);
  127. vec3 f = fract(x);
  128. f = f*f*(3.0-2.0*f);
  129. float n = p.x + p.y*157.0 + 113.0*p.z;
  130. return mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
  131. mix( hash(n+157.0), hash(n+158.0),f.x),f.y),
  132. mix(mix( hash(n+113.0), hash(n+114.0),f.x),
  133. mix( hash(n+270.0), hash(n+271.0),f.x),f.y),f.z);
  134. }
  135.  
  136. float tri( const in vec2 p ) {
  137. return 0.5*(cos(6.2831*p.x) + cos(6.2831*p.y));
  138.  
  139. }
  140.  
  141. const mat2 m2 = mat2( 0.80, -0.60, 0.60, 0.80 );
  142.  
  143. float fbm( in vec2 p ) {
  144. float f = 0.0;
  145. f += 0.5000*noise( p ); p = m2*p*2.02;
  146. f += 0.2500*noise( p ); p = m2*p*2.03;
  147. f += 0.1250*noise( p );
  148.  
  149. #ifndef LOW_QUALITY
  150. #ifndef VERY_LOW_QUALITY
  151. p = m2*p*2.01;
  152. f += 0.0625*noise( p );
  153. #endif
  154. #endif
  155. return f/0.9375;
  156. }
  157.  
  158. float fbm( const in vec3 p, const in float a, const in float f) {
  159. float ret = 0.0;
  160. float amp = 1.0;
  161. float frq = 1.0;
  162. for(int i = 0; i < FBM_STEPS; i++) {
  163. float n = pow(noise(p * frq),2.0);
  164. ret += n * amp;
  165. frq *= f;
  166. amp *= a * (pow(n,0.2));
  167. }
  168. return ret;
  169. }
  170.  
  171. //-----------------------------------------------------
  172. // Lightning functions
  173. //-----------------------------------------------------
  174.  
  175. float diffuse( const in vec3 n, const in vec3 l) {
  176. return clamp(dot(n,l),0.,1.);
  177. }
  178.  
  179. float specular( const in vec3 n, const in vec3 l, const in vec3 e, const in float s) {
  180. float nrm = (s + 8.0) / (3.1415 * 8.0);
  181. return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
  182. }
  183.  
  184. float fresnel( const in vec3 n, const in vec3 e, float s ) {
  185. return pow(clamp(1.-dot(n,e), 0., 1.),s);
  186. }
  187.  
  188. //-----------------------------------------------------
  189. // Math functions
  190. //-----------------------------------------------------
  191.  
  192. vec2 rotate(float angle, vec2 v) {
  193. return vec2(cos(angle) * v.x + sin(angle) * v.y, cos(angle) * v.y - sin(angle) * v.x);
  194. }
  195.  
  196. float boolSub(float a,float b) {
  197. return max(a,-b);
  198. }
  199. float sphere(vec3 p,float r) {
  200. return length(p)-r;
  201. }
  202.  
  203. //-----------------------------------------------------
  204. // Intersection functions (by iq)
  205. //-----------------------------------------------------
  206.  
  207. vec3 nSphere( in vec3 pos, in vec4 sph ) {
  208. return (pos-sph.xyz)/sph.w;
  209. }
  210.  
  211. float iSphere( in vec3 ro, in vec3 rd, in vec4 sph ) {
  212. vec3 oc = ro - sph.xyz;
  213. float b = dot( oc, rd );
  214. float c = dot( oc, oc ) - sph.w*sph.w;
  215. float h = b*b - c;
  216. if( h<0.0 ) return -1.0;
  217. return -b - sqrt( h );
  218. }
  219.  
  220. float iCSphereF( vec3 p, vec3 dir, float r ) {
  221. float b = dot( p, dir );
  222. float c = dot( p, p ) - r * r;
  223. float d = b * b - c;
  224. if ( d < 0.0 ) return -MAX;
  225. return -b + sqrt( d );
  226. }
  227.  
  228. vec2 iCSphere2( vec3 p, vec3 dir, float r ) {
  229. float b = dot( p, dir );
  230. float c = dot( p, p ) - r * r;
  231. float d = b * b - c;
  232. if ( d < 0.0 ) return vec2( MAX, -MAX );
  233. d = sqrt( d );
  234. return vec2( -b - d, -b + d );
  235. }
  236.  
  237. vec3 nPlane( in vec3 ro, in vec4 obj ) {
  238. return obj.xyz;
  239. }
  240.  
  241. float iPlane( in vec3 ro, in vec3 rd, in vec4 pla ) {
  242. return (-pla.w - dot(pla.xyz,ro)) / dot( pla.xyz, rd );
  243. }
  244.  
  245. //-----------------------------------------------------
  246. // Wet stone by TDM
  247. //
  248. // https://www.shadertoy.com/view/ldSSzV
  249. //-----------------------------------------------------
  250.  
  251. const float ASTEROID_TRESHOLD = 0.001;
  252. const float ASTEROID_EPSILON = 1e-6;
  253. const float ASTEROID_DISPLACEMENT = 0.1;
  254. const float ASTEROID_RADIUS = 0.13;
  255.  
  256. const vec3 RING_COLOR_1 = vec3(0.42,0.3,0.2);
  257. const vec3 RING_COLOR_2 = vec3(0.51,0.41,0.32) * 0.2;
  258.  
  259. float asteroidRock( const in vec3 p, const in vec3 id ) {
  260. float d = sphere(p,ASTEROID_RADIUS);
  261. for(int i = 0; i < ASTEROID_NUM_BOOL_SUB; i++) {
  262. float ii = float(i)+id.x;
  263. float r = (ASTEROID_RADIUS*2.5) + ASTEROID_RADIUS*hash(ii);
  264. vec3 v = normalize(hash31(ii) * 2.0 - 1.0);
  265. d = boolSub(d,sphere(p+v*r,r * 0.8));
  266. }
  267. return d;
  268. }
  269.  
  270. float asteroidMap( const in vec3 p, const in vec3 id) {
  271. float d = asteroidRock(p, id) + noise(p*4.0) * ASTEROID_DISPLACEMENT;
  272. return d;
  273. }
  274.  
  275. float asteroidMapDetailed( const in vec3 p, const in vec3 id) {
  276. float d = asteroidRock(p, id) + fbm(p*4.0,0.4,2.96) * ASTEROID_DISPLACEMENT;
  277. return d;
  278. }
  279.  
  280. void asteroidTransForm(inout vec3 ro, const in vec3 id ) {
  281. float xyangle = (id.x-.5)*time*2.;
  282. ro.xy = rotate( xyangle, ro.xy );
  283.  
  284. float yzangle = (id.y-.5)*time*2.;
  285. ro.yz = rotate( yzangle, ro.yz );
  286. }
  287.  
  288. void asteroidUnTransForm(inout vec3 ro, const in vec3 id ) {
  289. float yzangle = (id.y-.5)*time*2.;
  290. ro.yz = rotate( -yzangle, ro.yz );
  291.  
  292. float xyangle = (id.x-.5)*time*2.;
  293. ro.xy = rotate( -xyangle, ro.xy );
  294. }
  295.  
  296. vec3 asteroidGetNormal(vec3 p, vec3 id) {
  297. asteroidTransForm( p, id );
  298.  
  299. vec3 n;
  300. n.x = asteroidMapDetailed(vec3(p.x+ASTEROID_EPSILON,p.y,p.z), id);
  301. n.y = asteroidMapDetailed(vec3(p.x,p.y+ASTEROID_EPSILON,p.z), id);
  302. n.z = asteroidMapDetailed(vec3(p.x,p.y,p.z+ASTEROID_EPSILON), id);
  303. n = normalize(n-asteroidMapDetailed(p, id));
  304.  
  305. asteroidUnTransForm( n, id );
  306. return n;
  307. }
  308.  
  309. vec2 asteroidSpheretracing(vec3 ori, vec3 dir, vec3 id) {
  310. asteroidTransForm( ori, id );
  311. asteroidTransForm( dir, id );
  312.  
  313. vec2 td = vec2(0.0);
  314. for(int i = 0; i < ASTEROID_NUM_STEPS; i++) {
  315. vec3 p = ori + dir * td.x;
  316. td.y = asteroidMap(p, id);
  317. if(td.y < ASTEROID_TRESHOLD) break;
  318. td.x += (td.y-ASTEROID_TRESHOLD) * 0.9;
  319. }
  320. return td;
  321. }
  322.  
  323. vec3 asteroidGetStoneColor(vec3 p, float c, vec3 l, vec3 n, vec3 e) {
  324. return mix( diffuse(n,l)*RING_COLOR_1*SUN_COLOR, SUN_COLOR*specular(n,l,e,3.0), .5*fresnel(n,e,5.));
  325. }
  326.  
  327. //-----------------------------------------------------
  328. // Ring (by me ;))
  329. //-----------------------------------------------------
  330.  
  331. const float RING_DETAIL_DISTANCE = 40.;
  332. const float RING_VOXEL_STEP_SIZE = .03;
  333.  
  334. vec3 ringShadowColor( const in vec3 ro ) {
  335. if( iSphere( ro, SUN_DIRECTION, vec4( 0., 0., 0., EARTH_RADIUS ) ) > 0. ) {
  336. return vec3(0.);
  337. }
  338. return vec3(1.);
  339. }
  340.  
  341. bool ringMap( const in vec3 ro ) {
  342. return ro.z < RING_HEIGHT/RING_VOXEL_STEP_SIZE && hash(ro)<.5;
  343. }
  344.  
  345. vec4 renderRingNear( const in vec3 ro, const in vec3 rd ) {
  346. // find startpoint
  347. float d1 = iPlane( ro, rd, vec4( 0., 0., 1., RING_HEIGHT ) );
  348. float d2 = iPlane( ro, rd, vec4( 0., 0., 1., -RING_HEIGHT ) );
  349.  
  350. if( d1 < 0. && d2 < 0. ) return vec4( 0. );
  351.  
  352. float d = min( max(d1,0.), max(d2,0.) );
  353.  
  354. if( d > ASTEROID_MAX_DISTANCE ) return vec4( 0. );
  355.  
  356. vec3 ros = ro + rd*d;
  357.  
  358. // avoid precision problems..
  359. vec2 mroxy = mod(ros.xy, vec2(10.));
  360. vec2 roxy = ros.xy - mroxy;
  361. ros.xy -= roxy;
  362. ros /= RING_VOXEL_STEP_SIZE;
  363. ros.xy -= vec2(.013,.112)*time*.5;
  364.  
  365. vec3 pos = floor(ros);
  366. vec3 ri = 1.0/rd;
  367. vec3 rs = sign(rd);
  368. vec3 dis = (pos-ros + 0.5 + rs*0.5) * ri;
  369.  
  370. float alpha = 0., dint;
  371. vec3 offset = vec3(0.), id, asteroidro;
  372. vec2 asteroid;
  373.  
  374. for( int i=0; i<RING_VOXEL_STEPS; i++ ) {
  375. if( ringMap(pos) ) {
  376. id = hash33(pos);
  377. offset = id*(1.-2.*ASTEROID_RADIUS)+ASTEROID_RADIUS;
  378. dint = iSphere( ros, rd, vec4(pos+offset, ASTEROID_RADIUS) );
  379.  
  380. if( dint > 0. ) {
  381. asteroidro = ros+rd*dint-(pos+offset);
  382. asteroid = asteroidSpheretracing( asteroidro, rd, id );
  383.  
  384. if( asteroid.y < .1 ) {
  385. alpha = 1.;
  386. break;
  387. }
  388. }
  389.  
  390. }
  391. vec3 mm = step(dis.xyz, dis.yxy) * step(dis.xyz, dis.zzx);
  392. dis += mm * rs * ri;
  393. pos += mm * rs;
  394. }
  395.  
  396. if( alpha > 0. ) {
  397. vec3 intersection = ros + rd*(asteroid.x+dint);
  398. vec3 n = asteroidGetNormal( asteroidro + rd*asteroid.x, id );
  399.  
  400. vec3 col = asteroidGetStoneColor(intersection, .1, SUN_DIRECTION, n, rd);
  401.  
  402. intersection *= RING_VOXEL_STEP_SIZE;
  403. intersection.xy += roxy;
  404. col *= ringShadowColor( intersection );
  405.  
  406. return vec4( col, 1.-smoothstep(0.4*ASTEROID_MAX_DISTANCE, 0.5* ASTEROID_MAX_DISTANCE, distance( intersection, ro ) ) );
  407. }
  408.  
  409. return vec4(0.);
  410. }
  411.  
  412. //-----------------------------------------------------
  413. // Ring (by me ;))
  414. //-----------------------------------------------------
  415.  
  416. float renderRingFarShadow( const in vec3 ro, const in vec3 rd ) {
  417. // intersect plane
  418. float d = iPlane( ro, rd, vec4( 0., 0., 1., 0.) );
  419.  
  420. if( d > 0. ) {
  421. vec3 intersection = ro + rd*d;
  422. float l = length(intersection.xy);
  423.  
  424. if( l > RING_INNER_RADIUS && l < RING_OUTER_RADIUS ) {
  425. return .5 + .5 * (.2+.8*noise( l*.07 )) * (.5+.5*noise(intersection.xy));
  426. }
  427. }
  428. return 0.;
  429. }
  430.  
  431. vec4 renderRingFar( const in vec3 ro, const in vec3 rd, inout float maxd ) {
  432. // intersect plane
  433. float d = iPlane( ro, rd, vec4( 0., 0., 1., 0.) );
  434.  
  435. if( d > 0. && d < maxd ) {
  436. maxd = d;
  437. vec3 intersection = ro + rd*d;
  438. float l = length(intersection.xy);
  439.  
  440. if( l > RING_INNER_RADIUS && l < RING_OUTER_RADIUS ) {
  441. float dens = .5 + .5 * (.2+.8*noise( l*.07 )) * (.5+.5*noise(intersection.xy));
  442. vec3 col = mix( RING_COLOR_1, RING_COLOR_2, abs( noise(l*0.2) ) ) * abs(dens) * 1.5;
  443.  
  444. col *= ringShadowColor( intersection );
  445. col *= .8+.3*diffuse( vec3(0,0,1), SUN_DIRECTION );
  446. col *= SUN_COLOR;
  447. return vec4( col, dens );
  448. } else {
  449. return vec4(0.);
  450. }
  451. } else {
  452. return vec4(0.);
  453. }
  454. }
  455.  
  456. vec4 renderRing( const in vec3 ro, const in vec3 rd, inout float maxd ) {
  457. vec4 far = renderRingFar( ro, rd, maxd );
  458. float l = length( ro.xy );
  459.  
  460. if( abs(ro.z) < RING_HEIGHT+RING_DETAIL_DISTANCE
  461. && l < RING_OUTER_RADIUS+RING_DETAIL_DISTANCE
  462. && l > RING_INNER_RADIUS-RING_DETAIL_DISTANCE ) {
  463.  
  464. float d = iPlane( ro, rd, vec4( 0., 0., 1., 0.) );
  465. float detail = mix( .5 * noise( fract(ro.xy+rd.xy*d) * 92.1)+.25, 1., smoothstep( 0.,RING_DETAIL_DISTANCE, d) );
  466. far.xyz *= detail;
  467. }
  468.  
  469. // are asteroids neaded ?
  470. if( abs(ro.z) < RING_HEIGHT+ASTEROID_MAX_DISTANCE
  471. && l < RING_OUTER_RADIUS+ASTEROID_MAX_DISTANCE
  472. && l > RING_INNER_RADIUS-ASTEROID_MAX_DISTANCE ) {
  473.  
  474. vec4 near = renderRingNear( ro, rd );
  475. far = mix( far, near, near.w );
  476. maxd=0.;
  477. }
  478.  
  479. return far;
  480. }
  481.  
  482. //-----------------------------------------------------
  483. // Stars (by me ;))
  484. //-----------------------------------------------------
  485.  
  486. vec4 renderStars( const in vec3 rd ) {
  487. vec3 rds = rd;
  488. vec3 col = vec3(0);
  489. float v = 1.0/( 2. * ( 1. + rds.z ) );
  490.  
  491. vec2 xy = vec2(rds.y * v, rds.x * v);
  492. float s = noise(rds*134.);
  493.  
  494. s += noise(rds*470.);
  495. s = pow(s,19.0) * 0.00001;
  496. if (s > 0.5) {
  497. vec3 backStars = vec3(s)*.5 * vec3(0.95,0.8,0.9);
  498. col += backStars;
  499. }
  500. return vec4( col, 1 );
  501. }
  502.  
  503. //-----------------------------------------------------
  504. // Atmospheric Scattering by GLtracy
  505. //
  506. // https://www.shadertoy.com/view/lslXDr
  507. //-----------------------------------------------------
  508.  
  509. const float ATMOSPHERE_K_R = 0.166;
  510. const float ATMOSPHERE_K_M = 0.0025;
  511. const float ATMOSPHERE_E = 12.3;
  512. const vec3 ATMOSPHERE_C_R = vec3( 0.3, 0.7, 1.0 );
  513. const float ATMOSPHERE_G_M = -0.85;
  514.  
  515. const float ATMOSPHERE_SCALE_H = 4.0 / ( EARTH_ATMOSPHERE );
  516. const float ATMOSPHERE_SCALE_L = 1.0 / ( EARTH_ATMOSPHERE );
  517.  
  518. const float ATMOSPHERE_FNUM_OUT_SCATTER = float(ATMOSPHERE_NUM_OUT_SCATTER);
  519. const float ATMOSPHERE_FNUM_IN_SCATTER = float(ATMOSPHERE_NUM_IN_SCATTER);
  520.  
  521. const int ATMOSPHERE_NUM_OUT_SCATTER_LOW = 2;
  522. const int ATMOSPHERE_NUM_IN_SCATTER_LOW = 4;
  523. const float ATMOSPHERE_FNUM_OUT_SCATTER_LOW = float(ATMOSPHERE_NUM_OUT_SCATTER_LOW);
  524. const float ATMOSPHERE_FNUM_IN_SCATTER_LOW = float(ATMOSPHERE_NUM_IN_SCATTER_LOW);
  525.  
  526. float atmosphericPhaseMie( float g, float c, float cc ) {
  527. float gg = g * g;
  528. float a = ( 1.0 - gg ) * ( 1.0 + cc );
  529. float b = 1.0 + gg - 2.0 * g * c;
  530.  
  531. b *= sqrt( b );
  532. b *= 2.0 + gg;
  533.  
  534. return 1.5 * a / b;
  535. }
  536.  
  537. float atmosphericPhaseReyleigh( float cc ) {
  538. return 0.75 * ( 1.0 + cc );
  539. }
  540.  
  541. float atmosphericDensity( vec3 p ){
  542. return exp( -( length( p ) - EARTH_RADIUS ) * ATMOSPHERE_SCALE_H );
  543. }
  544.  
  545. float atmosphericOptic( vec3 p, vec3 q ) {
  546. vec3 step = ( q - p ) / ATMOSPHERE_FNUM_OUT_SCATTER;
  547. vec3 v = p + step * 0.5;
  548.  
  549. float sum = 0.0;
  550. for ( int i = 0; i < ATMOSPHERE_NUM_OUT_SCATTER; i++ ) {
  551. sum += atmosphericDensity( v );
  552. v += step;
  553. }
  554. sum *= length( step ) * ATMOSPHERE_SCALE_L;
  555.  
  556. return sum;
  557. }
  558.  
  559. vec4 atmosphericInScatter( vec3 o, vec3 dir, vec2 e, vec3 l ) {
  560. float len = ( e.y - e.x ) / ATMOSPHERE_FNUM_IN_SCATTER;
  561. vec3 step = dir * len;
  562. vec3 p = o + dir * e.x;
  563. vec3 v = p + dir * ( len * 0.5 );
  564.  
  565. float sumdensity = 0.;
  566. vec3 sum = vec3( 0.0 );
  567.  
  568. for ( int i = 0; i < ATMOSPHERE_NUM_IN_SCATTER; i++ ) {
  569. vec3 u = v + l * iCSphereF( v, l, EARTH_RADIUS + EARTH_ATMOSPHERE );
  570. float n = ( atmosphericOptic( p, v ) + atmosphericOptic( v, u ) ) * ( PI * 4.0 );
  571. float dens = atmosphericDensity( v );
  572.  
  573. float m = MAX;
  574. sum += dens * exp( -n * ( ATMOSPHERE_K_R * ATMOSPHERE_C_R + ATMOSPHERE_K_M ) )
  575. * (1. - renderRingFarShadow( u, SUN_DIRECTION ) );
  576. sumdensity += dens;
  577.  
  578. v += step;
  579. }
  580. sum *= len * ATMOSPHERE_SCALE_L;
  581.  
  582. float c = dot( dir, -l );
  583. float cc = c * c;
  584.  
  585. return vec4( sum * ( ATMOSPHERE_K_R * ATMOSPHERE_C_R * atmosphericPhaseReyleigh( cc ) +
  586. ATMOSPHERE_K_M * atmosphericPhaseMie( ATMOSPHERE_G_M, c, cc ) ) * ATMOSPHERE_E,
  587. clamp(sumdensity * len * ATMOSPHERE_SCALE_L,0.,1.));
  588. }
  589.  
  590. float atmosphericOpticLow( vec3 p, vec3 q ) {
  591. vec3 step = ( q - p ) / ATMOSPHERE_FNUM_OUT_SCATTER_LOW;
  592. vec3 v = p + step * 0.5;
  593.  
  594. float sum = 0.0;
  595. for ( int i = 0; i < ATMOSPHERE_NUM_OUT_SCATTER_LOW; i++ ) {
  596. sum += atmosphericDensity( v );
  597. v += step;
  598. }
  599. sum *= length( step ) * ATMOSPHERE_SCALE_L;
  600.  
  601. return sum;
  602. }
  603.  
  604. vec3 atmosphericInScatterLow( vec3 o, vec3 dir, vec2 e, vec3 l ) {
  605. float len = ( e.y - e.x ) / ATMOSPHERE_FNUM_IN_SCATTER_LOW;
  606. vec3 step = dir * len;
  607. vec3 p = o + dir * e.x;
  608. vec3 v = p + dir * ( len * 0.5 );
  609.  
  610. vec3 sum = vec3( 0.0 );
  611.  
  612. for ( int i = 0; i < ATMOSPHERE_NUM_IN_SCATTER_LOW; i++ ) {
  613. vec3 u = v + l * iCSphereF( v, l, EARTH_RADIUS + EARTH_ATMOSPHERE );
  614. float n = ( atmosphericOpticLow( p, v ) + atmosphericOpticLow( v, u ) ) * ( PI * 4.0 );
  615. float m = MAX;
  616. sum += atmosphericDensity( v ) * exp( -n * ( ATMOSPHERE_K_R * ATMOSPHERE_C_R + ATMOSPHERE_K_M ) );
  617. v += step;
  618. }
  619. sum *= len * ATMOSPHERE_SCALE_L;
  620.  
  621. float c = dot( dir, -l );
  622. float cc = c * c;
  623.  
  624. return sum * ( ATMOSPHERE_K_R * ATMOSPHERE_C_R * atmosphericPhaseReyleigh( cc ) +
  625. ATMOSPHERE_K_M * atmosphericPhaseMie( ATMOSPHERE_G_M, c, cc ) ) * ATMOSPHERE_E;
  626. }
  627.  
  628. vec4 renderAtmospheric( const in vec3 ro, const in vec3 rd, inout float d ) {
  629. // inside or outside atmosphere?
  630. vec2 e = iCSphere2( ro, rd, EARTH_RADIUS + EARTH_ATMOSPHERE );
  631. vec2 f = iCSphere2( ro, rd, EARTH_RADIUS );
  632.  
  633. if( length(ro) <= EARTH_RADIUS + EARTH_ATMOSPHERE ) {
  634. if( d < e.y ) {
  635. e.y = d;
  636. }
  637. d = e.y;
  638. e.x = 0.;
  639.  
  640. if ( iSphere( ro, rd, vec4(0,0,0,EARTH_RADIUS)) > 0. ) {
  641. d = iSphere( ro, rd, vec4(0,0,0,EARTH_RADIUS));
  642. }
  643. } else {
  644. if( iSphere( ro, rd, vec4(0,0,0,EARTH_RADIUS + EARTH_ATMOSPHERE )) < 0. ) return vec4(0.);
  645.  
  646. if ( e.x > e.y ) {
  647. d = MAX;
  648. return vec4(0.);
  649. }
  650. d = e.y = min( e.y, f.x );
  651. }
  652. return atmosphericInScatter( ro, rd, e, SUN_DIRECTION );
  653. }
  654.  
  655. vec3 renderAtmosphericLow( const in vec3 ro, const in vec3 rd ) {
  656. vec2 e = iCSphere2( ro, rd, EARTH_RADIUS + EARTH_ATMOSPHERE );
  657. e.x = 0.;
  658. return atmosphericInScatterLow( ro, rd, e, SUN_DIRECTION );
  659. }
  660.  
  661. //-----------------------------------------------------
  662. // Seascape by TDM
  663. //
  664. // https://www.shadertoy.com/view/Ms2SD1
  665. //-----------------------------------------------------
  666.  
  667. const int SEA_ITER_GEOMETRY = 3;
  668. const int SEA_ITER_FRAGMENT = 5;
  669.  
  670. const float SEA_EPSILON = 1e-3;
  671. #define SEA_EPSILON_NRM (0.1 / iResolution.x)
  672. const float SEA_HEIGHT = 0.6;
  673. const float SEA_CHOPPY = 4.0;
  674. const float SEA_SPEED = 0.8;
  675. const float SEA_FREQ = 0.16;
  676. const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
  677. const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
  678. float SEA_TIME;
  679. const mat2 sea_octave_m = mat2(1.6,1.2,-1.2,1.6);
  680.  
  681. float seaOctave( in vec2 uv, const in float choppy) {
  682. uv += noise(uv);
  683. vec2 wv = 1.0-abs(sin(uv));
  684. vec2 swv = abs(cos(uv));
  685. wv = mix(wv,swv,wv);
  686. return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
  687. }
  688.  
  689. float seaMap(const in vec3 p) {
  690. float freq = SEA_FREQ;
  691. float amp = SEA_HEIGHT;
  692. float choppy = SEA_CHOPPY;
  693. vec2 uv = p.xz; uv.x *= 0.75;
  694.  
  695. float d, h = 0.0;
  696. for(int i = 0; i < SEA_ITER_GEOMETRY; i++) {
  697. d = seaOctave((uv+SEA_TIME)*freq,choppy);
  698. d += seaOctave((uv-SEA_TIME)*freq,choppy);
  699. h += d * amp;
  700. uv *= sea_octave_m; freq *= 1.9; amp *= 0.22;
  701. choppy = mix(choppy,1.0,0.2);
  702. }
  703. return p.y - h;
  704. }
  705.  
  706. float seaMapHigh(const in vec3 p) {
  707. float freq = SEA_FREQ;
  708. float amp = SEA_HEIGHT;
  709. float choppy = SEA_CHOPPY;
  710. vec2 uv = p.xz; uv.x *= 0.75;
  711.  
  712. float d, h = 0.0;
  713. for(int i = 0; i < SEA_ITER_FRAGMENT; i++) {
  714. d = seaOctave((uv+SEA_TIME)*freq,choppy);
  715. d += seaOctave((uv-SEA_TIME)*freq,choppy);
  716. h += d * amp;
  717. uv *= sea_octave_m; freq *= 1.9; amp *= 0.22;
  718. choppy = mix(choppy,1.0,0.2);
  719. }
  720. return p.y - h;
  721. }
  722.  
  723. vec3 seaGetColor( const in vec3 n, vec3 eye, const in vec3 l, const in float att,
  724. const in vec3 sunc, const in vec3 upc, const in vec3 reflected) {
  725. vec3 refracted = SEA_BASE * upc + diffuse(n,l) * SEA_WATER_COLOR * 0.12 * sunc;
  726. vec3 color = mix(refracted,reflected,fresnel(n, -eye, 3.)*.65 );
  727.  
  728. color += upc*SEA_WATER_COLOR * (att * 0.18);
  729. color += sunc * vec3(specular(n,l,eye,60.0));
  730.  
  731. return color;
  732. }
  733.  
  734. vec3 seaGetNormal(const in vec3 p, const in float eps) {
  735. vec3 n;
  736. n.y = seaMapHigh(p);
  737. n.x = seaMapHigh(vec3(p.x+eps,p.y,p.z)) - n.y;
  738. n.z = seaMapHigh(vec3(p.x,p.y,p.z+eps)) - n.y;
  739. n.y = eps;
  740. return normalize(n);
  741. }
  742.  
  743. float seaHeightMapTracing(const in vec3 ori, const in vec3 dir, out vec3 p) {
  744. float tm = 0.0;
  745. float tx = 1000.0;
  746. float hx = seaMap(ori + dir * tx);
  747. if(hx > 0.0) return tx;
  748. float hm = seaMap(ori + dir * tm);
  749. float tmid = 0.0;
  750. for(int i = 0; i < SEA_NUM_STEPS; i++) {
  751. tmid = mix(tm,tx, hm/(hm-hx));
  752. p = ori + dir * tmid;
  753. float hmid = seaMap(p);
  754. if(hmid < 0.0) {
  755. tx = tmid;
  756. hx = hmid;
  757. } else {
  758. tm = tmid;
  759. hm = hmid;
  760. }
  761. }
  762. return tmid;
  763. }
  764.  
  765. vec3 seaTransform( in vec3 x ) {
  766. x.yz = rotate( 0.8, x.yz );
  767. return x;
  768. }
  769.  
  770. vec3 seaUntransform( in vec3 x ) {
  771. x.yz = rotate( -0.8, x.yz );
  772. return x;
  773. }
  774.  
  775. void renderSea( const in vec3 ro, const in vec3 rd, inout vec3 n, inout float att ) {
  776. vec3 p,
  777. rom = seaTransform(ro),
  778. rdm = seaTransform(rd);
  779.  
  780. rom.y -= EARTH_RADIUS;
  781. rom *= 1000.;
  782. rom.xz += vec2(3.1,.2)*time;
  783.  
  784. SEA_TIME = time * SEA_SPEED;
  785.  
  786. seaHeightMapTracing(rom,rdm,p);
  787. float squareddist = dot(p - rom, p-rom );
  788. n = seaGetNormal(p, squareddist * SEA_EPSILON_NRM );
  789.  
  790. n = seaUntransform(n);
  791.  
  792. att = clamp(SEA_HEIGHT+p.y, 0.,1.);
  793. }
  794.  
  795. //-----------------------------------------------------
  796. // Terrain based on Elevated and Terrain Tubes by IQ
  797. //
  798. // https://www.shadertoy.com/view/MdX3Rr
  799. // https://www.shadertoy.com/view/4sjXzG
  800. //-----------------------------------------------------
  801.  
  802. #ifndef HIDE_TERRAIN
  803.  
  804. const mat2 terrainM2 = mat2(1.6,-1.2,1.2,1.6);
  805.  
  806. float terrainLow( vec2 p ) {
  807. p *= 0.0013;
  808.  
  809. float s = 1.0;
  810. float t = 0.0;
  811. for( int i=0; i<2; i++ ) {
  812. t += s*tri( p );
  813. s *= 0.5 + 0.1*t;
  814. p = 0.97*terrainM2*p + (t-0.5)*0.12;
  815. }
  816. return t*33.0;
  817. }
  818.  
  819. float terrainMed( vec2 p ) {
  820. p *= 0.0013;
  821.  
  822. float s = 1.0;
  823. float t = 0.0;
  824. for( int i=0; i<6; i++ ) {
  825. t += s*tri( p );
  826. s *= 0.5 + 0.1*t;
  827. p = 0.97*terrainM2*p + (t-0.5)*0.12;
  828. }
  829.  
  830. return t*33.0;
  831. }
  832.  
  833. float terrainHigh( vec2 p ) {
  834. vec2 q = p;
  835. p *= 0.0013;
  836.  
  837. float s = 1.0;
  838. float t = 0.0;
  839. for( int i=0; i<7; i++ ) {
  840. t += s*tri( p );
  841. s *= 0.5 + 0.1*t;
  842. p = 0.97*terrainM2*p + (t-0.5)*0.12;
  843. }
  844.  
  845. t += t*0.015*fbm( q );
  846. return t*33.0;
  847. }
  848.  
  849. float terrainMap( const in vec3 pos ) {
  850. return pos.y - terrainMed(pos.xz);
  851. }
  852.  
  853. float terrainMapH( const in vec3 pos ) {
  854. float y = terrainHigh(pos.xz);
  855. float h = pos.y - y;
  856. return h;
  857. }
  858.  
  859. float terrainIntersect( in vec3 ro, in vec3 rd, in float tmin, in float tmax ) {
  860. float t = tmin;
  861. for( int i=0; i<TERRAIN_NUM_STEPS; i++ ) {
  862. vec3 pos = ro + t*rd;
  863. float res = terrainMap( pos );
  864. if( res<(0.001*t) || t>tmax ) break;
  865. t += res*.9;
  866. }
  867.  
  868. return t;
  869. }
  870.  
  871. float terrainCalcShadow(in vec3 ro, in vec3 rd ) {
  872. vec2 eps = vec2(150.0,0.0);
  873. float h1 = terrainMed( ro.xz );
  874. float h2 = terrainLow( ro.xz );
  875.  
  876. float d1 = 10.0;
  877. float d2 = 80.0;
  878. float d3 = 200.0;
  879. float s1 = clamp( 1.0*(h1 + rd.y*d1 - terrainMed(ro.xz + d1*rd.xz)), 0.0, 1.0 );
  880. float s2 = clamp( 0.5*(h1 + rd.y*d2 - terrainMed(ro.xz + d2*rd.xz)), 0.0, 1.0 );
  881. float s3 = clamp( 0.2*(h2 + rd.y*d3 - terrainLow(ro.xz + d3*rd.xz)), 0.0, 1.0 );
  882.  
  883. return min(min(s1,s2),s3);
  884. }
  885. vec3 terrainCalcNormalHigh( in vec3 pos, float t ) {
  886. vec2 e = vec2(1.0,-1.0)*0.001*t;
  887.  
  888. return normalize( e.xyy*terrainMapH( pos + e.xyy ) +
  889. e.yyx*terrainMapH( pos + e.yyx ) +
  890. e.yxy*terrainMapH( pos + e.yxy ) +
  891. e.xxx*terrainMapH( pos + e.xxx ) );
  892. }
  893.  
  894. vec3 terrainCalcNormalMed( in vec3 pos, float t ) {
  895. float e = 0.005*t;
  896. vec2 eps = vec2(e,0.0);
  897. float h = terrainMed( pos.xz );
  898. return normalize(vec3( terrainMed(pos.xz-eps.xy)-h, e, terrainMed(pos.xz-eps.yx)-h ));
  899. }
  900.  
  901. vec3 terrainTransform( in vec3 x ) {
  902. x.zy = rotate( -.83, x.zy );
  903. return x;
  904. }
  905.  
  906. vec3 terrainUntransform( in vec3 x ) {
  907. x.zy = rotate( .83, x.zy );
  908. return x;
  909. }
  910.  
  911.  
  912. float llamelTime;
  913. const float llamelScale = 5.;
  914.  
  915. vec3 llamelPosition() {
  916. llamelTime = time*2.5;
  917. vec2 pos = vec2( -400., 135.-llamelTime*0.075* llamelScale);
  918. return vec3( pos.x, terrainMed( pos ), pos.y );
  919. }
  920.  
  921. vec3 terrainShade( const in vec3 col, const in vec3 pos, const in vec3 rd, const in vec3 n, const in float spec,
  922. const in vec3 sunc, const in vec3 upc, const in vec3 reflc ) {
  923. vec3 sunDirection = terrainTransform(SUN_DIRECTION);
  924. float dif = diffuse( n, sunDirection );
  925. float bac = diffuse( n, vec3(-sunDirection.x, sunDirection.y, -sunDirection.z) );
  926. float sha = terrainCalcShadow( pos, sunDirection );
  927. float amb = clamp( n.y,0.0,1.0);
  928.  
  929. vec3 lin = vec3(0.0);
  930. lin += 2.*dif*sunc*vec3( sha, sha*sha*0.1+0.9*sha, sha*sha*0.2+0.8*sha );
  931. lin += 0.2*amb*upc;
  932. lin += 0.08*bac*clamp(vec3(1.)-sunc, vec3(0.), vec3(1.));
  933. return mix( col*lin*3., reflc, spec*fresnel(n,-terrainTransform(rd),5.0) );
  934. }
  935.  
  936. vec3 terrainGetColor( const in vec3 pos, const in vec3 rd, const in float t, const in vec3 sunc, const in vec3 upc, const in vec3 reflc ) {
  937. vec3 nor = terrainCalcNormalHigh( pos, t );
  938. vec3 sor = terrainCalcNormalMed( pos, t );
  939.  
  940. float spec = 0.005;
  941.  
  942. #ifdef DISPLAY_TERRAIN_DETAIL
  943. float no = noise(5.*fbm(1.11*pos.xz));
  944. #else
  945. const float no = 0.;
  946. #endif
  947. float r = .5+.5*fbm(.95*pos.xz);
  948. vec3 col = (r*0.25+0.75)*0.9*mix( vec3(0.08,0.07,0.07), vec3(0.10,0.09,0.08), noise(0.4267*vec2(pos.x*2.,pos.y*9.8))+.01*no );
  949. col = mix( col, 0.20*vec3(0.45,.30,0.15)*(0.50+0.50*r),smoothstep(0.825,0.925,nor.y+.025*no) );
  950. col = mix( col, 0.15*vec3(0.30,.30,0.10)*(0.25+0.75*r),smoothstep(0.95,1.0,nor.y+.025*no) );
  951. col *= .88+.12*no;
  952.  
  953. float s = nor.y + 0.03*pos.y + 0.35*fbm(0.05*pos.xz) - .35;
  954. float sf = fwidth(s) * 1.5;
  955. s = smoothstep(0.84-sf, 0.84+sf, s );
  956. col = mix( col, 0.29*vec3(0.62,0.65,0.7), s);
  957. nor = mix( nor, sor, 0.7*smoothstep(0.9, 0.95, s ) );
  958. spec = mix( spec, 0.45, smoothstep(0.9, 0.95, s ) );
  959.  
  960. col = terrainShade( col, pos, rd, nor, spec, sunc, upc, reflc );
  961.  
  962. #ifdef DISPLAY_LLAMEL
  963. col *= clamp( distance(pos.xz, llamelPosition().xz )*0.4, 0.4, 1.);
  964. #endif
  965.  
  966. return col;
  967. }
  968.  
  969. vec3 terrainTransformRo( const in vec3 ro ) {
  970. vec3 rom = terrainTransform(ro);
  971. rom.y -= EARTH_RADIUS - 100.;
  972. rom.xz *= 5.;
  973. rom.xz += vec2(-170.,50.)+vec2(-4.,.4)*time;
  974. rom.y += (terrainLow( rom.xz ) - 86.)*clamp( 1.-1.*(length(ro)-EARTH_RADIUS), 0., 1.);
  975. return rom;
  976. }
  977.  
  978. vec4 renderTerrain( const in vec3 ro, const in vec3 rd, inout vec3 intersection, inout vec3 n ) {
  979. vec3 p,
  980. rom = terrainTransformRo(ro),
  981. rdm = terrainTransform(rd);
  982.  
  983. float tmin = 10.0;
  984. float tmax = 3200.0;
  985.  
  986. float res = terrainIntersect( rom, rdm, tmin, tmax );
  987.  
  988. if( res > tmax ) {
  989. res = -1.;
  990. } else {
  991. vec3 pos = rom+rdm*res;
  992. n = terrainCalcNormalMed( pos, res );
  993. n = terrainUntransform( n );
  994.  
  995. intersection = ro+rd*res/100.;
  996. }
  997. return vec4(res, rom+rdm*res);
  998. }
  999.  
  1000. #endif
  1001.  
  1002. //-----------------------------------------------------
  1003. // LLamels by Eiffie
  1004. //
  1005. // https://www.shadertoy.com/view/ltsGz4
  1006. //-----------------------------------------------------
  1007. #ifdef DISPLAY_LLAMEL
  1008. float llamelMapSMin(const in float a,const in float b,const in float k){
  1009. float h=clamp(0.5+0.5*(b-a)/k,0.0,1.0);return b+h*(a-b-k+k*h);
  1010. }
  1011.  
  1012. float llamelMapLeg(vec3 p, vec3 j0, vec3 j3, vec3 l, vec4 r, vec3 rt){//z joint with tapered legs
  1013. float lx2z=l.x/(l.x+l.z),h=l.y*lx2z;
  1014. vec3 u=(j3-j0)*lx2z,q=u*(0.5+0.5*(l.x*l.x-h*h)/dot(u,u));
  1015. q+=sqrt(max(0.0,l.x*l.x-dot(q,q)))*normalize(cross(u,rt));
  1016. vec3 j1=j0+q,j2=j3-q*(1.0-lx2z)/lx2z;
  1017. u=p-j0;q=j1-j0;
  1018. h=clamp(dot(u,q)/dot(q,q),0.0,1.0);
  1019. float d=length(u-q*h)-r.x-(r.y-r.x)*h;
  1020. u=p-j1;q=j2-j1;
  1021. h=clamp(dot(u,q)/dot(q,q),0.0,1.0);
  1022. d=min(d,length(u-q*h)-r.y-(r.z-r.y)*h);
  1023. u=p-j2;q=j3-j2;
  1024. h=clamp(dot(u,q)/dot(q,q),0.0,1.0);
  1025. return min(d,length(u-q*h)-r.z-(r.w-r.z)*h);
  1026. }
  1027.  
  1028. float llamelMap(in vec3 p) {
  1029. const vec3 rt=vec3(0.0,0.0,1.0);
  1030. p.y += 0.25*llamelScale;
  1031. p.xz -= 0.5*llamelScale;
  1032. p.xz = vec2(-p.z, p.x);
  1033. vec3 pori = p;
  1034.  
  1035. p /= llamelScale;
  1036.  
  1037. vec2 c=floor(p.xz);
  1038. p.xz=fract(p.xz)-vec2(0.5);
  1039. p.y -= p.x*.04*llamelScale;
  1040. float sa=sin(c.x*2.0+c.y*4.5+llamelTime*0.05)*0.15;
  1041.  
  1042. float b=0.83-abs(p.z);
  1043. float a=c.x+117.0*c.y+sign(p.x)*1.57+sign(p.z)*1.57+llamelTime,ca=cos(a);
  1044. vec3 j0=vec3(sign(p.x)*0.125,ca*0.01,sign(p.z)*0.05),j3=vec3(j0.x+sin(a)*0.1,max(-0.25+ca*0.1,-0.25),j0.z);
  1045. float dL=llamelMapLeg(p,j0,j3,vec3(0.08,0.075,0.12),vec4(0.03,0.02,0.015,0.01),rt*sign(p.x));
  1046. p.y-=0.03;
  1047. float dB=(length(p.xyz*vec3(1.0,1.75,1.75))-0.14)*0.75;
  1048. a=c.x+117.0*c.y+llamelTime;ca=cos(a);sa*=0.4;
  1049. j0=vec3(0.125,0.03+abs(ca)*0.03,ca*0.01),j3=vec3(0.3,0.07+ca*sa,sa);
  1050. float dH=llamelMapLeg(p,j0,j3,vec3(0.075,0.075,0.06),vec4(0.03,0.035,0.03,0.01),rt);
  1051. dB=llamelMapSMin(min(dL,dH),dB,clamp(0.04+p.y,0.0,1.0));
  1052. a=max(abs(p.z),p.y)+0.05;
  1053. return max(min(dB,min(a,b)),length(pori.xz-vec2(0.5)*llamelScale)-.5*llamelScale);
  1054. }
  1055.  
  1056. vec3 llamelGetNormal( in vec3 ro ) {
  1057. vec2 e = vec2(1.0,-1.0)*0.001;
  1058.  
  1059. return normalize( e.xyy*llamelMap( ro + e.xyy ) +
  1060. e.yyx*llamelMap( ro + e.yyx ) +
  1061. e.yxy*llamelMap( ro + e.yxy ) +
  1062. e.xxx*llamelMap( ro + e.xxx ) );
  1063. }
  1064.  
  1065. vec4 renderLlamel( in vec3 ro, const in vec3 rd, const in vec3 sunc, const in vec3 upc, const in vec3 reflc ) {
  1066. ro -= llamelPosition();
  1067. float t=.1*hash(rd.xy),d,dm=10.0,tm;
  1068. for(int i=0;i<36;i++){
  1069. t+=d=llamelMap(ro+rd*t);
  1070. if(d<dm){dm=d;tm=t;}
  1071. if(t>1000.0 || d<0.00001)break;
  1072. }
  1073. dm=max(0.0,dm);
  1074. if( dm < .02 ) {
  1075. vec3 col = vec3(0.45,.30,0.15)*.2;
  1076. vec3 pos = ro + rd*tm;
  1077. vec3 nor = llamelGetNormal( pos );
  1078. col = terrainShade( col, pos, rd, nor, .01, sunc, upc, reflc );
  1079. return vec4(col, clamp( 1.-(dm-0.01)/0.01,0., 1.) );
  1080. }
  1081.  
  1082. return vec4(0.);
  1083. }
  1084. #endif
  1085.  
  1086. //-----------------------------------------------------
  1087. // Clouds (by me ;))
  1088. //-----------------------------------------------------
  1089.  
  1090. vec4 renderClouds( const in vec3 ro, const in vec3 rd, const in float d, const in vec3 n, const in float land,
  1091. const in vec3 sunColor, const in vec3 upColor, inout float shadow ) {
  1092. vec3 intersection = ro+rd*d;
  1093. vec3 cint = intersection*0.009;
  1094. float rot = -.2*length(cint.xy) + .6*fbm( cint*.4,0.5,2.96 ) + .05*land;
  1095.  
  1096. cint.xy = rotate( rot, cint.xy );
  1097.  
  1098. vec3 cdetail = mod(intersection*3.23,vec3(50.));
  1099. cdetail.xy = rotate( .25*rot, cdetail.xy );
  1100.  
  1101. float clouds = 1.3*(fbm( cint*(1.+.02*noise(intersection)),0.5,2.96)+.4*land-.3);
  1102.  
  1103. #ifdef DISPLAY_CLOUDS_DETAIL
  1104. if( d < 200. ) {
  1105. clouds += .3*(fbm(cdetail,0.5,2.96)-.5)*(1.-smoothstep(0.,200.,d));
  1106. }
  1107. #endif
  1108.  
  1109. shadow = clamp(1.-clouds, 0., 1.);
  1110.  
  1111. clouds = clamp(clouds, 0., 1.);
  1112. clouds *= clouds;
  1113. clouds *= smoothstep(0.,0.4,d);
  1114.  
  1115. vec3 clbasecolor = vec3(1.);
  1116. vec3 clcol = .1*clbasecolor*sunColor * vec3(specular(n,SUN_DIRECTION,rd,36.0));
  1117. clcol += .3*clbasecolor*sunColor;
  1118. clcol += clbasecolor*(diffuse(n,SUN_DIRECTION)*sunColor+upColor);
  1119.  
  1120. return vec4( clcol, clouds );
  1121. }
  1122.  
  1123. //-----------------------------------------------------
  1124. // Planet (by me ;))
  1125. //-----------------------------------------------------
  1126.  
  1127. vec4 renderPlanet( const in vec3 ro, const in vec3 rd, const in vec3 up, inout float maxd ) {
  1128. float d = iSphere( ro, rd, vec4( 0., 0., 0., EARTH_RADIUS ) );
  1129.  
  1130. vec3 intersection = ro + rd*d;
  1131. vec3 n = nSphere( intersection, vec4( 0., 0., 0., EARTH_RADIUS ) );
  1132. vec4 res;
  1133.  
  1134. #ifndef HIDE_TERRAIN
  1135. bool renderTerrainDetail = length(ro) < EARTH_RADIUS+EARTH_ATMOSPHERE &&
  1136. dot( terrainUntransform( vec3(0.,1.,0.) ), normalize(ro) ) > .9996;
  1137. #endif
  1138. bool renderSeaDetail = d < 1. && dot( seaUntransform( vec3(0.,1.,0.) ), normalize(ro) ) > .9999;
  1139. float mixDetailColor = 0.;
  1140.  
  1141. if( d < 0. || d > maxd) {
  1142. #ifndef HIDE_TERRAIN
  1143. if( renderTerrainDetail ) {
  1144. intersection = ro;
  1145. n = normalize( ro );
  1146. } else {
  1147. return vec4(0);
  1148. }
  1149. #else
  1150. return vec4(0.);
  1151. #endif
  1152. }
  1153. if( d > 0. ) {
  1154. maxd = d;
  1155. }
  1156. float att = 0.;
  1157.  
  1158. if( dot(n,SUN_DIRECTION) < -0.1 ) return vec4( 0., 0., 0., 1. );
  1159.  
  1160. float dm = MAX, e = 0.;
  1161. vec3 col, detailCol, nDetail;
  1162.  
  1163. // normal and intersection
  1164. #ifndef HIDE_TERRAIN
  1165. if( renderTerrainDetail ) {
  1166. res = renderTerrain( ro, rd, intersection, nDetail );
  1167. if( res.x < 0. && d < 0. ) {
  1168. return vec4(0);
  1169. }
  1170. if( res.x >= 0. ) {
  1171. maxd = pow(res.x/4000.,4.)*50.;
  1172. e = -10.;
  1173. }
  1174. mixDetailColor = 1.-smoothstep(.75, 1., (length(ro)-EARTH_RADIUS) / EARTH_ATMOSPHERE);
  1175. n = normalize( mix( n, nDetail, mixDetailColor ) );
  1176. } else
  1177. #endif
  1178. if( renderSeaDetail ) {
  1179. float attsea, mf = smoothstep(.5,1.,d);
  1180.  
  1181. renderSea( ro, rd, nDetail, attsea );
  1182.  
  1183. n = normalize(mix( nDetail, n, mf ));
  1184. att = mix( attsea, att, mf );
  1185. } else {
  1186. e = fbm( .003*intersection+vec3(1.),0.4,2.96) + smoothstep(.85,.95, abs(intersection.z/EARTH_RADIUS));
  1187. #ifndef HIDE_TERRAIN
  1188. if( d < 1500. ) {
  1189. e += (-.03+.06* fbm( intersection*0.1,0.4,2.96))*(1.-d/1500.);
  1190. }
  1191. #endif
  1192. }
  1193.  
  1194. vec3 sunColor = .25*renderAtmosphericLow( intersection, SUN_DIRECTION).xyz;
  1195. vec3 upColor = 2.*renderAtmosphericLow( intersection, n).xyz;
  1196. vec3 reflColor = renderAtmosphericLow( intersection, reflect(rd,n)).xyz;
  1197.  
  1198. // color
  1199. #ifndef HIDE_TERRAIN
  1200. if(renderTerrainDetail ) {
  1201. detailCol = col = terrainGetColor(res.yzw, rd, res.x, sunColor, upColor, reflColor);
  1202. d = 0.;
  1203. }
  1204. #endif
  1205.  
  1206. if( mixDetailColor < 1. ) {
  1207. if( e < .45 ) {
  1208. // sea
  1209. col = seaGetColor(n,rd,SUN_DIRECTION, att, sunColor, upColor, reflColor);
  1210. } else {
  1211. // planet (land) far
  1212. float land1 = max(0.1, fbm( intersection*0.0013,0.4,2.96) );
  1213. float land2 = max(0.1, fbm( intersection*0.0063,0.4,2.96) );
  1214. float iceFactor = abs(pow(intersection.z/EARTH_RADIUS,13.0))*e;
  1215.  
  1216. vec3 landColor1 = vec3(0.43,0.65,0.1) * land1;
  1217. vec3 landColor2 = RING_COLOR_1 * land2;
  1218. vec3 mixedLand = (landColor1 + landColor2)* 0.5;
  1219. vec3 finalLand = mix(mixedLand, vec3(7.0, 7.0, 7.0) * land1 * 1.5, max(iceFactor+.02*land2-.02, 0.));
  1220.  
  1221. col = (diffuse(n,SUN_DIRECTION)*sunColor+upColor)*finalLand*.75;
  1222. #ifdef HIGH_QUALITY
  1223. col *= (.5+.5*fbm( intersection*0.23,0.4,2.96) );
  1224. #endif
  1225. }
  1226. }
  1227.  
  1228. if( mixDetailColor > 0. ) {
  1229. col = mix( col, detailCol, mixDetailColor );
  1230. }
  1231.  
  1232. #ifdef DISPLAY_LLAMEL
  1233. if(renderTerrainDetail ) {
  1234. vec3 rom = terrainTransformRo(ro),
  1235. rdm = terrainTransform(rd);
  1236. d = iSphere( rom, rdm, vec4( llamelPosition(), llamelScale*3. ) );
  1237. if( d > 0. ) {
  1238. vec4 llamel = renderLlamel( rom+rdm*d, rdm, sunColor, upColor, reflColor );
  1239. col = mix(col, llamel.rgb, llamel.a);
  1240. }
  1241. }
  1242. #endif
  1243.  
  1244. d = iSphere( ro, rd, vec4( 0., 0., 0., EARTH_RADIUS+EARTH_CLOUDS ) );
  1245. if( d > 0. ) {
  1246. float shadow;
  1247. vec4 clouds = renderClouds( ro, rd, d, n, e, sunColor, upColor, shadow);
  1248. col *= shadow;
  1249. col = mix( col, clouds.rgb, clouds.w );
  1250. }
  1251.  
  1252. float m = MAX;
  1253. col *= (1. - renderRingFarShadow( ro+rd*d, SUN_DIRECTION ) );
  1254.  
  1255. return vec4( col, 1. );
  1256. }
  1257.  
  1258. //-----------------------------------------------------
  1259. // Lens flare by musk
  1260. //
  1261. // https://www.shadertoy.com/view/4sX3Rs
  1262. //-----------------------------------------------------
  1263.  
  1264. vec3 lensFlare( const in vec2 uv, const in vec2 pos) {
  1265. vec2 main = uv-pos;
  1266. vec2 uvd = uv*(length(uv));
  1267.  
  1268. float f0 = 1.5/(length(uv-pos)*16.0+1.0);
  1269.  
  1270. float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;
  1271.  
  1272. float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.25;
  1273. float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.23;
  1274. float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.21;
  1275.  
  1276. vec2 uvx = mix(uv,uvd,-0.5);
  1277.  
  1278. float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0;
  1279. float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0;
  1280. float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0;
  1281.  
  1282. vec3 c = vec3(.0);
  1283.  
  1284. c.r+=f2+f4; c.g+=f22+f42; c.b+=f23+f43;
  1285. c = c*.5 - vec3(length(uvd)*.05);
  1286. c+=vec3(f0);
  1287.  
  1288. return c;
  1289. }
  1290.  
  1291. //-----------------------------------------------------
  1292. // cameraPath
  1293. //-----------------------------------------------------
  1294.  
  1295. vec3 pro, pta, pup;
  1296. float dro, dta, dup;
  1297.  
  1298. void camint( inout vec3 ret, const in float t, const in float duration, const in vec3 dest, inout vec3 prev, inout float prevt ) {
  1299. if( t >= prevt && t <= prevt+duration ) {
  1300. ret = mix( prev, dest, smoothstep(prevt, prevt+duration, t) );
  1301. }
  1302. prev = dest;
  1303. prevt += duration;
  1304. }
  1305.  
  1306. void cameraPath( in float t, out vec3 ro, out vec3 ta, out vec3 up ) {
  1307. #ifndef HIDE_TERRAIN
  1308. time = t = mod( t, 92. );
  1309. #else
  1310. time = t = mod( t, 66. );
  1311. #endif
  1312. dro = dta = dup = 0.;
  1313.  
  1314. pro = ro = vec3(900. ,7000. ,1500. );
  1315. pta = ta = vec3( 0. , 0. , 0. );
  1316. pup = up = vec3( 0. , 0.4, 1. );
  1317.  
  1318. camint( ro, t, 5., vec3(-4300. ,-1000. , 500. ), pro, dro );
  1319. camint( ta, t, 5., vec3( 0. , 0. , 0. ), pta, dta );
  1320. camint( up, t, 7., vec3( 0. , 0.1, 1. ), pup, dup );
  1321.  
  1322. camint( ro, t, 3., vec3(-1355. , 1795. , 1.2 ), pro, dro );
  1323. camint( ta, t, 1., vec3( 0. , 300. ,-600. ), pta, dta );
  1324. camint( up, t, 6., vec3( 0. , 0.1, 1. ), pup, dup );
  1325.  
  1326. camint( ro, t, 10., vec3(-1355. , 1795. , 1.2 ), pro, dro );
  1327. camint( ta, t, 14., vec3( 0. , 100. , 600. ), pta, dta );
  1328. camint( up, t, 13., vec3( 0. , 0.3, 1. ), pup, dup );
  1329.  
  1330. vec3 roe = seaUntransform( vec3( 0., EARTH_RADIUS+0.004, 0. ) );
  1331. vec3 upe = seaUntransform( vec3( 0., 1., 0. ) );
  1332.  
  1333. camint( ro, t, 7.,roe, pro, dro );
  1334. camint( ta, t, 7., vec3( EARTH_RADIUS + 0., EARTH_RADIUS - 500., 500. ), pta, dta );
  1335. camint( up, t, 6., upe, pup, dup );
  1336.  
  1337. camint( ro, t, 17.,roe, pro, dro );
  1338. camint( ta, t, 17., vec3( EARTH_RADIUS + 500., EARTH_RADIUS + 1300., -100. ), pta, dta );
  1339. camint( up, t, 18., vec3(.0,1.,1.), pup, dup );
  1340.  
  1341. camint( ro, t, 11., vec3( 3102. , 0. , 1450. ), pro, dro );
  1342. camint( ta, t, 4., vec3( 0. , -100. , 0. ), pta, dta );
  1343. camint( up, t, 8., vec3( 0. , 0.15, 1. ), pup, dup );
  1344. #ifndef HIDE_TERRAIN
  1345. roe = terrainUntransform( vec3( 0., EARTH_RADIUS+0.004, 0. ) );
  1346. upe = terrainUntransform( vec3( 0., 1., 0. ) );
  1347.  
  1348. camint( ro, t, 7., roe, pro, dro );
  1349. camint( ta, t, 12., vec3( -EARTH_RADIUS, EARTH_RADIUS+200., 100.), pta, dta );
  1350. camint( up, t, 2., upe, pup, dup );
  1351.  
  1352. roe = terrainUntransform( vec3( 0., EARTH_RADIUS+0.001, 0. ) );
  1353. camint( ro, t, 17.,roe, pro, dro );
  1354. camint( ta, t, 18., roe + vec3( 5000., EARTH_RADIUS-100., -2000.), pta, dta );
  1355. camint( up, t, 18., vec3(.0,1.,1.), pup, dup );
  1356.  
  1357. roe = terrainUntransform( vec3( 0., EARTH_RADIUS+1.8, 0. ) );
  1358. camint( ro, t, 4.,roe, pro, dro );
  1359. camint( ta, t, 4.5, roe + vec3( EARTH_RADIUS, EARTH_RADIUS+2000., -30.), pta, dta );
  1360. camint( up, t, 4., vec3(.0,1.,1.), pup, dup );
  1361. #endif
  1362. camint( ro, t, 10., vec3(900. ,7000. , 1500. ), pro, dro );
  1363. camint( ta, t, 2., vec3( 0. , 0. , 0. ), pta, dta );
  1364. camint( up, t, 10., vec3( 0. , 0.4, 1. ), pup, dup );
  1365.  
  1366. up = normalize( up );
  1367. }
  1368.  
  1369. //-----------------------------------------------------
  1370. // mainImage
  1371. //-----------------------------------------------------
  1372.  
  1373. void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
  1374. vec2 uv = fragCoord.xy / iResolution.xy;
  1375.  
  1376. vec2 p = -1.0 + 2.0 * (fragCoord.xy) / iResolution.xy;
  1377. p.x *= iResolution.x/iResolution.y;
  1378.  
  1379. vec3 col;
  1380.  
  1381. // black bands
  1382. vec2 bandy = vec2(.1,.9);
  1383. if( uv.y < bandy.x || uv.y > bandy.y ) {
  1384. col = vec3(0.);
  1385. } else {
  1386. // camera
  1387. vec3 ro, ta, up;
  1388. cameraPath( iTime*.7, ro, ta, up );
  1389.  
  1390. vec3 ww = normalize( ta - ro );
  1391. vec3 uu = normalize( cross(ww,up) );
  1392. vec3 vv = normalize( cross(uu,ww));
  1393. vec3 rd = normalize( -p.x*uu + p.y*vv + 2.2*ww );
  1394.  
  1395. float maxd = MAX;
  1396. col = renderStars( rd ).xyz;
  1397.  
  1398. vec4 planet = renderPlanet( ro, rd, up, maxd );
  1399. if( planet.w > 0. ) col.xyz = planet.xyz;
  1400.  
  1401. float atmosphered = maxd;
  1402. vec4 atmosphere = .85*renderAtmospheric( ro, rd, atmosphered );
  1403. col = col * (1.-atmosphere.w ) + atmosphere.xyz;
  1404.  
  1405. vec4 ring = renderRing( ro, rd, maxd );
  1406. if( ring.w > 0. && atmosphered < maxd ) {
  1407. ring.xyz = ring.xyz * (1.-atmosphere.w ) + atmosphere.xyz;
  1408. }
  1409. col = col * (1.-ring.w ) + ring.xyz;
  1410.  
  1411. #ifdef DISPLAY_CLOUDS
  1412. float lro = length(ro);
  1413. if( lro < EARTH_RADIUS+EARTH_CLOUDS*1.25 ) {
  1414. vec3 sunColor = 2.*renderAtmosphericLow( ro, SUN_DIRECTION);
  1415. vec3 upColor = 4.*renderAtmosphericLow( ro, vec3(-SUN_DIRECTION.x, SUN_DIRECTION.y, -SUN_DIRECTION.z));
  1416.  
  1417. if( lro < EARTH_RADIUS+EARTH_CLOUDS ) {
  1418. // clouds
  1419. float d = iCSphereF( ro, rd, EARTH_RADIUS + EARTH_CLOUDS );
  1420. if( d < maxd ) {
  1421. float shadow;
  1422. vec4 clouds = renderClouds( ro, rd, d, normalize(ro), 0., sunColor, upColor, shadow );
  1423. clouds.w *= 1.-smoothstep(0.8*EARTH_CLOUDS,EARTH_CLOUDS,lro-EARTH_RADIUS);
  1424. col = mix(col, clouds.rgb, clouds.w * (1.-smoothstep( 10., 30., d)) );
  1425. }
  1426. }
  1427. float offset = lro-EARTH_RADIUS-EARTH_CLOUDS;
  1428. col = mix( col, .5*sunColor, .15*abs(noise(offset*100.))*clamp(1.-4.*abs(offset)/EARTH_CLOUDS, 0., 1.) );
  1429. }
  1430. #endif
  1431.  
  1432. // post processing
  1433. col = pow( clamp(col,0.0,1.0), vec3(0.4545) );
  1434. col *= vec3(1.,0.99,0.95);
  1435. col = clamp(1.06*col-0.03, 0., 1.);
  1436.  
  1437. vec2 sunuv = 2.7*vec2( dot( SUN_DIRECTION, -uu ), dot( SUN_DIRECTION, vv ) );
  1438. float flare = dot( SUN_DIRECTION, normalize(ta-ro) );
  1439. col += vec3(1.4,1.2,1.0)*lensFlare(p, sunuv)*clamp( flare+.3, 0., 1.);
  1440.  
  1441. uv.y = (uv.y-bandy.x)*(1./(bandy.y-bandy.x));
  1442. col *= 0.5 + 0.5*pow( 16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y), 0.1 );
  1443. }
  1444. fragColor = vec4( col ,1.0);
  1445. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement