2021.9.29こんにちは!情熱開発部の辻野です!今回でブログ作成は2回目ですが、今回もタイトル通りレイマーチングの解説です。この記事は1回目のレイマーチング基礎の続きとなっています。Geometry)を実装していきます。CSGができるようになると複雑な形のオブジェクトを作れるようになるので、より一層おもしろく感じられると思います!※今回の記事ではShaderToyを用いたプログラミングとなります、他のプラットフォームによって一部表記が変わるためご注意ください。今までは単一のオブジェクトしか描画できていなかったので、複数描画してみましょう、後に説明するCSGにも必要になってくるので解説していきます。コードは前回の記事の最後から引き継いだものとなります。同じオブジェクトの描画まずは球体を画面に2つ表示してみましょう変更箇所はここだけです。d1);}sphere_dは球の距離関数であり、距離関数はレイの先端とオブジェクトの最短距離を表すので、d0とd1を比較し近いほうを返すことにより、複数のオブジェクトを描画することができます。0.0)を足すことによって、オブジェクトの位置をずらしています。これはオブジェクト自体を動かすというより、レイをずらすことによって相対的に移動を実現しています。主観ですがレイマーチングを含むレイトレースではよくオブジェクトの回転や移動をレイによって解決しています。描画位置をずらす処理と2つの距離関数をsphere_d内にまとめている理由は、法線ベクトルを求める関数getNormalでsphere_dを使用しているからです。使う画像みたいになりました。次は球と箱型を同時に描画してみたいと思います。箱型を描画するには球の距離関数とは別に箱型の距離関数を使う必要があります。関数はこちらのサイトのものを使用させていただきました。下記は使用する箱型の距離関数です。sphere_dをbox_dに変更するだけで箱型が描画されます。0.0);}この処理でなぜ箱型を描画できるか、ざっくりとですが解説したいと思います。初めに上記の関数は3次元ですがわかりやすくするため、原点を中心とした2次元の正方形と任意の点との距離を計算するものとして考えていきます。abs(pos)によって座標を絶対値に変換します、これは計算を第1象限だけに絞るためです。正方形のサイズになります。どちらの要素も範囲外だった場合は、頂点と点との距離になるのでlengthで計算できます。0.0))になります。上の計算式は点が箱型の中にいると0を返してしまいます。q.z))で点から一番近い平面を調べ、その平面と点の距離を内外判断をできるようにマイナスで返します。minが使用されているのは点が箱型の外にいる際に、計算を行わないようにするためです。箱型と球のオブジェクトを描画するために新しく関数distanceを追加したコードです。違う形のオブジェクトが同時に描画できました。レイマーチの実装は結構独特なので色々な発見があります。Geometry)簡単なオブジェクトを同時に描画する事はできましたが、もっと色々な形を描画したいと思いませんか?そこで使用するのがCSGです。)などを用いて描画する方法です。箱型と球で確認していきましょう。ちなみに和集合はオブジェクト両方をそのまま描画するだけなのですでにやっていますね。d1);}minからmaxに変更したため、オブジェクトとレイが衝突したと判定するにはd1とd0どちらかが0でもう片方が0以下でなければいけません、その結果どちらかのオブジェクトとレイが衝突しても続行され、重なっている部分のみが描画されたように見えます。d1);}共通集合からd0の符号を反転しました、これにより球の表面から外側ではd0が選ばれなくなり、球が描画されなくなります。球の内側にレイの先端がある際に箱型とレイが衝突した場合は、-d0が戻り値として使用されるので、箱型が球でえぐられたように描画されます。いかがでしょうか?コードを少しいじるだけで、とても簡単に形を変えることができました。たくさんのオブジェクトをCSGで描画すると下のような変わった形も作れます。おわりに以上解説になりました。前回よりも簡単だったかなと思います、レイマーチは色々な要素入れていく毎に大幅に変わっていくので、楽しみながら調べられます。株式会社ロジカルビートは一切の責任を負いません。understrap.com。