Amerio.Stephane Posted February 10, 2021 Posted February 10, 2021 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. 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... ) 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 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!
romain.janil Posted February 10, 2021 Posted February 10, 2021 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.
silent Posted February 10, 2021 Posted February 10, 2021 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: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Amerio.Stephane Posted February 10, 2021 Author Posted February 10, 2021 4 hours ago, silent said: There is no render_distance_offset command as far as I know 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).
cash-metall Posted February 11, 2021 Posted February 11, 2021 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 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
Amerio.Stephane Posted February 11, 2021 Author Posted February 11, 2021 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! 1
Recommended Posts