LearnOpenGL-高级OpenGL-6.天空盒
本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正
我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject
文章目录
- 天空盒
- 介绍
- 如何采样
- OpenGL纹理目标
- 例子0:天空盒效果
- 环境映射
- 反射
- 例子1:Cube反射
- 例子2:模型反射
- 折射
- 例子1:Cube折射
- 例子2:模型折射
- 测试-先渲染天空盒再渲染物体,默认深度LESS比较方式
天空盒
介绍
立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面:一个有纹理的立方体。
如何采样

- 方向向量的大小并不重要,只要提供了方向,OpenGL就会获取方向向量(最终)所击中的纹素,并返回对应的采样纹理值。
- 只要立方体的中心位于原点,我们就能使用立方体的实际位置向量来对立方体贴图进行采样了。
- 我们可以将所有顶点的纹理坐标当做是立方体的顶点位置。最终得到的结果就是可以访问立方体贴图上正确面(Face)纹理的一个纹理坐标。
立方体有36个顶点位置,在顶点着色器后每个片段都有自己的顶点位置,采样天空盒时用这个顶点位置当做纹理坐标即可。
OpenGL纹理目标

| 纹理目标 | 方位 |
|---|---|
GL_TEXTURE_CUBE_MAP_POSITIVE_X | 右 |
GL_TEXTURE_CUBE_MAP_NEGATIVE_X | 左 |
GL_TEXTURE_CUBE_MAP_POSITIVE_Y | 上 |
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y | 下 |
GL_TEXTURE_CUBE_MAP_POSITIVE_Z | 后 |
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z | 前 |
例子0:天空盒效果
-
加载天空盒
// 加载纹理// ------------- unsigned int cubeTexture = loadTexture(FileSystem::getPath("assest/textures/container.jpg").c_str()); // 加载天空盒 vector<std::string> faces{FileSystem::getPath("assest/textures/skybox/right.jpg"),FileSystem::getPath("assest/textures/skybox/left.jpg"),FileSystem::getPath("assest/textures/skybox/top.jpg"),FileSystem::getPath("assest/textures/skybox/bottom.jpg"),FileSystem::getPath("assest/textures/skybox/front.jpg"),FileSystem::getPath("assest/textures/skybox/back.jpg") }; unsigned int cubemapTexture = loadCubemap(faces); // 加载天空盒 // 加载顺序 // order: // +X (right) // -X (left) // +Y (top) // -Y (bottom) // +Z (front) // -Z (back) unsigned int loadCubemap(vector<std::string> faces) {unsigned int textureID;glGenTextures(1, &textureID);glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);int width, height, nrChannels;for (unsigned int i = 0; i < faces.size(); i++) {unsigned char* data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);if (data) {glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);stbi_image_free(data);}else {std::cout << "Cubemap texture failed to load at path:" << faces[i] << std::endl;stbi_image_free(data);}}glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);;glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);;glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);;glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);;glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);;return textureID; } -
为天空盒创建立方体的六个面的顶点数据以及VAO VBO
// skybox VAO unsigned int skyboxVAO, skyboxVBO; glGenVertexArrays(1, &skyboxVAO); glGenBuffers(1, &skyboxVBO); glBindVertexArray(skyboxVAO); glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glBindVertexArray(0); -
渲染
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST);glm::mat4 model = glm::mat4(1.0f); glm::mat4 view = camera.GetViewMatrix(); glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);// 渲染立方体 shader.use(); view = camera.GetViewMatrix(); shader.setMat4("model", model);// 不变,在中心 shader.setMat4("view", view); shader.setMat4("projection", projection); glBindVertexArray(cubeVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, cubeTexture); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0);// 渲染天空盒 // 重点代码:小于等于。由于深度缓冲区的默认值为1,而到顶点着色器里设置了天空盒的深度值为1,所以要为小于等于,1=1,测试才通过才到片段着色器采样颜色 glDepthFunc(GL_LEQUAL); skyboxShader.use(); //view = camera.GetViewMatrix(); // 重点代码:取4x4矩阵左上角的3x3矩阵来移除变换矩阵的位移部分,再变回4x4矩阵。/// // 防止摄像机移动,天空盒会受到视图矩阵的影响而改变位置,即摄像机向z后退,天空盒和cube向z前进 view = glm::mat4(glm::mat3(camera.GetViewMatrix())); skyboxShader.setMat4("view", view); skyboxShader.setMat4("projection", projection); glBindVertexArray(skyboxVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);// 第一个参数从GL_TEXTURE_2D 变为GL_TEXTURE_CUBE_MAP glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); glDepthFunc(GL_LESS); -
glsl和采样
#version 330 core layout (location = 0) in vec3 aPos;// 纹理坐标是3维的 out vec3 TexCoords; // 不用model转换到世界矩阵 uniform mat4 projection; uniform mat4 view; void main() {// 纹理坐标等于位置坐标/TexCoords = aPos;vec4 pos = projection * view * vec4(aPos, 1.0);// z为w,透视除法除后z=(z=w/w)=1,深度为最远///gl_Position = pos.xyww; }#version 330 core out vec4 FragColor;// 纹理坐标是3维的 in vec3 TexCoords;// 纹理坐标// 天空盒纹理采样 uniform samplerCube skybox;void main(){ FragColor = texture(skybox, TexCoords); } -
关键地方
-
天空盒不会跟随摄像机移动
// 重点代码:取4x4矩阵左上角的3x3矩阵来移除变换矩阵的位移部分,再变回4x4矩阵。 // 防止摄像机移动,天空盒会受到视图矩阵的影响而改变位置,即摄像机向z后退,天空盒和cube向z前进 view = glm::mat4(glm::mat3(camera.GetViewMatrix())); -
天空盒后渲染,也不会覆盖先前绘制的物体
-
先绘制其它物体
-
设置深度测试为小于等于
-
绘制天空盒
在天空盒的顶点着色器运行后,会执行透视除法,将gl_Position的
xyz坐标除以w分量,将gl_Position的xyz坐标除以w分量(透视除法所做)。所以我们设置天空盒的z为w,z=(z=w/w)=1
gl_Position = pos.xyww;// z为w,透视除法除后z=(z=w/w)=1,深度为最远 -
由于深度测试为小于等于(结合下面图示)
-
在其他物体已占据片段的深度缓冲值<=1
天空盒的深度值1不小于等于这些片段的缓冲值,所以不会通过深度测试,从而保持原有的物体片段颜色。
-
其他物体未占据片段深度缓冲的默认值为1
天空盒的深度值1小于等于深度缓冲的值1,所以会通过深度测试,从而输出天空盒片段。
-
-
错误做法,将深度测试为默认的小于
-
其他物体未占据片段深度缓冲的默认值为1
天空盒的深度值1不小于深度缓冲区的默认值1,不会通过深度测试,从而具有天空盒的颜色的片段不会输出到屏幕上。
-
-
-
-
效果

