@openglobus/og 0.20.2 → 0.20.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/css/og.css +55 -23
  3. package/lib/@openglobus/js/Globe.d.ts +3 -0
  4. package/lib/@openglobus/js/control/Atmosphere.d.ts +27 -3
  5. package/lib/@openglobus/js/control/AtmosphereConfig.d.ts +59 -0
  6. package/lib/@openglobus/js/control/index.d.ts +29 -29
  7. package/lib/@openglobus/js/entity/EntityCollection.d.ts +4 -0
  8. package/lib/@openglobus/js/entity/GeoObject.d.ts +7 -3
  9. package/lib/@openglobus/js/entity/GeoObjectHandler.d.ts +5 -8
  10. package/lib/@openglobus/js/layer/Vector.d.ts +5 -0
  11. package/lib/@openglobus/js/math/Quat.d.ts +1 -0
  12. package/lib/@openglobus/js/scene/Planet.d.ts +6 -0
  13. package/lib/@openglobus/js/shaders/atmos.d.ts +19 -3
  14. package/lib/@openglobus/js/shaders/drawnode.d.ts +2 -1
  15. package/lib/@openglobus/js/terrain/GlobusTerrain.d.ts +2 -0
  16. package/lib/@openglobus/js/webgl/Handler.d.ts +3 -1
  17. package/lib/@openglobus/og.css +1 -1
  18. package/lib/@openglobus/og.esm.js +1 -1
  19. package/lib/@openglobus/og.esm.js.map +1 -1
  20. package/lib/@openglobus/og.umd.js +1 -1
  21. package/lib/@openglobus/og.umd.js.map +1 -1
  22. package/lib/js/Globe.d.ts +3 -0
  23. package/lib/js/Globe.js +4 -1
  24. package/lib/js/control/Atmosphere.d.ts +27 -3
  25. package/lib/js/control/Atmosphere.js +109 -43
  26. package/lib/js/control/AtmosphereConfig.d.ts +59 -0
  27. package/lib/js/control/AtmosphereConfig.js +348 -0
  28. package/lib/js/control/DebugInfo.js +5 -4
  29. package/lib/js/control/Lighting.js +13 -5
  30. package/lib/js/control/index.d.ts +29 -29
  31. package/lib/js/control/index.js +29 -29
  32. package/lib/js/entity/EntityCollection.d.ts +4 -0
  33. package/lib/js/entity/EntityCollection.js +7 -0
  34. package/lib/js/entity/GeoObject.d.ts +7 -3
  35. package/lib/js/entity/GeoObject.js +31 -16
  36. package/lib/js/entity/GeoObjectHandler.d.ts +5 -8
  37. package/lib/js/entity/GeoObjectHandler.js +34 -63
  38. package/lib/js/layer/Layer.js +2 -2
  39. package/lib/js/layer/Vector.d.ts +5 -0
  40. package/lib/js/layer/Vector.js +16 -1
  41. package/lib/js/math/Quat.d.ts +1 -0
  42. package/lib/js/math/Quat.js +4 -0
  43. package/lib/js/renderer/RendererEvents.js +1 -3
  44. package/lib/js/scene/Planet.d.ts +6 -0
  45. package/lib/js/scene/Planet.js +25 -11
  46. package/lib/js/shaders/atmos.d.ts +19 -3
  47. package/lib/js/shaders/atmos.js +40 -26
  48. package/lib/js/shaders/drawnode.d.ts +2 -1
  49. package/lib/js/shaders/drawnode.js +15 -12
  50. package/lib/js/shaders/geoObject.js +22 -71
  51. package/lib/js/terrain/GlobusRgbTerrain.js +2 -2
  52. package/lib/js/terrain/GlobusTerrain.d.ts +2 -0
  53. package/lib/js/terrain/GlobusTerrain.js +2 -0
  54. package/lib/js/ui/Slider.js +3 -3
  55. package/lib/js/webgl/Handler.d.ts +3 -1
  56. package/lib/js/webgl/Handler.js +38 -28
  57. package/package.json +1 -1
@@ -102,6 +102,7 @@ export class Planet extends RenderNode {
102
102
  }
103
103
  gl.enable(gl.DEPTH_TEST);
104
104
  };
105
+ this._atmosphere = new Atmosphere(options.atmosphereParameters);
105
106
  this._prevNodes = new Map();
106
107
  this._currNodes = new Map();
107
108
  this.transitionTime = 580;
@@ -424,24 +425,39 @@ export class Planet extends RenderNode {
424
425
  });
425
426
  }
426
427
  }
