Bezier Curves, Loop and Blinn Style

A few days ago, I began to effectively analyze bezier curves, and I came across this method, developed by Charles Peter and Jim Blinn, which seemed very interesting. Be that as it may, after a lot of experiments with their algorithm, I just can't get it to display cubic curves. The squares are beautiful, no problem.

The only resources I have found so far are the following:

GPU Graphics 3 Chapter 25

Curvy blues

Independent graphics curve using graphics hardware

To quickly test testing, I do this in XNA. Basically, I transfer the coordinates of the texture with my vertices to the GPU, apply perspective transformation and use the formula specified in all the articles in the pixel shader to make the final result. Be that as it may, the problem (I think) is how I calculate the coordinates of the texture. Check this code:

public void Update() { float a1 = Vector3.Dot(p1, Vector3.Cross(p4, p3)); float a2 = Vector3.Dot(p2, Vector3.Cross(p1, p4)); float a3 = Vector3.Dot(p3, Vector3.Cross(p2, p2)); float d1 = a1 - 2 * a2 + 3 * a3; float d2 = -a2 + 3 * a3; float d3 = 3 * a3; float discr = d1 * d1 * (3 * d2 * d2 - 4 * d1 * d3); if (discr > 0) { Type = CurveTypes.Serpentine; float ls = 3 * d2 - (float)Math.Sqrt(9 * d2 * d2 - 12 * d1 * d3); float lt = 6 * d1; float ms = 3 * d2 + (float)Math.Sqrt(9 * d2 * d2 - 12 * d1 * d3); float mt = 6 * d1; TexCoord1 = new Vector3(ls * ms, (float)Math.Pow(ls, 3), (float)Math.Pow(ms, 3)); TexCoord2 = new Vector3((3 * ls * ms - ls * mt - lt * ms) / 3, ls * ls * (ls - lt), ms * ms * (ms - mt)); TexCoord3 = new Vector3((lt * (mt - 2 * ms) + ls * (3 * ms - 2 * mt)) / 3, (float)Math.Pow(lt - ls, 2) * ls, (float)Math.Pow(mt - ms, 2) * ms); TexCoord4 = new Vector3((lt - ls) * (mt - ms), -(float)Math.Pow(lt - ls, 3), -(float)Math.Pow(mt - ms, 3)); } else if (discr == 0) { Type = CurveTypes.Cusp; } else if (discr < 0) { Type = CurveTypes.Loop; } } 

Sorry mess, this is just some test code. p1 ... p4 are the control points in world space, and TexCoord1 ... TexCoord4 are the corresponding coordinates of the texture. This is a replication of what the GPU Gems article says.

There are several issues here. First, when calculating a3, we use p2 for both parameters, which, of course, always leads to a (0,0,0) vector and takes the point product of this and p3 will always give us 0. This is pretty useless, so why should they mention this article?

This, of course, will make the wrong one wrong, and we won’t even be able to determine what type of curve it has.

After working a little with this code, I decided to try to do exactly what they did in the paper Loop and Blinn. From this I get something like this:

 public void Update() { Matrix m1 = new Matrix( p4.X, p4.Y, 1, 0, p3.X, p3.Y, 1, 0, p2.X, p2.Y, 1, 0, 0, 0, 0, 1); Matrix m2 = new Matrix( p4.X, p4.Y, 1, 0, p3.X, p3.Y, 1, 0, p1.X, p1.Y, 1, 0, 0, 0, 0, 1); Matrix m3 = new Matrix( p4.X, p4.Y, 1, 0, p2.X, p2.Y, 1, 0, p1.X, p1.Y, 1, 0, 0, 0, 0, 1); Matrix m4 = new Matrix( p3.X, p3.Y, 1, 0, p2.X, p2.Y, 1, 0, p1.X, p1.Y, 1, 0, 0, 0, 0, 1); float det1 = m1.Determinant(); float det2 = -m2.Determinant(); float det3 = m3.Determinant(); float det4 = -m4.Determinant(); float tet1 = det1 * det3 - det2 * det2; float tet2 = det2 * det3 - det1 * det4; float tet3 = det2 * det4 - det3 * det3; float discr = 4 * tet1 * tet3 - tet2 * tet2; if (discr > 0) { Type = CurveTypes.Serpentine; float ls = 2 * det2; float lt = det3 + (float)((1 / Math.Sqrt(3)) * Math.Sqrt(3 * det3 * det3 - 4 * det2 * det4)); float ms = 2 * det2; float mt = det3 - (float)((1 / Math.Sqrt(3)) * Math.Sqrt(3 * det3 * det3 - 4 * det2 * det4)); TexCoord1 = new Vector3(lt * mt, (float)Math.Pow(lt, 3), (float)Math.Pow(mt, 3)); TexCoord2 = new Vector3(-ms * lt - ls * mt, -3 * ls * lt * lt, -3 * ms * mt * mt); TexCoord3 = new Vector3(ls * ms, 3 * ls * ls * lt, 3 * ms * ms * mt); TexCoord4 = new Vector3(0, -ls * ls * ls, -ms * ms * ms); } else if (discr == 0) { Type = CurveTypes.Cusp; } else if (discr < 0) { Type = CurveTypes.Loop; } } 

Guess what didn't work either. Be that as it may, now it seems that this is a little more correct. At least it has the right sign, and it is zero when the control points are positioned so as to form a point. However, I still get the same visual result, except that the curve disappears randomly (the pixel shader formula is always greater than zero) and returns after I moved the control point back to a large square shape. Here is the pixel shader code:

  PixelToFrame PixelShader(VertexToPixel PSIn) { PixelToFrame Output = (PixelToFrame)0; if(pow(PSIn.TexCoords.x, 3) - PSIn.TexCoords.y * PSIn.TexCoords.z > 0) { Output.Color = float4(0,0,0,0.1); } else { Output.Color = float4(0,1,0,1); } return Output; } 

Here's all the helpful information I can think of now. Does anyone know what is going on? Because I'm running from them.

+8
c # xna graphics bezier hlsl
source share
1 answer

I looked at the paper and your code, and these are the seams, you are missing the multiplication by the M3 matrix.

Your coordinates p1, p2, p3 and p4 must be placed in the matrix and multiplied by the matrix M3 before using it to calculate the determinants. eg.

 Matrix M3 = Matrix( 1, 0, 0, 0, -3, 3, 0, 0, 3, -6, 3, 0, -1, 3, -3, 1); Matrix B = Matrix( p1.X, p1.Y, 0, 1, p2.X, p2.Y, 0, 1, p3.X, p3.Y, 0, 1, p4.X, p4.Y, 0, 1); Matrix C = M3*B; 

Then you use each row of matrix C as coordinates for the m1-m4 matrices in your code. If the first and second values ​​of the string are the x, y coordinates, and the last is the w coordinate.

Finally, the texture coordinate matrix must be copied inverse to M3 for example.

 Matrix invM3 = Matrix( 1, 0, 0, 0, 1, 0.3333333, 0, 0, 1, 0.6666667, 0.333333, 0, 1, 1, 1, 1); Matrix F = Matrix( TexCoord1, TexCoord2, TexCoord3, TexCoord4); Matrix result = invM3*F; 

Each row of the resulting matrix corresponds to the texture coordinates necessary for the shader.

I have not implemented it myself yet, so I can’t guarantee that it will solve your problem. This is just what, as I noticed, disappeared from your implementation after reading the article.

I hope this helps, if I'm wrong, tell me, because I will learn it soon.

+7
source share

All Articles