Nao_uの日記 このページをアンテナに追加 RSSフィード

2017-10-22

[]OSM+Houdini OSM+Houdini - Nao_uの日記 を含むブックマーク はてなブックマーク - OSM+Houdini - Nao_uの日記 OSM+Houdini - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20171022171505p:image

houdini game dev toolのopen street mapでニューヨークを取り込んでFBX出力したものを、UnityでGoogle Mapの衛星画像と合わせてみた。OSMの道路データも加工できると面白そうなんだけど、そっちは簡単にはいかなそう

Yoshiaki Higa‏ @YoshiakiHiga 10月21日

道路はラインポリゴンで読み込まれるのできれいに作ろうとしたら難しそうですね。自分も色々やってますがなかなか上手くいってないです。地図画像のスクショとって画像からジオメトリ生成するのがきれいにできそうです。(多分)

いただいたアドバイスを元に、地図の画像から道路の色を抜き出してポリゴン化してみた。


f:id:Nao_u:20171022171850p:image

画像解像度より細かくしたGridにUVを割り当てて画像を転写して、Wrangleで色の白いところだけを残して頂点を削り、fuseしてから、Groupで端のエッジをグループ化。Groupでエッジを残す方法は以下の通り。

f:id:Nao_u:20171022171349p:image


この後は、dissplveで端のエッジグループ以外を削除。ここでfuseしてないといるエッジまで消える?この辺トラブってた。

最後にresampleで適当に削ってるけど、ここももっといいやり方ありそう

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20171022

2017-08-20

[]剛体破壊をテクスチャに焼いてUnityに持っていく(5) 剛体破壊をテクスチャに焼いてUnityに持っていく(5) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(5) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(5) - Nao_uの日記 のブックマークコメント

頂点位置だけでなく法線も出力してみたら、法線が共有できなくなるので頂点数が数倍に膨れ上がり、2048頂点を超えたあたりでUVの精度不足かポリゴンが壊れるようになったり、レンダリング時に変なピクセルが出たりと問題がいろいろ発生。まだ一筋縄ではいかなそうだけど今回はここで時間切れ…

f:id:Nao_u:20170820224018g:image


頂点とテクスチャが一対一対応している前提ならSV_VertexIDで頂点番号からUVを計算したいところだけど、HoudiniからUnityに出す間のどこかで頂点順が変わっているのかうまくいかず。あと法線も2成分だけ出して残りは外積で求められるなら、Posのαに圧縮して入れられそう

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20170820

2017-08-19

[]剛体破壊をテクスチャに焼いてUnityに持っていく(4) 剛体破壊をテクスチャに焼いてUnityに持っていく(4) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(4) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(4) - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170820224031g:image

Houdiniの頂点テクスチャアニメ、標準機能は使わず自前で位置情報をf16のテクスチャに出力してみた。ひとまずベタに座標のみ出してみると今回は位置のずれは発生せず。テクスチャが位置情報だけで1600頂点×190フレームで2.3MBもあるので、実用的に使うなら剛体化は必須かも…。


Houdiniからの頂点テクスチャ出力、標準のvertex_animation_textureから必要な部分を切りしてみたら、テクスチャの生成処理が「ドット絵のようなグリッドモデルを作ってカメラで撮影する」という予想外の実装になってた。テクスチャを出す方法ってこれしかないのかな?

UnlimitedEffectWorks‏ @ijiVFX さん


pointにCdのアトリビュートが設定されたグリッド上のメッシュならこんな感じでPythonのPILを使って吐き出せます

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20170819

2017-08-17

[]剛体破壊をテクスチャに焼いてUnityに持っていく(3) 剛体破壊をテクスチャに焼いてUnityに持っていく(3) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(3) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(3) - Nao_uの日記 のブックマークコメント

頂点カラーに焼かれていた回転中心をuv3に持っていけないかとデフォルトのvexを書き換えたりして試したけど、モデルが壊れるだけでうまくいかず。

出力部分と同等のものをゼロから作ろうとしてみてるけど、テクスチャの出力がグリッドの板ポリに頂点カラーを割り当てたものをカメラで撮影して作ってるっぽい。

