Я пишу простой движок для 2D-игр, используя холст HTML5. Я пришел к добавлению осветительного двигателя. Каждый источник света имеет значение радиуса и значение интенсивности (0-1, например, 1 будет очень ярким). Также есть значение окружающего освещения, которое используется для освещения всего остального в мире, которое не находится рядом с источником света (0-1, например, 0,1 будет лунным светом). Процесс освещения выполняется на отдельном холсте над основным холстом:
Мой код для этого:
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';
Однако вместо того, чтобы получать то, что мне не нужно, из движка (слева) я получаю своего рода обратный градиент (справа). Я думаю, это связано с тем, что когда я рисую прямоугольник с помощью составной операции источник-выход
, он влияет на цвета самого градиента, потому что они полупрозрачны.
Есть ли способ сделать это по-другому или лучше? Может быть, использовать обрезку или сначала нарисовать прямоугольник поверх всего?
Кроме того, я модифицировал пример Mozila Dev Centre по компостированию, чтобы воспроизвести то, что мне нужно сделать, и ни один из составных режимов, похоже, не работал, проверьте , если это поможет.
Большое спасибо, любой ответ будет отличным :)