2017-08-02 9 views
0

個々の頂点に異なる継続時間と遅延を使用して、3つの3Dモデルから3つの頂点に3つの頂点をモーフィングしたいと考えています。均一な変数を使用して異なる遷移遅延の頂点を移動する

まず、私は両方のモデルを読み込み、より大きなvert countでモデルを取り込み、頂点の位置をコピーします。

class CustomGeometry extends THREE.BufferGeometry { 
    constructor (refGeo1, refGeo2) { 
     super() 
     let count = refGeo1.attributes.position.count 

     let targets = new Float32Array(count * 3) 
     for (let i = 0; i < count; i += 3) { 
     // if there is no corresponding vertex, simply assign 0 
     targets[i + 0] = refGeo2.attributes.position.array[i + 0] || 0 
     targets[i + 1] = refGeo2.attributes.position.array[i + 1] || 0 
     targets[i + 2] = refGeo2.attributes.position.array[i + 2] || 0 
     } 

     this.addAttribute('position', refGeo1.attributes.position) 
     this.addAttribute('targetPosition', new THREE.BufferAttribute(targets, 3)) 
    } 
} 

その後、私は均一な変数mixFactorを渡し、私の頂点シェーダで行うことができます:その後、私は2番目のモデルを取ると、割り当てることがtargetPosition属性として頂点位置だ

vec3 newPosition = mix(position, targetPosition, mixFactor)

そして、ここではライブですexample

これは、mixFactor変数が変更されたときに頂点が同じタイミング間隔で空間を一様に移動する点を除いては問題ありません。どのようにミックスに遅延と異なるタイミングを追加しますか?

は私がattribute float mixFactorは、CPUにそれらのすべてを均一のinstedしてからトゥイーン行うことができます理解しますが、これは自分のパフォーマンスを殺すのだ...私はtransitionTimingtransitionDelayフロートは、私の頂点に属性を追加する必要が疑われるが、失われています私のシェーダで数学を行う方法...

答えて

1

さらに、頂点ごとに別の属性を追加します。mixAmountOffsetと呼んでください。これをシェーダのmixAmount計算で使用します。あなたは

vec4 position = mix(position1, position2, realMixAmount); 

をミックスして

attribute float mixAmountOffset; 
uniform float mixAmount; 

.... 

    float realMixAmount = clamp(mixAmount + mixAmountOffset, 0., 1.); 

その後、あなたはすべての頂点のための0と1の間を通過するrealMixAmountを必要とより明確にしようとするあなたはJavaScriptのみ

mixAmountを更新する必要がrealMixmountを使用しています。それでは、今mixAmount + mixAmountOffsetニーズが0から1にすべてのポイントを通過させるための数学はmixAmountOffsetの範囲は意味0 -1になりましたあなたが

for (let i = 0; i < vertexCount ++i) { 
    mixAmountOffset[i] = -i/vertexCount; 
} 

頂点

ために-1に0から負の値に mixAmountOffsetを設定しましょうmixAmountが0の場合、 mixAmount + mixAmountOffsetはすべての頂点で0から-1になります。 clampのため、すべての頂点で0〜0になります。 mixAmount1とき

することは、その後mixAmount + mixAmountOffsetは唯一の最初の頂点が第2のモデルの位置を使用している意味1から0に行きます、最後の頂点はまだ最初のモデルの位置を使用しています。

mixAmountを0から2に変更する必要があります。mixAmountが2の場合、mixAmount + mixAmountOffsetはすべての頂点で2から1になり、クランプはすべての頂点で1対1になります。言い換えれば、すべての頂点はmodel2を使用します

mixAmountOffsets何を使用するのか、realMixeAmountを計算する方法はあなた次第です。ポイントはすべての頂点を開始する前に数学を作る必要があります。realMixAmountが0になり、物事が終わったらすべての頂点はrealMixAmountになります。その方法は無限にあります。

あなたのコードを見ると、mixAmountOffsetの頂点インデックスが渡されています。たとえば、別のユニフォームvertexCountscaledMixAmountOffset = mixAmountOffset/vertexCountを渡すことができます。

それとも、あなたはmixAmountOffsetバッファに0から1に正の値を入れてから-1 1

それとも...等へmixAmountをlerp ...あなたがしたい場合があります

他のものでしたやる:あなたはlerpときmixAmountを上が、この場合には、平滑化機能のいくつかの種類を使用することができますもちろん

は、すべての頂点が効果的に別途lerpingされているので、おそらく、シェーダ内のスムージング機能を入れたい

例:

... 

float smooth(float pos) { 
    pos *= 2.; 
    if (pos < 1.) { 
     return 0.5 * pow(2., 10. * (pos - 1.)); 
    } 
    return 0.5 * (-pow(2., -10. * --pos) + 2.); 
    } 

    void main() { 
    float realFactorOffset = clamp(mixFactor + mixFactorOffset, 0.0, 1.0); 
    realFactorOffset = smooth(realFactorOffset); 
    vec3 newPosition = mix(position, targetPosition, realFactorOffset); 


... 

参照:https://codepen.io/greggman/pen/aymqdV

+0

@gmanねえ、あなたの提案に感謝、残念ながら、私はそれを動作させるように見えることはできません。それは最初のモデルの位置がいくつかの奇妙な未定義の空間に終わる間に2番目のモデルをうまく表示することになります。あなたはここでそれをチェックすることができます:https://codepen.io/gbnikolov/pen/JyXKaW –

+0

申し訳ありませんが、私はすべてを綴る必要があることを認識していませんでした。更新された答えを明確にしようとしました – gman

+0

ちょっと@gman、時間をとってくれてありがとう!ちょっとゆっくりと始まる。 –

関連する問題