Unity自定义shader打包SpriteAtlas图集问题
Unity打包图集还是有一些坑的,至于图集SpriteAtlas是什么请参考我之前写的文章:【Sprite Atlas】Unity新图集系统SpriteAtlas超详细使用教程_spriteatlas 使用-CSDN博客
问题:
今天碰到的问题是,shader绘制的时候,因为打包图集后,MainTexture是图集的图片,所以shader渲染就错误了。
非图集是这样显示的,正常的一个地块。
打包完图集后,发现这个MainTexture是整个图集的图片
导致显示就错乱了,如下图。
正常的显示是这样的。
问题所在:
原因就是打包图集后传入给shader的uv变了,本来只有图片的时候,uv就是0-1的本地uv值,现在素材换成一张更大的图了,导致uv采样就出现了问题。
解决方法:
将图片本身的uv信息传给shader,做一个计算转换即可。
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Sprites;
using UnityEngine;public class StaticGroundObject : GroundObject
{public GameObject notCellObjectShow;private SpriteRenderer spriteRenderer;private const string _UVRangeName = "_UVRange";protected override void OnStart(){base.OnStart();SetSortingOrder();spriteRenderer = GetComponentInChildren<SpriteRenderer>();UpdateSpriteRenderer();}protected override void OnEnable(){base.OnEnable();}//修改也要void UpdateSpriteRenderer(){if (spriteRenderer != null){Sprite sprite = spriteRenderer.sprite;Vector2 texelSize = sprite.texture.texelSize;Rect rect = sprite.textureRect;Vector4 uvRemap = new(rect.x * texelSize.x,rect.y * texelSize.y,rect.width * texelSize.x,rect.height * texelSize.y);// 将UV值传递给材质Material material = spriteRenderer.material;if (material != null){// 确保shader中有对应的属性if (material.HasProperty(_UVRangeName)){material.SetVector(_UVRangeName, uvRemap);Debug.Log("UV值已成功写入shader");}else{Debug.LogError("shader缺少必要的属性,请确保shader中定义了_UV1和_UV2属性");}}else{Debug.LogError("renderer的材质为空");}}}public override void SetNotCellObjectShow(GameObject notCellObjectShow){base.SetNotCellObjectShow(notCellObjectShow);this.notCellObjectShow = notCellObjectShow;}protected override void CheckRandomPrefabs(bool isShow){if (notCellObjectShow != null){//上面没有东西,而且没有混合到其他格子上if (ParentGround == null && isShow){notCellObjectShow.SetActive(true);}else{notCellObjectShow.SetActive(false);}}}private void SetSortingOrder(){var ground = GetComponentsInChildren<SpriteRenderer>(true)[0];var groundName = ground.name;var lastIndex = groundName.LastIndexOf('_');var secondLastIndex = groundName.LastIndexOf('_', lastIndex - 1);int.TryParse(groundName.Substring(secondLastIndex + 1, lastIndex - secondLastIndex - 1), out int result);ground.sortingOrder -= result;}protected override void SetBlendMaskValue(Texture2D newBlendMask, int newRotateMaskValue, Texture2D mainBlendTex,Texture2D blendMaskChamfer, Dictionary<int, float> _offsetList){// base.SetBlendMaskValue(newBlendMask, newRotateMaskValue, mainBlendTex, blendMaskChamfer, offsetList);//获得要渲染的对象if (mainBlends.Count == 0){mainBlends = GetComponentsInChildren<Renderer>().ToList();}if (mainBlends.Count == 0){Debug.LogError("mainBlends.Count==0");return;}//设置遮罩贴图this.blendMask = newBlendMask;this.rotateMaskValue = newRotateMaskValue;this.mainBlendTex = mainBlendTex;this.blendMaskChamfer = blendMaskChamfer;//设置偏移值this.blendOffsetTargetList = _offsetList;UpdateMaterial();UpdateSpriteRenderer();}protected override void SetBlendOffsetList(Dictionary<int, float> _offsetList){// base.SetBlendOffsetList(_offsetList);blendOffsetTargetList = _offsetList;UpdateMaterial();UpdateSpriteRenderer();}
}public class MaterialCacheTool
{public static Dictionary<string, Material> materialCache = new Dictionary<string, Material>();public static Material CheckMaterial(string materialKey, Renderer defaultRenderer, Action<Material> onInit){Material checkMaterial = null;if (materialCache.ContainsKey(materialKey)){checkMaterial = materialCache[materialKey];}else{var material = new Material(defaultRenderer.sharedMaterial);material.name = materialKey;onInit?.Invoke(material);materialCache.Add(materialKey, material);checkMaterial = material;}return checkMaterial;}
}
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Shader/GroundObjectV3_Code"
{Properties{[NoScaleOffset]_MaskMap("MaskMap", 2D) = "white" {}[NoScaleOffset]_MainTex("MainTex", 2D) = "white" {}[NoScaleOffset]_Chamfer("Chamfer", 2D) = "black" {}_RotateMask("RotateMask",Range(0, 360)) = 0_OffsetUp("OffsetUp", Range(0, 1)) = 0_OffsetDown("OffsetDown", Range(0, 1)) = 0_OffsetLeft("OffsetLeft", Range(0, 1)) = 0_OffsetRight("OffsetRight", Range(0, 1)) = 0_OffsetUpLeft("OffsetUpLeft", Range(0, 1)) = 0_OffsetUpRight("OffsetUpRight", Range(0, 1)) = 0_OffsetDownLeft("OffsetDownLeft", Range(0, 1)) = 0_OffsetDownRight("OffsetDownRight", Range(0, 1)) = 0//相反_IsInversion("IsInversion", Float) = 0[NoScaleOffset]_BlendMaskMap("BlendMaskMap", 2D) = "black" {}[NoScaleOffset]_BlendMainTex("BlendMainTex", 2D) = "white" {}[NoScaleOffset]_BlendChamfer("_BlendChamfer", 2D) = "black" {}_BlendOffsetUp("BlendOffsetUp", Range(0, 1)) = 0_BlendOffsetDown("BlendOffsetDown", Range(0, 1)) = 0_BlendOffsetLeft("BlendOffsetLeft", Range(0, 1)) = 0_BlendOffsetRight("BlendOffsetRight", Range(0, 1)) = 0_BlendOffsetUpLeft("BlendOffsetUpLeft", Range(0, 1)) = 0_BlendOffsetUpRight("BlendOffsetUpRight", Range(0, 1)) = 0_BlendOffsetDownLeft("BlendOffsetDownLeft", Range(0, 1)) = 0_BlendOffsetDownRight("BlendOffsetDownRight", Range(0, 1)) = 0[HideInInspector]_QueueOffset("_QueueOffset", Float) = 0[HideInInspector]_QueueControl("_QueueControl", Float) = -1[HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}[HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}[HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}_OffsetFactor("OffsetFactor", Float) = 0_OffsetUnits("OffsetUnits", Float) = 0[ToggleUI] _ReceiveShadows("Receive Shadows", Float) = 1.0[ToggleUI] _CastShadows("Cast Shadows", Float) = 1.0//阴影模糊_ShadowBlur("ShadowBlur", Float) = 0.0_Cull("__cull", Float) = 2.0// 新增距离缩放因子属性_DistanceScaleFactor("Distance Scale Factor", Range(0.1, 100.0)) = 60.0//补充UV_UVRange("UV Range", Vector) = (0, 0, 1, 1)}SubShader{Tags{"RenderPipeline"="UniversalPipeline""RenderType"="Opaque""UniversalMaterialType" = "Lit""Queue"="AlphaTest""DisableBatching"="LODFading""ShaderGraphShader"="true""ShaderGraphTargetId"="UniversalLitSubTarget""EnableGPUInstancing" = "true"}LOD 100Pass{// Render StateCull BackZTest LEqualZWrite OnBlend One ZeroAlphaToMask Onoffset [_OffsetFactor] , [_OffsetUnits]HLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog// #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"#include "EgoLight.hlsl"#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREENstruct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;//光照计算float4 positionOS : POSITION;float4 normalOS : NORMAL;};struct v2f{float2 uv : TEXCOORD0;// UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;float3 worldPos : TEXCOORD1;//光照计算float3 viewDirWS : TEXCOORD2;float3 normalWS : TEXCOORD3;// 新增距离变量float distanceToCamera : TEXCOORD4;float prevLod : TEXCOORD5; // 新增变量存储上一次的LODfloat2 uv2:TEXCOORD6;};sampler2D _MaskMap;float4 _MaskMap_ST;sampler2D _MainTex;float4 _MainTex_ST;sampler2D _Chamfer;float4 _Chamfer_ST;float _RotateMask;float _OffsetUp;float _OffsetDown;float _OffsetLeft;float _OffsetRight;float _OffsetUpLeft;float _OffsetUpRight;float _OffsetDownLeft;float _OffsetDownRight;float _IsInversion;//混合剔除的参数sampler2D _BlendMaskMap;float4 _BlendMaskMap_ST;sampler2D _BlendMainTex;float4 _BlendMainTex_ST;sampler2D _BlendChamfer;float4 _BlendChamfer_ST;float _BlendOffsetUp;float _BlendOffsetDown;float _BlendOffsetLeft;float _BlendOffsetRight;float _BlendOffsetUpLeft;float _BlendOffsetUpRight;float _BlendOffsetDownLeft;float _BlendOffsetDownRight;float4 _GlobalShadowColor;// 新增距离缩放因子属性变量,放在HLSL代码的合适位置,这里在函数外部声明float _DistanceScaleFactor;float4 _UVRange;v2f vert (appdata v){v2f o;o.uv = TRANSFORM_TEX(v.uv, _MaskMap);float2 spriteRectPos = _UVRange.xy;float2 spriteRectSize = _UVRange.zw;float2 localUV = (v.uv - spriteRectPos) / spriteRectSize;o.uv2 = localUV;o.vertex = TransformObjectToHClip(v.vertex);//UnityObjectToClipPos //o.vertex = mul(UNITY_MATRIX_MVP,v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;// 计算物体到摄像机的距离o.distanceToCamera = distance(mul(unity_ObjectToWorld, v.vertex).xyz, _WorldSpaceCameraPos.xyz);o.prevLod = 0; // 初始化//光照计算VertexPositionInputs positionInputs = GetVertexPositionInputs(v.positionOS.xyz);VertexNormalInputs normalInputs = GetVertexNormalInputs(v.normalOS.xyz);o.viewDirWS = GetCameraPositionWS() - positionInputs.positionWS;o.normalWS = normalInputs.normalWS;return o;}float2 GetMaskUV(float2 uv){float2 maskUV=uv;maskUV -= 0.5;// 旋转 45 度(π/4 弧度)float angle = radians(_RotateMask);float cosAngle = cos(angle);float sinAngle = sin(angle);float2x2 rotationMatrix = float2x2(cosAngle, -sinAngle, sinAngle, cosAngle);maskUV = mul(rotationMatrix, maskUV);// 平移回原来的坐标maskUV += 0.5;return maskUV;}//全部的Offsetfloat GetColorMask(sampler2D colorMask, sampler2D colorChamfer,float2 uv, float _OffsetUp, float _OffsetDown, float _OffsetLeft, float _OffsetRight, float _OffsetUpLeft, float _OffsetUpRight, float _OffsetDownLeft, float _OffsetDownRight,float _lod){float offsetMax = 0.5;float2 offsets[8] = {float2(0, -_OffsetUp * offsetMax),float2(0, _OffsetDown * offsetMax),float2(_OffsetLeft * offsetMax, 0),float2(-_OffsetRight * offsetMax, 0),float2(_OffsetUpLeft * offsetMax, -_OffsetUpLeft * offsetMax),float2(-_OffsetUpRight * offsetMax, -_OffsetUpRight * offsetMax),float2(_OffsetDownLeft * offsetMax, _OffsetDownLeft * offsetMax),float2(-_OffsetDownRight * offsetMax, _OffsetDownRight * offsetMax)};float alpha = 0;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv),0,_lod)).r;// 循环采样偏移纹理//for (int i = 0; i < 8; i++) {// alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[i]),0,_lod)).r;//}alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[0]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[1]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[2]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[3]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[4]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[5]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[6]),0,_lod)).r;alpha += tex2Dlod(colorMask, float4(GetMaskUV(uv + offsets[7]),0,_lod)).r;// 采样倒角纹理alpha += tex2Dlod(colorChamfer, float4(uv + float2( _OffsetLeft * offsetMax, -_OffsetUp * offsetMax),0,_lod)).r;alpha += tex2Dlod(colorChamfer, float4(uv + float2(-_OffsetRight * offsetMax, -_OffsetUp * offsetMax),0,_lod)).r;alpha += tex2Dlod(colorChamfer, float4(uv + float2( _OffsetLeft * offsetMax, _OffsetDown * offsetMax),0,_lod)).r;alpha += tex2Dlod(colorChamfer, float4(uv + float2(-_OffsetRight * offsetMax, _OffsetDown * offsetMax),0,_lod)).r;// 透明度限制在0-1之间alpha = clamp(alpha, 0, 1); return alpha;}float4 frag (v2f i) : SV_Target{float2 maskUV = i.uv2; float lod = i.distanceToCamera / _DistanceScaleFactor;lod = clamp(lod, 0, 5); float mainAlpha = GetColorMask( _MaskMap, _Chamfer, maskUV, _OffsetUp, _OffsetDown, _OffsetLeft, _OffsetRight, _OffsetUpLeft, _OffsetUpRight, _OffsetDownLeft, _OffsetDownRight,lod);// 计算主纹理的UV偏移float2 mainTexUV = TRANSFORM_TEX(i.uv, _MainTex).xy;float4 mainColor = tex2Dlod(_MainTex, float4(mainTexUV, 0, lod));//tex2D(_MainTex, TRANSFORM_TEX(i.uv, _MainTex));mainAlpha *= mainColor.a;float f = lerp(1.01,0.99,_IsInversion);//1.01;//maskUV缩放变大一点点maskUV -= 0.5;maskUV *=lerp(1.01,0.99,_IsInversion); // 1.005;maskUV += 0.5;//各个边移动多一丢丢// _BlendOffsetUp += float2(0,f);// _BlendOffsetDown += float2(0,-f);// _BlendOffsetLeft += float2(-f,0);// _BlendOffsetRight += float2(f,0);// _BlendOffsetUpLeft += float2(-f,f);// _BlendOffsetUpRight += float2(f,f);// _BlendOffsetDownLeft += float2(-f,-f);// _BlendOffsetDownRight += float2(f,-f);float blendAlpha = GetColorMask( _BlendMaskMap, _BlendChamfer, maskUV, _BlendOffsetUp, _BlendOffsetDown, _BlendOffsetLeft, _BlendOffsetRight, _BlendOffsetUpLeft, _BlendOffsetUpRight, _BlendOffsetDownLeft, _BlendOffsetDownRight,lod);float4 blendColor = tex2Dlod(_BlendMainTex, float4(TRANSFORM_TEX(i.uv, _BlendMainTex),0,lod));blendAlpha*=blendColor.a;float alpha = mainAlpha - blendAlpha;alpha = lerp(alpha,1-alpha,_IsInversion); // 根据距离调整纹理采样的LOD// mainColor = tex2Dlod(_MainTex, float4(TRANSFORM_TEX(i.uv, _MainTex).xy, 0, lod));// blendColor = tex2Dlod(_BlendMainTex, float4(TRANSFORM_TEX(i.uv, _BlendMainTex).xy, 0, lod));float _Cutoff = 0.8;float3 color = CheckColor(i.worldPos,i.normalWS,_GlobalShadowColor,mainColor.rgb);clip(alpha - _Cutoff);return float4(color.rgb, alpha);}ENDHLSL}}
}
参考这个链接会解释的更加详细点:
Local UVs for Sprites in Sprite Sheet/Atlas | Cyanilux
相关文章:
Unity自定义shader打包SpriteAtlas图集问题
Unity打包图集还是有一些坑的,至于图集SpriteAtlas是什么请参考我之前写的文章:【Sprite Atlas】Unity新图集系统SpriteAtlas超详细使用教程_spriteatlas 使用-CSDN博客 问题: 今天碰到的问题是,shader绘制的时候,因…...
系统集成项目管理工程师学习笔记之启动过程组
第十章 启动过程组 制定项目章程 定义 制定项目章程是编写一份正式批准项目并授权项目经理在项目活动中使用组织资源的文件的过程。 正式批准的项目文件 作用 1、明确项目与组织战略目标之间的直接联系 2、确立项目的正式地位 3、展示组织对项目的承诺 本过程仅开展一…...
vscode 常用调试
一、文件执行 python script.py {"name": "Python 调试程序: 当前文件","type": "debugpy","request": "launch","program": "${file}","console": "integratedTerminal"…...
Java 07异常
异常 指的是程序在编译和执行的过程中,出现的非正常的情况; 当然语法错误并不属于错误异常体系 最大的Throwable; 分为两个:Error ExceptionError 严重级别问题 常见的 堆内存溢出 栈内存溢出Exception 分为两个子类 RuntimeException 运…...
2025年PMP 学习二十三 16章 高级项目管理
2025年PMP 学习二十三 16章 高级项目管理 文章目录 2025年PMP 学习二十三 16章 高级项目管理高级项目管理战略管理战略管理的组成要素:企业战略转化为战略行动的阶段: 组织战略类型战略组织类型组织级项目管理OPM(公司项目管理) 组…...
【Java高阶面经:微服务篇】1.微服务架构核心:服务注册与发现之AP vs CP选型全攻略
一、CAP理论在服务注册与发现中的落地实践 1.1 CAP三要素的技术权衡 要素AP模型实现CP模型实现一致性最终一致性(Eureka通过异步复制实现)强一致性(ZooKeeper通过ZAB协议保证)可用性服务节点可独立响应(支持分区存活)分区期间无法保证写操作(需多数节点可用)分区容错性…...
ISCC 2025决赛 wp
PWN Dilemma 64位程序没有开启PIE,并且过滤了execve,不能使用system这些的了,所以要考虑ORW来做 进入main函数分析,这里有两个函数一个func_1一个func_2。 这两个函数都有漏洞,以下是详细分析: 对于func…...
C++(5)switch语句 循环while
这是一个电影评分的程序 default 就是 如果上述的都没有执行 就统一的执行default的内容。 然后记得break ___________________________________ 循环 (while) while的使用方式 输出 0-9的while循环...
操作系统----软考中级软件工程师(自用学习笔记)
目录 1、计算机系统层次结构 2、程序顺序执行的特征 3、程序并发执行的特征 4、三态模型 5、同步与互斥 6、信号量机制 7、PV操作 8、死锁 9、进程资源图 10、死锁避免 11、线程 12、程序局部性原理 13、分页存储管理 14、单缓冲器 15、双缓冲区 16、磁盘调度算…...
利用Spring Boot和Redis构建高性能缓存系统
利用Spring Boot和Redis构建高性能缓存系统 引言 在现代Web应用中,缓存是提升系统性能的关键技术之一。Redis作为一种高性能的内存数据库,广泛应用于缓存场景。本文将介绍如何利用Spring Boot和Redis构建一个高性能的缓存系统,涵盖Redis的基…...
每日一题:1、虚拟IPv4地址转换为32位整数(JS)
题目背景 我们需要处理一种特殊的虚拟IPv4地址,这种地址由4个小节组成,每节之间用#分隔。与标准IPv4地址不同,虚拟IPv4地址的第一节范围是1~128,后三节的范围是0~255。我们需要将这种虚拟IPv4地址转换为一个唯一的32位整数。如果…...
[Vue]组件介绍和父子组件间传值
组件介绍 Vue3的 .vue文件中的主要部分分别分为三个:<template>、<script>、<style> <template>: 结构,相当于原html中的<head><body><footer>部分。原本的index.html现在只做一个容器࿰…...
Vue3 中使用 provide/inject 实现跨层级组件传值失败的原因及解决方案
1、基础用法 父组件: <script setup> import { ref, provide } from vue; import ChildComponent from ./ChildComponent.vue; const parentData ref(初始数据); // 提供数据 provide(parentData, parentData); </script>子组件: <sc…...
Git Hooks 和 自动生成 Commit Message
前言: 企业编程必须始终依赖流程,而不是个人。个人能力很重要,应该鼓励,但不能指望它,否则软件质量将不一致,没有可持续性。一旦顶级程序员跳槽,公司就会陷入困境。企业应该努力改进工作流程&am…...
【小明剑魔视频Viggle AI模仿的核心算法组成】
Viggle AI 作为一款先进的生成式视频AI工具,其核心技术栈融合了多项前沿算法。以下是深度解析其核心算法架构及实现原理: 一、核心算法组成 1. 运动控制生成(Motion Control Generation) 算法框架:基于扩散模型&…...
Linux学习心得问题整理(二)
day05 Linux基础入门 Linux语法解析 如何理解ssh远程连接?如何使用ssh使用远程连接服务? ssh进也称远程服务终端,常见连接方式可以包括windows和Linux两种方式 首先咱们使用windows窗口进行连接,这里就采用xshell连接工具来给大家做演示吧…...
百度网盘加速补丁v7.14.1.6使用指南|PC不限速下载实操教程
软件介绍 本加速补丁可突破百度网盘限速限制,无需会员、无次数限制,实测下载速度可达带宽峰值。 三步极速配置教程 1. 环境准备 → 卸载电脑原有百度网盘客户端(避免冲突) → 关闭杀毒软件/安全卫士(防止误删补丁&am…...
RocketMQ消息拉取模式详解
RocketMQ提供了两种消息拉取模式,Pull模式(主动拉取)和 Push模式(长轮询)。 一、消息拉取模式分类 1. Pull模式(主动拉取) 特点:消费者主动向Broker发送请求拉取消息实现类&#…...
C++23 容器从其他兼容范围的可构造性与可赋值性 (P1206R7)
文章目录 背景与动机提案内容与实现细节提案 P1206R7实现细节编译器支持 对开发者的影响提高灵活性简化代码向后兼容性 总结 C23标准引入了对容器构造和赋值的新特性,这些特性使得容器能够更灵活地从其他兼容范围初始化,并支持从范围赋值。这些改进由提案…...
深入解析 HTTP 中的 GET 请求与 POST 请求
在互联网的世界里,数据的传输与交互无时无刻不在发生。HTTP(超文本传输协议)作为 Web 应用的基石,承载着浏览器与服务器之间的通信重任。而 GET 请求和 POST 请求,作为 HTTP 协议中最为常用的两种请求方法,…...
华三(H3C)IRF堆叠心跳的LACP MAD、BFD MAD和ARP MAD差异
华三(H3C)IRF堆叠心跳的三种MAD(多主检测)机制——LACP MAD、BFD MAD和ARP MAD在实现原理、组网要求及适用场景上存在显著差异。以下是三者的对比分析: 一、核心区别对比 特性LACP MADBFD MADARP MAD检测原理扩展LAC…...
thread 的mutex优化
std::mutex mtx; int shared_data 0;void increment() {std::lock_guard<std::mutex> lock(mtx); // 自动加锁shared_data; // 临界区 } // 离开作用域时自动解锁std::lock_guard 在离开作用域时自动解锁的行为是基于 C 的 RAII (Resource Acquisition Is Initializa…...
深入解析前端 JSBridge:现代混合开发的通信基石与架构艺术
引言:被低估的通信革命 在移动互联网爆发式增长的十年间,Hybrid App(混合应用)始终占据着不可替代的地位。作为连接 Web 与 Native 的神经中枢,JSBridge 的设计质量直接决定了应用的性能上限与开发效率。本文将突破传…...
打破次元壁,VR 气象站开启气象学习新姿势
在教育领域,VR 气象站同样发挥着巨大的作用,为气象教学带来了全新的模式,打破了传统教学的次元壁,让学生们以全新的姿势学习气象知识。 在传统的气象教学中,学生们主要通过课本、图片和老师的讲解来学习气象知识。这…...
python八股文汇总(持续更新版)
python装饰器 一、装饰器是什么? 装饰器是Python中一种"化妆师",它能在不修改原函数代码的前提下,给函数动态添加新功能。 本质:一个接收函数作为参数,并返回新函数的工具。作用:像给手机贴膜…...
C#入门系列【基础类型大冒险】从0到1,解锁编程世界的“元素周期表”
C#入门系列【基础类型大冒险】从0到1,解锁编程世界的“元素周期表” 嘿,欢迎来到C#的奇妙世界!如果把编程比作建造一座大厦,那么基础类型就是我们手中的“砖块”和“水泥”。它们看似普通,却构成了所有复杂程序的基石…...
物流项目第四期(运费模板列表实现)
前三期: 物流项目第一期(登录业务)-CSDN博客 物流项目第二期(用户端登录与双token三验证)-CSDN博客 物流项目第三期(统一网关、工厂模式运用)-CSDN博客 模板列表 在后台系统中,…...
数据中心Overlay解决方案
文档围绕数据中心 Overlay 解决方案展开,指出数据中心向大集中、虚拟化、云业务演进,传统架构存在网络规划复杂、弹性不足、业务扩展受限等问题。Overlay 网络在物理网络上构建虚拟网络,实现名址分离、网络与物理解耦,支持业务灵活部署。方案采用VXLAN 技术(如 SDN 控制模…...
中级网络工程师知识点8
1.无线控制器:实现无线网络统一管理,无缝漫游 2.无线认证系统:实现用户使用用户名和密码认证登录,外来访客通过扫描二维码或者手机短信验证登录无线网络 3.POE交换机:实现无线AP的接入和供电 4.高密吸顶式AP&#x…...
【Linux笔记】——简单实习一个日志项目
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹: 【Linux笔记】——线程同步信号量与环形队列生产者消费者模型的实现(PV操作) 🔖流水不争…...
BRIGHTONE : 520-On-Chain WOHOO Carnival
BRIGHTONE is launching the “520-On-Chain WooHoo Carnival,” and the very first blast of $WOOHOO goes live right on schedule—ushering in a new on-chain celebration of joy! At exactly 21:09 on May 20, the “520-On-Chain WooHoo Carnival” officially kicks…...
在Java项目中集成Deepseek大语言模型实践指南
1. 引言 随着人工智能技术的发展,大语言模型在各领域应用日益广泛。本文将详细介绍如何在Java项目中集成Deepseek大模型,实现智能文本生成、对话等功能。 2. 前期准备 准备Java Spring Boot项目环境确保Maven已配置注册Deepseek账号并获取API密钥 获取a…...
医疗影像中,DICOM点云、三角面片实体混合渲染(VR)
此文章,涉及到专业性比较强,所以,大部分的内容,基本上都是示例代码的形式出现。以下的技术路径,完全经过实践验证,并且效果很好,可以放心使用。 1 概述 在医学影像中,对DICOM的渲染…...
程序运行报错分析文档
zryhuawei:~/src/modules/Connect$ ./newbuild/OpConnectAidTool \WARNING: MYSQL_OPT_RECONNECT is deprecated and will be removed in a future version. replace into process_tracking (step_id,date,status,context_data,start_time,end_time,error_log) values(?,?,?…...
C++数据结构——红黑树
文章目录 一、背景二、关键操作1. 旋转2. 变色3. 查找4. 插入5. 删除 三、面试考点 一、背景 红黑树(Red-Black Tree)是一种自平衡的二叉搜索树(BST),通过颜色标记和旋转操作保证树的高度平衡,从而确保插入…...
【Java实战】线程池 并发 并行 生命周期(详细解释)
线程池: 一种复用线程的技术 不使用线程池的问题: 用户每提出一个需求,都要创建一个新的线程。 创建线程池的方法: JDK 5.0起提供了一个代表线程池的接口:ExecutorService。 方式一: 使用ExecutorServic…...
Qwen3多方位评测
一、Qwen3核心优势 结论,针对这些场景:上下文理解、任务编排、工具调用、数据要素抽取等环节,Qwen3-32B已接近DeepSeek-R1。 二、关键测试环节 1、上下文改写 Qwen3-32B对绝对时间语境理解优于Qwen2.5-72B。 其余改写方面,三…...
银行反欺诈理论、方法与实践总结(下):解决方案
一、金融反欺诈防控体系 反欺诈防控体系是金融机构应对欺诈风险的重要工具,它通常包括事前识别、事中决策和事后处置三个关键阶段。 事前识别阶段:此阶段涉及欺诈情报的收集和账户安全的保护,通过名单和画像的构建来识别潜在风险。例如&…...
自回归图像编辑 EditAR: Unified Conditional Generation with Autoregressive Models
Paperhttps://arxiv.org/pdf/2501.04699 Code (coming soon) 目录 方法 实验 EditAR是一个统一的自回归框架,用于各种条件图像生成任务——图像编辑、深度到图像、边缘到图像、分割到图像。 next-token预测的功效尚未被证明用于图像编辑。 EditAR主要构建在Ll…...
Java中的集合详解
下面是文章详细介绍了 Java 集合框架的基本思路、主要接口与实现、各类集合之间的区别与各自的适用场景,以及一些常见的使用技巧和最佳实践,供你参考。 Java中的集合详解 在 Java 开发中,集合(Collection)作为存储和操…...
前端mjs和js文件区别,mjs和cjs区别---.es.js和.mjs的区别
https://www.cnblogs.com/jocongmin/p/18432236 同一份配置如下,一般打包出来的结果时是一样的,只不过扩展名不一样 export default defineConfig({build: {rollupOptions: {output: [// 同一份配置,仅扩展名不同{ format: es, entryFileNames: [name].mjs },{ fo…...
【深度学习】Transformer 的应用
目录 一、自然语言处理领域 1、自然语言处理领域的应用 2、BART模型 3、BERTSum模型与自动文本摘要 4、SG-Net与机器阅读理解 5、SG-Net的应用 6、总结 二、计算机视觉领域 1、图像分类 (1)背景与挑战 (2)Transformer的…...
C#学习10——泛型
一、什么是泛型? 官方理解:允许开发者在定义类、接口、方法或委托时使用类型参数 个人理解: 类型模具(类似Object变色龙) 二、泛型有什么用? 通过参数化类型实现代码复用,提升类型安全性并…...
Spring Validation校验
使用 JSR 303 (Bean Validation) 校验接口参数 JSR 303,也称为Bean Validation规范,提供了一种在Java应用程序中执行验证的标准化方式。它允许你通过注解直接在领域或者DTO(数据传输对象)类上定义校验规则。 1. 添加依赖 首先需…...
精益数据分析(72/126):MVP的核心法则——消除阻碍与聚焦关键指标
精益数据分析(72/126):MVP的核心法则——消除阻碍与聚焦关键指标 在创业领域,许多失败案例源于对产品开发的认知偏差——过度追求功能完善或盲目跟风增长,却忽略了用户核心需求的最直接满足。今天,我们结合…...
从头实现react native expo本地生成APK
根据github上老外的经验制作了一个react native expo项目起始模版,准备放到资源下载里(已经免积分放置好),这个起始模版带有个人非常喜欢的tailwindcss,由于raact native使用sheetstyle这种风格的样式,不太喜欢.当然,我们使用react native paper组件库时,就要对组件库里的组件使…...
打卡第二十三天
仔细回顾一下之前21天的内容,没跟上进度的同学补一下进度。 作业: 自行学习参考如何使用kaggle平台,写下使用注意点,并对下述比赛提交代码。 使用Kaggle平台的注意点 Kaggle是一个数据科学竞赛平台,提供了丰富的数据…...
关于汇编语言与接口技术——单片机串行口的学习心得
学习目标: 1.了解AT89S51单片机片内串行口的基本工作原理 2.掌握与串行口有关的特殊功能寄存器以及四种工作方式 一、串行口内部结构 单片机串行口有两个独立的接收、发送缓冲器SBUF,属于特殊功能寄存器,可以同时发送、接收数据;…...
汇川PLC通过Profinet转ModbusTCP网关读取西门子PLC数据案例
Modbus TCP主站即Modbus TCP客户端,Modbus TCP主站最多支持同时与31个Modbus TCP从站 。(Modbus TCP服务器)进行通信。 第一步设置PLC IP地址; 默认PLC IP地址为192.168.1.88。根据需要判断是否需要修改。 第二步添加Modbus TCP…...
2025-05-20 模型下载--文本向量化--Faiss检索
模型下载 使用Python脚本进行下载 from huggingface_hub import snapshot_download # import os# os.environ["HF_ENDPOINT"] "https://hf-mirror.com" # 自定义下载目录(Windows 路径建议用 raw string 或 pathlib) download_di…...