Постепенное затухание путем многократного рисования прозрачного прямоугольника - PullRequest
4 голосов
/ 25 июля 2011

Это вопрос о Processing.org .

Я затушевываю ранее нарисованные объекты, рисуя полупрозрачный белый прямоугольник поверх вида для каждого кадра.

Однако кажется, что они никогда не исчезают до полностью белого цвета.Выцветание имеет фиксированную точку на некотором заметно небелом оттенке серого.То же самое происходит при попытке перехода к черному.

Является ли это стандартной функцией того, как альфа-смешение работает при обработке?Есть ли относительно простой способ обойти это, чтобы получить полностью белый фон (с учетом достаточного количества шагов)?

Я представлял, что результирующий цвет будет линейной комбинацией смешанных цветов,что означает, что предел должен быть белым.Возможно, небелая фиксированная точка является артефактом округления?

Пример кода, иллюстрирующего проблему:

void setup() {
  size(300,300);
  background(0);
  noStroke();
  frameRate(15);
}

void draw() {
  fill(255,10);
  rect(0,0,width,height);
  fill(255);
  rect(0,0,50,50); // for comparison to white
}

edit: добавлено java тег в надежде на большее внимание

Ответы [ 3 ]

0 голосов
/ 18 июня 2015

Я много копал, и теперь я с уверенностью могу сказать, что полное затухание с альфа-каналом невозможно.Однако есть вещь, называемая яркостью, поэтому давайте ее использовать.

void setup() {
  size(300,300);
  background(0);
  noStroke();
  frameRate(15);

  // White rectangle for fading comparison.
  fill(255);
  rect(0, 0, 50, 50);
}

void draw() {
  fade(10);
}

void fade(final int fadeSpeed) {
  loadPixels();
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      final int pixelIndex = row * width + col;
      int pixel = pixels[pixelIndex];
      int red   = ((pixel >>> 16) & 0xFF) + fadeSpeed;
      int green = ((pixel >>>  8) & 0xFF) + fadeSpeed;
      int blue  =  (pixel         & 0xFF) + fadeSpeed;
      if (red   > 255) { red   = 255; }
      if (green > 255) { green = 255; }
      if (blue  > 255) { blue  = 255; }

      // Shift bits back into propper position and 
      red   <<= 16;
      green <<=  8;
      pixel &= 0xFF000000;  // Keep alpha bits.
      pixel |= red |= green |= blue;

      pixels[pixelIndex] = color(pixel);
    }
  }
  updatePixels();
}

Увеличивая все три цветовых канала (красный, зеленый, синий) одновременно, мы не меняем цвет, но яркость.

0 голосов
/ 22 февраля 2018

Я обнаружил, что, хотя ошибка округления (если это так) применяется почти ко всему, что вы можете попробовать, используя blendMode(SUBTRACT), за которым следует заливка очень маленьким оттенком серого (например, fill(2)), достигаетсяпостепенное затухание в течение многих draw() циклов без «призрачного» изображения, которое, как кажется, имеют все другие подходы, при сохранении частоты кадров (что часто критично в ситуациях рисования в реальном времени).

 // The only reasonable way to actually "fade" out the pixels.
blendMode(SUBTRACT);
fill(2);
rect(0, 0, width, height);
blendMode(NORMAL);
0 голосов
/ 04 октября 2011

Я не уверен, что происходит, похоже, вы должны быть правы, и если число нарисованных прямоугольников * альфа-значение этих прямоугольников больше 255, оно должно быть полностью белым. В любом случае, почему бы просто не перерисовать каждый кадр (как я делаю, переместив линию фона (0) в цикл рисования), а затем просто увеличить свое альфа-значение. Я думаю, что этот путь даст вам больше контроля над вашими анимациями в будущем.

int a;

void setup() {
  size(300,300);
  noStroke();
  frameRate(15);
  a = 0;
}

void draw() {
  background(0);
  a += 1;
  if(a<=255){
    fill(255,a);
  }
  rect(0,0,width,height);
  fill(255);
  rect(0,0,50,50); // for comparison to white
}
...