のぐそんブログ

暗いおじさんがシコシコ書くブログです。

Cache TOPを利用して版ずれのような演出をする

Cache TOPを利用して、印刷の版ずれのような表現をしてみたいと思います。

版ずれさせる3Dオブジェクトを準備

まずは演出の対象となる、3Dのオブジェクトと、カメラ、ライト、ジオメトリを用意します。

noise SOPを挟んでいるのは、Geometoryに動きを出すためです。

Cache TOPを用意する

Cache TOPを用意します。 Cache TOPは、過去のフレーム情報を保持することができるオペレーターです。 ここでは、Cache Size32に設定されている為、過去の32フレームが保持されています。

Cache Select TOPでキャッシュした情報を取り出す

キャッシュした情報をとりだすには、Cache Select TOPを使います。 Cache Select TOPCache Indexに設定した値のフレーム情報を取得できます。

Reorder TOPでRGBそれぞれの値を設定する

Reorder TOPを利用すると、RGBAの値をそれぞれ設定することができます。 Cache Select TOPで取り出したフレーム情報をRGBそれぞれに設定していきます。

Cache Indexをずらしたことで、版ずれのような表現になります。

Feedback TOPなどと組み合わせると、こんな感じになったりします。

6月-26-2018 00-21-11.gif

サンプルファイル

3Dオブジェクトの頂点情報を取得

3Dオブジェクトの頂点座標をデータとして取得する際は、「SOP to CHOP」を利用しました。 だだし、取得できるのはX,Y,Zの座標データのみでした。

ちなみにここでは、Sphere SOP」を利用してます。

続きを読む

3Dオブジェクトの頂点情報をデータとして利用する

TouchDesignerで3Dオブジェクトから頂点座標を抜き出す

3Dオブジェクトから頂点座標を抜き出して、データとして利用する方法のメモです。

①SOPから、好きな3Dオブジェクトを配置。
②オペレーターの右下にある「 + 」ボタンを押す。

③右クリックでコンテキストメニューから「Display Options」を選択

トラックパッドの場合は2点タッチ

④メニューからAllを選択

⑤SOP toオペレーターをつかって頂点座標を数値化する

頂点座標に3Dオブジェクトを配置する

3Dオブジェクトを利用するためには、「Camera COMP」、Light COMP」、「Geometry COMP」が必要です。

インスタンスを利用する

①Geometoryでインスタンスを利用できるようにする

Geometryを選択して、「instancce」タブを選択して「Instancing」をONにします。 ONにすることで、「Instance CHOP/DAT」を選択できるようになります。

②頂点データをインスンタンスに設定する

インスタンスの座標を割り当てる

②で設定した頂点データをどの座標として使うかを設定する。

④頂点に設定されているgeometoryの大きさを調整

Box SOPをSIZE「0.01,0.01,0.01」で設定する。

その他

頂点データの詳しい内容は、DATAのSOP toオペレーターで確認することができる。

f:id:nogson2:20180410233926p:plain

まとめ

最終的にはこんな感じになります。 基礎的な部分ですがよく使う方法らしいので、覚えておくようにしたいと思います。

GPGPUがまったくわからないのでGPUComputationRenderer.jsをまず調べてみるメモ

GPGPU用のヘルパーライブラリであるGPUComputationRenderer.jsの使い方を調べてみました。

GPGPUが難しいので上手く説明できておらず、よくわからない文章になってしまっています。 あまり参考にならないかもしれません。

こちらの「Three.jsのGPGPUのサンプルが難しすぎるから解体して勉強してみる」のがとてもわかりやすので参考になります。

やること事

なんとなくのイメージこんな感じです。 GPGPUなのでテクスチャをデータ格納用に利用します。 テクスチャは、参照用と、データ格納用を作成して毎レーム入れ替えていきます。 ※複数のフレームバッファを使う場合です。1つだけの場合は「オフスクリーンレンダリング2」はいりません。

STEP 1

GPUComputationRendererのインスタンスを作成する。

引数のwidth, height, rendererはオフスクリーンレンダリング用のWebGLRenderTargetや、DataTextureを作成する際に利用される。

var gpuRender = new GPUComputationRenderer(width, height, renderer);

GPUComputationRendererのインスタンスを作成すると、はじめに下記のようなオブジェクトが作成される。

