すあまの備忘録

誰得内容の自分のための非営利目的備忘録ブログ(筆者がわかっても内緒にしてください)

POP Grain メモ

f:id:godofsuama:20210205224721g:plain

今更すぎる機能だけど、忘れないうちに。

VellumでもGrainを扱えるが、大量に数を出したときはまだPOP Grainのほうが軽い印象。

コンストレインを使用する場合はどっちが速いかなんとも言えない感じ。

数を出す必要があるならまだまだPOP Grainsは現役っぽい。

注意メモ

  • Substepが低いと爆発しやすいので、POP Solverのmin/max Substepを10くらいまで上げてから様子を見て下げるほうが安定する。

  • POP GrainsのUse OpenCLは必要なPoint Attributesに応じてオフにする。

  • コンストレインがあり、切る場合、POP GrainsのCollide Mutually Constrained Particlesをオンにすると安定する。(コンストレイン解除時のパーティクル間のフォースを無効にする)

  • Particleが重なるほどPOP GrainsのConstraint Iterationsを上げる必要がある。

  • Grainをエミットする場合、POP SourceのOverlappingにチェックを入れると爆発しない。(pscaleの範囲内で重なったPointを削除する)

  • エミットする場合、Jitter Birth Timeをオフにしたほうがいい。Overlappingと似た理由。

  • vなし、塊でエミットする場合、POP SourceのImpulse Activationにif($F==$FF,1,0)をいれると爆発しない。(Substepを上げた際にずれてエミットしているパーティクルで爆発する)

  • エミットしない場合は、POP SourceのImpulse Activationを$SF==1にする。Grain UpdateのActivationを$ST > 0にする。

  • コンストレインを使うならVellumのが早い

Atrributes

一部OpenCLだとPoint Attributesが効かない。その場合はパラメーターでの一律指定になる。

POP Grains作成時はデフォルトはOpenCLがオンなので注意。

