🌊

[blender]3DCGってどうなってんのっていう話[気合]

2024/04/23に公開

はじめに

こんにちは、ゆきおです。
今日はBlenderを使った3DCGレンダリングについて、ザっと書いていこうと思います。
一個一個書いてたら来世になるので大事な要素や流れとかを残しておきたいなと思いました。

作成したCG

以前すこし触れましたが、自然風景を3DCGで作りたいという気持ちがあったのでUdemyで教材を探してチャレンジしてみました。
スクリーンショット 2023-08-10 193925.png
スクリーンショット 2023-08-16 161041.png
スクリーンショット 2023-08-18 124458.png
本当に何もないところから地面を作成し、草をモデリングして生やしたり石を転がしたり川を流したり木を生やしたりして自然風景を作成しました。
モノによってはUnityやUEのように元々用意されているアセットだったり、川や草なんかは1から作成しました。
このモデリングの作業がほんとーーーーーにチマチマ地道作業で気合と根性です。
今回はどういった流れでこれを作成したのか、重要な機能など簡単にですがまとめていきたいと思います。

ノード

3Dを作成する際に欠かせない要素として、「ノード」というものがあります。
これはUnityやUEなど他のツールでも使われる機能です。
CGを出力するためのプログラムを言語で組むのではなく、ノードと呼ばれる様々な役割を持ったパーツを線で繋げて形や色、表面の質感(テクスチャ)だったり陰影(シェーダー)を表現します。
プログラムというのは上から下へインプット→アウトプットになりますが、ノードエディタの場合は左がインプットで右がアウトプットです。

・ジオメトリノード
オブジェクトの形状や位置、回転や大きさなどの属性を生成したり変更したりするシステム。
今回は地面の凸凹具合や、各オブジェクトの量や回転をジオメトリノードで繋ぎ合わせることでランダムかつ自然な配置を実現しています。
スクリーンショット 2024-04-23 112623.png
ほんの一例ですが、このように一つ一つがノードというもので、数学的な関数を掛け合わせたりフラグを立てたりして、地面に対してどの程度生やすかとか川の上にはレンダリングしないようにとか色々表現できます。
地面に対してと書きましたが、ほかにも「岩に対してどのくらい苔を生やすか」とか「木の枝に対してどのくらい葉をつけるか」なんて使い方もしています。

今回作ったものに関しては木、草、石、川などがあり更にそれの大・中・小だったりちょっとした種類違いだったりのジオメトリノードを作成しており、メインの親ジオメトリノードは以下のようになります。
スクリーンショット 2024-04-23 113731.png
カラフルな小さいノードの中身が先ほどのジオメトリノードで、各オブジェクトのジオメトリノードをこの親ジオメトリノードで繋ぎ合わせてプロパティとして定義し(一番左の長ーいノード)、エディタの方で微調整しやすくしています。
草や花などのモデリングももちろんですが、こういった作業もチマチマやります。

スクリーンショット 2024-04-23 114349.png
こんな感じで各オブジェクトの量をエディタの方で一括管理できるようになります。(ざっくり

同じ名前のオブジェクトが「render」と「VP」という二つの項目に分かれている理由は後述します。

・シェーダーノード
次に同じく重要な要素として、シェーダーというものがあります。
オブジェクトに張り付けるマテリアル、その質感であるテクスチャ、それに光が当たった時の反射や影、透明度などを表現します。

現実世界にあるもの、起こっていることをめちゃくちゃ数学的に表現します。
スクリーンショット 2024-04-23 122309.png
これまたノードを繋ぎ合わせています。

主な機能としては
マテリアルのプロパティ制御:色、透明度、反射率、屈折率、ラフネス(ザラつき)など、マテリアルの様々な属性を制御
テクスチャマッピング:画像やプロシージャルテクスチャをマテリアルに適用し、よりリアルな見た目を実現
ライティングの制御:マテリアルが光をどのように反射し、影を落とすかを設定

水面とかガラスとか、布だとか革だとか、鉄だとか銅だとか、あらゆる質感や光の反射具合などをこのシェーダーエディタで調整します。

そのためには色情報を持つカラーマップ、凸凹情報をもつ法線マップ、粗さを表現するラフネスマップ、金属感を表現するメタリックマップなど様々な画像を重ねてオブジェクトに張り付けることで、リアルな3Dというのが表現できます。

なんとなくお察しかとは思いますが、リアルなほど容量がデカく、かつそれを大量に描写するのでめちゃくちゃ重くてPCが火を噴いてしまいます。

ということで、次は重たい作業負荷を軽減する手法を書いていきます。

Proxyの作成

そんな重たい3DCG制作ですが、プロキシを作成するという手法があります。
プロキシはサーバーなんかで使われる言葉で「代理」という意味ですね。
本来レンダリングするオブジェクトに形だけ寄せたドシンプルなオブジェクトを、作業中はビューポート(Blenderのエディタ画面)上に表示し、レンダリングの時は実際のオブジェクトを表示するようにジオメトリノードのフラグで設定することで作業中の負荷を軽減させます。
スクリーンショット 2024-04-23 110125.png
このようにわかりやすく色分けしてザックリとした形のオブジェクトを作業中は表示するようにできます。
スクリーンショット 2024-04-23 110157.png
色分けすることで何がどんくらい配置されているかを把握しやすくなります。
先ほどrenderとVPの2つに分けていたのはレンダリングとビューポートの配置で分けてるわけです。
基本的にrenderとVPの値を一緒にしておけばビューポートで見たまんまの構図でレンダリングできます。

じゃあレンダリングしたら結局重いじゃん。て話なんですが、めちゃくちゃ重いです。

スペックによっては何時間もかかったりする上に火を噴きます。
それを少しでも軽減する手法があります。

LODとカリング

LODとはLevel Of Detailの略で「カメラからの距離に応じてポリゴン数を増減させる」というものです。
カメラの近くは精細にレンダリングして、遠くにあるものはざっくりレンダリングするという機能です。
「LOD0」とか「LOD1」のように定義して、レベルに応じたポリゴン数のモデルを用意します。
なのでレベルの数だけ同じモデルのポリゴン違いが必要になりますね。

もうひとつの要素であるカリングは「カメラの画角外のオブジェクトをカットする」という機能です。
カメラの視界に入っていないものは一切レンダリングしないというものです。

これもノードエディタ同様、UnityやUEなどほかのツールでもよく使う共通言語みたいなものです。

オープンワールドやバトロワみたいな広いマップのゲームをプレイしていると分かりやすいと思いますが、遠ーくの建物や景色は霧がかかってることが多いと思います。
遠近感を演出するとともに、遠くのオブジェクトの粗さを目立たなくしているんだと思っています。

カリングに関しても、グランドセフトオートで爆速で移動してみると移動とレンダリングが非同期で走ってるのがわかりやすいかと思います。
カメラに映ってない部分はレンダリングしておらず、カメラの移動に合わせてマップをレンダリングしているので、それが追い付かないレベルで爆走してると建物が生えてくるのが見えると思います(たぶん

こういった機能を使うことで、レンダリングの負荷も極力軽減させることができます。

おわり

今回は主な機能やテクニックについて紹介しました。
ちょくちょく書いていますが、これらはゲームエンジンや3Dツールで頻繁に使われる機能です。
もちろん、Blenderで作成したモデルをUnityなどでアセットとして使うことだってできます。
Udemyにもたくさん教材があるので、ゲーム制作やCG制作に興味がある方はぜひともチャレンジしてみてください!

Discussion