开篇
这个分类主要想记录一下实现地表植被覆盖的n种方式,之前做场景的时候用ue地形模式刷过植被,也用过一些风格化的、可交互草地的素材资源...但它们!都不是!我的草!😕 还是会从案例学习分析开始,然后自己再复现一遍案例的效果。借此机会也积累一些自己做的shader、模型等等,熟悉一下各种实现的应用流程~ 总之就是,从零开始的播种计划!🌿🌿🌿
VFX Graph in Unity
上周实习看了一周的VFXGraph,今天的第一个案例就来自Unity官方的Sample#4 -GrassWind。 案例中的粒子草有如下特征:
- 每棵草是一个lit quad,通过alpha clip生成草叶(近看像素锯齿有点明显哎...);
- 静止时有风噪;
- 与玩家碰撞时会向移动方向弯曲,玩家离开后逐渐复位。 实例场景是一个类似开放世界的地图,场景中总共生成了65536棵草。似乎也没有LOD,看起来挺吓人的()但VFXgraph是用GPU计算,也不好说...反正现在的mbp运行啥都卡得要死🤔等我学会性能分析了再回来看看!
Generate
Grass Wind is an example that showcases the simulation of something totally different from regular particles: grass on a terrain. Using a point cache generated from terrain data, we spawn grass crops on a terrain with an up vector blended from the terrain normal and a world up vector. 从Houdini生成Point Cache,position存储世界空间坐标,direction存储地形法线。 在Initialize模块中需要完成:
Simulate
!!!
!!! 为实现与玩家的交互,我们需要获取玩家的位置和速度信息,可以通过自带的VFX Property Binder脚本抓取Controller状态。 计算粒子与玩家的距离用于采样曲线,用于模拟碰撞计算————0.5m内影响为1,>0.5m逐渐衰减。
- set Alpha
Alpha stores the pushed state : 1.0 = Not pushed, 0.0 = Fully Pushed. Negative values are allowed but the visual will not change. 两次插值距离和速度的影响:ReleaseSpeed控制粒子在玩家远离或静止时,alpha恢复的速度。
- add Velocity
Velocity will hold the push direction, based on the player position , velocity and push state.
- set Velocity
Render
我们希望草能够受到环境光的影响,并可以投射阴影,所以这里的输出选用了HDRP Lit Quad。为了让草有一定的随机性,粒子使用了一个Texture Sheet,通过random的index获取不同贴图。 注意,这里原项目中使用的Maincolor为psd格式,而不是下面这张png。psd文件单独储存了a通道用于Alpha clipping,背景色可以防止Threshold变化时出现边边。 草草倒伏的实现使用了VFXGaph很方便的一个节点[ConnectTarget],它可以自动计算旋转角,使粒子的z轴从自己的Position指向TargetPosition(initialize时设置为了朝上的草尖尖),同时正面(xy)保持朝向摄像机。 但是在connect之前,还需要将之前存储的velocity应用到target position上。
- set target position
- add target position from map
最后调整一下粒子的尺寸,使其距离过远时size也会衰减。(这里原始vfx里camera的线断了,可能是引擎版本问题。maincamera不能直接连给distance,展开找到position子项即可。) 别忘了把alpha设置回1,不然你就会变成行走的割草机。 最后整理一下细节~ 常用的粒子attribute见下图,这个案例中是把需要用到的一个vector3和一个float的数据存在了direction和alpha中。 direction和velocity挂钩,但因为草粒子本身其实是不动的,完全用不到这个属性,所以可以一直存储当前的倒伏方向。可以注意到,每次update到时候,是在原先的属性上ADD新的变化。 但alpha属性在渲染时是要用的,alpha clip时会计算来自贴图的alpha信息乘以粒子的Alpha信息。所以要在output时设置回1,下一次update时重新计算alpha。 如果不希望这么做,也可以用一个Custom Attribute来存储~
综上!通过VFXGraph来实现可交互草从逻辑上还是挺简单的,直觉而言感觉计算量好像有点大... 这几天过年在家,笔记本实在是太费劲啦!暂且省略复现的part,等回学校之后再补上。 Over!