解决Cesium1.50对gltf2.0/3dtiles数据读取的问题
问题说明
Cesium 1.50(2018/10/01)版本打开3dtiles可能会出现加载不上导致渲染停止的错误。
错误说明为:RuntimeError: Unsupported glTF Extension: KHR_technique_webgl
错误截图如下:
解决方案
我发现原因是KHR_technique_webgl扩展新版Cesium已经不支持的缘故,需要升级一下gltf数据,使用KHR_techniques_webgl扩展即可(注意多了一个s)。
当然如果直接修改3dtiles数据,比较劳心费神。这里提供一个简单的方法,只需要在Cesium.js加载以后,运行以下代码即可正常显示3dtiles数据了。
var fixGltf = function(gltf) {
if (!gltf.extensionsUsed) {
return;
}
var v = gltf.extensionsUsed.indexOf('KHR_technique_webgl');
var t = gltf.extensionsRequired.indexOf('KHR_technique_webgl');
// 中招了。。
if (v !== -1) {
gltf.extensionsRequired.splice(t, 1, 'KHR_techniques_webgl');
gltf.extensionsUsed.splice(v, 1, 'KHR_techniques_webgl');
gltf.extensions = gltf.extensions || {};
gltf.extensions['KHR_techniques_webgl'] = {};
gltf.extensions['KHR_techniques_webgl'].programs = gltf.programs;
gltf.extensions['KHR_techniques_webgl'].shaders = gltf.shaders;
gltf.extensions['KHR_techniques_webgl'].techniques = gltf.techniques;
var techniques = gltf.extensions['KHR_techniques_webgl'].techniques;
gltf.materials.forEach(function (mat, index) {
gltf.materials[index].extensions['KHR_technique_webgl'].values = gltf.materials[index].values;
gltf.materials[index].extensions['KHR_techniques_webgl'] = gltf.materials[index].extensions['KHR_technique_webgl'];
var vtxfMaterialExtension = gltf.materials[index].extensions['KHR_techniques_webgl'];
for (var value in vtxfMaterialExtension.values) {
var us = techniques[vtxfMaterialExtension.technique].uniforms;
for (var key in us) {
if (us[key] === value) {
vtxfMaterialExtension.values[key] = vtxfMaterialExtension.values[value];
delete vtxfMaterialExtension.values[value];
break;
}
}
};
});
techniques.forEach(function (t) {
for (var attribute in t.attributes) {
var name = t.attributes[attribute];
t.attributes[attribute] = t.parameters[name];
};
for (var uniform in t.uniforms) {
var name = t.uniforms[uniform];
t.uniforms[uniform] = t.parameters[name];
};
});
}
}
Object.defineProperties(Cesium.Model.prototype, {
_cachedGltf: {
set: function (value) {
this._vtxf_cachedGltf = value;
if (this._vtxf_cachedGltf && this._vtxf_cachedGltf._gltf) {
fixGltf(this._vtxf_cachedGltf._gltf);
}
},
get: function () {
return this._vtxf_cachedGltf;
}
}
});
寻根探底
KHR_technique_webgl的来源
这里不得不说下gltf2.0版本曾经存在的奇葩问题:只支持PBR材质,而不支持自定义shader。
2015年的gltf1.0标准时,本来是天然的支持也仅支持自定义shader的。大家都知道webgl是不支持固定管线的,gltf1.0支持自定义shader,和webgl标准是相当地匹配,但凡按照gltf1.0中的shader来渲染自然是不成问题。
但没想到gltf升级到2.0以后,居然默认只能使用PBR材质,而且是不再支持自定义shader。这个就很要命了:
首先各家渲染引擎(three.js/babylon/Cesium)对PBR材质的理解貌似都不一样,结果导致同一个gltf模型在不同的渲染引擎中渲染出来的效果还都有差别。。所以到目前为止也没有统一。从渲染效果上来说,three.js的渲染效果很棒,babylon也还可以,Cesium貌似理解得不太到位,效果差了一大截。。
其次,另外一个问题对Cesium更严重,Cesium早期本身按照gltf1.0的标准来绘制。到了gltf2.0时代,Cesium的Model类为了能同时支持gltf1.0和gltf2.0,不得不做出调整,将所有gltf1.0的模型都在内部自动升级成gltf2.0,然后再渲染。问题是gltf2.0不支持自定义shader啊,gltf1.0的自定义shader怎么转化成gltf2.0?自定义shader的自由度太大,是不太可能转成PBR材质的。。
那么Cesium怎么解决gltf1.0升级gltf2.0的问题呢?这里就用到了gltf2.0当时还处于草案阶段的扩展KHR_technique_webgl。通过这个扩展来在gltf2.0中实现自定义shader。
然而隐患恰恰来自于这个KHR_technique_webgl扩展。。
因为这个扩展尚未推出,于是出现了一个奇怪的现象。对于某些gltf2.0的模型(使用了KHR_technique_webgl扩展),只有Cesium能打开,连three.js、babylon都爱莫能助。Cesium变得异常强大。。
然而,好景不长,Cesium在使用这个扩展时,gltf2.0也在逐步进化,居然连KHR_technique_webgl这个扩展的名字都改了,technique后面加了一个s。。所以现在的扩展名叫KHR_techniques_webgl。。
这下对广大使用Cesium做开发的网友来说,就不太好了。因为之前发布模型时,但凡最终转化成带有KHR_technique_webgl扩展的数据就都会变得不能用。Cesium这次做得也很绝,连兼容性都不做一下。。这就意味着从Ceisum 1.50版本以后,之前使用了该扩展的3dtiles数据就都打不开了。(如果Cesium官方重视的话,或许会推出一个Cesium 1.50.1的补丁版本来解决这个问题吧,呵呵,毕竟也还算好改,就是上文提到的代码就能解决大部分问题了。)
从KHR_technique_webgl升级到KHR_techniques_webgl
注意前面是technique,后面是techniques。
Khronos把KHR_technique_webgl升级到KHR_techniques_webgl,也并非只是改了下名字这样简单。内部也做了一些调整。主要变化有:
1 把techniques、programs、shaders这三种类型的节点中都放到了扩展中去定义,不像之前直接放在主节点下;
2 techniques下的technique属性原先会有attributes、parameters、uniforms等几个节点,其中attributes、uniforms节点中定义的shader变量,是要去parameters节点下找到最终的类型和语义(semantic)的。之前看gltf1.0时也是这个地方不太理解为啥要这么折腾下。。现在看来貌似是没有必要了。KHR_techniques_webgl的扩展变得更加精简。直接去掉了parameters节点,并将其中的定义挪至attributes、uniforms中去。
3 KHR_technique_webgl扩展时,materials节点下的material也需要定义成扩展形式
4 还有其他的,我还没用到。。
令人欣喜的Cesium和隐忧
这一次Cesium貌似又走在了各大引擎的前列,首先支持上了KHR_techniques_webgl扩展。而其他引擎,比如three.js、babylon都还没支持上呢。以下是测试结果:
three.js视景器
https://gltf-viewer.donmccurdy.com/
three.js读取貌似正常,实际上会给出警告,没有使用这个扩展。
babylon视景器
babylonjs比较直白,直接表示不认得KHR_techniques_webgl。
国产引擎clay
clay也是著名的ECharts使用的底层WebGL引擎。
https://pissang.github.io/clay-viewer/editor/
居然没有报错。。而且渲染效果也不错!不得不赞叹一下国产引擎的强大。
隐忧
不太好的问题是KHR_techniques_webgl扩展仍然处于草案阶段,也就是说以后还是有可能会修改的。。这就意味着即使现在的3dtiles能渲染,或许以后Cesium版本升级,还会有渲染不出来的问题。。
欢迎关注 Cesium实验室 ,QQ群号:595512567。
解决Cesium1.50对gltf2.0/3dtiles数据读取的问题的更多相关文章
- 解决echarts饼图不显示数据为0的数据
如图所示 饼图数据为0但是还是会显示lableline和lable 解决方法 var echartData = [{ value: data_arry[0]==0?null:data_arry[0], ...
- 使用AFNetworking 2.0 请求数据时出现错误 Request failed: unacceptable content-type: text/html 解决方法
使用AFNetworking 2.0 请求数据时出现错误 Request failed: unacceptable content-type: text/html 解决方法 添加一行 manager. ...
- 解决InputStream中数据读取不完整问题
转载:https://blog.csdn.net/lilidejing/article/details/37913627 当需要用到InputStream获取数据时,这时就需要读取InputStrea ...
- 问题-MyBatis不识别Integer值为0的数据
问题-MyBatis不识别Integer值为0的数据 问题:使用MyBatis的过程中,发现一个值为0的数据,Mybatis所识别,最后定位才发现,是自己的写法有问题, <if test=&qu ...
- tensorflow 1.0 学习:十图详解tensorflow数据读取机制
本文转自:https://zhuanlan.zhihu.com/p/27238630 在学习tensorflow的过程中,有很多小伙伴反映读取数据这一块很难理解.确实这一块官方的教程比较简略,网上也找 ...
- cesium纽约3dtiles数据下载
cesium示例有纽约的3dtiles数据,下载官方有下载链接,但是下载后为乱码. 因此研究了下,写了个爬虫解码下载,使用办法,安装Python直接运行即可,代码如下: #coding=utf-8 f ...
- Cesium案例解析(五)——3DTilesPhotogrammetry摄影测量3DTiles数据
目录 1. 概述 2. 案例 3. 结果 1. 概述 3D Tiles是用于传输和渲染大规模3D地理空间数据的格式,例如摄影测量,3D建筑,BIM / CAD,实例化特征和点云等.与常规的模型文件格式 ...
- 3dTiles 数据规范详解[2] Tileset与Tile
转载请声明出处:全网@秋意正寒 https://www.cnblogs.com/onsummer/p/13128682.html 一.一个简单的3dTiles数据示例 上图是一份 3dTiles数据集 ...
- 3dTiles 数据规范详解[3] 内嵌在瓦片文件中的两大数据表
转载请声明出处:全网@秋意正寒 零.本篇前言 说实话,我很纠结是先介绍瓦片的二进制数据文件结构,还是先介绍这两个重要的表.思前想后,我决定还是先介绍这两个数据表. 因为这两个表不先给读者灌输,那么介绍 ...
随机推荐
- 图论最短路径算法——SPFA
为了不要让太多人被害,我还是说一下这种算法,它实际上很简单,但被人讲着讲着绕晕了. 主要思想 有人说,SPFA是Bellman-Ford的队列优化.这个算法我也懂了,但是还没试过.我不管是什么算法的优 ...
- JWT生成token
1.JWT简介 JSON Web Token 简称JWT.一个JWT实际上就是一个字符串,它由三部分组成,头部.载荷与签名.JWT生成的token是这样的 2.Json Web Token(JWT)生 ...
- 「题解」:[组合数学][DP]:地精部落
拿到这道题秒懂题意:波动序列. 然鹅不会打.想了一节课,想打纯组合数学,结果找不到规律. 想的是先假设拍出一个序列,然后交换其中的元素求组合, 无奈没啥规律可循,显然不能一口气求出来(我说的是我没办法 ...
- php链表笔记:合并两个有序链表
<?php /** * Created by PhpStorm. * User: huizhou * Date: 2018/12/2 * Time: 15:29 */ /** * 合并两个有序链 ...
- WCF加密操作(包括证书和证书+帐号密码)
WCF作为.net三大组件之一,伟大之处不用多说,但是其加密配置对于我这样的萌新来说还是颇有难度,因此将几天来的研究成果共享出来,与各位共勉~ 首先声明我的开发环境,Win10创意者更新 + Visu ...
- solusvm 主控端迁移
难点在于solusvm被控端已经开了小鸡的情况. 备份数据库: #!/bin/sh ## Vars CONF=/usr/local/solusvm/includes/solusvm.conf FILE ...
- Django自带的认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- 05_Hibernate数据库连接池
一.配置连接池 连接池:连接池是创建和管理数据库连接的缓冲池技术. 优点:合理利用数据库连接资源.简化的编程模式.受控的资源使用. 主流连接池: DBCP(DataBase connection po ...
- springcloud 使用RabbitMq
新建一个项目,三个module 分别为eureka-server,config-server,config-client, eureka-server 的pom.xml, <?xml versi ...
- kafka comsumer
kafka的顺序消费只保证在同一个partition中而已