Cesium开启海洋水效果

一、前言

       之前有一个项目用的是UE5+cesium for unreal插件,甲方想要海洋效果,最后是同事缓存了一份在线数据实现的,今天偶尔发现新版本的cesium有这个例子,果断搬过来感慨一下。

二、效果

三、环境

版本:cesium1.101

四、关键代码

createWaterEffect(viewer) {
      let worldRectangle = viewer.scene.primitives.add(
        new Cesium.Primitive({
          geometryInstances: new Cesium.GeometryInstance({
            geometry: new Cesium.RectangleGeometry({
              rectangle: Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
              vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
            }),
          }),
          appearance: new Cesium.EllipsoidSurfaceAppearance({
            aboveGround: false,
          }),
          show: true,
        }),
      );

      worldRectangle.appearance.material = new Cesium.Material({
        fabric: {
          type: "Water",
          uniforms: {
            specularMap: "./data/material/earthspec1k.jpg",
            normalMap: Cesium.buildModuleUrl("./data/material/waterNormals.jpg"),
            frequency: 10000.0,       //频率
            animationSpeed: 0.01,     //动画速度
            amplitude: 5.0,           //振幅
            specularIntensity:0.2,    //镜面反射强度
            blendColor:Cesium.Color.POWDERBLUE //边缘混合颜色
          },
        },
      });
    },

这是官方给的例子里面的一段代码,逻辑很简单:创建一个大的矩形,再给矩形应用了一个材质,specularMap是一个单通道的黑白图片,用于区分陆地和海洋,这个图片像素有点粗,陆地和海洋衔接处有些生硬,如果项目要求高的话可以二次加工一下。

顺便说一句官方的水材质源文件在Cesium1101Source\packages\engine\Source\Shaders\Materials\Water.glsl,其内容如下:
 

// Thanks for the contribution Jonas
// http://29a.ch/2012/7/19/webgl-terrain-rendering-water-fog

uniform sampler2D specularMap;
uniform sampler2D normalMap;
uniform vec4 baseWaterColor;
uniform vec4 blendColor;
uniform float frequency;
uniform float animationSpeed;
uniform float amplitude;
uniform float specularIntensity;
uniform float fadeFactor;

czm_material czm_getMaterial(czm_materialInput materialInput)
{
    czm_material material = czm_getDefaultMaterial(materialInput);

    float time = czm_frameNumber * animationSpeed;

    // fade is a function of the distance from the fragment and the frequency of the waves
    float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);

    float specularMapValue = texture2D(specularMap, materialInput.st).r;

    // note: not using directional motion at this time, just set the angle to 0.0;
    vec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);
    vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));

    // fade out the normal perturbation as we move further from the water surface
    normalTangentSpace.xy /= fade;

    // attempt to fade out the normal perturbation as we approach non water areas (low specular map value)
    normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);

    normalTangentSpace = normalize(normalTangentSpace);

    // get ratios for alignment of the new normal vector with a vector perpendicular to the tangent plane
    float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);

    // fade out water effect as specular map value decreases
    material.alpha = mix(blendColor.a, baseWaterColor.a, specularMapValue) * specularMapValue;

    // base color is a blend of the water and non-water color based on the value from the specular map
    // may need a uniform blend factor to better control this
    material.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);

    // diffuse highlights are based on how perturbed the normal is
    material.diffuse += (0.1 * tsPerturbationRatio);

    material.diffuse = material.diffuse;

    material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);

    material.specular = specularIntensity;
    material.shininess = 10.0;

    return material;
}

原创不易,记得点赞加关注哦,我会持续分享实用的功能(:-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一梦、んんん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值