Surface шейдер с кастомным освещением не принимает тени
Добавлено: 09 авг 2013, 17:56
Добрый день, начал изучать писание шейдеров для Вроде написал для друга шейдер, который идеально работал, но другу понадобились реалтаймовые тени, и оказалось что венец моего творения не умеет принимать тени, я попробовал прибавить _PrePass к модели освещения тени начали приниматься, но вырубился спекуляр. На deferred lighting переключено, юнити про. Вот код шейдера:
Я туповатый моделлер и не очень могу понять, насколько я разобрался, deferred lighting чхать хотело на блок LightingBlinnPhong2 и берёт только LightingBlinnPhong2_PrePass а в него не идут ни вектор взгляда ни направление света, а выстраданный спекуляр основывается на них. Или я что-то не понимаю?
Синтаксис:
Используется glsl
//This is my second shader.
Shader "LavrEnvir"
{
Properties
{
_Base ("Diffuse map(A = Specular map)", 2D) = "white" {}
_Shininess ("Specular focus", Range(1,100)) = 1
_Blik("Spec power", Range (0,5)) = 0
AlbOffsetU("Difise offset X", float) = 0
AlbOffsetV("Difise offset Y", float) = 0
_Detail ("(R:Dirt1, G:Dirt2, B: CubeMapMask)", 2D) = "white" {}
DirtCol1("Dirt 1 color", Color) = (0,0,0,0)
DirtCol2("Dirt 2 color", Color) = (0,0,0,0)
DetailMod("Dirt mixer", Range(0,1)) = 0
_NormalMap ("Normal", 2D) = "bump" {}
_NormalMapDetail ("Normal map detail", 2D) = "bump" {}
NormForce ("Normal Force", float) = 1
_Cube ("CubeMap", CUBE) = "" {}
_RefVal("Reflection Value (10 maximum)", float) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
Cull off
CGPROGRAM
#pragma surface surf BlinnPhong2
#pragma target 3.0
struct MySurfaceOutput
{
float3 Albedo;
float3 Normal;
float3 Gloss;
float3 Specular;
float3 Emission;
float Alpha;
float Multi;
float Custom;
};
fixed4 LightingBlinnPhong2_PrePass (MySurfaceOutput s, half4 light)
{
fixed spec = light.a * s.Gloss * s.Specular * s.Multi;
fixed4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * _SpecColor.rgb * spec);
c.a = s.Alpha + spec * _SpecColor.a;
return c;
}
float4 LightingBlinnPhong2 (MySurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
{
float3 h = normalize (lightDir + viewDir);
float3 n = normalize (s.Normal);
float3 v = normalize (viewDir);
float3 l = normalize (lightDir);
float3 r = reflect ( -v, n );
//float4 diff = max (0,dot(s.Normal, lightDir));
float4 diff = max(0,dot(n,l));
float nh = max(0,dot(l,r));
float3 spec = pow(nh,s.Gloss) * s.Specular * s.Multi;
float4 te = 0;
te.rgb =s.Albedo * diff * _LightColor0.rgb + spec * _LightColor0.rgb;
te.a = s.Alpha + spec * _SpecColor.a;
//te.a = 0.0;
te *= atten * 2;
return LightingBlinnPhong2_PrePass(s, te);
}
struct Input
{
float2 uv_Base;
float2 uv_Detail;
float2 uv_NormalMap;
float2 uv_NormalMapDetail;
float3 worldRefl;
INTERNAL_DATA
};
sampler2D _Base;
sampler2D _Detail;
sampler2D _NormalMap;
sampler2D _NormalMapDetail;
samplerCUBE _Cube;
float4 DirtCol1;
float4 DirtCol2;
float AlbOffsetU;
float AlbOffsetV;
float _RefVal;
float NormForce;
float DetailMod;
float _Shininess;
float _Blik;
void vert (inout appdata_full v, out Input o)
{}
void surf (Input IN, inout MySurfaceOutput o)
{
float2 DiTeCoord = float2 (IN.uv_Base.x + AlbOffsetU/2, IN.uv_Base.y + AlbOffsetV/2);//Сдвиг карты дифуза
float4 tex = tex2D (_Base, DiTeCoord);// Первый дифуз тут
float4 NM = tex2D (_NormalMap, DiTeCoord);
float4 NMD = tex2D (_NormalMapDetail, DiTeCoord);
NMD.a = 0.5;
NM.a = 0.5;
float3 FNM = UnpackNormal (NM) + UnpackNormal (NMD);//карта нормалей помноженная на усилитель
FNM = lerp(float3(0,0,1),FNM,NormForce);
//FNM.b = FNM.b * NormForce2;
//FNM = normalize (FNM);
float4 Dirt1 = tex2D (_Detail, IN.uv_Detail).r;
float4 Dirt2 = tex2D (_Detail, IN.uv_Detail).g;
float4 DirtAll = lerp (Dirt1, Dirt2, DetailMod);
float4 Difuse = lerp (lerp(DirtCol1, DirtCol2, DetailMod), tex, DirtAll);
o.Albedo = Difuse.rgb;
o.Normal = FNM;
o.Emission = (texCUBE (_Cube, WorldReflectionVector (IN, o.Normal)).rgb * tex2D (_Detail, IN.uv_Detail).b * _RefVal/10);
o.Specular = tex2D (_Base, DiTeCoord).a;
o.Gloss = _Shininess ;
o.Multi = _Blik;
}
ENDCG
}
FallBack "Diffuse"
}
Shader "LavrEnvir"
{
Properties
{
_Base ("Diffuse map(A = Specular map)", 2D) = "white" {}
_Shininess ("Specular focus", Range(1,100)) = 1
_Blik("Spec power", Range (0,5)) = 0
AlbOffsetU("Difise offset X", float) = 0
AlbOffsetV("Difise offset Y", float) = 0
_Detail ("(R:Dirt1, G:Dirt2, B: CubeMapMask)", 2D) = "white" {}
DirtCol1("Dirt 1 color", Color) = (0,0,0,0)
DirtCol2("Dirt 2 color", Color) = (0,0,0,0)
DetailMod("Dirt mixer", Range(0,1)) = 0
_NormalMap ("Normal", 2D) = "bump" {}
_NormalMapDetail ("Normal map detail", 2D) = "bump" {}
NormForce ("Normal Force", float) = 1
_Cube ("CubeMap", CUBE) = "" {}
_RefVal("Reflection Value (10 maximum)", float) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
Cull off
CGPROGRAM
#pragma surface surf BlinnPhong2
#pragma target 3.0
struct MySurfaceOutput
{
float3 Albedo;
float3 Normal;
float3 Gloss;
float3 Specular;
float3 Emission;
float Alpha;
float Multi;
float Custom;
};
fixed4 LightingBlinnPhong2_PrePass (MySurfaceOutput s, half4 light)
{
fixed spec = light.a * s.Gloss * s.Specular * s.Multi;
fixed4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * _SpecColor.rgb * spec);
c.a = s.Alpha + spec * _SpecColor.a;
return c;
}
float4 LightingBlinnPhong2 (MySurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
{
float3 h = normalize (lightDir + viewDir);
float3 n = normalize (s.Normal);
float3 v = normalize (viewDir);
float3 l = normalize (lightDir);
float3 r = reflect ( -v, n );
//float4 diff = max (0,dot(s.Normal, lightDir));
float4 diff = max(0,dot(n,l));
float nh = max(0,dot(l,r));
float3 spec = pow(nh,s.Gloss) * s.Specular * s.Multi;
float4 te = 0;
te.rgb =s.Albedo * diff * _LightColor0.rgb + spec * _LightColor0.rgb;
te.a = s.Alpha + spec * _SpecColor.a;
//te.a = 0.0;
te *= atten * 2;
return LightingBlinnPhong2_PrePass(s, te);
}
struct Input
{
float2 uv_Base;
float2 uv_Detail;
float2 uv_NormalMap;
float2 uv_NormalMapDetail;
float3 worldRefl;
INTERNAL_DATA
};
sampler2D _Base;
sampler2D _Detail;
sampler2D _NormalMap;
sampler2D _NormalMapDetail;
samplerCUBE _Cube;
float4 DirtCol1;
float4 DirtCol2;
float AlbOffsetU;
float AlbOffsetV;
float _RefVal;
float NormForce;
float DetailMod;
float _Shininess;
float _Blik;
void vert (inout appdata_full v, out Input o)
{}
void surf (Input IN, inout MySurfaceOutput o)
{
float2 DiTeCoord = float2 (IN.uv_Base.x + AlbOffsetU/2, IN.uv_Base.y + AlbOffsetV/2);//Сдвиг карты дифуза
float4 tex = tex2D (_Base, DiTeCoord);// Первый дифуз тут
float4 NM = tex2D (_NormalMap, DiTeCoord);
float4 NMD = tex2D (_NormalMapDetail, DiTeCoord);
NMD.a = 0.5;
NM.a = 0.5;
float3 FNM = UnpackNormal (NM) + UnpackNormal (NMD);//карта нормалей помноженная на усилитель
FNM = lerp(float3(0,0,1),FNM,NormForce);
//FNM.b = FNM.b * NormForce2;
//FNM = normalize (FNM);
float4 Dirt1 = tex2D (_Detail, IN.uv_Detail).r;
float4 Dirt2 = tex2D (_Detail, IN.uv_Detail).g;
float4 DirtAll = lerp (Dirt1, Dirt2, DetailMod);
float4 Difuse = lerp (lerp(DirtCol1, DirtCol2, DetailMod), tex, DirtAll);
o.Albedo = Difuse.rgb;
o.Normal = FNM;
o.Emission = (texCUBE (_Cube, WorldReflectionVector (IN, o.Normal)).rgb * tex2D (_Detail, IN.uv_Detail).b * _RefVal/10);
o.Specular = tex2D (_Base, DiTeCoord).a;
o.Gloss = _Shininess ;
o.Multi = _Blik;
}
ENDCG
}
FallBack "Diffuse"
}
Я туповатый моделлер и не очень могу понять, насколько я разобрался, deferred lighting чхать хотело на блок LightingBlinnPhong2 и берёт только LightingBlinnPhong2_PrePass а в него не идут ни вектор взгляда ни направление света, а выстраданный спекуляр основывается на них. Или я что-то не понимаю?