Search Unity

No Shadow Handling when calling Graphics.DrawProcedural

Discussion in 'Shaders' started by qornflex, Aug 4, 2014.

  1. qornflex

    qornflex

    Joined:
    Dec 6, 2012
    Posts:
    36
    Hi,

    I'm outputing a procedural mesh with Graphics.DrawProcedural.
    All is fine, uv, normals, vertices, ... lighting is ok too.
    But I'm not able to cast or receive shadows on this procedural mesh.

    I'm correctly using macros like LIGHTING_COORDS, TRANSFER_VERTEX_TO_FRAGMENT and LIGHT_ATTENUATION but nothing seems to work.

    I found some examples here:
    http://forum.unity3d.com/threads/li...so-using-surface-shaders.198141/#post-1344367

    Apparently, there is something with FallBack "VertexLit" that helps shaders to cast/receive shadows but since my material is called like below and not from a mesh renderer, I think there is a problem to handle light and shadow data from unity engine:

    void OnPostRender()
    {
    material.SetPass(0);
    material.SetBuffer("ouputVertices", outVerticesBuffer);
    ...
    Graphics.DrawProcedural(MeshTopology.Triangles, nVertices, i);​
    }

    When we proceed in that way, Fallbacks, LightMode Passes and other stuff are still processed and accessible in my custom shader/material?

    Many thanks
     
  2. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    See if there's a way to set the mesh filter to your generated mesh, that might fix it.
     
  3. qornflex

    qornflex

    Joined:
    Dec 6, 2012
    Posts:
    36
    There is no way to use mesh filter with Graphics.DrawProcedural :(

    Aras? Please help!
     
  4. qornflex

    qornflex

    Joined:
    Dec 6, 2012
    Posts:
    36
    Nothing?
     
  5. MartijnHoekstra

    MartijnHoekstra

    Joined:
    Aug 6, 2014
    Posts:
    4
    Hi OrtOfOn,

    I am not using Procedural drawing but I do have shadow issues even within MeshRenderer.
    I have not tried it out yet, but found some "LightMode" pass tags to be worthwhile inspecting.

    http://docs.unity3d.com/Manual/SL-PassTags.html
    Am referring to the: ShadowCaster and ShadowCollector.

    Are you able to embed these somehow in the shader?

    I assume you have these set up properly; but anyway I'd like to point out the Quality settings for shadow: Specially the Distance one
     
  6. qornflex

    qornflex

    Joined:
    Dec 6, 2012
    Posts:
    36
    I tried many things, including ShadowCaster and ShadowCollector tags... but no shadow or light attenuation.

    Here is the goal: ... casting/receiving shadows on people.



    This crowd is drawn with DrawProcedural (more than 1.000.000 vertices).
    In that way, I can avoid the 32bit limitation of Unity (65.000 verts max per mesh) and I don't need to split crowd into separated meshes.

    The shadow distance is also correctly set but don't give attention to that video, there is no shadow at all in that preview.
     
  7. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    That's correct, currently DrawProcedural does not integrate with lighting/shadowing at all.
     
    PrimalCoder likes this.
  8. qornflex

    qornflex

    Joined:
    Dec 6, 2012
    Posts:
    36
    Thanks for your reply Aras.
    That's a bad news :( ... is this foreseen for a near future?

    Maybe it will be on with Unity 5 ?
     
    Last edited: Oct 28, 2014
  9. qornflex

    qornflex

    Joined:
    Dec 6, 2012
    Posts:
    36
    Any news on this guys?
    Would be great to use lighting/shadow in DrawProcedural() ... espacially shadows, I have some difficulties to handle shadowmaps by my own :(

    Thanks

    Q.
     
  10. sebj

    sebj

    Joined:
    Dec 4, 2013
    Posts:
    70
    Bump, yes, it would be nice to know if Unity will be fixed so Mesh/MeshFilter/MeshRenderer can support the resource limits of D3D11 etc.

    Modern graphics cards can process huge numbers of primitives. In fact I was looking at this just 5 minutes ago - 150 draw calls, half with the same material, and the GPU barely registered. CPU on the other hand took 3ms to dispatch them. This may not seem like much, but x2 for update depth buffer, x2 of that for shadows x2 of all of the above for stereoscopy and it adds up.

    This is important in emerging applications like VR, where a consistent frame rate is of utmost importance. In VR there isn't time for the CPU to do dynamic batching and culling on larger scenes, whereas GPUs can take millions of triangles with no slow down. There is a very easy and obvious solution here, but Unity's 16 bit limit is sitting smack-bang in the way of it!
     
  11. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    I've used this recently, DrawProcedural can work with lighting just fine. Plug it into a command buffer and draw it into the deferred pipeline to get lighting.

    However, shadows cannot work. The reason being that a shadowmap is generated by a camera render; this is a DIFFERENT camera than the one the draw procedural worked on. The DrawProcedural is a direct instanced call to the GPU to render geometry. It renders it into the existing buffers. The geometry does not 'exist' in the game world, which means it does not exist for a shadow camera to see, unless you also render the geometry for that camera. And if you're rendering the geometry for every camera, you're going to be drawing those millions of vertexes on every camera. For 4 lights, that would be rendering the sets of geometry 4x more times (if you're pushing geometrical limits with a million vertexes, turning that into 5 million -will- stress the GPU, except in all but the very highest end cards).

    Yes, it would be nice to have the functionality to add the draw procedurals to the shadow cameras, but remember that for every light with shadows, it would be drawing the entirety of your geometry again.
     
  12. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    This one could sound a bit obvious, but... :D Wouldn't you just render the object twice, one for shadows, and one for the geometry? Most things need to be drawn twice anyway for shadowing, so it only makes sense to do that. ;)
     
  13. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Remember that shadows need to be interpolated for different angles! It would need to be rendered once for geometry, from the camera view, and then once for each angle that it is being viewed at for shadows. You can't just render it again for shadows, as it is being rendered from the perspective of a second camera, for each light source.

    Drop in unity's realtime shadows - notice that for each real time shadowed light, it increases the draw calls for each light, not just once for everything. Add 3 lights hitting 10 objects, and it'll add 30 draw calls - because each one is getting drawn again, from the perspective of each shadowmap rendering camera.
     
  14. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    I did mean from the light's POV, not the scene camera... :D probably my fault for not clenaning that up!
     
  15. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Yep. Theoretically that is possible. However, if you're pushing limits with DrawProcedural to draw vertexes far faster than you ever could with normal meshes, then you'll probably run into issues drawing them multiple times. That's the issue I'm finding, since I have my own shadow rendering system set up, adding my draw procedural calls to the shadow cameras is far too intensive.
     
  16. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
  17. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    Umm, shadowmaps are done in 2 steps, 1 from the light, and 1 from the cameras perspective. You only get 1 extra draw call per camera if unity has done things correctly. However you are correct that the number of draw calls is lights*shadowcasters, but then it's + number of cameras. (Unless unity is acting stupid...)
     
  18. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    Example:
    https://www.dropbox.com/s/kreb66l8k48a4ki/Screenshot 2015-07-02 18.04.58.png?dl=0
    https://www.dropbox.com/s/yf3pvbsiqdzxfi1/Screenshot 2015-07-02 18.05.06.png?dl=0
    https://www.dropbox.com/s/2firsa62me0bo2a/Screenshot 2015-07-02 18.05.16.png?dl=0
    https://www.dropbox.com/s/5qzw2mabmbb7sjr/Screenshot 2015-07-02 18.05.24.png?dl=0
    https://www.dropbox.com/s/r1jusfrzaw2xxmt/Screenshot 2015-07-02 18.08.18.png?dl=0

    It does not cache the shadowmap between cameras, because they're completely separate and distinct rendering pipelines, per camera. Arguably it should, but there's always complications.

    However, what I meant by camera was the shadowmap rendering camera - the camera you don't ever see or interact with, or most people even know exist. Basically, it does a render of the scene from the position of the light to get the shadow map - so when I was mentioning how it's each drawn again, from each shadow camera, I meant how it renders the scene from the position of each light, to build the shadowmap. That is why the draw calls is lights * shadowcasters, those draw calls are there because of the additional renders of the scene (though they are basically depth passes, not as complete as a normal shader pass).
     
  19. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    This would not work, unless you draw them into the shadowmap yourself, because that's after the shadowcasters are rendered; but the shadowcasters don't render with geometry from the DrawProcedural call. They don't know that geometry even exists.
     
  20. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    And that's the reason for what I suggested, adding a command buffer that does the DrawProcedural call at the LightEvent.AfterShadowMap would cause them to be drawn INTO THE SHADOWMAP, as it's still the bound target!
    (It's something unity added recently)
    And I'm pretty sure they also added the ability to draw prodcedural from inside command buffers.
     
  21. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    I could be wrong, but I believe the shadowmap is the screen-based texture - to render correctly for that, you'd need to get the shadow projections of the procedural mesh yourself from all the different light angles, which would still involve drawing it for each shadowed light source, and building your own shadpwmap from the depth texture + those projections, and more fun complexity. Simply rendering the meshes after the shadow buffer won't do anything; the shadow buffer is just the final screen-based shadow texture that's applied.

    So yes, that is a possibility, but essentially, if you're pushing the limits of vertexes through the usage of DrawProcedural, then you probably don't have the overhead to draw realtime shadows on the meshes.

    This is based upon my own experience in the last couple months writing both a custom shadow system, and a custom, volumetric grass system throgh the use of these methods (and command buffers, as it will, as the grass does integrate right into the deferred pipeline and draws into the GBuffer). If I'm correct in how they have their system (which would be typical for a deferred pipeline) then there's no way you can just render meshes after the shadow buffer and having the mesh's cast shadows (since the buffer isn't based around meshes, the shadow buffer is based around the cross of checking each pixel from the depth texture against the various shadow maps).
     
  22. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    I'm not 100% certain, but if you read what it says in the callback you'll see it says before the render target is removed. (And the second set's of callbacks talk about converting to the screen space buffer).

    All of them aligned with the light :).

    Well, sure, IF your rasterizer bound, and that is not necessarily the case. (Remember that it's separate hardware from what I understand, so it might have almost no extra cost, especially if your using unity 5 physically based lighting!)
     
    Last edited: Jul 6, 2015
  23. bilke

    bilke

    Joined:
    Jul 13, 2012
    Posts:
    54
    Any news on lighting support for DrawProcedural()? It seems to use just one light.
     
  24. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    Was this ever solved? For example using CommandBuffer?
     
  25. BrkTbn

    BrkTbn

    Joined:
    Jun 29, 2016
    Posts:
    13
    Any updates on this?
     
  26. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    Use Graphics.DrawMesh and create a point mesh topology type beforehand and send the point buffer to your shader.
     
  27. CharlieBudd

    CharlieBudd

    Joined:
    Jul 24, 2017
    Posts:
    17
    Yes but I believe this will not work for more than ~65000 vertices