skip to Main Content

CONTEXT:
I am trying to make a light source using ray casting, that the player can use in a randomly generated maze. The rays cast from the mouse pointer. The radial gradient that I’m using changes their colour from white (the light) to black (to simulate darkness).

The problem:
The problem that I’m having is that the ctx.createRadialGradient() isnt making the lines transparent, and is rather just a solid white colour, and I cant see the other stroke lines through the transparency of the white colour.

The goal:
I want the player to be unable to see other ctx.stroke() lines when the gradient of the line is black, but when the gradient of the line is still a transparent white, I want to be able to actually see the other ctx.stroke() lines.

WORTH NOTING: there are exactly 1,000 rays that are being cast to create a circle (using rays).

Code:

const x = this.rays[i].x
const y = this.rays[i].y
const color0 = this.rays[i].radialGradient.colorStop0 // this color is white;
const color1 = this.rays[i].radialGradient.colorStop1 // this color is black;
const radius = this.circularRayRadius // the radius is equal to 200;
gradient = this.ctx.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, color0);
gradient.addColorStop(1, color1);

2

Answers


  1. From the little you posted I’m not seeing where you’re using the alpha channel to create transparency.

    Your comments say the color is "white" but that only means…

    rgb(255,255,255)       <-- solid white
    

    While I was expecting something more like…

    rgba(255,255,255,128)  <-- 50% transparent white
    
    rgba(255,255,255,64)   <-- 25% transparent white
    

    But anyway, I doubt you’ll get impressive results from a radial gradient and not to mention the slow speed.

    To create a truer "light source" I suggest you look into the SVG filter "SpecularLighting" which I use

    successfully in my image manipulating program to create some pretty spectacular effects on images but of course it’s not limited to images.

    Svg filters are very fast and very effective, so do look into this one in particular which I’m sure is better for your needs from what you describe:

    <svg
      height="200"
      width="200"
      viewBox="0 0 220 220"
      xmlns="http://www.w3.org/2000/svg">
      <filter id="filter">
        <feSpecularLighting
          result="specOut"
          specularExponent="20"
          lighting-color="#bbbbbb">
          <fePointLight x="50" y="75" z="200" />
        </feSpecularLighting>
        <feComposite
          in="SourceGraphic"
          in2="specOut"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
      </filter>
      <circle cx="110" cy="110" r="100" style="filter:url(#filter)" />
    </svg>
    

    https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feSpecularLighting

    NB: If you haven’t used an SVG filter before I can tell you now that they’re not easy to use, but do persevere because the end result is worth it.

    Login or Signup to reply.
  2. Look into using the canvas globalCompositeOperation property, to combine your gradient with whatever lines are already on the canvas. For example setting,

    ctx.globalCompositeOperation = "darken"

    before drawing your gradient.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search