|
本文档主要记录一下如何在unity中要加入实时阴影。
一、阴影投射。
首先,要先加入一个LightMode为ShadowCaster的pass,例如:- // Pass to render object as a shadow caster
- Pass
- {
- Name "ShadowCaster"
- Tags { "LightMode" = "ShadowCaster" }
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #pragma target 2.0
- #pragma multi_compile_shadowcaster
- #pragma multi_compile_instancing // allow instanced shadow pass for most of the shaders
- #include "UnityCG.cginc"
- struct v2f {
- V2F_SHADOW_CASTER;
- UNITY_VERTEX_OUTPUT_STEREO
- };
- v2f vert(appdata_base v)
- {
- v2f o;
- UNITY_SETUP_INSTANCE_ID(v);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
- TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
- return o;
- }
- float4 frag(v2f i) : SV_Target
- {
- SHADOW_CASTER_FRAGMENT(i)
- }
- ENDCG
- }
复制代码 这个Pass把物体渲染进ShadowMap
二、阴影接收
在ForwardBase Pass中,加入- Pass
- {
- Tags { "LightMode" = "ForwardBase" }
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- #pragma multi_compile_fwdbase
- #include "AutoLight.cginc"
- struct v2f
- {
- float4 pos : SV_POSITION;
- float3 worldPos : Texcoord0;
- LIGHTING_COORDS(1,2)
- };
- v2f vert(appdata_base v) {
- v2f o;
- o.pos = UnityObjectToClipPos(v.vertex);
- TRANSFER_VERTEX_TO_FRAGMENT(o);
- return o;
- }
- fixed4 frag(v2f i) : COLOR {
- float atten = LIGHT_ATTENUATION(i);
- //UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
- fixed3 outColor = fixed3(0.6, 0.0, 0.0) * atten;
- return float4(outColor, 0.5);
- }
- ENDCG
- }
复制代码 得到的atten 就是shadow值。
代码来说还是很简单的,但是在测试过程中遇到几个问题,在这里记录一下:
1.ForwardBase Pass中只处理平行光阴影,LightMap等,其他的灯光需要在ForwordAdd Pass中进行处理。
2.在顶点着色器中加入顶点变换的话,接受阴影需要使用UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);因为在设置阴影坐标的时候是把v.vertex变换到灯光空间,位移之后除非改动v.vertex,否则阴影坐标计算的是顶点变换前的。
3.PC平台和移动平台对阴影的默认设置不一样,比如PC平台默认是Cascaded Shadow开启,那如果物体想仅接收阴影,也必须写Shadowcaster Pass,因为使用的屏幕空间的Cascaded Shadow Map, 移动平台默认是关闭Cascaded Shadow,仅接收阴影不用写Shadowcaster Pass;具体可参见unity5.0更新说明,Shadowcaster实际是用来收集CameraDepthTexture:
示例工程:https://github.com/willFederer/ShadowTest |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|