ゲームプログラミング/3Dグラフィック/手書きアニメ調の3D

よく、3D-CGなのに、まるで手書きアニメっぽい画像を表示するゲームが、何本もある。
あれらの仕組みはどうなっているのかというと、一般にはトゥーン・レンダリングといわれる技術を使っていると考えられ、下記のような工夫がよくある。
トゥーンレンダリングといった場合、主に、
がある。
しかし、ゲーム産業では、たとえアニメキャラ風のキャラクターデザインのゲームでも、あまり色彩の階調化は使われない。
いっぽう、アニメ絵風のゲームでも、輪郭線の自動的な描画は使われる作品が多い。

この、輪郭線や鼻ラインや口ラインなどの抽出のことを、CG学では「ライン描画」などと言います。
計算量さえ無視していいのなら、かなり厳密に正確なライン描画をする方法がいくつか知られています。
たとえば、カメラの向きを少し変えた2枚の画像を照合して、片方の面で新しく現れた面を、黒く(輪郭線の色)で表示することによって、輪郭線を描くという方法もあ、これは「暗示的輪郭線」(suggestive contours)といわれる手法です。
この方法を使えば、顔の側面などの輪郭だけでなく、鼻や口などのラインも抽出できます。実際、書籍『可視化の技術と現代幾何学』では、 デッサン人形風の3Dデータの顔をもとに、この抽出法で、手書きの線画のようは鼻や口のラインを抽出するのに成功したシミュレーション結果を掲載しています。
しかし、この方法は、ゲームとしては、2つの画面の3次元データを照合する必要があるので、ややアルゴリズムが複雑になる懸念と、計算量がやや多そうな懸念があるでしょう。
もし、鼻も口も抽出せずに、単に、顔の側面や胴体側面などといった側面の輪郭だけを抽出する場合なら、単に、ベクトル内積の計算を使って、ポリゴンの垂直線(仮にuとする)と、カメラの視線ベクトル(仮にvとする)の内積 u・v が0になるところを選べばいいだけです。
(高校数学で習うように、垂直に交わり会うベクトルは内積が0であるので。そして、顔の側面などの輪郭線は、必ず カメラの向きに垂直になるので。 )
ただし、この方法だけだと、鼻も口も書かれないので、人の顔だとは認識しづらい結果になります。
なので、学問的には、なんとかして、顔や口のラインを抽出する方法が求められています。こういうのに、ハリウッド映画業界などが投資していたり、数学者と共同研究したりしています。
しかし、日本の中小のゲーム会社はそんな大金を投資できないし、そこまで共同研究できないので、もっと別の方法を考えだしています。下記の「シルエットなんとか法」とか、テクスチャーとして最初から目や口の絵を書き込んでしまうとか、そういう方法を使います。
こうすれば、研究費を削減できるし、ポリゴン数も減らせて処理速度も向上するので一石二鳥です。
当然、ハリウッド映画などには応用できない手法でしょう。

登場人物のCGの輪郭線を、マンガみたいに線を強調して表示したい場合、手法はいろいろとあるが、どれも仕組みは単純である。

手法のひとつとして、単に人物の画像をコピーして、それをすべてシルエット上に真っ黒にコピーしてから、やや大きく拡大し、さらにその上にもとの画像(黒くしてない画像)を載せると、輪郭ちかくのハジッコのほうだけは手前の画像に隠されずに奥側の黒い画像が見えるので、あたかも輪郭線っぽく見えるという手法がある。
これは、3D計算が不要なので、簡便だが便利な方法である。
欠点としては、たとえば「腕をくんでるポーズの人」をカメラが見た場合のように、人物の胴体の手前に人物の手が重なっている等の、人体のパーツどうしが重なっている場合には、手間が増える(人物1体ごとの黒コピーに加えて、さらに身体各部の黒コピーをする必要がある)。
また、身体各部の黒コピーをした場合、間接のあたりに、妙な線が発生しやすい。普通の漫画家は、腕を曲げてない場合には肘の内側を見てるシーンでは間接のシワ線を書かないが、しかし黒コピー線が曲げてない間接のあたりで発生しやすい。
こうした想定外の間接線を除外する方法としては、間接の近くでは黒コピーを除外する、つまり、最初からコピーする時点ですでに間接ちかくの部分はコピーしないでおく、・・・といった方法もある。
このような、間接ちかくをコピー除外する方式の場合、もし間接を曲げても線が描写されない事になるので、そういう事態を受け入れるしかない。
こうしないと、手のひらのアップで指の拡大画像を描写するときとかに、指には多数の間接があるので、ナゾの間接ラインが多数に発生しかねない。

