ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/noise.C
(Generate patch)

Comparing deliantra/server/common/noise.C (file contents):
Revision 1.12 by root, Tue Apr 26 14:41:35 2011 UTC vs.
Revision 1.13 by root, Sat Apr 30 05:41:17 2011 UTC

241 241
242template class permutation<256, uint8_t>; 242template class permutation<256, uint8_t>;
243 243
244///////////////////////////////////////////////////////////////////////////// 244/////////////////////////////////////////////////////////////////////////////
245 245
246// various s-shaped curves, smooth to, first, or second derivative
247// used for smooth interpolation from 0..1
248
249// linear
250template<typename T>
251inline T
252sigmoid0 (T x)
253{
254 return x;
255}
256
257// 3x²-2x³
258template<typename T>
259inline T
260sigmoid1 (T x)
261{
262 return (3 - 2 * x) * x * x;
263}
264
265// 6x⁵ - 15x⁴ + 10x³
266template<typename T>
267inline T
268sigmoid2 (T x)
269{
270#ifdef MORE_PARALLELITY
271 float x2 = x * x;
272 float x4 = x2 * x2;
273
274 return (6 * x4 + 10 * x2) * x - 15 * x4;
275#endif
276
277 // simple horner
278 return ((6 * x - 15) * x + 10) * x * x * x;
279}
280
281// blend between a and b
282// c is the control function - if lower than ca
283// then return a, if higher than cb, return b
284template<typename T, typename U>
285inline T
286blend (T a, T b, U c, U ca, U cb, T weight (U) = sigmoid1)
287{
288 if (c <= ca) return a;
289 if (c >= cb) return b;
290
291 T w = weight (lerp (c, ca, cb, T(0), T(1)));
292 return (T(1) - w) * a + w * b;
293}
294
295// blend between a and b
296// c is the control function - if lower than -c_w
297// then return a, if higher than +c_w then b.
298template<typename T, typename U>
299inline T
300blend0 (T a, T b, U c, U c_w, T weight (U) = sigmoid1)
301{
302 return blend<T,U> (a, b, c, -c_w, c_w, weight);
303}
304
305/////////////////////////////////////////////////////////////////////////////
306
307static vec2d
308floor (vec2d v)
309{
310 return vec2d (fastfloor (v[0]), fastfloor (v[1]));
311}
312
313static vec3d
314floor (vec3d v)
315{
316 return vec3d (fastfloor (v[0]), fastfloor (v[1]), fastfloor (v[2]));
317}
318
319template<class vec_t> 246template<class vec_t>
320void 247void
321noise_gen_base<vec_t>::seed (seedable_rand_gen &rng) 248noise_gen_base<vec_t>::seed (seedable_rand_gen &rng)
322{ 249{
323 for (int i = 0; i < array_length (rvmap); ++i) 250 for (int i = 0; i < array_length (rvmap); ++i)
333 this->seed (rng); 260 this->seed (rng);
334} 261}
335 262
336template<> 263template<>
337vec2d::T_numtype 264vec2d::T_numtype
338noise_gen_base<vec2d>::operator() (vec2d P) 265noise_gen_base<vec2d>::operator() (vec2d P, uint32_t seed)
339{ 266{
340 vec2d I = floor (P); 267 vec2d I = floor (P);
341 vec2d F = P - I; 268 vec2d F = P - I;
342 269
343 float v = 0; 270 value_t v = 0;
271
272 uint8_t i1 = uint8_t (I[1]) ^ (seed >> 16);
273 uint8_t i0 = uint8_t (I[0]) ^ (seed >> 8);
344 274
345 for (int j = -1; j <= 2; ++j) 275 for (int j = -1; j <= 2; ++j)
276 {
277 uint8_t h1 = rvmap[1](i1 + j) ^ seed;
278
346 for (int i = -1; i <= 2; ++i) 279 for (int i = -1; i <= 2; ++i)
347 { 280 {
348 vec2d A = F - vec2d (i, j); 281 vec2d A = F - vec2d (i, j);
349
350 float d = dot (A, A); 282 value_t d = dot (A, A);
351 283
352 if (d < 4) 284 if (d < 4)
353 { 285 {
354 float t1 = 1 - d / 4; 286 value_t t1 = 1 - d / 4;
355 float t2 = t1 * t1; 287 value_t t2 = t1 * t1;
356 float t4 = t2 * t2; 288 value_t t4 = t2 * t2;
357 289
358 float p = (4 * t1 - 3) * t4; 290 value_t p = (4 * t1 - 3) * t4;
359 291
360 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j); 292 uint8_t h = rvmap[0](i0 + i) ^ h1;
361 vec2d G = charges2[h & 0xff]; 293 vec2d G = charges2[h & 0xff];
362 294
363 v += dot (A, G) * p; 295 v += dot (A, G) * p;
364 } 296 }
365 } 297 }
298 }
366 299
367 return v; 300 return v;
368} 301}
369 302
370///////////////////////////////////////////////////////////////////////////// 303/////////////////////////////////////////////////////////////////////////////
371 304
372template<> 305template<>
373vec3d::T_numtype 306vec3d::T_numtype
374noise_gen_base<vec3d>::operator() (vec3d P) 307noise_gen_base<vec3d>::operator() (vec3d P, uint32_t seed)
375{ 308{
376 vec3d I = floor (P); 309 vec3d I = floor (P);
377 vec3d F = P - I; 310 vec3d F = P - I;
378 311
379 float v = 0; 312 uint8_t i2 = uint8_t (I[2]) ^ (seed >> 24);
313 uint8_t i1 = uint8_t (I[1]) ^ (seed >> 16);
314 uint8_t i0 = uint8_t (I[0]) ^ (seed >> 8);
380 315
381 for (int j = -1; j <= 2; ++j) 316 value_t v = 0;
382 for (int i = -1; i <= 2; ++i) 317
383 for (int k = -1; k <= 2; ++k) 318 for (int k = -1; k <= 2; ++k)
319 {
320 uint8_t h2 = rvmap[2](i2 + k) ^ seed;
321
322 for (int j = -1; j <= 2; ++j)
384 { 323 {
385 vec3d A = F - vec3d (i, j, k); 324 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
386 float d = dot (A, A);
387 325
388 if (d < 4) 326 for (int i = -1; i <= 2; ++i)
389 { 327 {
390 float t1 = 1 - d / 4;
391 float t2 = t1 * t1;
392 float t4 = t2 * t2;
393
394 // (4t⁵ - 3t⁴)
395 float p = (4 * t1 - 3) * t4;
396
397 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j) ^ rvmap[2](I[2] + k);
398 const float *G = charges3[h & 0xff];
399
400 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
401 }
402 }
403
404 return v * 2;
405}
406
407vec3d::T_numtype
408noise_gen<vec3d>::operator() (vec3d P, vec3d N)
409{
410 vec3d I = floor (P);
411 vec3d F = P - I;
412
413 float v = 0;
414
415 for (int j = -1; j <= 2; ++j)
416 for (int i = -1; i <= 2; ++i)
417 for (int k = -1; k <= 2; ++k)
418 {
419 vec3d D = F - vec3d (i, j, k); 328 vec3d A = F - vec3d (i, j, k);
420 float e = dot (D, N);
421 float o = 1 - abs (e);
422
423 if (o > 0)
424 {
425 vec3d A = D - e * N;
426 float d = dot (A, A); 329 value_t d = dot (A, A);
427 330
428 if (d < 4) 331 if (d < 4)
429 { 332 {
430 float t1 = 1 - d / 4; 333 value_t t1 = 1 - d / 4;
431 float t2 = t1 * t1; 334 value_t t2 = t1 * t1;
432 float t4 = t2 * t2; 335 value_t t4 = t2 * t2;
433 336
434 float o2 = o * o;
435
436 // (4t⁵ - 3t⁴) * (3o³ - 2o²) 337 // (4t⁵ - 3t⁴)
437 // alternative? ((o * 6 - 15) * o + 10) * o³ 338 value_t p = (4 * t1 - 3) * t4;
438 float p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o);
439 339
440 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j) ^ rvmap[2](I[2] + k); 340 uint8_t h = rvmap[0](i0 + i) ^ h1;
441 const float *G = charges3[h & 0xff]; 341 const value_t *G = charges3[h & 0xff];
442 342
443 v += dot (A, vec3d (G[0], G[1], G[2])) * p; 343 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
444 } 344 }
445 } 345 }
446 } 346 }
347 }
348
349 return v * 2;
350}
351
352vec3d::T_numtype
353noise_gen<vec3d>::operator() (vec3d P, vec3d N, uint32_t seed)
354{
355 vec3d I = floor (P);
356 vec3d F = P - I;
357
358 uint8_t i2 = uint8_t (I[2]) ^ (seed >> 24);
359 uint8_t i1 = uint8_t (I[1]) ^ (seed >> 16);
360 uint8_t i0 = uint8_t (I[0]) ^ (seed >> 8);
361
362 value_t v = 0;
363
364 for (int k = -1; k <= 2; ++k)
365 {
366 uint8_t h2 = rvmap[2](i2 + k) ^ seed;
367
368 for (int j = -1; j <= 2; ++j)
369 {
370 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
371
372 for (int i = -1; i <= 2; ++i)
373 {
374 vec3d D = F - vec3d (i, j, k);
375 value_t e = dot (D, N);
376 value_t o = 1 - abs (e);
377
378 if (o > 0)
379 {
380 vec3d A = D - e * N;
381 value_t d = dot (A, A);
382
383 if (d < 4)
384 {
385 value_t t1 = 1 - d / 4;
386 value_t t2 = t1 * t1;
387 value_t t4 = t2 * t2;
388
389 value_t o2 = o * o;
390
391 // (4t⁵ - 3t⁴) * (3o³ - 2o²)
392 // alternative? ((o * 6 - 15) * o + 10) * o³
393 value_t p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o);
394
395 uint8_t h = rvmap[0](i0 + i) ^ h1;
396 const value_t *G = charges3[h & 0xff];
397
398 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
399 }
400 }
401 }
402 }
403 }
447 404
448 return v; 405 return v;
449} 406}
450 407
451template class noise_gen<vec2d>; 408template class noise_gen<vec2d>;
452template class noise_gen<vec3d>; 409template class noise_gen<vec3d>;
453 410
454///////////////////////////////////////////////////////////////////////////// 411/////////////////////////////////////////////////////////////////////////////
455 412
456// find some uncorrelated spot - we assume that noise 2 units away
457// is completely uncorrelated - this is not true for other coordinates,
458// but generally works well.
459template<class vec_t> 413template<class vec_t>
460static vec_t 414frac_gen<vec_t>::frac_gen (int octaves, value_t lacunarity, value_t hurst_expo, seed_t seed)
461ith_octave (vec_t P, int i) 415: octaves (octaves), lac (lacunarity), h (hurst_expo)
462{
463 vec_t r = P;
464 r[0] += i;
465 r[1] += i * 2;
466 return r;
467}
468
469template<class vec_t>
470frac_gen<vec_t>::frac_gen (value_t hurst_expo, value_t lacunarity, seed_t seed)
471: h (hurst_expo), lac (lacunarity)
472{ 416{
473 this->seed (seed); 417 this->seed (seed);
474 418
475 value_t exsum = 0; 419 value_t exsum = 0;
476 value_t phi = noise (vec_t (value_t (0))) * 0.5 + 1; 420 value_t phi = noise (vec_t (value_t (0))) * 0.5 + 1;
477 421
478 for (int i = 0; i < MAX_OCTAVES; ++i) 422 for (int i = 0; i < octaves; ++i)
479 { 423 {
480 ex [i] = pow (lac, -h * i); 424 ex [i] = pow (lac, -h * i);
481 exsum += ex [i]; 425 exsum += ex [i];
482 fbm_mul [i] = 0.5 / (exsum * 0.75); // .75 is a heuristic 426 fbm_mul [i] = 0.5 / (exsum * 0.75); // .75 is a heuristic
483 rot [i].set (phi * i + 1); 427 rot [i].set (phi * i + 1);
484 } 428 }
485} 429}
486 430
487template<class vec_t> 431template<class vec_t>
488typename frac_gen<vec_t>::value_t 432typename frac_gen<vec_t>::value_t
489frac_gen<vec_t>::fBm (vec_t P, int octaves) 433frac_gen<vec_t>::fBm (vec_t P)
490{ 434{
491 value_t v = 0; 435 value_t v = 0;
492 436
493 for (int i = 0; i < octaves; ++i) 437 for (int i = 0; i < octaves; ++i)
494 { 438 {
495 rot [i](P); 439 rot [i](P);
496 v += noise (ith_octave (P, i)) * ex [i]; 440 v += noise (P, i) * ex [i];
497 P *= lac; 441 P *= lac;
498 } 442 }
499 443
500 return v * fbm_mul [octaves - 1]; 444 return v * fbm_mul [octaves - 1];
501} 445}
502 446
503template<class vec_t> 447template<class vec_t>
504typename frac_gen<vec_t>::value_t 448typename frac_gen<vec_t>::value_t
505frac_gen<vec_t>::turbulence (vec_t P, int octaves) 449frac_gen<vec_t>::turbulence (vec_t P)
506{ 450{
507 value_t v = 0; 451 value_t v = 0;
508 452
509 for (int i = 0; i < octaves; ++i) 453 for (int i = 0; i < octaves; ++i)
510 { 454 {
511 rot [i](P); 455 rot [i](P);
512 v += abs (noise (ith_octave (P, i))) * ex [i]; 456 v += abs (noise (P, i)) * ex [i];
513 P *= lac; 457 P *= lac;
514 } 458 }
515 459
516 return v * fbm_mul [octaves - 1] * (0.5 / noise_gen<vec_t>::abs_avg ()); 460 return v * fbm_mul [octaves - 1] * (0.5 / noise_gen<vec_t>::abs_avg ());
517} 461}
518 462
519template<class vec_t> 463template<class vec_t>
520typename frac_gen<vec_t>::value_t 464typename frac_gen<vec_t>::value_t
521frac_gen<vec_t>::multifractal (vec_t P, int octaves, value_t offset) 465frac_gen<vec_t>::multifractal (vec_t P, value_t offset)
522{ 466{
523 value_t v = 1; 467 value_t v = 1;
524 468
525 for (int i = 0; i < octaves; ++i) 469 for (int i = 0; i < octaves; ++i)
526 { 470 {
532 return v * value_t (0.5); 476 return v * value_t (0.5);
533} 477}
534 478
535template<class vec_t> 479template<class vec_t>
536typename frac_gen<vec_t>::value_t 480typename frac_gen<vec_t>::value_t
537frac_gen<vec_t>::heterofractal (vec_t P, int octaves, value_t offset) 481frac_gen<vec_t>::heterofractal (vec_t P, value_t offset)
538{ 482{
539 value_t v = noise (P) + offset; 483 value_t v = noise (P) + offset;
540 484
541 for (int i = 1; i < octaves; ++i) 485 for (int i = 1; i < octaves; ++i)
542 { 486 {
548 return v / (1 << octaves); 492 return v / (1 << octaves);
549} 493}
550 494
551template<class vec_t> 495template<class vec_t>
552typename frac_gen<vec_t>::value_t 496typename frac_gen<vec_t>::value_t
553frac_gen<vec_t>::hybridfractal (vec_t P, int octaves, value_t offset, value_t gain) 497frac_gen<vec_t>::hybridfractal (vec_t P, value_t offset, value_t gain)
554{ 498{
555 value_t v = (noise (P) + offset) * ex [0]; 499 value_t v = (noise (P) + offset) * ex [0];
556 value_t weight = v; 500 value_t weight = v;
557 501
558 for (int i = 1; i < octaves; ++i) 502 for (int i = 1; i < octaves; ++i)
570 return v * value_t (0.5) + value_t (0.5); 514 return v * value_t (0.5) + value_t (0.5);
571} 515}
572 516
573template<class vec_t> 517template<class vec_t>
574typename frac_gen<vec_t>::value_t 518typename frac_gen<vec_t>::value_t
575frac_gen<vec_t>::ridgedmultifractal (vec_t P, int octaves, value_t offset, value_t gain) 519frac_gen<vec_t>::ridgedmultifractal (vec_t P, value_t offset, value_t gain)
576{ 520{
577 value_t sig = offset - abs (noise (P)); 521 value_t sig = offset - abs (noise (P));
578 sig *= sig; 522 sig *= sig;
579 value_t v = sig; 523 value_t v = sig;
580 524
581 for (int i = 1; i < octaves; ++i) 525 for (int i = 1; i < octaves; ++i)
582 { 526 {
583 rot [i](P); 527 rot [i](P);
584 P *= lac; 528 P *= lac;
585 529
530 // weight higher octaves by previous signal
586 value_t w = clamp (sig * gain, 0, 1); 531 value_t w = clamp (sig * gain, 0, 1);
587 532
588 sig = offset - abs (noise (P)); 533 sig = offset - abs (noise (P));
589 sig *= sig; 534 sig *= sig;
590 sig *= w; 535 sig *= w;
595 return v * value_t (0.25); 540 return v * value_t (0.25);
596} 541}
597 542
598template<class vec_t> 543template<class vec_t>
599typename frac_gen<vec_t>::value_t 544typename frac_gen<vec_t>::value_t
600frac_gen<vec_t>::billowfractal (vec_t P, int octaves, value_t offset, value_t gain) 545frac_gen<vec_t>::billowfractal (vec_t P, value_t offset, value_t gain)
601{ 546{
602 value_t v = 0; 547 value_t v = 0;
603 548
604 offset += 2 * noise_gen<vec_t>::abs_avg () - 1; 549 offset += 2 * noise_gen<vec_t>::abs_avg () - 1;
605 550
606 for (int i = 0; i < octaves; ++i) 551 for (int i = 0; i < octaves; ++i)
607 { 552 {
608 rot [i](P); 553 rot [i](P);
609 v += (abs (noise (ith_octave (P, i))) * gain - offset) * ex [i]; 554 v += (abs (noise (P, i)) * gain - offset) * ex [i];
610 P *= lac; 555 P *= lac;
611 } 556 }
612 557
613 return v; 558 return v;
614} 559}
615 560
616// http://www.gamasutra.com/view/feature/3098/a_realtime_procedural_universe_.php?page=2 561// http://www.gamasutra.com/view/feature/3098/a_realtime_procedural_universe_.php?page=2
617template<class vec_t> 562template<class vec_t>
618typename frac_gen<vec_t>::value_t 563typename frac_gen<vec_t>::value_t
619frac_gen<vec_t>::terrain (vec_t P, int octaves) 564frac_gen<vec_t>::terrain (vec_t P)
620{ 565{
621 value_t v = 0; 566 value_t v = 0;
622 567
623 for (int i = 0; i < octaves; ++i) 568 for (int i = 0; i < octaves; ++i)
624 { 569 {
632 return v <= 0 ? - pow (-v, 0.7) : pow (v, 1 + noise (P) * v); 577 return v <= 0 ? - pow (-v, 0.7) : pow (v, 1 + noise (P) * v);
633} 578}
634 579
635template<class vec_t> 580template<class vec_t>
636typename frac_gen<vec_t>::value_t 581typename frac_gen<vec_t>::value_t
637frac_gen<vec_t>::terrain2 (vec_t P, int octaves) 582frac_gen<vec_t>::terrain2 (vec_t P)
638{ 583{
639 value_t a = fBm (P, octaves); 584 value_t a = fBm (P);
640 value_t b = ridgedmultifractal (P, octaves, 1, 8); 585 value_t b = ridgedmultifractal (P, 1, 8);
641 value_t fade = fBm (P + vec_t(10.3), octaves); 586 value_t fade = fBm (P + vec_t(10.3));
642 587
643 const value_t width = 0.05; 588 const value_t width = 0.05;
644 589
645 if (fade > 0.5 + width) 590 if (fade > 0.5 + width)
646 return a; 591 return a;
661///////////////////////////////////////////////////////////////////////////// 606/////////////////////////////////////////////////////////////////////////////
662 607
663void noise_test (); 608void noise_test ();
664void noise_test () 609void noise_test ()
665{ 610{
666 frac_gen<vec2d> gen; 611 frac2d gen;
667 frac_gen<vec3d> gen3; 612
613 frac2d vec_gen1 (4, 2, 0.5, 1);
614 frac2d vec_gen2 (4, 2, 0.5, 2);
668 615
669#if 1 616#if 1
670 int N = 1024; 617 int N = 1024;
671 618
672 printf ("P5 %d %d 255\n", N, N); 619 printf ("P6 %d %d 255\n", N, N);
673 // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm 620 // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm
674 for (int y = 0; y < N; ++y) 621 for (int y = 0; y < N; ++y)
675 { 622 {
676 if (!(y&63))fprintf (stderr, "y %d\n", y);//D 623 if (!(y&63))fprintf (stderr, "y %d\n", y);//D
677 for (int x = 0; x < N; ++x) 624 for (int x = 0; x < N; ++x)
678 { 625 {
679 vec2d P = vec2d (x, y) * (5000.f / N); 626 vec2d P = vec2d (x, y) * (25000.f / N);
680 627
681 //putc (127 * gen.noise (vec2d (x * 0.01, y * 0.01)) + 128, stdout); 628 //putc (127 * gen.noise (vec2d (x * 0.01, y * 0.01)) + 128, stdout);
682 //putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout); 629 //putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout);
683 //putc (256 * gen.fBm (vec2d(x * 0.01, y * 0.01), 16), stdout); 630 //putc (256 * gen.fBm (vec2d(x * 0.01, y * 0.01), 16), stdout);
684 //putc (256 * gen.turbulence (vec2d (x * 0.004 - 1, y * 0.004 - 1), 10), stdout); 631 //putc (256 * gen.turbulence (vec2d (x * 0.004 - 1, y * 0.004 - 1), 10), stdout);
689 636
690 // temperature 637 // temperature
691 //putc (256 * gen.fBm (vec2d (x * 0.002, y * 0.002), 2), stdout); 638 //putc (256 * gen.fBm (vec2d (x * 0.002, y * 0.002), 2), stdout);
692 // rain 639 // rain
693 640
694 float continent = gen.fBm (P * 0.0004, 12) + 0.1f; 641 float continent;
695 float mountain = gen.ridgedmultifractal (P * 0.004, 8, 0.8, 10) * 2;
696 float river = gen.ridgedmultifractal (P * 0.004, 3, 0.8, 10);
697 float sel1 = gen.noise (P * 0.001 + vec2d (5,0));
698 642
699 { 643 {
700 const float W = 100; 644 const float continent_scale = 0.00008;
645
646 vec2d perturb (
647 vec_gen1.fBm (P * 0.0004),
648 vec_gen2.fBm (P * 0.0004)
649 );
650
651 const float W = 1000 * continent_scale;
701 const float N = 5000 - 1; 652 const float N = (25000 - 1) * continent_scale;
653
654 static frac2d perturb_gen (4, 2, 0.5, 3);
655 float perturb_perturb = gen.fBm (P * 0.0004);
656 perturb_perturb = perturb_perturb * perturb_perturb * 0.004;
657
658 vec2d P_perturb = P * continent_scale + perturb * min (W, gen.noise (P * perturb_perturb) * W * 8);
659
660 static frac2d continent_gen (13, 2.13, 0.5);
661 continent = continent_gen.fBm (P_perturb) + 0.05f;
702 662
703 float border = W; // within n places of the border 663 float border = W; // within n places of the border
704 664
705 min_it (border, P [0]); 665 min_it (border, P_perturb [0]);
706 min_it (border, N - P [0]); 666 min_it (border, N - P_perturb [0]);
707 min_it (border, P [1]); 667 min_it (border, P_perturb [1]);
708 min_it (border, N - P [1]); 668 min_it (border, N - P_perturb [1]);
709 669
710 continent = blend (-1.f, continent, border, 0.f, W); 670 continent = blend (-1.f, continent, border, 0.f, W);
711 } 671 }
712 672
713 //float v = blend (mountain, 0.f, river + sel1 * 0.2f, 0.25f, 0.1f); 673 vec3d c (1, 1, 1);
714 float v = blend0 (0.f, 1.f, continent, 0.05f); 674 float v;
715 675
676 if (continent < 0)
677 {
678 // ocean
716 679
717 putc (255 * clamp (v, 0.f, 1.f), stdout); 680 v = min (continent * 10, -0.2f);
681 c = vec3d (0, 0, 1);
682 }
683 else
684 {
685 // continent
686
687 // big rivers
688 static frac2d river_gen (2);
689 float river1 = river_gen.fBm (P * 0.0004);// - (P[0] / 25000) * 0.18 + 0.06;
690 float river2 = river_gen.ridgedmultifractal (P * 0.04 + vec2d (3, 5), 0.8, 10) - (P[1] / 25000) * 0.1;
691
692 if (river1 > 0.05f)
693 {
694 v = -0.1f;
695 c = vec3d (0.4, 0.4, 1);
696 }
697 else if (river1 > 0.08f && river2 > 0.1f)
698 {
699 v = -0.05f;
700 c = vec3d (0.4, 0.4, 1);
701 }
702 else
703 {
704 river1 -= 0.07f;
705
706 //c = river1 > 0 ? vec3d (0.8, 0.8, 0) : vec3d (0.8, 0, 0);
707 c = blend0 (vec3d (0.8, 0, 0), vec3d (0.8, 0.8, 0), river1, 0.01f);;
708
709 static frac2d mountain_gen (8, 2.14, 0.5);
710 float mountain = mountain_gen.ridgedmultifractal (P * 0.004);
711 v = blend0 (mountain * 3 - 1, continent, river1, 0.05f);
712 }
713
714 v=abs(river1) < 0.1;
715 c=vec3d(1,1,1);
716 }
717
718 c *= v * 0.5 + 0.5;
719
720 putc (clamp<int> (255 * c[0], 0, 255), stdout);
721 putc (clamp<int> (255 * c[1], 0, 255), stdout);
722 putc (clamp<int> (255 * c[2], 0, 255), stdout);
718 723
719 //cells 724 //cells
720 //putc (127.49 * gen.billowfractal (vec2d (x * 0.01, y * 0.01), 9) + 128, stdout); 725 //putc (127.49 * gen.billowfractal (vec2d (x * 0.01, y * 0.01), 9) + 128, stdout);
721 } 726 }
722 } 727 }
723#else 728#else
724 int N = 512; 729 int N = 128;
725 730
726 //printf ("P6 %d %d 255\n", N, N); 731 //printf ("P6 %d %d 255\n", N, N);
727 // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm 732 // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm
733 frac3d gen3 (3);;
728 for (int z = 0; z < N; ++z) 734 for (int z = 0; z < N; ++z)
729 { 735 {
730 if (!(z&7))fprintf (stderr, "z %d\n", z);//D 736 if (!(z&7))fprintf (stderr, "z %d\n", z);//D
731 for (int y = 0; y < N; ++y) 737 for (int y = 0; y < N; ++y)
732 for (int x = 0; x < N; ++x) 738 for (int x = 0; x < N; ++x)
733 { 739 {
734 float v = gen3.ridgedmultifractal (vec3d (x * 0.01 + 0.2, y * 0.01 + 0.2, z * 0.01 + 0.2), 3, 1.03, 2) * 2; 740 float v = gen3.ridgedmultifractal (vec3d (x * 0.001 + 0.2, y * 0.001 + 0.2, z * 0.01 + 0.2), 1.03, 2) * 2;
735 741
736#if 0 742#if 0
737 if (z < 64) 743 if (z < 64)
738 v = v * (z * z) / (64 * 64); 744 v = v * (z * z) / (64 * 64);
739#endif 745#endif
740 746
741 if (v <= 0.9999) 747 if (v <= 0.9)
742 continue; 748 continue;
743 749
744 float r[4]; 750 float r[4];
745 int i[4]; 751 int i[4];
746 752

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines