Cesium 使用着色器实现点光源

​/**

     * 添加点光源

     * @param {Viewer} viewer

     * @param {Cesium3DTileset} tileset

     */

    addPointLight(viewer,tileset, distance = 1000) {

        // 点光源 颜色、位置

        const lightPoint = {

          color: Cesium.Color.RED,

          position: Cesium.Cartesian3.fromDegrees(110, 27, 50)

        };

     

        viewer.entities.add({

          position: Cesium.Cartesian3.fromDegrees(110, 27, 50),

          ellipsoid: {

            radii: new Cesium.Cartesian3(2, 2, 2),

            material: Cesium.Color.RED.withAlpha(0.5),

          }

        })

        const customShader = new Cesium.CustomShader({

            lightingModel: Cesium.LightingModel.UNLIT, // Cesium.LightingModel.PBR

            uniforms: {

              u_distance: {

                type: Cesium.UniformType.FLOAT,

                value: distance

              },

              u_cameraDirectionWC: {

                type: Cesium.UniformType.VEC3,

                value: viewer.scene.camera.positionWC,

              },

              u_lightColor: {

                type: Cesium.UniformType.VEC4,

                value: lightPoint.color,

              },

              u_lightPosition: {

                type: Cesium.UniformType.VEC3,

                value: lightPoint.position,

              },

            },

            fragmentShaderText: `

     

                // 构造光照

                vec4 makeLight(vec4 lightColorHdr,vec3 lightPos, vec3 positionWC,vec3 positionEC,vec3 normalEC,czm_pbrParameters pbrParameters)

                {

                  // 透明度 0.0 全透明 1 不透明

                  float mx1 = 0.0;

                 

                  // 渲染目标到点光源的向量

                  vec3 light1Dir = positionWC - lightPos;

                  float distance = length(light1Dir);

     

                  if(distance < u_distance){

                    // czm_view * 世界坐标 -> 相机坐标

                    vec4 l1 = czm_view * vec4(lightPos, 1.0);

                    // lightDirection相机坐标

                    vec3 lightDirectionEC = l1.xyz - positionEC;

                    mx1 = 1.0 - distance / u_distance;

                    color = czm_pbrLighting(positionEC,normalEC,lightDirectionEC,lightColorHdr.xyz,pbrParameters).xyz;

                  }

                  //

                  mx1 = max(color.r,max(color.g,color.b)) * pow(mx1,1.0) * 10.0;

                  // return vec4(color,mx1);

                  return vec4(lightColorHdr.rgb,mx1);

                }

     

     

                void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)

                {

                  // 世界坐标

                  vec3 positionWC = fsInput.attributes.positionWC;

                  // 相机坐标系下的法线向量

                  vec3 normalEC = fsInput.attributes.normalEC;

                  // 相机坐标

                  vec3 positionEC = fsInput.attributes.positionEC;

       

                  vec3 lightColorHdr = czm_lightColorHdr;

                  vec3 lightDirectionEC = czm_lightDirectionEC;

                 

                  lightDirectionEC = (czm_view * vec4(u_cameraDirectionWC,1.0)).xyz - positionEC;

     

                  czm_pbrParameters pbrParameters0;

                  pbrParameters0.diffuseColor = material.diffuse;

                  pbrParameters0.f0 = vec3(0.5); 

                  pbrParameters0.roughness = 1.0;

                  vec3 lightColor0 = czm_pbrLighting(positionEC, normalEC, lightDirectionEC, lightColorHdr, pbrParameters0);

     

                  czm_pbrParameters pbrParameters;

                  pbrParameters.diffuseColor = material.diffuse;

                  pbrParameters.f0 = vec3(0.5);

                  pbrParameters.roughness = 1.0;

     

                  vec4 lightColorR = makeLight(u_lightColor, u_lightPosition, positionWC, positionEC, normalEC, pbrParameters);

                  vec3 finalColor = mix(lightColor0.rgb, lightColorR.rgb, lightColorR.a);

                  material.diffuse = finalColor;

                }

            `

        });

        tileset.customShader = customShader;

        // tileset.customShader.setUniform("u_lightPosition", Cesium.Cartesian3.fromDegrees(112,28,80));

    }

参考:Cesium建筑自定义光源效果_cesium shader-CSDN博客

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值