发布时间:2026/8/5 12:22:43
Unity自定义渲染通道:核心函数详解与实战应用 1. 项目概述为什么我们需要自定义渲染通道如果你在Unity里做过一段时间开发尤其是涉及一些稍微“花哨”点的视觉效果时大概率会遇到一个瓶颈Unity内置的渲染管线无论是Built-in还是URP/HDRP的默认流程好像有点不够用了。你想给角色加一个只在特定情况下显示的轮廓光或者想实现一个基于屏幕空间的后处理特效但发现它影响了UI又或者你只是想更精细地控制某些物体在什么阶段、以什么状态被绘制。这个时候自定义渲染通道Custom Render Pass就成了你必须掌握的技能。简单来说自定义渲染通道就是让你在Unity渲染流程的特定“缝隙”里插入一段自己写的渲染逻辑。它就像是在一条预设好的流水线上临时加装一个属于你自己的工位可以对这个工位上流经的“半成品”也就是渲染目标如颜色缓冲区、深度缓冲区进行任意加工。这个“入门报告”的目的不是让你成为图形学专家而是让你能快速上手理解并运用最核心的五个函数把它们当作趁手的工具去解决实际项目中那些内置管线搞不定的渲染需求。在可编程渲染管线SRP尤其是URP和HDRP中渲染通道是组织渲染逻辑的基本单元。一个通道Pass定义了“画什么”通过FilteringSettings、“怎么画”通过RenderStateBlock以及“用什么画”通过Shader。而自定义渲染通道就是继承自ScriptableRenderPass的类你需要重写其中的关键函数来定义这个“工位”的具体工作内容。接下来我们就深入这五个函数看看它们各自扮演什么角色以及如何协同工作。2. 核心函数深度解析与设计思路自定义一个渲染通道本质上是在编写一个ScriptableRenderPass的子类。这个类有几个生命周期函数但最核心、你必须理解和实现的是下面五个。它们构成了一个渲染通道从创建、配置到执行、清理的完整闭环。2.1 Configure为你的通道搭建舞台Configure函数是你的“舞台搭建”环节。这个方法在渲染通道被执行之前调用它的核心任务不是执行渲染命令而是声明你这个通道需要什么样的输入和输出资源以及配置一些全局的渲染状态。为什么需要这个步骤现代GPU渲染是高度并行和流水线化的。渲染管线需要提前知道每个通道会读写哪些纹理Render Texture以便高效地分配内存、管理生命周期比如某些临时纹理在用完后可以立即释放并避免资源冲突。Configure就是让你提前“报备”。在这个函数里你最常打交道的是ConfigureTarget和ConfigureClear。ConfigureTarget: 告诉管线我这个通道会把结果画到哪里去。你可以指定一个颜色渲染目标RenderTargetIdentifier和一个深度渲染目标。在URP中经常使用renderingData.cameraData.renderer.cameraColorTarget和cameraDepthTarget来指代相机当前的颜色和深度缓冲。ConfigureClear: 设置在执行这个通道前是否要清空渲染目标以及清空成什么颜色或深度/模板值。这对于需要全新画布的通道如绘制到一个临时RT至关重要。注意Configure阶段通常不进行实际的渲染指令提交如CommandBuffer.Blit,CommandBuffer.DrawRenderer。那些操作属于Execute函数的职责。这里主要是配置和声明。实操心得我经常在这里创建和申请临时渲染纹理RT。例如如果我的通道需要一个全屏的临时纹理来做模糊中间存储我会在Configure里用RenderTexture.GetTemporary申请并用ConfigureTarget将其设为渲染目标。同时我会用ConfigureClear将其清空为黑色或透明确保没有上一帧的残留数据干扰。2.2 Execute渲染逻辑的核心执行者Execute函数是整个自定义渲染通道的“心脏”是你编写具体渲染命令的地方。当渲染管线运行到你的通道时就会调用这个函数。这个函数接收两个关键参数CommandBuffer cmd: 这是你向GPU发送指令的“传令官”。所有渲染操作如设置渲染目标、绘制网格、复制纹理、分派计算着色器等都需要通过向这个CommandBuffer添加命令来完成。RenderingData renderingData: 这是一个包含了当前帧所有渲染相关信息的结构体比如相机数据位置、矩阵、渲染路径、光源信息、剔除结果等。它是你做出绘制决策的依据。在Execute里你通常会做什么设置渲染状态通过cmd.SetRenderTarget来指定当前绘制到哪个纹理可能已在Configure中声明过但这里可以再次设置或更改。执行绘制调用cmd.DrawRenderer: 绘制特定的渲染器Renderer。cmd.DrawMesh: 直接绘制一个网格。cmd.DrawProcedural: 绘制程序化几何常用于全屏效果。cmd.Blit: 最常用的全屏纹理拷贝和处理方法可以配合材质Material实现复杂的图像处理。设置着色器参数使用cmd.SetGlobalVector,cmd.SetGlobalTexture等函数将计算好的矩阵、颜色、纹理等数据传递给你在绘制时使用的Shader。设计思路Execute函数的逻辑应该清晰、高效。通常的模式是根据renderingData例如通过剔除结果获取可见的特定物体准备数据 - 设置好着色器所需的全部参数 - 提交一个或多个绘制命令。避免在这里进行复杂的每帧对象查找或资源加载这些工作最好在通道初始化或外部完成。2.3 FrameCleanup善后工作与资源回收FrameCleanup函数顾名思义是在每帧渲染结束后对于该通道而言进行清理工作。它的调用时机在Execute之后确保了这一帧你的通道所使用的某些临时资源可以被安全释放。为什么资源回收如此重要在渲染中尤其是后处理链中我们经常会创建一些中间过程的临时渲染纹理RT。这些RT只在当前帧的某个特定通道中有用帧结束后就必须释放否则会造成内存泄漏更专业地说是GPU内存泄漏长时间运行后可能导致崩溃或性能下降。在FrameCleanup中你最核心的任务就是释放那些在Configure或Execute中申请的临时渲染纹理。// 在类的成员变量中持有RT的引用 private RenderTargetHandle m_TemporaryColorTexture; // 在FrameCleanup中释放 public override void FrameCleanup(CommandBuffer cmd) { if (m_TemporaryColorTexture ! RenderTargetHandle.CameraTarget) { cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id); // 或者如果你使用的是 RenderTexture.GetTemporary // RenderTexture.ReleaseTemporary(m_TemporaryColorTexture); } }常见问题一个容易被忽略的坑是如果你在Execute中根据某些条件动态地申请了RT那么必须在FrameCleanup中同样根据条件去释放否则在条件不满足的帧之前申请的RT就不会被释放。确保“申请”和“释放”成对出现是写出健壮渲染代码的基本功。2.4 辅助函数OnCameraSetup 与 OnFinishCameraRendering除了上述三个核心函数还有两个非常有用的辅助函数它们提供了更精细的生命周期钩子。OnCameraSetup: 这个函数在为每个相机开始执行渲染通道之前调用。它比Configure更早并且是针对每个相机的。这意味着如果你在一个多相机场景中比如主相机反射探头场景相机这个函数会被调用多次。它的参数ref RenderingData renderingData包含了当前相机的具体数据。使用场景当你的一些初始化或配置工作依赖于具体的相机参数时就适合放在这里。例如你需要根据相机的分辨率来创建特定大小的RT或者根据相机类型是场景相机还是预览相机来决定是否启用某个特效。OnCameraSetup给了你一个基于相机进行差异化配置的机会。OnFinishCameraRendering: 与OnCameraSetup相对应这个函数在每个相机的所有渲染通道执行完毕之后调用。它标志着对这个相机的渲染工作已经完全结束。使用场景这是进行最终清理或执行一些后置操作的绝佳位置。虽然FrameCleanup用于释放通道自身的临时资源但OnFinishCameraRendering可以处理一些更全局的、与相机渲染生命周期相关的任务。例如如果你手动接管了相机的渲染目标比如渲染到RT然后自己显示可以在这里进行最终的呈现Present操作。在移动平台有时也在这里处理一些与平台相关的帧结束逻辑。选择指南每通道每帧的配置- 用Configure每相机每帧开始前的配置- 用OnCameraSetup每通道每帧的渲染命令- 用Execute每通道每帧的临时资源释放- 用FrameCleanup每相机每帧渲染完全结束后的处理- 用OnFinishCameraRendering理解它们调用的时机和频率能帮助你更精准地组织代码避免资源泄露或逻辑错误。3. 完整实现流程与核心环节拆解理论讲完了我们动手实现一个具体的例子一个简单的“高亮选中物体”的自定义渲染通道。这个效果常用于角色选中、可交互物体提示等。它的思路是在正常的场景渲染之后用一个单独的通道以特定的颜色如发光轮廓再次绘制被选中的物体。3.1 第一步创建渲染通道脚本与渲染器特性首先创建一个继承自ScriptableRenderPass的C#脚本比如叫HighlightRenderPass。using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class HighlightRenderPass : ScriptableRenderPass { // 存储需要高亮的渲染器列表 private ListRenderer m_HighlightedRenderers new ListRenderer(); // 高亮使用的材质 private Material m_HighlightMaterial; // 用于过滤渲染器的设置 private FilteringSettings m_FilteringSettings; // 绘制设置 private DrawingSettings m_DrawingSettings; // 构造函数初始化一些基本设置 public HighlightRenderPass(Material highlightMaterial) { this.renderPassEvent RenderPassEvent.AfterRenderingOpaques; // 设置执行时机在不透明物体渲染之后 m_HighlightMaterial highlightMaterial; // 配置过滤我们只渲染不透明几何体 m_FilteringSettings new FilteringSettings(RenderQueueRange.opaque); // 创建绘制设置指定使用高亮材质的Shader Pass m_DrawingSettings new DrawingSettings(new ShaderTagId(UniversalForward), new SortingSettings()); m_DrawingSettings.overrideMaterial m_HighlightMaterial; m_DrawingSettings.overrideMaterialPassIndex 0; // 使用材质的第一个Pass } // 提供一个方法让外部如MonoBehaviour可以设置需要高亮的物体 public void SetHighlightedObjects(ListRenderer renderers) { m_HighlightedRenderers renderers; } // 核心的Configure函数 public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { // 在这个例子中我们直接绘制到相机当前的颜色缓冲。 // 因为是在不透明物体之后绘制所以是叠加效果。 ConfigureTarget(renderingData.cameraData.renderer.cameraColorTarget); // 不清空保留之前不透明通道的内容 ConfigureClear(ClearFlag.None, Color.black); } // 核心的Execute函数 public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (m_HighlightMaterial null || m_HighlightRenderers.Count 0) return; CommandBuffer cmd CommandBufferPool.Get(Highlight Pass); // 这里可以设置一些全局Shader属性比如高亮颜色 cmd.SetGlobalColor(_HighlightColor, Color.yellow); // 手动为每个高亮的渲染器提交绘制命令 foreach (var renderer in m_HighlightedRenderers) { if (renderer ! null) { // 更规范的做法是使用context.DrawRenderers但这里为了清晰使用直接绘制Mesh // 实际项目中需要获取renderer的sharedMesh和materialPropertyBlock MeshFilter mf renderer.GetComponentMeshFilter(); if (mf ! null mf.sharedMesh ! null) { cmd.DrawMesh(mf.sharedMesh, renderer.transform.localToWorldMatrix, m_HighlightMaterial, 0, 0); } } } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } // FrameCleanup public override void FrameCleanup(CommandBuffer cmd) { // 本例中没有申请额外的临时RT所以不需要释放。 // 但这是一个好习惯保持函数存在以备将来扩展。 base.FrameCleanup(cmd); } }接下来创建一个ScriptableRendererFeature。这是将你的RenderPass插入到URP渲染器中的“插件”。using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class HighlightRendererFeature : ScriptableRendererFeature { [System.Serializable] public class Settings { public Material highlightMaterial; // 在Inspector中指定高亮材质 } public Settings settings new Settings(); private HighlightRenderPass m_HighlightPass; // 初始化创建RenderPass实例 public override void Create() { if (settings.highlightMaterial null) { Debug.LogWarning(Highlight material is not assigned.); return; } m_HighlightPass new HighlightRenderPass(settings.highlightMaterial); m_HighlightPass.renderPassEvent RenderPassEvent.AfterRenderingOpaques; // 再次确认时机 } // 每帧调用将Pass添加到渲染器中 public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { if (renderingData.cameraData.cameraType CameraType.Game) { // 只对游戏主相机添加此Pass renderer.EnqueuePass(m_HighlightPass); } } }将这个HighlightRendererFeature拖到你的URP Asset的Renderer Features列表中并分配一个高亮材质。3.2 第二步编写高亮Shader高亮材质需要一个简单的Shader。这里实现一个最简单的轮廓光效果法线外扩。Shader Custom/Highlight { Properties { _HighlightColor (Highlight Color, Color) (1,1,0,1) _OutlineWidth (Outline Width, Range(0, 0.1)) 0.03 } SubShader { Tags { RenderTypeOpaque QueueGeometry1 } // Queue在不透明之后 // 第一个Pass正常渲染物体背面并沿法线外扩 Pass { Name OUTLINE Cull Front // 剔除正面只渲染背面形成轮廓 CGPROGRAM #pragma vertex vert #pragma fragment frag #include UnityCG.cginc struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; }; float _OutlineWidth; fixed4 _HighlightColor; v2f vert (appdata v) { v2f o; // 将顶点沿法线方向外扩 float4 pos mul(unity_ObjectToWorld, v.vertex); float3 worldNormal normalize(mul(v.normal, (float3x3)unity_WorldToObject)); pos.xyz worldNormal * _OutlineWidth; o.pos mul(UNITY_MATRIX_VP, pos); return o; } fixed4 frag (v2f i) : SV_Target { return _HighlightColor; } ENDCG } } }这个Shader有两个关键点1.Cull Front只渲染背面这样外扩的背面就会在物体原有轮廓外围形成一层“壳”。2. 在顶点着色器中将顶点沿世界空间法线方向外扩一定距离_OutlineWidth。3.3 第三步在游戏逻辑中驱动最后你需要一个MonoBehaviour脚本来管理哪些物体被高亮并通知HighlightRenderPass。using System.Collections.Generic; using UnityEngine; public class HighlightManager : MonoBehaviour { public HighlightRendererFeature highlightFeature; // 拖入你的RendererFeature实例 public ListGameObject objectsToHighlight; private ListRenderer m_RendererList new ListRenderer(); void Start() { if (highlightFeature ! null) { // 获取RendererFeature中的Pass引用这里需要根据你的具体实现来获取可能需要修改RendererFeature暴露接口 // 假设我们修改了RendererFeature提供了一个public方法来设置高亮物体 // highlightFeature.SetHighlightedRenderers(m_RendererList); } UpdateRendererList(); } void Update() { // 每帧更新需要高亮的渲染器列表 UpdateRendererList(); // 这里应该将m_RendererList传递给RenderPass。一种常见做法是通过一个静态类或Singleton来传递数据。 // HighlightData.Instance.highlightedRenderers m_RendererList; // 然后在RenderPass的Execute中从HighlightData.Instance读取。 } void UpdateRendererList() { m_RendererList.Clear(); foreach (var obj in objectsToHighlight) { if (obj ! null) { var renderers obj.GetComponentsInChildrenRenderer(); m_RendererList.AddRange(renderers); } } } }这里的关键是数据传递。RenderPass在渲染线程执行而MonoBehaviour在游戏逻辑线程。你不能直接传递引用。安全的做法是使用一个线程安全的数据结构如ConcurrentBag或者每帧将数据拷贝到一个共享的、结构简单的容器中如ListMatrix4x4或Listint (instance ID)。在Execute中再根据这些ID去查找或直接使用矩阵进行绘制。4. 常见问题排查与性能优化技巧即使理解了原理和步骤在实际集成自定义渲染通道时你依然会遇到各种“坑”。下面是我在项目中总结的一些典型问题及其解决方法。4.1 问题一通道没有任何效果物体没有被绘制这是最常见的问题。排查步骤如下检查RenderPassEvent时机这是最可能的原因。你的通道可能被插入到了一个不合适的时机。例如如果你在AfterRenderingSkybox之前绘制但你的物体是不透明的它可能会被后续的不透明通道覆盖。或者你在AfterRenderingPostProcessing之后绘制但后处理效果可能已经改变了颜色缓冲区。调试方法尝试将renderPassEvent设置为RenderPassEvent.BeforeRenderingPostProcessing或AfterRenderingOpaques这些比较明确的位置看是否出现。检查渲染目标Render Target在Configure和Execute中你是否正确设置了渲染目标如果你要绘制到相机纹理确保使用了正确的RenderTargetIdentifier。在URP中通常通过renderingData.cameraData.renderer.cameraColorTarget获取。调试方法在Execute中用cmd.SetGlobalTexture将一个纯色纹理如红色绘制到屏幕如果屏幕变红说明渲染目标设置正确问题出在绘制逻辑本身。检查绘制命令cmd.DrawMesh或context.DrawRenderers的参数是否正确网格、矩阵、材质是否有效材质的Shader是否兼容当前渲染管线必须是URP Shader调试方法使用一个最简单的、肯定能工作的材质比如Unity自带的Default-Material进行测试。检查Renderer Feature是否启用确保你的ScriptableRendererFeature已添加到URP Asset的Renderer List中并且没有禁用。在Game视图的Stats面板可以查看当前激活的渲染通道数量。检查相机遮罩Camera Mask如果你的ScriptableRendererFeature在AddRenderPasses中根据相机类型进行了过滤确保当前渲染的相机是你期望的类型如CameraType.Game。4.2 问题二效果闪烁、错位或深度测试异常这类问题通常与深度Depth和模板Stencil缓冲区有关。深度测试问题自定义通道中绘制的物体与场景中其他物体的前后关系错误。解决方案在创建DrawingSettings或RenderStateBlock时正确配置深度状态。例如如果你想在高亮通道中让物体始终画在最前面可以设置DepthState为DepthState.Default即开启深度测试和写入但需要确保你的高亮几何体如外扩的轮廓的深度值比原物体更靠近相机。对于轮廓效果通常会在Shader的轮廓Pass中关闭深度写入ZWrite Off但使用一个偏移Offset来确保轮廓能画出来。模板测试问题如果你使用了模板缓冲区来标记特定区域在自定义通道中需要确保模板状态的设置与你的逻辑匹配。解决方案仔细检查RenderStateBlock中的stencilState确保参考值、比较函数、操作等设置正确。一个常见的技巧是先在一个通道中写入模板值然后在自定义通道中根据模板值来绘制。矩阵问题物体位置错位可能是变换矩阵传递错误。在cmd.DrawMesh时第二个参数是物体的localToWorldMatrix。确保你传递的是渲染器Renderer的变换矩阵而不是其他无关的矩阵。对于蒙皮网格渲染器SkinnedMeshRenderer需要使用renderer.localToWorldMatrix并且绘制命令有所不同。4.3 性能优化核心技巧自定义渲染通道很强大但滥用会严重影响性能。以下是几个关键的优化点最小化临时RT的创建与释放频繁申请和释放RT是性能杀手。如果可能复用RT。例如如果你的效果需要多个中间纹理可以考虑在通道初始化时Create创建固定大小的RT池而不是每帧GetTemporary。确保在FrameCleanup中准确释放避免泄漏。精确控制绘制范围不要绘制看不到的东西。在Execute中利用renderingData.cullingResults进行视锥体剔除。通过CullingResults.visibleRenderers可以获取在当前相机视锥体内且符合过滤条件的渲染器列表只绘制这些可见的渲染器。使用更高效的绘制方法对于大量相同的物体考虑使用GPU Instancing。在自定义通道中支持Instancing需要一些额外设置确保材质启用了GPU Instancing并且在DrawingSettings中设置enableInstancing true。然后可以使用cmd.DrawMeshInstanced或cmd.DrawRenderer并配合合适的渲染数据块。警惕全屏Blitcmd.Blit是一个全屏绘制调用代价不菲。避免在同一个通道或连续通道中多次进行不必要的全屏Blit。如果后处理链中有多个效果尽量将它们合并到一个材质中通过多次采样和计算在单个Pass内完成这被称为“后处理堆叠”Post-processing Stack。合理选择RenderPassEvent将你的通道放在最合适的时机。如果它不需要后处理效果就放在BeforeRenderingPostProcessing之前。如果它需要深度纹理但只在透明物体之后有用可以考虑放在AfterRenderingTransparents。正确的时机可以避免不必要的纹理拷贝和带宽占用。4.4 进阶调试手段当问题比较复杂时你需要更强大的工具Frame DebuggerUnity内置的帧调试器是你的第一选择。它可以清晰地展示每一帧的渲染命令序列精确看到你的自定义通道在什么位置被插入执行了哪些绘制调用渲染目标是什么。这是诊断渲染顺序和状态问题的终极利器。RenderDoc或Xcode GPU Debugger / Android GPU Inspector这些外部工具可以捕获一帧完整的GPU调用和状态查看每一个纹理、缓冲区的具体内容。当你的Shader计算出现问题时可以用它们来检查输入输出是否正确。自定义调试视图在开发阶段可以在Execute中临时添加一些调试绘制。例如将中间过程的纹理通过cmd.Blit复制到一个全局纹理属性然后在屏幕角落用一个简单的四边形和材质显示出来直观地观察每一步的结果。自定义渲染通道是深入Unity渲染引擎的必经之路。它开始时可能令人望而生畏但一旦你掌握了这五个关键函数的职责和协作方式就相当于获得了一把打开高级图形效果大门的钥匙。从简单的物体高亮、全屏模糊到复杂的自定义光照模型、多相机合成其可能性只受限于你的想象力和对图形管线的理解深度。记住多动手实践多用Frame Debugger观察从简单的例子开始逐步构建复杂的效果这才是最有效的学习路径。

