WebGL Shader着色器GLSL语言

在2D绘图中的坐标系统,默认情况下是与窗口坐标系统相同,它以canvas的左上角为坐标原点,沿X轴向右为正值,沿Y轴向下为正值。其中canvas坐标的单位都是’px’。
在这里插入图片描述
WebGL使用的是正交右手坐标系,且每个方向都有可使用的值的区间,超出该矩形区间的图像不会绘制:
X轴最左边为-1,最右边为1;
Y轴最下边为-1,最上边为1;
Z轴朝向你的方向最大值为1,远离你的方向最大值为-1;
注:这些值与Canvas的尺寸无关,无论Canvas的长宽比是多少,WebGL的区间值都是一致的。
在这里插入图片描述
渲染管线就像一条流水线,由一系列具有特定功能的数字电路单元组成,下一个功能单元处理上一个功能单元生成的数据,逐级处理数据。
顶点着色器和片元着色器是可编程的功能单元,拥有更大的自主性,还有光删器,深度测试等不可编程的功能单元,CPU会通过WebGL API和GPU通信,传递着色器程序和数据,GPU执行的着色器程序可以通过useProgram方法切换,传递数据就是把CPU主存中的数据传送到GPU的显存中。
在这里插入图片描述
顶点着色器
顶点着色器是GPU渲染管线上一个可以执行着色器语言的功能单元,具体执行的就是顶点着色器程序,webGL顶点着色器程序在JavaScript中以字符串的形式存在,通过编译器处理后传递给顶点着色器执行。顶点着色器主要作用就是执行顶点着色器程序对顶点进行变换计算,比如顶点位置坐标执行进行旋转,平移等矩阵变换,变换后新的顶点坐标然后赋值给内置变量gl_Position,作为顶点着色器的输出,图元装配和光栅化环节的输入。
在这里插入图片描述
图元装配
顶点变换后的操作是图元装配(primitive assembly),硬件上具体是怎么回事不用思考,从程序的角度来看,就是绘制函数drawArrays()或drawELement()第一个参数绘制模式mode控制顶点如何装配为图元,gl.LINES的定义的是把两个顶点装配成一个线条图元,gl.TRIANGLES定义的是三个顶点装配为一个三角面图元,gl.POINTS定义的是一个点域图元。
在这里插入图片描述
光删化
片元着色器和顶点着色器一样是GPU渲染管线上一个可以执行着色器程序的功能单元,顶点着色器处理的是逐顶点处理顶点数据,片元着色器是逐片元处理片元数据,通过给内置变量gl_FragColor赋值可以给每一个片元进行着色,值可以是一个确定的RGBA值,可以是一个和片元位置相关的值,也可以是插值后的顶点颜色,除了给片元进行着色之外通过关键字discard还可以实现哪些片元可以被丢弃,被丢弃的片元不会出现在帧缓冲区,自然不会显示在canvas画布上。
在这里插入图片描述
着色器(shader)是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Fragment Shader(片元着色器)主要负责片源颜色等的计算。
(1)顶点着色器
顶点着色器,顾名思义,是对顶点进行一系列操作的着色器。顶点除了有基本的位置属性,还可以包含很多其他属性,比如纹理,法线等等。通过顶点着色器,显卡就知道顶点应该绘制在具体什么位置。顶点着色器是非常重要的着色器,且必须要我们自己去定义。
顶点着色器作用于每个顶点,可以生成每个顶点的最终位置。针对每个顶点,它都会执行一次,一旦每个顶点的最终位置确定了,GPU就可以把这些可见的集合组装成点,直线以及三角形,从而提高渲染场景和模型的速度。
(2)片元着色器
如果你已经有使用电脑绘图的经验,你就会知道在这个过程中你会画一个圆,然后是一个矩形,一条线,一些三角形,直到你组成你想要的图像。这个过程与手写一封信或一本书非常相似——它是一组执行一项又一项任务的指令。着色器也是一组指定,但指令是针对屏幕上的每个像素一次性执行的,这意味着你编写的代码必须根据屏幕上像素的位置表现出不同的行为,就像打字机一样,你的程序将作为一个接收位置并返回颜色的函数工作,并且当它被编译时,它会运行得非常快。
语言特性
是一种强类型语言,赋值时等号左右两侧的数据类型必须一致,否则报错,定义函数时必须指定函数的返回值类型
对大小写敏感
每个语句都以英文分号结束
程序自上而下逐行执行
Shader颜色
1.颜色分为红®,绿(g),蓝(b),透明度(a)四个值,组合为一个4维向量(r,g,b,a)。
2.每个分量的范围是0 ~1 的浮点数,即颜色值 /255
3.可以每个分量进行加减乘除计算,也可对整个颜色向量进行加减乘除计算。
(0.0,0.0,0.0,0.0) : 黑色
(1.0,1.0,1.0,1.0) : 白色
(1.0,0.0,0.0,1.0) : 红色
(0.0,1.0,0.0,1.0) : 绿色
(0.0,0.0,1.0,1.0) : 蓝色
Shader中颜色计算
经常遇到问题:
1.底色比如是黑色,无论乘上什么数都还是黑色;
2.如何是白色,乘以什么就是他本身。
3.底色是黑色,加上什么颜色就是颜色本身。
4.如果颜色系数小于0,那么返回的效果也都是黑色。
5.如果颜色系数大于1,那么返回的效果也都是白色。
shader的核心在与数学公式,在于数字的加减乘除,我们的学习过程一定是不断的学习数学,并且总结数学,将规律封装成关键公式去使用。
Shader中坐标系统
在这里插入图片描述
GLSL ES语言的变量,需要遵循以下原则:
1.变量名只能包含英文字符,数字和下划线即(a-z,A-Z,0-9,_ )
2.变量名首字母不能是数字
3.不能以gl_, webgl_或 webgl开头,这些前缀已经被OpenGL ES保留了
4.不能是GLSL ES内置的关键字和保留的关键字
GLSL ES关键字
在这里插入图片描述
GLSL ES保留字
在这里插入图片描述
变量基本类型
GLSL ES中变量类型中的基本类型主要有布尔类型,整型和浮点型。
在这里插入图片描述
基本类型的赋值和类型转换
使用等号(=)可以将值赋给变量,GLSL ES是强类型语言,在语义上 8 和 8.0是一个值,但是,将8 赋值给浮点型变量时会出错。
在这里插入图片描述
矢量类型
向量指的是具有大小(Magnitude)和方向(Direction)量。在物理学中也称为矢量,向量的表示通常使用小写字母加上向右的箭头——>表示,例如a;或者使用粗体的小写字母表示,例如a。向量具有平移不变形。向量只与大小和方向有关系,和向量的起点和终点没有关系。向量也只包含两个属性:大小和方向。对于空间中的两个点A和B,从A到B的向量可以表示为AB,计算方法为AB=B-A。GLSLES支持矢量类型,这种数据类型适合用来处理计算机图形。矢量类型的变量包含多个元素,每个元素是一个数值(整型数,浮点数或布尔值)。矢量将这些元素排成一列,可以用来表示顶点坐标或颜色值等。
在这里插入图片描述
矢量构造,赋值与取值
构造
在GLSL ES中,矢量非常重要,所以GLSL ES提供了丰富灵活的方式来创建矢量。
赋值
使用等号(=)来对矢量进行赋值操作,记住,赋值运算符左右两边的变量/值的类型必须一致,左右两边的元素个数也必须相同。
例:
vec3 v3=vec3(1.0,1.2,1.5);//三维矢量v3的设置为(1.0,1.2,1.5),即v3的三个分量x,y,z分别是1.0,1.2,1.5
vec2 v2=vec2(v3);//使用三维矢量v3赋值给二维矢量v2,实际是使用v3的前两个元素给v2赋值
vec4 v4=vec4(1.0);//将四位矢量v4设置为(1.0,1.0,1.0,1.0)
vec4 v4b=vec4(v2,v4);//使用v2和v4赋值v4b,结果为(1.0,1.2,1.0,1.0)
注:如果向构造函数中只传一个参数,构造函数会自动将整个参数赋值所有元素,但是如果给构造函数传了不止一个值,但比所需的参数个数少,就会报错。
取值
矢量即可以通过点运算符(.)来访问也可以通过方括号运算符([])来访问。通常矢量通过点运算符来访问,只需要在矢量变量名后接点运算符,然后在接上分量名。
x,y,z,w 用来获取顶点坐标的分量
r,g,b,a 用来获取颜色分量
s,t,p,q 用来获取纹理坐标的分量
矢量可以用来存储顶点坐标,颜色和纹理坐标,所以GLSL ES支持以上三种分量名,这样大家在使用的时候便于理解,实际上,一个矢量的x分量或r分量还少s分量都会返回这个矢量的第1个分量,一个矢量的y分量或g分量还少t分量都会返回这个矢量的第2个分量。
注:这点实际上咋们前端JavaScript很类似哈。
注:这块需要大家留意的需要多个分量搭配使用的方法,进行灵活运用。
矢量常见用法
向量归一化
向量的大小(长度)称为向量的模(norm),一般记作 shader中用法:length()
在这里插入图片描述
单位向量(Unit vector)指的是模为1的向量。单位向量的计算公式为:
在这里插入图片描述
单位向量的长度为1,一般只用来表示方向。shader中用法:normalize()
向量乘法
点乘(Dot product),又称为向量的内积,计算公式为:
在这里插入图片描述
点乘满足交换律以及分配律。
在这里插入图片描述
在这里插入图片描述
代数上表示
在这里插入图片描述
shader中用法:float f=dot(vec2(0.,2.),vec2(0.,1.))
向量加法与减法
向量的求和可以用两种法则:平行四边形法则或者三角形法则。
在这里插入图片描述
在代数上,对于在笛卡尔坐标系中定义的向量,向量求和可以简化为求向量各个对应坐标值的和。
shader中用法:vec2 f +=vec2(1.,1.)
向量点乘应用
1.计算两个向量夹角
在这里插入图片描述
2.计算一个向量到另一个向量上的投影
向量b在向量a上的投影满足
在这里插入图片描述
k的大小为:k= ||b⊥||=||b|| cos0.已知两个向量的内积,一个向量在另一个向量上的投影长度为
在这里插入图片描述
向量乘法
叉乘(Crossproduct),又称作向量的外积。两个向量叉乘的结果还是一个向量,这个向量和原来的两个向量垂直。叉乘的结果向量的长度为:
在这里插入图片描述
代数上表示
在这里插入图片描述
几何意义
在几何中,叉积得到的向量与a和b所在平面垂直,长度等于向量a和b组成的平行四边形的面积,改向量被称为法向量。如图
在这里插入图片描述
法向量反向:使用右手定则,首先伸出右手,并竖起大拇指,并将其余的四个手指握紧。
以最小角度旋转向量a,使其与向量b的方向一致,四个手指朝向如下图,大拇指所指的方向就是法向量的方向。
在这里插入图片描述
shader中用法:vec2 f=cross (vec2(.1,.2,.3),vec2(.3,.2,.1))
矩阵定义
矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方程组的系数及常数所构成的方阵。这一概念由19世纪英国数学家凯利首先提出。
矩阵类型介绍
mat2 2x2 的浮点数矩阵 mat2x2 2x2 的浮点数矩阵
mat3 3x3 的浮点数矩阵 mat2x3 2x3 的浮点数矩阵
mat4 4x4 的浮点数矩阵 mat2x4 2x4 的浮点数矩阵
mat3x2 3x2 的浮点数矩阵 mat4x2 4x2 的浮点数矩阵
mat3x3 3x3 的浮点数矩阵 mat4x3 4x3 的浮点数矩阵
mat3x4 3x4 的浮点数矩阵 mat4x4 4x4 的浮点数矩阵
在学习矩阵构造和赋值前先搞明白两个概念,按行主序和按列主序。webGL中矩阵元素是按列主序存储在数组中。
在这里插入图片描述
在webGL中使用的矩阵都是按列主序的,例如你用构造函数创建一个4x4的矩阵时,向矩阵构造函数中传入矩阵的每一个元素的数值来构造矩阵,注意传入值的顺序必须是列主序的。
在这里插入图片描述
左乘
在这里插入图片描述
右乘
在这里插入图片描述
矩阵构造,赋值与取值
在这里插入图片描述
取值
在这里插入图片描述
矩阵常见用法
在这里插入图片描述
矩阵和矩阵相乘
在这里插入图片描述
结构体定义
着色器中的机构体类似于我们其他语言中的类,GLSL的结构体可以组合基本类型和数组来形成用户自定义的类型,在定义结构体的时候,你可以直接定义一个结构体实例,或者在后面定义结构体实例。
在这里插入图片描述
结构体访问与使用
1,=为结构体赋值。
2.==,!=来判断两个结构体是否相等。
只有结构体中的每个成分都相等,那么这两个结构体才是相等的。
3.访问结构体的内部成员使用.(点语法)来访问。
4.固定大小的数组也可以被包含在结构体中。GLSL的结构体不支持嵌套定义。只有预先声明的结构体可以嵌套其中。
结构体注意事项
1.GLSL的结构体不支持嵌套定义,只有预先声明的结构体才可以嵌套其中。
2.结构体定义后面一定要加分号。
3.结构体定义是和main函数并列的。
4.结构体至少包含一个成员。
在这里插入图片描述
数组定义
在GLSL中,可以像C一样声明和访问数组
只支持一维数组
下标不能为负
//声明含有4个数浮点数的数组
float Array1[4];
//声明含2个vec4的对象数组
vec4 Array2[2];
注意:
1.整型字面量
2.数组的长度必须大于0;
3.数组前面定义的是每个子量的类型
数组的赋值和访问
1.只有整型常量表达式和uniform变量可以被用作数组的索引值。此外,与JavaScript或C不同,数组不能在声明时被一次性地初始化,而必须是显式地对每个元素进行初始化。如下所示:
vec4 Array[0]=vec4(4.0,5.0,6.0,1.0);
vec4 Array[1]=vec4(3.0,2.0,0.0,1.0);
2.数组元素可以通过索引值来访问,和JS等语言一样,索引值也是从0开始的。比如,下面这句代码就可以访问float Array变量的第3个元素:
float aa=Array[2];
数组运算
数组本身只支持[]运算符,但数组元素能够参与其自身类型支持的任意运算,如下:
//将floatArray的第2个元素乘以3.14
float f=Array[1] * 3.14
//将vec4Array的第1个元素乘以vec4
vec4 v4=vec4Array[0] * vec4(1.0,2.0,3.0,4.0);
函数定义
函数结构
GLSL ES的函数定义与C语言接近,基本构成包括返回类型,函数名,参数和函数体,若无返回值,需要使用void代替。具体结构如下:
返回类型 函数名 (type0 arg0,type1 arg1,…,typen argn,){
函数计算
retutn 返回值;
}
注意:GLSL 的函数不能递归,不能嵌套。
规范声明
与C语言一样,如果函数定义在其调用之后,那么必须在进行调用前先声明该函数的规范,规范声明预先告诉GLSL系统函数的参数,参数类型,返回值等信息。
流程控制
着色器中的流程控制与C和JavaScript语言中的流程控制几乎无异,主要是通过if语句和for语句等控制流程。
if语句
if语句有三种控制流程的语句模型,分别是if模型。if…else…模型和if…else if…else模型
在这里插入图片描述
for语句
大多数循环程序都是通过for语句实现的,GLSL ES语言一样,for语句的格式如下:
for(初始化表达式;条件表达式;循环歩进表达式){
重复执行的语句;
}
GLSL ES语言的for循环的循环变量有一些特殊的限制,具体如下:
1.一个for循环中只允许有一个循环变量,且只能是int类型或float类型;
2.循环歩进表达式必须是以下的形式中的一种,i++,i–,i+= 常量表达式,i-=常量表达式;
3.条件表达式必须是循环变量与整形常量的比较;
4.循环体内,循环变量不可以被赋值。
在这里插入图片描述
参数限定词
参数限定词顾名思义就是来限制函数参数的,根据参数不同的行为将它们分为以下几类:
只向函数中传值
在函数中被赋值
即向函数中传值也在函数中被赋值
在这里插入图片描述
存储限定词
存储限定词其实就是我们用来向着色器传值的变量类型,GLSL ES提供了attribute,uniform和varying三个限定词来声明特定用途的变量,此外,我们有时也会使用const限定字,它表示着色器中的某个变量是恒定的常量。
在这里插入图片描述
attribute变量
attribute变量只能出现在顶点着色器中,只能被声明为全局变量,被用来表示逐顶点的信息。顶点着色器中能够容纳的attribute变量的最大数目与设备有关,你可以通过访问内置的全局常量来获取该值(最大数目),支持webGL的环境都支持最少8个attribute变量。
在这里插入图片描述
uniform变量
uniform变量可以用在顶点着色器和片元着色器中,且必须是全局变量,uniform变量是只读的,不支持数组和结构体类型。
varying变量
varying限定词声明的变量也要求是全局变量,它担任着一个很重要的角色,就是从顶点着色器向片元着色器传值。
精度限定词
GLSL ES 新引入了精度限定字,目的是帮助着色器程序提高运行效率,削减内存开支。
精度默认值写法:
#ifdef GL_ES
precision mediump float;
#endif
WebGL程序支持三种精度,限定词分别是highp,mediump和lowp
在这里插入图片描述
通常会使用precision关键字为某一类型的变量设置默认精度,这个设置必须放置在程序的顶部。使用方式如下:
precision <精度限定词><类型名称>
默认精度限定参照表:
在这里插入图片描述
预处理指令
预处理指令用来在着色器程序真正编译之前对代码进行预处理,预处理指令都是以(#)开始。
当我们编写GLSL代码时,编译器需要先对代码进行处理,然后才能将其编译成机器可以执行的指令。预处理指令就是在这个处理过程中对代码进行一些操作。
在这里插入图片描述
在这里插入图片描述
预处理指令可以让我们更好地组织代码,提高代码的可读性和可维护性,同时也能够帮助我们调试和诊断代码问题。
内置变量
在这里插入图片描述
内置常量
在这里插入图片描述
光圈特效
fm.glsl文件
在这里插入图片描述
vt.glsl文件
在这里插入图片描述
vite引入

 //在导入时,告诉vite,以字符串形式加载.glsl文件即可,即在文件后面加上“raw”参数即可:
  import vertexShader from './vt.glsl?raw'
  import fragmentShader from './fm.glsl?raw'
	 function initshader(){
           material = new THREE.ShaderMaterial({
                        vertexShader,
                        fragmentShader,
                        side: THREE.DoubleSide,
                        uniforms: {
                            innerCircleWidth: {
                                value: 0
                            },
                            circleWidth: {
                                value: 300
                            },
                            diff: {
                                value: new THREE.Color('#e2fb00')
                            },
                            color: {
                                value: new THREE.Color('#041cf3')
                            },
                            opacity: {
                                value: 0.3
                            },
                            center: {
                                value: new THREE.Vector3(0, 0, 0)
                            }
                        },
                        transparent: true,
                        
                    });
                    var groundGeo = new THREE.PlaneBufferGeometry( 600, 600 );
            var ground = new THREE.Mesh( groundGeo, material );
            ground.name='光效'
            ground.position.y=0.65
            ground.rotation.x = -Math.PI/2
            scene.add( ground );
 }
  //封装一个渲染函数 动画
   const animate=()=>{
          renderer.render(scene, camera)
          requestAnimationFrame(animate);
          if (material) {
                material.uniforms.innerCircleWidth.value += 10
                if(material.uniforms.innerCircleWidth.value > 600){
                    material.uniforms.innerCircleWidth.value = -300
                }
            }
  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/59565.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c语言野指针int*p、空指针int*p = NULL、万能指针void* p

1、野指针&#xff0c;既没有初始化的指针&#xff0c;//如果没有给指针初始化&#xff0c;则指针p的内容为随机地址&#xff0c;会随机指向&#xff0c;故成为野指针&#xff0c;不可以操作野指针 #include "stdio.h" #include <stdlib.h>int main() {//1、野…

ORACLE常用基础

. 1.oracle开机启动流程 su - oracle lsnrctl start lsnrctl status sqlplus / as sysdba startup 2、如何查看数据库版本 select * from v$version; 3.如何查看用户从那个设备连接的数据库 SELECT DISTINCT machine , terminal FROM V$SESSION; 4.如何查看表结构 selec…

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法 首先,我们查看报警说明书上的介绍: 总结:即在机械手断裂设置为无效时,机器人检测出了机械手断裂信号(不该有的信号,现在检测到了,所以报警) 使机械手断裂设定为无效/有效的具体方法:  按下示教器的MENU菜单…

Vue前端框架入门

文章目录 Vue快速入门Vue指令生命周期 Vue 经过一小段时间学习 我认为vue就是在原js上进行的一个加强 简化JS中的DOM操作 vue是分两个层的 一个叫做视图层(View)&#xff0c;你可以理解为展现出来的前端页面 一个叫数据模型层(Model),包含数据和一些数据的处理方法 MVVM就是实…

数据结构10 -查找_树表查找

创建二叉搜索树 二叉搜索树 二叉搜索树是有数值的了&#xff0c;二叉搜索树是一个有序树。 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值&#xff1b; 若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它的根结点的值&#xff1b; 它…

从0到1开发go-tcp框架【2-实现Message模块、解决TCP粘包问题、实现多路由机制】

从0到1开发go-tcp框架【2-实现Message模块、解决TCP粘包问题、实现多路由机制】 1 实现\封装Message模块 zinx/ziface/imessage.go package zifacetype IMessage interface {GetMsdId() uint32GetMsgLen() uint32GetMsgData() []byteSetMsgId(uint32)SetData([]byte)SetData…

组合总和——力扣39

文章目录 题目描述回溯 题目描述 回溯 class Solution { public:vector<vector<int>> res;vector<int> seq; void dfs(vector<int>& nums, int pos, int target){if(target0){res.emplace_back(seq);return;}if(posnums.size()){return;}//直接跳过…

2023上半年手机及数码行业分析报告(京东销售数据分析)

2023年上半年&#xff0c;手机市场迎来复苏&#xff0c;同环比来看&#xff0c;销量销额纷纷上涨。 而数码市场中&#xff0c;各个热门品类表现不一。微单相机及智能手表同比去年呈现增长态势&#xff0c;而笔记本电脑市场则出现下滑。 基于此现状&#xff0c;鲸参谋发布了20…

Ubuntu 虚拟机和主机无法互相复制文字和文件

1.在虚拟机列表中&#xff0c;右键查看是否有安装VMware Tools&#xff0c;如果没有安装点击安装&#xff0c;如果已经安装了&#xff0c;上面显示重现安装VMware Tools&#xff0c;并且为灰色&#xff0c;如图&#xff1a; 2.如果没有安装点击安装&#xff0c;如果已经安装&am…

【知识产权】专利的弊端

接上篇【知识产权】著作权的作用_qilei2010的博客-CSDN博客。 ​ 1 专利的分类 首先,专利分为:发明专利、实用新型专利、外观设计专利。这里要说明的是专利的不同种类在不同的国家都是有不同规定的,并不是所有国家和地区都是分成这三类。 >国家法律法规数据库 >中华…

untiy代码打压缩包,可设置密码

1、简单介绍&#xff1a; 用的是一个插件SharpZipLib&#xff0c;在vs的Nuget下载&#xff0c;也可以去github下载https://github.com/icsharpcode/SharpZipLib 用这个最主要的是因为&#xff0c;这个不用请求windows的文件读写权限&#xff0c;关于这个权限我搞了好久&#…

51单片机(普中HC6800-EM3 V3.0)实验例程软件分析 实验四 蜂鸣器

目录 前言 一、原理图及知识点介绍 1.1、蜂鸣器原理图&#xff1a; 二、代码分析 前言 第一个实验:51单片机&#xff08;普中HC6800-EM3 V3.0&#xff09;实验例程软件分析 实验一 点亮第一个LED_ManGo CHEN的博客-CSDN博客 第二个实验:51单片机&#xff08;普中HC6800-EM…

快速文件传输常见问题

我们所处的世界充斥着各种信息&#xff0c;能够迅速获得正确的数据往往是企业成功的关键因素。将文件从A点移动到B点需要考虑很多问题&#xff0c;但是当涉及需要在最短时间内送达全球各地收件人的大型关键任务文件时&#xff0c;就不能再使用Dropbox和 Google Drive 等方案了。…

安全学习DAY13_WEB应用源码获取

信息打点-WEB应用-源码获取 文章目录 信息打点-WEB应用-源码获取小节概述-思维导图资产架构-源码获取&#xff08;后端&#xff09;后端-开源后端-闭源-源码泄露源码泄露原因源码泄露方式集合网站备份压缩包git&#xff0c;svn源码泄露DS_Store文件泄露composer.json 泄露资源搜…

C语言预备知识

安装Visual studio 官方网址 https://visualstudio.microsoft.com/zh-hans/ 选择第一个社区版本&#xff08;免费&#xff09; 下载完成后打开安装包 安装完成后会自动打开程序选择c项目然后安装即可&#xff08;c兼容c&#xff09; 安装完成后启动程序注意这里需要注册也可…

设备管理系统与物联网的融合:实现智能化设备监控和维护

在数字化时代&#xff0c;设备管理系统和物联网技术的融合为工业企业带来了巨大的变革和创新。本文将探讨设备管理系统与物联网的融合&#xff0c;重点介绍设备健康管理平台在实现智能化设备监控和维护方面的关键作用和优势。 一、设备管理系统与物联网的融合 随着物联网技术的…

OJ:C++ | [vector] — 力扣

文章目录 118. 杨辉三角 - 力扣思路解&#xff1a; 17. 电话号码的字母组合 - 力扣思路&#xff1a;递归解&#xff1a; 137. 只出现一次的数字 II- 力扣思路&#xff1a;解&#xff1a; 118. 杨辉三角 - 力扣 题目链接&#xff1a;118. 杨辉三角 - 力扣&#xff08;LeetCode&…

算法与数据结构(二十一)二叉树(纲领篇)

备注&#xff1a;本文旨在通过 labuladong 的二叉树&#xff08;纲领篇&#xff09;理解框架思维&#xff0c;用于个人笔记及交流学习&#xff0c;版权归原作者 labuladong 所有&#xff1b; 我刷了这么多年题&#xff0c;浓缩出二叉树算法的一个总纲放在这里&#xff0c;也许…

使用可视化docker浏览器,轻松实现分布式web自动化

01、前言 顺着docker的发展&#xff0c;很多测试的同学也已经在测试工作上使用docker作为环境基础去进行一些自动化测试&#xff0c;这篇文章主要讲述我们在docker中使用浏览器进行自动化测试如果可以实现可视化&#xff0c;同时可以对浏览器进行相关的操作。 02、开篇 首先…

Android 死机问题学习笔记

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、死机系统简图二、死机的可能原因三、死机问题需要分析哪些数据四 、Java Backtrace 分析五、常见 Java backtrace 举例六、Native Backtrace七、Ke…