Search Unity

Spot and Point pixel light support in forward base pass?

Discussion in 'Shaders' started by gtpdzbiz, May 25, 2011.

  1. gtpdzbiz

    gtpdzbiz

    Joined:
    Mar 21, 2011
    Posts:
    53
    Is it possible to use pixel spot/point light in forward base pass? Looks like they are only available in the forward add pass though.:(
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    No, the base pass supports directional lights only. It calculates one using the standard lighting function, and additional directional lights by approximating them as spherical harmonics.
     
    furquijos likes this.
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Why? What if you don't want directional lights? You have to waste a pass on everything?
     
  4. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Isn't it possible to use 4 additional vertex lights in the forward base pass? From http://unity3d.com/unity/whats-new/unity-3.4 :

     
  5. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Yeah, the base pass is ambient + spherical harmonics + up to four vertex lights + the most influential directional light.
     
  6. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    I've written a small tutorial about how to use vertex lights in the ForwardBase pass: http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Multiple_Lights (mainly in order to show an application of a for-loop in GLSL).

    Strangely enough, unity_LightPosition[] doesn't work for me, neither with Unity 3.4 on Windows nor on MacOS X. I would appreciate it if anyone could test this on iOS. Thanks!
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I don't seem to be having success with unity_LightPosition, either. Thanks very much for that tutorial, but I'm not finding it practical, for point lights in the first pass, which I want, without the ability for the shader to incorporate the range of the lights. Any ideas? Are you just putting unity_LightAtten[x] into the shader in the hopes that it won't be broken eventually?
     
  8. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Good point. I guess I was thinking this way: for a given attenuation function and a given intensity of the light source, the range has to be chosen appropriately large to avoid artifacts. (Not the other way round where you would choose the attenuation function to reduce the intensity to 0 at the range of the point light.)

    Hm, I didn't try it but you might be able to use a script to encode the range in the alpha component of the color of the light. Of course, that's only a hack.

    Yes. :) Actually, I might also have overlooked something and there might be situations where these values are unequal to 1.
     
  9. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    I've found that unity_4LightAtten0 decreases when you increase the range of a "vertex"point light. (Multiply it by a small value to see that in action.) I'm not sure what that value represents exactly yet, but I'm going to go study the Shade4PointLights function in UnityCG.cginc, which should hopefully clear it up.
     
  10. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    LightAtten is, I believe, the attenuation of the light (distance of vertex to light relative to the lights range). It might also include the shadow value, as the regular surface shaders atten or the LIGHT_ATTENUATION(i) value does.
     
  11. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Thanks, I missed that. I fixed the tutorial. (I also fixed the upper limit of the for loop.)

    Based on code of built-in shaders I assume that the factors in unity_4LightAtten0 is multiplied to the squared distance between surface point and light source, then 1.0 is added and the light color is divided (i.e. attenuated) by the whole expression (see the code in the tutorial). Thus, a smaller value in unity_4LightAtten0 corresponds to a slower attenuation with distance (as it should be for an increased range.)

    I did some testing with two vertex lights, and wasn't able to see both vertex lights at the same time with the current code. However, a built-in shader behaves the same way and three vertex lights worked; thus, I assume this has to do with Unity sometimes deciding to handle vertex lights as spherical harmonics.