なお、シルエットの2次元黒画像を転写するかわりに、黒色の3Dポリゴンを拡大コピーして、表画像から少しだけ奥の場所に黒ポリゴンを配置する方法もあるが、これだとポリゴン描画量が倍増してしまうので(単純計算で2倍のポリゴン数になる)、ゲームとしては(ゲームでは描画の軽量化・高速化が必要なので)、ややデメリットがある。
どうしても黒ポリゴン追加の方式をゲームで活用する場合、ローポリ(ポリゴン数を低くする)にする必要があるだろう。
なお、後述するポリゴンの法線には、表向きと符号を裏返した裏向きの2種類があるので、背景黒側の法線を裏返して、そして法線がカメラから見て裏向き(法線とカメラの向きが同じ向きのとき)の場合の被写体を黒く塗ることで、この方式の輪郭に流用できる。俗に「裏ポリゴン」なんとか方式とか言われる。
シルエット法も裏ポリゴン法も発想は同じで、違いは単に、黒い背景画像の追加をどの段階で行うかの違いだけである。

原理的には、下記の方法でも輪郭を検出できるが、画素ごとの計算が必要なのハズなで、メモリ負担が大きい。
ゲームとして使う場合、携帯モバイル機器では、画素ごとに計算する方法は利用が難しいだろう。
また、(非ゲームの)テレビ番組や映画などのアニメ作品などでは、メモリ負担は製作側が負担するので、画素ごとに計算する方法も有効だろう。
比較のため、掲載しておく。

輪郭線の発生場所とは、幾何学的には、奥行き方向(z方向)に段差のある場所で輪郭線が発生しているわけである。なので、元画像の各画素ごとに、その画素の対応するz座標を記録しておいて、そして隣の画素とのz数値との差によって、輪郭の点を描画するかどうかを決める方法である。
この方法は、カメラから見た深度をもとに計算しているので、「深度」なんとか法などとも言われる。「なんとか」とか言ってるのは、新しい分野なので名前があまり統一しておらず、業界や会社によって微妙に用語が違い、「深度法」とか「深度バッファ法」とか用語にバラツキがあるので、とりあえず当ページでは「深度なんとか」と言ってる。
欠点として、たとえば等角図のような図の、外側輪郭いがいの部分を検出しづらい。
また、ほかの欠点として、画素ごとに計算するので、計算の手間や、メモリなどへの計算量の負担が増える。
さらに他の方法もある。
それは、各ポリゴン面ごとに、その面の垂直線(面の垂線の場合、正確には「法線」(ほうせん)という)をあらかじめ全部の面ごとに計算しておいて、そして垂直線がカメラ向きに対して90度近くの場合にだけ、「そこに輪郭がある」として黒い点を描画していく方法である。
なお、法線ベクトルとカメラ向きベクトルとの内積を計算してもいい、・・・というか、普通は法線の情報はベクトルによって与えられるので、向きの計算も内積で計算することになる。
直角に交わるベクトルどうし2個の内積は0なので、つまりベクトル内積の絶対値が(0ちかくの)一定値未満になれば、輪郭があると検出することになる。
ともかく、このような法線による輪郭検出の方式のことを、「法線」なんとか法と言う。
長所としては、法線を計算しておけば、ほかの計算にも流用できる。
また、市販の3D-CGモデリングソフトによっては、すでに法線の自動計算の機能がついているものもある。
欠点としては、フラクタル図形のような被写体があるとき、見る角度によっては、その図形すべてを描画したりしかねず、真っ黒に写りかねない。
もっとも、通常の市販の3D-CGモデリングソフトでは、フラクタルの描画ができないので、めったにその事態に遭遇することは無いだろう。
なお、等角図の描写について、もし単に、カメラ向きと法線とを比較した場合には、「法線」なんとか法では描けない。
「法線」なんとか法を改良した方式のエッジ検出方式では、等角図も描ける。
「エッジ検出方式」とは、各画素とその周囲の画素との法線を比較する方式である。「エッジ抽出方式」ともいう。

