2014年05月18日

WAVに関するメモ

忘れそうなのでWAVに関するメモです。用語などについては[1]に合わせているつもりです。

wav_memo_001.png

チャンネル数を減らすモノラル化です。サイズを変えたくない場合は平均値をLR両方にコピーする方法もあると思います。
wav_memo_002.png

フーリエ変換などを使えばもっとうまくサンプリングレートを変更できるんでしょうかね。
wav_memo_003.png

再生速度の変え方ってこれでいいのでしょうか。何か無理やり感があるのですが・・・。図を作るのが面倒になって最後はかなり適当です。
wav_memo_004.png

[1] http://www.kk.iij4u.or.jp/~kondo/wave/

web拍手 by FC2
posted by シンドラー at 15:50 | Comment(0) | TrackBack(0) | OpenAL | このブログの読者になる | 更新情報をチェックする

OpenAL Softを使った3Dオーディオのテスト

OpenAL Soft[1]を使うと3Dオーディオが簡単?にできるみたいなので試してみることにしました。[2]を参考にWAVを扱うクラスを作って、[3]を参考にOpenAL Softで3Dオーディオを使ってみました。WAVについてはOpenALのヘルパー関数?を使えば読込みはできるようですが、一応自分で読書き、ステレオのモノラル化、サンプリングレートの変更、再生速度の変更などを適当に実装しました。

実行結果

あぴミクさんと、[4]の歩きモーションとMMDBridgeを使用させていただいております。足音と歩行が合うように無理やりWAVデータを引き延ばしているだけです。足が地面に接触した場合に足音1回鳴らすようにすれば速度の変化にも対応できるとは思うのですが、接触判定などが大変ですね。



なぜかブログのプレイヤでは音声が再生されないみたいですのでダウンロードを押してください。動画のフォーマットが悪いんでしょうか。

[1] http://kcat.strangesoft.net/openal.html
[2] http://www.kk.iij4u.or.jp/~kondo/wave/
[3] http://cranialburnout.blogspot.jp/2012/08/openal-soft-demonstration-of-binaural.html
[4] http://www.nicovideo.jp/watch/sm9554606

web拍手 by FC2
posted by シンドラー at 00:52 | Comment(0) | TrackBack(0) | OpenAL | このブログの読者になる | 更新情報をチェックする

2014年05月05日

レイキャスティングと重心空間を用いたデプスバッファの計算 その2

良く考えたらポリゴンの内部かどうかは別として、レイキャスティングの時点で深度値は計算できてますよね…。それにスクリーン座標系の深度値って非線形だった気がするのですが、深度値をZ座標として平面計算してしまって問題ないのでしょうか…。

とりあえずOpenCLで実装をしてみました。GlobalWorkSize(size_t gws[2])の設定を久々だったので間違えていて無駄に時間がかかりましたのでメモしておきます。

LocalWorkSizeはsize_t lws[2] = {16,16};にしておきます。GlobalWorkSizeは、LocalWorkSizeの定数倍になっていないと駄目なようです。2次元の画像の場合、widthとheightを16の倍数にする必要があります。そのために、16で割ってceil関数で整数にしてもう一度16を掛けます。
void setGlobalWorkSize2D(const int width, const int height, 
const size_t lws[2], size_t gws[2])
{
gws[0] = lws[0]*ceil((double)width/(double)lws[0]);
gws[1] = lws[1]*ceil((double)height/(double)lws[1]);
}
各頂点、各面のデータに対して処理する場合、基本的には1次元の頂点数、面数を使えばいいのだと思いますが、面倒なので?2次元に分割して使用することにします。
void setGlobalWorkSize1D(const int dataNum, 
const size_t lws[2], size_t gws[2])
{
// データ数の平方根を横幅にする
gws[0] = lws[0]*ceil(sqrt((double)dataNum)/(double)lws[0]);
// 縦幅
gws[1] = lws[1]*ceil(ceil(((double)dataNum/(double)gws[0]))/(double)lws[1]);
}
普通に1次元でやった方が楽ですかね。

