9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Shadertoy はじめました week #3

Posted at

gemclock.png
https://www.shadertoy.com/view/MsXcWr

Week #3

前回、割とまともな屈折ができたので、やっぱりダイヤモンドをやってみたいということで、Brilliant-cut の距離関数の導出に挑戦しました。

brilliant-cut.glsl
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)))))));
}

もてる数学知識を総動員して挑んだものの、最後は力業でねじ伏せました(starAngleugrdAnglelgrdAngleの謎係数が手動調整値)。手動調整では、傾斜が0.1度違うだけでも、きれいな三角形にならないというシビアな職人世界を経験でき、宝石職人スゲーって思いました(小並感)。

一応どうにか Brilliant-cut の距離関数を導出できたので、見せ方を考えた結果、繰り返しによって等間隔に無限にばらまくと、すごくチープに見えることが分かったため、計算負荷はほとんど変わりませんが、表示12個に限定することにしました。
また、着色や巨大化もおもちゃ感がでてこれまたチープに見えてしまうので、あまりやりたくなかったのですが、無着色、小粒ダイヤモンドの絵ずらがあまりにも地味だったので、今の形に落ち着きました。
宝石の表現って正確なレンダリング以上に、配置による心理的効果が重要だなと感じました。面白い。

Tips #3

成果物3つ目です。
GEM Clock
先日、Tipsもようやく一つ目を書いてみたのですが、思った以上に難しく非常に時間がかかりました。これ全部かけるのかな...

  • オリジナル形状(Brilliant-cut)の距離関数の導出
  • レンダリングパスの設計による計算負荷の調整
  • 時計の表現
  • 円周配置
  • バウンドモーション関数
9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?