原神3.x的沙漠地面交互很有意思,尝试复现了一下。目前能够复现基础的下陷和恢复效果。这里记录大致方案。选择这个方案的主要原因是美术效果上限高且配置简单,场景里放一个 script 就能生效,与网上一些教程不同,无需为每个角色配置粒子发射器。
方案是用两张 depth texture,一张从上方捕捉地形,一张从下方捕捉物体,合并计算出一张物体陷入沙地的 indent map。indent map 的 R通道代表凹陷,通过后处理在G通道生成描边(模拟凹陷周围的一圈凸起)并模糊。沙地 shader 用这张 indent map 作为高度图,配合 distance-based tessellation。目前只能在固定范围内生效,且没有优化性能开销和美术表现。后续有空可能会慢慢继续开发。
大致需求:
- 不仅限于角色。怪物,物件等都能与沙地产生交互
- 无需为每个可以产生交互的单位做特殊配置
- 沙子下陷区域的轮廓贴合与其接触的 mesh (是 mesh 本身而不是碰撞体积)
- 下陷区域周围有一圈凸起的沙子,模拟沙子被向周围推开的效果
- 下陷随时间恢复
- 效果生效范围可以很大,兼容开放世界
Some simple interactive snow shaders found online require special per-object setups. Eg. Add particle emitters to a character’s left and right foot, use a camera to capture particles from the top, and pass the render texture to the shader. Most approaches also only work in a small pre-defined area. These methods work well for small projects and demos, but lack accuracy, flexibility, and scalabiliy. Scalability is a crucial aspect to consider, especially for games like Genshin Impact, where there’a a large expanding open world and new characters are being constantly implemented. It would be quite cumbersome to add another step to the character configuration process, just for one functionality available in certain regions of a scene. It would be better to have a system that is decoupled from the character configuration process. Furthermore, it we would need a lot of work to ensure visual quality using the particle emitter approach, since the shapes of the particles are largely fixed.
Batman: Arkham Origins uses a depth capture method, described in this GDC video. This is a promising approach with high extendability. Camera depth texture captures object shapes with higher precision, and we don’t have to setup particle systems for every character or object we want to capture. There are some limitations though. The depth capture method used in Batman: Arkham Origins only supports flat terrain, and doesn’t work well on uneven surfaces. Objects on a higher elevation might be ignored because they’re outside the depth threshold. One way to address this problem is to use a second depth camera to capture terrain depth. Then, we can combine object depth with terrain depth to obtain a normalized depth texture that describes object depth in terrain space. Another problem is open world compatibility. Batman: Arkham Origins uses a pooling approach to manage multiple depth textures for different pre-defined areas. To allow easier open world integration, it might be possible to just use one texture, and constantly offset its contents based on the world offset of our character.
The current WIP terrain deformation pipeline uses a modified approach to achieve similar results as Genshin Impact.
Features
√ The shape of sand deformation follows the contour of whatever mesh that intersects with the terrain.
√ Detailed indents, including a ring of raised sand around the indent, simulating how sand is pushed away from the point of contact.
√ Indentations slowly regenerate over time.
√ Compatible with open world. The effect will be triggered within an area around the player character.
√ No special configuration needed. Any mesh can leave trails on the terrain as long as they’re in the target layers.
How it works
- Use a 2-camera setup: Bottom camera to capture object depths, and top camera to capture terrain depth. The depth textures are combined to generate a single normalized depth texture of object depths.
- Apply Kawase blur to the depth texture to smooth the result. Apply an extra pass to generate outlines on a different color channel.
- Areas where sand should be lowered are now marked by R pixels, while areas where sand should be raised are marked by G pixels.
- Add the new pixels to the current heightmap texture. A compute shader updates the texture to fade pixels over time, which regenerates the indentations.
- An external script passes required information to the sand shader and controls the worldspace position of the depth cameras. This script can be configured to follow the current active character and provide its wordspace position change per frame. The heigthmap is shifted based on target position change. This way, the effect will always be available around the player.
- The sand shader uses the heightmap texture to perform distance-based tessellation. The shader also maps worldspace position change to texture uv, so that deformation is applied at the correct position.
Note
- No Unity terrain system integration at the moment.
- Due to precision limitations, the heigtmap under bilinear/trilinear filtering will be come a bit more blurry every time it’s shifted. A potential solution is to accumulate character position change and only offset the texture when we reach whole values.
- Genshin Impact has special self-shadows in the indented area. This is not implemented here.