Great idea! Unfortunately, at least in 2019.2.5f1 it appears Unity still overrides the Grass shader even with this change! When the asset gets loaded it’s stomping on the shader overrides and setting them back to null. >.<
Then I guess it works starting from 2019.2.6, because is the one I currently use. I also tried it on 2019.3.0 and seems to work the same. Don’t know how to fix it for older versions tho :S
Also, one thing about that bug report that @xdegtyarev filed. As worded, Unity was indeed correct to close it as “by design” as the bug report is on automatic replacement of the terrain shader. With 2019 you can assign a material directly on the Terrain component rather than needing to override it via shader name. The note on the issue is it now uses “standard asset referencing”, which is accurate. The problem is (as @Gufetto 's workaround seems to show) they also changed the grass shaders to use “standard asset referencing”, but didn’t expose those properties anywhere for users to assign.
So the real issue isn’t really that automatic overriding doesn’t work, it’s that there is no exposed way to override it!
@bgolus for me it was critical to do it in an older way, as we added additional render types to built-in shaders to be able to draw them with specific replacement shaders for thermal/segmentation during dataset generation. We have tons of terrains in asset bundles that could not be modified now.
@xdegtyarev Yeah, I can understand that, as it’s something that’s breaking backwards compatibility, and I don’t think it was explicitly called out in any patch notes (or I missed it). But it is a subtly different case than the one this thread is about, which is something I (and I think other people) missed.
Basically, the specific issue of “there’s no obvious way to override the grass shaders” wasn’t what Unity called “by design”. Someone needs to issue a bug report specifically on overriding the grass shader as it’s a different problem.
@bgolus I’ve found the closest match of an issue on forums and submitted reports of exactly my problem. So I agree with you, it makes sense to create another issue on tracker for grass.
@xdegtyarev Yep. It is technically the same issue in terms of the cause; Unity no longer does name matches to search for shaders internally. I reported the grass issue separately and it got closed as a duplicate and “by design” pointing at the issue you reported. >.<
Not your fault. Just frustrating. I already responded to the e-mail they sent me explaining why the closed it arguing my case for why it’s different, but it can be hard to get things past the “first defenders” when there’s similar but subtly different issues that have already been marked closed, especially when they’re “as designed” since it’s not even an issue of regression testing.
@VitaSkr I don’t know if you’re paying attention to this topic any more either, but it’s Case 1214113 if you want to reproduce the issue. Not sure if I should resubmit the bug with different wording to make the issue more clear.
@bgolus Accept my apologies for the delayed reply. I will take a look at this issue and will update you as soon as possible. Also, if you have any other details about the issue, let me know.
Cheers,
Vita
Thank you for the reply.
Concisely: Unity 2019 removed overriding of terrain shaders via shader name and replaced it with direct asset referencing. For the terrain’s main passes this can be modified by using a material with a custom terrain shader. However the terrain’s Grass, Grass Billboard, and Vertex Lit detail shaders, those references are not exposed so they can not by user set when using the built in rendering paths.
The Terrain shader used to reference those detail shaders through the terrain shader itself and its “dependencies” during the Unity 4.0 days. This was broken sometime during Unity 5.0, which was fine because almost everyone was using shader name implicit overriding instead. Now neither work and there’s no official way to set those shaders outside of the SRPs which do have those shader asset references exposed as part of the renderer asset class. There needs to be some equivalent for the built in rendering paths, preferably per terrain like the terrain material setting.
Took me a while to figure this out, but it’s actually intended behavior and works properly as expected. The settings for the terrain shaders are now included in the HDRenderPipelineEditorResources asset. You’ll have to create your own asset so you can edit the shaders in the fields, but it works properly and actually is a pretty straightforward system. Hope this helps!
This does fix the specific issue described in the original post. For the LWRP / URP there’s a similar RenderPipelineEditorResources asset.
However:
It’s broken for the built in rendering paths.
Definitely, I have been using this thread as a reference for the HDRP so I wanted to point this out if it was relevant to HDRP folks.
I’ve run into this same issue, using the builtin rendering path. Totally agree that there should be a grass material parameter on the Terrain settings just like there is for the Terrain material if it’s not already on the roadmap. Without it, I am unable to override the Waving Grass shader on Unity 2019.2.6f1 using the path name method. As you discussed it appears they closed off this override function but never exposed the grass and vertex lit shaders to users, which is extremely problematic because it’s removing functionality that used to work.
I tried out the script from Gufetto but I couldn’t get it to work. I only made a few tweaks to where the converted Terrain is output, and the asset was created successfully. But I got the error “Assertion failed on expression: m_Shape == NULL”. Not sure what that means, but it’s probably one of the terrain parameters in the asset because it seems to match the other JSON properties you edit in the script. The terrain data was set correctly, but when I made changes to the Shader I set it to it didn’t update, and I didn’t see any differences in the grass, even after setting the color to solid red. Maybe I’m missing something but if not it might be the error which is giving me trouble.
Then I ran into a problem because I could not for the life of me find a way to set the Terrain Component’s data outside of code. So I wasn’t able to revert my terrain back to the un-converted original state. I made this little script which is an Editor window to do just that:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
#if UNITY_EDITOR
public class MSetTerrainData : ScriptableWizard
{
[Header("Data")]
public Terrain terrainToSet;
public TerrainData terrainData;
void OnWizardUpdate()
{
}
void OnWizardCreate()
{
//function to execute on submit
if(terrainToSet != null && terrainData != null)
{
terrainToSet.terrainData = terrainData;
}
}
[MenuItem("Window/Terrain/Set Terrain Data")]
static void MakeBillboard()
{
ScriptableWizard.DisplayWizard<MSetTerrainData>(
"Set Terrain Data", "Set");
}
}
#endif
Hopefully that helps anyone that needs to set terrain data manually.
I just seem to keep hitting roadblock after roadblock with my project and what I’ve learned is apparently never start your project on the latest version of Unity since it’s possible to be missing dozens of crucial features which can completely halt progress. I’m sure there is some workaround, if I could figure out the error and get the script working perhaps, but I’d much rather just set the material through a parameter. I’ve already wasted over an hour just trying to override the shader using different methods but no luck. I’m probably going to move to 2019.3 eventually for Cloth fixes, so I really hope that the grass shader will be exposed for the builtin pipeline by that point.
To change TerrainData in the inspector, you have to enable Debug mode (by clicking on the top right button), then select the terrain and it will be exposed there.
Huh… I’ve been using Unity for 8+ years and I never knew that existed. Thanks!
Any idea what the “m_shape == NULL” is or if that could be related to the shader not being set on the duplicate data? I didn’t think my few changes could really impact the individual properties but I could be mistaken.
I have no idea about the m_shape thing, I’m sorry. It would be so easy for unity to just expose the grass shader property and avoid so many problems, but whatever…
I’m trying to get this to work for URP. Using 2019.3.0f6, I can create a new RenderPipelineAsset, but it seems the default RenderPipelineEditorResources asset is stuck in “Packages” and uneditable. Was there a way you’ve seen this asset created? And if so, how can I assign it to my RenderPipelineAsset to use those editor resources?
Thanks
I am having the same problem in 2019.2 not using LWRP
Is there an update plan?
In Unity 2019.3.6f1 I still can’t override the terrain billboard shaders! It only picks it up if you create a completely new terrain, but then the custom shader only works in Unity Editor not if you build it.
What is going on? Is there no way to override billboard shader???
So I created a bug report for this with a test project and they were unable to reproduce the problem. Oddly, after reopening the test project I had created I to show the problem I could not reproduce the problem anymore and the terrain properly used the shader I had included though I did not try making a building in that project. Part of the problem is in trying to find a work around I’d partially broken the override shader so I don’t know if it’d magically fixed itself while I was fiddling with it.
Those having problems, can you try restarting the editor and see if the grass starts magically using the new shader.