Download

Hide out of sight units : stencil or distance Field ?

Hello everybody :slight_smile:

Here’s my problem : I have units that have a “scanner” to see the world around them. They assaulted by a lot of foes.
The scanner sight is visualized in game with a spheric static mesh.
I want that the enemies that are outside one of these sphere are hidden in some way.

I’m thinking about 2 solutions :

Using distance field :

I have already activated the distance field in my project and use it a lot.
I can set the material of my enemies to use the distance field generated by the world and the scanner spheres. If the foe is inside something that generate distance field, the opacity of the enemy material is set to 1 and to 0 if it is outside.
This solution seams perfect for me but I have a lot of enemy units… Even if I use ditheringAA to smooth the shader complexity, I’m afraid of the performance cost for this…

Using Stencils :

I can use my spheres has a mask for the stencil I will use to render the enemies.
I don’t know exactly how to do this yet but I’ve seen some samples that let me thinking it will be pretty easy :slight_smile:
I think this solution has two problems (maybe just one, I’m not sure ^^)

  • The units will be rendered if they are see through the sphere, not only if they are inside… When the camera will see the game from a not so vertical point of view, it can be a problem.
  • I don’t know if I will be able to make the appearance and disappearance of the enemies smooth. With the distance field option, I can make a blur zone around the object and I can manage to make the ants appears smoothly.

As you can see, from an artistic and gameplay aspect, I prefer the distance field solution a lot.
But I’m afraid that having hundreds of translucent units at the screen will hit negatively the framerate of my game.
I can imagine that, once the units are render in a specific stencil, I can hide them without using a translucent material and doesn’t need to call the getNearestDistance node…

Is the stencil method a lot more performant than the distance field + translucency option ?

Maybe can you think at another solution for dealing with this ^^.

this seems something that should be handled by code
less is more! if a unit is outside the radius… hide it.
you save up on performance not just by avoiding translucency, but by rendering less

I had though at this solution but eliminate it because I believe that it will be too expensive to calculate the distance from any enemy to any units with a scanner, at each tick…
And I can’t make them appear smoothly…

Am I wrong about the cost of the calculus per tick ?
A hit test again the sphere in the enemy BP can be more effective ^^

EDIT : I can use the hitTest idea to hide the units outside the spheres and use the distanceField / transluscency thing to make them appear smoothly with a cool FX when they are inside… This way, I cut the cost of the outside units and have the cool FX too. The best of two world :slight_smile:

if done properly the cost in code should be significantly less. you’d be calculating each unit against each sphere in the worst case scenario, which you might optimize with octree or similar solutions, or limiting the amount of calculated units per frame, etc. and there are other methods like using collision touch responses as you say.
on the other hand accessing the global distancefield data in a material is quite costly from what I’ve seen, and you might start having problems with other meshes that generate distance fields as well (i.e. how do you filter your sphere from anything else in the world that generates distance fields?)

you might want to consider other fancy types of warp/dissolve effects instead of just a translucent fade. translucency has multiple limitations like incorrect depth sorting (if you have translucent water in your level you’ll start having a headache, but even just units clipping through eachother will cause issues) as well as the very limited shadow resolution and shadow-distance available for translucent objects (as they use an entirely different shadowing system which is based on voxels), not to mention the high pixelshader cost neeeded to [almost] have the same shading capabilities as solid/masked.

The spheres are the only object that generate distance field for now… I don’t need to filter them…But I want to use the distance shadowing system so that not a good argument :slight_smile:
I don’t know anything about octree but I will read a bit on this subject. I can put the calculus in my enemies IA and check the sphere only each 0.5 sec with a bit of random ^^

I can do something cool with a masked material ! I see in the shader complexity preview that a masked material fully opaque is render as a opaque one.

If you are doing test per pixel you do that one two million times.(for 1080p) CPU method should be couple magnitude faster than pixel shader method. And cpu method saves additional gpu performance by rendering less. You can also do the fancy shader for objects that are in transition zone and cheap shader that are fully inside the circle.

When you speak of “test per pixel”, you speak about the stencil option, right ?
I’ m actually setting a collision sphere with a radius a little bit larger than the visible sphere.

When a unit is outside this collision sphere, it is hidden.
When inside the collision but outside the sphere, i perform my FX with translucency (masked, I think) and everything.
When the unit is inside the visible sphere, I will swap the material to a simple one.

That way, I hide the non visible units, perform any effect I want in the transition and finally, get a simple opaque material when the transition is finished…
It seams to me that it’s the best solution to get every thing I want without losing too much FPS.
I will give you some feedback when ready.
Thank for your help :slight_smile:

