Skip to content

Commit ebc5733

Browse files
committed
Added explanation of octaves of noise
1 parent 8843510 commit ebc5733

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

src/volumetric_clouds/main.clj

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -518,14 +518,16 @@
518518
(interpolate z3 2.5 3.5 5.5) => 2.0))
519519

520520
;; ### Octaves of noise
521+
;;
522+
;; Fractal Brownian Motion is implemented by computing a weighted sum of the same base noise function using different frequencies.
521523
(defn fractal-brownian-motion
522524
[base octaves & args]
523525
(let [scales (take (count octaves) (iterate #(* 2 %) 1))]
524526
(reduce + 0.0
525527
(map (fn [amplitude scale] (* amplitude (apply base (map #(* scale %) args))))
526528
octaves scales))))
527529

528-
530+
;; Here the Fractal Brownian Motion is tested using an alternating 1D function and later a 2D checkboard function.
529531
(facts "Fractal Brownian motion"
530532
(let [base1 (fn [x] (if (>= (mod x 2.0) 1.0) 1.0 0.0))
531533
base2 (fn [y x] (if (= (Math/round (mod y 2.0)) (Math/round (mod x 2.0)))
@@ -545,12 +547,13 @@
545547
(fractal-brownian-motion base1 [0.0 1.0] 0.0) => 0.0
546548
(fractal-brownian-motion base1 [0.0 1.0] 0.5) => 1.0))
547549

548-
550+
;; ### Remapping and clamping
551+
;;
552+
;; The remap function is used to map a range of values of an input tensor to a different range.
549553
(defn remap
550554
[value low1 high1 low2 high2]
551555
(dfn/+ low2 (dfn/* (dfn/- value low1) (/ (- high2 low2) (- high1 low1)))))
552556

553-
554557
(tabular "Remap values of tensor"
555558
(fact ((remap (tensor/->tensor [?value]) ?low1 ?high1 ?low2 ?high2) 0)
556559
=> ?expected)
@@ -564,11 +567,11 @@
564567
1 0 2 0 4 2)
565568

566569

570+
;; The clamp function is used to clamp a value to a range.
567571
(defn clamp
568572
[value low high]
569573
(dfn/max low (dfn/min value high)))
570574

571-
572575
(tabular "Clamp values of tensor"
573576
(fact ((clamp (tensor/->tensor [?value]) ?low ?high) 0) => ?expected)
574577
?value ?low ?high ?expected
@@ -577,17 +580,20 @@
577580
0 2 3 2
578581
4 2 3 3)
579582

580-
583+
;; ### Generating octaves of noise
584+
;;
585+
;; The octaves function is to create a series of decreasing weights and normalize them so that they add up to 1.
581586
(defn octaves
582587
[n decay]
583588
(let [series (take n (iterate #(* % decay) 1.0))
584589
sum (apply + series)]
585590
(mapv #(/ % sum) series)))
586591

587-
592+
;; Here is an example of noise weights decreasing by 50% at each octave.
588593
(octaves 4 0.5)
589594

590595

596+
;; Now a noise array can be generated using octaves of noise.
591597
(defn noise-octaves
592598
[tensor octaves low high]
593599
(tensor/clone
@@ -603,10 +609,15 @@
603609
low high 0 255)
604610
0 255)))
605611

612+
;; ### 2D examples
613+
;;
614+
;; Here is an example of 4 octaves of Worley noise.
606615
(bufimg/tensor->image (noise-octaves worley-norm (octaves 4 0.6) 120 230))
607616

617+
;; Here is an example of 4 octaves of Perlin noise.
608618
(bufimg/tensor->image (noise-octaves perlin-norm (octaves 4 0.6) 120 230))
609619

620+
;; Here is an example of 4 octaves of mixed Perlin and Worley noise.
610621
(bufimg/tensor->image (noise-octaves perlin-worley-norm (octaves 4 0.6) 120 230))
611622

612623

@@ -1320,4 +1331,5 @@ float shadow(vec3 point)
13201331
;; * [Vertical density profile](https://www.wedesoft.de/software/2023/05/03/volumetric-clouds/)
13211332
;; * [Powder function](https://advances.realtimerendering.com/s2015/index.html)
13221333
;; * [Curl noise](https://www.wedesoft.de/software/2023/03/20/procedural-global-cloud-cover/)
1334+
;; * [Precomputed atmospheric scattering](https://ebruneton.github.io/precomputed_atmospheric_scattering/)
13231335
;; * [Deep opacity maps](https://www.wedesoft.de/software/2023/05/03/volumetric-clouds/)

0 commit comments

Comments
 (0)