Unity接收阴影--SHADOW_COORDS, TRANSFER_SHADOW, SHADOW_ATTENUATION---计算阴影的三个主要部分

关于阴影深度的基础知识:

传统的ShadowMap

ShadowMap说起来十分简单,把摄像机和光源的位置重叠,那么场景中该光源的阴影区域就是那些摄像机看不到的地方,主要应用在前向渲染路径中。

具体实现分以下几个步骤:

  • 如果有平行光开启了阴影,Unity就会为该光源计算它的ShadowMap(只会计算一个平行光),这张ShadowMap其实就是深度图,记录了从该光源的位置出发、能看到的场景中距离它最近的表面位置(深度信息)。
  • Unity中实现了一个额外的Pass来专门更新光源的ShadowMap,这个Pass就是LightMode标签被设置为ShadowCaster的Pass。
  • 然后在正常渲染的Pass中把顶点位置变换到光源空间下,以得到它在光源空间中的三维位置信息。然后根据坐标信息对ShadowMap采样,得到该点在ShadowMap中的深度信息。比较后,判断该点是否应该在阴影中。
  • 注意:利用Receive Shadows的开关可以控制物体是否显示阴影,但是不影响渲染。而Cast Shadows的开关则控制该物体是否会加入到Shadowmap的渲染。

屏幕空间的阴影

延迟渲染中的光照计算绝大部分都是在屏幕空间里进行的,同样也包括阴影。这种屏幕空间的阴影实现主要有这么几个步骤:

  1. 首先得到从当前摄像机处观察到的深度纹理。在延迟渲染里这张深度图本来就有,如果是前向渲染的话就需要把场景整个渲染一遍,把深度渲染到深度图中。
  2. 然后再从光源出发得到从该光源处观察到的深度纹理,也被称为这个光源的ShadowMap
  3. 然后在屏幕空间做一次阴影收集计算(Shadows Collector),这次计算会得到一张屏幕空间阴影纹理,也就是说这张图里面需要有阴影的部分已经显示在图上了。这个过程概括来说就是把每一个像素根据它在摄像机深度纹理中的深度值得到世界空间坐标,再把它的坐标从世界空间转换到光源空间中,和光源的ShadowMap里面的深度值对比,如果大于ShadowMap中的深度距离,那么就说明光源无法照到,在阴影内。
  4. 最后,在正常渲染物体为它计算阴影的时候,只需要按照当前处理的fragment在屏幕空间中的位置对步骤3得到的屏幕空间阴影图采样就可以了。

二者的主要异同就是:两者都会渲染光源空间的深度图,但前者的采样发生在光源空间,片元坐标转换到光源空间对ShadowMap采样,而后者会做一次阴影收集计算(Shadow Collecctor)得到屏幕空间阴影纹理,片元在屏幕空间对阴影纹理采样。

Unity3D中开启不同阴影的情况

截止到Unity 5.4,当项目工程的目标平台是Mobile的时候,就不会使用屏幕空间的阴影映射技术,即使用原始的Shadows Map方法。在代码里,Unity会定义内置宏UNITY_NO_SCREENSPACE_SHADOWS来控制。而当项目工程的目标平台是支持屏幕空间阴影的话,例如PC, Mac & Linux Standalone平台时,会开启屏幕空间的阴影映射技术。

我们可以通过帧调试器(Frame Debugger)来分辨当前是否使用了屏幕空间的阴影映射技术:

 

让物体能够接受阴影的三剑客(SHADOW_COORDS, TRANSFER_SHADOW, SHADOW_ATTENUATION)

三个内置宏(SHADOW_COORDS, TRANSFER_SHADOW, SHADOW_ATTENUATION) 就是计算阴影的三个主要部分。可以在AutoLight.cginc中找到它们的声明。

作用:让物体能够接收阴影,原理是采样“LightMode” = “ShadowCaster" Pass里渲染出来的阴影深度图,然后与光照融合,阴影越强烈,贴图像素数值越靠近0

需要在Pass中包含新的内置文件 #include "AutoLight.cginc"

 

SHADOW_COORDS 声明了一个名为_ShadowCoord的阴影纹理坐标变量。

它的作用是声明一个用于对阴影纹理采样的uv坐标。一般用于片元着色器的输入结构体中,而且这个宏的参数需要是下一个可用插值寄存器的索引值,本例中是2。

