Okay, I tried implementing that, but realized that I'm at a complete loss on how to remove the lighting.
I just recently figured out how surface shaders work, after experimenting a lot with strumpy's shader editor and reading all the confusing material on the net.
I realize I could probably write my current surface shader as a fragment shader, but I can't get my head around how, and if it will have any benefit at all. The shader is currently combining the light from the scene, with a special screen overlay light texture (that is larger than the screen, to avoid certain artifacts). It also uses a "Specularity" texture, that affects how much of the light texture it picks up.
Shader "MapLitAlpha"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_MainTex("Base (RGB) Tranparency (A)", 2D) = "gray" {}
_Specularity("Specularity (RGB) Emission (A)", 2D) = "gray" {}
_Light("Lighting (RGB)", 2D) = "gray" {}
_Cutoff("Alpha cutoff", Float) = 0.5
_LightColor("Fake Lighting", Color) = (0.5,0.5,0.5,0.5)
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="TransparentCutout"
}
Cull Back
ZWrite On
ZTest LEqual
ColorMask RGBA
Fog{Mode Off}
CGPROGRAM
#pragma surface surf SimpleLambert nolightmap noforwardadd approxview halfasview alpha decal:blend vertex:vert
//#pragma target 2.0
// Warning: Modified: don't use Strumpy anymore!
float4 _Color;
sampler2D _MainTex;
sampler2D _Specularity;
sampler2D _Light;
float _Cutoff;
struct EditorSurfaceOutput {
half3 Albedo;
half3 Normal;
half3 Emission;
half Specular;
half Alpha;
//half3 Gloss;
//half4 Custom;
};
half4 LightingSimpleLambert (EditorSurfaceOutput s, half3 lightDir, half atten) {
half NdotL = dot (s.Normal, lightDir);
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
c.a = s.Alpha;
return c;
}
struct Input {
float2 uv_MainTex;
float2 uv_Specularity;
float4 screenPos;
float depth;
};
void vert (inout appdata_full v, out Input o)
{
v.tangent = float4(1,0,0,0);
// Front is darker than back
float depthFactor = 0.4 - ( _WorldSpaceCameraPos.z - mul(_Object2World, v.vertex).z )*0.2;
o.depth = depthFactor;
// Init to fix dx11 errors
o.screenPos = float4(0,0,0,0);
o.uv_Specularity = float2(0,0);
o.uv_MainTex = float2(0,0);
}
void surf (Input IN, inout EditorSurfaceOutput o)
{
float4 Tex2D0 = tex2D(_MainTex,(IN.uv_MainTex.xyxy).xy);
float4 Albedo = Tex2D0 * _Color;
float4 Tex2D2 = tex2D(_Specularity,(IN.uv_Specularity.xyxy).xy);
// Calculate sizes and margin
float2 Size = float2(2048, 2048);
float2 Margin = (Size - _ScreenParams.xy)*0.5;
Margin /= Size;
// Map back to texture
float2 SamplePos = lerp(Margin, 1-Margin, IN.screenPos.xy);
float4 Tex2D1 = tex2D(_Light,SamplePos);
float4 Emission = Tex2D1 * 8;
Emission *= Tex2D2.a;
Emission *= Albedo;
o.Albedo = Albedo;
o.Emission = IN.depth*Emission;
o.Normal = float3(0.0,0.0,1.0);
o.Alpha = Tex2D0.a;
}
ENDCG
}
Fallback "Transparent/Cutout/Diffuse"
}
On another note -
I've put all characters into the same collection now, but it doesn't seem to make any difference for the draw calls. It still adds 11 draw calls per character, and also 11 "saved by batching". I don't use atlas spanning.
Maybe I'm doing something wrong with the shader, but if I switch between my shader and the tk2d CutoutVertexColor (and have my whole screen filled with characters = ~5000 draw calls), I only get a difference of 2 draw calls for the entire scene, and the difference in performance in the profiler is immeasurably small, so I don't think it really matters, or is the bottle neck here.
If I switch to BlendVertexColor, the DrawCalls go down to almost nothing (lets say 1 or 2 draw calls for everything). But I have the impression that the order of the sprites is then not guaranteed. Do you have more suggestions, how I could lessen the decrease of performance?