PixarAnimationStudios / OpenSubdiv

An Open-Source subdivision surface library.
graphics.pixar.com/opensubdiv
Other
2.87k stars 558 forks source link

Ptex Face : Input UV query #785

Open nyue opened 8 years ago

nyue commented 8 years ago

Hi,

I am constructing the input geometry to OSD with per vertex UV information.

During my iteration of the ptex faces, how do I determine for a certain ptexid, what is the corresponding input UV and in the case of subfaces, is the coarse face UV also propagated to the subface ?

OpenSubdiv::Far::PtexIndices ptexIndices(*fefiner);
// Create a far patch map
OpenSubdiv::Far::PatchMap _patchMap(*_patchTable);
int nPtexFaces = ptexIndices.GetNumFaces();
for (size_t ptexID = 0;ptexID<nPtexFaces;ptexID++)
{
    // for each ptexid, find out UV (not ST) for the given face/sub-face
}

Is there some example code I can look at ?

Background context : I am trying to map a collection of UVs (from the coarse geometry) into ptexID base S,T so that I can build the patchcoord array for use in the limit surface evaluation.

Cheers

manuelk commented 8 years ago

Sorry - not sure I understand the question : each Ptex face is a normalized bi-linear parametric space. A "ptex face" therefore can cover an area of your UV layout, not just a single location. Depending on boundary rules and UV topology, the exact shape of this area can be fairly complex ("smooth" UVs), and definitely not just a quadrilateral (ergo: very hard to integrate).

The case of extra-ordinary faces is handled with the same rules as subdivision : Ptex breaks the face into sub-quads that together cover the same parametric area of your UV layout. Ptex sub-faces are also normalized bi-linear spaces, with the origin set on the first vertex of the sub-face. In OSD, by convention, the first vertex of non-quad sub-faces "rotates" to match the parent's face : ie. vertex '2' of a sub-quad is always the 'face-vertex' child of the parent n-gon (image on the left)

sub-faces

Are you trying to evaluate unwrapped UV layouts for arbitrary limit locations on the CPU ? (like converting UV textures to Ptex, or vice-versa ?). If so, there should be API functions to do that, but you'll have to do it one texel at a time (which you would have to for filtering).

nyue commented 8 years ago

To get me started, can you point me to those API functions you mentioned in your post ?

Or...given a collection (lots, potentially millions) of UVs on the (input) coarse mesh, what is the recommended way to find the equivalent representation as PatchCoord so that I can feed them into the limit surface evaluator.

Any example code illustrating possible classes, methods, routine which I can use to construct this code.

manuelk commented 8 years ago

It looks like I was a little ahead of the code : i confused the recent Far::PrimvarRefiner::LimitFaceVarying() with the limit interpolation arbitrary face-varying locations. I guess this will be coming soon (Barry ?).

However, if you are not using bi-cubic boundary rules, you could apply this function to the face-varying vectors and then interpolate linearly.

Are you writing some UV -> Ptex texture converter ?

nyue commented 8 years ago

Yes, I need a way to convert UV -> Ptex

It would be awesome if I don't have to write such a thing as I think there would be many people finding it useful.

Moreover, I think it can be done a lot more efficiently and internally to OSD as during the building of the various acceleration structures, there must surely be more thread-efficient way to do all these calculations.

Anyone working on these for release in OSD 3.1.x ?

Cheers

barfowl commented 8 years ago

The main feature that is coming in 3.1.x -- patches for non-linear face-varying data -- will help here, but there are no plans I am aware of to provide an out-of-the-box conversion to Ptex. If your UVs are not face-varying, and instead are per-vertex, then there are some tools available that can help now and easily extended to face-varying later.

I don't have direct experience with Ptex, but if your goal is to convert UV texture sets to Ptex, I would think you can avoid the texture inversion problem (i.e. given a texture coordinate (u,v) identify the parametric (s,t) location at which it occurs) and sample the non-linear (vertex or face-varying) patches directly. Texels in a Ptex face are uniform and aligned with the local ST parmeterization, so it makes sense to me (again, with my limited Ptex experience) to use the local ST parametrization to compute corresponding UV texture coordinates and sample/populate the texels somhow from that corresponding UV point or region.

With a Far::PatchTable constructed to include texture patches (they will come for free now if textures are assigned per-vertex, later on request in 3.1.x if assigned as face-varying), you should be able to distribute the computation for each Ptex face over multiple threads. This will provide a very clear association between the texels in the local ST space of a Ptex face and the non-linear UV regions of your mapped texture, but it still leaves the sampling and filtering issues of the conversion up to you.

There's probably information about UV->Ptex conversion available elsewhere as this is not a particularly new problem, but I haven't looked into it myself.

On Wed, Feb 17, 2016 at 8:57 AM, Nicholas Yue notifications@github.com wrote:

Yes, I need a way to convert UV -> Ptex

It would be awesome if I don't have to write such a thing as I think there would be many people finding it useful.

Moreover, I think it can be done a lot more efficiently and internally to OSD as during the building of the various acceleration structures, there must surely be more thread-efficient way to do all these calculations.

Anyone working on these for release in OSD 3.1.x ?

Cheers

— Reply to this email directly or view it on GitHub https://github.com/PixarAnimationStudios/OpenSubdiv/issues/785#issuecomment-185296499 .

manuelk commented 8 years ago

I had this as a feature on my to-do list once upon a time... and indeed, this would be most useful, although i don't think it really belongs in OSD.

Barry : what you describe is how exactly how i would go about it - generate uniform grids of texel locations in ptex space, then map those in UV space and start sampling. Your up-coming fvar patch functionality should make mapping the texels fairly easy, but the filtering part could get very tricky. Automatically generating the good log2 per-face texel resolutions can also be challenging.

Ideally, you would want to lose as little information as possible, so that artists won't have to go 'fix' the ptex files. Given that, splatting approaches, that would go from UV to ptex (dual mapping) would be the way to go, but i don't know that there is a reasonable analytic solution to this problem (similar to ray-subd intersection problems in a way, if you squint hard)

jtran56 commented 6 years ago

Filed as internal issue #151668.