Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3D Tiles - Dynamic Screen Space Error #4307

Merged
merged 15 commits into from
Oct 21, 2016
Merged

3D Tiles - Dynamic Screen Space Error #4307

merged 15 commits into from
Oct 21, 2016

Conversation

lilleyse
Copy link
Contributor

@lilleyse lilleyse commented Sep 9, 2016

For #3241

Like terrain fog, this enables a dynamic screen space error for rendering lower detail tiles based on distance. I mainly tested this with replacement refinement tilesets and I see about 20% reduction in the number of visited tiles for street-level views for city-like tilesets and anywhere from 50% to 70% improvement for more terrain-like datasets without too much loss in visual quality. These percentages fluctuate depending on the maximumScreenSpaceError that is applied, and is more favorable for lower values.

The settings can be tweaked by changing tileset.usesDynamicScreenSpaceError, tileset.dynamicScreenSpaceErrorDensity, and tileset.dynamicScreenSpaceErrorFactor.

@@ -131,7 +131,7 @@ define([

// Fade fog in as the camera tilts toward the horizon.
var positionNormal = Cartesian3.normalize(camera.positionWC, scratchPositionNormal);
var dot = CesiumMath.clamp(Cartesian3.dot(camera.directionWC, positionNormal), 0.0, 1.0);
var dot = Math.abs(Cartesian3.dot(camera.directionWC, positionNormal));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this because I noticed that any views that are looking from horizon-view to birds-eye-view would result in a negative dot product. So all views between horizon and birds-eye are considered to be in complete fog, but really it should adjust.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, this does not really affect anything in practice, so if anything we could just remove this code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you and @bagnell

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want to revert this. You can look up at terrain (try at Everest, it's pretty easy) in which case we want to clamp at zero.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, after talking offline. This will be fine. @lilleyse is going to update the tests.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 9, 2016

@bagnell can you also take a quick look at this?

@pjcozzi pjcozzi mentioned this pull request Sep 9, 2016
@@ -70,6 +72,7 @@ define([
* @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile.
* @param {Number} [options.maximumScreenSpaceError=16] The maximum screen-space error used to drive level-of-detail refinement.
* @param {Boolean} [options.refineToVisible=false] Whether replacement refinement should refine when all visible children are ready. An experimental optimization.
* @param {Boolean} [options.useDynamicScreenSpaceError=false] Reduce the screen space error for tiles that are further away from the camera.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally don't start variables with use, e.g., above is just refineToVisible, not useRefineToVisible, so this could just be dynamicScreenSpaceError or scaleScreenSpaceErrorByDistance.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 9, 2016

Just those comments. Will also test this with some datasets once the Sandcastle example has more options.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 10, 2016

When fog is used with a dynamic SSE for terrain, we also stop requesting tiles that are completely in fog.

It is worth doing something similar here with a max distance?

@lilleyse
Copy link
Contributor Author

lilleyse commented Sep 12, 2016

When fog is used with a dynamic SSE for terrain, we also stop requesting tiles that are completely in fog. It is worth doing something similar here with a max distance?

We could do that, but also the tiles in the distance should be pretty low res to begin with so there won't be that many requests saved.

EDIT: it does depend on the dataset though.

@lilleyse lilleyse closed this Sep 12, 2016
@lilleyse lilleyse reopened this Sep 12, 2016
@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 12, 2016

We could do that, but also the tiles in the distance should be pretty low res to begin with so there won't be that many requests saved.

This widely depends on the tileset. Consider a root tile with 300 children, or just a uniform grid.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 12, 2016

Any concerns if I merge this into 3d-tiles-temp for testing?

@lilleyse
Copy link
Contributor Author

Any concerns if I merge this into 3d-tiles-temp for testing?

Nope, go ahead.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 12, 2016

My testing and the code look good. I still don't think the doc for dynamicScreenSpaceErrorDensity and dynamicScreenSpaceErrorFactor make it obvious how to use them, e.g., explain-ish how they are non-linear. Perhaps the terrain doc also should be improved.

I'll also hold off on merging until the local coordinate system change we discussed offline.

@lilleyse
Copy link
Contributor Author

Updated.

When fog is used with a dynamic SSE for terrain, we also stop requesting tiles that are completely in fog.

It is worth doing something similar here with a max distance?

I could be wrong, but I think it's just doing the same thing as here, requesting less because it refines less. But the uniform grid type scenario for 3d tiles is definitely worth handling. Is it ok if I handle this in another PR? I also want to clean up some of the checks we do (check sse, check visibility, compute distance, sort by distance, check request volume) that we do in multiple places.

*
* @see Fog.density
*/
this.dynamicScreenSpaceErrorDensity = 0.00278;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this and dynamicScreenSpaceErrorFactor should not also be constructor arguments?

var root = tileset._root;
var tileBoundingVolume = root.contentBoundingVolume;

if (tileBoundingVolume instanceof TileBoundingRegion) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know how fast instanceof is? If it isn't basically free we should not use it here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is only for the root tile. Probably not an issue, but we should still research.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's only once per update. According to jsPerf on my machine instanceof can be done in 224,000 operations per second.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is actual kind of slow I bet compared to, for example, === with numbers. Regardless, it is fine here, of course.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lilleyse which test did you use? There's no way that's correct. I get 146,620,901 on this one https://jsperf.com/instanceof-vs-method?

The performance of instanceof depends on a lot of factors (the most significant of which is how far up the prototype chain you need to look.). But I wouldn't worry about it's usage unless you already identified a given function as a hotspot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used this test: https://jsperf.com/instanceof-performance/2.

The code is not much of a hotspot, it is called once per frame.

}
}

// The range where the density starts to lessen. Start at the quarter height of the tileset.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be a user option?

var scratchPosition = new Cartesian3();
var scratchDirection = new Cartesian3();

function updateDynamicScreenSpaceError(tileset, frameState) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is test coverage? Does the new test cover all the paths in this function?

@lilleyse
Copy link
Contributor Author

I'll look at this

@lilleyse
Copy link
Contributor Author

Updated. I addressed the remaining points. I just have to add one more bounding volume test, and will update this issue when its ready (should be later today).

@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 19, 2016

CC @pmconne

@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 19, 2016

Looks good, let me know when the tests are finished.

@lilleyse
Copy link
Contributor Author

The last test is done now.

@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 20, 2016

Do these tests fail for you?

Scene/GlobeSurfaceTileProvider fog culls tiles in full fog
Expected [ 255, 0, 0, 255 ] to equal [ 0, 0, 0, 255 ].
Error: Expected [ 255, 0, 0, 255 ] to equal [ 0, 0, 0, 255 ].
    at stack (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:1475:17)
    at buildExpectationResult (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:1445:14)
    at Spec.expectationResultFactory (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:584:18)
    at Spec.addExpectationResult (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:332:34)
    at Expectation.addExpectationResult (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:528:21)
    at Expectation.toEqual (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:1399:12)
    at http://localhost:8080/Specs/Scene/GlobeSurfaceTileProviderSpec.js:391:48
    at Promise.then (http://localhost:8080/Source/ThirdParty/when.js:196:34)
    at http://localhost:8080/Source/ThirdParty/when.js:297:13
    at processQueue (http://localhost:8080/Source/ThirdParty/when.js:647:4)
Scene/GlobeSurfaceTileProvider fog culls tiles because of increased SSE
Expected [ 255, 0, 0, 255 ] not to equal [ 255, 0, 0, 255 ].
Error: Expected [ 255, 0, 0, 255 ] not to equal [ 255, 0, 0, 255 ].
    at stack (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:1475:17)
    at buildExpectationResult (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:1445:14)
    at Spec.expectationResultFactory (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:584:18)
    at Spec.addExpectationResult (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:332:34)
    at Expectation.addExpectationResult (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:528:21)
    at Expectation.toEqual (http://localhost:8080/ThirdParty/jasmine-2.2.0/jasmine.js:1399:12)
    at http://localhost:8080/Specs/Scene/GlobeSurfaceTileProviderSpec.js:417:52
    at Promise.then (http://localhost:8080/Source/ThirdParty/when.js:196:34)
    at http://localhost:8080/Source/ThirdParty/when.js:297:13
    at processQueue (http://localhost:8080/Source/ThirdParty/when.js:647:4)

@lilleyse
Copy link
Contributor Author

Ah those are caused by this change: #4307 (comment)

Because of the old math, fog would be applied in bird's eye view, which is the view these tests use. But my change prevents fog from happening for those views. @bagnell can you check that my code change makes sense?

@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 20, 2016

@bagnell thoughts here? We want to merge this soon.

@lilleyse
Copy link
Contributor Author

Updated. Those tests pass now.

@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 21, 2016

👍

@pjcozzi pjcozzi merged commit 4cb21ad into 3d-tiles Oct 21, 2016
@pjcozzi pjcozzi deleted the dynamic-sse branch October 21, 2016 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants