Blog Site map
Works Profile

Endorse endavid on Coderwall

[Valid RSS]

This page is the latest incarnation of my official website. It’s a compendium of things I have published and other stuff I made during my spare time.

In this blog, I will keep track of the updates of this site. If you are interested, just subscribe to the RSS feed.

Weighted Blender Order-Independent Transparency on iOS/OpenGL ES 3.0
Sun, 07 Dec 2014 22:11:30 +0000
Snake o.S. has no sprites or effects at all (there were some 2D sprites, though --did you clear the game?), but recently I've been playing around and adding some sprites to the engine.

I found this paper, Weighted Blender Order-Independent Transparency, and I decided to give it a try. The idea behind it is quite simple, but powerful. All the alpha-geometry is rendered in any order, and given a weight per pixel. In a final compositing pass, the weighted color sum is normalized by the alpha sum.

This is very attractive, since it means I don't have to sort the sprites on the CPU, plus the blending is per-pixel, so it gives more detailed and consistent results. The only problem is finding an appropriate weighting function. In my case, because the distances are very short (50 is the farthest), I've used a simpler function than that of the paper. It's a simple Gaussian, with a maximum value of 100, and with a tail starting around z=50.

Here are 3 unsorted sprites, being the blue one the closest to the camera, and the red one the farthest one,

And here's the result using OIT,

They look a bit blurrier because I'm rendering them at half resolution in a separate buffer. For comparison, here are the sprites using normal alpha-blending again, after sorting the sprites back to front,

I took a couple of videos of something that pretends to be a cloud... The one below is using normal alpha-blending. Of course if the sprites were sorted, it would look better, but there are always popping artifacts

And this is the result of using the Weighted Blended OIT

I think the result is quite impressive for the simplicity of the algorithm. The problem is that I need MRT and float buffers, so it's going to be OpenGL ES3.0 only. For ES 2.0 I should consider sorting the sprites and go for a traditional method, but since I'm doing this engine as a hobby, I think I'd rather keep improving it for ES 3.0 devices, and keep just a small subset of features in ES 2.0

More SSAO tweaks
Sun, 24 Aug 2014 16:56:13 +0100
I had to come back to the Ambient Occlusion. I tried rotating the camera, and the depth difference created a too thick shadow. Also, I didn't like the self-shadowing of the floor. I decided to clear the planet's depth to 0, so self-shadowing problem disappeared, but the from the character now looks even thicker,

