Search Unity

Get Main Light Position

Discussion in 'Universal Render Pipeline' started by Twin-Stick, Jan 17, 2020.

  1. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    Could someone please tell me how I'd be able to access the _MainLightPosition constant using shader graph?

    I've tried to get it via a custom function node but it tells me the variable isn't defined.

    I reviewed the source for URP and in the ForwardLights.cs (https://github.com/Unity-Technologi...-pipelines.universal/Runtime/ForwardLights.cs) it does indeed seem to be setting a global variable...

    Code (CSharp):
    1. void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData)
    2.         {
    3.             Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir, lightOcclusionChannel;
    4.             InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightOcclusionChannel);
    5.  
    6.             cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos);
    7.             cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor);
    8.         }
    And in the Lighting.hlsl library I can see it being used...
    Code (CSharp):
    1. Light GetMainLight()
    2. {
    3.     Light light;
    4.     light.direction = _MainLightPosition.xyz;
    5.     // unity_LightData.z is 1 when not culled by the culling mask, otherwise 0.
    6.     light.distanceAttenuation = unity_LightData.z;
    7. #if defined(LIGHTMAP_ON) || defined(_MIXED_LIGHTING_SUBTRACTIVE)
    8.     // unity_ProbesOcclusion.x is the mixed light probe occlusion data
    9.     light.distanceAttenuation *= unity_ProbesOcclusion.x;
    10. #endif
    11.     light.shadowAttenuation = 1.0;
    12.     light.color = _MainLightColor.rgb;
    13.  
    14.     return light;
    15. }
    Any help would be GREATLY appreciated!
     
  2. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    *UPDATE*
    It 'seems' as though I can now get it by wrapping it around an if SHADERGRAPH_PREVIEW statement, but it is set to 0,0,0
    Code (CSharp):
    1. #if SHADERGRAPH_PREVIEW
    2.     Color = 1;
    3.     DistanceAtten = 1;
    4.     ShadowAtten = 1;
    5.     LightPos = half3(10,10,0);
    6. #else
    7.     LightPos = _MainLightPosition;
    8. //..........//
    9. #endif
    Do I need to trigger the SRP to update the light constants manually? I would have assumed this would be done per frame based on the rendering diagram on the documentation -> https://docs.unity3d.com/Packages/c...rsal@7.1/manual/rendering-in-universalrp.html
     
    Last edited: Jan 17, 2020
  3. Elvar_Orn

    Elvar_Orn

    Unity Technologies

    Joined:
    Dec 9, 2019
    Posts:
    162
    Heyhey,

    Can I ask why you need the World Space Position of the main light?

    Main light is always a directional light so it doesn't have a position. It's actually bad naming of the variable in the shader calling it a _MainLightPosition. As you can see in the code snippet you posted above that it's actually the direction of the directional light.
     
  4. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    Ohhhh - yes you're totally right - I was so focused on finding the position I didn't really click that it is indeed the direction.

    In my project I'm basically wanting an omnidirecitonal light (a point light with no falloff I suppose) which will be a sun in a small solar system.

    This works perfectly if I hard code the light position, but this position will change at times.

    I'm aware of the issues with shadows and I will not be using realtime shadows.
    I suppose I could do this with a point-light and manually tune the light attenuation in my shader.

    After looking at the light struct I'd love to put the world position in there!
     
  5. Twin-Stick

    Twin-Stick

    Joined:
    Mar 9, 2016
    Posts:
    111
    Jackrabbit82 and lang_fox like this.