ライトの設定とか、exrを出力してもUnityで読めないとかわからない点が多くて困ってるが、一通りこの辺が動くようにできれば理解は深まりそう。

調査メモ:

テクスチャを出すために、今のフレームの頂点位置を頂点カラーに焼いた横長のグリッドを作って、それをBlockBegin-endでマージしながら合成した板を作り、その板をレンダリングしている


レンダリング時にはcameraと同階層にMaterial Networkが置かれていて、その中にMaterialBuilderでConstantのシェーダーが置かれている。コメントには"Created from Gallery Entry: Constant. Mantra Constant Shader"と書かれているので、なにかコンスタントなシェーダーを作る方法があるのかもしれない。

描画するTEXTURE_MESH のGeometryに../matnet1/constant のシェーダーが割り当てられていた。


Houdiniでの任意のテクスチャの出力方法

シェーダーをGetmetryに割り当てる方法
  • Material Networkを任意の場所に作れる。今回は、out/objnet1の下に作る。
  • Material Palletを開いて、out/objnet1/matnet1 に Constantのシェーダーをコピーすれば、matnet1にConstantのシェーダーが増やせる。
  • GeometryのRenderタブのMaterialから作成したシェーダーを割り当てることで、該当Geometryに任意のシェーダーを設定することができる。

Render Viewから任意のカメラを設定することで、レンダリング結果を確認できる。

カメラの設定と出力解像度
  • ViewタブのResolution のXYで、出力テクスチャの解像度が決まる。レンダーターゲットの縦横比もこの時点で決まる。
  • ProjectionをOrthographicにして、Ortho Widthを設定することで、横幅が決まる。縦の長さは出力テクスチャの解像度に依存
    • なので、Ortho WidthはResolutionの横幅と一致させるようにする
テクスチャの出力
  • outにMantraノードを作って、Cameraに適切なカメラを設定する
  • "Render to Disk"のボタンでOutput Pictureにファイルを描きだす。
    • Output Deviceでテクスチャフォーマットを決める
  • OutputタブのPixel Filter は"minmax max"になっていた。内容は要確認…
  • Quantization は 32bit float になってた

たまにUnityで読めない.exrができちゃうんだけど、何をミスってるんだろう…


とりあえずexrのテクスチャが吐けたのでノード構成をメモ

f:id:Nao_u:20170819110601p:image

  • 基本はvertex_animation_texture_bataのrigid_objを改変したもの。
  • pointwrangleで頂点数分の横長のポイント列を生成して、copyPointsでgridを並べて横長のグリッドに変換し、block_begin-endでtimeshiftしながら時系列にループさせて縦に並べる
  • block_metaでblock_beginのループ回数を取得できるらしい。
  • wrangleで1番目につないだノード(左端は0番目)の頂点数は、[npoints(1)]で取得できる
    • 今回は、wrangleに ch("vert_count") と書いて、右側のボタンを押すとwrangleのパラメータを追加できる。そのパラメータにnpoints(1)を設定して、頂点数を取得していた。

  • テクスチャの幅は、cameraのviewのResolutuion.xとOrthoWidthには npoints("../geo1/object_merge1") を設定して、Resolution.yには bbox("../geo1", D_YSIZE) を設定

モデルの出力側

f:id:Nao_u:20170820132323p:image

  • unpackして頂点を展開してから、pointWrangleでuv2を生成して、vertexにpromoteする
トラックバック - http://game.g.hatena.ne.jp/Nao_u/20170817

2017-08-16

[]剛体破壊をテクスチャに焼いてUnityに持っていく(2) 剛体破壊をテクスチャに焼いてUnityに持っていく(2) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(2) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(2) - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170820224055g:image


f:id:Nao_u:20170816161209p:image

破片のだいたいの動きは再現できるんだけど、Houdiniで平面になっているブロックの並びが、Unityに持っていくとジグザグに崩れてしまう。

テクスチャ精度の問題なのか、何か他に要因があるのか…

→回転中心が頂点カラーに焼かれていて、精度が8bitに落とされているのが原因のような気が。

ずしさんに検証いただいた結果、positionがf16で精度不足になっている可能性が。ただ、こちらは最初から0-1にNormalizeしているので、別原因の可能性も?

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20170816

