cesium视频投影
- 游戏开发
- 2025-09-01 09:30:01

先看效果 使用cesium做视频投影效果,而且还要跟随无人机移动而移动,我现在用定时器更新无人机的坐标来实现效果具体代码如下: 1、CesiumVideo3d.js(某个cesium技术群大佬分享的)
// import ECEF from "./CoordinateTranslate"; let CesiumVideo3d = (function () { var videoShed3dShader = "\r\n\r\n\r\n\r\nuniform float mixNum;\r\nuniform sampler2D colorTexture;\r\nuniform sampler2D stcshadow; \r\nuniform sampler2D videoTexture;\r\nuniform sampler2D depthTexture;\r\nuniform mat4 _shadowMap_matrix; \r\nuniform vec4 shadowMap_lightPositionEC; \r\nuniform vec4 shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness; \r\nuniform vec4 shadowMap_texelSizeDepthBiasAndNormalShadingSmooth; \r\nvarying vec2 v_textureCoordinates;\r\nvec4 toEye(in vec2 uv, in float depth){\r\n vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\r\n vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);\r\n posInCamera =posInCamera / posInCamera.w;\r\n return posInCamera;\r\n}\r\nfloat getDepth(in vec4 depth){\r\n float z_window = czm_unpackDepth(depth);\r\n z_window = czm_reverseLogDepth(z_window);\r\n float n_range = czm_depthRange.near;\r\n float f_range = czm_depthRange.far;\r\n return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\r\n}\r\nfloat _czm_sampleShadowMap(sampler2D shadowMap, vec2 uv){\r\n return texture2D(shadowMap, uv).r;\r\n}\r\nfloat _czm_shadowDepthCompare(sampler2D shadowMap, vec2 uv, float depth){\r\n return step(depth, _czm_sampleShadowMap(shadowMap, uv));\r\n}\r\nfloat _czm_shadowVisibility(sampler2D shadowMap, czm_shadowParameters shadowParameters){\r\n float depthBias = shadowParameters.depthBias;\r\n float depth = shadowParameters.depth;\r\n float nDotL = shadowParameters.nDotL;\r\n float normalShadingSmooth = shadowParameters.normalShadingSmooth;\r\n float darkness = shadowParameters.darkness;\r\n vec2 uv = shadowParameters.texCoords;\r\n depth -= depthBias;\r\n vec2 texelStepSize = shadowParameters.texelStepSize;\r\n float radius = 1.0;\r\n float dx0 = -texelStepSize.x * radius;\r\n float dy0 = -texelStepSize.y * radius;\r\n float dx1 = texelStepSize.x * radius;\r\n float dy1 = texelStepSize.y * radius;\r\n float visibility = \r\n (\r\n _czm_shadowDepthCompare(shadowMap, uv, depth)\r\n +_czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy0), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy0), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy0), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, 0.0), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, 0.0), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy1), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy1), depth) +\r\n _czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy1), depth)\r\n ) * (1.0 / 9.0)\r\n ;\r\n return visibility;\r\n}\r\nvec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point){\r\n vec3 v01 = point -planeOrigin;\r\n float d = dot(planeNormal, v01) ;\r\n return (point - planeNormal * d);\r\n}\r\nfloat ptm(vec3 pt){\r\n return sqrt(pt.x*pt.x + pt.y*pt.y + pt.z*pt.z);\r\n}\r\nvoid main() \r\n{ \r\n const float PI = 3.141592653589793;\r\n vec4 color = texture2D(colorTexture, v_textureCoordinates);\r\n vec4 currD = texture2D(depthTexture, v_textureCoordinates);\r\n if(currD.r>=1.0){\r\n gl_FragColor = color;\r\n return;\r\n }\r\n \r\n float depth = getDepth(currD);\r\n vec4 positionEC = toEye(v_textureCoordinates, depth);\r\n vec3 normalEC = vec3(1.0);\r\n czm_shadowParameters shadowParameters; \r\n shadowParameters.texelStepSize = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.xy; \r\n shadowParameters.depthBias = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.z; \r\n shadowParameters.normalShadingSmooth = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.w; \r\n shadowParameters.darkness = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.w; \r\n shadowParameters.depthBias *= max(depth * 0.01, 1.0); \r\n vec3 directionEC = normalize(positionEC.xyz - shadowMap_lightPositionEC.xyz); \r\n float nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \r\n vec4 shadowPosition = _shadowMap_matrix * positionEC; \r\n shadowPosition /= shadowPosition.w; \r\n if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \r\n { \r\n gl_FragColor = color;\r\n return;\r\n }\r\n\r\n shadowParameters.texCoords = shadowPosition.xy; \r\n shadowParameters.depth = shadowPosition.z; \r\n shadowParameters.nDotL = nDotL; \r\n float visibility = _czm_shadowVisibility(stcshadow, shadowParameters); \r\n\r\n vec4 videoColor = texture2D(videoTexture,shadowPosition.xy);\r\n if(visibility==1.0){\r\n gl_FragColor = mix(color,vec4(videoColor.xyz,1.0),mixNum*videoColor.a);\r\n }else{\r\n if(abs(shadowPosition.z-0.0)<0.01){\r\n return;\r\n }\r\n gl_FragColor = color;\r\n }\r\n} "; var Cesium=null var videoShed3d=function(cesium,viewer, param) { Cesium=cesium this.ECEF = new ECEF(); this.param = param; var option = this._initCameraParam(); this.optionType = { Color: 1, Image: 2, Video: 3 } this.near = option.near ? option.near : 0.1; if (option || (option = { }), this.viewer = viewer, this._cameraPosition = option.cameraPosition, this._position = option.position, this.type = option.type, this._alpha = option.alpha || 1, this.url = option.url, this.color = option.color, this._debugFrustum = Cesium.defaultValue(option.debugFrustum, !0), this._aspectRatio = option.aspectRatio || this._getWinWidHei(), this._camerafov = option.fov || Cesium.Math.toDegrees(this.viewer.scene.camera.frustum.fov), this.texture = option.texture || new Cesium.Texture({ context: this.viewer.scene.context, source: { width: 1, height: 1, arrayBufferView: new Uint8Array([255, 255, 255, 255]) }, flipY: !1 }), this._videoPlay = Cesium.defaultValue(option.videoPlay, !0), this.defaultShow = Cesium.defaultValue(option.show, !0), !this.cameraPosition || !this.position) return void console.log('初始化失败:请确认相机位置与视点位置正确!'); switch (this.type) { default: case this.optionType.Video: this.activeVideo(this.url); break; case this.optionType.Image: this.activePicture(this.url); this.deActiveVideo(); break; case this.optionType.Color: this.activeColor(this.color), this.deActiveVideo(); } this._createShadowMap(), this._getOrientation(), this._addCameraFrustum() this._addPostProcess() this.viewer.scene.primitives.add(this) } Object.defineProperties(videoShed3d.prototype, { alpha: { get: function () { return this._alpha }, set: function (e) { return this._alpha = e } }, aspectRatio: { get: function () { return this._aspectRatio }, set: function (e) { this._aspectRatio = e, this._changeVideoWidHei() } }, debugFrustum: { get: function () { return this._debugFrustum }, set: function (e) { this._debugFrustum = e, this.cameraFrustum.show = e } }, fov: { get: function () { return this._camerafov }, set: function (e) { this._camerafov = e, this._changeCameraFov() } }, cameraPosition: { get: function () { return this._cameraPosition }, set: function (e) { e && (this._cameraPosition = e, this._changeCameraPos()) } }, position: { get: function () { return this._position }, set: function (e) { e && (this._position = e, this._changeViewPos()) } }, videoPlay: { get: function () { return this._videoPlay }, set: function (e) { this._videoPlay = Boolean(e), this._videoEle && (this.videoPlay ? this._videoEle.paly() : this._videoEle.pause()) } }, params: { get: function () { var t = { } return t.type = this.type, this.type == this.optionType.Color ? t.color = this.color : t.url = this.url, t.position = this.position, t.cameraPosition = this.cameraPosition, t.fov = this.fov, t.aspectRatio = this.aspectRatio, t.alpha = this.alpha, t.debugFrustum = this.debugFrustum, t } }, show: { get: function () { return this.defaultShow }, set: function (e) { this.defaultShow = Boolean(e), this._switchShow() } } }) videoShed3d.prototype._initCameraParam = function () { var viewPoint = this.ECEF.enu_to_ecef({ longitude: this.param.position.x * 1, latitude: this.param.position.y * 1, altitude: this.param.position.z * 1 }, { distance: this.param.far, azimuth: this.param.rotation.y * 1, elevation: this.param.rotation.x * 1 }); var position = Cesium.Cartesian3.fromDegrees(viewPoint.longitude, viewPoint.latitude, viewPoint.altitude); var cameraPosition = Cesium.Cartesian3.fromDegrees(this.param.position.x * 1, this.param.position.y * 1, this.param.position.z * 1); return { type: 3, url: this.param.url, cameraPosition: cameraPosition, position: position, alpha: this.param.alpha, near: this.param.near, fov: this.param.fov, debugFrustum: this.param.debugFrustum } } /** * 旋转 */ videoShed3d.prototype._changeRotation = function (e) { if (e) { this.param.rotation = e; var option = this._initCameraParam(); this.position = option.position; } } /** * 相机位置 */ videoShed3d.prototype._changeCameraPosition = function (e) { if (e) { this.param.position = e; var option = this._initCameraParam(); this.cameraPosition = optioncesium视频投影由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“cesium视频投影”