1
\$\begingroup\$

I've a 3D-game using perspective view, through raycasting, I create a mesh that represents the line of sight of my characters.

I'm looking for a way to "darken" (think old-school Fog of War - Unexplored = pitch black, explored but not in sight = darkened) the entire area outside of this mesh, preferably using a shader?

Black grid above scene doesn't really work well with perspective camera + mesh, as they create the hole based on the camera and not the unit. (i.e, I want the shader to act upon the characters line of sight and not the characters line of sight as seen by the camera - otherwise units can see behind walls).

Anyone have any pointers on how to achieve this?

In the following image, the white area is a mesh created by raycasting, I'd like to create a fog-of-war shader that darkens everything outside the LoS-mesh in screen-space.

enter image description here

The result should be similar to what you'd see in older roguelikes, I think it's called "shadowcasting", but in 3D.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ youtube.com/… . Also, if you want to create a fog of war then you need to change a texture every time fog of war changes. A common solution to this is drawing a very small texture, then scale it, then smooth it, then apply it to view. You can also use a ready solution, here you go github.com/LeLocTai/Fog-of-war . But your question isn't quite in the rules of the community. I have found all the tutorials and materials on this topic myself, this means you can do it too! \$\endgroup\$ – Candid Moon _Max_ Oct 11 '17 at 16:09
  • \$\begingroup\$ And it's like one of 20 questions about the fog of war in this community + this question doesn't add anything new. gamedev.stackexchange.com/questions/75957/… gamedev.stackexchange.com/questions/87456/… gamedev.stackexchange.com/questions/134040/… \$\endgroup\$ – Candid Moon _Max_ Oct 11 '17 at 16:13
  • \$\begingroup\$ @Candid Moon Those tutorials use a radius when drawing the fog of war, ie, for x radius, draw a lightened circle around this point. I am looking for tutorials where the shader creates the fog of war from my 2D (flat) mesh. The stencil shader only works in ortographic/topdown view - I'm looking for tutorials/resources/anything regarding similar shaders that works in 3D-perspective, I am currently editing my post and will add some pictures to create a better description. \$\endgroup\$ – ag4w Oct 11 '17 at 16:27
  • \$\begingroup\$ @DMGregory I apologize for being vague in my original post, I've edited the post and added pictures to clarify what I'm looking to accomplish. \$\endgroup\$ – ag4w Oct 11 '17 at 16:41
-1
\$\begingroup\$

Well, it appears to me that you already have part of the solution.

You should accumulate the raycast mesh over time, that gives you a 'memory' of what you've seen. Then you need to render your scene using two different lighting solutions ...

1) The Visible view - what your player character can see now. Use normal lighting such as HSAmbient + Point + Cone

2) The Seen (Memory) view - what your player character has seen. Use a darker lighting solution - eg hemispherical ambient lighting only.

Anything else is not rendered (black).

So looking at your image. You have the Visible mesh but you are making the mistake of rendering Not-Yet-Seen environment with the Visible lighting solution, specific to your image you have a global point/spot light lighting up unexplored environment - You should only render with environmental lighting when that environment is in LOS. So first render Has-Seen environment with ambient lighting solution (including the current visible mesh), then for the environment that intersects with your Visible mesh, render that with full lighting solution (excluding the already computed ambient term). You can then composite the two outputs.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Sorry for a slightly slow response, this causes multiple issues. Most notorious being that the mesh is 2D, it's not feasible to do volumetric raycasting due to performance reasons, and if I render the 2D mesh to the camera as some form of mask - I get artifacts along walls and similar where the player doesn't see "above" the mesh even though they should. This is solvable by raycast upwards from the mesh outline, but it's not very elegant and not really feasible in terms of performance either. I was really hoping this would be solveable via a screenspace shader instead. \$\endgroup\$ – ag4w Oct 12 '17 at 16:44
  • \$\begingroup\$ Some other ideas I've had are .. 1) Use the alpha layer (if you're not using it) or keep an extra texture for all surfaces, each texture / layer is a map of what part of the surface you've seen already. You can then check this texture in shader to know if you've seen the pixel before. 2) If you constrain the view to be orthogonal (at an angle - so isometric) then you'll have a 2d view of the world, and you can paint the visible scene onto a mega texture to record the level that you've seen. \$\endgroup\$ – Gavin Williams Oct 18 '17 at 9:35
  • \$\begingroup\$ This is really just half an answer. A good answer would not just talk about the theory but deliver a working solution. \$\endgroup\$ – Philipp Feb 13 '18 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.