Triplanar shading

User avatar
Acegikmo
Neat Corp / Admin

PostWed Oct 07, 2015 8:05 am

Triplanar shading is a way to relatively sensibly map textures to an object, without supplying UV coordinates through the mesh data.
It basically works by projecting a texture onto an object along each of the three coordinate axes.
It then blends those three projections into one, depending on which direction the surface is facing, so the more it's facing upwards, the more it blends towards the upwards projection, and so on.

As with most shaders, a triplanar shader will look different depending on what you want to achieve. Here's a "bare minimum" setup:

sf_triplanar_basic.png
sf_triplanar_basic.png (370.05 KiB) Viewed 10643 times


If the orientation matters, such as when your texture has letters, or when it simply looks strange when mirrored, you can use this setup:

sf_triplanar_oriented.png
sf_triplanar_oriented.png (629.3 KiB) Viewed 10643 times



One thing we haven't covered, is how to do a triplanar shader using normal maps. Normal-mapped triplanar shaders are tricky, because you can no longer rely on tangent-space, which you generally do with normals. More on this another time :)

Hope it helps!
User avatar
DMeville
Shader Forge Moderator
Location: Canada

PostTue Oct 13, 2015 2:34 am

Awesome guide!

If you want the textures to move with the object I found you can do this: Image

What about responding properly to an objects local rotation, rather than the world axis, is there an easy way to get that working?
User avatar
Acegikmo
Neat Corp / Admin

PostTue Oct 13, 2015 5:53 am

DMeville wrote:What about responding properly to an objects local rotation, rather than the world axis, is there an easy way to get that working?


I believe you can add a Transform node between subtract and comp. mask, from world to local
User avatar
DMeville
Shader Forge Moderator
Location: Canada

PostTue Oct 13, 2015 6:22 am

You have to add a transform from world to local both before the component mask and after the Normal Direction node as well. Works great!
Waz

PostWed Oct 14, 2015 11:54 pm

I tried adding a Transform node From:World, To:Local, after Normal Dir, but rotating the object just smeared the textures. (SF 1.21)

Edit: fixed - I was using the "Subtract" method for object pos, using Transform for that too fixes the problem.
kilik

PostMon Oct 19, 2015 10:50 am

thank's for this post :)
Marco Sperling
Shader Forge Moderator
Location: Germany

PostWed Oct 21, 2015 4:50 pm

Acegikmo wrote:One thing we haven't covered, is how to do a triplanar shader using normal maps. Normal-mapped triplanar shaders are tricky, because you can no longer rely on tangent-space, which you generally do with normals. More on this another time :)


I am currently struggling with this challenge. I have a mesh that has to use 2 tiling Tangent space normal maps - one for the walls and one for the top/bottom plate.
The walls were mapped cylindrically and have a rectangular layout. Both top and bottom are mapped planar and have an arbitrary size, Rotation and Position compared to the wall uv Shell.
The textures get blended by a vertex Color mask.

Now I know that Tangent space normal maps rely on their UV layout to get correct shading. And this is exactly where I see the shading issue - at the uv border between the cylindrical mapped wall and the planar mapped plates.

Would I be able to fix this by generating two UV sets? One where the walls maintain a Connection to the plates and vice versa?
User avatar
Acegikmo
Neat Corp / Admin

PostThu Oct 22, 2015 2:57 am

I think the easiest way to do it is to simply no longer rely on the mesh UVs/tangents for mapping the normals. You'd need to create your own tangent space on a shader level, using the projection direction for each planar projection, and the normal in projection space, and the local axis directions.
I'll probably do a tutorial on this at some point :)
Puppeteer

PostTue Oct 27, 2015 2:55 pm

Creating the tangents is quite easy.
You just have to rotate the normal by 90° in the right direction and you have your tangent.
For example if you look at the XZ projection plane the tangent would be: normal.y,-normal.x,normal.z,1 if I am not mistaken.

I however am struggling to find out how to input the new tangent in a ShaderForge PBR shader without having to do the whole PBR thing myself.
I could calculate the world space triplanar normal direction and convert it to mesh-tangent space, but this seems kinda tedious to me and would introduce a lot of redundant calculations.
It would be great if there was a world space normal option in Shaderforge for those kind of purposes...
EDIT: I just used my eyes and beheld the feature I so much sought....
Puppeteer

PostTue Oct 27, 2015 11:38 pm

Here is how to triplanar normal mapping. I hope I did nothing wrong.
EDIT: Of course you have to add the correct UVs to the map!!! And also my UV planes are different then the ones above!
I use: XZ, XY, YZ.
EDIT2: Also I hooked up the last channelblend the wrong way. I might post a correct fully working version of the triplanar shader with normalmapping here later that aligns with joachims implementation to avoid confusion.
Attachments
normals.png
normals.png (353.11 KiB) Viewed 9981 times
User avatar
Acegikmo
Neat Corp / Admin

PostWed Oct 28, 2015 8:50 am

Puppeteer wrote:Here is how to triplanar normal mapping. I hope I did nothing wrong.
EDIT: Of course you have to add the correct UVs to the map!!! And also my UV planes are different then the ones above!
I use: XZ, XY, YZ.
EDIT2: Also I hooked up the last channelblend the wrong way. I might post a correct fully working version of the triplanar shader with normalmapping here later that aligns with joachims implementation to avoid confusion.


