ComputeBufferによるボリュームレンダリング

CPU部分

        _volumeData = new ComputeBuffer(volumeSizeX * volumeSizeY * volumeSizeZ, 4);
        _volumeData.SetData(volumeColors);
        _rayMarchMaterial.SetInt("_VolumeSizeX", volumeSizeX);
        _rayMarchMaterial.SetInt("_VolumeSizeY", volumeSizeY);
        _rayMarchMaterial.SetInt("_VolumeSizeZ", volumeSizeZ);
        _rayMarchMaterial.SetBuffer("_VolumeData", _volumeData);

GPU部分

	#define STEP_CNT 512
	#define STEP_SIZE 1 / STEP_CNT
	half4 raymarch(v2f i, float offset) 
	{
		float3 frontPos = tex2D(_FrontTex, i.uv[1]).xyz;		
		float3 backPos = tex2D(_BackTex, i.uv[1]).xyz;				
		float3 dir = backPos - frontPos;
		float3 pos = frontPos;
		float4 dst = 0;
		float3 stepDist = dir * STEP_SIZE;
		float ws = _WindowCenter - _WindowWidth/2;

//外側ならすべてが1になるみたい。
		if (pos.x >= 1.0f && pos.y >= 1.0f && pos.z >= 1.0f)
		{
			return dst;
		}
		for(int k = 0; k < STEP_CNT; k++)
		{
			int3 size = { _VolumeSizeX ,_VolumeSizeY ,_VolumeSizeZ};
			int3 index = (int3)(pos.xyz*size);
			int id = index.x + (index.y * size.x) + (index.z * (size.x * size.y));
			float src = (_VolumeData[id] + ws) / _WindowWidth;
			float a = saturate(src);

			// clipping
			float border = step(1 - _ClipDims.x, pos.x);
			border *= step(pos.y, _ClipDims.y);
			border *= step(pos.z, _ClipDims.z);
			border *= step(0, dot(_ClipPlane, float4(pos - 0.5, 1)) + _ClipPlane.w);

			// Standard blending	        
			a *= saturate(_Opacity * border);

			src *= a;
			dst.r = (1.0f - dst.a) * src + dst.r;
			dst.a = (1.0f - dst.a) * a + dst.a;
			pos += stepDist;
//一定の不透明度を超えたら演算中断
			if (dst.a >= 0.8) {
				break;
			}
		}
		dst.g = dst.b = dst.r / 2;
//黒い部分にも色を付けたい
		dst.b += 0.1;
		dst.g += 0.1;
		return dst;
	}

前回失敗していたのは
_volumeData = new ComputeBuffer(volumeSizeX * volumeSizeY * volumeSizeZ, 4);
での引数の4部分が小さかったためだった。
実機でTexture3Dの倍の512*512*120ほどのボクセルデータが読み込めるようになった。
もっといけるはずだが今のとこ描画が追いつかない・・。

コメントを残す

メールアドレスが公開されることはありません。