Tuesday, May 25, 2010

MikeTracker


MikeTracker is a small project I've been developing these days. It's a tracker, just like M4G, but for PC. It's also uglier. It uses the FMOD library (great lib!) and Allegro, as usual.

Sunday, March 14, 2010

MkPerfMon

MkPerfMon showing CPU idle time.
MkPerfMon is a test program for the PDH API in Windows.

Tuesday, March 2, 2010

Raytracing - Part 1


A raytracer is a program which creates images tracing rays from the camera to the scene. It can handle easily things that are described with mathematical methods, it's capable of creating photorealistic images. Unfortunately, it's (often) a slow method. Examples of raytracing include Pixar movies, POV-Ray...

The algorithm is simple: you have to trace a ray for each pixel on the screen. If a ray touches a shape, then calculate lighting for that point and plot it. It's simple, but you need to code intersection testing code for each shape you want to render (spheres, planes...). Sphere-ray intersection testing code is one of the easiest to code. So, the main loop for a raytracer is:

For each point:
Trace ray and test intersection.
If it exists, calculate lighting and plot point.


You can use orthographic projection for the ray: set the ray's origin to the point, and set the direction as an unit vector pointing forward.

The formula for testing line-sphere intersection is:

d: distance
l: direction of the ray (normalized)
o: start position of the ray
c: sphere center
r: sphere radius

d = (l * c) +- sqrt( (l * c)2 - c2 + r2 )
If the value under the root is less than zero, the ray doesn't intersect the sphere.
If the value is greater than zero, there are two intersection points (using +-):
p = o + d*l


This formula is easy to code. I'll handle lighting in part 2.

Tuesday, February 23, 2010

Starfield


The starfield effect is a popular effect, present in a lot of demos. It's easy to code and optimize.

A starfield effect consists of a lot of 3D points, that are animated and projected. The initial position of the stars is usually random. After projecting each point, you decrement the Z coordinate of the point. If the point goes off-screen, the point needs to be recreated.

To project a 3D point, use this formula:

projected x = x / z
projected y = y / z


Create an array of random points. After projecting each point, decrement its Z coordinate. If Z becomes a negative number, or the projected point goes offscreen, calculate another random point. You should scale/translate the projected point.

When you plot the point you can apply different effects, like antialiased particles, different velocities, motion blur, lines or circles instead of pixels...

Tuesday, February 9, 2010

Metaballs


The metaball effect is a famous demoscene effect. It's a cool effect, and it's easy to optimize.
The theory is pretty simple: for each ball, you evaluate the value of a function for a given point, and add it to a variable. If it's over some threshold, then you can plot that point. The function is usually:

P: center of the metaball
S: screen point

f(S, P) = 1 / (S - P)2
For each metaball add f(S, P) to a variable (P: current ball center)


It's very easy to compute this function for each metaball. Howewer, this function is slow, due to the division. For this reason, you must find an alternate function. Another possible function is:
f(S, P) = (1 - S - P2)2

You can erase the square root, due to this:
sqrt(x)2 = x

So, the final formula is:

r = (Sx - Px)2 + (Sy - Py)2
f(S, P) = (1 - r)2


This formula is faster, but not fast enough. However, there's another trick you could do. Most of the space in the screen won't be covered by the metaballs, so you can change the code to scan for metaballs (each rectangle in the image, for example), instead of scanning each pixel of the screen.

Monday, February 8, 2010

Mandelbrot Fractal - Part 3


In my last post I said I was going to show the fractal with colors, and here it is! In this post I'll describe colors in the Mandelbrot fractal.

In my last post I wrote some pseudocode you could use to draw the fractal. In the pseudocode I told you to count the number of times you use the formulas. That's an index for your pallete. You should be able to implement that easily.

If you draw it, though, you'll notice a problem. You can see "banding" in the fractal. No matter how high your iteration limit is, the banding will still be there. You can fix this by changing your formula. Up until now you were doing something like this:

i: index into pal
cnt: iteration counter

i = (pal_size * cnt) / limit
plot pallete[i]


The algorithm should be similiar to that. To eliminate banding, replace the algorithm to this:

i: index into pal
cnt: iteration counter

