温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

发布时间:2021-11-15 16:42:01 来源:亿速云 阅读:546 作者:柒染 栏目:大数据

这篇文章给大家介绍Unity Shader如何结合Projector和Rendertexture来实现实时阴影,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

说到实时阴影的实现,一般比较容易想到使用ShadowMap,通过投射灯光空间的深度图,并在投射物体上进行深度比较,判断是否处于阴影的范围,以此来渲染阴影。深度图投射到接受阴影的物体上的效果如图所示:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

深度图投射

你所需要做的就是在灯光空间渲染一张深度纹理,并投射到接受阴影的物体上,并和接受阴影的物体上对应像素位置的深度(灯光空间)进行比较,来确定当前像素是否处于阴影即可,此外还要考虑深度图的精度以及以此会造成的ZFighting等,当然这并不是本文讨论的重点。

本文主要介绍一种直接投射灯光空间摄像机的Rendertexture来实现阴影的方法,并将在稍后将其和projector结合。当然同时熟悉这两项技术的开发者应该已经清楚,使用projector实现阴影意味着你将会消耗额外的drawcall,实际上被投射projector并且未在shader中使用"IgnoreProjector"="true"的物体都会在自身shader渲染完(也可能是渲染前,具体看自身渲染队列和projector的shader的渲染队列的先后顺序)后再次使用projector的shader渲染一次。

首先比较一下这种技术和shadowmap技术,实际上个人感觉很大程度上两者的技术其实差不多,都需要用到屏幕投影,只不过shadowmap投射的是深度图(深度缓冲),而本文介绍的是直接投射屏幕纹理(帧缓冲),因此投射的纹理是带Alpha通道的,

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

注意灯光空间的摄像机背景颜色的Alpha因为0,否则会把背景色也投射到接受阴影的物体上

和shadowmap不同的是,灯光空间的摄像机应该只看到投射阴影的物体:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

此时投射后的效果大致如图所示:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

当然使用这种方式投射rendertexture必然造成的一个问题是,由于没有投射接受阴影的平面,导致一旦投射阴影的物体穿透接受阴影的物体时会造成阴影的穿帮:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

阴影投射物体穿透阴影接受物体

接受阴影物体Shader主要实现代码:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

其中viewMatrix为灯光空间摄像机的worldToCameraMatrix,projMatrix为灯光空间摄像机的投影矩阵。

当然使用这种方式实现阴影的不足之处在于需要明确的知道投射阴影的物体和接受阴影的物体。

接下来将尝试将其与Projector结合,注意之前已经讨论过,使用projector意味着额外的drawcall,尤其是场景中物件很多且全部都是分离的物体时,不建议使用这种方式。当然如果场景中只有极少部分物体需要接受阴影,比如只有主要地形,则不妨可以尝试使用这种方式,因为使用projector,你可以很方便的在shader中加入IgnoreProjector标签来忽略投影机的作用,或者直接在projector上修改projector影响的层。

从unity标准资源包中的projector shader我们大致可以了解,projector shader中需要两个4阶矩阵,分别为_Projector和_ProjectorClip,其中后者主要用于近远裁面的淡入淡出,并不是必须的。而前者的_Projector,注意这个矩阵应该区别于摄像机的projection矩阵(尽管摄像机和projector在很多参数上很相似),原因是官方的projector shader中直接通过:o.uvShadow = mul (_Projector, vertex);计算得到投影纹理坐标,这意味着_Projector矩阵应该同时实现将vertex转换到世界空间,再转换到projector的局部空间,最后转换到projector的投影空间的功能,所以其性质应该类似UNITY_MATRIX_MVP矩阵,所以使用projector实现投射rendertexture的效果,只需要添加一个脚本,其会创建一个摄像机,并使用projector的参数,并将这个摄像机的rendertexture传递给projector的material,具体实现如下:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

其中_FadeTex是一张表示阴影衰减的贴图,其r、g通道效果如下:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

这是实现后的阴影效果:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

这里由于使用的RT是原始摄像机尺寸的1/2所以阴影质量有所下降

另外由于投射的是带Alpha通道的Rendertexture,意味着可以方便的对其使用模糊shader完成模糊效果,这里是我自己编写的模糊脚本效果图:

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

Unity Shader如何结合Projector和Rendertexture来实现实时阴影

关于Unity Shader如何结合Projector和Rendertexture来实现实时阴影就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI