I wanted to play around with some shaders recently so I was looking for simple things to implement. One of the nicest ways to get started in a new graphics framework is to get some fractals going—so this is what I did.

We first require some GLSL magic to make the Mandelbrot fractal happen:

```uniform int iterations;

uniform highp vec2 centre;
uniform highp float scale;

varying highp vec2 texture_out;

void main()
{
vec2 z;
vec2 c;
c.x = scale * ( 3.0 * texture_out.x - 2.0 ) + centre.x;
c.y = scale * ( 2.0 * texture_out.y - 1.0 ) + centre.y;

z = c;

int i = 0;
for(; i < iterations; ++i)
{
float x = z.x*z.x - z.y*z.y + c.x;
float y = z.x*z.y + z.y*z.x + c.y;

if( x*x + y*y > 4.0 )
break;

z.x = x;
z.y = y;
}

vec4 color = vec4(0.0);

if(i < iterations - 1)
{
color.x = sin(float(i) / 3.0);
color.y = sin(float(i) / 6.0);
color.z = cos(float(i) / 12.0 + 3.141 / 4.0);
}

gl_FragColor = color;
}
```

Basically, I am filling the texture coordinates with colours, based on the number of iterations it took for the series to reach the desired norm of 4.0. The `scale` and `centre` parameter exist only for the purpose of modifying the view within the controlling application.

```uniform int iterations;

uniform highp vec2 c;
uniform highp vec2 centre;
uniform highp float scale;

varying highp vec2 texture_out;

void main()
{
vec2 z;
z.x = scale * ( 3.0 * texture_out.x - 2.0 ) + centre.x;
z.y = scale * ( 2.0 * texture_out.y - 1.0 ) + centre.y;

int i = 0;
for(; i < iterations; ++i)
{
float x = z.x*z.x - z.y*z.y + c.x;
float y = z.x*z.y + z.y*z.x + c.y;

if( x*x + y*y > 4.0 )
break;

z.x = x;
z.y = y;
}

vec4 color = vec4(0.0);

if(i < iterations - 1)
{
color.x = sin(float(i) / 3.0);
color.y = sin(float(i) / 6.0);
color.z = cos(float(i) / 12.0 + 3.141 / 4.0);
}

gl_FragColor = color;
}
```

Note that the differences between the shaders are minuscule at best.

# Using Qt 5 to put it together

Putting the fractals on the screen then turned out to be a rather easy exercise with Qt 5. Using a `QGLShaderProgram`, I only need to render a quad onto the screen, bind the appropriate shader, and we are done. Check out the code on GitHub for more details.

# Screenshots

Click to see the screenshots in their original resolution.

Posted late Sunday evening, May 31st, 2015 Tags:

I just had the privilege of watching lots of great talks at the EuroVis 2015 conference. Since giving a talk about your research is a common occurrence, even for undergraduate students, I thought it worthwhile to think a little bit about what makes a talk truly great.

It goes without saying these are my personal opinions. They reflect the ways in which I perceive a talk. Still, here are some rules that good talks tend to adhere to:

1. Preparing a good talk takes time. You should figure that into your calculations. To prepare a good talk, several iterations are probably required. Test it on your friends, your colleagues, your family, and so on.
2. Avoid last-minute changes. Been there, done that. Try to avoid it unless your colleagues or supervisor have some specific criticisms about your slides that can be fixed. Do not do it on your own.
3. Know your audience. Your audience determines the level of specificity your talk should have. An all-expert audience can take more technical details than a more general audience. If in doubt, follow the rule of thirds: Prepare one third of your talk for the experts, one third for your peers, and one third for the general listener.