Open44

sog-loader実装スレ

にー兄さんにー兄さん

codebookが256個の要素の配列なのは、テクスチャの色が8bit整数であり
8bit整数値がcodebookのindexと対応していて、そのindex値に入っているfloat32の値が格納したい値だったんだな

謎の係数がかけられて、最終的に[0, 1]の範囲のfloatが算出されるな

// SH_C0 = Y_0^0 = 1 / (2 * sqrt(pi))
const SH_C0 = 0.28209479177387814;

const r = 0.5 + meta.sh0.codebook[sh0.r] * SH_C0;
const g = 0.5 + meta.sh0.codebook[sh0.g] * SH_C0;
const b = 0.5 + meta.sh0.codebook[sh0.b] * SH_C0;
const a = sh0.a / 255;

https://developer.playcanvas.com/user-manual/gaussian-splatting/formats/sog/#34-base-color--opacity-dc

にー兄さんにー兄さん

実装フローを整理

Zipファイル
↓
SOGデータ {means:[byte[], byte[]], scales:byte[]}
↓
WebPデコード byte[] -> RGBA[]
↓
汎用GSデータ {pos:vec3[], rot: quat[], scale:vec3[], color:rgba[], sh:f32[]}
にー兄さんにー兄さん

WebPデコードの前に、ここまでのコードがwasmで動くのかを検証したいので
wasm-bindgenに入門する

ちょっと調べてみた感じ、意外とあまり資料がないな

にー兄さんにー兄さん

適当なrustのlibプロジェクトを作成し、

cargo add wasm-bindgen

を実行してbindgenを導入する

にー兄さんにー兄さん
cargo install wasm-bindgen-cli

でCLIをインストールする
結構いろいろな依存関係がインストールされる

にー兄さんにー兄さん

これで

cargo build --target wasm32-unknown-unknown

でビルドすると、成果物が得られる
たしか、wasm32-unknown-unknownを使うためにはcargoに何か設定が必要だったんだけど、自分はどこかでやっていたんだよな

にー兄さんにー兄さん

この記事の指示に従って、bindgenのコマンドを実行する
https://ohwhsmm7.blog/?p=261

そうすると、jsとd.tsファイルができているな

にー兄さんにー兄さん

コマンドはこれ パスが長いだけでシンプルではある

wasm-bindgen .\target\wasm32-unknown-unknown\debug\rust-wasm-bindgen-testbed.wasm --out-dir .\target\wasm32-unknown-unknown\debug\ --target web
にー兄さんにー兄さん

あ~これ、出力先をWebプロジェクトのassetsか何かにしてインポートすればいいのかな

にー兄さんにー兄さん

ん~なんか、bindgenの方がうまく反映されないことがある
前のキャッシュが残るというか?

にー兄さんにー兄さん

actionsでビルドしていたら、bindgenのフォーマットのバージョン違いでエラーになった?

にー兄さんにー兄さん

zip解凍するだけのメソッドをwasm化してみたところ、エラーだ…

sog-wasm_bg.wasm:0xa7f8a Uncaught RuntimeError: unreachable
にー兄さんにー兄さん

うぉ!zip展開できた!

なんか、mainとかにあった処理を煎らない部分を削除したら実行できたな…

にー兄さんにー兄さん

上でエラーが出ていたの、もしかしたらmain関数の中に書いてあった処理がpanicしていたからかもしれない

なぜか今の設定だとmain関数がないとビルドできなくて、かつmainの中ではファイルシステム経由でsogファイルを取得している

にー兄さんにー兄さん

試しにwasm-optのWindowsバイナリを使って最適化してみたら、ファイルサイズが半分くらいになって凄い

にー兄さんにー兄さん

いちいちwasmにコンパイルするのめんどいので、rust上でデバッグして確かめたいなぁ

にー兄さんにー兄さん

rust-analyzer+CodeLLDBを使えば、

まずCargo.tomlでrlibも指定しておく

[lib]
crate-type = ["cdylib", "rlib"]

そうするとexamplesの中でもライブラリコードが参照できる

examples/debug.rs
use rustwasm_decoder_testbed::test_func;

fn main() {
    let a = test_func();
    println!("{}", &a);
}

そしてF5を押せば普通にデバッグできて神