Ive got a tile im procedurally generating UVs using a simple spherical projection.
var uv = new float2(math.atan2(normal.y, normal.z) / (-2f * math.PI), math.asin(normal.x) / math.PI + 0.5f);
Problem is the further I move away from origin the larger the texture projection is as show with the two tiles in the image. I know the radius from each tile to origin 0.0.0 so I feel there some fancy way to fix this. Please any help.
Is that top pentagon the same size in worldspace as the yellow cutout on the one at the bottom? I infer that but I just wanted to ask to be sure, because from that perspective it obviously looks bigger.
I assume these are also using the same instance of the material, ie., same UV multipliers?
Edit: just noticed the bottom ones are hexagons… but are they the same diameter/radius (within reason).
Yea same material too , so the only real difference between the two tiles is where they are samples . Bottom tile is at y 0 and top at y 25. If I sample bottom tile at y 25 the texture tiling is the same.
It just feels like one of the shader ops is doing something more with local space. It can’t be those trig functions so perhaps however you end up with the normal implies that it be also offset/scaled by local position???
Oh wait, I think I see it: if you are normalizing the vert positions, then the size of the x and the y will be consequentially smaller as the z (vertical) axis grows larger, which changes your mapping inputs.
Think about 2 points separated by 1 horizontal unit. Raise that 1 vertical and normalize you have 1 and 1, so 0.7071 for horizontal, or sqrt(2). something like (0.7, 0.7, 0.7)
Now lift up by 10 vertical unit and you have norm of (1, 1, 10): this normalizes out to something with much smaller x and y axes (something like (0.1, 0.1, 0.9));
FIX: I think maybe don’t normalize the vertex positions before you put into your atan/asin funcs?
If you can give us a little more of your code, someone might notice a scaling factor. The one line of code from yesterday doesn’t seem like it should depend on radius.
Best we can do is hazard guesses what is wrong with your normal vector.
Sorry, I’ve never attempted a spherical projection, so I don’t have any examples I prefer.
This is what I was suggesting in my Reply #11 above. Note the addition of the actual vector argument, which is un-normalized.
You would intuit this would not make a difference because the use is in a ratio, but I think it makes a difference on two subsequent calls to this UV-maker with linearly-spaced points being pulled further up the axis.
Try it. You just have to modify your call site to also supply the actual vert in addition to the normal.
private static float2 GetGraphVertexUv00_MOAR([ReadOnly] float3 actual, [ReadOnly] float3 normal, bool axesVertical)
{
// TODO : https://gamedev.stackexchange.com/questions/136314/sphere-uv-mapping-texture-streched
if (axesVertical == true)
{
var uv = new float2(math.atan2(actual.x, actual.z) / (-2f * math.PI), math.asin(normal.y) / math.PI + 0.5f);
if (uv.x < 0f) uv.x += 1f;
return uv;
}
else
{
var uv = new float2(math.atan2(actual.y, actual.z)/ (-2f * math.PI), math.asin(normal.x) / math.PI + 0.5f);
if (uv.x < 0f) uv.x += 1f; // TODO maybe should be y
return uv;
}
}