ニッチなblender手記

世の中には自分に似た人が3人いるとされています。その人達へと情報共有するために主にblenderの記事を書いていきます。

loose create ellipse shader

概要

このツイートの内容が面白かったので、手順をメモ。
そのまま引用したら面白くないので、 +α で処理を付け足した。

シェーダのみで平面上へ(XY軸)楕円を生成する。
楕円としているが、実際は矩形にベベルをかけるようなシェーダなので、下図のように四角形や角丸を作成することもできる。

なおここからの図は基本的に矩形を表示する。矩形を表示するのはその方が範囲の確認がしやすいから。

f:id:r9aArrowhead:20210822002228j:plain

この処理の基本的な考え方を下に示す。
基本はX軸とY軸に線を引き、それらが重なり合う部分を取り出せば矩形になるという考え方で作成していくことになる。。

f:id:r9aArrowhead:20210822002202j:plain f:id:r9aArrowhead:20210822002209j:plain f:id:r9aArrowhead:20210822002220j:plain

このシェーダのキモは3点。

  • X軸上、Y軸上を走る線を描くようにする
    • 2つのラインを合成して、2つの直線が直交するクロス状のシェーダにする
    • 線の長さを変えられるようにすることで、矩形のように見せることができる
  • ラインを膨張させることで円状にしたりする仕組みを作る

手順

  • 下準備
  • 単一軸上(X軸)を走る線のシェーダを作成
  • 単一軸上(Y軸)を走る線のシェーダを作成
  • 2 つの線の合成
  • オプション処理
    • 矩形にグラデーション処理をつける
    • グループ化

下準備

Plane オブジェクトを新規作成して、新規マテリアルを設定しておく。

f:id:r9aArrowhead:20210822002250j:plain

そして、 Texture Coordinate でオブジェクトのテクスチャ座標を参照できるようにしておく。

f:id:r9aArrowhead:20210822002256j:plain

単一軸上(X軸)を走る線のシェーダを作成

Texture Coordinate -> Object で生成したテクスチャ座標を Converter -> Separate XYZ で各座標軸毎に分割しておく。

f:id:r9aArrowhead:20210822002303j:plain

ここからはX軸に対するテクスチャ座標の数値をベースに以下の作業を進めていく。

  • 入力値の補正
  • 入力値の補完
  • 値の抽出

入力値の補正

Converter -> Math: Divide で取得した X 軸のテクスチャ座標値を補正できるようにする。
Divide の値を変更することで、値の大小を制御できるようにすることで全体の色の強さを変更できるようになる。

f:id:r9aArrowhead:20210822002554j:plain

f:id:r9aArrowhead:20210822002603j:plain

入力値の補完

ここでは平面オブジェクトの反対側にも色がつくように処理を追加する。
Converter -> Math: Absolute を追加して接続すると、X軸のマイナス方向に伸びている側にも色がつくようになる。

f:id:r9aArrowhead:20210822002611j:plain

この処理の補足。
Math: Absolute を接続した瞬間に平面オブジェクトの反対側にも色がついたが、そのなぜそうなったのかは下図の通り。
元々マイナスの値を持っていた部分を絶対値として処理したため、両側に色がついたかのような処理になった。

f:id:r9aArrowhead:20210822002618j:plain f:id:r9aArrowhead:20210822002625j:plain

ここでの処理の最後に、黒色部分の領域を拡大・縮小できるような処理を追加する。
何故黒色部分の領域を拡大・縮小できるような処理にするかというと、 矩形を描画するのに利用するのは今黒色で表示する ためとなる。 Converter -> Math: Power を追加して接続すると、値を増減させることで黒色部分の領域を拡大・縮小できるようになる。

f:id:r9aArrowhead:20210822002633j:plain f:id:r9aArrowhead:20210822002640j:plain

この処理の補足。
Converter -> Math: Power は入力した数値を階乗処理する。階乗なので 1 より小さい数値を階乗すれば 0 に近づく。
結果、 1 (=真っ白)ではない部分が階乗処理によって 0 (=真っ黒) へ近づいた。

