Unity Shader编程】之高级纹理
一,立方体纹理 Cubemap 用途
用途 | 说明 |
---|---|
反射贴图 | 表面镜面高光或金属反射 |
环境光采样 | 模拟环境对物体的影响 |
天空盒背景 | 使用六张图拼接场景背景 |
全景投影 | 做360度相机渲染、投影等 |
二,创建立方体纹理
在 Unity 中创建和保存一个 立方体纹理(Cubemap) 有几种方式,具体看你是想要:
✅ 一、使用现成的六张图片创建 Cubemap(最常用)
步骤如下:
-
准备六张图像:
命名如下(Unity 会自动识别):myCubemap_front.png myCubemap_back.png myCubemap_left.png myCubemap_right.png myCubemap_up.png myCubemap_down.png
-
导入到 Unity:
将六张图拖入 Unity 的Assets
目录中。 -
创建 Cubemap 资源:
- 在
Assets
空白处右键 >Create > Legacy > Cubemap
- 命名为
MyCubemap
- 选中它后,在 Inspector 中点击
各个面
,分别拖入上面对应的图(Unity 会有 Front、Back、Left、Right、Up、Down 的插槽)
- 在
-
保存 Cubemap:
这个.cubemap
文件本身就会保存在你的项目里,可以直接拖入 Shader 中的 Cubemap 属性上。
✅ 二、将全景图(equirectangular)转换为 Cubemap(HDRI)
Unity 也支持将 全景 HDR 图 转换为 Cubemap 使用,适用于天空盒、环境反射等。
-
拖入
.hdr
或.exr
图像到项目中 -
在该图像的
Inspector
里设置:- Texture Type →
Cube
- Mapping →
Latitude-Longitude Layout
- Generate Mip Maps → 勾选(反射需要)
- Apply
- Texture Type →
这样 Unity 就会自动将它作为 Cubemap 处理。
✅ 三、运行时生成立方体纹理(程序生成)
如果你需要运行时创建一个 Cubemap 并保存(例如截图天空),可以这样做:
public class CubemapCapture : MonoBehaviour
{public Camera renderCamera;public int cubemapSize = 128;public string savePath = "Assets/CapturedCubemap.cubemap";void Start(){Cubemap cube = new Cubemap(cubemapSize, TextureFormat.RGBA32, false);renderCamera.RenderToCubemap(cube);// 保存#if UNITY_EDITORUnityEditor.AssetDatabase.CreateAsset(cube, savePath);UnityEditor.AssetDatabase.SaveAssets();#endif}
}
⚠️ 注意事项:
- 你必须挂载一个摄像机并指向你想捕捉的中心。
- 只能在 Editor 下使用保存功能(运行时不能创建
.cubemap
文件,除非导出为贴图数组等特殊形式)。
✅ 四、通过 Reflection Probe 生成 Cubemap
Unity 中的 Reflection Probe 本质上也在实时生成 Cubemap:
- GameObject > Light > Reflection Probe
- 设置为 Baked 或 Realtime
- 勾选
Box Projection
(可选) - Bake 后它会自动生成一个 Cubemap,用于环境反射
你可以通过 Shader 中 _ReflectionProbe0
获取它,或绑定到材质里。
其中,Reflection Probe bake的时候,你可能会发现它只bake进去天空盒,那是因为Reflection Probe只会bake进去场景中为static的物体
✅ 小结:创建 Cubemap 的常用方法
方式 | 适用场景 | 是否支持保存 |
---|---|---|
手动导入六图拼接 | 天空盒、自定义 Cubemap | ✔ |
HDRI 贴图转 Cube | 天空盒、环境光 | ✔ |
Camera.RenderToCubemap | 动态反射、截图环境 | ✔(仅 Editor) |
Reflection Probe | 物理反射、全局光照 | 自动生成 |
三,反射,折射贴图
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unity Shaders Book/Chapter 10/Refraction" {Properties {// 材质颜色,用于混合漫反射颜色_Color ("Color Tint", Color) = (1, 1, 1, 1)// 折射颜色,可用于调节 Cubemap 显示色调_RefractColor ("Refraction Color", Color) = (1, 1, 1, 1)// 折射混合权重:0表示完全漫反射,1表示完全折射_RefractAmount ("Refraction Amount", Range(0, 1)) = 1// 折射率比(η),用于控制折射方向,通常设置为空气到玻璃的折射率比,如 1.0/1.33_RefractRatio ("Refraction Ratio", Range(0.1, 1)) = 0.5// 用于折射的 Cubemap 环境贴图,通常使用场景天空盒_Cubemap ("Refraction Cubemap", Cube) = "_Skybox" {}}SubShader {// 使用 Opaque 渲染队列,并归类为 Geometry 类型Tags { "RenderType"="Opaque" "Queue"="Geometry" }Pass {// 使用前向渲染的主光源通道Tags { "LightMode"="ForwardBase" }CGPROGRAM// 开启前向光照编译宏(支持多个光源和阴影)#pragma multi_compile_fwdbase // 指定使用的顶点/片元函数#pragma vertex vert#pragma fragment frag// 引入 Unity 的光照与阴影宏定义#include "Lighting.cginc"#include "AutoLight.cginc"// 声明从 Properties 中传入的变量fixed4 _Color;fixed4 _RefractColor;float _RefractAmount;fixed _RefractRatio;samplerCUBE _Cubemap;// 顶点输入结构体:包含位置和法线struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;};// 顶点到片元的传输结构体(插值器)struct v2f {float4 pos : SV_POSITION; // 裁剪空间顶点位置(用于屏幕映射)float3 worldPos : TEXCOORD0; // 顶点世界坐标fixed3 worldNormal : TEXCOORD1; // 世界法线fixed3 worldViewDir : TEXCOORD2; // 世界视线方向(摄像机指向像素点)fixed3 worldRefr : TEXCOORD3; // 世界折射方向SHADOW_COORDS(4) // Unity 内置阴影坐标宏};// 顶点着色器:计算空间变换、折射方向等v2f vert(a2v v) {v2f o;// 将顶点从本地空间转换为裁剪空间,作为 SV_POSITION 输出o.pos = UnityObjectToClipPos(v.vertex);// 将法线从本地空间转换为世界空间,并归一化o.worldNormal = UnityObjectToWorldNormal(v.normal);// 将顶点位置从对象空间转换到世界空间o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;// 计算视线方向:摄像机 → 当前像素(世界空间)o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);//反射,模拟镜面效果,和折射相冲突,保留一个// o.worldRefr=reflect(-o.worldViewDir,o.worldNormal);// 使用 HLSL 内置函数 refract 计算折射方向// 输入方向 I = -视线方向(从像素指向相机),法线 N,折射率 etao.worldRefr = refract(-normalize(o.worldViewDir), normalize(o.worldNormal), _RefractRatio);// 阴影贴图相关数据插值初始化(支持阴影衰减)TRANSFER_SHADOW(o);return o;}// 片元着色器:执行漫反射、折射采样、颜色混合等fixed4 frag(v2f i) : SV_Target {// 标准化输入的法线fixed3 worldNormal = normalize(i.worldNormal);// 获取主光源方向(世界空间)fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));// 获取标准化视线方向(摄像机 → 当前像素)fixed3 worldViewDir = normalize(i.worldViewDir);// 获取环境光颜色fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;// 标准 Lambert 漫反射计算fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0, dot(worldNormal, worldLightDir));// 用折射方向采样 Cubemap 环境贴图,并乘上折射色调fixed3 refraction = texCUBE(_Cubemap, i.worldRefr).rgb * _RefractColor.rgb;// 计算阴影衰减(基于阴影贴图)UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);// 最终颜色混合:将漫反射与折射按权重混合fixed3 color = ambient + lerp(diffuse, refraction, _RefractAmount) * atten;// 返回最终颜色,alpha = 1(不透明)return fixed4(color, 1.0);}ENDCG}}// 降级 Shader,如果目标平台不支持此 Shader 则使用FallBack "Reflective/VertexLit"
}
四,渲染纹理
在unity中有一种特殊的pass,GrabPass,定义后,unity会把当前屏幕的图像绘制在一张纹理中,然后我们可以通过对这个纹理来进行操作
4.1 玻璃效果
// Upgrade NOTE: replaced ‘_Object2World’ with ‘unity_ObjectToWorld’
// Upgrade NOTE: replaced ‘mul(UNITY_MATRIX_MVP,)’ with 'UnityObjectToClipPos()’
Shader “Unity Shaders Book/Chapter 10/Glass Refraction” {
Properties {
_MainTex (“Main Tex”, 2D) = “white” {} // 主纹理贴图
_BumpMap (“Normal Map”, 2D) = “bump” {} // 法线贴图
_Cubemap (“Environment Cubemap”, Cube) = “_Skybox” {} // 环境反射贴图(立方体)
_Distortion (“Distortion”, Range(0, 100)) = 10 // 法线扰动强度(影响折射扭曲)
_RefractAmount (“Refract Amount”, Range(0.0, 1.0)) = 1.0 // 折射/反射混合比例
}
SubShader {Tags { "Queue"="Transparent" "RenderType"="Opaque" }// 捕捉当前屏幕图像到 _RefractionTex(背景图像用于模拟折射)GrabPass { "_RefractionTex" }Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;sampler2D _BumpMap;float4 _BumpMap_ST;samplerCUBE _Cubemap;float _Distortion;fixed _RefractAmount;sampler2D _RefractionTex; // 被 GrabPass 捕捉到的背景图像float4 _RefractionTex_TexelSize; // 屏幕图像的像素大小(用于精确偏移)struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float2 texcoord : TEXCOORD0;};struct v2f {float4 pos : SV_POSITION;float4 scrPos : TEXCOORD0; // 屏幕坐标,用于 GrabPass UV 采样float4 uv : TEXCOORD1; // uv.xy = 主纹理UV,uv.zw = 法线纹理UVfloat4 TtoW0 : TEXCOORD2; // TBN矩阵第1行 + worldPos.xfloat4 TtoW1 : TEXCOORD3; // TBN矩阵第2行 + worldPos.yfloat4 TtoW2 : TEXCOORD4; // TBN矩阵第3行 + worldPos.z};v2f vert (a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex); // 模型 → 裁剪空间// 计算当前像素在屏幕上的 GrabPass 采样位置(自动透视修正)o.scrPos = ComputeGrabScreenPos(o.pos);// 主纹理、法线纹理 UV 变换o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);// 构建 TBN 矩阵(切线空间 → 世界空间)float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;float3 worldNormal = UnityObjectToWorldNormal(v.normal);float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);float3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;// 每行存 TBN basis 的 xyz,w 分量存 worldPos 对应轴o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);return o;}fixed4 frag (v2f i) : SV_Target {// 恢复世界坐标(从每个 w 分量提取)float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);// 计算从像素指向摄像机的视线方向(世界空间)fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));// 从法线贴图采样切线空间法线(范围[-1, 1])fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw));// ✅【产生玻璃折射扭曲感】的核心代码:float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy;i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;// 采样 GrabPass 纹理作为“背景折射”颜色fixed3 refrCol = tex2D(_RefractionTex, i.scrPos.xy / i.scrPos.w).rgb;// 法线从切线空间转换到世界空间(TBN乘切线法线)bump = normalize(half3(dot(i.TtoW0.xyz, bump),dot(i.TtoW1.xyz, bump),dot(i.TtoW2.xyz, bump)));// 计算反射方向fixed3 reflDir = reflect(-worldViewDir, bump);// 从 Cubemap 中采样反射环境颜色fixed4 texColor = tex2D(_MainTex, i.uv.xy);fixed3 reflCol = texCUBE(_Cubemap, reflDir).rgb * texColor.rgb;// ✅【反射 + 折射】混合(_RefractAmount 控制)fixed3 finalColor = reflCol * (1 - _RefractAmount) + refrCol * _RefractAmount;return fixed4(finalColor, 1); // 不透明(你可以改为支持透明混合)}ENDCG}
}Fallback "Diffuse"
}
bump.xy 决定了你往哪个方向“挤压/偏移”
_Distortion 放大效果
texel size 保证单位一致(从像素偏移变成 UV 偏移)
i.scrPos.xy 原本就是当前像素在屏幕中的 UV 坐标(GrabPass用)
i.scrPos.z 透视深度校正因子(从 ComputeGrabScreenPos() 中得)
offset * i.scrPos.z 根据深度远近决定偏移强度,防止透视拉伸过度
- i.scrPos.xy 添加偏移量,实现“错位采样”
这是一个折射的功能shader,为什么要添加cubemap来作为反射呢?
➤ 它是模拟玻璃表面上的环境反射(如天空、高光、远处光源反光)
不影响背景的错位采样
不影响整体透视扭曲
仅仅为表面提供一种“微妙的光泽感”
🧪 如果 Cubemap 是纯黑图,你会发现玻璃表面失去了高光反射感,变“哑光”
相关文章:
Unity Shader编程】之高级纹理
一,立方体纹理 Cubemap 用途 用途说明反射贴图表面镜面高光或金属反射环境光采样模拟环境对物体的影响天空盒背景使用六张图拼接场景背景全景投影做360度相机渲染、投影等 二,创建立方体纹理 在 Unity 中创建和保存一个 立方体纹理(Cubema…...

类 Excel 数据填报
类 Excel 填报模式,满足用户 Excel 使用习惯 数据填报,可作为独立的功能模块,用于管理业务流程、汇总采集数据,以及开发各类数据报送系统,因此,对于报表工具而言,其典型场景之一就是利用报表模…...
vscode调试stm32,Cortex Debug的配置文件lanuch.json如何写,日志
https://blog.csdn.net/jiladahe1997/article/details/122046665 https://discuss.em-ide.com/blog/67-cortex-debug 第一版 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?li…...

Office文档图片批量导出工具
软件介绍 本文介绍一款专业的Office文档图片批量导出工具。 软件特点 这款软件能够批量导出Word、Excel和PPT中的图片,采用绿色单文件设计,体积小巧仅344KB。 基本操作流程 使用方法十分简单:直接将Word、Excel或PPT文件拖入软件…...

【iOS】ARC 与 Autorelease
ARC 与 Autorelease 文章目录 ARC 与 Autorelease前言何为ARC内存管理考虑方式自己生成的对象,自己持有非自己生成的对象,自己也可以持有不再需要自己持有的对象时释放非自己持有的对象无法释放 ARC的具体实现编译期和运行期ARC做的事情ARC实现: __autoreleasing 与 Autoreleas…...
人工智能在智能零售中的创新应用与未来趋势
随着电子商务的蓬勃发展和消费者需求的不断变化,零售行业正面临着前所未有的挑战和机遇。智能零售作为零售行业的重要发展方向,通过引入人工智能(AI)、物联网(IoT)、大数据和云计算等前沿技术,正…...
业务材料——半导体行业MES系统核心功能工业协议AI赋能
一、前置概念 半导体行业 半导体行业主要生产基于半导体材料(如硅、锗、化合物半导体等)的电子元器件及相关产品,广泛应用于计算、通信、能源、医疗等领域。 MES系统 MES系统(Manufacturing Execution System,制造…...
docker部署命令行 — 启动一个 MySQL 数据库服务 并且把它的数据存储挂载到卷(volume)里
挂载卷的配置写法: version: "3" services:db:image: mysqlvolumes:- mysql_data:/var/lib/mysqlvolumes:mysql_data:这段 docker-compose.yml 配置非常典型,是用来启动一个 MySQL 数据库服务 并且把它的数据存储挂载到卷(volume&…...

铁电液晶破局 VR/AR:10000PPI 重构元宇宙显示体验
一、VR/AR 沉浸感困境:传统显示技术的天花板在哪? (一)纱窗效应与眩晕感:近眼显示的双重枷锁 当用户戴上 VR 头显,眼前像素网格形成的 “纱窗效应” 瞬间打破沉浸感。传统液晶 500-600PPI 的像素密度&…...
2025年微信小程序开发:AR/VR与电商的最新案例
引言 微信小程序自2017年推出以来,已成为中国移动互联网生态的核心组成部分。根据最新数据,截至2025年,微信小程序的日活跃用户超过4.5亿,总数超过430万,覆盖电商、社交、线下服务等多个领域(WeChat Mini …...
从零开始,学会上传,更新,维护github仓库
以下是一份从头到尾、覆盖安装、配置、创建仓库、上传项目到 GitHub 的完整教程。全程使用通用示例,不包含任何具体的仓库链接,仅供参考。 一、准备工作 1. 注册 GitHub 账号 打开浏览器,访问 GitHub 官网(输入 “GitHub” 即可找…...
#STM32 HAL库实现的STM32F407时钟配置程序以及和STM32F103配置对比
以下是使用STM32 HAL库实现的STM32F407时钟配置完整代码(基于8MHz外部晶振,配置为168MHz系统时钟),包含详细注释和关键点说明: 完整HAL库实现(system_stm32f4xx.c main.c) 1. 首先在stm32f4xx…...

竞争加剧,美团的战略升维:反内卷、科技与全球化
5月26日,美团发布2025年第一季度业绩报告,交出了一份兼具韧性与创新性的成绩单。 报告显示,公司一季度总营收866亿元,同比增长18%;核心本地商业收入643亿元,同比增长18%;季度研发投入58亿元&a…...

(17)课36:窗口函数的例题:例三登录时间与连续三天登录,例四球员的进球时刻连续进球。
(89)例三登录时间 : 保留代码版本 : CREATE TABLE sql_8( user_id varchar(2), login_date date ); insert into sql_8(user_id,login_date) values(A,2024-09-02),(A,2024-09-03),(A,2024-09-04),(B,2023-11-25),(B,2023-12- 3…...

高性能分布式消息队列系统(二)
上一篇博客将C进行实现消息队列的用到的核心技术以及环境配置进行了详细的说明,这一篇博客进行记录消息队列进行实现的核心模块的设计 五、项目的需求分析 5.1、项目框架的概念性理解 5.1.1、消息队列的设计和生产消费者模型的关系 在现代系统架构中,…...
Spring 官方推荐构造函数注入
1. 依赖关系明确 构造函数注入可以清晰地声明类的依赖关系,所有必需的依赖项都通过构造函数参数传递,使得代码的可读性更高。这种方式让类的使用者能够直观地了解类的依赖,而不需要通过注解或反射来猜测。 2. 增强代码健壮性 构造函数注入…...

华为OD机试真题——天然蓄水库(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《天然蓄水库》: 目录 题目…...

【Harmony OS】数据存储
目录 数据存储概述 首选项数据存储 关系型数据库 数据存储概述 • 数据存储 是为了解决应用数据持久化问题,使得数据能够存储在外存中,达到保存或共享目的。 • 鸿蒙应用数据存储包括 本地数据存储 和 分布式数据存储 。 • 本地数据存储 为应用…...

MybatisPlus--核心功能--service接口
Service接口 基本用法 MyBatisPlus同时也提供了service接口,继承后一些基础的增删改查的service代码,也不需要去书写。 接口名为Iservice,而Iservice也继承了IRepository,这里提供的方法跟BaseMapper相比只多不少,整…...

uniapp调试,设置默认展示的toolbar内容
uniapp调试,设置默认展示的toolbar内容 设置pages.json中 pages数组中 json的顺序就可以只需要调整顺序,不会影响该bar在页面中的显示默认展示第一条page...

笔记本电脑开机无线网卡自动禁用问题
1.问题环境 电脑品牌:华硕笔记本天选4 电脑型号:FX507VV 电脑系统:windows 11_x64_24h2 文档编写时间:2025年6月 2.问题现象 1. 笔记本电脑开机之后自动禁用无线网卡 使用USB转RJ45转接头同样无效,这个网卡也给禁…...

推荐一款使用html开发桌面应用的工具——mixone
简介 mixone是开发桌面应用(Win、Mac、Linux)的一款工具、其基于electron实现。其拥有简单的工程结构。以为熟悉前端开发的程序员可以很轻松的开发出桌面应用,它比electron的其他框架更简单,因为那些框架基本上还需要了解electro…...
支持TypeScript并打包为ESM/CommonJS/UMD三种格式的脚手架项目
支持TypeScript并打包为ESM、CommonJS和UMD三种格式的脚手架项目 码云地址 NODE 版本要求 node v16.17.1 npm 8.15.0 设置淘宝镜像 npm set registry https://registry.npmjs.org/ cnpm set registry https://registry.npmjs.org/安装依赖 npm install打包 npm run build…...

【云原生开发】如何通过client-go来操作K8S集群
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

八.MySQL复合查询
一.基本查询回顾 分组统计 group by 函数作用示例语句说明count(*)统计记录条数select deptno, count(*) from emp group by deptno;每个部门有多少人?sum(sal)某字段求和select deptno, sum(sal) from emp group by deptno;每个部门总工资avg(sal)求平均值select…...
cacti导出的1分钟监控数据csv文件读取并按5分钟求平均值,然后计算95计费值,假设31天的月份
cacti导出的1分钟监控数据csv文件读取并按5分钟求平均值,然后计算95计费值,假设31天的月份 import pandas as pd import openpyxl from openpyxl.styles import Font from openpyxl.utils.dataframe import dataframe_to_rows import os import chardet…...

FastMCP vs MCP:协议标准与实现框架的协同
你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…...

AI视频“入驻”手机,多模态成智能终端的新战场
文|乐乐 今天,无线蓝牙耳机(TWS)已经成为人人都用得起的产品。 但退回到9年前,苹果AirPods是全球第一款真正意义上的无线蓝牙耳机。靠着自研并申请专利的Snoop监听技术,苹果解决了蓝牙耳机左右延时和能耗…...

nginx+tomcat负载均衡群集
一 案例部署Tomcat 目录 一 案例部署Tomcat 1.案例概述 1.1案例前置知识点 (1)Tomcat简介 (2)应用场景 2.实施准备 (1)关闭Linux防火墙 (2)安装Java 2.1 安装配置TOMACT …...
DEEPSEEK帮写的STM32消息流函数,直接可用.已经测试
#include "main.h" #include "MessageBuffer.h"static RingBuffer msgQueue {0};// 初始化队列 void InitQueue(void) {msgQueue.head 0;msgQueue.tail 0;msgQueue.count 0; }// 检查队列状态 type_usart_queue_status GetQueueStatus(void) {if (msgQ…...