Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Directional light shadow moves w/ player

Discussion in 'Editor & General Support' started by techbinge, Dec 3, 2007.

  1. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    I'm using the sample First Person Controller prefab in a simple scene along w/ a single directional light that has shadows turned on. For whatever reason, as I move the player around using W,A,S,D, the shadow appears to move as well.


    Any thoughts?

    Thanks!
     
  2. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Is it possible that you have the directional light childed to the player?
     
  3. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    Its in the prefab, and its not under any of the prefab objects in the hiearchy view. This should mean its not a child of anything correct? I tried parenting the directional light w/ another scene model but the shadows still moves w/ the player.

    I tried placing a spot light w/ shadows on and that seams to work fine.

    Thanks for the response though!
     
  4. Harry1960

    Harry1960

    Joined:
    May 15, 2007
    Posts:
    136
    The CharacterShadow script doesn't move with the player since it's logic only uses point lights and therefor their positions. You just have to move the light with you'r player on use a different ortographic view.
    The side effect is that you'll get much sharper/detailed shadows with the same texture size.
     
  5. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    not sure if you read my question or if I'm misinterpreting your suggestion, but I want nice static shadows as if from a sun (yes, dynamic, not baked) however when I move w/ the FPS prefab the shadows move as well.
     
  6. Harry1960

    Harry1960

    Joined:
    May 15, 2007
    Posts:
    136
    Look at my changes in CharacterShadow the changes work fine in my project. The script examines the light type and changes it's behaviour. When using a dirctinal light the projector (not the light) gets moved with the player.



    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class CharacterShadow : MonoBehaviour
    4. {
    5.     public GameObject target;
    6.     public float castingDistance = 10.0f;
    7.     public float lightness = 0.6f;
    8.     public int textureSize = 512;
    9.     public Texture fadeoutTexture;
    10.     public bool blur = false;
    11.     public int blurIterations = 1;
    12.     public LayerMask ignoreLayer; // don't cast shadow on this layers
    13.     public LayerMask targetLayer; // all objects within this layer are used to cast shadows
    14.     public float directionalOffset = 1.0f;
    15.    
    16.     private RenderTexture shadowmap;
    17.     private GameObject child;
    18.     private Projector proj;
    19.     private Camera cam;
    20.     private int savedPixelLightCount;
    21.    
    22.    
    23.     private static string shadowMatString =
    24. @"Shader ""Hidden/ShadowMat"" {
    25.     Properties {
    26.         _Color (""Color"", Color) = (0,0,0,0)
    27.     }
    28.     SubShader {
    29.         Pass {
    30.             ZTest Greater Cull Off ZWrite Off
    31.             Color [_Color]
    32.             SetTexture [_Dummy] { combine primary }
    33.         }
    34.     }
    35.     Fallback off
    36. }";
    37.  
    38.     static Material m_ShadowMaterial = null;
    39.     protected static Material shadowMaterial {
    40.         get {
    41.             if (m_ShadowMaterial == null)
    42.                 m_ShadowMaterial = new Material (shadowMatString);
    43.             return m_ShadowMaterial;
    44.         }
    45.     }
    46.    
    47.     private static string projectorMatString =
    48. @"  Shader ""Hidden/ShadowProjectorMultiply"" {
    49.     Properties {
    50.         _ShadowTex (""Cookie"", 2D) = ""white"" { TexGen ObjectLinear }
    51.         _FalloffTex (""FallOff"", 2D) = ""white"" { TexGen ObjectLinear }
    52.     }
    53.     Subshader {
    54.         Pass {
    55.             ZWrite off
    56.             Offset -1, -1
    57.             Fog { Color (1, 1, 1) }
    58.             AlphaTest Greater 0
    59.             ColorMask RGB
    60.             Blend DstColor Zero
    61.             SetTexture [_ShadowTex] {
    62.                 combine texture, ONE - texture
    63.                 Matrix [_Projector]
    64.             }
    65.             SetTexture [_FalloffTex] {
    66.                 constantColor (1,1,1,0)
    67.                 combine previous lerp (texture) constant
    68.                 Matrix [_ProjectorClip]
    69.             }
    70.         }
    71.     }
    72. }";
    73.  
    74.     private Material projectorMaterial = new Material (projectorMatString);
    75.    
    76.     void Start()
    77.     {
    78.         if( !target )
    79.         {
    80.             Debug.Log("No target assigned! Disabling CharacterShadow script");
    81.             enabled = false;
    82.             return;
    83.         }
    84.        
    85.         if( ignoreLayer == 0 ) {
    86.             Debug.Log("Warning: target layer should use a separate layer (!=default)");
    87.             // still continue...
    88.         }
    89.        
    90.         // create a child camera/projector object
    91.         child = new GameObject("ChildCamProjector");
    92.         cam = (Camera)child.AddComponent("Camera");
    93.         proj = (Projector)child.AddComponent("Projector");
    94.         child.AddComponent("CharacterShadowHelper");
    95.         if (blur) {
    96.             child.AddComponent("BlurEffect");
    97.             // adjust iterations as needed or better expose a property
    98.             ((BlurEffect)child.GetComponent(typeof(BlurEffect))).iterations = blurIterations;
    99.         }
    100.            
    101.         cam.clearFlags = CameraClearFlags.Color;
    102.         cam.backgroundColor = Color.white;
    103.         cam.cullingMask = targetLayer;
    104.         cam.isOrthoGraphic = true;
    105.        
    106.         proj.isOrthoGraphic = true;
    107.         proj.orthoGraphicSize=1.0F;
    108.         proj.ignoreLayers = ignoreLayer;
    109.         proj.material = projectorMaterial;
    110.         proj.material.SetTexture("_FalloffTex", fadeoutTexture);
    111.        
    112.         child.transform.parent = transform;
    113.         if (light.type!=LightType.Directional) {
    114.             child.transform.localPosition = Vector3.zero;
    115.             child.transform.localRotation = Quaternion.identity;
    116.         }
    117.         else {
    118.             proj.transform.rotation = transform.rotation;
    119.         }  
    120.     }
    121.    
    122.     void Update()
    123.     {
    124.         if (!shadowmap) {
    125.             shadowmap = new RenderTexture( textureSize, textureSize, 16 );
    126.             shadowmap.isPowerOfTwo = true;
    127.             shadowmap.wrapMode = TextureWrapMode.Clamp;
    128.             cam.targetTexture = shadowmap;         
    129.             proj.material.SetTexture("_ShadowTex", shadowmap);
    130.         }
    131.         OrientToEncloseTarget();
    132.     }
    133.    
    134.     void OnEnable()
    135.     {  
    136.         if (proj)
    137.             proj.enabled = true;
    138.     }
    139.  
    140.     void OnDisable()
    141.     {
    142.         if (proj)
    143.             proj.enabled = false;
    144.     }
    145.    
    146.     public void OnPreRender()
    147.     {
    148.         savedPixelLightCount = Light.pixelLightCount;
    149.     }
    150.                
    151.     public void OnPostRender()
    152.     {
    153.         shadowMaterial.color = new Color(lightness,lightness,lightness,lightness);
    154.        
    155.         GL.PushMatrix();
    156.         GL.LoadOrtho();
    157.         // LoadOrtho loads -1..100 depth range in Unity's
    158.         // conventions. We invert it for OpenGL
    159.         // and pu the depth at the very far end.
    160.         const float depth = -99.99f;
    161.        
    162.         for (int i = 0; i < shadowMaterial.passCount; i++)
    163.         {
    164.             shadowMaterial.SetPass (i);
    165.             GL.Begin (GL.QUADS);
    166.             GL.TexCoord2(0,0); GL.Vertex3( 0, 0, depth );
    167.             GL.TexCoord2(1,0); GL.Vertex3( 1, 0, depth );
    168.             GL.TexCoord2(1,1); GL.Vertex3( 1, 1, depth );
    169.             GL.TexCoord2(0,1); GL.Vertex3( 0, 1, depth );
    170.             GL.End();
    171.         }
    172.         GL.PopMatrix ();
    173.        
    174.         Light.pixelLightCount = savedPixelLightCount;
    175.     }
    176.    
    177.     private void OrientToEncloseTarget()
    178.     {
    179.         Vector3 center = target.transform.position;
    180.         // REMARK: radius fails if the mesh data is not found in the target (e.g. mesh is found in childs only)
    181.         float radius = 5.0f;
    182.         if( target.renderer ) {
    183.             Bounds b = target.renderer.bounds;
    184.             center = b.center;
    185.             radius = b.extents.magnitude;
    186.         }
    187.        
    188.         if (blur)
    189.             radius *= 1.1f;
    190.         else   
    191.             radius *= 1.05f;
    192.            
    193.         if (light.type!=LightType.Directional) {
    194.             float distance = (center - transform.position).magnitude;
    195.            
    196.             child.transform.LookAt( center );
    197.            
    198.             cam.orthographicSize = radius;
    199.             cam.nearClipPlane = distance - radius;
    200.             cam.farClipPlane = distance + radius;
    201.            
    202.             proj.orthoGraphicSize = radius;
    203.             proj.nearClipPlane = distance;
    204.             proj.farClipPlane = distance + castingDistance;
    205.             proj.material.SetTexture("_ShadowTex", shadowmap);
    206.         }
    207.         else { // directional
    208.             radius = 1.2F;
    209.            
    210.             // der Projektor wird einfach mit dem target-Objekt mitgeführt
    211.             child.transform.position = target.transform.position;
    212.             child.transform.Translate(-transform.forward*directionalOffset);  
    213.            
    214.             cam.orthographicSize = radius;
    215.             cam.nearClipPlane = 0.01F;
    216.             cam.farClipPlane = castingDistance;
    217.  
    218.             proj.orthoGraphicSize = radius;
    219.             proj.nearClipPlane = directionalOffset-0.2F; // capsule radius*2
    220.             proj.farClipPlane = castingDistance;
    221.             proj.material.SetTexture("_ShadowTex", shadowmap);
    222.         }  
    223.     }
    224. }
    225.  
    [/code]
     
  7. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    I'm not sure I understand the problem. You have a character. When it moves, it's shadow also moves.

    Isn't that what you want? Do you want it's shadow to stay in the old place instead?
     
  8. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    I *think* he wants roughly the same effect as a blob shadow, actually (but dynamically animating with the model.)

    In other words, the light source is SO high (the sun) that the angle of the shadow doesn't shift and stretch.

    So, that's why the suggestions of moving the light source with the character came up. To keep the shadow at a consistent angle to the player.

    That's how I read it, but he keeps using the word "move" which means 10 different things. :D
     
  9. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    hahaha, alright, this 'misunderstanding' was my fault.
    I should have been very specific :).

    I'm using the First Person Controller prefab for basic player movement. As well, I am using a single light source (a directional light) to simulate the sun. In my scene is a basic ground mesh and some props. Now, in editor, the directional light is casting shadows from these props onto my ground mesh and it looks great.

    However, as soon as I press play or build the project and test it, as I move my player, all the shadows in the scene move - 3d objects shadows, not just the players shadows.

    Does that make better sense? I'm trying to figure out why static objects shadows are moving when the player moves.

    Sorry for the confusion and the great help so far!
     
    TimeWalk-org likes this.
  10. jeffcraighead

    jeffcraighead

    Joined:
    Nov 15, 2006
    Posts:
    740
    Do they actually move across the ground like the object were moving or do they crawl/sparkle because of aliasing? I've seen that, you need to mess with the cascade settings and draw distance if that is the case to tune the shadows for the scene.
     
  11. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    It retains the shadows shape and moves them across my ground mesh. Not an AA issue as far as I can tell. Thought it could be clipping plane related?
     
  12. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    So it "moves" in a sense "the shadow just ran 10 meters!", or "moves" in a sense "it stays in the same place, but there's some crawling and shimmering"?

    In the latter case, tweak shadow quality settings to get the resolution right for your scene size. Documentation here.
     
  13. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    Sorry for the slow reply - they move as in, whoa, they just moved 10 meters. It doesn't appear to be a graphical / shadow quality issues, as the shadows look great, but they move.
     
  14. Omar Rojo

    Omar Rojo

    Joined:
    Jan 4, 2007
    Posts:
    494
  15. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    That is strange. Do a small project that reproduces the issue, and send it with Report Bug.app (found next to Unity application, or from Help menu in Unity).
     
  16. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    This is going to sound simple, but... does the light source move? Rigidbody accidentally attached or a script you were playing around with once and forgot about? Or is it in the hierarchy of another object that moves somehow?

    Probably not... but... it seems like the most likely possibility from what little I know here.

    I guess it could be that your entire terrain is moving or something like that, too. I remember dealing with some physics tests and I was tilting my entire "floor" around just by moving a player across it. Might be subtle enough to not see the movement, and the shadows would be the most obvious place it's noticed... especially if the camera follows the player.

    And now, I will stop suggesting stuff that you probably already checked. :)
     
  17. techbinge

    techbinge

    Joined:
    Jul 22, 2006
    Posts:
    88
    I ended up tweaking my camera clip plane settings to solve this. I was having all kinds of issues - skybox not showing, hall of mirrors effects, graphical oddities and moving shadows.

    Thanks for everyone's feedback. I guess the scale I'm using is smaller than intended as I've had to tweak a lot of defaults to get things looking right.

    Thanks!
     
  18. Qbert34

    Qbert34

    Joined:
    Apr 2, 2015
    Posts:
    8
    gosh.. this post is so old.. but it seems to be the only one explaining the exact issue i am facing..
    all the worlds shadows are moving with the player/camera..

    I tried playing with the cameras. turning all off but one, giving it full clipping range..
    I tried turning all the lights off but one, played with its settings..
    I checked that the light, nor my buildings/land/world are moving..

    still having shadows moving all over the place..
    since noone else is reporting this issue.. i wonder what i am doing wrong..
     
    devaell likes this.
  19. Cervelx

    Cervelx

    Joined:
    Feb 25, 2014
    Posts:
    19
    I've the same F****G problem :( only in my mobile android build
     
  20. TimeWalk-org

    TimeWalk-org

    Joined:
    Nov 3, 2014
    Posts:
    38
    Me too, for Oculus and Windows versions on Unity 2020.1
     
  21. Tiberius1701

    Tiberius1701

    Joined:
    Sep 16, 2014
    Posts:
    71
    I was encountering this too, and found the answer, at least for recent Unity versions. I am using URP, so it may be a URP specific answer as well.

    Go to the Universal Pipeline Asset and open the Shadows rollout - you will see a Max Distance. Mine was set to 50 by default. I set it to 10000 and the problems went away. Other posts have mentioned the Cascade Count as a problem - this is also located on this rollout.
     
  22. atur94

    atur94

    Joined:
    Apr 7, 2019
    Posts:
    11
    Unity defaults max shadow distance to low values. If you struggling with the same problem try to change the Project Settings -> Quality -> Shadow Distance to higher values and check if that works. It seems that you
    @Tiberius1701 solved my problem. Thanks
     
  23. Dushyant_Bhatt

    Dushyant_Bhatt

    Joined:
    Nov 1, 2022
    Posts:
    1
    this is not working for me in unity 2022.3.7f1 LTS version. is there any other solution for this , i'm also stuck here.