2017-08-15

[]剛体破壊をテクスチャに焼いてUnityに持っていく 剛体破壊をテクスチャに焼いてUnityに持っていく - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170820224043g:image


基本的には下記リンクの通りで動くようになるが、手順が多くてHoudiniから出しなおすたびにうまく動かなくなって原因を調べる、みたいな状態で無駄に時間がかかった。

またハマりそうな点をいくつかメモ。

  • BBOX MAX と MINは、テクスチャの再出力後になぜか更新されない時がある。そのときは、/outを抜けてもう一度入りなおすと最新の値になる?
    • BBOX MAXが間違った値になっていると、回転の中心がずれておかしな位置に出てしまうので、そのような挙動になったらBBOXを疑うように。
  • レンダリングモードをLinearに切り替えないと、posはセンターがずれるし、rotは微妙に向きが変になる。新しくプロジェクトを作り直した時には、こちらも忘れないように。
トラックバック - http://game.g.hatena.ne.jp/Nao_u/20170815

2017-02-19

[]オプティカルフローテスト スロー煙 オプティカルフローテスト スロー煙 - Nao_uの日記 を含むブックマーク はてなブックマーク - オプティカルフローテスト スロー煙 - Nao_uの日記 オプティカルフローテスト スロー煙 - Nao_uの日記 のブックマークコメント

Houdiniで8フレームおきにレンダリングした煙をオプティカルフローで補間して、スロー再生。

前回から少しシェーダーを修正。前回は現フレームと次フレームそれぞれで別々にオプティカルフローで流したものを補完していたが、今回は現フレームと次フレームのオプティカルフローを補完して、同じ方向にそれぞれのフレームをゆがめた後でフレーム補完している。


オプティカルフロー生成時のパラメータは前回と同じなので、差分が大きすぎてクランプされて変になってる箇所がある。速度ベクトルの補正係数は絵によって調整が必要か。

こういう流体的な絵であれば、ちゃんと調整すれば長いフレーム補間も十分機能しそう。

f:id:Nao_u:20170219232254j:image f:id:Nao_u:20170219232255p:image

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20170219

2016-08-05

[]Witcher 3 Blood and Wine architectural material Witcher 3 Blood and Wine architectural material - Nao_uの日記 を含むブックマーク はてなブックマーク - Witcher 3 Blood and Wine architectural material - Nao_uの日記 Witcher 3 Blood and Wine architectural material - Nao_uの日記 のブックマークコメント

建物の参考画像に。


[]破壊動画 破壊動画 - Nao_uの日記 を含むブックマーク はてなブックマーク - 破壊動画 - Nao_uの日記 破壊動画 - Nao_uの日記 のブックマークコメント

いい崩れ方

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20160805

2016-07-29

[]テクスチャを頂点カラーに転写 テクスチャを頂点カラーに転写 - Nao_uの日記 を含むブックマーク はてなブックマーク - テクスチャを頂点カラーに転写 - Nao_uの日記 テクスチャを頂点カラーに転写 - Nao_uの日記 のブックマークコメント

  • https://www.sidefx.com/forum/topic/18597/
    • vertexuv_to_point-2.hipnc
    • vopsopで、uvとcmapを取得してからcolormapに突っ込んでテクスチャをサンプリングし、outputのCdに入れることでテクスチャの模様の頂点カラーを生成

[]Game Development Toolset Game Development Toolset - Nao_uの日記 を含むブックマーク はてなブックマーク - Game Development Toolset - Nao_uの日記 Game Development Toolset - Nao_uの日記 のブックマークコメント

Game Development Toolset は SideFX が提供するゲームコンテンツ制作で便利なツール集。Github から提供されている。ここでは、そのインストール方法と主要なツールを紹介する。


[]VOPの中でアトリビュートを生成して値を入れる方法 VOPの中でアトリビュートを生成して値を入れる方法 - Nao_uの日記 を含むブックマーク はてなブックマーク - VOPの中でアトリビュートを生成して値を入れる方法 - Nao_uの日記 VOPの中でアトリビュートを生成して値を入れる方法 - Nao_uの日記 のブックマークコメント

  • https://twitter.com/_shohey_/status/567700950249242625
    • 値を入れるのはSet Attributeで。i1にptnum、valueに値を繋ぐ
    • アトリビュートの生成は add Attributeで。新規の時はこのノードで生成しないとSetできない。ノードが存在すればつなぐ必要はない

