Is there a way to create custom shaders for terrain in HDRP currently? I wasn’t able to get Lit materials to work with Terrain in HDRP either (It does seem to work but I can’t use terrain layer)
If I do use Lit material I can’t access the splat map or terrain layer by default either, is there a way to get it working currently?
Technically, nothing prevents you to assign the HDRP/Lit to a material and assign it to the terrain, but indeed, it will totally ignore the terrain layers.
HDRP comes with a terrain compatible shader, doesn’t it fit your needs ?
An alternative hack is to use the HDRP/LayeredLit shader for the terrain, and assign the terrain splat map to the layer map on the material. But it will ignore the terrain layer settings, you will have to set up everything on the material itself, and is limited to 4 layers.
Finally, you can create a shadergraph that you assign to the terrain material, but once again, you’ll have to assign the terrain splat maps and the different layer textures to it manually.
I think it should be possible to automagically grab them in the shader using custom function nodes where you declare the proper shader variables in the code, but you’ll have to try that out.
Check the video I linked above, things like shader based random noise and other things for better terrain shading aren’t available in HDRP terrain shader by default and it can’t be achieved just using paint techniques or something like Gaia (asset store package).
So, I really wanted to try and create custom terrain material for my needs
Incase you never found out the answer i’ll go ahead and necro this post since it comes up pretty high on google rankings.
You can simply ignore that warning about terrain tangents, they do exist in HDRP atleast, but the Unity shader doesn’t use them and they presume you must be using a shader that functions identically to the unity terrain shader, so it’s safe to completely disregard that warning as it’s not true if your shader does use them.
As to why Unity has decided to keep rolling with 10 a ten year old shader with more TODO, Hack, Bug comments than comments about how it does work or why they think that their shader is so good you’d never want to replace it is anybody’s guess but you Can make your own and do it with Shader Graph to boot.
Steps you’ll need to do to achieve this:
Find all the relevant variables in the unity terrain shader, declare those as unexposed variables in your shader graph
Sample them for the most part as they do but instead of using the derivative functions for tiling you use 1/tiling + offset method for the UV sampling.
Create a component that grabs the relevant data from a given terrain compnent: splatmaps, terrainlayer properties etc
Apply that data to a material property block, then apply that MPB to each terrains material.
Limitations, i was not personally able to get instancing to work in SRP but i made the shader itself compatible with SRP Batcher and keep the terrain size small and handle culling for those terrains myself. (Which is ludicrously fast even on the CPU if you use Jobs&Burst which are a godsend example of good tech Unity has)
Visual examples of a custom HDRP Terrain Shader Graph in a soon to release production:
Without PP, custom heightmap sampling with identical layer weights demonstrating 4-6 layers in single spot:
Obviously Unitys heightmapping isn’t designed to be able to do this and ergo looks worse than it would in actual use since you wouldn’t paint 6 equal weights of layers with the Unity shader. As such the shots were taken as demonstration of what you Can do when you have a custom terrain shader. In addition to that we now have the ability to have fully global effects since 100% of the environment shaders we have are now subgraph modularized shaders.
Since we’re releasing this very month we’re on 2020.3 LTS and not the newer tech branches where the Tessellation stage is an in-built feature of Shader Graph i cannot say for certain. I don’t see an obvious blocker.
If it’s worth developing your own Terrain shader you should consider your priorities first and foremost, what version of Unity will you be releasing on and how important are the features you’re looking to get out of it. If you already have a suitable in-place system for doing that it may or may not be worth the hassle.
But if you don’t want to dedicate the time to develop your own terrain shader graph only to find it potentially may not work with Tessellation and that is a feature you really want, i can do a test run with ours and see if it works but that’ll have to wait until may since i’m rather busy until then. If you can wait for that and want to know for sure then fire up a PM at me here at the forums and i’ll add it to my calendar.
Despite I wasn’t the one being asked but I cannot withhold myself - 8 textures limit. Seriously it is a massive dealbreaker for me. We have to stick with solutions like Microsplat which are far superior in terms of performance and extensibility for that matter. Why do you guys try not to see what is the real problem with your approach?
Who goes around and hand paints their entire landscape? Unity should come with a proper shader for landscapes that takes different materials and combines them based on presets.
The fact that I can find numerous videos explaining how to do this in Unreal Engine using blueprints but not a single video on how to do this in Unity is annoying.
It makes me think the terrain tool is essentially useless and I am better off just making a Terrain in Blender and importing it into unity as a mesh and then using a shader to apply materials.
Even that I mean… I might as well just use Unreal Engine at this point.
Nothing prevents you to create a Lit shadergraph, assign it to a material, and assign this material to the terrain.
You can then in the shader do some procedural layering (similar to what the videos you’ve mentioned are doing) by blending textures based on : altitude, world position, slope … without ever using the layer painting.
Not directly, but you can assign the splatmap texture from the terrain (visible as sub asset of the terrain in the project window) as texture input for your material, as well as the different layers textures.
You’ll then be able to sample the splatmaps and layers textures from you shader and work with it.
This is how i did it, i simply have an additional component on every Terrain instance, it automatically samples the splats/textures and applies them to the Terrain material via a property block. In editor it also monitors for changes to the Terrains dirty state and whenever it’s dirty it reapplies the splats/textures.
It’s a bit of a hassle to reverse engineer the shader + the terrain components way of doing things but it’s not pure blind dev since both do have the relevant portions exposed in code for us.
As a bonus since i now have a component on each Terrain i made my own culling solution on them which disables the entire terrain if it isn’t in view or in the Main Directional Light cone. Which gives quite a few precious frames if you use high quality Terrain extensively.
Since this thread is alive again, here’s my opinion on the matter of Shader Graph support for terrain.
I’m quoting your reply/question to the OP from 2021 - “doesn’t it fit your needs”? It’s a totally fair question because on the surface the built-in shader and the generally upgraded terrain system is pretty good. But as is often the case in Unity, the given feature is quite close to what you need, but then there is just that one thing you want to do, and can’t get (and I’m not picking on Unity, I’m sure the “other engine” has similar issues).
In our case (with Farm Folks), we almost instantly needed 12 layers in the terrain - and guess what… HDRP for some reason is hard-coded to 8. So I had to copy and paste all the source textures, and hand modify the source so that 8 means 12, so I basically hacked 12 layers into it, and thank goodness the terrain component’s UI was quite happy to live with this (and not also forced to 8).
Now I imagine in my head this utopia, where I click Create → Shader Graph → Terrain. On the main settings in this shader graph, I select “Number of layer” → 12. Or possibly a Terrain Layers node for sampling layer weights, with a dropdown selecting how many layers to expect. Then you have some nodes for sampling and blending the splats according to the layer weights. Etc. It would be so nice to have a dedicated Shader Graph for advanced terrain materials.
So back to the original question - I actually think that in most cases, the built-in shader, material, terrain component settings, etc… it does not meet “the requirements” because people have very specific requirements. If custom Shader Graphs are often required in for general objects, foliage, characters, and everything else, then it stands to reason that such custom Shader Graphs would also be required for terrain… I mean… why not?
Unity planned for terrain shader graph integration, but the person working on it left unity I believe in 2021, someone else at unity picked up the work at that time, but it seems that nothing came out of it/the idea was abandoned. Not sure what happened. A proper integrated solution would be great for sure.