您当前的位置: 首页 >  unity

VT LI

暂无认证

  • 5浏览

    0关注

    126博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

unity-builtin实现体积光

VT LI 发布时间:2022-03-06 22:55:41 ,浏览量:5

参考GitHub - SlightlyMad/VolumetricLights: Volumetric Lights for Unity这里实现的体积光会包括几个方面的影响。

 

 

 

制作的核心:

核心是灯光类型(平行光,点光源,聚光灯)。这些灯光类型会受到米尔散射通透度影响,高度指数雾,级联阴影,噪音影响以及降噪。

原理:

无论哪个光照,他都会按照步进的次数跟摄像机的四个视角顶点的距离做比较,然后再跟深度以及地面比较,看究竟跟哪个最近则选择谁是最终碰撞点,然后选取颜色。

平行光:

首先_FrustumCorners存储的是视野的四个角的位置世界坐标。

顶点着色:

在顶点着色中通过i.uv.x + i.uv.y*2来获取_FrustumCorners的索引,看究竟这个顶点跟在屏幕空间究竟跟哪个角最接近,则方向就以这个角为终点的xy值。

片元着色:

在片元着色器中摄像机位置为起点,顶点着色得到的的摄像机的角再乘深度值得到世界坐标值。然后除总长度得到他的步长单位方向,然后给到RayMarch去步进

 

RayMarch

再RayMarch中,通过步进总长度除步进次数得到每次步进的长度。

然后首先获取灯光的阴影GetLightAttenuation,他这里考虑了级联阴影,通过GetCascadeWeights_SplitSpheres来获取位置与级联阴影的的距离,因为最多四个级联阴影所以刚好记录在一个float4中,然后记录到权重中,权重的值要拿级联的前后级相减来得到差异。

 

拿到的权重带入到GetCascadeShadowCoord中得到采样的级联的位置。主要是采样四个级联的阴影然后根据权重混合起来

 

如果在级联范围内则采样这个权重级联的值,不然直接算作1.

 

除了拿到阴影,还要拿密度GetDensity,他的密度跟x轴和z轴有关,z轴越远密度越高。

 

密度这里如果开启了高度相关的雾效则会执行ApplyHeightFog,主要是跟高度成指数关系变化。

 

然后拿到密度后根据步进步长计算通透和衰减。衰减成指数衰减。

 

步进完成得到颜色后会加上mie散射的值,mie散射强度与频率的二次方成正比,并且散射在光线向前方向比向后方向更强,方向性比较明显。在从c#中的MieG即使米尔散射的强度。

 

shader中:

 

点光源: 片元着色:

点光源要关注到到要步进的最长长度,这里要注意的是首先会先拿到raylength,他是像素位置的世界坐标到相机的位置的距离“长度A”,因为这个距离内可能会有被挡着的对象,所以还需要拿到相机的朝向做步进的投影,让深度除投影的值来得到深度上最大的步长“长度B”。然后长度A和长度B的最小值就是步进的最大值。

 

RayMarch

然后还是执行RayMarch来步进,这里的米尔散射会在步进的时候计算,他跟平行光有差异,平行光只需要步进完一次性计算,但是点光会有衰减,所以要步进过程中计算。

 

后面的计算跟平行光一样。

聚光灯:

聚光灯需要关注三个的最小值才为相交的物体

第一个是关注平面RayPlaneIntersect,这里个到两个参数可以确定平面信息,一个是平面的法线,一个是平面方程ax + by + cz + d = 0的d。然后按投影的方式得到t,这个t就是平面和点的距离。

 

第二个关注的是聚光灯的圆锥范围内的相交RayConeIntersect。

 

第三个是深度

三个选最小的

 

然后进行步进RayMarch,步进方式跟点光源一样。

关注
打赏
1649603425
查看更多评论
立即登录/注册

微信扫码登录

0.1617s