集光模様で描いてみよう

集光模様で描いてみよう

集光模様とは

光の当たった水の入ったグラスや、透き通った遠浅の海をイメージしてみてください。その存在感をさらに際立たせる要素として、「集光模様」というものがあります。
 集光模様とは、その名の通り、透明な物体がレンズのように光を集めて作る模様のことです。英語では「コースティクス」caustics といいます。ギリシャ語の καυστός(燃えた)が語源で、日光を集中させると物が燃えることに由来するそうです\(。\)

説明
説明

透明な物体の形状で集光模様が定まるなら、逆に模様から透明な物体の形状を逆算できるのではないか、と考えました。そこで調べてみたところ、非常に興味深い論文を見つけました。

今回のTechBlogでは、その論文を紹介します。

なおこの論文、目的自体は比較的分かりやすいのですが、その方法は非常に複雑です。そのため本記事では、特に興味深い部分に絞って、簡潔に解説していきます。

論文の解説

論文:High-contrast Computational Caustic Designとは
こちらはスイス連邦工科大学ローザンヌ校で発表された論文で、「集光模様から逆算して 透明板の形状を生成する手法」を提案しています。

実は、「集光模様から逆算して 透明板の形状を生成する手法」は、これまでもいくつか提案されてきました。今回提案される方法はその中でも、より高いコントラストを実現できる方法として位置付けられます。

手法の構成と解説

 透明板の形状の設計は、2段階に分かれます。

  1. 光の目標点の生成
  2. 透明板の表面形状の生成
  

  
  
1.光の目標点の生成
  

   

  
2.透明板の表面形状の生成
    

光の目標点の生成

「光の目標点の生成」で得られる情報は、次の3つです。

  1. 透明板上での光の場所
  2. 目標画像が投影された時の光の場所
  3. 両者の対応関係

このとき、光はできるだけ近距離で輸送することが望まれます。光の輸送距離が小さいほど、屈折による光路の変化を抑えることができ、結果として入射面の表面の傾斜が緩やかになり、全体を滑らかに設計しやすくなるためです。
 この「光の輸送距離はできるだけ小さくする」という目標のため、最適輸送に関するアルゴリズムを用います。

  

    光の輸送距離が小さい
    ↓
    屈折による光路の変化が小さい
    ↓
    透明板の表面の傾斜が緩やか
    ↓
    面全体の連続性を保ちやすい
  

最適輸送とボロノイ分割

最適輸送を解く手段として「ボロノイ分割を用いて目標画像を表現する」という操作を行います。なぜこの操作が最適輸送を解くことになるのかについては、Merigot(2011)による別の論文で証明されています。興味のある方はそちらを参照してください。本稿では、「ボロノイ分割を用いて目標画像を表現する」とは具体的にどのような操作なのかを解説します。

入射光位置・投影光位置・対応関係の算出

「ボロノイ分割を用いて目標画像を表現する」という操作で、今回の目的である「入射光位置・投影光位置・対応関係」をすべて求めることができます。

大まかな流れは以下の通りです。

  1. 透明板をボロノイ分割する
  2. その分割をそのまま投影面に当てはめる
  3. 各ボロノイセルの大きさを調整し、明るさが目標画像に一致するようにする

    それでは順を追って説明します。

①  透明板のボロノイ分割

  • 透明板をランダムにボロノイ分割します。ランダムな分割には、Lloyd Sampling という手法を用います(それゆえ六角形に近い形状になっています)。
  • このとき、各セルに含まれる光束(光の量)が均一になるように調整します。

② その分割をそのまま投影面に当てはめる

  • まずはこの分割をそのまま投影面に当てはめます。(この時点では、透明で平らな板を置いているのと同じ状態です。)
  • 同一のボロノイ分割を用いているため、セルの対応関係は同じセル同士で一対一に対応します。
    したがって、対応関係はこの時点で確定します。

例えば、5番のセルに入った光は投影面でも5番のセルに送られ、そこに変更はありません。
(但し後の操作でセルの大きさを調整するのでセル位置は変化します)

③ ボロノイセルの大きさを調整し、明るさを投影画像に合わせる

  • 各セルに含まれる光束は一定です。そのため、セルを大きくすると暗くなり、セルを小さくすると明るくなります。なぜならセルが持つ光束が一定なので、大きさを変えると光束の密度が変化するからです。この性質を利用して、セルの大きさを調整することで、明るさを制御します。
   

    
    
ボロノイが目標画像に近づくイメージで実際の処理の過程ではありません
  

  

    説明
    
