<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cedric Pinson - OpenGL / OpenSceneGraph / WebGL &#187; blog</title>
	<atom:link href="http://plopbyte.com/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://plopbyte.com</link>
	<description>Providing OpenGL services around OpenSceneGraph, WebGL and more</description>
	<lastBuildDate>Mon, 02 Jan 2012 02:46:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>DemoJS</title>
		<link>http://plopbyte.com/2011/12/demojs/</link>
		<comments>http://plopbyte.com/2011/12/demojs/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 23:00:10 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[osgjs]]></category>
		<category><![CDATA[webgl]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=1055</guid>
		<description><![CDATA[We had a meeting a few months ago before the demojs event in Paris to organize it. I worked on the intro to announce the event 10 days before the deadline. 4 of us made this intro: Guillaume Lecollinet who helped on design and css stuff, Ulrick for the music and Mestaty for 3d models, [...]]]></description>
			<content:encoded><![CDATA[<p>We had a meeting a few months ago before the demojs event in Paris to organize it. I worked on the <a href="http://cedricpinson.com/demojs-fff/">intro</a> to announce the event 10 days before the deadline. 4 of us made this intro: Guillaume Lecollinet who helped on design and css stuff, Ulrick for the music and Mestaty for 3d models, both are from <a href="http://frequency.fr/">FRequency</a> demo group and I worked on the code. If you are interested in particles you really need to read this <a href="http://directtovideo.wordpress.com/">blog</a>. This guy does awesome things.</p>
<h2>Particles again</h2>
<p>At the beginning I did not really know what I wanted to create. I wanted to work on particles but with more complexity than my <a href="http://plopbyte.net/2010/08/webgl-particles/">previous toy</a>. Finally I did an intro only with particles. The consequence is that the entire intro used the same shader, I will describe the following stuff I used into the intro.
<ul>
<li>Verlet physic integration</li>
<li>Spawning particles</li>
<li>Distance map</li>
<li>Velocity field</li>
<li>Morphing of 3d models</li>
</ul>
<h2>Verlet Integration</h2>
<p><a href="http://en.wikipedia.org/wiki/Verlet_integration">Verlet integration</a> in a nutshell is a numerical method used to integrate Newton&#8217;s equations of motion. There is a good <a href="http://codeflow.org/entries/2010/nov/29/verlet-collision-with-impulse-preservation/">blog</a> and examples how to use it.  In webgl we can&#8217;t use render to texture on floating point texture. In fact we can use an extension but I wanted to make it works on most browser with webgl so I did not use the extension. The consequence is that particles coordinates has to be encoded in specific format on rgba pixels.</p>
<ul class="gallery">
<li>
<a href="http://plopbyte.com/2011/12/demojs/samsung-5/" rel="attachment wp-att-1226"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/11/buffers-300x180.jpg" alt="" title="SAMSUNG" width="300" height="180" class="alignnone size-medium wp-image-1226" /></a>
</li>
<li><a href="http://plopbyte.com/2011/12/demojs/samsung-4/" rel="attachment wp-att-1223"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/11/pixels-300x180.jpg" alt="" title="SAMSUNG" width="300" height="180" class="alignnone size-medium wp-image-1223" /></a>
</li>
</ul>
<p>In my previous <a href="http://plopbyte.net/2010/08/webgl-particles/">particles toy</a> I used 16 bits fixed point to encode coordinates, but on this one I wanted to improve it and try 24 bits to have more precision, I encoded more informations like signed distance, life of particle, or material id in pixels. (picture above left). In webgl there is no multi render target and I had to draw the scene 3 times to compute particle&#8217;s positions, for x, y and z. To select each dimension I wanted I used a uniform.<br />
Finally to compute a &#8216;next&#8217; frame (3 textures) it required &#8216;current&#8217; frame (3 textures) &#8216;previous&#8217; frame (3 textures), in final I needed 9 textures to just have the verlet physic running without controlling their motions. For this I used others textures I will describe after. Texture size . To not hurt too much my gpu, I fixed the texture&#8217;s size to 512&#215;512, meaning 262144 particles. We could </p>
<h2>Spawning particles</h2>
<p>To determine the life span and position of new particles, I used uv range of particles to distributes them in space. It&#8217;s not really elegant or pratical for bigger projects/shapes. For example, the equalizer scene was done allowing particles on a plane where equalizers were. Basically there is a range 0.25 in &#8216;u&#8217; per equalizer bar and I limited the v to 0.5. So we have 0.25*(4 equalizer) and v limited in 0.5 it means 0.25*4u + 0.5v = 131072 particles allocated for equalizers, and the 131072 others are used for the 3d models. Next time I would like to try &#8216;mesh emitter&#8217; or something more useful than doing it manually.</p>
<h2>Distance Map</h2>
<p>What is a distance map ? you can read this <a href="http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf">paper from valve</a> that explains how it works.<br />
Distance map is a really useful tool to control particles. In the intro I used texture that encodes distance map and gradient (the vector that tells you which direction to take to go to the nearest point on the shape). For this I created a tool (<a href="https://github.com/cedricpinson/DistanceMapGenerator">DistanceMapGenerator</a>) and then I computed the gradient from the distance map. Finally I constructed a texture that contains both pieces of information. During the computation of the position I take the signed distance of this position to fit the shape I want, eg:</p>
<p><code><br />
 vec3 getDirection(vec3 pos) {<br />
   vec4 d = texture2D( DistanceMap, vec2(pos.x, pos.z));<br />
   vec2 grad = d.rg;<br />
   vec3 dir = vec3(0.5-grad[0], 0.125*(0.5-pos.y), 0.5-grad[1]);<br />
   dir = normalize(dir);<br />
   return dir;<br />
}<br />
float getDistance(vec3 pos) {<br />
   float d = texture2D( DistanceMap, vec2(pos.x, pos.z)).b;<br />
   return d;<br />
}<br />
// here I know at wich distance my particle is from the nearest border<br />
distance = getDistance(currentPosition)*weightDistanceMap;<br />
// and here I know in wich direction the nearest border is<br />
direction = getDirection(currentPosition)*weightDistanceMap*0.4;<br />
// it's easy after to use this direction to create a force and make the<br />
// particle go in the direction of the shape<br />
</code> </p>
<ul class="gallery">
<li>
<a href="http://portfolio.plopbyte.net/wp-uploads/2011/11/Title.jpg"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/11/Title-300x167.jpg" alt="" title="Title" width="300" height="167" class="alignnone size-medium wp-image-1093" /></a> </li>
<li>
<a href="http://portfolio.plopbyte.net/wp-uploads/2011/11/Title_grad.jpg"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/11/Title_grad-300x167.jpg" alt="" title="Title_grad" width="300" height="167" class="alignnone size-medium wp-image-1094" /></a></li>
</ul>
<p>This technique was used for most of the motions/shapes I wanted the particles to fit in. I tried to manipulate particles manually but it was too complex and I was not able to do what I wanted to. Distance maps is really easier. </p>
<h2>Velocity field</h2>
<p><a href="http://portfolio.plopbyte.net/wp-uploads/2011/11/udav1.jpg"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/11/udav1-300x167.jpg" alt="" title="udav" width="300" height="167" class="alignnone size-medium wp-image-1070" /></a></p>
<p>To add some perturbation motion like &#8216;procedural wind&#8217; I used a MathGL/udav tool. The idea was to find a nice formula I could use in the shader that produces nice motion. For that I used udav to display the vector field from the formula. Once I was happy with the vector field, I added some variation in real time depending on time. This tool was not really convenient and maybe next time I will write something to help me with this. Once the formula was selected I used a lookup to get my vector depending on particle&#8217;s position. It looks like this below:</p>
<p><code><br />
            "vec3 getVelocityField(vec3 pos) {",<br />
            "   float t = mod(time,15.0); //mod(time, 5.0);",<br />
            "   float vx = 0.0+cos(0.5+2.0*(pos.x*pos.x*t));",<br />
            "   float vy = cos(4.0*(pos.y*t+ seed*0.5)) + seed * sin(4.0*pos.x*t*t);",<br />
            "   float vz = cos(pos.z*2.0*t);",<br />
            "   vec3 vel = vec3( vx, vy, vz);",<br />
            "   return normalize(vel);",<br />
            "}",<br />
</code></p>
<h2>3D models</h2>
<p>At the end of the intro I used morphing between different 3d models ( the firefox logo, and the abstract model formed of cube ). To use those models with particles I first had to convert them into a suitable format for the particle system, meaning into textures that would encode the model&#8217;s position as rgb pixels. The particle system used 262k particles but models used up to 131k vertexes ( remember 131k particles were allocated for the equalizers ). So we have 131k particles to display morph and animate our 3d models. The morphing between the different shapes works with a lerp between position ( finalVertex = model0*t + model1*(1.0-t) ). To add some perturbation to the motion we still add the &#8216;fake wind&#8217; during the animation. If you want to check the tool to build vertex to texture format used by the particle system look <a href="https://github.com/cedricpinson/osg/tree/master/src/osgPlugins/vert2text32">here</a>. It&#8217;s a plugin for <a href="http://www.openscenegraph.org/">openscenegraph</a>.</p>
<h2>Music</h2>
<p>The music was done by Ulrick from FRequency and they used their own tool to export pattern events in a c++ header. I made a little script to convert the result into json, and then I injected events data into timeline.js. <a href="https://github.com/cedricpinson/timeline.js">Timeline.js</a> was great but I needed to patch it to support callback and use an external time, the one that came from the music.</p>
<h2>Improvements</h2>
<p>There is a lot of stuff I would have wanted to do better but 10 days was too short. So I discarded lighting on particles, shadow, spawn mesh emitter, post process effect, smoke simulation with sph. Maybe the next time I will play with particles I will be able to add some of those elements.</p>
<h2>links</h2>
<ul>
<li><a href="http://plopbyte.com/demojs-fff/">Intro fff</a> or the <a href="http://www.youtube.com/watch?v=DHup1JfEsXo">video</a> </li>
<li><a href="http://directtovideo.wordpress.com/">directtovideo</a></li>
<li><a href="http://codeflow.org/">codeflow</a></li>
<li><a href="http://frequency.fr/">FRequency</a></li>
<li><a href="http://osgjs.org">osgjs</a></li>
<li><a href="https://github.com/cedricpinson/DistanceMapGenerator">DistanceMapGenerator</a></li>
<li><a href="https://github.com/cedricpinson/osg/tree/master/src/osgPlugins/vert2text32">model to texture</a></li>
<li><a href="http://demojs.org/">demojs.org</a></li>
<li><a href="https://github.com/cedricpinson/timeline.js">Timeline.js</a></li>
</ul>
<p>Thanks for people who helps to make this webgl intro it was really fun. The most stuff I liked was the good ambience of the team, that was really cool. Thank you guys :)</p>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/12/demojs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GlobeTweeter &#8211; Experience</title>
		<link>http://plopbyte.com/2011/05/globetweeter-experience/</link>
		<comments>http://plopbyte.com/2011/05/globetweeter-experience/#comments</comments>
		<pubDate>Tue, 03 May 2011 09:47:13 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[osgjs]]></category>
		<category><![CDATA[webgl]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=316</guid>
		<description><![CDATA[Over the last few months, I have been working on a webgl demo for firefox. The objective was to create a demo to showcase webgl technology. I am currently working on a 3D framework called osgjs so the application uses this javascript library. osgjs is a javascript implementation of OpenSceneGraph and helps to manage 3d [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last few months, I have been working on a webgl demo for firefox.  The objective was to create a demo to showcase webgl technology. I am currently working on a 3D framework called <a href="http://osgjs.org">osgjs</a> so the application uses this javascript library. osgjs is a javascript implementation of <a href="http://openscenegraph.org">OpenSceneGraph</a> and helps to manage 3d scenes and webgl states. You can get more information on the <a href="http://osgjs.org">website</a>.</p>
<p>We did different experiments before we ended up with globetweeter, I kept some of them for history :)</p>
<h3>Jurassic Park</h3>
<p>I started off by creating a file system similar to the 3D file system used in Jurassic Park. I had to figure out the best type of camera that would be suitable to use with the system.</p>
<ul class="gallery">
<li>
<img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/camera-1-300x168.jpg" alt="" title="Camera" width="300" height="168" class="alignnone size-medium wp-image-666" />
</li>
<li>
<img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/camera-0-300x168.jpg" alt="" title="Camera" width="300" height="168" class="alignnone size-medium wp-image-667" />
</li>
</ul>
<p>The idea is simple. Let&#8217;s say a user selects the item <strong>B</strong> . When selected, the camera moves from its current viewpoint to the chosen item. The position of the camera (<strong>C</strong>) is in orbit relative to the selected item. Basically I used a lookat matrix from the camera position (<strong>C</strong>) to the target item. To create the camera motion when moving from one item to another, I interpolated the target position (<strong>from A to B</strong>) and generated a rotation around this interpolated point (<strong>X</strong>) during the animation. I added some constraints like the distance from the target point and some limits in the rotation to keep the camera position in range (like if we would see the item from a 3rd person).  Check out this <a href="http://plopbyte.com/ff4demo/demo3/demo.html">experiment</a> (use &#8216;del&#8217; key to go to previous level).</p>
<h3>Twitter</h3>
<p>This idea ended up being too geeky, so we tried out something more popular and surrounded by more hype.  And therein was born the idea of displaying tweets with 3D.<br />
A first try was to iterate on something like tweet deck but we wanted something that would be more responsive and with eye candy features&#8230; the first ugly <a href="http://plopbyte.com/ff4demo/demo2/demo.html">experiment</a> was to render tweets in a canvas and to use them as texture in 3D. We ended up dropping this idea and instead decided to show tweets geo-localized on the earth.</p>
<p>The last idea we had is the current incarnation of the globe tweeter. To make the globe I used 3 data files from <a href="http://www.naturalearthdata.com/">natural earth data</a></p>
<ul>
<li><a href="http://showwebgl.com/show/?q=g6lu4j6t5m8scg4s8og0wkwwss0gwk0&#038;LIGHT=0&#038;CULL_FACE=0">110m admin 0 countries.shp</a> contains the polygons of countries</li>
<li><a href="http://showwebgl.com/show/?q=6f68hn2hr8so44csowwc4skkcgg4s8k&#038;LIGHT=0">110m coastline.shp</a> contains only the coastline (meaning lines around oceans)</li>
<li><a href="http://showwebgl.com/show/?q=fxaeg6xeuvc4so0sgcgkswsgk0sw8g4&#038;LIGHT=0">110m admin 0 boundary lines land.shp</a> contains the lines inside land boundaries</li>
</ul>
<p>As you can see, those data are flat and need to be projected on a sphere. Before projecting those data, however,  I had to tesselate the triangles in order to have enough vertex to project a clean shape on the sphere. For this I have created a tool called &#8216;grid&#8217;. It tessellates the input shape with a grid. It&#8217;s a kind of boolean union operation.</p>
<ul class="gallery">
<li>
<a href="http://plopbyte.net/2011/05/globetweeter-experience/grid/" rel="attachment wp-att-685"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/grid-300x168.jpg" alt="" title="grid" width="300" height="168" class="alignnone size-medium wp-image-685" /></a>
</li>
<li>
<a href="http://plopbyte.net/2011/05/globetweeter-experience/grid0/" rel="attachment wp-att-694"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/grid0-300x168.jpg" alt="" title="grid0" width="300" height="168" class="alignnone size-medium wp-image-694" /></a>
</li>
</ul>
<p>Above on the left, you can see the white model that is the original &#8217;110m admin 0 countries.shp&#8217;. The black model is the same model but tesselated a bit more to fit more closely on the sphere. On the right is the model (grid) use to tessellate the original &#8217;110m admin 0 countries.shp&#8217;. The idea is to add subdivisions on the height section of the model. </p>
<p>Once the data is subdivided enough, I created a tool to project each vertex onto a sphere using the standard <a href="http://en.wikipedia.org/wiki/WGS84">WGS84 projection</a>. <strong>You can see a webgl version of the projected model by clicking on the picture</strong>.</p>
<ul class="gallery">
<li>
<a href="http://showwebgl.com/show/?q=e8lx1nt7jd448k8cg8g4gsws44owsgo&#038;LIGHT=0"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/globe-2-300x168.jpg" alt="" title="globe-2" width="300" height="168" class="alignnone size-medium wp-image-701" /></a>
</li>
<li>
<a href="http://showwebgl.com/show/?q=iy9ll8zf4kgks8cw8wk0oc48g8w80ww&#038;LIGHT=0"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/globe-1-300x168.jpg" alt="" title="globe-1" width="300" height="168" class="alignnone size-medium wp-image-702" /></a>
</li>
<li>
<a href="http://showwebgl.com/show/?q=lvzodmgqc7kcsc0k08cgs08owwsccwk&#038;CULL_FACE=0"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/globe-0-300x168.jpg" alt="" title="globe-0" width="300" height="168" class="alignnone size-medium wp-image-703" /></a>
</li>
<li>
<a href="http://showwebgl.com/show/?q=ageig6tuwqgw04gscw40k08s0ssgckg&#038;LIGHT=0"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/03/globe-4-300x168.jpg" alt="" title="globe-4" width="300" height="168" class="alignnone size-medium wp-image-704" /></a>
</li>
</ul>
<p>Once the data below were ready we selected a nice color for each model. On the demo I drew the globe in two passes. The first pass drew back faces of &#8217;110m admin 0 countries&#8217; with &#8216;back color&#8217; and the second drew the front faces with &#8216;front color&#8217;. It was necessary to have transparency of the globe because of the blending mode &#8216;One Minus Src Alpha&#8217;.</p>
<p>The Final result looks like this<br /><br />
<a href="http://plopbyte.net/2011/05/globetweeter-experience/screenshot-21/" rel="attachment wp-att-1044"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/05/Screenshot-21-1024x576.jpg" alt="" title="Screenshot-21" width="1024" height="576" class="alignnone size-large wp-image-1044" /></a></p>
<h3>SceneGraph representation</h3>
<p><a href="http://plopbyte.net/2011/05/globetweeter-experience/samsung-3/" rel="attachment wp-att-934"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/04/gt_tree.jpg" alt="" title="SceneGraph" width="1325" height="994" class="alignnone size-full wp-image-934" /></a></p>
<h3>Wave</h3>
<p>To add some details about twitter activity I setup a simple wave physics simulation that produces waves where tweets appear. The algorithm to produce the waves is explained <a href="http://freespace.virgin.net/hugo.elias/graphics/x_water.htm">here</a>. To accomplish this I used two small hidden canvases with a size of 128&#215;64 , I used small canvases because the computation is done on javascsipt and can be expensive. The update of waves was updated every 1/30 seconds. The update function did the following operations:</p>
<ul>
<li>Convert tweets locations into source wave in the canvas.
</li>
<li>Do the physics computation and store the result into the current canvas.
</li>
<li>Upload the current canvas as texture to use in the vertex shader.<br />
The vertex shader used this texture as a <a href="http://en.wikipedia.org/wiki/Heightmap">heightmap</a>. To understand better how the heightmap works you can see <a href="http://showwebgl.com/show/?q=7m1vu1clptog8ccs880o0s44cwks000&#038;LIGHT=0">here</a> the original model without waves.
</li>
</ul>
<p>Vertex Shader</p>
<pre><code>
#ifdef GL_ES
precision highp float;
#endif
attribute vec3 Vertex;
attribute vec3 TexCoord0;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 NormalMatrix;
uniform float scale;
uniform sampler2D Texture0;
varying float height;
float maxHeight = 1400000.0;
void main(void) {
    vec4 color = texture2D( Texture0, TexCoord0.xy);
    height = color[0];
    vec3 normal = normalize(Vertex);
    vec3 normalTransformed = vec3(NormalMatrix * vec4(normal,0.0));
    float dotComputed = dot(normalTransformed, vec3(0,0,1));
    height *= max(0.0, dotComputed);
    vec4 vrt = vec4(Vertex +  normal * ( height * maxHeight * scale),1.0);
    gl_Position = ProjectionMatrix * ModelViewMatrix * vrt;
    height *= 5.0 * scale;
}
</code></pre>
<p>Fragment Shader</p>
<pre><code>
#ifdef GL_ES
precision highp float;
#endif
uniform vec4 fragColor;
varying float height;
void main(void) {
    gl_FragColor = fragColor * height;
}
</code></pre>
<p>This shader is applied on a regular grid model projected on the sphere as explained before but this time the grid has a better resolution. Some of you will not see the relief of the waves because some webgl implementation does not expose texture unit on the vertex shader. Therefore as a work around I made another shader that does not move the vertexes in the vertex shader. Instead it only changes the color of the vertexes. You can read more about this issue on the <a href="https://groups.google.com/group/angleproject/browse_thread/thread/fbf08f0ab51ff26d">Angle project</a>.</p>
<p>Vertex Shader</p>
<pre><code>
#ifdef GL_ES
precision highp float;
#endif
attribute vec3 Vertex;
attribute vec3 TexCoord0;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 NormalMatrix;
varying float dotComputed;
varying vec2 TexCoordFragment;
void main(void) {
    TexCoordFragment = TexCoord0.xy;
    vec3 normal = normalize(Vertex);
    vec3 normalTransformed = vec3(NormalMatrix * vec4(normal,0.0));
    dotComputed = max(0.0, dot(normalTransformed, vec3(0,0,1)));
    if (dotComputed > 0.001) {
        dotComputed = 1.0;
    }
    gl_Position = ProjectionMatrix * ModelViewMatrix * vec4(Vertex, 1);
}
</code></pre>
<p>Fragment Shader</p>
<pre><code>
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D Texture0;
uniform vec4 fragColor;
uniform float scale;
varying float dotComputed;
varying vec2 TexCoordFragment;
void main(void) {
    vec4 color = texture2D( Texture0, TexCoordFragment.xy);
    gl_FragColor = fragColor * min(2.0*dotComputed * color.x, 0.999999);
}
</code></pre>
<p>Yes it&#8217;s a bit sad, I have seen this issue lately &#8230; :( . As conclusion this effect works well but it takes too much cpu in javascript/canvas, I should have tried a different effect that was less cpu intensive. Have a look at this <a href="http://www.youtube.com/watch?v=ul9cIj7wISE">video</a> if you can&#8217;t see the waves&#8217;s relief.</p>
<h3>Tweets</h3>
<p>Tweets are displayed with the avatar image with simple quad oriented and positioned on the sphere from latitude/longitude. To add a nice border around the image I used a blending operation in the canvas with the following image.</p>
<p><img src="http://portfolio.plopbyte.net/wp-uploads/2011/04/tweets.jpg" alt="" title="tweets" width="300" height="168" class="alignnone size-full wp-image-894" /></p>
<p>Finally to have a nice animation when a tweet appears and disappears, I used an EaseInQuad function for the color, and EaseOutElastic for the scale component.</p>
<pre><code>
EaseInQuad = function(t) { return (t*t); };
EaseOutElastic = function(t) { return Math.pow(2.0, -10.0*t) *
                                         Math.sin((t-0.3/4.0) *
                                         (2.0*Math.PI) / 0.3) + 1.0; };
</code></pre>
<p>Zooming to the earth made tweet really huge related to the screen. To prevent this effect I introduced a scale factor that depends on the camera altitude. The full code to update a tweet looks like this</p>
<pre><code>
update: function(node, nv) {
    var ratio = 0;
    var currentTime = nv.getFrameStamp().getSimulationTime();
    if (node.startTime === undefined) {
        node.startTime = currentTime;
        if (node.duration === undefined) {
            node.duration = 5.0;
        }
    }

    var dt = currentTime - node.startTime;
    if (dt > node.duration) {
        node.setNodeMask(0);
        return;
    }
    ratio = dt/node.duration;
    if (node.originalMatrix) {
        var scale;
        if (dt > 1.0) {
            scale = 1.0;
        } else {
            scale = osgAnimation.EaseOutElastic(dt);
        }

        scale *= (this.manipulator.height/this.WGS_84_RADIUS_EQUATOR);
        if (this.manipulator.height > this.limit) {
           var limitConst = 0.8/(2.5*this.WGS_84_RADIUS_EQUATOR-this.limit);
           var rr = 1.0 - (this.manipulator.height-this.limit) * limitConst;
           scale *= rr;
        }
        var scaleMatrix = osg.Matrix.makeScale(scale, scale, scale);
        node.setMatrix(osg.Matrix.mult(node.originalMatrix, scaleMatrix));
    }

    var value = (1.0 - osgAnimation.EaseInQuad(ratio));
    var uniform = node.uniform;
    var c = [value, value, value, value];
    uniform.set(c);
    node.traverse(nv);
}
</code></pre>
<p><br /></p>
<h3>NodeJS</h3>
<p>The server responsible for sending tweets to the clients is done with nodejs. I used twitter-node, socket.io, and express modules to build the server. The code is really short so you can have a look on the server directly. You can get the server code <a href="http://hg.plopbyte.net/globetweeter-server/">here</a> and improve it :) A big huggy to proppy who bootstraps the the nodejs server \o/</p>
<h3>Stats</h3>
<p>The first graph shows the number of connections per day. There is a big spike when the news was broadcasted. The second graph shows the number of connections per day but with a smaller scale and the last graph shows the cumulated number of connections.<br />
<br /><a href="http://plopbyte.net/2011/05/globetweeter-experience/stats-2/" rel="attachment wp-att-1020"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/05/stats1-853x1024.png" alt="" title="stats" width="853" height="1024" class="alignnone size-large wp-image-1020" /></a></p>
<p><strong>Links</strong></p>
<ul>
<li>video <a href="http://www.youtube.com/watch?v=fWuPWaBbS_o"> Firefox 4 3D WebGL Demo &#8211; GlobeTweeter</a></li>
<li>video <a href="http://www.youtube.com/watch?v=Dw5G0UvWB80"> GlobeTweeter&#8211;Behind the Making of the Demo</a></li>
<li>video <a href="http://www.youtube.com/watch?v=ul9cIj7wISE"> GlobeTweeter</a></li>
<li>video <a href="http://www.youtube.com/watch?v=Wo_LlP-VvhY"> WebGL globetweeter demo Firefox 4.0</a></li>
<li><a href="https://mozillademos.org/demos/globetweeter/demo.html">globe tweeter demo</a></li>
<li><a href="https://github.com/cedricpinson/globetweeter/">globe tweeter source code</a></li>
<li><a href="http://hg.plopbyte.net/globetweeter-server/">globe tweeter server source code</a></li>
<li><a href="https://github.com/cedricpinson/osgjs">osgjs</a></li>
<li><a href="https://showwebgl.com">showwebgl to convert / display model on the web</a></li>
<li><a href="http://plopbyte.com/insideglobetweeter/">conf at parisjs#6</a></li>
</ul>
<p>A big thanks to Paul Rouget from Mozilla who made this demo possible and Guillaume Lecollinet who designed this demo.</p>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/05/globetweeter-experience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ParisJS &#8211; Inside GlobeTweeter</title>
		<link>http://plopbyte.com/2011/04/parisjs-inside-globetweeter/</link>
		<comments>http://plopbyte.com/2011/04/parisjs-inside-globetweeter/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 16:15:32 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[osgjs]]></category>
		<category><![CDATA[webgl]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=913</guid>
		<description><![CDATA[For ParisJS #6 I did a conference about GlobeTweeter, and an overview of code inside the application. I did the slides with dzslides from Paul Rouget, thanks for this tool :)]]></description>
			<content:encoded><![CDATA[<p>For <a href="http://parisjs.org/">ParisJS</a> #6 I did a conference about <a href="https://mozillademos.org/demos/globetweeter/demo.html">GlobeTweeter</a>, and an overview of code inside the application. I did the slides with <a href="http://paulrouget.com/e/introdzslides/">dzslides</a> from Paul Rouget, thanks for this tool :)</p>
<ul class="gallery">
<li>
<a href="http://plopbyte.net/insideglobetweeter/"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/04/slides1.jpg" alt="" title="slides1" width="300" height="169" class="alignnone size-full wp-image-916" /></a>
</li>
<li>
<a href="http://plopbyte.net/insideglobetweeter/"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/04/slides0.jpg" alt="" title="slides0" width="300" height="169" class="alignnone size-full wp-image-919" /></a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/04/parisjs-inside-globetweeter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenSceneGraph tools for OpenGL es 2.0</title>
		<link>http://plopbyte.com/2011/04/openscenegraph-tools-for-opengl-es-2-0/</link>
		<comments>http://plopbyte.com/2011/04/openscenegraph-tools-for-opengl-es-2-0/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 10:37:57 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=760</guid>
		<description><![CDATA[I have done plugins and pseudo loader for OpenSceneGraph to work with OpenGL es 2.0 spec and webgl. The first thing you need when working with big mesh is to split them in bunch of 65536 vertexes because opengl es 2.0 speccification limit the size of indexes to 16 bits. In order to manage this [...]]]></description>
			<content:encoded><![CDATA[<p>I have done plugins and pseudo loader for OpenSceneGraph to work with OpenGL es 2.0 spec and webgl. The first thing you need when working with big mesh is to split them in bunch of 65536 vertexes because opengl es 2.0 speccification limit the size of indexes to 16 bits. In order to manage this case, I have done a <a href="http://hg.plopbyte.net/osg-trunk/file/1af36d5c6fff/src/osgPlugins/split">pseudo loader called split</a>, so you can use it like that</p>
<p><code><br />
osgconv hugemodel.osg.split hugemodel_splited.osg # careful about the MERGE_GEOMETRY flag in OSG_OPTIMIZATION<br />
</code><br />
I have also done a resolve pseudo loading to re affect location of texture filename. The problem is that when I convert models to <a href="http://osgjs.org">osgjs</a>, osg is able to find the file because he can find in a path list, but once the image loaded it does not update the file location ( and it makes sense ) . It&#8217;s not suitable for <a href="http://showwebgl.com">showwebgl</a> that converts models on server side and need to reassign the image path before converting it to osgjs, this plugin loader is called <a href="http://hg.plopbyte.net/osg-trunk/file/1af36d5c6fff/src/osgPlugins/resolve">resolve</a> . And the last plugin is osgjs itself that is able to convert osg native format to <a href="http://hg.plopbyte.net/osg-trunk/file/1af36d5c6fff/src/osgPlugins/osgjs">osgjs format</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/04/openscenegraph-tools-for-opengl-es-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ShowWebGL</title>
		<link>http://plopbyte.com/2011/04/showwebgl/</link>
		<comments>http://plopbyte.com/2011/04/showwebgl/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 23:18:25 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=723</guid>
		<description><![CDATA[I have put online http://showwebgl.com it&#8217;s a website for artists and developers who want to show and share their models. The workflow is really simple you have a model you want to show to people. Upload it and get the url of the model, then share the url or embed the model in an iframe. [...]]]></description>
			<content:encoded><![CDATA[<p>I have put online <a href="http://showwebgl.com">http://showwebgl.com</a> it&#8217;s a website for artists and developers who want to show and share their models. The workflow is really simple you have a model you want to show to people. Upload it and get the url of the model, then share the url or embed the model in an iframe.<br />
The current website is still in progress so consider it in beta, in a few weeks It will have a nice skin and better feature, but you can still try it and report to bug to me :)</p>
<p>The list of file format showwebgl is able to read the following file extension obj, ive, 3ds, dae, ply, osg2, osgb, osgt, osgx, osgs, gem, geo, mdl, rgb, lws, dxf, tgz, osgterrain, shp, zae, stl, sta, bvh, ac, flt, ogr, osga, md2, x, json, txp, dw, osgtgz, 3dc, asc, lw, lwo, gdal, bsp, osg</p>
<p>You can add texture putting everything inside a zip archive, for example you can put your collada model and its texture inside a zip then upload the zip file.</p>
<p>The back end use OpenSceneGraph :)</p>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/04/showwebgl/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>stats.js</title>
		<link>http://plopbyte.com/2011/02/stats-js/</link>
		<comments>http://plopbyte.com/2011/02/stats-js/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 23:11:10 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[osgjs]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=590</guid>
		<description><![CDATA[I have written this afternoon a little class to manage graph, for osg.js I will need to graph the update/cull/draw traversal and I guess more others things, so I needed a stats functionnality a bit like in Three.js demo. I have first get his stats.js, but it did not fit my use and I wanted [...]]]></description>
			<content:encoded><![CDATA[<p>I have written this afternoon a little class to manage graph, for <a href="http://osgjs.org">osg.js</a> I will need to graph the update/cull/draw traversal and I guess more others things, so I needed a stats functionnality a bit like in <a href="https://github.com/mrdoob/three.js/">Three.js</a> demo. I have first get his stats.js, but it did not fit my use and I wanted to try without redrawing the full graph. I want to get the previous result of the canvas then shift it by a delta (new_time &#8211; previous_time) and draw only one line for the delta elapsed. I have not check if it produces better performance but it was cool to code it. You can see the result <a href="http://plopbyte.net/stats.js/">here</a> and the source code is on <a href="https://bitbucket.org/cedricpinson/stats.js/overview">bitbucket</a> . The only problem I could see is that the line are not as clean as it could because they are not connect from a full path, and the consequence is that antialias can&#8217;t work on the full path.</p>
<p><a href="http://plopbyte.net/stats.js/"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/02/Screenshot-12.jpg" alt="" title="Screenshot-12" width="625" height="351" class="alignnone size-full wp-image-595" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/02/stats-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>osg.js</title>
		<link>http://plopbyte.com/2011/02/osg-js/</link>
		<comments>http://plopbyte.com/2011/02/osg-js/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 22:48:54 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[osgjs]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=578</guid>
		<description><![CDATA[Since I play with WebGL, I wanted a way to work as I do with OpenSceneGraph. So I started to write a subset of OpenSceneGraph in javascript that uses same concept. For this I have done a plugin for OpenSceneGraph that is able to export scene graph to osgjs json format. osgjs.org is young but [...]]]></description>
			<content:encoded><![CDATA[<p>Since I play with WebGL, I wanted a way to work as I do with <a href="http://openscenegraph.org">OpenSceneGraph</a>. So I started to write a subset of <a href="http://openscenegraph.org">OpenSceneGraph</a> in javascript that uses same concept. For this I have done a plugin for <a href="http://openscenegraph.org">OpenSceneGraph</a> that is able to export scene graph to osgjs json format. <a href="http://osgjs.org">osgjs.org</a> is young but still ready to be used for project, I have created <a href="http://osgjs.org">osgjs.org</a> to centralize information related to it. The project needs users and contributors, so want to help ? Go to <a href="http://osgjs.org">osgjs.org</a> and try it.</p>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/02/osg-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenSceneGraph beginners book</title>
		<link>http://plopbyte.com/2011/01/openscenegraph-beginners-book/</link>
		<comments>http://plopbyte.com/2011/01/openscenegraph-beginners-book/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 15:57:03 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[osg]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=351</guid>
		<description><![CDATA[Packt Publishing have published a new OpenSceneGraph beginners book, I am happy for having reviewed the technical part of this book and I recommand it for all beginners who wanted to start quickly on OpenSceneGraph]]></description>
			<content:encoded><![CDATA[<p>Packt Publishing have published a new OpenSceneGraph beginners book, I am happy for having reviewed the technical part of this book and I recommand it for all beginners who wanted to start quickly on <a href="http://openscenegraph.org">OpenSceneGraph</a></p>
<ul class="gallery">
<li>
<a href="https://www.packtpub.com/openscenegraph-3-0-beginners-guide/book"><img src="http://portfolio.plopbyte.net/wp-uploads/2011/01/BeginnersGuide.png" alt="" title="BeginnersGuide" width="125" height="152" class="aligncenter size-full wp-image-352" /></a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2011/01/openscenegraph-beginners-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebGL Particles</title>
		<link>http://plopbyte.com/2010/08/webgl-particles/</link>
		<comments>http://plopbyte.com/2010/08/webgl-particles/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 01:24:58 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[osgsj]]></category>
		<category><![CDATA[webgl]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=197</guid>
		<description><![CDATA[I have played with render to texture to generate particles with physics, the idea is to compute particles position on the gpu and use it as input to render them. For this I have use the firefox logo in 512&#215;512 so we have 262144 particles animated even if somes are invisibles. You can find some [...]]]></description>
			<content:encoded><![CDATA[<p>I have played with render to texture to generate particles with physics, the idea is to compute particles position on the gpu and use it as input to render them. For this I have use the firefox logo in 512&#215;512 so we have 262144 particles animated even if somes are invisibles. You can find some useful information from this articles <a href="http://directtovideo.wordpress.com/2009/10/06/a-thoroughly-modern-particle-system/">http://directtovideo.wordpress.com/2009/10/06/a-thoroughly-modern-particle-system/</a><br />
Ideally It would be great to have render to texture that support floating point for webGL, but without that I did a 16 bits precision with two textures ( high bits and low bits). It&#8217;s a bit boring, in fact It breaks me to try more effects, I would really like to have render to texture with floating point support.</p>
<p>To get a WebGL Implementation have look to Khronos instructions <a href="http://www.khronos.org/webgl/wiki/Getting_a_WebGL_Implementation">http://www.khronos.org/webgl/wiki/Getting_a_WebGL_Implementation</a></p>
<p>You need a browser able to run webGL to try the realtime version <a href="http://plopbyte.net/webgl-particles-demo/">http://plopbyte.net/webgl-particles-demo</a> else click on the image to show the youtube video.</p>
<ul class="gallery">
<li><a href="http://www.youtube.com/watch?v=ShrUOL1V-xc"><img src="http://plopbyte.net/wp-uploads/2010/08/Screenshot-2-300x168.jpg" alt="" title="Screenshot-2" width="300" height="168" class="alignnone size-medium wp-image-453" /></a>
</li>
<li><a href="http://www.youtube.com/watch?v=ShrUOL1V-xc"><img src="http://plopbyte.net/wp-uploads/2010/08/Screenshot-0-300x169.jpg" alt="" title="Screenshot-0" width="300" height="169" class="alignnone size-medium wp-image-454" /></a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2010/08/webgl-particles/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ArtGame Weekend</title>
		<link>http://plopbyte.com/2010/07/artgame-weekend/</link>
		<comments>http://plopbyte.com/2010/07/artgame-weekend/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 22:37:52 +0000</pubDate>
		<dc:creator>Cedric Pinson</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[artgameweekend]]></category>
		<category><![CDATA[game]]></category>

		<guid isPermaLink="false">http://plopbyte.net/?p=176</guid>
		<description><![CDATA[A Month ago, we have participated to the artgame weekend . The idea is to make a game in 48h on a mobile platform. I joined Chen to work on her concept, the idea was to use a guitar hero gameplay on an Hitler speech. The concept is strong and make people feel uncomfortable with [...]]]></description>
			<content:encoded><![CDATA[<p>A Month ago, we have participated to the <a href="http://artgameweekend.com/">artgame weekend</a>  . The idea is to make a game in 48h on a mobile platform. I joined Chen to work on her concept, the idea was to use a guitar hero gameplay on an Hitler speech. The concept is strong and make people feel uncomfortable with the game.<br />
I have made the  choice to work on android because I have a HTC hero and it&#8217;s more open than Iphone. When I started I had just installed eclipse on my ubuntu box and tried the hello world example. I am a novice on mobile platform. 48h later I am really impressed by this experience.<br />
The workflow to test and develop android apps with eclipse was impressive. It just worked as expected. usually I am an emacs users, but for this experience I have used the &#8216;regular&#8217; path as explained on the android sdk.</p>
<p>At the end we had a game, but we worked more after the weekend to release it. Because of the sensible subject the game is, we had to adjust/change some part. The source code is in GPL you can get it <a href="http://hg.plopbyte.net/triumph-of-the-word/">here</a></p>
<p>links:<br />
[adroidlib](http://www.androlib.com/android.application.com-artgame-triumph-jxACz.aspx)<br />
[androidzoom](http://www.androidzoom.com/android_games/casual/triumph-of-the-word_ijqc.html)</p>
<ul class="gallery">
<li><a href="http://www.youtube.com/watch?v=roN9HsVh1zo"><img src="http://portfolio.plopbyte.net/wp-uploads/2010/07/screen1-300x169.jpg" alt="" title="screen1" width="300" height="169" class="alignnone size-medium wp-image-463" /></a>
</li>
<li><a href="http://market.android.com/details?id=com.artgame.triumph"><img src="http://portfolio.plopbyte.net/wp-uploads/2010/07/chart-300x168.jpg" alt="" title="chart" width="300" height="168" class="alignnone size-medium wp-image-461" /></a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://plopbyte.com/2010/07/artgame-weekend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/


Served from: www.plopbyte.net @ 2012-02-05 03:15:29 -->