[]カーブ上の先頭からの距離を求める(1) カーブ上の先頭からの距離を求める(1) - Nao_uの日記 を含むブックマーク はてなブックマーク - カーブ上の先頭からの距離を求める(1) - Nao_uの日記 カーブ上の先頭からの距離を求める(1) - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20160730145641p:image

カーブ上の距離を求める準備段階として、一つ前の点との距離を新規Attributeで追加するPoint VOPを作るとこうなった。

  • ptnumをsubConst→importPoint(P)でひとつ前の頂点座標を取得
  • Pからひとつ前の頂点を引いてlengthで距離を計算
  • ひとつ前の頂点との差分はptnum==0で破綻するので、ptnumをcompare==0して、two Wayでptnum==0のとき0を返すように
  • addAttributeしておいたアトリビュートに、setAttributeで値を入れる。このとき、i1には頂点番号を入れる必要がある

[]カーブ上の先頭からの距離を求める(2) カーブ上の先頭からの距離を求める(2) - Nao_uの日記 を含むブックマーク はてなブックマーク - カーブ上の先頭からの距離を求める(2) - Nao_uの日記 カーブ上の先頭からの距離を求める(2) - Nao_uの日記 のブックマークコメント

You can get the length of a curve primitive with the arclen expression function. Example:

arclen(“../curve1”, 0, 0, 1)


You could also use a Resample SOP after the curve, choose the Maximum Segment Length option, specify a segment length, and use the resampled curve as a template geometry (second input) in the Copy SOP, using the box you wish to duplicate along the curve as the first input of the Copy SOP.

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20160729

2016-06-18

[]Houdini Engine、Unity5で使うには、 Houdini Engine、Unity5で使うには、 - Nao_uの日記 を含むブックマーク はてなブックマーク - Houdini Engine、Unity5で使うには、 - Nao_uの日記 Houdini Engine、Unity5で使うには、 - Nao_uの日記 のブックマークコメント

      • \Houdini 15.5.480\engine\unity\Assets
    • の下をUnityの該当プロジェクトのAssetsフォルダの下に丸コピーする必要があった
  • ライセンスのためにアカウントを作るのが面倒だったので、とりあえず30日試用版で。
トラックバック - http://game.g.hatena.ne.jp/Nao_u/20160618

0017-09-02

[]CEDEC2017で紹介されていたビルを作るHDA CEDEC2017で紹介されていたビルを作るHDA - Nao_uの日記 を含むブックマーク はてなブックマーク - CEDEC2017で紹介されていたビルを作るHDA - Nao_uの日記 CEDEC2017で紹介されていたビルを作るHDA - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170903145449p:image

回転対応などの汎用性を無視して、それっぽいものを実装してみる

特殊 等分割のほうは、「エッジなし」「エッジ半分」「エッジ両方」は未実装だけど、やっぱり必須だなぁ…。

3分割

string groupName = ch("groupName");
float sizeA = ch("Size_a");
float sizeB = ch("Size_b");
string groupNameA = ch("groupNameA");
string groupNameB = ch("groupNameB");
string groupNameC = ch("groupNameC");
float turn90 = ch("turn90");

