新闻详情

新闻详情

首页 / 资讯中心 / 详情

OsgEarth 加载CESIUM或ReadyMap 后,再加载模型,结果黑乎乎

发布时间:2026/11/5 1:25:25来源:尧图网络
OsgEarth 加载CESIUM或ReadyMap 后,再加载模型,结果黑乎乎
最近做了一个有关地球的OsgEarth的项目发现OsgEarth 加载CESIUM或ReadyMap 后再加载模型结果黑乎乎。。。折腾数日发现了解决方法。。。原理就不说了直接贴代码/** * file ModelShaderLoader.h * brief 模型加载自建着色器工具类解决osgEarth ReadyMap / CesiumNative模型发黑问题 * details * 两套渲染环境二选一自动选择对应着色器 * 1. ReadyMap不启用GL3RealizeOperation使用osg_*别名版本shader屏幕微分法线漫反射 * 2. CesiumNative启用GL3RealizeOperation(Core Profile)不能使用osg_*别名 * 使用显式location顶点属性Node回调实时推送MVP矩阵uniform同样屏幕微分法线漫反射。 * 功能加载模型、挂载对应shader、全局缩放。 * author xxx * date 2026-09-23 * note * - 两套环境模型加载都正常着色器分支自动切换消除模型发黑 * - CesiumNative环境禁止调用setUseModelViewAndProjectionUniforms/setUseVertexAttributeAliasing会崩溃。 * warning * - CesiumNative使用NodeCallback实时更新矩阵uniform有极小额外开销 * - 着色器状态使用OVERRIDE子节点材质无法覆盖。 */ #pragma once #include QObject #include osg/ref_ptr #include osg/NodeCallback #include string class ModelShaderLoader : public QObject { Q_OBJECT public: enum class RenderEnv { ReadyMap, CesiumNative }; explicit ModelShaderLoader(QObject* parent nullptr); void setRenderEnv(RenderEnv env); /** * brief 加载模型并自动挂载对应环境的自建shader修复发黑 * param[in] filePath 模型路径 * param[in] scale 模型缩放系数 * return osg::ref_ptrosg::Node 组装完成节点失败返回nullptr */ osg::ref_ptrosg::Node loadModel(const std::string filePath, double scale); private: RenderEnv _renderEnv RenderEnv::ReadyMap; // ReadyMap 版本shader源码osg_*别名 static const char* vertSrcReadyMap; static const char* fragSrcReadyMap; // CesiumNative CoreProfile版本shader源码无osg_*别名 static const char* vertSrcCesium; static const char* fragSrcCesium; // Cesium环境回调遍历节点更新MVP uniform struct MatrixUpdateCallback; }; /** * file ModelShaderLoader.cpp * brief ModelShaderLoader实现自建shader解决osgEarth Cesium/ReadyMap模型发黑 * author xxx * date 2026-09-23 */ #include ModelShaderLoader.h #include osgViewer/Viewer #include osg/State #include osg/Texture #include osg/NodeVisitor #include osg/MatrixTransform #include osg/Uniform #include osg/Shader #include osg/Program #include osgDB/ReadFile #include iostream // ReadyMap Shaderosg_*别名 const char* ModelShaderLoader::vertSrcReadyMap R( #version 330 core in vec4 osg_Vertex; in vec4 osg_MultiTexCoord0; uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ModelViewMatrix; out vec2 vTexCoord; out vec3 vViewPos; void main() { gl_Position osg_ModelViewProjectionMatrix * osg_Vertex; vViewPos (osg_ModelViewMatrix * osg_Vertex).xyz; vTexCoord osg_MultiTexCoord0.xy; } ); const char* ModelShaderLoader::fragSrcReadyMap R( #version 330 core uniform sampler2D tex0; in vec2 vTexCoord; in vec3 vViewPos; out vec4 fragColor; void main() { vec3 dx dFdx(vViewPos); vec3 dy dFdy(vViewPos); vec3 normal normalize(cross(dx, dy)); vec3 lightDir normalize(vec3(0.6, 0.7, 0.4)); float diff max(dot(normal, lightDir),0.0); vec4 texColor texture(tex0, vTexCoord); vec3 rgb texColor.rgb * (0.3 0.7 * diff); fragColor vec4(rgb, texColor.a); } ); // CesiumNative ShaderCoreProfile无osg_* const char* ModelShaderLoader::vertSrcCesium R( #version 330 core layout(location 0) in vec3 aPos; layout(location 1) in vec2 aTexCoord; uniform mat4 uMVP; uniform mat4 uModelView; out vec2 vTexCoord; out vec3 vViewPos; void main() { gl_Position uMVP * vec4(aPos,1.0); vViewPos (uModelView * vec4(aPos,1.0)).xyz; vTexCoord aTexCoord; } ); const char* ModelShaderLoader::fragSrcCesium R( #version 330 core uniform sampler2D tex0; in vec2 vTexCoord; in vec3 vViewPos; out vec4 fragColor; void main() { vec3 dx dFdx(vViewPos); vec3 dy dFdy(vViewPos); vec3 normal normalize(cross(dx, dy)); vec3 lightDir normalize(vec3(0.6, 0.7, 0.4)); float diff max(dot(normal, lightDir),0.0); vec4 texColor texture(tex0, vTexCoord); vec3 rgb texColor.rgb * (0.3 0.7 * diff); fragColor vec4(rgb, texColor.a); } ); // Cesium 矩阵更新回调每帧遍历获取模型矩阵上传MVP struct ModelShaderLoader::MatrixUpdateCallback : public osg::NodeCallback { osg::ref_ptrosg::Uniform _uMVP; osg::ref_ptrosg::Uniform _uModelView; MatrixUpdateCallback() { _uMVP new osg::Uniform(uMVP, osg::Matrixf()); _uModelView new osg::Uniform(uModelView, osg::Matrixf()); } void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osg::Matrixd MVP node-getMatrix() * nv-getViewMatrix() * nv-getProjectionMatrix(); osg::Matrixd MV node-getMatrix() * nv-getViewMatrix(); _uMVP-set(MVP); _uModelView-set(MV); traverse(node, nv); } }; ModelShaderLoader::ModelShaderLoader(QObject* parent) : QObject(parent) { } void ModelShaderLoader::setRenderEnv(RenderEnv env) { _renderEnv env; } osg::ref_ptrosg::Node ModelShaderLoader::loadModel(const std::string filePath, double scale) { osg::ref_ptrosg::Node modelNode osgDB::readNodeFile(filePath); if (!modelNode) { std::cerr [ModelShaderLoader] load model failed: filePath std::endl; return nullptr; } osg::ref_ptrosg::Program program new osg::Program; osg::ref_ptrMatrixUpdateCallback matrixCb; if (_renderEnv RenderEnv::ReadyMap) { std::cout [ModelShaderLoader] ReadyMap env, use osg_alias shader std::endl; program-addShader(new osg::Shader(osg::Shader::VERTEX, vertSrcReadyMap)); program-addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSrcReadyMap)); program-addBindAttribLocation(osg_Vertex, 0); program-addBindAttribLocation(osg_MultiTexCoord0, 1); } else { std::cout [ModelShaderLoader] CesiumNative env, use core profile shader std::endl; program-addShader(new osg::Shader(osg::Shader::VERTEX, vertSrcCesium)); program-addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSrcCesium)); matrixCb new MatrixUpdateCallback(); } // 遍历Geode挂载shader struct ApplyShaderVisitor : public osg::NodeVisitor { osg::Program* _prog; MatrixUpdateCallback* _mtxCb; ApplyShaderVisitor(osg::Program* p, MatrixUpdateCallback* cb) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), _prog(p), _mtxCb(cb) {} void apply(osg::Geode geode) override { for (unsigned int i 0; i geode.getNumDrawables(); i) { osg::Drawable* draw geode.getDrawable(i); osg::StateSet* ss draw-getOrCreateStateSet(); ss-setAttributeAndModes(_prog, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); ss-setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); ss-addUniform(new osg::Uniform(tex0, 0)); if (_mtxCb) { ss-addUniform(_mtxCb-_uMVP.get()); ss-addUniform(_mtxCb-_uModelView.get()); } } } }; ApplyShaderVisitor vis(program.get(), matrixCb.get()); modelNode-accept(vis); // 外层缩放节点 绑定矩阵回调Cesium环境 osg::ref_ptrosg::MatrixTransform scaleXform new osg::MatrixTransform; scaleXform-setMatrix(osg::Matrix::scale(osg::Vec3(scale, scale, scale))); scaleXform-addChild(modelNode.get()); if (matrixCb) { scaleXform-addUpdateCallback(matrixCb.get()); } return scaleXform; } // 1. CesiumNative开启GL3RealizeOperation auto loader new ModelShaderLoader(this); loader-setRenderEnv(ModelShaderLoader::RenderEnv::CesiumNative); auto modelNode loader-loadModel(xxx.obj, 1.0); // 2. ReadyMap不开启GL3RealizeOperation打开alias开关 auto loader new ModelShaderLoader(this); loader-setRenderEnv(ModelShaderLoader::RenderEnv::ReadyMap); auto modelNode loader-loadModel(xxx.obj, 1.0);
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/4 15:56:54

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/4 22:55:41

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/4 17:01:23

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/4 12:33:12

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/4 1:25:31

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/4 3:51:11

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