Skip to content

Commit ffb4b1a

Browse files
committed
Working on OpenGL explanation
1 parent ebc5733 commit ffb4b1a

1 file changed

Lines changed: 30 additions & 27 deletions

File tree

src/volumetric_clouds/main.clj

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
[org.lwjgl.opengl GL GL11 GL12 GL13 GL15 GL20 GL30 GL32 GL42]))
3030

3131

32-
;; # Procedural generation of volumetric clouds
33-
;;
3432
;; Volumetric clouds are commonly used in flight simulators and visual effects.
3533
;; For a introductory video see [Sebastian Lague's video "Coding Adventure: Clouds](https://www.youtube.com/watch?v=4QOcCGI6xOU).
3634
;; Note that this article is about procedural generation and not about simulating real weather.
@@ -39,7 +37,7 @@
3937
;;
4038
;; [Worley noise](https://en.wikipedia.org/wiki/Worley_noise) is a type of structured noise which is defined for each pixel using the distance to the nearest seed point.
4139
;;
42-
;; ### Noise parameters
40+
;; #### Noise parameters
4341
;;
4442
;; First we define a function to create parameters of the noise.
4543
;;
@@ -57,7 +55,7 @@
5755
(make-noise-params 256 8 2) => {:size 256 :divisions 8 :cellsize 32 :dimensions 2})
5856

5957

60-
;; ### 2D and 3D vectors
58+
;; #### 2D and 3D vectors
6159
;;
6260
;; Next we need a function which allows us to create 2D or 3D vectors depending on the number of input parameters.
6361
(defn vec-n
@@ -69,7 +67,7 @@
6967
(vec-n 2 3 1) => (vec3 2 3 1))
7068

7169

72-
;; ### Random points
70+
;; #### Random points
7371
;;
7472
;; The following method generates a random point in a cell specified by the cell indices.
7573
(defn random-point-in-cell
@@ -115,7 +113,7 @@
115113
(plotly/layer-point {:=x :x :=y :y})))
116114

117115

118-
;; ### Modular distance
116+
;; #### Modular distance
119117
;;
120118
;; In order to get a periodic noise array, we need to component-wise wrap around distance vectors.
121119
(defn mod-vec
@@ -158,7 +156,7 @@
158156
0 5 0 0 3.0)
159157

160158

161-
;; ### Modular lookup
159+
;; #### Modular lookup
162160
;;
163161
;; We also need to lookup elements with wrap around.
164162
;; We recursively use `tensor/select` and then finally the tensor as a function to lookup along each axis.
@@ -187,7 +185,7 @@
187185
(division-index {:cellsize 4} 7.5) => 1
188186
(division-index {:cellsize 4} -0.5) => -1)
189187

190-
;; ### Getting indices of Neighbours
188+
;; #### Getting indices of Neighbours
191189
;;
192190
;; The following function determines the neighbouring indices of a cell recursing over each dimension.
193191
(defn neighbours
@@ -204,7 +202,7 @@
204202
(neighbours 1 10) => [[0 9] [1 9] [2 9] [0 10] [1 10] [2 10] [0 11] [1 11] [2 11]])
205203

206204

207-
;; ### Sampling Worley noise
205+
;; #### Sampling Worley noise
208206
;;
209207
;; Using above functions one can now implement Worley noise.
210208
;; For each pixel the distance to the closest seed point is calculated.
@@ -240,7 +238,7 @@
240238
;; [Perlin noise](https://adrianb.io/2014/08/09/perlinnoise.html) is generated by choosing a random gradient vector at each cell corner.
241239
;; The noise tensor's intermediate values are interpolated with a continuous function, utilizing the gradient at the corner points.
242240

243-
;; ### Random gradients
241+
;; #### Random gradients
244242
;;
245243
;; The 2D or 3D gradients are generated by creating a vector where each component is set to a random number between -1 and 1.
246244
;; Random vectors are generated until the vector length is greater 0 and lower or equal to 1.
@@ -305,7 +303,7 @@
305303
(plotly/base {:=title "Random gradients" :=mode "lines"})
306304
(plotly/layer-point {:=x :x :=y :y})))
307305

308-
;; ### Corner vectors
306+
;; #### Corner vectors
309307
;;
310308
;; The next step is to determine the vectors to the corners of the cell for a given point.
311309
;; First we define a function to determine the fractional part of a number.
@@ -346,7 +344,7 @@
346344
(v2 1 1) => (vec2 -0.25 -0.5)
347345
(v3 0 0 0) => (vec3 0.75 0.5 0.25)))
348346

349-
;; ### Extract gradients of cell corners
347+
;; #### Extract gradients of cell corners
350348
;;
351349
;; The function below retrieves the gradient values at a cell's corners, utilizing `wrap-get` for modular access.
352350
(defn corner-gradients
@@ -372,7 +370,7 @@
372370
((corner-gradients {:cellsize 4 :dimensions 3} gradients3 (vec3 9 6 3)) 0 0 0)
373371
=> (vec3 2 1 0)))
374372

375-
;; ### Influence values
373+
;; #### Influence values
376374
;;
377375
;; The influence value is the function value of the function with the selected random gradient at a corner.
378376
(defn influence-values
@@ -395,7 +393,7 @@
395393
(influence2 1 1) => 11.0
396394
(influence3 1 1 1) => 111.0))
397395

398-
;; ### Interpolating the influence values
396+
;; #### Interpolating the influence values
399397
;;
400398
;; For interpolation the following "ease curve" is used.
401399
(defn ease-curve
@@ -437,7 +435,7 @@
437435
(weights3 0 0 0) => (roughly 0.010430 1e-6)))
438436

439437

440-
;; ### Sampling Perlin noise
438+
;; #### Sampling Perlin noise
441439
;;
442440
;; A Perlin noise sample is computed by
443441
;; * Getting the random gradients for the cell corners.
@@ -478,15 +476,15 @@
478476

479477
;; ## Mixing noise values
480478
;;
481-
;; ### Combination of Worley and Perlin noise
479+
;; #### Combination of Worley and Perlin noise
482480
;;
483481
;; One can mix Worley and Perlin noise by simply doing a linear combination of the two.
484482
(def perlin-worley-norm (dfn/+ (dfn/* 0.3 perlin-norm) (dfn/* 0.7 worley-norm)))
485483

486484
;; Here for example is the average of Perlin and Worley noise.
487485
(bufimg/tensor->image (dfn/+ (dfn/* 0.5 perlin-norm) (dfn/* 0.5 worley-norm)))
488486

489-
;; ### Interpolation
487+
;; #### Interpolation
490488
;;
491489
;; One can linearly interpolate tensor values by recursing over the dimensions as follows.
492490
(defn interpolate
@@ -517,7 +515,7 @@
517515
(interpolate y3 2.5 3.5 3.0) => 3.0
518516
(interpolate z3 2.5 3.5 5.5) => 2.0))
519517

520-
;; ### Octaves of noise
518+
;; #### Octaves of noise
521519
;;
522520
;; Fractal Brownian Motion is implemented by computing a weighted sum of the same base noise function using different frequencies.
523521
(defn fractal-brownian-motion
@@ -547,7 +545,7 @@
547545
(fractal-brownian-motion base1 [0.0 1.0] 0.0) => 0.0
548546
(fractal-brownian-motion base1 [0.0 1.0] 0.5) => 1.0))
549547

550-
;; ### Remapping and clamping
548+
;; #### Remapping and clamping
551549
;;
552550
;; The remap function is used to map a range of values of an input tensor to a different range.
553551
(defn remap
@@ -580,7 +578,7 @@
580578
0 2 3 2
581579
4 2 3 3)
582580

583-
;; ### Generating octaves of noise
581+
;; #### Generating octaves of noise
584582
;;
585583
;; The octaves function is to create a series of decreasing weights and normalize them so that they add up to 1.
586584
(defn octaves
@@ -609,7 +607,7 @@
609607
low high 0 255)
610608
0 255)))
611609

612-
;; ### 2D examples
610+
;; #### 2D examples
613611
;;
614612
;; Here is an example of 4 octaves of Worley noise.
615613
(bufimg/tensor->image (noise-octaves worley-norm (octaves 4 0.6) 120 230))
@@ -621,8 +619,11 @@
621619
(bufimg/tensor->image (noise-octaves perlin-worley-norm (octaves 4 0.6) 120 230))
622620

623621

624-
;; ## Testing shaders
622+
;; ## Volumetric clouds
625623

624+
;; #### OpenGL setup
625+
;;
626+
;; In order to render the clouds we create a window and an OpenGL context.
626627
(GLFW/glfwInit)
627628

628629
(def window-width 640)
@@ -635,7 +636,9 @@
635636
(GLFW/glfwMakeContextCurrent window)
636637
(GL/createCapabilities)
637638

638-
639+
;; #### Compiling and linking shader programs
640+
;;
641+
;; The following method is used compile a shader program.
639642
(defn make-shader [source shader-type]
640643
(let [shader (GL20/glCreateShader shader-type)]
641644
(GL20/glShaderSource shader source)
@@ -664,17 +667,17 @@
664667
program))
665668

666669

667-
(def vertex-test "
668-
#version 130
670+
(def vertex-test
671+
"#version 130
669672
in vec3 point;
670673
void main()
671674
{
672675
gl_Position = vec4(point, 1);
673676
}")
674677

675678

676-
(def fragment-test "
677-
#version 130
679+
(def fragment-test
680+
"#version 130
678681
out vec4 fragColor;
679682
void main()
680683
{

0 commit comments

Comments
 (0)