VisualEYEzer

 

I almost forgot to post this little demo. It’s a remake of an old experiment with procedural eyes I made in flash long time ago. (Actually, the old one look kind of cooler than this, think it’s the normal-mapping that does the difference. Haven’t gotten to the point of making that in a procedural shader yet, probably have to use off-screen renderers and stuff)

This time it’s done with three.js and shaders. So basically I just started of with the sphere-geometry. The vertices near the edge of the z-axis got an inverted z-position in relation to the original radius, forming the iris as a concave parabolic disc on the sphere.

The shader is then doing it’s thing. By reading the uv-coordinate and the surface-positions I apply different patterns to different sections. I separate those sections in the shader by using a combination of step (or smoothstep) with mix. Step is almost like a if-statement, returning a factor that is 1 if inside the range, and 0 outside. Smoothstep blurs the edge for a smoother transition. You can then use that in the mix-method to choose between two colors, for example the pupille and the iris. I mentioned this method in my last post as well.

Check out the fragment shader here

To give the eye the reflective look, I added a second sphere just outside the first one with a environment-map. The reason for not using the same geometry was that I wanted the reflection on the correct surface around the iris. And by making the second sphere just slightly larger it gives the surface some kind of thickness.

To spice it up little, I added some audio-analysing realtime effects, with this little nifty library called Audiokeys.js. With that you can specify a range of frequencies to listen in to and get a sum of that level. Perfect for controlling parameters and send them to the shaders as uniforms.

Open demo

Plasma ball

Run demo

More noisy balls. Time to be nostalgic with a classic from the 80′s: The plasma lamp. I have never had the opportunity to own one myself, maybe that’s why I’m so fascinated by them. There is even small USB driven ones nowadays. I’ve had this idea for a demo a long time and finally made a rather simple one.

The electric lightning  is made up by tubes that is displaced and animated in the vertex shader, just as in my last experiment.  I reuse the procedurally generated noise-texture that is applied to the emitting sphere. I displace local x- and z-position with an offset multiplied by the value I get from the noise-texture on the corresponding uv-position (along y-axis). To make the lightning progress more naturally I also use a easing-function on this factor. Notice that it’s less displacement near the center and more at the edges.

I’m have this idea of controlling the lightning with a multi-touch websocket-connection between a mobile browser and the browser just to learn node.js and sockets. Let’s wait and see how this evolves. Running this on on a touch-screen directly would have been even nicer of course. If someone can do that, I will add multiple touch-points, just let me know.

Set a sphere on fire with three.js

Fire it up!

Next element of nature in line, smoke and fire! I did a version in flash about a year ago, playing with 4D Perlin noise. That bitmapdata was like 128×128 big using haxe to work with fast memory. At 20fps. Now we can do fullscreen in 60+ fps. Sweet.

First, note that code snippets below is taken out of context and that they using built-in variables and syntax from three.js. If you have done shaders before you will recognize variables like mvPosition and viewMatrix, or uniforms and texture-lookups.

The noise is generated within a fragment shader, applied to a plane inside a hidden scene, rendered to a texture and linked to the target material. This process is just forked from this demo by @alteredq. Before wrapping the texture around the sphere we have to adjust the output of the noise to be suitable for spherical mapping. If we don’t, the texture will look pinched at the poles as seen in many examples. This is one of the advantages of generating procedural noise; that you can modify the output right from the start. By doing this, each fragment on the sphere get the same level of details in the texture instead of stretching the image across a surface. For spheres, this following technique is one way of finding where (in the imaginary volume of noise) you should fetch the noise-value:

float PI = 3.14159265;
float TWOPI = 6.28318531;
float baseRadius = 1.0;

vec3 sphere( float u, float v) {
	u *= PI;
	v *= TWOPI;
	vec3 pSphere;
	pSphere.x = baseRadius * cos(v) * sin(u);
	pSphere.y = baseRadius * sin(v) * sin(u);
	pSphere.z = baseRadius * cos(u);
	return pSphere;
}

 

Notice the 2d-position that that goes into the function and the returning vec3-type. The uv-coordinates is translated to a 3d-position on the sphere. Now we can just look up that noise-value and plot it to the origin uv-position. Changing the baseRadius affects the repeating of the texture.

Another approach is to do everything in the same shader-pair, both noise and final output. We get the interpolated world-position of each fragment from the vertex-shader, so no need for manipulating right? But since this example uses displacements in the vertex-shader I need to create the texture in a separate pass and send it as a flat texture to the last shader.

