mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-04 01:04:17 +00:00 
			
		
		
		
	
		
			
	
	
		
			416 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			416 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								const Common = `
							 | 
						||
| 
								 | 
							
								        uniform sampler2D heightMap;
							 | 
						||
| 
								 | 
							
								        uniform float heightScale;
							 | 
						||
| 
								 | 
							
								        uniform float maxElevation;
							 | 
						||
| 
								 | 
							
								        uniform float minElevation;
							 | 
						||
| 
								 | 
							
								        uniform sampler2D iChannel0;
							 | 
						||
| 
								 | 
							
								        uniform float iTime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        uniform float coast2water_fadedepth;
							 | 
						||
| 
								 | 
							
								        uniform float large_waveheight; // change to adjust the "heavy" waves
							 | 
						||
| 
								 | 
							
								        uniform float large_wavesize;  // factor to adjust the large wave size
							 | 
						||
| 
								 | 
							
								        uniform float small_waveheight;  // change to adjust the small random waves
							 | 
						||
| 
								 | 
							
								        uniform float small_wavesize;   // factor to ajust the small wave size
							 | 
						||
| 
								 | 
							
								        uniform float water_softlight_fact;  // range [1..200] (should be << smaller than glossy-fact)
							 | 
						||
| 
								 | 
							
								        uniform float water_glossylight_fact; // range [1..200]
							 | 
						||
| 
								 | 
							
								        uniform float particle_amount;
							 | 
						||
| 
								 | 
							
								        uniform float WATER_LEVEL; // Water level (range: 0.0 - 2.0)
							 | 
						||
| 
								 | 
							
								        vec3 watercolor = vec3(0.0, 0.60, 0.66); // 'transparent' low-water color (RGB)
							 | 
						||
| 
								 | 
							
								        vec3 watercolor2 = vec3(0.0,0.0,0.5); // deep-water color (RGB, should be darker than the low-water color)
							 | 
						||
| 
								 | 
							
								        vec3 water_specularcolor = vec3(1.3, 1.3, 0.9);    // specular Color (RGB) of the water-highlights
							 | 
						||
| 
								 | 
							
								        vec3 light;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // calculate random value
							 | 
						||
| 
								 | 
							
								        float hash(float n) {
							 | 
						||
| 
								 | 
							
								            return fract(sin(n) * 43758.5453123);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 2d noise function
							 | 
						||
| 
								 | 
							
								        float noise1(in vec2 x) {
							 | 
						||
| 
								 | 
							
								            vec2 p = floor(x);
							 | 
						||
| 
								 | 
							
								            vec2 f = smoothstep(0.0, 1.0, fract(x));
							 | 
						||
| 
								 | 
							
								            float n = p.x + p.y * 57.0;
							 | 
						||
| 
								 | 
							
								            return mix(mix(hash(n + 0.0), hash(n + 1.0), f.x), mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float noise(vec2 p) {
							 | 
						||
| 
								 | 
							
								            return textureLod(iChannel0, p * vec2(1. / 256.), 0.0).x;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float height_map(vec2 p) {
							 | 
						||
| 
								 | 
							
								            float f = texture(heightMap,p).r;
							 | 
						||
| 
								 | 
							
								            return clamp(f, 0., 10.);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const mat2 m = mat2(0.72, -1.60, 1.60, 0.72);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float water_map(vec2 p, float height) {
							 | 
						||
| 
								 | 
							
								            vec2 p2 = p * large_wavesize;
							 | 
						||
| 
								 | 
							
								            vec2 shift1 = 0.001 * vec2(iTime * 160.0 * 2.0, iTime * 120.0 * 2.0);
							 | 
						||
| 
								 | 
							
								            vec2 shift2 = 0.001 * vec2(iTime * 190.0 * 2.0, -iTime * 130.0 * 2.0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // coarse crossing 'ocean' waves...
							 | 
						||
| 
								 | 
							
								            float f = 0.6000 * noise(p);
							 | 
						||
| 
								 | 
							
								            f += 0.2500 * noise(p * m);
							 | 
						||
| 
								 | 
							
								            f += 0.1666 * noise(p * m * m);
							 | 
						||
| 
								 | 
							
								            float wave = sin(p2.x * 0.622 + p2.y * 0.622 + shift2.x * 4.269) * large_waveheight * f * height * height;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            p *= small_wavesize;
							 | 
						||
| 
								 | 
							
								            f = 0.;
							 | 
						||
| 
								 | 
							
								            float amp = 1.0, s = .5;
							 | 
						||
| 
								 | 
							
								            for(int i = 0; i < 9; i++) {
							 | 
						||
| 
								 | 
							
								                p = m * p * .947;
							 | 
						||
| 
								 | 
							
								                f -= amp * abs(sin((noise(p + shift1 * s) - .5) * 2.));
							 | 
						||
| 
								 | 
							
								                amp = amp * .59;
							 | 
						||
| 
								 | 
							
								                s *= -1.329;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return wave + f * small_waveheight;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float nautic(vec2 p) {
							 | 
						||
| 
								 | 
							
								            p *= 18.;
							 | 
						||
| 
								 | 
							
								            float f = 0.;
							 | 
						||
| 
								 | 
							
								            float amp = 1.0, s = .5;
							 | 
						||
| 
								 | 
							
								            for(int i = 0; i < 3; i++) {
							 | 
						||
| 
								 | 
							
								                p = m * p * 1.2;
							 | 
						||
| 
								 | 
							
								                f += amp * abs(smoothstep(0., 1., noise(p + iTime * s)) - .5);
							 | 
						||
| 
								 | 
							
								                amp = amp * .5;
							 | 
						||
| 
								 | 
							
								                s *= -1.227;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return pow(1. - f, 5.);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float particles(vec2 p) {
							 | 
						||
| 
								 | 
							
								            p *= 200.;
							 | 
						||
| 
								 | 
							
								            float f = 0.;
							 | 
						||
| 
								 | 
							
								            float amp = 1.0, s = 1.5;
							 | 
						||
| 
								 | 
							
								            for(int i = 0; i < 3; i++) {
							 | 
						||
| 
								 | 
							
								                p = m * p * 1.2;
							 | 
						||
| 
								 | 
							
								                f += amp * noise(p + iTime * s);
							 | 
						||
| 
								 | 
							
								                amp = amp * .5;
							 | 
						||
| 
								 | 
							
								                s *= -1.227;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return pow(f * .35, 7.) * particle_amount;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float test_shadow(vec2 xy, float height) {
							 | 
						||
| 
								 | 
							
								            vec3 r0 = vec3(xy, height);
							 | 
						||
| 
								 | 
							
								            vec3 rd = normalize(light - r0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float hit = 1.0;
							 | 
						||
| 
								 | 
							
								            float t = 0.001;
							 | 
						||
| 
								 | 
							
								            for(int j = 1; j < 25; j++) {
							 | 
						||
| 
								 | 
							
								                vec3 p = r0 + t * rd;
							 | 
						||
| 
								 | 
							
								                float h = height_map(p.xy);
							 | 
						||
| 
								 | 
							
								                float height_diff = p.z - h;
							 | 
						||
| 
								 | 
							
								                if(height_diff < 0.0) {
							 | 
						||
| 
								 | 
							
								                    return 0.0;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                t += 0.01 + height_diff * .02;
							 | 
						||
| 
								 | 
							
								                hit = min(hit, 2. * height_diff / t); // soft shaddow   
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return hit;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								`;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default class Erosion extends Cesium.Primitive {
							 | 
						||
| 
								 | 
							
								  constructor(options) {
							 | 
						||
| 
								 | 
							
								    super();
							 | 
						||
| 
								 | 
							
								    this.viewer = options.viewer;
							 | 
						||
| 
								 | 
							
								    this.extent = options.extent;
							 | 
						||
| 
								 | 
							
								    this.maxElevation = options.maxElevation;
							 | 
						||
| 
								 | 
							
								    this.minElevation = options.minElevation;
							 | 
						||
| 
								 | 
							
								    this.heightMap = options.canvas;
							 | 
						||
| 
								 | 
							
								    this.noise = options.noise;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.coast2water_fadedepth = 0.1;
							 | 
						||
| 
								 | 
							
								    this.large_waveheight = 0.5; // change to adjust the "heavy" waves
							 | 
						||
| 
								 | 
							
								    this.large_wavesize = 4; // factor to adjust the large wave size
							 | 
						||
| 
								 | 
							
								    this.small_waveheight = 0.9; // change to adjust the small random waves
							 | 
						||
| 
								 | 
							
								    this.small_wavesize = 0.12; // factor to ajust the small wave size
							 | 
						||
| 
								 | 
							
								    this.water_softlight_fact = 36; // range [1..200] (should be << smaller than glossy-fact)
							 | 
						||
| 
								 | 
							
								    this.water_glossylight_fact = 120; // range [1..200]
							 | 
						||
| 
								 | 
							
								    this.particle_amount = 70;
							 | 
						||
| 
								 | 
							
								    this.WATER_LEVEL = 0.34;
							 | 
						||
| 
								 | 
							
								    this._showLines = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.resolution = Cesium.defaultValue(
							 | 
						||
| 
								 | 
							
								      options.resolution,
							 | 
						||
| 
								 | 
							
								      new Cesium.Cartesian2(1024, 1024)
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  createCommand(context) {
							 | 
						||
| 
								 | 
							
								    const rectangle = new Cesium.RectangleGeometry({
							 | 
						||
| 
								 | 
							
								      ellipsoid: Cesium.Ellipsoid.WGS84,
							 | 
						||
| 
								 | 
							
								      rectangle: Cesium.Rectangle.fromDegrees(...this.extent),
							 | 
						||
| 
								 | 
							
								      vertexFormat: Cesium.VertexFormat.POSITION_AND_ST,
							 | 
						||
| 
								 | 
							
								      granularity: Cesium.Math.toRadians(0.0001), // 调整这个参数以增加顶点密度
							 | 
						||
| 
								 | 
							
								      height: this.minElevation,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    const geometry = Cesium.RectangleGeometry.createGeometry(rectangle);
							 | 
						||
| 
								 | 
							
								    const attributeLocations =
							 | 
						||
| 
								 | 
							
								      Cesium.GeometryPipeline.createAttributeLocations(geometry);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const va = Cesium.VertexArray.fromGeometry({
							 | 
						||
| 
								 | 
							
								      context: context,
							 | 
						||
| 
								 | 
							
								      geometry: geometry,
							 | 
						||
| 
								 | 
							
								      attributeLocations: attributeLocations,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    const vs = `
							 | 
						||
| 
								 | 
							
								        in vec4 position;
							 | 
						||
| 
								 | 
							
								        in vec2 st;
							 | 
						||
| 
								 | 
							
								        out vec2 v_st;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const float PI = 3.141592653589793;
							 | 
						||
| 
								 | 
							
								        const float earthRadius = 6378137.0; // WGS84 椭球体的平均半径
							 | 
						||
| 
								 | 
							
								        const float angularVelocity = 180.0 / PI;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const float RADII_X = 6378137.0;
							 | 
						||
| 
								 | 
							
								        const float RADII_Y = 6378137.0;
							 | 
						||
| 
								 | 
							
								        const float RADII_Z = 6356752.314245;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        vec3 worldToGeographic(vec3 worldPosition) {
							 | 
						||
| 
								 | 
							
								            // 步骤1: 世界坐标到ECEF坐标
							 | 
						||
| 
								 | 
							
								            vec3 ecef = worldPosition;  // 假设世界坐标已经是ECEF
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 步骤2: ECEF到地理坐标
							 | 
						||
| 
								 | 
							
								            float l = length(ecef.xy);
							 | 
						||
| 
								 | 
							
								            float e2 = 1.0 - (RADII_Z * RADII_Z) / (RADII_X * RADII_X);
							 | 
						||
| 
								 | 
							
								            float u = atan(ecef.z * RADII_X / (l * RADII_Z));
							 | 
						||
| 
								 | 
							
								            float lat = atan((ecef.z + e2 * RADII_Z * pow(sin(u), 3.0)) / 
							 | 
						||
| 
								 | 
							
								                            (l - e2 * RADII_X * pow(cos(u), 3.0)));
							 | 
						||
| 
								 | 
							
								            float lon = atan(ecef.y, ecef.x);
							 | 
						||
| 
								 | 
							
								            float N = RADII_X / sqrt(1.0 - e2 * sin(lat) * sin(lat));
							 | 
						||
| 
								 | 
							
								            float alt = l / cos(lat) - N;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 将弧度转换为度
							 | 
						||
| 
								 | 
							
								            lat = degrees(lat);
							 | 
						||
| 
								 | 
							
								            lon = degrees(lon);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return vec3(lon, lat, alt);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        vec3 geo2cartesian(vec3 geo){
							 | 
						||
| 
								 | 
							
								            float cosLat=cos(geo.y);
							 | 
						||
| 
								 | 
							
								            float snX=cosLat*cos(geo.x);
							 | 
						||
| 
								 | 
							
								            float snY=cosLat*sin(geo.x);
							 | 
						||
| 
								 | 
							
								            float snZ=sin(geo.y);
							 | 
						||
| 
								 | 
							
								            vec3 sn=normalize(vec3(snX,snY,snZ));
							 | 
						||
| 
								 | 
							
								            vec3 radiiSquared=vec3(40680631.59076899*1000000.,40680631.59076899*1000000.,40408299.98466144*1000000.);
							 | 
						||
| 
								 | 
							
								            vec3 sk=radiiSquared*sn;
							 | 
						||
| 
								 | 
							
								            float gamma=sqrt(dot(sn,sk));
							 | 
						||
| 
								 | 
							
								            sk=sk/gamma;
							 | 
						||
| 
								 | 
							
								            sn=sn*geo.z;
							 | 
						||
| 
								 | 
							
								            return sk+sn;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        vec3 deg2cartesian(vec3 deg) {
							 | 
						||
| 
								 | 
							
								            vec2 radGeo=radians(deg.xy);
							 | 
						||
| 
								 | 
							
								            vec3 geo=vec3(radGeo.xy,deg.z);
							 | 
						||
| 
								 | 
							
								            return geo2cartesian(geo);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void main() {
							 | 
						||
| 
								 | 
							
								            float normalizedHeight = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            vec2 uv = st;
							 | 
						||
| 
								 | 
							
								            float deepwater_fadedepth = 0.5 + coast2water_fadedepth;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float height = height_map(uv);
							 | 
						||
| 
								 | 
							
								            vec3 col;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float waveheight = clamp(WATER_LEVEL * 3. - 1.5, 0., 1.);
							 | 
						||
| 
								 | 
							
								            float level = WATER_LEVEL + .2 * water_map(uv * 15. + vec2(iTime * .1), waveheight);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(height <= level) {
							 | 
						||
| 
								 | 
							
								                normalizedHeight = level;
							 | 
						||
| 
								 | 
							
								            }else{
							 | 
						||
| 
								 | 
							
								                normalizedHeight = height; // 减少边缘拉伸的割裂感
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float heightOffset = (maxElevation - minElevation) * normalizedHeight;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            // 将顶点位置从模型空间转换到世界空间
							 | 
						||
| 
								 | 
							
								            vec4 worldPosition = czm_model * position;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            // 将世界坐标转换为经纬度和高度
							 | 
						||
| 
								 | 
							
								            vec3 llh = worldToGeographic(worldPosition.xyz);
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            // 将调整后的经纬度和高度转换回笛卡尔坐标
							 | 
						||
| 
								 | 
							
								            vec3 adjustedCartesian = deg2cartesian(vec3(llh.xy,minElevation+heightOffset));
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            gl_Position = czm_projection * czm_view * vec4(adjustedCartesian,1.0);
							 | 
						||
| 
								 | 
							
								            v_st = st;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      `;
							 | 
						||
| 
								 | 
							
								    const fs = `
							 | 
						||
| 
								 | 
							
								        in vec2 v_st;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void main(){
							 | 
						||
| 
								 | 
							
								            light = vec3(-0., .0, 2.8); // position of the sun
							 | 
						||
| 
								 | 
							
								            vec2 uv = v_st;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float deepwater_fadedepth = 0.5 + coast2water_fadedepth;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float height = height_map(uv);
							 | 
						||
| 
								 | 
							
								            vec3 col;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            float waveheight = clamp(WATER_LEVEL * 3. - 1.5, 0., 1.);
							 | 
						||
| 
								 | 
							
								            float level = WATER_LEVEL + .2 * water_map(uv * 15. + vec2(iTime * .1), waveheight);
							 | 
						||
| 
								 | 
							
								            if(height <= level) {
							 | 
						||
| 
								 | 
							
								                vec2 dif = vec2(.0, .01);
							 | 
						||
| 
								 | 
							
								                vec2 pos = uv * 15. + vec2(iTime * .01);
							 | 
						||
| 
								 | 
							
								                float h1 = water_map(pos - dif, waveheight);
							 | 
						||
| 
								 | 
							
								                float h2 = water_map(pos + dif, waveheight);
							 | 
						||
| 
								 | 
							
								                float h3 = water_map(pos - dif.yx, waveheight);
							 | 
						||
| 
								 | 
							
								                float h4 = water_map(pos + dif.yx, waveheight);
							 | 
						||
| 
								 | 
							
								                vec3 normwater = normalize(vec3(h3 - h4, h1 - h2, .125)); // norm-vector of the 'bumpy' water-plane
							 | 
						||
| 
								 | 
							
								                uv += normwater.xy * .002 * (level - height);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                col = vec3(1.0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                float coastfade = clamp((level - height) / coast2water_fadedepth, 0., 1.);
							 | 
						||
| 
								 | 
							
								                float coastfade2 = clamp((level - height) / deepwater_fadedepth, 0., 1.);
							 | 
						||
| 
								 | 
							
								                float intensity = col.r * .2126 + col.g * .7152 + col.b * .0722;
							 | 
						||
| 
								 | 
							
								                watercolor = mix(watercolor * intensity, watercolor2, smoothstep(0., 1., coastfade2));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                vec3 r0 = vec3(uv, WATER_LEVEL);
							 | 
						||
| 
								 | 
							
								                vec3 rd = normalize(light - r0); // ray-direction to the light from water-position
							 | 
						||
| 
								 | 
							
								                float grad = dot(normwater, rd); // dot-product of norm-vector and light-direction
							 | 
						||
| 
								 | 
							
								                float specular = pow(grad, water_softlight_fact);  // used for soft highlights                          
							 | 
						||
| 
								 | 
							
								                float specular2 = pow(grad, water_glossylight_fact); // used for glossy highlights
							 | 
						||
| 
								 | 
							
								                float gradpos = dot(vec3(0., 0., 1.), rd);
							 | 
						||
| 
								 | 
							
								                float specular1 = smoothstep(0., 1., pow(gradpos, 5.));  // used for diffusity (some darker corona around light's specular reflections...)                          
							 | 
						||
| 
								 | 
							
								                float watershade = test_shadow(uv, level);
							 | 
						||
| 
								 | 
							
								                watercolor *= 2.2 + watershade;
							 | 
						||
| 
								 | 
							
								                watercolor += (.2 + .8 * watershade) * ((grad - 1.0) * .5 + specular) * .25;
							 | 
						||
| 
								 | 
							
								                watercolor /= (1. + specular1 * 1.25);
							 | 
						||
| 
								 | 
							
								                watercolor += watershade * specular2 * water_specularcolor;
							 | 
						||
| 
								 | 
							
								                watercolor += watershade * coastfade * (1. - coastfade2) * (vec3(.5, .6, .7) * nautic(uv) + vec3(1., 1., 1.) * particles(uv));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                col = mix(col, watercolor, coastfade);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								                float alpha = clamp(coastfade,0.1,0.6);
							 | 
						||
| 
								 | 
							
								                out_FragColor = vec4(col,1.0);
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								      `;
							 | 
						||
| 
								 | 
							
								    const shaderProgram = Cesium.ShaderProgram.fromCache({
							 | 
						||
| 
								 | 
							
								      context: context,
							 | 
						||
| 
								 | 
							
								      vertexShaderSource: Common + vs,
							 | 
						||
| 
								 | 
							
								      fragmentShaderSource: Common + fs,
							 | 
						||
| 
								 | 
							
								      attributeLocations: attributeLocations,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    const texture = new Cesium.Texture({
							 | 
						||
| 
								 | 
							
								      context: context,
							 | 
						||
| 
								 | 
							
								      width: 2048.0,
							 | 
						||
| 
								 | 
							
								      height: 2048.0,
							 | 
						||
| 
								 | 
							
								      pixelFormat: Cesium.PixelFormat.RGBA,
							 | 
						||
| 
								 | 
							
								      pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
							 | 
						||
| 
								 | 
							
								      flipY: true,
							 | 
						||
| 
								 | 
							
								      sampler: new Cesium.Sampler({
							 | 
						||
| 
								 | 
							
								        minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
							 | 
						||
| 
								 | 
							
								        magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
							 | 
						||
| 
								 | 
							
								        wrapS: Cesium.TextureWrap.REPEAT,
							 | 
						||
| 
								 | 
							
								        wrapT: Cesium.TextureWrap.REPEAT,
							 | 
						||
| 
								 | 
							
								      }),
							 | 
						||
| 
								 | 
							
								      source: this.heightMap,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    const noise = new Cesium.Texture({
							 | 
						||
| 
								 | 
							
								      context: context,
							 | 
						||
| 
								 | 
							
								      width: 512.0,
							 | 
						||
| 
								 | 
							
								      height: 512.0,
							 | 
						||
| 
								 | 
							
								      pixelFormat: Cesium.PixelFormat.RGBA,
							 | 
						||
| 
								 | 
							
								      pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
							 | 
						||
| 
								 | 
							
								      flipY: true,
							 | 
						||
| 
								 | 
							
								      sampler: new Cesium.Sampler({
							 | 
						||
| 
								 | 
							
								        minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
							 | 
						||
| 
								 | 
							
								        magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
							 | 
						||
| 
								 | 
							
								        wrapS: Cesium.TextureWrap.REPEAT,
							 | 
						||
| 
								 | 
							
								        wrapT: Cesium.TextureWrap.REPEAT,
							 | 
						||
| 
								 | 
							
								      }),
							 | 
						||
| 
								 | 
							
								      source: this.noise,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    const uniformMap = {
							 | 
						||
| 
								 | 
							
								      heightMap: () => {
							 | 
						||
| 
								 | 
							
								        return texture;
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      heightScale: () => 1.0,
							 | 
						||
| 
								 | 
							
								      minElevation: () => this.minElevation,
							 | 
						||
| 
								 | 
							
								      maxElevation: () => this.maxElevation,
							 | 
						||
| 
								 | 
							
								      iTime: () => this.time,
							 | 
						||
| 
								 | 
							
								      iChannel0: () => noise,
							 | 
						||
| 
								 | 
							
								      coast2water_fadedepth: () => this.coast2water_fadedepth,
							 | 
						||
| 
								 | 
							
								      large_waveheight: () => this.large_waveheight, // change to adjust the "heavy" waves
							 | 
						||
| 
								 | 
							
								      large_wavesize: () => this.large_wavesize, // factor to adjust the large wave size
							 | 
						||
| 
								 | 
							
								      small_waveheight: () => this.small_waveheight, // change to adjust the small random waves
							 | 
						||
| 
								 | 
							
								      small_wavesize: () => this.small_wavesize, // factor to ajust the small wave size
							 | 
						||
| 
								 | 
							
								      water_softlight_fact: () => this.water_softlight_fact, // range [1..200] (should be << smaller than glossy-fact)
							 | 
						||
| 
								 | 
							
								      water_glossylight_fact: () => this.water_glossylight_fact, // range [1..200]
							 | 
						||
| 
								 | 
							
								      particle_amount: () => this.particle_amount,
							 | 
						||
| 
								 | 
							
								      WATER_LEVEL: () => this.WATER_LEVEL,
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    const renderState = Cesium.RenderState.fromCache({
							 | 
						||
| 
								 | 
							
								      depthTest: { enabled: true },
							 | 
						||
| 
								 | 
							
								      depthMask: { enabled: true },
							 | 
						||
| 
								 | 
							
								      blending: Cesium.BlendingState.ALPHA_BLEND,
							 | 
						||
| 
								 | 
							
								      cull: {
							 | 
						||
| 
								 | 
							
								        enabled: false,
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    this.drawCommand = new Cesium.DrawCommand({
							 | 
						||
| 
								 | 
							
								      modelMatrix: this.modelMatrix,
							 | 
						||
| 
								 | 
							
								      vertexArray: va,
							 | 
						||
| 
								 | 
							
								      primitiveType: Cesium.PrimitiveType.TRIANGLES, //TRIANGLES LINES
							 | 
						||
| 
								 | 
							
								      shaderProgram: shaderProgram,
							 | 
						||
| 
								 | 
							
								      uniformMap: uniformMap,
							 | 
						||
| 
								 | 
							
								      renderState: renderState,
							 | 
						||
| 
								 | 
							
								      pass: Cesium.Pass.OPAQUE,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  set showLines(value) {
							 | 
						||
| 
								 | 
							
								    this._showLines = value;
							 | 
						||
| 
								 | 
							
								    this.drawCommand.primitiveType = this._showLines
							 | 
						||
| 
								 | 
							
								      ? Cesium.PrimitiveType.LINES
							 | 
						||
| 
								 | 
							
								      : Cesium.PrimitiveType.TRIANGLES;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  get showLines() {
							 | 
						||
| 
								 | 
							
								    return this._showLines;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  async update(frameState) {
							 | 
						||
| 
								 | 
							
								    const now = performance.now();
							 | 
						||
| 
								 | 
							
								    this.deltaTime = (now - this.lastUpdateTime) / 1000.0; // 转换为秒
							 | 
						||
| 
								 | 
							
								    this.lastUpdateTime = now;
							 | 
						||
| 
								 | 
							
								    this.time = now / 1000;
							 | 
						||
| 
								 | 
							
								    this.frame += 0.02;
							 | 
						||
| 
								 | 
							
								    if (!this.drawCommand) {
							 | 
						||
| 
								 | 
							
								      this.createCommand(frameState.context);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    frameState.commandList.push(this.drawCommand);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  destroy() {
							 | 
						||
| 
								 | 
							
								    super.destroy();
							 | 
						||
| 
								 | 
							
								    const commondList = [this.drawCommand];
							 | 
						||
| 
								 | 
							
								    commondList.forEach((drawCommand) => {
							 | 
						||
| 
								 | 
							
								      if (drawCommand) {
							 | 
						||
| 
								 | 
							
								        const va = drawCommand.vertexArray,
							 | 
						||
| 
								 | 
							
								          sp = drawCommand.shaderProgram;
							 | 
						||
| 
								 | 
							
								        if (!va.isDestroyed()) va.destroy();
							 | 
						||
| 
								 | 
							
								        if (!sp.isDestroyed || !sp.isDestroyed()) {
							 | 
						||
| 
								 | 
							
								          sp.destroy();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        drawCommand.isDestroyed = function returnTrue() {
							 | 
						||
| 
								 | 
							
								          return true;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        drawCommand.uniformMap = undefined;
							 | 
						||
| 
								 | 
							
								        drawCommand.renderState = Cesium.RenderState.removeFromCache(
							 | 
						||
| 
								 | 
							
								          drawCommand.renderState
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    this.drawCommand = null;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |