/* * Set Texture Data. Setting a pixel out of bound does nothing */ protected void SetPixel(int x, int y, HColor pixel) { if (IndexInBounds(x, y)) { m_pixels[ToArrayCoords(x, y)] = pixel; } }
/// <summary> /// Set Data from Texture2D /// </summary> private bool SetPixels(Texture2D source) { if (!TextureOperations.IsReadableWritable(source)) { Console.LogError("TexturePixelSource GetData(): source Texture2D(" + source.name + ") is compressed and therefore not readable"); return(false); } else { // If the source is not the desired size resize it if (source.width != Width || source.height != Height) { source = TextureOperations.ResizeTexture(source, Width, Height); } // Get Mip level 0 pixels for (int x = 0; x < Width; ++x) { for (int y = 0; y < Height; ++y) { mPixels[(y * Width) + x] = new HColor(source.GetPixel(x, y)); } } return(true); } }
// ** SINGLE PIXEL BLEND FUNCTIONS ** // /* * Pixel2 is the 'top' pixel, Pixel1 is the bottom */ static public HColor BlendPixelsLayer(HColor pixel1, HColor pixel2) { float a = pixel2.a / 255f; float aComplement = 1 - (pixel2.a / 255f); byte r = (byte)((pixel1.r * aComplement) + (pixel2.r * a)); byte g = (byte)((pixel1.g * aComplement) + (pixel2.g * a)); byte b = (byte)((pixel1.b * aComplement) + (pixel2.b * a)); return(new HColor(r, g, b, pixel2.a)); }
/* Filter a pixel based on some parameters and return a color value */ public override HColor FilterPixel(HColor source) { HSVA pixel = HueSaturationValue.ColorToHSV(source); pixel.h = (pixel.h + mHSVA.h) % 360; pixel.s = Mathf.Clamp01(pixel.s + mHSVA.s); pixel.v = Mathf.Clamp01(pixel.v * mHSVA.v); pixel.a = Mathf.Clamp01(pixel.a * mHSVA.a); return(HueSaturationValue.HSVToHColor(pixel)); }
/* Filter a pixel based on some parameters and return a color value */ public override HColor FilterPixel(HColor source) { HSVA pixel = HueSaturationValue.ColorToHSV(source); /* Set the source pixel Hue */ pixel.h = mHSVA.h; pixel.s = pixel.s * mHSVA.s; pixel.v = pixel.v * mHSVA.v; /* Apply alpha as a multiplier */ pixel.a *= mHSVA.a; return(HueSaturationValue.HSVToHColor(pixel)); }
/* * We combine the layers using a Top down per pixel approach * for each pixel we traverse down * the layers but only if the lower layer's pixel is visible */ protected virtual void FlattenDirtyPixels(int interval, int offset) { int startX = (int)mDirtyPixels.x + offset; int startY = (int)mDirtyPixels.y; int endX = (int)mDirtyPixels.x + (int)mDirtyPixels.width; int endY = (int)mDirtyPixels.y + (int)mDirtyPixels.height; // For each Dirty Pixel for (int x = startX; x < endX; x += interval) { for (int y = startY; y < endY; ++y) { mResultTexture.SetPixel(x, y, HColor.ToUnityColor(FlattenPixel(x, y, mLayers.Count, mLayers))); } } }
/// <summary> /// Flatten a Pixel of the Complex Texture. Recurse down the layers and combine pixels /// </summary> protected HColor FlattenPixel(int x, int y, int level, List <PixelSourceLayer> layers) { // Base Case 1 switch (level) { case 0: return(new HColor(0, 0, 0, 0)); case 1: return(layers[0][x, y]); default: PixelSourceLayer currentLayer = layers[level - 1]; // Optimization 1: Out of PixelSource Bounds // If we are out of bounds for this layer don't bother Blending Pixels, go to next layer if (!currentLayer.IndexInBounds(x, y)) { return(FlattenPixel(x, y, level - 1, layers)); } HColor pixel = currentLayer[x, y]; Pixel.PixelBlendMode blendMode = currentLayer.PixelBlendMode; // Optimization 2 // If layer Blendmode == Layer, and alpha is 1, get the hell out of here if (blendMode == Pixel.PixelBlendMode.Layer) { // Quick Exit if (pixel.a == 255) { return(pixel); } // If 100% transparent go down to next layer if (pixel.a == 0) { return(FlattenPixel(x, y, level - 1, layers)); } } // Else recurse down and combine pixel with the result of the lower pixel Pixel.BlendPixels blendFunction = Pixel.GetBlendFunction(blendMode); return(blendFunction(FlattenPixel(x, y, level - 1, layers), pixel)); } }
/* * We combine the layers using a Top down per pixel approach * for each pixel we traverse down * the layers but only if the lower layer's pixel is visible */ protected override void FlattenDirtyPixels(int interval, int offset) { // for each zone List <PixelSourceLayer> zoneLayers; Rect dirtyPixels; int startX; int startY; int endX; int endY; // For each Zone check if it has dirty pixels for (int z = 0; z < mZones.Count; ++z) { // If there is a intersection with Dirty Rect dirtyPixels = RectUtility.PixelIntersection(mDirtyPixels, mZones[z].Area); if (dirtyPixels.width > 0 && dirtyPixels.height > 0) { // Flatten only layers that belong to this zone in dirty rect zoneLayers = mZones[z].ZoneLayers; if (zoneLayers.Count > 0) { startX = (int)dirtyPixels.x + offset; startY = (int)dirtyPixels.y; endX = (int)dirtyPixels.x + (int)dirtyPixels.width; endY = (int)dirtyPixels.y + (int)dirtyPixels.height; // For each Dirty Pixel for (int x = startX; x < endX; x += interval) { for (int y = startY; y < endY; ++y) { // If the Dirty mask is set to true mResultTexture.SetPixel(x, y, HColor.ToUnityColor(FlattenPixel(x, y, zoneLayers.Count, zoneLayers))); } } } } } }
/* Filter a pixel based on some parameters and return a color value */ public override HColor FilterPixel(HColor source) { HSVA pixel = HueSaturationValue.ColorToHSV(source); /* Set the source pixel Hue */ pixel.h = mHSVA.h; /* * Assume the source pixel has saturation 1 and subtract inverse of saturation from it * This subtractive process will not saturate white pixels like highlites */ pixel.s = Mathf.Clamp01(pixel.s - (1 - mHSVA.s)); /* * Use the value as an exponent to darken pixels * This method does not darken white pixels ( to maintain highlights ) */ pixel.v = Mathf.Clamp01(Mathf.Pow(pixel.v, 1 + (1 - (mHSVA.v)) * 2.5f)); /* Apply alpha as a multiplier */ pixel.a *= mHSVA.a; return(HueSaturationValue.HSVToHColor(pixel)); }
/* * Constructor */ public SolidColorPixelSource(int width, int height, Color color) : base(width, height) { mColor = new HColor(color); mIsWhite = (color == Color.white); }
public static HColor Multiply(HColor c1, HColor c2) { return(new HColor((byte)((c1.r * c2.r) / 255), (byte)((c1.g * c2.g) / 255), (byte)((c1.b * c2.b) / 255), (byte)((c1.a * c2.a) / 255))); }
public static HSVA ColorToHSV(HColor source) { return(ColorToHSV((float)source.r / 255, (float)source.g / 255, (float)source.b / 255, (float)source.a / 255)); }
public static bool IsWhite(HColor c) { return(c.r == 255 && c.g == 255 && c.b == 255); }
public static Color ToUnityColor(HColor c) { return(new Color(c.r / 255f, c.g / 255f, c.b / 255f, c.a / 255f)); }
public override bool IsPixelWhite(int x, int y) { return(HColor.IsWhite(this[x, y])); }
public static HColor Add(HColor c1, HColor c2) { return(new HColor(c1.r + c2.g, c1.b + c2.g, c1.b + c2.b, c1.a + c2.a)); }
/* * Filter a pixel based on some parameters and return a color value * This base class doesn't modify the pixel source */ public override HColor FilterPixel(HColor source) { return(source); }
/* Filter a pixel based on some parameters and return a color value */ public override HColor FilterPixel(HColor source) { float alpha = Mathf.Floor(((source.a * mColor.a) / 65025f) * 255); return(new HColor(mColor.r, mColor.g, mColor.b, (byte)alpha)); }
public SolidColorFilter() : base() { mColor = new HColor(1f, 1f, 1f, 1f); }
/* * Filter a pixel based on some parameters and return a color value * This base class doesn't modify the pixel source */ public abstract HColor FilterPixel(HColor source);