Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolution independent cubic bezier drawing on GPU (Blinn/Loop)

Based on the following resources, I have been trying to get resolution independent cubic bezier rendering on the GPU to work:

GPU Gems 3 Chapter 25

Curvy Blues

Resolution Independent Curve Rendering using Programmable Graphics Hardware

But as stated in the Curvy Blues website, there are errors in the documents on the other two websites. Curvy Blues tells me to look at the comments, but I don't seem to be able to find those comments. Another forum somewhere tells me the same, I don't remember what that forum was. But there is definitely something I am missing.

Anyway, I have tried to regenerate what is happening and I fail to understand the part where the discriminant is calculated from the determinants of a combination of transformed coordinates.

So I have the original coordinates, I stick them in a 4x4 matrix, transform this matrix with the M3-matrix and get the C-matrix. Then I create 3x3 matrices from the coordinates in the C-matrix and calculate the determinants, which then can be combined to create the a, b and c of the quadratic equation that will help me find the roots.

Problem is, when I do it exactly like that: the discriminant is incorrect. I clearly put in coordinates for a serpentine (a symmetric one, but a correct serpentine), but it states it is a cusp. When I calculate it myself using wxMaxima, deriving to 1st and 2nd order and then calculating the cross-product, simplifying to a quadratic equation, the discriminant of that equation seems to be correct when I put in the same coordinates. When I force the code to use my own discriminant to determine if it's a serpentine or not, but I use the determinants to calculate the further k,l,m texture coordinates, the result is also incorrect. So I presume there must be an error in the determinants.

Can anyone help me get this right?

like image 467
scippie Avatar asked Mar 20 '13 09:03

scippie


2 Answers

I think I have managed to solve it. The results are near to perfect (sometimes inverted, but that's probably a different problem).

This is where I went wrong, and I hope I can help other people to not waste all the time I have wasted searching this.

I have based my code on the blinn-phong document. I had coordinates b0, b1, b2, b3. I used to view them as 2D coordinates with a w, but I have changed this view, and this solved the problem. By viewing them as 3D coordinates with z = 0, and making them homogenous 4D coordinates for transformation (w = 1), the solution arrived.

By calculating the C matrix: C = M3 * B, I got these new coordinates. When calculating the determinants d0, d1, d2, d3, I used to take the x, y coordinates from columns 0 and 1 in the C matrix, and the w factor from column 2. WRONG! When you think of it, the coordinates are actually 3D coordinates, so, for the w-factors, one should take column 3 and ignore column 2.

This gave me correct determinants, resulting in a discriminant that was able to sort out what type of curve I was handling.

But beware, what made my search even longer was the fact that I assumed that when it is visibly a serpentine, the result of the discriminant should always be > 0 (serpentine). But this is not always the case, when you have a mathematically perfect sepentine (coordinates are so that the mean is exact middle), the determinant will say it's a cusp (determinant = 0). I used to think that this result was wrong, but it isn't. So don't be fooled by this.

like image 64
scippie Avatar answered Nov 17 '22 15:11

scippie


The book GPU Gem 3 has a mistake here, and the page on nVidia's website has the mistake too:

a3 = b2 * (b1 x b1)

It's actually a3 = b2 * (b1 x b0).

There're other problems about this algorithm: the exp part of the floating point will overflow during the calculation, so you should be cautious and add normalize operations into your code.

like image 26
lymastee Avatar answered Nov 17 '22 15:11

lymastee