Author Topic: Equirectangular Distortion  (Read 7095 times)

So I'm trying to build a spherical distortion function, because I have a "Proceduaral Ball" and I want to wrap a procedural texture of dimples (Golf) or Nubs (Basketball) or scratches or seams (Soccer) around the ball. Except at the polar coordinates it gets pinched.

So I found a couple of threads that illustrate the idea:

And the Math Behind projections :

But I can't quite put my finger on if doing a FX Map is the right pathway, as it doesn't deal with value sampling and the "Math" of how to distort the image, but the Pixel Processor has no concept of where on the map it is currently.

Someone maybe suggest a workflow, and I'll share the Function with everybody, once I get it working.

I don't have the answer for this (although it's a nice challenge), but I am convinced that if there is a way to achieve this, it wold imply pixel processor.

I'll add this to my "things to look at" list :)

[...] but the Pixel Processor has no concept of where on the map it is currently.
Yes it has. You can read the $pos variable (which is a 2D floating point vector). It will give you the position of the pixel you are working on in the output image (normalized in [0,1]²).

[...] but the Pixel Processor has no concept of where on the map it is currently.
Yes it has. You can read the $pos variable (which is a 2D floating point vector). It will give you the position of the pixel you are working on in the output image (normalized in [0,1]²).

Yes doing some more digging I found that that is the case, I was going off the fact that if you make a Pixel Processor it starts you out with a Vector4, which only describes each pixel's color value, which wan't really that interesting to me. But upon viewing some more tutorials on using Functions / Pixel Processors I came across that as well, so now I'm trying to make headway on the math potion.

Here is what I have so far, which doesn't seem to work.

I'm struggling with the atan component of the following formula:

longitude = x * pi
latitude = atan(exp(-2 * pi * y))

Going further, I've gotten closer with the following, which is better but still not right:

But Works if you're looking for a kind of Polar Distortion, the issue with this is that it distorts from the equator, as opposed to not distorting 'till you get somewhere around the arctic circle. So back to the drawing board. I just wanted to update the thread letting everybody know that the links at the top referencing the page for the Mercator Projection didn't work out for me.

I think this method will still not work well due to the distortion so early after the equator, as it moves to the poles, but something else that someone could maybe confirm, the sphere that Substance Uses to render what things look like on spheres (UV Coordinates). They seem to have a sawtooth mapping at the poles, as opposed to a pinched system. And I'm guessing that each will need their own mapping algorithm to properly represent the particular style of mapping, for each solution.

It also has some serious issues tiling around the left and right of the texture, maybe fixable with a tiling node when coming back from this, but ideally it should make the edges horizontally contiguous.

Last Edit: December 10, 2015, 08:14:19 am

In your specific case, it would be a good idea to import your own sphere with the UVs you need : you will have more control.

If I wanted a specific case, I'd do the dimples in maya, bake the textures onto my UV, and be done with it.
I think it's a cool question to answer for all kinds of applications in VR to Allegorithmic, to Nuke, to Maya, where you want to "Pre-Distort" a regular pattern so that it maps properly onto a sphere. And I wanted to approach the problem from both ends, the baking which I have for the seams on the basketball, and now I'm trying to match procedural nubs, and wear and tear  so that it looks correct without distortion.


P.S. Sorry that sounded a bit dismissive, but in my frame of mind it's not that difficult to "Cheat" it to make the effect work, I'm looking at more of a "Tool" as opposed to a hack, since the hack only works for a specific use case, while the tool would be nice to use, and I'm trying to learn something new.
Last Edit: December 11, 2015, 12:07:28 am

Since I plan to release both the distortion algorithm, and the Basketball Shader to substance share, I don't have to be cagey, so here's the source UV, and the "Pre-Distorted" basketball Pattern, that I got by transferring the model geometry to the UV setup via Maya's Transfer Maps tool, which projects the geometry information from the geo to a UV Setup on the receiving side.

The Objective is to get the proceduraly generated pattern :

To get distorted so that at the polar coordinates the circles are still semi round.

Hi, this is something I've been trying to figure out as well. I got pretty close with an FX-Map Function. It calculates how much to stretch the input pattern horizontally based on it's vertical position, and it also figures out how many of these can fit onto that row without overlapping and calculates even offset distances.

The problem with this method is it's calculating an overall horizontal stretch per pattern, instead of per pixel row on that pattern. Distortion errors become very obvious near the poles, which results in circles looking like guitar picks. I fixed this by using a tri-planar node for rows near the poles. The graph got pretty messy but it's functional.

With that said I found your thread here and decided to play around with the pixel processor myself. But I ran into the same exact issue that you are having.

This gets the correct "center" positions of the patterns, but they are warped incorrectly and appear skewed to either the left or right.

Using an FX-Map Function I can instead calculate those positions myself.

Now, if it was possible to use a Pixel Processor on a per-pattern basis, and warp each pattern individually(from it's center outwards), correct distortion would be achieved.

Can you show us what you were doing (functionally), and maybe allegorithmic will jump in, and we can see if we can get such a node made ?