if( groupName == "" || inprimgroup(@Opinput1,groupName,@primnum) == 1 )
{
    removeprim(geoself(), @primnum, 0);
    
    int points[] = primpoints(0, @primnum);
    
    int ip0, ip1, ip2, ip3;
    if( turn90 != 0 ){
        ip0 = points[1];
        ip1 = points[2];
        ip3 = points[3];
        ip2 = points[0];
    }else{
        ip0 = points[0];
        ip1 = points[1];
        ip3 = points[2];
        ip2 = points[3];
    }
    
    vector p0 = point(0, "P", ip0);
    vector p1 = point(0, "P", ip1);
    vector p2 = point(0, "P", ip2);
    vector p3 = point(0, "P", ip3);
    
    vector ap0 = p0 + normalize(p2-p0)*sizeA;
    vector ap1 = p1 + normalize(p3-p1)*sizeA;
    vector ap2 = p2 + normalize(p0-p2)*sizeB;
    vector ap3 = p3 + normalize(p1-p3)*sizeB;
    
    int iap0 = addpoint(geoself(), ap0);
    int iap1 = addpoint(geoself(), ap1);
    int iap2 = addpoint(geoself(), ap2);
    int iap3 = addpoint(geoself(), ap3);
    
    int prim;
    
    // Aプリミティブを生成
    prim = addprim(geoself(), "poly");
    addvertex(geoself(), prim, ip0);
    addvertex(geoself(), prim, ip1);
    addvertex(geoself(), prim, iap1);
    addvertex(geoself(), prim, iap0);
    if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
    setprimgroup(geoself(), groupName+"_"+groupNameA, prim, 1, "set");
    
    // Bプリミティブを生成
    prim = addprim(geoself(), "poly");
    addvertex(geoself(), prim, iap2);
    addvertex(geoself(), prim, iap3);
    addvertex(geoself(), prim, ip3);
    addvertex(geoself(), prim, ip2);
    if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
    setprimgroup(geoself(), groupName+"_"+groupNameB, prim, 1, "set");
    
    // Cプリミティブを生成
    prim = addprim(geoself(), "poly");
    addvertex(geoself(), prim, iap0);
    addvertex(geoself(), prim, iap1);
    addvertex(geoself(), prim, iap3);
    addvertex(geoself(), prim, iap2);
    if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
    setprimgroup(geoself(), groupName+"_"+groupNameC, prim, 1, "set");
}

特殊 等分割


string groupName = ch("groupName");
float sizeA = ch("sizeA");
float sizeB = ch("sizeB");
if( sizeB < 0.001 ) sizeB = 0.001;
string groupNameA = ch("groupNameA");
string groupNameB = ch("groupNameB");
float turn90 = ch("turn90");

if( groupName == "" || inprimgroup(@Opinput1, groupName, @primnum) == 1 )
{
    removeprim(geoself(), @primnum, 0);
    
    int points[] = primpoints(0, @primnum);
    int ip0, ip1, ip2, ip3;
    if( turn90 != 0 )
    {
        ip0 = points[0];
        ip1 = points[1];
        ip3 = points[2];
        ip2 = points[3];
    }else{
        ip0 = points[1];
        ip1 = points[2];
        ip3 = points[3];
        ip2 = points[0];
    }
    
//    printf("[%d] %d,%d,%d,%d",@primnum,ip0,ip1,ip2,ip3);
    
    vector p0 = point(0, "P", ip0);
    vector p1 = point(0, "P", ip1);
    vector p2 = point(0, "P", ip2);
    vector p3 = point(0, "P", ip3);
    
    // 進行方向のベクトルを求める
    vector dirVec = normalize(p1-p0);
    
    // 幅を求める
    float width = distance(p1,p0);
    // 繰り返し回数を求める
    int rep = 1+width / (sizeA+sizeB);
    // 繰り返し回数の上限を設定
    if( rep > 100 ) rep = 100;
    
    /*
    printf("w=%f\n",width);
    printf("a=%f\n",sizeA);
    printf("b=%f\n",sizeB);
    printf("rep=%d\n",rep);
    */
    // sizeBをちょうどいい幅に補正
    sizeB = (width - sizeA*rep) / rep;
    
    int prim;
    
    // 前の点のベクトル
    vector pp0 = p0;
    vector pp1 = p2;
    int ipp0 = addpoint(geoself(), pp0);
    int ipp1 = addpoint(geoself(), pp1);
    // 今追加したベクトル
    vector pn0, pn1;    
    int ipn0, ipn1;
    
    for( int i=0; i<rep; i++)
    {
        // Aを追加
        pn0 = pp0 + dirVec * sizeA;
        pn1 = pp1 + dirVec * sizeA;
        ipn0 = addpoint(geoself(), pn0);
        ipn1 = addpoint(geoself(), pn1);
    
        prim = addprim(geoself(), "poly");
        addvertex(geoself(), prim, ipp0);
        addvertex(geoself(), prim, ipp1);
        addvertex(geoself(), prim, ipn1);
        addvertex(geoself(), prim, ipn0);
        if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
        setprimgroup(geoself(), groupName+"_"+groupNameA, prim, 1, "set" );
        pp0 = pn0; ipp0 = ipn0;
        pp1 = pn1; ipp1 = ipn1;
    
        // Bを追加
        pn0 = pp0 + dirVec * sizeB;
        pn1 = pp1 + dirVec * sizeB;
        ipn0 = addpoint(geoself(), pn0);
        ipn1 = addpoint(geoself(), pn1);
    
        prim = addprim(geoself(), "poly");
        addvertex(geoself(), prim, ipp0);
        addvertex(geoself(), prim, ipp1);
        addvertex(geoself(), prim, ipn1);
        addvertex(geoself(), prim, ipn0);
        if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
        setprimgroup(geoself(), groupName+"_"+groupNameB, prim, 1, "set" );
        pp0 = pn0; ipp0 = ipn0;
        pp1 = pn1; ipp1 = ipn1;
    }
}
トラックバック - http://game.g.hatena.ne.jp/Nao_u/00170902

