Note that there are some explanatory texts on larger screens.

plurals
  1. POCanvas - Fill a rectangle in all areas that are fully transparent
    primarykey
    data
    text
    <p>I'm writing a simple 2D game engine using the HTML5 canvas. I've come to adding a lighting engine. Each light source has a radius value and an intensity value (0-1, eg 1 would be very bright). There's also an ambient light value that is used to light everything else in the world that isn't near a light source (0-1, eg 0.1 would be moonlight). The process of lighting is done on a separate canvas above the main canvas:</p> <ol> <li>For each light source, a radial gradient is drawn at that position with the same radius as the light source. The gradient is given two stops: the center is black with an alpha of 1-intensity of the light and the end/edge is black with alpha of 1-ambient light value. That all works fine.</li> <li>This is where it goes wrong :/ I need to fill the whole canvas with black with and alpha of 1-ambient light value and at the moment I do this by setting the context.globalCompositeOperation to source-out then fillRecting the whole canvas. </li> </ol> <p>My code for this stuff is:</p> <pre><code>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 &gt; 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'; </code></pre> <p>However instead of getting what I wan't out of the engine (left) I get a kind of reversed gradient (right). I think this is because when I draw the rectangle with the <code>source-out</code> composite operation it affects the colours of the gradient itself because they are semi-transparent.<br /><br /> <img src="https://i.stack.imgur.com/T6fsx.png" alt="Desired lighting effect"> <img src="https://i.stack.imgur.com/u6itZ.png" alt="I get this"></p> <p>Is there a way to do this differently or better? Using clipping maybe, or drawing the rect over everything first?</p> <p>Also, I modified the Mozila Dev Centre's <a href="https://developer.mozilla.org/en/Canvas_tutorial/Compositing" rel="noreferrer">example</a> on composting to replicate what I need to do and none of the composite modes seemed to work, <a href="http://chopapp.com/#1b0f6c3e" rel="noreferrer">check that out</a> if it would help.</p> <p>Thanks very much, any answer would be great :)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload