欢迎光临散文网 会员登陆 & 注册

21.Shader阴影效果

2023-06-11 17:44 作者:机智的小草yns  | 我要投稿

1.理论基础

在Unity当中,一般会采用阴影映射纹理(shadow map)实现阴影效果 。  

深度纹理:根据目标与相机的距离,越近颜色越深,反之越亮。

阴影映射纹理,则是在灯光视角的深度纹理


101的图

很多效果可以通过深度图来实现,比如相交高亮,方向雾效,扫描效果,水体的深度效果等等。


传统的阴影实现

把顶点位置变换到光源空间下,然后对阴影映射纹理进行采样,得到该位置的深度信息。如果纹理的深度<顶点的深度 , 则说明该点位于阴影中。

而在Unity 5中,使用的是屏幕空间的阴影映射技术(Screenspace Shadow Map)。屏幕空间的阴影映射原本是延迟渲染中产生阴影。(显卡需要支持MRT)

与传统阴影差不多,区别在于是延迟渲染,只计算屏幕空间内阴影

Unity的屏幕空间的阴影映射技术

使用ShadowCaster的Pass得到光源的阴影映射纹理以及摄像机的深度纹理

由两者映射得到屏幕空间的阴影图,然后对阴影图采样即可。


阴影映射纹理生成过程:

Unity把摄像机放到光源的位置上,然后调用该Pass,由顶点变换得到光源空间位置,并保存深度信息到阴影映射纹理中。


屏幕空间的阴影图生成过程:

从摄像机的深度纹理里采样得到该fragment的深度值,利用矩阵变换,

视角空间->世界空间-> 光源空间坐标, 与对比光源的阴影纹理的深度对比。

如果坐标深度>纹理深度, 则在阴影中。将阴影颜色记录在阴影图中。


以上的步骤,Unity都帮忙封装好了,我只需要使用它提供的宏, 得到阴影图,然后进行采样...


2.投射阴影

点光源的需要开启阴影

生成ShadowMap,固定写法,模式为ShadowCaster,使用到3个宏

代码 前篇的Lighting_mult.shader上修改)


出现点光源的阴影

核心宏

V2F_SHADOW_CASTER
TRANSFER_SHADOW_CASTER_NORMALOFFSET
SHADOW_CASTER_FRAGMENT


3.接收阴影

对阴影图采样即可。

核心代码

对于点光源 的阴影, 需要额外修改编译宏 ,其他的不变


接收到方块上阴影


核心宏

SHADOW_COORDS(n)  声明一个TEXCOORDn用于阴影采样坐标

TRANSFER_SHADOW(outputStruct o)   转换阴影的uv坐标

SHADOW_ATTENUATION(inputStruct i)   用来计算阴影值的, 相当于亮度值  

完整代码

https://github.com/smartgrass/MyCodes/blob/main/ShaderLearning/Lighting_mult_shadow.shader



21.Shader阴影效果的评论 (共 条)

分享到微博请遵守国家法律