値の抽出

矩形を作成するために今まで黒い部分となっていた領域を取得したい ので、ここでは黒い領域を取得して白色へ変換する。
Converter -> Math: Less Than を追加して、第2 パラメータで 0以上の値を指定する。

0 を指定した場合は全ての値をがそれより大きくなるので全ての値が取得できなくなって 0 (黒色)となる。

Math: Less than を経由したことで、指定した値よりも小さい値は 1 、それ以外は 0 となる。
この処理によって白と黒が逆転し、目当ての黒色部分の領域が取得できるようになった。

f:id:r9aArrowhead:20210822002648j:plain

ちなみに Math: LessThan では値が 0 と 1 にハッキリと別れてしまうため、グラデーションを効かせるには別の処理が必要になる。
最初からグラデーション処理も視野に入れているのであれば、 Converter -> ColorRamp を使った方が良い。
ただしこのノードを利用した場合は、プロシージャルに幅を変更させることができなくなる。

この問題を解決してパラメトリックに取得する方法は後述。

f:id:r9aArrowhead:20210822002655j:plain

ここまですれば以下のような構成のシェーダが完成し、 X軸上に線を描く処理は完了する。

f:id:r9aArrowhead:20210822002701j:plain

単一軸上(Y軸)を走る線のシェーダを作成

やることは X 軸上での作業と変わらないため割愛する。
Texture Coordinate -> Separate XYZ で取り出したテクスチャ座標の内、 Y軸のソケットを使う点に注意する必要がある。 ここでの作業を済ませると、下図のような構成となって平面オブジェクト上に Y 軸に沿った線が走るような見た目となる。

f:id:r9aArrowhead:20210822002709j:plain

2 つの線の合成

単一軸上を走る線の描画でできるようになったため、この線を合成して矩形を描画するようにしていく。
2つの合成自体は Converter -> Math: Add につなげるだけで実現できる。
注意点としては、白黒反転に使った Math: Less Than の前で合成する必要があることと、その後で Math: Less Than をつなげて白黒反転するようにしておく必要がある。

f:id:r9aArrowhead:20210822002725j:plain f:id:r9aArrowhead:20210822002732j:plain

オプション:矩形にグラデーション処理をつける

矩形を作成するだけならばここまでの処理をノードで作成すれば実現できる。
せっかくなので、矩形にグラデーションのような処理を付け加える。

コツは、 Math: Less Than を用いないようにすること。
Math: Less Than を使えば特定の範囲を切り抜くようなことができるが、出力結果が 0 または 1 の白黒 2 値となる。 そのため、 以降では 0 でも 1 でもない数値 を処理できなくなってしまう。

中間の値を拾ってあげるために、 Math: Less Than による範囲の抽出ではなく Subtract を用いた値の反転処理を使って矩形の範囲を作成する。

f:id:r9aArrowhead:20210822002739j:plain f:id:r9aArrowhead:20210822002746j:plain f:id:r9aArrowhead:20210822002752j:plain

ここまでの処理を行うと矩形にグラデーションがついたかのような表現になっている。
下図に Math: Less Than による表現を示しておくので、見比べてみて欲しい。

f:id:r9aArrowhead:20210822002759j:plain

仕上げとして、 Converter -> Math: Power を接続する。
ここのパラメータを調整することで、作成した矩形の形を崩すことなく色の調整が可能になる。

f:id:r9aArrowhead:20210822002805j:plain

色の反転や調整をする手法は Converter -> ColorRamp がよく使われている。
実際、このノードを使えばここでやろうとしたことの処理を 1 つのノードで実現できてしまう。
ただし、毎回ノードの調整が必要になるのでケースバイケースで使い分けた方が良い。

f:id:r9aArrowhead:20210822002811j:plain

グループ化

f:id:r9aArrowhead:20210822002817j:plainf:id:r9aArrowhead:20210822002823j:plain