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ほどのボクセルデータが読み込めるようになった。
もっといけるはずだが今のとこ描画が追いつかない・・。