相关新闻

2026/8/5 12:22:43

抖音批量下载终极指南:从零开始打造你的个人媒体库

抖音批量下载终极指南:从零开始打造你的个人媒体库 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support.…

2026/8/5 15:22:55

New API 一站式部署指南:从源码到生产环境的完整实践

New API 一站式部署指南:从源码到生产环境的完整实践 【免费下载链接】new-api A unified AI model hub for aggregation & distribution. It supports cross-converting various LLMs into OpenAI-compatible, Claude-compatible, or Gemini-compatible format…

2026/8/5 15:22:55

终极PS4手柄Windows兼容方案:DS4Windows完全指南

终极PS4手柄Windows兼容方案:DS4Windows完全指南 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 想让你的PlayStation 4手柄在Windows电脑上完美工作吗?DS4Windows…

2026/8/5 15:22:55

终极指南:使用palera1n实现iOS设备一键越狱

终极指南:使用palera1n实现iOS设备一键越狱 【免费下载链接】palera1n Jailbreak for A8 through A11, T2 devices, on iOS/iPadOS/tvOS 15.0, bridgeOS 5.0 and higher. 项目地址: https://gitcode.com/GitHub_Trending/pa/palera1n 还在为iOS系统的功能限制…

2026/8/5 15:22:55

几何构造分析基本原理

