I have a fairly long shader that I am currently writing and it works great with a single directional light and the forwardbase pass also works fine. When I add a ForwardAdd pass the forwardadd pass always returns black for some reason (even if i were to write a very simple return red vertex and fragment program there). The pixel light count in my scene is set to 1000. There are multiple point lights around the object and the object is within range. I am still not sure why this is returning black. I have also tried returning black in the forward base pass and returning white in the forward add pass doing an additive blend to narrow it down, but it still does not work. In the below shader, the forward base and forward add pass are the same except for the ambient light calculation in the pixel shader (line just above the return statement), the forwardbase hass it and the forwardadd does not.
Cheers!
Shader "Custom/Lighting/LightingMaster"
{
Properties
{
_MainTex("_MainTex", 2D) = "white"{}
_SpecTex ("_SpecTex (RGB) Color (A) Gloss", 2D) = "white"{}
_BumpTex ("_BumpTex (RGB) Normal (A) Height", 2D) = "bump"{}
_diffuseLightingStrength("_diffuseLightingStrength lightmap strength", float) = 1.0
_SpecularPower ("_SpecularPower (Phong, Blinn)", float) = 15.0
_SpecularStrength ("_SpecularStrength (Phong, Blinn Ward)", float) = 1.0
_AniX ("_AniX (Ward)", float) = 1.0
_AniY ("_AniY (Ward)", float) = 1.0
_NormalMapStrength ("_NormalMapStrength", float) = 1.0
_NormalMapZHeight ("_NormalMapZHeight", float) = 1.0
_BackScatterColor ("_BackScatterColor (Translucence)", color) = (1,1,1,1)
_BackScatterIntensity ("_BackScatterIntensity (Translucence)", float) = 1.0
_TranslucenceColor ("_TranslucenceColor (Translucence)", color) = (1,1,1,1)
_TranslucenceIntensity ("_TranslucenceIntensity (Translucence)", float) = 1.0
_TranslucencePower ("_TranslucencePower (Translucence)", float) = 1.0
_Roughness1 ("_Roughness1 (OrenNayar, CookTorrance)", range(0.01,1.01)) = 1.0
_ReflectanceAtNormalIncidence ("_ReflectanceAtNormalIncidence (Cook Torrance)",range (0.01, 1.01)) = 1.0
}
CGINCLUDE
//#define SpecularLightMode_Phong
//#define SpecularLightMode_Ward
//#define SpecularLightMode_Blinn
#define DiffuseLightMode_Lambert
//#define DiffuseLightMode_OrenNayar
//#define SpecularLightMode_CookTorrance
//#define Calculate_Specular
//#define UseNormalMap
//#define UseTranslucence
//#define DiffuseLightMode_LightMap
uniform float _diffuseLightingStrength;
#if !defined(DiffuseLightMode_LightMap)
uniform float4 _LightColor0;
#if defined (Calculate_Specular)
#if defined(SpecularLightMode_Phong) || defined(SpecularLightMode_Blinn)
uniform float _SpecularPower;
uniform float _SpecularStrength;
#endif
#if defined (SpecularLightMode_Ward)
uniform float _AniX;
uniform float _AniY;
uniform float _SpecularStrength;
#endif
#endif
#if defined(UseTranslucence)
uniform float4 _BackScatterColor;
uniform float _BackScatterIntensity;
uniform float4 _TranslucenceColor;
uniform float _TranslucenceIntensity;
uniform float _TranslucencePower;
#endif
#if defined (DiffuseLightMode_OrenNayar) || defined(SpecularLightMode_CookTorrance)
uniform float _Roughness1;
#endif
#if defined (SpecularLightMode_CookTorrance)
uniform float _ReflectanceAtNormalIncidence;
uniform float _SpecularStrength;
#endif
#endif
///////////////////////////////////works fine/////////////////////////////////
#if defined(DiffuseLightMode_LightMap)
// undefine everything else
#undef DiffuseLightMode_Lambert
#undef SpecularLightMode_Phong
#undef SpecularLightMode_Blinn
#undef Calculate_Specular
#undef SpecularLightMode_Ward
#undef UseNormalMap
#undef UseTranslucence
#undef DiffuseLightMode_OrenNayar
#undef SpecularLightMode_CookTorrance
float4 lightmap (float4 lightmap, float4 diffuseMap)
{
return diffuseMap * lightmap * _diffuseLightingStrength;
}
#endif
#if !defined(DiffuseLightMode_LightMap)
//diffuse lighting functions
#if defined(DiffuseLightMode_Lambert)
float4 lambert(float3 normalVector, float3 lightVector, float attenuation, float3 diffuseMap)
{
float4 diffuseLit = saturate(dot(normalVector, lightVector)) * attenuation;
diffuseLit.rgb *= diffuseMap * _diffuseLightingStrength * _LightColor0.rgb;
return diffuseLit;
}
#endif
#if defined (DiffuseLightMode_OrenNayar)
float4 orenNayar(float3 normalVector, float3 lightVector, float3 cameraVector, float4 diffuseMap, float attenuation)
{
// Compute the other aliases
float nDotL = dot( lightVector, normalVector );
float cDotn = dot( cameraVector, normalVector );
float gamma = dot ( (cameraVector - normalVector * cDotn), (lightVector - normalVector * nDotL) );
float roughness_Sq = _Roughness1 * _Roughness1;
float A = 1.0f - 0.5f * (roughness_Sq / (roughness_Sq + 0.57f));
float B = 0.45f * (roughness_Sq / (roughness_Sq + 0.09));
float alpha = max( acos( cDotn ), acos( nDotL ) );
float beta = min( acos( cDotn ), acos( nDotL ) );
float C = sin(alpha) * tan(beta);
float3 final = (A + B * max( 0.0f, gamma ) * C);
float4 diffuseLit = float4( diffuseMap * max( 0.0f, nDotL ) * final, 1.0f ) * attenuation;
diffuseLit.rgb *= _diffuseLightingStrength * _LightColor0.rgb;
return diffuseLit;
}
#endif
//specular lighting functions
#if defined (Calculate_Specular)
#if defined(SpecularLightMode_Phong )
float4 phong(float3 reflectionVector, float3 cameraVector, float attenuation, float4 specularMap)
{
float4 specularLit = pow(saturate(dot(reflectionVector, cameraVector)), _SpecularPower * specularMap.a) * _SpecularStrength * specularMap * _LightColor0;
return specularLit;
}
#endif
#if defined(SpecularLightMode_Ward)
float4 ward(float3 normalVector, float3 lightVector, float3 cameraVector, float3 tangentVector, float3 binormalVector, float3 halfVector, float attenuation, float4 specularMap)
{
float nDotL = dot(normalVector, lightVector);
float nDotH = dot(normalVector, halfVector);
float nDotV = dot(normalVector, cameraVector);
float tDotHX = dot(tangentVector, halfVector)/_AniX;
float bDotHY = dot(binormalVector, halfVector)/_AniY;
float4 specularLit = specularMap;
specularLit.rgb *= attenuation * nDotL * _LightColor0.rgb * exp(-(tDotHX * tDotHX + bDotHY * bDotHY)) * _SpecularStrength;
return specularLit;
}
#endif
#if defined(SpecularLightMode_Blinn)
float4 blinn(float3 halfVector, float3 normalVector, float attenuation, float4 specularMap)
{
float4 specularLit = pow(saturate(dot(halfVector, normalVector)), _SpecularPower * specularMap.a) * _SpecularStrength * specularMap * _LightColor0;
return specularLit;
}
#endif
#if defined (SpecularLightMode_CookTorrance)
float4 cookTorrance(float3 halfVector, float3 normalVector, float3 lightVector, float3 cameraVector, float4 specularMap)
{
float NdotL = saturate( dot( normalVector, lightVector ) );
float NdotH = saturate( dot( normalVector, halfVector ) );
float NdotV = saturate( dot( normalVector, cameraVector ) );
float VdotH = saturate( dot( cameraVector, halfVector ) );
float r_sq = _Roughness1 * _Roughness1 * specularMap.w;
// Evaluate the geometric term
// --------------------------------
float geo_numerator = 2.0f * NdotH;
float geo_denominator = VdotH;
float geo_b = (geo_numerator * NdotV ) / geo_denominator;
float geo_c = (geo_numerator * NdotL ) / geo_denominator;
float geo = min( 1.0f, min( geo_b, geo_c ) );
float roughness_a = 1.0f / ( 4.0f * r_sq * pow( NdotH, 4 ) );
float roughness_b = NdotH * NdotH - 1.0f;
float roughness_c = r_sq * NdotH * NdotH;
float roughness = roughness_a * exp( roughness_b / roughness_c );
float fresnel = pow( 1.0f - VdotH, 5.0f );
float ref_at_norm_incidence = _ReflectanceAtNormalIncidence * specularMap.w;
fresnel *= ( 1.0f - ref_at_norm_incidence );
fresnel += ref_at_norm_incidence;
float3 Rs_numerator = ( fresnel * geo * roughness );
float Rs_denominator = NdotV * NdotL;
float3 Rs = Rs_numerator/ Rs_denominator;
float3 final = (specularMap.rgb * Rs);
float4 specularLit = float4( final, 1.0f ) * _SpecularStrength * _LightColor0;
return specularLit;
}
#endif
#endif
#if defined (UseTranslucence)
float3 CalculateTranslucency(float3 normalVector, float3 cameraVector, float3 lightVector, float attenuation, float3 diffuseMap)
{
float3 backScatter = attenuation* _LightColor0.xyz * _BackScatterColor.xyz * saturate(dot(normalVector, -lightVector)) * _BackScatterIntensity;
float3 translucence = attenuation * _LightColor0.xyz * _TranslucenceColor.xyz * pow(saturate(dot(cameraVector, -lightVector)), _TranslucencePower)*_TranslucenceIntensity;
return (backScatter+translucence)*diffuseMap;
}
#endif
#endif
ENDCG
SubShader
{
Pass
{
Tags
{
"LightMode" = "ForwardBase"
}
cull back
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
//*********************************uniforms**********************************
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
#if !defined(DiffuseLightMode_LightMap)
#if defined (Calculate_Specular)
uniform sampler2D _SpecTex;
#endif
#if defined (UseNormalMap)
sampler2D _BumpTex;
uniform float _NormalMapStrength;
uniform float _NormalMapZHeight;
#endif
#endif
#if defined(DiffuseLightMode_LightMap)
uniform sampler2D unity_Lightmap;
uniform float4 unity_LightmapST;
#endif
//******************************end of uniforms******************************************
//*******************************Input Struct********************************
struct a2v
{
float4 vertex : POSITION;
#if !defined(DiffuseLightMode_LightMap)
float4 normal : NORMAL;
#if defined(SpecularLightMode_Ward) || defined (UseNormalMap)
float4 tangent : TANGENT;
#endif
#endif
float2 texcoord : TEXCOORD0;
#if defined(DiffuseLightMode_LightMap)
float4 texcoord1 : TEXCOORD1;
#endif
};
//******************************End of Input Struct*************************************
//********************************Output Struct*******************************
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
#if !defined(DiffuseLightMode_LightMap)
float3 worldNormal : TEXCOORD1;
float4 lightVector : TEXCOORD2;
#if defined (Calculate_Specular) || defined(UseNormalMap)
float3 cameraVector : TEXCOORD3;
#if defined (SpecularLightMode_Ward) || defined (UseNormalMap)
float3 worldTangent : TEXCOORD4;
float3 worldBinormal : TEXCOORD5;
#endif
#endif
#endif
#if defined (DiffuseLightMode_LightMap)
float2 lightMapUvs : TEXCOORD1;
#endif
};
//*******************************End of Output Struct*************************************
//***********************************vertex shader******************************************
v2f vert(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
//vector data
#if !defined(DiffuseLightMode_LightMap)
o.worldNormal = normalize(mul(v.normal, _World2Object).xyz);
float4 worldSpacePos = mul(_Object2World, v.vertex);
o.lightVector.xyz = lerp(_WorldSpaceLightPos0.xyz, (worldSpacePos.xyz - _WorldSpaceLightPos0.xyz), _WorldSpaceLightPos0.w);
o.lightVector.w = lerp(1, 1/length(o.lightVector.xyz),_WorldSpaceLightPos0.w);
#if defined (Calculate_Specular) defined(SpecularLightMode_Ward) || defined (UseNormalMap)
o.worldTangent = normalize(mul(_Object2World, float4(v.tangent.xyz,0)).xyz);
o.worldBinormal = cross (o.worldNormal, o.worldTangent);
#endif
#if defined (Calculate_Specular) || defined(UseTranslucence)
o.cameraVector = _WorldSpaceCameraPos.xyz - worldSpacePos.xyz;
#endif
#endif
#if defined(DiffuseLightMode_LightMap)
o.lightMapUvs = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
return o;
}
//***************************************end of vertex shader******************************************
//*************************************pixel shader*****************************************************
float4 frag(v2f i) : COLOR
{
float4 result = (0,0,0,0);
//texture data
float4 mainTexture = tex2D(_MainTex, i.uv);
#if !defined(DiffuseLightMode_LightMap)
//*********************************diffuse lighting functions********************************************
//vector data used for lighting
float3 worldNormal = i.worldNormal;
#if defined (UseNormalMap)
float4 worldNormalMap = tex2D(_BumpTex, i.uv);
worldNormal = float3(2.0 * worldNormalMap.ag - float2(1,1), 0.0) * _NormalMapStrength;
worldNormal.z = _NormalMapZHeight;
float3x3 local2WorldTranspose = float3x3(
i.worldTangent,
i.worldBinormal,
i.worldNormal
);
worldNormal = mul(worldNormal, local2WorldTranspose);
worldNormal = normalize(worldNormal);
#endif
float3 lightVector = normalize(i.lightVector.xyz);
#if defined(DiffuseLightMode_Lambert)
float4 diffuseLightingMode = lambert(worldNormal, lightVector, i.lightVector.w, mainTexture.rgb);
#endif
#if defined (Calculate_Specular) || defined (UseTranslucence) || defined (DiffuseLightMode_OrenNayar) || defined (SpecularLightMode_CookTorrance)
float3 cameraVector = normalize(i.cameraVector);
#if defined (DiffuseLightMode_OrenNayar)
float4 diffuseLightingMode = orenNayar(worldNormal, lightVector, cameraVector, mainTexture, i.lightVector.w);
#endif
//*********************************end of diffuse lighting functions*****************************************
#if defined(UseTranslucence)
float3 translucenceResult = CalculateTranslucency(worldNormal, cameraVector, lightVector, i.lightVector.w, mainTexture.xyz);
#endif
#if defined (Calculate_Specular)
float4 specularTexture = tex2D (_SpecTex, i.uv);
//********************************specular lighting functions*******************************************
// vectors caclulated only if needed
#if defined(SpecularLightMode_Phong)
float3 reflectionVector = reflect(-lightVector.xyz, worldNormal);
#endif
#if defined(SpecularLightMode_Ward) || defined(SpecularLightMode_Blinn) || defined(SpecularLightMode_CookTorrance)
float3 halfVector = normalize(lightVector.xyz + cameraVector);
#if defined(SpecularLightMode_Ward)
float3 worldTangent = i.worldTangent;
float3 worldBinormal = i.worldBinormal;
#endif
#endif
//end of vector calculation
#if defined(SpecularLightMode_Phong )
result += phong(reflectionVector, cameraVector, i.lightVector.w, specularTexture);
#endif
#if defined(SpecularLightMode_Ward )
result += ward(worldNormal, lightVector, cameraVector, worldTangent, worldBinormal, halfVector, i.lightVector.w, specularTexture);
#endif
#if defined (SpecularLightMode_Blinn)
result += blinn(halfVector, worldNormal, i.lightVector.w, specularTexture);
#endif
#if defined(SpecularLightMode_CookTorrance)
result += cookTorrance(halfVector, worldNormal, lightVector, cameraVector, specularTexture);
#endif
#endif
#endif
#endif
//********************************end of specular lighting functions*******************************************
//*****************************************lightmap*******************************************************
#if defined (DiffuseLightMode_LightMap)
float4 unity_Lightmaptexture = tex2D(unity_Lightmap, i.lightMapUvs);
float4 diffuseLightingMode = lightmap(unity_Lightmaptexture, mainTexture);
diffuseLightingMode.a = 1;
#endif
//***************************************** end of lightmap*******************************************************
//combine
result += diffuseLightingMode;
result *= diffuseLightingMode.a;
#if defined(UseTranslucence)
result.rgb += translucenceResult;
#endif
result.rgb += UNITY_LIGHTMODEL_AMBIENT * mainTexture;
return result;
}
//**************************************************** end of pixel shader**************************************
ENDCG
}
Pass
{
Tags
{
"LightMode" = "ForwardAdd"
}
Blend One One
cull back
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
//*********************************uniforms**********************************
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
#if !defined(DiffuseLightMode_LightMap)
#if defined (Calculate_Specular)
uniform sampler2D _SpecTex;
#endif
#if defined (UseNormalMap)
sampler2D _BumpTex;
uniform float _NormalMapStrength;
uniform float _NormalMapZHeight;
#endif
#endif
#if defined(DiffuseLightMode_LightMap)
uniform sampler2D unity_Lightmap;
uniform float4 unity_LightmapST;
#endif
//******************************end of uniforms******************************************
//*******************************Input Struct********************************
struct a2v
{
float4 vertex : POSITION;
#if !defined(DiffuseLightMode_LightMap)
float4 normal : NORMAL;
#if defined(SpecularLightMode_Ward) || defined (UseNormalMap)
float4 tangent : TANGENT;
#endif
#endif
float2 texcoord : TEXCOORD0;
#if defined(DiffuseLightMode_LightMap)
float4 texcoord1 : TEXCOORD1;
#endif
};
//******************************End of Input Struct*************************************
//********************************Output Struct*******************************
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
#if !defined(DiffuseLightMode_LightMap)
float3 worldNormal : TEXCOORD1;
float4 lightVector : TEXCOORD2;
#if defined (Calculate_Specular) || defined(UseNormalMap)
float3 cameraVector : TEXCOORD3;
#if defined (SpecularLightMode_Ward) || defined (UseNormalMap)
float3 worldTangent : TEXCOORD4;
float3 worldBinormal : TEXCOORD5;
#endif
#endif
#endif
#if defined (DiffuseLightMode_LightMap)
float2 lightMapUvs : TEXCOORD1;
#endif
};
//*******************************End of Output Struct*************************************
//***********************************vertex shader******************************************
v2f vert(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
//vector data
#if !defined(DiffuseLightMode_LightMap)
o.worldNormal = normalize(mul(v.normal, _World2Object).xyz);
float4 worldSpacePos = mul(_Object2World, v.vertex);
o.lightVector.xyz = lerp(_WorldSpaceLightPos0.xyz, (worldSpacePos.xyz - _WorldSpaceLightPos0.xyz), _WorldSpaceLightPos0.w);
o.lightVector.w = lerp(1,1/length(o.lightVector.xyz),_WorldSpaceLightPos0.w);
#if defined (Calculate_Specular) defined(SpecularLightMode_Ward) || defined (UseNormalMap)
o.worldTangent = normalize(mul(_Object2World, float4(v.tangent.xyz,0)).xyz);
o.worldBinormal = cross (o.worldNormal, o.worldTangent);
#endif
#if defined (Calculate_Specular) || defined(UseTranslucence)
o.cameraVector = _WorldSpaceCameraPos.xyz - worldSpacePos.xyz;
#endif
#endif
#if defined(DiffuseLightMode_LightMap)
o.lightMapUvs = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
return o;
}
//***************************************end of vertex shader******************************************
//*************************************pixel shader*****************************************************
float4 frag(v2f i) : COLOR
{
float4 result = (0,0,0,0);
//texture data
float4 mainTexture = tex2D(_MainTex, i.uv);
#if !defined(DiffuseLightMode_LightMap)
//*********************************diffuse lighting functions********************************************
//vector data used for lighting
float3 worldNormal = i.worldNormal;
#if defined (UseNormalMap)
float4 worldNormalMap = tex2D(_BumpTex, i.uv);
worldNormal = float3(2.0 * worldNormalMap.ag - float2(1,1), 0.0) * _NormalMapStrength;
worldNormal.z = _NormalMapZHeight;
float3x3 local2WorldTranspose = float3x3(
i.worldTangent,
i.worldBinormal,
i.worldNormal
);
worldNormal = mul(worldNormal, local2WorldTranspose);
worldNormal = normalize(worldNormal);
#endif
float3 lightVector = normalize(i.lightVector.xyz);
#if defined(DiffuseLightMode_Lambert)
float4 diffuseLightingMode = lambert(worldNormal, lightVector, i.lightVector.w, mainTexture.rgb);
#endif
#if defined (Calculate_Specular) || defined (UseTranslucence) || defined (DiffuseLightMode_OrenNayar) || defined (SpecularLightMode_CookTorrance)
float3 cameraVector = normalize(i.cameraVector);
#if defined (DiffuseLightMode_OrenNayar)
float4 diffuseLightingMode = orenNayar(worldNormal, lightVector, cameraVector, mainTexture, i.lightVector.w);
#endif
//*********************************end of diffuse lighting functions*****************************************
#if defined(UseTranslucence)
float3 translucenceResult = CalculateTranslucency(worldNormal, cameraVector, lightVector, i.lightVector.w, mainTexture.xyz);
#endif
#if defined (Calculate_Specular)
float4 specularTexture = tex2D (_SpecTex, i.uv);
//********************************specular lighting functions*******************************************
// vectors caclulated only if needed
#if defined(SpecularLightMode_Phong)
float3 reflectionVector = reflect(-lightVector.xyz, worldNormal);
#endif
#if defined(SpecularLightMode_Ward) || defined(SpecularLightMode_Blinn) || defined(SpecularLightMode_CookTorrance)
float3 halfVector = normalize(lightVector.xyz + cameraVector);
#if defined(SpecularLightMode_Ward)
float3 worldTangent = i.worldTangent;
float3 worldBinormal = i.worldBinormal;
#endif
#endif
//end of vector calculation
#if defined(SpecularLightMode_Phong )
result += phong(reflectionVector, cameraVector, i.lightVector.w, specularTexture);
#endif
#if defined(SpecularLightMode_Ward )
result += ward(worldNormal, lightVector, cameraVector, worldTangent, worldBinormal, halfVector, i.lightVector.w, specularTexture);
#endif
#if defined (SpecularLightMode_Blinn)
result += blinn(halfVector, worldNormal, i.lightVector.w, specularTexture);
#endif
#if defined(SpecularLightMode_CookTorrance)
result += cookTorrance(halfVector, worldNormal, lightVector, cameraVector, specularTexture);
#endif
#endif
#endif
#endif
//********************************end of specular lighting functions*******************************************
//*****************************************lightmap*******************************************************
#if defined (DiffuseLightMode_LightMap)
float4 unity_Lightmaptexture = tex2D(unity_Lightmap, i.lightMapUvs);
float4 diffuseLightingMode = lightmap(unity_Lightmaptexture, mainTexture);
diffuseLightingMode.a = 1;
#endif
//***************************************** end of lightmap*******************************************************
//combine
result += diffuseLightingMode;
result *= diffuseLightingMode.a;
#if defined(UseTranslucence)
result.rgb += translucenceResult;
#endif
return result;
}
//**************************************************** end of pixel shader**************************************
ENDCG
}
}
Fallback "Diffuse"
}