尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Unity URP热扭曲Shader实战:让半透明物体也“动”起来的屏幕扰动方案

Unity URP热扭曲Shader实战:让半透明物体也“动”起来的屏幕扰动方案
📅 发布时间:2026/7/14 8:23:24

1. 项目概述与核心价值

最近在做一个科幻题材的移动端项目,里面有不少能量核心、推进器喷口这类需要表现高温扭曲空气视觉效果的元素。一开始,我直接用了网上一个现成的热扭曲Shader,效果在编辑器里看着还行,但一打包到真机上,特别是针对那些带有半透明通道的粒子特效叠加时,要么效果全无,要么渲染顺序错乱,画面直接“糊”成一团。相信不少用Unity URP(Universal Render Pipeline,通用渲染管线)做特效或者场景的同学都遇到过类似的问题:一个看似简单的热扭曲效果,想要让它和UI、半透明物体、后处理效果和谐共处,特别是让扭曲效果也能正确作用于半透明物体之上,里面的坑可真不少。

这篇文章,我就把自己从踩坑到填坑的完整过程梳理出来,核心目标就一个:在Unity URP下,实现一个性能可控、兼容性良好,并且能让“热空气”扭曲效果正确影响其后方所有物体(包括不透明和半透明物体)的实战方案。我会附上完整的、可直接使用的Shader代码,并重点解释每一步背后的“为什么”,而不仅仅是“怎么做”。无论你是Shader新手,还是有一定基础但被URP渲染顺序困扰的开发者,这篇内容都能帮你彻底理清思路。

2. 热扭曲效果原理与URP下的设计思路

在开始写代码之前,我们必须先搞清楚两件事:热扭曲效果的本质是什么?以及URP的渲染架构对我们实现它提出了哪些挑战?

2.1 效果本质:基于屏幕后处理的UV扰动

所谓“热扭曲”,视觉上模拟的是高温空气密度不均导致光线折射率变化,从而让背后的物体看起来在“晃动”或“扭曲”。在实时渲染中,我们几乎不会去真正模拟物理光线追踪,而是采用一种取巧但高效的方案:屏幕后处理(Image Effect)或抓屏扰动。

其核心流程可以概括为:

  1. 抓取当前帧的屏幕图像:在几乎所有物体渲染完毕后,将整个屏幕的颜色缓存(Frame Buffer)保存为一张纹理(我们常称为_CameraOpaqueTexture或_CameraColorTexture)。
  2. 对抓取的屏幕纹理进行UV坐标扰动:在需要表现热扭曲的区域,根据一个动态的噪声图(Noise)或波纹图,去扭曲、偏移采样屏幕纹理时使用的UV坐标。
  3. 将扰动后的结果混合回屏幕:用扰动后的颜色,替换或混合原始区域的颜色,从而产生视觉上的扭曲感。

关键在于“抓屏”的时机。在URP中,渲染是分批次、分Pass进行的,有严格的顺序。

2.2 URP渲染顺序与核心挑战

URP的默认渲染顺序大致如下(简化版):

  1. 不透明物体渲染(Opaque Pass):所有不透明物体(RenderQueue<= 2500)在这一步绘制。完成后,URP会生成一张_CameraOpaqueTexture,这张纹理包含了当前所有不透明物体的最终颜色。
  2. 天空盒渲染(Skybox)。
  3. 半透明物体渲染(Transparent Pass):所有半透明物体(RenderQueue> 2500)在这一步绘制,并按照从后到前的顺序进行Alpha混合。

我们的核心挑战就来自于此:如果我们在半透明物体(比如一个火焰粒子)上使用传统的、基于_CameraOpaqueTexture抓屏的热扭曲Shader,那么它只能扭曲到步骤1中渲染好的不透明物体和天空盒。而对于在它之后渲染的其他半透明物体(比如另一层更靠前的烟雾),则完全无法产生扭曲效果。因为抓屏发生在半透明渲染之前,后续的半透明信息根本没被抓取到。

这就是标题中“让半透明物体也‘动’起来”要解决的核心问题。我们需要的,是一个能作用于所有已渲染内容(包括不透明和半透明)的扭曲效果。

