Where to start to achieve this effect?


Have been researching for a while but have no idea where to start to archive this effect. I don’t know if is better to try to archive it with postprocess, a material, a particle effect…

Basically what I want is make a mesh hidden except the polygons that are being illuminated by my spot light (ideally)

Is there a way to detect the amount of light from a source in a material?

Thank you.

there is no easy way for materials to know where light is hitting them. but there may very well be easy solutions to your problem once you tell us a bit more about your specific use-case. for example if your spotlight is in first person, etc.

Yes, it is for a single-player game, to use in first person camera only. It is for some kind of terror game when you only see the “ghost” when you focus him with a flashlight.

in that case you could figure out the spotlights position in screenspace (i’m assuming it’s moving around and not just in the center, which would make it even easier) and create a spheremask with that information to mask the mesh’s opacity.

I am not sure but may be distance fields can be used for this.

You should be able to solve this analytically using world positions without resorting to screenspace. If you know your flashlight position and direction in the world then you can solve it in your receiver material.

The basis for this will be a spheremask and we will be computing a cone instead of a sphere by calculating a different radius along the length of the line. Just going to off the cuff this so apologies if there are errors.

I would start by making a “Material Parameter Collection” where you add two Vector Params: FlashLightPosition and FlashLightDirection. In your player BP, set these MPC values using the flashlight position and rotation X vector (assuming it points along the X axis, adjust accordingly).

Next place “Absolute World Position” and “Spheremask” into your material for the receiver. Hook WorldPos into the “A” of the Spheremask.

The B of the spheremask will be more of an expression using a line:

FlashLightPosition + ( dot((WorldPosition - FlashLightPosition), FlashLightDirection) * FlashLightDirection)

That expression returns the closest point along the center of the flashlight beam for any point in the world.

Then radius just needs to be the Tangent of the cone angle times the length along the line.

The tangent can be calculated easily. Say your beam has a half angle of 12.25 meaning a total angle of 22.5. Your tan will be tan(12.25) = 0.1989

The length along the line can be extracted from the previous expression:

length( dot((WorldPosition - FlashLightPosition), FlashLightDirection) * FlashLightDirection )

I will try and test this out soon since there is a chance I messed something up.

I forgot to mention that the last line needs to calculate the length of the vector:

length( dot((WorldPosition - FlashLightPosition), FlashLightDirection) * FlashLightDirection )

Once I fixed that I tested it out and it works perfectly.


Then to make this work for visibility you can change the ‘hardness’ of the spheremask and use it as an opacity mask. Keep in mind this won’t have shadows from the environment and if you need those, you will likely need a much more elaborate features like a scene capture just to get the scene depth as seen from the light. Or you could try to raytrace the scene depth for intersection.

Thank you everyone for your advice.

RyanB, thank you especially for such detailed explanation, I’m going to try it. :slight_smile:

RyanB’s approach is what I’d do, too – use a special material for the ghost, feed the flashlight parameters into the material, calculate visibility there.

Work like a charm, thank you very much again!

Hello, this is an old post, but I need help. I can’t reproduce this effect, I think the problem is with the rotation of the Flashlight in my case. Coudl somebody give an example of a bp for “set these MPC values using the flashlight position and rotation X vector (assuming it points along the X axis, adjust accordingly).” ?

What did you do to make it work with opacity, could I see the BP if you still have it?
What I have so far is a material called InvisibleMaterial and have everything set up like in RyanB’s example but putting the material on any object just makes the object black and nothing else.

You need to set the flashlight direction on tick to ActorForwardVector of the flashlight, and the direction from ActorWorldLocation or whate

Was anyone able to get shadow casting done here?

Capture Scene Depth from Flashlight
If distance Flashlight : Pixel > Scene Depth, Mask out.

I have all the math in the blueprint and material right for a spotlight (complete with inverse square falloff, Lambertian diffuse, and various specular models), I just need to figure out how to align the render target to the scene properly. It needs to be aligned as if it was planar mapped from the flashlight onto the environment, and the FOV needs to match the angle of the light.

Bump. Made some progress with getting shadow map render target to align via world position, but it’s still not aligning quite right. Can anyone get these settings correct?