https://www.shadertoy.com/view/MsXcWr
Week #3
前回、割とまともな屈折ができたので、やっぱりダイヤモンドをやってみたいということで、Brilliant-cut の距離関数の導出に挑戦しました。
float dfBC (in vec3 p, float r) {
float angleStep = P2/8.;
float crownAngle = radians(33.0);
float pavilionAngle = radians(41.0);
float tableArea = 0.58;
float starArea = 0.5;
float starAngle = crownAngle * 0.640;
float bezlAngle = crownAngle;
float ugrdAngle = crownAngle * 1.209;
float pavlAngle = pavilionAngle;
float lgrdAngle = pavilionAngle * 1.049;
vec3 vHlfStep = vec3(cos(angleStep/2.), 0, sin(angleStep/2.));
vec3 vQrtStep = vec3(cos(angleStep/4.), 0, sin(angleStep/4.));
float a = floor(atan(p.z,p.x)/angleStep+.5)*angleStep, c=cos(a), s=sin(a);
mat3 m = mat3(c,0,s, 0,1,0, -s,0,c) * r;
vec3 q = inverse(m) * p;
q.z = abs(q.z);
vec3 nmlBezel = vec3(sin(bezlAngle), cos(bezlAngle),0);
float fcBezel = dot(q, nmlBezel) - sin(bezlAngle);
vec3 nmlUGird = normalize(vec3(vQrtStep.x*sin(ugrdAngle), cos(ugrdAngle)*vQrtStep.x, vQrtStep.z*sin(ugrdAngle)));
vec3 nmlLGird = normalize(vec3(vQrtStep.x*sin(lgrdAngle), -cos(lgrdAngle)*vQrtStep.x, vQrtStep.z*sin(lgrdAngle)));
float fcUGird = dot(q, nmlUGird) - dot(nmlUGird, vQrtStep*vQrtStep.x);
float fcLGird = dot(q, nmlLGird) - dot(nmlLGird, vQrtStep*vQrtStep.x);
vec3 nmlStar = vec3(sin(starAngle)*vHlfStep.x,cos(starAngle),sin(starAngle)*vHlfStep.z);
float starDst = (1.-tableArea) * (1.-starArea) * (tan(ugrdAngle)/tan(starAngle)-1.) + 1.;
float fcStar = dot(q, nmlStar) - starDst * sin(starAngle);
vec3 nmlPMain = vec3(sin(pavlAngle), -cos(pavlAngle),0);
float fcPMain = dot(q, nmlPMain) - sin(pavlAngle);
float fcTable = q.y - (1.-tableArea) * tan(bezlAngle);
float fcCulet = - q.y - tan(pavlAngle) * .96;
float fcGirdl = length(q.xz) - .975;
return max(fcGirdl, max(fcCulet, max(fcTable, max(fcBezel, max(fcStar, max(fcUGird, max(fcPMain,fcLGird)))))));
}
もてる数学知識を総動員して挑んだものの、最後は力業でねじ伏せました(starAngle
、ugrdAngle
、lgrdAngle
の謎係数が手動調整値)。手動調整では、傾斜が0.1度違うだけでも、きれいな三角形にならないというシビアな職人世界を経験でき、宝石職人スゲーって思いました(小並感)。
一応どうにか Brilliant-cut の距離関数を導出できたので、見せ方を考えた結果、繰り返しによって等間隔に無限にばらまくと、すごくチープに見えることが分かったため、計算負荷はほとんど変わりませんが、表示12個に限定することにしました。
また、着色や巨大化もおもちゃ感がでてこれまたチープに見えてしまうので、あまりやりたくなかったのですが、無着色、小粒ダイヤモンドの絵ずらがあまりにも地味だったので、今の形に落ち着きました。
宝石の表現って正確なレンダリング以上に、配置による心理的効果が重要だなと感じました。面白い。
Tips #3
成果物3つ目です。
GEM Clock
先日、Tipsもようやく一つ目を書いてみたのですが、思った以上に難しく非常に時間がかかりました。これ全部かけるのかな...
- オリジナル形状(Brilliant-cut)の距離関数の導出
- レンダリングパスの設計による計算負荷の調整
- 時計の表現
- 円周配置
- バウンドモーション関数