Я пишу простой 2D игровой движок с использованием HTML5 canvas.Я пришел, чтобы добавить двигатель освещения.Каждый источник света имеет значение радиуса и значение интенсивности (0-1, например, 1 будет очень ярким).Также есть значение рассеянного света, которое используется для освещения всего остального в мире, которое не находится рядом с источником света (0-1, например, 0,1 будет лунным светом).Процесс освещения осуществляется на отдельном холсте над основным холстом:
- Для каждого источника света радиальный градиент рисуется в этой позиции с тем же радиусом, что и источник света.Градиент задается двумя ступенями: центр черный с альфа-1-интенсивностью света, а конец / край черный с альфа-значением 1-рассеянного света.Это все работает нормально.
- Вот где все идет не так: / Мне нужно заполнить весь холст черным с альфа-значением значения 1-ambient light, и в настоящий момент я делаю это, устанавливая context.globalCompositeOperationк исходному тексту, затем fillRecting весь холст.
Мой код для этого материала:
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';
Однако вместо того, чтобы получить то, что я не выбрал из двигателя (слева), я получаю своего рода обратный градиент (справа)).Я думаю, это потому, что когда я рисую прямоугольник с помощью составной операции source-out
, это влияет на цвета самого градиента, потому что они полупрозрачны.
Есть ли способ сделать это по-другому или лучше?Может быть, используя отсечение или сначала рисуя прямоугольник поверх всего?
Кроме того, я изменил пример Центра разработки Mozila для компостирования, чтобы воспроизвести то, что мне нужно сделать, и ни один из составных режимов не показалсяработа, проверьте это , если это поможет.
Большое спасибо, любой ответ будет отличным:)