法線の計算はベクトル計算なので、エッジ法の場合は、ベクトル内積が一定未満の場合にだけ輪郭があると認定して検出方式である。(同じ向きの単位ベクトルの内積は、1である。向きの差が大きくなるほど、内積は1から下がっていく。直交するベクトルは内積0である。さらに、反対どうしの内積はマイマス1である。)
エッジ法の弱点としては、フラクタル的な図形が「法線」なんとか方式と同様に苦手だろうが、しかしそもそも手書き風3Dアニメでフラクタル図形を描画することは普通は無いので(SFとかの例外は考えないでおく)、あまり気にしなくていいだろう。

法線なんとか法やエッジ法などの法線ベクトルを使う手法の場合、弱点として、カドっこを丸めるフィレット処理などの処理をされると、とたんに輪郭の検出が描画が難しくなる。
「フィレット」とは、工業製品などで、エッジのある場所に丸みをつける加工をすることである。
なぜフィレットのような処理に弱いかというと、円柱側面状の丸みのある場合、その場所の傾きは連続的に変化していくので、微分していくと法線どうしの向きは一致していき、よって法線の向きの差分を検出しづらい。
かといって対策として、(1画素単位といった)微分ではなく、数画素単位~十数画素のような大きな単位での差分にすると、今度は、輪郭線を書きたくない場所に誤検出をする可能性がある。
ゲームやアニメなどの娯楽コンテンツでは、もとからエッジを強調したままのデザインにしとけばいいので、フィレットをしなくても問題にはならない。
だが、工業製品などの3D-CGでは、重要な問題である。工業製品では、(切り傷などのケガを防ぐための)安全のため、エッジをとがらせずに、(金属ヤスリなどでエッジを削るなどして、エッジを)丸めたりすることもある。
3D-CG屋さんは、ときどき、製造業メーカーなどから宣伝用CG動画などの製作を頼まれる場合もある。
フィレットがあってもどうしても輪郭を検出したい場合、後述の方法がある。
市販の3Dモデリングソフトでは、各部分の「材質」(『マテリアル』ともいう)をパーツごとに登録できる。なので、エッジ法や深度法などでの、各部の画素どうしの法線の比較のついでに、材質の比較をすることで、材質の変化をした部分に輪郭線を引くこともできる。このため、たとえば材質「服」と材質「肌」との境目の画素のぶぶんに輪郭線を引くこともできる。
ただし、材質どうしの比較だと、たとえば手を胸(説明の簡単化のため、男の平らな胸にする)に当てている場合や、手を腹に当てている場合などは、手も胸も腹も材質は同じ「肌」なので、この方法では検出できない。
どうしても、このような場合でも、手と胸との境界線を「材質」比較の方法で描画したい場合、対策として、たとえば材質「肌-手」や材質「肌-胸」など、身体各部ごとに材質をつくっておけばいい。
なお、普通のアニメ絵では、胸と腹のあいだの境界線は書かないし、胸と肩のあいだの境界線も書かない。
なので、例外として、材質が違っていても境界線を書かない組み合わせをあらかじめ登録しておき、それ以外の組み合わせが隣りあった場合にだけ境界線を描けばいい。
もっとも、この方法を使わなくても、前述したような黒背景の方法や「法線」なんとか法などでも、手と男胸との輪郭線を描画できる可能性はある。

