Unity编写Shader基本知识

这篇具有很好参考价值的文章主要介绍了Unity编写Shader基本知识。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

返回目录

大家好,我是阿赵。
这里通过手写一个最简单的shader,来介绍一下在Unity里面编写Shader的一些基础知识。

一、Shader基本结构

新建一个shader,把里面的内容都删掉,然后输入下面这些内容

shader "testShader"
{
	Properties
	{

	}
	SubShader
	{
		Pass
		{

		}
	}
}

可以发现,现在这个Shader就已经能运作了,新建一个材质球,使用刚才写的shader,然后赋给一个Cube,可以看到Cube被正常的显示出来
Unity编写Shader基本知识

只是这时候Cube的颜色是一片纯白,也没有光影的效果
分析一下上面的Shader结构,可以看到,
1、在最开始的shader单词后面跟着一个字符串shader “testShader”,那个testShaderr就是Shader的名字,这个名字用于Shader的查找,可以用斜杠作为目录,比如shader “azhao/testShader”
2、Properties结构体,这里是声明Shader对外显示的属性
3、SubShader结构体,子渲染器,一个Shader可以包含多个SubShader,至少要有一个
4、Pass结构体,语义块,通常一个Pass就代表了一次的渲染。一个SubShader里面可以包含多个Pass,至少要有一个Pass

二、对外属性

写在Properties结构体里面的属性,用于暴露给玩家修改的属性
类型:

1、数字类型

(1)Float:浮点
(2)Int:整型
(3)Range:数值范围

2、四元数和颜色

(1)Color
(2)Vector
都是用(number,number,number,number)的形式来表示

3、贴图类

(1)2D
(2)Cube
(3)3D
都是用”默认颜色”{}来表示
代码举例:

Properties
{
_floatVal(“浮点变量”,Float) = 0
_intVal(“整型变量”,Int) = 1
_rangeVal(“数值范围”,Range(0,1)) = 0

_col("颜色",Color) = (1,1,1,1)
_vectVal("四元数",Vector) = (0,0,0,0)

_2dTex("2D贴图",2D) = "white"{}
_cubeTex("Cube贴图",Cube) = "green"{}
_3dTex("3D贴图",3D) = "black"{}

}

效果:
Unity编写Shader基本知识

可以看出,一行属性的构成是:变量名(“显示名称”,类型) = 默认值

定义了的变量,如果要在Pass里面使用,还需要在Pass里面再声明一次和Properties里面一样的名字,这个在下面CG代码再说明

三、CG代码和各种定义

1、CGPROGRAM结构

目前主流的着色器语言有HLSL,GLSL,Cg。三者在语法上也有诸多共通之处,选择一种学习即可。而Unity选择Cg作为着色器语言。如果要编写Cg代码,需要在Pass里面定义一个cg代码的开始和结束位置,使用CGPROGRAM开头,使用ENDCG结尾,夹在中间的就是cg代码了
Unity编写Shader基本知识

2、顶点和片段程序

在上一步加入了没有内容的CG代码开始和结束标记之后,会发现shader出问题了,Unity给出了警告
Unity编写Shader基本知识

第一条警告的意思大概是当前这个Shader是不被支持的,没有子渲染器或者fallback被支持,这是因为我们的CG代码部分不完整,Unity不知道我们想做什么。
第二条警告,是说我们使用了CG代码,但没有指定顶点(vertex)和片段(fragment)程序
定义顶点和片段程序的方法是:
#pragma vertex 顶点程序名称
#pragma fragment 片段程序的名称
比如我这样写:

Pass
{
	CGPROGRAM
	#pragma vertex azhaoVert
	#pragma fragment azhaoFrag
	ENDCG
}

这个时候,shader依然是报错的
Unity编写Shader基本知识

这是因为我们声明了顶点和片段程序,但没有具体实现这两个程序。
这两个程序的具体写法会在下面说明。

说句题外话:结合之前讲的渲染管线流程,可以得知一个最基础的shader,应该要包括顶点片段程序,所以顶点片段程序是最基础和最核心的编写Shader方式,Unity还提供了其他的形式的Shader编写方式,比如Surface之类,其实我一直都不是很推荐一开始就使用的,因为那些都是Unity在基础的顶点片段程序基础上再封装了的形式,它使用可能会很方便,直接指定环境色、法线之类的值,就能看到不错的效果,但实际上一个shader他为什么能出现具体的效果,我个人感觉还是要在顶点片段程序里面才能比较好的体现出来。