环境映射
-
什么是环境映射
通过使用环境的立方体贴图,我们可以给物体反射和折射的属性。
这样使用环境立方体贴图的技术叫做环境映射(Environment Mapping),其中最流行的两个是反射(Reflection)和折射(Refraction)。
反射
-
原理图

例子1:Cube反射
-
代码
立方体的shader,天空盒的shader不变(还是和上面例子:天空盒效果的一样)
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal;out vec3 Normal; out vec3 Position;uniform mat4 projection; uniform mat4 model; uniform mat4 view; void main() {// 法线矩阵Normal = mat3(transpose(inverse(model))) * aNormal;// 到世界空间Position = vec3(model * vec4(aPos, 1.0));// 这里不再是gl_Position = pos.xyww;因为这是中间立方体的,不是天空盒的shadergl_Position = projection * view * vec4(aPos, 1.0); }#version 330 core out vec4 FragColor;in vec3 Normal; in vec3 Position; // 片段的坐标-世界空间uniform vec3 cameraPos;// 天空盒纹理采样 uniform samplerCube skybox;void main(){ // 从眼睛位置指向片段位置vec3 I = normalize(Position - cameraPos);vec3 R = reflect(I, normalize(Normal));// 采样天空盒的uv坐标是3维的FragColor = vec4(texture(skybox, R).rgb, 1.0);// FragColor = texture(skybox, R); 这个效果一样 }cpp
Shader shader("assest/shader/4高级OpenGL/6.2.1.cube-反射天空盒.vs", "assest/shader/4高级OpenGL/6.2.1.cube-反射天空盒.fs"); Shader skyboxShader("assest/shader/4高级OpenGL/6.1.1.天空盒-普通效果.vs", "assest/shader/4高级OpenGL/6.1.1.天空盒-普通效果.fs"); ..... // shader configuration // -------------------- shader.use(); shader.setInt("skybox", 0);skyboxShader.use(); skyboxShader.setInt("skybox", 0);glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);// 第一个参数从GL_TEXTURE_2D 变为GL_TEXTURE_CUBE_MAP// render loop // ----------- while (!glfwWindowShouldClose(window)) {// 渲染立方体shader.use();view = camera.GetViewMatrix();shader.setMat4("model", model);// 不变,在中心shader.setMat4("view", view);shader.setMat4("projection", projection);// 为了反射传入shader.setVec3("cameraPos", camera.Position);glBindVertexArray(cubeVAO);glDrawArrays(GL_TRIANGLES, 0, 36);glBindVertexArray(0);// 其它和天空盒的代码一样 -
效果

箱子上的贴图是后面的天空盒贴图
例子2:模型反射
-
代码
立方体的shader,天空盒的shader不变(还是和上面例子:天空盒效果的一样)
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTexCoords;out vec3 Normal; out vec3 Position; // 片段的坐标-世界空间 out vec2 TexCoords;// 纹理坐标uniform mat4 model; uniform mat4 view; uniform mat4 projection;void main() {gl_Position = projection * view * model * vec4(aPos, 1.0);TexCoords = aTexCoords;// 到世界空间Position = vec3(model * vec4(aPos, 1.0));// 这里不再是gl_Position = pos.xyww;因为这是中间立方体的,不是天空盒的shaderNormal = mat3(transpose(inverse(model))) * aNormal; }#version 330 core out vec4 FragColor;in vec3 Normal; in vec3 Position; // 片段的坐标-世界空间 in vec2 TexCoords;// 纹理坐标uniform vec3 cameraPos; uniform sampler2D texture_diffuse1; uniform sampler2D texture_specular1; uniform sampler2D texture_height1;// 天空盒纹理采样 uniform samplerCube skybox;void main(){ vec3 I = normalize(Position - cameraPos);vec3 R = reflect(I, normalize(Normal));// 采样镜面光贴图颜色(uv坐标是2维的)vec4 specular4 = texture(texture_specular1, TexCoords); // 采样出来的颜色是4维的vec3 specular3 = specular4.rgb;// 采样天空盒颜色(uv坐标是3维的)并乘以镜面光贴图颜色FragColor = vec4(texture(skybox, R).rgb * specular3, 1.0) ;// FragColor = vec4(texture(skybox, R).rgb, 1.0) ;// 未乘以镜面光贴图颜色 }cpp
// 加载模型 Model ourModel(FileSystem::getPath("assest/model/nanosuit/nanosuit.obj"));// shader configuration // -------------------- shader.use(); shader.setInt("skybox", 4);skyboxShader.use(); skyboxShader.setInt("skybox", 4); // 设置的天空盒的纹理单元位置,好像不会与普通的纹理冲突,但保险起见还是设为4 glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);// 第一个参数从GL_TEXTURE_2D 变为GL_TEXTURE_CUBE_MAPwhile (!glfwWindowShouldClose(window)) {// 渲染这个模型// 为了反射传入model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));model = glm::scale(model, glm::vec3(0.1f, 0.1f, 0.1f));shader.use();shader.setVec3("cameraPos", camera.Position);shader.setMat4("model", model);shader.setMat4("view", view);shader.setMat4("projection", projection);ourModel.Draw(shader); } -
效果
采样天空盒颜色,未乘以镜面光贴图颜色

采样天空盒颜色,并乘以镜面光贴图颜色

折射
-
原理

-
折射率表
材质 折射率 空气 1.00 水 1.33 冰 1.309 玻璃 1.52 钻石 2.42 例子中,光线/视线从空气(折射率1)进入玻璃(如果我们假设箱子是玻璃制的),所以比值为1.00/1.52=0.658
例子1:Cube折射
-
代码
和反射的代码差不多,就是中间立方体的glsl片段着色器代码不一样
void main(){ float ratio = 1.00 / 1.52;vec3 I = normalize(Position - cameraPos);vec3 R = refract(I, normalize(Normal), ratio);// refract,第三个参数是折射率// 采样天空盒颜色(uv坐标是3维的)FragColor = vec4(texture(skybox, R).rgb, 1.0);// FragColor = texture(skybox, R); 这个效果一样 } -
效果

例子2:模型折射
-
代码
void main(){ float ratio = 1.00 / 1.52;vec3 I = normalize(Position - cameraPos);vec3 R = refract(I, normalize(Normal), ratio);// refract,第三个参数是折射率// 采样天空盒颜色(uv坐标是3维的)FragColor = vec4(texture(skybox, R).rgb, 1.0);// FragColor = texture(skybox, R); 这个效果一样 } -
效果

测试-先渲染天空盒再渲染物体,默认深度LESS比较方式
-
代码
// 将天空盒的盒子长宽为20 float skyboxVertices[] = {// positions -10.0f, 10.0f, -10.0f,-10.0f, -10.0f, -10.0f,..... }; // 渲染天空盒 //glDepthFunc(GL_LEQUAL); // 不用LEQUAL而是默认的LESS skyboxShader.use(); // 重点代码:取4x4矩阵左上角的3x3矩阵来移除变换矩阵的位移部分,再变回4x4矩阵。 // 防止摄像机移动,天空盒会受到视图矩阵的影响而改变位置,即摄像机向z后退,天空盒和cube向z前进 view = glm::mat4(glm::mat3(camera.GetViewMatrix())); skyboxShader.setMat4("view", view); skyboxShader.setMat4("projection", projection); glBindVertexArray(skyboxVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);// 第一个参数从GL_TEXTURE_2D 变为GL_TEXTURE_CUBE_MAP glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); //glDepthFunc(GL_LESS);// 渲染立方体 shader.use(); view = camera.GetViewMatrix(); shader.setMat4("model", model);// 不变,在中心 shader.setMat4("view", view); shader.setMat4("projection", projection); glBindVertexArray(cubeVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, cubeTexture); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0);天空盒的顶点位置z透视除法后不为1
//gl_Position = pos.xyww;// z=w,透视除法除后还是1,深度为最远 gl_Position= projection * view * vec4(aPos, 1.0); -
解释代码顺序
-
天空盒的盒子长宽为20
-
先绘制天空盒,再绘制箱子
-
这代码天空盒将不会受摄像机的观察矩阵的位移部分影响
所以虽然glsl天空盒的深度值z未设置w,但是视觉上依旧是无限远
不过实际上现在代码造成的影响是,不论摄像机所在什么位置,以摄像机为原点,处在一个20*20大小的立方体盒子里,在20*20范围内的物体被显示,20*20外的物体被天空盒颜色所覆盖。
换句话说:注意摄像机在原点,所以20*20的盒子半径为10,于是原点为出发点距离摄像机长度小于10的物体会显示,大于10的物体会被天空盒颜色所覆盖。
-
-
进一步解释(结合下方图)
-
箱子离摄像机的距离 <10(第一幅图)
箱子的深度值小于天空盒,所以天空盒同箱子所占的片段区域会被丢弃,显示箱子的片段颜色
-
箱子离摄像机的距离 > 10(第二幅图)
箱子的深度值大于天空盒,所以天空盒同箱子所占的片段区域会覆盖箱子,显示天空盒的片段颜色


-
相关文章:
LearnOpenGL-高级OpenGL-6.天空盒
本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject 文章目录天空盒介绍如何采样OpenGL纹理目标例子0:天空盒效果环境映射反射例子1:Cube…...
Printk打印内核日志
一、背景 Linux 内核中提供了内核日志打印的工具printk。它的使用方式C语言中的printf是类似的。接下来我们介绍一下printk的使用方式。本文以打印Binder中的日志为例,进行演示。 printk的方法声明和日志级别binder驱动中增加 打印代码android系统中查看日志信息 …...
界面控件DevExpress WPF 202计划发布的新功能合集
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。本文将介绍今年DevExpr…...
Spring Cloud Alibaba 微服务2,注册中心演变 + Nacos注册中心与配置中心
目录专栏导读一、什么是Nacos?二、注册中心演变及其设计思想1、RestTemplate调用远程服务2、通过Nginx维护服务列表(upStream)3、通过Nacos实现注册中心4、心跳版Nacos三、Nacos Discovery四、Nacos核心功能1、服务注册2、服务心跳3、服务同步…...
Navicat 图形化界面工具
Navicat 介绍 Navicat是一套可创建多个连接的数据库管理工具,用以方便管理 MySQL、Oracle、SQL Server等不同类型的数据库 目录 Navicat 介绍 Navicat 下载 Navicat 安装 Navicat 使用 Navicat连接MySQL数据库 Navicat创建数据库和表 Navicat 下载 1、点击这…...
2023年网络安全比赛--attack(新)数据包分析中职组(超详细)
一、竞赛时间 180分钟 共计3小时 任务环境说明: 1 分析attack.pcapng数据包文件,通过分析数据包attack.pcapng找出恶意用户第一次访问HTTP服务的数据包是第几号,将该号数作为Flag值提交; 2.继续查看数据包文件attack.pcapng,分析出恶意用户扫描了哪些端口,将全部的端口号…...
C语言之extern(七十)
extern同一个文件:修饰变量声明#include <stdio.h>int add(){extern int x,y;return x y; }int main(){printf("%d\n", add()); }int x 10; int y 20;extern文件之间:修饰函数声明<1>.add.cint sum(){extern int x ;extern in…...
树的前中后序的Morris遍历
目录 一.Morris遍历 1.什么是Morris遍历 2.基本思想 3.Morris遍历的优点和缺点 4.知识回顾----二叉树的线索化 二.中序Morris遍历 1.中序Morris遍历的分析 2.中序Morris遍历的思路 3.具体的代码实现 三.前序Morris遍历 1.前序Morris遍历的思路 2.具体的代码实现 四…...
到底什么是线程?线程与进程有哪些区别?
上一篇文章我们讲述了什么是进程,进程的基本调度 http://t.csdn.cn/ybiwThttp://t.csdn.cn/ybiwT 那么本篇文章我们将了解一下什么是线程?线程与进程有哪些区别?线程应该怎么去编程? 目录 http://t.csdn.cn/ybiwThttp://t.csdn…...
你真的知道如何系统高效地学习数据结构与算法吗?
文章目录前言:什么是数据结构?什么是算法?学习这个算法需要什么基础?学习的重点在什么地方?一些可以让你事半功倍的学习技巧1.边学边练,适度刷题2.多问、多思考、多互动3.打怪升级学习法4.知识需要沉淀&…...
Linux操作系统基础的常用命令
1,Linux简介Linux是一种自由和开放源码的操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、台式计算机。1.1Linux介绍Linux出现于1991年,…...
Jasypt加密库基本使用方法
目录 1 Jasypt简介... 2 基础知识回顾... 3 Jasypt基本加密器... 4 JasyptPBE加密器... 5 Jasypt池化加密器... 6 Jasypt客户端工具... 7 JasyptSpringboot基本用法... 8 JasyptSpringboot自定义加密器... 9 JasyptSprin…...
C++并发编程之五 高级线程管理
文章目录5.1.1 线程池5.1.1 线程池 在前面我们引入了线程的通信和同步手段,那么为什么还要引入线程池呢? 线程池是一种管理多个线程的技术,它可以减少线程的创建和销毁的开销,提高并发性能。线程池中有一定数量的空闲线程&#x…...
单片机——IIC协议与24C02
1、基础知识 1.1、IIC串行总线的组成及工作原理 I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。 1.2、I2C总线的数据传输 I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟…...
案例05-将不必要的逻辑放到前端(发送调查问卷)
目录一:背景介绍背景二:思路&方案重大问题:解决办法优点:三:总结一:背景介绍 本篇博客书写的意义是警示大家不必把不必要的逻辑放到前端。 明确前后端分离的意义。 背景 下面的主要逻辑是࿱…...
【每日一题】——矩阵相等判定
🌏博客主页:PH_modest的博客主页 🚩当前专栏:每日一题 💌其他专栏: 🔴 每日反刍 🟢 读书笔记 🟡 C语言跬步积累 🌈座右铭:广积粮,缓称…...
Linux防火墙的关闭
查看防火墙的状态打开终端输入如下命令systemctl status firewalld如图所示:running表示防火墙目前处于打开状态输入命令进行关闭防火墙:systemctl stop firewalld如图所示正常的用户是没有权限的,需要输入管理员的密码才能够进行关闭防火墙。…...
Request和Response的概述
⭐作者介绍:大二本科网络工程专业在读,持续学习Java,输出优质文章⭐作者主页:︶ㄣ释然⭐如果觉得文章写的不错,欢迎点个关注😉有写的不好的地方也欢迎指正,一同进步😁Request和Respo…...
常见的Web安全漏洞:SYN攻击/CSRF/XSS
一、SYN攻击(属于DOS攻击) 什么情况下被动方出现SYN_RCVD状态?(flood攻击服务) 客户伪造 ip 端口, 向服务端发送SYN请求。完成2次握手,第三次服务端 等待客户端ACK确认,但由于客户不存在服务端一直未收到确认&#…...
【STC15单片机】 超声波模块的使用
目录 1 基于STC15F2K60S2的超声波测距代码 1.1 基本注意事项 1.1.1 跳线帽接法 1.1.2 晶振设置 1.2 板载超声波工作原理 1.2.1 原理总结 1.2.2 超声波代码思路 1.3 STC15单片机代码部分 1.3.1 定时器0&定时器1初始化 1.3.2 超声波ultrasonic.c ultrasonic.h文件配…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
