Jump to content

State of the Renderer


Recommended Posts

I've looked through some of the graphics code and somewhat figured out how things work together, so I thought I'd report on what I found and what I want to do about it to let everyone know and get some opinions on what I plan to do.

 

The renderer works and looks great overall, but is currently scattered between not less than 3 different places. Parts of it are under 'renderer', parts are under 'graphics', and the glsl has been dumped in with mods, which some of that should certainly go there but a lot of things definitely should be moved into the engine proper. I'd like to simplify the organization and keep all the graphics-related stuff that the engine should handle directly all in one place. That includes the GLSL, which needs JIT compiling and will need a new home in the engine. On a related note I think that maps should also have an option to include custom shaders, so that people can add things like fireflies to maps, for example.

 

The renderer is also an ad-hoc mixture of GLSL and some non-GLSL stuff that is most definitely not very efficient. Overall the renderer performs excellently for the level of effects it produces but I think it could be better both in performance and effects. The admixture of code is bad for maintainability though, and I think the renderer should be moved entirely to GLSL. There was already a discussion about that 4 years ago and everyone seemed to agree that dinosaur cards weren't really worth supporting for all the downsides.

 

That said, what I'd like to do is move everything also to OpenGL 3.1. The oldest/cheapest graphics cards you can buy today (ie GeForce 200 series as well as at least one generation earlier than that) support GL 3.1 and so do the vast majority of all embedded cards that have been produced since 2011. GL 3.1 allows for MRT, non-hardcoded conditionals, loops and other features which are useful for producing efficient renderers. I do not intend to use openCL, as not all cards (nor mine) support it (and it tends to be used for super expensive stuff anyway).

 

Another thing is graphics options. I think a lot of things that are currently optional should either become defaults or removed. For example sky rendering isn't even visible in-game unless you hack the camera, and although sky is used in water reflections sky rendering isn't necessary for that to work. Lots of things that are optional also are trivially cheap and thus don't warrant options. Reflective/refractive water and 'use real water depth' fall in that category. Some things which are currently expensive (the shore waves part of HQ water, mainly) could probably be considerably cheaper than they are now, and may eventually end up in the 'trivially cheap + definitive aesthetic gain' list.

 

FYI my current hardware is a Core i3 2120 with 4GB of RAM + Geforce 240GT with 1GB of DDR3 (not even GDDR). It's fairly old and low-end, and I'm also running at 1080p so I think the setup is pretty good for performance/generality testing (ati cards notwithstanding).

  • Like 3
Link to comment
Share on other sites

If you use 4.1 then I won't be able to run it. :P That might be useful for some high-quality optional shaders though. On the other hand if someone is already leapfrogging me then I suppose there are no objections to 3.x then. I think cleaning everything up and ensuring forward maintainability is more important right now though.

Link to comment
Share on other sites

Hi, just some notes.

For reference Yves OpenGL 4 branch is here https://github.com/Yves-G/0ad/commits/OGL4 and OpenGL 4 is intented to be optional IIRC.

Here are some stats about gfx features available at our users: http://feedback.wildfiregames.com/report/opengl/ . Before adding features it is a good idea to check here how many users we could left.

Sky rendering is useful for cut scenes, just landed in current svn and will appear in a20, have a look at this example 

 

Link to comment
Share on other sites

Well, if sky rendering is used for cutscenes it could automatically be loaded when a cutscene starts and unloaded when it ends. That's not particularly complicated to do. I still don't think it makes sense as an option though.

 

Reading through the openGL compatibility census shows quite a few people using old hardware. I think it would be worthwhile in this case to maintain a legacy renderer, but I think it should be split fully from the newer renderer to keep things organized.

 

On the other hand, extension wise I don't think any of the things I plan on implementing have special requirements. Deferred rendering doesn't require anything aside from FBOs, renderbuffers and MRT (which is defining for all GL3+ implementations and also mainly an optimization). Most of the current effects will still basically use the same implementations, just reshuffling the rendering process and economizing things. Soft shadow volumes doesn't require anything outside of basic GLSL support and could even be included in the legacy renderer. Also a lot of the things I'm looking at are just tuning of current implementations (depth of field for example, to make it usable).

 

I don't really know what Yves is using from GL4.1, but to me that's the realm of things like light propagation volumes, adaptive bloom, stochastic rasterization and other really expensive (albeit shiny) stuff. There are also additional shader stages but I don't really know what they're used for.

Link to comment
Share on other sites

Fixed shaders and non-GLSL path IIRC are required when on OpenGL < 2, which is about ~5% users (probably this number is even lower now), which is not a lot, and could eventually be dropped if needed, as already discussed in the past here. There are however ~20% user with OpenGL 2.x, so probably not worth dropping it.

I would suggest to start proposing some small and incremental changes before doing big rewriting, just to get in taste with 0 A.D. development.

Link to comment
Share on other sites

I was actually wrong about that. MRT has been supported since OpenGL 2.0. I doubt that I'll actually even require any 3.x features. I also found a normal "if" condition in the water shader, so apparently that's nothing new either (nor something required often, but it's nice to know that it's supported).

 

Also, I'm working on finishing up a basic patch for water reflections/refractions atm, which will probably be finished tomorrow. I'm not really intending to try to do all of that at once, but that is the direction I'm looking at for the long term.

Edited by aeonios
  • Like 1
Link to comment
Share on other sites