So now we have a sphere with a noise texture applied to it. It look nice but the surface is flat.

I mentioned displacements, this is all you have to do:

#ifdef VERTEX_TEXTURES
	vec3 texturePosition = texture2D( tHeightMap, vUv ).xyz;
	float dispFactor = uDispScale * texturePosition.x + uDispBias;
	vec4 dispPos = vec4( normal.xyz * dispFactor, 0.0 ) + mvPosition;
	gl_Position = projectionMatrix * dispPos;
#else
	gl_Position = projectionMatrix * mvPosition;
#endif

 

uDispScale and uDispBias is uniform variables that we can control with javascript at runtime. We just add a value to the original position along the normal direction. The #ifdef-condition let us use a fallback for those on browsers or environments that doesn’t support textures in the vertex-shader. It’s not available in all implementations of webGL, but depending on your hardware and drivers it should work in latest Chrome and Firefox builds. Correct me if I’m wrong here. This feature is crucial for this demo, so I prompt a alert-box for those unlucky users.

After adding displacement I also animate the vertices. You can e.g. modify the vertex-positions based on time, the vertex position itself or the uv-coordinates to make the effects more dynamic. One of the effects available in the settings-panel is “twist”. I found it somewhere I don’t remember now, but here it is if you’re interested:

vec4 DoTwist( vec4 pos, float t )
{
	float st = sin(t);
	float ct = cos(t);
	vec4 new_pos;

	new_pos.x = pos.x*ct - pos.z*st;
	new_pos.z = pos.x*st + pos.z*ct;

	new_pos.y = pos.y;
	new_pos.w = pos.w;

	return( new_pos );
}

//this goes into the main function
float angle_rad = uTwist * 3.14159 / 180.0;
float force = (position.y-uHeight*0.5)/-uHeight * angle_rad;

vec4 twistedPosition = DoTwist(mPosition, force);
vec4 twistedNormal = DoTwist(vec4(vNormal,1.0), force);

//change matrix
vec4 mvPosition = viewMatrix * twistedPosition;

 

The variable force has to be changed to your need. Basically you want to set a starting position and a range that is going to be modified.

Then we reach the final fragment-shader. This one is fairly simple. I blend two colors. Multiply those with one of the channels in the height-map (the noise texture). Then mix this color with the smoke color. All colors get their values based on the screen-coord, a quickfix for this solution. Lastly I apply fog to make fire blend into the background, looking less like a sphere.

For some final touch, a bloom filter is applied and some particles is thrown in as well. Had some help by @aerotwist and his particle tutorial.

That’s it folks, thanks for reading.

 

 

Procedural eyes

Procedural graphics is surely my favorite. The concept of create visual things with just code. Really comes in handy when your a crappy designer and still want to do visual stuff. Here you can see the result of yet another experiment on this track. It’s a eye-shader for generating procedural eyes. The 3D-engine of choice is Away3d. I use a CompositeMaterial consisting a PhongMultiPassMaterial and a SphericEnvMapPBMaterial (for the environment reflections). The bitmap that is used in the material is generated by a haxe-swf that is loaded in runtime. Just as previous experiments. The same bitmap is used as a base for the spherical normalmap. That adds a nice displacement to the surface. The iris is quite simple and could have more layers and complexity to get a more realistic pattern. Anyway, the texture looks something like this.

When wrapping this on a sphere it will fit seamlessly . I know, the blood-vessels aren’t that great. Perhaps I should use lines with turbulence instead.

Design your own eye

Here is a tool where you can try the different settings and create a unique eye.
Open editor

Demo

This “mars-attacks”-demo follows the mouse. To get two eyes I duplicates the output from the view. Thats why he can’t look at his nose (if existed). Notice that he is reacting to light, sort of…


Click to open

Open demo

Playing with fire

Last time I made some wood. Now let’s burn that up. Still experimenting with the same 3D perlin noise as before, but this time animated. When you can take control over each pixel of noise it’s easy to add extra rules to form the shape of the noise such as turbulence based on y-value or an offset animation along the z-axis to gain some depth. Applying “ridges” to the perlin noise (invert all negative values when the range is between -1 to 1) makes the flames look more interesting. The bitmap generated is just 80×80 and 2 octaves of Perlin noise, so the possibilities are quite limited.

Click here or on the fireplace above to get warm.

