Open6

GLSL Multi TOPのtexelFetchで任意の位置のピクセルの色情報を取得する

syoukerasyoukera

やりたかったこと

Noiseのポテンシャル場の影響で加速するパーティクルを描画したかった.普通の言語だったら配列として持っているNoiseの値を線形補間か何かして計算するのだろうが,GLSLで配列の概念を使用することってあまり記憶していない.これまで見てきたチュートリアルはPositionもNoise同じ座標(vUV.xyなど)を参照していたので,その点について少し調べた.

syoukerasyoukera

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));
}
syoukerasyoukera

主な変更点はここで,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という組み込みの構造体を用いて取得することができる