嘘つきCycles

>この記事は[Blender Advent Calender 2016](http://www.adventar.org/calendars/1571) 12/13 分のものです。

# はじめに

Cycles便利ですよね。Blenderに標準でついていながら高性能で、ノードベースのマテリアル構築の仕方も分かりやすいです。特にフォトリアルなシーンに力を発揮してくれます。

しかしながらそのレンダリング方式によりノイズが生じやすいという弱点もあります。サンプル数をめちゃくちゃ上げればノイズをほぼ消すことができますが、1フレームにかかる時間が長くなりアニメーションするにはつらい、つらすぎる。

またフォトリアル以外の用途にも使いたいところです。BlenderにはCycles実装以前から存在する別のレンダリングエンジン(BI)もあるものの、マテリアルの設定方式がCyclesとは大きく異なり脳の切り替えにエネルギーを奪われがちですし、BIよりもCyclesの方が楽にマテリアルが設定できる<font color="DarkGray">(※個人の感想です)</font>ので何とかCyclesに一本化したいところです。

ありがたいことにCyclesは厳格な物理レンダラーではなく、案外いろんな箇所で**嘘**をつくことできる仕組みが用意されています。そこでCycles上での様々なフェイクを駆使して、レンダリング負荷の軽減やフォトリアルからの脱却を図りたいと思います。




# ガラスのフェイク

## 集光表現のフェイク

Cyclesを素直にフォトリアルな用途に使用する場合においても、Cyclesが最も苦手とするのが**集光表現**でしょう。例えば「虫メガネを使って太陽光を一点に集中させる」といった表現をCyclesでそのまま行うと悲惨な結果になります。

![glass-trueglass1.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/9fc35c93-6442-ab11-294f-715a49ca17b1.jpeg)
<font color="DarkGray">レンズ形状が適当なので綺麗に一点に集光してくれていないのはご愛嬌</font>

集光を要する箇所でノイズが荒ぶっています。サンプル数を上げてもノイズが消えてくれる気配がありません。

![glass-trueglass2.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/41dabe2b-5f80-910d-21c6-0052bd6ad6e0.jpeg)
レンダリングプロパティの`Filter Glossy`や`Clamp Direct/Indirect`の値を調整することで若干低減させることができるものの、抜本的な改善にはなってくれないみたいです。

![glass-trueglass3.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/fb80a116-ec33-c7bb-210a-a57ec307f925.jpeg)
`Reflective Caustics`および`Refractive Caustics`をOFFにすると集光そのものを無効にするので、荒ぶるノイズは無くなりますが集光表現も無くなってしまいます。

---

そこでCyclesマテリアル側で嘘をつくことで擬似的な集光表現を行ってみます。`Reflective Caustics`および`Refractive Caustics`はOFFにしておきます。

Cyclesの`Light Path`ノードのうち`Is Shadow Ray`を活用すると、そのオブジェクトの影だけを弄るといったことが可能です。
![glass-fakeshadow.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/89a60c61-1db2-a072-862f-3e708eda8a40.jpeg)


これを利用しつつ、光線が飛び交う中で影の原因となった元の面の角度をうまい具合にパラメータとして影の色に影響させれば、あたかも集光が生じたような影が得られるようです。
![glass-fakecaustics.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/f7031fe8-14f7-abcd-1c5d-1b01c614b322.jpeg)


このノードの`ColorRamp` (およびその隣の`Multiply`ノード) を変化させることで疑似集光の出方を調節できます。
![glass-fakecaustics2.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/f3d135a2-1c0d-1058-81c8-fd42b43ce928.jpeg)

物理的には正しくないものの、これで集光表現を得る際のレンダリング負荷を減らすことができました。

---


ちなみにこの方法はそのマテリアルを持つオブジェクトの影の色だけを弄っているため、マテリアルそのものはガラスシェーダでなくともいいみたいです。

![glass-fakecaustics3.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/7fc7dae7-8cd5-24f3-dc58-30af22486baa.jpeg)


意味わかんないですね。

### 参考：

* fake caustics in cycles – Urchin  
  http://urchn.org/post/fake-caustics-in-cycles





## ガラスの暗所(Dark Artifacts)を低減する

レンダリング設定で`Bounces`の数値を少なくしているとき、ガラスのように光線が何度もその内部を反射したり通ったりしうるような場合だと、Bouncesの値以上の反射・入射を要する光線は打ち切られてしまい、特に次のような典型的な暗所が生じてしまいます。 (*Dark Artifacts* とか呼ばれているみたいです。)

![glass-darkartifacts.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/175d2792-e8da-6d07-1cf8-e6a8720c46b6.jpeg)

基本的にBouncesは低い値を設定するほどレンダリング速度は上がるものの物理的な正確さは犠牲になります。普通はちょっとシーンが暗くなったりする程度で済むことが多いですが、今回のようなケースはかなり目立つため何らかの対策が必要です。

### Ray Depthを使う

再び`Light Path`ノードを用意して、今度は`Ray Depth`の値を利用して*光線のバウンスが一定値以上になったら以降は透明と見なす*という設定にすれば、ガラスの*Dark Artifacts*を擬似的に解消させることができるみたいです。

![glass-darkartifacts2.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/e40ee917-b160-f792-ff4e-cb354d9daafa.jpeg)

Bouncesの値を上げること無く解消できました。
上のノード中の`Greater Than`の値はおおむねBouncesの設定の中の`Glossy`と`Transmission`のうち小さい方の値にしとくといいみたいです。

またこれは必要に応じて既に行った疑似集光表現とも組み合わせて使うことができますね。




### 参考：

* The Cycles Input Encyclopedia | Blender Guru
  http://www.blenderguru.com/articles/cycles-input-encyclopedia/








# ライトを使わずに特定箇所だけ光らせる

エネルギー保存則をぶち壊すと評判の`Add Shader`を使って、ライトを使用することなく部分的に光らせてみます。

![addshader-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/8e029d60-abc3-5fac-92bc-e6cba13d8504.jpeg)
スザンヌのシェーダは元々はディフューズのみです。

![addshader-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/b245d40b-81f8-0ec8-7d03-c189a5941f2f.jpeg)
例えばVertex Colorをこのように当てて

![addshader-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/7c486fcc-8125-0a83-e0fb-99435c7c9207.jpeg)

Add Shaderを繋げて元の光を何倍にも増幅したものを、先程のVertex Colorをマスクとして用いつつ元のシェーダとミックスすれば…

![addshader-4.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/b56d4e8e-1e72-8175-f79a-faf090268d98.jpeg)
<font color="DarkGray">ペカー</font>

フランシスコ・ザビエル・スザンヌが誕生しました。ライトを追加せずに一部分を照らすことができましたね。

先程は増幅した光のミックスに使うマスクとしてVertex Colorを使用しましたが、Vertex Colorを単にMix ShaderのFacに繋いでいるだけなのを見れば分かるように、何らかの値であれば他の何でも良いです。

![addshader-withwavetex.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/8464fe80-76f2-f9ae-b4e2-d3658b6eaa5a.jpeg)
例えばWave Textureだったり…

![addshader-withpointdensity.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/5a8b78c9-c630-3e27-2ff7-2f70a5938036.jpeg)

Point Densityを使えば、Point Lightを擬似的に表現することもできます。
これと似た感じを得る他の方法として、`Dynamic Paint`を通したVertex Colorを使うというのもあります。

ともあれ、これを利用すれば皆が大好きなリムライトをお手軽に、かつかなり嘘っぽいレベルまで強調できたりします。(アニメーションには不向きですが。)

![addshader-fakerimlight.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/e3d0e770-0a6a-009b-18e8-8ca0558a91aa.jpeg)

---

※ちなみに、あまりにも明るすぎる光線はノイズの原因になるので、Add Shaderで光を増幅する場合は`Light Path`ノードを組み合わせてカメラにのみ増幅した光を見せるというのも一つの方法です。

![addshader-uselightpath.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/8a41aa7a-1ed3-35f1-7e53-276bbe841113.jpeg)




# CyclesでBIっぽいレンダリングを行う

フォトリアルからの脱却の一環として、CyclesでないBlender内蔵レンダラー(BI)のようなシェーディングをあえてCyclesで行ってみます。

メッシュの法線と適当なベクトルとの内積の値をそのまま明るさとして採用すれば、BIの`Hemi Lamp`と同じ結果が得られます。

![bilike-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/b37a0a1a-9acb-c7f9-47b6-7c1df3342cae.jpeg)

先程の内積を取る部分をグループ化しておいて…

![bilike-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/a4751f52-2927-2cfb-32f9-973c3d4b908f.jpeg)

入力ベクトルを変えるとHemi光源の方向が変えられます。それらに色を付けつつ加算することで、複数光源で照らした状態を再現できます。

![bilike-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/3e9f1848-b6a9-c5e0-2584-401ebce53f70.jpeg)
<font color="DarkGray">2種類のHemi光源を組み合わせる</font>


![bilike-4.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/5864b5fb-b050-d8ce-400b-3428bbc8e757.jpeg)
<font color="DarkGray">Hemi光源を加工して簡易的なスペキュラーとしてみる</font>

![bilike-5.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/a6c2765e-68c1-bc37-6c1f-f9f467d0b043.jpeg)
<font color="DarkGray">テクスチャをカラーとして使う</font>

![bilike-6.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/224673f3-12aa-dd73-48ad-5c5c8f266fb4.jpeg)
<font color="DarkGray">テクスチャをディスプレイスとして使う</font>

良い感じにBIっぽくなってきました。実際のシェーダはEmissionのみで、ユーザーがいじるのは色だけというのもBIに通じるものが有りますね。
しかし問題点が1つあって、この方式ではライトによる影(Shadow)が利用できません。というかそもそもライトという概念が使われていません。仕方ないのでPoint Densityで代用します。

![bilike-7.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/863ab9f2-1ff0-f933-3801-93988f0b761f.jpeg)
<font color="DarkGray">Point Densityで参照するメッシュを忍ばせておいて…</font>

![bilike-8.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/6715a2b3-97b1-f038-32d7-10bbf504a99a.jpeg)
<font color="DarkGray">Multiplyに繋げる</font>

苦しい感じですが、何とか影の表現を擬似的に行えるようになりました。ソリッドな形の影を得るには工夫がいりそうです。


これでCyclesでも原始的な感じのシェーディングを得ることができるようになりました。制約付きのBIといった具合ですが、テクスチャ等はCyclesのノードシステムをそのまま使うことができるので、両方を行き来して混乱したくない場合には使えるかもしれません。またシェーダもEmissionのみの使用となるためノイズもありません。素晴らしいですね。


![bilike-9.jpg](https://qiita-image-store.s3.amazonaws.com/0/152179/928c889a-0212-6bae-0943-f1171f56ea9c.jpeg)
<font color="DarkGray">なんか一人だけレンダリングエンジン違くない？</font>




# おわりに

物理ベースとはいったい・・・うごごご


<font color="White">.</font>

<font color="White">.</font>

---
> [Blender Advent Calender 2016](http://www.adventar.org/calendars/1571) 明日の記事は sakura_rtd さんによる「ショートカット一覧表（入門者向け）」です。