リアリティは乏しくなるが、輪郭線として検出したいエッジ部に場所に、最初から(周囲の色が黒くなければ)エッジに黒く色をぬっておく方法も、単純だが効果的である。
エッジがフィレットされて丸められても、そのエッジごと黒くぬれば、周囲の色と違うので、簡単に見分けがつくというワケである。
テクスチャ的な手法である。
アニメ調にデフォルメされた子供のCGキャラクターなどは、最初から鼻の下のカゲなどが、黒くぬっておかれる場合もよくある。
弱点として、リアル調のCGでは導入が困難である。
また、見る角度やデザインの画風によっては、テクスチャが目立ちかねない。近くで接写する構図だと難しい。
対策として、カメラと被写体の距離や角度によって、輪郭にしたい部分のモデルだけをこっそりと輪郭テクスチャなしのモデルに入れ替える手法だと(たとえばカメラが接写になるほど近くなった場合には輪郭部テクスチャをオフにして、テクスチャ無し3Dモデルに入れ替えるなどの方法)などが考えられる。ただし、少しプログラミング的にメンドウくさい。

レイ・トレーシングなどのあとで、明暗差を使う方法もある。明暗差の大きい場所を輪郭として認識する方式である。
ただし、レイトレーシング自体が、計算量が多いので、メモリ負担がキツイ。
また、明暗差が無ければ輪郭線として認識しないので、光源の位置によっては、輪郭線として表現したい場所に、かならずしも輪郭線を検出するとはかぎらない。

数学者たちのよると、視線方向の「法曲率」の「変曲点」を求めると、このようなライン抽出ができると言われています。
数学書『可視化の技術と現代幾何学』には、第2微分形式がうんたらかんたらとあります。読者に数学に詳しい人がいたら、微分幾何学での第2微分形式の勉強の際に、応用としてライン抽出を思い浮かべながら勉強するのも良いかもしれません。(数学には、微分幾何学(びぶん きがかく)という分野があり、ガウスやリーマンなどの古い時代から、よく研究されてきました。「第2微分形式」というのも、微分幾何学にある概念のひとつです。)
ただし、面の曲率計算をするということはつまり、どうあがいても、二次元曲面の微分計算が必要なわけであり、これはつまり、画面上にあるポリゴン全てに対し、そのポリゴンと隣り合った一定範囲の位置内にある別ポリゴンとの向きの微妙なズレを計算するというわけですから(「微分」とは、高校で習うように(1変数の場合なら)傾きの変化具合ですので)、計算量が増えてしまいます。
なので、ゲームとしては、やや処理速度の観点から、難点があるかもしれません。ゲームではなく、ハリウッド映画などに応用するなら、利用の価値は高いかもしれません。
ちなみに若山正人 編『可視化の技術と現代幾何学』の共著者のひとりの安生健一(書籍中の第5章『デジタル映像表現の幾何学』を著作)は、ハリウッド映画『アバター』のCG担当企業 Weta Digital 社との共同研究者です。劇場版ポケットモンスターの3D研究開発にも協力したとのことです。
若山氏は、ゲームには処理速度が必要だという亊も分かっており、前書きなどで語られています。。若山らのグループは、どうにかして、ソリトン方程式やkdV方程式などの「可積分系」と言わる非線形方程式を活用して離散化することで、ポリゴン数の削減に応用できないかと行った理論を提唱しています。参考文献の第2章の若山健司『離散可積分系の基礎』の理論で、どうにかポリゴン数を削減できないか、若山は提唱しています。
実際にその理論でポリゴン削減できるのかどうかは、当wikiの立場としては知りません。

