Access Immediate Mode from within Update Loop

Avatar
  • updated
  • Completed

I planned to use Shapes to draw nicer looking Debug Data for example to visualize RayCasts.

How Would I go about doing that elegantly I know I could store the data and then in OnPostRender draw it, but I think it would be very handy to just use like Like Debug.DrawLine() from within Update.

Reporting a bug? please specify Unity version:
Reporting a bug? please specify Shapes version:
Reporting a bug? please specify Render Pipeline:
Pinned replies
Avatar
Freya Holmér
  • Answer
  • Completed

This is now possible in 3.0.0, but it is not recommended

immediate mode needs to know when to add and when to remove these draw calls, and it's very easy to mistakenly add calls, without the engine knowing when to remove them at the right time.

basically - if you add a draw command in Update(), that draw command will only be removed once the specified camera has rendered, but if the camera isn't rendering, you're now adding a draw command every frame, without removing it.

It might sound like this is hard to accidentally do, but consider being in the editor, and you add a command in Update(). Then let's say you switch to the scene view, so the game isn't rendering - you're now stacking draw calls every frame without removing them, because the camera hasn't consumed those events. this is both an issue with how Unity's cameras lack proper callbacks, and more of a code structure thing on the user end. I could make the system smarter, but that would mean users would have to start caching variables and keep track of objects, which is an overhead I don't want users to have to think about

I have also added a helper class to make it easier to draw Shapes from MonoBehaviours, that automatically pipes into the correct onPostRender callback, so you don't have to manage that

Avatar
Freya Holmér
  • Answered

This isn't possible no, because of how immediate mode drawing works. It's identical to using Graphics.DrawMeshNow, which, similarly doesn't really allow you to do it in Update

but if you are only using it for debugging, then, you can draw in OnDrawGizmos, if you don't want to juggle onPostRender events

Avatar
Geordie Hall

+1 to some kind of deferred draw API that can be called from anywhere in the frame. 

I actually ended up making a little static wrapper class around the Shapes.Draw methods that queues a command with the necessary payload, and then in its `Camera.onPostRender` callback goes through the queue to actually make the draw calls. Makes it super easy to fire off debug visuals from deep within the actual script/algorithm you're working on and have the actual drawing automatically deferred till the end of the frame (UE4's debug draws work in a similar way, and you can give them a duration if wanting to last across multiple frames). 

I realise Shapes isn't necessarily trying to be a debug visualization library, so understand if you'd rather leave that to the game layer and avoid the maintenance/feature requests, but could be something to think about if it'd save everyone having to write their own version

Avatar
Freya Holmér

It's possible, but it has implications outside of the scope of the way you draw immediate mode right now. from the top of my head:

1. draw in what cameras?
2. draw editor, in-game, or both?
3. editor only or runtime too?
4. supporting all render pipelines
5. having a persistent manager object that can keep track of all delayed rendering
6. having the API calls support delays would have to be designed carefully

7. everything I haven't been able to predict at the time of writing that might go wrong or additional unexpected work I'd have to do

like, not saying it's impossible! I might have to do something like this for proper SRP support, but, it gets complicated and adds overhead in having a manager object, not to mention everything that can go wrong with it (serialization, timing, editor vs play switching, etc), and it presumes things with regards to your game loop and camera setup, which I don't like. Especially when I feel like I already have higher prio things to fix right now. That said feel free to open it as a feature request! just might not happen for a while as Shapes isn't primarily designed to be a debug library

Avatar
Jan Schneider

  • From The Top Of my Head:
    1. in all
    2. everywhere as long as show gizmos are toggled
  • 3. Editor Only would be fine I think (Maybe a a global option)
    4. I dont know how much work that is, but would make sense (I use URP)
    5. Would be great as you could also do some drawcall batching
  • 6. I think being able to specify for how long you want the shape to be drawn would be huge plus
  • Avatar
    Can Chen

    This is something I want to do too. 

    Avatar
    Freya Holmér

    just wanted to update and say this might actually be a side-effect of a refactor I'm doing of the immediate mode system for HDRP compatibility!

    Avatar
    Freya Holmér
    • Answer
    • Completed

    This is now possible in 3.0.0, but it is not recommended

    immediate mode needs to know when to add and when to remove these draw calls, and it's very easy to mistakenly add calls, without the engine knowing when to remove them at the right time.

    basically - if you add a draw command in Update(), that draw command will only be removed once the specified camera has rendered, but if the camera isn't rendering, you're now adding a draw command every frame, without removing it.

    It might sound like this is hard to accidentally do, but consider being in the editor, and you add a command in Update(). Then let's say you switch to the scene view, so the game isn't rendering - you're now stacking draw calls every frame without removing them, because the camera hasn't consumed those events. this is both an issue with how Unity's cameras lack proper callbacks, and more of a code structure thing on the user end. I could make the system smarter, but that would mean users would have to start caching variables and keep track of objects, which is an overhead I don't want users to have to think about

    I have also added a helper class to make it easier to draw Shapes from MonoBehaviours, that automatically pipes into the correct onPostRender callback, so you don't have to manage that