(calculate iteration formulas 4 more times)
cnt = cnt + 5 - ( log(log(|z|)) / log(2) )
i = (pal_size * cnt) / limit
plot pallete[i]

If you test it using these formulas, banding should be gone (mostly). Alter your pallete until you get something you like.

Sunday, February 7, 2010

MK-Hextiler


This is MK-Hextiler, an enhanced version of Hextiler (a program we use at NSN). It uses the Agar library.

Thursday, February 4, 2010

Mandelbrot Fractal - Part 2


This is the follow-up to part 1. I'm going to continue the explanation from part 1 and describe some initial pseudocode. Beware: this pseudocode is slow. I'll probably handle optimization in a later post.

In my previous post I gave you two formulas that describe the Mandelbrot set :

|z| > 2
z = z2 + c


I also told you what z and c were (complex numbers), and how c relates to the screen point.

First of all, I'm going to describe 3 basic operations with complex numbers. You'll use these to calculate the formulas.

a and b are complex numbers, where .real is the real part, and .imag is the imaginary part.

(a + b).real = a.real + b.real
(a + b).imag = a.imag + b.imag

(a * b).real = (a.real * b.real) - (b.imag * b.imag)
(a * b).imag = (a.imag * b.real) + (a.real * b.imag)

|a| = sqrt( (a.real * a.real) + (a.imag * a.imag) )

Be careful with multiplication: the imaginary part depends on the original real part. This means, save the real part in a temporary variable! It drove me crazy when I first programmed the fractal.

In my previous post, I told you the Mandelbrot set is evaluated using a iterative process: if the condition (|z| > 2) is false, try again, until the counter reaches the limit, or the condition evaluates to true. That counter is going to be important in the process, since it'll determine the final color for the point. I'll refer to it as i.

Knowing this, we can write down some pseudocode, like this:

i = 0
limit = 20

z.real = 0
z.imag = 0

c.real = x
c.imag = y

while i < limit then
- if sqrt( z.real2 + z.imag2 ) > 2 then
-- plot as white
-- break
- z = z2 + c
- i = i + 1

If you plot that code, using C, you'll notice two things:
  • It's ugly.
  • It's slow.

It should look like the photo, if everything ia correct. The photo fractal uses limit=50. It's ugly, but it changes dramatically when you add color. I'll address that in the next part.

Tuesday, February 2, 2010

Mandelbrot Fractal - Part 1

I'm going to describe the Mandelbrot fractal, the most beautiful fractal that I know. I assume you have experience with complex numbers (addition, multiplication...).


First of all, what is the Mandelbrot fractal? It's a set of points. To draw the fractal, you must plot every point that is in the Mandelbrot set. The Mandelbrot set is defined using this formula :
z = z2 + c
|z| > 2

where z and c are complex numbers and c is the point you are testing, such as : c.real = x, c.imag = y.

If the condition is true, the point is in the set. If it isn't true, you must iterate using the first formula. If, after a maximium number of iterations, the condition is still false, then the point isn't in the set.

Tuesday, January 26, 2010

Plasma effect


I'm going to describe my version of the popular plasma demoscene effect. There may be another way of doing it, but my version works.

The basic effect uses an index into a pallete, which is defined using a sine based equation. The index depends on two variables (x and y). These are the coordinates of the screen point being evaluated. Example:

idx = sin((PI * x) / 45.0f) + sin((PI * y) / 90.0f);

45 and 90 are just values I've chosen randomly. Change them to alter the plasma. To plot this in screen, do this: for each point in the screen, apply the code. Use idx as an index into a greyscale pallete. There is a problem : it's static. The effect doesn't move. But don't worry, because it's very easy to animate! Change the first formula to:

idx = sin((PI * x) / 45.0f) + sin((PI * y) / 90.0f) + sin((PI * i) / 180.0f);

There's a new element in the formula (sin((PI * i) / 180.0f)). There's a new variable in it (i). If you increment that variable, the effect will animate. You could increment it after a screen draw.

Tuesday, January 19, 2010

M4GTracker


Smiker and I are working in a tracker for GBA, known as M4GTracker. It's popular in the chiptune community, because it's one of the first trackers for GBA. We are currently redoing the UI system, using artwork from iLKke. You can find the link here: http://8bitcollective.com/forums/viewtopic.php?id=13641&p=1.