目录
体积光的项目分享:
https://github.com/Claymoreno1/volumelight
https://github.com/Claymoreno1/GodRay
体积光的实现方法有很多种,这里列出三种常用的,此篇博客详细讲解了通过后处理径向模糊方式的体积光实现,另一篇RayMarching体积光讲解了另一种更真实效果更好的方法,其它方式提供了方法和详细链接。
- 最简单,手游比较常见的是特效贴片
我们看见的光束其实就是下面这张图片,通过粒子效果很简单就能够实现
- ShadowGun中经典的GodRays,Blinking GodRays和Blinking GodRays Billboarded,根据远近控制淡入淡出,稍微复杂一点的增加了闪烁和广告牌,如果想学习可以看女神的ShadowGun系列之二——雾和体积光
- 屏幕后处理方式(消耗高,也更真实,也是本篇博客的重点内容)
第一步:提取光源部分
这一部分比较简单,我们主要从深度和颜色两个方面做阈值,来得到体积光光源
因为体积光的光源一般在距离比较远或者高的地方,必须防止把人物或者其他拥有强颜色的物体错当成光源。(当然,有时候我们也不想让远处的物体发光,把step翻过来用就行了)
片段着色器代码如下,本文会在最后提供后处理体积光的全部C#与ShaderLab代码
float4 frag(v2f i):SV_Target{
float4 col=tex2D(_MainTex,i.uv);
float linearDepth=LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv));
col*=step(_StepColor.r+_StepColor.g,col.r+col.g)*step(_Depthfloor,linearDepth);
return col;
}
第一个pass结果:
第二步:径向模糊
径向模糊和高斯模糊的区别就在于一个是照着一条线采样求均值,另一个是在像素周围采样利用权值计算均值。
- 方法1
首先得到一条从当前像素到模糊中心的向量
float2 center=_LightPos.xy;
float2 uv=i.uv-center;
当前点的像素颜色值,来自于从沿着这条向量采样的颜色均值
for(float j=0;j<_Level;j++){
col+=tex2D(_MainTex,uv*(1-0.01*j)+center);
}
col/=_Level;
- 方法2
其实大体原理和方法1一样,因为径向模糊定义就是如此,不同之处在于添加了采样步长控制向量,添加了一些setp来控制模糊方向
float2 blur=_LightDir.xy*(_LightPos.xy-i.uv);//*step(0,_LightPos.y-i.uv.y);
for(float j=0;j<_Level;j++){
col+=tex2D(_MainTex,i.uv);
i.uv+=blur;
}
col/=_Level;
这个效果需要在OnRenderImage函数中对采样步长修改,反复Blit几次
blurtype为ture,方法2
if (blurtype)
{
for (int i = 0; i < LightIntencity; i++)
{
LightDirx_2 = LightDirx * (i * 2 + 2);
LightDiry_2 = LightDiry * (i *