TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

How to create 2D visibility/shadow effects for your game

305 pointsby ncasenmareabout 11 years ago

16 comments

dlluabout 11 years ago
Related:<p>1) a tutorial on the same topic by Red Blob Games: <a href="http://www.redblobgames.com/articles/visibility/" rel="nofollow">http:&#x2F;&#x2F;www.redblobgames.com&#x2F;articles&#x2F;visibility&#x2F;</a><p>2) a public domain Javascript visibility polygon library that runs in O(n log n), which is actually used in the Nothing to Hide game: <a href="https://code.google.com/p/visibility-polygon-js/" rel="nofollow">https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;visibility-polygon-js&#x2F;</a><p>3) a blog post by author of said library discussing the algorithm: <a href="http://byronknoll.blogspot.ca/2013/05/on-log-n.html" rel="nofollow">http:&#x2F;&#x2F;byronknoll.blogspot.ca&#x2F;2013&#x2F;05&#x2F;on-log-n.html</a><p>Shooting a ray to every vertex and then naively computing intersections takes O(n^2) since there are n rays with up to O(n) intersections each. It is interesting to read and think about O(n log n) algorithms for computing the visibility polygon.
评论 #7382096 未加载
tjaervabout 11 years ago
You, sir, must be from the future, what with the uncopyrighted, bitcoin-based crowdfunding campaign. Backing this effort is a no-brainer.<p><a href="https://back.nothingtohide.cc/" rel="nofollow">https:&#x2F;&#x2F;back.nothingtohide.cc&#x2F;</a>
评论 #7382503 未加载
评论 #7382757 未加载
评论 #7382455 未加载
highCsabout 11 years ago
Nice article. However I think there&#x27;s a better algorithm: the one actually used in Doom from Id Software.<p>First the scene must be put into a 2d bsp (that requires slicing some edge). After that, the bsp must be traversed front-to-back and that gives the edges in the right order. Just keep track of which angles are occluded then while traversing. During the process, when an edge is proccessed, cast&#x2F;create the shadow accordingly. The algorithm stop when the field of vision is fully occluded - and not farther.
评论 #7385347 未加载
shurcooLabout 11 years ago
Very cool article. Providing actual working demos for each step makes the technique a lot easier to explain to others.<p>I had fun implementing this effect a long time, in a pre-graphics-shader era [1].<p>[1] <a href="https://github.com/shurcooL/eX0#screenshots" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;shurcooL&#x2F;eX0#screenshots</a>
评论 #7383708 未加载
Osmiumabout 11 years ago
Really cool tutorial. It also looks like the author has a pledge drive ending today, and he&#x2F;she is really close to hitting their funding goal. Would be a shame to miss it while being so close, especially for something that looks so promising.<p>(Note: I have no connection to this developer. Just thought it was worth mentioning.)
DanAndersenabout 11 years ago
Great presentation of the information. The interactive sections are really good at conveying the concepts.
liabruabout 11 years ago
Nice example, but ray casting like this is overkill for this effect and with a low number of rays it&#x27;s pretty inaccurate.<p>I prefer using the technique shown in this classic article on 2D soft shadows: <a href="http://archive.gamedev.net/archive/reference/programming/features/2dsoftshadow/" rel="nofollow">http:&#x2F;&#x2F;archive.gamedev.net&#x2F;archive&#x2F;reference&#x2F;programming&#x2F;fea...</a><p>The basic idea is to project the geometry, rather than ray cast. I&#x27;ve implemented this sort of technique in the past and it works well.
kevingaddabout 11 years ago
I have an open source XNA&#x2F;MonoGame implementation of a similar lighting technique available here:<p><a href="https://github.com/sq/Illuminant" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;sq&#x2F;Illuminant</a><p>It&#x27;s hardware-accelerated and has a few other useful features; we&#x27;re using it in Escape Goat 2 and it works on Windows&#x2F;Linux&#x2F;Mac on pretty much any D3D9-spec hardware. You can see some of the levels using it here: <a href="https://www.youtube.com/watch?v=-9s1PyotS18#t=1m20s" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=-9s1PyotS18#t=1m20s</a><p>For EG2 we have a pair of separate lighting environments; one for the foreground plane and one for the background plane. Most light sources exist on both planes but have different parameters in order to create a depth effect; some light sources are only on the background plane. We apply a customized ramp texture to the light sources in order to replace the smooth attenuation with quantized attenuation, and we don&#x27;t use soft shadows (though we do render lighting at a lower resolution and upscale it, because that softens things a little.) We also do a simple HDR camera model by sampling lighting intensity across the scene&#x27;s foreground&#x2F;background planes and using that to adjust the range of the final lightmap so that we can automatically tune exposure&#x2F;white point etc to highlight certain parts of a level.<p>I also have a similar pure-software-rendering lighting library from around ~8 years ago available here, in C++:<p><a href="https://github.com/kg/Fury2/blob/master/libraries/SoftFX/module/Fury2.cpp#L2708" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;kg&#x2F;Fury2&#x2F;blob&#x2F;master&#x2F;libraries&#x2F;SoftFX&#x2F;mod...</a><p>That one&#x27;s garbage, but may still be of some use.<p>I&#x27;ll note that the author&#x27;s approach (needing extra intersection points at +- 0.00001 radian) is a little perplexing. I&#x27;m not sure why that is needed; I&#x27;ve never needed it.<p>A better approach for &#x27;fuzzy&#x27; shadows is to model the penumbra; you can render it as a single triangle that borders on the actual shadow umbra and then make it smooth by using a simple lookup texture. This technique is described here:<p><a href="http://archive.gamedev.net/archive/reference/programming/features/2dsoftshadow/page4.html" rel="nofollow">http:&#x2F;&#x2F;archive.gamedev.net&#x2F;archive&#x2F;reference&#x2F;programming&#x2F;fea...</a><p>Another great option for 2D lighting is to associate normal maps with your sprites and do per-pixel lighting against each light source using the normal map. This can produce some really great results. I think that SpriteLamp, <a href="http://snakehillgames.com/spritelamp/" rel="nofollow">http:&#x2F;&#x2F;snakehillgames.com&#x2F;spritelamp&#x2F;</a> does this; the Fury2 library I linked above also did per-pixel sprite lighting with normal maps. The upcoming game Full Bore (<a href="http://www.wholehog-games.com/fullbore/" rel="nofollow">http:&#x2F;&#x2F;www.wholehog-games.com&#x2F;fullbore&#x2F;</a>) is using per-pixel lighting on its sprites and environment art, and I believe Spelunky for PC&#x2F;XBLA uses it on environment art.
ANTSANTSabout 11 years ago
I&#x27;m kinda tired of the &quot;cone-of-vision&quot; mechanic and associated visual effect common in modern 2D games. In traditional 2D games, being able to see things that are not visible to the player&#x27;s avatar is, IMO, a significant part of the charm. Not being restricted to a realistic viewpoint lets you become the larger-than-life hero of cartoons and cheesy action movies that does impossible things like leaping into a room full of bad guys and shooting them all before they have a chance to react, or &quot;sensing&quot; someone behind him and dodging the arrow at the last second. When you make a 2D game that tries to &quot;realistically&quot; limit the player&#x27;s view, you&#x27;re getting the downsides of <i>both</i> 2D and 3D games. It says to me, &quot;I really wanted to make an FPS but I don&#x27;t know how.&quot;<p>No criticism is intended towards OP&#x27;s game; the &quot;un-stealth game&quot; is a different and interesting idea. I&#x27;m just throwing it out there for those dreaming up yet another top-down cone-of-vision stealth shooter to chew on.
评论 #7383901 未加载
评论 #7383247 未加载
jherikoabout 11 years ago
this is interesting (although this sort of effect has never mystified me) - i can&#x27;t help but think how this can be optimised. the steps gone through here are things i never would have done and the final solution is about where i would start...<p>just blindly tracing to all of the verts &#x27;feels wrong&#x27; its the sort of thing that is intuitively unreasonable with large data sets and is quite obviously going to be constrained by available horsepower at some size.<p>precomputed vis data is the obvious optimisation and removes the O(n) behaviour. not only do you not have to test everypoint but your raycast itself need not test every edge. i wrote something ages ago about generating PVS in 2d as an example of how to approach the problem in 3D...<p>(<a href="http://jheriko-rtw.blogspot.co.uk/2011/05/visibility-determination-with-convex.html" rel="nofollow">http:&#x2F;&#x2F;jheriko-rtw.blogspot.co.uk&#x2F;2011&#x2F;05&#x2F;visibility-determi...</a>)<p>the other thing that bugs me here is the jitter. it is the classic &#x27;lazy&#x27; way to soften shadows... a better effect can be gotten for less - if you offset the light position perpendicular to the direction toward the test vert, in both directions by the same amount then you can generate two ray casts. triangulating the resulting mesh might be a little painful (unless you cut the world into convex chunks - then it is nearly trivial) but you will get the outline for both edges of the shadow and can then do something like vertex interpolated colour to give you the same visual result as infinite raycasts for the price of two...
thewarriorabout 11 years ago
I learnt the parametric representation of a circle sometime in highschool but never remember learning the representation of a line segment.
评论 #7386609 未加载
MasterScratabout 11 years ago
Illuminated.js did something very similar:<p><a href="http://bit.ly/LZ2dq1" rel="nofollow">http:&#x2F;&#x2F;bit.ly&#x2F;LZ2dq1</a>
supercoderabout 11 years ago
Brilliant work on the presentation!
wudfabout 11 years ago
This is really awesome. Thanks a lot for breaking down your process, it&#x27;s both enlightening and inspiring for me just starting out.
shultaysabout 11 years ago
This could be achieved a lot simpler using an algorithm like shadow volumes
Mithalduabout 11 years ago
He uses a nice trick to approximate the real thing, however this algorithm wouldn&#x27;t be able to deal with curved objects.
评论 #7382014 未加载
评论 #7382494 未加载
评论 #7382008 未加载