private void Update(EvaluationContext context) { var image = InputImage.GetValue(context); var imageSrv = InputImageSrv.GetValue(context); if (image == null) { Log.Debug("input not completet"); return; } var d3DDevice = ResourceManager.Instance().Device; var immediateContext = d3DDevice.ImmediateContext; if (_imageWithCPUAccess == null || _imageWithCPUAccess.Description.Format != image.Description.Format || _imageWithCPUAccess.Description.Width != image.Description.Width || _imageWithCPUAccess.Description.Height != image.Description.Height || _imageWithCPUAccess.Description.MipLevels != image.Description.MipLevels) { var desc = new Texture2DDescription() { BindFlags = BindFlags.None, Format = image.Description.Format, Width = image.Description.Width, Height = image.Description.Height, MipLevels = image.Description.MipLevels, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Staging, OptionFlags = ResourceOptionFlags.None, CpuAccessFlags = CpuAccessFlags.Read, ArraySize = 1 }; Utilities.Dispose(ref _imageWithCPUAccess); _imageWithCPUAccess = new Texture2D(d3DDevice, desc); } if (_distanceFieldImage == null || _distanceFieldImage.Description.Format != image.Description.Format || _distanceFieldImage.Description.Width != image.Description.Width || _distanceFieldImage.Description.Height != image.Description.Height || _distanceFieldImage.Description.MipLevels != image.Description.MipLevels) { var desc = new Texture2DDescription() { BindFlags = BindFlags.ShaderResource, Format = image.Description.Format, Width = image.Description.Width, Height = image.Description.Height, MipLevels = 1, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Dynamic, OptionFlags = ResourceOptionFlags.None, CpuAccessFlags = CpuAccessFlags.Write, ArraySize = 1 }; Utilities.Dispose(ref _distanceFieldImage); _distanceFieldImage = new Texture2D(d3DDevice, desc); } // if (Changed) { immediateContext.CopyResource(image, _imageWithCPUAccess); int width = image.Description.Width; int height = image.Description.Height; if (_data == null || _data.Length != width * height) { _data = new float[width * height]; _xDist = new short[width * height]; _yDist = new short[width * height]; _gradients = new SharpDX.Vector2[width * height]; } DataStream sourceStream; var sourceDataBox = immediateContext.MapSubresource(_imageWithCPUAccess, 0, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out sourceStream); // Convert img into float (data) using (sourceStream) { sourceStream.Position = 0; float minValue = 255, maxValue = -255; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { var color = new Color4(sourceStream.Read <Int32>()); float v = color.Red; _data[y * width + x] = v; if (v > maxValue) { maxValue = v; } if (v < minValue) { minValue = v; } } sourceStream.Position += sourceDataBox.RowPitch - width * 4; } // Rescale image levels between 0 and 1 for (int i = 0; i < width * height; ++i) { _data[i] = (_data[i] - minValue) / maxValue; } // transform background (black pixels) ComputeGradient(_data, width, height); var outside = Edtaa3(_data, height, width); // transform forground (white pixels) for (int i = 0; i < width * height; ++i) { _data[i] = 1 - _data[i]; // invert input } ComputeGradient(_data, width, height); var inside = Edtaa3(_data, height, width); // write resulting distance field to target texture DataStream destinationStream; var destinationDataBox = immediateContext.MapSubresource(_distanceFieldImage, 0, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out destinationStream); using (destinationStream) { sourceStream.Position = 0; destinationStream.Position = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int i = y * width + x; // distmap = outside - inside; % Bipolar distance field var color = new Color4(sourceStream.Read <Int32>()); outside[i] = MathUtils.Clamp(128.0f + (outside[i] - inside[i]) * 16.0f, 0.0f, 255.0f); //color.Alpha = (255 - (byte) outside[i])/255.0f; float f = (255 - (byte)outside[i]) / 255.0f; color.Red = f; color.Blue = f; color.Green = f; float alpha = 1 - _data[i]; { // do alpha dilatation const int range = 1; int xs = Math.Max(x - range, 0); int xe = Math.Min(x + range, width - 1); int ys = Math.Max(y - range, 0); int ye = Math.Min(y + range, height - 1); for (int yy = ys; yy <= ye; yy++) { for (int xx = xs; xx <= xe; xx++) { alpha = Math.Max(alpha, 1 - _data[yy * width + xx]); } } } color.Alpha = alpha;// * 0.8f; // > 0.0f ? 0.5f : 0; destinationStream.Write(color.ToRgba()); } destinationStream.Position += destinationDataBox.RowPitch - width * 4; } immediateContext.UnmapSubresource(_distanceFieldImage, 0); } immediateContext.UnmapSubresource(_imageWithCPUAccess, 0); } // Changed = false; } Output.Value = _distanceFieldImage; }