3、引用库

Unity给我们准备了很多东西,比如一些常用的函数方法、常用的常量、转换的矩阵等。我们也可以自己写一些自己的函数以便以后直接使用。这些已经写好的东西,一般会放在cginc文件里面。有一个包含了很多常用函数的库,叫做UnityCG.cginc
通过#include “文件名.cginc”就可以导入。

Pass
{
	CGPROGRAM
	#pragma vertex azhaoVert
	#pragma fragment azhaoFrag
	#include "UnityCG.cginc"
	ENDCG
}

4、声明可用变量

之前在shader开头的地方声明了一些对外的变量

Properties
{
_floatVal(“浮点变量”,Float) = 0
_intVal(“整型变量”,Int) = 1
_rangeVal(“数值范围”,Range(0,1)) = 0

_col("颜色",Color) = (1,1,1,1)
_vectVal("四元数",Vector) = (0,0,0,0)

_2dTex("2D贴图",2D) = "white"{}
_cubeTex("Cube贴图",Cube) = "green"{}
_3dTex("3D贴图",3D) = "black"{}

}

为了能在CG程序里面使用这些变量,所以我们要在CG程序里面再声明一次

Pass
{
	CGPROGRAM
	#pragma vertex azhaoVert
	#pragma fragment azhaoFrag
	#include "UnityCG.cginc"

	float _floatVal;
	float _intVal;
	float _rangeVal;
	float4 _col;
	float4 _vectVal;
	sampler2D _2dTex;
	float4 _2dTex_ST;
	samplerCUBE _cubeTex;
	sampler3D _3dTex;

	ENDCG
}

这里需要注意几点:
1.不论在外部声明了变量是float、int、Vector、color,在实际使用的时候,就只有float,差别只在于float是几维的,比如float、float2、float3、float4。
2.当float3要补全到float4时,如果原来的float3是坐标,则在后面补1,如果原来的float3是向量,则后面补0
3.贴图类型的变量,都是sampler采样器,区别在于是sampler2D、samplerCUBE、sampler3D
4.贴图类型的变量,如果想读取材质球上面的平铺和缩放参数,需要再定义一个float4,名字是贴图变量名字加_ST,比如上面的_2dTex_ST
Unity编写Shader基本知识

这个ST变量的xy代表了Tiling,zw代表了Offset

四、顶点程序

顶点程序是一个有输入和输出结构体的程序,所以在编写顶点程序之前,需要先定义好输入和输出的结构体。

1、输入结构

一般习惯上,定义输入顶点程序的结构体的名字为appdata,它代表着可以直接从模型上面获取到的数据,比如

	struct appdata
	{
		float4 pos : POSITION;//顶点坐标
		float2 uv : TEXCOORD0;//uv1
		float2 uv2 : TEXCOORD1;//uv2
		float2 uv3 : TEXCOORD2;//uv3
		float2 uv4 : TEXCOORD3;//uv4
		float3 normal : NORMAL;//法线
		float4 tangent:TANGENT;//切线
		float4 color:COLOR;//顶点颜色
	};

这些数据,一般会在模型上可以直接获取得到,但也不一定都有值。比如模型可能会没有uv2-uv4的信息,没有顶点颜色,之类。需要注意,这里的TEXCOORD是uv坐标的寄存器,最大支持4组UV。
在引用了UnityCG.cginc之后,可以直接使用一些已经定义好的输入结构:

struct appdata_base {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct appdata_tan {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct appdata_full {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    float4 texcoord2 : TEXCOORD2;
    float4 texcoord3 : TEXCOORD3;
    fixed4 color : COLOR;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

但我还是喜欢自己定义,因为可以根据自己的需要去增加减少需要读取的参数

2、输出结构

输出结构的名字一般习惯会命名为v2f,意思是vertex to fragment。因为这个结构体是顶点程序的输出结果,同时也是片段程序的输入数据。

	struct v2f
	{
		float4 pos:SV_POSITION;
		float4 col:COLOR;
		float2 val1:TEXCOORD0;
		float3 val2:TEXCOORD1;
		float4 val3:TEXCOORD2;
		//……
	};

这里需要注意2个地方:
1.片段程序的pos定义的类型是SV_POSITION,而顶点程序定义的坐标是POSITION,SV_POSITION是输入片段程序固定的坐标使用类型。
2.片段程序里面的TEXCOORD不再是代表UV坐标了,每一个TEXCOORD寄存器都是一个Vector4,可以寄存任意你想存的自定义数据。比如我们可以写成这样,用TEXCOORD0保存uv坐标,TEXCOORD1保存世界空间法线,TEXCOORD2保存世界空间切线。

