protected override void Dispose(bool disposing) { Utilities.Dispose(ref _prefilteredCubeMap); Utilities.Dispose(ref _cubeMapRtv); Utilities.Dispose(ref _rasterizerState); base.Dispose(disposing); }
private void Update(EvaluationContext context) { if (!Gradients.IsConnected) { return; } var gradientsCount = Gradients.CollectedInputs.Count; if (gradientsCount == 0) { return; } const int sampleCount = 256; const int entrySizeInBytes = sizeof(float) * 4; const int gradientSizeInBytes = sampleCount * entrySizeInBytes; int bufferSizeInBytes = gradientsCount * gradientSizeInBytes; using (var dataStream = new DataStream(bufferSizeInBytes, true, true)) { var texDesc = new Texture2DDescription() { Width = sampleCount, Height = gradientsCount, ArraySize = 1, BindFlags = BindFlags.ShaderResource, Usage = ResourceUsage.Default, MipLevels = 1, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R32G32B32A32_Float, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; foreach (var gradientsInput in Gradients.CollectedInputs) { var gradient = gradientsInput.GetValue(context); if (gradient == null) { dataStream.Seek(gradientSizeInBytes, SeekOrigin.Current); continue; } for (var sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { var sampledColor = gradient.Sample((float)sampleIndex / sampleCount); dataStream.Write(sampledColor.X); dataStream.Write(sampledColor.Y); dataStream.Write(sampledColor.Z); dataStream.Write(sampledColor.W); } } //Curves.DirtyFlag.Clear(); dataStream.Position = 0; var dataRectangles = new DataRectangle[] { new DataRectangle(dataStream.DataPointer, gradientSizeInBytes) }; Utilities.Dispose(ref GradientsTexture.Value); GradientsTexture.Value = new Texture2D(ResourceManager.Instance().Device, texDesc, dataRectangles); } }
private void Update(EvaluationContext context) { // Parameters var parameterBufferContent = new PbrMaterialParams { BaseColor = BaseColor.GetValue(context), EmissiveColor = EmissiveColor.GetValue(context), Roughness = Roughness.GetValue(context), Specular = Specular.GetValue(context), Metal = Metal.GetValue(context) }; ResourceManager.Instance().SetupConstBuffer(parameterBufferContent, ref _parameterBuffer); // Textures var resourceManager = ResourceManager.Instance(); var device = resourceManager.Device; Utilities.Dispose(ref _baseColorMapSrv); var tex = BaseColorMap.GetValue(context) ?? PbrContextSettings.WhitePixelTexture; _baseColorMapSrv = new ShaderResourceView(device, tex); context.PbrMaterialTextures.AlbedoColorMap = _baseColorMapSrv; Utilities.Dispose(ref _normalMapSrv); var tex2 = NormalMap.GetValue(context) ?? PbrContextSettings.NormalFallbackTexture; _normalMapSrv = new ShaderResourceView(device, tex2); context.PbrMaterialTextures.NormalMap = _normalMapSrv; Utilities.Dispose(ref _rsmoMapSrv); var tex3 = RoughnessSpecularMetallicOcclusionMap.GetValue(context) ?? PbrContextSettings.RsmoFallbackTexture; _rsmoMapSrv = new ShaderResourceView(device, tex3); context.PbrMaterialTextures.RoughnessSpecularMetallicOcclusionMap = _rsmoMapSrv; Utilities.Dispose(ref _emissiveColorMapSrv); var tex4 = EmissiveColorMap.GetValue(context) ?? PbrContextSettings.WhitePixelTexture; _emissiveColorMapSrv = new ShaderResourceView(device, tex4); context.PbrMaterialTextures.EmissiveColorMap = _emissiveColorMapSrv; var previousParameters = context.PbrMaterialParams; context.PbrMaterialParams = _parameterBuffer; SubTree.GetValue(context); context.PbrMaterialParams = previousParameters; }
private void Update(EvaluationContext context) { var filePath = Filepath.GetValue(context); var filterCharacters = FilterCharacters.GetValue(context); var brightnessTable = SortAsciiLetters(filePath, filterCharacters); if (brightnessTable == null) { return; } //Log.Debug("Generating texture"); var sampleCount = brightnessTable.Length; const int entrySizeInBytes = sizeof(float); var listSizeInBytes = sampleCount * entrySizeInBytes; var bufferSizeInBytes = 1 * listSizeInBytes; using (var dataStream = new DataStream(bufferSizeInBytes, true, true)) { var texDesc = new Texture2DDescription() { Width = sampleCount, Height = 1, ArraySize = 1, BindFlags = BindFlags.ShaderResource, Usage = ResourceUsage.Default, MipLevels = 1, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R32_Float, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; var filterOutFactor = (256f - filterCharCount) / 256; for (var sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { var index = (int)(sampleIndex * filterOutFactor).Clamp(0, sampleCount); dataStream.Write((float)brightnessTable[index].Index / 256f); } dataStream.Position = 0; var dataRectangles = new DataRectangle[] { new DataRectangle(dataStream.DataPointer, listSizeInBytes) }; Utilities.Dispose(ref MappingTexture.Value); MappingTexture.Value = new Texture2D(ResourceManager.Instance().Device, texDesc, dataRectangles); } }
private void Update(EvaluationContext context) { var param = Params.GetCollectedTypedInputs(); int arraySize = (param.Count / 4 + (param.Count % 4 == 0 ? 0 : 1)) * 4; // always 16byte slices for alignment var array = new float[arraySize]; if (array.Length == 0) { return; } for (int i = 0; i < param.Count; i++) { array[i] = param[i].GetValue(context); } Params.DirtyFlag.Clear(); var resourceManager = ResourceManager.Instance(); var device = resourceManager.Device; var size = sizeof(float) * array.Length; using (var data = new DataStream(size, true, true)) { data.WriteRange(array); data.Position = 0; if (Buffer.Value == null || Buffer.Value.Description.SizeInBytes != size) { Utilities.Dispose(ref Buffer.Value); var bufferDesc = new BufferDescription { Usage = ResourceUsage.Default, SizeInBytes = size, BindFlags = BindFlags.ConstantBuffer }; Buffer.Value = new Buffer(device, data, bufferDesc); } else { device.ImmediateContext.UpdateSubresource(new DataBox(data.DataPointer, 0, 0), Buffer.Value, 0); } } Buffer.Value.DebugName = nameof(FloatsToBuffer); }
private void Restore(EvaluationContext context) { var deviceContext = ResourceManager.Instance().Device.ImmediateContext; deviceContext.Rasterizer.SetViewports(_prevViewports, _prevViewports.Length); deviceContext.OutputMerger.BlendState = _prevBlendState; // Vertex shader var vsStage = deviceContext.VertexShader; vsStage.Set(_prevVertexShader); vsStage.SetConstantBuffers(0, _prevVsConstantBuffers.Length, _prevVsConstantBuffers); vsStage.SetShaderResources(0, _prevVsShaderResourceViews.Length, _prevVsShaderResourceViews); Utilities.Dispose(ref _prevVertexShader); // Vertex shader var gsStage = deviceContext.GeometryShader; gsStage.Set(_prevGeometryShader); gsStage.SetConstantBuffers(0, _prevGsConstantBuffers.Length, _prevGsConstantBuffers); gsStage.SetShaderResources(0, _prevGsShaderResourceViews.Length, _prevGsShaderResourceViews); Utilities.Dispose(ref _prevGeometryShader); // Pixel shader var psStage = deviceContext.PixelShader; psStage.Set(_prevPixelShader); psStage.SetConstantBuffers(0, _prevPsConstantBuffers.Length, _prevPsConstantBuffers); psStage.SetShaderResources(0, _prevPsShaderResourceViews.Length, _prevPsShaderResourceViews); psStage.SetSamplers(0, _prevPsSamplerStates.Length, _prevPsSamplerStates); Utilities.Dispose(ref _prevPixelShader); //deviceContext.OutputMerger.SetTargets(_previousRtv, null); if (_prevRenderTargetViews.Length > 0) { deviceContext.OutputMerger.SetRenderTargets(_prevDepthStencilView, _prevRenderTargetViews); } foreach (var rtv in _prevRenderTargetViews) { rtv?.Dispose(); } Utilities.Dispose(ref _prevDepthStencilView); }
private float EdgeDf(SharpDX.Vector2 g, float a) { float df; if ((g.X == 0) || (g.Y == 0)) { // Either A) gu or gv are zero, or B) both df = 0.5f - a; // Linear approximation is A) correct or B) a fair guess } else { float gradientLength = (float)Math.Sqrt(g.X * g.X + g.Y * g.Y); if (gradientLength > 0.0) { g.X = g.X / gradientLength; g.Y = g.Y / gradientLength; } g.X = Math.Abs(g.X); g.Y = Math.Abs(g.Y); if (g.X < g.Y) { Utilities.Swap(ref g.X, ref g.Y); } float a1 = 0.5f * g.Y / g.X; if (a < a1) { // 0 <= a < a1 df = 0.5f * (g.X + g.Y) - (float)Math.Sqrt(2.0f * g.X * g.Y * a); } else if (a < (1.0 - a1)) { // a1 <= a <= 1-a1 df = (0.5f - a) * g.X; } else { // 1-a1 < a <= 1 df = -0.5f * (g.X + g.Y) + (float)Math.Sqrt(2.0f * g.X * g.Y * (1.0f - a)); } } return(df); }
protected override void Dispose(bool disposing) { Utilities.Dispose(ref _queryTimeStampDisjoint); Utilities.Dispose(ref _queryTimeStampFrameBegin); Utilities.Dispose(ref _queryTimeStampFrameEnd); }
private void Update(EvaluationContext context) { var updateLive = UpdateLive.GetValue(context); if (_updatedOnce && !updateLive) { FilteredCubeMap.Value = _prefilteredCubeMap; return; } var exposure = Exposure.GetValue(context); //ConstantBuffers.GetValues(ref _constantBuffers, context); ShaderResources.GetValues(ref _shaderResourceViews, context); SamplerStates.GetValues(ref _samplerStates, context); var vs = VertexShader.GetValue(context); var gs = GeometryShader.GetValue(context); if (CubeMap.IsConnected && CubeMap.DirtyFlag.IsDirty) { //Log.Debug("Dirty"); } var cubeMapSrc = CubeMap.GetValue(context); // Needs to be checked for null! if (cubeMapSrc == null) { FilteredCubeMap.Value = null; return; } var device = ResourceManager.Instance().Device; var deviceContext = device.ImmediateContext; // Vertex shader stage var vsStage = deviceContext.VertexShader; _prevVsConstantBuffers = vsStage.GetConstantBuffers(0, 1); _prevVsShaderResourceViews = vsStage.GetShaderResources(0, _shaderResourceViews.Length); _prevVertexShader = vsStage.Get(); if (vs == null) { Log.Warning($"{nameof(_SpecularPrefilter)} requires valid vertex shader", SymbolChildId); return; } vsStage.Set(vs); vsStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews); // Geometry shader stage var gsStage = deviceContext.GeometryShader; _prevGsConstantBuffers = gsStage.GetConstantBuffers(0, 1); _prevGsShaderResourceViews = gsStage.GetShaderResources(0, _shaderResourceViews.Length); _prevGeometryShader = gsStage.Get(); if (gs == null) { Log.Warning($"{nameof(_SpecularPrefilter)} requires valid geometry shader", SymbolChildId); return; } gsStage.Set(gs); gsStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews); // Pixel shader stage var psStage = deviceContext.PixelShader; _prevPixelShader = psStage.Get(); _prevPsConstantBuffers = psStage.GetConstantBuffers(0, 1); _prevPsShaderResourceViews = psStage.GetShaderResources(0, _shaderResourceViews.Length); _prevPsSamplerStates = psStage.GetSamplers(0, _samplerStates.Length); var ps = PixelShader.GetValue(context); if (ps == null) { Log.Warning($"{nameof(_SpecularPrefilter)} requires valid pixel shader", SymbolChildId); return; } psStage.Set(ps); psStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews); psStage.SetSamplers(0, _samplerStates); // if (_prefilteredCubeMap != null && !Changed) // { // context.Image = _prefilteredCubeMap; // return context; // } Vector2 cubeMapSize = new Vector2(cubeMapSrc.Description.Width, cubeMapSrc.Description.Height); // Log.Debug($"source size: {cubeMapSrc.Description.Width} num mips in src: {cubeMapSrc.Description.MipLevels}"); // if ( _prefilteredCubeMap == null ) // { var cubeMapDesc = new Texture2DDescription { BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, Format = cubeMapSrc.Description.Format, Width = (int)cubeMapSize.X, Height = (int)cubeMapSize.Y, MipLevels = cubeMapSrc.Description.MipLevels, SampleDescription = cubeMapSrc.Description.SampleDescription, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.TextureCube | ResourceOptionFlags.GenerateMipMaps, CpuAccessFlags = CpuAccessFlags.None, ArraySize = 6 }; Utilities.Dispose(ref _prefilteredCubeMap); try { _prefilteredCubeMap = new Texture2D(device, cubeMapDesc); } catch (SharpDXException e) { Log.Debug($"can't create CubeMap target {e.Message}"); return; } var rastDesc = new RasterizerStateDescription { FillMode = FillMode.Solid, CullMode = CullMode.None, IsDepthClipEnabled = false }; _rasterizerState = new RasterizerState(device, rastDesc); // Input Assembler var previousTopology = device.ImmediateContext.InputAssembler.PrimitiveTopology; device.ImmediateContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; _prevBlendState = device.ImmediateContext.OutputMerger.GetBlendState(out _prevBlendFactor, out _prevSampleMask); device.ImmediateContext.OutputMerger.BlendState = DefaultRenderingStates.DisabledBlendState; device.ImmediateContext.OutputMerger.DepthStencilState = DefaultRenderingStates.DisabledDepthStencilState; _prevRenderTargetViews = device.ImmediateContext.OutputMerger.GetRenderTargets(1); device.ImmediateContext.OutputMerger.GetRenderTargets(out _prevDepthStencilView); var rtvDesc = new RenderTargetViewDescription() { Dimension = RenderTargetViewDimension.Texture2DArray, Format = cubeMapSrc.Description.Format, Texture2DArray = new RenderTargetViewDescription.Texture2DArrayResource() { ArraySize = 6, FirstArraySlice = 0, MipSlice = 0 } }; int size = _prefilteredCubeMap.Description.Width; _prevViewports = device.ImmediateContext.Rasterizer.GetViewports <RawViewportF>(); device.ImmediateContext.Rasterizer.State = _rasterizerState; int numMipLevels = _prefilteredCubeMap.Description.MipLevels; int mipSlice = 0; while (mipSlice < numMipLevels) { // Log.Debug($"Update mipmap level {mipSlice} size: {size}"); var viewport = new RawViewportF { X = 0, Y = 0, Width = size, Height = size, MinDepth = 0, MaxDepth = 1 }; device.ImmediateContext.Rasterizer.SetViewports(new[] { viewport }); Utilities.Dispose(ref _cubeMapRtv); rtvDesc.Texture2DArray.MipSlice = mipSlice; _cubeMapRtv = new RenderTargetView(device, _prefilteredCubeMap, rtvDesc); device.ImmediateContext.OutputMerger.SetTargets(_cubeMapRtv, null); var roughness = (float)mipSlice / (_prefilteredCubeMap.Description.MipLevels - 1); // Is this required? if (_settingsBuffer != null) { Utilities.Dispose(ref _settingsBuffer); } for (int i = 0; i < _samplingParameters.Length; ++i) { int indexToUse = -1; if (Math.Abs(roughness - _samplingParameters[i].roughness) < 0.001f) { indexToUse = i; } if (indexToUse == -1 && roughness < _samplingParameters[i].roughness) { indexToUse = i - 1; } if (indexToUse != -1) { var parameterData = _samplingParameters[indexToUse]; parameterData.roughness = roughness; parameterData.exposure = exposure; ResourceManager.Instance().SetupConstBuffer(parameterData, ref _settingsBuffer); break; } } var constantBuffers = new[] { _settingsBuffer }; psStage.SetConstantBuffers(0, 1, constantBuffers); vsStage.SetConstantBuffers(0, 1, constantBuffers); gsStage.SetConstantBuffers(0, 1, constantBuffers); device.ImmediateContext.Draw(3, 0); size /= 2; ++mipSlice; } FilteredCubeMap.Value = _prefilteredCubeMap; Utilities.Dispose(ref _cubeMapRtv); //device.ImmediateContext.InputAssembler.PrimitiveTopology = previousTopology; Restore(context); _updatedOnce = true; }
private void Update(EvaluationContext context) { _curves.Clear(); if (Curves.IsConnected) { foreach (var curveInput in Curves.CollectedInputs) { var curve = curveInput.GetValue(context); if (curve == null) { continue; } _curves.Add(curve); } } else { if (Curves.Value != null) { _curves.Add(Curves.Value); } } var curveCount = _curves.Count; if (curveCount == 0) { return; } const int sampleCount = 256; const int entrySizeInBytes = sizeof(float); const int curveSizeInBytes = sampleCount * entrySizeInBytes; int bufferSizeInBytes = curveCount * curveSizeInBytes; using (var dataStream = new DataStream(bufferSizeInBytes, true, true)) { var texDesc = new Texture2DDescription() { Width = sampleCount, Height = curveCount, ArraySize = 1, BindFlags = BindFlags.ShaderResource, Usage = ResourceUsage.Default, MipLevels = 1, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R32_Float, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; foreach (var curve in _curves) { // var curve = curveInput.GetValue(context); // if (curve == null) // { // dataStream.Seek(curveSizeInBytes, SeekOrigin.Current); // continue; // } for (var sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { dataStream.Write((float)curve.GetSampledValue((float)sampleIndex / sampleCount)); } } //Curves.DirtyFlag.Clear(); dataStream.Position = 0; var dataRectangles = new DataRectangle[] { new DataRectangle(dataStream.DataPointer, curveSizeInBytes) }; Utilities.Dispose(ref CurveTexture.Value); CurveTexture.Value = new Texture2D(ResourceManager.Instance().Device, texDesc, dataRectangles); } }
private void Update(EvaluationContext context) { if (!Values.IsConnected) { return; } var values = Values.GetValue(context); if (values == null || values.Count == 0) { return; } int rangeStart = RangeStart.GetValue(context).Clamp(0, values.Count - 1); int rangeEnd = RangeEnd.GetValue(context).Clamp(0, values.Count - 1); float gain = Gain.GetValue(context); float pow = Pow.GetValue(context); if (Math.Abs(pow) < 0.001f) { return; } if (rangeEnd < rangeStart) { var tmp = rangeEnd; rangeEnd = rangeStart; rangeStart = tmp; } int sampleCount = (rangeEnd - rangeStart) + 1; int entrySizeInBytes = sizeof(float); int listSizeInBytes = sampleCount * entrySizeInBytes; int bufferSizeInBytes = 1 * listSizeInBytes; using (var dataStream = new DataStream(bufferSizeInBytes, true, true)) { var texDesc = new Texture2DDescription() { Width = sampleCount, Height = 1, ArraySize = 1, BindFlags = BindFlags.ShaderResource, Usage = ResourceUsage.Default, MipLevels = 1, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R32_Float, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; //foreach (var curveInput in Curves.CollectedInputs) //{ // var curve = curveInput.GetValue(context); // if (curve == null) // { // dataStream.Seek(curveSizeInBytes, SeekOrigin.Current); // continue; // } for (var sampleIndex = rangeStart; sampleIndex <= rangeEnd; sampleIndex++) { //dataStream.Write((float)curve.GetSampledValue((float)sampleIndex / sampleCount)); float v = (float)Math.Pow(values[sampleIndex] * gain, pow); dataStream.Write(v); } //} //Curves.DirtyFlag.Clear(); dataStream.Position = 0; var dataRectangles = new DataRectangle[] { new DataRectangle(dataStream.DataPointer, listSizeInBytes) }; Utilities.Dispose(ref CurveTexture.Value); CurveTexture.Value = new Texture2D(ResourceManager.Instance().Device, texDesc, dataRectangles); } }
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; }