Crystal Renderer 技術解説①

Models by :

left : 3D Jewels(3djewels.pro/jewelry-3d-mod)/Adapted, CC0

right : Evan(sketchfab.com/3d-models/the-)/Adapted, CC4.0

宝石(ダイヤモンド)部分が CrystalRenderer により描画されています。

 

 

概要 この記事について

Crytal Renderer(次項にて説明)で使用されている技術についての解説です。

一見するとなかなか複雑なエフェクトですが、実際には基礎的な知識(高校生程度+多少の UnrealEngine)を使って作られています。

汎用性のある基礎を応用する例として、これを実現するロジックについてご紹介するシリーズです。

※)ようはタネ明かしです。ある程度エンジン自体の心得や基礎がある人であれば似たものを作れるようになるくらいのつもりで書きます。「作ってみた」報告が届くと嬉しいです。

※)UE5 向けのプラグインについての事例となりますが、理屈についてはゲームエンジン等の環境によらず通じます(すでに公開をやめていますが、過去にはほぼ同様の機能をUnity向けに販売していました)ので、エンジニア・テクニカルアーティスト一般に有益な内容になると思っています。

 

全3回+αに分けての解説を予定しています(これはボリューム等を見て変更する可能性があります)。

第1回:Crystal Renderer の原理(本記事)

第2回:光の反射と屈折

第3回:形状をマテリアルに取り込む

補講:色収差について

 

Crystal Renderer について

Crystal Renderer は UE5 用のプラグインです。

結晶内での光の反射および出入り時の屈折をシミュレートし、リアリティの高いレンダリングを実現します。

主に透明な宝石のような物体に適しています。

おまけとして、メッシュを生成するための補助機能を備えています。

www.unrealengine.com

以下、本題です。

Crystal Renderer の原理

上で少し触れたように、Crystal Renderer は光の経路を計算することをが機能の核です。

光の経路を計算というと「レイトレーシング」という言葉が思い浮かぶかもしれません。Crystal Renderer は物凄く大雑把に言えば「状況を大幅に限定することで通常のピクセルシェーダーに落とし込んだレイトレーシングっぽい何か」・・・と言うとまさかりが飛んでくるかもしれませんが、概ねそのような雰囲気のものです。

以下に模式図を示します。

この図の意味するところについて説明していきます。

光の性質について

まず、光について知っておくべき基本的な性質が二つほどあります。

光の経路は可逆である

光の基本的な性質の一つに、経路を逆に辿れるというものがあります。

つまり、視点から発射した光が最終的にどこに辿り着くかを調べることによって、その方向から届くはずの光について知ることができるというわけです。

これはレイトレーシングの基本的な考え方ですので、このワードで検索すると詳しい説明が見つかると思います。

反射と屈折

光が屈折率の異なる物質との境界に当たったとき、反射と屈折が起こります。

ここで反射と屈折の割合や方向については一定の法則があります。

詳しくは次回の記事で計算式やコードとともに触れる予定ですが、これが Crystal Renderer の核です。

光の経路の計算手順

上の二点を踏まえると、結晶の外界を環境マップとして用意する必要はあるものの以下のような方法で結晶の表面に映る色を計算することができそうです。

 

①視点から放たれたレイ(仮想的な、計算上の「光線」)が結晶表面に当たる。

 ここで反射(外界に離脱)したレイと屈折(結晶内部に進入)したレイとに分かれる。

②反射したレイについて、その方向を用いて環境マップから色をサンプリング

③進入したレイが結晶表面に当たる。

 ここで反射(結晶内部に留まる)レイと屈折(外界に離脱)レイとに分かれる。

④屈折したレイについて、その方向を用いて環境マップから色をサンプリング

⑤反射したレイについて、③に戻って再計算

 

理屈の上では無限に続く計算になりますが、計算資源は有限ですので繰り返しは適当なところで切り上げます(反射を起こらなくします)。Crystal Renderer においては切り上げる回数をパラメータ化し、負荷を調整できるようにしてあります。

 

⑥最終的に②と④で得られる色を重みづけして足しこみ、色を決定する

 

こういうことですので、環境マップからサンプリングする位置及び重みを計算するためにレイを使っているという見方もできますね。

 

まとめ

ここまでの説明で「あーなるほどね」と感じた方は、実装を試してみるのも良いでしょう(時間はかかると思いますが)。

それで詰まるようなことがあれば、次以降の記事が助けになるかもしれません。

次回の公開までしばらく時間がかかると思いますが、気長にお待ちいただければと思います。