GN引擎:15MB实现移动端UE5级画质的渲染管线重构与优化
1. 项目概述GN引擎的“不可能三角”挑战最近在圈子里GN引擎这个名字被讨论得越来越频繁。起因是它放出了一个技术演示宣称仅凭一个15MB左右的运行时库就能在移动端实现接近UE5虚幻引擎5的渲染画质。这听起来像是个“标题党”毕竟UE5的Nanite虚拟几何体和Lumen全局光照哪一个不是以庞大的计算资源和存储空间为代价的一个15MB的库连塞牙缝都不够。但当我深入研究了其公开的技术文档和有限的演示片段后发现这背后并非简单的营销噱头而是一套对现代渲染管线进行“外科手术式”重构的激进思路。它瞄准的不是在PC或主机上与UE5正面硬刚而是在一个更残酷的战场——移动端和超轻量级桌面应用——上用极致的“瘦身”和“效率”去逼近顶级画质的下限。这对于独立开发者、中小团队乃至对安装包体积和启动速度有严苛要求的应用场景如小程序、云游戏、轻量级工业仿真来说无疑具有巨大的吸引力。那么这个“国产黑科技”究竟是如何拆解并重组渲染管线的它牺牲了什么又换来了什么这正是我们今天要拆解的核心。2. GN引擎核心设计哲学极致的“按需渲染”要理解GN引擎首先要跳出传统游戏引擎“大而全”的思维定式。UE5、Unity这类通用引擎是“瑞士军刀”为了应对从手机休闲游戏到3A大作的几乎所有场景内置了海量功能模块、渲染路径和兼容性代码。这带来了无与伦比的灵活性和强大的工具链但同时也伴随着巨大的运行时开销和体积膨胀。GN引擎则走了另一条路它更像一把为特定任务精心打磨的“手术刀”其设计哲学可以概括为“极致的按需渲染与数据驱动”。2.1 从“通用管线”到“专用管线”的范式转变传统的前向渲染Forward Rendering和延迟渲染Deferred Rendering管线虽然各有优劣但都是相对固定的流水线。例如延迟渲染管线为了应对复杂的光照和材质通常包含GBuffer填充、光照计算、后处理等多个固定阶段即使场景中只有一个物体、一盏灯这套流程也几乎要全走一遍存在一定的冗余。GN引擎的渲染管线是高度可定制和可剪枝的。它并非提供两三条固定管线而是提供了一套用于组装渲染管线的“乐高积木”基础组件即那15MB运行时库的核心。开发者或美术人员可以通过数据配置文件或可视化工具来定义一条最适合当前场景或应用的渲染流程。比如一个室内静态场景可能不需要复杂的动态全局光照GI那么管线就可以直接剔除实时GI计算模块转而使用烘焙好的光照贴图Lightmap和反射探针Reflection Probe这些数据以高度优化的格式直接参与最终着色跳过了昂贵的实时光照积分过程。注意这里的“剔除”不是在运行时做条件判断而是在管线组装期或项目构建期就物理上移除不必要的Shader变体和计算模块。这是其体积小的关键之一。2.2 核心黑科技混合精度渲染与数据压缩15MB的库要承载高质量渲染必须在数据表示和计算精度上做极端优化。GN引擎在这方面采用了激进的混合精度策略。1. 渲染缓冲区压缩不同于传统引擎在GBuffer中使用完整的RGBA16F或RGBA32F格式GN引擎针对移动端Tile-Based GPU架构进行了深度优化。它可能使用诸如RGB10_A2用于反照率、RG16F用于法线粗糙度等更紧凑的格式来存储中间渲染数据。更关键的是它大量使用了帧内缓冲区复用和压缩技术。例如将深度信息与法线信息通过特定编码打包到同一个缓冲区或者在Tile内存中直接进行中间结果的压缩存储显著降低了带宽占用和内存需求这对于移动端GPU的能效比提升至关重要。2. 着色计算优化在着色器层面GN引擎并非简单地使用低精度浮点数如mediump而是智能地根据计算阶段选择精度。例如在光照累积阶段使用高精度但在纹理采样、颜色混合等对精度不敏感的阶段使用低精度。同时它极度依赖预计算技术。复杂的材质模型如基于物理的渲染PBR中的部分计算如环境BRDF积分会被预计算成查找表LUT运行时只需一次纹理采样用极低的代价换取视觉上近似的结果。3. 几何体处理GN的“类Nanite”思路UE5的Nanite核心是虚拟几何体通过软件光栅化和动态细节层次LOD实现海量三角形的渲染。GN引擎在移动端显然无法照搬这套吃算力的方案。它的思路更接近“极致优化的静态网格体LOD 实例化”。首先它对静态网格体的LOD生成算法进行了优化在保证视觉连续性的前提下生成更激进但更有效的简化模型。其次它对实例化渲染Instancing的支持做到了极致。不仅支持常规的静态实例化还可能通过自定义的顶点格式将大量物体的变换信息、材质参数索引等压缩后打包在一个Draw Call内完成渲染极大降低了CPU提交开销和GPU状态切换。对于需要动态的细节它可能会采用屏幕空间的技术如视差遮蔽映射POM来模拟而非增加真实的几何复杂度。3. 渲染管线拆解GN如何实现“UE5级”效果宣称“UE5级画质”是个模糊的说法。UE5的标志是Nanite和Lumen。GN引擎显然无法在移动端完整复现它们。因此它的目标是在关键视觉特征上逼近特别是高精度的几何细节、丰富的材质表现和动态的光影氛围。下面我们拆解它如何实现这几个点。3.1 几何细节虚拟纹理与微多边形置换没有Nanite的硬件级网格细分GN引擎依赖一套组合拳来营造几何丰富度虚拟纹理Virtual Texture这是GN引擎可能采用的核心技术之一。它将超高清的材质纹理如4K、8K切割成许多小块Tile运行时只将视野内的部分加载到GPU内存。这不仅解决了移动端显存有限的问题更重要的是虚拟纹理可以与高度图Height Map结合实现视差遮蔽映射Parallax Occlusion Mapping, POM甚至虚拟位移贴图Virtual Displacement Mapping。在屏幕上这能产生极其逼真的表面凹凸感和几何细节观众几乎难以区分这是真实三角形还是贴图模拟的。虽然这需要额外的屏幕空间射线步进计算但在Fragment Shader中的开销是可控的远低于增加数百万个真实三角形。极致优化的LOD系统GN引擎的LOD切换可能不仅仅是基于距离还会结合屏幕空间覆盖率、运动速度等因素实现更平滑、更不易察觉的过渡。同时其网格简化算法会特别注意保留 silhouettes轮廓线上的特征因为人眼对物体轮廓的变化最为敏感。3.2 材质与光照烘焙与实时结合的混合方案纯粹的实时全局光照如Lumen在移动端是不现实的。GN引擎走的是“高质量烘焙 灵活实时补充”的混合路线。光照烘焙的深度利用它可能使用比传统引擎更先进的光照烘焙器支持方向性光照贴图Directional Lightmap不仅能存储光照强度还能存储主要光照方向用于在着色时计算更准确的漫反射和高光弥补了传统光照贴图无法表现高光的缺陷。烘焙的质量可以非常高因为这是离线过程。实时动态光照的“取巧”对于场景中的动态物体角色、车辆或可移动光源GN引擎可能采用一种Light Propagation VolumesLPV或Voxel Global Illumination的简化变种。这些技术将场景体素化在体素网格中传播间接光信息。GN引擎可能会大幅降低体素分辨率并限制传播距离和次数将其控制在一个可接受的性能预算内。虽然效果精度不如Lumen但在移动端小屏幕上配合高质量的烘焙基底足以营造出“有动态全局光照感觉”的氛围。屏幕空间反射SSR与后处理高质量的反射是提升画质的关键。GN引擎肯定会实现屏幕空间反射并可能结合平面反射Planar Reflection用于地面、水面等关键平面。在后处理方面它实现了色调映射Tone Mapping、泛光Bloom、自动曝光Auto Exposure和高质量的屏幕空间环境光遮蔽SSAO等标准特性。关键在于这些后处理效果的Shader都经过极度优化使用降分辨率计算、智能降噪等技术来保证效率。3.3 渲染管线的数据驱动组装这是GN引擎架构上最独特的一点。开发者可以通过一个JSON或自定义格式的配置文件来定义一条渲染管线{ RenderPipeline: MyMobileScene, Stages: [ { name: DepthPrePass, enable: true, clear: [depth], target: DepthBuffer }, { name: GBufferFill, enable: true, shader: Shaders/GBufferFill.json, targets: [AlbedoRoughness, NormalMetalness, Emissive] }, { name: SunLightShadow, enable: true, technique: CSM, // 级联阴影映射 cascades: 4 }, { name: DeferredLighting, enable: true, input: [AlbedoRoughness, NormalMetalness, DepthBuffer], lights: [directional, point, spot], gi: Lightmap // 指定GI来源为光照贴图而非实时计算 }, { name: SkyAndFog, enable: true, type: ProceduralSky }, { name: PostProcessing, enable: true, effects: [ToneMapping, Bloom, FXAA] } ] }在这个例子中管线明确指定了使用光照贴图作为GI源。如果换一个需要部分实时GI的场景可以将gi字段改为VoxelGI并相应地在运行时库中链接或加载对应的计算模块。这种设计使得最终打包的应用中只包含它真正用到的渲染功能代码和Shader变体这是实现15MB超小运行时的架构基础。4. 与UE5的对比优势、妥协与适用场景将GN引擎与UE5直接对比是不公平的因为它们的目标完全不同。但通过对比我们能更清楚GN引擎的定位。特性维度GN引擎 (15MB运行时)UE5 (完整引擎)分析与解读核心目标极致轻量、快速启动、移动端优先顶级画质、全平台覆盖、完整工具链GN是特种兵UE5是重装集团军。渲染管线高度可定制、数据驱动、可剪枝功能固定但极其强大Nanite, LumenGN的灵活性以牺牲“开箱即用”的便利性为代价需要更多技术配置。几何渲染虚拟纹理POM、极致LOD、超级实例化Nanite虚拟几何体革命性GN模拟细节UE5渲染真实海量三角面。GN方案在移动端性价比极高。全局光照高质量烘焙 简化实时GI如低分辨率体素Lumen全动态全局光照革命性GN的混合方案在静态场景中视觉质量可以很高但动态交互光照受限。材质系统基于物理渲染PBR重度依赖预计算LUT强大的材质编辑器支持复杂实时计算GN的材质表现力足够但创作复杂特效的灵活性和能力远不如UE5。工具链与生态极简可能只有核心运行时和有限工具极其庞大编辑器、蓝图、MetaHuman、商城等这是GN最大的短板也是其“轻”的必然结果。适合技术向团队。适用场景移动端中重度游戏、轻量级工业应用、AR/VR、小程序、云游戏客户端3A/主机/PC游戏、大型影视动画、高保真仿真GN填补了UE5因体积和开销过大而无法进入的细分市场。GN引擎的核心妥协动态性牺牲为了效率和体积极度依赖预计算烘焙光照、预烘焙动画等对完全动态、可破坏的场景支持较弱。工具链缺失没有UE5蓝图那样强大的可视化脚本没有完善的动画、粒子编辑器对美术和策划不够友好更偏向程序驱动。平台特性其优化高度针对移动端特别是ARM Mali/Adreno GPU在PC上可能无法完全发挥其体积优势甚至性能表现不一定比得过成熟引擎。GN引擎的真正优势场景对安装包体积和内存占用极度敏感的应用如手机预装应用、微信小游戏、快应用等。需要秒级启动的云游戏/云应用客户端运行时库小下载和加载速度快。固定功能的工业软件或仿真演示场景和渲染需求相对固定可以量身定制一条最优管线获得最佳性能画质比。作为大型引擎的补充或特定功能模块例如在某个大型应用中只有3D展示模块需要高质量渲染可以嵌入GN引擎的运行时而不是引入整个UE4/5。5. 开发者实操如何评估与尝试GN引擎如果你是一个被其“15MB实现UE5画质”口号吸引的开发者在决定是否深入之前需要理性评估。5.1 技术选型评估清单在考虑GN引擎前先问自己以下几个问题项目目标平台是什么如果主要是PC/主机UE5或Unity可能是更稳妥的选择。如果核心是移动端且对包体有硬性限制如小于50MBGN引擎值得深入研究。项目类型是什么是高度动态的开放世界还是场景相对固定、美术资源精致的关卡式游戏或应用后者更适合GN引擎的“烘焙为主”的架构。团队技术栈如何团队是否拥有较强的图形学程序员能够理解并定制渲染管线还是更依赖美术通过可视化工具进行创作GN引擎目前更适合技术导向型团队。对引擎生态的依赖度是否需要大量的第三方插件、资产商店资源、或特定的平台服务GN引擎的生态几乎从零开始你需要自己造很多轮子。5.2 入门尝试与性能分析如果评估后觉得可以尝试建议按以下步骤进行获取与编译从官方渠道获取源代码或SDK。由于其轻量编译过程通常比UE5简单快捷得多。重点关注其提供的示例项目。剖析示例管线不要急于创作而是深入研究其提供的示例渲染管线配置文件。理解每一个Stage的作用尝试禁用或修改某些阶段观察画面和性能变化。导入自有资产尝试导入一个你自己的、经过优化的模型和纹理。使用其工具链如果有或按照规范进行光照烘焙。观察最终渲染效果、Draw Call数量、GPU和内存占用。性能剖析Profiling使用引擎自带的或外部工具如ARM Mobile Studio、Snapdragon Profiler进行深度性能分析。重点关注GPU瓶颈是Fragment Shader填充率/纹理复杂还是Vertex Processing顶点处理负载高亦或是带宽受限CPU瓶颈Draw Call提交开销、场景图遍历、动画更新是否成为瓶颈内存纹理、网格、渲染目标的实际占用是否如宣传般精简5.3 可能遇到的“坑”与应对策略坑1工具链不完善工作流断裂。可能没有方便的材质编辑器需要手写Shader代码或编辑JSON动画系统可能简陋。应对建立团队内部的工作流规范。可以考虑使用第三方DCC工具如Blender、Substance进行内容创作然后通过自定义导出插件转换为GN引擎格式。将GN引擎视为一个“渲染后端”而非完整的创作套件。坑2特定效果实现复杂。比如需要实现一套复杂的粒子系统或毛发渲染引擎没有内置支持。应对利用其可编程渲染管线的特性自己实现一个计算着色器Compute Shader或定制一个渲染阶段来模拟。这要求团队有较高的图形学功底。坑3平台兼容性问题。虽然针对移动端优化但不同厂商GPUMali, Adreno, PowerVR驱动差异可能导致细微的渲染错误或性能差异。应对必须在目标市场的主流真机上进行充分测试。建立设备实验室覆盖低中高端机型。坑4学习资料和社区稀缺。不同于UE5/Unity有海量教程和问答。应对仔细研读官方文档和源码注释。鼓励团队成员深入源码理解其设计。尝试与核心开发团队建立联系如通过GitHub Issues。6. 未来展望轻量级渲染管线的趋势GN引擎的出现反映了一个趋势渲染技术正在从“追求绝对极限”向“追求最优效率”分化。随着移动设备、XR设备、嵌入式设备和云游戏的发展对高质量图形渲染的需求无处不在但承载它们的硬件平台却千差万别且往往资源受限。未来的渲染引擎可能会更普遍地采用“核心微内核可插拔模块”的架构。一个极小的、经过形式验证的渲染核心负责最基础的资源管理、命令提交和管线调度而各种高级渲染特性如不同的GI方案、后处理效果、抗锯齿算法则作为独立的、可选的模块存在。应用可以根据目标平台和需求像搭积木一样组装出自己的运行时。这对于开发者来说意味着更高的灵活性和优化上限但也带来了更高的技术门槛和集成复杂度。像GN引擎这样的先行者正是在探索这条道路上的可行性与边界。它或许不会取代UE5、Unity这样的巨头但它为特定领域提供了一个极具吸引力的、差异化的解决方案。对于图形程序员和技术美术来说理解其设计思想比单纯使用它更为重要因为这种“按需构建、极致优化”的思维正是未来高性能图形应用开发的必备素养。

相关新闻

LLM - 大模型上下文窗口管理的那些事:从长度焦虑到上下文工程

LLM - 大模型上下文窗口管理的那些事:从长度焦虑到上下文工程

文章目录从「能塞多少」到「该塞什么」一、上下文窗口到底是什么1.1 一个直观的定义1.2 为什么会有这个上限二、长上下文的幻觉:为什么「读得进」不等于「读得懂」2.1 「迷失在中间」(Lost in the Middle)2.2 上下文腐烂(Context …

2026/10/12 17:34:22 阅读更多 →
C语言学习之指针数组和数组指针

C语言学习之指针数组和数组指针

今天学习了指针数组和数组指针,相较于之前学习过指针来讲,今天学习的算是之前从未接触过的新知识,算是知识上的盲区,指针变来变了去,对概念的理解也逐渐的模糊了,所以接下来的时间要好好去琢磨这一块的知识…

2026/10/8 2:35:02 阅读更多 →
3步找回你丢失的QQ空间记忆:GetQzonehistory终极指南

3步找回你丢失的QQ空间记忆:GetQzonehistory终极指南

3步找回你丢失的QQ空间记忆:GetQzonehistory终极指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾经想要找回那些在QQ空间里丢失的青春记忆?那些记录…

2026/9/29 1:02:23 阅读更多 →

最新新闻

Maya 2019新手入门:零基础学会界面认识与基础操作

Maya 2019新手入门:零基础学会界面认识与基础操作

很多新手下载完Maya 2019,打开软件的那一刻就直接懵了:满屏的面板、密密麻麻的按钮、黑不溜秋的视口,根本不知道从哪里下手。我这套「咸鱼Maya笔记」就是写给这样的人看的——我自己当年也是一条咸鱼,靠着翻文档、看视频、踩坑踩出…

2026/10/13 9:51:00 阅读更多 →
MySQL存储过程与函数实战:核心区别、游标、异常处理与性能优化

MySQL存储过程与函数实战:核心区别、游标、异常处理与性能优化

1. 为什么存储过程和函数值得单独拎出来讲刚入行那会儿,我对存储过程和函数的理解就停留在“数据库里能写逻辑”这个层面。直到有一次做报表统计,一条复杂查询在应用层拼了七八个SQL,网络往返十几次,响应时间直接飙到三秒多。后来…

2026/10/13 9:51:00 阅读更多 →
Redisson集成实战:原始依赖与Spring Boot Starter对比解析

Redisson集成实战:原始依赖与Spring Boot Starter对比解析

我们从标题就能看出来,这不是一个单纯录个依赖坐标、能跑就完事的问题。项目里到底是用Redisson官方原生依赖手写配置,还是直接引入Spring Boot Starter让框架自动装配,这背后的流程差异、可维护性差异、甚至是坑的差异都很大。我最近刚好在几…

2026/10/13 9:51:00 阅读更多 →
python-字符串全解(六):正则表达式-分组

python-字符串全解(六):正则表达式-分组

这一章我们讲分组,分组在正则表达式中是一个很有用的工具。它主要有以下的作用:重复,缩小逻辑运算的范围,内容提取,反向引用,通过命名读取内容等。如果你之前没有学习过分组,这么一看这些作用说…

2026/10/13 9:51:00 阅读更多 →
深入理解 SAP ABAP CDS External Entities,从 ABAP SQL 到跨系统数据联邦

深入理解 SAP ABAP CDS External Entities,从 ABAP SQL 到跨系统数据联邦

在传统 ABAP 开发里,只要看到 SELECT,大多数人的第一反应都是从当前 AS ABAP 所连接的数据库读取数据。无论底层是 SAP HANA,还是早期系统里的其他数据库,ABAP SQL 面向的基本都是当前 ABAP System 自己的数据空间。 CDS External Entity 改变了这个边界。 它让一段看起来…

2026/10/13 9:51:00 阅读更多 →
Lost in Context: Addressing Context Anxiety in Large Language Models

Lost in Context: Addressing Context Anxiety in Large Language Models

《Lost in Context: Addressing Context Anxiety in Large Language Models》全文总结、创新点 + 指定章节中英对照翻译 一、论文整体核心内容总结 1. 核心概念:上下文焦虑(Context Anxiety) 本文首次系统性定义上下文焦虑:大模型明明具备完成任务的能力、且任务所需tok…

2026/10/13 9:49:58 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →