Antoft
1
is it possible render shadows with deferred render, when I'm using this custom version of the toonLighted shader.
Shader "Toon/bumpLighted" {
Properties {
_Color ("Main Color", Color) = (0.5,0.5,0.5,1)
_MainTex ("Base (RGB) Illumin (A)", 2D) = "white" {}
_BumpMap ("Normalmap ", 2D) = "bump" {}
_Ramp ("Toon Ramp (RGB)", 2D) = "gray" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 400
CGPROGRAM
#pragma surface surf ToonRamp
sampler2D _Ramp;
// custom lighting function that uses a texture ramp based
// on angle between light direction and normal
#pragma lighting ToonRamp exclude_path:prepass
inline half4 LightingToonRamp (SurfaceOutput s, half3 lightDir, half atten)
{
#ifndef USING_DIRECTIONAL_LIGHT
lightDir = normalize(lightDir);
#endif
half d = dot (s.Normal, lightDir)*0.5 + 0.5;
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
c.a = 0;
return c;
}
sampler2D _MainTex;
sampler2D _BumpMap;
float4 _Color;
struct Input {
float2 uv_MainTex : TEXCOORD0;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// o.Alpha = c.a;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
o.Emission = c.rgb * tex2D(_MainTex, IN.uv_MainTex).a;
}
ENDCG
}
Fallback "Diffuse"
}
Why it won't work the same
As per the docs, a deferred rendering shader's lighting function must have the form:
half4 LightingName_PrePass (SurfaceOutput s, half4 light);
Because the computation of toon lighting is dependent upon the dot product of the surface normal and the light direction (the cosine of the angle between the light and the surface) and pre-pass lighting doesn't provide us with the light direction, we cannot compute the same lighting exactly.
Approximation by clamping luminance (like a posterize)
What pre-pass lighting does provide us with is the pre-calculated lighting values as light.rgb. If we were to use the luminance of the lighting to index a different ramp, you could get something similar (but still not the same) with the addition of something like:
#include "UnityCG.cginc"
inline half4 LightingToonRamp_PrePass (SurfaceOutput s, half4 light)
{
half spec = light.a * s.Gloss;
half d = Luminance(light.rgb);
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
half4 c;
c.rgb = s.Albedo * light.rgb * ramp;
c.a = 0;
return c;
}
But the ramp used would have to account for luminance rather than cos(angle) *.5 + .5; or you'd have to multiply the luminance by 0.1 and add 0.9 to get a similar look. The problem comes in the fact that the light.rgb has falloff already applied and so you will get a different look around the edges of your light circles by using luminance to index the ramp.
Antoft
3
Modified the code a bit, and got a more predictable solution.
CGPROGRAM
#pragma surface surf ToonRamp
sampler2D _Ramp;
// custom lighting function that uses a texture ramp based
// on angle between light direction and normal
#include "UnityCG.cginc"
inline half4 LightingToonRamp_PrePass (SurfaceOutput s, half4 light)
{
half spec = light.a * s.Gloss;
half d = Luminance(light.rgb)*0.5;
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
half4 c;
c.rgb = s.Albedo * ramp * (light.rgb * 2);
c.a = 0;
return c;
}
sampler2D _MainTex;
sampler2D _BumpMap;
float4 _Color;
struct Input {
float2 uv_MainTex : TEXCOORD0;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
o.Emission = c.rgb * tex2D(_MainTex, IN.uv_MainTex).a;
}
ENDCG