EDIT : About the filter of the world from the scanner sphere with distance mesh, There’s no problem in deed because I work with negative value of the distance field (inside the mesh) and the foes units will never be inside another volume than the sphere <- that’s a better argument ^^

The best way to get rid of any other distant field is to create a sphere mask with same radius and location you are using to create those sight spheres. You can use a parameter to adjust the radius and another one to use in the sphere mask hardness to create a transition area around the sight spheres… this will help you to have the transition effect (FX) for the units material to appear smoothly and not be bothered by any other distance field. The cost for the sphere mask is pure math, few instructions, plus the masking operation 1-x and multiply, so is damm cheap. Im not sure how you set up your materials, but in some cases you can save time from shaders generating render targets somewhere else, so you will not need to repeat the operations per units, in the end the time expent from CPU+GPU generating and saving the rendertarget will be compensated by the time you are saving in the materials elsewhere using the resulting rendertargets.

I use the distance field to make one object from several spheres. But what you’re suggesting about the sphere mask seams very interesting to me. But how the material of a enemy can use the sphere mask in the sphere material without something like distance field ?
I didn’t get anything in what you explain on the render target… I have so much to learn ^^

Render target is an object you can use like a texture, meaning every place you can use a Texture2D you can use a Render Target. To put content into a render target you use a blueprint and call a node called Draw Material to Render Target, where you feed the material and the destination render target. I have posted a video where I have used a sphere mask to cut a postprocess, it is very simple, and I do explain what to do for multiple elements. It is not exactly what you have, but will make you understand at least the sphere mask part. https://youtu.be/FUxQAv5FIuM

I know sometimes all seems a huge puzzle… which we will check each piece and learn how to fit all together to solve it. It is perfectly normal…

After the video and reading my previous paragraph more this one, the whole thing will look more feasible. It might make you change a bit the current solution. Don’t worry yet with the performance cost, but first get the solution working for after that come back here and tell us the progress and then we will discuss how to make it more performatic.

Thank a lot :slight_smile:
I think your render to target thing can serve so much purpose !

It’s not that my project is too complex but every time open a door, it’s a whole universe of possibility and new ideas that pop up :slight_smile:
UE4 is a bottomless pit of wonderfulness !

EDIT : looked at your video and you speak a lot about sphere mask and go very quick on the blending system at the end ^^
I realize I have a very weak knowledge of PP :slight_smile:

Wokay :slight_smile:

So, I make a service that is run by the AI of the foes.
This way, the calculus of the distance from a foes to an ally unit is repartited in time and every foes doesn’t perform the check at the same time.
The enemy units are hidden if they are outside the bubble but I had a little offset to the radius of the bubble for the ants to appear before they are inside the sphere and disappear after they’re out.

I also use the already existing distance field of the bubble to build an opacity mask in the foe’s material, witch is masked.

It works perfectly and smoothly !

portee_preview_2.jpg

I certainly can remove the shadow of the enemies when they are visible but outside the sphere but in fact, when I saw this, I was very happy with this unwanted effect :slight_smile:
It’s like the Martian can detect a presence a bit before seeing it for real… Or when the foe get out the sphere, we still see his shadow for a small time and it’s pretty cool !

My enemies have a masked material… but the impact on the render time is not so bad… Inside the sphere, they are fully opaque and doesn’t affect the shader complexity. When they are far enough, they are hidden.
portee_preview_complexity.jpg

They have a non 1 opacity only in the small zone around the sphere. It’s a good deal for me :slight_smile:

I still have to make the fancy effect at the intersection of the enemy and the bubble ! Let’s go ^^

Thank a lot for all your advises.

Yay, it is really cool. If those shadows were like a generic shadow or something even more faint in shape, you could cause some goosebumps in the players because he could see the approach of the shadow without knowing exactly the real type of enemy approaching (at least for the 1st time encounter), so supposing you have bigger foes, that would cause an “impact” on the player.

Kudos for managing yourself implementing this far as it is. You seen really competent in understanding concepts, which is a great value for any professional and I foresee a bright future for you!

Woh ! That’s very nice.

About the shadows, I will soon test the distance shadowing. I heard tha it can be more performant in great exterior level and the blurred shadow are certainly beautiful !
I will see how the enemies shadows react.
I’ve been thinking at add some staticMesh in the enemy BP that react to the distance field in the opposite way : off inside, on outside the bubble.
Then, I can use this SM, visible only outside the bubble to make this “presence reminder”…

I will see :slight_smile:
Nevertheless, thank for your help :slight_smile: