Currently, this asset doesn’t work on Unity 5.6 (as of Unity 5.6.2p2). Please use another version of Unity (Unity 5.5 or Unity 2017)

This tutorial shows how to add a Dynamic Shadow Projector object into a scene.

The final result will look like this:

  1. Start with a new scene
    Now, the scene has only a main camera and a directional light. In the project, there are DynamicShadowProjector and Standard Assets (Camera package and Character package).
    tutorial-newscene
  2. Add a plane object and a character object
    You will already have a terrain object and a player character object in your scene. In this tutorial, I use a plane object as a terrain, and ThirdPersonController in Standard Assets as a player character.
    tutorial-planeandcharacter
  3. Turn off shadowmap
    If you can see a shadow at this point, it is a shadowmap. Select the directional light in Hierarchy view, and change the Shadow Type to “No Shadows”. If you want to use GI, it might better to use Quality Settings to disable shadowmap.
    tutorial-disableshadowmap
  4. Create a projector object
    Create an empty game object under the directional light, so that the transform of the object can be same as the transform of the directional light, and name the object “Shadow Projector”.
    tutorial-createobject
  5. Add “Draw Target Object” component to the projector object
    Click “Add Component” button in Inspector view, and select “Scripts” > “DynamicShadowProjector” > “Draw Target Object”.
    tutorial-addcomponent
  6. Set the character object as a target
    The shadow projector object should have Projector component, Shadow Texture Renderer component, and Draw Target Object component now. Drag ThirdPersonController object (character object), and drop it into Target field in Draw Target Object component.
    tutorial-settarget
  7. Create a new material for the shadow projector
    Next, you need to create a material for the Projector component. Right click in the Assets folder, and select “Create” > “Material”. Then, name the material “Shadow Projector”. You can use any projector shader for this material, for example, “Projector/Multiply” shader in Effects package of Standard Assets. In this tutorial, I would like to use “DynamicShadowProjector/Projector/Dynamic/MipmappedShadow” shader to demonstrate Percentage Closer Filter like soft shadow.
    tutorial-creatematerial
  8. Assign the material to the Projector component
    Select the shadow projector object in Hierarchy view, drag the projector material and drop it into the Projector component.
    tutorial-assignmaterial
  9. Adjust the projector position and size
    Now it is ready to draw a shadow. Set the parameters of Projector component, and adjust the position of the projector object in Scene view as in the below image. Please be noted that the right value of the position will change according to the position of the character object. Make sure that the shadow image comes in the center of the texture.
    tutorial-adjustprojector
  10. Change texture settings
    To take advantage of mipmapped shadow shader, you need to change texture settings as in the below image. You will see several shadow images in Shadow Texture window in Scene view. The left most image is the image of mip level 0, and the right most image is the image of the most highest level.
    * Version 1.0 had a memory leak bug. If mip level was greater than 0, a temporary render texture had not been released every frame. Version 1.0.1 will be released soon. Please don’t forget to update this asset.
    tutorial-texturesettings
  11. Adjust clip planes
    In spite of the blurry mipmapped shadow texture, the character object still has a hard shadow. This is because the image of mip level 0 is always used for the shadow. A mip level picked by mipmapped shadow shader is derived from the distance between the near clip plane of the projector and a point where the shadow is dropped. That means, mip level 0 will be used for drawing a shadow around the near clip plane, and the highest level will be used for drawing a shadow around the far clip plane. So, the clip planes of the projector component need to be adjusted to make the shadow more blurry.
    tutorial-adjustclipplanes
  12. Add a layer for the character object
    If you look at the character from behind, you will notice that the shadow is casted on the feet of the character. To remove the self cast shadow, you need to add a layer for the character object. Click the “Layers” dropdown at the top right side of Unity window, and select “Edit Layers…”. Then you will see “Tags & Layers” settings in Inspector view. Input a layer name to any of User Layers.
    tutorial-editlayer
  13. Assign the layer to the character object
    Select the character object, and assign the layer in Inspector view.
    tutorial-assignlayer
  14. Add the layer to ignore layers field in the projector
    Go back to the shadow projector object, and add the layer to “Ignore Layers” field in Projector component. Then, the self cast shadow will disappear.
    tutorial-ignorelayer
  15. Add a fallback component
    The shadow looks perfect now, but there is one more step left. Mipmapped shadow shader uses tex2Dlod function. It requires shader model 3.0 (DirectX), OpenGL ES 3.0, or OpenGL ES 2.0 + texture lod extension. So, it might not work on some old devices. It is better to prepare a fallback for those devices, especially if you are targeting mobile devices.

    Click “Add Fallback Component” button in Inspector view. Then, Mipmapped Shadow Fallback component will be added to the shadow projector object. If you check “Test Fallback”, you can test the fallback in Scene view, and adjust the fallback parameters.
    tutorial-addfallback
    tutorial-fallback

  16. Add a camera rig and play the scene
    It’s time to test the scene. To make it easier to check the shadow, let’s add a camera rig. Drag & drop MultipurposeCameraRig in Standard Assets into the scene, and set the character object as a target of the camera. Don’t forget to delete the old main camera.
    tutorial-camerarig
    Now, you can play the scene. Control the character with arrow keys or A D W S keys (Move), and with space bar (Jump).

