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.
This is take two on a little toy that I posted some weeks ago on Twitter. I’ve added some new features so it’s not completely old news. There is two new materials and dynamic sounds (chrome only).
This demo is a fun way to demonstrate a simple procedural shader. As you start working with the lathe machine you will carve into the imaginary space defined by numbers and calculations. I like to imagine the surface as a viewport to a calculated world, ready to be explored and tweaked. This is nothing fancy compared to the fractal ray-marching shaders around, but It’s kind of magical about setting up some simple rules and be able to travel through it visually. Remember, you get access to the objects surface-coordinates in 3D for each rendered pixel. This is a big difference when comparing to 3d without shaders, where you have to calculate this on a 2D plane and wrap it around the object with UV-coordinates instead. I did an experiment in flash 10 ages ago, doing just that, one face at the time generated to a bitmapData. Now you get it for free.
Some words about the process of making this demo. Some knowledge in GLSL may come in handy, but it’s more of a personal log than a public tutorial. I will not recommend any particular workflow since it’s really depending on your needs from case to case. My demos is also completely unoptimized and with lots of scattered files all over the place. That why I’m not on Github I’m already off to the next experiment instead.
When testing a new idea for a shader, I’m often assemble all bits and pieces into a pair of external glsl-files to get a quick overview. There is often some tweaks I want to try that’s not supported or structured in the same way in the standard shader-chunks available. And my theory is also that if I edit the source manually and viewing it more often I will get a better understanding of what’s going on. And don’t underestimate the force of changing values randomly (A strong force for me). You can literally turn stone into gold if you are lucky.
The stone material in the demo is just ordinary procedural Perlin-noise. The wood and metal shaders though is built around these different features:
What if I could have a layer that is shown before you start carving? My first idea was to have a canvas to draw on offstage and then mix this with the procedural shader like a splat-map. But then I found another obvious solution. I just use the radius with the step-method (where you can set the edge-values for a range of values). Like setting the value to 1 when the normalized radius is more than 0.95 and to 0 if it’s less. With smoothstep this edge getting less sharp. Then this value and using mix and interpolates between two different colors, the coat and the underlaying part. In the wood-shader coat is a texture and in the the metal-shader it’s a single color.
DiffuseColour = mix(DiffuseColor1, DiffuseColor2 , smoothstep( .91, .98, distance( mPosition, vec3(0.0,0.0,mPosition.z))/uMaxRadius));
This is the grains revealed inside the wood and the tracks that the chisel makes in the metal-cylinder. Basically I again interpolate between two different colors depending on the fraction-part or the Math.sin-output of the position. Say we make all positions between x.8 and x in along the x-axis a different color. A width of 10 is 10 stripes that is 0.2 thick. By scaling the values you get different sizes of the pattern. But it’s pretty static without the…
To make the pattern from previous step look more realistic I turn to a very common method: making noise. I’m using a 3D Simlex noise (Perlin noise 2.0 kind of) with the surface position to get the corresponding noise-value. The value returned for each calculation/pixel is a single float that in turn modifies the mix between the two colors in the stripes and rings. The result is like a 3d smudge-tool, pushing the texture in different directions.
I’m using Phong-shading with three directional light sources to make the metal looking more reflective without the need of an environment map. You can see how the lights forms three horizontal trails in the cylinder, with the brightest one in the middle.
I just copied the shadow map part from WebGLShaders.js into my shader. One thing to mention is the properties available on directional lights to set the shadow-frustum (shadowCameraLeft, shadowCameraRight, shadowCameraTop and shadowCameraBottom). You also have helper guides if you enable dirLight.shadowCameraVisible=true, then it’s easier to set the values. When the shadows is calculated and rendered the light is used as a camera, and with these settings you can limit the “area” of the lights view that will be squeezed into the shadow map. With spotlights you already have the frustum set, but with directional lights you can define one that suites your needs. The shadow-map have a fixed size for each light and when drawing to this buffer the render pipeline will automatically fit all your shadows into it. So the smaller bounding box of geometries you send to it, the higher resolution of details you get. So play around with this settings if you have a larger scene with limited shadowed areas. Just keep an eye on the resolution of the shadows. If the scene is small, your shadowmap-size large and the shadows are low res, your settings are probably wrong. Also, check the scales in your scene. I’ve had troubles in som cases when exporting from 3d studio max if the scaling is to small or big, so that the relations to the cameras goes all wrong or something.
That’s it for know, try it out here. And please, ask questions and correct me if I’m wrong or missing something. See you later!
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.
I have finally started to play with Unity3D. First goal is to get an overview of how shaders work. This will come in handy regardless of what platform I choose as my target. My favorite method when it comes to learning is to port stuff from another languages. Here I get the opportunity to learn two new languages at the same time. And all the trial and error involved often inspires me to do things that wasn’t intended in the first place.
My choice of shader to implement is written by Joost van Dongen (@JoostDevBlog) and he calls it “interior mapping”. It’s a technique to render buildings with a facade with reflections and lighting, and perspectively correct looking interiors (well, at least the walls is correct. Furniture or details on the walls is of course flat) seen through the windows, giving an illusion of loads of geometry on a wall with just two triangles. All done by a single shader. The use of raycasting together with interpolated fragments opens up for a lot of interesting ideas. It’s not a new technique though, I’m just exploring this field for the first time. Check out his excellent paper for details, complete with sources and explanations.
In this demo I use another source of inspiration as well. If you’re into Unity, you have probably seen this cityscape made by @bartekd. I using his example to plot out procedural buildings in a grid, and in the same time learning how to create meshes by scripting. That leaded me to add roads, sidewalks and lights. I also added a simple day/night-system which fades between two sky-boxes (looks weird with fading sun, but that’s enough for this demo ), this parameter also control the lighting and if the activity in the building. Check it out:
View the procedural city here
One thing that I’m totally missing here is optimization skills. Unity folks will shake their heads and laugh out loud. I don’t know where to start really. The buildings and ground is just few triangles, but I have added loads of point lights and streetlight models. I should probably use some sort of light-mapping, but I think that is pro-licence-feature only. The ground is also a grid that looks exactly the same in each cell, maybe there is a way to optimize that. I have tried combining children and meshes, but I got stuck with light-problems or hitting the roof of max vertices. The shader has to be unique for each building, so I can’t combine those either. About shader models, this shader uses shader model 3.0, could not fit the instructions needed otherwise. But get rid of random walls from a texture-atlas and it will compile to model 2.0. But framerate is pretty smooth for this experiment and at least I got a playground where I can practice my forthcoming skills.
Download the building shader I put together in Unity. It would be nice to do a surface-shader instead to get real-time shadows, but once again i’m not a owner of a pro license, so that have to wait. If you like, check out the whole scene package. It’s my first Unity experiments, so please be honest and tell me what can be done better.
Now back to the drawingboard, I have an idea that involves physics, so thats my next stop on the Unity bus. Until then, thanks for reading.
I stumbled on a interesting pattern-generating process the other day, called reaction-diffusion. To quote wikipedia: “Reaction–diffusion systems are mathematical models which explain how the concentration of one or more substances distributed in space changes under the influence of two processes: local chemical reactions in which the substances are transformed into each other, and diffusion which causes the substances to spread out over a surface in space.”
There is a lot of different types and variations with names that makes it sound pretty advanced: Turing (which my experiment is based on), Meinhardt, Gray-Scott and Ginzburg-Landau. These patterns can be seen in nature, like dots and stripes on animal fur. There is some java applets (or I’m sure there are flash apps as well) on the web doing this faster and more advanced than mine, but I had some ideas that I wanted to try. More of that in future posts.
Original source can be found here. If you want my haxe-version, just let me know.
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.
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…