tag:blogger.com,1999:blog-43715605708087009572024-02-02T05:10:05.707-08:00time sequencekurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.comBlogger28125tag:blogger.com,1999:blog-4371560570808700957.post-16066834628310658422017-06-29T18:20:00.000-07:002017-06-30T09:55:35.424-07:00Unity experimentsI started experimenting more in Unity. First, I worked on converting some point cloud stuff I was doing in TouchDesigner to Unity's compute shaders. The screen capture didn't come out too well, but it runs at about 100fps.
<br>
<br>
<iframe
src="https://player.twitch.tv/?video=v155447268&autoplay=false"
width="640"
height="360"
frameborder="0"
scrolling="no"
allowfullscreen="true">
</iframe>
<br>
<br>
I also started building a whip weapon in the style of Dr. Strange-meets-vaporwave. It really needs to be in VR for the full effect.
<br>
<br>
<iframe
src="https://player.twitch.tv/?video=v155349367&autoplay=false"
width="640"
height="360"
frameborder="0"
scrolling="no"
allowfullscreen="true">
</iframe>
<br>
<iframe
src="https://player.twitch.tv/?video=v154841154&autoplay=false"
width="640"
height="360"
frameborder="0"
scrolling="no"
allowfullscreen="true">
</iframe>kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com1tag:blogger.com,1999:blog-4371560570808700957.post-34523886855303508912017-04-12T22:29:00.000-07:002017-04-12T22:52:49.059-07:00Melange devSome quick videos showing my Masters project, Melange. The strings are used as waveforms to sonify the fluid field.
<br />
<br />
Strings visible:
<br/>
<video autoplay="" controls="" id="video-player" loop="" max-width:480px="">
<source src="https://photectics.com/data/blog/mp4/wip.120417_0.mp4"></source>
</video>
<br />
<br />
<video autoplay="" controls="" id="video-player" loop="" max-width:480px="">
<source src="https://photectics.com/data/blog/mp4/wip.120417_1.mp4"></source>
</video>
<br />
<br />
Turning up string velocity feedback:
<br/>
<video autoplay="" controls="" id="video-player" loop="" max-width:480px="">
<source src="https://photectics.com/data/blog/mp4/wip.120417_2.mp4"></source>
</video>
<br />
<br />kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-9787452840402545202017-04-10T23:33:00.000-07:002017-04-13T18:45:42.156-07:00150 Media Stream<video align="right" autoplay="" controls="" id="video-player" loop="" max-width:480px="">
<source src="https://photectics.com/data/blog/mp4/riverside_030417_1.mp4"></source>
</video>
<br />
<br />
Last month I flew to Chicago to get my piece Cirrus running on <a href="http://150mediastream.com/" target="_blank">150 Media Stream</a>. The LED wall is 150' x 22' and runs four 4k streams across five computers. Cirrus is a live real time fluid dynamics + reaction-diffusion simulation.<br />
<br />
Videos are sped up 5x.<br />
<br />
<video align="right" autoplay="" controls="" id="video-player" loop="" max-width:480px="">
<source src="https://photectics.com/data/blog/mp4/riverside_030417_2.mp4"></source>
</video>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVfPjFNKDJWsFe-MVUvzwkxBaDb8XU8eQ-lnEElM6_L8rojkLt4OGbpvn5wuZkzbxxppdeZduE1hatmVyo9P46jo8QB9H-8IJ38IGXuVPdXhtTPWlJKKtkVMiJ4UvpgmV6p1mHCMBcon8/s1600/IMG_0424.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVfPjFNKDJWsFe-MVUvzwkxBaDb8XU8eQ-lnEElM6_L8rojkLt4OGbpvn5wuZkzbxxppdeZduE1hatmVyo9P46jo8QB9H-8IJ38IGXuVPdXhtTPWlJKKtkVMiJ4UvpgmV6p1mHCMBcon8/s640/IMG_0424.jpg" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj02JOZhd_4SVOoGMbg5CTYhVKFGHjiJwUSXbdfd_FSLVZUQ3uXoZb840olQAoSy2K4wBuU1afqdnZOPmftRJJ9BpGOZSECAhBn_VEt-C_UdTAT9cfc8MQi8Ewy19dY4iJGPYrAEfTjM1M/s1600/IMG_0462-2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj02JOZhd_4SVOoGMbg5CTYhVKFGHjiJwUSXbdfd_FSLVZUQ3uXoZb840olQAoSy2K4wBuU1afqdnZOPmftRJJ9BpGOZSECAhBn_VEt-C_UdTAT9cfc8MQi8Ewy19dY4iJGPYrAEfTjM1M/s640/IMG_0462-2.jpg" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirKT4uAufRPzT3zZBsUzYk3IWDvo7yPoRGwKP_yd4EPLOekefK4gu_0UBfq03EoCwudo4BqCuF_ytxWwfMHaguf1P2Rq9QR6VoZBYTAeoijtY-d9uxdMEcc3PqVDc8x0usoCESJXd-I0Q/s1600/IMG_0446.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirKT4uAufRPzT3zZBsUzYk3IWDvo7yPoRGwKP_yd4EPLOekefK4gu_0UBfq03EoCwudo4BqCuF_ytxWwfMHaguf1P2Rq9QR6VoZBYTAeoijtY-d9uxdMEcc3PqVDc8x0usoCESJXd-I0Q/s640/IMG_0446.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxBTATUqvmDy3N4OG7fmK1bdb04HViHF_rbMklMS3z6Cb1KXW6HB2rIITvLcyDVPTElyt-Fw7UmG9lX3I3kYMXx0lwVClIYaV_onLSnU4CXIOU2Zhj5wFQBdXI1TkiB24pHB4LPJk9VEY/s1600/20170305_103044_2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiabsdASWe2OVGdnqyuvcktv1WvvVeXRDREDxIwACysYHYOm_v-gqxYIQ7MsLbUseZTh11Yzbi7j9vlUMXPaGgLIt2YDnlM-nw3Xa6PcSZUam5ldAHQrq2UpiMcnmIfahKznvfO4Rm-cgw/s1600/IMG_0458.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiabsdASWe2OVGdnqyuvcktv1WvvVeXRDREDxIwACysYHYOm_v-gqxYIQ7MsLbUseZTh11Yzbi7j9vlUMXPaGgLIt2YDnlM-nw3Xa6PcSZUam5ldAHQrq2UpiMcnmIfahKznvfO4Rm-cgw/s640/IMG_0458.jpg" width="640" /></a></div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxBTATUqvmDy3N4OG7fmK1bdb04HViHF_rbMklMS3z6Cb1KXW6HB2rIITvLcyDVPTElyt-Fw7UmG9lX3I3kYMXx0lwVClIYaV_onLSnU4CXIOU2Zhj5wFQBdXI1TkiB24pHB4LPJk9VEY/s1600/20170305_103044_2.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxBTATUqvmDy3N4OG7fmK1bdb04HViHF_rbMklMS3z6Cb1KXW6HB2rIITvLcyDVPTElyt-Fw7UmG9lX3I3kYMXx0lwVClIYaV_onLSnU4CXIOU2Zhj5wFQBdXI1TkiB24pHB4LPJk9VEY/s640/20170305_103044_2.jpg" width="640" /></a><br />
<br />kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com1tag:blogger.com,1999:blog-4371560570808700957.post-14463177324255560922017-03-19T00:28:00.000-07:002017-03-19T01:45:46.500-07:00Spring-mass GLSL<video autoplay="" controls="" id="video-player" loop="" max-width:512px="">
<source src="https://photectics.com/data/blog/mp4/springmass2.mp4"></source>
</video>
<br><br>
This spring-mass system was adapted to the GPU in GLSL from <a href="http://paulbourke.net/miscellaneous/particle/">Paul Bourke's example</a>. I'm using it to sonify the fluid in a way that allows for more structure and flexibility than directly sampling the velocity field. I'll post more about this technique in the future.
<br><br>
The system uses a 1024 x 4 texture map with simple one-dimensional spring connections that bind each pixel to its horizontal neighbor, forming 4 lines. I extended Paul's example to include an anchor force which pulls the particles back to a rest position (in this case concentric rings), and an impulse force that applies velocity from an outside source.
<br><br>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.0em .0em;"><pre style="margin: 0; line-height: 125%">layout(location<span style="color: #333333">=</span><span style="color: #4400EE; font-weight: bold">0</span>) <span style="color: #008800; font-weight: bold">out</span> <span style="color: #008800; font-weight: bold">vec3</span> fragColorPosition;
layout(location<span style="color: #333333">=</span><span style="color: #0000DD; font-weight: bold">1</span>) <span style="color: #008800; font-weight: bold">out</span> <span style="color: #008800; font-weight: bold">vec3</span> fragColorVelocity;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> dt;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> springConstant;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> restLength;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> dampingConstant;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> viscousDrag;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> anchorForce;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> impulseForce;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> mass;
<span style="color: #008800; font-weight: bold">uniform</span> <span style="color: #008800; font-weight: bold">float</span> fluidLengthThreshold;
<span style="color: #008800; font-weight: bold">vec2</span> springs[<span style="color: #0000DD; font-weight: bold">2</span>] <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">vec2</span>[<span style="color: #0000DD; font-weight: bold">2</span>](<span style="color: #008800; font-weight: bold">vec2</span>(<span style="color: #333333">-</span><span style="color: #6600EE; font-weight: bold">1.</span>,<span style="color: #6600EE; font-weight: bold">0.</span>), <span style="color: #008800; font-weight: bold">vec2</span>(<span style="color: #6600EE; font-weight: bold">1.</span>,<span style="color: #6600EE; font-weight: bold">0.</span>));
<span style="color: #008800; font-weight: bold">const</span> <span style="color: #008800; font-weight: bold">int</span> POSITION_OLD <span style="color: #333333">=</span> <span style="color: #4400EE; font-weight: bold">0</span>;
<span style="color: #008800; font-weight: bold">const</span> <span style="color: #008800; font-weight: bold">int</span> VELOCITY_OLD <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">1</span>;
<span style="color: #008800; font-weight: bold">const</span> <span style="color: #008800; font-weight: bold">int</span> VELOCITY_NEW <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">2</span>;
<span style="color: #008800; font-weight: bold">const</span> <span style="color: #008800; font-weight: bold">int</span> ANCHOR <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">3</span>;
<span style="color: #008800; font-weight: bold">const</span> <span style="color: #008800; font-weight: bold">float</span> smallf <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">0.000001</span>;
<span style="color: #008800; font-weight: bold">void</span> main() {
<span style="color: #888888">// Calculate forces</span>
<span style="color: #008800; font-weight: bold">vec3</span> pos0 <span style="color: #333333">=</span> texture(sTD2DInputs[POSITION_OLD], vUV.st).xyz;
<span style="color: #008800; font-weight: bold">vec3</span> vel0 <span style="color: #333333">=</span> texture(sTD2DInputs[VELOCITY_OLD], vUV.st).xyz;
<span style="color: #008800; font-weight: bold">vec3</span> vel_new <span style="color: #333333">=</span> texture(sTD2DInputs[VELOCITY_NEW], pos0.xy).xyz;
<span style="color: #008800; font-weight: bold">vec3</span> anchor <span style="color: #333333">=</span> texture(sTD2DInputs[ANCHOR], vUV.st).xyz;
<span style="color: #008800; font-weight: bold">vec3</span> force <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">vec3</span>(<span style="color: #6600EE; font-weight: bold">0.</span>);
force <span style="color: #333333">-=</span> viscousDrag <span style="color: #333333">*</span> vel0;
force <span style="color: #333333">+=</span> vel_new <span style="color: #333333">*</span> dt <span style="color: #333333">*</span> dt <span style="color: #333333">*</span> impulseForce;
force <span style="color: #333333">+=</span> (anchor<span style="color: #333333">-</span>pos0) <span style="color: #333333">*</span> anchorForce;
<span style="color: #888888">// spring interaction</span>
<span style="color: #888888">// 1d horizontal connection</span>
<span style="color: #008800; font-weight: bold">float</span> cellSize <span style="color: #333333">=</span> uTD2DInfos[POSITION_OLD].res.x; <span style="color: #888888">// 1/width</span>
<span style="color: #008800; font-weight: bold">for</span> (<span style="color: #008800; font-weight: bold">int</span> i <span style="color: #333333">=</span> <span style="color: #4400EE; font-weight: bold">0</span>; i <span style="color: #333333"><</span> <span style="color: #0000DD; font-weight: bold">2</span>; i<span style="color: #333333">++</span>) {
<span style="color: #008800; font-weight: bold">vec2</span> offset <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">vec2</span>(cellSize, <span style="color: #6600EE; font-weight: bold">0.</span>);
offset <span style="color: #333333">*=</span> springs[i];
<span style="color: #008800; font-weight: bold">vec2</span> coord <span style="color: #333333">=</span> vUV.st <span style="color: #333333">+</span> offset;
<span style="color: #008800; font-weight: bold">if</span> (coord.x <span style="color: #333333"><</span> <span style="color: #6600EE; font-weight: bold">0.</span>) coord.x <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1.</span><span style="color: #333333">-</span>cellSize;
<span style="color: #008800; font-weight: bold">if</span> (coord.x <span style="color: #333333">></span> <span style="color: #6600EE; font-weight: bold">1.</span>) coord.x <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">0.</span><span style="color: #333333">+</span>cellSize;
<span style="color: #008800; font-weight: bold">vec3</span> pos1 <span style="color: #333333">=</span> texture(sTD2DInputs[POSITION_OLD], coord).xyz;
<span style="color: #008800; font-weight: bold">vec3</span> vel1 <span style="color: #333333">=</span> texture(sTD2DInputs[VELOCITY_OLD], coord).xyz;
<span style="color: #008800; font-weight: bold">vec3</span> dx <span style="color: #333333">=</span> pos0 <span style="color: #333333">-</span> pos1;
<span style="color: #008800; font-weight: bold">float</span> len <span style="color: #333333">=</span> length(dx) <span style="color: #333333">+</span> smallf;
<span style="color: #008800; font-weight: bold">vec3</span> f <span style="color: #333333">=</span> <span style="color: #008800; font-weight: bold">vec3</span>(springConstant <span style="color: #333333">*</span> (len <span style="color: #333333">-</span> restLength));
f <span style="color: #333333">+=</span> dampingConstant <span style="color: #333333">*</span> (vel0 <span style="color: #333333">-</span> vel1) <span style="color: #333333">*</span> dx<span style="color: #333333">/</span><span style="color: #008800; font-weight: bold">vec3</span>(len);
f <span style="color: #333333">*=</span> <span style="color: #333333">-</span>dx<span style="color: #333333">/</span><span style="color: #008800; font-weight: bold">vec3</span>(len);
force <span style="color: #333333">+=</span> f;
}
<span style="color: #888888">// Apply derivative</span>
<span style="color: #008800; font-weight: bold">vec3</span> dpdt <span style="color: #333333">=</span> vel0;
<span style="color: #008800; font-weight: bold">vec3</span> dvdt <span style="color: #333333">=</span> force<span style="color: #333333">/</span><span style="color: #008800; font-weight: bold">vec3</span>(mass);
pos0 <span style="color: #333333">+=</span> dpdt <span style="color: #333333">*</span> dt;
vel0 <span style="color: #333333">+=</span> dvdt <span style="color: #333333">*</span> dt;
fragColorPosition <span style="color: #333333">=</span> pos0;
fragColorVelocity <span style="color: #333333">=</span> vel0;
} <span style="color: #888888">//main</span>
</pre></div>
kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-32988185561719578482017-02-19T21:47:00.000-08:002017-02-20T10:21:35.180-08:00Riverside look dev<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjInD4c5qB3ATiMxyKs4ipFYbPojawc8-IwBoUYBmbVJqZH0BSRPOhoKGYbgUrUkw-4WYdeO_FLsH_oUBFSOwfVwL8xuwWpe4cWL5_VCZxWVSGY28mTLGq7Hzk8DLDSlEjLk2Fz5OiGdY4/s1600/021917.2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjInD4c5qB3ATiMxyKs4ipFYbPojawc8-IwBoUYBmbVJqZH0BSRPOhoKGYbgUrUkw-4WYdeO_FLsH_oUBFSOwfVwL8xuwWpe4cWL5_VCZxWVSGY28mTLGq7Hzk8DLDSlEjLk2Fz5OiGdY4/s400/021917.2.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieuICCxI7P0PG_ItYu25_6zj0V9RgqG8O6AK3JY4JkazvoWnb3dQJyVNhLCcfy84WPOocd5YBrdCIEZcNsHTzV5wviOyNauS0nVu6_IN75hdcc7aeVRvYlZoDaSozfmIObmFWu2bnRjCQ/s1600/021917.4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieuICCxI7P0PG_ItYu25_6zj0V9RgqG8O6AK3JY4JkazvoWnb3dQJyVNhLCcfy84WPOocd5YBrdCIEZcNsHTzV5wviOyNauS0nVu6_IN75hdcc7aeVRvYlZoDaSozfmIObmFWu2bnRjCQ/s400/021917.4.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0OlFylMao6QOTwGiMSe5DWJsCYSSa_gehqm3hgzYAnaAfmBFJ5E5Ule1ztcWzBajK2GiQD-KWkgYSSFXTc-lZqkzUxGnZw5FdtricXmdE64tMnmMTbKOgFIj4l0-BLK-zX3f2jdGi89s/s1600/021917.3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0OlFylMao6QOTwGiMSe5DWJsCYSSa_gehqm3hgzYAnaAfmBFJ5E5Ule1ztcWzBajK2GiQD-KWkgYSSFXTc-lZqkzUxGnZw5FdtricXmdE64tMnmMTbKOgFIj4l0-BLK-zX3f2jdGi89s/s400/021917.3.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-59644685369760028552017-02-12T17:32:00.001-08:002017-03-17T17:11:09.961-07:00Playing with reaction diffusion anisotropy and scale<video autoplay="" controls="" id="video-player" loop="" max-width:512px="">
<source src="https://photectics.com/data/blog/mp4/RD_direction1.mp4"></source>
</video>
kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-16003009356906078332017-02-12T15:46:00.001-08:002017-02-13T09:33:07.117-08:00150 Media StreamPieces are coming together for the media wall installation in Chicago. It has a website now:<br />
<br />
<a href="http://150mediastream.com/">150mediastream.com</a><br />
<br />
Here are some photos of a test shoot of my fluid work that I'm now calling Cirrus. They only had one half of the display working:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV0XQvJX-DEOb1fvy9dGu6RaWGLyKyqAARQ2iJYK9IEm9ysXnSr_wukVMvMg6-VhtyUQK41r3fdza4W8C0nyfCRK4rsoXg7EVrQtdR0ZeRKFlfeNUZAk7eiKff2WTkXGTAhJj_1kA4AAE/s1600/MAS_2465.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV0XQvJX-DEOb1fvy9dGu6RaWGLyKyqAARQ2iJYK9IEm9ysXnSr_wukVMvMg6-VhtyUQK41r3fdza4W8C0nyfCRK4rsoXg7EVrQtdR0ZeRKFlfeNUZAk7eiKff2WTkXGTAhJj_1kA4AAE/s400/MAS_2465.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmt7ycOsfOthPGFYY5KR-fdVd3Rp3KgR6A6Q3hBoQmFq3dOg7zIpz5q4zKALFqfzrMa6xTpWuu5kWnpiDoDpxMM7BRgOcnrLjKo814lrjLYueEsIK8IvJbYXEXbcongF7gsDhzpS6bOqo/s1600/MAS_2472.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmt7ycOsfOthPGFYY5KR-fdVd3Rp3KgR6A6Q3hBoQmFq3dOg7zIpz5q4zKALFqfzrMa6xTpWuu5kWnpiDoDpxMM7BRgOcnrLjKo814lrjLYueEsIK8IvJbYXEXbcongF7gsDhzpS6bOqo/s400/MAS_2472.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrpf2OZh61RBqGGO6W_P-FQ_MDmlkZev7_7YQ_YU_i-tMARLDB9bvx0jW-PzwOb47kdnys6ymO_1WEr_FE3b63wSD7h-bm2_9KhzSlRdqf-w4MjmPv6e88wB79Rsl_a9OT6fDKpdUS1ws/s1600/MAS_2522.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrpf2OZh61RBqGGO6W_P-FQ_MDmlkZev7_7YQ_YU_i-tMARLDB9bvx0jW-PzwOb47kdnys6ymO_1WEr_FE3b63wSD7h-bm2_9KhzSlRdqf-w4MjmPv6e88wB79Rsl_a9OT6fDKpdUS1ws/s400/MAS_2522.jpg" width="266" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzMGg5BvG6epyGg6TqXDLhYZDj69TMcTdJ6xItNg2FpPY7MUWfP0mHfEteCv4PghvKbld_XJJ-hOpjOkW-S8IFw1f39aese2O81TX2XqiGbrsHC1_Ia0TmQzLG8BhBYO8uhd0F24pUopo/s1600/MAS_2545.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzMGg5BvG6epyGg6TqXDLhYZDj69TMcTdJ6xItNg2FpPY7MUWfP0mHfEteCv4PghvKbld_XJJ-hOpjOkW-S8IFw1f39aese2O81TX2XqiGbrsHC1_Ia0TmQzLG8BhBYO8uhd0F24pUopo/s400/MAS_2545.jpg" width="266" /></a></div>
<span id="goog_66490691"></span><span id="goog_66490692"></span><br />kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-15068222019232868702017-01-06T00:14:00.000-08:002017-03-18T19:58:22.068-07:00Fluid.tox, move to GLSL<video autoplay="" controls="" id="video-player" loop="" max-width:512px>
<source src="https://photectics.com/data/blog/mp4/2017-01-05.fluidtox.1.mp4"></source>
</video>
<br/><br/>
While I was visiting Russia last year, I was alerted to a thread on the TouchDesigner forums about some people who had found touchFluid on Github and were struggling to get it to work. Part of that had to do with me omitting some files from the public repo due to the licensing language on those files (which I was later told is out of date and will be revised), but they were also getting stuck on setting up their CUDA environment correctly. I don't blame them, Touch is only compatible with an older version of CUDA and is difficult to install on newer systems. You have to jump through a bunch of hoops to get an old version of VS which still isn't quite old enough so you still have to force CUDA to talk to it so you can build a dll. I couldn't work on it remotely anyway since my laptop is a Mac.
<br/><br/>
On a whim one morning, I tried transcribing my code to GLSL in Touch. It went surprisingly fast and I got it working in a couple hours. It was also about four times faster.
<br/><br/>
I made a tough call to drop supporting CUDA and move forward with GLSL. The main thing I lost was the potential to implement Ted's wavelet turbulence on the GPU. This was something I wanted to do as soon as I got Stam's stuff working, but the math and engineering involved was making it slow sailing for this Bachelors of Fine Arts noggin. With an installation deadline looming, I wasn't making progress on the art side fast enough either. Shader development time is faster, they're more portable, easier to read (more "hackable"), and are more performant given my circumstances.
<br/><br/>
CUDA is incredibly powerful and has the potential to completely maximize NVIDIA GPU's. The problem essentially came down to my desire to continue learning its nuances.
<br/><br/>
Writing kernels in CUDA is pretty easy, but writing fast kernels is a lot trickier. A common technique to speed up bandwidth is to use their concept of shared memory, which is essentially just a cache that performs 100x faster than reading from the GPU's global memory. It makes sense, but the code is ugly as sin and further obfuscates the already confusing thread/block/grid indexing scheme one is forced to use when working with thousands of cores. My code could have benefited from shared memory because many kernels use a Von-Neumann grid to look up neighboring values, causing about 4x redundant global memory reads. The problem was exacerbated by the fact that my data was stored linearly, so I needed huge strides to look up neighbors above and below the current cell- the image width * 4 (the rgba channels). According to <a href="https://devblogs.nvidia.com/parallelforall/how-access-global-memory-efficiently-cuda-c-kernels/">this official blog post</a> about shared memory, bandwidth drops by 80% after a stride of just 4 and continues to decline after that. This is the graph that convinced me to at least try shaders:
<br><br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWUE6iigJUwvnOuLb-Zk7ODwSpfHwN2RrvJlhPn7Kz5iONGfucPXIIAwbntAYYDYc-qCUzi5rsck7NIl8htwhehr5SFRAuclQUFJRnjH6_n8JLl0zLC0rLgcFinwQPvvN9xQvjM58prrU/s1600/stride-1024x683.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWUE6iigJUwvnOuLb-Zk7ODwSpfHwN2RrvJlhPn7Kz5iONGfucPXIIAwbntAYYDYc-qCUzi5rsck7NIl8htwhehr5SFRAuclQUFJRnjH6_n8JLl0zLC0rLgcFinwQPvvN9xQvjM58prrU/s640/stride-1024x683.png" width="640" height="427" /></a>
<br><br>
The speed boost I suspect comes from not having to deal with strides at all, instead encoding all the data into textures, which are optimized for random lookup.
<br><br>
Simulating using shaders is hardly a new thing. That, along with a few other oddities steered me away from them early on. You have to always be mindful that you are dealing with textures as a data structure so setting the filtering and format appropriately is crucial. They're also notoriously cryptic to debug, although that's slowly changing. Those are minor gripes when taking into account their ubiquity and accessible parallelism for visual media in general. The paradigm continues to advance with new hardware supporting things like dynamic tessellation and multiple camera matrices, and the community of users has never been stronger.
<br><br>
A couple months ago I wrapped everything up into a single tox, TouchDesigner's format for sharing snippets and single components, and <a href="https://www.derivative.ca/Forum/viewtopic.php?f=20&t=9476">put it on the forums</a> to positive feedback. The CUDA repo <a href="https://github.com/kamindustries/touchFluidCUDA">lives on as a fork</a>, but I'll continue working with <a href="https://github.com/kamindustries/touchFluid">the shader version</a> from here on out.
<br><br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEvV7IrlweJECttDNqEcFGg0Fewj48J7s2-U0OqYZm_-5eewDM_lAZf43FrFnlWw_asytMdTxvsBBdMnHRBwIhh7zqicYn_2KI41vm5DZfGZF0xI9_nCxCWXHKpEPYugFDQPq7wrL5Egc/s1600/fluidtox1.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEvV7IrlweJECttDNqEcFGg0Fewj48J7s2-U0OqYZm_-5eewDM_lAZf43FrFnlWw_asytMdTxvsBBdMnHRBwIhh7zqicYn_2KI41vm5DZfGZF0xI9_nCxCWXHKpEPYugFDQPq7wrL5Egc/s640/fluidtox1.png" width="640" height="390" /></a>kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-55202675654340612902017-01-05T22:16:00.001-08:002017-01-05T22:17:23.030-08:00HiatusNo posts for six months. I probably shouldn't be blogging.
<br><br>
My time has been split between traveling and working freelance. I wish I could post more about the project as it involves a lot of cool realtime graphics, but the NDA is real. Later this year I'll write something about it.
<br><br>
This summer I attended the Bridges math art conference in Jyväskylä, Finland to show my tiling work. The work has seen a decent run last year having been in Bridges, the End of Year Show, and the <i>Computation and Expression</i> show at the Art Design & Architecture Museum at UCSB.
<br><br>
More to come this year.
<br><br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQe_WOmn-l89hr9MuZk7Pxq4QxZlicSXQas1ziCBtS9XZrJUChGfztawtf1Ptfc9s-o1wF38EVhwSEEZESC8JK0R0EcgP3zL3unUByY_jj4-6GLik56FKTR1DN-rrNM20FVqtSpmSPDqI/s1600/20160624_171046.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQe_WOmn-l89hr9MuZk7Pxq4QxZlicSXQas1ziCBtS9XZrJUChGfztawtf1Ptfc9s-o1wF38EVhwSEEZESC8JK0R0EcgP3zL3unUByY_jj4-6GLik56FKTR1DN-rrNM20FVqtSpmSPDqI/s600/20160624_171046.jpg" width="600" /></a>
<br>
Art Design & Architecture Museum
<br><br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3wT5rhMsgpQaL-aTzQB1HbRc0QMMfvgpseXEmWsKcB3VBUFrTxtMdA8OKir4VzP73prKo2cx4uXaB7HnVQ5mZGFjLyclFr3Z_2fbc2k3M92TCjmHnUIhV3M_RQT79F9mK-BqN-SjpWP8/s1600/20160810_111947.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3wT5rhMsgpQaL-aTzQB1HbRc0QMMfvgpseXEmWsKcB3VBUFrTxtMdA8OKir4VzP73prKo2cx4uXaB7HnVQ5mZGFjLyclFr3Z_2fbc2k3M92TCjmHnUIhV3M_RQT79F9mK-BqN-SjpWP8/s600/20160810_111947.jpg" width="600" /></a>
<br>
Bridges, Finlandkurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-80843235547403860852016-06-30T18:33:00.000-07:002017-03-18T19:58:47.172-07:00BCH Rotations<video autoplay="" controls="" id="video-player" loop="" max-width:480px>
<source src="https://photectics.com/data/blog/mp4/2016-06-30-bch.mp4"></source>
</video>
<br />
<br />
For about a year I've had a secret weapon I've been using in nearly all of my projects: a colorspace based in spherical coordinates called "BCH" which stands for Brightness, Chroma, Hue. It was described by Sergey Bezryadin and Pavel Bourov. There isn't much information available about it online, but <a href="http://www.slideserve.com/orien/color-coordinate-systems-for-accurate-color-image-editing-software">these slides</a> explain everything.
<br/>
<br/>
Everyday usage is similar to HSV, but BCH has many advantages. It is grounded in real-world light response according to the user's preferred standard white point reference (D65, D50, etc). The color is represented by a vector where the magnitude is the brightness, the inclination is the saturation, and the azimuth is the hue. The motivation behind its development was to have more realistic exposure and contrast adjustment control over low dynamic range images, such as standard JPEGs. I used this capability to great effect when performing <a href="http://www.kurtkaminski.com/lukidus">Lukidus</a> last year where it drove the realtime color correction of video micrography.
<br/>
<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHFoD1Ms4bYGf6H7EmuwvGEu6yp9x-LB6y9MuFvDrbYbjg8dBZ9J8qMPu6DRKaVNuZVdc0HA5zFKiNuN3Xe_eYV1VDgJxre3AHBawS7b2tMdhKBff5uy9FqiD_GvfDSG_Yo8MwjI7DI84/s1600/our-definitions-of-brightness-chroma-and-hue-n.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHFoD1Ms4bYGf6H7EmuwvGEu6yp9x-LB6y9MuFvDrbYbjg8dBZ9J8qMPu6DRKaVNuZVdc0HA5zFKiNuN3Xe_eYV1VDgJxre3AHBawS7b2tMdhKBff5uy9FqiD_GvfDSG_Yo8MwjI7DI84/s400/our-definitions-of-brightness-chroma-and-hue-n.jpg" /></a>
<br/>
<br/>
Since the color is a vector, hue is a rotation around 2 * pi. In the video above, the angle of the velocity is mapped to the hue and I modulate independent multipliers for the sine and cosine components of the rotation. These both start at 0, so we only see red, but as I open them up, more colors are introduced, eventually reaching a rainbow pattern (complete rotation), passing through interesting color palettes along the way. I'm really interested in exploring this colorspace further and have some ideas of different mappings that could benefit from it.
<br/>
<br/>
Here's a Shadertoy I made with a BCH implementation and comparison to HSV:
<br/>
<a href="https://www.shadertoy.com/view/lsVGz1">https://www.shadertoy.com/view/lsVGz1 </a>
kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-69069368420936953302016-06-30T17:19:00.001-07:002017-03-18T19:59:22.532-07:00EOYS<video autoplay="" controls="" id="video-player" loop="" max-width:420px="">
<source src="https://photectics.com/data/blog/mp4/2016-06-30-eoys1.mp4"></source>
</video>
<br />
It's been a while since my last post. I've been recovering from the end of year show and working on doing wavelet turbulence up-resing on the GPU. Above is a video of some different presets that I'm cycling through and were used during the show.
<br />
<br />
I presented the current iteration as "Time Differential" and made an instruction manual for the Minilab that was printed and displayed next to the controller to solidify the idea that it is a video synthesizer. This was a quick and dirty 3d model I made in Houdini and rendered using wren.
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOK3S6QOQyBpRLU79-46-rV-oTGmJCa_Z-km7sYDBOQJfA2I4tXDOciXYzIagQv7GJtMvx0W1PBHZ2uQdpncsN3r4i73kwDsjCEehoAzqBTCtUD2Q3KgMipPnK5qP_72D087h8zum6Yz0/s1600/manual_03_sm2_resized.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOK3S6QOQyBpRLU79-46-rV-oTGmJCa_Z-km7sYDBOQJfA2I4tXDOciXYzIagQv7GJtMvx0W1PBHZ2uQdpncsN3r4i73kwDsjCEehoAzqBTCtUD2Q3KgMipPnK5qP_72D087h8zum6Yz0/s530/manual_03_sm2_resized.jpg" /></a>
<br />
<br />
An Apple Magic Trackpad 2 was used with multitouch input to add density and velocity. It wasn't exactly elegant, but it worked fairly well: I ran <a href="https://github.com/dboehle/SendMultiTouches">this really neat hack</a> on my laptop which captures multitouch data and broadcasts them as OSC messages. A Processing sketch running along side it received the position and finger size information and sent them across an ad-hoc wifi network to my desktop, which Touch then assembled into a CHOP where 1 sample = 1 finger. That CHOP was then sent as an array to my shaders. It was surprisingly responsive and more or less reliable.
<br />
<br />
Overall it went pretty well with a good amount of interest and constructive feedback. The controller was available for the public to play with, and I've already made some changes to the knobs and layout as a result. A lot of people were interested in the sound-reactive capabilities of it which led to a lot of clapping and yelling. Plus, kids loved it, which is a good omen I guess.
<br/>
<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDpSzCjWJP8zWaC09POsrf9NUCHycH6egH6m28-1w-5Nm2BCInp8eSd1CAy-Du_EQifo0DIShyphenhyphenIchQAw4L4zcGnt_wjUq6RGNrhshJrLD_1XfOO5TuIXS5wtKarr_sgEJ6dJQ7WuMtXuA/s1600/IMG_0043.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDpSzCjWJP8zWaC09POsrf9NUCHycH6egH6m28-1w-5Nm2BCInp8eSd1CAy-Du_EQifo0DIShyphenhyphenIchQAw4L4zcGnt_wjUq6RGNrhshJrLD_1XfOO5TuIXS5wtKarr_sgEJ6dJQ7WuMtXuA/s530/IMG_0043.jpg" /></a>
<br/>
<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOrmwgpxjHj9XpnfkUDV4ciafW3Mym63_5QdN4h5YvnUuR6yPGTQO9yHMPfpIP_uhz4OIY6XSZdmtXxCerUYTh5i4DNnJ3j9NueOIv482lMe9bveAwzNx3XD6LGzAeWdhxpKGbnSMFOQk/s1600/IMG_0042.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOrmwgpxjHj9XpnfkUDV4ciafW3Mym63_5QdN4h5YvnUuR6yPGTQO9yHMPfpIP_uhz4OIY6XSZdmtXxCerUYTh5i4DNnJ3j9NueOIv482lMe9bveAwzNx3XD6LGzAeWdhxpKGbnSMFOQk/s530/IMG_0042.jpg" /></a>kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-7375804137592123432016-05-09T15:44:00.001-07:002017-03-18T19:59:45.075-07:00Tukey Window<video autoplay="" controls="" id="video-player" loop="" max-width:480px>
<source src="https://photectics.com/data/blog/mp4/2016-05-09-TukeyWindowmp4.mp4"></source>
</video>
<br />
<br />
This is a quick video demonstrating <a href="https://en.wikipedia.org/wiki/Window_function#Tukey_window">Tukey Windowing</a> modulating the particle size using age as the input signal. Alpha (from the window function, not rgba) is set to .3 and it's been zoomed in to see the effect easier. Windowing the particle size will help ease transitions from particle birth and death so there's less noticeable pops. Here's some glsl code:
<br/>
<br/>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:none;border-width:.1em .1em .1em .8em;padding:0em 0em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">float</span> tukeyWindow(<span style="color: #008800; font-weight: bold">float</span> sig, <span style="color: #008800; font-weight: bold">float</span> alpha) {
<span style="color: #008800; font-weight: bold">if</span> (alpha <span style="color: #333333">==</span> <span style="color: #6600EE; font-weight: bold">0.</span>) <span style="color: #888888">// rectangular window</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #6600EE; font-weight: bold">1.</span>;
<span style="color: #008800; font-weight: bold">else</span> <span style="color: #008800; font-weight: bold">if</span> (sig <span style="color: #333333"><</span> alpha <span style="color: #333333">/</span> <span style="color: #6600EE; font-weight: bold">2.</span>)
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #6600EE; font-weight: bold">0.5</span> <span style="color: #333333">*</span> (<span style="color: #6600EE; font-weight: bold">1.</span> <span style="color: #333333">+</span> cos(<span style="color: #6600EE; font-weight: bold">2.</span><span style="color: #333333">*</span><span style="color: #6600EE; font-weight: bold">3.1459265</span><span style="color: #333333">/</span>alpha <span style="color: #333333">*</span> (sig<span style="color: #333333">-</span>alpha<span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">2.</span>)));
<span style="color: #008800; font-weight: bold">else</span> <span style="color: #008800; font-weight: bold">if</span> (sig <span style="color: #333333">></span> <span style="color: #6600EE; font-weight: bold">1.</span><span style="color: #333333">-</span>alpha<span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">2.</span>)
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #6600EE; font-weight: bold">0.5</span> <span style="color: #333333">*</span> (<span style="color: #6600EE; font-weight: bold">1.</span> <span style="color: #333333">+</span> cos(<span style="color: #6600EE; font-weight: bold">2.</span><span style="color: #333333">*</span><span style="color: #6600EE; font-weight: bold">3.1459265</span><span style="color: #333333">/</span>alpha <span style="color: #333333">*</span> (sig<span style="color: #333333">-</span><span style="color: #6600EE; font-weight: bold">1.</span><span style="color: #333333">+</span>alpha<span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">2.</span>)));
<span style="color: #008800; font-weight: bold">else</span>
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #6600EE; font-weight: bold">1.</span>;
}
</pre></div>
kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-22242201607621903452016-05-09T15:34:00.000-07:002017-03-18T19:59:54.883-07:00Control<video autoplay="" controls="" id="video-player" loop="" max-width:540px>
<source src="https://photectics.com/data/blog/mp4/2016-05-09-Ctrl1.mp4"></source>
</video>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5XDqn_WJxvKbtfNJ1CnRBg-IsZC2yPUp9KMxUcnqQifUfkDtJo7KKt02fNohWapeKYMN6L7w0hM3ZN2Lqkms_vuZSkiolU6JvE1lLey5kGzKF8DN6Gu14IW_DYjI8_xfZZBYitIiu10M/s1600/minilab.jpg" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5XDqn_WJxvKbtfNJ1CnRBg-IsZC2yPUp9KMxUcnqQifUfkDtJo7KKt02fNohWapeKYMN6L7w0hM3ZN2Lqkms_vuZSkiolU6JvE1lLey5kGzKF8DN6Gu14IW_DYjI8_xfZZBYitIiu10M/s530/minilab.jpg" /></a>
<br />
<br/>
I've started integrating my Arturia Minilab to control various simulation parameters, inputs, and visualization options. Here is a quick video demonstrating the UI I've made that captures the midi signals for all of the knobs, pads, and sliders. Pads 1-4 select a different bank of knob settings, each with their own presets and color indicator. Values can be changed by both the controller and the on-screen UI. The keys work as well, but I'm focusing on these first as they will be the primary way of sculpting the behavior of the system. The keys will likely act as gates and triggers for adding new input (i.e. sound or image data).kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-46012871898014928382016-04-24T20:40:00.001-07:002017-03-18T20:00:14.919-07:00Particle trails<video autoplay="" controls="" id="video-player" loop="" max-width:420px>
<source src="https://photectics.com/data/blog/mp4/2016-04-24-Particles2mp4.mp4"></source>
</video>
<br />
<br />
Messing around with feedback to get flow lines from the fluid sim. The color represents velocity direction and value is the magnitude of the velocity. Particles can bounce around obstacles and don't spawn inside them. 1 million particles @60 fps.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-54179438594769597122016-04-21T02:07:00.001-07:002017-03-18T20:00:23.174-07:00GPU particles<video autoplay="" controls="" id="video-player" loop="" max-width:400px>
<source src="https://photectics.com/data/blog/mp4/2016-04-21-Particles_sm.mp4"></source>
</video>
<br />
<br />
Here's 250,000 particles being advected by the velocity field. This is being done using glsl shaders in TouchDesigner. The value of the particles is currently just the magnitude of the velocity, but I'll be adding a lot more color options later. I'm maintaining 60fps using a 512x512 fluid container.
<br/>
<br/>
I'm going to spend the next couple of weeks making big pushes in UI to prepare for a public demonstration at the end of year show. A lot to do still.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-82555019840759053482016-03-30T20:20:00.000-07:002017-03-18T20:00:32.369-07:00Audio visualization, obstacle velocity<video autoplay="" controls="" height="100%" id="video-player" loop="" width="100%">
<source src="https://photectics.com/data/blog/mp4/2016-03-30-AudioViz.mp4"></source>
</video>
<br />
<br />
Here's a quick update that includes a couple new features: passing velocity in with obstacle data and rendering 3d geometry to a 2d image to use as input (although in this video, actual obstacles and density fields aren't present). I've got a simple particle simulation running on the CPU in TouchDesigner whose initial velocity and direction is being controlled by an audio waveform. I followed along with <a href="http://www.derivative.ca/Events/2016/NorwayWorkshop/">Derivative's 2016 Norway Workshop</a> to get the system set up. Particle velocities are rendered as colors and piped into the CUDA sim. Adding these features went fairly smoothly.
<br/>
<br/>
Here it's very apparent that the simulation container doesn't have any interesting border conditions, which can be a good and bad thing. It's another feature to add. In the coming months, I'll be working on the UI, different composition techniques, experimenting with looks, and improving stability to prepare for MAT's End of Year Show. I've also become very interested in Ted's <a href="http://www.cs.cornell.edu/~tedkim/wturb/">Wavelet Turbulence</a> paper which would really send the visuals through the roof. No timeline on that yet, but it's going on the list.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com2tag:blogger.com,1999:blog-4371560570808700957.post-84261147447797654542016-03-16T16:06:00.001-07:002017-03-18T20:00:40.896-07:00Boundaries and color<video autoplay="" controls="" height="100%" id="video-player" loop="" width="100%">
<source src="https://photectics.com/data/blog/mp4/2016-03-16-Touch_color.mp4"></source>
</video>
<br />
<br />
This update includes a lot of changes to the simulation algorithm as well as some new features. I ended up restructuring the velocity solve to mirror the one found in <a href="http://http.developer.nvidia.com/GPUGems/gpugems_ch38.html" target="_blank">GPU Gems</a>, which is still based on Stam's solution, but is more clear about the pressure and temperature fields, and simplifies the gradient subtraction a bit, so the performance is better.
<br/>
<br/>
For the reaction coupling, I diffuse two density fields with a laplacian kernel and apply the Gray-Scott equation, then advect them. Since there is a slight amount of diffusion from bilinear interpolation in the advection step, I suspect the Gray-Scott feed and kill values might be a little off. Nonetheless it appears stable. I'm passing a texture from Touch into cuda to define obstacles. The color is coming from the velocity, with hue mapped to its polar angle.
<br/>
<br/>
There are a lot of fields and variables to play with now. I'll have to decide if I want to start working on robustness and composition techniques, or to move forward with adding a particle system and pushing the resolution as far as possible.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-61093044413935462772016-02-28T23:07:00.000-08:002016-02-28T23:07:10.122-08:00TilingI returned to some of my previous work on aperiodic tiles from two years ago. This time, I'm overlaying different iterations of the same prototile and rendering them as polygonal tubes with Mantra. Everything is done in Houdini with a little color correction in Photoshop. I'm trying to decide which ones to submit to <a href="http://bridgesmathart.org/" target="_blank">Bridges</a> this year.<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrlCNT_VpNLvBMICpsEs1hufmMmwcg45RJcrQtQUiiTfLixnJIrFyvOd9M3O8g-kJS38LJ9DYjIinBFyAoZs6NJi1x7nrVHBiX3rDpPih_nreSob8P1Q_bMlHZFA4Ud5yRmrafhtjCJRo/s1600/w12_dia_red.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrlCNT_VpNLvBMICpsEs1hufmMmwcg45RJcrQtQUiiTfLixnJIrFyvOd9M3O8g-kJS38LJ9DYjIinBFyAoZs6NJi1x7nrVHBiX3rDpPih_nreSob8P1Q_bMlHZFA4Ud5yRmrafhtjCJRo/s320/w12_dia_red.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu2E-B0_xKD21sxT8l1AfOFfVV-BohswfbhAsl3cl8AzCHYhrd-mJWMPpkLSBpXPuxzIoaZY3z36GLRNIiPLw0KLNMRlUGtnlTV_ds1u-9aDvIj5_m5GpmrS-RNBpQ3ht8Bm3xZqymZ7Q/s1600/w12_sq_green.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu2E-B0_xKD21sxT8l1AfOFfVV-BohswfbhAsl3cl8AzCHYhrd-mJWMPpkLSBpXPuxzIoaZY3z36GLRNIiPLw0KLNMRlUGtnlTV_ds1u-9aDvIj5_m5GpmrS-RNBpQ3ht8Bm3xZqymZ7Q/s320/w12_sq_green.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfp8ksKqYzT6Wp41r2iSCuT47DRyvffWUl4GSirl0DuLusOGncR47WAHksTYhHdN1mfn7lMtHC3fy7nUI3exkcnhSR_uoVkbgK0ftbP9dowrut3sAUoVXcBad_ywdypaJL7kIAXG2pRh8/s1600/w12v_tri_blue.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfp8ksKqYzT6Wp41r2iSCuT47DRyvffWUl4GSirl0DuLusOGncR47WAHksTYhHdN1mfn7lMtHC3fy7nUI3exkcnhSR_uoVkbgK0ftbP9dowrut3sAUoVXcBad_ywdypaJL7kIAXG2pRh8/s320/w12v_tri_blue.jpg" width="320" /></a></div>
<div>
<br /></div>
kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com3tag:blogger.com,1999:blog-4371560570808700957.post-55833160539861474132016-02-25T13:06:00.002-08:002017-03-18T20:00:56.055-07:00TouchDesigner + CUDA<video id="video-player" autoplay="" controls="" height=100% loop="" width=100%>
<source src="https://photectics.com/data/blog/mp4/2016-02-25-Touch_RD.mp4"></source>
</video>
<br />
<br />
I moved over to Windows and got reaction diffusion working in TouchDesigner using a CUDA .dll I adapted from my original experiments in Linux. This is a big checkpoint and hopefully represents the beginning of what will be the final environment and toolkit I will commit to for my thesis. Thinking of TouchDesigner as a modular OpenGL app authoring tool is extremely liberating.
<br/>
<br/>
I'm going to shoot for adding user-defined boundary conditions next as that seems to be coming up a lot lately. Color shouldn't be too far behind.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-2851923531475561912016-02-02T22:52:00.000-08:002016-02-02T22:54:22.369-08:00TEM/AP<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgetFJq4eR1XsJyrXb_TplAUP8qKJoQiBqn27AcSSSSfEcNItRHJeR7cZBjMDG1evo8YT-pVkSpFXwLmVQVCVWjbA2GYHyxGghJAlI54EUuBqfWKMMHMYxZSQX4iaQA-pFQyZCwESfRv2c/s1600/IMG_9853.jpg" imageanchor="0"><img border="0" height="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgetFJq4eR1XsJyrXb_TplAUP8qKJoQiBqn27AcSSSSfEcNItRHJeR7cZBjMDG1evo8YT-pVkSpFXwLmVQVCVWjbA2GYHyxGghJAlI54EUuBqfWKMMHMYxZSQX4iaQA-pFQyZCwESfRv2c/s1600/IMG_9853.jpg" width="100%" /></a></div>
<br />
Atom probe and transmission electron tomography in the sphere.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-17920495757405049512016-01-30T00:35:00.002-08:002017-03-18T20:01:19.143-07:00particle advection<video id="video-player" autoplay="" controls="" height=100% loop="" width=100%>
<source src="https://photectics.com/data/blog/mp4/cuda_AVC_particles_MP4.mp4"></source>
</video>
<br />
<br />
I got particle advection working with advection-reaction-diffusion and vorticity confinement. The particle system is based on Memo’s <a href="https://github.com/memo/ofxMSAFluid" target="_blank">MSAFluid</a> example. 100,000 particles being pushed around an advection-reaction-diffusion velocity field.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-20905304054082131132016-01-30T00:30:00.000-08:002016-01-30T10:22:43.572-08:00Moved to BloggerAfter putting up with it for 2 weeks, I couldn't stand the extra compression tumblr adds to everything. It handles this type of content particularly poorly. They also don't support the <video> tag. I'm now hosting html5 videos on dropbox and embedding them here. I have a bash script to do the encoding for me.<br />
<br />
Here are the guts which take a png sequence and convert it to a YUV file which is used to make a webm which is used to make an mp4 for the Safari people.<br />
<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">png2yuv -I p -f 60 -b 1 -n $numFrames -j $input > $outputYuv</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">vpxenc --good --cpu-used=0 --auto-alt-ref=1 --lag-in-frames=16 --end-usage=vbr --passes=2 --threads=2 --target-bitrate=3000 -o $outputWebm $outputYuv</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">ffmpeg -i $outputWebm -r $_frameRate -codec:v libx264 -preset slow -b:v 2500k -threads 0 -codec:a libfdk_aac -b:a 128k $outputMp4</span>kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-89856939071137788532016-01-30T00:16:00.000-08:002016-01-30T10:54:52.812-08:00vorticity confinement<video autoplay="" controls="" height=100% loop="" width=100%>
<source src="https://dl.dropboxusercontent.com/s/16pyv3jc1zvjaa3/cuda_AVC_WEBM.webm"></source>
<source src="https://dl.dropboxusercontent.com/s/er24extkrxlfia7/cuda_AVC_MP4.mp4"></source>
</video>
<br />
<br />
Here’s the previous advection-reaction-diffusion simulation with additional vorticity confinement and buoyancy terms. This gives me more control over the vortices and overall flow of the field. In the video I alternate the strength and direction of the buoyancy with mouse input. Coupled with reaction-diffusion, the grid fills up quickly, so I’m already thinking of intuitive ways to manage this without resetting everything.
The implementation described <a href="http://www.multires.caltech.edu/teaching/demos/java/stablefluids.htm" target="_blank">here</a> was a big help.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-38949250454969234272016-01-29T23:38:00.001-08:002017-03-18T20:01:32.801-07:00<video autoplay controls loop height=100% width=100%>
<source src="https://photectics.com/data/blog/mp4/cuda_simpleAdv_vel_MP4.mp4"></source>
</video>
<br />
<br />
I was working on visualizing the velocity field for simple advection when this Euclidean waterpark emerged.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0tag:blogger.com,1999:blog-4371560570808700957.post-48689542659483150542016-01-29T23:17:00.000-08:002017-03-18T20:01:40.907-07:00advection-reaction-diffusion<video autoplay="" controls="" height=100% loop="" width=100%>
<source src="https://photectics.com/data/blog/mp4/cuda_ARD_MP4.mp4"></source>
</video>
<br />
<br />
Naive coupling of reaction-diffusion with Stam’s advection. The Gray-Scott reaction and simple 4 axis laplacian used for diffusion are not unconditionally stable as described by <a href="http://gamma.cs.unc.edu/SARD/stable_ard_kim_lin.pdf" target="_blank">Kim</a>, which I would like to make my next technical hurdle. I’m mostly excited about Ted’s anisotropic reaction-diffusion which has a lot of potential to be used expressively.
<br />
<br />
I might take a step back at this point and start thinking more about the bigger picture in terms of application, artistic control, sound synthesis, and pushing the system visually.kurtoonhttp://www.blogger.com/profile/16674192622228682586noreply@blogger.com0