Rendering system improvements: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(Fixed grammatical errors using Grammarly)
 
Line 1: Line 1:
This page is intended to be a talk about possible technical changes to the FlightGear rendering engine to allow better appearance and performance. Please keep feature requests etc on some other page.
This page is intended to be a talk about possible technical changes to the FlightGear rendering engine to allow better appearance and performance. Please keep feature requests etc on some other page.


= Current state =
== Current state ==
This section describes how the scenery is currently rendered.
This section describes how the scenery is currently rendered.


== Rendering system ==
== Rendering system ==
Flightgear has mostly one pass rendering system, where the whole scenery is rendered in one pass. Lighting is applied directly when rendering, and currently there is support for only one light (the sun).
Flightgear has mostly one pass rendering system, where the whole scenery is rendered in one pass. Lighting is applied directly when rendering, and currently, there is support for only one light (the sun).


== Cameras ==
== Cameras ==
By default flightgear has at least three cameras: Near camera, far camera and gui camera. The first two are used to render the scenery and the last one is used to render all(?) 2D stuff, like menus.
By default, FlightGear has at least three cameras: Near camera, far camera, and GUI camera. The first two are used to render the scenery and the last one is used to render all(?) 2D stuff, like menus.


Scenery cameras render so that the far camera is rendered first and then the near camera. The transition is at 100 meters by default (iirc). Near camera has znear at around 1cm and far camera has zfar at ~12km.
Scenery cameras render so that the far camera is rendered first and then the rear camera. The transition is at 100 meters by default (IIRC). Near camera has near at around 1cm and the far camera has far at ~12km.


The near/far camera system is in place because of zbuffer precision issues, which appear if one wants to render things very near and very far. See [http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html].
The near/far camera system is in place because of buffer precision issues, which appear if one wants to render things very near and very far. See [http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html].


== Rendering order ==
== Rendering order ==
Line 28: Line 28:


(*) 2D clouds are rendered differently, the rendering order is from bottom to top and top to bottom, the render bins do not very well match 3D cloud bin leading to artifacts.
(*) 2D clouds are rendered differently, the rendering order is from bottom to top and top to bottom, the render bins do not very well match 3D cloud bin leading to artifacts.
(**) Translucent objects should be renderd in the same bin as 3D clouds, but currently they are rendered after clouds, so they can be seen through the clouds which looks wrong.
(**) Translucent objects should be rendered in the same bin as 3D clouds, but currently, they are rendered after clouds, so they can be seen through the clouds which looks wrong.
(***) The cockpit mostly fits the near camera and that's why it's rendered last.
(***) The cockpit mostly fits the near camera and that's why it's rendered last.


This order leads to significant amount of overdraw, terrain is drawn over the sky and cockpit is then drawn over the terrain. With heavy shaders this overdraw is slow.
This order leads to a significant amount of overdraw, the terrain is drawn over the sky and cockpit is then drawn over the terrain. With heavy shaders this overdraw is slow.


= Other rendering systems =
== Other rendering systems ==
== One pass multi lights ==
== One pass multi lights ==
In this method, the scene is rendered in one pass and shaders/lighting models takes all lights into account.
In this method, the scene is rendered in one pass and shaders/lighting models take all lights into account.
* No overdraw
* No overdraw
* Limited amount of lights -> Suits for outdoor scenes with only sun/moon
* Limited amount of lights -> Suits for outdoor scenes with only sun/moon
Line 45: Line 45:
* Works with translucent objects
* Works with translucent objects


== Multi pass one light ==
== Multi-pass one light ==
Render only one light at the time, rendering the whole scene with additive blending for all lights.
Render only one light at the time, rendering the whole scene with additive blending for all lights.
* Infinite amount of lights
* Infinite amount of lights
* Huge amount of overdraw
* Huge amount of overdraw
* Needs heavy sorting and culling to improve speed
* Needs heavy sorting and culling to improve the speed
* Works with complex shaders
* Works with complex shaders
* Lighting model depends on the object, can have various different models
* Lighting model depends on the object, can have various different models
Line 65: Line 65:
* Geometry pass shader is/should be simple and fast
* Geometry pass shader is/should be simple and fast
* One lighting shader for all geometry -> limited lighting models (maybe 4 different lighting types)
* One lighting shader for all geometry -> limited lighting models (maybe 4 different lighting types)
* No overdraw in lighting pass
* No overdraw in the lighting pass
* Does not work with translucent objects
* Does not work with translucent objects


Line 71: Line 71:
A mixed system combines some of the above to give good performance and visual appearance. I think something like this could suit our needs:
A mixed system combines some of the above to give good performance and visual appearance. I think something like this could suit our needs:
* Render scene with one pass, use two lights: sun and moon
* Render scene with one pass, use two lights: sun and moon
* Render diffuse color and depth (and normal?) to texture targets -> allows post processing effects
* Render diffuse color and depth (and normal?) to texture targets -> allows post-processing effects
* Render all other small lights using those textures -> the ''light cone'' approach
* Render all other small lights using those textures -> the ''light cone'' approach
** Texture targets allow recovering the original color during night
** Texture targets allow recovering the original color during night
** Storing normal and depth allows rendering smooth light in the light cone
** Storing normal and depth allows rendering smooth light in the light cone
** Light cones can be easily culled by visiblity
** Light cones can be easily culled by visibility
* Allows various lighting models in the sun/moon pass, light cones have all only basic lighting model
* Allows various lighting models in the sun/moon pass, light cones have all only basic lighting model
* Light cones need stencil operations and changing the front/backface culling -> might be slow?
* Light cones need stencil operations and changing the front/backface culling -> might be slow?
* Fog rendered as a post process quad (after opaque geometry) -> same fog for every object
* Fog rendered as a post-process quad (after opaque geometry) -> same fog for every object
* Translucent objects?
* Translucent objects?


= Rendering systems in other projects =
== Rendering systems in other projects ==
Currently just a placeholder to write some notes about other projects and what we might learn from them.
Currently, just a placeholder to write some notes about other projects and what we might learn from them.


== Outerra ==
== Outerra ==
Line 92: Line 92:
* Limited amount of materials (4?) -> Easy to mix on shader level
* Limited amount of materials (4?) -> Easy to mix on shader level


I don't really understand how are roads implemented in Outerra, some kind of shader level spline interpolator, but how can the amount of splines be large enough?
I don't really understand how are roads implemented in Outerra, some kind of shader level spline interpolator, but how can the number of splines be large enough?


