In threejs there is the base curve class, along with a number of built in options that extend this base curve class to create paths in 2D and also very much 3D space. There are a whole lot of use case examples for these curves such as using them to move objects along a path, or use any point along a curve as a point of reference to have an object look at. However there is also using them to make geometry also by getting an array of Vectors for a 3d curve and then quickly creating a geometry with just a position attribute that will work fine with THREE.Points, or THREE.Line. However things can prove to get a little involved when it comes to making the kind of geometry that will work well with THREE.Mesh. There is working out some kind of project that has to do with using curves as a way to create a custom geometry, however maybe a good starting point for this sort of thing would be to just use the THREE.TubeGeometry class.
As the name suggests this built in geometry constructor will take a 3d curve as the first argument along with several other options arguments to create a geometry that is a kind of tube around a curve. As with many of the other built in options for geometry constructors it will also set up normal and uv attributes as well so one can quickly get up and running with this to create geometry around a curve. Also this kind of geometry can often serve as a nice replacement for THREE.Line or THREE.LineSegements as the full range options and features of mesh materials can be used, and also it can help to address the problem where line width will not always work on all platforms.
If you think you might need to learn more about curves in general I have a long, detailed main blog post on curves in which I think I cover most bases with curves in threejs. There is a whole lot to write about with them that I would like to now get into to much with this post as I would like to keep the focus more so with the nature of Tube Geometry alone.
The Tube Geometry class is just one built in option for making geometry that extends the base Buffer Geometry class. What is nice about these built in options is that it can quickly help set up a position, normal, and uv attribute for a geometry. However in some cases these attributes might need to be adjusted, and also some times I might just need to make a full custom geometry from the ground up. There is also a lot to be aware of with both prototype methods of the buffer geometry class as well as values that are nested in a buffer geometry instance such as the buffer attribute class.
The source code examples in this post can also be found in the folder that corresponds to this post in my test threejs repository on Github. This is also where I park the source code examples for all of my other blog posts on threejs as well.
When I first wrote this blog post I was using r152 of threejs and thus was following the style rules that I set for myself for that revision of threejs when first writing these demos. This means that I am using module type script tags, and import maps when it comes to my html code.
For this first section as always I will just be starting out with a few basic examples of Tube Geometry. Nothing fancy with curve paths, and updating the curve objects, and geometry over time. Just some simple, clean starting points.
One has to start somewhere with everything, and when it comes to Tube Geometry apart from the usual objects that are needed for any threejs demo, I also need a curve to pass as the first argument. So with this first demo after creating the scene object, camera, and renderer I then create a curve object. For this curve object I went with THREE.QuadraticBezierCurve3 which is a nice built in curve class extension that takes a start point, end point, and a single control point as arguments.
Once I have a curve to use I can just pass that as the first argument when calling THREE.TubeGeometry to create the buffer geometry that will be used with a mesh object. There are then a number of additional arguments that can be used to adjust how many sections there will be along the tube, as well as for each ring of the tube as well. Other arguments have to do with setting the radius, and also if the ends should be closed or not.
Now that I have a geometry I can use it to create a mesh object by just passing the geometry as the first argument for THREE.Mesh, along with a material as the second argument. For this first basic example I am not doing anything fancy with materials and I am just going with the THREE.MeshNormalMaterial as I find that this is a nice option for just quickly seeing some depth without having to do anything to complex with light and textures. When I made the Tube geometry I went with leaving the ends open though, so I am setting the side option of the material to THREE.DoubleSide.
One major improvement of using tube Geometry over that of THREE.Points, or THREE.Lines is that I can use the Mesh materials and all the various options of such materials. With that said in this example I am making a texture using a canvas element for the map option of the Basic material. When it comes to the code that I am using to draw the canvas it is just a little quick code for making a checkered pattern. I then just pass the canvas element to the THREE.CanvasTexture constructor and I then get a texture. I can then use this texture for options like the map option of the basic material.
Often I will want to not make a tube geometry with just one curve object, but a path of curve objects. So in this section I am going to look into working out a few demos in which I am doing just that.
For this example I started to explore the use of curve paths and tube geometry. Two help make things simple I went with just one type of curve for each child of the curve path which is THREE.CubicBezierCurve3. This means that I will not have to bother checking the type for each child when making a more advanced example where I update the curves and the geometry of the tubes. Also this is a built in curve option where I have two control points to work with rather than just one.
Working out a simple static demo of a Tube Geometry made from a curve path is one thing, but updating the curve path, and also the tube geometry made from the curve path is a whole other matter. This is where things will get a little involved as not only do I need to work out the logic I want to use to update the state of the curve path, but I also need to update the geometry made from the tube Geometry constructor function as well.
The Tube Geometry class is then the only Built in Geometry class that will create a geometry from a curve, well at least a 3d curve anyway. When it comes to 2d curves there is getting into the use of shape geometry, extrude geometry and lathe geometry. However that all might be things that I should get into in another post.