I'm making my graphics engine from scratch, at that moment I have some architecture and my engine can render PBR materials parsed from GLTF 2.0 models (embedded textures)
Here's some of my classes:
-AbstractResource (reload and validate)
-AbstractBuffer (VBO/IBO/SBO, gotta imlement CBO later (atomic counters))
-BufferLayout (description how attributes lying in VBO)
-AbstractCommand (basic command with execute() method, examples: BindShader, BindTexture2D, BindTextureCube, BindVertexArray, Draw, SetUniform<T>)
-AbstractDrawable (everything that have update(dt), generate_batch_list(model, view, proj))
-AbstractMaterial (describes how to render stuff, basically: textures, specific shader variant and way how to bind shader, uniforms and textures together in a correct way)
-Batch (all the information needed to render something using one draw call: vao, material, uniforms and some flags. Can generate CommandList via generate_command_list())
-AbstractShader (stores sources of vertex and fragment shaders + stores shader variants)
-AbstractShaderVariant (compiled shader with specific ShaderSettings)
-ShaderSettings (flags + definitions)
-AbstractTexture2D, AbstractTextureCube, AbstractSampler2D, TextureFormat, TextureType, ...
-AbstractVertexArray
-AbstractRenderPass (execute(batches), reload, validate)
-Pipeline (list of render passses)
-GAPI (using gapi we can make OpenGL objects. Basically it stores factories)
-Engine (stores GAPI, pipeline and BatchList (vector of batches, updates and flushes every frame. We can "push" batches/drawables or "flush" them (to render all the batches and clear BatchList)
Everything was good until today... Because today I started dreaming about OIT (Order Independent Transparency).
I implemented such a passes: DepthPrepass, OpaquePass, TransparentPass, and logically OIT must be somewhere inside of TransparentPass.
OIT requieres two passes:
1. Render ALL transparent fragments with disabled depth test + store depth and color of each fragment in SBO (SSBO)
2. Render again, but now with depth test. Use info from (1) to correctly mix a fragment colors
To do an OIT I need one SBO and one r32ui texture. Great, but... IT CAN'T BE PART OF MATERIAL. Why the freak material shaders should know about things requiered for OIT?
That's just weird. Yes, (1) transparent pass need to know color of each fragment, but... Ideologically AbstractMaterial should care about shading models and not about transparency ;(
I was thinking about subroutines, like I can standardize function names requiered for lighting, but..... I'm working with ES 3.1 and here I don't have any subroutines.
Also I support ES2, but in that case I can just say "ok, no OIT"
What can be done with that? I'm completely lost