The basic material options in threejs
In threejs the basic material is the default material that is used when creating a mesh object if a material is not specified as the second argument after giving the geometry to use. It is still a decent material if I want to just skin a mesh with a texture, and do not want to do anything special involving the reflection of light. There are also some other use cases that will work okay with the basic material such as using vertex colors with a geometry.
Still the basic material supports a few options when it comes to texture maps, there is the basic color map, but there is are a few more options such as an alpha map for example. Still there are even more options when it comes to texture maps with other materials that will respond to light sources such as the standard material which I have found to be my usual go to material.
So today I thought I would continue expanding my collection of posts on threejs by writing a post on the basic material, and what it has to offer when making a threejs project. This will involve a few simple hello world type examples, but I will also need to get into at least a few examples that involve the use of textures.
What to know before reading up more on the Basic Material
Learn a thing or two about canvas elements, or figure out the texture loader
Vertex colors, uv mapping, and other Buffer Geometry topics
Another option for having something other than a mass of color to look at would be to add a color attribute to the buffer geometry that is being used if there is not one in place to begin with. Also if using a texture there is adjusting, or creating the UV attribute that is used to map the 2d texture to the 3D Object.
Be aware of what the full options are with materials
You might also want to check out my post on threejs materials in general for more info on the various material options in threejs. The basic material is fine when I just want to skin a geometry with a texture, but not do anything to far beyond that. There are a whole lot of other materials that might be a better choice for other situations though, for example the depth material might be a good choice when it comes to figuring out what the values should be for the near and far values of a camera. If one will want to add one or more light sources to a project these days I like to go with the Phong material for that.
Source code is up on Github
The source code examples that I am writing about in this post can also be found on Github. This is also where I place all the source code examples that I have made for my other blog posts on threejs as well.
Version Numbers are impotent with three.js
When I first wrote this post I was using version r91 of threejs and the last time I came around to do some editing I was using r146. Sense then not much has changed when it comes to using the basic material. Still code breaking changes are introduced all the time into threejs as new revision numbers come out, so always be mindful of the versions of threejs that was used when looking at threejs examples on the open web.
1 - Some basic exmaples that make use of the basic material
For this section I will be looking at a few basic examples that make use of the mesh basic material as a way to skin the geometry of a mesh object. One of the major problems with the Mesh basic material is that one will end up with a solid mass of color for any geometry unless one makes use of some option to address that. Making use of a light source is out of the question as the basic material does not support that. There is making use of a texture but that is something that I will like to leave to a more advanced section in this post. So here I will be starting out with just a few basic getting started examples, and then maybe some options that address this issue of having a solid mass of color that does not involve a texture.
1.1 - The Basic Material is the default material
The Basic material is the default material used for a mesh object. So if I create a mesh object by calling the THREE.Mesh constructor function and just give a geometry by way of the first argument, but give no material as the second argument the result will be that the mesh will use the basic material. This can be confirmed by doing just that creating a mesh with a geometry and no material, and then checking the type property of the materials property of the mesh object.
1.2 - Setting the Color of the basic material
Typically I will want to use the Mesh Basic Material constructor to create an instance of basic material and pass that as the second argument when making a mesh even if it is the default material anyways. When doing so I can pass an options object to the mesh basic material constructor which can have one or more options that I would like to set. One such option would be to set a solid color for the material, for thus there is the color option. The color should follow the syntax that I have in the example below, or the THREE.Color constructor can be used to create the color as well.
This results in a cube that is sold red all over, but it looks like just one blob of red rather than a cube. This is often not a desired result as there is no sense of depth on the cube. If I add a light source of some kind nothing will change because the basic material of course does not work with light sources. This alone is one of the major reasons why I often like to go with the standard material so I can use a point light, directional light, or one of many other options for light sources to get some sense of depth that way. However when it comes to sticking with the basic material there are of course some options here. If I do not want to use a solid color, and just have a blob of color, then a texture can be used with the map property. A texture can then be used as a way to get some sense of depth then.
1.3 - Using vertex colors
One option to go about having some depth without using a texture would be to make use of vertex colors. If you are lucky there will be a color attribute set up all ready for the geometry, but more often then not one will need to define what that is. The process of doing so is a little involved but I will be quickly touching base on a fairly simple example here.
For this example of vertex colors and the mesh basic material I am getting a reference to the position attribute of the box geometry. Once I have that I can use the count property of the position attribute to know how many color values to create. So for the value of the count property of the position attribute I will want to push a red, green and blue color channel value. Once that is done I ca create the color attribute by calling the THREE.BufferAttribute function and pass the array of color channel data making sure that it is a Float32Array. I will also want to pass the number 3 as the second argument for the attribute as this is a situation I which I have three values for each item. I can then add my color attribute to the box geometry by calling the set attribute method followed by the string color, and then the color buffer attribute I just made.
Now that I have a geometry with a color attribute I can set the vertex colors option of the basic material to true, and the n end result will be random vertex colors.
1.4 - Using Geometry Groups and an array of Mesh Basic material objects
Another option would be to use not one but an array of materials. When doing this I will want to make sure that I have a groups property set up for the geometry. When it comes to the box geometry this is all ready set up for me, I just need to adjust the material index values as needed. If the groups property of the geometry is set up the way I want it then I just need to pass an array for materials where each material can be a basic material, with a differing color.
1.5 - Using Lines as a child object of the mesh
Yet another option do have something other than a big blob of color in the scene would be to create a Line and then add that as a child for the mesh object. The same geometry that is used for the mesh can also be used for the Line or LineSegemnets Objects, but often I might want to create a new geometry from the geometry by using THREE.EdgesGeometry.
The use of lines might work okay on most platforms, but I have found that the line width will not work on all platforms. For this reason I might want to go with other options that I have outlined in this section, mainly just using a texture, and working out what needs to happen in terms of uv mapping.
2 - Color Maps and the Basic Matreial
The Basic Material will not work with any light sources that may of may not be in the scene, and although there may be a number of ways to add some depth to the faces of a geometry used with the basic material, the typical way is to use the map option. Although in some cases one might be able to just add a texture to the map option and be done with it, for the most part there are a few more things that will need to happen also. The main thing that comes to mind with this would be the UV attribute of the buffer geometry that is used. Simply put the UV attribute is what is used to define what parts of a 2d texture will get mapped to a 3d object.
So then in this section I am going to want to go over at least a few examples that have to do with using the map option of the basic material, as well as some closely related topics such as UV Mapping.
2.1 - Adding a color map texture to a basic material in threejs using canvas
To create a texture with canvas I am going to want to create the canvas element using the document.createElement method and then also get the 2d drawing context from that canvas element by way of the get context canvas prototype method. Getting into every little detail about the 2d drawing context with canvas is of course beyond the scope of this post. However I will start out with a basic texture where I am just drawing a circle and square on the canvas element. Once I am done drawing to the canvas element I can use the THREE.CanvasTexture constructor to create a texture with the canvas element. The resulting texture created with that constrictor can then be used as the value for the map value of the material.
I have written a post on using canvas as a texture in which I covered this in further detail, but the basic idea is there.
2.2 - UV Mapping and setting images for each side of a cube using a color map and the basic material
I have made a number of threejs project examples that I write about in blog posts such as this one, and one of them has to do with the mutation of the uv attribute of a Box geometry. The reason why I bring this up is because often one can not just simply create a texture by some means and then add it to the basic material by way of the map option and be done with it. There is the matter of the UV attribute and adjusting that to work with a texture. In many of these examples thus far I am working with a Box Geometry, and by default the UV attribute is set up to use all of the texture for each face of the box. More often than not this will work fine, but if I want to use differing parts of a texture for various faces of the cube then I will need to mutate the UV attribute.
3 - An Alpha map with the Basic material
One more quick example of the basic material in action for now until I come around to edit this post once again at some point in the future. So the basic material is a bit limited in terms of the options when it comes to texture maps, but there are still a few to chose from, and getting into all of them might be beyond the scope of this post. Yet again maybe not, in any case I will need time to work out some more basic examples of each of the features of the basic materials when it comes to texture maps. However for now I think I will write about one more texture map option with the basic material when is an alpha map.
An alpha map is a way to apply a texture that does not change color like the color map example that I coved above, but what it does do is apply a texture that will effect the transparency of the mesh. When using the alpha map it is important to make sure that the transparent boolean of the material is set to true. In addition to that I might also want to play around with the global opacity of the material.
For this example of an alpha map I once again used a canvas element as a way to create a texture. However when it comes to alpha maps I want to make sure that the resulting image is in gray scale. The levels of black and white are what are used to set the range of opacity and transparency.
The basic material is just as the name suggests, there are other materials to use in three.js if you want to do something more advanced but the basic material gets the job done when it comes to simple projects. There is of course the Lambert material that is a good choice if you want to do something involving light in a real time environment. There are of course many other materials to chose from when working with a mesh as well that might have better values to offer when it comes to how things look compared to how much resources they eat up.