このwikiのこのセクション書いた編集者のうろ覚えですが、 たしかテレビアニメ業界などで3D-CG担当を得意にしている「サンジゲン」(企業名)という会社も、一時期、東大あたりの数学者と共同研究していたと、 何かの数学雑誌(『数学セミナー』とか『大学への数学』など)で報じられてたか、でなければ科学雑誌(『日経サイエンス』など)で、2015〜2020年ごろに理系の雑誌で報じられていたような気がします。
ちなみに参考文献『可視化の技術と現代幾何学』の若山らは九州大学の研究グループである。九州大には、こういった数理解析とコンピュータを組み合わせて、理学部ならCG研究をしたりとか、九州大の別組織だが工学部なら流体解析をしたりとかの有名な研究グループが在籍しており、九州大はそういった応用解析の日本での中心地みたいな大学のひとつなのである。なお、数学者リーマンの名前が、微分幾何学でも流体力学でも、そういった応用解析の教科書を読んでるとよく出てくるものである。
余談のさらに余談ですが、サンジゲン社は、テレビインタビューで2012年頃、入社志望者について「よくコンピュータと向き合いたい内向的な人が志望してくるが、当社は、営業の外回りが多い会社です」みたいに自己紹介していたような気がします。当時、たしかBSフジで、そういうアニメ業界特集番組があったような気がします。
余談の余談のさらなる余談(=余談×3)ですが、国民的アニメなどを制作するアニメ会社は、実はとっくに株式をテレビ局が取得しているし、四季報とかで普通に確認もできると、BSフジのその番組で取材していたような気がします。テレビ局の垣根を越えて、テレビ朝日やテレビ東京の人が、親切かつ真面目に取材に応えていました。なのでテレビ朝日あの長寿アニメ番組とか、フジテレビのあの長寿アニメ番組とか、とっくにテレビ局がアニメ会社の株式取得しています。
テレビ局は視聴率競争があるものの、マジメで研究的な番組だと、意外と局の垣根を越えて取材に応じるということもあるのです。脱線しますが、ラジオ業界だと、1990年代の後半の時点で、文化放送のアニメラジオ番組とTBSラジオのアニメラジオ番組とが、局の垣根を越えてアニメを盛り上げようとするコラボ企画などをしていた気がします。文化放送の おたっきー佐々木 などの局員が、そういう企画に携わっていたような気がします。そのラジオ番組かどうかは覚えていませんが、当時、アニメのエヴァンゲリオンの総監督の人がたびたびラジオ番組で取材されていてインタビューに応えていたのですが、「ラジオはテレビよりも自由度が高くて、凄い」といった感じのことを監督が言ってました。
脱線した話をBSフジのハナシに戻すと、その他、ソニーなどのゲーム会社がアニメ会社の株式を取得している場合もあると、BSフジは報じてたような気がします。放映当時、アニメ『ソードアートオンライン』などの制作で有名なアニメ会社が、ソニー系列に株式的な資本関係があると、BSフジに取材されていました。
BSフジの番組の司会役のアニメキャラ(女子アナっぽいお姉さんキャラ)演じるその声優が、そのアニメ版『ソードアートオンライン』で美少女キャラのリズベット役の人だったので、BSフジのその番組でなんかネタにされていました。
まず、2005年ていどまでの手書きアニメでは、色のグラデーションが無いのが普通である。
かつて、1980~90年代のアニメ業界では、アゴ下と顔の境目の影を強調したり、ワキの下などの影を強調する手法が流行した。
しかし2010年代の現代では絵柄の流行が変わっており、作品にもよるが、ゲームでは、このような影はあまり使われてない。
もし、アニメ風に階調化したいなら、下記のようになるだろう。
階調化を自動的にしたい場合、 たとえば、あらかじめ前提として、レイ・トレーシングによって、影の位置を算出しておいて、各部の明暗が連続的に変化するので、その明暗に応じて各部の地の色のていどを変化させることで、連続的なグラデーションのあるモデルを作る。
次に、これを、色情報などをもとに何段階かの階調に分類すればいいだけである。具体的には、たとえば、各部の色を、何階調かに近似すればいいのである。
また、階調は、色ごとに設定する。 たとえば、ある物体の、光(ふつうの白色光)の当たる前の標準状態の色が水色だった場合、たとえば3階調として
のように、3階調に分割する。
色ごろに階調を設定しないと、アカっぽい色は、ぜんぶアカになったりとかして、役に立たなくなってしまう。
なお、現代コンピュータでは色データの濃淡は普通は255段階である。256×256×256 = 16777216 の約1600万色である。
ただし、実は2010年代のアニメ風ゲーム業界では、絵柄の流行が変わっており、もはや階調化した影の強調は、流行から外れている。(もしかしたら強調してないだけで階調化じたいはしている可能性も否定しきれないが、少なくとも影の階調が素人目には見つけられない作品が普通に多い。)
このため、そもそもの階調化の需要が、ゲーム産業では、乏しくなってきている。
どうしてもゲームでプレイヤーの操作できるシーンのCG動画に影や光沢を描きたい場合、テクスチャ的に被写体に影を貼り付ける場合もある。
たとえばアニメキャラの瞳の光沢など、テクスチャ的に最初から描いておくことも多いだろう(一方、もしレイトレーシングだと処理負担になりかねないので)。
顔のあご下の首の影になる部分も、最初から暗めの肌色で塗っておく作品も多いだろう。
もちろん、テクスチャなので、たとえば人物が暗い場所に入って、懐中電灯を顔より下の位置に持っていても(いわゆる逆光の状態)、なぜか目の光沢が瞳の上にあるような不整合は起きるだろうが、やむをえない(もしくは、逆光の場合のテクスチャを別途、用意するか)。
あご下の影テクスチャも、逆立ちしても、あごの下が暗かったりとかの不整合もあるが、やむをえない。
なお、トゥーンシェーデイングを使わないリアルなもとのシェーディングのことは、ローカルシェーディングと言います。
トゥーンシェーディングの、色の階調化の原理は、単純であり、しきい値(しきいち)による方法です。
ただし、のちのちの工程のため、ポリゴンの垂直線(「法線」という)を一緒に保管します。
光沢などのハイライトも、しきい値でトゥーンシェーディング対応しています。
なお、手書きアニメでのシェーディングの話題ですが、数学書『可視化の技術と現代幾何学』(岩波書店、P.203)によると、数値計算的にリアルなハイライトの位置や大きさを表示しても、アニメっぽく見えないので、さらに位置をズラしたりとのことです。
たとえば、書籍中にあるシェーディング例ではリンゴの光沢が例にされてるのですが、リアルなハイライト位置では被写体の正面にある場合でも、 しかしアニメでは記号的に、やや右上または左上に光沢の位置をずらすこともあります(書籍では右上にズラしている)。
さらに、この数学書『可視化の技術と現代幾何学』の報告によると、手書きアニメ業界だけでなく実写風CG業界でも同様とのことです。
ただし、ゲーム産業で果たして実用的かどうか、この数学書からは分かりません。
数学的に、ハイライトをズラす実装する方法は、しきい値を、方向によって変えることです。たとえば、右側にハイライトをズラしたいなら、ポリゴンの垂直線(法線)が右側を向いているポリゴン面ほど、階調化のしきい値を低くすればいいのです。

もしも、レイ・トレーシングをそのまま実行すると、メモリに負担がけっこう掛かる。
なので、ゲームのジャンルによってはレイ・トレーシングをせずに、影や光沢による色の補正を行う必要にせまられる場合もありうるだろう。
アニメ絵風のゲームで、もしも登場人物が日陰に入ったときなどに、人物をやや暗く表現するには、わざわざレイトレーシングする必要はなく、半透明の黒~灰色のレイヤーでも人物画像の上にでも載せて合成画像にして描画すればいい。
(Windowsの場合なら、たとえば 『Windows API/画像の操作』 でGDI+ を用いたWin#2API的なプログラミング方法での半透明レイヤーの合成方法を説明してある。ただし、照会先ページの方法だけだと描画に時間が掛かり画面がチラついてしまうので、ゲームとしては裏画面の活用などの対策が必要である。)
この方法は、日陰に入る前後の瞬間については物理学的には影の位置は不正確だが、しかしそもそもアニメ絵風のゲームでは、影の正確な位置なんぞにプレイヤーは興味ない。
そもそも、プレイヤーがもしも実写そっくりの位置にできる影に興味あるなら、そういうプレイヤーは実写キャラクター風のゲームをプレイしているからである。