您的位置:首页 > 编程语言

untiy 3d ShaderLab_第9章_3_球体阴影(三) 点光源对球体的投影

2016-10-26 11:25 260 查看
如图所示,淡黄色的是阴影的淡入淡出,淡紫色的是点光源的阴影。在接受阴影的Shader 中计算了平行光和点光源两种阴影。平行光的:点击,原理是一样的,这里就不多说了。



具体实现的是:

Shader "Tut/Shadow/SphereShadow_3" {
Properties {
_spPos ("Sphere Position", vector) = (0,0,0,1)
_spR ("Sphere Radius", float) = 1
_Intensity("Intensity Of Shadow",range(0,1))=0.5
}
SubShader {
pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float4 _spPos;
float _spR;
float _Intensity;
float4 _LightColor0;
struct v2f{
float4 pos:SV_POSITION;
float3 litDir:TEXCOORD0;
float3 spDir:TEXCOORD1;
float4 vc:TEXCOORD2;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.litDir=WorldSpaceLightDir(v.vertex);
o.spDir=(_spPos-mul(_Object2World,v.vertex)).xyz;

float3 ldir=ObjSpaceLightDir(v.vertex);
ldir=normalize(ldir);
o.vc=_LightColor0*max(0,dot(ldir,v.normal));
return o;
}
float4 frag(v2f i):COLOR
{
float3 litDir=normalize(i.litDir);
float3 spDir=i.spDir;
float spDistance=length(spDir);
spDir=normalize(spDir);

float cosV=dot(spDir,litDir);
float sinV=sin(acos(max(0,cosV)));
float D=sinV*spDistance;
float shadow=step(_spR,D);//spR>D 0,else 1
float atten=pow((D/_spR),4);
float c=lerp(1-_Intensity,1,min(1,shadow+atten));//0 is dark  //*step(0,dot(i.N,litDir))
return i.vc*c;
}
ENDCG
}//endpass
pass{
Tags{"LightMode"="ForwardAdd"}
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float4 _spPos;
float _spR;
float _Intensity;
float4 _LightColor0;
struct v2f{
float4 pos:SV_POSITION;
float3 litDir:TEXCOORD0;
float3 spDir:TEXCOORD1;
float4 vc:TEXCOORD2;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.litDir=WorldSpaceLightDir(v.vertex);
o.spDir=(_spPos-mul(_Object2World,v.vertex)).xyz;

float3 ldir=ObjSpaceLightDir(v.vertex);
float atten=1/(1+length(ldir));
ldir=normalize(ldir);
o.vc=_LightColor0*max(0,dot(ldir,v.normal))*atten;
return o;
}
float4 frag(v2f i):COLOR
{
float litAtten=length(i.litDir);
float3 litDir=normalize(i.litDir);

float3 spDir=i.spDir;
float spDistance=length(spDir);
spDir=normalize(spDir);

float cosV=dot(spDir,litDir);
float sinV=sin(acos(max(0,cosV)));
float D=sinV*spDistance;
float shadow=step(0,D-_spR);//spR>D 0,else 1
float atten=pow((D/_spR),4);
float c=lerp(1-_Intensity,1,min(1,shadow+atten));//0 is dark  //*step(0,dot(i.N,litDir))//
return c*i.vc;
}
ENDCG
}//endpass
}
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