レイトレ合宿10参加レポート

# はじめに

まずは運営の皆さん、今年もありがとうございました。参加者が増えて活気がありましたが、準備など本当に大変だったと思います。

今回は初島での開催でした。前回は現地参加も作品提出ともしなかったので、実質２年ぶりの参加です。気温は少し高めでしたが、爽やかな風が吹き、３日間とも素晴らしい天気に恵まれました。

<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/a925697f-b359-03aa-bc28-21391dfc0428.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/afe3e7e8-3564-0d1a-9c56-df48a25b04c4.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/49c00982-d82a-fea7-5b1e-4878ae7d21de.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/48212c21-20b6-1721-6c17-bd680a540d93.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/9a922137-f3c9-903c-65cf-a048a1fca3d5.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/763b385a-93cf-da26-6a08-2e2dd5dd1c90.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/1dde3568-f7a3-10a9-2cd6-7a0de9fe9ea9.jpeg">
<img width="400" alt="A" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/d24fc4d9-f262-2168-896e-aa58fb399ba5.jpeg">

セミナーと、自作のレンダラで作った作品の出来栄えを競う本選、レクリエーションなど内容は盛りだくさんでした。景色、温泉、プール、食事を堪能し、話の通じる人たちと連日楽しく過ごすことができました。今年はセミナーの内容がとても充実していたように思います。

[テーマ曲](https://raytracing.jp/nan/)も秀逸でした。


# 本選

## 実行環境およびルール

今回は256秒で静止画およびアニメーションを生成して、技術と作品の出来栄えを競います。私は今回もCPUインスタンスを選択しました。上位の大半の参加者はGPUのインスタンスを用いていました。

CPUは192コアを利用できるものの、GPUと異なりレイトレーシングの専用ハードウェアがないというハンディを強いられます。

* CPUはSapphire Rapids(第4世代なので2世代前)、Intel 7(10nm ESF)
* GPUは[A10G](https://www.techpowerup.com/gpu-specs/a10g.c3798)、Samsung 8nm

このSapphire Rapidsのインスタンスは意外と遅く(チップあたり最大56コアなので、192vCPUだと48コアx4といった構成になるためか)、例えば、M1プロセッサで800msくらいで終わるBVHの構築が3秒以上かかります。いよいよCPUでの参加は厳しいように感じられましたが、アイデアや工夫でなんとでもなるとも思うので、これからもCPUでの参加を続ける予定です。

## 提出したレンダラについて

16、17歳でレイトレーシングを始めて以来かれこれ30年近く同じコードベースをメンテしていて、様々なものを実装してきました。今年はこれまでに書いたコードの整理とARMのサポートを中心に作業を行っていましたが、細かいいくつかの新機能も実装しました。

* Distance Shader
* Shadow Catcher
* Object Tracking Camera
* Geometry Processing Nodes
    * Fur Generator
    * Mesh Segmentation
    * Frame Interpolation
    * Knit Weaving
    etc.

実装したGeometry Processing Nodesの一つを使えば、今回使用したRhinoを編み物のようなオブジェクトへと簡単に変えることができます。
![rhino_weave.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/e96541ee-6c49-9156-1b48-bc2bd2ed0ef4.png)

さて、今年からレンダラの作成で使用した外部のコードの明記が義務付けられましたが、私が使用したのは
* stb_image.h
* cyCodeBase

の2つです。

実行環境ではpower shellのスクリプトを実行するとのことだったので、いろいろ実験したく、実行担当の方に最新版のpower shellをインストールしてもらいました。

```
arguments =`
"asset/scene.rq min 50 max 114 offset 0 step 4 subframe 0 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 0 step 4 subframe 1 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 0 step 4 subframe 2 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 1 step 4 subframe 0 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 1 step 4 subframe 1 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 1 step 4 subframe 2 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 2 step 4 subframe 0 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 2 step 4 subframe 1 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 2 step 4 subframe 2 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 3 step 4 subframe 0 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 3 step 4 subframe 1 subframes 3 cpu 16 mute",`
"asset/scene.rq min 50 max 114 offset 3 step 4 subframe 2 subframes 3 cpu 16 mute"

$job = $arguments | ForEach-Object -Parallel{
    $process = Start-Process "./redqueen" -argumentlist $_ -PassThru -NoNewWindow
    try
    {
        $process | Wait-Process -Timeout 256 -ErrorAction Stop
        Write-Warning -Message 'Process successfully completed within timeout.'
    }
    catch
    {
        Write-Warning -Message 'Process exceeded timeout, will be killed now.'
        $process | Stop-Process -Force
    }
} -ThrottleLimit 12 -AsJob

$job | Wait-Job | Receive-Job
```

深く考えずネットで見かけた記事をもとに適当に用意したので、書き方が正しいか怪しいですが、最終的に上記のスクリプトを利用して12プロセスを立ち上げて全コアを使い、256秒たてば全てのプロセスが停止するようにしました。NUMAの問題を解消する手っ取り早い解決法であるとともに、恐らく同じプロセス内のスレッドがソケットを跨ぐといったこともないと思われるので、キャッシュなどを考慮すると意外と良い方法かもしれません。

## 提出した作品について

作品用にコードを書いたりアセットを準備したりするのは締め切り2週間前くらいから、平日の仕事の後に少しずつ行いました。長く開発してきたため様々な機能を備えていますが、できる限り今年作成した機能で作品をつくることにします。

今回使用したアセットはNavdeep SinghさんによるRhino Anim for FX Guysで、作品はPoly Havenの16kの画像一枚のみを使ってライティングを行うといういたって単純なものです。

アセットは比較的ポリゴン数が少ないのでそのままレンダリングしたのでは面白くありません。皮膚の細かい凹凸を再現しようかとも思いましたが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/d9ed7e74-7f21-9cb9-186d-99472e361792.png)
[画像引用元](https://etc.usf.edu/clippix/picture/rhinoceros-skin.html)

調べていると昔のサイには毛が生えていたらしいことがわかり、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/87fa57af-8f6b-e4e6-67aa-881e273220ac.png)
[画像引用元](https://www.earthtouchnews.com/natural-world/evolution/heres-a-line-up-of-prehistoric-beasts-from-the-rhino-family-tree/)

以下のような感じで毛をはやすことにしました。プレゼンの時言い忘れたのですが、皆が角と呼んでいるものはどちらかというと髭なのだそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/fcd49f2a-fa8b-1270-3049-7d15692efad9.png)

各フレームでレンダリングを行うデータは、Geometry Processing Nodesで生成します。まず入手したアセットの動きがカクカクなので、連続する2コマを補間するノードを使用してサブフレームを生み出します。つづいてノードから出力されたメッシュをターゲットトラッキングを行うためカメラに接続します。さらに同じメッシュをセグメンテーションを行うノードにも接続し、歯や眼球、ボディなどに分解します。その結果を、毛の長さを指示するための濃淡画像とともに毛をはやすノードに接続して、ボディのみに毛を生やします。各フレームで毛の位置が変わってはいけないので、レストポーズでの面積を用いて生成した1Dテーブルを用いて毛を生やす位置のサンプリングを行います。これら一連の処理は全フレームで行います。可能な限り処理は並列化して行いますが毎フレーム300msを消費します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/1303df5a-c1f2-cbb6-0995-0d1296228650.png)

