/** * Return a volume texture containing a representation of this distance field. */ public Texture3D GetVolumeTexture(int size) { if (!Initialized) { return(null); } // upper bound of the distance from any point inside the bounds to the surface. float maxDist = Mathf.Max(bounds.size.x, bounds.size.y, bounds.size.z); float spacingX = bounds.size.x / (float)size; float spacingY = bounds.size.y / (float)size; float spacingZ = bounds.size.z / (float)size; Texture3D tex = new Texture3D(size, size, size, TextureFormat.Alpha8, false); var cols = new Color[size * size * size]; int idx = 0; Color c = Color.black; for (int z = 0; z < size; ++z) { for (int y = 0; y < size; ++y) { for (int x = 0; x < size; ++x, ++idx) { Vector3 samplePoint = bounds.min + new Vector3(spacingX * x + spacingX * 0.5f, spacingY * y + spacingY * 0.5f, spacingZ * z + spacingZ * 0.5f); float distance = ASDF.Sample(nodes, samplePoint); if (distance >= 0) { c.a = distance.Remap(0, maxDist * 0.1f, 0.5f, 1); } else { c.a = distance.Remap(-maxDist * 0.1f, 0, 0, 0.5f); } cols[idx] = c; } } } tex.SetPixels(cols); tex.Apply(); return(tex); }
private void RefreshCutawayTexture(ObiDistanceField field) { if (field == null) { return; } Bounds b = field.FieldBounds; sampleSize = field.EffectiveSampleSize; sampleCount = (int)(b.size[0] / sampleSize) + 1; CreatePlaneMesh(field); ResizeTexture(); float sweep = (sampleCount * slice) * sampleSize; Vector3 origin = b.center - b.extents; for (int x = 0; x < sampleCount; ++x) { for (int y = 0; y < sampleCount; ++y) { Vector3 offset = Vector3.zero; switch (axis) { case Axis.X: offset = new Vector3(sweep, y * sampleSize, x * sampleSize); break; case Axis.Y: offset = new Vector3(x * sampleSize, sweep, y * sampleSize); break; case Axis.Z: offset = new Vector3(x * sampleSize, y * sampleSize, sweep); break; } float distance = ASDF.Sample(field.nodes, origin + offset); float value = ObiUtils.Remap(distance, -maxDistance, maxDistance, 0, 1); cutawayTexture.SetPixel(x, y, new Color(value, 0, 0)); } } cutawayTexture.Apply(); }