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