1- import { useRef } from 'react'
2- import { MapboxImageryProvider } from "cesium"
3- import h from '@macrostrat/hyper'
4- import { ImageryLayer } from "resium"
5- import { useSelector } from 'react-redux'
6- import REGL from 'regl'
7- import { vec3 } from 'gl-matrix'
1+ import { useRef } from "react" ;
2+ import { MapboxImageryProvider } from "cesium" ;
3+ import h from "@macrostrat/hyper" ;
4+ import { ImageryLayer } from "resium" ;
5+ import { useSelector } from "react-redux" ;
6+ import REGL from "regl" ;
7+ import { vec3 } from "gl-matrix" ;
8+ import { terrainProvider } from "./provider" ;
89// https://wwwtyro.net/2019/03/21/advanced-map-shading.html
910
10- type Img = HTMLImageElement | HTMLCanvasElement
11+ type Img = HTMLImageElement | HTMLCanvasElement ;
1112
1213class HillshadeImageryProvider extends MapboxImageryProvider {
14+ // Fib about tile size in order to download fewer elevation tiles
15+ tileWidth = 512 ;
16+ tileHeight = 512 ;
17+ terrainProvider = terrainProvider ;
18+
1319 processImage ( image : Img , rect : Cesium . Rectangle ) : Img {
1420 const canvas = document . createElement ( "canvas" ) ;
1521 canvas . width = image . width ;
1622 canvas . height = image . height ;
17- const regl = REGL ( { canvas, extensions : [ "OES_texture_float" ] } ) ;
23+ const regl = REGL ( {
24+ canvas,
25+ extensions : [ "OES_texture_float" , "WEBGL_color_buffer_float" ] ,
26+ } ) ;
1827
1928 const tElevation = regl . texture ( {
2029 data : image ,
21- flipY : true
30+ flipY : true ,
2231 } ) ;
2332
24- const angle = rect . east - rect . west
33+ const angle = rect . east - rect . west ;
2534 // rough meters per pixel (could get directly from zoom level)
26- const pixelScale = 6371000 * angle / image . width
35+ const pixelScale = ( 6371000 * angle ) / image . width ;
2736
2837 const fboElevation = regl . framebuffer ( {
2938 width : image . width ,
3039 height : image . height ,
31- colorType : "float"
40+ colorType : "float" ,
3241 } ) ;
3342
3443 const cmdProcessElevation = regl ( {
@@ -59,24 +68,24 @@ class HillshadeImageryProvider extends MapboxImageryProvider {
5968 }
6069 ` ,
6170 attributes : {
62- position : [ - 1 , - 1 , 1 , - 1 , 1 , 1 , - 1 , - 1 , 1 , 1 , - 1 , 1 ]
71+ position : [ - 1 , - 1 , 1 , - 1 , 1 , 1 , - 1 , - 1 , 1 , 1 , - 1 , 1 ] ,
6372 } ,
6473 uniforms : {
6574 tElevation : tElevation ,
6675 elevationScale : 1.0 ,
67- resolution : [ image . width , image . height ]
76+ resolution : [ image . width , image . height ] ,
6877 } ,
6978 viewport : { x : 0 , y : 0 , width : image . width , height : image . height } ,
7079 count : 6 ,
7180 framebuffer : fboElevation ,
7281 } ) ;
7382
74- cmdProcessElevation ( )
83+ cmdProcessElevation ( ) ;
7584
7685 const fboNormal = regl . framebuffer ( {
7786 width : image . width ,
7887 height : image . height ,
79- colorType : "float"
88+ colorType : "float" ,
8089 } ) ;
8190
8291 const cmdNormal = regl ( {
@@ -110,29 +119,32 @@ class HillshadeImageryProvider extends MapboxImageryProvider {
110119 }
111120 ` ,
112121 attributes : {
113- position : [ - 1 , - 1 , 1 , - 1 , 1 , 1 , - 1 , - 1 , 1 , 1 , - 1 , 1 ]
122+ position : [ - 1 , - 1 , 1 , - 1 , 1 , 1 , - 1 , - 1 , 1 , 1 , - 1 , 1 ] ,
114123 } ,
115124 uniforms : {
116125 tElevation : fboElevation ,
117126 pixelScale : pixelScale ,
118- resolution : [ image . width , image . height ]
127+ resolution : [ image . width , image . height ] ,
119128 } ,
120129 viewport : { x : 0 , y : 0 , width : image . width , height : image . height } ,
121130 count : 6 ,
122- framebuffer : fboNormal
131+ framebuffer : fboNormal ,
123132 } ) ;
124133
125134 cmdNormal ( ) ;
126135
127136 const cmdDirect = regl ( {
137+ // The vertex shader tells the GPU where to draw the vertices.
128138 vert : `
129139 precision highp float;
130140 attribute vec2 position;
141+ uniform vec2 scale;
131142
132143 void main() {
133- gl_Position = vec4(position, 0, 1);
144+ gl_Position = vec4(scale* position, 0, 1);
134145 }
135146 ` ,
147+ // The fragment shader tells the GPU what color to draw.
136148 frag : `
137149 precision highp float;
138150
@@ -149,41 +161,45 @@ class HillshadeImageryProvider extends MapboxImageryProvider {
149161 }
150162 ` ,
151163 attributes : {
152- position : [ - 1 , - 1 , 1 , - 1 , 1 , 1 , - 1 , - 1 , 1 , 1 , - 1 , 1 ]
164+ position : [ - 1 , - 1 , 1 , - 1 , 1 , 1 , - 1 , - 1 , 1 , 1 , - 1 , 1 ] ,
153165 } ,
154166 uniforms : {
155167 tNormal : fboNormal ,
156168 tElevation : fboElevation ,
169+ scale : [ 1 , 1 ] ,
157170 resolution : [ image . width , image . height ] ,
158- sunDirection : vec3 . normalize ( [ ] , [ 1 , 1 , 0.5 ] )
171+ sunDirection : vec3 . normalize ( [ ] , [ 1 , 1 , 0.5 ] ) ,
159172 } ,
160173 viewport : { x : 0 , y : 0 , width : image . width , height : image . height } ,
161- count : 6
174+ count : 6 ,
162175 } ) ;
163176
164177 cmdDirect ( ) ;
165178
166- return canvas
179+ return canvas ;
167180 }
168- requestImage ( x , y , z , request ) {
169- const res = super . requestImage ( x , y , z , request )
170- const rect = this . tilingScheme . tileXYToRectangle ( x , y , z )
171- return res ?. then ( d => this . processImage ( d , rect ) )
181+ requestImage ( x , y , z , request ) {
182+ const res = this . terrainProvider . backend . requestImage ( x , y , z , request ) ;
183+ if ( res == null ) return undefined ;
184+ const rect = this . tilingScheme . tileXYToRectangle ( x , y , z ) ;
185+ return res . then ( ( d ) => this . processImage ( d , rect ) ) ;
172186 }
173187}
174188
175- const HillshadeLayer = ( props ) => {
176- const hasSatellite = useSelector ( state => state . update . mapHasSatellite )
189+ const HillshadeLayer = ( props ) => {
190+ const hasSatellite = useSelector ( ( state ) => state . update . mapHasSatellite ) ;
177191
178- let hillshade = useRef ( new HillshadeImageryProvider ( {
179- mapId : 'mapbox.terrain-rgb' ,
180- maximumLevel : 14 ,
181- accessToken : process . env . MAPBOX_API_TOKEN
182- } ) )
183-
184- if ( hasSatellite ) return null
185- return h ( ImageryLayer , { imageryProvider : hillshade . current , ...props } )
186- }
192+ let hillshade = useRef (
193+ new HillshadeImageryProvider ( {
194+ mapId : "mapbox.terrain-rgb" ,
195+ maximumLevel : 14 ,
196+ accessToken : process . env . MAPBOX_API_TOKEN ,
197+ format : "@2x.webp" ,
198+ } )
199+ ) ;
187200
201+ if ( hasSatellite ) return null ;
202+ return h ( ImageryLayer , { imageryProvider : hillshade . current , ...props } ) ;
203+ } ;
188204
189- export { HillshadeLayer }
205+ export { HillshadeLayer } ;
0 commit comments