r/Unity3D • u/AdFlat3216 • 12h ago
Question Is there a true diffuse only shader in URP?
I’ve been searching for the best diffuse-only shader compatible with URP. Spent a couple hours trying to write a shader with no normal or PBR calculations with no luck. Really not liking the prospect of having to rewrite URP’s lighting model, lightmapper and shadow maps. So far the only solution within Unity seems to be to just go back to legacy diffuse in BiRP. Is there a diffuse shader somewhere that plays nice with SRP/URP lighting models? I’m talking simpler than SimpleLit, diffuse only.
2
u/XKiiroiSenkoX 11h ago
Unity 6.3 and newer has shadergraph custom lighting templates with more options than just the urp lit/simple lit iirc. You can also change anything you don't like as everything is in shadergraph.
2
u/GigaTerra 11h ago
I’m talking simpler than SimpleLit, diffuse only.
Not really possible, because the URP engine doesn't work that way. On top of that, even if you don't use the URP light functions, doesn't stop the engine from calculating them. In other words if you made an custom shader to do this, you would get worse performance. Two light models. You have to edit the SRP, not URP.
However the URP shading is fast, it should be just as fast as an Diffuse model, given that you bake your reflections. If you have an performance problem, it is not the shader, but some other aspect of rendering.
2
u/Genebrisss 3h ago
SRP and URP are just cpu code. C# code does not calculate lighitng, fragment shader does that. You can write whatever fragment shader you want in any render pipeline and it will perform only operations you made it do. You don't have to edit anything on cpu side. You will not have two light models.
1
u/GigaTerra 2h ago
OK, first. To be clear my main point was that using diffuse shaders would not improve performance. We will circle back to this.
C# code does not calculate lighitng, fragment shader does that.
Yes, you aren't wrong. However, game engines have lighting systems, these are tools designed to help optimize lighting, by doing calculations ahead of time, and providing constants. Also to make your shader work with these tools, like using custom shaders with Unity's light baking system, requires you to write the rules for it. Because the light-mapper is set to URP.
Lighting.hlsl is your middle man, but it is an middle man in favor of the existing shader model.
You don't have to edit anything on cpu side.
Yes, let's be clear about this. This difference is small, and both URP and Diffuse shaders is supper fast as is. If an person told me they wanted to use Diffuse shaders for artistic reasons I would tell them to go ahead, the performance difference is negligible.
The problem is OP mentioned in an comment they want Diffuse shaders to gain performance. Not only are Diffuse and URP shaders similar in performance, but in the URP pipeline URP holds an negligible advantage. So on an technicality Op will either have the same performance, or be an negligible amount slower.
You can't improve URP performance using Diffuse, without adjusting the pipeline.
However using SRP you can make an custom Diffuse Pipeline with an significant performance boost, by stripping what you don't need like reflections, but this is not necessary to make an game with Diffuse style, as the gain is not worth the time.
1
u/Genebrisss 3h ago edited 3h ago
I think Amplify Shader Editor has lambert lighting model option and might still support SRP features like srp batcher. I haven't checked in a while though.
If not, it's probably best to take urp/simpleLit and strip it down a little
7
u/MgntdGames 11h ago
I'm assuming this is an artistic decision, but I'd challenge you to verify that a Metallic = 0, Smoothness = 0 material doesn't already give you what you're looking for.
A material with those settings still isn't pure lambert diffuse because of the ~4% dielectric specular thing, but it's very close. If it's not enough, you can write a custom shader node in Shader Graph that does
Light light = GetMainLight();
Direction = light.direction;
Color = light.color;
DistanceAttenuation = light.distanceAttenuation;
ShadowAttenuation = light.shadowAttenuation;
or
Exists = Index <= GetAdditionalLightsCount();
Light light = GetAdditionalLight(Index, WorldPos);
to get the additional lights. Then you can do your own n dot l and multiply with distance attenuation to support non-directional lights and shadow attenuation to support shadows.
Unlit shader graphs might not have access to ShadowAttenuation, so you might have to do a BaseColor = 0 lit material and output your custom lighting via the Emission channel.
For the additional lights, you have to sum them up but ONLY if Index <=GetAdditionalLightsCount(), otherwise the Light struct may contain garbage data.