	struct v2f
	{
		float4 pos:SV_POSITION;
		float4 col:COLOR;
		float2 uv:TEXCOORD0;
		float3 worldNormal:TEXCOORD1;
		float4 worldTangent:TEXCOORD2;

	};

3、编写顶点程序

	v2f azhaoVert(appdata i)
	{
		v2f o;
		//模型顶点坐标转世界空间坐标
		float4 worldPos = mul(unity_ObjectToWorld, i.pos);
		//世界空间顶点坐标转观察空间坐标
		float4 viewPos = mul(UNITY_MATRIX_V, worldPos);
		//观察空间坐标转裁剪空间坐标
		float4 clipPos = mul(UNITY_MATRIX_P, viewPos);
		o.pos = clipPos;
		o.col = i.color;
		o.uv = i.uv*_2dTex_ST.xy+ _2dTex_ST.zw;
		o.worldNormal = UnityObjectToWorldNormal(i.normal);
		o.worldTangent = UnityObjectToWorldDir(i.tangent);
		return o;
	}

说明:
1.顶点程序使用appdata结构体作为输入数据,v2f结构体作为输出数据,我个人习惯,appdata的变量命名为i(input),而v2f的变量命名为o(output)。
2.顶点程序主要控制和改变模型的顶点位置,例子里面用繁琐的方式表达了一个顶点坐标是怎样从模型坐标空间转换到裁剪空间的,如果我们有需要对顶点坐标进行修改,就可以根据需要在其中某一步进行修改,如果没有需要修改的地方,其实可以简写成

float4 clipPos = mul(UNITY_MATRIX_MVP, i.pos);

或者

float4 clipPos = UnityObjectToClipPos(i.pos );

3.在v2f结构体里面定义了多少个使用的变量,那么在顶点程序里面就要给多少个变量赋值。
4.为了使用uv的平铺和偏移,我把_2dTex_ST放进去计算了,这里其实可以简写成

o.uv = TRANSFORM_TEX(i.uv,_2dTex);

五、片段程序

写一个最简单的片段程序:

