Renderer.txt 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. Get renderer to run
  2. - Go through TODOs on BansheeRenderer
  3. - What happens to MeshRenderData when mesh is destroyed? It contains a callback to Mesh, so I must ensure it outlives it.
  4. - Just keep a reference to the MeshPtr instead of that notify callback.
  5. - OR just notify MeshRenderData on Mesh destruction (And make it use a shared ptr)
  6. - How to clean up RenderableProxies in Renderer?
  7. - Even though I allocate material proxies with frame alloc I think I still need to free them for debug purposes
  8. What happens when technique/shader changes?
  9. - Have isProxyDirty flag in Material. Renderable checks that flag and returns dirty for the Renderable when toggled (and cleans the flag).
  10. Then we just create a new Material proxy. When new material proxy is created a copy of all current GpuParams is created.
  11. What happens when gpu prog param buffer changes?
  12. - Material has another flag areParamsDirty (actally GpuParams should have that flag). If true I call
  13. updateMaterialProxy() with wanted pass, gpu prog idx and BindableGpuParams. BindableGpuParams are then used
  14. for copying new data to core thread GpuParams.
  15. What happens when a parameter is updated?
  16. - Same as above. Make sure not to send updates if shared or renderer param block was updated.
  17. Next stage:
  18. - Track material changes
  19. - Figure out how to update material data buffers only when material actually changes (shader or parameters)
  20. - Should each object have their own set of buffers instead of just updating material ones per frame? Probably.
  21. - Although I should still have an option to use a shared block that isn't per object.
  22. - Add sort type, priority and separable pass options to Shader (and its RTTI)
  23. - Implement RenderQueue sorting with support for sort type, priority and separable pass
  24. - Document elements marked with TODO UNDOCUMENTED
  25. - Add Renderer <-> Material interface matching
  26. - Allow parameter blocks to be specified as one-time, per-frame, per-object, etc.
  27. - Actually add frustum culling
  28. Finally
  29. - Refactor/rename everything so it makes more sense. Possibly lay out a design diagram.
  30. - Get rid of Camera::getIgnoreSceneRenderables it can be doing using layers
  31. - Delete RenderOperation as I don't think I use it anymore
  32. Semantic/design issues:
  33. - DrawList is too similar to RenderQueue - Their names need to be more distinct
  34. - MeshProxy is very different that material/camera/renderable proxy. Rename it to something else?
  35. - Material and camera proxy is returned by value while renderable by pointer. Also material proxy seems a bit heavy weight to be passed by value.
  36. - Consider removing SceneManager from Core? I two scene manager base classes.
  37. - Consider moving RenderOperation in RenderQueue and removing its header/source. Maybe also renaming it to something more render queue specific.
  38. - Remove DefaultRenderQueue. Instead make RenderQueue non-abstract and have it provide default implementation.
  39. -----------------------------------------
  40. While I am on this also consider working on how will parameter matching between Renderer and Material work (e.g. when rendering with
  41. shadows or lighting the renderer will expect materials to have certain parameters used for those effects)
  42. - Make it a separate GPU param buffer? RendererOneTime, RendererPerFrame, RendererPerObject
  43. Each renderer can specify which Renderable types it supports.
  44. - Renderable can have various options like shadow, no shadow, animation, etc.
  45. - Together those options result in an Enum describing the type of Renderable
  46. Each renderer can specify a set of parameters it needs from a material, per Renderable type
  47. - e.g. "Matrix4 viewProjTfrm" for BasicRenderable type
  48. When a Material is hooked up to a Renderable is will check if the Material has the required parameters.
  49. - If not that object will be drawn using a dummy (most basic) shader.
  50. - Optionally the parameters are grouped into parameter blocks e.g. RendererOneTime, RendererPerFrame, RendererPerObject.
  51. - If a parameter block is detected by the renderer it will only update those parameters once when they are needed, and reuse
  52. them in all materials. If no parameter block is detected the parameters will be updated on all objects whenever it is changed.
  53. - I will potentially need to add parameter block semantic to Shader in order to make the user able to specify which blocks
  54. are for the renderer. (And so that Material knows not to create those buffers manually)
  55. when calling addParameter add an argument "rendererSemantic" - 0 means its a custom parameter, and the rest are enum values
  56. provided by the renderer. (Actually an UINT32 so it may be extended). When render proxy is being created I compare those parameters
  57. and ensure they match. If they don't match I use a dummy material.
  58. you can so something similar to parameter blocks - also provide a semantic to determine if its renderer one time, per frame,
  59. per object, etc. If shader has such a block AND the gpu program desc actually has a parameter block then this will also be
  60. checked for validity when when creating a proxy (actually it might be better to check validity any time material or renderable options
  61. change and then just cache it). Param block and its members must exactly match (type AND order).
  62. Material DOES NOT automatically create param blocks with renderer semantic
  63. ---------------------------
  64. Just notes for later potentially:
  65. - I can only update entire Mesh at once.
  66. - I keep bounds for the entire mesh and not per-submesh
  67. - I don't serialize bounds and they are recalculated whenever a mesh is loaded
  68. OLD:
  69. Since DrawHelper needs to queue render commands together with scene objects (in order for transparency to work okay), I will need to implement the RenderOperation approach I thought about earlier.
  70. Rename current RenderOperation to SubMeshData
  71. Real render operations contains SubMeshData + layer (can be filtered per-camera) + queue (each mesh has a queue and another queue by camera) + Pass
  72. (Remove Camera->rendersSceneObjects and replace it with layer)
  73. (Make sure to set up preset queues, like opaque, transparent, etc)
  74. Then I can hook up GUIManager, OverlayManager and DrawHelper with a callback that is used by Renderer to retrieve their operations
  75. Attempt to move all sorting (including by render target) out of forward renderer and into an overridable sorter class
  76. - Create a hash list with key(containing type, queue, layer, etc.) used for sorting
  77. Add "materialGroup" to material. It can be used for sorting similar materials together, instead of using some automatic way of determining it.
  78. Issues with my render operation system:
  79. Sorting by depth is impossible because I don't provide any position info with my RenderOperation
  80. For each frame I will need to calculate world bounds and world position. I cannot do it each time I retrieve a RenderOperation so it should be cached somewhere and reused throughout the frame.
  81. - Unity keeps it with Renderable
  82. - What happens when the Mesh resource is updated?
  83. - How do I do it for non-renerables though?
  84. ---------------------
  85. RenderOpSorter:
  86. - (Before we send RenderOps to the sorter we first filter them by camera)
  87. - Accepts parameters whether to sort back-to-front, front-to-back or ignore depth (depth ignored with skybox and overlay)
  88. - Another parameter is whether to sort by pass (transparent ops can't be sorted by pass)
  89. - Then we sort:
  90. - If back to front
  91. - We sort by depth and that's it. We could also sort by material by that only makes sense if two elements have exact same depth which will almost never happen
  92. - If front to back
  93. - Sort by material first. We call materialSimilarity() method which returns lesser value depending how similar two materials are. We do a pass over all unsorted materials and if similarity is below some threshold we add it to the current bucket. If there are no more similar materials we create a new bucket.
  94. - Within bucket we sort by similarity as well (as the elements are added)
  95. - Then finally we sort the buckets by depth front to back
  96. - No depth
  97. - Same as front to back, without the depth sort
  98. - Sorter should operate directly on provided render op array