ssebi / jmonkeyengine

Automatically exported from code.google.com/p/jmonkeyengine
0 stars 0 forks source link

Optimized handling for lighting #510

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Currently jME3 is unable to handle more than a couple of lights. The main issue 
permeates itself in how exactly lights are handled. The user creates an ambient 
light to make sure the scene isn't completely dark, then, a directional light 
is added to give the scene some ambiance. After that, many point lights are 
added with attenuation (read: setRadius() called with low value). The result is 
extremely low FPS. Each point light in the scene means the WHOLE SCENE must be 
re-rendered. Even though the radius of the light is very small, the entire 
scene must be vertex shaded (could be 10K verts..) and then every visible pixel 
of the scene is shaded. Even occluded pixels are shaded (those covered by 
walls) for indoor scenes. In addition, for GLSL 1.0 based GPUs, spot light and 
attenuation processing is done for lights that are not spot lights or lights 
without attenuation (due to lack of hardware flow control), which increases the 
processing cost even further.
In conclusion, the current state of the engine prevents the lighting system 
from being used to its full potential due to lack of optimization in the 
engine. 

Rest is TBD ... 

Original issue reported on code.google.com by ShadowIs...@gmail.com on 13 Jun 2012 at 9:06

GoogleCodeExporter commented 9 years ago
The current agenda for this issue is as follows:
1) Take out all rendering code from the Material class into either its own 
utility class or something more modular (interface perhaps?)
2) Allow user code to control how a material is rendered:
 * Query the lighting mode (fixed, single pass, multi pass)
 * Single call to setup GL/renderer state to render the material
   - render state
   - select shader based on light type (for define based multipass or glsl 1.0)
   - world params -> uniforms
   - mat params -> uniforms
   - light params -> uniforms (single pass takes 1 light as argument, multipass takes light array)
   - unset uniforms not set by material
 * The method would set the Shader and RenderState on the Renderer, from that point on simply rendering the mesh is enough to finish the rendering operation.
 * In addition, the code handling rendering from this point on can choose to project the point/spot light volume onto the camera and determine a scissor box (to reduce fillrate where the light has no influence)
3) Given the functionality available in #2, its possible to sort the render 
bucket by light type + shader and avoid render state changes
 * GeometryList becomes BatchList -> The Batch class contains sufficient information to render the batch, such as: Geometry, Light, and distance to camera (rest TBD)
 * When rendering "LightMode MultiPass" material, a single batch is added per light on the geometry
 * When rendering any other material (single pass, unshaded), a single batch is added per geometry, the light field is set to null
4) The current light list management system in spatial needs to be changed to 
accommodate the changes
 * A light list refresh requires per light granularity: light addition / removal / modify transform operation require re-propagation for that light down the scene graph. A light can only be associated with a single node (the one that contains the light in its local light list). This allows the light to notify its parent node of changes in its own transform to execute the light list refresh operation.
 * For each spatial in the subtree under the light, a culling operation is performed to check if the light is contained in that spatial's bounding volume. If the light does not intersect the volume, then that node is not influenced by the light and therefore the subtree under that node must not contain the light in its world light list (it may have been contained there previously ..) . If an intersection is detected, then this operation is performed for each child of that node. Once the leaves are reached, the light is added to their world light list. 
 * Given the above requirements (#4) the common case is satisfied: many lights on root node, most of them static. Some lights may be updated per frame, in that case their updates are checked against the entire scene graph (re-propagation), the number of intersection checks is reduced to minimum.

Original comment by ShadowIs...@gmail.com on 9 Jul 2012 at 4:10

GoogleCodeExporter commented 9 years ago
Wow now that sounds like something! :) So if I get this right in this new 
system the node-dependency for light (only sub-geometry is lit) is lifted and 
we get a system to determine the culling list for each light - globally?

Original comment by normen667 on 9 Jul 2012 at 7:42

GoogleCodeExporter commented 9 years ago
@Normen: Yes you will be able to add any number of lights to the root node and 
it will propagate properly so only those spatials that are within the light's 
bounding volume will actually be rendered with that light.

Original comment by ShadowIs...@gmail.com on 9 Jul 2012 at 8:49

GoogleCodeExporter commented 9 years ago

Original comment by ShadowIs...@gmail.com on 6 Sep 2012 at 6:11

GoogleCodeExporter commented 9 years ago
@Kirill, What's up on this issue?
I know you started it, could you share what you've done.
If you don't have time I can take over where you left.

Original comment by remy.bou...@gmail.com on 27 Aug 2013 at 5:52