428
+ initAtmosphereShader(atmosParams) {
429
+ if (this.renderer && this.renderer.handler && this._atmosphereEnabled) {
430
+ let h = this.renderer.handler;
431
+ if (h.isWebGl2()) {
432
+ h.removeProgram("drawnode_screen_wl");
433
+ h.addProgram(shaders.drawnode_screen_wl_webgl2Atmos(atmosParams), true);
434
+ }
435
+ else {
436
+ console.warn("Atmosphere WebGL2 only");
437
+ }
438
+ }
439
+ }
440
+ get atmosphereControl() {
441
+ return this._atmosphere;
442
+ }
427
443
  _initializeAtmosphere() {
444
+ if (!this.renderer)
445
+ return;
428
446
  let h = this.renderer.handler;
429
447
  h.removeProgram("drawnode_screen_wl");
430
448
  if (this._atmosphereEnabled) {
431
449
  this._renderScreenNodesPASS = this._renderScreenNodesPASSAtmos;
432
450
  this._renderScreenNodesWithHeightPASS = this._renderScreenNodesWithHeightPASSAtmos;
451
+ if (!this.renderer.controls.Atmosphere) {
452
+ this.addControl(this._atmosphere);
453
+ }
454
+ this._atmosphere.activate();
433
455
  if (h.isWebGl2()) {
434
- h.addProgram(shaders.drawnode_screen_wl_webgl2Atmos(), true);
456
+ h.addProgram(shaders.drawnode_screen_wl_webgl2Atmos(this._atmosphere.parameters), true);
435
457
  }
436
458
  else {
437
459
  h.addProgram(shaders.drawnode_screen_wl_webgl1NoAtmos(), true);
438
460
  }
439
- if (!this.renderer.controls.Atmosphere) {
440
- this.addControl(new Atmosphere());
441
- }
442
- else {
443
- this.renderer.controls.Atmosphere.activate();
444
- }
445
461
  if (this.renderer.controls.SimpleSkyBackground) {
446
462
  this.renderer.controls.SimpleSkyBackground.deactivate();
447
463
  }
@@ -449,9 +465,7 @@ export class Planet extends RenderNode {
449
465
  else {
450
466
  this._renderScreenNodesPASS = this._renderScreenNodesPASSNoAtmos;
451
467
  this._renderScreenNodesWithHeightPASS = this._renderScreenNodesWithHeightPASSNoAtmos;
452
- if (this.renderer.controls.Atmosphere) {
453
- this.renderer.controls.Atmosphere.deactivate();
454
- }
468
+ this._atmosphere.deactivate();
455
469
  if (!this.renderer.controls.SimpleSkyBackground) {
456
470
  this.addControl(new SimpleSkyBackground());
457
471
  }
@@ -1061,7 +1075,7 @@ export class Planet extends RenderNode {
1061
1075
  let transparentSegments = [];
1062
1076
  let isEq = this.terrain.equalizeVertices;
1063
1077
  let i = renderedNodes.length;
1064
- if (cam.slope > 0.8 /*|| cam.getAltitude() > 10000*/) {
1078
+ if (cam.slope > 0.8 || !this.terrain || this.terrain.isEmpty /*|| cam.getAltitude() > 10000*/) {
1065
1079
  while (i--) {
1066
1080
  let ri = renderedNodes[i];
1067
1081
  let s = ri.segment;
@@ -1,4 +1,20 @@
1
1
  import { Program } from '../webgl/Program';
2
- export declare const COMMON = "\n \n \n float getLerpValue(in float min, in float max, in float between)\n {\n return (clamp(between, min, max) - min) / (max - min);\n }\n \n vec3 aces(vec3 color) \n {\n float a = 2.51;\n float b = 0.03;\n float c = 2.43;\n float d = 0.59;\n float e = 0.14;\n return clamp((color * (a * color + b)) / (color * (c * color + d ) + e), 0.0, 1.0);\n }\n \n bool intersectSphere(vec3 rayOrigin, vec3 rayDirection, float radius, inout float t1, inout float t2) \n {\n float b = dot(rayDirection, rayOrigin);\n float c = dot(rayOrigin, rayOrigin) - radius * radius;\n float d = b * b - c;\n if (d < 0.0) {\n return false;\n }\n t1 = -b - sqrt(d);\n t2 = -b + sqrt(d);\n return true;\n }\n \n bool intersectSphere(vec3 rayOrigin, vec3 rayDirection, float radius, inout float t) \n {\n float b = dot(rayDirection, rayOrigin);\n float c = dot(rayOrigin, rayOrigin) - radius * radius;\n float d = b * b - c;\n if (d < 0.0) {\n return false;\n }\n t = -b - sqrt(d);\n return true;\n }\n \n bool intersectEllipsoid( in vec3 ro, in vec3 rd, in vec3 ra, inout float t )\n {\n vec3 ocn = ro/ra;\n vec3 rdn = rd/ra;\n float a = dot( rdn, rdn );\n float b = dot( ocn, rdn );\n float c = dot( ocn, ocn );\n float h = b*b - a*(c-1.0);\n \n if (h < 0.0) \n { \n return false; \n }\n \n t = (-b-sqrt(h))/a;\n \n return true;\n }\n \n bool intersectEllipsoid( in vec3 ro, in vec3 rd, in vec3 ra, inout float t1, inout float t2)\n {\n vec3 ocn = ro/ra;\n vec3 rdn = rd/ra;\n float a = dot( rdn, rdn );\n float b = dot( ocn, rdn );\n float c = dot( ocn, ocn );\n float h = b*b - a*(c-1.0);\n \n if (h < 0.0) \n { \n return false; \n }\n \n h = sqrt(h);\n t1 = (-b-h)/a;\n t2 = (-b+h)/a;\n \n return true;\n }\n \n vec3 normalEllipsoid( in vec3 pos, in vec3 ra )\n {\n return normalize( pos/(ra*ra) );\n }\n\n \n #define PI 3.1415926538\n #define ATMOS_HEIGHT 100000.0\n #define RAYLEIGH_SCALE 0.08\n #define MIE_SCALE 0.012\n \n #define SAMPLE_COUNT 16\n #define SQRT_SAMPLE_COUNT 4\n \n const float GROUND_ALBEDO = 0.05 / PI;\n\n // Sphere\n const float BOTTOM_RADIUS = 6356752.3142451793;\n const float TOP_RADIUS = 6356752.3142451793 + ATMOS_HEIGHT;\n \n // Ellipsoid\n const vec3 bottomRadii = vec3(6378137.0, 6378137.0, 6356752.3142451793); \n const vec3 topRadii = bottomRadii + ATMOS_HEIGHT;\n \n const vec3 SPHERE_TO_ELLIPSOID_SCALE = vec3(BOTTOM_RADIUS) / bottomRadii; \n \n const vec2 rayleighMieHeights = vec2(RAYLEIGH_SCALE, MIE_SCALE) * ATMOS_HEIGHT;\n \n const vec3 rayleighScatteringCoefficient = vec3(5.802, 13.558, 33.100) * 1e-6;\n \n const float mieScatteringCoefficient = 3.996e-06;\n const float mieExtinctionCoefficient = 4.440e-06;\n const vec3 ozoneAbsorptionCoefficient = vec3(0.650, 1.881, 0.085) * 1e-6;\n \n const float SUN_ANGULAR_RADIUS = 0.004685;\n const float SUN_INTENSITY = 1.0; \n \n vec3 sunWithBloom(vec3 rayDir, vec3 sunDir) \n {\n float minSunCosTheta = cos(SUN_ANGULAR_RADIUS); \n float cosTheta = dot(rayDir, sunDir);\n if (cosTheta >= minSunCosTheta) return vec3(1.0); \n float offset = minSunCosTheta - cosTheta;\n float gaussianBloom = exp(-offset*15000.0)*0.7;\n float invBloom = 1.0/(0.09 + offset*200.0)*0.01;\n return vec3(gaussianBloom + invBloom);\n }\n \n float rayleighPhase(float angle) \n {\n return 3.0 / (16.0 * PI) * (1.0 + (angle * angle));\n }\n \n float miePhase(float angle) \n {\n float g = 0.8;\n return 3.0 / (8.0 * PI) * ((1.0 - g * g) * (1.0 + angle * angle)) / ((2.0 + g * g) * pow(1.0 + g * g - 2.0 * g * angle, 1.5));\n }\n \n vec3 opticalDepth(float height, float angle) \n {\n vec3 rayOrigin = vec3(0.0, BOTTOM_RADIUS + height, 0.0);\n vec3 rayDirection = vec3(sqrt(1.0 - angle * angle), angle, 0.0);\n float t1, t2;\n intersectSphere(rayOrigin, rayDirection, TOP_RADIUS, t1, t2);\n float segmentLength = t2 / float(SAMPLE_COUNT);\n \n float t = segmentLength * 0.5;\n vec3 opticalDepth = vec3(0.0);\n \n for (int i = 0; i < SAMPLE_COUNT; i++) \n {\n vec3 position = rayOrigin + t * rayDirection;\n float height = length(position) - BOTTOM_RADIUS;\n opticalDepth.xy += exp(-height / rayleighMieHeights) * segmentLength;\n \n // density of the ozone layer is modeled as a triangular \n // function that is 30 km wide and centered at 25 km altitude\n opticalDepth.z += (1.0 - min(abs(height - 25e3) / 15e3, 1.0)) * segmentLength; \n t += segmentLength;\n }\n \n return opticalDepth;\n }\n \n vec3 transmittance(float height, float angle) \n {\n vec3 opticalDepth = opticalDepth(height, angle);\n return exp(-(rayleighScatteringCoefficient * opticalDepth.x + mieExtinctionCoefficient * opticalDepth.y + ozoneAbsorptionCoefficient * opticalDepth.z));\n }";
3
- export declare function transmittance(): Program;
4
- export declare function scattering(): Program;
2
+ import { NumberArray3 } from "../math/Vec3";
3
+ export interface AtmosphereParameters {
4
+ ATMOS_HEIGHT: number;
5
+ RAYLEIGH_SCALE: number;
6
+ MIE_SCALE: number;
7
+ GROUND_ALBEDO: number;
8
+ BOTTOM_RADIUS: number;
9
+ rayleighScatteringCoefficient: NumberArray3;
10
+ mieScatteringCoefficient: number;
11
+ mieExtinctionCoefficient: number;
12
+ ozoneAbsorptionCoefficient: NumberArray3;
13
+ SUN_ANGULAR_RADIUS: number;
14
+ SUN_INTENSITY: number;
15
+ ozoneDensityHeight: number;
16
+ ozoneDensityWide: number;
17
+ }
18
+ export declare const COMMON: (atmosParams?: AtmosphereParameters) => string;
19
+ export declare function transmittance(atmosParams?: AtmosphereParameters): Program;
20
+ export declare function scattering(atmosParams?: AtmosphereParameters): Program;
@@ -1,39 +1,57 @@
1
1
  import { Program } from '../webgl/Program';
2
2
  import { UTILS } from './utils';
3
- export const COMMON = `
4
-
3
+ const DEFAULT_PARAMS = {
4
+ ATMOS_HEIGHT: 100000.0,
5
+ RAYLEIGH_SCALE: 0.08,
6
+ MIE_SCALE: 0.012,
7
+ GROUND_ALBEDO: 0.05,
8
+ BOTTOM_RADIUS: 6356752.3142451793,
9
+ rayleighScatteringCoefficient: [5.802, 13.558, 33.100],
10
+ mieScatteringCoefficient: 3.996,
11
+ mieExtinctionCoefficient: 4.440,
12
+ ozoneAbsorptionCoefficient: [0.650, 1.881, 0.085],
13
+ SUN_ANGULAR_RADIUS: 0.004685,
14
+ SUN_INTENSITY: 1.0,
15
+ ozoneDensityHeight: 25e3,
16
+ ozoneDensityWide: 15e3,
17
+ };
18
+ export const COMMON = (atmosParams = DEFAULT_PARAMS) => `
5
19
  ${UTILS}
6
20
 
7
21
  #define PI 3.1415926538
8
- #define ATMOS_HEIGHT 100000.0
9
- #define RAYLEIGH_SCALE 0.08
10
- #define MIE_SCALE 0.012
22
+ #define ATMOS_HEIGHT ${atmosParams.ATMOS_HEIGHT.toFixed(2)}
23
+ #define RAYLEIGH_SCALE ${atmosParams.RAYLEIGH_SCALE.toFixed(5)}
24
+ #define MIE_SCALE ${atmosParams.MIE_SCALE.toFixed(5)}
11
25
 
12
26
  #define SAMPLE_COUNT 16
13
27
  #define SQRT_SAMPLE_COUNT 4
14
28
 
15
- const float GROUND_ALBEDO = 0.05 / PI;
29
+ const float GROUND_ALBEDO = ${atmosParams.GROUND_ALBEDO.toFixed(2)} / PI;
16
30
 
17
31
  // Sphere
18
- const float BOTTOM_RADIUS = 6356752.3142451793;
19
- const float TOP_RADIUS = 6356752.3142451793 + ATMOS_HEIGHT;
20
-
32
+ const float BOTTOM_RADIUS = ${atmosParams.BOTTOM_RADIUS.toFixed(10)};
33
+ const float TOP_RADIUS = BOTTOM_RADIUS + ATMOS_HEIGHT;
34
+ const float EQUATORIAL_RADIUS = 6378137.0;
35
+
21
36
  // Ellipsoid
22
- const vec3 bottomRadii = vec3(6378137.0, 6378137.0, 6356752.3142451793);
37
+ const vec3 bottomRadii = vec3(EQUATORIAL_RADIUS, EQUATORIAL_RADIUS, BOTTOM_RADIUS);
23
38
  const vec3 topRadii = bottomRadii + ATMOS_HEIGHT;
24
39
 
25
40
  const vec3 SPHERE_TO_ELLIPSOID_SCALE = vec3(BOTTOM_RADIUS) / bottomRadii;
26
41
 
27
42
  const vec2 rayleighMieHeights = vec2(RAYLEIGH_SCALE, MIE_SCALE) * ATMOS_HEIGHT;
28
43
 
29
- const vec3 rayleighScatteringCoefficient = vec3(5.802, 13.558, 33.100) * 1e-6;
44
+ const vec3 rayleighScatteringCoefficient = vec3(${atmosParams.rayleighScatteringCoefficient[0].toFixed(5)}, ${atmosParams.rayleighScatteringCoefficient[1].toFixed(5)}, ${atmosParams.rayleighScatteringCoefficient[2].toFixed(5)}) * 1e-6;
30
45
 
31
- const float mieScatteringCoefficient = 3.996e-06;
32
- const float mieExtinctionCoefficient = 4.440e-06;
33
- const vec3 ozoneAbsorptionCoefficient = vec3(0.650, 1.881, 0.085) * 1e-6;
46
+ const float mieScatteringCoefficient = ${atmosParams.mieScatteringCoefficient.toFixed(3)} * 1e-6;
47
+ const float mieExtinctionCoefficient = ${atmosParams.mieExtinctionCoefficient.toFixed(3)} * 1e-6;
48
+ const vec3 ozoneAbsorptionCoefficient = vec3(${atmosParams.ozoneAbsorptionCoefficient[0].toFixed(5)}, ${atmosParams.ozoneAbsorptionCoefficient[1].toFixed(5)}, ${atmosParams.ozoneAbsorptionCoefficient[2].toFixed(5)}) * 1e-6;
34
49
 
35
- const float SUN_ANGULAR_RADIUS = 0.004685;
36
- const float SUN_INTENSITY = 1.0;
50
+ const float SUN_ANGULAR_RADIUS = ${atmosParams.SUN_ANGULAR_RADIUS.toFixed(10)};
51
+ const float SUN_INTENSITY = ${atmosParams.SUN_INTENSITY.toFixed(2)};
52
+
53
+ const float ozoneDensityHeight = ${atmosParams.ozoneDensityHeight.toFixed(1)};//25e3;
54
+ const float ozoneDensityWide = ${atmosParams.ozoneDensityWide.toFixed(1)};//15e3;
37
55
 
38
56
  vec3 sunWithBloom(vec3 rayDir, vec3 sunDir)
39
57
  {
@@ -73,10 +91,7 @@ export const COMMON = `
73
91
  vec3 position = rayOrigin + t * rayDirection;
74
92
  float height = length(position) - BOTTOM_RADIUS;
75
93
  opticalDepth.xy += exp(-height / rayleighMieHeights) * segmentLength;
76
-
77
- // density of the ozone layer is modeled as a triangular
78
- // function that is 30 km wide and centered at 25 km altitude
79
- opticalDepth.z += (1.0 - min(abs(height - 25e3) / 15e3, 1.0)) * segmentLength;
94
+ opticalDepth.z += (1.0 - min(abs(height - ozoneDensityHeight) / ozoneDensityWide, 1.0)) * segmentLength;
80
95
  t += segmentLength;
81
96
  }
82
97
 
@@ -88,7 +103,7 @@ export const COMMON = `
88
103
  vec3 opticalDepth = opticalDepth(height, angle);
89
104
  return exp(-(rayleighScatteringCoefficient * opticalDepth.x + mieExtinctionCoefficient * opticalDepth.y + ozoneAbsorptionCoefficient * opticalDepth.z));
90
105
  }`;
91
- export function transmittance() {
106
+ export function transmittance(atmosParams) {
92
107
  return new Program("transmittance", {
93
108
  uniforms: {
94
109
  iResolution: "vec2"
@@ -106,7 +121,7 @@ export function transmittance() {
106
121
  fragmentShader: `
107
122
  precision highp float;
108
123
 
109
- ${COMMON}
124
+ ${COMMON(atmosParams)}
110
125
 
111
126
  uniform vec2 iResolution;
112
127
 
@@ -119,7 +134,7 @@ export function transmittance() {
119
134
  }`
120
135
  });
121
136
  }
122
- export function scattering() {
137
+ export function scattering(atmosParams) {
123
138
  return new Program("scattering", {
124
139
  uniforms: {
125
140
  iResolution: "vec2",
@@ -141,7 +156,7 @@ export function scattering() {
141
156
  uniform sampler2D transmittanceTexture;
142
157
  uniform vec2 iResolution;
143
158
 
144
- ${COMMON}
159
+ ${COMMON(atmosParams)}
145
160
 
146
161
  vec3 transmittanceFromTexture(float height, float angle)
147
162
  {
@@ -223,8 +238,7 @@ export function scattering() {
223
238
  vec3 hitPoint = rayOrigin + rayDirection * distanceToGround;
224
239
  vec3 normal = normalize(hitPoint);
225
240
  float diffuseAngle = max(dot(normal, lightDirection), 0.0);
226
- float earthAlbedo = 0.05;
227
- light += transmittanceCamera * transmittanceLight * (earthAlbedo / PI) * diffuseAngle;
241
+ light += transmittanceCamera * transmittanceLight * GROUND_ALBEDO * diffuseAngle;
228
242
  }
229
243
  }
230
244
  }
@@ -1,8 +1,9 @@
1
+ import { AtmosphereParameters } from "./atmos";
1
2
  import { Program } from "../webgl/Program";
2
3
  export declare function drawnode_screen_nl(): Program;
3
4
  export declare function drawnode_screen_wl_webgl1NoAtmos(): Program;
4
5
  export declare function drawnode_screen_wl_webgl2NoAtmos(): Program;
5
- export declare function drawnode_screen_wl_webgl2Atmos(): Program;
6
+ export declare function drawnode_screen_wl_webgl2Atmos(atmosParams?: AtmosphereParameters): Program;
6
7
  export declare function drawnode_colorPicking(): Program;
7
8
  export declare function drawnode_heightPicking(): Program;
8
9
  export declare function drawnode_depth(): Program;
@@ -1,4 +1,4 @@
1
- import * as atmos from "./atmos";
1
+ import { COMMON } from "./atmos";
2
2
  import { Program } from "../webgl/Program";
3
3
  import { UTILS } from './utils';
4
4
  // REMEMBER!
@@ -468,7 +468,7 @@ export function drawnode_screen_wl_webgl2NoAtmos() {
468
468
  }`
469
469
  });
470
470
  }
471
- export function drawnode_screen_wl_webgl2Atmos() {
471
+ export function drawnode_screen_wl_webgl2Atmos(atmosParams) {
472
472
  return new Program("drawnode_screen_wl", {
473
473
  uniforms: {
474
474
  projectionMatrix: "mat4",
@@ -591,7 +591,7 @@ export function drawnode_screen_wl_webgl2Atmos() {
591
591
 
592
592
  ${DEF_BLEND}
593
593
 
594
- ${atmos.COMMON}
594
+ ${COMMON(atmosParams)}
595
595
 
596
596
  vec3 transmittanceFromTexture(float height, float angle)
597
597
  {
@@ -619,14 +619,21 @@ export function drawnode_screen_wl_webgl2Atmos() {
619
619
  }
620
620
 
621
621
  void atmosGroundColor(out vec4 fragColor, in vec3 normal)
622
- {
622
+ {
623
+ vec3 cameraPosition = cameraPosition;
624
+
625
+ if(length(cameraPosition * SPHERE_TO_ELLIPSOID_SCALE) < BOTTOM_RADIUS + 1.0){
626
+ cameraPosition = normalize(cameraPosition * SPHERE_TO_ELLIPSOID_SCALE) * (BOTTOM_RADIUS + 1.0) / SPHERE_TO_ELLIPSOID_SCALE;
627
+ }
628
+
623
629
  vec3 rayDirection = normalize(v_vertex - cameraPosition);
624
630
  vec3 lightDir = normalize(sunPos);
625
631
 
626
632
  rayDirection = normalize(rayDirection * SPHERE_TO_ELLIPSOID_SCALE);
627
633
  vec3 camPos = cameraPosition * SPHERE_TO_ELLIPSOID_SCALE;
628
634
  lightDir = normalize(lightDir * SPHERE_TO_ELLIPSOID_SCALE);
629
-
635
+
636
+
630
637
  vec3 light = vec3(0.0);
631
638
  vec3 transmittanceFromCameraToSpace = vec3(1.0);
632
639
  float offset = 0.0;
@@ -656,13 +663,9 @@ export function drawnode_screen_wl_webgl2Atmos() {
656
663
  float distanceToGround = 0.0;
657
664
 
658
665
  bool hitGround = intersectSphere(camPos, rayDirection, BOTTOM_RADIUS, distanceToGround) && distanceToGround > 0.0;
659
-
660
- // Fix black dots on the edge of atmosphere
661
- // if(camHeight < 700000.0 || !hitGround)
662
- // {
663
- // distanceToGround = distance(camPos, v_vertex * SPHERE_TO_ELLIPSOID_SCALE);
664
- // }
665
-
666
+ //intersectSphere(camPos, rayDirection, BOTTOM_RADIUS, distanceToGround);
667
+
668
+
666
669
  if(length(v_vertex * SPHERE_TO_ELLIPSOID_SCALE) > BOTTOM_RADIUS){
667
670
  distanceToGround = distance(camPos, v_vertex * SPHERE_TO_ELLIPSOID_SCALE);
668
671
  }
@@ -1,4 +1,7 @@
1
1
  import { Program } from "../webgl/Program";
2
+ const QROT = `vec3 qRotate(vec4 q, vec3 v){
3
+ return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
4
+ }`;
2
5
  export const geo_object = () => new Program("geo_object", {
3
6
  uniforms: {
4
7
  viewMatrix: "mat4",
@@ -10,7 +13,8 @@ export const geo_object = () => new Program("geo_object", {
10
13
  lightsParamsv: "vec3",
11
14
  lightsParamsf: "float",
12
15
  uTexture: "sampler2d",
13
- uUseTexture: "float"
16
+ uUseTexture: "float",
17
+ useLighting: "float"
14
18
  },
15
19
  attributes: {
16
20
  aVertexPosition: "vec3",
@@ -18,11 +22,10 @@ export const geo_object = () => new Program("geo_object", {
18
22
  aTexCoord: "vec2",
19
23
  aPositionHigh: { type: "vec3", divisor: 1 },
20
24
  aPositionLow: { type: "vec3", divisor: 1 },
21
- aDirection: { type: "vec3", divisor: 1 },
22
- aPitchRoll: { type: "vec2", divisor: 1 },
23
25
  aColor: { type: "vec4", divisor: 1 },
24
26
  aScale: { type: "vec3", divisor: 1 },
25
- aDispose: { type: "float", divisor: 1 }
27
+ aDispose: { type: "float", divisor: 1 },
28
+ qRot: { type: "vec4", divisor: 1 }
26
29
  },
27
30
  vertexShader: `precision highp float;
28
31
 
@@ -30,13 +33,12 @@ export const geo_object = () => new Program("geo_object", {
30
33
  attribute vec3 aVertexNormal;
31
34
  attribute vec3 aPositionHigh;
32
35
  attribute vec3 aPositionLow;
33
- attribute vec3 aDirection;
34
- attribute vec2 aPitchRoll;
35
36
  attribute vec4 aColor;
36
37
  attribute vec3 aScale;
37
38
  attribute float aDispose;
38
39
  attribute float aUseTexture;
39
40
  attribute vec2 aTexCoord;
41
+ attribute vec4 qRot;
40
42
 
41
43
  uniform vec3 uScaleByDistance;
42
44
  uniform mat4 projectionMatrix;
@@ -51,11 +53,8 @@ export const geo_object = () => new Program("geo_object", {
51
53
  varying vec4 vColor;
52
54
  varying float vDispose;
53
55
  varying vec2 vTexCoords;
54
- //varying float useLighting;
55
56
 
56
- const float PI = 3.141592653589793;
57
-
58
- const float RADIANS = PI / 180.0;
57
+ ${QROT}
59
58
 
60
59
  void main(void) {
61
60
 
@@ -69,43 +68,16 @@ export const geo_object = () => new Program("geo_object", {
69
68
  vec3 look = cameraPosition - position;
70
69
  float lookLength = length(look);
71
70
 
72
- // useLighting = 1.0;
73
- // if(lookLength > 2000000.0){
74
- // useLighting = 0.0;
75
- // }
76
-
77
-
78
71
  vColor = aColor;
79
72
  vTexCoords = aTexCoord;
80
73
 
81
- float cos_roll = cos(aPitchRoll.y);
82
- float sin_roll = sin(aPitchRoll.y);
83
-
84
- mat3 rotZ = mat3(
85
- vec3(cos_roll, sin_roll, 0.0),
86
- vec3(-sin_roll, cos_roll, 0.0),
87
- vec3(0.0, 0.0, 1.0)
88
- );
89
-
90
- float cos_pitch = cos(aPitchRoll.x);
91
- float sin_pitch = sin(aPitchRoll.x);
92
-
93
- mat3 rotX = mat3(
94
- vec3(1.0, 0.0, 0.0),
95
- vec3(0.0, cos_pitch, sin_pitch),
96
- vec3(0.0, -sin_pitch, cos_pitch)
97
- );
98
-
99
- vec3 r = cross(normalize(-position), aDirection);
100
- mat3 modelMatrix = mat3(r, normalize(position), -aDirection) * rotX * rotZ;
101
-
102
74
  mat4 viewMatrixRTE = viewMatrix;
103
75
  viewMatrixRTE[3] = vec4(0.0, 0.0, 0.0, 1.0);
104
76
 
105
77
  vec3 highDiff = aPositionHigh - eyePositionHigh;
106
78
  vec3 lowDiff = aPositionLow - eyePositionLow;
107
79
 
108
- vNormal = modelMatrix * aVertexNormal;
80
+ vNormal = qRotate(qRot, aVertexNormal);
109
81
 
110
82
  // if(lookLength > uScaleByDistance[1])
111
83
  // {
@@ -116,9 +88,10 @@ export const geo_object = () => new Program("geo_object", {
116
88
  // scd = lookLength / uScaleByDistance[0];
117
89
  // }
118
90
  // ... is the same math
91
+ // use scaleByDistance: [1.0, 1.0, 1.0] for real sized objects
119
92
  float scd = uScaleByDistance[2] * clamp(lookLength, uScaleByDistance[0], uScaleByDistance[1]) / uScaleByDistance[0];
120
93
 
121
- vec3 vert = modelMatrix * (aVertexPosition * aScale) * scd;
94
+ vec3 vert = qRotate(qRot, (aVertexPosition * aScale)) * scd;
122
95
 
123
96
  vert += lowDiff;
124
97
 
@@ -135,19 +108,19 @@ export const geo_object = () => new Program("geo_object", {
135
108
  uniform float lightsParamsf[MAX_POINT_LIGHTS];
136
109
  uniform sampler2D uTexture;
137
110
  uniform float uUseTexture;
111
+ uniform float useLighting;
138
112
 
139
113
  varying vec3 cameraPosition;
140
114
  varying vec3 v_vertex;
141
115
  varying vec4 vColor;
142
116
  varying vec3 vNormal;
143
117
  varying vec2 vTexCoords;
144
- //varying float useLighting;
145
118
 
146
119
  void main(void) {
147
120
 
148
121
  vec3 lightWeighting = vec3(1.0);
149
122
 
150
- //if(useLighting != 0.0){
123
+ if(useLighting != 0.0){
151
124
  vec3 normal = normalize(vNormal);
152
125
  vec3 lightDir = normalize(lightsPositions[0]);
153
126
  vec3 viewDir = normalize(cameraPosition - v_vertex);
@@ -156,7 +129,7 @@ export const geo_object = () => new Program("geo_object", {
156
129
  float specularLightWeighting = pow( reflection, lightsParamsf[0]);
157
130
  float diffuseLightWeighting = max(dot(normal, lightDir), 0.0);
158
131
  lightWeighting = lightsParamsv[0] + lightsParamsv[1] * diffuseLightWeighting + lightsParamsv[2] * specularLightWeighting;
159
- //}
132
+ }
160
133
 
161
134
  if(uUseTexture > 0.0) {
162
135
  vec4 tColor = texture2D(uTexture, vTexCoords);
@@ -179,22 +152,20 @@ export const geo_object_picking = () => new Program("geo_object_picking", {
179
152
  aVertexPosition: "vec3",
180
153
  aPositionHigh: { type: "vec3", divisor: 1 },
181
154
  aPositionLow: { type: "vec3", divisor: 1 },
182
- aDirection: { type: "vec3", divisor: 1 },
183
- aPitchRoll: { type: "vec2", divisor: 1 },
184
155
  aPickingColor: { type: "vec3", divisor: 1 },
185
156
  aScale: { type: "vec3", divisor: 1 },
186
- aDispose: { type: "float", divisor: 1 }
157
+ aDispose: { type: "float", divisor: 1 },
158
+ qRot: { type: "vec4", divisor: 1 }
187
159
  },
188
160
  vertexShader: `precision highp float;
189
161
 
190
162
  attribute vec3 aVertexPosition;
191
163
  attribute vec3 aPositionHigh;
192
- attribute vec3 aPositionLow;
193
- attribute vec3 aDirection;
194
- attribute vec3 aPickingColor;
195
- attribute vec2 aPitchRoll;
164
+ attribute vec3 aPositionLow;
165
+ attribute vec3 aPickingColor;
196
166
  attribute vec3 aScale;
197
167
  attribute float aDispose;
168
+ attribute vec4 qRot;
198
169
 
199
170
  uniform vec3 eyePositionHigh;
200
171
  uniform vec3 eyePositionLow;
@@ -205,7 +176,7 @@ export const geo_object_picking = () => new Program("geo_object_picking", {
205
176
 
206
177
  varying vec3 vColor;
207
178
 
208
- const float RADIANS = 3.141592653589793 / 180.0;
179
+ ${QROT}
209
180
 
210
181
  void main(void) {
211
182
 
@@ -214,29 +185,9 @@ export const geo_object_picking = () => new Program("geo_object_picking", {
214
185
  }
215
186
 
216
187
  vColor = aPickingColor;
217
-
218
- float cos_roll = cos(aPitchRoll.y);
219
- float sin_roll = sin(aPitchRoll.y);
220
188
 
221
- mat3 rotZ = mat3(
222
- vec3(cos_roll, sin_roll, 0.0),
223
- vec3(-sin_roll, cos_roll, 0.0),
224
- vec3(0.0, 0.0, 1.0)
225
- );
226
-
227
- float cos_pitch = cos(aPitchRoll.x);
228
- float sin_pitch = sin(aPitchRoll.x);
229
-
230
- mat3 rotX = mat3(
231
- vec3(1.0, 0.0, 0.0),
232
- vec3(0.0, cos_pitch, sin_pitch),
233
- vec3(0.0, -sin_pitch, cos_pitch)
234
- );
235
-
236
189
  vec3 position = aPositionHigh + aPositionLow;
237
190
  vec3 cameraPosition = eyePositionHigh + eyePositionLow;
238
- vec3 r = cross(normalize(-position), aDirection);
239
- mat3 modelMatrix = mat3(r, normalize(position), -aDirection) * rotX * rotZ;
240
191
 
241
192
  mat4 viewMatrixRTE = viewMatrix;
242
193
  viewMatrixRTE[3] = vec4(0.0, 0.0, 0.0, 1.0);
@@ -261,7 +212,7 @@ export const geo_object_picking = () => new Program("geo_object_picking", {
261
212
  // tays in the vert above it affects on Mac Safari jitter
262
213
  float scd = pickingScale * uScaleByDistance[2] * clamp(lookLength, uScaleByDistance[0], uScaleByDistance[1]) / uScaleByDistance[0];
263
214
 
264
- vec3 vert = modelMatrix * (aVertexPosition * aScale) * scd;
215
+ vec3 vert = qRotate(qRot, (aVertexPosition * aScale)) * scd;
265
216
 
266
217
  vert += lowDiff;
267
218
 
@@ -7,14 +7,14 @@ const urlPref = {
7
7
  const urlRewriteFunc = (tileX, tileY, tileZoom, tileGroup) => {
8
8
  let g = urlPref[tileGroup];
9
9
  if (g)
10
- return `https://terrain.openglobus.org/public/poles/${g}/${tileZoom}/${tileX}/${tileY}.png`;
10
+ return `https://terrain.openglobus.org/poles/${g}/${tileZoom}/${tileX}/${tileY}.png`;
11
11
  };
12
12
  export class GlobusRgbTerrain extends RgbTerrain {
13
13
  constructor(name, options) {
14
14
  super(name || "GlobusEarthRgb", {
15
15
  maxNativeZoom: 6,
16
16
  maxZoom: 17,
17
- url: "https://{s}.terrain.openglobus.org/public/all/{z}/{x}/{y}.png",
17
+ url: "https://{s}.terrain.openglobus.org/all/{z}/{x}/{y}.png",
18
18
  urlRewrite: urlRewriteFunc,
19
19
  ...options
20
20
  });
@@ -19,6 +19,8 @@ type TileData = {
19
19
  extent: Extent | null;
20
20
  };
21
21
  /**
22
+ * @deprecated
23
+ * Use GlobusRgbTerrain
22
24
  * Class that loads segment elevation data, converts it to the array and passes it to the planet segment.
23
25
  * @class
24
26
  * @extends {GlobusTerrain}
@@ -12,6 +12,8 @@ import { TILEGROUP_COMMON } from "../segment/Segment";
12
12
  import { Ray } from "../math/Ray";
13
13
  import { Vec3 } from "../math/Vec3";
14
14
  /**
15
+ * @deprecated
16
+ * Use GlobusRgbTerrain
15
17
  * Class that loads segment elevation data, converts it to the array and passes it to the planet segment.
16
18
  * @class
17
19
  * @extends {GlobusTerrain}
@@ -18,7 +18,7 @@ class Slider extends View {
18
18
  })
19
19
  });
20
20
  this._onResize = () => {
21
- this._setOffset(this._value * this.$panel.clientWidth / (this._max - this._min));
21
+ this._setOffset((this._value - this._min) * this.$panel.clientWidth / (this._max - this._min));
22
22
  };
23
23
  this._onMouseWheel = (e) => {
24
24
  //@ts-ignore
@@ -57,7 +57,7 @@ class Slider extends View {
57
57
  let clientX = clamp(e.clientX, rect.left, rect.right);
58
58
  let dx = this._startPosX - clientX;
59
59
  this._startPosX = clientX;
60
- this.value = (this.$pointer.offsetLeft - dx) * (this._max - this._min) / this.$panel.clientWidth;
60
+ this.value = this._value - dx * (this._max - this._min) / this.$panel.clientWidth;
61
61
  };
62
62
  this._onMouseUp = () => {
63
63
  document.removeEventListener("mouseup", this._onMouseUp);
@@ -95,7 +95,7 @@ class Slider extends View {
95
95
  if (val !== this._value) {
96
96
  this._value = clamp(val, this._min, this._max);
97
97
  this.$input.value = this._value.toString();
98
- this._setOffset(this._value * this.$panel.clientWidth / (this._max - this._min));
98
+ this._setOffset((this._value - this._min) * this.$panel.clientWidth / (this._max - this._min));
99
99
  this.events.dispatch(this.events.change, this._value, this);
100
100
  }
101
101
  }
@@ -56,6 +56,7 @@ export interface IDefaultTextureParams {
56
56
  * @param {Array.<string>} [params.extensions] - Additional WebGL extension list. Available by default: EXT_texture_filter_anisotropic.
57
57
  */
58
58
  declare class Handler {
59
+ protected _throttledDrawFrame: () => void;
59
60
  /**
60
61
  * Events.
61
62
  * @public
@@ -158,6 +159,7 @@ declare class Handler {
158
159
  resizeObserver?: ResizeObserver;
159
160
  protected _requestAnimationFrameId: number;
160
161
  constructor(canvasTarget: string | HTMLCanvasElement | undefined, params?: IHandlerParameters);
162
+ set frameDelay(delay: number);
161
163
  isInitialized(): boolean;
162
164
  protected _createCanvas(): void;
163
165
  /**
@@ -431,7 +433,7 @@ declare class Handler {
431
433
  * Draw single frame.
432
434
  * @public
433
435
  */
434
- drawFrame(): void;
436
+ drawFrame: () => void;
435
437
  /**
436
438
  * Clearing gl frame.
437
439
  * @public