Jump to content

LOD and variable FOV (extreme range)


photo

Recommended Posts

Hello,

We have a use case where the FOV of the player can be variable and extreme (from 90° down to 1°, continuous). At the moment, we are still using the TerrainGlobal so I understand it does not cope so well with short FOV, but let's put that aside for the moment.

I'm more concerned with LOD and min/max distances for surfaces and decals.

  1. Is there a way (CIGI/config/code) to dynamically adapt the range of min/max LOD to the current FOV (without of course going through all nodes... )
  2. I played with render_distance_scale and render_distance_offset but I couldn't get any result. I'm probably using them wrong so a quick demo would help
  3. I think this is a perfect case to replace the "LOD by distance" by a "LOD by screen %" or "LOD by pixel size", or to have some automatic adaptation.

Current state: zooming into our airport from a 40km distance only show the terrain and some runway lights. Of course changing the nodes LOD min/max distance manually would help, but it's more of a workaround than a real solution.

Thanks!

Link to comment

I tend to agree, for eg UE LOD by screen percentage paradigm is often really more convenient to setup properly in my experience, even in less extreme situation than yours.

Link to comment

Hi Stephane,

Quote
  • I played with render_distance_scale and render_distance_offset but I couldn't get any result. I'm probably using them wrong so a quick demo would help

There is no render_distance_offset command as far as I know. render_distance_scale simply modifies all the visibility distances by the specified number. So, if your node max visible distance was set to 10 units, setting render_distance_scale to 2 will change this parameter to 20 (the same with the shadows and lights). So, if you need to some the distant meshes with small FOV you need to adjust render_distance_scale to some high value. You can simply do some tests in Editor to see how it works.

Regarding an ability to replace distance based approach for LODs with the screen percentage in Engine - right now we don't have such plans. Screen percentage approach is not always the best one (especially in case of the perspective distortions or some kind panoramic rendering and VR). And we definitely would not mix distance-based and screen percentage approaches together at the same time due to the complexity of resulting solution.

 

Quote
  • Is there a way (CIGI/config/code) to dynamically adapt the range of min/max LOD to the current FOV (without of course going through all nodes... )

There is no such logic implemted. Such adjustments on-fly would be impossible to make since the content of each scene is different and LODs settings are also different. You can try to implement this kind of logic on your side for your specific project. You can try to use World::getIntersection() with bound frustum to collect all the nodes that currently seen by camera (basically you need to pass camera->getProjection(), camera->getModelView() into the WorldBoundFrustum() constructor) and than do whatever you need.

As an alternative approach you can simplify some stuff if you already know that zoom would be used only to view the the specific area. In that case you can try to create a pre-defined hq copy of that area and when users will use zoom just replace the original contents with the high quality ones (leaving all the other things unchanged).

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment
4 hours ago, silent said:

There is no render_distance_offset command as far as I know

image.png.b0e84f38024fa3474f197898f1654ee6.png

Maybe it's not (yet) implemented, maybe it just shouldn't be there :) Anyway, your explanation about render_distance_scale is enough for the moment and I now understand how it works.

In the end, I just need to way to link render_distance_scale value to the current FOV (smallest value between horizontal FOV and vertical FOV). I see there is a Camera::getFov() but the value is unrelated to the FOV values set through CIGI ViewDefinition packet. Is there any way to get these values (ie. the actual FOV)?

4 hours ago, silent said:

Regarding an ability to replace distance based approach for LODs with the screen percentage in Engine - right now we don't have such plans. Screen percentage approach is not always the best one (especially in case of the perspective distortions or some kind panoramic rendering and VR)

I agree that "screen %" would not be the panacea either, but it would definitively be better than "surface distance" which only works for a fixed FOV. At least "screen %" or "meter per pixel" / "pixel per meter" have the advantages of being independent of the camera FOV (still with no regard to warping, but that can be left out as a very-very special and difficult case).

Link to comment
14 hours ago, Amerio.Stephane said:

CIGI ViewDefinition packet. Is there any way to get these values (ie. the actual FOV)?

CIGI send top and bottom half-angle of frustum

image.png

float real_fov = view->getTopDeg() + view->getBottomDeg();

 

Camera::getFov() not updating, if used camera->setProjection


// mapping from cigi projection to unigine projection
float left = near * Math::tan(left_deg * UNIGINE_DEG2RAD);
float right = near * Math::tan(right_deg * UNIGINE_DEG2RAD);
float top = near * Math::tan(top_deg * UNIGINE_DEG2RAD);
float bottom = near * Math::tan(bottom_deg * UNIGINE_DEG2RAD);

mat4 projection = (proj_type == PROJECTION::PERSPECTIVE) ? frustum(left, right, bottom, top, near, far) : ortho(left, right, bottom, top, near, far);

// disable aspect correction
float aspect = (float)(App::getWidth()) / App::getHeight();
projection.m00 *= aspect;

node_player->getCamera()->setProjection(projection);

 

I don't know how to get real_fov back from the projection matrix. maybe from here atan(proj.m11) * 2 * RAD2DEG, but I'm not sure

 image.png
 

 

Link to comment
3 hours ago, cash-metall said:

atan(proj.m11) * 2 * RAD2DEG

I'll work from there! As a note, maybe it should be documented that Camera|Player::getFov() only returns the FOV set with its sibling setFOV() and not directly through the projection matrix.

Thanks!

  • Thanks 1
Link to comment
×
×
  • Create New...