几何构造分析基本原理 01 几何“变不变” 相信在很小的时候,家里人或是老师都会告诉我们为什么塔吊之类的设施都会焊接成三角形的形式,因为三角形最稳定嘛。 其实,这其中就包含了结构分析原理中的一个重要概念:几何可变体系与几何不变体系。毫无疑问的是,我们不能把结构…

2026/8/5 3:13:11

如何用免费工具突破游戏窗口限制:SRWE完整使用指南

如何用免费工具突破游戏窗口限制:SRWE完整使用指南 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 你是否遇到过这样的困扰?想为心爱的游戏截图,却发现游戏不支持自定义分辨率…

2026/8/5 0:01:34

三升四,比成绩下滑更可怕的,是孩子开始「认命」

分水岭上,最难的不是翻过去,是孩子不想翻了。八月初了。这两个字,对三升四的家长来说,比任何闹钟都让人清醒。最近的家长群里,气氛明显不一样了。一升二的在关心兴趣班,二升三的在讨论要不要提前学英语。而…

2026/8/5 0:01:34

Java缓存框架:JetCache

TOC 一、简介 JetCache 是一个 Java 缓存抽象框架,为不同的缓存解决方案提供了统一的使用方式。 它提供的注解比 Spring Cache 更加强大。 JetCache 的注解支持原生 TTL、两级缓存以及在分布式环境中的自动刷新功能,同时你也可以通过代码直接操作 Cach…

2026/8/5 0:01:34

AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

需求:通孔焊盘 十字花;过孔 Via 实心直连;贴片焊盘按需设置 AD 测试版本AD24 很多工程师踩坑:全部统一十字,导致接地过孔阻抗高、大电流发热! 一、快捷键打开规则 PCB 界面按下:D R 展开…

2026/8/3 22:40:58

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/3 13:26:41

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/3 16:43:13

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…