上記のノードグラフを用いて、256秒で192枚の画像を生成し、24fpsで8秒のアニメーションを生成しました。解像度は1024x1024ピクセルと中途半端で、16サンプル/ピクセルとかなりノイズの多いものになってしまいました。それでもデノイザーを使っては面白くないので、使用していません。最終的に生成された動画は[こちら](https://raytracing.jp/rtcamp10/movie/redqueen__Shinji_Ogaki__CPU.mp4)で今年は2位でした。景品の深度カメラは何かに生かしたいと思います。


## 他の方の作品

全作品は[こちら](https://sites.google.com/view/rtcamp10)から見られます。各参加者は自身の作品も含め各作品にスコアを付けます。私は、良いと思った他の方の作品にはできる限り自分の作品以上の点をつけるようにしました。今回高い点を付けたのは

Samuel Huangさんの[ポータルを使った作品](https://raytracing.jp/rtcamp10/movie/Ether__Samuel_Huang__GPU.mp4)

https://x.com/gam0022/status/1845357806406283371

https://x.com/Shocker_0x15/status/1845387260260474924

以上の3作品です。

# 最後に

社会人一年目の方や学生の方が健闘していたのが印象的でした。皆がAIばかりやっていてはつまらないので、若い人たちには数学的に最適で美しいアルゴリズムをどんどん生み出していってほしいと思います。私はもともと絵を作りたくてレンダラを書き始めたので、プログラマーズアートをやらないように、技術抜きでも楽しめるようなアニメーション作品を作ることを目標に次回頑張りたいと思います。