ダイヤモンドをキラキラと美しく見せるカットとして有名な、ラウンドブリリアントカットを削り出してみたいと思います。
とはいえ、専門ではないので、まずは「ラウンドブリリアントカット」で調べてみました。
わかったのは、ざっと、以下のような感じ。
ここからは、実際の絵を見ながら説明した方が楽なのですが、少々作図が難しいので、順番が逆になりますが完成したレイトレーシング画像を使って説明します。ワイヤフレームモデルではないので、面の濃淡で稜線を視認する必要があり、ちょっと見にくいですがご容赦を。
横から見た図。
ついでなので、これから作ろうとしているモデルの座標軸やパラメータも図示してあります。図の奥側へ向かってy軸が伸びています。x軸とz軸の交わったところをストーンの中心として、原点を置きます。z軸正の方向がcrown、負の方向がpavilion、そのつなぎ目に当たる部分をgirdleと呼びます。名前の付いた面毎に色分けしてあるのですが、各面の呼び名については別な図で説明します。パラメータに関しては、最初のまとめで記したようにサイトによってばらつきがあるので、適当に「それらしい値」を選択してデータを作成しました。
自然界でたまたま見つかった原石から、少しでも大きなストーンを切り出したいでしょうから、多少サイズにばらつきがあるのかな?と、理解しています。
以下、上から見た図です。
table(1、カッコ内は面数)、star facet(8)、bezel facet(8)、upper girdle facet(16)と呼ばれる面があります。
次は下から見た図。
pavilion facet(8)、lower girdle facet(16)、culet(1)と呼ばれる面があります。culetは一番下のとがった部分で、少しだけ面取りしてあるようです。レイトレ画像では小さすぎて見えていませんが……、データ上はgirdle直径の0.1%程度の深さで面取りしてあるつもりです。
まず、ベースとなるのは、crown(上側)の八面体と、pavilion(下側)の八面体です。規則的な図形なので、8回ループを回して作ります。ちなみに、ここで削り出した面が、bezel facetとpavilion facetになります。
var R=50; // girdle半径
var a_crown=34.5; // crown角度
var a_pavil=40.8; // pavilion角度
idx=0;
while (idx<8)
{
screwz idx*360/8;
model
{
// bezel facet
para R,0,0;
screwy a_crown;
plane 0,0,0, 0,0,1;
}
model
{
// pavilion facet
para R,0,0;
screwy -a_pavil;
plane 0,0,0, 0,0,-1;
}
idx=idx + 1;
}
キーとした定数は、crown角度a_crown、pavilion角度a_pavil、girdle半径Rの3つです。これらの定数を使って、下図の様に平面を上下2枚づつ、z軸の周りに回転させながら定義しています。
示したソースリストには入っていませんが、このずっと上位で、全体を括るand { }ブロックがあって、全ての定義した平面のandを取って、最終的にラウンドブリリアントカットが完成しています。
やはりここでも、「少しでも大きなストーンを切り出したい」という思いが見えるのは、凹ませる(えぐる様な)カットが1つもないという事。図形としては、いわゆる凸多面体という分類となります。ですので、and { }ブロック1つの中に、58面全ての平面を定義したら、完成、となっています(全ての平面の共通部分、andがラウンドブリリアントカットになっています)。
tableとculetを削り取ると、だいぶそれらしい形になりました。ここまでculetを含めて18面。全部で58面なので、まだまだ、完成には程遠いんですけどね。
var r_crown=0.16; // crown高さ(直径を1とした比)
var r_pavil=0.43; // pavilion高さ(直径を1とした比)
// table
plane 0,0,2*R*r_crown, 0,0,1;
// culet
plane 0,0,-2*R*r_pavil, 0,0,-1;
キーとなった定数は、girdle直径に対するtableの高さr_crownと、pavilionの深さr_pavilです。実際には、これに加えて、girdleの厚さも2.5%程度持っているようですが、今回はこの分を0%としました。
pavilion角度a_pavil=40.8°で、girdle半径Rですので、pavilionの一番下で8つの面が集約している部分の頂点までの長さL_pavil=R*tan(40.8°)=0.863R=0.4316×(2R)。girdle直径2Rの43.16%に相当する深さ、となります。culetの面取りを2Rのr_pavil=0.43(43%)で実施しているので、直径2Rの0.16%程度が面取り(culet)で削られている計算です。この設定だと、ほぼ、点ですね。
bezel facetとtableを削った時点の模式図(上面図)を書いてみます。
外側の六角形がgirdle部分、内側の六角形がtable部分ですので、実際には高さが異なっています。
いくつか補助線が引いてあって、説明しやすい様に記号を振ってあります。「D(E)」など、括弧付きで2つの記号が振ってある点は、上から見ると同じ位置ですが、高さが違っていることを示しています。補助線ODBとOCAで切った断面図を示します。
star facetは、△GEE'となります。点GとEの座標を計算し(E'はEのy軸座標を符号反転)、三点を含む平面を定義します。
Gのx座標は、girdle半径RとOCの中点に置きます。
既知なパラメータは以下。
この数値を使って、Gの座標を計算します。
Eは∠AOBだけz軸の周りに回転しているので、以下の通り。
Xi-TRACEの平面定義は、平面上の1点(px,py,pz)と、法線ベクタ(nx,ny,nz)を指定するようになっています。
plane px,py,pz, nx,ny,nz;
今回は、計算した「三点を含む平面」を定義したいので、三点[a]、[b]、[c]を含む平面を定義する手続きを作っておきます。ここでは、[ ]をベクタを示すのに使います。[a]=(ax,ay,az)という三次元ベクタだと思ってください。
平面上の1点[p]は、そのまま[a]を使うことにします:[p]=[a]。
[a]から[b]へ向かうベクタ:[b]-[a]と、[a]から[c]へ向かうベクタ:[c]-[a]を考え、この2ベクタに垂直なベクタが法線ベクタ[n]となります。理屈はアレですが、([b]-[a])と([c]-[a])のベクタ積(外積)が、2ベクタに垂直なベクタになりますので、[n]=([b]-[a])*([c]-[a])と、なります。ここで、'*'はベクタ積です。[n]の方向は、掛け算の順番で決まり、[n]は、([b]-[a])が([c]-[a])に回転する方向が反時計回りに見える側を向きます。
以下、完成した手続きです。
procedure pla3p a.x,a.y,a.z, b.x,b.y,b.z, c.x,c.y,c.z
{
// 三点a,b,cを含む平面を定義する。
// 法線ベクタは、a→b→cが反時計回りに見える方向を向く
var ab.x,ab.y,ab.z;
var ac.x,ac.y,ac.z;
ab.x=b.x - a.x;
ab.y=b.y - a.y;
ab.z=b.z - a.z;
ac.x=c.x - a.x;
ac.y=c.y - a.y;
ac.z=c.z - a.z;
var n.x,n.y,n.z;
n.x=ab.y*ac.z - ab.z*ac.y;
n.y=ab.z*ac.x - ab.x*ac.z;
n.z=ab.x*ac.y - ab.y*ac.x;
var l;
l=sqrt (sq (n.x) + sq (n.y) + sq (n.z));
// l=0だと、平面にならない。
if (l=0)
{
return;
}
n.x=n.x/l;
n.y=n.y/l;
n.z=n.z/l;
plane a.x,a.y,a.z, n.x,n.y,n.z;
}
△GEE'(star facet)を削り取ると、以下となります。
さて、もう一度、上からみた模式図を示しておきます。
ここまでは、上から見て正八角形をしています。ここから、正八角形の頂点を削って、正1六角形にしていきます。上図には、正八角形に内接する円を補助線として引いてあります。OAと内接円の交点がHです。ごちゃごちゃするので、他の記号を消してしまったのですが、upper girdle facetは、△GHBと△GHB'です。点HとB(B'はBのy軸座標を符号反転)の座標を計算して、三点を含む平面を定義すればOKです。
upper girdle facetを削ると、こうなります。
// upper girdle facet
pla3p G.x,G.y,G.z, H.x,H.y,H.z, B.x,B.y,B.z;
pla3p G.x,G.y,G.z, B.x,-B.y,B.z, H.x,H.y,H.z;
pla3pに渡す座標の順番に気を付けてください。「三点を含む平面」で解説した通り、pla3pに渡す座標の順番が、反時計回りに見える側に法線ベクタが向いた平面が定義されるので、順番を間違うと逆側を向いてしまい、AND演算すると何も残らなくなってしまいます。上に示したように、△GHBに関してはpla3pにG→H→Bの順番で渡していますが、△GHB'に関してはG→B'→Hの順で渡さないと表裏反転してしまいます。
いよいよ最後の面です。OAで切った下側(pavilion)の断面図で説明します。
パラメータは、lower half length:r_lhalf(=0.75)です。この値はgirdle直径からの比で、左右のlower half lengthの和が直径のr_lhalfという事みたいです。つまり、上図の様に片側(右半分)で考える場合には、girdlr半径Rのr_lhalf倍と解釈しました。
lower girdle facetは、△HJBと△HJB'です。点HとBの座標は計算済みなので、残りのJ座標を計算します。
58面全てを削り終えました。では、削り出しの過程をまとめてみます。
一応、色分け画像作成用のデータを載せておきます。画像が小さくて見にくい場合は、ダウンロードしてレイトレーシングしてみてください。
Xi-TRACEデータ:brilliant_shape.xitr
ダイヤモンドの屈折率は約2.42程度ですね。色や屈折率、反射率などの属性を指定する命令、attr命令の中で、indexという項目が物体の屈折率を指定する項目なので、ここにセットします。
index 2.42;
反射率の設定reflについては、まず、反射率は1.00に設定します。これは、「全ての光を反射する」という意味ではありません。Xi-TRACEでは、フレネルの式(物理モデル)に従って、入射角と屈折率から反射率(R_spc_fles)を計算しています。レンダリングに用いる鏡面反射率は、R_spc_rend=R_spc_fles×<R_spc>で計算しています。ここで、reflの第1パラメータに設定した、1.00と言う数値が<R_spc>に相当します。よって、フレネルの式による反射率R_spc_flesをそのまま使う場合には、<R_spc>=1.00とします。蛇足ですが、R_spc_flesの値を使用せず、直接反射率を設定したい場合、<R_spc>に負の値を設定します。<R_spc><0の場合には、その絶対値をレンダリングに使用します:R_spc_rend=abs(<R_spc>)。
reflについては、ハイライトに関する設定を適当にして終わりです。比較的鈍いハイライトがつくように設定しました(第3パラメータ0.6)。ハイライトの起きる角度が広がるので、より輝いて見えるはず。本来は、凹凸を少なくきれいに研磨していれば、鋭いハイライト(第3パラメータが0.2等)になるべきなのかもしれません。
refl 1.00, 1, 0.6;
透過率の設定tranについては、reflと同様に、フレネルの式で算出した透過率をそのまま使うように、透過率(第1パラメータ)を1.00に設定しています。その他、拡散透過無し(第2パラメータ0.00)、透過中の光の減衰なし(第3パラメータ0)と、理想的な値に設定してあります。
tran 1.00, 0.00, 0;
フレネルの式をそのまま使うのは、今回のデータには特に重要です。何しろ、ダイヤモンドの上面から入射した光が、下の面(pavilion)で全反射することによって、100%の強度で跳ね返り、そのほとんどが上面から外へ出ていくことによって、キラキラと輝くわけです。固定反射率を使ってしまって全反射が起きなくなったら、意味がありません。
以下、attr命令のまとめです。
attr brilliant=
{
index 2.42;
tran 1.00, 0.00, 0;
refl 1.00, 1, 0.6;
};
完成した画像は、まあ、「こんなものかな?」という感じですね。キラキラしているようにも見えるし、そうでもない様にも……。後は、うまく光線源強度なり、ハイライト強度なりを調整して、もっとキラキラ感を醸し出すことは可能だと思います。
しかし、ここでは、手っ取り早く、Olive+のフィルタを使って、キラキラした画像にしてみます。前の節で示した画像をOlive+で読み込みます。メニューから、「フィルタメニュー ⇒ ハーロー」を選択します。
ウインドウが表示されるので、上のように設定してOKを押します。以下が結果。
例によって、レイトレーシングで動画を生成するので、ハーローフィルタも動画に対して掛けてみます。
完成したデータと動画です。
Xi-TRACEデータ:brilliant.xitr
まずはレイトレーシングしたままのラウンドブリリアントカットダイヤモンド。
次はOlive+のハーローフィルタで輝かせたラウンドブリリアントカットダイヤモンド。
動画は作り直していませんが、girdleに厚みを持たせたバージョンのデータを作りましたので、置いておきます。
Xi-TRACEデータ:brilliant_girdle.xitr
最初に作成した時には、girdle部分の厚みを0としていましたが、実際にカットされたダイヤモンドでは、girdle部分が有限の厚みを持っています。具体的には、手を入れる必要のある面数の少ない、pavilion(下)側をgirdle厚み(r_girdle)分だけ平行移動しました。対象となった面は以下の通りです。
加えて、1つ円柱面(cylind)を追加し、girdle部分を丸く削りました。追加部分に関しては、「brilliant.xitr」と「brilliant_girdle.xitr」を見比べてみてください。