摸索半天并未搜到有具体的实现方式,但从众多文章里边找到了一条小路。大家都知道思路就是修改顶点着色器的高度值,但是怎么去修改?
下边是我参考的两篇文章,感谢岭南灯火、百年内必成大牛
https://www.cnblogs.com/webglblog#/c/subject/p/17093810.html
https://www.cnblogs.com/onsummer/p/14212009.html
customShader中修改vertexShaderText,vsOutput.positionMC就是最后输出的模型内部顶点坐标,可以在官方沙盒测试一下,大家都说修改高度,那就直接让它的z等于0,有变化了,模型变平了,哎怎么是斜的,修改xy也是斜的。
这个时候你可能会问是不是少了什么?难道还要变换矩阵吗?这可就费劲了,上学时候线性代数我都是60多分啊,其实不是我们只需换个自己的数据再试一下就会看到正常的变化,而且3dtiles的坐标轴不一样,更改的参数也不一样,需要试一下,一般是修改y。
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
vsOutput.positionMC.y = 0.;
}
`,
找了自己的数据试了以后又出来了一个新的问题,不同瓦片并不是在同一个平面,根据以往经验应该还是包围盒中心点不在一个高度,所以不能直接想当然的等于0,让它贴地。
由于这里我已经把范围点传进来了,就试了下等于传进来点的y,效果是几乎在一个平面上,对是几乎。不同瓦片之间存在缝隙及闪面问题,闪面应该是重合的问题,缝隙是不同瓦片高度还是存在一点点差别。
这里先不谈缝隙及闪面,暂未深究。
那么外部点是怎么传进去的呢,答案是uniforms,先来个四边形吧,实际上只需要对角线的1和3就行。
uniforms: {
u_firstPWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84576776093665,34.70286868401709,25
),
},
u_first2PWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84676776093665,34.70286868401709, 25
),
},
u_first3PWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84676776093665,34.70186868401709, 25
),
},
u_first4PWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84576776093665,34.70186868401709, 25
),
},
},
上边第二篇文章里有世界坐标转模型内部坐标的方法
可以通过四边形范围的x和z来限制压平范围,(xz方向可能不同需要自己调整), 至于不规则多边形可以通过点是否在多边形内判断,网上一大堆可以去试试,然后加上交互把多边形点传进去就行了。一般项目里压平操作是为了放置或替换其他模型,比如挖掉倾斜然后放精模,矩形就够了。不压平裁剪掉也可以。
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
vec4 firstpMC = czm_inverseModel * vec4(u_firstPWC, 1);
vec4 firstp3MC = czm_inverseModel * vec4(u_first3PWC, 1);
if(vsOutput.positionMC.x>firstpMC.x && vsOutput.positionMC.xfirstp3MC.z && vsOutput.positionMC.z
总结一下,本文只是简易版,能凑合用,未测试更多数据,(大雁塔数据没有缝隙)具体效果因数据而异。目前大面积压平有闪面、缝隙、视锥裁剪问题,欢迎其他朋友分享解决方案。
cesium版本是103,最后CustomShader完整代码
let customShader = new Cesium.CustomShader({
lightingModel: Cesium.LightingModel.UNLIT,
uniforms: {
u_firstPWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84576776093665,34.70286868401709,25
),
},
u_first2PWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84676776093665,34.70286868401709, 25
),
},
u_first3PWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84676776093665,34.70186868401709, 25
),
},
u_first4PWC: {
type: Cesium.UniformType.VEC3,
value: Cesium.Cartesian3.fromDegrees(
113.84576776093665,34.70186868401709, 25
),
},
},
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
vec4 firstpMC = czm_inverseModel * vec4(u_firstPWC, 1);
vec4 firstp3MC = czm_inverseModel * vec4(u_first3PWC, 1);
if(vsOutput.positionMC.x>firstpMC.x && vsOutput.positionMC.xfirstp3MC.z && vsOutput.positionMC.z
写东西确实有点费劲~