0017-08-20

[]剛体破壊をテクスチャに焼いてUnityに持っていく(5) 剛体破壊をテクスチャに焼いてUnityに持っていく(5) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(5) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(5) - Nao_uの日記 のブックマークコメント

頂点位置だけでなく法線も出力してみたら、法線が共有できなくなるので頂点数が数倍に膨れ上がり、2048頂点を超えたあたりでUVの精度不足かポリゴンが壊れるようになったり、レンダリング時に変なピクセルが出たりと問題がいろいろ発生。まだ一筋縄ではいかなそうだけど今回はここで時間切れ…

f:id:Nao_u:20170820224018g:image


頂点とテクスチャが一対一対応している前提ならSV_VertexIDで頂点番号からUVを計算したいところだけど、HoudiniからUnityに出す間のどこかで頂点順が変わっているのかうまくいかず。あと法線も2成分だけ出して残りは外積で求められるなら、Posのαに圧縮して入れられそう

トラックバック - http://game.g.hatena.ne.jp/Nao_u/00170820

0017-08-19

[]剛体破壊をテクスチャに焼いてUnityに持っていく(4) 剛体破壊をテクスチャに焼いてUnityに持っていく(4) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(4) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(4) - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170820224031g:image

Houdiniの頂点テクスチャアニメ、標準機能は使わず自前で位置情報をf16のテクスチャに出力してみた。ひとまずベタに座標のみ出してみると今回は位置のずれは発生せず。テクスチャが位置情報だけで1600頂点×190フレームで2.3MBもあるので、実用的に使うなら剛体化は必須かも…。


Houdiniからの頂点テクスチャ出力、標準のvertex_animation_textureから必要な部分を切りしてみたら、テクスチャの生成処理が「ドット絵のようなグリッドモデルを作ってカメラで撮影する」という予想外の実装になってた。テクスチャを出す方法ってこれしかないのかな?

UnlimitedEffectWorks‏ @ijiVFX さん


pointにCdのアトリビュートが設定されたグリッド上のメッシュならこんな感じでPythonのPILを使って吐き出せます

トラックバック - http://game.g.hatena.ne.jp/Nao_u/00170819

0017-08-17

[]剛体破壊をテクスチャに焼いてUnityに持っていく(3) 剛体破壊をテクスチャに焼いてUnityに持っていく(3) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(3) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(3) - Nao_uの日記 のブックマークコメント

頂点カラーに焼かれていた回転中心をuv3に持っていけないかとデフォルトのvexを書き換えたりして試したけど、モデルが壊れるだけでうまくいかず。

出力部分と同等のものをゼロから作ろうとしてみてるけど、テクスチャの出力がグリッドの板ポリに頂点カラーを割り当てたものをカメラで撮影して作ってるっぽい。

ライトの設定とか、exrを出力してもUnityで読めないとかわからない点が多くて困ってるが、一通りこの辺が動くようにできれば理解は深まりそう。

調査メモ:

テクスチャを出すために、今のフレームの頂点位置を頂点カラーに焼いた横長のグリッドを作って、それをBlockBegin-endでマージしながら合成した板を作り、その板をレンダリングしている


