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

fix large entities on terrain/GroundPrimitives crossing IDL in 3D #6967

Merged
merged 1 commit into from
Aug 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Change Log
* Fixed an issue where switching from 2D to 3D could cause a crash. [#6929](https://github.com/AnalyticalGraphicsInc/cesium/issues/6929)
* Fixed an issue where point primitives behind the camera would appear in view. [#6904](https://github.com/AnalyticalGraphicsInc/cesium/issues/6904)
* The `createGroundPolylineGeometry` web worker no longer depends on `GroundPolylinePrimitive`, making the worker smaller and potentially avoiding a hanging build in some webpack configurations.
* Fixed an issue that cause terrain entities (entities with unspecified `height`) and `GroundPrimitives` to fail when crossing the international date line in 3D. [#6951](https://github.com/AnalyticalGraphicsInc/cesium/issues/6951)

### 1.48 - 2018-08-01

Expand Down
32 changes: 26 additions & 6 deletions Source/Scene/ShadowVolumeAppearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,13 +636,27 @@ define([
// rectangle cartographic coords !== spherical because it's on an ellipsoid
var southWestExtents = latLongToSpherical(boundingRectangle.south, boundingRectangle.west, ellipsoid, sphericalScratch);

// Slightly pad extents to avoid floating point error when fragment culling at edges.
var south = southWestExtents.x - CesiumMath.EPSILON5;
var west = southWestExtents.y - CesiumMath.EPSILON5;
var south = southWestExtents.x;
var west = southWestExtents.y;

var northEastExtents = latLongToSpherical(boundingRectangle.north, boundingRectangle.east, ellipsoid, sphericalScratch);
var north = northEastExtents.x + CesiumMath.EPSILON5;
var east = northEastExtents.y + CesiumMath.EPSILON5;
var north = northEastExtents.x;
var east = northEastExtents.y;

// If the bounding rectangle crosses the IDL, rotate the spherical extents so the cross no longer happens.
// This rotation must happen in the shader too.
var rotationRadians = 0.0;
if (west > east) {
rotationRadians = CesiumMath.PI - west;
west = -CesiumMath.PI;
east += rotationRadians;
}

// Slightly pad extents to avoid floating point error when fragment culling at edges.
south -= CesiumMath.EPSILON5;
west -= CesiumMath.EPSILON5;
north += CesiumMath.EPSILON5;
east += CesiumMath.EPSILON5;

var longitudeRangeInverse = 1.0 / (east - west);
var latitudeRangeInverse = 1.0 / (north - south);
Expand All @@ -653,6 +667,12 @@ define([
componentsPerAttribute: 4,
normalize: false,
value : [south, west, latitudeRangeInverse, longitudeRangeInverse]
}),
longitudeRotation : new GeometryInstanceAttribute({
componentDatatype: ComponentDatatype.FLOAT,
componentsPerAttribute: 1,
normalize: false,
value : [rotationRadians]
})
};

Expand All @@ -669,7 +689,7 @@ define([
};

ShadowVolumeAppearance.hasAttributesForSphericalExtents = function(attributes) {
return defined(attributes.sphericalExtents) &&
return defined(attributes.sphericalExtents) && defined(attributes.longitudeRotation) &&
defined(attributes.planes2D_HIGH) && defined(attributes.planes2D_LOW) &&
defined(attributes.uMaxVmax) && defined(attributes.uvMinAndExtents);
};
Expand Down
8 changes: 5 additions & 3 deletions Source/Shaders/ShadowVolumeAppearanceFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ varying vec2 v_inversePlaneExtents;
varying vec4 v_westPlane;
varying vec4 v_southPlane;
#endif // SPHERICAL
varying vec2 v_uvMin;
varying vec3 v_uvMinAndSphericalLongitudeRotation;
varying vec3 v_uMaxAndInverseDistance;
varying vec3 v_vMaxAndInverseDistance;
#endif // TEXTURE_COORDINATES
Expand Down Expand Up @@ -58,6 +58,8 @@ void main(void)
#ifdef SPHERICAL
// Treat world coords as a sphere normal for spherical coordinates
vec2 sphericalLatLong = czm_approximateSphericalCoordinates(worldCoordinate);
sphericalLatLong.y += v_uvMinAndSphericalLongitudeRotation.z;
sphericalLatLong.y = czm_branchFreeTernary(sphericalLatLong.y < czm_pi, sphericalLatLong.y, sphericalLatLong.y - czm_twoPi);
uv.x = (sphericalLatLong.y - v_sphericalExtents.y) * v_sphericalExtents.w;
uv.y = (sphericalLatLong.x - v_sphericalExtents.x) * v_sphericalExtents.z;
#else // SPHERICAL
Expand Down Expand Up @@ -131,8 +133,8 @@ void main(void)
// Remap texture coordinates from computed (approximately aligned with cartographic space) to the desired
// texture coordinate system, which typically forms a tight oriented bounding box around the geometry.
// Shader is provided a set of reference points for remapping.
materialInput.st.x = czm_lineDistance(v_uvMin, v_uMaxAndInverseDistance.xy, uv) * v_uMaxAndInverseDistance.z;
materialInput.st.y = czm_lineDistance(v_uvMin, v_vMaxAndInverseDistance.xy, uv) * v_vMaxAndInverseDistance.z;
materialInput.st.x = czm_lineDistance(v_uvMinAndSphericalLongitudeRotation.xy, v_uMaxAndInverseDistance.xy, uv) * v_uMaxAndInverseDistance.z;
materialInput.st.y = czm_lineDistance(v_uvMinAndSphericalLongitudeRotation.xy, v_vMaxAndInverseDistance.xy, uv) * v_vMaxAndInverseDistance.z;
#endif

czm_material material = czm_getMaterial(materialInput);
Expand Down
5 changes: 3 additions & 2 deletions Source/Shaders/ShadowVolumeAppearanceVS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ varying vec2 v_inversePlaneExtents;
varying vec4 v_westPlane;
varying vec4 v_southPlane;
#endif // SPHERICAL
varying vec2 v_uvMin;
varying vec3 v_uvMinAndSphericalLongitudeRotation;
varying vec3 v_uMaxAndInverseDistance;
varying vec3 v_vMaxAndInverseDistance;
#endif // TEXTURE_COORDINATES
Expand All @@ -40,6 +40,7 @@ void main()
#ifdef TEXTURE_COORDINATES
#ifdef SPHERICAL
v_sphericalExtents = czm_batchTable_sphericalExtents(batchId);
v_uvMinAndSphericalLongitudeRotation.z = czm_batchTable_longitudeRotation(batchId);
#else // SPHERICAL
#ifdef COLUMBUS_VIEW_2D
vec4 planes2D_high = czm_batchTable_planes2D_HIGH(batchId);
Expand Down Expand Up @@ -71,7 +72,7 @@ void main()

v_uMaxAndInverseDistance = vec3(uMaxVmax.xy, uvMinAndExtents.z);
v_vMaxAndInverseDistance = vec3(uMaxVmax.zw, uvMinAndExtents.w);
v_uvMin = uvMinAndExtents.xy;
v_uvMinAndSphericalLongitudeRotation.xy = uvMinAndExtents.xy;
#endif // TEXTURE_COORDINATES

#ifdef PER_INSTANCE_COLOR
Expand Down
72 changes: 71 additions & 1 deletion Specs/Scene/GroundPrimitiveSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ defineSuite([
geometryInstances : new GeometryInstance({
geometry : new RectangleGeometry({
ellipsoid : ellipsoid,
rectangle : rectangle
rectangle : Rectangle.fromDegrees(-180 + CesiumMath.EPSILON4, -90 + CesiumMath.EPSILON4, 180 - CesiumMath.EPSILON4, 90 - CesiumMath.EPSILON4)
}),
id : 'depth rectangle',
attributes : {
Expand Down Expand Up @@ -362,6 +362,76 @@ defineSuite([
verifyGroundPrimitiveRender(primitive, rectColor);
});

it('renders GroundPrimitives with spherical texture coordinates across the IDL in 3D', function() {
if (!GroundPrimitive.isSupported(scene)) {
return;
}

var rectColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(1.0, 1.0, 0.0, 1.0));
var bigIdlRectangle = Rectangle.fromDegrees(176.0, 30.0, -176.0, 34.0);
var bigIdlRectangleInstance = new GeometryInstance({
geometry : new RectangleGeometry({
ellipsoid : ellipsoid,
rectangle : bigIdlRectangle
}),
id : 'rectangle',
attributes : {
color : rectColorAttribute
}
});

primitive = new GroundPrimitive({
geometryInstances : bigIdlRectangleInstance,
asynchronous : false
});

scene.camera.setView({ destination : bigIdlRectangle });

scene.groundPrimitives.add(depthPrimitive);
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba).not.toEqual([0, 0, 0, 255]);
expect(rgba[0]).toEqual(0);
});

scene.groundPrimitives.add(primitive);
expect(scene).toRender(rectColor);
});

it('renders GroundPrimitives with planar texture coordinates across the IDL in 3D', function() {
if (!GroundPrimitive.isSupported(scene)) {
return;
}

var rectColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(1.0, 1.0, 0.0, 1.0));
var smallIdlRectangle = Rectangle.fromDegrees(179.6, 30.0, -179.6, 30.9);
var smallIdlRectangleInstance = new GeometryInstance({
geometry : new RectangleGeometry({
ellipsoid : ellipsoid,
rectangle : smallIdlRectangle
}),
id : 'rectangle',
attributes : {
color : rectColorAttribute
}
});

primitive = new GroundPrimitive({
geometryInstances : smallIdlRectangleInstance,
asynchronous : false
});

scene.camera.setView({ destination : smallIdlRectangle });

scene.groundPrimitives.add(depthPrimitive);
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba).not.toEqual([0, 0, 0, 255]);
expect(rgba[0]).toEqual(0);
});

scene.groundPrimitives.add(primitive);
expect(scene).toRender(rectColor);
});

it('renders in Columbus view when scene3DOnly is false', function() {
if (!GroundPrimitive.isSupported(scene)) {
return;
Expand Down
7 changes: 7 additions & 0 deletions Specs/Scene/ShadowVolumeAppearanceSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ defineSuite([
expect(value[1]).toEqualEpsilon(-CesiumMath.PI_OVER_FOUR, CesiumMath.EPSILON4);
expect(value[2]).toEqualEpsilon(1.0 / CesiumMath.PI_OVER_TWO, CesiumMath.EPSILON4);
expect(value[3]).toEqualEpsilon(1.0 / CesiumMath.PI_OVER_TWO, CesiumMath.EPSILON4);

var longitudeRotation = attributes.longitudeRotation;
expect(longitudeRotation.componentDatatype).toEqual(ComponentDatatype.FLOAT);
expect(longitudeRotation.componentsPerAttribute).toEqual(1);
expect(longitudeRotation.normalize).toEqual(false);
value = longitudeRotation.value;
expect(value[0]).toEqualEpsilon(0.0, CesiumMath.EPSILON4);
});

function checkGeometryInstanceAttributeVec3(attribute) {
Expand Down