Removing the blur, and just using the shrink buffer looks a bit better. The shrinking itself acts as a convolution, so there are still some lines, but of course thinner. They are also visibly aliased, due to the reduced size of the buffer (it's the same size as before, but of course the Gaussian filter and bilinear interpolation helped disguise it),

However, the details inside the objects are gone as well. So what I decided to do is applying a kind of anisotropic filter on the depth. The bigger the difference between adjacent pixels, the smaller the sigma of the Gaussian. In one extreme, we'll have no filter at all (so the result will look like just using the unfiltered shrink buffer), and in the other extreme we have a normal averaging operator. This is the result,

We still have aliased lines around the character, but I don't mind a bit of a toonish look. The important thing is that objects have now some AO, and they look rooted to the floor. Here's the code of the Blur shader. Notice that the alpha channel is blurred normally because I have the projected shadow from the sun there.

    mediump vec4 a_1 = texture2D(texAlbedo, vfTexCoord.xy + vUVTransform.xy);
    mediump vec4 a0 = texture2D(texAlbedo, vfTexCoord.xy);
    mediump vec4 a1 = texture2D(texAlbedo, vfTexCoord.xy +;
    // weights
    mediump float dw = 1.0/3.0;
    mediump vec4 w = vec4(0.4, 0.4, 0.2, 0.2);
    mediump float z0 = dw*(a0.x + a0.y + a0.z);
    mediump float zDiff_1 = abs(dw*(a_1.x + a_1.y + a_1.z)-z0);
    mediump float zDiff1 = abs(dw*(a1.x + a1.y + a1.z)-z0);
    mediump float zDiff = 1.0 - 8.0 * (zDiff_1 + zDiff1);
    // the more different, the less blur
    w.x *= clamp(zDiff, 0.0, 1.0) ;
    w.z = 1.0 - 2.0 * w.x;
    gl_FragColor = w.xxxy * a_1 + w.zzzw * a0 + w.xxxy * a1;

This is how the depth buffer would look if blurred normally (as in the first screenshot),

and this is with the anisotropic blur,

This is how the difference (8 * (zDiff_1+zDiff1)) looks like; the brightest the color, the less blur,

After adding the ambient light I think it looks alright,

Without the AO,

Another shot,

Now I need to fix the ambient light!

SSAO approximations
Sun, 20 Jul 2014 23:56:43 +0100
If you've read about the fake SSAO implementation I used in Snake on a Sphere, you'll know it's just a depth differential. It worked for me because the view was always from above the character. However, if you tilt the camera, you'll notice that the contact area has actually no ambient occlusion, and the further away, the darker it looks. That's the opposite of what ambient occlusion should be... But I can't do better with the differential of the depth... What about using the normals? I've tried replacing the depth by a normal buffer, blur it, and take the length of the differential, similar to what I did with the depth. Here's a comparison,

This is without any fake SSAO,

This is using the depth differential, the same I used in Snake o.S.,

And this is with the normal differential,

The normal differential helps to define some lines, but it also introduces shadowing of whole surfaces. On the other hand, the depth approach looks more like a toon-shader effect. Moreover, as I already mentioned, there's no ambient occlusion where the houses contact the floor. Nevertheless, I think I'm going to stick with this toon-shader look. I think it's better than no fake SSAO at all, and I can't afford any real SSAO on iOS at the moment (less now that I introduced real shadows for directional lights ;) More about that in another post). What do you think?

Skinned Mesh Animation on a header file? Why not!
Sat, 12 Jul 2014 14:06:19 +0100
I've recently updated my Collada parser so I can export skeleton animations and turn the whole thing (mesh with weights, animation matrices, skeleton) into a header file. I find this convenient for small projects where everything can be static.

When I made Snake on a Sphere I didn't want to invest time adding support for animation, so the original snake doesn't even open its mouth when eating That's why I hide the "action" with icon popups

I've just added animation to the engine, and with the help of the exporter, I can now import skinned models and animate them quite fast.

The skeleton tree is represented with a flat array structure, with array index pointers to the parent of each transform. When the parent is oneself, then it means the transform has no parent.

After export, the skeleton will look something like this (it's huge, so I just copy a few lines),

 * @file monigote.h

static const vertexDataSkinned g_monigoteVertices[] = {
	{ {0.5323272f, 5.348835f, -1.007801f}, {0.1901608f, 0.07721179f, -0.9786981f}, {0.0f, 0.0f}, {0.5937652f, 0.3770943f, 0.02914047f}, {0, 5, 10, 0} }, 
	// etc

// rest of the data
// etc

// skeleton
static struct core::TreeNode g_monigoteJointTransformTree[] = {
	/*0: Control*/{0, math::Matrix4(-1.0f, 0.0f, -0.0f, 0.0f, 0.0f, 1.0f, -0.0f, -4.416751f, -0.0f, -0.0f, -1.0f, -0.0f, 0.0f, 0.0f, -0.0f, 1.0f)}, 
	/*1: Stomach*/{0, math::Matrix4(-0.9999999f, 8.74228e-08f, -7.10543e-15f, 0.0f, -4.84881e-09f, -0.05546403f, -0.9984608f, 4.62893f, -8.72882e-08f, -0.9984607f, 0.05546403f, 0.212178f, 0.0f, 0.0f, -0.0f, 1.0f)}, 
	// rest of the bones...

You can find the header files for reference in the Headerify project

If you find it useful, please let me know

Historias cortas de Shin'Ichi Hoshi
Sun, 08 Jun 2014 11:27:50 +0100
Shin'Ichi Hoshi (1926-1997) es uno de mi autores de ciencia ficción preferidos. Escribió más de 1000 historias cortas en japonés, de las cuales sólo unas cuantas han sido traducidas al inglés. No tengo constancia de ninguna traducción al castellano de las mismas, así que me ha dado por traducir algunas de las historias que me han gustado.

Léelas aquí: Historias cortas de Shin'Ichi Hoshi

A tiny piece of the future past
Sun, 01 Jun 2014 11:18:51 +0100
I haven't read any non-tech book for a while... Last year I started reading some short stories by Shin'ichi Hoshi and I just finished it yesterday... Readings

ひとにぎりの未来 (A tiny piece of the future) had some good short stories, but also some boring ones. It is also interesting to see his vision of the future, with machines that would look retro nowadays

So yeah, it's almost a future that never happened but it's already "past"...

Shin'ichi Hoshi wrote hundreds of short stories, so I plan to read more books. Unfortunately, not so many publications of his publications have been translated to English. If you are curious, you can take a look here: There are also some animated short movies produced by the NHK.

Prettify code bits in this blog
Sun, 30 Mar 2014 13:05:34 +0100
As you may have noticed, I've been trying to update this site a bit this weekend. Apart from drawing some simple emoticons , I also added the "share" buttons, and added more quotes to the top banner.

Today, I have added Prettify, so in case I want to post bits of code, they should be nicely formatted. Here's a test,

 * @return a point sample of a Spherical Harmonic basis function
 *  l is the band, range [0..N]
 *  m in the range [-l..l]
 *  theta in the range [0..Pi]
 *  phi in the range [0..2*Pi]
double SphericalHarmonics::SH(int l, int m, double theta, double phi)

    const double sqrt2 = sqrt(2.0);
    if(m==0) return K(l,0)*P(l,m,cos(theta));
    else if(m>0) return sqrt2*K(l,m)*cos(m*phi)*P(l,m,cos(theta));
    else return sqrt2*K(l,-m)*sin(-m*phi)*P(l,-m,cos(theta));
This code, by the way, is part of my Harmoniker app that you can find in github.

Twitter share button added
Sat, 29 Mar 2014 15:30:57 +0000
Apart from adding a Tweet button to posts, I also fixed (I believe) the problem of the previewed text when sharing in Facebook (and Google+?). I had to rewrite the blog parser completely, so now I can change the meta attributes of the generated page. Let's see how it goes... (Facebook scrapes your page every 24 hours to ensure the properties are up to date. So I guess I'll have to wait)

Share in Facebook or Google Plus
Sat, 29 Mar 2014 09:22:52 +0900
I added +1 and Like buttons to every post, so at least even if I don't have comments in this site, people can share it and comment in their favorite social network. Not that I post much here anyway ...

The only problem I have so far is that the contents of what you share don't seem to preview properly in either Facebook or Google Plus. They don't show the text of this post :( Perhaps they don't like PHP? I also tried adding a meta name="description", but it failed as well

Happy New Year 2014!
Sun, 05 Jan 2014 09:37:29 +0900
Happy new year! The year of the horse in Japan!
I start the year with problems with the app store. I forgot to renew my dev membership, so Snake on a Sphere was removed from the app store. I just renewed my membership today, so hopefully the game should be back online soon.


Previous year