为什么只给GPU传“点”就能长出百万棵草?Realistic-Real-Time-Grass-Rendering-With-Unity的内存节省原理
【免费下载链接】Realistic-Real-Time-Grass-Rendering-With-UnityRealistic Real Time Grass Rendering With Unity. Using the Geometry Shader to generate millions of grass on GPU. ref:Edward Lee项目地址: https://gitcode.com/gh_mirrors/re/Realistic-Real-Time-Grass-Rendering-With-Unity
Realistic-Real-Time-Grass-Rendering-With-Unity 是一个 Unity 实时草地渲染项目:它只向 GPU 传送每棵草一个点,再由几何着色器(Geometry Shader)在 GPU 上把每个点“长成”一棵完整的草,从而用极小的显存开销生成数百万棵随风摇曳的草。本文带你搞懂这套 GPU 草地生成方案的内存节省原理。
传统做法:每棵草都是一坨顶点
先看看“老实”的渲染方式有多费内存。
如果你想渲染 100 万棵草,传统思路是给每棵草建一个完整网格(至少一个四边形,4 个顶点),然后把全部顶点数据塞进顶点缓冲:
| 数据项 | 每棵草占用 |
|---|---|
| 顶点位置(4 个 × 3 个 float) | 48 字节 |
| 法线(4 个 × 3 个 float) | 48 字节 |
| 纹理坐标(4 个 × 2 个 float) | 32 字节 |
| 索引(2 个三角形 × 3) | 12 字节 |
| 合计 | ≈ 140 字节 |
100 万棵草 ≈140MB纯几何数据,还没算动画更新时 CPU 每帧搬运数据的开销。显存吃紧不说,顶点吞吐也会成为帧率瓶颈。
核心原理:点图元 + 几何着色器
这个项目的思路非常巧妙——把“几何数据”和“几何生成”拆开:
- CPU 只发点:GrassSpanner.cs 读取高度贴图(Heightmap),按
30×30的草斑(patch)划分地块,在每个草斑里随机撒 30 个坐标点,总计约 2.7 万个点。每个点只有位置数据,且按 65000 点一块切分成多个 Mesh(受 16 位索引上限限制)。 - GPU 现场长草:GrassGeometryShader.shader 中的几何着色器声明为
geom(point v2g points[1], ...)——输入图元是点。每收到 1 个点,就在 GPU 上展开成 12 个顶点、拼成 10 个三角形的完整草叶,直接交给三角形流水。
也就是说:存的是 1 个点,画的是 1 棵草,中间 11 倍膨胀的顶点全部由 GPU 临时计算出来,从不落地、不占显存。
项目自带的高度贴图Assets/Texture/Heightmap.png:CPU 用它采样灰度值,决定每棵草的落点高度
内存账本:140MB 降到 14MB
对比一下两种方案在 100 万棵草规模下的显存占用:
| 方案 | 每棵草数据 | 100 万棵总占用 |
|---|---|---|
| 传统完整网格 | ≈ 140 字节 | ≈140MB |
| 本项目的点图元 | ≈ 14 字节(12B 位置 + 2B 索引) | ≈14MB |
显存直接省了约 10 倍,而且省得越多越香——草的规模越大,传统方案的顶点缓冲膨胀得越快,点图元方案始终只有“每个点 14 字节”的线性开销。这就是“百万棵草”在普通显卡上也跑得动的底气。
免费附赠:动画也在 GPU 上
传统方案还有一个隐藏成本:草要随风摆动,CPU 每帧得更新顶点缓冲、来回搬数据。而在这个项目里,风是几何着色器里几行正弦函数的活儿:
- 根据点坐标算出一个确定性随机数,让每棵草的高度和宽度各不相同(
_Height、_Width在着色器里动态扰动); - 用
_Time驱动风力向量,草叶越高摆幅越大,形成自然的“根部固定、梢部摇摆”效果。
动画、随机化全部发生在 GPU 的几何着色阶段,CPU 端每帧零更新——内存省了,带宽也省了。

项目附带的草地与落叶混合材质预览(Assets/Grass & dead leafs 01/),几何着色器生成的草叶同样能配合这类高质量纹理
快速体验:三步跑通 Demo
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/re/Realistic-Real-Time-Grass-Rendering-With-Unity- 用 Unity 2017.1+ 打开项目(README 标注 Unity 5.6+ 即可运行;Unity 2017.3 起支持 32 位索引缓冲,单 Mesh 可放下更多点)。
- 打开
Assets/Scene/demo.unity场景,等待GrassSpanner在地形上撒完点,即可看到整片草地随风摆动。
💡 注意:几何着色器要求
#pragma target 4.0,即显卡需支持 DirectX 11 / Shader Model 4.0(现代独立显卡基本都满足)。
关键文件速查
| 文件 | 作用 |
|---|---|
Assets/Shader/GrassGeometryShader.shader | 核心:点 → 草叶的几何着色器,含随机化与风力计算 |
Assets/Script/GrassSpanner.cs | 读取高度图生成地形,并在草地上撒点(65000 点分块) |
Assets/Mat/GrassMat.mat | 草地渲染材质 |
Assets/Texture/Heightmap.png | 高度贴图,决定地形起伏与草的落点 |
Assets/Texture/grassBlade.png | 草叶 Albedo 贴图 |
Assets/Texture/grassBladeAlpha.png | 草叶 Alpha 贴图 |
一句话总结:把每棵草的顶点数从 GPU 视角压缩到 1 个点,让几何着色器在流水线上现算现用——这是 Realistic-Real-Time-Grass-Rendering-With-Unity 能用极小内存渲染百万棵草的全部秘密。
【免费下载链接】Realistic-Real-Time-Grass-Rendering-With-UnityRealistic Real Time Grass Rendering With Unity. Using the Geometry Shader to generate millions of grass on GPU. ref:Edward Lee项目地址: https://gitcode.com/gh_mirrors/re/Realistic-Real-Time-Grass-Rendering-With-Unity
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考