cl側での参照の仕方を書いていなかったので追記します。(2014.5.6)
上の方法で1次元データを2次元で処理する場合、横幅はGlobalWorkSizeと一致しますので、それを使って判定できます。領域外かどうかは、データ数を渡してあげる必要はあります。(必要なのかどうかはわかりませんが)
__kernel void Test1d(__global float *vertexPos, __global float *screenPos, int vertexNum)
{
// x座標
const unsigned int idx = get_global_id(0);
// y座標
const unsigned int idy = get_global_id(1);
// get_global_size(0)で横幅を取得して一次元に直す
unsigned int index = get_global_size(0)*idy + idx;
// データ数を渡しておいて範囲外の時は処理しない
if (index >= vertexNum) return;
...
}

2次元画像の場合、GlobalWorkSizeと画像のサイズは異なっていますので、領域外かどうか判定するためにget_image_dim関数を使用して画像の大きさを取得します。
__kernel void Test1d(__read_only image2d_t im_in, __write_only image2d_t im_out)
{
// x座標
const unsigned int idx = get_global_id(0);
// y座標
const unsigned int idy = get_global_id(1);
// 画像の大きさを取得して範囲外の時は処理しない
const int2 imageSize = get_image_dim(im_out);
if (idx >= imageSize.x || idy >= imageSize.y) return;
...
}

実行結果

640x480の画像で2秒ぐらいかかるのでやはり使えなさそうですね。メモリ的にもギリギリみたいですし。

center_gravity_003.png

web拍手 by FC2
posted by シンドラー at 16:42 | Comment(0) | TrackBack(0) | OpenCL | このブログの読者になる | 更新情報をチェックする

2014年05月02日

レイキャスティングと重心空間を用いたデプスバッファの計算

グラフィックボードがやってくれるのでやる必要のないデプスバッファの計算方法です。以前も自前で微妙なラスタライズをしたりBulletのレイキャスティングを使ったりしていたのですが、実例で学ぶゲーム3D数学[1]を眺めていたら、重心空間というものが載っていましたので、これを使って三角ポリゴンのデプスバッファ計算をしてみることにしました。計算量が多いので微妙ですが。

手順
0. デプスバッファの深度値を1.0で初期化
1.ポリゴンの3頂点をModelViewProjectionViewport変換してスクリーン座標に変換する
2. スクリーン座標に変換したポリゴンから平面の方程式を計算する(11.5.2 3点を使った定義)
3.各画素(x, y)において、以下の計算を行う
3.0. ポリゴンの枚数だけ3.1.〜3.4.を繰返す
3.1. スクリーン座標(x+0.5,y+0.5,-1.0)として、レイ(0,0,1)とポリゴンの平面との交点Pを求める(12.9 光線と平面の交差)。この際、交点Pのz値が-1.0未満もしくは1.0以上の場合はクリッピングの領域外なので何もしない
3.2. 交点Pを重心座標に変換する(11.6.3 重心空間)。この際、b1, b2, b3のうち一つでも負の値があればポリゴンの領域外なので何もしない
3.3. b1, b2, b3を重みとして深度値、法線ベクトル、テクスチャ座標等の補間を行う
3.4. 現在保存されている深度値と、今回の深度値を比較して、小さければ更新

実行結果

2枚の三角ポリゴンの結果です。3.2.でif (b1 < 0 || b2 < 0 || b3 < 0) としたら2枚のポリゴンの境目の線が見えてしまったので、オフセットで調整しました。

深度値

center_gravity_001.png

頂点に適当に設定した法線ベクトル

center_gravity_002.png

うーん、それっぽいような何か違うような。これであっているのかどうか自信がないですね。

[1] Fletcher Dunn, Ian Parberry 著, 松田 晃一 訳, 「実例で学ぶゲーム3D数学」, オライリー・ジャパン

web拍手 by FC2
posted by シンドラー at 00:15 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする