-
Notifications
You must be signed in to change notification settings - Fork 2
/
atom
177 lines (160 loc) · 45.4 KB
/
atom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>M. Utku Altınkaya</title><link href="/./" rel="alternate"></link><link href="/./atom" rel="self"></link><id>/./</id><updated>2013-07-03T11:30:00+03:00</updated><entry><title>Including GLSL Shaders</title><link href="/./including-glsl-shaders.html" rel="alternate"></link><updated>2013-07-03T11:30:00+03:00</updated><author><name>M. Utku Altınkaya</name></author><id>tag:/.,2013-07-03:including-glsl-shaders.html</id><summary type="html"><p>Shaders are combination of different effects, you may need skinning and shadows to render your character, but just diffuse textures for skymap, while doing a depth pass only, you do not need to render any textures but deformation is still needed for skinned meshes. More effects you have, more combinations you end up with. </p>
<p>One solution to this problem is writing a mega-shader, a shader combines multiple effects but choses which ones to run using conditional blocks. However even if you are using uniform variables which does not change until rasterization is complete, you still can suffer from performance penalty by changing uniforms in some driver implementations.<a href="http://www.opengl.org/discussion_boards/showthread.php/152817-nVidia-FP-uniforms-driver-optimization-lags?p=1094138#post1094138">[1]</a></p>
<p>Non-implementation dependent solution is to use preprocessor directives in GLSL, and generating shaders for your effect combinations. This way we can organize code into different mini-shaders combined in compile time.</p>
<p>For example:</p>
<div class="highlight"><pre><span class="n">reShader</span><span class="o">*</span> <span class="n">shader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">reShader</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">reEFFECT_SHADOW_MAP</span> <span class="o">&amp;</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">shader</span><span class="o">-&gt;</span><span class="n">defines</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="s">&quot;_SHADOW_MAP_&quot;</span><span class="p">);</span> <span class="c1">// Shadow effect</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">reEFFECT_DIFFUSE_TEXTURE</span> <span class="o">&amp;</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">shader</span><span class="o">-&gt;</span><span class="n">defines</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="s">&quot;_DIFFUSE_TEXTURE_&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">reEFFECT_SKIN</span> <span class="o">&amp;</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">shader</span><span class="o">-&gt;</span><span class="n">defines</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="s">&quot;_SKIN_&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">shader</span><span class="p">;</span>
</pre></div>
<p>Vertex shader GLSL:</p>
<div class="highlight"><pre><span class="cp">#ifdef _SHADOW_CAST_</span>
<span class="cp">#pragma include &quot;vsm_cast.fp&quot;</span>
<span class="cp">#else</span>
<span class="k">float</span> <span class="n">illumination</span><span class="p">()</span>
<span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="cp">#endif</span>
<span class="k">vec4</span> <span class="n">getDiffuse</span><span class="p">()</span>
<span class="p">{</span>
<span class="cp">#ifdef _DIFFUSE_TEXTURE_</span>
<span class="k">return</span> <span class="n">diffuseColor</span> <span class="o">*</span> <span class="n">texture2D</span><span class="p">(</span><span class="n">diffuseTexture</span><span class="p">,</span> <span class="n">uv</span><span class="p">);</span>
<span class="cp">#else</span>
<span class="k">return</span> <span class="n">diffuseColor</span><span class="p">;</span>
<span class="cp">#endif</span>
<span class="p">}</span>
<span class="cp">#ifdef _SHADOW_MAP_</span>
<span class="cp">#pragma include &quot;vsm_shadow.fp&quot;</span>
<span class="cp">#else</span>
<span class="k">vec4</span> <span class="n">getColor</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">vec4</span> <span class="n">color</span> <span class="o">=</span> <span class="n">getDiffuse</span><span class="p">()</span> <span class="o">*</span> <span class="n">illumination</span><span class="p">();</span>
<span class="k">return</span> <span class="n">color</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">#endif</span>
<span class="k">void</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">gl_FragColor</span> <span class="o">=</span> <span class="n">getColor</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<p>Inluding shaders is a way of organizing your code, however GLSL does not provide a way for source code inclusion, since it does not really have a concept of files. We need a small function to do it for us:</p>
<div class="highlight"><pre><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">reShader</span><span class="o">::</span><span class="n">preprocess</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">src</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">stringstream</span> <span class="n">ss</span><span class="p">(</span><span class="n">src</span><span class="p">),</span> <span class="n">out</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">;</span>
<span class="n">string</span> <span class="nf">pragma</span><span class="p">(</span><span class="s">&quot;#pragma include&quot;</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">getline</span><span class="p">(</span><span class="n">ss</span><span class="p">,</span> <span class="n">line</span><span class="p">))</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">pos</span> <span class="o">=</span> <span class="n">line</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">pragma</span><span class="p">)</span> <span class="o">!=</span> <span class="n">string</span><span class="o">::</span><span class="n">npos</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">string</span> <span class="n">include</span> <span class="o">=</span> <span class="n">line</span><span class="p">.</span><span class="n">substr</span><span class="p">(</span><span class="n">pos</span><span class="o">+</span><span class="n">pragma</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">pos</span><span class="o">+</span><span class="n">line</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="n">pragma</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">4</span><span class="p">);</span>
<span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="n">reRadial</span><span class="o">::</span><span class="n">shared</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">assetLoader</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">loadFile</span><span class="p">(</span><span class="s">&quot;shaders/&quot;</span><span class="o">+</span><span class="n">include</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="n">line</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">out</span><span class="p">.</span><span class="n">str</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<h2>Conlusion</h2>
<p>If you have too many effect combinations, you will end up with too many shaders, switches between shaders can also have performance penalty, so most of the times, combining shaders can also be used with conditionals. For instance multiple effects commonly used together can be defined as single effect, this way we can also specialize the code for certain combination. Your mileage will vary depending on the platform you target, benchmarks are necessary to find optimal render strategy for your needs.</p></summary><category term="OpenGL"></category><category term="C++"></category></entry><entry><title>Procedural terrain collider for Bullet</title><link href="/./procedural-terrain-collider.html" rel="alternate"></link><updated>2013-06-05T12:30:00+03:00</updated><author><name>M. Utku Altınkaya</name></author><id>tag:/.,2013-06-05:procedural-terrain-collider.html</id><summary type="html"><p>Generating terrain entirely on the GPU is cool, however as pretty as it looks, in the end you need to interact with it. <a href="http://http://bulletphysics.org">Bullet</a> Physics engine provides very neat ways to define your own collider shapes. So I decided to port GPU code to C++ and use the output for bullet shape.</p>
<p>Porting <a href="https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl">noise</a> was easy since <a href="http://glm.g-truc.net/0.9.4/index.html">GLM</a> library has been designed to be as close as to shader code. You can checkout it on <a href="https://github.com/mua/Radial-Engine/blob/master/src/engine/reNoise.cpp">Github</a></p>
<p>Now the fun part: <a href="https://github.com/mua/Radial-Engine/blob/master/src/engine/reBody.cpp#L290">Full code</a></p>
<div class="highlight"><pre><span class="k">virtual</span> <span class="kt">void</span> <span class="nf">processAllTriangles</span><span class="p">(</span><span class="n">btTriangleCallback</span><span class="o">*</span> <span class="n">callback</span><span class="p">,</span>
<span class="k">const</span> <span class="n">btVector3</span><span class="o">&amp;</span> <span class="n">aabbMin</span><span class="p">,</span>
<span class="k">const</span> <span class="n">btVector3</span><span class="o">&amp;</span> <span class="n">aabbMax</span><span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
<span class="n">reVec3</span> <span class="n">expand</span><span class="p">(</span><span class="mf">1.5</span><span class="p">,</span><span class="mf">1.5</span><span class="p">,</span><span class="mf">1.5</span><span class="p">);</span>
<span class="n">reVec3</span> <span class="n">min</span> <span class="o">=</span> <span class="n">fromBullet</span><span class="p">(</span><span class="n">aabbMin</span><span class="p">)</span><span class="o">-</span><span class="n">expand</span><span class="p">,</span> <span class="n">max</span> <span class="o">=</span> <span class="n">fromBullet</span><span class="p">(</span><span class="n">aabbMax</span><span class="p">)</span><span class="o">+</span><span class="n">expand</span><span class="p">;</span>
<span class="n">btVector3</span> <span class="n">c</span> <span class="o">=</span> <span class="n">toBullet</span><span class="p">(</span><span class="n">calculateVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">((</span><span class="n">min</span><span class="p">.</span><span class="n">x</span><span class="o">+</span><span class="n">max</span><span class="p">.</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="mf">0.5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="n">min</span><span class="p">.</span><span class="n">z</span><span class="o">+</span><span class="n">max</span><span class="p">.</span><span class="n">z</span><span class="p">)</span><span class="o">*</span><span class="mf">0.5</span><span class="p">)));</span>
<span class="n">btVector3</span> <span class="n">bl</span> <span class="o">=</span> <span class="n">toBullet</span><span class="p">(</span><span class="n">calculateVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">min</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">min</span><span class="p">.</span><span class="n">z</span><span class="p">)));</span>
<span class="n">btVector3</span> <span class="n">br</span> <span class="o">=</span> <span class="n">toBullet</span><span class="p">(</span><span class="n">calculateVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">min</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">max</span><span class="p">.</span><span class="n">z</span><span class="p">)));</span>
<span class="n">btVector3</span> <span class="n">tl</span> <span class="o">=</span> <span class="n">toBullet</span><span class="p">(</span><span class="n">calculateVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">max</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">min</span><span class="p">.</span><span class="n">z</span><span class="p">)));</span>
<span class="n">btVector3</span> <span class="n">tr</span> <span class="o">=</span> <span class="n">toBullet</span><span class="p">(</span><span class="n">calculateVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">max</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">max</span><span class="p">.</span><span class="n">z</span><span class="p">)));</span>
<span class="n">btVector3</span> <span class="n">vertices</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">bl</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">br</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
<span class="n">callback</span><span class="o">-&gt;</span><span class="n">processTriangle</span><span class="p">(</span><span class="n">vertices</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tr</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tl</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
<span class="n">callback</span><span class="o">-&gt;</span><span class="n">processTriangle</span><span class="p">(</span><span class="n">vertices</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">br</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tr</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
<span class="n">callback</span><span class="o">-&gt;</span><span class="n">processTriangle</span><span class="p">(</span><span class="n">vertices</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">tl</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">bl</span><span class="p">;</span>
<span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
<span class="n">callback</span><span class="o">-&gt;</span><span class="n">processTriangle</span><span class="p">(</span><span class="n">vertices</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Each time bullet queries out collision shape, the noise functions are used to get the vertices necessary and return triangles. One of the other cool things about this is, bullet actually queries with AABB(axis aligned bounding box) of interest, what we return depends on location of that AABB, we generate the surface inside of it, so the virtual resolution of our terrain is very very high, smoother simulation is a bonus.</p>
<h2>Conclusion</h2>
<p>Putting together a procedural terrain collider was easier than I thought, and bullet played with it pretty nicely. This still seems more and more like a very viable option for mobile games.</p></summary><category term="OpenGL"></category><category term="C++"></category><category term="Physics"></category></entry><entry><title>Procedural terrain generation on GPU</title><link href="/./procedural-3d-terrain.html" rel="alternate"></link><updated>2013-06-01T10:20:00+03:00</updated><author><name>M. Utku Altınkaya</name></author><id>tag:/.,2013-06-01:procedural-3d-terrain.html</id><summary type="html"><p>While working on a small mobile project, I've started to look for ways to render infinite terrain. Modern mobile GPUs come with very slow memory, low bandwidth, but reasonable processing power. So procedural content does not only have interesting gameplay value, but also performance advantages. </p>
<p>I constructed simple terrain mesh:</p>
<div class="highlight"><pre><span class="kt">void</span> <span class="n">rePTerrainRenderable</span><span class="o">::</span><span class="n">load</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">reGroup</span><span class="o">*</span> <span class="n">group</span> <span class="o">=</span> <span class="k">new</span> <span class="n">reGroup</span><span class="p">;</span>
<span class="n">reVec3</span> <span class="nf">offset</span><span class="p">(</span><span class="o">-</span><span class="n">columns</span><span class="p">()</span><span class="o">*</span><span class="n">size</span><span class="p">().</span><span class="n">x</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="n">rows</span><span class="p">()</span><span class="o">*</span><span class="n">size</span><span class="p">().</span><span class="n">y</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">x</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">x</span><span class="o">&lt;</span><span class="n">columns</span><span class="p">();</span> <span class="n">x</span><span class="o">++</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span> <span class="kt">size_t</span> <span class="n">y</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">y</span><span class="o">&lt;</span><span class="n">rows</span><span class="p">();</span> <span class="n">y</span><span class="o">++</span><span class="p">)</span> <span class="c1">// Each &quot;cell&quot; is made of 2 faces</span>
<span class="p">{</span>
<span class="kt">float</span> <span class="n">x1</span> <span class="o">=</span> <span class="n">x</span><span class="o">*</span><span class="n">size</span><span class="p">().</span><span class="n">x</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">y1</span> <span class="o">=</span> <span class="n">y</span><span class="o">*</span><span class="n">size</span><span class="p">().</span><span class="n">y</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">x2</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">size</span><span class="p">().</span><span class="n">x</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">y2</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">size</span><span class="p">().</span><span class="n">y</span><span class="p">;</span>
<span class="n">reFace</span> <span class="n">face1</span><span class="p">,</span> <span class="n">face2</span><span class="p">;</span>
<span class="n">face1</span><span class="p">.</span><span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">reVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">x1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y2</span><span class="p">)</span><span class="o">+</span> <span class="n">offset</span><span class="p">);</span>
<span class="n">face1</span><span class="p">.</span><span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">reVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">x2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y1</span><span class="p">)</span><span class="o">+</span> <span class="n">offset</span><span class="p">);</span>
<span class="n">face1</span><span class="p">.</span><span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">reVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">x1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y1</span><span class="p">)</span><span class="o">+</span> <span class="n">offset</span><span class="p">);</span>
<span class="n">face2</span><span class="p">.</span><span class="n">vertices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">reVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">x1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y2</span><span class="p">)</span><span class="o">+</span> <span class="n">offset</span><span class="p">);</span>
<span class="n">face2</span><span class="p">.</span><span class="n">vertices</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">reVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">x2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y2</span><span class="p">)</span><span class="o">+</span> <span class="n">offset</span><span class="p">);</span>
<span class="n">face2</span><span class="p">.</span><span class="n">vertices</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">reVertex</span><span class="p">(</span><span class="n">reVec3</span><span class="p">(</span><span class="n">x2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y1</span><span class="p">)</span><span class="o">+</span> <span class="n">offset</span><span class="p">);</span>
<span class="n">group</span><span class="o">-&gt;</span><span class="n">faces</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">face1</span><span class="p">);</span>
<span class="n">group</span><span class="o">-&gt;</span><span class="n">faces</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">face2</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">mesh</span><span class="o">-&gt;</span><span class="n">groups</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">group</span><span class="p">);</span>
<span class="n">group</span><span class="o">-&gt;</span><span class="n">bufferChanged</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>We need pseudo random values changing in a smooth way, pseudo random since we need continuity.
There are various noise implementations for GLSL, I've chosen <a href="https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl">snoise</a>.</p>
<p>Here is the vertex shader, generally speaking how jagged the surface is defined by amount of change of input, so by dividing input vector we are smoothing the surface, adding a second as multiplier just increases variation.</p>
<p>Vertex shader is very simple:</p>
<div class="highlight"><pre><span class="k">vec4</span> <span class="n">calculateVertex</span><span class="p">(</span><span class="k">vec4</span> <span class="n">pos</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">vec2</span> <span class="n">loc</span> <span class="o">=</span> <span class="k">vec2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">z</span><span class="p">);</span>
<span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">snoise</span><span class="p">(</span><span class="n">loc</span><span class="o">/</span><span class="mf">50.0</span><span class="n">f</span><span class="p">)</span><span class="o">*</span><span class="mi">3</span><span class="o">*</span><span class="n">snoise</span><span class="p">(</span><span class="n">loc</span><span class="o">/</span><span class="mf">100.0</span><span class="n">f</span><span class="p">);</span>
<span class="k">return</span> <span class="n">pos</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Calculating normals requires taking your vertex and extending in both +x, -x, +z, -z directions, after that we end up with 4 triangles. Cross product of edges gives us the triangle normal. Average of these normals can be used as approximate vertex normal we can interpolate.</p>
<div class="highlight"><pre><span class="k">vec3</span> <span class="n">calculateNormal</span><span class="p">(</span><span class="k">vec4</span> <span class="n">pos</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">float</span> <span class="n">s</span> <span class="o">=</span> <span class="mf">.01</span><span class="p">;</span> <span class="c1">// it should be small enough to be precise, </span>
<span class="c1">// big enough to match visible surface</span>
<span class="k">vec3</span> <span class="n">l</span> <span class="o">=</span> <span class="n">calculateVertex</span><span class="p">(</span><span class="n">pos</span> <span class="o">+</span> <span class="k">vec4</span><span class="p">(</span> <span class="o">-</span><span class="n">s</span><span class="p">,</span> <span class="mo">0</span><span class="p">,</span> <span class="mo">0</span><span class="p">,</span> <span class="mo">0</span><span class="p">))</span> <span class="o">-</span> <span class="n">pos</span><span class="p">;</span>
<span class="k">vec3</span> <span class="n">t</span> <span class="o">=</span> <span class="n">calculateVertex</span><span class="p">(</span><span class="n">pos</span> <span class="o">+</span> <span class="k">vec4</span><span class="p">(</span> <span class="mo">0</span><span class="p">,</span> <span class="mo">0</span><span class="p">,</span> <span class="o">-</span><span class="n">s</span><span class="p">,</span> <span class="mo">0</span><span class="p">))</span> <span class="o">-</span> <span class="n">pos</span><span class="p">;</span>
<span class="k">vec3</span> <span class="n">b</span> <span class="o">=</span> <span class="n">calculateVertex</span><span class="p">(</span><span class="n">pos</span> <span class="o">+</span> <span class="k">vec4</span><span class="p">(</span> <span class="mo">0</span><span class="p">,</span> <span class="mo">0</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="mo">0</span><span class="p">))</span> <span class="o">-</span> <span class="n">pos</span><span class="p">;</span>
<span class="k">vec3</span> <span class="n">r</span> <span class="o">=</span> <span class="n">calculateVertex</span><span class="p">(</span><span class="n">pos</span> <span class="o">+</span> <span class="k">vec4</span><span class="p">(</span> <span class="n">s</span><span class="p">,</span> <span class="mo">0</span><span class="p">,</span> <span class="mo">0</span><span class="p">,</span> <span class="mo">0</span><span class="p">))</span> <span class="o">-</span> <span class="n">pos</span><span class="p">;</span>
<span class="k">vec3</span> <span class="n">n1</span> <span class="o">=</span> <span class="n">cross</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">t</span><span class="p">);</span>
<span class="k">vec3</span> <span class="n">n2</span> <span class="o">=</span> <span class="n">cross</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
<span class="k">vec3</span> <span class="n">n3</span> <span class="o">=</span> <span class="n">cross</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">l</span><span class="p">);</span>
<span class="k">vec3</span> <span class="n">n4</span> <span class="o">=</span> <span class="n">cross</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
<span class="k">return</span> <span class="n">normalize</span><span class="p">((</span><span class="n">normalize</span><span class="p">(</span><span class="n">n1</span><span class="p">)</span><span class="o">+</span><span class="n">normalize</span><span class="p">(</span><span class="n">n2</span><span class="p">)</span><span class="o">+</span><span class="n">normalize</span><span class="p">(</span><span class="n">n3</span><span class="p">)</span><span class="o">+</span><span class="n">normalize</span><span class="p">(</span><span class="n">n4</span><span class="p">))</span><span class="o">/</span><span class="mf">4.0</span><span class="n">f</span><span class="p">);</span>
<span class="p">}</span>
</pre></div></summary><category term="OpenGL"></category><category term="C++"></category></entry></feed>