目標画像
  
  • 目標画像に近づくよう、セルの明るさを調整します。厳密には、各セルの明るさと、投影画像における対応領域の明るさが一致するように調整します。前述のとおり明るさはセルの大きさで調整します。この時、セルの大きさは重み ω で調整します。投影面のボロノイは重み付きボロノイと定義しており、ωはその変数になります。重み付きボロノイについて詳細は後述します。ここではωがセルの大きさを調整できるんだ、というところまで理解していてください。

  • ここで問題が生じます。セルの大きさが変化すると、セルが投影画像上で覆う領域の広さや位置も変わります。その結果、セルの目標とする明るさ自体が変化してしまいます。すなわち、ある明るさに合わせて調整しても、その調整によって目標値が変わってしまうというジレンマが生じます。

  • この問題は、「反復」によって解決します。具体的には、「セルの大きさ(設計変数)の調整」と「目標値(後述の勾配)の更新」を繰り返します。この反復最適化には L-BFGS という手法を用います。L-BFGS は本記事の主題ではないため詳細は省略しますが、代表的な最適化手法の一つです。

    • 設計変数:各ボロノイセルの重み
    \(\boldsymbol{\omega} =[\omega_1,\omega_2, \omega_3, \ldots]\)
    • 目的関数:全領域での光の移動量の最小値
      \(\min_{\pi} \int \|x - \pi(x)\|^2 \, d\mu_S(x)\)
    • 双対目的関数:目的関数を変換したもの(なぜ変換するとこうなるのかは別の論文を参照してください)
      \(f(\boldsymbol{\omega}) = \sum_{i} \left[ \omega_i \mu_S(C_i^0) - \int_{C_i^{\omega}} \left( \|x - s_i\|^2 - \omega_i \right) d\mu_T(x) \right]\)
    • 勾配:双対目的関数を微分したもの。これが0になる(=光の移動量が最小の時)ω を求める
      \(\frac{\partial f}{\partial \omega_i} = \mu_S(C_i^0) - \mu_T(C_i^{\omega})\)
  • 反復最適化の結果、投影面におけるボロノイセルの大きさと位置が決定されます。

重み付きボロノイとは?

ボロノイの大きさ調整において、本件では数学的概念である「重み付きボロノイセル」を用います。

そもそも、ボロノイセルとは?

ボロノイセルとは「点との距離で領域を分割したもの」というものです。

例えば2点 S₁、S₂ に対して、その境界は以下の条件を満たす点 A の集合として表されます。
これは、Aは常に S₁、S₂の中間にいるということになります。

\(|A - S_1|=|A - S_2|\)

重み付きボロノイセルとは?

一方、重み付きボロノイセルでは、各中心点(S₁、S₂...)に「重み(ω)」を導入することでセルの大きさを調整します。このときの境界上の点 A は、次のように表されます。

\((A - S_1)^2 - w_1=(A - S_2)^2 - w_2\)

これは幾何的に表現すると以下の図の状態において、赤い線が等しいことを示します。

もう少し厳密に言うと、距離の二乗から重み ω を減ずることで、半径 √ω の球の接平面からの距離を等しくしています。その結果、境界は直線となります。
単純に距離(絶対値)から重みを引く数式では、境界が曲線となってしまい処理が複雑になるため、本論文では距離の二乗から重みを引くこの方式を採用しています。

この重み ω を調整することで、各セルの大きさを制御します。

表面形状の生成

いよいよ、表面形状の生成に入ります。本論文では、まず平坦で格子点を持つ初期形状を用意し、各格子点を移動させることで最終的な表面形状を得ます。

したがって、ここで目標とするものは全格子点の座標データです。

処理の大まかな流れは以下の通りです。

  1. 目標となる光路の算出
  2. 格子点座標の調整
  3. 収束するまで上記を繰り返す

目標の光路の算出

目標の光路とは?

「目標の光路」という表現から、「先ほどすでに算出したのではないか」と疑問に思うかもしれません。しかし、ここで求める光路は先ほどのものとは異なります。
簡潔に言えば、「より高解像度な光路」です。

先ほどのボロノイによる割り当ては、あくまでボロノイセル単位でした。一方、ここで求めるのは格子点単位です。 透明板上の各格子点から出た光が、投影面上のどの位置に到達するかという対応関係です。この格子は、ボロノイ分割よりも細かく設定します。

(そのため、まだ光路の設定が必要なのですが、これは形状生成のための格子点の調整であり、内容もあくまで光路補間なので表面形状の生成の項に持ってきました)

算出方法
格子点単位での光路は、ボロノイセル単位の光路の補間で求めます。

  • 透明板上での格子点とボロノイの関係の算出
     透明板上ある格子点をサイト(中心点)として追加し、新たなボロノイセルを生じさせます。
    そしてそのセルが既存の「どのセルから」、「どのくらいの面積」を奪ったか算出します。(図中の赤い部分)

  • 投影面上の対応点の算出
    上記で得られた「どのセルから」「どの程度の面積を占有したか」という情報に基づき、ボロノイの中心点の加重平均を計算します。この点が、対応する投影面上の位置となります。

格子点座標の生成

いよいよ最終的な成果物に近づきます。ようやく目標となる光路が定まったため、ここから透明板の表面形状の生成が始まります。
表面形状は複数の目的関数に基づく最適化で生成します。

目的関数