レンダリング時にはcameraと同階層にMaterial Networkが置かれていて、その中にMaterialBuilderでConstantのシェーダーが置かれている。コメントには"Created from Gallery Entry: Constant. Mantra Constant Shader"と書かれているので、なにかコンスタントなシェーダーを作る方法があるのかもしれない。

描画するTEXTURE_MESH のGeometryに../matnet1/constant のシェーダーが割り当てられていた。


Houdiniでの任意のテクスチャの出力方法

シェーダーをGetmetryに割り当てる方法
  • Material Networkを任意の場所に作れる。今回は、out/objnet1の下に作る。
  • Material Palletを開いて、out/objnet1/matnet1 に Constantのシェーダーをコピーすれば、matnet1にConstantのシェーダーが増やせる。
  • GeometryのRenderタブのMaterialから作成したシェーダーを割り当てることで、該当Geometryに任意のシェーダーを設定することができる。

Render Viewから任意のカメラを設定することで、レンダリング結果を確認できる。

カメラの設定と出力解像度
  • ViewタブのResolution のXYで、出力テクスチャの解像度が決まる。レンダーターゲットの縦横比もこの時点で決まる。
  • ProjectionをOrthographicにして、Ortho Widthを設定することで、横幅が決まる。縦の長さは出力テクスチャの解像度に依存
    • なので、Ortho WidthはResolutionの横幅と一致させるようにする
テクスチャの出力
  • outにMantraノードを作って、Cameraに適切なカメラを設定する
  • "Render to Disk"のボタンでOutput Pictureにファイルを描きだす。
    • Output Deviceでテクスチャフォーマットを決める
  • OutputタブのPixel Filter は"minmax max"になっていた。内容は要確認…
  • Quantization は 32bit float になってた

たまにUnityで読めない.exrができちゃうんだけど、何をミスってるんだろう…


とりあえずexrのテクスチャが吐けたのでノード構成をメモ

f:id:Nao_u:20170819110601p:image

  • 基本はvertex_animation_texture_bataのrigid_objを改変したもの。
  • pointwrangleで頂点数分の横長のポイント列を生成して、copyPointsでgridを並べて横長のグリッドに変換し、block_begin-endでtimeshiftしながら時系列にループさせて縦に並べる
  • block_metaでblock_beginのループ回数を取得できるらしい。
  • wrangleで1番目につないだノード(左端は0番目)の頂点数は、[npoints(1)]で取得できる
    • 今回は、wrangleに ch("vert_count") と書いて、右側のボタンを押すとwrangleのパラメータを追加できる。そのパラメータにnpoints(1)を設定して、頂点数を取得していた。

  • テクスチャの幅は、cameraのviewのResolutuion.xとOrthoWidthには npoints("../geo1/object_merge1") を設定して、Resolution.yには bbox("../geo1", D_YSIZE) を設定

モデルの出力側

f:id:Nao_u:20170820132323p:image

  • unpackして頂点を展開してから、pointWrangleでuv2を生成して、vertexにpromoteする
トラックバック - http://game.g.hatena.ne.jp/Nao_u/00170817

0017-08-16

[]剛体破壊をテクスチャに焼いてUnityに持っていく(2) 剛体破壊をテクスチャに焼いてUnityに持っていく(2) - Nao_uの日記 を含むブックマーク はてなブックマーク - 剛体破壊をテクスチャに焼いてUnityに持っていく(2) - Nao_uの日記 剛体破壊をテクスチャに焼いてUnityに持っていく(2) - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170820224055g:image


f:id:Nao_u:20170816161209p:image

破片のだいたいの動きは再現できるんだけど、Houdiniで平面になっているブロックの並びが、Unityに持っていくとジグザグに崩れてしまう。

テクスチャ精度の問題なのか、何か他に要因があるのか…

→回転中心が頂点カラーに焼かれていて、精度が8bitに落とされているのが原因のような気が。

ずしさんに検証いただいた結果、positionがf16で精度不足になっている可能性が。ただ、こちらは最初から0-1にNormalizeしているので、別原因の可能性も?

トラックバック - http://game.g.hatena.ne.jp/Nao_u/00170816