Холст - Заполните прямоугольник во всех полностью прозрачных областях

Я пишу простой движок для 2D-игр, используя холст HTML5. Я пришел к добавлению осветительного двигателя. Каждый источник света имеет значение радиуса и значение интенсивности (0-1, например, 1 будет очень ярким). Также есть значение окружающего освещения, которое используется для освещения всего остального в мире, которое не находится рядом с источником света (0-1, например, 0,1 будет лунным светом). Процесс освещения выполняется на отдельном холсте над основным холстом:

  1. Для каждого источника света в этом месте рисуется радиальный градиент с тем же радиусом, что и у источника света. Градиенту дается две ступени: центр черный с альфа-интенсивностью света 1, а конец / край черный с альфа-значением 1-окружающего освещения. Все работает нормально.
  2. Здесь происходит ошибка: / Мне нужно заполнить весь холст черным цветом с альфа-каналом, равным 1-окружающему свету, и в данный момент я делаю это, устанавливая context.globalCompositeOperation на исходный код, а затем заполняя холст.

Мой код для этого:

var amb = 'rgba(0,0,0,' + (1-f.ambientLight) + ')';
for(i in f.entities) {
    var e = f.entities[i], p = f.toScreenPoint(e.position.x, e.position.y), radius = e.light.radius;

    if(radius > 0) {
        var g = cxLighting.createRadialGradient(p.x, p.y, 0, p.x, p.y, radius);
        g.addColorStop(0, 'rgba(0,0,0,' + (1-e.light.intensity) + ')');
        g.addColorStop(1, amb);

        cxLighting.fillStyle = g;
        cxLighting.beginPath();
        cxLighting.arc(p.x, p.y, radius, 0, Math.PI*2, true);
        cxLighting.closePath();
        cxLighting.fill();
    }
}
//Ambient light
cxLighting.globalCompositeOperation = 'source-out';
cxLighting.fillStyle = amb;
cxLighting.fillRect(0, 0, f.width, f.height);
cxLighting.globalCompositeOperation = 'source-over';

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

Desired lighting effectI get this

Есть ли способ сделать это по-другому или лучше? Может быть, использовать обрезку или сначала нарисовать прямоугольник поверх всего?

Кроме того, я модифицировал пример Mozila Dev Centre по компостированию, чтобы воспроизвести то, что мне нужно сделать, и ни один из составных режимов, похоже, не работал, проверьте , если это поможет.

Большое спасибо, любой ответ будет отличным :)

5
задан jt78 26 October 2011 в 22:53
поделиться