Pass shader Properties to overrideMaterial

Hello,

in my older thread I managed to solve the problem with different ShaderPasses for different object types:

Immediately after that a new problem arose. In the overrideMaterial of my DrawSettings i pass a material with a shader in which i need to use “_MainTex” or other Properties of the original shader I try to override.

A little research led me to this post, that claims the overrideMaterial will NOT get the Properties passed: Replacement Shaders in URP

Is this still true or will the properties now get passed on? If this is still not possible what would be a workaround? Would be pretty annoying to create a overrideMaterial for every single material i need to use in my CustomPass, and therefore also execute the commandBuffer for every Material…

Any Ideas?

According to this (quite old) post, this was not a problem and pretty easily done in the default render pipeline:

Anyone?

Seems like a pretty important replacement shader technique is missing in URP or not working.

Does anyone have any information whatsoever? Maybe the Unity Team? Like am i just missing something obvious or doing it wrong or is this issue even known and will be fixed?

Thanks in advance for any answer actually :smile:

Sorry I didn’t see this sooner. Are you using a CommandBuffer (eg in a ScriptableRenderPass)? If so, I also ran into this issue, and the only thing I could get to work was using global properties. Eg…

[DomainSafe] private static readonly int ID_LIGHT_CHANNEL = Shader.PropertyToID("_burningmime_lightChannel");
// ...
cmd.SetGlobalVector(ID_LIGHT_CHANNEL, channelForLight(iLight));
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, material, 0, 0);

Thanks for the reply!

Yes I use a CommandBuffer in a custom ScriptableRenderPass. I also thought of using global properties at first, the problem just is this won’t work out for me since i need to access the _MainTex of all involved materials, so global properties aren’t really an option, since it would result in a custom global property for each distinctive material.

I ran into this because I need to compute a custom depthTexture for creating a fog effect that blends to my procedural sky at a certain distance. So for different kinds of material types i need to compute a custom depth pass. For example for the tree leaves i need a transparent cutout pass, for my billboard trees i need a custom shader since they use a geometry shader pass, for my water shader i need to ignore depth at all and so on.

All basically works fine, it now just comes down to the problem that I can’t access the material properties in this situation like you would normally be able to in the standard render pipeline when using replaceShaders.

I am using 2020.2.2f1 btw. so maybe this has been fixed in a newer version by now?

Anyone from the Unity-Team?

I would really need that feature or at least need to know anything about it, is this a known problem to the Unity-Team, is it an abandoned problem, is there a workaround, did i miss something obvious, just anything would be great. Since it works in the default render pipeline there must be some information available?

Unfortunately there is not an option to do this with overrideMaterial. I’ve done similar pass (custom depth pass for occlusion effect) and only solution that actually worked was to add another pass to all your material shaders with custom LightMode like this :

Pass
{
Name "CustomDepth"
Tags{"LightMode" = "CustomDepthPass"}

... rest of pass
}

In scriptable pass you can filter renderers by shadertagsid (that’s what unity does in depth prepass or opaque pass) using your newly created lightmode.

In this case you’re custom shader pass has access to all properties. Big donwside is that all shaders have to be scripts Maybe you’ll find it helpful :slight_smile:

1 Like

Ahh ok I didn’t think of that before, that might actually solve the Problem for my case. A bit more annoying but still viable I think, thanks a lot! :slight_smile:

Tried adding a custom light mode before but for my previous problem, will give an update if it works here.

So this basically works out well, thanks again. Just a different Problem arises now… again :eyes:

I would now have to add custom passes to some built-in shaders like the URP Lit shader or the SpeedTree shader, which i tried to do by just simply adding a pass after all other passes. The problem is the compiler just rewrites the shaders and deletes my custom code - which i kind of expected already and also didn’t sound like a good idea in the first place anyway.

I guess i could just add an extra material to all objects with my custom depth pass, that just seems like an unnecessary performance impact that i would like to avoid if possible. Also it would require creating a distinct material with my custom pass for every type of tree leaf for example, which i kind of tried to avoid in the first place…

Any suggestions?

1 Like

Just tried to simply copy the SpeedTree8 shader into a seperate folder in my project and editing it in there works out so i guess i finally found a viable solution - seems a bit unwise to not use the actual built in shaders, since I might have to edit them again in case I update URP for example but I guess for now this is a quite elegant solution.

URP updates are changing a lot inside built-in shaders. That’s why I stick to one version (URP 10.2). Unfortunately, if you want to do some specific effects the best idea is to fork URP repository and customize it to your needs. You can change whole shader libraries adjusting things to your specific needs. I didn’t find better solution so far :slight_smile:

1 Like

Also stuck in this issue, and things work well in built-in shaderReplacement.:frowning:

I find a way may help. Use AOVRequest to extract MaterialPropertie’s alpha channel to screen-space AOV buffer, than we can clip the rt, and use it as a mask on transparent fragment.