Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Thursday, June 8, for a Q&A with Unity's Content Pipeline group here on the forum, and on the Unity Discord, and discuss topics around Content Build, Import Workflows, Asset Database, and Addressables!
    Dismiss Notice

Question vector math question (for normal maps)

Discussion in 'Shaders' started by canslp, Mar 22, 2023.

  1. canslp


    May 6, 2019
    i'm sure this is a question that's been answered to death but i can't find exactly what i'm looking for anywhere and my vector math is a little rusty. i need to take a uv-space normal vector i've read from a texture and point it in the right direction. so what i have as inputs are:
    - my normal map's normal vector in uv space
    - the completely perpendicular normal vector at the point in worldspace
    - the tangent vector at the point in worldspace
    and i need to convert it to a normal vector in worldspace. i know that you can set this up to accept a tangent-space vector too but that seems harder to implement honestly


    so in math terms really what i'm asking is- how can i transform a 3D vector in order to rotate it into the space defined by my normal and tangent vectors. i'm doing this in the urp shader graph

    ok i think that actually i was wrong about which axis should be my new y axis. instead of the tangent vector i think now that it should be the vector that represents "up" in the way i am projecting the texture- so everything else should be the same? or maybe i am wrong about this. any feedback helps!
    Last edited: Mar 22, 2023
  2. bgolus


    Dec 7, 2012
    Which UV? If it's the mesh's first UV (UV0), then that's already in the mesh's tangent space. Just pipe that directly into the master stack's Normal (Tangent Space).

    If it is not the first UV, then the mesh's tangent vector is useless as that exists only for converting from the mesh's tangent space (aka UV0 space) to world space. That's what the internal shader code uses to do that conversion for the Normal (Tangent Space) input or if you use a Transform node set to go from Tangent to World.

    If the UV you're using is a different mesh UV, or one you're generating in the shader (for example, world space UVs) then you have to calculate the transform from that tangent space to world space yourself, which isn't always easy to do.

    World space or Object space UVs you can do with some cross products between the normal and the world or object space axis. But if they're from a different UV set you'd need to calculate the tangent and bitangent using partial pixel derivatives (DDX & DDY) of the UVs and the world space position as unfortunately there's no build in node to do this. The Normal From Height node does something similar, but not quite what you're looking for.
    canslp likes this.
  3. canslp


    May 6, 2019
    yes, you're right. i shouldn't have been using the tangent vector at all. i needed to derive the "up" vector of the projected texture manually. i think i got it working now- thanks