0
$\begingroup$

New to Blender last month, I had mapped a rectangular image onto a sphere using Cycles nodes. I noticed that Blender put the seam (where the left and right edges of the image meet) on the front of the sphere. I wanted the seam in the back. Rather than rotate the sphere, I decided to rotate the texture around the sphere.

First I tried a simple Z-axis rotation of the texture. The result was worthy of Salvador Dali — not at all what I had expected.

Next, I tried shifting the texture by 50% of its width in the +X direction and changing the Image Texture node's extrapolation option from Clip to Repeat. (See the picture below.)  The result was not as distorted as the previous attempt but still nothing like my goal.

Obviously I was making some bad assumptions. So I set out to figure out exactly how transformation of textures works in Blender. I built the test bed pictured. The Generated output of a Texture Coordinate node was fed into the Vector input of a Mapping node. That Mapping node's output was fed through a second Mapping node (to allow multiple transforms in an unambiguous order) and then to the Vector input of an Image Texture node. The Color output from the Image Texture node traveled through a Diffuse BSDF shader node to the Material Output node.

I drew a test picture with distinctive regions, edges, and corners so I could see what was getting mapped where. I then projected the image onto five test objects (cube, rectangular prism, sphere, cylinder, and meta cube) in various ways by adjusting the transforms in the Mapping nodes and the Image Texture node projection options. I also did a simple Flat projection of the image onto a rectangular plaque in the foreground for reference.

Blender window with scene, test image, and nodes

I started with simple Flat projection and tried various multiple transforms. Once I had developed a model of what Blender was doing and tested it on the Flat projection I went on to the Tube and Sphere.

So how was my original thinking wrong? It took a long time for my experiments to yield enlightenment because of side issues mentioned in my answer below. Hopefully someone else new to Blender can glance at this question/answer and avoid losing the time I wasted.

$\endgroup$
1
$\begingroup$

I eventually came up with a reasonable model for the mechanism. But along the way I was confused by Blender's order of transforms and its display of materials.

Projection Model

My basic problem was that I was not considering exactly where the object and the texture are located in what I will call "texture space". Conceptually the object and texture are placed into texture space and the surface of the object is colored according to where it intersects the projected texture.

As a starting point for the texture mapping the object and the image are made "the same size". The object's bounding box (a rectangular prism in its local coordinates) is scaled in the X, Y, and Z directions to create a cube one unit on a side. The cube with its distorted object is placed in the first octant of the 3D texture space with its lower left front corner at the origin and its upper right back corner at (+1,+1,+1). The rectangular image is scaled in the X and Y directions to become a square one unit on a side (usually making its pixels rectangular rather than square).

For a Flat projection the texture square is placed into the X-Y plane on the bottom face of the object cube. The lower left-hand corner of the image is at the origin and the upper right-hand corner is at (+1,+1,0). Each pixel of the texture square projects as a perpendicular rod (rectangular in cross-section) that extends parallel to the Z-axis towards infinity in both the +Z and -Z directions.

The problem that arises with rotations is that the axes of rotation are the texture space coordinate axes which pass through the texture space origin, not the more convenient axes at the centers of the object and texture. So if you want to rotate either the cube or the texture around its central Z-axis you have to

  1. Translate its center to the texture space Z-axis.
  2. Perform the rotation around the texture space Z-axis.
  3. Translate the center back its original position.

With the Tube projection the image has been wrapped around a vertical (parallel to the Z-axis) cylinder of irrelevant radius one unit high centered on (0.5,0.5,0.5). Each pixel of the image projects horizontally from the center of the cylinder outwards in an infinite pie-shaped wedge one pixel high passing exactly through its rectangle on the surface of the cylinder.

The Sphere projection wraps the image around a sphere of irrelevant radius centered at (0.5,0.5,0.5). Each pixel of the image projects from the center of the sphere outwards to pass exactly through its rectangle or triangle on the surface of the sphere.

Suzanne stuffed into the cube above flat with cylinder and sphere surrounding

So rotating the object or the texture about the Z-axis without the extra translations separates the projected texture and the object, grossly distorting their intersection.

Order Of Transforms

The first diversion on the way to the texture mapping model was figuring out the order in which Blender was executing the transforms from the Mapping nodes.

It turns out that within a Mapping node the transforms are essentially performed right to left. The scaling is performed first. Then the rotations are performed in Blender's default Euler XYZ order. Finally any translations take place.

However the order in which the chain of Mapping nodes is applied depends upon the choice of Texture vs. Point set in the Mapping nodes. (Assume that all Mapping nodes use the same option and ignore Vector and Normal for present purposes.)

With the default Point selection the Mapping nodes describe how the object is transformed in texture space while the image projection remains fixed. The chain of Mapping nodes is applied left-to-right; the leftmost Mapping node is applied first, and each Mapping node transforms the result coming from the node on its left.

With Texture selected the Mapping nodes describe how the texture is transformed in texture space while the object in its cube remains fixed. The chain of Mapping nodes is applied right-to-left; the rightmost Mapping node is applied first, and each mapping node effectively transforms the result from the node on its right. (This is the effect, not how it is actually implemented.)

Point and Texture chains create net transforms which move the object cube and the texture relative to each other. Choosing between the two approaches is a matter of convenience for the user.

Display Of Materials

The second diversion on the way to the texture mapping model involved accurate display of the mapped texture.

The Preview display in the Material section of the Properties Editor is your best friend. If you are doing transparency or texture mapping you need to have it active.

It did not dawn on me for a while that the 3D View was lying to me about materials. I naively assumed that if I set the 3D View's "Viewport Shading" to Material I would see the actual material. In fact the only way to guarantee that is to select Render from the "Method to display/shade objects in the 3D View:" (Viewport Shading) list. The limitation is perfectly understandable in terms of computation time; using Render can be very slow so Material can be expected to compromise.

But one result is that an Image Texture node set for Clip will show in the Material selection for the 3D View as if Repeat has been chosen. That was confusing during the early tests.

The other limitation on the Material shading arises directly from computational expense. The non-Rendered display methods for the 3D View cannot display some materials (e.g., transparency) on any object. And they cannot display any material on some objects (e.g., a meta).

Moral

Do not make assumptions about how Blender works without taking the time to test those assumptions.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.