public void Values_Can_Be_Negative() { // setup float addValue = -10; var addFilter = FilterUtility.CreateInstance <AddFilter>(); addFilter.value = addValue; m_Stack.Add(addFilter); var prevRT = RenderTexture.active; var dest = RTUtils.GetTempHandle(RTUtils.GetDescriptor(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); Graphics.Blit(Texture2D.blackTexture, dest); // init to black // eval m_Stack.Eval(m_Context, null, dest); // source isn't actually used yet var tex = new Texture2D(1, 1, TextureFormat.RGBAFloat, false, true); RenderTexture.active = dest; tex.ReadPixels(new Rect(0, 0, 1, 1), 0, 0, false); var check = tex.GetPixel(0, 0).r - 1; // minus 1 because we start off with a white texture within FilterStack.Eval // clean up RenderTexture.active = prevRT; UObject.DestroyImmediate(tex); RTUtils.Release(dest); Assert.That(check, Is.EqualTo(addValue)); }
public void Add_Filter() { // setup float addValue = 9000f; var addFilter = FilterUtility.CreateInstance <AddFilter>(); addFilter.value = addValue; var prevRT = RenderTexture.active; var src = RTUtils.GetTempHandle(RTUtils.GetDescriptor(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); var dest = RTUtils.GetTempHandle(RTUtils.GetDescriptor(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); Graphics.Blit(Texture2D.blackTexture, src); Graphics.Blit(Texture2D.blackTexture, dest); // eval addFilter.Eval(m_Context, src, dest); var tex = new Texture2D(1, 1, TextureFormat.RGBAFloat, false, true); RenderTexture.active = dest; tex.ReadPixels(new Rect(0, 0, 1, 1), 0, 0, false); var check = tex.GetPixel(0, 0).r; // clean up RenderTexture.active = prevRT; UObject.DestroyImmediate(tex); RTUtils.Release(src); RTUtils.Release(dest); UObject.DestroyImmediate(addFilter); Assert.That(check, Is.EqualTo(addValue)); }
/// <summary> /// Evaluate the FilterStack. Composited result will be copied into fc.destinationRenderTexture /// <param name="fc">The FilterContext that should be used for composition</param> /// <exception>Throws an exception if source or destination RenderTexture is null</exception> /// </summary> public void Eval(FilterContext fc, RenderTexture source, RenderTexture dest) { if (dest == null) { throw new InvalidOperationException("FilterContext::Eval: Source and destination RenderTextures are not properly set up"); } using (new ActiveRenderTextureScope(RenderTexture.active)) { int count = filters.Count; int srcIndex = 0; int destIndex = 1; var descriptor = RTUtils.GetDescriptor(dest.width, dest.height, 0, FilterUtility.defaultFormat); swapBuffer[0] = RTUtils.GetTempHandle(descriptor).WithName(k_BufferName0); swapBuffer[1] = RTUtils.GetTempHandle(descriptor).WithName(k_BufferName1); // ensure the textures are created for compute usage swapBuffer[0].RT.Create(); swapBuffer[1].RT.Create(); //don't remove this! needed for compute shaders to work correctly. Graphics.Blit(Texture2D.whiteTexture, swapBuffer[0]); // TODO: change this to black or source. should build up the mask instead of always multiply Graphics.Blit(Texture2D.blackTexture, swapBuffer[1]); for (int i = 0; i < count; ++i) { var filter = filters[i]; if (!filter.enabled) { continue; } filter.Eval(fc, swapBuffer[srcIndex], swapBuffer[destIndex]); // swap indices destIndex += srcIndex; srcIndex = destIndex - srcIndex; destIndex = destIndex - srcIndex; } Graphics.Blit(swapBuffer[srcIndex], dest); RTUtils.Release(swapBuffer[0]); RTUtils.Release(swapBuffer[1]); swapBuffer[0] = null; swapBuffer[1] = null; } }
public void Noise_Filter_Can_Be_Rotated(int dim) { var noiseFilter = FilterUtility.CreateInstance <NoiseFilter>(); noiseFilter.SetLocalSpace(true); m_Stack.Add(noiseFilter); var dest = RTUtils.GetTempHandle(RTUtils.GetDescriptor(dim, dim, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); Graphics.Blit(Texture2D.blackTexture, dest); // init to black m_Context.brushRotation = 0; m_Context.brushPos = Vector3.zero; m_Context.brushSize = dim; m_Stack.Eval(m_Context, null, dest); // source isn't actually used yet var unrotatedColors = GetColorsFromRT(dest); m_Context.brushRotation = 180; m_Stack.Eval(m_Context, null, dest); // source isn't actually used yet var rotatedColors = GetColorsFromRT(dest); RTUtils.Release(dest); int failureCount = 0; var difference = new Color[rotatedColors.Length]; for (int x = 0; x < dim; x++) { for (int y = 0; y < dim; y++) { int rotatedIndex = (dim - 1 - x) + (dim - 1 - y) * dim; var index = x + y * dim; difference[index] = new Color(Mathf.Abs(rotatedColors[rotatedIndex].r - unrotatedColors[index].r), 0, 0, 1); // comparing with a small value to eliminate issues coming from floating point offset if (Mathf.Abs(rotatedColors[rotatedIndex].r - unrotatedColors[index].r) > 0.001f) { failureCount++; } } } Assert.That(failureCount, Is.Zero); }