2.3 方案选型:渲染到中间RT与CommandBuffer

经过调研和测试,在URP中实现全屏幕内容扭曲,主要有两种主流思路:

  1. 方案A:使用Blit在渲染事件中抓全屏

    • 思路:订阅URP的渲染事件(如RenderPipelineManager.beginCameraRendering),在相机开始渲染时,通过CommandBuffer.Blit将当前_CameraColorTexture(包含到此为止的所有渲染结果)复制到一个自定义的RenderTexture(RT)中。然后在Shader中采样这个自定义RT。
    • 优点:灵活性高,可以在任何时机抓屏。
    • 缺点:需要管理RT的生命周期,容易引入性能开销和内存泄漏风险;与URP的Scriptable Render Pass集成不够优雅,代码较为分散。
  2. 方案B:利用URP内置的_CameraColorTexture与渲染队列技巧

    • 思路:URP在渲染完不透明物体后,_CameraOpaqueTexture可用;而在渲染完所有物体(包括后处理)后,_CameraColorTexture才是最终屏幕图像。但我们需要在半透明物体渲染期间获取它之前的所有内容。一个更巧妙的做法是:将热扭曲物体的渲染队列(RenderQueue)设置为一个非常大的值(例如4000),并确保它在所有其他半透明物体之后渲染。同时,配合URP的Camera设置,确保_CameraColorTexture在渲染这个物体时是可用的。
    • 优点:无需复杂的外部脚本管理RT,完全在Shader和材质球属性内完成配置,更符合URP的设计哲学,简洁高效。
    • 缺点:对渲染顺序有严格依赖,需要美术同学在制作特效时注意材质队列设置。

对于大多数项目,特别是需要大量热扭曲特效且由特效美术负责制作的场景,方案B的简洁性和易用性优势更明显。它避免了程序员和美术之间繁琐的协调,美术只需调一个材质参数即可。因此,本文将重点深入讲解方案B的实现。

注意:方案B要求将热扭曲物体放在所有常规渲染的最后。这意味着它本身必须是完全透明(或接近透明)的,且不会遮挡任何你需要看到的内容。通常,我们用一个简单的面片(Quad)或网格,赋予它一个半透明的扰动纹理来实现。

3. 完整Shader代码实现与逐行解析

接下来,我们动手编写Shader。创建一个新的Shader文件,命名为URPHeatDistortion.shader。

3.1 Shader属性与基础结构

