1+ <!--********************************************************************
2+ * by dagedezhiyin
3+ https://blog.csdn.net/dagedezhiyin/article/details/146601505
4+ *********************************************************************-->
5+ <!DOCTYPE html>
6+ < html >
7+
8+ < head >
9+ < meta charset ="UTF-8 " />
10+ < script src ="https://cesium.com/downloads/cesiumjs/releases/1.127/Build/Cesium/Cesium.js "> </ script >
11+ < link href ="https://cesium.com/downloads/cesiumjs/releases/1.127/Build/Cesium/Widgets/widgets.css "
12+ rel ="stylesheet " />
13+ < script src ="./cesium.map.min.js "> </ script >
14+ </ head >
15+
16+ < body style ="
17+ margin: 0;
18+ overflow: hidden;
19+ background: #fff;
20+ width: 100%;
21+ height: 100%;
22+ position: absolute;
23+ top: 0;
24+ ">
25+ < div id ="map " style ="margin: 0 auto; width: 100%; height: 100% "> </ div >
26+
27+ < script type ="text/javascript ">
28+
29+ function init ( ) { }
30+
31+ Cesium . Ion . defaultAccessToken =
32+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZjQ5ZGUzNC1jNWYwLTQ1ZTMtYmNjYS05YTY4ZTVmN2I2MDkiLCJpZCI6MTE3MTM4LCJpYXQiOjE2NzY0NDUyODB9.ZaNSBIfc1sGLhQd_xqhiSsc0yr8oS0wt1hAo9gbke6M" ;
33+
34+ let viewer = new Cesium . Viewer ( "map" , { } ) ;
35+ viewer . imageryLayers . remove ( viewer . imageryLayers . get ( 0 ) ) ;
36+
37+ // // 添加底图
38+ // var options = {
39+ // style: "elec",
40+ // crs: "WGS84",
41+ // };
42+ // viewer.imageryLayers.add(
43+ // new Cesium.ImageryLayer(new Cesium.AMapImageryProvider(options))
44+ // );
45+ // setViewerTheme(viewer);
46+
47+ var options = {
48+ crs : "WGS84" , // 使用84坐标系,默认为:GCJ02
49+ style : 4 ,
50+ } ;
51+ viewer . imageryLayers . add (
52+ new Cesium . ImageryLayer ( new Cesium . TencentImageryProvider ( options ) )
53+ ) ;
54+
55+ // 添加白膜
56+ initTiles ( ) ;
57+
58+ async function initTiles ( ) {
59+ // 加载 3D Tiles
60+ const palaceTileset = await Cesium . Cesium3DTileset . fromUrl (
61+ "http://localhost:81/hefei/tileset.json"
62+ ) ;
63+
64+ // 添加到场景
65+ viewer . scene . primitives . add ( palaceTileset ) ;
66+
67+ const lightPositionRed = Cesium . Cartesian3 . fromDegrees (
68+ 117.23585 ,
69+ 31.83864 ,
70+ 100
71+ ) ;
72+
73+ const lightPositionGreen = Cesium . Cartesian3 . fromDegrees (
74+ 117.21589 ,
75+ 31.840009 ,
76+ 100
77+ ) ;
78+
79+ const lightPositionBlue = Cesium . Cartesian3 . fromDegrees (
80+ 117.213929 ,
81+ 31.8500233 ,
82+ 100
83+ ) ;
84+
85+ const lightColorRed = new Cesium . Cartesian3 ( 3.0 , 0.0 , 0.0 ) ;
86+ const lightColorGreen = new Cesium . Cartesian3 ( 0.0 , 3.0 , 0.0 ) ;
87+ const lightColorBlue = new Cesium . Cartesian3 ( 1.0 , 3.0 , 3.0 ) ;
88+
89+ const lightRadius = 700.0 ;
90+
91+ palaceTileset . customShader = new Cesium . CustomShader ( {
92+ mode : Cesium . CustomShaderMode . REPLACE_MATERIAL ,
93+ lightingModel : Cesium . LightingModel . UNLIT ,
94+ uniforms : {
95+ u_lightPositionRed : {
96+ type : Cesium . UniformType . VEC3 ,
97+ value : lightPositionRed ,
98+ } ,
99+ u_lightPositionGreen : {
100+ type : Cesium . UniformType . VEC3 ,
101+ value : lightPositionGreen ,
102+ } ,
103+ u_lightPositionBlue : {
104+ type : Cesium . UniformType . VEC3 ,
105+ value : lightPositionBlue ,
106+ } ,
107+
108+ u_lightColorRed : {
109+ type : Cesium . UniformType . VEC3 ,
110+ value : lightColorRed ,
111+ } ,
112+ u_lightColorGreen : {
113+ type : Cesium . UniformType . VEC3 ,
114+ value : lightColorGreen ,
115+ } ,
116+ u_lightColorBlue : {
117+ type : Cesium . UniformType . VEC3 ,
118+ value : lightColorBlue ,
119+ } ,
120+
121+ u_lightRadius : {
122+ type : Cesium . UniformType . FLOAT ,
123+ value : lightRadius ,
124+ } ,
125+ } ,
126+ fragmentShaderText : `
127+ void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
128+ vec3 positionWC = (czm_model * vec4(fsInput.attributes.positionMC, 1.0)).xyz;
129+ vec3 normalEC = normalize(fsInput.attributes.normalEC);
130+ vec3 totalLight = vec3(0.0);
131+ // 计算红色光源
132+ vec3 lightDirRed = u_lightPositionRed - positionWC;
133+ float distanceRed = length(lightDirRed);
134+ vec3 lightDirectionRed = normalize(lightDirRed);
135+ float diffuseFactorRed = max(dot(normalEC, lightDirectionRed), 0.9);
136+ vec3 diffuseRed = diffuseFactorRed * u_lightColorRed;
137+ float distanceFactorRed = clamp(distanceRed / u_lightRadius, 0.2, 1.0);
138+ // 修改为你提供的颜色
139+ vec3 customRedColor = vec3(0.0, 0.1, 0.3); // 自定义颜色:#3C96FA (RGB)
140+ // 如果在光源范围外,设置渐变颜色
141+ vec3 mixedColorRed = mix(customRedColor, diffuseRed, 1.0 - distanceFactorRed); // 从蓝色到红色的渐变
142+ totalLight += mixedColorRed;
143+ // 计算绿色光源
144+ vec3 lightDirGreen = u_lightPositionGreen - positionWC;
145+ float distanceGreen = length(lightDirGreen);
146+ vec3 lightDirectionGreen = normalize(lightDirGreen);
147+ float diffuseFactorGreen = max(dot(normalEC, lightDirectionGreen), 0.9);
148+ vec3 diffuseGreen = diffuseFactorGreen * u_lightColorGreen;
149+ float distanceFactorGreen = clamp(distanceGreen / u_lightRadius, 0.2, 1.0);
150+ // 修改为你提供的颜色
151+ vec3 customGreenColor = vec3(0,0.1,0.3); // 自定义颜色:#3C96FA (RGB)
152+ // 如果在光源范围外,设置渐变颜色
153+ vec3 mixedColorGreen = mix(customGreenColor, diffuseGreen, 1.0 - distanceFactorGreen); // 从蓝色到红色的渐变
154+ totalLight += mixedColorGreen;
155+ // 计算蓝色光源
156+ vec3 lightDirBlue = u_lightPositionBlue - positionWC;
157+ float distanceBlue = length(lightDirBlue);
158+ vec3 lightDirectionBlue = normalize(lightDirBlue);
159+ float diffuseFactorBlue = max(dot(normalEC, lightDirectionBlue), 0.9);
160+ vec3 diffuseBlue = diffuseFactorBlue * u_lightColorBlue;
161+ float distanceFactorBlue = clamp(distanceBlue / u_lightRadius, 0.2, 1.0);
162+ // 修改为你提供的颜色
163+ vec3 customBlueColor = vec3(0,0.1,0.3); // 自定义颜色:#3C96FA (RGB)
164+ // 如果在光源范围外,设置渐变颜色
165+ vec3 mixedColorBlue = mix(customBlueColor, diffuseBlue, 1.0 - distanceFactorBlue); // 从蓝色到红色的渐变
166+ totalLight += mixedColorBlue;
167+ material.diffuse = totalLight;
168+ // 计算光环效果(保持原样)
169+ float _baseHeight = -10.0;
170+ float _heightRange = 100.0;
171+ float _glowRange = 300.0;
172+ float vtxf_height = fsInput.attributes.positionMC.z - _baseHeight;
173+ float vtxf_a11 = fract(czm_frameNumber / 100.0) * 3.14159265 * 2.0;
174+ float vtxf_a12 = vtxf_height / _heightRange + sin(vtxf_a11) * 0.1;
175+ material.diffuse *= vec3(vtxf_a12, vtxf_a12, vtxf_a12);
176+
177+ float vtxf_a13 = fract(czm_frameNumber / 360.0);
178+ float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
179+ vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
180+ float vtxf_diff = step(0.005, abs(vtxf_h - vtxf_a13));
181+ material.diffuse += material.diffuse * (1.0 - vtxf_diff);
182+ }
183+ ` ,
184+ } ) ;
185+
186+ viewer . zoomTo ( palaceTileset ) ;
187+
188+
189+ // setTimeout(() => {
190+ // updateLightPosition(palaceTileset, 121.25, 31.4, "red");
191+ // }, 5000);
192+
193+
194+
195+ }
196+
197+ // 动态更新光源位置
198+ function updateLightPosition ( tileset , newLongitude , newLatitude , lightIndex ) {
199+ const newLightPosition = Cesium . Cartesian3 . fromDegrees (
200+ newLongitude ,
201+ newLatitude ,
202+ 100
203+ ) ;
204+
205+ // 根据 lightIndex 更新不同的光源位置
206+ if ( lightIndex === "red" ) {
207+ tileset . customShader . uniforms . u_lightPositionRed . value =
208+ newLightPosition ;
209+ } else if ( lightIndex === "green" ) {
210+ tileset . customShader . uniforms . u_lightPositionGreen . value =
211+ newLightPosition ;
212+ } else if ( lightIndex === "blue" ) {
213+ tileset . customShader . uniforms . u_lightPositionBlue . value =
214+ newLightPosition ;
215+ }
216+ }
217+
218+ function setViewerTheme ( viewer , options = { } ) {
219+ const baseLayer = viewer . imageryLayers . get ( 0 ) ;
220+ if ( ! baseLayer ) return ;
221+
222+ baseLayer . brightness = options . brightness ?? 0.6 ;
223+
224+ baseLayer . contrast = options . contrast ?? 1.8 ;
225+
226+ baseLayer . gamma = options . gamma ?? 0.3 ;
227+
228+ baseLayer . hue = options . hue ?? 1 ;
229+
230+ baseLayer . saturation = options . saturation || 0 ;
231+
232+ const baseFragShader =
233+ viewer . scene . globe . _surfaceShaderSet . baseFragmentShaderSource
234+ . sources ;
235+
236+ for ( let i = 0 ; i < baseFragShader . length ; i ++ ) {
237+ const strS =
238+ "color = czm_saturation(color, textureSaturation);\n#endif\n" ;
239+
240+ let strT =
241+ "color = czm_saturation(color, textureSaturation);\n#endif\n" ;
242+
243+ if ( ! options . invertColor ) {
244+ strT += `
245+ color.r = 1.0 - color.r;
246+ color.g = 1.0 - color.g;
247+ color.b = 1.0 - color.b;
248+ ` ;
249+ }
250+
251+ strT += `
252+ color.r = color.r * ${ options . filterRGB_R ?? 100 } .0/255.0;
253+ color.g = color.g * ${ options . filterRGB_G ?? 138 } .0/255.0;
254+ color.b = color.b * ${ options . filterRGB_B ?? 230 } .0/255.0;
255+ ` ;
256+
257+ baseFragShader [ i ] = baseFragShader [ i ] . replace ( strS , strT ) ;
258+ }
259+ viewer . scene . requestRender ( ) ;
260+ }
261+
262+
263+ </ script >
264+ </ body >
265+
266+ </ html >
0 commit comments