👀

ノンデザイナーズ・3D画作り入門

2021/12/31に公開

「なんか物足りないなあ」

何年か前にゲームを作っていましたが、そのときにUnity初学者の後輩にレクスチャーしたことをいくつかまとめてみます。注意点として、これを書いているのはデザイナーではなくエンジニアです。まあ、本職じゃないから伝えられることもあるという感じです。

基本

デザインの基本

『ノンデザイナーズ・デザインブック』によると、デザインの基本原則は次の4つ

  • 近接
  • 整列
  • 反復
  • コントラスト

これは 3Dにおいても当てはまる

ここでは、これに加えてもう1つのキーワードを加えたい。

  • 密度

人間は 情報量が多いものを美しいと感じる

画を良くする

この野暮ったい画をどうにかしよう。

最初に4つの簡単なテクニックを紹介しつつ、周辺の技術についても考えてみる。この4つを使えればだいたいのことはカバーできるだろうし、他のエフェクトも使いなせるようになるだろう。

シャドウ

実は上の画像はデフォルトのUnityプロジェクトの設定とは異なっている。そう、シャドウ(shadow)が無効化されているのだ。有効化してみよう。

good! 良くなったことがわかる。 なぜ良くなったのだろうか。 これを考えることが重要だ。なぜ良くなったのかがわかればあらゆることに応用を効かせることができる。

  • 立体感が増えている
  • 「高さ」と「距離」がわかるようになった
  • 情報量が増えることによって 以前より安心感 がある
  • (物理法則に則った形で)「近接」「反復」「整列」の全てが増えている
  • コントラストが増えてる
  • 画面内の密度が増している

以前より情報量が増し有益そうになっているが、それ以上に美しくなっているように感じるのではないだろうか。これは気のせいではない。

美しさの代償についても触れておく。Unityのシャドウは以下の特徴を持つ(forward renderingの場合)

  • オブジェクトスペースのエフェクトの一種である
    • 影を実装するにはcasterとreceiverの2つが必要だが、casterは後述するshadowmapのレンダリング、receiverはfragment shader内のマクロとして実装されている
  • shadow mapによる実装である
    • shadow mapのバッファ分だけメモリを使用する
    • 毎フレーム、shadow mapをレンダリングするコスト(主にfragment shader)がかかる、これはshadow mapのサイズに依存する
    • clip planeによっては ギザギザしたりする がこれは原理的に避けられない(軽減する工夫はできる)

フォグ

もう1つ、オブジェクトスペースのエフェクトを使う。フォグだ。

フォグを使って 世界の境界線 を消す。そもそもリアルの世界には境界線はない。地平線は遠すぎて見えない。これが見えてしまうと作り物っぽく見えてしまう。

世界の果ての色 (この場合はskyboxの高度ゼロの色)をフォグに設定することで、この不自然さを軽減できる。

Unityのフォグについても簡単に説明しておこう。

  • オブジェクトスペースのエフェクトの一種である
    • shadowと同様に、fragment shader内のマクロとして実装されている
  • フォグの計算
    • やっていることは非常に簡単で、Unityのinspector上から設定できること(Fog, Color, Mode, Density)をシェーダにuniform変数として渡して、fragment shader内で該当ピクセルのワールド座標から色を計算しているだけである
    • ワールド座標からカメラとの距離を計算して、近ればそのまま、遠ければフォグ色とブレンドすれば良い
    • Unityのデフォルトのフォグだと微妙に線が見えるが、自前でシェーダを書けば完全に溶け込ませることができる。例えば、フォグ色を視線方向のskyboxから参照するとかすれば良い。

カラーコレクション

次はスクリーンスペースのエフェクトの一種、カラーコレクションを使う。

Post-processのcolor gradingを使った。今回は特に意図がないので、適当に彩度を落としただけである。

配色の基本、トンマナの一貫性を半ば強制的に実現できる。

color gradingの特徴についても説明しておこう。

  • スクリーンスペースのエフェクトである
  • ピクセルことに1回だけ計算するため、スクリーンサイズ分のバッファと計算量が必要になる

ブルーム

次はブルームを使おう。