	half4 azhaoFrag(v2f o) : SV_Target
	{
		return half4(1,1,1,1);
	}

这个片段程序使用v2f作为输入数据结构,half4作为输出数据,SV_Target是DX10+用于fragment函数着色器颜色输出的语义。
由于这里只是展示一个格式,所以v2f结构体并没有参与运算,直接返回了一个half4(1,1,1,1)颜色。
如果我们写得详细点,比如把刚才的一些贴图参数和颜色参数用上,片段程序可以写成这样:

half4 azhaoFrag(v2f o) : SV_Target
			{
				half4 texCol = tex2D(_2dTex,o.uv);
				half3 finalCol = texCol.rgb*_col.rgb;
				return half4(finalCol, texCol.a);
			}

这里使用了tex2D来采样了2D贴图,并获得它的颜色值,和之前定义的_col颜色值相乘,然后再返回结果。这样,我们就可以通过贴图和颜色来控制模型的外观了。
经过上面的编写,一个算是比较完整的shader就编写完了,现在整个shader代码是这样的:

shader "testShader"
{
	Properties
	{
		_floatVal("浮点变量",Float) = 0
		_intVal("整型变量",Int) = 1
		_rangeVal("数值范围",Range(0,1)) = 0

		_col("颜色",Color) = (1,1,1,1)
		_vectVal("四元数",Vector) = (0,0,0,0)

		_2dTex("2D贴图",2D) = "white"{}
		_cubeTex("Cube贴图",Cube) = "green"{}
		_3dTex("3D贴图",3D) = "black"{}
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex azhaoVert
			#pragma fragment azhaoFrag
			#include "UnityCG.cginc"

			float _floatVal;
			float _intVal;
			float _rangeVal;
			float4 _col;
			float4 _vectVal;
			sampler2D _2dTex;
			float4 _2dTex_ST;
			samplerCUBE _cubeTex;
			sampler3D _3dTex;

			struct appdata
			{
				float4 pos : POSITION;//顶点坐标
				float2 uv : TEXCOORD0;//uv1
				float2 uv2 : TEXCOORD1;//uv2
				float2 uv3 : TEXCOORD2;//uv3
				float2 uv4 : TEXCOORD3;//uv4
				float3 normal : NORMAL;//法线
				float4 tangent:TANGENT;//切线
				float4 color:COLOR;//顶点颜色
			};

			struct v2f
			{
				float4 pos:SV_POSITION;
				float4 col:COLOR;
				float2 uv:TEXCOORD0;
				float3 worldNormal:TEXCOORD1;
				float3 worldTangent:TEXCOORD2;

			};

			v2f azhaoVert(appdata i)
			{
				v2f o;
				//模型顶点坐标转世界空间坐标
				float4 worldPos = mul(unity_ObjectToWorld, i.pos);
				//世界空间顶点坐标转观察空间坐标
				float4 viewPos = mul(UNITY_MATRIX_V, worldPos);
				//观察空间坐标转裁剪空间坐标
				float4 clipPos = mul(UNITY_MATRIX_P, viewPos);
				o.pos = clipPos;
				o.col = i.color;
				o.uv = i.uv*_2dTex_ST.xy+ _2dTex_ST.zw;
				o.worldNormal = UnityObjectToWorldNormal(i.normal);
				o.worldTangent = UnityObjectToWorldDir(i.tangent);
				return o;
			}

			half4 azhaoFrag(v2f o) : SV_Target
			{
				half4 texCol = tex2D(_2dTex,o.uv);
				half3 finalCol = texCol.rgb*_col.rgb;
				return half4(finalCol, texCol.a);
			}

			ENDCG
		}
	}
}

六、变量精度问题

对于数字变量,可以使用的精度有3种,分布是float,half,fixed,上面的例子里面就有用到了half和float的例子。他们的区别只在于精度,其他用法一样,比如表达多维时,可以是float4、half4、fixed4。
下面分别介绍一下:
1、float:32位浮点数,精度最高,一般用于世界坐标计算、需要高精度计算的变量
2、half:16位,取值范围是[-60000,+60000],精度为3位小数,一般用于本地坐标、方向向量、HDR颜色等
3、fixed:11位,取值范围是[-2,+2],进度是1/256,一般用于颜色、低精度运算等。
需要注意的是,fixed现在已经很少用到了,在很多手机硬件里面,half和fixed的精度其实是一样的。

七、背面剔除

Cull背面剔除模式:
Cull Back:默认,剔除背面
Cull Front:剔除正面
Cull Off:不进行剔除(双面显示)
直接写字SubShader里面或者Pass里面就可以了,比如

