|
@@ -375,7 +375,7 @@ When setting the initial screen mode, Graphics does a few checks:
|
|
|
- For Direct3D9, the supported shader model is checked. 2.0 is minimum, but 3.0 will be used if available. %Shader model 2.0 can be forced by calling \ref Graphics::SetForceSM2() "SetForceSM2()".
|
|
- For Direct3D9, the supported shader model is checked. 2.0 is minimum, but 3.0 will be used if available. %Shader model 2.0 can be forced by calling \ref Graphics::SetForceSM2() "SetForceSM2()".
|
|
|
- For OpenGL, version 2.0 with EXT_framebuffer_object and EXT_packed_depth_stencil extensions is checked for.
|
|
- For OpenGL, version 2.0 with EXT_framebuffer_object and EXT_packed_depth_stencil extensions is checked for.
|
|
|
- Are hardware shadow maps supported? Both ATI & NVIDIA style shadow maps can be used. If neither are available, a fallback mode using a color texture and minimal shadow filtering will be chosen instead.
|
|
- Are hardware shadow maps supported? Both ATI & NVIDIA style shadow maps can be used. If neither are available, a fallback mode using a color texture and minimal shadow filtering will be chosen instead.
|
|
|
-- Is light pre-pass rendering supported? This requires either readable hardware depth support, or multiple render target and R32F texture format support.
|
|
|
|
|
|
|
+- Is light pre-pass rendering supported? This requires either readable hardware depth stencil texture, or multiple render target and R32F texture format support.
|
|
|
|
|
|
|
|
\section Rendering_Renderer Renderer
|
|
\section Rendering_Renderer Renderer
|
|
|
|
|
|
|
@@ -385,7 +385,7 @@ To render, it needs a Scene with an Octree component, and a Camera that does not
|
|
|
|
|
|
|
|
By default there is one viewport, but the amount can be increased with the function \ref Renderer::SetNumViewports "SetNumViewports()". The viewport(s) should cover the entire screen or otherwise hall-of-mirrors artifacts may occur. By specifying a zero screen rectangle the whole window will be used automatically. The viewports will be rendered in ascending order, so if you want for example to have a small overlay window on top of the main viewport, use viewport index 0 for the main view, and 1 for the overlay.
|
|
By default there is one viewport, but the amount can be increased with the function \ref Renderer::SetNumViewports "SetNumViewports()". The viewport(s) should cover the entire screen or otherwise hall-of-mirrors artifacts may occur. By specifying a zero screen rectangle the whole window will be used automatically. The viewports will be rendered in ascending order, so if you want for example to have a small overlay window on top of the main viewport, use viewport index 0 for the main view, and 1 for the overlay.
|
|
|
|
|
|
|
|
-Either forward or light pre-pass rendering can be chosen, see \ref Renderer::SetLightPrepass "SetLightPrepass()". Light pre-pass will be advantageous once there is a large number of per-pixel lights affecting each object, but its disadvantages are the lack of hardware antialiasing and inability to choose the lighting model per object.
|
|
|
|
|
|
|
+Either forward or light pre-pass rendering can be chosen, see \ref Renderer::SetLightPrepass "SetLightPrepass()". %Light pre-pass will be advantageous once there is a large number of per-pixel lights affecting each object, but its disadvantages are the lack of hardware antialiasing and inability to choose the lighting model per material.
|
|
|
|
|
|
|
|
The steps for rendering each viewport on each frame are roughly the following:
|
|
The steps for rendering each viewport on each frame are roughly the following:
|
|
|
|
|
|
|
@@ -394,21 +394,15 @@ The steps for rendering each viewport on each frame are roughly the following:
|
|
|
- Construct render operations (batches) for the visible objects.
|
|
- Construct render operations (batches) for the visible objects.
|
|
|
- Perform these render operations during the rendering step at the end of the frame.
|
|
- Perform these render operations during the rendering step at the end of the frame.
|
|
|
|
|
|
|
|
-When using forward rendering, the rendering operations proceed in the following order:
|
|
|
|
|
|
|
+The rendering operations proceed in the following order:
|
|
|
|
|
|
|
|
-- Opaque geometry ambient and per-vertex lighting pass.
|
|
|
|
|
|
|
+- Opaque geometry ambient pass, or G-buffer pass in case of light pre-pass rendering.
|
|
|
- Opaque geometry per-pixel lighting passes. For shadow casting lights, the shadow map is rendered first.
|
|
- Opaque geometry per-pixel lighting passes. For shadow casting lights, the shadow map is rendered first.
|
|
|
|
|
+- (%Light pre-pass only) Opaque geometry material pass, which renders the objects with accumulated per-pixel lighting.
|
|
|
- Pre-alpha rendering pass for custom render ordering such as the skybox.
|
|
- Pre-alpha rendering pass for custom render ordering such as the skybox.
|
|
|
- Transparent geometry rendering pass. Transparent, alpha-blended objects are sorted according to distance and rendered back-to-front to ensure correct blending.
|
|
- Transparent geometry rendering pass. Transparent, alpha-blended objects are sorted according to distance and rendered back-to-front to ensure correct blending.
|
|
|
- Post-alpha rendering pass.
|
|
- Post-alpha rendering pass.
|
|
|
|
|
|
|
|
-When using light pre-pass rendering, the following order is used instead:
|
|
|
|
|
-
|
|
|
|
|
-- Opaque geometry G-buffer pass. Normals, specular power and depth are rendered.
|
|
|
|
|
-- Lighting accumulation pass. Per-pixel lighting for opaque geometry is generated by rendering light volumes. For shadow casting lights, the shadow map is rendered first.
|
|
|
|
|
-- Opaque geometry material pass. Ambient and vertex lighting, and per-pixel lighting from the light accumulation buffer are combined.
|
|
|
|
|
-- The rest of the passes happen like in forward rendering.
|
|
|
|
|
-
|
|
|
|
|
\section Rendering_Drawable Rendering components
|
|
\section Rendering_Drawable Rendering components
|
|
|
|
|
|
|
|
The rendering-related components defined by the %Graphics library are:
|
|
The rendering-related components defined by the %Graphics library are:
|
|
@@ -441,7 +435,36 @@ Note that many more optimization opportunities are possible at the content level
|
|
|
|
|
|
|
|
See also \ref Materials "Materials", \ref Lights "Lights and shadows", \ref Particles "Particle systems" and \ref AuxiliaryViews "Auxiliary views".
|
|
See also \ref Materials "Materials", \ref Lights "Lights and shadows", \ref Particles "Particle systems" and \ref AuxiliaryViews "Auxiliary views".
|
|
|
|
|
|
|
|
-For details on how Direct3D9 and OpenGL rendering differs, see \ref APIDifferences "Differences between Direct3D9 and OpenGL".
|
|
|
|
|
|
|
+See \ref ForwardPrepass "Forward and light pre-pass rendering" for detailed discussion on the two rendering modes.
|
|
|
|
|
+
|
|
|
|
|
+See \ref APIDifferences "Differences between Direct3D9 and OpenGL" for what to watch out for when using the low-level rendering functionality directly.
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+\page ForwardPrepass Forward and light pre-pass rendering
|
|
|
|
|
+
|
|
|
|
|
+Urho3D implements both forward and light pre-pass rendering modes. Where they differ is how per-pixel lighting is calculated for opaque objects; transparent objects always use forward rendering.
|
|
|
|
|
+
|
|
|
|
|
+Forward rendering first renders the ambient light pass for an object; this also adds any per-vertex lights. Then, the object is re-rendered for each per-pixel light affecting it (basic multipass rendering), up to the maximum per-pixel light count, which is by default unlimited, but can be reduced with \ref Drawable::SetMaxLights() "SetMaxLights()". The render operations are sorted by lights, ie. render the effect of the first light to all affected objects first, then the second etc. If shadow maps are re-used (default on), a shadow casting light's shadow map will be updated immediately before rendering the lit objects. When shadow maps are not re-used, all shadow maps are updated first even before drawing the ambient pass.
|
|
|
|
|
+
|
|
|
|
|
+%Light pre-pass requires a minimum of two passes per object. First the normal, specular power, depth and lightmask (8 low bits only) of opaque objects are rendered to the following G-buffer. If the INTZ readable hardware depth stencil texture format is available, the second color render target will be omitted:
|
|
|
|
|
+
|
|
|
|
|
+- RT0: World-space normal and specular power (D3DFMT_A8R8G8B8)
|
|
|
|
|
+- RT1: Linear depth (D3DFMT_R32F)
|
|
|
|
|
+- DS: Hardware depth and lightmask (D3DFMT_D24S8 or INTZ)
|
|
|
|
|
+
|
|
|
|
|
+After the G-buffer is complete, light volumes (spot and point lights) or fullscreen quads (directional lights) will be rendered to a light accumulation buffer to calculate the diffuse light color and specular light intensity at each opaque pixel. Stencil compare (AND operation) with the 8 low bits of the light's lightmask will be used for light culling. Similarly to forward rendering, shadow maps will be updated before each light as necessary.
|
|
|
|
|
+
|
|
|
|
|
+Finally, the opaque geometry material pass re-renders the objects, combining ambient and vertex lighting with per-pixel lighting from the light accumulation buffer. After this rendering proceeds to the pre-alpha pass, transparent object rendering pass, and the post-alpha pass, just like forward rendering.
|
|
|
|
|
+
|
|
|
|
|
+\section ForwardPrepass_Comparision Advantages and disadvantages
|
|
|
|
|
+
|
|
|
|
|
+Whether using forward or light pre-pass rendering is more advantageous depends on the scene and lighting complexity.
|
|
|
|
|
+
|
|
|
|
|
+If the scene contains a large number of complex objects lit by multiple lights, forward rendering has to re-transform the vertices for each light, which quickly increases the total vertex count. However, light pre-pass rendering has a higher fixed cost due to the generation of the G-buffer. Also, in forward per-pixel lighting more calculations (such as light direction and shadow map coordinates) can be done at the vertex shader level, while in light pre-pass all calculations need to happen per-pixel. This means that for a low light count, for example 1-2 per object, forward rendering will run faster based on the more efficient lighting calculations alone.
|
|
|
|
|
+
|
|
|
|
|
+Forward rendering also enables hardware multisampling and using different lighting models in different materials if needed, while neither is possible in light pre-pass rendering.
|
|
|
|
|
+
|
|
|
|
|
+Finally note that due to OpenGL frame buffer object limitations an extra framebuffer blit has to happen at the end of light pre-pass rendering, which costs some performance. Also due to the FBO specification - color render targets must have the same format - R32F texture format can not be used for linear depth, but instead 24-bit depth is manually encoded and decoded into RGB channels.
|
|
|
|
|
|
|
|
|
|
|
|
|
\page APIDifferences Differences between Direct3D9 and OpenGL
|
|
\page APIDifferences Differences between Direct3D9 and OpenGL
|
|
@@ -458,7 +481,7 @@ For details on how Direct3D9 and OpenGL rendering differs, see \ref APIDifferenc
|
|
|
|
|
|
|
|
- Modifying an index buffer on OpenGL will similarly cause the existing index buffer assignment to be lost. Therefore, always set the vertex and index buffers before rendering.
|
|
- Modifying an index buffer on OpenGL will similarly cause the existing index buffer assignment to be lost. Therefore, always set the vertex and index buffers before rendering.
|
|
|
|
|
|
|
|
-- Shader resources are stored in different locations depending on the API: CoreData/Shaders/SM2 or CoreData/Shaders/SM3 on Direct3D9, and CoreData/Shaders/GLSL for OpenGL.
|
|
|
|
|
|
|
+- %Shader resources are stored in different locations depending on the API: CoreData/Shaders/SM2 or CoreData/Shaders/SM3 for Direct3D9, and CoreData/Shaders/GLSL for OpenGL.
|
|
|
|
|
|
|
|
- On OpenGL there is never a "device lost" condition, which would cause dynamic textures or vertex/index buffers to lose their contents. However, when the screen mode is changed, the context (along with all GPU resources) will be manually destroyed and recreated. This would be strictly necessary only when changing the multisampling mode, but as bugs may otherwise occur with some GPU drivers, it is best to do for any mode change.
|
|
- On OpenGL there is never a "device lost" condition, which would cause dynamic textures or vertex/index buffers to lose their contents. However, when the screen mode is changed, the context (along with all GPU resources) will be manually destroyed and recreated. This would be strictly necessary only when changing the multisampling mode, but as bugs may otherwise occur with some GPU drivers, it is best to do for any mode change.
|
|
|
|
|
|
|
@@ -560,7 +583,7 @@ It is possible to limit which objects are affected by each light, by calling \re
|
|
|
|
|
|
|
|
Care must be utilized when doing light culling with lightmasks, because they easily create situations where a light's influence is cut off unnaturally. However, they can be helpful in preventing light spill into undesired areas, for example lights inside one room bleeding into another, without having to resort into shadow-casting lights.
|
|
Care must be utilized when doing light culling with lightmasks, because they easily create situations where a light's influence is cut off unnaturally. However, they can be helpful in preventing light spill into undesired areas, for example lights inside one room bleeding into another, without having to resort into shadow-casting lights.
|
|
|
|
|
|
|
|
-In light pre-pass rendering, light culling happens by writing the objects' light masks to the stencil buffer during G-buffer rendering, and comparing the stencil buffer to the light's light mask when rendering light volumes. In this case light masks are limited to the low 8 bits only.
|
|
|
|
|
|
|
+In light pre-pass rendering, light culling happens by writing the objects' lightmasks to the stencil buffer during G-buffer rendering, and comparing the stencil buffer to the light's light mask when rendering light volumes. In this case lightmasks are limited to the low 8 bits only.
|
|
|
|
|
|
|
|
\section Lights_ShadowedLights Shadowed lights
|
|
\section Lights_ShadowedLights Shadowed lights
|
|
|
|
|
|