最も重要なのは「光路」の一致です。これは本来の目的そのものです。集光模様を作る透明板を現実に製作することを考えると、他にも考慮すべき要素が存在します。論文では、以下の項目が挙げられています。

  • 光路のずれ量:法線方向を一致させる

    \(E_{int}=\sum_{v \in M_T}\frac{\|n - \tilde{n}\|^2}{2}\)
    • n:目標の法線(前段で算出した光路)
    • ñ:現状の法線(現状の表面形状から算出される光路)
  • 横ズレ量:元の光線からの横ずれを抑える

    \(E_{dir}=\sum_{v \in M_T}\frac{\left\|x - \operatorname{proj}_{(x_S, d_I)}(x)\right\|^2}{2}\)
    • x:最適化で動かした後の頂点位置
    • xs: 透明板上の元の頂点位置(固定)
    • dI:入射光の方向(固定)
    • proj(xs,dI):点xs を通り方向 dIの直線上で、xに最も近い点
  • 光束ズレ量:光の量を保つ

    \(E_{flux}=\sum_{t \in M_T}\left\|\Phi_T(t) - \Phi_S(t_S)\right\|^2\)
    • φT(t):元のメッシュの三角形tに入る光束

    • φS(ts):変形後のメッシュの三角形tに入る光束

  • 頂点と周囲とのズレ量:メッシュ品質を保つ

    \( E_{reg} = \|L X\|_2^2\)
    • LX:Lがラプラシアン行列、Xが移動後の頂点の座標群。
        隣り合う頂点たちの重心とのズレ量になります。
  • 投影面との距離制約:物理的な安全距離を保つ

    \(E_{bar}=\sum_{v \in M_T}\left\|f_{bar}\!\left(n_R \cdot (x - x_R)\right)\right\|^2\)
    • nR:受光面の法線ベクトル(固定)
    • xR:受光面上の対応点(固定)
    • x:最適化で動く頂点位置
      スクリーンの距離に近づくほど指数関数的に増加する関数

      \(f_{bar}(x)=\max(0,-\log((1-x)+d_{TH}))\)

これらの項を重み付きで合成した目的関数が最小となるように、頂点座標 [x, y, z] を調整します。

\(w \cdot [E_{int},\ E_{dir},\ E_{flux},\ E_{reg},\ E_{bar}]\)

頂点座標の最適化

  • 最適化手法 Levenberg–Marquardt 法
     この最適化には Levenberg–Marquardt 法を用います。各ステップで勾配(および近似的な2次情報)を用いて更新量を決定する手法です。
    前半のボロノイ最適化とは異なり、ここの操作では目的関数が複数登場するため Levenberg–Marquardt 法を採用しています。

 弊社TechBlogにて複数の最適化手法を紹介した記事もありますので、興味ある方はご参照ください:「リンク機構を「解く」:連続最適化による機構設計入門」

 なお、この問題は凸性が保証されていないため、理論的には局所最適解に陥る可能性があります。
ただし、本適用事例では初期形状が平面であるため、極端に不適切な局所解に収束する可能性は低いと考えられます。

  • 反復処理
     頂点座標が更新されるたびに、光路( 透明板上の頂点と投影面上の目標点を結ぶ経路)も変化します。そのため、各反復において光路を再計算し、その結果に基づいて再び頂点座標を更新します。

 このような反復処理を経て、最終的に任意の集光模様を生成する透明板の形状が得られます。

生成物の確認

ここからは、実際の生成物の検証を行います。論文では実際の造形まで含めて検証が行われています。幸い、この透明板生成プログラムが公開されているため、実際にモデルを作成して確認してみました。

今回の 透明板は非常に繊細な造形精度が要求され実機作成が難しいため、シミュレーションによって設計の妥当性を確認しました。

サンプル画像

サンプル画像には、人間が認識しやすいよう顔画像を用いました。なお、肖像権等に配慮し、画像はAIによって生成しています。

シミュレーションでの検証

シミュレーションには Blender を用い、レンダラーとして Cycles より高品質とされる LuxCoreRender を使用しました。


想像以上に鮮明に顔が再現されました。表面形状を見ても顔らしい特徴はほとんど確認できないにもかかわらず、このような像が得られる点は非常に興味深いです。一方で、圧縮されたメッシュデータを確認すると、メッシュ密度の分布がわずかに顔の形状を反映していることが分かります。

  

  
  
メッシュデータを上からみた図
本来出力されるメッシュは格子状です。これは動作を軽くするため圧縮・再構成されたメッシュになります
  

   

  説明2
斜め方向から見た図
目や鼻等の細かい凹凸はほとんどわからない
    

まとめ

本論文では、複雑な数学的手法が多数用いられていることが分かりました。当然それらの手法は集光模様のために作られたものではありません。にも関わらず、それらの手法が最終的に実際の物理現象の制御へと結びつき、一つの設計解に収斂していく流れは、集光模様の様に美しいものでした。
 その時はなんの役に立つか分からずとも、どこかでなにかにつながる日を思いながら技術を吸収していきたいと思いました。

参考文献

  • [1]"High-contrast Computational Caustic Design"; Yuliy Schwartzburg, Romain Testuz, Andrea Tagliasacchi, Mark Pauly(2014)
  • [2]リンク機構を「解く」:連続最適化による機構設計入門(Nature Architects Tech Blog); 高橋卓人(2025)

Author