【Overload游戏引擎分析】画场景栅格的Shader分析
Overload引擎地址: GitHub - adriengivry/Overload: 3D Game engine with editor
一、栅格绘制基本原理
Overload Editor启动之后,场景视图中有栅格线,这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现,这个栅格的几何网格只有两个三角形面片组成的正方形,使用特殊Shader绘制出来的。

绘制栅格的代码在EditorRenderer.cpp中,代码如下:
void OvEditor::Core::EditorRenderer::RenderGrid(const OvMaths::FVector3& p_viewPos, const OvMaths::FVector3& p_color)
{constexpr float gridSize = 5000.0f; // 栅格的总的大小FMatrix4 model = FMatrix4::Translation({ p_viewPos.x, 0.0f, p_viewPos.z }) * FMatrix4::Scaling({ gridSize * 2.0f, 1.f, gridSize * 2.0f }); // 栅格的模型矩阵m_gridMaterial.Set("u_Color", p_color); // 栅格的颜色m_context.renderer->DrawModelWithSingleMaterial(*m_context.editorResources->GetModel("Plane"), m_gridMaterial, &model); // 绘制栅格// 绘制坐标轴的三条线m_context.shapeDrawer->DrawLine(OvMaths::FVector3(-gridSize + p_viewPos.x, 0.0f, 0.0f), OvMaths::FVector3(gridSize + p_viewPos.x, 0.0f, 0.0f), OvMaths::FVector3(1.0f, 0.0f, 0.0f), 1.0f);m_context.shapeDrawer->DrawLine(OvMaths::FVector3(0.0f, -gridSize + p_viewPos.y, 0.0f), OvMaths::FVector3(0.0f, gridSize + p_viewPos.y, 0.0f), OvMaths::FVector3(0.0f, 1.0f, 0.0f), 1.0f);m_context.shapeDrawer->DrawLine(OvMaths::FVector3(0.0f, 0.0f, -gridSize + p_viewPos.z), OvMaths::FVector3(0.0f, 0.0f, gridSize + p_viewPos.z), OvMaths::FVector3(0.0f, 0.0f, 1.0f), 1.0f);
}
从中看出,先将面片平移到视点的前方,使得三角形始终在视锥体范围内,同时将三角形进行缩放,总的尺寸缩放到10000。然后使用m_gridMaterial材质进行绘制。所谓的材质就是Shader的封装。最后再绘制坐标轴的三条线。
可以使用RenderDoc抓帧,可以验证确实是这么实现的。