Links:
Links:
Line 111: Line 111:
* Object performance: [http://xplanescenery.blogspot.com/2010/05/zen-and-art-of-obj-1-anatomy-of-obj.html], [http://xplanescenery.blogspot.com/2010/05/zen-and-art-of-obj-2-performance.html]
* Object performance: [http://xplanescenery.blogspot.com/2010/05/zen-and-art-of-obj-1-anatomy-of-obj.html], [http://xplanescenery.blogspot.com/2010/05/zen-and-art-of-obj-2-performance.html]


= Other things =
== Other things ==
== New rendering order ==
== New rendering order ==
To limit the overdraw, I suggest following rendering order:
To limit the overdraw, I suggest following rendering order:
# Opaque parts of cockpit
# Opaque parts of the cockpit
# Terrain
# Terrain
# Skydome
# Skydome
# Clouds (3D)/translucent objects
# Clouds (3D)/translucent objects
# Translucent parts of cockpit
# Translucent parts of the cockpit


With near/far camers there might be need to use stencil operations or similar to limit rendering only to parts visible from the cockpit.
With near/far cameras there might need to use stencil operations or similar to limit rendering only to parts visible from the cockpit.


== Get rid of near/far camera ==
== Get rid of near/far camera ==
Line 127: Line 127:
=== Custom z function ===
=== Custom z function ===
Use custom z function in the shader, for example log(z).
Use custom z function in the shader, for example log(z).
* Better precision -> no z fighting
* Better precision -> no z fighting
* Cannot use early z kill in the shader -> All pixels are evaluated -> Slow
* Cannot use early z kill in the shader -> All pixels are evaluated -> Slow
Line 132: Line 133:
An interesting read: [http://www.humus.name/index.php?ID=255]
An interesting read: [http://www.humus.name/index.php?ID=255]


=== Floating point z buffer ===
=== Floating point z-buffer ===
* Link to NVidia extension, that allows unclamped depth values to be written into depth buffer. It seems to be a draft and not accepted, though: [http://developer.download.nvidia.com/opengl/specs/GL_NV_depth_buffer_float.txt]
* Link to NVidia extension, that allows unclamped depth values to be written into the depth buffer. It seems to be a draft and not accepted, though: [http://developer.download.nvidia.com/opengl/specs/GL_NV_depth_buffer_float.txt]
* This extension might be related too: [http://www.opengl.org/registry/specs/EXT/wgl_depth_float.txt]
* This extension might be related too: [http://www.opengl.org/registry/specs/EXT/wgl_depth_float.txt]
* Tim Moore has done some things with fp-zbuffer: [http://shiny-dynamics.blogspot.com/2010/03/floating-point-depthbuffers-in-osg.html] and an example:[http://cache.gmane.org//gmane/comp/graphics/openscenegraph/cvs/7284-002.bin]
* Tim Moore has done some things with fp-buffer: [http://shiny-dynamics.blogspot.com/2010/03/floating-point-depthbuffers-in-osg.html] and an example:[http://cache.gmane.org//gmane/comp/graphics/openscenegraph/cvs/7284-002.bin]


=== Cockpit only near camera ===
=== Cockpit only near camera ===
Render only the inside view using near camera, everything else with far camera. Put the transition to somewhere around 0.5-1.0m.
Render only the inside view using near the camera, everything else with far camera. Put the transition to somewhere around 0.5-1.0m.
* Is the precision then sufficient?
* Is the precision then sufficient?
* No z fighting in the instruments
* No z-fighting in the instruments
* Can render everything else in single pass
* Can render everything else in a single pass
* Might need to use stencil operations with cockpit if cockpit is rendered first
* Might need to use stencil operations with cockpit if the cockpit is rendered first


= Performance or eye candy related things =
== Performance or eye candy related things ==
Ideas to boost the performance of the renderer.
Ideas to boost the performance of the renderer.


== Shared object performance ==
== Shared object performance ==
* If object uses only one texture image for one object and only one material and no animations
* If an object uses only one texture image for one object and only one material and no animations
* => Use a smart combining algorithm to combine hundreds of similar objects to one object ([https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter03.html])
* => Use a smart combining algorithm to combine hundreds of similar objects to one object ([https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter03.html])
* Only vertices of the original array, copy face array for each clone, then a BIND_PER_PRIMITIVE attribute containing the center of the clone and a quaternion of it's rotation
* Only vertices of the original array, copy face array for each clone, then a BIND_PER_PRIMITIVE attribute containing the center of the clone and a quaternion of its rotation
* Shader places the object correctly, no state changes during the rendering of ~100 objects => fast
* Shader places the object correctly, no state changes during the rendering of ~100 objects => fast
* Similar system is in use for the trees and clouds
* Similar system is in use for the trees and clouds
* Most likely breaks height-over-terrain and other collision checking
* Most likely breaks height-over-terrain and another collision checking


== Grass and vegetation ==
== Grass and vegetation ==
Line 168: Line 169:
* Rendering of wet materials [http://groups.csail.mit.edu/graphics/pubs/wet_materials_egwr99.pdf]
* Rendering of wet materials [http://groups.csail.mit.edu/graphics/pubs/wet_materials_egwr99.pdf]
* Apply a more "metallic" shader as a default for aircraft models? Link?
* Apply a more "metallic" shader as a default for aircraft models? Link?
* Atmospheric scattering, at least for skydome, maybe for terrain too (Post process if using mixed mode?)
* Atmospheric scattering, at least for skydome, maybe for terrain too (Post process if using mixed-mode?)
* Different models are described here (taken from [[Shader requests]]): [http://wiki.gamedev.net/index.php/D3DBook:Lighting]. A simple summarty:
* Different models are described here (taken from [[Shader requests]]): [http://wiki.gamedev.net/index.php/D3DBook:Lighting]. A simple summary:
** Plastic: Phong or Blinn-Phong (currently the only model)
** Plastic: Phong or Blinn-Phong (currently the only model)
** Metals and Plastics: Cook-Torrance, Strauss
** Metals and Plastics: Cook-Torrance, Strauss
** Rough surfaces: Oren-Nayar
** Rough surfaces: Oren-Nayar
** Clothing, anisotropic surfaces: Ward
** Clothing, anisotropic surfaces: Ward
** Other models for probably wide range of materials: Ashikhmin-Shirley
** Other models for a probably wide range of materials: Ashikhmin-Shirley


= Related wiki pages =
== Related wiki pages ==
* [[Proposals:Scenery related]]
* [[Proposals:Scenery related]]
* [[Proposals:Eye Candy related]]
* [[Proposals:Eye Candy related]]
Line 182: Line 183:
* [[TerraGear texmapped line data]]
* [[TerraGear texmapped line data]]
* [[Shader requests]]
* [[Shader requests]]


[[Category:Developer Plans]]
[[Category:Developer Plans]]

Latest revision as of 09:46, 7 September 2019

This page is intended to be a talk about possible technical changes to the FlightGear rendering engine to allow better appearance and performance. Please keep feature requests etc on some other page.

Current state

This section describes how the scenery is currently rendered.

Rendering system

Flightgear has mostly one pass rendering system, where the whole scenery is rendered in one pass. Lighting is applied directly when rendering, and currently, there is support for only one light (the sun).

Cameras

By default, FlightGear has at least three cameras: Near camera, far camera, and GUI camera. The first two are used to render the scenery and the last one is used to render all(?) 2D stuff, like menus.

Scenery cameras render so that the far camera is rendered first and then the rear camera. The transition is at 100 meters by default (IIRC). Near camera has near at around 1cm and the far camera has far at ~12km.

The near/far camera system is in place because of buffer precision issues, which appear if one wants to render things very near and very far. See [1].

Rendering order

Scenery is rendered in following order (this is from my memory, there might be some errors....)

  1. Skydome
    1. Sky itself
    2. Stars
    3. Moon and sun halos
    4. Moon and sun
  2. Terrain and opaque objects
  3. Clouds (3D) (Back-to-front) (*)
  4. Translucent objects (Back-to-front) (**)
  5. Lights
  6. Cockpit (***)

(*) 2D clouds are rendered differently, the rendering order is from bottom to top and top to bottom, the render bins do not very well match 3D cloud bin leading to artifacts. (**) Translucent objects should be rendered in the same bin as 3D clouds, but currently, they are rendered after clouds, so they can be seen through the clouds which looks wrong. (***) The cockpit mostly fits the near camera and that's why it's rendered last.

This order leads to a significant amount of overdraw, the terrain is drawn over the sky and cockpit is then drawn over the terrain. With heavy shaders this overdraw is slow.

Other rendering systems

One pass multi lights

In this method, the scene is rendered in one pass and shaders/lighting models take all lights into account.

  • No overdraw
  • Limited amount of lights -> Suits for outdoor scenes with only sun/moon
    • OpenGL fixed pipeline supports 10 lights
    • With shaders it depends on the available uniforms/varyings. Depending on the shader complexity, maybe 4 lights would be possible
  • Lighting model depends on the object, can have various different models
  • Lighting is calculated for all pixels for all lights, even if they are unlit
  • Must do sorting by light volume to select best lights
  • Works with translucent objects

Multi-pass one light

Render only one light at the time, rendering the whole scene with additive blending for all lights.

  • Infinite amount of lights
  • Huge amount of overdraw
  • Needs heavy sorting and culling to improve the speed
  • Works with complex shaders
  • Lighting model depends on the object, can have various different models
  • Depending on the culling, lighting is only calculated for objects that are in the light
  • Has issues with translucent objects

Deferred shading

In deferred shading, the whole scene is first rendered with a simple shader that writes diffuse color, normal, depth, and other parameters to multiple textures (G-buffer). Then, lighting is calculated with those parameters. See for example [2] and [3].

  • Infinite amount of lights
  • One big light is about as heavy as many small ones
  • Suits for indoor scenes with multiple small lights
  • Rendering target precision is an issue (especially normal buffer)
  • Large memory footprint
  • Geometry pass shader is/should be simple and fast
  • One lighting shader for all geometry -> limited lighting models (maybe 4 different lighting types)
  • No overdraw in the lighting pass
  • Does not work with translucent objects

Mixed

A mixed system combines some of the above to give good performance and visual appearance. I think something like this could suit our needs:

  • Render scene with one pass, use two lights: sun and moon
  • Render diffuse color and depth (and normal?) to texture targets -> allows post-processing effects
  • Render all other small lights using those textures -> the light cone approach
    • Texture targets allow recovering the original color during night
    • Storing normal and depth allows rendering smooth light in the light cone
    • Light cones can be easily culled by visibility
  • Allows various lighting models in the sun/moon pass, light cones have all only basic lighting model
  • Light cones need stencil operations and changing the front/backface culling -> might be slow?
  • Fog rendered as a post-process quad (after opaque geometry) -> same fog for every object
  • Translucent objects?

Rendering systems in other projects

Currently, just a placeholder to write some notes about other projects and what we might learn from them.

Outerra

[4]

  • Continuous noise coordinates -> continuous noise function
  • Slope, curvature etc as vertex attributes
  • Terrain refinement on load time and on shader
  • Trees -> Billboards -> Baked texture
  • Limited amount of materials (4?) -> Easy to mix on shader level

I don't really understand how are roads implemented in Outerra, some kind of shader level spline interpolator, but how can the number of splines be large enough?

Links:

  • About procedural terrain refinement: [5]
  • Horizontal displacement: [6], [7]
  • Logarithmic z-buffer: [8]
  • Floating point z-buffer: [9]

X-Plane

[10]

  • X-Plane 10 uses deferred shading for global illumination, see link below.
  • Seven LOD levels for clouds, from 1mx1m upwards

Links:

  • Auto-variation in terrain textures: [11], [12]
  • Visiblity (how far is far enough?): [13]
  • Global illumination: [14], videos [15]
  • Object performance: [16], [17]

Other things

New rendering order

To limit the overdraw, I suggest following rendering order:

  1. Opaque parts of the cockpit
  2. Terrain
  3. Skydome
  4. Clouds (3D)/translucent objects
  5. Translucent parts of the cockpit

With near/far cameras there might need to use stencil operations or similar to limit rendering only to parts visible from the cockpit.

Get rid of near/far camera

Ways to get rid of near and far cameras.

Custom z function

Use custom z function in the shader, for example log(z).

  • Better precision -> no z fighting
  • Cannot use early z kill in the shader -> All pixels are evaluated -> Slow
  • Shaders can easily modify z value -> relief mappign etc

An interesting read: [18]

Floating point z-buffer

  • Link to NVidia extension, that allows unclamped depth values to be written into the depth buffer. It seems to be a draft and not accepted, though: [19]
  • This extension might be related too: [20]
  • Tim Moore has done some things with fp-buffer: [21] and an example:[22]

Cockpit only near camera

Render only the inside view using near the camera, everything else with far camera. Put the transition to somewhere around 0.5-1.0m.

  • Is the precision then sufficient?
  • No z-fighting in the instruments
  • Can render everything else in a single pass
  • Might need to use stencil operations with cockpit if the cockpit is rendered first

Performance or eye candy related things

Ideas to boost the performance of the renderer.

Shared object performance

  • If an object uses only one texture image for one object and only one material and no animations
  • => Use a smart combining algorithm to combine hundreds of similar objects to one object ([23])
  • Only vertices of the original array, copy face array for each clone, then a BIND_PER_PRIMITIVE attribute containing the center of the clone and a quaternion of its rotation
  • Shader places the object correctly, no state changes during the rendering of ~100 objects => fast
  • Similar system is in use for the trees and clouds
  • Most likely breaks height-over-terrain and another collision checking

Grass and vegetation

[24] and [25]

  • Make tree blobs larger, i.e. more trees on a single object
  • Remove the second pass of the tree rendering effect if possible

Clouds

  • Volume rendering [26]
  • Render far away clouds to a texture and then render that image as a billboard
  • Needs to refresh the cloud texture every now and then

Lighting models

  • Rendering of wet materials [27]
  • Apply a more "metallic" shader as a default for aircraft models? Link?
  • Atmospheric scattering, at least for skydome, maybe for terrain too (Post process if using mixed-mode?)
  • Different models are described here (taken from Shader requests): [28]. A simple summary:
    • Plastic: Phong or Blinn-Phong (currently the only model)
    • Metals and Plastics: Cook-Torrance, Strauss
    • Rough surfaces: Oren-Nayar
    • Clothing, anisotropic surfaces: Ward
    • Other models for a probably wide range of materials: Ashikhmin-Shirley

Related wiki pages