public class LaplacianSmoothing3D : MonoBehaviour
struct LaplacianSmoothingJob : IJobParallelFor
public NativeArray<float> Input;
public NativeArray<float> Output;
public void Execute(int index)
int z = index / (Width * Height);
int y = (index / Width) % Height;
for (int dz = -1; dz <= 1; dz++)
for (int dy = -1; dy <= 1; dy++)
for (int dx = -1; dx <= 1; dx++)
if (dx == 0 && dy == 0 && dz == 0)
if (nx >= 0 && nx < Width && ny >= 0 && ny < Height && nz >= 0 && nz < Depth)
int neighborIndex = nx + Width * (ny + Height * nz);
sum += Input[neighborIndex];
float laplacian = sum / count;
Output[index] = laplacian;
int totalVoxels = width * height * depth;
// Generate a sample texture3D with random values
Texture3D texture = new Texture3D(width, height, depth, TextureFormat.RFloat, false);
Color[] pixels = new Color[totalVoxels];
for (int i = 0; i < totalVoxels; i++)
pixels[i] = new Color(Random.value, 0, 0, 0);
texture.SetPixels(pixels);
// Convert texture data to a NativeArray
NativeArray<float> input = new NativeArray<float>(totalVoxels, Allocator.TempJob);
NativeArray<float> output = new NativeArray<float>(totalVoxels, Allocator.TempJob);
for (int z = 0; z < depth; z++)
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
int index = x + width * (y + height * z);
input[index] = texture.GetPixel(x, y, z).r;
// Schedule the Laplacian Smoothing job
LaplacianSmoothingJob job = new LaplacianSmoothingJob
JobHandle handle = job.Schedule(totalVoxels, 64);
// Retrieve the smoothed data
for (int z = 0; z < depth; z++)
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
int index = x + width * (y + height * z);
Color color = new Color(output[index], 0, 0, 0);
texture.SetPixel(x, y, z, color);