找回密码
 立即注册
查看: 522|回复: 0

浅谈Unity的实时阴影

[复制链接]
发表于 2021-1-17 14:32 | 显示全部楼层 |阅读模式
本文档主要记录一下如何在unity中要加入实时阴影。
一、阴影投射。
首先,要先加入一个LightMode为ShadowCaster的pass,例如:
  1. // Pass to render object as a shadow caster
  2. Pass
  3. {
  4. Name "ShadowCaster"
  5. Tags { "LightMode" = "ShadowCaster" }
  6.     CGPROGRAM
  7.     #pragma vertex vert
  8.     #pragma fragment frag
  9.     #pragma target 2.0
  10.     #pragma multi_compile_shadowcaster
  11.     #pragma multi_compile_instancing // allow instanced shadow pass for most of the shaders
  12.     #include "UnityCG.cginc"
  13.     struct v2f {
  14.         V2F_SHADOW_CASTER;
  15.         UNITY_VERTEX_OUTPUT_STEREO
  16.     };
  17.     v2f vert(appdata_base v)
  18.     {
  19.         v2f o;
  20.         UNITY_SETUP_INSTANCE_ID(v);
  21.         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  22.         TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
  23.         return o;
  24.     }
  25.     float4 frag(v2f i) : SV_Target
  26.     {
  27.         SHADOW_CASTER_FRAGMENT(i)
  28.     }
  29.     ENDCG
  30. }
复制代码
这个Pass把物体渲染进ShadowMap
二、阴影接收
在ForwardBase Pass中,加入
  1. Pass
  2. {
  3.     Tags { "LightMode" = "ForwardBase" }
  4.     CGPROGRAM
  5.     #pragma vertex vert
  6.     #pragma fragment frag
  7.     #include "UnityCG.cginc"
  8.     #pragma multi_compile_fwdbase
  9.     #include "AutoLight.cginc"
  10.     struct v2f
  11.     {
  12.         float4 pos : SV_POSITION;
  13.         float3 worldPos : Texcoord0;
  14.         LIGHTING_COORDS(1,2)
  15.     };
  16.     v2f vert(appdata_base v) {
  17.         v2f o;
  18.         o.pos = UnityObjectToClipPos(v.vertex);
  19.         TRANSFER_VERTEX_TO_FRAGMENT(o);
  20.         return o;
  21.     }
  22.     fixed4 frag(v2f i) : COLOR {
  23.         float atten = LIGHT_ATTENUATION(i);
  24.         //UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
  25.         fixed3 outColor = fixed3(0.6, 0.0, 0.0) * atten;
  26.         return float4(outColor, 0.5);
  27.     }
  28.     ENDCG
  29. }
复制代码
得到的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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-20 13:24 , Processed in 0.091811 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表