- Home /
Get Second Directional Light In Scene
I'm looking for a way to add a second directional light to my scene to represent the moon at night. It is meant to be passed into the skybox shader that I am using to provide the direction and other data for the moon to be rendered in the sky.
I am fully aware the there cannot be multiple directional lights casting shadows, which is all well and good, but I do want to be able to pull the other lighting data from it to use at runtime in the SRP Volume of my choosing.
Anyone have any relevant experience with doing this? I've been poking around in LightLoop.cs and the closest thing that I have found is a function titled GetDirectionalLightData(...). There is also a function called GetDominantLightWithShadows() but I wouldn't assume that would matter since there can only be one shadowcasting directional light
You shouldn't need to have two directional lights affecting the scene simultaneously, so I would suggest either using a single light and adjusting its parameters when appropriate or disabling one when it isn't needed so that the other becomes the scene's do$$anonymous$$ant light.
I'm afraid that doesn't solve my problems. To clarify, I'm trying to create a dynamic time of day system, and using one light or disabling one or the other yields awful results. The procedural sky turns to black by default once the sun is below the horizon, and enabling another light snaps it back to bright.
Not entirely sure how the procedural skybox works in SRP, but in the built-in pipeline you could specifically set the Sun object in the lighting window, which the skybox would use regardless of its intensity. If you are using a custom skybox to implement night rendering however, could you not pass some form of identification as to whether the directional light is the sun or the moon and then go from there using the same data?
Actually, that's sort of what I've been trying to do. SRP has a script called LightLoop.cs that, from what I understand, does things any time lights in the scene are changed. There's a function that gets data from each directional light (Implying the possibility of multiple dir-lights) that contains a conditional statement to get a "sun" light based on the shadowcasting properties. I'm currently testing to what extend I can extend this to also check for a moon light.
I do remember being able to explicitly define a sunlight in Built-in. Ah, simpler times. HDRP has been an adventure.
The light-loop controls all light rendering in the pipeline. The function you mentioned (GetDirectionalLightData) does indeed setup the appropriate light for use with the skybox;
...
// Fallback to the first non shadow casting directional light.
m_CurrentSunLight = m_CurrentSunLight == null ? lightComponent : m_CurrentSunLight;
...
If you wanted to extend the available light data, you can add your own components to the script (aptly named) "HDAdditionalLightData.cs". This component is added to all HDRP lights and allows you to add custom data to any light which is automatically passed into the light loop.
Interestingly enough, I did attempt to find where the sun is actually passed to the skybox, and it would appear that that functionality has been deprecated - ins$$anonymous$$d you are supposed to manually do it with emissives;
...
// 'renderSunDisk' parameter is not supported.
// Users should ins$$anonymous$$d create an emissive (or lit) mesh for every relevant light source
// (to support multiple stars in space, moons with moon phases, etc).
public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderForCubemap, bool renderSunDisk)
{
...
That is interesting, I didn't see anything related in there when I last looked at it. Perhaps we are looking at different versions; I am using 2018.4.6f1, with HDRP version 4.10.
That opens a few more questions. I've never seen emissive meshes used explicitly to represent these before, if this is indeed was is being done. Would those meshes then be purely visual? Would stars be represented as a simple sphere with a texture?
With a physically based atmosphere, how would it handle lighting? Does your version then use a volumetric solution? This has been the most promising answer I've gotten, but now I'm confused.
I think I've gotten a bit closer to a solution. The first thing I thought to do was to add support for a moon light in the built-in sky parameters, but to make that work involves modifying the rendering pipeline a bunch, and would not support much extension beyond one more light easily.
I have decided to modify or extend the AdditionalLightData as needed like @Namey5 spoke about, and attempt to create a new parameter for the SRP Volume framework to contain the data for the new directional light. The new parameter would have to extend the VolumeParameter class, from what I understand.
If this is successful, I will post a detailed answer as soon as I have time to do so.
A parameter containing a reference to a light has been created. I have successfully brought data from the reference into the SkyRenderer class and passed it from there into the shader. I will be closing this question with an answer soon and will attempt to find a way to publish what I have learned, in greater detail than I could here.
Answer by yourecrippled · Dec 30, 2019 at 02:22 PM
If you want a light to represent moonlight in your scene choose a right skybox shader for your project and try to find the best skybox reflection setting from lighting settings.
Yes, that's kind of the point. I am writing a procedural skybox shader, since the default one does not cover the scope of my project.
The lighting settings have absolutely no bearing on anything but GI since I am using HDRP. Reflections are irrelevant until the shader is finished, and to get it there, I need to pass in a second directional light. I hope this helps to clarify.