Open6
GLSL Multi TOPのtexelFetchで任意の位置のピクセルの色情報を取得する
作成したProject fileは以下
GLSLでパーティクル位置の計算とレンダリングの二か所からネットワークは作成
GLSLでのパーティクル描画で,主に参考にしたのは noones img 氏のチュートリアル「Particle system with GLSL」
作成したのは以下
やりたかったこと
Noiseのポテンシャル場の影響で加速するパーティクルを描画したかった.普通の言語だったら配列として持っているNoiseの値を線形補間か何かして計算するのだろうが,GLSLで配列の概念を使用することってあまり記憶していない.これまで見てきたチュートリアルはPositionもNoise同じ座標(vUV.xyなど)を参照していたので,その点について少し調べた.
GLSL Multi TOPで記述している主なコードはこれ.ほとんど上のチュートリアルと同一だが,Noiseの値を取得する箇所で少し改変している.
layout (local_size_x = 8, local_size_y = 8) in;
void main()
{
float step = 1.0/60.0;
vec4 pos_ini = texelFetch(sTD2DInputs[0], ivec2(gl_GlobalInvocationID.xy), 0);
vec4 pos = texelFetch(sTD2DInputs[1], ivec2(gl_GlobalInvocationID.xy), 0);
vec4 vel = texelFetch(sTD2DInputs[2], ivec2(gl_GlobalInvocationID.xy), 0);
float life = pos.a;
float x_width = 0.5;
float y_width = 0.5;
float z_width = 0.5;
float ix_width = uTD2DInfos[0].res.z;
float iy_width = uTD2DInfos[0].res.w;
// index should be between 0 and resolution value
int ix = int((pos.x/x_width + 1.0)/2.0*ix_width);
int iy = int((pos.y/y_width + 1.0)/2.0*iy_width);
vec4 acc = texelFetch(sTD2DInputs[3], ivec2(ix, iy), 0);
vel = acc;
// vel += acc*step;
pos += vel*step;
life -= step;
if (pos.x < -x_width || pos.x > x_width || pos.y < -y_width || pos.y > y_width || pos.z < -z_width || pos.z > z_width || life < 0.0) {
vel = vec4(0.0);
pos = pos_ini;
life = pos_ini.a;
}
imageStore(mTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.xy), TDOutputSwizzle(vec4(pos.xyz, life)));
imageStore(mTDComputeOutputs[1], ivec2(gl_GlobalInvocationID.xy), TDOutputSwizzle(vel));
}
主な変更点はここで,texelFetchの第2引数をgl_GlobalInvocationID.xy
から,直前で計算したixとiyに変更している.
vec4 acc = texelFetch(sTD2DInputs[3], ivec2(ix, iy), 0);
texelFetchの第2引数はint型でピクセルの値を指定すると,その座標の色情報を読み込んでくれる.これを用いるために,パーティクルの位置情報posからピクセル座標を計算しているのが以下
int ix = int((pos.x/x_width + 1.0)/2.0*ix_width);
int iy = int((pos.y/y_width + 1.0)/2.0*iy_width);
パーティクルの位置情報posは-1から1までの値をとるのでそれを0から1に変更した後に,xとyの分解能の値ix_widthとiy_widthをかけてピクセル値にスケールしている.xとyの分解能の値はuTD2DInfos
という組み込みの構造体を用いて取得することができる