The problem with that one though is that it's not UV independent, it relies on your mesh having the correct UVs set up for that particular shader
User avatar
Acegikmo
Neat Corp / Admin

PostWed Oct 28, 2015 10:16 am

Here's a normal-mapped triplanar that's close to fully working. It works on the positive XYZ axes, but fails on the negative ones. If any if you try to get the negative axes right, I'd love to see the results!

sf_triplanar_10282015.png
sf_triplanar_10282015.png (1.34 MiB) Viewed 9971 times
Puppeteer

PostTue Nov 03, 2015 4:55 pm

Acegikmo wrote:
Puppeteer wrote:Here is how to triplanar normal mapping. I hope I did nothing wrong.
EDIT: Of course you have to add the correct UVs to the map!!! And also my UV planes are different then the ones above!
I use: XZ, XY, YZ.
EDIT2: Also I hooked up the last channelblend the wrong way. I might post a correct fully working version of the triplanar shader with normalmapping here later that aligns with joachims implementation to avoid confusion.


The problem with that one though is that it's not UV independent, it relies on your mesh having the correct UVs set up for that particular shader


It is UV independent. I just left that part out.

I attached a seemingly working version. However I am not entirely sure why it works....
You can download the shader here and tell me if you can find any mistakes:
Click me

EDIT: I think I know why know! Because the UVs are mirrored! That also inverts the respective normal map axis and I had to fix that by taking the absolute of the normal.
So if you are using triplanar UVs that do not mirror your textures you have to remove the abs after the normal dir in my shader.

EDIT2: btw is that a preview bug on most of my nodes?
Attachments
normals.png
normals.png (477.19 KiB) Viewed 9908 times
Braldye

PostTue Nov 17, 2015 5:22 pm

Triplaner code nodes have been added in the shader forge wiki by Lucas Nore http://acegikmo.com/shaderforge/wiki/in ... ar_Mapping with downloads. These nodes will help clean up your shader project quite a bit.


Image

Image
User avatar
CodersExpo

PostSun Jan 03, 2016 6:02 pm

WOW! Simply awesome. All of you deserve kudos for your contributions on this topic. I've learned so much through the videos and examples here (and suggested by Ace). I'm trying hard now to take what I know and apply these techniques using multiple textures. I'll share if I think I have something worthy ;-) Thanks again to all of you.
GaryDave

PostMon Jan 25, 2016 12:16 pm

Hey hey. Has anyone been able to get this sort of thing working on mobile?
User avatar
sfbaystudios

PostTue Oct 11, 2016 2:40 am

Has a solution to the normal map issue been found?
User avatar
sfbaystudios

PostTue Oct 11, 2016 7:41 am

I should add, I've tried the "Object Space" shader listed here:

http://acegikmo.com/shaderforge/wiki/in ... ar_Mapping

It works with the diffuse. however, whenever I try to copy the code portion to make it work with another map, even if I change the variable names etc, I get a broken shader, so I'm not sure if it'll work with more than just one map?

[I have no idea what the code is doing, or how to modify it properly]
Ourob

PostWed Nov 30, 2016 2:22 pm

Hi guys!
I'm actually working on a "Triplanar mapping" but what I am trying to do is kind of replacing ONE "UV" node with triplanar. I have several textures for this shader that superposes, and I feel that making this triplanar method for each of them will be a P in the A.
This is what I got so far (working quite well for "planes" but not at all for "spherical" items) :
Image
Image

Am I doing it right or there is absolutely no way of making it work like this ? x)
Thank you in advance! First time posting here, but have been hanging around for quite a while now. ^^
Pernroth

PostWed Mar 01, 2017 12:57 pm

Acegikmo wrote:Here's a normal-mapped triplanar that's close to fully working. It works on the positive XYZ axes, but fails on the negative ones. If any if you try to get the negative axes right, I'd love to see the results!

sf_triplanar_10282015.png


I think the problem lies in the Normal Blend Node (if the issue you got was strange black flickering on the negative axes). It seems like that node has a bug when the base input values are exactly -1, like for three of the sides of cube that has no rotations applied. If you multiply the Normal direction going into Normal blends with 0.9 there are no glitches on the negative sides anymore.

Perhaps this is what this is about:

if (n1.z < -0.9999999) // Handle the singularity
{
b1 = float3( 0, -1, 0);
b2 = float3(-1, 0, 0);
}

on this page http://blog.selfshadow.com/publications ... in-detail/
limaoscar1

PostWed Aug 02, 2017 10:00 am

Acegikmo wrote:I think the easiest way to do it is to simply no longer rely on the mesh UVs/tangents for mapping the normals. You'd need to create your own tangent space on a shader level, using the projection direction for each planar projection, and the normal in projection space, and the local axis directions.
I'll probably do a tutorial on this at some point :)



did you manage to do a tutorial on this ?
User avatar
totrider

PostSun Nov 19, 2017 3:33 pm

How would one go about projecting on only the top surface of an object? so that you would have a top, side and bottom mapping, instead of x,y,z?

Return to “Guides & Tutorials”



Who is online

Online users: No registered users and 3 guests