Hmm.. that'd be doable but I'm not sure how practical it'd be. You'd have to render the scene once per reflective surface, although not necessarily at a large resolution. It's also not historically accurate since there were not very good mirrors back then (personal mirrors were copper and not all that specular).

 

Yves's project seems to be focused on minimizing the number of draw calls, which is certainly a major CPU-side overhead currently. I should note that GLMultiDrawArrays is listed as GL 1.4 and supported by 99% of all players. I don't see why any of that should require GL4.0 to be used. It's also complimentary to deferred shading.

 

Another thing I noticed is that the renderer currently uses 9001 different FBOs, basically one per texture. Switching between FBOs is actually quite expensive, whereas swapping the textures attached to an FBO is cheap. Ideally the renderer would use exactly one FBO and just swap the attached textures as needed (and an FBO can have at least half a dozen different color textures attached at once).

  • Like 2
Link to comment
Share on other sites

Are you sure about FBOs?

 

Also Yves is definitely focusing on draw calls but not only that, and porting to OpenGL 4.0 requires quite q few changes so definitely talk to him if you wish to update the renderer.

FYI the chrome was never committed as there were some slight issues with implementation details, but it used the skybox, not a "real" 3D Reflection. It would be pretty much impossible to render realistic reflections for arbitrary items, but for a few very important ones we could in theory render a very downsampled box texture of the surrounding terrain. This is the technique used by games such as GTA5.

 

My belief remains that we need to implement software batching by actually merging objects together to unlock great performance.

 

Also FYI the water shader is really separate from the rest so I used an "if" there as it was supposed to be a more "modern" feature, which are very widely supported. The rest of the code is supposed to be runnable for an Opengl 2 system, but that decision might change.

  • Like 1
Link to comment
Share on other sites

15 hours ago, wraitii said:

Are you sure about FBOs?

This was my source regarding FBOs: http://www.songho.ca/opengl/gl_fbo.html

15 hours ago, wraitii said:

Also Yves is definitely focusing on draw calls but not only that, and porting to OpenGL 4.0 requires quite q few changes so definitely talk to him if you wish to update the renderer.

Updating to 4.0 would alienate more than half of all players, and if it's optional then it shouldn't interfere with the rest of the code anyway. Eventually I'll look through his code and see what he's actually trying to do and how that could best fit in. I'm not really to the point where it's relevant yet anyway though.

15 hours ago, wraitii said:

My belief remains that we need to implement software batching by actually merging objects together to unlock great performance.

That's what deferred shading does basically. First all objects are rendered onto a scene texture without lighting, and then all of the lighting calculations are done on the scene texture rather than per-object. Basically the entire scene becomes one object when fragment shading, which reduces the number of fragments that need to be produced.

15 hours ago, wraitii said:

Also FYI the water shader is really separate from the rest so I used an "if" there as it was supposed to be a more "modern" feature, which are very widely supported. The rest of the code is supposed to be runnable for an Opengl 2 system, but that decision might change.

The "if" I was talking about was actually the branch for the red-water issue, which is an "if" as opposed to an "#if". That's actually only supported by GL3.1 or newer, which I didn't notice before, but that's probably the only thing in the entire shader which isn't 2.0 compatible. TBH I'm not even sure why that compiles when the shader version is set to 110 and dynamic conditionals require version 140.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...
On 12.02.2016 at 8:42 AM, aeonios said:

This was my source regarding FBOs: http://www.songho.ca/opengl/gl_fbo.html

Updating to 4.0 would alienate more than half of all players, and if it's optional then it shouldn't interfere with the rest of the code anyway. Eventually I'll look through his code and see what he's actually trying to do and how that could best fit in. I'm not really to the point where it's relevant yet anyway though.

That's what deferred shading does basically. First all objects are rendered onto a scene texture without lighting, and then all of the lighting calculations are done on the scene texture rather than per-object. Basically the entire scene becomes one object when fragment shading, which reduces the number of fragments that need to be produced.

The "if" I was talking about was actually the branch for the red-water issue, which is an "if" as opposed to an "#if". That's actually only supported by GL3.1 or newer, which I didn't notice before, but that's probably the only thing in the entire shader which isn't 2.0 compatible. TBH I'm not even sure why that compiles when the shader version is set to 110 and dynamic conditionals require version 140.

Supporting of OpenGL3+ is a good idea, and I think it would be good to have separated (possibility to switch) renderers (2 - why we have arb shaders, 3.1, 4+, probably vulkan). Disabling of sky isn't good idea, because sky and reflections should use the same texture, and it doesn't really save time, instead f.e. lods, async ocqueries, geomips and many other things, that we haven't implemented yet.

I think no need to move shaders, because shaders are moddable, so user shouldn't go to engine to change them.

Deferred shading doesn't actually do what you said to wraitii about batching (he means something else), it saves time for fragment processing (it's something in other way), but not vertex. Batching and instancing saves cpu time (because no need to change states so often) and gpu time (no need to change cache so often to calc vertices). But yes, deferred shading is the good technique, and we need it, but there are few things: we need to store the g-buffer as small as possible (components packing), more number of textures to rendering.

Dirs 'graphics' and 'renderer' don't do the same thing, 'graphics' is mostly preprocessing, and 'renderer' is actually rendering.

UPD. FBOs, it's not actually true, because we don't need to switch between all FBO textures, why? Because we switch to FBO only when need to render to that, but we could use this textures without a FBO binding. So mostly it isn't expensive, but really we don't need so many FBOs.

Edited by vladislavbelov
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...