texture-splatter.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
  2. import {math} from './math.js';
  3. import {spline} from './spline.js';
  4. export const texture_splatter = (function() {
  5. const _WHITE = new THREE.Color(0x808080);
  6. const _DEEP_OCEAN = new THREE.Color(0x20020FF);
  7. const _SHALLOW_OCEAN = new THREE.Color(0x8080FF);
  8. const _BEACH = new THREE.Color(0xd9d592);
  9. const _SNOW = new THREE.Color(0xFFFFFF);
  10. const _ApplyWeightsOREST_TROPICAL = new THREE.Color(0x4f9f0f);
  11. const _ApplyWeightsOREST_TEMPERATE = new THREE.Color(0x2b960e);
  12. const _ApplyWeightsOREST_BOREAL = new THREE.Color(0x29c100);
  13. const _GREEN = new THREE.Color(0x80FF80);
  14. const _RED = new THREE.Color(0xFF8080);
  15. const _BLACK = new THREE.Color(0x000000);
  16. class FixedHeightGenerator {
  17. constructor() {}
  18. Get() {
  19. return [50, 1];
  20. }
  21. }
  22. class FixedColourGenerator {
  23. constructor(params) {
  24. this._params = params;
  25. }
  26. Get() {
  27. return this._params.colour;
  28. }
  29. }
  30. class HeightGenerator {
  31. constructor(generator, position, minRadius, maxRadius) {
  32. this._position = position.clone();
  33. this._radius = [minRadius, maxRadius];
  34. this._generator = generator;
  35. }
  36. Get(x, y, z) {
  37. return [this._generator.Get(x, y, z), 1];
  38. }
  39. }
  40. class TextureSplatter {
  41. constructor(params) {
  42. const _colourLerp = (t, p0, p1) => {
  43. const c = p0.clone();
  44. return c.lerp(p1, t);
  45. };
  46. this._colourSpline = [
  47. new spline.LinearSpline(_colourLerp),
  48. new spline.LinearSpline(_colourLerp)
  49. ];
  50. // Arid
  51. this._colourSpline[0].AddPoint(0.0, new THREE.Color(0xb7a67d));
  52. this._colourSpline[0].AddPoint(0.5, new THREE.Color(0xf1e1bc));
  53. this._colourSpline[0].AddPoint(1.0, _SNOW);
  54. // Humid
  55. this._colourSpline[1].AddPoint(0.0, _ApplyWeightsOREST_BOREAL);
  56. this._colourSpline[1].AddPoint(0.5, new THREE.Color(0xcee59c));
  57. this._colourSpline[1].AddPoint(1.0, _SNOW);
  58. this._oceanSpline = new spline.LinearSpline(_colourLerp);
  59. this._oceanSpline.AddPoint(0, _DEEP_OCEAN);
  60. this._oceanSpline.AddPoint(0.03, _SHALLOW_OCEAN);
  61. this._oceanSpline.AddPoint(0.05, _SHALLOW_OCEAN);
  62. this._params = params;
  63. }
  64. _BaseColour(x, y, z) {
  65. const m = this._params.biomeGenerator.Get(x, y, z);
  66. const h = math.sat(z / 100.0);
  67. const c1 = this._colourSpline[0].Get(h);
  68. const c2 = this._colourSpline[1].Get(h);
  69. let c = c1.lerp(c2, m);
  70. if (h < 0.1) {
  71. c = c.lerp(new THREE.Color(0x54380e), 1.0 - math.sat(h / 0.05));
  72. }
  73. return c;
  74. }
  75. _Colour(x, y, z) {
  76. const c = this._BaseColour(x, y, z);
  77. const r = this._params.colourNoise.Get(x, y, z) * 2.0 - 1.0;
  78. c.offsetHSL(0.0, 0.0, r * 0.01);
  79. return c;
  80. }
  81. _GetTextureWeights(p, n, up) {
  82. const m = this._params.biomeGenerator.Get(p.x, p.y, p.z);
  83. const h = p.z / 100.0;
  84. const types = {
  85. dirt: {index: 0, strength: 0.0},
  86. grass: {index: 1, strength: 0.0},
  87. gravel: {index: 2, strength: 0.0},
  88. rock: {index: 3, strength: 0.0},
  89. snow: {index: 4, strength: 0.0},
  90. snowrock: {index: 5, strength: 0.0},
  91. cobble: {index: 6, strength: 0.0},
  92. sandyrock: {index: 7, strength: 0.0},
  93. };
  94. function _ApplyWeights(dst, v, m) {
  95. for (let k in types) {
  96. types[k].strength *= m;
  97. }
  98. types[dst].strength = v;
  99. };
  100. types.grass.strength = 1.0;
  101. _ApplyWeights('gravel', 1.0 - m, m);
  102. if (h < 0.2) {
  103. const s = 1.0 - math.sat((h - 0.1) / 0.05);
  104. _ApplyWeights('cobble', s, 1.0 - s);
  105. if (h < 0.1) {
  106. const s = 1.0 - math.sat((h - 0.05) / 0.05);
  107. _ApplyWeights('sandyrock', s, 1.0 - s);
  108. }
  109. } else {
  110. if (h > 0.125) {
  111. const s = (math.sat((h - 0.125) / 1.25));
  112. _ApplyWeights('rock', s, 1.0 - s);
  113. }
  114. if (h > 1.5) {
  115. const s = math.sat((h - 0.75) / 2.0);
  116. _ApplyWeights('snow', s, 1.0 - s);
  117. }
  118. }
  119. // In case nothing gets set.
  120. types.dirt.strength = 0.01;
  121. let total = 0.0;
  122. for (let k in types) {
  123. total += types[k].strength;
  124. }
  125. if (total < 0.01) {
  126. const a = 0;
  127. }
  128. const normalization = 1.0 / total;
  129. for (let k in types) {
  130. types[k].strength / normalization;
  131. }
  132. return types;
  133. }
  134. GetColour(position) {
  135. return this._Colour(position.x, position.y, position.z);
  136. }
  137. GetSplat(position, normal, up) {
  138. return this._GetTextureWeights(position, normal, up);
  139. }
  140. }
  141. return {
  142. HeightGenerator: HeightGenerator,
  143. TextureSplatter: TextureSplatter,
  144. }
  145. })();