例如: 

// 片元着色器的输入结构体
struct Interpolators{
    flaot4 uv : TEXCOORD0;
    float3 normal : TEXCOORD1;
    float4 pos : SV_POSITION;  //裁剪坐标,变量名要写死为pos,配合TRANSFER_SHADOW            
    SHADOW_COORDS(2) // 相当于float4 _ShadowCoord : TEXCOORD2 
}

源码:

#define SHADOW_COORDS(idx1) unityShadowCoord4 _ShadowCoord : TEXCOORD##idx1;

 

TRANSFER_SHADOW会得到一个用于提取阴影贴图的uv坐标

作用:得到一个用于采样阴影贴图的坐标

TRANSFER_SHADOW 会根据平台的不同而有所差异:

1:如果当前平台可以使用屏幕空间的阴影映射技术(SCREENSPACE_SHADOWS),则会调用内置的ComputeScreenPos函数计算屏幕空间的uv坐标,存储在_ShadowCoord,后续直接用屏幕uv坐标采样屏幕阴影贴图;

2:如果不支持则会使用传统的阴影映射技术,TRANSFER_SHADOW会把顶点坐标从模型空间转换到光源空间后存储到_ShadowCoord中,后续根据坐标信息对ShadowMap采样。

例如:

// 顶点着色器, 参数命名要写死v,v里面的顶点坐标要写死vertex,配合TRANSFER_SHADOW
Interpolators MyVertexProgram(appdata v){
    Interpolators o;

    o.pos = UnityObjectToClipPos(v.vertex); // 裁剪坐标,变量名要写死为pos,配合TRANSFER_SHADOW

    TRANSFER_SHADOW(o);
    return o;
}

源码:

红框部分:

 

SHADOW_ATTENUATION 负责使用_ShadowCoord对对应的纹理进行采,得到阴影信息。

用法1:在片元着色器中,把片元函数输入结构体传给SHADOW_ATTENUATION,直接得到衰减

UnityLight light;
// 片元着色器中使用
float attenuation = SHADOW_ATTENUATION(i)
light.color = _LightColor0.rgb * attenuation;

用法2:在片元着色器中,把片元函数输入结构体传给UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos)的第二个参数,然后间接调用SHADOW_ATTENUATION

UnityLight light;
// 片元着色器中使用
UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos);
light.color = _LightColor0.rgb * attenuation;

UNITY_LIGHT_ATTENUATION解析:https://blog.csdn.net/zengjunjie59/article/details/109533698

源码:

红框部分:

 

最后:

以上是以直射光作为例子讲解的,不同灯光类型的宏会略有不同,具体请看unity buildin的源码

  • 12
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"photon-server-sdk_v4-0-29-11263.exe" 是一款名为"Photon Server SDK" 的软件文件。Photon Server SDK 是由Exit Games公司开发的一套高性能的多人实时游戏服务器解决方案。 Photon Server SDK 定位于提供一个可靠、稳定和高效的多人游戏服务器引擎。它提供了一系列功能,使开发者能够轻松地构建和管理多人游戏。它支持多种平台和编程语言,包括Windows、Linux、iOS和Android,以及C++、C#、Unity和Netty等编程语言和引擎。 Photon Server SDK 的主要功能包括: 1. 提供可靠的服务器架构:它提供了高度可扩展的服务器架构,能够处理成千上万个并发连接。 2. 实时数据同步:它支持实时数据同步,使得多个玩家能够在游戏中实时交互、同步游戏状态和数据。 3. 多人房间管理:它提供了强大的多人房间管理功能,使开发者能够创建、加入和管理多人游戏房间。 4. 客户端集成和网络通信:它提供了客户端集成的API和网络通信功能,使开发者能够轻松地与服务器通信,发送和接收游戏数据。 5. 实时聊天和语音通话功能:它支持实时聊天和语音通话功能,使玩家能够在游戏中进行实时沟通。 总之,"photon-server-sdk_v4-0-29-11263.exe" 是一款功能强大的多人实时游戏服务器解决方案的安装文件。通过使用Photon Server SDK,开发者能够快速构建稳定、可扩展和高效的多人游戏服务器,并实现实时数据同步、多人房间管理和实时通信等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值