Well, I’m still trying it on my own, since no is responding here…
I’m having trouble getting it to work with directional lights. I’ve attempted editing the shader I linked to in my original post, and here is what I have so far:
// Shader for Unity integration with SpriteLamp
// Written by Steve Karolewics Indreams Studios
Shader "Custom/shr_SpriteNormalShader"
{
Properties
{
_MainTex ("Diffuse Texture", 2D) = "white" {}
_Normal ("Normal", 2D) = "bump" {}
_Depth ("Depth", 2D) = "gray" {}
_SpecColor ("Specular Material Color", Color) = (1,1,1,1)
_Shininess ("Shininess", Float) = 10
_AmplifyDepth ("Amplify Depth", Float) = 1
_CelShadingLevels ("Cel Shading Levels", Float) = 0
}
SubShader
{
ZWrite On
AlphaTest Greater 0.1
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// User-specified properties
uniform sampler2D _MainTex;
struct VertexInput
{
float4 vertex : POSITION;
float4 color : COLOR;
float4 uv : TEXCOORD0;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
VertexOutput vert(VertexInput input)
{
VertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.color = input.color;
output.uv = float2(input.uv);
return output;
}
float4 frag(VertexOutput input) : COLOR
{
float4 diffuseColor = tex2D(_MainTex, input.uv);
float3 ambientLighting = float3(UNITY_LIGHTMODEL_AMBIENT) * float3(diffuseColor) *
float3(input.color);
return float4(ambientLighting, diffuseColor.a);
}
ENDCG
}
Pass
{
Tags { "LightMode" = "ForwardAdd" }
Blend One One // additive blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
// User-specified properties
uniform sampler2D _MainTex;
uniform sampler2D _Normal;
uniform sampler2D _Depth;
uniform float4 _SpecColor;
uniform float4 _LightColor0;
uniform float _Shininess;
uniform float _AmplifyDepth;
uniform float _CelShadingLevels;
struct VertexInput
{
float4 vertex : POSITION;
float4 color : COLOR;
float4 uv : TEXCOORD0;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
float4 posWorld : TEXCOORD1;
};
VertexOutput vert(VertexInput input)
{
VertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.posWorld = mul(_Object2World, input.vertex);
output.uv = float2(input.uv);
output.color = input.color;
return output;
}
float4 frag(VertexOutput input) : COLOR
{
float4 diffuseColor = tex2D(_MainTex, input.uv);
// To compute the correct normal:
// 1) Get the pixel value from the normal map
// 2) Subtract 0.5 and multiply by 2 to convert from the range 0...1 to -1...1
// 3) Multiply by world to object matrix, to handle rotation, etc
// 4) Negate Z so that lighting works as expected (sprites further away from the camera than
// a light are lit, etc.)
// 5) Normalize
float3 normalDirection = (tex2D(_Normal, input.uv).xyz - 0.5f) * 2.0f;
normalDirection = float3(mul(float4(normalDirection, 1.0f), _World2Object));
normalDirection.z *= -1;
normalDirection = normalize(normalDirection);
// To adjust depth:
// 1) Get the depth value from the depth map
// 2) Subtract 0.5 and multiply by 2 to convert from the range 0...1 to -1...1
// 3) Multiply by the amplify depth value, and subtract from the fragment's z position
float depthColor = (tex2D(_Depth, input.uv).x - 0.5f) * 2.0f;
float3 posWorld = float3(input.posWorld);
posWorld.z -= depthColor * _AmplifyDepth;
float attenuation;
float3 lightDirection;
if (0.0 == _WorldSpaceLightPos0.w) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(float3(_WorldSpaceLightPos0));
}
else{
//float3 vertexToLightSource = float3(_WorldSpaceLightPos0 - mul(modelMatrix, input.vertex));
float3 vertexToLightSource = float3(_WorldSpaceLightPos0) - posWorld;
float distance = length(vertexToLightSource);
attenuation = 1.0 / distance; // linear attenuation
lightDirection = normalize(vertexToLightSource);
}
// Compute diffuse part of lighting
float normalDotLight = dot(normalDirection, lightDirection);
float diffuseLevel = attenuation * max(0.0f, normalDotLight);
// Compute specular part of lighting
float specularLevel;
if (normalDotLight < 0.0f)
{
// Light is on the wrong side, no specular reflection
specularLevel = 0.0f;
}
else
{
// For orthographic cameras, the view direction is always known
float3 viewDirection = float3(0.0f, 0.0f, -1.0f);
specularLevel = attenuation * pow(max(0.0, dot(reflect(-lightDirection, normalDirection),
viewDirection)), _Shininess);
}
// Add cel-shading if enough levels were specified
if (_CelShadingLevels >= 2)
{
diffuseLevel = floor(diffuseLevel * _CelShadingLevels) / (_CelShadingLevels - 0.5f);
specularLevel = floor(specularLevel * _CelShadingLevels) / (_CelShadingLevels - 0.5f);
}
float3 diffuseReflection = float3(diffuseColor) * input.color *
float3(_LightColor0) * diffuseLevel;
float3 specularReflection = float3(_LightColor0) * float3(_SpecColor) *
input.color * specularLevel;
return float4(diffuseReflection + specularReflection, diffuseColor.a);
}
ENDCG
}
}
// The definition of a fallback shader should be commented out
// during development:
// Fallback "Transparent/Diffuse"
}
I’ve gone through this page to see how directional lights were done there and to try to add it to this shader, but I honestly have no clue what I’m doing.
Would really like some help, please.