Travail en cours Dans les heures ou les jours suivants, des travaux sur cet article ou section seront effectués. Voyez l'histoire de l'article pour les derniers développements. |
Pourquoi ce nom?
Rembrandt était un peintre hollandais du XVIIème siècle, maître incontesté du "clair-obscur".
Ce projet a pour but de changer la manière de rendre les éclairages et les ombres qu'utilise FlightGear, et d'essayer d'imiter le style de Rembrandt dans FG.
De quoi s'agit-il ?
L'idée maîtresse du projet est d'implémenter le rendu différé au sein de FlightGear. Depuis le début, FlightGear utilise un moteur de rendu en avant qui affiche toutes les propriétés d'un objet en une fois (ombre, éclairage, brouillard, ...), ce qui rend difficile le rendu d'un ombrage plus sophistiqué (voir le 'Uber-shader') du fait que tous les paramètres de l'équation lumineuse doivent être traités en une seule fois.
Au contraire, le rendu différé cherche à séparer les opérations en étapes simplifiées et à collecter les résultats intermédiaires dans des buffers cachés, qui peuvent être utilisés par la prochain étape.
- Le premier stade est celui de la Géométrie
- nous rendons la scène entière dans 4 textures, en utilisant le rendu multi-cibles pour les traiter en un seul passage: un pour le buffer de profondeur, un pour les normales (en bas à gauche de l'image), un pour les couleurs "diffuses" (en bas à gauche) et un pour les couleurs "spéculaires" (en haut à droite).
- Le stade suivant est celui de l'ombre
- nous rendons encore la scène dans une texture profondeur concernant les éclairages. Il y aura une texture pour chaque lumière diffusant des ombres.
- Ensuite, c'est le stade de l'éclairage, avec plusieurs sous-stades
-
- Sky pass: Le ciel est dessiné d'abord selon la méthode classique.
- Ambient pass: la mémoire-tampon "diffuse" est modulé avec la couleur ambiante de la scène, et est dessiné comme un quad texturé aligné sur l'écran
- Sunlight pass: Un second quad aligné à l'écran est dessiné et un shader examine la position pour calculer sa couleur "diffuse" et "specular" en utilisant le "normal" stocké dans le premier stade. La couleur résultante et mélangée avec la passe précédente. Les ombres sont examinées ici par comparaison de la position du pixel avec la position du cache lumière stockée dans la carte shadows
- stade de la lumière additionnelle: le scene graph sera traversé une autre fois pour afficher les volumes de lumière (cône ou tronc de cône pour les taches de lumière, sphère pour les lumières omni directionnelles), et leur shader ajoutera la lumière composée uniquement par les pixels éclairés.
- stade brouillard: un nouveau quad aligné sur l'écran est dessiné, et la position du pixel est calculée pour évaluer la quantité de brouillard du pixel. La couleur du brouillard est mélangée avec le résultat du stade précédent.
- Stade des objets transparents: les objets transparents (et les nuages) sont enfin rendus en utilisant la méthode classique.
- Tous les données de lumière sont accumulées dans une seule mémoire tampon, qui sera utilisée pour le dernier stade en addition au stade Géométrie.
- A la fin, le stade affichage, avec l'option effet post-traitement
- Les résultats des précédents tampons sont poussés dans le tampon principal pour être affichés, optionnellement modifiés pour montrer Glow, Motion blur, HDR, redout ou blackout, occlusion ambiante de l'espace écran, anti-aliasing, etc...
Dans FG, on termine le pipeline du rendu par l'affichage du GUI et du HUD.
Tous ces phases sont plus précisément décrites dans tutorial c'est la base du code actuel, avec quelque addition ou modifications.
Avertissements
Le rendu différé n'affiche pas la transparence. Pour le moment, les nuages doivent être éclairés et ombrés par eux-mêmes. Les surfaces transparentes sont alpha-testées et non mélangées. Elles doivent être amenées dans leur propre bin sur l'image composite.
La partition profondeur ne marche pas non plus, à cause de la mémoire tampon profondeur, qui doit être gardée pour retenir la position de zone de vue, et, pour le moment, z-fighting est tout à fait visible. La partition profondeur sans rangée de profondeur superposée pourrait être la solution, et devrait être essayée.
Le passage de la lumière peut rendre certains MFD illisibles (ce qui utilisent une couleur émissive) car flous. Ils devront être traités comme transparents.
Mise en œuvre
Répertoires
Le code est la principale branche du répertoire officiel. Aucune autre localisation n'existe.
Rendu des surfaces transparentes
Les surfaces transparentes sont détectées par les plugins OSG loader qui captent la nuance de rendu TRANSPARENT_BIN
In the culling pass, the cull visitor orders transparent surfaces in transparent bin. In a cull callback attached to the Geometry camera, after the scenegraph traversal, the transparent bins are removed from the render stage and saved in a temporary collection. In a cull callback attached to the Lighting camera, after the scenegraph traversal, the transparent bins saved at the previous stage, are added to the render stage of the Lighting camera with a high order num. That way, the transparent surface are drawn on top of the scene lighted from the Gbuffer.
Memory consumption
For each camera defined in the camera group, there is a separate shadow map, so the video memory usage is :
- G-buffer and Lighting buffer: 20 bytes per pixel. For an HD screen (1920x1080) memory requirement is 40 Mb
- Shadow map: 3 x shadow_map_size x shadow_map_size bytes (if size is 8192, whole map size is 192 Mb
Not counting textures, display list or vertex buffers for models and terrain
3 HD screens require 120 Mb of memory for the buffers (shadow excluded), you're asking 3x8192x8192x3 = 576 Mb (megabytes) of memory for the shadows alone.
If you are seeing error messages during startup or FlightGear doesn't start up properly, it's probably because you don't have enough free video memory. Reduce the size of the shadow map in preferences.xml by locating
<map-size type="int">8192</map-size>
And put 4096 or 2048 instead. You can also use a startup parameter: --prop:/sim/rendering/shadows/map-size=2048
Configurable pipeline
The Rembrandt renderer uses an XML file to setup its pipeline for each viewport described in the camera group. This file describes the way the intermediary buffers are setup and how the different rendering stages are sequenced. The general outline of a pipeline file is as follow :
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<!-- BUFFERS -->
<buffer>
<!-- First buffer definition -->
</buffer>
<buffer>
<!-- nth buffer definition -->
</buffer>
<!-- STAGES -->
<stage>
<!-- First stage definition -->
</stage>
<stage>
<!-- nth stage definition -->
</stage>
</PropertyList>
Buffers
A buffer is a texture used as a storage area in the GPU. It's size is usually a multiple of the screen size, but fixed size is supported (typical for shadow map). The description of a buffer is described below :
<buffer>
<name>buffer-name</name>
<internal-format>rgba8</internal-format> <!-- rgb8, rgba8, rgb16, rgba16, rg16, depth-component24, depth-component32 or OpenGL hex value -->
<source-format>rgba</source-format> <!-- rg, rgb, rgba, depth-component or OpenGL hex value -->
<source-type>unsigned-byte</source-type> <!-- unsigned-byte, unsigned-short, unsigned-int, float or OpenGL hex value -->
<width>screen</width> <!-- screen, value or <property>/a/width/property</property> -->
<height>screen</height> <!-- screen, value or <property>/a/height/property</property> -->
<scale-factor>1.0</scale-factor>
<wrap-mode>clamp-to-border</wrap-mode> <!-- clamp, clamp-to-border, clamp-to-edge, mirror, repeat or OpenGL hex value -->
<!-- optional, for shadow map -->
<shadow-comparison>true</shadow-comparison>
<!-- optional condition -->
<condition>
<!-- Valid boolean expression -->
</condition>
</buffer>
Stages
A stage is an unit of rendering to a group of buffer. Most stages are predefined and their type is not free. When a type is not specified, the name is used. Stage types are :
Stage type | Purpose |
---|---|
geometry | The geometry stage initialize most of the buffers and works on the real objects and geometry. Transparent objects are set aside and will be used untouched in the lighting stage. Other opaque geometry is rendered with the standard effects that do the hard work to put sensible data in the buffers. |
shadow | In this stage, the geometry is rendered in the normal map from the perspective of the sun. |
lighting | This stage uses the buffers filled by the previous stages to light every pixel of the scene. The result is rendered in another buffer to allow post effects. |
fullscreen | Stages of this type are used to alter the whole scene or transform data from a particular buffer. |
display | Final rendering of the scene to the screen or the texture defined in the camera group. |
A stage description is outlined below :
<stage>
<name>stage-name</name>
<type>stage-type</type> <!-- optional if name is one of the predefined type except fullscreen -->
<order-num>-1</order-num>
<effect>Effects/fullscreen-effect</effect> <!-- only if type == fullscreen -->
<needs-du-dv>true</needs-du-dv> <!-- only if type == fullscreen -->
<scale-factor>0.25</scale-factor> <!-- only if type == fullscreen -->
<!-- optional condition -->
<condition>
<!-- Valid boolean expression -->
</condition>
<attachment>
<!-- First attachment definition -->
</attachment>
<attachment>
<!-- Nth attachment definition -->
</attachment>
<!-- Passes only for the lighting stage -->
<pass>
<!-- First pass definition -->
</pass>
<pass>
<!-- Nth pass definition -->
</pass>
</stage>
Stages render in buffers (except for the display stage). Attachments describe which buffers are affected by each stage.
Attachments
Attachment describe bindings between buffer and attachment point :
<attachment>
<component>color0</component> <!-- depth, stencil, packed-depth-stencil, color0, color1, color2 or color3 -->
<buffer>buffer-name</buffer>
<!-- optional condition -->
<condition>
<!-- Valid boolean expression -->
</condition>
</attachment>
Passes
Passes are only available in the lighting stage. Three kind of stage are allowed :
Pass type | Purpose |
---|---|
sky-clouds | Renders the skydome, sun, moon, planet, stars and clouds |
lights | Renders additional spot and point lights |
fullscreen | Fullscreen pass analog to a fullscreen stage except that it renders in the buffers attached to the lighting stage |
A pass is defined like below :
<pass>
<name>pass-name</name>
<type>pass-type</type> <!-- optional if name is one of the predefined type except fullscreen -->
<order-num>-1</order-num>
<effect>Effects/fullscreen-effect</effect> <!-- only if type == fullscreen -->
<!-- optional condition -->
<condition>
<!-- Valid boolean expression -->
</condition>
</pass>
A typical lighting stage is a succession of 5 passes :
- sky-clouds pass
- fullscreen pass for ambient light
- fullscreen pass for sun light (and shadows)
- lights pass
- fullscreen pass for fog
Each effect attached to the fullscreen passes define the way blending is done between the pass and the previous accumulation of render.
Running Flightgear with Rembrandt
The Rembrandt renderer is now integrated in the main repository but needs to be enabled to run. There are two ways to enable it (only one is needed!):
--enable-rembrandt
(when using FGRun, you may add this behind the FG_EXECUTABLE on the first page).--prop:/sim/rendering/rembrandt/enabled=true
(with FGRun this can be added via Advanced > Properties on the last page).
The View > Rendering Options > Rembrandt Options dialog allows you to toggle and adjust the various features that Rembrandt offers.
Rembrandt is quite demanding in GPU resources and may fail to run with the default options. The more frequent symptom is an OSG message in the console :
RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x8cd6 Warning: RenderStage::runCameraSetUp(State&) Pbuffer does not support multiple color outputs.
Some card also exhibit messages like this :
glLinkProgram "" FAILED Program "" infolog: Fragment info ------------- 0(37) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable 0(36) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable 0(35) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable 0(34) : error C6013: Only arrays of texcoords may be indexed in this profile, and only with a loop index variable
There is a number of additional options that can help to avoid these problems :
--prop:/sim/rendering/rembrandt/use-color-for-depth=true | Some old NVidia cards, such as 7600GT, don't give enough resolution for depth and that result in "fog curtains" at few meters from the viewer. One trick is to encode depth in another texture and get the proper value afterward. This option enables that. |
--prop:/sim/rendering/shadows/enabled=false | Disable shadows altogether. |
--prop:/sim/rendering/shadows/num-cascades=1 | Avoid the "error C6013" message on old cards at the cost of resolution in the cockpit. Set /sim/rendering/shadows/cascade-far-m[0] to change the shadow map range. The more the range, the less the resolution (default value is 5 meters) |
--prop:/sim/rendering/shadows/map-size=<power-of-two> | Set the shadow map size. Useful values are 1024, 2048, 4096 or 8192. Few cards have the resources to support 16384. |
--prop:/sim/rendering/shadows/num-cascades | Set the shadow map cascade number. Less cascades means less time spent in shadow map generation, but also means lower shadow quality. Integer between 1 and 4. |
--prop:/sim/rendering/shadows/cascade-far-m[i]
(1 <= i <= /sim/rendering/shadows/num-cascades <= 4) |
Set the shadow map cascade range for each cascade. Default values are 5m, 50m, 500m and 5000m for 4 cascades. |
--prop:/sim/rendering/rembrandt/no-16bit-buffer=false | By default, Rembrandt uses 8 bit buffers for normals (so the property is set to true by default). This may create banding artifacts on specular highlights. If it's unacceptable and the GPU supports it, set to false to have better precision for normals and effects relying on normal direction. |
Guidelines for shader writers
Predefined uniforms
These glsl uniforms don't need to be declared in the effect file.
Name | Type | Purpose |
---|---|---|
fg_ViewMatrix | mat4 | In fullscreen pass only, view matrix used to transform the screen position to view direction |
fg_ViewMatrixInverse | mat4 | In fullscreen pass only, view matrix inverse used to transform the screen position to view direction |
fg_ProjectionMatrixInverse | mat4 | In fullscreen pass only, projection matrix inverse used to transform the screen position to view direction |
fg_CameraPositionCart | vec3 | Position of the camera in world space, expressed in cartesian coordinates |
fg_CameraPositionGeod | vec3 | Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters) |
fg_SunAmbientColor | vec4 | |
fg_SunDiffuseColor | vec4 | |
fg_SunSpecularColor | vec4 | |
fg_SunDirection | vec3 | |
fg_FogColor | vec4 | |
fg_FogDensity | float | |
fg_ShadowNumber | int | |
fg_ShadowDistances | vec4 | |
fg_DepthInColor | bool | Tells if the depth is stored in a depth texture or a color texture |
fg_Planes | vec3 | Used to convert the value of the depth buffer to a depth that can be used to compute the eye space position of the fragment |
fg_BufferSize | vec2 | Dimensions of the buffer, used to convert gl_FragCoord into the range [0..1][0..1] |
osg_ViewMatrix | mat4 | Defined by OSG, used only when working on actual geometry |
osg_ViewMatrixInverse | mat4 | Defined by OSG, used only when working on actual geometry |
They still have to be declared in the fragment or the vertex shader to be used.
Utility functions
To ease the maintenance of shaders, several utility functions are available for the fragment shader. These functions are put together in two files : gbuffer-functions.frag and gbuffer-encode.frag.
gbuffer-encode.frag
- void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)
- Used to encode all the values of the G-Buffer in material shaders
gbuffer-functions.frag
- vec2 normal_encode(vec3 n)
- Used to compress normals into the G-Buffer in material shaders. Normally called from encode_gbuffer()
- vec3 normal_decode(vec2 enc)
- Reconstruct normals from the G-Buffer. Used in fullscreen shaders and light shaders
- vec3 float_to_color(in float f)
- Encode float values in the range [0..1] in the 24 bits of a color. This function is used by encode_gbuffer() if the /sim/rendering/use-color-for_depth is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.
- float color_to_float(vec3 color)
- Decode float values in the range [0..1] from the 24 bits of a color. This function is used by position() if the /sim/rendering/use-color-for_depth is true, for old cards that don't provide depth information with enough resolution inside fullscreen or light shaders.
- vec3 position( vec3 viewDir, float depth )
- Reconstruct eye space position from the view direction and the depth read from the depth buffer
- vec3 position( vec3 viewDir, vec3 depthColor )
- Reconstruct eye space position from the view direction and the depth encoded in a color read from the depth buffer
- vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )
- Reconstruct eye space position from the view direction and the depth buffer (real depth or color, according to the value of /sim/rendering/use-color-for_depth) at a given fragment on screen, given by coords
Usage
For material shaders, it is necessary to provide both gbuffer-functions.frag and gbuffer-encode.frag in the effect file, like this :
<program>
<vertex-shader>Shaders/ubershader.vert</vertex-shader>
<fragment-shader>Shaders/ubershader-gbuffer.frag</fragment-shader>
<fragment-shader>Shaders/gbuffer-functions.frag</fragment-shader>
<fragment-shader>Shaders/gbuffer-encode.frag</fragment-shader>
</program>
For fullscreen passes shaders, only gbuffer-functions.frag should be provided, like this :
<program>
<vertex-shader>Shaders/sunlight.vert</vertex-shader>
<fragment-shader>Shaders/sunlight.frag</fragment-shader>
<fragment-shader>Shaders/gbuffer-functions.frag</fragment-shader>
</program>
In the main function of the shader, the functions referenced need to be declared first. With no #include files, the whole function prototype needs to be typed :
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);
main() {
vec3 normal;
vec3 color;
int mId;
float specular;
float shininess;
float emission;
float depth;
// Do shader computations
encode_gbuffer(normal, color, mId, specular, shininess, emission, depth);
}
Geometry Stage
The Geometry Stage is there to fill the G-buffer. Shading doesn't occur at this stage, so light or fog computation should not be part of the shader. The required operation in the Fragment Shader is to fill every individual buffer with sensible value :
depth (gl_FragDepth) | GL_DEPTH_COMPONENT32 | Fragment depth | |||
gl_FragData[0] | GL_RG16 | normal.x * 0.5 + 0.5 | normal.y * 0.5 + 0.5 | ||
gl_FragData[1] | GL_RGBA8 | diffuse.r | diffuse.g | diffuse.b | material id * 1/255.0 |
gl_FragData[2] | GL_RGBA8 | specular.l | specular.s | emission.l | pixel valid if != 0 |
This is the default layout expected by the sunlight shader. material Id can be used to detect a different layout
Additional light pass
There would be a single shader for each light type used. The plan is to create lights like animations in the model XML file. The light shader will retrieve scene geometry by combining screen space position converted in view space ray by the inverse of the projection matrix (an helper function should be provided), and the fragment depth at that screen position read from the depth buffer. With the help of the fragment normal, the diffuse and specular color and the properties of the light the shader implements, it will be possible to add to the lighting buffer the contribution of the light rendered.
Fog Pass
Using the fragment depth, it will be possible to compute any fog distribution. For the moment, the simple fog equation is implemented.
Bloom Pass
This is a two-pass effect that blurs the lighting buffer in a small texture. This texture is then added to the lighting buffer at the display stage.
Required Effects
Several pass are implemented using the effect system. For this purpose, some effects are referenced in the core code using reserved names. these effects are:
Name | Kind | Purpose |
---|---|---|
Effects/ssao | Works on a full screen quad | Compute ambient occlusion from the normal buffer and the depth buffer |
Effects/ambient | Works on a full screen quad | Copies the diffuse color buffer multiplied by the ambient light to the lighting buffer. Ambient Occlusion can also affect ambient light. |
Effects/light-spot | Works on real geometry of the light volume | Computes the light contribution of a spot light defined in a light animation having a light-type of spot |
Effects/fog | Works on a full screen quad | Computes the fog from the G-buffer and the lighting parameters |
Effects/display | Works on a full screen quad | Renders the composite final image from the G-buffer and the lighting buffer |
Guidelines for modelers
Porting aircraft
- Rembrandt computes shadows => no more fake shadows in the model
- Rembrandt computes ambient occlusion => no ambient occlusion baked into textures
- Rembrandt has light => static lightmap are not needed, emissive color to see models at night is not needed and would interfere
- Rembrandt has glow => incorrectly used emissive colors may blur displays and make some text unreadable. Light size may have to be adjusted
- Rembrandt has strict needs with shaders => shaders need to be adjusted to comply with the new framework otherwise the view will be plain wrong
- Rembrandt can't do transparent surfaces => transparent surface need to be properly registered to render them with the classical path
Registering all translucent surfaces
Every model is, by default, rendered using the Effects/model-default effect. This effect initialize the G-buffer, ignoring transparent surfaces, by doing alpha testing and rendering all the geometry in the default bin. It is not possible to redirect rendering to transparent bins when the associated texture has alpha channel because most models use a single texture atlas and even opaque parts are rendered with texture with alpha channel.
If a model needs to have transparent or translucent surfaces, these surface objects need to be assigned a different effect that sets explicitly the render bin to "DepthSortedBin", or sets the rendering hint to "transparent". This tells the renderer to render this object using forward rendering, so lighting and fog need to be enabled, and if a shader program is used, they should be computed in the classical way. The Effects/model-transparent can be used to register simple transparent/translucent surfaces. You assign this effect to an object (or multiple objects) like:
<effect> <inherits-from>Effects/model-transparent</inherits-from> <object-name>TheObject</object-name> </effect>
If opaque surface need to have special effect, for example to apply bump mapping, this effect should use the "RenderBin" bin, or the rendering hint set to "opaque", and the G-buffer needs to be initialized correctly in the Geometry stage.
Adding lights to a model
There are two things to consider: the appearance of the light source and the illuminated area. For the appearance of the light source (what you see when you look at the bulb), you need a model with an emissive material that will produce the glow effect and that is visible at night.
For the effect of the source on its environment (the lit area), we must have in the 3D model (the .ac file) a volume that includes the effect (Light Volume). It can be a large cone for spotlights or a sphere for point light. It's important that the light volume is closed, convex and it's normals are oriented outward.
The light volume must be part of the geometry of the model and be referenced in the animation file. No need to add a color or an effect to this volume. Light calculation is only done on the fragments covered by the light volume, but has no influence on the color or the attenuation of the light.
All available animations are possible on the light volume, except material and texture. It is not possible to change color of lights for the moment, except switching to another animation. Axis and position are in object space and are transformed by the subsequent animations.
Spotlights
<animation>
<type>light</type>
<light-type>spot</light-type>
<name>LightSrcRight</name>
<object-name>LightRight</object-name>
<nopreview/>
<position>
<x>0.169</x>
<y>0.570</y>
<z>0.713</z>
</position>
<direction>
<x>-0.9988</x>
<y>0.0349</y>
<z>-0.0349</z>
</direction>
<ambient>
<r>0.03</r>
<g>0.03</g>
<b>0.03</b>
<a>1.0</a>
</ambient>
<diffuse>
<r>0.7</r>
<g>0.7</g>
<b>0.6</b>
<a>1.0</a>
</diffuse>
<specular>
<r>0.7</r>
<g>0.7</g>
<b>0.7</b>
<a>1.0</a>
</specular>
<dim-factor>
<property>dimming/property</property>
<!-- optional begin -->
<expression />
<interpolation />
<factor>1</factor>
<offset>0</offset>
<min>0</min>
<max>1</max>
<!-- optional end -->
</dim-factor>
<attenuation>
<c>1.0</c>
<l>0.002</l>
<q>0.00005</q>
</attenuation>
<exponent>30.0</exponent>
<cutoff>39</cutoff>
<near-m>3.5</near-m>
<far-m>39</far-m>
</animation>
|
|
Point lights
<animation>
<type>light</type>
<light-type>point</light-type>
<name>LightSrcRight</name>
<object-name>LightRight</object-name>
<nopreview/>
<position>
<x>0.169</x>
<y>0.570</y>
<z>0.713</z>
</position>
<ambient>
<r>0.03</r>
<g>0.03</g>
<b>0.03</b>
<a>1.0</a>
</ambient>
<diffuse>
<r>0.7</r>
<g>0.7</g>
<b>0.6</b>
<a>1.0</a>
</diffuse>
<specular>
<r>0.7</r>
<g>0.7</g>
<b>0.7</b>
<a>1.0</a>
</specular>
<dim-factor>
<property>dimming/property</property>
<!-- optional begin -->
<expression />
<interpolation />
<factor>1</factor>
<offset>0</offset>
<min>0</min>
<max>1</max>
<!-- optional end -->
</dim-factor>
<attenuation>
<c>1.0</c>
<l>0.002</l>
<q>0.00005</q>
</attenuation>
<near-m>3.5</near-m>
<far-m>39</far-m>
</animation>
|
|
TODO List
Completed tasks
- Fix shadow rendering when using multi threading in OSG
- Implement Cascaded Shadow Map (need to be optimized - frustum calculation and night)
- Honor 'noshadow' animation (done)
- See what happens with glow in fog : unknown landclass creates white patches in the emission buffer - scenery generation problem
- Test multi-screen (mostly done)
- Restore splashscreen
- Draw transparent objects with forward rendering (may need to capture the transparent bin from the geometry stage and move it in the display stage) (OK - needs model contribution)
- Add spotlights as animations (nearly finished)
- find a solution for ambient and emissive color of material (may need an additional buffer)
- Provide a shader for transparent objects that could render to the emissive buffer too (using MRT) not doable. Light pass can't use MRT
- Use stencil buffer to limit light range(no - done in light shader)
- needed for cockpit light to implement fake shadows and avoid lighting the runway from the cabin through the airframe
- Use effect system instead of hard-coded shaders
- Add new animation to link a light source to a model (need to provide point light animation duplicating spot light) (done)
- Tidy up the architecture (done)
- Global strength of glow or ambient occlusion via slider in rendering dialog
- Fix dim-factor in multiplayer mode (done)
- Design and implement a configurable pipeline (done)
- Document rendering pipeline configuration file format (done)
Near term tasks
- Convert existing shaders to deferred rendering
- Avoid to redraw opaque objects in the light pass. Involve OSG node mask not properly initialized.
- take care of particles and precipitation
- Fix fog on clouds
- Fix shadow matrices in multi-screen
- Implement lightfield shader
Long term ideas (unsorted)
- implement strength of glow (in the emissive buffer alpha channel)
- provide levels 0 to 5 - we are currently at level 5
- level 0 should be ok for MFDs that are currenly unreadable because blurred
- Modify shadows to allow multiple casters (limited list)
- Implement a priority list of light sources, based on priority and distance from the viewer
- Restore depth partitioning using depth ranges
- Restore stereo and other options currently available in CameraGroup
- Implement quality vs performance user control
Gallery
Appendix
References
|