Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Convert world space normals to tangent space with Pixel Processor node

Community Beginner ,
Nov 03, 2024 Nov 03, 2024

I heard mention on a video that this was possible, but unsure where to start. Wondering if someone has some ideas?

TOPICS
How to
4.0K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 03, 2024 Nov 03, 2024

Hello converting World Normals to Tangent Normals is absolutely possible using a Pixelprocessor, although it involves a little linear algebra and the use of matrices, which are not part of the function set in Substance 3D Designer.

These have to be build from scratch, which can be a little tricky.

 

I have some of the needed functions lying around and I should be able to create you a Node, which does this, today or tomorrow.

 

If you want to give it a try by yourself, here is a step by step explanation of the workflow:

 

  • Calculate the Tangent and Bitangent from the UV-Coordinates and the Position-Map, this can be done, by sampling the neighbors of the current position and construct the tangent and bitangent vectors, from these positions. The Tangent Vector is retrieved from the vector in x-Direction, the Bitangent is retrieved in y-Direction.

 

  • Construct the TBN-Matrix from the Tangent-, Bitangent- and WorldNormal-Vectors. This step involves a little creativity, because there is no 3x3 Matrix Data-Type in SD so use 3 Float3 for this (I usually use them as matrix columns, because then they are the same as the 3 Vectors)

 

  • Now you have to calculate the Inverse of the TBN-Matrix, which is the hardest part and involves a deeper understanding how matrices work and how to calculate the inverse of a matrix (I have such a function lying around for 4x4 matrices, as soon as I'm home from work I can change it, so it fits your needs, but that may take a little)

 

  • The last step is to Transform the World Normals to Tangent Normals by multiplying the World Normals with the Inverse of the TBN Matrix. 

 

I hope this helps and if you have one or two days, I would be very happy to create such a node for you.

 

Stay healthy and creative Marco 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 03, 2024 Nov 03, 2024

Legendary, thanks for the response!
Will definitely give this a go, but if you have the space for it, if you could create a node I would be absolutely over the moon.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 04, 2024 Nov 04, 2024

You could also try the World Space Direction baker, using your existing World Space Normal texture as a direction file.

 

Dave

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 04, 2024 Nov 04, 2024

That's true, I didn't think about that. But but approximating the direction, from a position map is not that complicated either 😉

Stay healthy and creative Marco

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 04, 2024 Nov 04, 2024

Good Morning,

I think I got it, and while I was building the node, I found out, that inverting the TBN matrix isn't really neccessary, because of the construction of the matrix, they are always orthogonal, so a simple dot product of the three vectors should do.

Make sure your baker settings are set like this, especially the .tif file format is important, so you get 32Bit Floating Point precision, which results in an accurate Normal map. Especially for the position map, this is important, because of possible negative values, which would be clamped to 0 when not using 32Bit floating point Textures.

 

MarcoVitale_0-1730790913368.png

MarcoVitale_1-1730790921792.png

Stay healthy and creative Marco

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 05, 2024 Nov 05, 2024

Thanks so much for this! It looks like it's pretty close to being exactly what I was after. Would love to shout you a coffee somehow after this!
I am however encountering an issue where when plugging in the Position Map, it seems to (perhaps) not calculate smoothed normals, instead showing as hard edged?

ConceptualArtist_0-1730838854738.png

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 05, 2024 Nov 05, 2024

This looks like it's calculating smooth normals pretty fine, the hard edges come from the flattened 2D representation of your 3D model. I'm not at my PC, so I try to explain what happens without any illustrations, I hope this is understandable.

Smooth Normals are basically interpolation the normals at any vertex by averaging the normals of adjacent faces, these averages get interpolated barycentric over every triangle of the mesh. World Normals are relative to the object space, Tangent Normals are relative to the tangent of each face, hard Tangent Normals would result in a Normal vector pointing in (0,0,1) direction from each face, so the resulting Normal map would be rgb(0.5,0.5,1.0). Since your resulting Normal map has different color gradients across every face it means, these are interpolated Normal vectors, converted into tangent space and mapped to your UVs, the hard edges come from the fact, that these Normals are relative to each face and basically compensate the direction of the hard faces, at the edges the Normals are pointing in different direction, because they are averaging the direction from different tangents. Try to apply this Normal Map to your mesh and the normals should be smooth. I hope that was understandable.

By the way, I'm always in for a good espresso https://marcovitale.gumroad.com/coffee 😉

Stay healthy and creative Marco 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 05, 2024 Nov 05, 2024

Cheers for the explanation Marco. Unfortunately it seems the normals aren't coming through as smooth when applied to the model here... (So very close to achieving the tool I need for stylized, procedurally painterly normals)

ConceptualArtist_0-1730857400074.png

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 05, 2024 Nov 05, 2024

OH I see,

I tested something, which is very promising. Instead of calculating the Tangent Direction, you can just bake it, which results in very smooth normals.

MarcoVitale_0-1730873100223.png

MarcoVitale_1-1730873116926.png

MarcoVitale_2-1730873140476.png

I updated the Node, with another Pixelprocessor which takes the World Normals and the two directions maps as Inputs and it seems to work fine.

Stay healthy and creative Marco

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 20, 2025 May 20, 2025

Hi Folks,

 

Reviving this thread.  I am trying to recreate this, but for use in a filter/generator for Substance Painter, so I'd prefer not to have to bake the world space direction maps, that adds a step that is clunky for my pipeline.

For the "simple" method using just position map and WSN map, I am not getting good results, I see something like this:

ApocalypseNau_0-1747761323380.png

 

I have a mesh with multiple UDIMs, could that be contributing to the weird result?


Thanks!

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 20, 2025 May 20, 2025

Heya, maybe this isn't what you're ultimately after, but I recently got my answer with this banger of a tool for SP:
https://www.artstation.com/marketplace/p/JmRRk/very-normal-paint

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 20, 2025 May 20, 2025

Kind of.  I have this tool and it is very clever.

 

However, I can see some performance issues with it,  and im very curious to see how they've converted the WSN to Normal, but, yes, I am trying to create a similar effect.  Im hoping to avoid adding the additional channel (user15) and having to re sample with every stroke.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 20, 2025 May 20, 2025

Its further complicating that you can't paint with a dynamic brush/procedrual in the normal channel, it produces something that looks like a flow map and isnt predictable/usuable in the way you'd want.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 21, 2025 May 21, 2025

Let's try to solve the problem, I don't think it's an issue with the UDIMs it looks to me like a range related problem.

First I have some questions about your setup:

  1. Do you use one of the Nodes I provided or did you recreate it by yourself? If you used one of the Nodes I provided, make sure to take the original one, which takes the Position-Map and the WSN as Inputs.
  2. What range does your Maps have? [0, 1] or [-1, 1]?
  3. Can you provide the baked maps, so I can have a look?

 

All the best Marco 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
May 21, 2025 May 21, 2025

Hi,

I think this happens when your input map is set to C8 insted of C32F

I hope that helped you.

 

Thank you Marco for the all the info on this thread.

 

All the best

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 22, 2025 May 22, 2025

The input maps were indeed set to C8 instead of C32F, this mustve been set by a SD default, I opened Marco's file and did not modify it.

Marco:
1. I used the nodes you provided and did not modify them.
2. My position map appears to be 0-1 and my WSN is 0-1 as well, I think.
3. I think I dont need to share my maps, changing the color depth fixed the issue

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 23, 2025 May 23, 2025
LATEST

I'm glad the issue is solved.

Stay healthy and creative Marco

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines