Main light direction inverted

Hello,

Has anyone experienced that the Main Light Direction shadergraph node outputs an inverted vector inside the simulator?

Looks like this was an oversight on our part. We’ll fix the issue in an upcoming release, but it’s probably worth noting that A. the coordinate space of the direction is Unity world space, and B. we currently just take the first light that matches the conditions for the PolySpatial Lighting node, regardless of whether it’s directional. In other words, you may experience issues with the node if you have multiple lights.

1 Like

If I run a Custom Function using the method GetMainLight().direction I still get it inverted. Did you transform it from one space to another in the “Main Light Direction” node? Is GetMainLight() giving the light in its model space?

I’m assuming this is not in visionOS/RealityKit/PolySpatial, because our support for custom function nodes when converting to MaterialX doesn’t include GetMainLight().direction. I can only tell you that we matched the behavior of the Main Light Direction shader graph node when converting it to MaterialX.

Looking at the code for the Main Light Direction node, I can see that it does in fact negate the result of GetMainLight().direction (for URP):

float3 shadergraph_URPMainLightDirection()
{
    return -GetMainLight().direction;
}

(you can see this in Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl)

Why is inverted? This is really, really wierd behaviour. When writing HLSL I would expect the direction to actually be the direction and not the opposite. And it is not documented either.

EDIT: Thanks for the tip on checking out the code in the package. I will do that more.

It’s not that weird. You’ll find that there are different conventions for light vectors based on how the lighting calculations are performed. One that’s very typical is to have a vector from the surface being lit to the eye (that is, pointing to the eye) and one that’s from the surface to the light (that is, pointing to the light–in the “opposite” direction of where the light is pointing). You can see an example of this convention in the diagram on this page. On the other hand, you can also find plenty of diagrams with the light vector pointing towards the surface. Typically, you just choose whichever convention makes the math simpler.

In this case, though, I suspect that the shader graph node was written for one render pipeline and needed to be consistent with all the other ones. If you look at what the other pipelines return for the node, HDRP returns something like _DirectionalLightDatas[lightIndex].forward; In other words, it uses the same convention as the shader graph node.

If you have more questions, you might try creating a new post with the shader-graph tag to get the attention of the shader graph team.