Jump to content
Mzigaib

UV cubic map procedurally

Recommended Posts

It seems simple but I couldn't figure out how to procedurally create a cubic UV map fora a simple 6 sides cube, Any tips?

Thanks.

Share this post


Link to post
Share on other sites

Thanks for the feedback.

Is about the way the uvs are layed, it needs to be layed follow a cubic vertical environment cube.

UV unwrap works for texturing but it doesn´t position the uv´s right away with the cross cubic env image you have to do it by hand. Does it make sense?

Share this post


Link to post
Share on other sites

You can do this by doing 6 separate projections (UV texture or UV project) for each side to the cube and move them in position.

If you simply do that upfront, you can afterwards change the cube and the UVs should remain intact.

You could even morph this cube in a quad sphere if that is what you are looking for.

Shameless self plug is shameless:

http://www.twandegraaf.nl/Art/Documents/Procedural%20planets%20into%20detail,%20Twan%20de%20Graaf%202012.pdf

see page 6.

  • Like 1

Share this post


Link to post
Share on other sites

I tried a similar thing a while back, its a fair amount of script to position the uv projections on each side of the box

Hope it helps

 

 

Share this post


Link to post
Share on other sites

Thanks Konstantin, it seems to work well for spaceship parts.

 

Now I can finally paint my ships in Mari!

Untitled-1.jpg

Edited by Atom

Share this post


Link to post
Share on other sites
20 minutes ago, Atom said:

Thanks Konstantin, it seems to work well for spaceship parts.

Hehe cool, makes me proud to see it´s of any use!

Share this post


Link to post
Share on other sites
On 4/27/2017 at 11:50 PM, konstantin magnus said:

Hehe cool, makes me proud to see it´s of any use!

I'm not proud !!! I'm reading your code over and over and still got NFI !!!

Share this post


Link to post
Share on other sites

Ok, it's been a while, but let's try it one by one:

1. Scaling world coordinates to unit size

vector bbox = relbbox(0, @P);
vector size  = getbbox_size(0);
vector ratio = size / max(size);
vector scale = bbox * ratio;

relbbox() creates linear gradients along each axis of the object from 0.0 to 1.0. Those can be spread out in UV space later.
getbbox_size() returns the absolute dimensions of the object. While we don't care about the actual size, we need to factor in how those dimensions relate to one another:
size / max(size) Dividing all dimensions by the biggest one effectively scales them to unit size while keeping the proportions. This is the aspect ratio for X, Y and Z.
bbox * ratio combines the gradients on all mesh points with the overall aspect ratio. All projections fit proportionally onto the UV grid now, we only need to split them up and lay them out.

 

2. Splitting up projection sides

vector side = sign(v@N);
vector nml  = abs(v@N);

if      (nml.x == max(nml)) { ...	}
else if (nml.y == max(nml)) { ...	}
else                        { ...	}

sign(v@N) decides towards which side the normals point to. Its either left or right, top or bottom, front or back. Later this will compensate for..
abs(v@N) setting all normals to positive values. So we can easily compare which direction they are mainly facing, using:
if (nml.x == max(nml)) for X, else if (nml.y == max(nml)) for Y and else for Z. By comparing each absolute component with the normals' maximum, we split the geometry into UV islands.

 

3. Laying out UV coordinates

if      (nml.x == max(nml)) { @uv = set(scale.y * side.x, scale.z, 0);             }
else if (nml.y == max(nml)) { @uv = set(scale.x * side.y, scale.z, 0); @uv.y += 1; }
else                        { @uv = set(scale.x * side.z, scale.y, 0); @uv.y += 2; }
@uv *= 0.3333;
@uv.x += 0.5;

set(scale.x * side.y, scale.z, 0); Depending on which side has won, the UV coordinates are composed of either top or side views (first component) and front or side views (second component). Setting the scale variables negative can be used to sort out direction issues.
*side.x*side.y and *side.z are simply flipping directions in case the normal directions have been negative. Thus getting their own islands on the left side. 
@uv.y += 1; and @uv.y += 2; are moving the UV islands upwards, so they are not landing on top of each other.
@uv *= 0.3333; Currently UV coordinates span across six unit spaces, so we scale them down to fit into one.
@uv.x += 0.5; Because of flipping the sides we also have to move all our coordinates to the right by half.

 

Alright, I hope things got less confusing now. ;)

Edited by konstantin magnus
  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites
On 10/4/2017 at 2:06 AM, konstantin magnus said:

Here is a vertexwrangle method for projecting cubic UVs on any kind of mesh:


vector bbox = relbbox(0, @P);
vector side = sign(@N);
vector nml  = abs(@N);

vector size  = getbbox_size(0);
vector ratio = size / max(size);
vector scale = bbox * ratio;

if      (nml.x == max(nml)) { @uv = set(scale.y * side.x, scale.z, 0);             }
else if (nml.y == max(nml)) { @uv = set(scale.x * side.y, scale.z, 0); @uv.y += 1; }
else                        { @uv = set(scale.x * side.z, scale.y, 0); @uv.y += 2; }

@uv *= 0.3333;
@uv.x += 0.5;

 

Thanks Konstantin, that's amazing!

For those who get some weird stretched uv, I solved by deleting any Normal attribute before feeding geo into vertex wrangler. Very basic but it took me a while to figure it out.. ;)

Share this post


Link to post
Share on other sites
Posted (edited)

Always cool to have stuff in vex! I just wanted to mention, that this is also implemented natively with the uvunwrap node.

 

Edit: Was just reading about the cubic vertical environment cube uv layout thing. Missed that one.

Edited by Drughi

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×