全体
パラメーター アトリビュート 説明 OpenCL
Particle Separation @pscale 粒の大きさ。コリジョン判定にも使う。 o
Friction(摩擦)
パラメーター アトリビュート 説明 OpenCL
With Colliders @friction コリジョンの摩擦係数 o
With Particles @friction パーティクル間での摩擦係数 o
Internal Collisions(パーティクル間の衝突)
パラメーター アトリビュート 説明 OpenCL
Weight @repulsionweight パーティクル間の衝突フォースの係数 x
Stiffness @repulsionstiffness パーティクル間の引き離す強さ x
Enable Mass-Shock Scaling @shockmass 重力逆方向へのパーティクルの質量のスケーリング o
Clamping (パーティクル間の凝集)
パラメーター アトリビュート 説明 OpenCL
Weight @attractionweight パーティクル間で凝縮の強さ係数 o
Stiffness @attractionstiffness パーティクル間で凝縮の強さ x
Explicit Constraints(パーティクル間のコンストレイン
パラメーター アトリビュート 説明 OpenCL
Weight @constraintweight コンストレインの強さ係数 x
Stiffness @constraintstiffness コンストレインの硬さ x

Primitive Attributesの@restlengthで初期のポイント間の距離を、@strengthで接続の強さを設定する。

Targets (Pins)
パラメーター アトリビュート 説明 OpenCL
Weight @targetweight targetPに拘束される強さ係数 o
Stiffness @targetstiffness targetPに拘束のの硬さ o

pscaleはすべて同じにすると、Assume Uniform Radiusで処理を高速化できる。

Enable Mass-Shock Scalingは、上方に行くほどパーティクルを軽くすることにより、パーティクルの重なりの収束が速くなり、より安定する。

Dry/Wet Sand

ShelfにあるDryとWetの違いはPOP GrainsのClamping(凝集)の差。

さらさらした砂ではClampingを0(もしくはかなり低く)することでパーティクル間が集まらなくなる。

f:id:godofsuama:20210205183010g:plain
Dry

Clampingを1にすると以下のように塊が生まれる。凝縮具合はStiffnessで設定。

f:id:godofsuama:20210205183623g:plain
Wet

Explicit Constraints

コンストレインを使用すると割と重くなる。

RBDなどと同じようにポイント間を接続するライン(Primitive)を作成しする。@restlength(接続感の初期長さ)、@strength(接続の強さ)がある。

Break Thresholdで、Constraintsを切るしきい値を調整する。

強めのコンストレインで、もちっとしたスライムのようになる。

Clusterなどを併用して塊具合の調整も可能。

f:id:godofsuama:20210205185135g:plain
Constraints -Break Threshold 0.05

f:id:godofsuama:20210205185913g:plain
Constraints -Break Threshold 0.02

f:id:godofsuama:20210205194608g:plain
Constraints with Cluster

コンストレイン(Grain Source)

Grain Sourceを使用する場合は、Explicit Constraintsの部分で作成する。

f:id:godofsuama:20210205184238p:plain

コンストレイン(塊でエミットする場合)

塊ごとにGrainをエミットする場合、DOP内でPoint番号が変わってしまうためSOP上では難しい。エミットし続ける場合はコンストレイン無理そう。

SOP Solverを使用してDOP内でConstraintを作成する。

動作はしてるんだけど…良いのかこれ?

f:id:godofsuama:20210205224752p:plain

f:id:godofsuama:20210205224822p:plain

@age==0でグループを作成

f:id:godofsuama:20210205224837p:plain

グループに対して以下の処理でラインを作成(この処理自体はConnect Adjacent Pieces内の同名ノードの改変)

f:id:godofsuama:20210205224913p:plain

float searchradius = ch("searchradius");
int haspscale = haspointattrib(0, 'pscale');

int points[];
float @pscale = 1.0;

points = pcfind(0, "P", @P, 2*searchradius*@pscale, chi("maxpt"));


foreach(int ptj; points)
{
    if(@ptnum == ptj)
        continue;
        
    // Only connect one direction
    if (ptj < @ptnum)
        continue;
        
    int prim = addprim(geoself(), "polyline");
    
    addvertex(geoself(), prim, @ptnum);
    addvertex(geoself(), prim, ptj);
}

Primitive Wrangleでrestlengthの有無をチェックし、グループへ

int chk = primattrib(0, "restlength", @primnum, chk);

if(chk == 0) {
    i@group_firstPrim = 1;
}else{
    i@group_firstPrim = 0;
}

@restlengthがないprimitiveだけMeasureでrestlengthを作成

f:id:godofsuama:20210205225044p:plain

最初に作ったグループに対してPoint VOPでClusterとClusterFrameを作成

f:id:godofsuama:20210205225138p:plain

Primitive WrangleでClusterFrameが異なるもの間のラインを削除

int pts[] = primpoints(0, @primnum);
int cf1 = point(0, "clusterFrame", pts[0]);
int cf2 = point(0, "clusterFrame", pts[1]);

if(cf1 != cf2) {
    removeprim(0,@primnum,1);
}

最後に@restlengthを作成したPrimitiveに対し、@strengthを作成し、Clusterが異なる部分の強度を変更。

f:id:godofsuama:20210205225307p:plain

f@strength = 1;

int pts[] = primpoints(0, @primnum);
int c1 = point(0, "cluster", pts[0]);
int c2 = point(0, "cluster", pts[1]);

if(c1 != c2) {
    f@strength = 0.1;
}

画像のようにラインも書き出されるので、シムしたあとはaddなどでPointのみにすること。

f:id:godofsuama:20210205225901p:plain

upres(Replicateで増やす)

Shelfのupresを実行するのと同じ。

f:id:godofsuama:20210205230224p:plain

Point Replicateで増やす数と増やす際の形状を設定、Copy Source Attributesも忘れずに。

pscaleを増やし多分最適化

f:id:godofsuama:20210205230447p:plain
upres前
f:id:godofsuama:20210205230319p:plain

f:id:godofsuama:20210205230522p:plain
upres後

コリジョン

RBD Packed Objectとコリジョンすることができる。

Convex DecompositionとAssembleで作成し、

f:id:godofsuama:20210205230816p:plain

普通にMergeする。

f:id:godofsuama:20210205230842p:plain

こんな感じ。

f:id:godofsuama:20210205230923p:plain

おまけ

もちろんRBDのシムとも同時にできる。

実践で使う場合は重いのと修正がしづらいので分けたほうが無難。

f:id:godofsuama:20210205231803p:plain