Search Unity

Creating a light which only casts shadows?

Discussion in 'Editor & General Support' started by invulse, Sep 12, 2013.

  1. invulse

    invulse

    Joined:
    Nov 29, 2010
    Posts:
    128
    I have a dilemma that I've been trying to solve recently. I would like to have a directional light which only casts shadows and does not actually apply any light to the objects. I know I can make the light have a very low brightness which will cast a shadow, however when I do this I kill all of my real-time normal mapped and specular objects because getting a light source to cast a shadow requires it to be the brightest light source which is also the requirement for specular and normal mapped shaders and this low brightness light doesn't cast enough light on the real-time objects with normal maps and spec to actually show them.

    I would like if possible to just cast real-time shadows from a light (or some other source) then do the realtime lighting with a different light. Is this possible?
     
  2. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    To have a light only cast shadows, you would have to modify the shader of every object being hit by it. The light itself doesn't decide how its data is treated, the shader does. To have an object being lit by some set of lights, and then only shadowed by some other light, seems a little weird to me. Could you explain why? As for a solution, well, it would be clumsy. But some initial filtering of the lights array might be possible, and then doing different calculations per incomming light. But again...I want to understand why, and have some more specifics, before I even want to think deeper about it ;)
     
  3. invulse

    invulse

    Joined:
    Nov 29, 2010
    Posts:
    128

    Consider a situation where I have a complex lighting setup for an indoor scene using no directional lights. I want to have a single shadow for the player character but not have to use a directional light in the scene. If I could make a light which only casts shadows I could have a faked shadow being cast in only one direction for the whole scene, or I could get more complex and make a system which piggybacks the current light probes, bakes in which direction the most intense light is coming from at that point, then average that direction for the 3 probes as they currently do and have the shadows for the scene use a dynamic direction which is determined using this baked information. Maybe I'm going about this the wrong way but having a way to cast shadows without creating light would be the only way to do this.
     
  4. oysterCAKE

    oysterCAKE

    Joined:
    Dec 3, 2012
    Posts:
    149
    Does setting the light colour to black work for this?
     
  5. Harinezumi

    Harinezumi

    Joined:
    Jan 7, 2013
    Posts:
    54
    Sorry for necroing the thread, but I'm also trying to do have a light source that only casts shadows.

    I've just tried and a light with black color does not cast any shadows. I suspect that the black color effectively reduces the intensity to 0, so no shadows (or light) is cast.

    Other ideas? For example using different culling masks?
     
  6. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    The point is, the shadow is not drawn. It is the surroundings that are drawn. And so the shadow appears where light is not added to the illumination.
    You would have to make speciel shaders for it, that takes a specific light, and instead of treating it as an additive illuminator, it would do a multiplication on the diffuse intensity, where the shadow should be. And I don't know of a way to identify a specific light in a shader (And treat it as a multiplier in the shadow region). It would be possible to do it more manually, where you render your own shadow map from a specific position and direction, and then throw that down into a shader variable using scripting, together with a matrix that can translate geometry into this space, and calculate if it is visible from the vantage point of the node that created it.
     
    mikeohc likes this.
  7. Thirty9

    Thirty9

    Joined:
    Apr 6, 2015
    Posts:
    16
    Did you find anything functional?
     
  8. danbfx

    danbfx

    Joined:
    Feb 22, 2011
    Posts:
    40
    Every Maya type program has this it would be super helpful to separate the lighting from the shadows.
     
    ARealiti likes this.
  9. ARealiti

    ARealiti

    Joined:
    Oct 4, 2013
    Posts:
    133
    Upvote this so you can have 2 lights in a scene and have one for lighting from any angle and other for static shadow positioning, this is because from back on characters look terrible with ambient lighting it is just really bad.
     
    Last edited: Nov 21, 2018
  10. evapro

    evapro

    Joined:
    May 22, 2017
    Posts:
    5
    I know your problem. I'm facing the same case.
    let me explain the situation we face both:
    a. we have 2 different layers. named env and player.
    b. we have environment items which layer is env .
    c. we have a player gameobject which layer is player.
    d. we do lighting jobs( light map) using light sources but culling mask not set "player". and light source only for player.
    e. we want player project shadows on env.
    f. the problem came out, since unity generate through shader data, the env and player share different light data. unity could not auto generate the shadows we want.


    we want a solution to have shadows on env and do not want other light source break the env lighting baked results.
     
    Last edited: Aug 3, 2020
  11. evapro

    evapro

    Joined:
    May 22, 2017
    Posts:
    5
    i am wondering creating custom shaders and determine how to use lighting data to achieve goal.
    assume there are 3 lights ( 1 main and 2 point) . main light lights all and point lights light env only.
    I think I can access only point light in shaders for env GOs. I'll have it a try.
     
  12. JamesL98

    JamesL98

    Joined:
    Oct 9, 2014
    Posts:
    50
    Hi everyone, I'm a bit late to the party but i have a working cheap solution so i thought id drop it here for any lost puppies trying to find a solution.



    Here I added a point light at the suns source to light the distant planets appropriately (correct light/dark sides). And I added a script that just makes the directional light look at the player. If your shadowcast distance is low enough (mine is 400) then planets away from you will be lit from the wrong side but you wont see the other side at any point and the "front" of the planets will always be lit because of the point light. The only issue with this may be that if your player is able to zoom in or some planets orbiting others may be lit, I guess the point light even set to a large distance could still cast those big shadows accurately enough. Otherwise you could use a directional light specific for each planet and have the layermask on the directional light only apply to that one planet/body. Hope this helps.


    Code (CSharp):
    1. public Transform player;
    2.  
    3.     // Update is called once per frame
    4.     void Update()
    5.     {
    6.         transform.LookAt(player);
    7.     }