Reputation: 41
I have a plane mesh (a custom trail) that uses an advanced shader in URP and I need it to detect overlaps and change it's color to red.
The application is 3d and the trail is always drawn at y zero. The user needs to have visual feedback when the trails overlap so they can fix their route. I am trying to do it using a Stencil Shader but stencil for URP doesn't work like in built-in renderer.
This question has exactly what I need to do, but the shader doesn't work in URP. Whatever shader I try to do multiple passes of stencil it just renders the first pass and never detects the other passes.
In URP I was able to use stencil only with one writer shader and one reader shader and Replacing the stencil buffer (adding doesn't work).
Since it can't detect the two different passes I can't even do it using doubled objects with writer and readers and my reader having a pass for the advanced shader and one for the flat red color.
Remember, I need a bunch of plane trails to detect overlapping and self overlapping. Can anyone make it work or suggest another approach? (I must finish this at my job)
Upvotes: 1
Views: 2408
Reputation: 41
Found two ways of doing it.
After some hours of searching I found this thread where Invertex says that:
URP doesn't automatically run all shader passes for performance reasons. You could make a second material that has the other pass enabled and add it to the object's material list. It would effectively be the same.
So I made a Shader with:
Tags {
"RenderType" = "Opaque"
"Queue" = "Geometry-1"
}
Pass
{
Stencil {
Ref 0
Comp Equal
Pass IncrSat
Fail IncrSat
}
}
//here the code that renders when not overlapping
And another shader with:
//this one is in "Queue"="Geometry"
Stencil {
Ref 1
Comp Less
}
//here the code that renders when overlapping
Then I place both shaders in my prefab. Since it has only one submesh, it renders both materials in it.
The method above is an ugly and costly workaround, so I kept searching on the problem
The solution I was after was in this thread. We can use "LightMode" tags like "DepthOnly", "Meta", "SRPDefaultUnlit", "UniversalForward", etc... to bypass the passes in URP. They will render in a specific order, no matter in which order they are on your file. You are limited to a few but it solves it in my case.
Since "SRPDefaultUnlit" will render first for all objects and then "UniversalForward" will render for all objects, I can use this to my advantage.
Inside the first pass:
Tags
{
"LightMode" = "SRPDefaultUnlit"
}
Stencil
{
Ref 0
Comp Equal
Pass IncrSat
Fail IncrSat
}
//here the code that renders when not overlapping
Inside the second pass:
Tags
{
"LightMode" = "UniversalForward"
}
Stencil
{
Ref 1
Comp Less
}
//here the code that renders when overlapping
NOTE: If you're using the Built in Render the LightMode will not work, you'll have to use the default one and change the passes order in code to get the desired effect. You'll put the overlay one after the base pass.
This seem to be the final solution for me but feel free to contribute as you may help other people in the future.
Upvotes: 2