【VFXGraph】速度マップの位置が0.5ズレる問題の応急処置


はじめに

Houdiniを使って以下のようなVectorFieldを作成しました。


0<x<0.5の時は速度(1,0,0)

-0.5<x<0の時は速度(-1,0,0)

それ以外では速度(0,0,0)


image.png

上記のVectorFieldを.fgaファイルとしてUnityにインポートし、3Dテクスチャ化したものを

VisualEffectGraphにて速度マップとして使ってみました。

image.png


発生した問題

その結果、「3Dテクスチャ(速度マップ)の位置が0.5ズレる」という現象が発生しました。

1.gif

座標(0,0,0)を中心とした立方体でパーティクルは発生していますが、速度マップは座標(0.5, 0.5, 0.5)を中心とした分布になっています。

今回、ソースコードを改造することでこの問題が解決したのでメモ書き程度に記事にしたいと思います。


環境

Unity2019.1.1f1

Visual Effect Graph - Version 5.13.0 (Preview)


対策1 : パーティクルの生成位置を0.5ずらす(間違った対策)

(パッケージの格納フォルダ)\Editor\Models\Blocks\Implementations\Positionフォルダの中にある、

PositionAABox.csの中を見ると以下のようなコードがあります。


PositionAABox.cs

...

public override string source
{
get
{
if (positionMode == PositionMode.Volume)
{
return @"position = Box_size * (RAND3 - 0.5f) + Box_center;";
}
...

ちなみに、source はVisualEffectGraph内部で管理されているコンピュートシェーダーの一部分です。


コードを書き換える

上記のコードを以下のように書き換えます。


PositionAABox.cs

...

public override string source
{
get
{
if (positionMode == PositionMode.Volume)
{
// return @"position = Box_size * (RAND3 - 0.5f) + Box_center;";
return @"position = Box_size * (RAND3) + Box_center;";
}
...

参考:

【Unity】PackageManagerが提供するパッケージのダウンロード先と、パッケージを改造する方法

http://tsubakit1.hateblo.jp/entry/2018/08/16/221016


結果

改造した状態でUnityを再起動したところ、以下のようになりました。

2.gif

Position(AABox)の中心が(0.5, 0.5, ,0.5)ズレました。

ぱっと見た感じ正しく見えますが、本来は(0,0,0)を中心とした速度分布になってほしいので、これは間違った対策になります。

PositionAABox.csは修正前の状態へ戻します


対策2 : 3Dテクスチャのサンプリング位置を0.5ずらす(たぶん正しい対策)

(パッケージの格納フォルダ)\Editor\Models\Blocks\Implementations\Attributeフォルダの中にある、

AttributeFromMap.cs を覗くと以下のようなコードがあります。

下記コードのSamplePositionが3Dテクスチャのサンプリング位置になっています。


AttributeFromMap.cs

...

if (SampleMode == AttributeMapSampleMode.Sample2DLOD || SampleMode == AttributeMapSampleMode.Sample3DLOD)
{
output += string.Format(@"
{0} value = ({0})attributeMap.t.SampleLevel(attributeMap.s, SamplePosition, LOD);
{1}
"
, GetCompatTypeString(valueType), biasScale);
}
...

これを以下のように書き換えます。


AttributeFromMap.cs

...

if (SampleMode == AttributeMapSampleMode.Sample2DLOD || SampleMode == AttributeMapSampleMode.Sample3DLOD)
{
output += string.Format(@"
{0} value = ({0})attributeMap.t.SampleLevel(attributeMap.s, SamplePosition + 0.5f, LOD);
{1}
"
, GetCompatTypeString(valueType), biasScale);
}
...


結果

改造した状態で、Unityを再起動したところ以下のようになりました。

3.gif

(0, 0, 0)を中心とした速度分布になっています。


補足 : attributeMapの定義場所

attributeMap は VFXCommon.cgincの中で定義されている構造体のようです。

Set Velocity from Map の Sample Mode を Sample3DLODに設定している場合は attributeMapの型として以下の構造体が使用されるようです。


(パッケージの格納フォルダ)\Shaders\VFXCommon.cginc

...

struct VFXSampler3D
{`
Texture3D t;
SamplerState s;
};
...


参考リンク

HoudiniでVectorField(.fga)を作成する方法(サンプルプロジェクト付き)

https://forty.hatenadiary.jp/entry/2018/11/07/000250

【Unity】UnityへFGAをインポートしてVisual Effect GraphのVectorFieldとして使う方法

https://forty.hatenadiary.jp/entry/2018/11/07/043600

【Unity】PackageManagerが提供するパッケージのダウンロード先と、パッケージを改造する方法

http://tsubakit1.hateblo.jp/entry/2018/08/16/221016