Texture rotation not working for non-square images

When using a non-square image as a texture, we set the vScale of the texture to the aspect ratio so that the image is not distorted. This all works fine. The issue arises when attempting to rotate the texture with wAng. When doing so, the image is distorted by the non-uniform scaling. Here is a very simple playground you can use to see the issue. Slide the wAng value to see the distortion. Specific slide it to PI / 4 which is around .78. Slide the the vScale value to see that no corrective action is possible to fix the distortion.

https://www.babylonjs-playground.com/#T32V41#16

The expected behavior would be that the scaling values rotate along with the rest of the texture.

Waiting for inputs from @sebavan or @Deltakosh to know if we should create an issue in the repo or if it is the expected behaviour.

Yes, thank you. Do you see the distortion when rotating the texture in the playground?

Yes I do see it, it probably comes from the way the transformation matrix is computed here:

I guess it is sort of expected but not a desirable one :frowning: I let @Deltakosh weight on it as this could be a back compat killer.

How can we fix that without breaking back compat ?

This is really central for our way of rendering textures so not an easy one (unless we hide it under a flag)

It is unlikely that someone in the past has actually desired that distortion, right? prepareRowForTextureGeneration seems to be around the correct area where the issue is and perhaps it involves some interpolation between the u and v scale as the rotation changes?

Iā€™m happy to review any PR if you want to give it a try

I already attempted the interpolation and found no vScale can be applied to fix the distortion (as seen in the playground when adjusting the vScale). Thatā€™s why I created the bug report, because I couldnā€™t find any corrective action to take on my end.

Conceptually, if you look at uOffset and vOffset, they both follow the axis of rotation (after wAng changes, the offset axes also rotate). Then, with uScale and vScale, they exhibit different behavior where the axes donā€™t update with rotation changes.

Yeah I feel this is maybe something where we want to rotate on wAng at then end?

Looking at this code in getTextureMatrix

this._prepareRowForTextureGeneration(0, 0, 0, this._t0);
this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1);
this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2);

and thinking perhaps the matrix there

[0, 0, 0]
[1, 0, 0]
[0, 1, 0]

Needs to be transformed by wAng before being used.

In the following playground you can see that I roughly altered getTextureMatrix around line 78 so that it Lerps between the 0 and 1 in that matrix based on wAng. At a specific rotation (specifically ~1.2 radians), it does actually remove distortion. Overall though it doesnā€™t work right. I think fundamentally I donā€™t understand what that matrix is and how it needs to be transformed.

https://www.babylonjs-playground.com/#T32V41#19

well I feel like it should be applied at the end with a 0,5/0,5 center

Applied to texture._cachedTextureMatrix right before the return? Do you know what operation to call on it?

Adding @Evgeni_Popov to see if he can help as Iā€™m swamped

Will have a look at it tomorrow.

Thank you @Evgeni_Popov and @Deltakosh

This PR should do what you want:

It adds a homogeneousRotationInUVTransform property to the texture which is false by default to avoid breaking changes.

This PG will work once the PR is merged: https://www.babylonjs-playground.com/#T32V41#22

1 Like