- Home /
Rewrite shader so that the Sprite-Diffuse shader doesn't take incidence angle into consideration when applying lighting?
Basically I want a sprite to apply lighting without taking the incidence angle into consideration. I only want the lighting to take range between light source and surface into consideration, so that a light actually illuminates the back of a wall or sprite.
This would be very easy to do if the surface-shader wasn't hiding the math behind the lighting. Is there any way to get the shader without the surface part?
Or is there any way to do this in the surface shader?
Or am I screwed because Unity reasons?
Answer by TruffelsAndOranges · Jun 23, 2016 at 09:16 AM
Solved it.
You can actually override Unity lighting!
Code that does what I want:
Shader "Sprites/DiffusePoint"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf PointLambert vertex:vert nofog keepalpha
#pragma multi_compile _ PIXELSNAP_ON
#pragma shader_feature ETC1_EXTERNAL_ALPHA
sampler2D _MainTex;
fixed4 _Color;
sampler2D _AlphaTex;
half4 LightingPointLambert(SurfaceOutput s, half3 lightDir, half atten) {
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * atten;
c.a = s.Alpha;
return c;
}
struct Input
{
float2 uv_MainTex;
fixed4 color;
};
void vert (inout appdata_full v, out Input o)
{
#if defined(PIXELSNAP_ON)
v.vertex = UnityPixelSnap (v.vertex);
#endif
UNITY_INITIALIZE_OUTPUT(Input, o);
o.color = v.color * _Color;
}
fixed4 SampleSpriteTexture (float2 uv)
{
fixed4 color = tex2D (_MainTex, uv);
#if ETC1_EXTERNAL_ALPHA
color.a = tex2D (_AlphaTex, uv).r;
#endif //ETC1_EXTERNAL_ALPHA
return color;
}
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
o.Albedo = c.rgb * c.a;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Transparent/VertexLit"
}
The LightingPointLambert function is the important function.
This was really useful for me and did sort of what I was looking for too - except using this makes all of my sprites semi-transparent and they all have semi-transparent black backgrounds too... I don't really know what's causing it or how to fix it, does anyone have any ideas?