vue-Cesium 和 Cesium加载3dtiles ,出现An error occurred while rendering

本文介绍了解决从gltf1.0升级到gltf2.0后因不支持自定义shader导致的报错问题,提供了两种解决方案:一是通过修改gltf文件的extensions属性,二是使用osg2cesiumApp工具转换osgb文件为3dtiles。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

报错原因

这是因为gltf1.0升级到gltf2.0后不支持自定义shader

解决方法一

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;

        }

    }

});

方法2,osgb转3dtiles时,直接使用工具osg2cesiumApp(我的资源里有哦)

使用这个转出来的3dtiles,不会报错,下载地址:
https://download.youkuaiyun.com/download/zhengshaofeng1/12692050 (转码过程中程序未响应的话,不用理会,他会转完的)

Uncaught (in promise) SyntaxError: Unexpected token '<', "<!doctype "... is not valid JSON at JSON.parse (<anonymous>) at Resource.js:1180:17 localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token '<', "<!doctype "... is not valid JSON at JSON.parse (<anonymous>) at Resource.js:1180:17 CesiumWidget.js:962 An error occurred while rendering. Rendering has stopped. InvalidStateError: The source image could not be decoded. InvalidStateError: The source image could not be decoded. CesiumWidget.showErrorPanel @ CesiumWidget.js:962 localhost/:1 Uncaught (in promise) Event 如上所示报错修改下面代码:<template> <div id="cesium-container" ref="cesiumContainer"></div> </template> <script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue'; import * as Cesium from 'cesium'; import 'cesium/Build/Cesium/Widgets/widgets.css'; // 使用你自己的有效 Cesium 访问令牌 Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZTdiZDBhZS0xNzBhLTRjZGUtOTY4NC1kYzA5ZDEyNGEyNjUiLCJpZCI6MzE2OTI5LCJpYXQiOjE3NTEzMzg2Mzh9.9QHGIwaWkUOX0NOSre5369rrf1k6bGhZu7xUQia4JmE'; const cesiumContainer = ref<HTMLDivElement | null>(null); let viewer: Cesium.Viewer | null = null; onMounted(async () => { // 改为异步函数 if (!cesiumContainer.value) return; try { // 异步创建世界地形 - 最新版 Cesium 的用法 const worldTerrain = await Cesium.createWorldTerrainAsync({ requestVertexNormals: true, requestWaterMask: true }); // 初始化Cesium地球 viewer = new Cesium.Viewer(cesiumContainer.value, { animation: false, baseLayerPicker: false, fullscreenButton: false, vrButton: false, geocoder: false, homeButton: false, infoBox: false, sceneModePicker: false, selectionIndicator: false, timeline: false, navigationHelpButton: false, navigationInstructionsInitiallyVisible: false, terrainProvider: worldTerrain, // 使用异步创建的地形 imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' }) }); // 设置初始视图位置(株洲市) viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(113.13, 27.83, 10000000), orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-90), roll: 0.0 }, duration: 2 }); // 添加水面效果 addWaterEffect(); // 添加光照效果 addLightingEffect(); } catch (error) { console.error('Failed to initialize Cesium:', error); } }); onUnmounted(() => { if (viewer) { viewer.destroy(); viewer = null; } }); // 添加水面效果 function addWaterEffect() { if (viewer) { viewer.scene.globe.enableLighting = true; viewer.scene.globe.dynamicAtmosphereLighting = true; viewer.scene.globe.dynamicAtmosphereLightingFromSun = true; } } // 添加光照效果 function addLightingEffect() { if (viewer) { viewer.scene.globe.showGroundAtmosphere = true; viewer.scene.fog.enabled = true; viewer.scene.skyAtmosphere.show = true; } } </script> <style scoped> #cesium-container { position: absolute; top: 0; left: 0; height: 100%; width: 100%; margin: 0; padding: 0; overflow: hidden; } /* 覆盖Cesium默认的logo */ :deep(.cesium-viewer-bottom) { display: none !important; } </style>
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值