UE4.26:How to get the direction of specific directional lights in custom node material?

I have more than one directional light in level, I want to get the direction from a specific directional light,
how to code in custom node in UE4 material?
I’m using the version UE4.26 now~

I am assuming you want to know the vector of the light from any material, eg: you might want materials to have a specific path for being lit under a torch vs general-lighting?

If it was me I’d put the position of the light into a material-parameter-collection. Use a BP to grab the position of the torch and put it’s location in worldspace into the mpc. In the material, figure the vector you need from that position to whatever the material is on, etc, etc.

This is the same kind of trick that does the grass-bendyness via WPO as the character typically updates it’s position to an MPC so the grass-material can bend. Same deal here except you are sampling ‘somethings’ position for a lighting-path.

Thanks a lot first!
But not in this kind of situation.
I’m making a vedio.
In my level, there is a directional light for the environment,
and there are two lights for two different characters,
these characters are stylized characters ,
their face shadows are controlled by the direction of the directional lights .
I used different channels to make one light match one character,
but it doesn’t work,
the character will get a direction message from a random directional light in level.
So I replaced the light direction with three vectors!
And yes!I’m using MPC instead of light direction,
and marking different values on sequences,
so when the characters are moving,
the face shadows can get change together.

For what it is worth, if you’re using these directional lights as suns with the SkyAtmosphere system then you can get each light by their index in the material editor using the SkyAtmosphereLightDirection node, the light index option will be in the details panel.

Ok!Thanks ! I will try it when I meet some problems like this

Interesting. I am wondering if you came across a solution? I’m also trying to figure out how to direct my own light vector (and then add some others per shader).

I never implemented this but why this wouldn’t work:

  • iterate through the light actors you need to keep track of in either C++ or Blueprints; capture what you need, likely it’s world-position and rotation?
  • write those values into an MPC
  • sample within your material; position and/or rotation ought to give you enough to calculate a vector for each pixel and whatever else you might (likely) need

My point here being that if you want to calculate light in a material, likely per-pixel, the the maths attached to that pixel need to be able to read the direction/vector of the light(s) in question. So unless you set them directly against a material (instance), an MPC seems the best, logical-choice since it’s performant, has a decent capacity, and is readily-accessible from any material/C++/BP.

It’s about knowing what X and Y need to know about one another, and how they can laterally share information.

ok, looks like a trail (pun intended).
Indeed, MPC seem to be the solution. But I don’t want the shader to track the sun’s direction (or 1 single directional light). I’d like to have different (objects, no need to be a light) to direct my own light vector on the material.
I’ll keep trying.

Doesn’t have to be a light, you can put whatever you want into the MPC be it the position, rotation, scaling (or all 3!) of whatever, or whatever else; it’s just a number. And recall that an MPC is 1 thousand scalar & 1000 4vecs. That’s a decent amount of space, and each material can refer to 2 distinct MPCs as well.

If you want to fake lighting from objects, you can do fake lighting in the material. Just track the xyz of whatever thing you wanted, doesn’t have to be a light. It would be something like WorldPosition of the pixel minus the position of the thingie to get the vector from the thingie to the pixel. Math your whatever from there. You could likely use a dot-product of the vertexnormalWS against that vector and multiply-add that to the dot-product of the normalWS and that vector. This mask would always be facing the object, on whatever thing you put the material on.

Is this (sorta) what you are looking for?

1 Like

This is the approach I’ve been doing to further customize things. But I’m still locked into the world’s sun light direction.

If I understood in your reply, I should be able to drive XYZ values from the RGB channels of a (thingie).
I also tried to figure out if I need a scene BP to use “get unit direction”, output a vector and use that as a variable in the material shader as the custom vector.

Yeah, I get that I don’t really need a light, just to math out 2 object’s positions in regards of each other, dot product it, normalize it and then (plug it where in the shader)? That’s the part I’m confused about. I can certainly limit (stylize) the shadow in a custom RGB channel (let’s imagine in Green channel), but then I don’t know how to add that vector into the shader itself (is it emission, roughness?). Maybe I am not picking the correct Material (it should be always unlit, and a fake vector gives the shadow mask it’s orientation in object’s VertexNormalsWS?)

Please elaborate a little bit more over the points you mentioned + my questions above.
Thank you.

Its neither.
Shadows are done differently and not part of regular materials.

You can implement runtime GI shadows based on custom pixel adjacent math or vertex math on a meterial set to a non lit type.

Look for GPU Gem Articles explaining how.

To be honest, its painful at the very least.

A less painful alternative may be to apply a post process effect.
Maybe pan different intensity transparent PNGs to fake shadows on objects mapped to stencil values.

The intended use of the light vector was to do stuff like rotating items (sun flowers) along with the moving sunlight.
not calculating your own shadows.

Sure, you can do both thigs. But obviously calculating shadoes is complicated / needs its own .usf shader, which is why the engine has different models to pick from usually.

I’d always defer to MostHost_LA but my intent was to be able to make a mask, which you seem to have done, and from there…whatever. It’s essentially the ‘snow-mask’ using the normal-map and WS-up, but you can do whatever besides just tinting.

You’re never going to be able to fake lighting in the shader 100%, but you could brighten the RGB, add a dash of specular, whatever you felt you needed to do for the visuals. What I mentioned above was more just to isolate the area one would be doing those things to.

Lighting is handled by the engine ultimately, and what you can do in a shader won’t know about the totality of the world around it, so you won’t 100% be able to faithfully reproduce that lighting the engine would otherwise be able to do for you. Anything past the mask is just style, dependent on whatever you feel you need to do in your project.

If I implied you can just-reproduce lighting in the shader, not really, so my apologies for any confusion.

I mean, you can do stuff like mask out whatever pixel is hit in a certain way by the light (dot product, limit the result range to something) and filter the final value of it out by a multiply or lerping a color or whatever else you think.

But to be able to properly shade shadows you’d need to know about the light vector at each pixel to do it this way.
And you don’t really.
Even with an MPC and youd need a ray trace or a value for each mesh quad.

First you’d essentially be replicating how ray tracing works, second, you’d be doing it on a single object which is cheaper, but manually and in a non optimized way (material shaders vs .usf) which is slower.

The shader can know about self shadowing, at least in theory.
Comparing the light vector to the vertex normal gives you an idea of what side should be darker.

So long as you know that’s just an idea
And that it doesnt really mean your mesh is not in the shade of something else already…

1 Like

Just as a hard-follow-up-week trying things here and there, I finally made a custom vector work.
Unfortunately I did it with (another) direct light. Both light sources (sky light) and my custom (object) direct light competed, and cancelled out the clouds in the (default third person project) sky.
I figured I could set the Forward Shading priority to 5 (main sky light) and 0 to my custom (light object - direct light), but I have no result on the sky.

(Custom vector solved). Sorry, I did not understand anything about what you mentioned about the material producing the light in your previous reply.

I solved the custom light vector on my own , but I created another problem with lights.
(EDIT): I inadvertently chose “unlit”. Back to LIT: Default lights, everything runs great. Custom vector + scene lights work.