Search Unity

Realtime light showing even when fragment shader just samples texture

Discussion in 'Shaders' started by Spaniel, Aug 22, 2018.

  1. Spaniel

    Spaniel

    Joined:
    Dec 23, 2012
    Posts:
    52
    I used ShaderForge to write the base for a complicated shader I need for a project. The shader features interpolation between a night and day lightmap, mixing sky light color and support for dynamic moving lights as well. Currently, I am trying to fix an issue with the dynamic lights and stripped the fragment shader down to virtually nothing so I can debug. The problem is, that the surface is illuminated by a dynamic light I have placed in the scene for testing, but for the life of me, I can't figure out why it's showing the light contribution.

    Here is the fragment portion of the shader that I completely stripped down:

    Code (CSharp):
    1.     float4 frag(VertexOutput i) : COLOR
    2.     {
    3.         float4 _MainTex_var = UNITY_SAMPLE_TEX2DARRAY(_MainTexArr, float3(i.uv0.x, i.uv0.y, _TextureIndex[(int)(i.uv0.z)]));
    4.  
    5.         return _MainTex_var;
    }

    It samples the color from the texture array (which is not the issue) and returns it. The issue I am having is that I can see light on the surface. Forgive the ugliness of the example but it's a plane surface with the tree leaves texture and I have put a green dynamic light right next to it. It shows up even though the fragment shader shouldn't handle lights:



    Where is this light calculation coming from? Am I missing something completely fundamental about shaders? I was under the impression if I sample just the texture color, no lighting would be displayed.

    To recap:
    1. Trying to debug dynamic lights with shader.
    2. Stripped shader down to just texture color.
    3. Am still seeing the dynamic green light on the surface.

    No idea why. Thank you!
     
  2. Spaniel

    Spaniel

    Joined:
    Dec 23, 2012
    Posts:
    52
    Update: Seems like I wasn't going crazy. But it's apparently hitting the secondary fragment shader too (contained within the same file). I had no idea that was possible. Can anyone illuminate the reasons for having two fragment shaders in one shader file?
     
    Last edited: Aug 22, 2018
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Because that's how Unity's forward renderer works. The ambient lighting, reflections, per vertex lights, baked lighting, and main directional light get rendered with the ForwardBase pass. Each additional real time light that affects a mesh renders the entire mesh another time using the ForwardAdd pass.
     
  4. Spaniel

    Spaniel

    Joined:
    Dec 23, 2012
    Posts:
    52
    Makes sense. In my case, I don't have a directional light. I just have lightmaps, and then x amount of dynamic lights.

    I will better formulate my question tonight and update with the full shader source. Thanks as always, bgolus.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    So the ForwardBase pass renders the mesh using the lightmap, and the ForwardAdd pass renders the dynamic lights. Try using the Frame Debugger, it might give you a better idea of what's going on.
     
  6. Spaniel

    Spaniel

    Joined:
    Dec 23, 2012
    Posts:
    52
    You're absolutely correct. Good to know!

    Here is the issue I am facing. I calculate the lighting like this:
    1. Interpolate between day (sunlight) and night (zone light) lightmaps based on time of day.
    2. Add in the sky color but only in areas where the day lightmap has illuminated the world (i.e. areas the sun would hit) and areas where the zone lights (torches, campfires) DO NOT illuminate.

    This looks great! But I need to have the player's dynamic light also affect this. My original idea was to combine the players light (which is apparently calculated in a a ForwardAdd pass) to the zone lights color but as they are calculated in different passes, I am not sure this is possible.

    Would be great if I could get all this data somehow in the ForwardBase pass but I assume this isn't possible.

    Let me know if you'd like me to clarify my shader or if you have any other questions.