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