2
0

Renderer.txt 7.9 KB

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