If you want to see how it works, here is a zip with sources for a simple example. No graphics or UI is included though. The noise is compiled with Haxe, but a swf is included if you want to skip that.

See this post for additional credits.

Noise Editor

The images in the last post was created with this tool. I use the heightmap to create a normal map with a excellent class called SphericalDispToNormConverter. So since I now have a heightmap and a normal map, Away3D can do the rest. The material used in this example is the PhongMultiPassMaterial. When “displacement map” is disabled a simple BitmapMaterial is used. The @away3D -team has really done a great job with the pixelbender materials.

Among the settings you can choose between a regular perlin noise or a ridged one. You will notice that the difference is pretty big. Also, check out the different presets.

The resolution on the heightmap is 400×200, but scaled down in the UI. (By the way I can’t tell you enough how I love the minimalcomps by mr @bit101.)  The heightmap-generation is pretty heavy on the CPU, so choose browser with care and stay away from debug-players ;)


Sphere designer

What do you think? Time for a generative material-library for Away3D?

Spherical Perlin Noise

I’m not quite done experimenting with 3d perlin noise. Another cool feature that I haven’t seen in flash is to wrap the noise on a sphere seamlessly. Here is the result:


Click the spheres for a slightly larger version

To get the texture to wrap seamless without distortion, we can use the 3d nature of the noise in a interesting way. If we evaluating the 3d-position of each point on the surface of a sphere we can get the noise in that particular point. To convert the point from 3d-space to 2d-space some trigonometry is needed. My math-skills really suck, but my cut-n-paste skills are excellent. Once again, LibNoise showed me the way with 5 lines of code. First I only got chaotic noise with some sort of repeating pattern. It took some time to figure out that I had to convert the numbers to a positive range.

lat = py / height * 180- 90;
lon = px / width * 360-180;
r = Math.cos(DEG_TO_RAD *  lat);

//range between 0-1
_x = (r * Math.cos (DEG_TO_RAD * lon) +1)*.5
_y = (Math.sin (DEG_TO_RAD * lat)+1)*.5
_z = (r * Math.sin(DEG_TO_RAD * lon)+1)*.5

For the sphere and the material/lighting I use Away3d. In the next post I will show you more about that and the tool for creating the different materials. Oh, and it’s looks a lot better animated :)

Ridged Perlin Noise

While doing research for the terrain editor I found a lot of different methods for creating noise. One of my favorite algorithms is “ridged fractal noise”. I haven’t found any examples of this in AS3 so I created my own version based on the Optimized Perlin Noise seen in the community before. I think the route of that source began with Ron Valstar’s AS3 version (@Sjeiti), then with a optimized version by @quasimondo, and further optimized with a haxe-version by Nicolas Cannasse. It was very easy to just add the ridged part to the noise generated. There is some source to look at in other languages such as C++, Java or C#. First some examples to see whats the characteristics of ridges. Some of them uses a Stok3d PhongShader created by @DerSchmale to add a nice depth:


Terrain | My favorite. Imagine using this with a voxelengine.


Marble


Electric


Trails | Put together in Photoshop to demonstrate the effect of the shader


Space


Stone texture

It’s quite fun to search for new patterns by just adjusting the few parameters:

Make some noise

Try it out for yourself. I have limited the size of the bitmap to 200×200. It’s pretty optimized, but still to slow for large bitmaps. A Cool thing is that the swf is just 26 kB. Thanks @bit101 for MinimalComps.


Open editor

Here is a explanations for some of the parameters (I borrowed the descriptions from the reference of world-machine):

Offset: Offset determines at what elevation the fractal behavior begins to change its character.
Gain: A multifractal parameter, Gain typically controls the relative strength of the detailed versus smooth regions of the fractal. Low values are very smooth, while high values bring on the detailed nature more quickly.
Persistence: Controls the degree to which the strength of each layer of noise is reduced as they are layered together. Low persistence values produce very smooth terrains, whereas increasing the persistence produces more detail (and spikiness). Unlike a low octaves value, all layers of noise are still calculated when using a low persistence, so that terrain features are smoothly introduced as the value is increased.

If you’re interested, here is the source code for the noise generator (in Haxe).

In a terrain a heightmap with ridges is suitable for creating high mountains or sand dunes, which was my primary goal. Next step is to visualize it in 3d. The ridges does not look so good with a low poly mesh, so I have to look for a voxel-engine now.