ActionScript Gradient Banding Problem
- by TheDarkIn1978
i'm having a strange issue with banding between certain colors of a gradient.
to create the gradient, i'm drawing evenly spaced circle wedges from the center to the border, and filling each circle wedge from a bitmap line gradient pixel in a loop.
public class ColorWheel extends Sprite
{
private static const DEFAULT_RADIUS:Number = 100;
private static const DEFAULT_BANDING_QUALITY:int = 3600;
public function ColorWheel(nRadius:Number = DEFAULT_RADIUS)
{
init(nRadius);
}
public function init(nRadius:Number = DEFAULT_RADIUS):void
{
var nRadians : Number;
var nColor : Number;
var objMatrix : Matrix = new Matrix();
var nX : Number;
var nY : Number;
var previousX : Number = nRadius;
var previousY : Number = 0;
var leftToRightColors:Array = new Array(0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF);
leftToRightColors.push(leftToRightColors[0]);
var leftToRightAlphas:Array = new Array();
var leftToRightRatios:Array = new Array();
var leftToRightPartition:Number = 255 / (leftToRightColors.length - 1);
//Push arrays
for (var j:int = 0; j < leftToRightColors.length; j++)
{
leftToRightAlphas.push(1);
leftToRightRatios.push(j * leftToRightPartition);
}
var leftToRightColorsMatrix:Matrix = new Matrix();
leftToRightColorsMatrix.createGradientBox(DEFAULT_BANDING_QUALITY, 1);
//Produce a horizontal leftToRightLine sprite
var leftToRightLine:Sprite = new Sprite();
leftToRightLine.graphics.lineStyle(1, 0, 1, false, LineScaleMode.NONE, CapsStyle.NONE);
leftToRightLine.graphics.lineGradientStyle(GradientType.LINEAR, leftToRightColors, leftToRightAlphas, leftToRightRatios, leftToRightColorsMatrix);
leftToRightLine.graphics.moveTo(0, 0);
leftToRightLine.graphics.lineTo(DEFAULT_BANDING_QUALITY, 0);
//Assign bitmapData to the leftToRightLine
var leftToRightLineBitmapData:BitmapData = new BitmapData(leftToRightLine.width, leftToRightLine.height);
leftToRightLineBitmapData.draw(leftToRightLine);
for(var i:int = 1; i < (DEFAULT_BANDING_QUALITY + 1); i++)
{
// Convert the degree to radians.
nRadians = i * (Math.PI / (DEFAULT_BANDING_QUALITY / 2));
// OR the individual color channels together.
nColor = leftToRightLineBitmapData.getPixel(i-1, 0);
// Calculate the coordinate in which the line should be drawn to.
nX = nRadius * Math.cos(nRadians);
nY = nRadius * Math.sin(nRadians);
// Create a matrix for the wedges gradient color.
objMatrix.createGradientBox(nRadius * 2, nRadius * 2, nRadians, -nRadius, -nRadius);
graphics.beginGradientFill(GradientType.LINEAR, [nColor, nColor], [1, 1], [127, 255], objMatrix);
graphics.moveTo( 0, 0 );
graphics.lineTo( previousX, previousY );
graphics.lineTo( nX, nY );
graphics.lineTo( 0, 0 );
graphics.endFill();
previousX = nX;
previousY = nY;
}
}
}
i'm creating a circle with 3600 wedges, although it doesn't look like it based on the screen shot within the orange color that is produced from gradating from red to yellow numbers. adding a orange number between red and yellow doesn't help. but if i create the circle with only 360 wedges, the gradient banding is much more obvious. 3600 is probably overkill, and doesn't really add more detail over, say, making the circle of 1440 wedges, but i don't know any other way to slightly elevate this banding issue.
any ideas how i can fix this, or what i'm doing wrong? could it be caused by the circleMatrix rotation?