Shader "Unlit/URPHeatDistortion" { Properties { // 控制扭曲区域的透明遮罩纹理,白色区域产生扭曲,黑色区域完全透明 [Header(Distortion Mask)] _DistortionMask ("Distortion Mask (R)", 2D) = "white" {} _MaskPower ("Mask Power", Range(0, 5)) = 1 _MaskScrollSpeed ("Mask Scroll Speed", Vector) = (0, 0, 0, 0) // 控制UV扰动的噪声纹理 [Header(Noise Texture)] _NoiseTex ("Noise Texture (RG)", 2D) = "gray" {} _NoiseScale ("Noise Scale", Range(0, 2)) = 0.1 _NoiseSpeed ("Noise Speed", Vector) = (0.1, 0.1, 0, 0) _DistortionStrength ("Distortion Strength", Range(0, 0.1)) = 0.01 // 颜色与透明度调节(可选,用于给热扭曲区域着色) [Header(Appearance)] _TintColor ("Tint Color", Color) = (1,1,1,1) _Intensity ("Intensity", Range(0, 5)) = 1 } SubShader { Tags { // 关键中的关键:渲染队列设为Transparent+1,确保在所有标准半透明物体之后渲染 "Queue" = "Transparent+1" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True" } // 关闭深度写入,避免遮挡后方物体 ZWrite Off // 使用Alpha混合模式,让扭曲效果与屏幕图像融合 Blend SrcAlpha OneMinusSrcAlpha // 可选:关闭剔除,让面片双面可见 Cull Off Pass { Name "HeatDistortion" HLSLPROGRAM #pragma vertex vert #pragma fragment frag // 包含URP的核心库 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // 包含声明_CameraColorTexture所需的库 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl" // 定义与Properties块对应的变量 TEXTURE2D(_DistortionMask); SAMPLER(sampler_DistortionMask); TEXTURE2D(_NoiseTex); SAMPLER(sampler_NoiseTex); CBUFFER_START(UnityPerMaterial) float4 _DistortionMask_ST; float _MaskPower; float4 _MaskScrollSpeed; float _NoiseScale; float4 _NoiseSpeed; float _DistortionStrength; float4 _TintColor; float _Intensity; CBUFFER_END

代码解析与关键点:

  • "Queue" = "Transparent+1":这是实现方案B的灵魂。Transparent的默认队列值是3000。设置为Transparent+1(即3001),可以确保这个Shader在所有渲染队列为3000的普通半透明物体(如粒子、UI)之后才被渲染。这样,当它执行时,_CameraColorTexture中已经包含了之前所有物体的信息。
  • #include ...DeclareOpaqueTexture.hlsl:这个头文件不仅声明了_CameraOpaqueTexture,更重要的是,在URP 12+版本中,它提供了SampleSceneColor函数,这是一个更推荐使用的、用于安全采样屏幕颜色的方法,它会自动处理不同渲染路径下的纹理来源。
  • ZWrite Off:热扭曲本身是一个视觉特效,不应该影响深度缓冲,否则可能会错误地遮挡住本应显示的内容。

3.2 顶点着色器

struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionHCS : SV_POSITION; float2 uvMask : TEXCOORD0; float2 uvNoise : TEXCOORD1; // 用于屏幕空间UV计算 float4 screenPos : TEXCOORD2; }; Varyings vert(Attributes IN) { Varyings OUT; // 将顶点位置从物体空间转换到齐次裁剪空间 VertexPositionInputs vertexInput = GetVertexPositionInputs(IN.positionOS.xyz); OUT.positionHCS = vertexInput.positionCS; // 计算遮罩纹理的UV,支持平铺和偏移,并加上滚动动画 OUT.uvMask = TRANSFORM_TEX(IN.uv, _DistortionMask) + _MaskScrollSpeed.xy * _Time.y; // 计算噪声纹理的UV,通常需要不同的平铺以产生丰富变化,同样加上动画 OUT.uvNoise = IN.uv * _NoiseScale + _NoiseSpeed.xy * _Time.y; // 计算屏幕空间位置,用于后续片段着色器中采样屏幕纹理 OUT.screenPos = ComputeScreenPos(OUT.positionHCS); return OUT; }

代码解析与关键点:

  • GetVertexPositionInputs:这是URP Shader Library提供的辅助函数,它统一处理了不同空间下的坐标转换,比直接使用TransformObjectToHClip更规范。
  • _Time.y:Unity内置的时间变量(以秒为单位),乘以速度向量,实现UV的持续滚动,这是产生动态扭曲效果的基础。
  • ComputeScreenPos:这个函数将裁剪空间下的位置(positionHCS)转换为用于透视校正插值的屏幕空间坐标。得到的screenPos在片段着色器中需要经过一步透视除法(screenPos.xy / screenPos.w)才能得到真正的屏幕UV。

3.3 片段着色器——扭曲逻辑的核心

half4 frag(Varyings IN) : SV_Target { // 1. 采样扭曲遮罩纹理 half mask = SAMPLE_TEXTURE2D(_DistortionMask, sampler_DistortionMask, IN.uvMask).r; // 对遮罩值进行幂运算,方便控制扭曲区域的衰减和形状 mask = pow(mask, _MaskPower); // 如果遮罩完全透明,则提前终止渲染,节省性能 #ifdef _ALPHATEST_ON clip(mask - 0.001); #endif // 2. 采样噪声纹理,获取RG两个通道的扰动值 half2 noise = SAMPLE_TEXTURE2D(_NoiseTex, sampler_NoiseTex, IN.uvNoise).rg; // 将噪声值从[0,1]映射到[-1,1],产生双向扰动 noise = noise * 2.0 - 1.0; // 3. 计算屏幕UV float2 screenUV = IN.screenPos.xy / IN.screenPos.w; // 4. 应用扰动到屏幕UV // 用噪声值乘以强度,再乘以遮罩,这样只有遮罩白色区域才有扭曲,且边缘平滑过渡 float2 distortedUV = screenUV + noise * _DistortionStrength * mask; // 5. 采样屏幕颜色(核心步骤) // 使用SampleSceneColor函数,它内部会判断并使用_CameraColorTexture half3 sceneColor = SampleSceneColor(distortedUV); // 6. 最终颜色输出 half4 finalColor; finalColor.rgb = sceneColor * _TintColor.rgb * _Intensity; // Alpha通道由遮罩值控制,_TintColor.a可用于整体透明度调节 finalColor.a = mask * _TintColor.a; return finalColor; } ENDHLSL } } // 后备SubShader,用于在不支持URP的旧管线显示一个简单颜色 SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; } half4 frag(v2f i) : SV_Target { return half4(1,0,0,0.5); } // 显示为红色半透明作为提示 ENDCG } } }

代码解析与关键点:

  • SampleSceneColor(distortedUV):这是最关键的一行代码。它取代了旧管线中直接采样_GrabTexture或URP中采样_CameraOpaqueTexture的做法。SampleSceneColor是URP提供的一个抽象接口,它会根据当前的渲染状态,自动返回当前已渲染到颜色缓冲中的内容。这正是我们实现“扭曲一切”的魔法所在。
  • 噪声映射noise * 2.0 - 1.0:默认采样的纹理值范围是[0,1]。通过这个简单的运算,将其映射到[-1,1],这样噪声就能同时产生正向和负向的偏移,扭曲效果更自然,避免单向拉伸。
  • 遮罩控制mask:遮罩纹理(通常是一张从中心向边缘衰减的渐变图)不仅控制扭曲的强度(noise * ... * mask),还直接控制最终输出的Alpha值(finalColor.a = mask * _TintColor.a)。这确保了扭曲效果在边缘平滑消失,与背景完美融合,不会出现生硬的矩形边界。
  • 性能优化clip:我们添加了一个可选的_ALPHATEST_ON指令。在片段着色器早期,如果发现遮罩值几乎为0(即像素完全透明),就使用clip函数将其丢弃。这可以避免对这些完全透明的像素执行后续昂贵的噪声计算和屏幕纹理采样,对于覆盖屏幕大面积但实际扭曲区域很小的特效(如枪口热浪),能有效提升性能。你可以在材质面板上启用“Alpha Clipping”来使用此功能。

4. 材质配置与场景搭建实战

写好Shader只是第一步,正确的材质和场景配置才能让它真正工作。

4.1 创建与配置材质球

  1. 在Project窗口右键,Create -> Material,命名为Mat_HeatDistortion。
  2. 将新创建的材质球的Shader选择为我们刚写的Unlit/URPHeatDistortion。
  3. 关键参数设置:
    • Distortion Mask:贴上一张黑白渐变纹理。推荐使用中心白、边缘黑、过渡柔和的圆形或椭圆形贴图。Mask Power值可以调节衰减的锐利程度,值越大,白色区域收缩得越厉害。
    • Noise Texture:贴上一张无缝的、对比度适中的噪声图。Noise Scale控制噪声的频率,值越小,扭曲的“波纹”越大。Distortion Strength是控制扭曲视觉强度的主要参数,从0.01开始微调。
    • Mask Scroll Speed/Noise Speed:给X和Y分量赋予不同的较小值(如(0.05, 0.03)),可以让扭曲产生流动感,而不是静止的波纹。
    • Tint Color:可以给热扭曲区域赋予一点暖色调(如淡淡的橙色),增强“热”的感觉。Intensity可以加强或减弱这个色调。

4.2 在场景中布置热扭曲物体

  1. 创建一个简单的Quad(GameObject -> 3D Object -> Quad)。它将成为我们热扭曲效果的载体。
  2. 将Mat_HeatDistortion材质拖拽到Quad上。
  3. 调整Transform:
    • 将Quad放置在需要表现热源的位置(如火箭发动机喷口)。
    • 调整Rotation使其面向摄像机(或者使用Billboard Shader让其始终面向相机,这里为简化使用Quad)。
    • 调整Scale,使其大小符合热浪影响的范围。
  4. 配置相机(至关重要):
    • 选中你的主摄像机。
    • 在Inspector面板,确保其Renderer使用的是URP的渲染器资产(如UniversalRenderer)。
    • 勾选Opaque Texture选项。这是_CameraOpaqueTexture和SampleSceneColor能够正常工作的前提。在URP Asset的Camera设置中,通常默认是开启的,但务必检查。

4.3 与粒子系统的配合

这是最常见的应用场景。你需要让热扭曲效果与火焰、烟雾粒子共存。

  1. 渲染顺序管理:确保你的火焰、烟雾等粒子特效所使用的Shader,其材质球的Render Queue设置为Transparent(3000)或更低的值。而我们热扭曲Quad的材质是Transparent+1(3001),这保证了粒子先渲染,热扭曲后渲染并能够抓取到包含粒子的屏幕图像进行扭曲。
  2. 层级与混合:热扭曲材质使用了Blend SrcAlpha OneMinusSrcAlpha,即标准的Alpha混合。这意味着它需要基于自身的Alpha值与背景混合。确保你的扭曲遮罩纹理(Distortion Mask)的Alpha通道或R通道(我们用的R)在边缘是平滑渐变的,这样混合边界才会自然。
  3. 性能考量:如果场景中有多个热扭曲源,尽量合并它们。可以使用一个稍大的Quad配合一张包含多个扭曲区域的遮罩图,或者使用GPU Instancing(需要修改Shader支持)来批量渲染多个简单的热扭曲面片。

实操心得:在移动端项目中使用时,Distortion Strength(扭曲强度)和Noise Scale(噪声尺度)不宜设置得过大。过强的扭曲和过细的噪声波纹在低分辨率屏幕下容易产生难看的锯齿和闪烁。通常强度在0.005-0.02,噪声尺度在0.05-0.2之间进行寻找最佳平衡点。另外,可以考虑对噪声图进行低通滤波(模糊一下),让扭曲变化更柔和,视觉上也更符合空气扰动的物理直觉。

5. 常见问题排查与深度优化技巧

即使按照上述步骤操作,你可能还是会遇到一些奇怪的问题。下面是我在项目中遇到过的典型问题及其解决方案。

5.1 问题速查表

问题现象可能原因解决方案
屏幕一片漆黑或扭曲区域为纯色1. 相机未开启Opaque Texture。
2. Shader中SampleSceneColor采样UV错误。
3. 热扭曲物体被其他不透明物体遮挡。
1. 检查相机设置,确保Opaque Texture已勾选。
2. 在片段着色器中,输出screenUV或distortedUV作为颜色查看其范围是否在[0,1]内。
3. 检查热扭曲Quad的渲染队列是否足够高,并确保其ZWrite为Off,ZTest可设为LEqual(默认)。
扭曲效果只对场景背景有效,对UI或部分粒子无效渲染顺序错误。UI和某些粒子的渲染队列可能高于3001。进一步提高热扭曲材质的Render Queue,例如设为Transparent+100(3100)。或者调整UI/粒子的渲染队列低于热扭曲物体。原则:需要被扭曲的物体必须先于热扭曲效果渲染。
扭曲边缘有硬边或矩形框遮罩纹理(Distortion Mask)的边缘过渡不柔和,或者Alpha通道为硬切。使用Photoshop等工具,将遮罩纹理的边缘进行充分的羽化或模糊处理,确保从白色到黑色的过渡是平滑的渐变。
扭曲效果闪烁或抖动严重1. 噪声纹理滚动速度过快。
2. 噪声纹理本身对比度过高或细节太碎。
3. 可能与TAA(时域抗锯齿)冲突。
1. 降低Noise Speed。
2. 更换更柔和、低频的噪声图,或降低Noise Scale。
3. 尝试在URP Asset中关闭TAA,或为热扭曲Shader添加[NoInterpolation]标签(需测试)。
在Game视图正常,但Build后失效可能Shader变体没有正确打包,或者_CameraColorTexture在目标平台不可用。1. 将热扭曲Shader加入到项目的Graphics Settings->Always Included Shaders列表中。
2. 对于非常旧的GPU,确保使用SHADER_API_GLES2或SHADER_API_GLES3进行兼容性判断,使用简单的后备方案。
性能开销较大1. 热扭曲面片过大,覆盖像素过多。
2. 使用了高分辨率噪声图。
3. 没有使用clip进行提前剔除。
1. 严格控制每个热扭曲效果的影响范围(Quad的Scale)。
2. 使用128x128或256x256的噪声图通常足够。
3. 在材质中启用Alpha Clipping,并设置合适的Cutoff值。

5.2 进阶优化:基于深度的扭曲衰减

基础版本中,扭曲强度仅由遮罩控制。但在现实中,热空气扭曲的强度会随着距离热源的距离增加而衰减。我们可以引入深度信息来模拟这一点。

实现思路:

  1. 在Shader中获取当前像素的深度值(SampleSceneDepth)和热扭曲面片中心的世界空间深度。
  2. 计算两者差值,并以此作为衰减系数,乘以最终的扭曲强度。

代码片段示例(在frag函数中添加):

// 在frag函数开头,声明深度纹理 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" ... // 计算当前像素的线性眼空间深度 float depth = SampleSceneDepth(screenUV); float linearEyeDepth = LinearEyeDepth(depth, _ZBufferParams); // 假设我们通过脚本将热源中心点的深度(world space Z)传递到Shader属性 _HeatSourceDepth float depthDiff = abs(linearEyeDepth - _HeatSourceDepth); float depthAttenuation = saturate(1.0 - depthDiff * _DepthFalloff); // _DepthFalloff为衰减系数 // 在计算扭曲强度时应用深度衰减 float effectiveStrength = _DistortionStrength * mask * depthAttenuation;

这需要额外的脚本计算并传递_HeatSourceDepth,增加了复杂度,但能带来更真实的体积感和空间层次。

5.3 与URP后处理堆栈(Post Processing)的兼容性

如果你的项目使用了URP的后处理效果(如Bloom, Color Grading, Vignette),需要注意渲染顺序。后处理通常在所有不透明和半透明物体渲染完成后才执行。

我们的热扭曲效果(Queue=Transparent+1)会在所有标准半透明物体之后,但在后处理之前渲染。这意味着:

  • 优点:热扭曲效果本身也会被后处理(如Bloom)影响,如果热扭曲区域带有亮色,它也能产生泛光,效果更统一。
  • 潜在问题:如果后处理中有强烈的颜色变换或失真效果(如Chromatic Aberration),可能会对热扭曲采样到的屏幕颜色进行二次处理,导致非预期结果。通常这没有问题,因为热扭曲采样的是经过后处理之前“干净”的屏幕缓冲。如果遇到问题,可以尝试调整后处理Volume的优先级或渲染阶段。

这个基于URP_CameraColorTexture和渲染队列管理的热扭曲方案,经过多个移动端和PC项目的验证,在效果、性能和易用性上取得了很好的平衡。它把复杂性封装在了Shader内部,对外只暴露直观的参数,使得特效美术可以像调节普通粒子一样自由地调整热浪的形状、强度和动画,大大提升了开发效率。

相关新闻

  • 高品质大米哪家好? - 中媒介
  • llama-nv-embed-reasoning-3b微调指南:如何为特定领域优化推理能力
  • Mac视频预览增强终极指南:让Finder支持MKV等所有视频格式快速预览

最新新闻

  • 掌握TisprCardStack高级操作:卡片上下移动、删除与状态监听全指南
  • OnscripterYuri Android开发指南:构建移动端视觉小说应用
  • 如何通过dpu-core与openEuler深度集成打造国产化DPU软件生态
  • C++实现24点游戏:从算法到工程实践
  • Photon Fusion 2入门实战:Unity高精度多人游戏同步方案详解
  • 遗传算法工程实战:工业级黑盒优化落地指南

日新闻

  • AWS SSM安全运维实践:零公网暴露的合规远程开发方案
  • Tableau 2024.1 图表选择指南:5种业务场景与最佳图表类型匹配
  • dsPIC33FJ与CMT-8540S-SMT在嵌入式音频处理中的高效应用

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号