Unity Shader编程】之渲染流程之深度及pass详解
关于透明物体的渲染,首先需要了解以下部分
- 深度缓冲区
- 深度写入
- 深度测试
- pass
- 渲染和深度测试的过程
- 深度测试和颜色混合过程
**
一,深度缓冲区
**
深度即物体距离相机的距离,深度写入即是把物体的距离相机信息记录下来,写入一个名为深度缓冲区的
深度缓冲区解释
深度缓冲区(Depth Buffer),也称为Z缓冲区(Z Buffer),是计算机图形渲染中一个非常重要的概念。它主要用于处理三维场景中物体之间的前后遮挡关系,确保最终画面显示的像素是正确可见的。
什么是深度缓冲区?
深度缓冲区是一个与帧缓冲区(Frame Buffer)大小相同的缓冲区。帧缓冲区负责存储屏幕上每个像素的颜色信息,而深度缓冲区则存储每个像素的深度信息。深度信息通常表示该像素对应的物体到摄像机的距离(在摄像机空间中的Z坐标)。
深度缓冲区的工作原理
在渲染一个三维场景时,渲染管线会为每个物体的像素计算一个深度值,并通过**深度测试(Depth Test)**来决定哪些像素应该被绘制。具体过程如下:
-
计算像素深度值
当渲染一个物体时,渲染管线会计算该物体每个像素的深度值(Z值),表示该像素距离摄像机的远近。 -
读取深度缓冲区中的值
对于屏幕上的每一个像素位置,渲染管线会检查深度缓冲区中存储的当前深度值。
二,深度写入
前面的深度缓冲区,里面的深度值就是是否写入是由unity shader来控制是否写入进去,在深度缓冲区中,默认的无穷大的,只有开启深度写入之后,才会更新缓冲区里面的深度值,而是否开启深入写入,则是看你是否要覆盖掉之前的像素,
什么情况下要开启深度写入?
在渲染场景时,是否开启深度写入取决于具体的渲染需求和物体的属性。通常以下情况下需要开启深度写入:
-
不透明物体渲染:
对于不透明物体,开启深度写入是默认且推荐的设置。渲染不透明物体时,深度写入会更新深度缓冲区,记录每个像素的深度信息。这样可以确保物体之间的遮挡关系正确,例如近处的物体遮挡远处的物体。如果不开启深度写入,后续渲染的物体可能会错误地覆盖前面的物体,导致视觉上的遮挡错误。 -
确保前后关系正确:
开启深度写入的主要目的是让渲染管线能够正确处理物体之间的前后关系。特别是在复杂的3D场景中,不透明物体需要依靠深度缓冲区来维护遮挡的正确性。
判断是否应该开启深度写入的关键点是什么?
判断是否开启深度写入的关键在于以下两点:
-
物体的透明属性:
- 不透明物体:需要开启深度写入。不透明物体不涉及颜色混合,渲染时需要更新深度缓冲区,以确保它们能正确遮挡其他物体。
- 透明物体:通常关闭深度写入。透明物体需要与背景或其他物体进行颜色混合,如果开启深度写入,可能会错误地阻挡后续物体的渲染,导致混合效果无法实现。
-
渲染需求:
- 如果渲染的目标是确保遮挡关系(如不透明物体之间的层次),则需要开启深度写入。
- 如果渲染的目标是实现颜色混合(如透明物体的叠加效果),则需要关闭深度写入。
为什么关闭深度写入之后,不透明物体还能正常渲染混合?
关闭深度写入后,不透明物体在某些情况下仍然可以正常渲染,甚至看似实现了“混合”,原因如下:
-
深度测试依然生效:
关闭深度写入并不意味着关闭深度测试。深度测试会根据深度缓冲区中的已有值判断当前像素是否应该被绘制。只要深度测试通过,不透明物体的颜色就会覆盖帧缓冲区中的颜色,而不会涉及真正的混合(Blending)。因此,如果深度缓冲区的初始值和渲染顺序配置得当,不透明物体仍能按照预期显示。 -
渲染顺序的影响:
如果不透明物体按照从前到后的顺序渲染,即使关闭了深度写入,后渲染的物体仍然可以覆盖前面的像素。这种情况下,渲染结果可能看起来是正确的。但如果顺序错误(例如从后到前),遮挡关系就会出现问题,导致视觉错误。 -
混合设置未启用:
不透明物体通常不使用混合功能(Blending),它们的颜色会直接覆盖帧缓冲区中的像素。因此,即使关闭深度写入,只要深度测试和渲染顺序得当,渲染结果可能仍然正常。但这并不意味着不透明物体真正实现了“混合”,因为混合是指透明物体特有的颜色叠加效果。
为什么不推荐关闭深度写入用于不透明物体?
尽管在特定条件下不透明物体关闭深度写入仍能渲染,但这种做法不推荐,原因包括:
- 遮挡错误风险:如果渲染顺序不正确,后渲染的物体可能错误地覆盖前面的物体,导致遮挡关系混乱。
- 性能问题:关闭深度写入可能导致更多的像素被绘制(过绘制),从而降低渲染效率。
- 不可预测性:依赖渲染顺序和深度测试的配置增加了复杂性,可能在不同场景下产生不可预测的结果。
总结
- 开启深度写入适用于不透明物体,以确保正确的遮挡关系。
- 关闭深度写入适用于透明物体,以实现颜色混合效果。
- 判断的关键点是物体的透明属性和渲染需求。
- 关闭深度写入后,不透明物体可能因深度测试和渲染顺序而正常渲染,但这种配置不稳定且不推荐。
三,深度测试
在Unity中,深度测试(Depth Testing)是通过比较每个像素的深度值来判断该像素是否应该被渲染的过程。每个像素有一个深度值,表示它距离观察者的远近。深度测试的目的是确保只有在正确的渲染顺序下显示物体,通常用于处理物体的遮挡关系。深度测试是默认开启的,如果要关闭,继续看下面
在Shader编程中,深度测试的判断过程是由GPU自动完成的,但它是通过比较当前片段(像素)的深度值与深度缓冲区中已存在的深度值来进行的。
深度测试的基本工作流程:
深度值计算:每个片段(像素)在屏幕空间中都有一个深度值。这个深度值是通过将物体的3D坐标转换到屏幕空间(通常是透视投影后)来得到的。
深度比较:深度测试会根据预设的深度比较函数(Depth Comparison Function)来决定该片段是否通过深度测试。常见的深度比较函数有:
-
Less(小于):如果当前片段的深度值小于缓冲区中的深度值,则该片段通过深度测试。
-
Greater(大于):如果当前片段的深度值大于缓冲区中的深度值,则该片段通过深度测试。
-
Equal(等于):如果当前片段的深度值等于缓冲区中的深度值,则该片段通过深度测试。
-
Lequal(小于等于):如果当前片段的深度值小于或等于缓冲区中的深度值,则该片段通过深度测试。
-
Gequal(大于等于):如果当前片段的深度值大于或等于缓冲区中的深度值,则该片段通过深度测试。
-
Never(从不):永远不会通过深度测试。
-
Always(始终通过):总是通过深度测试。
通过与否:如果当前片段通过深度比较(比如在使用“Less”时,当前片段的深度值小于缓冲区中的值),该片段就会被渲染出来,并且其深度值会被更新到深度缓冲区中;如果不通过,片段就会被丢弃,不会被渲染。
以上是深度测试的一些比较,来判断是否通过深度测试,那么,是否有其他方式来控制深度测试是否通过
在Unity的Shader中,通常深度测试是由GPU自动进行的,但你确实可以通过一些设置来手动控制是否通过深度测试。这通常是通过改变 ZTest
和 ZWrite
的行为,或者直接控制深度缓冲区来实现的。
以下是几种手动控制的方式:
1. 禁用深度测试(不进行深度比较)
你可以禁用深度测试,让渲染过程不依赖深度缓冲区进行深度比较,完全不做遮挡判断。这样所有物体都会被渲染,不管它们是否被其他物体遮挡。
Shader "Custom/NoDepthTest"
{SubShader{Pass{// 禁用深度测试,所有片段都会通过ZTest Always// 禁用深度写入,确保不会更新深度缓冲区ZWrite Off// 其他渲染设置CGPROGRAM// shader代码ENDCG}}
}
ZTest Always
使得所有片段都通过深度测试,无论它们的深度值是多少。这意味着所有物体都会被渲染出来。
2. 完全关闭深度写入
如果你只想禁用深度写入,而依然保持深度测试,这样就不会影响深度缓冲区的内容,但仍然会执行深度比较,允许物体依然受到遮挡影响。
Shader "Custom/NoDepthWrite"
{SubShader{Pass{ZTest Less // 可以使用任何你想要的深度比较ZWrite Off // 禁用深度写入// 其他渲染设置CGPROGRAM// shader代码ENDCG}}
}
在这种情况下,深度测试仍然存在,但是不会修改深度缓冲区,因此可能会出现一些不希望的渲染效果,比如物体不被正确遮挡。
3. 手动修改深度值
你可以在片段着色器中手动修改深度值。通过 SV_Position
中的 z
值(即深度值),你可以直接控制它,从而影响深度测试的结果。例如,改变 z
值来决定片段是否通过深度测试。
void frag(v2f i) : SV_Target
{float depth = i.pos.z / i.pos.w; // 计算深度// 手动设置深度值(注意:这里可能会影响后续的渲染,可能导致一些视觉问题)gl_FragDepth = depth;return color;
}
4. 通过Discard
来手动丢弃片段
你可以在片段着色器中使用 discard
命令来手动丢弃某些片段,使其不通过渲染管线。这是一种直接控制哪些片段渲染、哪些片段丢弃的方式。通常结合自定义的深度条件来实现:
void frag(v2f i) : SV_Target
{if (i.pos.z > 0.5) // 你可以设置自己的条件来丢弃片段{discard; // 丢弃该片段}return color; // 渲染其他片段
}
5. 深度测试的替代方法:通过自定义遮挡判断
如果你希望控制遮挡而不使用传统的深度测试,可以通过其他方式来实现,比如通过自定义的屏幕空间遮挡算法、碰撞检测等方法来决定是否渲染某个物体,而不依赖GPU的深度测试。
6. 在某些特定情况下绕过深度测试
比如在渲染透明物体时,通常你会关闭深度写入,避免透明物体更新深度缓冲区。但深度测试通常仍然开启。若透明物体只需依赖“无深度测试”或“深度比较”来控制顺序,手动干预可以确保它们正确排序:
Shader "Custom/TransparentNoDepthTest"
{SubShader{Pass{// 关闭深度写入,同时使用深度比较ZWrite OffZTest LEqualBlend SrcAlpha OneMinusSrcAlpha// 其他设置CGPROGRAM// shader代码ENDCG}}
}
总结:
手动不通过深度测试的方式可以通过禁用深度测试、控制深度写入、在片段着色器中使用 discard
,或者手动修改深度值等方法来实现。你可以根据具体需要选择其中一种或多种方式来控制渲染的行为。
你有什么具体的应用场景或效果需要实现吗?我可以帮你提供更详细的实现建议。
在物体通过测试之后才会进行深度写入
四,pass
在Unity Shader中,Pass 是定义渲染操作的核心单元,每个Pass对应一次完整的绘制流程。以下是关于Pass的详细解析:
在Unity Shader中,Pass 是定义渲染操作的核心单元,每个Pass对应一次完整的绘制流程。以下是关于Pass的详细解析:
Pass的作用
多次渲染叠加效果:每个Pass执行一次物体渲染,多个Pass可叠加效果(如先绘制漫反射,再叠加高光)。
独立配置渲染状态:每个Pass可自定义剔除、深度测试、混合模式等,实现不同阶段的渲染需求。
支持不同光照模式:通过LightMode标签适配渲染路径(如前向渲染中的主光源和附加光源)。
Pass的结构
glsl
Copy Code
Pass {
// 1. 标签(定义渲染阶段)
Tags { “LightMode” = “ForwardBase” }
// 2. 渲染状态配置
Cull Off
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha// 3. 着色器代码
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// ... 顶点/片段着色器代码
ENDCG
}
关键组成部分
Tags
控制Pass在渲染管线中的执行时机。常见标签:
“LightMode”:指定光照模式(如ForwardBase、ForwardAdd、ShadowCaster)。
“Queue”:定义渲染顺序(需谨慎使用,通常作用于SubShader层级)。
“RenderType”:用于Shader替换或后处理筛选。
渲染状态
Cull:设置剔除模式(Back/Front/Off)。
ZWrite:控制深度写入(On/Off)。
Blend:定义混合模式(如透明度混合)。
其他:ZTest、Stencil、ColorMask等。
着色器代码
使用CGPROGRAM或HLSLPROGRAM编写顶点/片段着色器逻辑。
不同Pass可复用代码,也可完全独立。
Pass的类型
常规Pass
直接编写渲染逻辑,处理颜色、光照等效果。
UsePass
复用其他Shader中的Pass,需通过大写名称引用:
glsl
Copy Code
UsePass “ShaderName/PASS_NAME”
GrabPass
抓取屏幕内容到纹理,用于折射、扭曲等效果:
glsl
Copy Code
GrabPass { “_MyGrabTexture” }
性能注意事项
减少Pass数量:过多的Pass会增加Draw Call,尤其在移动端需优化。
合并渲染逻辑:尽量在单个Pass中完成复杂计算(如多光源处理)。
合理使用标签:避免不必要的渲染阶段调用。
执行顺序与继承
顺序执行:Pass按在Shader中的书写顺序依次执行。
状态独立性:每个Pass的渲染状态独立配置,不继承其他Pass的设置(默认值由Unity或SubShader定义)。
特殊用途Pass
ShadowCaster:生成深度纹理用于阴影计算。
MotionVectors:处理运动模糊的移动矢量数据。
Deferred:在延迟渲染路径中处理GBuffer填充。
示例:多Pass叠加高光
glsl
Copy Code
Shader “Custom/MultiPassExample” {
SubShader {
// Pass 1:基础漫反射
Pass {
Tags { “LightMode” = “ForwardBase” }
CGPROGRAM
// 计算漫反射光照
ENDCG
}
// Pass 2:附加高光Pass {Tags { "LightMode" = "ForwardAdd" }Blend One One // 叠加模式CGPROGRAM// 计算高光ENDCG}
}
}
通过合理设计Pass结构,开发者能实现复杂的渲染效果,同时平衡性能与视觉表现。理解Pass的配置和执行逻辑是掌握Unity Shader编写的重要基础。
在Unity中,渲染顺序遵循队列分组执行原则,而非按Pass连续执行。具体规则如下:
- 全局渲染流程
阶段一:渲染所有不透明物体(队列 ≤ 2500)
执行所有标记为"Queue"=“Geometry”(2000)、“Queue”=“AlphaTest”(2450)的物体。
执行顺序:从近到远(Early-Z优化,减少Overdraw)。
每个物体的Pass按Shader中的书写顺序执行,但仅处理不透明Pass(若存在多个Pass,需通过标签控制)。
阶段二:渲染所有透明物体(队列 ≥ 3000)
执行所有标记为"Queue"=“Transparent”(3000)的物体。
执行顺序:从远到近(确保混合顺序正确)。
透明物体的Pass按Shader顺序执行,但需关闭深度写入(ZWrite Off)并启用混合(如Blend)。
2. 跨物体Pass执行示例
假设场景中有两个物体:
物体A:包含1个不透明Pass(队列Geometry) + 1个透明Pass(队列Transparent)。
物体B:仅包含1个不透明Pass(队列Geometry)。
实际渲染流程:
plaintext
Copy Code
-
阶段一(不透明物体):
- 物体B的不透明Pass
- 物体A的不透明Pass(若其队列设为Geometry)
-
阶段二(透明物体):
- 物体A的透明Pass(若其队列设为Transparent)
-
关键规则总结
行为 是否允许 注意事项
同一物体内混合不透明+透明Pass 允许,但需分属不同队列 需拆分材质,避免同一Shader同时处理两种类型(否则队列冲突)
透明Pass在不透明队列执行 技术上可行,但会导致混合错误 透明效果可能被后续不透明物体覆盖,需强制设为Transparent队列
不透明Pass在透明队列执行 不推荐 深度测试可能失效,破坏Early-Z优化 -
正确配置示例
场景需求
一个角色同时包含不透明的盔甲和透明的护盾,需分别渲染。
Shader分拆方案
glsl
Copy Code
// 盔甲材质(不透明)
Shader “Armor” {
SubShader {
Tags { “Queue” = “Geometry” }
Pass {
ZWrite On
// 不透明着色逻辑…
}
}
}
// 护盾材质(透明)
Shader “Shield” {
SubShader {
Tags { “Queue” = “Transparent” }
Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
// 透明着色逻辑…
}
}
}
- 常见错误与修复
错误现象
透明物体被不透明物体遮挡,但期望显示在前。
原因分析
透明物体的队列未设为Transparent(停留在默认的Geometry队列)。
同一Shader中不透明与透明Pass未分拆,导致队列冲突。
修复步骤
将透明材质独立为单独Shader,设置"Queue"=“Transparent”。
确保透明Pass关闭深度写入:ZWrite Off。
使用Frame Debugger验证Draw Call顺序。
6. 性能与质量权衡
策略 优点 缺点
分拆材质(推荐) 队列清晰,避免混合冲突 增加Draw Call
同一Shader多Pass 减少Draw Call 需严格管理队列标签,易引发深度/混合问题
结论
Unity的渲染顺序严格按队列分组执行,而非连续执行同一物体的所有Pass。要实现不透明与透明效果的正确叠加,必须:
将不透明与透明物体分属不同队列。
确保透明物体在Transparent队列中按从远到近渲染。
避免在同一Shader内混用不透明与透明Pass(除非明确控制队列标签)。
通过合理分拆材质与配置队列,可确保渲染效果与性能的最佳平衡。
五,渲染和深度测试的过程
应用阶段(CPU) → 顶点处理(GPU) → 光栅化(GPU) → 片元处理(含深度测试) → 帧缓冲输出
六,深度测试和颜色混合过程
在渲染透明物体(如玻璃)时,涉及到深度测试和颜色混合的过程。以下是针对你问题的详细解答:
渲染和深度测试的过程
-
墙的渲染:
- 墙是不透明物体,通常会先渲染。
- 渲染时,墙的颜色会被写入帧缓冲区,同时其深度值会被写入深度缓冲区。
- 墙开启了深度写入功能,确保后续物体在深度测试中能正确判断前后关系。
-
玻璃的渲染:
- 玻璃是透明物体,通常在不透明物体(如墙)渲染完成后才进行渲染。
- 玻璃关闭了深度写入功能(即不会更新深度缓冲区),但会进行深度测试:
- 如果玻璃的像素深度值小于深度缓冲区中的值(即玻璃在墙前面),通过深度测试,该像素会被绘制。
- 如果玻璃的像素深度值大于深度缓冲区中的值(即玻璃在墙后面),不通过深度测试,该像素不会被绘制。
颜色混合的过程
当玻璃的像素通过深度测试(即确定在墙前面)时,它的颜色需要与帧缓冲区中已有的颜色(例如墙或背景的颜色)进行混合。这种混合并不是简单相加,而是使用 Alpha Blending 技术。
Alpha Blending 的原理
Alpha Blending 是图形渲染中最常用的透明混合方法。它通过透明度(Alpha 值)对两种颜色进行加权混合:
- 源颜色:玻璃的颜色,用 ((R_s, G_s, B_s)) 表示,Alpha 值为 (A_s)(范围 0 到 1,0 表示完全透明,1 表示完全不透明)。
- 目标颜色:帧缓冲区中已有的颜色(例如墙的颜色),用 ((R_d, G_d, B_d)) 表示。
- 混合公式:
[
R = R_s \times A_s + R_d \times (1 - A_s)
]
[
G = G_s \times A_s + G_d \times (1 - A_s)
]
[
B = B_s \times A_s + B_d \times (1 - A_s)
]
最终颜色 ((R, G, B)) 是源颜色和目标颜色的加权和,权重由玻璃的 Alpha 值 (A_s) 决定。
举个例子
假设:
- 玻璃的颜色是浅蓝色 ((R_s, G_s, B_s, A_s) = (0, 0.5, 1, 0.5))(Alpha 为 0.5 表示半透明)。
- 墙的颜色是灰色 ((R_d, G_d, B_d) = (0.5, 0.5, 0.5))。
混合后的颜色计算如下: - (R = 0 \times 0.5 + 0.5 \times (1 - 0.5) = 0 + 0.25 = 0.25)
- (G = 0.5 \times 0.5 + 0.5 \times (1 - 0.5) = 0.25 + 0.25 = 0.5)
- (B = 1 \times 0.5 + 0.5 \times (1 - 0.5) = 0.5 + 0.25 = 0.75)
最终颜色为 ((0.25, 0.5, 0.75)),呈现出玻璃和墙颜色融合后的效果。
为什么不是简单相加?
你可能会想,为什么不直接把玻璃的颜色和背景颜色相加(例如 (R_s + R_d, G_s + G_d, B_s + B_d))?原因如下:
- 颜色溢出:简单相加可能导致颜色值超过 1(例如 (0.5 + 0.6 = 1.1)),这在渲染中是不合法的,会导致不自然的效果。
- 透明度失控:简单相加无法反映玻璃的透明程度(Alpha 值),而 Alpha Blending 通过 (A_s) 和 (1 - A_s) 的权重,精确控制了玻璃对背景的“遮挡”程度,呈现出真实的透明感。
总结
- 玻璃在墙前面时,通过深度测试的像素会被绘制。
- 绘制时,玻璃的颜色与背景颜色通过 Alpha Blending 混合,而不是简单相加。
- 混合公式是加权和,权重由玻璃的 Alpha 值决定,确保透明效果自然且符合视觉预期。
相关文章:
Unity Shader编程】之渲染流程之深度及pass详解
关于透明物体的渲染,首先需要了解以下部分 深度缓冲区深度写入深度测试pass渲染和深度测试的过程深度测试和颜色混合过程 ** 一,深度缓冲区 ** 深度即物体距离相机的距离,深度写入即是把物体的距离相机信息记录下来,写入一个名…...
【算法笔记】图论基础(一):建图、存图、树和图的遍历、拓扑排序、最小生成树
目录 何为图论图的概念 图的一些基本概念有向图和无向图带权图连通图和非连通图对于无向图对于有向图 度对于无向图对于有向图一些结论 环自环、重边、简单图、完全图自环重边简单图 稀疏图和稠密图子图、生成子图同构 图的存储直接存边邻接矩阵存边邻接表存边链式前向星存边 图…...
Compose 原理解析
Compose 的组件都是放在 setContent() 之后才能显示的,那需要先看看这个函数的作用。 先看 ComponentActivity 的扩展函数 setContent(): /*** 将给定的可组合项合成到给定的 Activity 中。[content] 将成为给定 Activity 的根视图。* 这大致相当于使用…...
pyspark学习rdd处理数据方法——学习记录
python黑马程序员 """ 文件,按JSON字符串存储 1. 城市按销售额排名 2. 全部城市有哪些商品类别在售卖 3. 上海市有哪些商品类别在售卖 """ from pyspark import SparkConf, SparkContext import os import jsonos.environ[PYSPARK_P…...
个人学习编程(3-22) leetcode刷题
连续子数组:(难) 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。 示例 2: 输入: nums [0,1,0] 输出: 2 说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。 需要理解的知识&a…...
RabbitMQ八股文
RabbitMQ 核心概念与组件 1. RabbitMQ 核心组件及其作用 1.1 生产者(Producer) 作用:创建并发送消息到交换机。特点:不直接将消息发送到队列,而是通过交换机路由。 1.2 交换机(Exchange) 作…...
运维面试题(七)
1.statefulset用来管理有状态的应用程序,有状态是什么意思? 每一个pod都有一个固定的网络标识符,在整个生命周期中不会改变。每个实例都可以拥有自己的持久化存储卷,即使容器被删除并重新创建,存储卷仍然存在。Statef…...
【项目设计】网页版五子棋
文章目录 一、项目介绍1.项目简介2.开发环境3.核心技术4.开发阶段 二、Centos-7.6环境搭建1.安装wget工具2.更换软件源(yum源)3.安装scl工具4.安装epel软件源5.安装lrzsz传输工具6.安装高版本gcc/g编译器7.安装gdb调试器8.安装git9.安装cmake10.安装boost库11.安装Jsoncpp库12.…...
Netty——BIO、NIO 与 Netty
文章目录 1. 介绍1.1 BIO1.1.1 概念1.1.2 工作原理1.1.3 优缺点 1.2 NIO1.2.1 概念1.2.2 工作原理1.2.3 优缺点 1.3 Netty1.3.1 概念1.3.2 工作原理1.3.3 优点 2. Netty 与 Java NIO 的区别2.1 抽象层次2.2 API 易用性2.3 性能优化2.4 功能扩展性2.5 线程模型2.6 适用场景 3. 总…...
Docker 安装 Mysql
以下是安装Docker版MySQL 8.0.25并实现目录挂载的步骤: docker仓库:https://hub.docker.com/_/mysql 1. 拉取Mysql镜像文件 docker pull mysql:8.0.252. 创建mysql临时容器服务 docker run -d \--name mysql \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD123…...
Electron打包文件生成.exe文件打开即可使用
1 、Electron 打包,包括需要下载的内容和环境配置步骤 注意:Electron 是一个使用 JavaScript、HTML 和 CSS 构建跨平台桌面应用程序的框架 首先需要电脑环境有Node.js 和 npm我之前的文章有关nvm下载node的说明也可以去官网下载 检查是否有node和npm环…...
线程和协程的区别了解
1.资源消耗 调度方式:线程由操作系统内核调度(抢占式),协程由程序自己控制调度(协作式)。切换开销:线程切换涉及内核态与用户态的转换,开销大;协程只在用户态切换上下文…...
楼宇自控系统的结构密码:总线与分布式结构方式的差异与应用
在现代建筑中,为了实现高效、智能的管理,楼宇自控系统变得越来越重要。它就像建筑的 智能管家,可自动控制照明、空调、通风等各种机电设备,让建筑运行更顺畅,还能节省能源成本。而在楼宇自控系统里,有两种关…...
算法及数据结构系列 - 滑动窗口
系列文章目录 算法及数据结构系列 - 二分查找 算法及数据结构系列 - BFS算法 算法及数据结构系列 - 动态规划 算法及数据结构系列 - 双指针 算法及数据结构系列 - 回溯算法 算法及数据结构系列 - 树 文章目录 滑动窗口框架思路经典题型76. 最小覆盖子串567. 字符串的排列438. …...
【江协科技STM32】软件SPI读写W25Q64芯片(学习笔记)
SPI通信协议及S为5Q64简介:【STM32】SPI通信协议&W25Q64Flash存储器芯片(学习笔记)-CSDN博客 STM32与W25Q64模块接线: SPI初始化: 片选SS、始终SCK、MOSI都是主机输出引脚,输出引脚配置为推挽输出&…...
2025.3.23机器学习笔记:文献阅读
2025.3.23周报 题目信息摘要Abstract创新点网络架构实验不足以及展望 题目信息 题目: Enhancement of Hydrological Time Series Prediction with Real-World Time Series Generative Adversarial Network-Based Synthetic Data and Deep Learning Models期刊&…...
Day20-前端Web案例——部门管理
目录 部门管理1. 前后端分离开发2. 准备工作2.1 创建Vue项目2.2 安装依赖2.3 精简项目 3. 页面布局3.1 介绍3.2 整体布局3.3 左侧菜单 4. Vue Router4.1 介绍4.2 入门4.3 案例4.4 首页制作 5. 部门管理5.1部门列表5.1.1. 基本布局5.1.2 加载数据5.1.3 程序优化 5.2 新增部门5.3…...
实验3 以太坊交易周期的需求分析
区块链技术 实验报告 实验名称 实验3 以太坊交易周期的需求分析 一、实验目的 1、学习并掌握以太坊交易的内容; 2、学习并掌握以太坊交易周期的四个阶段; 3、学习并掌握结构化需求分析方法; 4、学习并掌握面向对象的需求分析方法&…...
Linux 通过压缩包安装 MySQL 并设置远程连接教程
一、引言 在 Linux 系统中,有时候我们需要通过压缩包的方式手动安装 MySQL 数据库,并且为了方便在其他设备上对数据库进行管理和操作,还需要设置允许远程连接。本文将详细介绍在 Linux(以 CentOS 为例)系统中通过压缩包安装 MySQL 8 并设置远程连接的步骤。 二、安装前准…...
【商城实战(56)】商城数据生命线:恢复流程与演练全解析
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
Java学习笔记-XXH3哈希算法
XXH3是由Yann Collet设计的非加密哈希算法,属于XXHash系列的最新变种,专注于极速性能与低碰撞率,适用于对计算效率要求极高的场景。 极速性能 在RAM速度限制下运行,小数据(如 1-128 字节)处理可达纳秒级&…...
同旺科技USB to SPI 适配器 ---- 指令循环发送功能
所需设备: 内附链接 1、同旺科技USB to SPI 适配器 1、周期性的指令一次输入,即可以使用 “单次发送” 功能,也可以使用 “循环发送” 功能,大大减轻发送指令的编辑效率; 2、 “单次发送” 功能,“发送数据…...
在Mac M1/M2芯片上完美安装DeepCTR库:避坑指南与实战验证
让推荐算法在Apple Silicon上全速运行 概述 作为推荐系统领域的最经常用的明星库,DeepCTR集成了CTR预估、多任务学习等前沿模型实现。但在Apple Silicon架构的Mac设备上,安装过程常因ARM架构适配、依赖库版本冲突等问题受阻。本文通过20次环境搭建实测…...
【CXX-Qt】2.5 继承
某些 Qt API 要求你从抽象基类中重写某些方法,例如 QAbstractItemModel。 为了支持直接从 Rust 中创建这样的子类,CXX-Qt 提供了多种辅助工具。 某些基类可能需要特殊的构造参数。这可以通过使用自定义构造函数来实现。 访问基类方法 要在 Rust 中访…...
Linux系统之美:环境变量的概念以及基本操作
本节重点 理解环境变量的基本概念学会在指令和代码操作上查询更改环境变量环境变量表的基本概念父子进程间环境变量的继承与隔离 一、引入 1.1 自定义命令(我们的exe) 我们以往的Linux编程经验告诉我们,我们在对一段代码编译形成可执行文件后…...
【nnUnetv2】推理+评估+测试
在 Windows 系统下设置环境变量 之前训练和推理的时候开着AutoDL的服务器,是在 Linux 系统下设置的环境变量。 但是现在开始研究具体代码了,就在本地跑(一直开着服务器有点费钱),所以就在Windows 系统下设置环境变量。 ①右键点击 “此电脑”,选择 “属性”。 ②在左侧…...
损失函数理解(一)——极大似然估计
本博客内容来自B站up主【王木头学科学】的视频内容 习惯看视频的小伙伴可移至视频链接[待补充]:~~~ 首先通俗地解释一下极大似然估计(Maximum Likelihood Estimation,MLE)的思想:通过结果寻找使该结果发生的最可能的原…...
ios端使用TCplayer直播播放三秒直接卡顿bug
1. 查看配置项没问题 setTcPlayer() {let that this;player new TcPlayer("videoPlayer", {live: this.activatPlayType "livePlay" ? true : false,x5_type: "h5",x5_fullscreen: true,systemFullscreen: true,x5_orientation: 1,x5_player…...
大模型-提示词工程与架构
什么是提示工程 提示工程(Prompt Engineering)是一门新兴的技术领域,专注于研究如何设计、构建和优化提示词,以充分发挥大模型的潜力 。它涉及到对语言结构、任务需求、模型特性等多方面因素的综合考量。提示工程的目标是通过精心…...
高斯数据库-WDR Snapshot生成性能报告
docker 安装高斯数据库: docker pull opengauss/opengauss:latestdocker run --name opengauss --privilegedtrue -d -e GS_PASSWORDopenGauss123 -p 8090:5432 -v /opengauss:/var/lib/opengauss/data opengauss/opengauss:latest 进入容器设置用户权限ÿ…...
损失函数理解(二)——交叉熵损失
损失函数的目的是为了定量描述不同模型(例如神经网络模型和人脑模型)的差异。 交叉熵,顾名思义,与熵有关,先把模型换成熵这么一个数值,然后用这个数值比较不同模型之间的差异。 为什么要做这一步转换&…...
CSS学习笔记
【1】CSS样式规则 【2】CSS样式表引入方式 1、行内式 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"/><meta name"vi…...
AI比人脑更强,因为被植入思维模型【15】马斯洛需求层次理论
马斯洛需求层次模型思维模型 定义 马斯洛需求层次模型是由美国心理学家亚伯拉罕马斯洛(Abraham Maslow)于1943年提出的一种心理学理论,用于描述人类动机的层次结构。该模型将人类的需求从低到高分为五个层次,分别是生理需求、安…...
cartographer中地图转换
文章目录 地图种类栅格地图 坐标系种类ros坐标系像素坐标系物理坐标系(世界坐标系) 地图种类 栅格地图 地图的初始化 在Cartographer中,栅格地图通过概率值来表示每个栅格的状态。每个栅格的初始概率值通常设置为0.5,表示未知状态。这种初始化方式允许…...
关于MTU的使用(TCP/IP网络下载慢可能与此有关)
参考链接:告诉你mtu值怎么设置才能网速最好! -Win7系统之家 出现网络速度被限制,可能与MTU值相关,先查看下本机的MTU winR,然后输入:netsh interface ipv4 show subinterfaces ,查看自己网络中的MTU&…...
【AI解题】Cache直接映射地址划分解析
一、问题背景 某32位总线处理器的Cache采用直接映射方式,已知 Cache总容量为16KB,每个Cache块大小为16字节。需要确定内存地址中 Offset(块内偏移)、Index(块索引)、Tag(标签) 三部…...
android音频概念解析
音频硬件接口(我们可以理解为ASOC的声卡) 官方代码里叫audio hardware interface 也称为module,定义在services/audiopolicy/config/audio_policy_configuration.xml: 分别有primary,a2dp,usb࿰…...
项目生命周期 和 项目管理生命周期的差异
在项目管理中,明确区分 项目生命周期 和 项目管理生命周期 是理解项目运作的关键。以下从定义、阶段划分到实际应用进行系统性分析: 一、项目生命周期(Project Life Cycle) 定义 项目生命周期是项目从 启动到结束 的自然演进过程,描述项目交付成果的 技术性阶段,通常与…...
UDP 协议
文章目录 UDP 协议简介数据包格式UDP 通信流程抓包分析参考 本文为笔者学习以太网对网上资料归纳整理所做的笔记,文末均附有参考链接,如侵权,请联系删除。 UDP 协议 UDP 是一种面向无连接的传输层协议,属于 TCP/IP 协议簇的一种。…...
[已解决]jupyter notebook报错 500 : Internal Server Error及notebook闪退
jupyter notebook出现如上图的报错,可以在黑色窗口中检查是为什么报错。 我检查发现是nbconvert导致的问题,卸载重装nbconvert。 但是这时候出现,jupyter notebook闪退问题。jupyter的黑色窗口出现一秒钟就没了。 在Anaconda Prompt中检查ju…...
APM 仿真遥控指南
地面站开发了一段时间了,由于没有硬件,所以一直在 APM 模拟器中验证。我们已经实现了 MAVLink 消息接收和解析,显示无人机状态,给无人机发送消息,实现一键起飞,飞往指定地点,降落,返…...
使用 ncurses 库创建文本用户界面:基础函数详解
简介 ncurses 是一个功能强大的库,用于在 Unix-like 系统中创建文本用户界面。它提供了丰富的函数来控制屏幕上的文本显示、处理键盘输入、绘制图形元素等。本文将详细介绍 ncurses 库中的一些基础函数,包括 printw、wrefresh、获取用户信息、键盘输入、…...
dify创建第一个Agent
1、首先LLM模型必须支持 Function Calling 由于deepseek-R1本地化部署时还不支持,所以使用 qwq模型。 2、创建空白 Agent 3、为Agent添加工具 4、测试 当未添加时间工具时 询问 时间 如下 5、开启时间工具 询问如下...
nebula graph传统使用Docker进行项目发版
nebula graph传统使用Docker进行项目发版 1. nebula graph服务2. 搭建ES集群3. 注意事项3.1 图数据库的启动顺序3.2 模糊查询失效 1. nebula graph服务 1.在测试服务器中执行如下命令 docker commit 85b6e2b8xxx xxx_nebula_es:1.0.0.2执行docker images之后能看到新的镜像 x…...
OpenCV vs MediaPipe:哪种方案更适合实时手势识别?
引言 手势识别是计算机视觉的重要应用,在人机交互(HCI)、增强现实(AR)、虚拟现实(VR)、智能家居控制、游戏等领域有广泛的应用。实现实时手势识别的技术方案主要有基于传统计算机视觉的方法&am…...
PRODIGY: “不折腾人”的蛋白-蛋白/蛋白-小分子结合能计算工具
PRODIGY(全称为 PROtein binDIng enerGY prediction)是一种蛋白质结合能预测工具,可利用蛋白质-蛋白质复合物的三维结构来预测其结合亲和力。PRODIGY 利用一种高效的基于接触的方法,在估计结合自由能和解离常数的同时,…...
IDEA修改默认作者名称
User: IDEA提示注释缺少author信息,但自动设置后,名称不是我想要的默认名称,应该如何修改IDEA里默认的作者名称? Kimi: 以下是几种修改IntelliJ IDEA中默认作者名称的方法: ### 方法一:修改File and Code …...
【嵌入式学习2】C语言 - VScode环境搭建
目录 ## 语言分类 ## c语言编译器 ## VScode相关配置 ## 语言分类 编译型语言:C,C解释型语言:python,JS ## c语言编译器 分类GCC 系列MinGWCygwinMSVC系列一套编程语言编译器将GCC编译器和GNU Binutils移植到Win32平台下的产物…...
【TI MSPM0】Timer学习
一、计数器 加法计数器:每进入一个脉冲,就加一减法计算器:每进入一个脉冲,就减一 当计数器减到0,触发中断 1.最短计时时间 当时钟周期为1khz时,最短计时时间为1ms,最长计时时间为65535ms 当时…...
SQL Server数据库慢SQL调优
SQL Server中慢SQL会显著降低系统性能并引发级联效应。首先,用户直接体验响应时间延长,核心业务操作(如交易处理、报表生成)效率下降,导致客户满意度降低甚至业务中断。其次,资源利用率失衡,CPU…...