二、栅格绘制的Shader代码
绘制栅格的Vertex Shader代码如下:
#version 430 corelayout (location = 0) in vec3 geo_Pos;
layout (location = 1) in vec2 geo_TexCoords;
layout (location = 2) in vec3 geo_Normal;layout (std140) uniform EngineUBO
{mat4 ubo_Model;mat4 ubo_View;mat4 ubo_Projection;vec3 ubo_ViewPos;float ubo_Time;
};out VS_OUT
{vec3 FragPos;vec2 TexCoords;
} vs_out;void main()
{vs_out.FragPos = vec3(ubo_Model * vec4(geo_Pos, 1.0)); // 计算顶点世界坐标系坐标vs_out.TexCoords = vs_out.FragPos.xz; // 对应的纹理坐标,取对应的世界坐标gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0); // 计算NDC坐标
}
Vertex Shader的代码相对较简单,有效的输入只有geo_Pos。EngineUBO是OpenGL的UBO变量,传入了模型、视图、投影矩阵。main方法中,计算了三角形的世界坐标系坐标、纹理坐标、输出gl_Position变量。
Fragment Shader的代码如下:
#version 430 coreout vec4 FRAGMENT_COLOR;layout (std140) uniform EngineUBO
{mat4 ubo_Model;mat4 ubo_View;mat4 ubo_Projection;vec3 ubo_ViewPos;float ubo_Time;
};in VS_OUT
{vec3 FragPos;vec2 TexCoords;
} fs_in;uniform vec3 u_Color;float MAG(float p_lp)
{const float lineWidth = 1.0f;const vec2 coord = fs_in.TexCoords / p_lp;const vec2 grid = abs(fract(coord - 0.5) - 0.5) / fwidth(coord);const float line = min(grid.x, grid.y);const float lineResult = lineWidth - min(line, lineWidth);return lineResult;
}float Grid(float height, float a, float b, float c)
{const float cl = MAG(a);const float ml = MAG(b);const float fl = MAG(c);const float cmit = 10.0f;const float cmet = 40.0f;const float mfit = 80.0f;const float mfet = 160.0f;const float df = clamp((height - cmit) / (cmet - cmit), 0.0f, 1.0f);const float dff = clamp((height - mfit) / (mfet - mfit), 0.0f, 1.0f);const float inl = mix(cl, ml, df);const float fnl = mix(inl, fl, dff);return fnl;
}void main()
{const float height = distance(ubo_ViewPos.y, fs_in.FragPos.y);const float gridA = Grid(height, 1.0f, 4.0f, 8.0f);const float gridB = Grid(height, 4.0f, 16.0f, 32.0f);const float grid = gridA * 0.5f + gridB;// const vec2 viewdirW = ubo_ViewPos.xz - fs_in.FragPos.xz;// const float viewdist = length(viewdirW);FRAGMENT_COLOR = vec4(u_Color, grid);
}
Fragment shader的代码没有看太明白,需要的时候再分析吧。
三、绘制坐标轴线Shader
相比之下,绘制坐标轴线的Shader就简单太多了。线的顶点使用两个uniform变量传入线的两个顶点,根据gl_VertexID判断使用哪个顶点。FS直接给出颜色。
############ Vertex Shader ############version 430 coreuniform vec3 start;
uniform vec3 end;
uniform mat4 viewProjection;void main()
{vec3 position = gl_VertexID == 0 ? start : end;gl_Position = viewProjection * vec4(position, 1.0);
}######## Fragment Shader #############
#version 430 coreuniform vec3 color;out vec4 FRAGMENT_COLOR;void main()
{FRAGMENT_COLOR = vec4(color, 1.0);
}
对应CPU端的代码:
void OvRendering::Core::ShapeDrawer::DrawLine(const OvMaths::FVector3& p_start, const OvMaths::FVector3& p_end, const OvMaths::FVector3& p_color, float p_lineWidth)
{// 绑定line Shaderm_lineShader->Bind();m_lineShader->SetUniformVec3("start", p_start); // 线的起点m_lineShader->SetUniformVec3("end", p_end); // 线的终点m_lineShader->SetUniformVec3("color", p_color); // 线的颜色// 绘制线m_renderer.SetRasterizationMode(OvRendering::Settings::ERasterizationMode::LINE);m_renderer.SetRasterizationLinesWidth(p_lineWidth);// 掉Draw callm_renderer.Draw(*m_lineMesh, Settings::EPrimitiveMode::LINES);m_renderer.SetRasterizationLinesWidth(1.0f);m_renderer.SetRasterizationMode(OvRendering::Settings::ERasterizationMode::FILL);m_lineShader->Unbind();
}
这里有个m_lineMesh对象,其包含两个随意的顶点即可,只是为了启动两次顶点着色器,真实的顶点坐标是靠uniform传入的。Overload将其全部初始化为0:
std::vector<Geometry::Vertex> vertices;vertices.push_back({0, 0, 0,// 坐标0, 0, // 纹理0, 0, 0,// 法线0, 0, 0,0, 0, 0});vertices.push_back({0, 0, 0,0, 0,0, 0, 0,0, 0, 0,0, 0, 0});m_lineMesh = new Resources::Mesh(vertices, { 0, 1 }, 0);相关文章:
【Overload游戏引擎分析】画场景栅格的Shader分析
Overload引擎地址: GitHub - adriengivry/Overload: 3D Game engine with editor 一、栅格绘制基本原理 Overload Editor启动之后,场景视图中有栅格线,这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现࿰…...
智能化物流管理:全国快递物流查询API的角色与优势
前言 当今社会,物流行业已经成为了国民经济的重要组成部分,而快递物流则是物流行业中的一个重要分支。随着信息技术的不断发展,智能化物流管理正逐渐成为快递物流领域的趋势,而全国快递物流查询API作为其中的一部分,在…...
Spring Boot如何配置CORS支持
Spring Boot如何配置CORS支持 CORS(跨源资源共享)是一种Web浏览器的安全性功能,用于控制网页上的脚本文件从不同的源加载其他网页资源。在开发现代Web应用程序时,通常需要跨域请求不同的资源,如API服务或其他Web应用程…...
Mybatis 拦截器(Mybatis插件原理)
Mybatis为我们提供了拦截器机制用于插件的开发,使用拦截器可以无侵入的开发Mybatis插件,Mybatis允许我们在SQL执行的过程中进行拦截,提供了以下可供拦截的接口: Executor:执行器ParameterHandler:参数处理…...
AXI总线协议基础--几分钟熟悉通道信号和基础架构
目录 一、AXI协议基础 1.1读写通道的基本架构图 1.2猝发操作举例 1.3传输顺序 二、各个通道中的信号描述 2.1全局信号 2.2写地址通道信号 2.3写数据通道信号 2.4写响应通道信号 2.5读地址通道信号 2.6读数据通道 三、通道握手 3.1单一信息传输时的握手过程 3.2不…...
matlab数学建模方法与实践 笔记汇总
matlab数学建模方法与实践 笔记汇总 写在最前面笔记1:快速入门1.导入数据2.数据探索3.多项式拟合4.发布功能5.数据类型6、全部代码 笔记2:数据的准备1.数据的读取与写入excel、txt读图读视频 2.数据预处理缺失值噪声过滤数据归约数据变换 3.数据统计4.数…...
[UE虚幻引擎] DTCopyFile 插件说明 – 使用蓝图拷贝复制文件 (Windows)
本插件可以在虚幻引擎中使用蓝图对系统的其他文件进行拷贝复制操作。 1. 节点说明 Async Copy File 异步复制文件 Param Source File : 要复制的源文件的完整路径。Param Target File : 要复制的目标文件的完整路径。Param Force Copy : 如果为true,则如果目标…...
如何用ChatGPT学或教英文?5个使用ChatGPT的应用场景!
原文:百度安全验证 AI工具ChatGPT的出现大幅改变许多领域的运作方式,就连「学英文」也不例外!我发现ChatGPT应用在英语的学习与教学上非常有意思。 究竟ChatGPT如何改变英文学习者(学生)与教学者(老师)呢? 有5个应用场景我感到…...
基于spirngboot人事考勤管理信息系统
一:功能介绍 本系统前端采用vue框架以及Elemnt-UI,后端采用springboot、mysql、redis、mybatis等技术栈。 主要功能有登录、员工考勤、数据统计、薪资管理、权限管理、打卡管理、考勤审核、请假审批、薪资发放、报表统计、文件上传、文件下载、考勤设置、请假设置。…...
QT界面窗口 (widget)的显示和隐藏,关闭
QT界面窗口的显示和隐藏,关闭_qt窗口隐藏关闭按钮_123无敌,就你了的博客-CSDN博客...
这7个AI软件让设计效率飞起,快来收藏 优漫动游
伴随着AI技术的发展,设计师使用AI工具来提高工作效率已成为一种趋势,越来越多的AI工具也出现在市场上。本文收集了市场上7个好用的AI工具推荐给大家,一起来看看吧! 这7个AI软件让设计效率飞起,快来收藏 1、即时AI…...
ElasticSearch环境准备
Elasticsearch 是一个基于 Apache Lucene™ 的开源搜索引擎。不仅仅是一个全文搜索引擎,它还是一个分布式的搜索和分析引擎,可扩展并能够实时处理大数据。以下是关于 Elasticsearch 的一些主要特点和说明: 1.实时分析:Elasticsear…...
JAVA练习百题之数组插入元素
题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。 程序分析 要将一个数插入已经排好序的数组中,我们可以采用以下步骤: 遍历数组,找到第一个大于待插入数的位置。将待插入数插入到该位…...
C++11常见语法
目录 lambda 表达式 可变模板参数 C11新类的默认函数 包装器 function bind lambda 表达式 lambda 表达式也是可调用对象,在C语言中就有函数指针,但是函数指针比较复杂。 而在C11之前,也有仿函数,使用仿函数,还…...
【数据分析】时间序列
UTC时间:时间戳是以格林威治时间1970年01月01日00时00分00秒为基准计算所经过时间的秒数,是一个浮点数。Python的内置模块time和datetime都可以对时间格式数据进行转换,如时间戳和时间字符串的相互转换。 报错记录:AR has been re…...
【图像算法相关知识点】
【图像算法工程师】 什么是图像处理? 图像处理是指对数字图像进行处理和分析,以达到特定的目的。例如,调整图像的颜色、对比度、亮度等参数,进行图像增强、去噪、分割、特征提取等操作,以及应用计算机视觉算法实现目标…...
竹云筑基,量子加密| 竹云携手国盾量子构建量子身份安全防护体系
9月23日-24日,2023量子产业大会在安徽合肥举行。作为量子科技领域行业盛会,2023年量子产业大会以“协同创新 量点未来”为主题,展示了前沿的量子信息技术、产业创新成果,并举办主旨论坛、量子科普讲座等系列专项活动。量子信息作为…...
数据结构P46(2-1~2-4)
2-1编写算法查找顺序表中值最小的结点,并删除该结点 #include <stdio.h> #include <stdlib.h> typedef int DataType; struct List {int Max;//最大元素 int n;//实际元素个数 DataType *elem;//首地址 }; typedef struct List*SeqList;//顺序表类型定…...
基于BERT模型进行文本处理(Python)
基于BERT模型进行文本处理(Python) 所有程序都由Python使用Spyder运行。 对于BERT,在运行之前,它需要安装一些环境。 首先,打开Spyder。其次,在控制台中单独放置要安装的: pip install transformers pip install tor…...
妙鸭相机功能代码复现
妙鸭相机功能代码复现 妙鸭相机主要实现人脸替换与人脸高清增强修复功能。可通过两种方式实现Roop和Lora模型。 RooP笔记 基础模型:inswapper_128.onnx 人脸分析模型:insightface 高清增强模型:gfpgan 大体流程为通过insightface检测出人脸,替换人脸,使用gfpgan对人…...
高性价比塑料链板输送机厂家排行适配指南
随着2026年《工业输送设备安全生产通用规范》正式落地,国内输送设备行业的准入门槛和生产标准迎来新一轮调整,新规对各领域使用的输送设备提出了更明确的合规要求,也给中小企业选购设备提供了清晰的参考标准。2026年输送设备安全生产新规核心…...
从文件上传到 RAG 检索:真正看懂了一个 AI 项目的知识库链路
一、前言:今天不是单独学一个知识点,而是串起了一条完整链路 今天继续分析 AI 项目中的 RAG 模块时,我发现自己之前对“文件上传”“文件切片”“向量化”“召回”“大模型回答”这些概念,虽然都单独听过,但真正放到项…...
GBase 8a之listagg/string_agg 函数的反函数实现
GBase8a数据库中 listagg/string_agg 函数的反函数实现一、业务场景背景 在日常数据开发中,我们经常会遇到这种场景:某张表的字段里存储了用逗号(或其他分隔符)拼接的多个值,比如商品分类、标签、关联系统名称等&#…...
蒙古语TTS准确率仅73%?ElevenLabs 2024Q2基准测试报告曝光:词级准确率91.4%,但需绕过这2个API默认参数坑
更多请点击: https://codechina.net 第一章:蒙古语TTS准确率争议的真相还原 近年来,多款商用及开源蒙古语文本转语音(TTS)系统在公开评测中报告了92%–97%的词级准确率,但一线教育机构与本地化团队反馈的实…...
开发AI应用时如何借助Taotoken模型广场进行选型
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 开发AI应用时如何借助Taotoken模型广场进行选型 当开发者着手构建一个AI应用时,选择合适的模型往往是项目成功的关键起…...
CG-75B 七参数微型气象传感器 超声波测量原理 集成 一体化
产品概述七参数微型气象传感器是一款利用发送的声波脉冲,基于超声波原理研发的风速风向测量仪器,测量接收端的时间或频率(多普勒变换)差别来计算风速和风向。该传感器可以同时测量风速,风向的瞬时数值,支持…...
CANN Skills:用 AIGC 内容帮助开发者学习昇腾
CANN 开源社区的 skills 仓库是一个挺有意思的项目。它不是一个技术库,不提供任何 API 或算子——它是一个由 AI Agent 驱动的技术内容 Skill 合集。 每份 Skill 是一份 SKILL.md 文件,定义了 Agent 写特定主题技术文章的行为规则——术语规范、文章类型…...
2026亲测:专业AI智能降重工具选这款就对了
2026 年降 AIGC 工具已经从“基础语义改写”进化为多维度智能优化系统,核心评测指标涵盖 AI 痕迹清除精准度、学术表达一致性、格式结构完整性、长段落逻辑流畅性、降重适配范围以及高校检测合规性。本次测评覆盖 8 款主流工具,测试内容包括中英文论文处…...
3个关键设置让Windows风扇控制软件发挥最佳性能
3个关键设置让Windows风扇控制软件发挥最佳性能 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/FanControl.Relea…...
别再手动画图了!WPS PPT里这个‘转智能图形’功能,3秒让文字变高级图示
WPS PPT智能图形进阶指南:3秒实现专业级视觉表达 在快节奏的职场环境中,演示文档的视觉呈现往往决定着信息传递的效率。传统PPT制作中,将文字列表转换为可视化图形需要经历形状绘制、文字排版、配色调整等多道工序,耗时且难以保证…...