いわゆる「光らせる」エフェクトである。Post-processのbloomを使った(わかりやすくするためにかなり強くかけている)。

  • 輝度の高い周辺のピクセルの輝度が上がる(=光る)
  • 全体の輝度が上がるため、全体的にはややコントラストが落ちる

「明るいものがあるとその周辺も明るくなる」という(直感的には正しいし、物理的にも正しい)現象を擬似的に再現する。

画面全体の情報量と密度は増えるが、それ以上に人間は光るものを美しいと感じる傾向がある。

bloomの特徴は

  • スクリーンスペースのエフェクトである
  • 比較的計算量が多い(と言われることが多い)
    • あるピクセルを計算するときにその周辺のピクセル値が必要になる、このため
    • 「綺麗にふわっと」出そうとするとある程度反復的な計算が必要になる(例えば「縦→横→縦→横と計算する」のように)
    • その分のバッファは必要になるが、バッファ自体は元のスクリーンの解像度は必ずしも必要はない(エッジを計算するというよりガウシアンを計算するようなものに近い)

ゲームを面白くする

これまで静止した画を改善することを考えてきたが、ついでに動くものを改善することを考えてみよう。

※ プロジェクトを用意する気力が残らなかっため、文字での説明だけになる。許してほしい。

アニメーション

それっぽいアニメーションを作る基本は 線形の変化は魅力ではない だ。線形の変化は人間にとって機械的で退屈に感じられる。

デザイナー的には「メリハリを出す」というワーディングになるのだろうか。ノンデザイナーズ・デザインブックでいうと「コントラストが弱い」という表現が適切だろう。

カメラ

カメラを考えるときに重要なのは次の2点

  • 被写体との距離
  • 画角(field of view)

ゲームの場合には、見やすさ(ゲームの難易度)と迫力(ゲームの体験)のトレードオフになる。TPSとFPSを考えてみればわかるだろう。

エフェクト

はじめてUnityを使いゲームを作り、友達に遊んでもらったときに誰もが同じようなフィードバックを受ける

  • 何が起きているかわかりにくい
  • なんか足りない

これは両方同じことを言っている。 エフェクトが足りない のだ。

ゲーム制作において、どのようなエフェクトをどれだけ入れるかについては実は原則がある。

  • ゲームの仕様(ルール)とエフェクトを一致させる
    • 1つの仕様に対して、最低1つのエフェクトが必要である
  • ゲームの体験とエフェクトを一致させる
    • 1つの体験に対して、最低1つのエフェクトが必要である
  • 仕様と体験の重要度とエフェクトの量を一致させる
    • 重要度とはゲームの目的達成にどれだけ関係するかである

例えば、「ドラッグしたらキャラが走る」というたった1行の短い仕様には次のエフェクトが必要になるだろう

  • ドラッグすることによってなにか変化が起きることを想起させる画面
  • ドラッグし始めた瞬間のUIエフェクト
    • UI上のエフェクトは操作に関わる情報を提示していることを想起させる
  • ドラッグ中のUIエフェクト
  • ドラッグ中にキャラが走るアニメーション
  • キャラが走っている最中に発生する砂埃のエフェクト
    • 砂埃はキャラの状態と地面の状態を想起させる
    • 砂埃の大きさは走っている速度に比例する
  • キャラが走っている足音のSE
    • 足音は走る速さと地面の状態を想起させる
  • ドラッグをやめることによってなにか変化が起きることを想起させるUI

ゲーム中のあらゆる状態とイベントにはエフェクトが必要である。なぜ初めて触ったゲームでも操作できるかというとそれだけ巧妙に作り込まれているからだ。「エフェクトは少なくて良い」という選択肢は存在しない。これは直感的に想像する数よりもずっと多い(ゲーム開発で見積もりを失敗しやすい理由の1つがこれだ)。

ゲームクリア(目的が達成された)あるいはゲームオーバー(目的達成が不可能になった)では、画面全体でそれを表現する必要がある。これに至るイベントが起きた場合や、近しい状態になった場合にもその重要度に比例するようにエフェクトを 複数重ねる 必要がある。

ゲーム以外のプロダクト開発経験があって、これからゲームを作ろうという人はこれだけ覚えておくと良い。ゲームに使用するエフェクトの量はそれ以外のプロダクトのものと比べると、3倍から10倍程度必要になる。

Discussion