/// <summary> /// Creates a ConvolutionEngine instance. /// </summary> /// <param name="device">The graphics device to use.</param> /// <param name="context">The graphics context to use.</param> /// <param name="resolution">The convolution resolution.</param> public ConvolutionEngine(Device device, DeviceContext context, Size resolution) { fft = FastFourierTransform.Create2DComplex(context, resolution.Width, resolution.Height); fft.InverseScale = 1.0f / (float)(resolution.Width * resolution.Height); this.resolution = resolution; FastFourierTransformBufferRequirements bufferReqs = fft.BufferRequirements; precomputed = new FFTBuffer[bufferReqs.PrecomputeBufferCount]; temporaries = new FFTBuffer[bufferReqs.TemporaryBufferCount]; for (int t = 0; t < precomputed.Length; ++t) precomputed[t] = FFTUtils.AllocateBuffer(device, bufferReqs.PrecomputeBufferSizes[t]); for (int t = 0; t < temporaries.Length; ++t) temporaries[t] = FFTUtils.AllocateBuffer(device, bufferReqs.TemporaryBufferSizes[t]); UnorderedAccessView[] precomputedUAV = new UnorderedAccessView[bufferReqs.PrecomputeBufferCount]; for (int t = 0; t < precomputed.Length; ++t) precomputedUAV[t] = precomputed[t].view; UnorderedAccessView[] temporariesUAV = new UnorderedAccessView[bufferReqs.TemporaryBufferCount]; for (int t = 0; t < temporaries.Length; ++t) temporariesUAV[t] = temporaries[t].view; fft.AttachBuffersAndPrecompute(temporariesUAV, precomputedUAV); lBuf = FFTUtils.AllocateBuffer(device, 2 * resolution.Width * resolution.Height); rBuf = FFTUtils.AllocateBuffer(device, 2 * resolution.Width * resolution.Height); tBuf = FFTUtils.AllocateBuffer(device, 2 * resolution.Width * resolution.Height); rConvolved = new GraphicsResource(device, resolution, Format.R32_Float, true, true); gConvolved = new GraphicsResource(device, resolution, Format.R32_Float, true, true); bConvolved = new GraphicsResource(device, resolution, Format.R32_Float, true, true); staging = new GraphicsResource(device, new Size(resolution.Width / 2, resolution.Height / 2), Format.R32G32B32A32_Float, true, true); BlendStateDescription description = new BlendStateDescription() { AlphaToCoverageEnable = false, IndependentBlendEnable = false, }; description.RenderTarget[0] = new RenderTargetBlendDescription() { IsBlendEnabled = true, SourceBlend = BlendOption.One, DestinationBlend = BlendOption.One, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.Zero, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, RenderTargetWriteMask = ColorWriteMaskFlags.Red | ColorWriteMaskFlags.Green | ColorWriteMaskFlags.Blue, }; blendState = new BlendState(device, description); }
/// <summary> /// Creates a DiffractionEngine instance. /// </summary> /// <param name="device">The graphics device to use.</param> /// <param name="context">The graphics context to use.</param> /// <param name="resolution">The diffraction resolution.</param> public DiffractionEngine(Device device, DeviceContext context, Size resolution) { fft = FastFourierTransform.Create2DComplex(context, resolution.Width, resolution.Height); fft.ForwardScale = 1.0f / (float)(resolution.Width * resolution.Height); this.resolution = resolution; FastFourierTransformBufferRequirements bufferReqs = fft.BufferRequirements; precomputed = new FFTBuffer[bufferReqs.PrecomputeBufferCount]; temporaries = new FFTBuffer[bufferReqs.TemporaryBufferCount]; for (int t = 0; t < precomputed.Length; ++t) precomputed[t] = FFTUtils.AllocateBuffer(device, bufferReqs.PrecomputeBufferSizes[t]); for (int t = 0; t < temporaries.Length; ++t) temporaries[t] = FFTUtils.AllocateBuffer(device, bufferReqs.TemporaryBufferSizes[t]); UnorderedAccessView[] precomputedUAV = new UnorderedAccessView[bufferReqs.PrecomputeBufferCount]; for (int t = 0; t < precomputed.Length; ++t) precomputedUAV[t] = precomputed[t].view; UnorderedAccessView[] temporariesUAV = new UnorderedAccessView[bufferReqs.TemporaryBufferCount]; for (int t = 0; t < temporaries.Length; ++t) temporariesUAV[t] = temporaries[t].view; fft.AttachBuffersAndPrecompute(temporariesUAV, precomputedUAV); /* We are doing a complex to complex transform, so we need two floats per pixel. */ buffer = FFTUtils.AllocateBuffer(device, 2 * resolution.Width * resolution.Height); transform = new GraphicsResource(device, resolution, Format.R32_Float, true, true); spectrum = new GraphicsResource(device, resolution, Format.R32G32B32A32_Float, true, true, true); }