Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.43 KB | None | 0 0
  1.  
  2. <!doctype html>
  3. <html>
  4. <head><title>Procedural Island</title></head>
  5. <body style="font-family: sans-serif;">
  6.  
  7. <b id="date_readout">---</b> &nbsp;
  8. <b id="low_readout">---</b>
  9.  
  10. <div id="mouse_elevation" style="position: fixed; z-index:1; background-color:transparent;"></div>
  11. <br>
  12.  
  13. <canvas id="map_canvas" style="background-color: black;">
  14. </canvas>
  15. <!--<canvas id="river_canvas" style = "position: absolute; z-index: 1; background-color:transparent;">
  16. </canvas>-->
  17. <br>
  18. [1] 50kA steps [2] 20kA steps [3] 5kA steps
  19. [S] fix sea level
  20.  
  21.  
  22.  
  23. <script src="noise.js"></script>
  24. <script src="utilities.js"></script>
  25. <script src="voronoi.js"></script>
  26.  
  27.  
  28. <script>
  29. "use strict";
  30.  
  31. create_voronoi_tiling(256, 256, 4, 0, 3);
  32.  
  33.  
  34. let bedrock_thickness = new Float32Array(cell_count);
  35. let sediment_thickness = new Float32Array(cell_count);
  36. let lake_thickness = new Float32Array(cell_count);
  37. let cell_elevation = new Float32Array(cell_count);
  38. let uplift_array = new Float32Array(cell_count);
  39. let erodibility = new Float32Array(cell_count);
  40.  
  41. const km3 = 1000*1000*1000;
  42. const pixel_length = 250; //meters
  43. const mean_sea_level = 2000;
  44. const rainfall = 0.3; // meters per year
  45. const sediment_erosion_distance = 60000; //meters
  46. const bedrock_erosion_distance = 120000;
  47. const fluvial_transport_coefficient = 60; //kg/m^3
  48. const sedimentation_distance = 25000; //meters
  49. const sediment_density = 2200; //kg/m^3
  50. const landscape_diffusion_coefficient = 2; //only applied underwater
  51. let time = 0;
  52. let timestep = 50000; //years
  53. /* Knickpoint retreat of 0.2-2mm/year, say 1mm.
  54. Implies 4km (~one cell) in 4Ma.
  55. --too slow */
  56. const lake_threshold = 5; //only display water if deeper than this
  57.  
  58. </script>
  59.  
  60. <script src="webgl.js"></script>
  61. <script src="drainage.js"></script>
  62.  
  63. <script>
  64.  
  65. //setup_canvas(river_canvas);
  66. //render_voronoi();
  67. //render_delauney();
  68.  
  69. let sea_level = mean_sea_level;
  70. //canvas.style.transform = "scale(0.75)";
  71. setup_initial_relief();
  72. setup_uplift();
  73. fill_lakes();
  74. initialize_drainage();
  75. calculate_drainage_graph();
  76. render();
  77.  
  78. var t0 = performance.now();
  79. //for (let i=0; i<30; i++) {step(timestep);}
  80. var t1 = performance.now();
  81. console.log(((t1 - t0)/30).toFixed(0) + " milliseconds.");
  82.  
  83.  
  84. function setup_initial_relief()
  85. {
  86. var shape = new SNoise(500, 400, -45+Math.random()*90); //-45);
  87. shape.octaves(6, 0.5);
  88. var chunks = new SNoise(500, 300, -45+Math.random()*90); //-45);
  89. chunks.octaves(6, 0.8);
  90. var surface = new SNoise(500, 300, -45+Math.random()*90); //45);
  91. surface.octaves(5, 0.6);
  92. var noise1 = new SNoise(500);
  93. noise1.octaves(2, 0.6);
  94. //var rifting = new SNoise(600, 200, -30+Math.random()*60);
  95. var rifting = new SNoise(200, 50, -30+Math.random()*60);
  96. rifting.octaves(4, 0.6);
  97.  
  98. var mountain = new SNoise(4000, 2400, 90);
  99. mountain.octaves(10, 0.6);
  100. let slope_s = 0.1*(Math.random()-0.5);
  101. let slope_t = 0.1*(Math.random()-0.5);
  102.  
  103. for (let cell=0; cell<cell_count; cell++)
  104. {
  105. bedrock_thickness[cell]=0;
  106. sediment_thickness[cell]=0;
  107. lake_thickness[cell]=0;
  108. erodibility[cell] = 0.5 + Math.random();
  109. let x = cell_x[cell];
  110. let y = cell_y[cell];
  111.  
  112.  
  113. var s = (x/pixel_width)*2-1;
  114. var t = (y/pixel_width)*2-1;
  115. var x_km = 2*x*pixel_length/1000;
  116. var y_km = 2*y*pixel_length/1000;
  117. var h=0;
  118.  
  119. var r = 2*(rifting.get(x_km + noise1.get(2*x_km, 2*y_km)*60, y_km)+0.4);
  120. if (r>0) r *= -10;
  121. else r=r*2000;
  122.  
  123. if (noise1.get(0.5*x_km, 0.5*y_km+10000000) + 0.1*noise1.get(3*x_km+30000, 3*y_km)>0)
  124. {
  125. x_km += 400;
  126. y_km -= 400;
  127. }
  128.  
  129. var e = 1.3*(s*s + t*t)+ 0.8*shape.get(x_km, y_km);
  130. e = 0.7-e;
  131. e = Math.min(e,s*slope_s + t*slope_t);
  132. e *= 5;
  133. h += 2100*(1+e);
  134. h += r*0.6;
  135.  
  136. if (h>=600)
  137. {
  138. h += Math.max(chunks.get(x_km + 99999 + noise1.get(x_km+45345.354, y_km + 45.234) * 200, y_km + noise1.get(x_km, y_km+20000)*200) * 1000, -10);
  139. h += shape.get(x_km*10, y_km*10)*100;
  140. h += Noise.simplex2(x/10, y/10)*20;
  141. h += Math.random()*1;
  142. }
  143.  
  144. if (h<600) h = 600;
  145.  
  146. bedrock_thickness[cell] = h;
  147. sediment_thickness[cell] += Math.random();
  148. if (shape.get(x, y)<0) { bedrock_thickness[cell]-=100; sediment_thickness[cell] +=200;}
  149. }
  150. }
  151.  
  152. function setup_uplift()
  153. {
  154. for (let cell=0; cell<cell_count; cell++)
  155. {
  156. let x = cell_x[cell];
  157. let y = cell_y[cell];
  158.  
  159. let s = (x/pixel_width)*2 -1;
  160. var t = (y/pixel_width)*2-1;
  161. let d=0;
  162. d += compression(x/2, y/2+100*Noise.simplex2(0.45*s,0*0.5*t+6055)+50*Noise.simplex2(s+4,0*t+4) + 18*Noise.simplex2(s*2+100, t*2+1034) + 5 * Noise.simplex2(x/30, y/30), 0);
  163. d += compression(x/2+y/2,x/2-y/2,1000) * 0.2;
  164. d += Noise.simplex2(x/4, y/4)*20;
  165. d += Math.random()*20;
  166. d*= Math.max(2*Noise.simplex2(0.5*s+100, 1.6*t+200)+Noise.simplex2(3*s+200, 5*t+400)*0.5, 0);
  167. d *= 0.5*(t+1);
  168.  
  169. d += Noise.simplex2(0.5*s+50.3, 0.5*t+100.7)*100; //long wavelength change
  170.  
  171. uplift_array[cell] = d/1600;
  172. }
  173. }
  174.  
  175. function setup_test_uplift()
  176. {
  177. for (let cell=0; cell<cell_count; cell++)
  178. {
  179. let x = cell_x[cell];
  180. let y = cell_y[cell];
  181.  
  182. let xx = (x-500)/200;
  183. let yy = (y-500)/200;
  184. let d = 1-Math.sqrt(xx*xx+yy*yy);
  185. //d += (0.2*Noise.simplex2(x/50, y/50))+ 0.3*Noise.simplex2(x/120, y/100) + 0.4*Noise.simplex2(x/250, y/200);
  186. if (d<0) d = 0;
  187. uplift_array[cell] = 2*d;
  188. /*if ((x>200 && x<700) && (y>300 && y<500))
  189. {
  190. uplift_array[cell] = 2;// -20* Math.abs(y-400);
  191. }*/
  192. }
  193. }
  194.  
  195. function uplift(dt)
  196. {
  197. for (let cell = 0; cell < cell_count; cell++)
  198. {
  199. let x = cell_x[cell];
  200. let y = cell_y[cell];
  201. if (cell_elevation[cell] < 1500) continue;
  202. //var h = uplift_array[cell]*dt*0.000004;
  203. let h = uplift_array[cell] * 0.001*dt; //uplift is in mm/year
  204. bedrock_thickness[cell] += h;
  205. }
  206. }
  207.  
  208. function compression(x,y, noise_offset)
  209. {
  210. var e =Noise.simplex2(x/1000+noise_offset, y/160+noise_offset)*y*(pixel_height-y)*1.3/pixel_height;
  211. e += Noise.simplex2(x/400-6+noise_offset, y/60+7+noise_offset)*y*(pixel_height-y)/pixel_height;
  212. e += Noise.simplex2(x/140-9+noise_offset, y/20+20+noise_offset)*y*(pixel_height-y)*0.8/pixel_height;
  213. if (e<0) e*=0.2;
  214. return e;
  215. }
  216.  
  217. function setup_test_initial_relief()
  218. {
  219. let bumps = new SNoise(300, 800, 45+Math.random()*90);
  220. let twist = new SNoise(600);
  221. twist.octaves(2);
  222. let form = new SNoise(900, 900);
  223. form.octaves(5);
  224. bumps.octaves(7, 0.6);
  225. for (let cell=0; cell<cell_count; cell++)
  226. {
  227. bedrock_thickness[cell]=0;
  228. sediment_thickness[cell]=0;
  229. lake_thickness[cell]=0;
  230. erodibility[cell] = 0.75+0.5*Math.random();
  231. let x = cell_x[cell];
  232. let y = cell_y[cell];
  233. if (x <200) bedrock_thickness[cell] = 0;
  234. else if (x<300) bedrock_thickness[cell] = 3100*(x-200)/100;
  235. else bedrock_thickness[cell] = 3100 + 10*Math.random();
  236.  
  237. /*let rift = (form.get(x,y) + 2*x/pixel_width-0.5)*2;
  238. rift = Math.min(1, Math.max(rift, 0));
  239. if (form.get(y+20130, x-23982)<0) y=y+4000;
  240.  
  241. bedrock_thickness[cell] = rift*Math.max(2150,
  242. (2000+1000*bumps.get(x+100*twist.get(x,y), y + 200*twist.get(y/2, x/2))+0.5*x)); //10*Math.random();
  243.  
  244. y = cell
  245.  
  246. _y[cell];
  247. if (y<30) bedrock_thickness[cell] += 120-4*y;
  248. if (y>pixel_height-30) bedrock_thickness[cell] += 4*(y - pixel_height+30);
  249. bedrock_thickness[cell] += Math.random()*2;*/
  250. }
  251. }
  252.  
  253. function old_setup_uplift()
  254. {
  255. let bumps = new SNoise(30, 10, 25);
  256. bumps.octaves(7, 0.6);
  257. for (let cell = 0; cell < cell_count; cell++)
  258. {
  259. uplift_array[cell] = 0.5*bumps.get(cell_x[cell], cell_y[cell]);
  260. uplift_array[cell] += 0.1*Math.random();
  261. }
  262. }
  263.  
  264.  
  265.  
  266.  
  267.  
  268. let change_sea_level = true;
  269. function step(dt)
  270. {
  271. time += dt;
  272. if (time>2000000 && change_sea_level) sea_level = mean_sea_level + 50 * Math.sin(2*Math.PI*time / 500000);
  273. if (time>500000 && change_sea_level) uplift(dt);
  274. initialize_drainage();
  275. calculate_drainage_graph();
  276. run_drainage(dt);
  277. render();
  278. }
  279.  
  280. function render()
  281. {
  282. //draw_GL_relief();
  283. draw_mesh(cell_elevation);
  284. draw_coastlines(1);
  285. draw_rivers(0.01*km3, 2*km3, 1);
  286. }
  287.  
  288.  
  289. let mouse_x = 0;
  290. let mouse_y = 0;
  291. let mouse_in_window = true;
  292. document.addEventListener('mousemove', mouse_move);
  293. document.addEventListener('mouseleave', function(){ mouse_in_window = false; mouse_elevation.innerHTML="";});
  294. document.addEventListener('mouseenter', function(){ mouse_in_window = true; });
  295.  
  296.  
  297.  
  298.  
  299. let animate_toggle=false;
  300. let auto_run = true;
  301. onkeydown = function(e)
  302. {
  303. e.preventDefault();
  304. console.log(e.keyCode);
  305. auto_run = false;
  306. if (e.keyCode === 32) {animate_toggle = true;}
  307. else if (e.keyCode === 51) { timestep = 5000; animate_toggle = true;} //3
  308. else if (e.keyCode === 50) { timestep = 20000; animate_toggle = true;} //2
  309. else if (e.keyCode === 49) { timestep = 50000; animate_toggle = true;} //1
  310. else if (e.keyCode === 83) { change_sea_level = !change_sea_level} //s
  311. }
  312. onkeyup = function(){animate_toggle = false; }
  313. function animate(t)
  314. {
  315. if (time < 4000000 && auto_run) step(50000);
  316. else if (time < 4200000 && auto_run) step(20000);
  317. else if (time < 4250000 && auto_run) step(5000);
  318. else if (animate_toggle) step(timestep);
  319. update_mouse();
  320. requestAnimationFrame(animate);
  321. }
  322. animate();
  323.  
  324. function draw_GL_relief()
  325. {
  326. for (let i=0; i<cell_count; i++)
  327. {
  328. cell_elevation[i] = bedrock_thickness[i]+sediment_thickness[i];
  329. }
  330. draw_mesh(cell_elevation);
  331. }
  332.  
  333.  
  334.  
  335. function mouse_move(event)
  336. {
  337. let rect = map_canvas.getBoundingClientRect();
  338. mouse_x = event.clientX - rect.left;
  339. mouse_y = event.clientY - rect.top;
  340. mouse_elevation.style.left = (event.clientX+20)+'px';
  341. mouse_elevation.style.top = (event.clientY+20)+'px';
  342. update_mouse();
  343. }
  344.  
  345. function update_mouse()
  346. {
  347. let Ma = (time/1000000).toFixed(2);
  348. text = (time/1000000).toFixed(2)+" Ma";
  349. date_readout.innerHTML = text;
  350.  
  351. let cell = get_nearest_cell(mouse_x, mouse_y);
  352. text = "";
  353. if (cell != -1 && mouse_in_window)
  354. {
  355. let elevation = bedrock_thickness[cell]+sediment_thickness[cell]-mean_sea_level;
  356. //let with_water = elevation + lake_thickness[i];
  357. text = "["+cell+"] "+elevation.toFixed(1)+"m";
  358. //if (with_water>elevation) text +=" ("+with_water.toFixed(0)+"m)";
  359.  
  360. /*for (let i=0; i<cell_neighbour_count[cell]; i++)
  361. {
  362. let weight = neighbour_weights[cell*9+i];
  363. if (weight != -1) text += ", "+weight.toExponential(1);
  364. else text += ", _"
  365. }*/
  366. }
  367. mouse_elevation.innerHTML = text;
  368.  
  369.  
  370. }
  371. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement