[REQ] UV Offset Plugin
-
Hi everyone! I've wanted to share a common issue with you and propose a solution to it.
So, while plugins like UVTools 0.2 are available, most of you are probably using SketchUp native tools for your texture mapping needs. One thing that is interesting to point out there is SketchUp carefree attitude towards UV coordinates and tiling. If you're texturing a brick building, it's not unreasonable to guess that your texture mapping will look similar to this:
That happens, obviously, because there is no reference to UV coordinates in SketchUp texture mapping mode, which means there is no way to tell which texture tile you're using. Only reference you have are red/green/blue/yellow controllers, initially sitting at the corners of original tile, but these change their position if the texture mapping was picked/inherited from another face (which is almost always the case).
While it's acceptable for tiled materials like brick to employ coordinates outside of original tile, this can be problematic for some cases.
Let's take a look at "ideal" lowpoly building model akin to ones used in Google Earth.
To optimize the file size and performance, it's using one single texture for everything. This texture contains every unique feature of the building, so there is no need to waste space on tiled roof textures, windows and stuff like that. It's not too hard to pinpoint repeating elements, even in fairly complex architecture.
The model is comprised of faces fitting these parts, which are mapped by appropriate parts of that texture.
Looks nice so far. But let's say we need to use that model in some proprietary engine (like high-end GPS navigator) or bake renderer, where UV space allowed for use is strictly limited to [0,1], i.e. only first tile can be used. This kind of requirement is very common.
Let's take a look at our faces in 3ds Max UV Editor to make sure everything sits inside the first tile. We expect lots of faces to be outside of [0,1] range (after all, we're using picked materials and inherited texture mapping from other faces quite often, so offsets are unavoidable), but it shouldn't be too hard to fix. Just a couple of grid-snapped move operations on UV islands, probably.
Disappointing, but expected. Still, well, it's not like everything could be too far from the first tile. We've only used inherited mapping a couple of times in a row tops. Let's zoom out a bit, everything should be nearby. Right?
Ugh, okay. Anything further?
You've got to be kidding me. But wait, there is more.
That's more than 20 tiles away from point of origin (!!!).
Now, remember, every face there is lined up with some part of the texture. Nothing goes over tile borders. So basically, everything should fit perfectly into one tile: only problem is, faces are scattered around a hundred tiles. Wrong ones.
And there is no grid snapping in the UV editor. You can't even fix the step of your move tool to the size of UV tile to make dragging everything back precise and easy. You have to zoom in and align every face again, manually (thankfully, at least axis snapping is available, so that was limited to a single axis at a time).
Eventually, it was done.
Guess how much time was wasted on dragging everything back to the point of origin? A bit too much.
Now to the proposed solution.
Obviously, changing SketchUp UV editor is out of reach for plugins, so it's not possible to implement some sort of optional range lock that will prevent texture mapping from flying away into infinity.
What can be done, though (probably) is the processing of UV data after the model is finished. As I've mentioned earlier, ideally, every face should be inside a tile, no border intersections around. This should make it possible to determine with absolute certainty on which tile a face is situated. So, let's say there is a magic button that we press once a model is finalized. It starts a check that will look up coordinates of UV islands.
Knowing these, it's then possible to determine the tile, and then, we can easily fix the position by adding an integer value like -1 to the UV island coordinates.
Extreme edition suggestion: if some face is crossing the tile border, abort the check and highlight it in the viewport.
As far as I understand, this kind of check should be possible and this kind of access to UV data with write permission should be available for plugins.
To elaborate on object types that can require this kind of check, here are some additional examples. In addition to Google Earth-like objects, everything I said is applicable to objects like these:
[img:1smkgstp]http://i.imgur.com/Efzld.jpg[/img:1smkgstp]
[img:1smkgstp]http://i.imgur.com/nFXqR.jpg[/img:1smkgstp][img:1smkgstp]http://i.imgur.com/oB89n.jpg[/img:1smkgstp]
[img:1smkgstp]http://i.imgur.com/X4QZC.jpg[/img:1smkgstp]
[img:1smkgstp]http://i.imgur.com/QLcd7.jpg[/img:1smkgstp]
[img:1smkgstp]http://i.imgur.com/yPw5j.jpg[/img:1smkgstp]Contrary to the popular belief, these kinds of objects can be mapped with SketchUp native tools. Only problem is aforementioned offset of some UV islands, which will prevent you, for example, from baking ambient occlusion in external software.
So, what do you think? Is it possible to write a plugin that will check UV island positions and move them to the first tile by adding integer values to their coordinates? Would it be useful, in your opinion.
Thanks in advance for any answer!
-
I'm not sure if I fully understand you, but you want to normalize UV coordinates to lie within 0.0 - 1.0 ? So if a face had UV mapping where it's coordinates where within 8.0 - 9.0 they'd be adjusted to 0.0 - 1.0?
Sample data:
[8.2, 6.3] [8.8, 6.3] [8.8, 6.9] [8.2, 6.9]
Expected result:
[0.2, 0.3] [0.8, 0.3] [0.8, 0.9] [0.2, 0.9]
And of course, if either the U or V range exceeds it's integer domain the UV mapping is invalid and it's not the UV mapping we expect. ?
-
It seems TextureResizer does this with
%(#000000)[Resize 100%]
(no resizing) and%(#000000)[Crop textures]
.
As thomthom said, just shifting the integer values wouldn't work if faces exceed (or intersect) the image borders like tiling textures do (TextureResizer then extends the image as much as necessary). -
thomthom
Yeah, your example is absolutely correct!
And right, if there is a face with coordinates like these:[7.2, 6.3]
[7.8, 6.3]
[8.8, 7.9]
[9.2, 5.9]Then there is no point to run such a script, and the most logical thing to do would be to abort operation. It would be extremely cool if offending face would be highlighted, but I'm not sure if it's an easy thing to do, since it might be buried inside the component hierarchy and directly selecting it might be impossible.
Aerilius
Thanks, I will definitely try this, even though the plugin description doesn't look very revelant. But maybe it does what's needed as an unintended side effect, will check.
Advertisement