Math for calculating visibility of closed set of lines

Hi!

I want to make a 2D game with classic vector graphics, like 1979 Asteroids

I only want to use a line renderer for this.
Therefore I need an algorithm to calculate the visibility of the background. (Normally a mesh with opaque material on it would do that).

When a polygon (a closed set of lines) appears the algorithm should cover the Background or other polygons that are in a lower “layer”.

I attached an example…the overlapping lines of P2 should not be visible in the calculated picture.
I somewhere read that this is called “hidden line/surface removal” …but unfortunately I could not find anything useful for my problem.

Can someone please point me in the right direction (math)?

Thanks
Andy

First a question. Why limit yourself to line renderers? GPUs exist to help solve this problem. Fill the area with a solid background colored polygon shape. For any useful hidden surface removal setup you’d likely have to calculate the triangle mesh of a polygon anyway for the occlusion calculations. Indeed, unless you want to start doing 2D CSG calculations (hint: you don’t) the most common techniques for hidden line removal amount to emulating a GPU in software… not that GPUs existed when these algorithms were first described, it’s what GPUs’ were built to do so they didn’t have to do it in software anymore!

So setup your rendering like this:

  • Render P2 polygon
  • Render P2 line
  • Render P1 polygon
  • Render P1 line

With a little bit of work you could even have the polygon rendering pass render the line at the same time, either by building the line mesh yourself on top of a polygon so they’re pre-sorted with the solid polygon’s tris being first in the list so the overlap of the polygon and line is handled, or by having the interior of the line “filled” with no overlaps.

If you’re trying to avoid having to deal with meshing arbitrary polygon shapes, again, you’d have to do that anyway for any kind of hidden line removal you might do. There’s no avoiding that.

Thanks for the reply!

I want to make a parallax scrolling background with many vector layers.
I tried making each layer out of a polygon and render the outlines extra to get that classic vector look, but I soon realized that every polygon (layer) needs at least 2 draw calls (one for the polygon and one for the outline …I used protoshape 2D for the polygons and fast line renderer for the outlines) and summing up for example 50 layers gives me a minimum of 100 draw calls. This is far too much.

My game should run super fast on old devices too (My test device is a galaxy note 2)

Analyzing the galaxy note 2 with help of the profiler and frame debugger showed that I have plenty of cpu power left but very little draw calls possible.
…that leads to the thought that I could calculate the complete background lines with help of the cpu and using only ONE draw call to render the whole background.
Attached is a picture how the parallax scrolling background should look when finished (picture taken from the movie alien 1 …nostromo landing sequence). The landscape itself should all be calculated too with help of procedural generation. So in the end no sprite is needed for the background, no artist, no memory, no loading time, nothing.

The player ship and all of the enemies are classic sprites because of the collision detection. The background is only for the optics and therefore no collision detection is needed.
5366991--542973--Bildschirmfoto 2020-01-08 um 22.13.42.png

Ouch.

I saw your original post on this. My original thought was to do something purely in the shader, or with multiple mesh layers that are being offset by the texture. But for a 7 year old mobile GPU, probably not.

The nice thing is this particular case is purely 2D, and purely height map based, which simplifies it even further. So all you need to do is calculate each line at the resolution you want, which is sampling the height map at the start and end points, and compare it against the lines below, which is also just sampling the height map at two points at the same “x” as the current line, but different “y” coordinates. You can limit the number of lines below you need to test against based on the max height displacement. Then if both points are higher, your entire line is occluded. If both are lower, then it’s not occluded. If only one point is higher, then it intersects and you need to do a two line segment intersection test (search stackoverflow) to see where in the line the intersection is. Store that as a fraction of the line between the start and end, and if it’s cutoff from the start (the start point of the next line is higher) or cutoff from the end (the end point of the next line is higher), and compare again against the next line down. If at any point the “start” fraction ends up bigger than the “end” fraction the line is fully occluded and you can skip. Otherwise you have a short line by itself. This assumes you’re keeping the line segments for every layer with the same spacing. If you want more segments in the last row vs the front this all gets way, way harder.

Still pretty damn expensive, depending on the number of line segments, and number of overlapping layers, but certainly plausible.

Kind of. I wanted to touch on this a bit because real-time procedural generation means smaller builds, and less stuff to load, but can mean more actual memory usage during generation, and the generation can take longer than loading pre-computed assets.

Wow, this is a very interesting suggestion. Will look further into this.
Since the background is repeating itself after a while I think the calculation of the terrain points can be finished before the level starts.
Only the visible points calculation has to be in real time.

The goal is to have a new background for every level without modifying anything manually.
So when the player reaches level 1000 for example there is an entirely new background there.

I try to make a game like williams defender from 1981, where there is only pure action and the background itself is not important but should give a kind of “out of this world” impression.