var material = new THREE.ShaderMaterial( {
  uniforms:{
    texture: { value: null }
  },
  vertexShader: vs,//中身は↓に記載
  fragmentShader: fs//中身は↓に記載
} );

var geometory =  new THREE.PlaneBufferGeometry( 2, 2 );

var mesh = new THREE.Mesh(geometory, material );
◎vs
void main()  {
    gl_Position = vec4( position, 1.0 );
}

◎fs

uniform sampler2D texture;

void main() {
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    gl_FragColor = texture2D( texture, uv );
}

STEP 2

テクスチャを作成する。

var textuer = gpuCompute.createTexture();

GPUComputationRenderer内で以下の処理が実行されテクスチャデータが作成される。

var arr = new Float32Array( width * height * 4 );
var texture = new THREE.DataTexture( arr, width, height, THREE.RGBAFormat, THREE.FloatType );
texture.needsUpdate = true;

STEP 3

matrialやtextuerなどのデータを格納しておくオブジェクトを作成する。

第二引数はフラグメントシェーダを指定します。 第三引数にはテクスチャを指定します。

var velVar = gpuCompute.addVariable( "textureVelocity", fragmentShaderVel, textuer );

GPUComputationRenderer内で以下の処理が実行され、設定した内容が保持される。

var material = new THREE.ShaderMaterial( {
  uniforms:{},
  vertexShader: vs,//中身は↓に記載
  fragmentShader: fragmentShaderVel
} );


var variable = {
  name: "textureVelocity",
  initialValueTexture: textuer,
  material: material,
  dependencies: null,
  renderTargets: [],
  wrapS: null,
  wrapT: null,
  minFilter: THREE.NearestFilter,
  magFilter: THREE.NearestFilter
};

//作成したデータをインスタンス内に保持する
this.variables.push( variable );
◎vs
void main()  {
    gl_Position = vec4( position, 1.0 );
}

STEP 4

velVar、posVarに設定されたフラグメントシェーダーそれぞれからSTEP 2で作成したテクスチャが参照できるようする為の前準備。 シェーダー間でテクスチャを参照できるようになる。

下記の場合は、velVarのフラグメントシェーダから、velVar、posVarのテクスチャを参照することができる。

gpuCompute.setVariableDependencies( velVar, [ velVar, posVar] );

velVarのフラグメントシェーダから、velVarのテクスチャの参照だけで良い場合は、下記のような定義になる。

gpuCompute.setVariableDependencies( velVar, [ velVar] );

STEP 5

オフスクリーンレンダリング用のWebGLRenderTargetを作成する。

「STEP 3」で空だったrenderTargetsの配列にWebGLRenderTargetのインスタンスを追加します。

gpuCompute.init()

GPUComputationRenderer内では、同じWebGLRenderTargetが2つ作成される。

variable.renderTargets[ 0 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );
variable.renderTargets[ 1 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );

また設定しているフラグメントシェーダーの頭に、テクスチャの読みこみ用の定義が追加される。

自分で用意したフラグメントシェーダーにuniform sampler2Dの定義がないのに、何故テクスチャが参照できるのだろうと疑問におもっていたがここでライブラリが自動で挿入してくれていた。

uniform sampler2D textureVelocity;
uniform sampler2D texturePosition;

//↓↓fragmentShaderVelに定義した処理がはいる↓↓

material(shaderMaterial)にも、uniformの定義が追加される。 この段階ではまだ、テクスチャの値はnull。

uniforms.textureVelocity = { value: null };

STEP 6

最後に毎フレーム毎に下記を実行して、参照用と格納用のテクスチャを切り替えていく。

gpuCompute.compute();

GPUComputationRenderer内では、STEP 5ではまだnullだったテクスチャデータに、 WebGLRenderTargetが挿入される。

サンプル

実際にサンプルを作りました。 このサンプルはオフスクリーンレンダリングは1つだけです。 内部的にはGPUComputationRendererがテクスチャを複製してくれるので2つです。

GPGPU SAMPLE

まとめ

GPUComputationRendererはGPGPUの面倒なところを代わりにやってくれるので、私のような初学者には大変助かるライブラリです。 だたし、中でなにをやっているかを正しく理解しないと、GPGPUとはなんなのかがわからなくなりそうです。