	SubShader
	{
		Cull Off
		Pass
		{
……

或者

SubShader
	{
			Pass
		{
Cull Off
……

这种枚举形式的模式选择,也可以暴露在变量里面让玩家选择

	Properties
	{
		[Enum(UnityEngine.Rendering.CullMode)]
		_cullMode("剔除模式",float) = 2
	}
	SubShader
	{
		Cull [_cullMode]
		Pass
		{
……

Unity编写Shader基本知识

这样在材质球里面就可以直接选择剔除模式了。默认值是2,因为默认的Back的值就是2

八、透明度测试

AlphaTest透明度测试,当同一个片元多次写入透明度数据时,需要一个规则去判断最终显示哪一个信息
1、AlphaTest Off:不做测试,所有都通过
2、AlphaTest Greater Value:大于某个值的透明度才能通过
3、AlphaTest GEqual Value:大于等于某个值才能通过
4、AlphaTest Less Value:小于某个值才能通过
5、AlphaTest LEqual Value:小于等于某个值才能通过
6、AlphaTest Equal Value:等于某个值才能通过
7、AlphaTest NotEqual Value:不等于某个值才能通过
8、AlphaTest Always:等于off,所有情况都通过
9、AlphaTest Never:所有情况都不通过
替代用法:

AlphaTest GEqual 0.1

等效于

clip(color.a - 0.1f)

九、半透明混合

当需要渲染半透明混合的时候,我们需要做几件事情:
1、把深度写入关掉:

ZWrite Off

2、把渲染队列改成2500以上:

Tags{"Queue" = "Transparent"}

3、计算alpha值要控制在0-1之间

saturate(alpha)

4、使用Blend命令控制混合方式
格式:Blend SrcFactor DstFactor
其中
SrcFactor是源因子
DstFactor是目标因子
Blend因子有(为了便于说明,没有按枚举来排列):
1.One:使用源和目标的所有颜色
2.Zero:去除源和目标的所有颜色
3.SrcColor:乘以源的颜色值
4.SrcAlpha:乘以源的alpha值
5.SrcAlphaSaturate:乘以源的alpha值(0-1)
6.DstColor:乘以目标颜色值
7.DstAlpha:乘以目标alpha值
8.OneMinusSrcColor:乘以(1-源颜色值)
9.OneMinusSrcAlpha:乘以(1-源alpha值)
10.OneMinusDstColor:乘以(1-目标颜色值)
11.OneMinusDstAlpha:乘以(1-目标alpha值)
常用混合效果:
1、传统半透明

Blend SrcAlpha OneMinusSrcAlpha

2、预乘半透明

Blend One OneMinusSrcAlpha

3、叠加

Blend One One

4、柔和叠加

Blend OneMinusDstAlpha One
Blend SrcAlpha One

5、倍增

Blend DstColor Zero

6、2x倍增

Blend DstColor SrcColor

和之前介绍过的剔除模式一样,这些枚举同样可以在暴露属性里面给使用者选择
Unity编写Shader基本知识

十、总结:

在最后,贴一下完整的shader:文章来源地址https://www.toymoban.com/news/detail-466592.html

shader "testShader"
{
	Properties
	{
		_floatVal("浮点变量",Float) = 0
		_intVal("整型变量",Int) = 1
		_rangeVal("数值范围",Range(0,1)) = 0

		_col("颜色",Color) = (1,1,1,1)
		_vectVal("四元数",Vector) = (0,0,0,0)

		_2dTex("2D贴图",2D) = "white"{}
		_cubeTex("Cube贴图",Cube) = "green"{}
		_3dTex("3D贴图",3D) = "black"{}
		[Enum(UnityEngine.Rendering.CullMode)]
		_cullMode("剔除模式",float) = 2

		[Enum(UnityEngine.Rendering.BlendMode)]
		_blend1("源因子",float) = 0

		[Enum(UnityEngine.Rendering.BlendMode)]
		_blend2("目标因子",float) = 0
	}
	SubShader
	{		
		Cull[_cullMode]
		ZWrite Off
		Tags{"Queue" = "Transparent"}
		Blend [_blend1] [_blend2]
		Pass
		{			
			CGPROGRAM
			#pragma vertex azhaoVert
			#pragma fragment azhaoFrag
			#include "UnityCG.cginc"

			float _floatVal;
			float _intVal;
			float _rangeVal;
			float4 _col;
			float4 _vectVal;
			sampler2D _2dTex;
			float4 _2dTex_ST;
			samplerCUBE _cubeTex;
			sampler3D _3dTex;

			struct appdata
			{
				float4 pos : POSITION;//顶点坐标
				float2 uv : TEXCOORD0;//uv1
				float2 uv2 : TEXCOORD1;//uv2
				float2 uv3 : TEXCOORD2;//uv3
				float2 uv4 : TEXCOORD3;//uv4
				float3 normal : NORMAL;//法线
				float4 tangent:TANGENT;//切线
				float4 color:COLOR;//顶点颜色
			};

			struct v2f
			{
				float4 pos:SV_POSITION;
				float4 col:COLOR;
				float2 uv:TEXCOORD0;
				float3 worldNormal:TEXCOORD1;
				float3 worldTangent:TEXCOORD2;

			};

			v2f azhaoVert(appdata i)
			{
				v2f o;
				//模型顶点坐标转世界空间坐标
				float4 worldPos = mul(unity_ObjectToWorld, i.pos);
				//世界空间顶点坐标转观察空间坐标
				float4 viewPos = mul(UNITY_MATRIX_V, worldPos);
				//观察空间坐标转裁剪空间坐标
				float4 clipPos = mul(UNITY_MATRIX_P, viewPos);
				o.pos = clipPos;
				o.col = i.color;
				o.uv = i.uv*_2dTex_ST.xy+ _2dTex_ST.zw;
				o.worldNormal = UnityObjectToWorldNormal(i.normal);
				o.worldTangent = UnityObjectToWorldDir(i.tangent);
				return o;
			}

			half4 azhaoFrag(v2f o) : SV_Target
			{
				half4 texCol = tex2D(_2dTex,o.uv);
				half3 finalCol = texCol.rgb*_col.rgb;
				return half4(finalCol, texCol.a);
			}

			ENDCG
		}
	}
}

到了这里,关于Unity编写Shader基本知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 基本知识

    FHS(Filesystem Hierarchy Standard)—— 文件系统层次化标准 。 Filesystem Hierarchy Standard(文件系统层次化标准)的缩写,多数Linux版本采用这种文件组织形式,类似于Windows操作系统中c盘的文件目录,FHS采用树形结构组织文件。FHS定义了系统中每个区域的用途、所需要的最小构成的

    2024年02月16日
    浏览(43)
  • 数学向量基本知识

    1.向量相关定义 2.向量的线性运算 3.向量积与数量积    向量积与数量积的区别 名称 标积/内积/数量积/点积 矢积/外积/向量积/叉积 运算式(a,b和c粗体字,表示向量) a·b=|a||b|·cosθ a×b=c,其中|c|=|a||b|·sinθ,c的方向遵守右手定则 几何意义 向量a在向量b方向上的投影与向

    2023年04月08日
    浏览(81)
  • Git基本知识

    Git 官网: https://book.git-scm.com/ Git 完整命令手册地址: http://git-scm.com/docs Git 中文文档: https://git-scm.com/book/zh/v2 Git 各平台安装包下载地址为: http://git-scm.com/downloads 2.1 Windows下的安装 安装包下载地址: https://github.com/git-for-windows/git/releases/ https://gitforwindows.org/ 官网慢,可以用

    2024年02月08日
    浏览(35)
  • python基本知识学习

    在控制台输出Hello,World! 单行注释:以#开头 多行注释: 选中要注释的代码Ctrl+/ 三单引号 三双引号 第一个字符必须是字母表中字母或下划线 _ 。 标识符的其他的部分由字母、数字和下划线组成。 标识符对大小写敏感。 标识符也叫变量名,变量名就是一个变量的名字,例如

    2024年02月15日
    浏览(45)
  • 电容的基本知识

    1、电容是电路中重要的元件,种类多、用途广,主要有插件类和贴片类两种。 2、电容主要特性参数:标称容量、耐压、误差、温度         2.1电容容量常用单位有微法《uF)、纳法《nF)、皮法《pF)        单位换算:1uF=10^3nF=10\\\"6pF《电容的基本单位用法拉(F)表示)例如: 105

    2024年02月11日
    浏览(49)
  • [Linux]线程基本知识

    一个正在执行的程序,它是 资源分配 的最小单位 进程中的事情需要按照一定的顺序逐个进行 进程出现了很多弊端: 一是由于进程是资源拥有者,创建、撤消与切换存在 较大的时空开销 ,因此需要引入轻型进程; 二是由于对称多处理机(SMP)出现,可以满足多个运行单位,

    2024年02月15日
    浏览(48)
  • CSS基本知识

    CSS叫做层叠样式表。CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果。能够做到页面的样式和结构分离。 举个例子: 这里的style标签我们一般设置在head标签里。 可以看出被选择器修饰的和没被修饰的不同。 写在 style 标签中,嵌入到 html 内部,理

    2024年01月24日
    浏览(48)
  • 前端基本知识介绍

    目录 一.前端三剑客 1.前导 2.三剑客的分工 二.VsCode的介绍与配置 1.vscode的介绍 2.vscode的下载安装 3.vscode的使用 3.1 图形界面操作 3.3 常用插件 三.HTML基础标签 HTML基础知识 1.HTML为何物? 2.标签介绍 3.HTML属性 4.HTML标签骨架 基本的HTML标签 1.HTML标题标签 2.换行与空格 3.HTML段落

    2024年02月03日
    浏览(38)
  • Qt 基本知识

    QMainWindow:主窗口 菜单栏 工具栏 状态栏 QWidget:空白的窗口 所有界面组件的基类 QDialog:对话框类 new project Qt Widget Application qmake 后缀为 .pro 基类:QWidget Generate form 不要去掉 自动生成 ui 文件 Kit 一般使用第一个 widget.ui 界面加个 label 就行 可以在右下角进行调整 GUI 程序结构

    2024年02月22日
    浏览(38)
  • 图论的基本知识

    1.数据结构 图论是数学的一个分支,研究图(Graph)的结构、性质以及它们之间的关系。图是由节点(或顶点)和边组成的一种数据结构,用于表示对象之间的关系。以下是一些图论的基本概念: 图(Graph): 图由节点(顶点)和连接节点的边组成。图可以分为有向图和无向

    2024年02月04日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包