
Unity Geometry Shader零基础指南从Realistic-Real-Time-Grass-Rendering-With-Unity拆解点扩展为12顶点草叶的完整流程【免费下载链接】Realistic-Real-Time-Grass-Rendering-With-UnityRealistic Real Time Grass Rendering With Unity. Using the Geometry Shader to generate millions of grass on GPU. refEdward Lee项目地址: https://gitcode.com/gh_mirrors/re/Realistic-Real-Time-Grass-Rendering-With-Unity这是一份面向新手的 Unity Geometry Shader 零基础教程。我们将基于开源项目Realistic-Real-Time-Grass-Rendering-With-Unity完整拆解如何用一张「点云贴图」 一段几何着色器在 GPU 上把 1 个顶点实时扩展成 12 个顶点的草叶最终渲染出数百万根随风摇曳的草——CPU 端几乎零开销。为什么 Geometry Shader 能渲染百万根草先建立一个直觉传统渲染中每一片草叶都是独立的网格顶点、法线、UV、三角形索引100 万根草意味着天文数字的顶点数据和海量 Draw Call。而这个项目的思路完全不同 阶段谁负责做什么CPUC# 脚本只生成「草地种子点」每根草 1 个点GPU 顶点着色器HLSL几乎原样转发点的位置、法线、UVGPU 几何着色器HLSL核心把 1 个点扩展成 12 个顶点的细长四边形条并施加风力动画GPU 片元着色器HLSL采样草叶贴图、Alpha 裁剪、光照计算一句话总结草的「身体」不存只存「根部坐标」几何体在 GPU 里现算。这就是它能轻松撑到数百万根的原因。项目要求 Unity 5.6本地搭建可用以下命令获取仓库git clone https://gitcode.com/gh_mirrors/re/Realistic-Real-Time-Grass-Rendering-With-Unity项目结构速览3 个文件撑起整套草渲染整个系统非常精简核心就三块建议对照项目目录逐个看Assets/Script/GrassSpanner.cs— CPU 端生成高度场地形 撒下草种子点Assets/Shader/GrassGeometryShader.shader— GPU 端Geometry Shader 点扩 12 顶点 风力 光照Assets/Mat/GrassMat.mat— 材质球绑定草叶贴图、高度、宽度参数辅助资源Assets/Texture/Heightmap.png地形高度图、Assets/Texture/grassBlade.png草叶贴图、Assets/Texture/grassBladeAlpha.pngAlpha 遮罩。第 1 步CPU 撒「种子点」——高度场地形与草点生成打开 GrassSpanner.csStart()里只做两件事GenerateTerrain()和GenerateField(30, 50)。高度图即地形。Heightmap.png是一张 1024×1024 的灰度图灰度值直接代表海拔。地形网格逐像素取样灰度 ×terrainHeight得到高度再随机撒点。三个新手要点草点贴地每个草点的高度同样查高度图heightMap.GetPixel(...).grayscale所以草会自然长在山坡上分块撒草GenerateField(30, 50)把 250×250 的地面划成 30×30 个 30×30 的小块每块撒 50 根密度均匀又不呆板按 65000 个点分 MeshSetIndices(..., MeshTopology.Points, 0)把拓扑设为「点」每 65000 个点拆一个grassLayer物体Unity 2017.3 之前索引缓冲是 16 位65535 是上限留了余量。CPU 的工作到此结束——场景里没有任何草的形状数据。第 2 步Geometry Shader 把 1 个点扩展成 12 顶点草叶打开 GrassGeometryShader.shader先注意两个「入场券」#pragma target 4.0— Geometry Shader 需要 Shader Model 4.0DirectX 11 / OpenGL 3.2[maxvertexcount(30)]— 向驱动声明「我一次最多吐出 30 个顶点」实际用 12 个留了余量。几何入口的签名值得逐字看懂void geom(point v2g points[1], inout TriangleStreamg2f triStream)point表示输入图元是点points[1]就是那 1 个根点triStream是输出流往里 Append 顶点就会自动组成三角形。Unity草渲染项目中草叶与落叶纹理材质效果预览12 个顶点是这样摆出来的草叶 6 段竖直四边形先取根点root用它的世界坐标算一个伪随机数random基于frac(root.x)、frac(root.z)的 sin 值——无需存储坐标即种子让每根草的高度和宽度都不一样_Width _Width random / 50_Height _Height random / 5进入 12 次循环偶数下标贴左侧、奇数下标贴右侧偶数pos.x root.x - _WidthUV 为(0, currentV)奇数pos.x root.x _WidthUV 为(1, currentV)并把currentV 1/5、currentVertexHeight currentV * _Height也就是说每走一对草叶就「向上长一段」6 对走完正好是一整片 0→1 的草叶贴图最后用 10 个三角形把 12 个顶点连成四边形条triStream.Append(v[p], v[p2], v[p1])循环p 0 … 9。整个草叶的「几何」就诞生于此——不占显存、不占顶点缓冲纯计算。第 3 步风力动画——为什么草叶上端摆得更厉害草叶要「活」就得随风摆动。项目没有做复杂的布娃娃模拟而是用了一段非常聪明的近似 ️基础风wind由sin(_Time.x * ...)叠加多频率正弦波构成再按根点坐标偏移相位避免全场草同步摆动随机扰动randomAngle/randomMagnitude给每根草一个固定的个体化风偏草群更自然关键一行windCoEff初始为 0每到一个奇数顶点就windCoEff offsetV即 0、0.2、0.4…1.0。位移量 wind * windCoEff根部系数为 0纹丝不动叶尖系数为 1摆幅最大——越往上摆得越大一行参数就模拟出了草叶的物理感。第 4 步片元着色器——AlphaTest 裁剪与 Blinn-Phong 光照frag阶段做的是标准光照流水线采样_MainTex草叶颜色_AlphaTexAlpha 通道配合 Pass 里的AlphaToMask On和材质队列AlphaTest把透明部分裁掉得到镂空草叶ShadeSH9取环境光 saturate(dot(N, L))漫反射 Blinn-Phong 高光三者和color.rgb相乘输出。材质 GrassMat.mat 中两个核心参数开箱即调参数默认值作用_Height3草叶基础长度顶点着色器中还会叠加随机量_Width0.05草叶基础宽度range 0~0.1想调「高瘦草」或「矮胖草」改这两个数即可无需碰代码。新手常见坑Geometry Shader 草渲染的 4 个注意点⚠️平台限制Geometry Shader 需要 SM 4.0部分老手机/低端 WebGL 环境会走 fallback 不显示草真机测试时留意⚠️65000 点的分块是 16 位索引缓冲的历史限制Unity 2017.3 支持 32 位索引后可以放宽⚠️Cull OFF别删草叶是双面薄片关闭双面裁剪否则背对镜头的草叶会消失⚠️[maxvertexcount]别小于实际输出顶点数否则驱动会直接丢弃图元屏幕上一片空白且很难排查。零基础总结这条管线你学会了吗把整条流程串起来就是一句话CPU 撒点 → 顶点着色器转发 → 几何着色器「点变草」→ 片元着色器上色。你只需要记住这个项目的精髓——把「形状生成」从 CPU 的模型数据挪到 GPU 的几何着色器里用坐标哈希出随机性用一行windCoEff换来整片草海的风声。掌握这套「点扩展」思路后替换贴图与参数你就能快速做出芦苇、头发、雪花等一切细长物体的海量实时渲染。【免费下载链接】Realistic-Real-Time-Grass-Rendering-With-UnityRealistic Real Time Grass Rendering With Unity. Using the Geometry Shader to generate millions of grass on GPU. refEdward Lee项目地址: https://gitcode.com/gh_mirrors/re/Realistic-Real-Time-Grass-Rendering-With-Unity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考