Home Reference Source

src/volume/sdf/FractalNoise.js

  1. import { Box3, Vector3 } from "three";
  2. import { SignedDistanceFunction } from "./SignedDistanceFunction";
  3. import { SDFType } from "./SDFType";
  4.  
  5. /**
  6. * Fades a given value.
  7. *
  8. * @param {Number} t - A value.
  9. * @return {Number} The faded value.
  10. */
  11.  
  12. function fade(t) {
  13.  
  14. return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
  15.  
  16. }
  17.  
  18. /**
  19. * Computes a gradient for a given integer.
  20. *
  21. * @param {Number} p - An arbitrary integer.
  22. * @return {Number} The gradient, 1 or -1.
  23. */
  24.  
  25. function gradient(p) {
  26.  
  27. /* const v = gradients[p % 256];
  28.  
  29. return (v > 0.5) ? 1.0 : -1.0; */
  30.  
  31. return 0;
  32.  
  33. }
  34.  
  35. /**
  36. * Computes a noise value for a given number.
  37. *
  38. * @param {Number} p - An arbitrary number.
  39. * @return {Number} The noise value.
  40. */
  41.  
  42. function noise(p) {
  43.  
  44. const p0 = Math.trunc(p);
  45. const p1 = p0 + 1;
  46.  
  47. const t = p - p0;
  48. const fadeT = fade(t);
  49.  
  50. const g0 = gradient(p0);
  51. const g1 = fade(p1);
  52.  
  53. return (1.0 - fadeT) * g0 * (p - p0) + fadeT * g1 * (p - p1);
  54.  
  55. }
  56.  
  57. /**
  58. * Fractal noise based on Perlin's technique.
  59. *
  60. * Reference:
  61. * https://gpfault.net/posts/perlin-noise.txt.html
  62. */
  63.  
  64. export class FractalNoise extends SignedDistanceFunction {
  65.  
  66. /**
  67. * Constructs a new perlin noise density field.
  68. *
  69. * @param {Object} parameters - The parameters.
  70. * @param {Number} [material] - A material index.
  71. */
  72.  
  73. constructor(parameters = {}, material) {
  74.  
  75. super(SDFType.PERLIN_NOISE, material);
  76.  
  77. /**
  78. * The upper bounds of this density field.
  79. *
  80. * @type {Vector3}
  81. */
  82.  
  83. this.min = new Vector3(...parameters.min);
  84.  
  85. /**
  86. * The upper bounds of this density field.
  87. *
  88. * @type {Vector3}
  89. */
  90.  
  91. this.max = new Vector3(...parameters.max);
  92.  
  93. }
  94.  
  95. /**
  96. * Calculates the bounding box of this density field.
  97. *
  98. * @return {Box3} The bounding box.
  99. */
  100.  
  101. computeBoundingBox() {
  102.  
  103. this.bbox = new Box3(this.min, this.max);
  104.  
  105. return this.bbox;
  106.  
  107. }
  108.  
  109. /**
  110. * Samples the volume's density at the given point in space.
  111. *
  112. * @param {Vector3} position - A position.
  113. * @return {Number} The euclidean distance to the surface.
  114. */
  115.  
  116. sample(position) {
  117.  
  118. }
  119.  
  120. /**
  121. * Serialises this SDF.
  122. *
  123. * @param {Boolean} [toJSON=false] - Whether the serialised data will be stringified.
  124. * @return {Object} A serialised description of this SDF.
  125. */
  126.  
  127. serialize(toJSON = false) {
  128.  
  129. const result = super.serialize();
  130.  
  131. result.parameters = {
  132. min: this.min.toArray(),
  133. max: this.max.toArray()
  134. };
  135.  
  136. return result;
  137.  
  138. }
  139.  
  140. }