Jump to content
mikela

(u,v) to (x,y,z)

Recommended Posts

This should have an easy answer, and I hope someone here helps me before I put too much time into finding it...

I have a vector in (u,v) coordinates that I need in (x,y,z) coordinates, object space. I'm in the displace context so I know P and N. How do I do it?

Unless there's some space transform I don't know about (I seem to remember coming across a texture space transform in the docs, but can't find it now) I think I would have to know exactly how my UVproject has layed things out. For example, if I lay uv coords on a torus so that u always lies in say the xy plane, then I can find u in object space with the N vector (which is orthogonal to uv). I don't think this kind of solution could handle a variety of uv layouts, though. Hmmm, maybe it's just been too long since I've done much 3D math...

BTW is there a difference between (u,v) and (s,t)?

Share this post


Link to post
Share on other sites

Hi Mikela,

The confusing bit is this: "I have a vector in (u,v) coordinates"

If you mean that this is some vector parameter that's expressed in a projected texture space, then one possibility would be to reinterpret it using the surface derivatives (change in st) as a basis; something like this:

displace MyDisplace (

Share this post


Link to post
Share on other sites

hmmm.... changed my mind. This question just won't let me go! :angry:

OK. Ignore all that stuff I posted.

What we really need as the pair of basis vectors for the projected texture "space" is the gradient (direction of increasing value) for both texture_U and texture_V (assuming u and v are orthogonal to each other). The parametric basis vectors are the normalized Du(P) and Dv(P). So now I'm thinking that if we express the slopes (derivs) of the texture attributes (u,v) in terms of that basis, then we'd get the gradients for u and v. Finally; we use those as our 2D frame for expressing the uv-based arbitrary vector....

Still thinking about this; but I threw together a little test shader, and it seems to be doing what I think.

//-----------------------------------------------------------
// Calc the gradient (normalized direction vector) of the 
// attribute x, given the two parametric basis vectors (normalized!)
//-----------------------------------------------------------
vector gradient(float x; vector sbasis,tbasis) {
   return normalize(sbasis*Du(x) + tbasis*Dv(x));
}

#pragma label  mode     "Visualize Mode"
#pragma choice mode     "gu"  "Gradient: Texture_U"
#pragma choice mode     "gv"  "Gradient: Texture_V"
#pragma choice mode     "usr" "User Vector in (U,V) Space"
#pragma hint   uv       hidden
#pragma label  vec      "UV-Vector"
#pragma label  makepos  "Force Positive"
#pragma hint   makepos  toggle
#pragma label  xtrap    "Extrapolate Derivatives"
#pragma hint   xtrap    toggle
#pragma label  smooth   "Smooth Derivatives"
#pragma hint   smooth   toggle

surface VectorUV (
      string   mode     =  "usr";
      vector   vec      =  {1,1,0};
      int      makepos  =  1,
               xtrap    =  1,
               smooth   =  1;

      // Hidden: Texture coords -- presumably bound
      vector   uv       =  0; 
   ) 
{
   vector T = isbound("uv") ? uv : set(s,t,0);

   vector sbasis = normalize(Du(P,"extrapolate",xtrap,"smooth",smooth));
   vector tbasis = normalize(Dv(P,"extrapolate",xtrap,"smooth",smooth));

   // Switch on vis-mode
   if(mode=="gu") {
      Cf = gradient(T.x,sbasis,tbasis);
   } else if(mode=="gv") {
      Cf = gradient(T.y,sbasis,tbasis);
   } else if(mode=="usr") {
      Cf =  gradient(T.x,sbasis,tbasis)*vec.x + 
            gradient(T.y,sbasis,tbasis)*vec.y;
   } else {
      Cf = 0.;
   }

   Cf = makepos ? Cf*0.5+0.5 : Cf;
}

This thing will let you visualize the two computed gradients and the uv_space user vector. Try it on both parametric surfaces and polys.

If anyone sees something wrong with this, please let me know... I'm still thinking about this whole gradient business. It would seem it should be simple to just say "give me the gradient of some arbitrary variable", but... hmmm...

Share this post


Link to post
Share on other sites

thanks, Mario!

When you suggested using dP/du I knew you were onto something, but your Du(uv) revelation really had me wondering for a while. Your final solution reminds me of my vector algebra--it looks right, anyway. When I plugged it into my shader it did what I wanted it to, but I can't say for sure untill tomorrow because I have lots of ugly displacement artifacts right now...

Share this post


Link to post
Share on other sites
Your final solution reminds me of my vector algebra--it looks right, anyway.

Well; I've gone over it a few more times, and I'm a little more confident now that the math is OK.

I would love to be able to say that it's "done", and stuff it into my library as a generic gradient function (which would be nice to have), but I can't, and here's why:

Something's rotten in the state of PolyGon <_<

Parametric surfaces and even polygonal ones built with quads all seem to behave as expected -- albeit the quad faces have a constant gradient, but that's what I'd expect. But polygonal surfaces built from triangles or mixed n-gons are a disaster. So...

Either I'm not accounting for something, or one of the assumptions is wrong.

Could it be that when we're shading a triangle, for example, the parametric derivs (dPdu,dPdv) are not orthogonal as I assume? (even though we're really inside a micropoly which is a quad?)...

Dunno. Something... I'll have to come back to it when I get a chance...

Any clues? mikela? Jason? anyone? (does MarkE lurk this board? :P )

Cheers.

Share this post


Link to post
Share on other sites
How do you subdivide a triangle into quads and still get consistent uv's?

:D

Right!

So; what to do?!?!

One could remove the dependence on both derivs and simply "construct" the second orthonormal vector. Something like:

basisX = normalize(Du(P));

basisY = cross(basisX,normalize(N));

Haven't tested this yet; but I've started thinking that way.

I'm just looking for something that works for ALL geometry -- plug it in and forget about it type of thing ;)

Share this post


Link to post
Share on other sites

...or, probably better, just bring in a world "up" vector and use

basisX = Up X N

basisY = basisX X N

and construct everything relative to that....

lol; my brain is fried; and now I'm just spamming ...

:P

Share this post


Link to post
Share on other sites

Well; if someone comes up with an answer to this one, I'd love to hear it.

But if I don't respond, it's because I'll be far away from any computer for a whole month.

See you all in March; and have fun with VEX! :D

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

×