レイトレーシングとGoroutine

 レイトレーシングとGoroutine

1514536d82df4b4a40628932c432a9c2?s=128

Takumasa Sakao

December 18, 2018
Tweet

Transcript

  1. レイトレーシングと Goroutine golang.tokyo #20 @sachaos

  2. 自己紹介 • @sachaos (サカオスと読みます) – Twitter, GitHub もこれでやってます。 – フォローしてくれると嬉しいです。

    • 所属: 株式会社アカツキ – 新卒 3 年目 – 技術基盤開発 – 主に GAE/Go を触っています。 – Go エンジニア募集中です。
  3. レイトレーシングとは? • 3D を描画する手法の一つ。 • Pros – 光の反射を綺麗に描画できる。 – アルゴリズムが直感的。

    • Cons – 非常に計算時間がかかる • リアルタイムに描画しなければならないゲームではあまり使われていない • 映画など予め描画して映像を作成できれば済むようなものに使用される
  4. そもそも 我々はどのようにして物を”視る“のか? 僕は赤を強く 反射する 赤い

  5. そもそも 我々はどのようにして物を”視る“のか? 僕は赤を強く 反射する 赤い そもそも 我々はどのようにして物を”視る“のか? • 光源が光を発する •

    光は空間内の物体にぶつかったら反射・屈折する • 反射・屈折してたまたま目に入った光から 情報を結合して物を認識する。
  6. レイトレーシングでは逆に カメラからレイ(視線)を飛ばす 僕は赤を強く 反射する

  7. レイトレーシングでは逆に カメラからレイ(視線)を飛ばす 僕は赤を強く 反射する • スクリーンの各ピクセルからレイ(視線)を飛ばす • 空間内の物体に衝突したら反射・屈折させる • 再帰的に最終的なピクセルの色を計算する

    レイトレーシングでは逆に カメラからレイ(視線)を飛ばす
  8. これを Go で フルスクラッチ実装してみました • https://github.com/sachaos/go-simple-raytracer • 実装的にはそこまで難しくはない • 高校数学(ベクトル)を理解できていれば

    コーディングできます
  9. 主な部品

  10. カメラ • ピクセル毎にレイ(視線) を飛ばす。 • アンチエイリアス: ピクセル毎にランダムに N個のレイを飛ばす。 N=3 N=100

  11. 反射するマテリアル • 金属、鏡のような 質感の物 • 単純にベクトルを 反射させる 入射レイ 反射レイ

  12. 乱反射するマテリアル • マットな質感の物 • レイが来た時にランダム に反射させる ランダムに 方向を決める 入射レイ

  13. Go を使うメリット • 標準パッケージで十分書ける – image/png で PNG を吐き出したりがシュッとできる。 –

    ベクトル計算は筋肉で書きました。 • レイトレーシングは並行処理が可能 – Goroutine で計算することができる! – (補足: 本来は GPU で並列計算します)
  14. 筋肉で書いた vector.go

  15. 並行処理が可能なので シュッと Goroutine にしてみる • これで速くなるはず!

  16. 並行処理が可能なので シュッと Goroutine にしてみる • これで速くなるはず! • 実際にやってみると速くならない!!! – むしろ遅くなった

    (51s => 1m24s)
  17. なぜか? pprof を使って見てみる • rand/math が原因である事がわかった。 • rand/math は goroutine

    safe で ロックを取っているので競合してしまう。
  18. mono0x/prand を使ってみた • https://github.com/mono0x/prand • rand を複数作っておいて プールして使い回す実装の様子 • Goroutine

    間で競合が起こるのを防ぐ事ができる。
  19. 問題解消、速くなった! • 51s => 30s に!

  20. Go で書いた感想 • シュッと Goroutine が決まると気持ちいい • 標準パッケージだけでも こんなに遊べるので Go

    は楽しい • 演算子オーバーロードできないのは ベクトル演算の時に若干辛かった
  21. ご静聴ありがとうございました