How to create textures for Three.js SphereGeometry using Blender

Franky Hung
Geek Culture
Published in
7 min readJan 4, 2023

--

This is probably a beginner’s common question: What type of images should we use to correctly texture spheres in Three.js? I bet we’ve all tried in the beginning to just spam a square image of probably a flower or a person onto a 3D sphere and “hope” it some how works 😂. And of course we found that the texture came out all stretched and ugly…

Now that I know a way to create textures for spheres such that it does not look distorted, it isn’t very straight-forward. So I think it’s nice to share with all of you Three.js devs/to-be devs how I do it. Please leave comments if you have other or better ways of doing it!

Restating the Problem

Let’s start with a simple scenario: you want to apply a golf ball texture to a SphereGeometry. If you google “golf ball texture” and pick one to “clothe” it onto your sphere, you’ll most probably have a distorted golf ball instead:

Left: a freepik.com image used as the sphere texture. Right: note how the image gets really distorted at the poles

So how do you circumvent the problem of uneven distortion, especially at the poles?

Equirectangular is your friend

If you know what “Equirectangular” means and how it works on texturing spheres, you can skip this section and read the next section on how to generate an equirectangular texture using Blender.

If you have come across one of the example scenes hosted on threejs.org, you might already have the key to this problem.

The example demonstrates a perfectly looking golf ball in the bottom left.

Although it does not directly apply a color or “albedo” texture onto the sphere, as it uses a normal map of a golf ball instead, it’s basically the same idea in this context.

Notice how this normal map image is different from our previously “Google Image” random pick:

https://github.com/mrdoob/three.js/blob/master/examples/textures/golfball.jpg

The holes are relatively even at the center but start to stretch horizontally nearing the top and bottom. This is called an “Equirectangular Image”. This term comes from how we project the Earth map onto a 2:1 image, see https://en.wikipedia.org/wiki/Equirectangular_projection for more in-depth explanation.

Let me explain how this works first by giving a brief overview on how Three.js maps textures onto SphereGeometry .

Three.js creates a default UV mapping for factory geometries. Let’s try applying a UV testing texture onto a vanilla SphereGeometry to figure this out. Originally the UV test texture looks like this:

U value increases from left to right, while V value increases from top to bottom

The top-left corner has a UV coordinate (0,0), while bottom-right (1,1).

Below are the top and bottom of a sphere dressed with this UV test texture.

Left: “North pole” of the sphere, Right: “South pole” of the sphere

You can see that the top of the sphere has V value at 0 while the bottom of the sphere has V value at 1. The U value runs horizontally but since a sphere is round, the right edge of UV map is stitched to its left edge, that’s why you can see the U value goes from 0.9 back to 0.0 in the above images.

So whatever image you apply as a sphere texture using this method, the top-left of the image would be assigned with UV (0,0) while bottom-right of the image with UV (1,1).

When the image is wrapped onto the sphere, the pixels will be cramped together at the poles. That’s why you see the golf bumps are much wider near the poles; because after the squashing, those bumps will come out just fine in the end result as you see in that Three.js example.

So when you’re looking for viable sphere textures, add in the keyword “equirectangular”!

Generate an Equirectangular Texture using Blender

Okay, here comes the meat of this article.

What if you can’t find a suitable equirectangular image online, or you actually need a custom-made pattern for your sphere? Well, you can do that in Blender!

We’re going to create a sphere in Blender with a custom material. Then we’ll bake that material out with the sphere’s default UV mapping into an equirectangular image. Let’s get started!

In a brand new Blender project, delete the default cube, and add a UV Sphere:

SHIFT-A to open the add menu

After you’ve added the sphere, expand the bottom-left adjustment menu to make the sphere more high-res by having 200 segments and 100 rings:

A more high-res sphere helps us get smoother generated textures in general.

Next go to the Shading tab, and add a new material:

You can just leave the material name unedited as Material.001

Then in the area below you would see default nodes being added(“Principled BSDF”, “Material Output”). Press SHIFT-A again to bring up the add menu and search for “Noise Texture”, which is one of the many texture nodes you can play with in Blender.

Join the “Color” outlet of the Noise Texture to the “Base color” inlet of the BSDF node. Then you should see some colorful noise pattern appearing on the sphere!

You can make sphere textures in a LOT of different ways, check this cool YouTube vid out and you’ll understand how much freedom you have in tweaking these textures. Let’s assume this simple noise texture is the texture we want to apply in our Three.js sphere for now. For the next part, we’re going to “bake” this texture into a savable image.

In some empty space beside the existing nodes, SHIFT-A again to add in the “Image Texture” node:

This Image Texture node doesn’t need to be connected to anything

Click New in the Image Texture node and name it something meaningful.

Since we’re creating a 2:1 equirectangular image, let’s up the width to 2048px. Press OK.

Then on the right-hand side panel, go to the “Camera” icon tab(which is “Render Properties), pick “Cycles” as the Render Engine as this is what people normally use for textures baking.

Then scroll down and expand the “Bake” section to apply the following settings:

  • Bake Type: “Diffuse”, which means we’re just baking the color out as the image texture
  • Contributions: only check “Color” as we don’t need lighting or other stuff to be contributed to the output texture
  • Target: select “Image Textures” as we’re going to store the baked output to the image instance we created previously at the Image Texture node.

Before you click the “Bake” button here, there’s a very important step you CANNOT MISS!

You need select both the Sphere object in the scene and the Image Texture node. Just clicking on them once will get them selected each.

Notice that the Sphere is highlighted in yellow and the Image Texture node is highlighted in white, that means they are selected

With both the sphere and the image texture node selected, you can safely click “Bake” in the side panel. It will take some time probably under a minute.

Why do we need to actively select the Image Texture node? Because that’s mentioned in Blender docs:

Baking requires a mesh to have a UV map, and either a Color Attribute or an Image Texture node with an image to be baked to. The Active Image Texture node or Color Attribute is used as the baking target.

The sphere in the Blender scene already comes with a default UV map so first requirement is already done.

After the progress bar at the bottom is complete, go to the “Rendering” tab at the top, then choose the noise texture image in the dropdown. Voila! The displayed image is the rendered result:

Now you can save this result as an image somewhere on your computer:

Applying this texture onto a Three.js SphereGeometry will give you an undistorted sphere:

Well…this doesn’t look convincing enough😅. Let’s make another example using “Voronoi Texture” node in “Minkowski” mode:

The rendered image texture from Blender

And how it looks when applied to the Three.js sphere:

Further “Reading”

These videos helped me understand the texture baking process in Blender better:

--

--

Franky Hung
Geek Culture

Founder of Arkon Digital. I’m not a code fanatic, but I’m always amazed by what code can do. The endless possibilities in coding is what fascinates me everyday.