Links

34 thoughts on “Tutorial

  • 2015/06/27 at 2:56 PM
    Permalink

    I followed your instructions with a simple cube and plane but could not get it to work. Your two samples didnt work either. I have Win 8.1, Unity 5.0. Can you post an example please.

    Reply
    • 2015/06/29 at 9:49 PM
      Permalink

      I tested on Win 7, Unity 5.0.3, but I couldn’t reproduce the problem. Can you check if the materials in Shaders folder are valid or not? And if not, please re-import those materials.
      If you still have the problem, please delete the asset and download it from Asset Store again.
      Thanks

      Reply
  • 2015/07/31 at 7:35 PM
    Permalink

    this asset can use for unity 4.6.1?

    Reply
    • 2015/08/01 at 11:25 AM
      Permalink

      No, it requires Unity 5.0.1 or later, because it uses new Unity 5 feature (command buffer).

      Reply
  • 2016/02/02 at 11:43 AM
    Permalink

    Very impressive work!

    Reply
  • 2016/03/31 at 4:12 PM
    Permalink

    Thank you for the nice tutorial I got super good shadow for my project.I only have one question that drives me crazy ,why the shadow dosent react my characters moving when i use it in my project.like when my character is running the shadow is moving with it but without running action.

    Reply
    • 2016/03/31 at 4:26 PM
      Permalink

      Do you change the character’s mesh or child objects after scene starts? Dynamic Shadow Projector creates a command buffer to draw a shadow onto a RenderTexture when scene starts. I guess, your animating character has a different mesh than the one referred from the command buffer. If so, you might need to call SetCommandBufferDirty() or UpdateCommandBuffer() methods of DrawTargetObject component.

      Reply
  • 2016/07/26 at 12:37 AM
    Permalink

    Great asset, all I needed, but I REALLY need a tutorial on how to add it in a land with trees for example, the ground should cast shadows on himself but does not work nothing as expected, it has a problem in the follow target and the worst of all is that that projector size does not fit the terrain. HELP ME URGENT!

    Reply
    • 2016/07/26 at 12:27 PM
      Permalink

      Thanks for your feedback. Unfortunately, this asset is not designed for terrain. If you need shadows of trees, I recommend you to use a shadow map or a baked light map.

      Reply
  • 2016/09/11 at 7:23 PM
    Permalink

    Are there any plans to make this work for VR headsets? Right now, the shadows move around as you move around your head.

    As an alternative, can the shadow be baked to the surface receiving the shadow?

    Thanks!

    Reply
    • 2016/09/12 at 10:32 AM
      Permalink

      It seems like the camera used for rendering shadow texture is rotated by VR SDK. It is hidden in ShadowTextureRenderer component. Do you know how the SDK controls cameras, and how I can disable it?

      Reply
  • 2017/01/30 at 10:59 AM
    Permalink

    Hi,

    I am trying out your package on Unity 5.6 Beta 5. Every time I get to the point of adding the “Draw Target Render” script, Unity crashes.

    Adding the Projector component manually is fine, but if I then add ShadowTextureRenderer, it crashes as well.

    As an aside, while I can open your demo scenes, they don’t look right in Unity 5.6. Something has definitely changed in 5.6 beta to break your plugin unfortunately 🙁

    It all works fine in Unity 5.5.0p3. I’m using the Beta because it has a lot of fixes for baked lighting which I plan to make heavy use of.

    Thanks for your time,

    Niall

    Reply
    • 2017/01/30 at 10:51 PM
      Permalink

      Thanks for the bug report. Currently I cannot download Unity 5.6 beta because of slow internet connection. I will check it later and I will reply again if I could fix it.

      Reply
  • 2017/01/31 at 12:22 AM
    Permalink

    Great, thanks a lot.

    If I click my projector in the Editor, it gives the following error:

    NullReferenceException: Object reference not set to an instance of an object
    DynamicShadowProjector.Editor.EditorBase.RemoveUnuserMaterialPropertyData (UnityEngine.Material mat, UnityEditor.SerializedProperty prop, System.String forceRemoveProperty) (at Assets/DynamicShadowProjector/Scripts/Editor/EditorBase.cs:79)
    DynamicShadowProjector.Editor.EditorBase.RemoveUnusedMaterialProperties (UnityEngine.Material mat, Boolean isDynamic) (at Assets/DynamicShadowProjector/Scripts/Editor/EditorBase.cs:100)
    DynamicShadowProjector.Editor.ShadowTextureRendererEditor.OnEnable () (at Assets/DynamicShadowProjector/Scripts/Editor/ShadowTextureRendererEditor.cs:42)

    Perhaps that can help point you in the direction?

    If you have any suggestions for me to try or even an area of code to look into (I’m not a graphics programmer, but I am a coder), I am happy to give them a go until you manage to download a copy of Unity 5.6b5. Given the nature of the crash (Full editor crash), I’m inclined to think it’s somewhere where you’re calling into native code…

    Thanks again,

    Niall

    Reply
    • 2017/01/31 at 2:53 AM
      Permalink

      I have done some more experimenting.

      I took a working “Dynamic Shadow Projector” project from 5.5 to 5.6, this avoids the crash I spoke about in my first message. This gives me a grey quad instead of my character shadow. If I then set set Blur Level to 0, the shadow renders correctly. Not a proper fix, but maybe it helps you narrow down some of the issues. From looking at the code, perhaps the issue is something to do with “useIntermediateTexture”?

      I’m very keen to use this plugin for my project moving forwards, I was able to get some great results with it in Unity 5.5 🙂 Thanks for making this public!

      Niall

      Reply
      • 2017/01/31 at 11:19 PM
        Permalink

        Hi Niall,

        Thank you for the information. Maybe the data structure of the materials has been changed. Please replace the function at Assets/DynamicShadowProjector/Scripts/Editor/EditorBase.cs:74 with the following one:

        This fix can remove the error message that was shown when a projector clicked, but I don’t think this is the main reason for the crash. I guess some of the shaders that are used for blurring are not working.

        This asset does not call any native code, and I am sure that the crash had happened inside Unity Editor.
        I will download and test Unity 5.6 as soon as possible, but it would be helpful if you can send a crash report to Unity.

        Thanks

        Reply
        • 2017/02/01 at 11:36 PM
          Permalink

          I managed to get Unity 5.6 beta 5. I’m using Mac, and I got the following error message instead of a crash:
          Rendering camera ‘GameObject’, but calling code does not set it up as current camera (current camera: ‘Main Camera’)
          UnityEngine.Camera:Render()
          DynamicShadowProjector.ShadowTextureRenderer:Update() (at Assets/DynamicShadowProjector/Scripts/ShadowTextureRenderer.cs:594)

          I think this error explains why Unity Editor crashes on some platforms. I tried inserting Camera.SetupCurrent(m_camera); at ShadowTextureRenderer.cs:594, but I still got the same error.

          I will continue my investigation.

          Reply
          • 2017/02/02 at 10:28 AM
            Permalink

            I noticed that every time when I edit a script file, Unity Editor crashed if there were ShadowTextureRenderer objects in the scene. Also, I tried to fix the grey quad problem, but I couldn’t find a solution. I just sent a bug report to Unity. Please wait until they give me a reply.

            Sorry for the inconvenience.

  • 2017/02/04 at 1:08 AM
    Permalink

    Thanks a lot for looking into this!

    I was getting crashes whenever I tried to edit ShadowTextureRenderer.cs as well. I didn’t know if the same was happening in earlier versions so ignored it.

    Do you have a link to the bug you reported on Unity’s issue tracker? They recommend that you also post the issue/case ID in the beta forum for any beta specific issues to make sure they get looked at.

    I see that beta 6 is already out: https://forum.unity3d.com/threads/5-6-0b6-is-available.454187/

    I haven’t had a chance to try it yet, but looks like it will require code changes from your end anyway to make it all work.

    Reply
    • 2017/02/04 at 11:57 PM
      Permalink

      Hi Niall,

      I simplified the grey quad problem, and I found a workaround. The problem occurs if the camera has a non-null targetTexture and a temporary texture is used for the actual render target. If null is set to the targetTexture in OnPostRender function, it works.

      The code is at ShadowTextureRenderer.cs line 890 (OnPostRender() function).

      Please replace this line with the following:

      However, this code might have another issue when used with VR. I sent another bug report to Unity. Here is the link to the issue tracker:
      https://fogbugz.unity3d.com/default.asp?877766_68lsfpq2iqf88c2p

      I haven’t tested beta 6 because I still have slow internet connection. Regarding the crash issue, even if I needed to change my code, Unity Editor should not crash, and it should report a proper error message. Otherwise I cannot fix the problem…

      Reply
      • 2017/02/08 at 11:28 PM
        Permalink

        Cheers for the workaround and getting the bugs reported so quickly. I will try the workaround when I manage to get back to lighting/shadow work!

        Reply
        • 2017/04/04 at 1:49 AM
          Permalink

          Hi Takao,

          Now that Unity 5.6 has been officially released, I thought it would be a good time to go back and check my project with it as we need some of the fixes they have made to baked lighting.

          I have implemented both of your fixes/workarounds, the changes to RemoveUnuserMaterialPropertyData and also the change so the targetTexture is set to null.

          While this does get the shadows rendering, I am getting a lot of errors in the console window when in the scene view:

          Rendering camera ‘Shadow Projector’, but calling code does not set it up as current camera (current camera: ‘Main Camera’)
          UnityEngine.Camera:Render()
          DynamicShadowProjector.ShadowTextureRenderer:Update() (at Assets/DynamicShadowProjector/Scripts/ShadowTextureRenderer.cs:594)

          I have tried adding the following (undocumented) function call:

          Camera.SetupCurrent(m_camera);

          just before the call to Render(), but this doesn’t seem to have any effect.

          The documentation for Camera.Current suggest you should only use it in OnRenderImage, OnPreRender, OnPostRender. Perhaps you can only set the current camera there as well…

          https://docs.unity3d.com/ScriptReference/Camera-current.html

          The bug you initially reported has been fixed in Unity 2017, I contacted Unity a number of weeks ago asking that they backport the fix to Unity 5.6 as we won’t be able to migrate the game to Unity 2017 (we’re locked in for Unity 5 lifecycle as we paid for the licenses already). They have said they will look into it, but we have not heard back as of yet.

          Any help you can provide is appreciated.

          Cheers,

          Niall

          Reply
          • 2017/04/06 at 12:25 PM
            Permalink

            Hi Niall,

            Sorry for the inconvenience. I made a patch for version 1.0.5.
            http://nyahoon.com/download/DynamicShadowProjector_1_0_5_patch1.unitypackage

            You will still see the error messages, but it will be only once. It seems like it is impossible to avoid this error message. I believe that is a Unity’s bug.

            This patch includes all other workarounds for Unity 5.6. I will submit this update to Asset Store as well.

  • 2017/02/24 at 12:48 AM
    Permalink

    So this work only on one object/character at the time? What if i want to use it on lets say 10 characters…

    Reply
    • 2017/02/24 at 9:52 AM
      Permalink

      If you have 10 characters, you need 10 projectors. However, if those projectors share a same material, they won’t work properly on Editor. When the scene starts, the material will be duplicated, and they will work properly. If you want to make it work on Editor, please use a different material for each projector.

      Reply
  • 2017/04/03 at 6:30 PM
    Permalink

    Hello,
    I have figured out the crash problem in unity5.6.
    Just change the line in OnValidate function
    SetTexturePropertyDirty();
    To
    CreateRenderTexture();

    I don’t know why this can cause the crash in unity 5.6. But after I change the code, the crash is gone.

    Also you can skip the code once in Update function if the editor has just called the OnValidate function. It will fix the crash too.

    Reply
    • 2017/04/04 at 3:30 PM
      Permalink

      Thank you for finding the workarounds! This information is really helpful.

      Reply
  • 2017/04/07 at 3:40 PM
    Permalink

    hello , this is a very good asset.
    but , i have a question
    When I use it to cast a shadow of a character,that the Batches add 20 or more .
    so ,Is there something wrong with me?
    please help me .

    Reply
    • 2017/04/07 at 11:23 PM
      Permalink

      Hi, blurring shadow texture and making mipmaps need some draw calls (Graphics.Blit). If you want to reduce it, check ‘Single Pass Mipmap Blur’.

      Reply
  • 2017/05/29 at 3:25 AM
    Permalink

    Hi!

    I am looking to an alternative to Unity realtime shadows.
    Is your technique faster?
    I mean Render + Drawcall cost? (With minimum settings of course)

    I target mobile devices.

    Cheers

    Reply
    • 2017/05/29 at 11:21 AM
      Permalink

      Hi, thank you for the comment.

      If you have only one shadow projector, it will be faster than Unity realtime shadow, but if you have more, it might be slower than Unity realtime shadow. It depends on the scene.

      Basically, the main cost of rendering shadows resides on GPU side, not CPU side. So you don’t need to care about Render + Drawcall cost so much. Instead, you need to care about fragment shader cost, especially if your target is mobile. Our another asset “Fast Shadow Receiver” can reduce fragment shader cost. It works with “Dynamic Shadow Projector”. For more details, please see FAQ page:
      http://nyahoon.com/products/fast-shadow-receiver/faq#Q2

      Anyway, please try Dynamic Shadow Projector first, and if you like it, try Fast Shadow Receiver.

      Thanks

      Reply
  • 2017/06/23 at 9:20 AM
    Permalink

    Unity 5.6.1f1, using your “Basic” sample and replacing the “SoftShadowSample” cube with a Unity sphere:
    If I set Blur Level or Mip Level to anything other than zero, I get a gray quad for a shadow, and another gray quad rendered on the ground plane. Setting both to zero is the ONLY way to get a shadow representative of what you would expect from a sphere, given the lighting setup (and, of course, the shadow is un-blurred and jagged).

    Additionally, I get the previously identified “Rendering camera ‘SoftShadowProjector’, but calling code does not set it up as current camera (current camera: ‘Main Camera’)” error. Setting the Blur Level to 1 and tweaking the Blur Size slider causes the same error to stack up in the console. Same deal with the upping the Mip Level to anything greater than zero.

    Basically, unless you want a visually unacceptable shadow or a gray quad (and it’s mysterious randomly-rendered evil twin ) the tool doesn’t work. By looking at the source it seems you put quick a lot of thought and effort into implementation, so it’s a shame it doesn’t work. 🙁 Did Unity throw a monkey wrench into the works with recent changes to their code?

    Cheers.

    Reply
    • 2017/06/28 at 11:19 AM
      Permalink

      Sorry for my late response.

      Actually, similar issue occurred since Unity 5.6 beta, and I added a workaround for it. However, in Unity 5.6.1, this issue happened again, and the workaround no longer worked. I already sent a bug report to Unity. I couldn’t find any workarounds so far.

      Only Unity 5.6 has this issue. Unity 5.5 and Unity 2017 have no problem.

      Reply

Leave a Reply to FengLau Cancel reply

Your email address will not be published. Required fields are marked *

Anti Spam Code *