1 Answer
1

You need normal and binormal for each point in your curve, as illustrated in this picture as n and b:

You can calculate the tangent t from the curve, it's the first derivative. If the derivative is not available, you can approximate it with a direction vector from previous sample point to the next one. Binormal is simply a cross product from tangent and normal. The only problem is how to define the normal. Normals can be arbitrary, but it should always be on the "same side of the curve" so that adjacent vertices in the tube are close to each other and not jumping around. Four ways to calculate the normal comes to my mind.

Manually define also normals for each control point in your curve and interpolate from those.

Define an up-vector or something similar in the world and calculate the normal from cross product of the up vector and tangent. In this case the curve must not go directly upwards. I used this myself recently, and it seemed to work well.

Choose the first normal arbitrarily and calculate the next normals always so that it is as close to the previous as possible.

If your curve lies in a plane, which is the case for a circle, you can use the plane normal directly.

When you have the normals and binormals, you can generate the tunnel vertices simply with a linear combination of those vectors.

Texture coordinates are simple to calculate if your points are evenly distributed or the stretching is not a problem. If those are a problem, you need to numerically first calculate the length of the curve and then also numerically find the correct texture coordinate for any given point in the curve. This gives the u part. v part is simply i / pointCount in the code above.