- Home /
How to write unlit surface shader?
Ive written a clipping unlit surface shader for something Im working on. It works great except that I get that annoying "shader wants normals" error. I don't use the normals. How can I tell shaderlab that they aren't necessary for this shader?
Code is below for reference
Shader "Custom/ClippingUnlitTransparent" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_cliprect ("Clip Rectangle", Vector) = (-1,-1,-1,-1)
}
SubShader {
Lighting Off
AlphaTest Greater 0.5
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Unlit
#include "UnityCG.cginc"
half4 LightingUnlit (SurfaceOutput s, half3 lightDir, half atten) {
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
sampler2D _MainTex;
float4 _cliprect;
struct Input {
float2 uv_MainTex;
float4 screenPos;
};
void surf (Input IN, inout SurfaceOutput o) {
float2 screenPosition = IN.screenPos.xy / IN.screenPos.w;
screenPosition.y = 1.0 - screenPosition.y;
screenPosition.xy = screenPosition.xy * _ScreenParams.xy;
if ((screenPosition.x>=_cliprect[0])&&
(screenPosition.x<=_cliprect[2])&&
(screenPosition.y>=_cliprect[1])&&
(screenPosition.y<=_cliprect[3]))
{
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
} else{
o.Albedo = float3(0,0,0);
o.Alpha = 0;
}
}
ENDCG
}
FallBack "Diffuse"
}
Answer by mtalbott · Jun 18, 2014 at 03:03 PM
just FYI, I found that the s.Albedo value in the lighting shader function was at double the correct intensity. i.e. //c.rgb = s.Albedo; //should be: c.rgb = s.Albedo*0.5f;
Actually, disregard the previous comment. Even s.Albedo*0.5f returned an over cooked color. $$anonymous$$y solution is to store the unlit color in the Emission slot (o.Emission = c.rgb) in the Surface function and in the LightingNoLighting Function just return a blank color (fixed4(0,0,0,0)).
You're right. I think you should update your answer to reflect it.
Yeah! It should like this
void surf (Input IN, inout SurfaceOutput o) {
//o.Albedo = _Color.rgb * _Color.a;
o.Emission = _Color.rgb;
o.Alpha = _Color.a;
}
fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten) {
return fixed4(0,0,0,0);//half4(s.Albedo, s.Alpha);
}
Answer by FlyingOstriche · Jan 12, 2013 at 09:04 PM
You can also create a no lighting shader function.
#pragma surface surf NoLighting
...
fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten)
{
fixed4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
This last comment needs to be upvoted SO much! Totally fixed my not-unlit-shader :D
Thanks mtalbott
upvote that comment! fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten) { return fixed4(0,0,0,0); }
Ins$$anonymous$$d of setting the Emission and letting the forward add passes crunch over a 0'd albedo, just use the "noforwardadd" command, like so:
pragma surface surf NoLighting noforwardadd
noforwardadd doesn't work. @mtalbott's comment works well.
Is LightingNoLighting called AFTER the surface function ? $$anonymous$$y object stays black no matter what I'm doing with the SurfaceOutput in the surface function :/
Answer by MyPad3DAssets · May 24, 2018 at 11:26 PM
For anyone else that comes across this problem and is trying to make this work, the best solution that I found was to add a "noambient" pragma to @FlyingOstriche's solution. This makes it so that the lighting function uses just the base colors as intended
#pragma surface surf NoLighting noambient
and
fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten) {
return fixed4(s.Albedo, s.Alpha);
}
This should provide a good look for an unlit material. The reason that the colors were blown out in earlier solutions was because the ambient light was being added to the final output after the lighting function. "noforwardadd" could also be used, though I doubt its very necessary.
Answer by ScroodgeM · Jul 14, 2012 at 01:45 PM
http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaders.html
try to disable all lighting method listed there.
also, best way to write shader that doesn't interact with lighting is to make a vertex/fragment shader, not surface.
also, in your shader you really interact with lighting - try to light your model by more than 1 light source and you'll show over-lighting effect. so you can just ignore light function (return;) and write color to emission in frag method or use amient color instead.
In my case, I put the tag "novertexlights" and it worked.
Answer by sgoodrow · May 01, 2015 at 04:06 AM
In addition to use a NoLighting shader function, you might also like to add noforwardadd, so that point lights do not affect the albedo. The Emission control ignores forward add passes, so that is a workaround that accomplishes the same thing, except the additional pass still takes place with 0s in the Albedo, resulting in 0 in the additive output.
Better to just skip it entirely!
Doesn't work in Unity 5.6. The Unity 5.6.1 message says: Surface lighting model 'NoLighting' not found. Available models: BlinnPhong, Lambert
*Bump.... same issue here with me. I was trying learning shaders and came across this 'No Lighting' Problem. $$anonymous$$y holographic shader seems to be working fine but i dont want lights to be affecting it. But sadly that directive seems to be not working for me. Has anybody have suggestions? Iam tried it on unity 5.6.0 and 2017.1. I have read some answers with people using it on 5.6.3. Iam posting this as another question though for now. $$anonymous$$aybe iam missing something.