---
title: 【Unity】大量の草を生やせ！
tags:  #unity  
author: [おかひろ](https://convert.docswell.com/user/okahiro_p)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/YE9NP934E3.jpg?width=480
description: 2023年8月に新横浜インディゲームもくもく会でLTした資料です。
published: August 14, 23
canonical: https://convert.docswell.com/s/okahiro_p/KJLQ2V-2023-08-14-081556
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/YE9NP934E3.jpg)

Unityで大量の草を生やせ！
おかひろ


# Page. 2

![Page Image](https://bcdn.docswell.com/page/GE8KD9MV7D.jpg)

自己紹介

おかひろ

Twitter：@okahiro_p

フリーランスのTA

個人で東方二次創作ゲーム作っています


# Page. 3

![Page Image](https://bcdn.docswell.com/page/LELZMW3RJR.jpg)

こういうやつをやります


# Page. 4

![Page Image](https://bcdn.docswell.com/page/4JMVY9DPJW.jpg)

草

1本6Trisの草を90本生やして1オブジェクトとする

オブジェクトを10,000個並べる


90万本の草
先端が風で揺れるような表現をする

VertexShaderで動かす


# Page. 5

![Page Image](https://bcdn.docswell.com/page/PJR29G4YE9.jpg)

こんな感じで写す

約7400オブジェクト（66万本の草）が写るショット


# Page. 6

![Page Image](https://bcdn.docswell.com/page/PEXDQX247X.jpg)

最初に

まずは愚直に10,000個オブジェクトを並べてみる
※左端1,000個選択


# Page. 7

![Page Image](https://bcdn.docswell.com/page/3EKX9WMP7D.jpg)

結果
※Pixel6で計測
・SetPassCall：23
・DrawCalls：7.3k
・Tris：3.9M


# Page. 8

![Page Image](https://bcdn.docswell.com/page/L735W1Y4E5.jpg)

重い！

DrawCallが7.3kある

DrawCall：CPUがGPUに出す描画命令。描画対象のオブジェクト数分発行される


10kでないのは、2.7kはカメラに写っていないためカリングされている
Materialはすべて一緒なのでSetPassCallは多くない
CPU
GPU
描画命令
7300回


# Page. 9

![Page Image](https://bcdn.docswell.com/page/87DDKX557G.jpg)

DrawMeshInstancedIndirect

同じMesh・Materialを大量に描画できる

CPUからGPUへの描画命令を1回で行う
CPU
GPU
描画命令


# Page. 10

![Page Image](https://bcdn.docswell.com/page/VJPXKPGD78.jpg)

結果
※Pixel6で計測
・SetPassCall：23
・DrawCalls：23


# Page. 11

![Page Image](https://bcdn.docswell.com/page/2EVLV26GJQ.jpg)

早くなった・・・けど

まだFPS30いっていない

更に改善

DrawMeshInstancedIndirectだと10,000オブジェクト分を指定しているが、実際はすべてカ
メラに写るわけではないので、Cullingを行う

ComputeShaderによる擬似視錐台カリング


最初の例ではUnityが勝手に視錐台カリングしてくれていたが、DrawMeshInstancedIndirectする場合は自前で
Cullingが必要
遠くの草も1オブジェクトあたり90本の草を描画しなくても良さそう。

ComputeShaderでLODを行い、遠くの草は低ポリゴンのものに差し替える

更に、遠くの草は風で揺れなくても良い（どうせ見えない）

VertexShaderの処理削減
中距離用の草（20本）
遠距離用の草（10本)


# Page. 12

![Page Image](https://bcdn.docswell.com/page/57GXLR2DEL.jpg)

CullingとLOD
CullingとLODなし
CullingとLODあり
※LODをわかりやすくするため、遠距離：赤、中
距離：青の色をつけている


# Page. 13

![Page Image](https://bcdn.docswell.com/page/4EQ8YVPXJP.jpg)

結果
※Pixel6で計測
・SetPassCall：23
・DrawCalls：23


# Page. 14

![Page Image](https://bcdn.docswell.com/page/KJ42WMY2E1.jpg)

草の生やし方

実際のゲームでは、草原がきれいな正方形になることはほとんどないと思う

描画速度を担保しつつ、生え方も考慮したい


# Page. 15

![Page Image](https://bcdn.docswell.com/page/LE1MY86K7G.jpg)

いろいろ方法がありそうだが・・・

100×100pxの画像を用意し、ピクセルごとにrの値が0なら草を生やさない、1
なら草を生やす処理を実装してみた

このあとCullingとLODのComputeShaderに値を回すのと、並列で処理しやすいので
これもComputeShaderで実行


# Page. 16

![Page Image](https://bcdn.docswell.com/page/GEW3GZWPE2.jpg)

例
わかりにくくなるためCullingはオフ


# Page. 17

![Page Image](https://bcdn.docswell.com/page/47ZVL156E3.jpg)

例
わかりにくくなるためCullingはオフ


# Page. 18

![Page Image](https://bcdn.docswell.com/page/YJ65WL9L7V.jpg)

例
わかりにくくなるためCullingはオフ


# Page. 19

![Page Image](https://bcdn.docswell.com/page/GJ5YM1NMJ4.jpg)

参考資料

モバイル向け大量描画テクニック


UnityURP-MobileDrawMeshInstancedIndirectExample


https://github.com/ColinLeung-NiloCat/UnityURPMobileDrawMeshInstancedIndirectExample
OpenWorldGrassDemo


https://www.youtube.com/watch?v=mmxpPDVskg0
https://github.com/Gamu2059/OpenWorldGrassDemo
Recipes for Shaders and Visual Effects

https://resources.unity.com/ebooks/the-universal-render-pipeline-cookbook-unity2022-lts-edition?ungated=true


# Page. 20

![Page Image](https://bcdn.docswell.com/page/LE35W129J5.jpg)

ご清聴ありがとうございました


