LearnGL - 15 - Skybox - 天空盒
文章目录
- 先看效果
- 思路
- 实践
- 准备一个 Cube
- 再准备好 CubeMap(立方体贴图)
- 天空盒子的 Shader
- 效果1
- 在应用层设置传入的视图变化矩阵前,删除移动的量
- 在GLSL shader层移动视图变化矩阵的移动量
- 效果3
- 添加其他几何体看看
- 深度问题
- 效果4
- 效果5
- 天空盒边界接缝处瑕疵问题
- 边界缝隙解决
- References
LearnGL - 学习笔记目录
前些篇:
- LearnGL - 11.1 - 实现简单的Gouraud-Phong光照模型
- LearnGL - 11.2 - 实现简单的Phong光照模型
- LearnGL - 11.3 - 实现简单的Blinn-Phong光照模型
- LearnGL - 11.4 - 实现简单的Flat BlinnPhong光照模型
- LearnGL - 13 - PointLight - 点光源
- LearnGL - 13.1 - SpotLight - 聚光灯
- LearnGL - 14 - MultiLight - 多光源
这些演示光照计算先告一段落。
这一篇:实现 Sky Box (天空盒)
其实参考的学习资料已经学习到后面的大部分了,只不过写文章的速度比较慢,当作是给自己复习。
前几天用 Unity 也做了一个小游戏给家里人玩玩,哈哈,顺便熟悉一下 Unity。
本人才疏学浅,如有什么错误,望不吝指出。
先看效果
思路
- 先准备一个 Cube(立方体),作为渲染 Skybox 天空盒的网格
- 再准备好 CubeMap(立方体贴图)
- 在 Shader 中使用 Cube 的 顶点坐标作为方向(从 原点 到 顶点坐标 的方向) 作为对 CubeMap 采样用的方向
实践
准备一个 Cube
使用之前我们自己自定义的网格文件格式:Testing_Skybox.m
#vertices:8
-0.5, 0.5, -0.50.5, 0.5, -0.50.5, -0.5, -0.5
-0.5, -0.5, -0.5
-0.5, 0.5, 0.50.5, 0.5, 0.50.5, -0.5, 0.5
-0.5, -0.5, 0.5
#indices:36
0, 1, 2
0, 2, 3
4, 7, 6
4, 6, 5
4, 0, 3
4, 3, 7
5, 6, 2
5, 2, 1
0, 4, 5
0, 5, 1
7, 3, 6
3, 2, 6
#colors:0
#uv:0
#normals:0
#tangents:0
可以看到,vertices
的顶点数量就只有 8 个顶点,还有索引,就没有其他数据了
这些索引可以对应下图的内容:
OK,Mesh 网格数据都准备好了,下一步是纹理
再准备好 CubeMap(立方体贴图)
如果用到就版本的 API 的话,我们需要使用到一些枚举:
纹理目标 | 方位 |
---|---|
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 | 前 |
这些枚举值是连续的,所以我们可以遍历的形式去使用,如下旧版 API 代码构建纹理:
int width, height, nrChannels;
unsigned char *data;
for(unsigned int i = 0; i < textures_faces.size(); i++)
{data = stbi_load(textures_faces[i].c_str(), &width, &height, &nrChannels, 0);glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
上面哪些枚举对应下图的方向的纹理
添加上对应的纹理就是:
上面的代码使用的是旧版本的 API
下面我们使用 OpenGL 4.5 版本的 API,也正是我使用的方式:
GLuint tex; // 要创建的纹理extern const GLvoid* texture_data[6];
GLsizei mipmap_level = 10;// 生成、绑定和初始化纹理对象,使用 GL_TEXTURE_CUBE_MAP 目标
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); // 创建纹理对象
glTextureStorage2D( // 4.5 APItex, // 纹理对象mipmap_level , // 10 个层级的 mipmapGL_RGBA8, // OpenGL 纹理对象内部使用的格式:RGBA四个分量,每个分量8个 bit1024, 102); // 纹理宽、高尺寸// 已经分配了纹理对象的存储空间,我们可以设置纹素数组中的纹理数据了
for (int face = 0; face < 6; face++)
{glTextureSubImage3D( // 4.5 APItex, // 纹理对象0, // 要设置的mipmap 层级0, 0, // 每个纹理的x,y像素位置偏移face, // z 偏移相当于上面旧版中对应的 GL_TEXTURE_CUBE_MAP_POSITIVE_X 等,的每个方向1024, 1024, // 每个面向纹理的尺寸1, // 每次一个面(深度)GL_RGBA, // 纹理外部数据的格式,RGBA 四个分量GL_UNSIGNED_BYTE, // 每个分量是一个无符号的 byte,即:0~255texture_data[face]);// 每个面向纹理的数据
}
// 如果需要 mipmap 多层级的话,这里可以调用 OpenGL API生成 mipmap 数据
if (mipmap_level > 1) {glGenerateTextureMipmap(tex);// opengl 4.5 API,生成指定纹理对象的mipmaps
}
还有另一种版本的,可以一次对 5个 cube_map 的生成:
GLuint tex; // 要创建的纹理extern const GLvoid* texture_data[6][5]; // 各个方面的数据
GLsizei mipmap_level = 10;// 生成、绑定和初始化纹理对象,使用 GL_TEXTURE_CUBE_MAP_ARRAY 目标
glGenTextures(1, &tex); // 创建纹理对象
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); // 绑定到 CUBE_MAP 目标上
glTexStorage3D( // 对当前绑定到 CUBE_MAP 目标上的纹理设置格式、分配大小GL_TEXTURE_CUBE_MAP_ARRAY, // 绑定到的目标类型mipmap_level , // 10 层mipmapGL_RGBA8, // 内部格式1024, 1024, // 宽、高尺寸5); // 把深度当做 Cube Map 的数据数量,5 个 cube// 已经分配了纹理对象的存储空间,可以设置纹素数组中的纹理数据了
for (int cube_index = 0; cube_index < 5; cube_index++)
{for (int face = 0; face < 6; face++){GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; // 对应要设置的面向glTexSubImage3D(target, // 面mipmap_level, // mipmap 层级0, 0, // x,y offsetcube_index, // 对应第几个 cube1024, 1024, // 每个面向纹理的尺寸1, // 面数GL_RGBA, // 纹理数据的外部数据格式,四个分量GL_UNSIGNED_BYTE, // 每个分量为一个无符号的 bytetexture_data[face][cube_index]); // 数据}
}
// 如果需要 mipmap 多层级的话,这里可以调用 OpenGL API生成 mipmap 数据
if (mipmap_level > 1) {glGenerateTextureMipmap(tex);// opengl 4.5 API,生成指定纹理对象的mipmaps
}
天空盒子的 Shader
网格、纹理我们都准备好了
那么可以开始 shader 部分内容了
// jave.lin - testing_skybox.vert
#version 450 compatibility
uniform mat4 mMat;
uniform mat4 vMat;
uniform mat4 pMat; in vec3 vPos;out vec3 fSkybox_sample_vec;void main() {// cube 的采样方向fSkybox_sample_vec = vPos;gl_Position = pMat * vMat * mMat * vec4(vPos, 1.0f);
}// jave.lin - testing_skybox.frag
#version 450 compatibilityuniform samplerCube main_tex; // 天空盒 纹理
in vec3 fSkybox_sample_vec; // 天空盒 的采样方向,可以不用归一化void main() {gl_FragColor = vec4(texture(main_tex, fSkybox_sample_vec).rgb, 1.0);
}
可以看到我们使用的是一个 vec3
的向量值来采样的,它的作用如下图:
黄·色的向量,是原点到顶点方向的向量,而我们 texture(cube_map, vec3)
就是根据这个向量来采样的,只要碰撞到Cube 的边界上的点对应的面向的纹理的纹素,就是采样到的内容:
如下图
然后我们将它传入到 片段着色器,主要看 顶点着色器 的:
// cube 的采样方向
fSkybox_sample_vec = vPos;
片段着色器 采样就一句话,完事!
gl_FragColor = vec4(texture(main_tex, fSkybox_sample_vec).rgb, 1.0);
为何传入一个向量就完事了呢?如果你还记得我们从顶点着色器传到片段着色器的数据是会插值处理的(除非你声明了 flat ),就像下图一样:
所以如果我们传入四个顶点的坐标,那么他们对应的每个片段上的方向都是插值的,这样刚好完美的对应用于 texture(cube_map, vec3)
中的 vec3 参数,而该 GLSL 中的 API texture(cube_map, vec3)
对采样向量是否归一化不是必要的,所以我们的代码中也没有 normalize
的处理
效果1
来看看运行效果:
可以看到,这不是我们想要的效果,这个问题是因为我们将相机返回的视图矩阵中的位移也应用到了天空盒上面去了
而我们的天空盒子是假设一个超级远的内容,当做是不会移动的一个超级远的内容。(当然真实情况并不是这样的,这里只是模拟)
所以我们需要想办法移除相机移动的数值,有两种方式:
- 在应用层设置传入的 视图变化 矩阵前,删除移动的量:
- 在GLSL shader层移动 视图变化 矩阵的移动量
在应用层设置传入的视图变化矩阵前,删除移动的量
glm::mat4 vMat = glm::mat4(glm::mat3(camera->getViewMatrix()));
思路是先 将 mat4
转型为 mat3
丢弃第四列第四行的内容,再转回 mat4
不会默认的第四列第四行的内容,我们的移动分量在第四列的前三个分量,默认值是0,所以这样是可以移除移动量的。
在GLSL shader层移动视图变化矩阵的移动量
这种方式相比上面在应用层来说性能会损耗一点点,不过可以忽略不计,但是对于应用层代码来说就不用修改了,可读性也高一些,不用为了天空盒而专门特殊处理代码。
所以这也是我采用的方式:
// jave.lin - testing_skybox.vert
#version 450 compatibility
uniform mat4 mMat;
uniform mat4 vMat;
uniform mat4 pMat; in vec3 vPos;out vec3 fSkybox_sample_vec;void main() {// cube 的采样方向fSkybox_sample_vec = vPos;// 复制mat4 new_vMat = vMat;/*X_x X_y X_z X_oY_x Y_y Y_z Y_oZ_x Z_y Z_z Z_o0 0 0 1将 X_o = Y_o = Z_o = 0矩阵变成X_x X_y X_z 0Y_x Y_y Y_z 0Z_x Z_y Z_z 00 0 0 1*///将 X_o = Y_o = Z_o = 0new_vMat[3][0] = new_vMat[3][1] = new_vMat[3][2] = 0;vec4 outPos = pMat * new_vMat * mMat * vec4(vPos, 1.0);gl_Position = outPos;
}
主要看、理解这么一句:
new_vMat[3][0] = new_vMat[3][1] = new_vMat[3][2] = 0;
具体可以查看注释说明
效果3
为何啥都看不到了?
因为我们在 shader 中移除了 view matrix 视图矩阵的移动量了,所以我们的镜头相当于一只都像 cube 立方体的中心点,那么我们看到的都是立方体内部的面,即:背面。
而我开了剔除面向的功能,并且剔除的是:背面,所以就不显示了
所以我们只要将剔除的面向该为:剔除:正面。
//mat->wire_frame = false; // 默认就是非线框模式,不用设置
//mat->enabledCullFace = true; // 默认启用面向剔除 : true,不用设置
mat->cullFace = DrawState_FaceCullingType::Front; // 剔除面向为:正面
//mat->enabledDepthTest = true; // 默认启用深度测试 : true,不用设置
//mat->depthCompare = DrawState_DepthTestingType::Less; // 默认为 Less 不用设置
mat->enabledDepthWrite = false; // 不用写深度,因为本身为最大深度了
主要看两句:
mat->cullFace = DrawState_FaceCullingType::Front; // 剔除面向为:正面
mat->enabledDepthWrite = false; // 不用写深度,因为本身为最大深度了
剔除正面
也不需要些深度,因为天空和只会被挡,而不会挡住其他东西(除非你要制作一些比天空盒还要远的东西,太空?那也只能动态过度不同的天空盒了)
添加其他几何体看看
添加上其他的几何体后,发现效果不对了?
天空盒都挡住了我们的几何体了?怎么办呢?
然后我们将相机往前移动里球体和气球猫网格几何体都近一些,会显示部分球体与气球猫的网格
这是因为深度的问题
深度问题
还记得我们之前看的 sky box 的 cube 的顶点数据吗?
#vertices:8
-0.5, 0.5, -0.50.5, 0.5, -0.50.5, -0.5, -0.5
-0.5, -0.5, -0.5
-0.5, 0.5, 0.50.5, 0.5, 0.50.5, -0.5, 0.5
-0.5, -0.5, 0.5
所以明显天空盒渲染出来的深度有些比球体和气球猫几何体的网格的深度要还小导致的
那么我们要想办法将天空盒的深度都渲染到最大的深度
之前说过的,深度的范围:0.0~1.0,深度越小,就越靠近镜头,越大,就越远离镜头
所以我们要想办法将天空盒渲染到最远的深度:1.0的值
shader 如下:
// jave.lin - testing_skybox.vert
#version 450 compatibility
uniform mat4 mMat;
uniform mat4 vMat;
uniform mat4 pMat; in vec3 vPos;out vec3 fSkybox_sample_vec;void main() {/*X_x X_y X_z X_oY_x Y_y Y_z Y_oZ_x Z_y Z_z Z_o0 0 0 1将 X_o = Y_o = Z_o = 0矩阵变成X_x X_y X_z 0Y_x Y_y Y_z 0Z_x Z_y Z_z 00 0 0 1*/// cube 的采样方向fSkybox_sample_vec = vPos;// 复制mat4 new_vMat = vMat;//将 X_o = Y_o = Z_o = 0new_vMat[3][0] = new_vMat[3][1] = new_vMat[3][2] = 0;vec4 outPos = pMat * new_vMat * mMat * vec4(vPos, 1.0);// 注意我们将 z 改为了 w,即:每个顶点都设置深度最大,因为天空盒都假设是最远的背景内容// 注意我们的深度范围是:0~1 (最小~最大)// 为何用w深度就可以为最大呢(1)// 因为顶点着色器之后,会执行透视除法// 透视除法:假设 pos(x,y,z,w) 是顶点变化后的坐标点// 透视除法将之前的坐标除以他第四个分量 w pos /= pos.w; // 相当于:pos.xyzw = pos.xyzw / pos.wwww;// 为何是第四分量,因为我们故意在 Projection 矩阵的[2][3] 设置为 -1,这样即可获取原本透视前的 z 值,即可:view space 下的 z// 然后结合齐次坐标的表示:(1,2,3,1)=(2,4,6,2)// 即可:(x,y,z,w)/w=(x/w,y/w,z/w,w/w)=(x/w,y/w,z/w,1)// 这就是 齐次坐标 透视除法 的由来// 那么回想刚刚我们前面设置的:pos = pos.xyww; // 注意后面两个分量是 ww// 相当于: pos.xyzw = pos.xyww// 如果:pos.xyzw / pos.wwww = 后面两个参数肯定都是1,因为非零的数除以本身等于1gl_Position = outPos.xyww;
}
主要查看:
gl_Position = outPos.xyww;
然后详细的说明可以看注释,这里不在重复说明
效果4
上面将天空盒的深度设置为 1.0 的越大值后,发现啥都不显示了,如下图:
这是因为我们的默认的深度比较是 Less
的方式导致的
Less
的方式意味着,必须比深度缓存中的值要小,才能通过,而我们的深度缓存值默认每帧渲染前都先清理深度缓存值为 1.0 导致的,这样天空盒渲染的也是深度为 1.0 ,所以天空盒的深度沒比緩存的值要小,而是相等,所以我们可以将天空盒的渲染状态的:深度比较调整为:LEqual
即可,LEqual
是小于、等于的意思(LEqual == Less or Equal)。
那么我们再调整好深度比较方式为:LEqual
(不要用 Equal
,因为会有精度问题,造成类似 z-fighting 的问题),再看看效果:
//mat->wire_frame = false; // 默认就是非线框模式,不用设置
//mat->enabledCullFace = true; // 默认启用面向剔除 : true,不用设置
mat->cullFace = DrawState_FaceCullingType::Front; // 剔除面向为:正面
//mat->enabledDepthTest = true; // 默认启用深度测试 : true,不用设置
//mat->depthCompare = DrawState_DepthTestingType::Less; // 默认为 Less 不用设置
mat->depthCompare = DrawState_DepthTestingType::LEqual;
mat->enabledDepthWrite = false; // 不用写深度,因为本身为最大深度了
效果5
将 mat->depthCompare = DrawState_DepthTestingType::LEqual;
后,运行效果为:
嗯,这看起来还不错的效果!
天空盒边界接缝处瑕疵问题
看起来上面的运行情况还想没啥问题了,其实,如果仔细看天空盒的每个面向的边界接缝处,都有一些缝隙,看起来很不舒服,如下图:
这是 底部 的边界缝隙的问题:
这是 顶部 的边界缝隙的问题:
边界缝隙解决
OpenGL 还专门提供了一个 API:
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
References
- Cubemap Texture
- 立方体贴图
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 企业服务总线ESB的分享
概念ESB全称为Enterprise Service Bus,指的是传统中间件技术与XML、Web服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。背景ESB在企业服务中还是占据了特别重要的席位,很早以前企业的资源管理可能一个SAP系统就搞定了,但是随着公司…...
2024/4/15 13:36:00 - vscode 前端部分插件推荐
vscode 前端插件推荐 前端前端 1.Auto Close Tag :自动闭合HTML/XML标签 2.Auto Rename Tag :自动完成另一侧标签的同步修改 3.Beautify:格式化 html ,js,css 4.Bracket Pair Colorizer :给括号加上不同的颜色,便于区分不同的区块,还可以定义不同括号类型和不同颜色。 效…...
2024/4/15 13:35:59 - 2020.8.6【算协集训】记忆化搜索
记忆化搜索A - Function Run Fun (POJ-1579)B - 滑雪 (POJ-1088)C - 漫步校园 (HDU-1428)D - Free Candies (UVA-10118)E - Zipper (HDU-1501)F - Bone Collector (HDU-2602)G - FatMouse and Cheese (HDU-1078) 网页链接:传送门 密码:hpuacm A - Function Run Fun (POJ-1579…...
2024/4/23 7:07:18 - 不是吧,难道你会了浮动,就不去学定位了吗?
一、定位 1.1 为什么需要定位浮动可以让多个块级盒子一行没有缝隙排列显示,经常用于横向排列盒子。 定位则是可以让盒子自由的再某个盒子内部移动位置或者固定屏幕中某个位置,并且可以压住其他盒子。1.2 定位组成 定位: 将盒子定在某一个位置,所以定位也是再摆放盒子,按照…...
2024/4/15 13:35:58 - Vue-cli3的问题&解决
1、错误: 报错: Avoided redundant navigation to current location: "/home". 当使用js代码来控制路由跳转的时候,会出现问题;当多次点击首页按钮时,会报错,冗余导航 解决方法:方法一: -在项目目录下运行 npm i vue-router@3.0 -S,将vue-router版本改为3.0…...
2024/4/15 13:35:56 - 基于DFA-前缀树的敏感词汇过滤算法(项目实用)
在敏感词汇过滤这块,不同的算法所造成的性能差异是非常大的,选择一个合适的算法非常重要。因为以前做算法的时候做过类似前缀树的字符串匹配之类的算法,所以一开始就打算用前缀树做的,后面了解了一下DFA的相关算法原理,其实用在敏感词汇过滤这块,主要还是前缀树的应用。这…...
2024/4/30 9:11:52 - Lock接口与队列同步器AQS
Lock接口 与synchronized锁对比在Java SE 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,…...
2024/4/22 19:11:56 - 《异星工厂》秘籍大全(lua控制台/代码修改)
《异星工厂》秘籍大全(lua控制台/代码修改)_cgamehttps://www.sohu.com/a/252275827_100204787如何输入 +打开聊天窗口(默认是按 ~ 或 /),输入以下秘籍指令回车确认可获得对应效果。添加开采资源 +以玩家角色为中心生成一个5X5的资源图片资源代码铁矿/c local surface = gam…...
2024/4/30 21:00:41 - 自然语言处理|SkipGram训练中文词向量
课程作业,训练语料是维基百科的中文语料,训练词向量计算两个词之间的余弦相似度。关于预处理网络上有不少教程,后面如果有时间会补一下,程序结构图里给出了对应步骤用到的库,可以借鉴。1. 程序结构概览2. 基于Word2Vec的实现 基于Word2Vec的实现直接调用了gensim库,调整了…...
2024/4/15 20:26:58 - Camunda工作流引擎二
本篇将在上一篇应用的基础上开发一个最基本的 ”流程Demo“ ! 提要 简单总结一下《Camunda工作流引擎一》中关于表的知识,大体上分为 4 类:act_RE_* :RE 表示 repository,这个前缀的表包含了流程定义和流程静态资源(图片,规则,等等)。 **act_RU_* **:RU 表示 runtime,…...
2024/4/15 20:26:57 - Harris 3D: a robust extension of the Harris operator for interest point detection on 3D meshes论文解读
本文是将参照二维Harris角点检测改进而来,目的是在三维点云中检测出关键点。1、计算Harris算子为了计算导数,我们将二次曲面拟合到以下点上变换点的集合。利用最小平方法,我们找到一个抛物线的形式。我们选择了一个只有6个项的二次曲面,因为它代表一个抛物线。也就是说,如…...
2024/4/15 20:26:55 - CVPR2020论文分方向整理之检测篇_3D目标检测(代码/论文解读/136篇打包下载)
CVPR2020论文分方向整理之检测篇(代码/论文解读/136篇打包下载)本周三,CVPR官方正式开放下载,极市第一时间将所有论文(共1467篇)进行了下载打包,详情见此处。为了方便大家进一步的学习,我们对这1467篇论文进行了整理,本次分享的是所有检测类论文,并将它们细分为3D目标…...
2024/4/15 20:26:55 - Spark -- cache和unpersist的正确用法
向导背景原理例子失败案例成功案例 背景cache和unpersist没有使用好,跟根本没用没啥区别,例如下面的例子,有可能很多人这样用: val rdd1 = ... // 读取hdfs数据,加载成RDD rdd1.cacheval rdd2 = rdd1.map(...) val rdd3 = rdd1.filter(...)rdd1.unpersistrdd2.take(10).fo…...
2024/4/23 15:16:16 - 使用 Laravel Sanctum 轻松验证 Vue SPA
Laravel Sanctum (以前称为 Laravel Airlock), 于今年早些时候发布,是一个轻量级的扩展包,可以使得在单页面应用或者本地移动应用上构建身份验证的流程变得尽可能地简单和轻松。在此之前,你要么使用基于 sessions 的 Web 中间件 ,要么使用外部集成的依赖包,如 Tymon 的 jw…...
2024/4/15 20:26:53 - 线性表的顺序表示和实现-----两个集合的并集(无序,有序),线性表的就地逆置,两个线性表的比较大小,插入元素(O(1)), A 表中 删去既在 B 表中出现又在 C 表中出现的元素,
线性表的顺序表示和实现①集合A=AUB,无序的;②A,B两个顺序表递增有序,执行C=AUB,算法时间复杂度要求为 O(n+m)(A,B这两个顺序表只允许遍历一次);③//实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,...,an)逆置为(an,...,a1);④//设A=(a1,...,an)和B=(b1,...,bn)…...
2024/4/15 20:26:51 - 设计模式之——单例模式你真的会吗?
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工…...
2024/4/19 0:24:47 - [论文阅读] Disentangling and Unifying Graph Convolutions for Skeleton-Based Action Recognition
Disentangling and Unifying Graph Convolutions for Skeleton-Based Action Recognitionpaper: https://arxiv.org/pdf/2003.14111.pdfarxiv.org code: https://github.com/kenziyuliu/ms-g3dgithub.com基于骨架的动作识别的分离和统一的图卷积 摘要 基于骨架的动作识别算…...
2024/4/15 20:26:50 - 牛客暑期多校训练营B—Mask Allocation
题目大意: 给定n*m个口罩,需要将这些口罩封装成盒, 有n个a类医院,m个b类医院,从这些盒子中可以找到n组口罩,这n组盒子中口罩数量一样多,也可以找到m组口罩,这m组口罩数量一样多,要求分组尽量少,并且字典序尽量大。题目思路: gcd递归构造最优解#include<iostream&…...
2024/4/15 20:26:49 - 业务安全 –业务逻辑漏洞
目录业务安全 –业务逻辑漏洞业务安全概述;业务安全测试流程:业务数据安全商品支付金额篡改前端JS限制绕过验证请求重放测试业务上线测试*商品订购数量篡改密码找回安全注入业务逻辑信息泄露业务安全概述;简单讲,随着社会发展,越来越多的行业都开始发展互联网业务,利用信息…...
2024/4/15 20:26:48 - PWA——下一代的web应用模型
PWA——下一代的web应用模型概述什么是PWAPWA为什么会出现如何判断一个web应用是PWA核心功能Service-Workers注册service workerservice worker中的常用事件Manifest清单文件添加到主屏Push&Notification通知API——请求授权推送发展趋势优势劣势 概述 不知道从什么时候开始…...
2024/4/15 20:26:46
最新文章
- Harbor服务器停电重启后用户不能登陆怎么办?
Harbor服务问题处理 今天遇到一个问题,可能因为这几天下暴雨打雷比较厉害,办公室机房跳闸,有一台测试服务器没有停电保护停机。重启这台服务器以后,上面运行的Harbor服务登陆不上,用户名和密码都没改过,搞…...
2024/5/1 7:47:08 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 【Java】假如把集合体系看作购物中心
购物中心入口:Java集合框架 “Java集合广场”的购物中心,这是一个集合了各种奇特商店的地方,每个商店都充满了不同的宝藏(数据结构)。 一楼:基础集合区 - Collection接口 一楼是基础集合区,这…...
2024/4/30 2:40:01 - Linux的软链接和硬链接
1、软链接 概念:给文件创建一个快捷方式,依赖原文件,和普通文件没有区别。 特性: 可以给存在的文件或目录创建软链接可以给不存在的文件或目录创建软链接可以跨文件系统创建软链接删除软链接不影响原文件、删除原文件会导致软链…...
2024/4/30 17:33:33 - 416. 分割等和子集问题(动态规划)
题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义:dp[i][j]表示当背包容量为j,用前i个物品是否正好可以将背包填满ÿ…...
2024/4/30 9:36:27 - 【Java】ExcelWriter自适应宽度工具类(支持中文)
工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...
2024/4/30 0:57:52 - Spring cloud负载均衡@LoadBalanced LoadBalancerClient
LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon,直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件,我们讨论Spring负载均衡以Spring Cloud2020之后版本为主,学习Spring Cloud LoadBalance,暂不讨论Ribbon…...
2024/4/29 18:43:42 - TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案
一、背景需求分析 在工业产业园、化工园或生产制造园区中,周界防范意义重大,对园区的安全起到重要的作用。常规的安防方式是采用人员巡查,人力投入成本大而且效率低。周界一旦被破坏或入侵,会影响园区人员和资产安全,…...
2024/5/1 4:07:45 - VB.net WebBrowser网页元素抓取分析方法
在用WebBrowser编程实现网页操作自动化时,常要分析网页Html,例如网页在加载数据时,常会显示“系统处理中,请稍候..”,我们需要在数据加载完成后才能继续下一步操作,如何抓取这个信息的网页html元素变化&…...
2024/4/30 23:32:22 - 【Objective-C】Objective-C汇总
方法定义 参考:https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...
2024/4/30 23:16:16 - 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】
👨💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】🌏题目描述🌏输入格…...
2024/5/1 6:35:25 - 【ES6.0】- 扩展运算符(...)
【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数࿰…...
2024/4/29 21:25:29 - 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?
文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕,各大品牌纷纷晒出优异的成绩单,摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称,在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁,多个平台数据都表现出极度异常…...
2024/5/1 4:35:02 - Go语言常用命令详解(二)
文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令,这些命令可以帮助您在Go开发中进行编译、测试、运行和…...
2024/4/30 14:53:47 - 用欧拉路径判断图同构推出reverse合法性:1116T4
http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b,我们在 a i a_i ai 和 a i 1 a_{i1} ai1 之间连边, b b b 同理,则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然࿰…...
2024/4/30 22:14:26 - 【NGINX--1】基础知识
1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息,并安装一些有助于配置官方 NGINX 软件包仓库的软件包: apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...
2024/5/1 6:34:45 - Hive默认分割符、存储格式与数据压缩
目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限(ROW FORMAT)配置标准HQL为: ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...
2024/4/30 22:57:18 - 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法
文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中,传感器和控制器产生大量周…...
2024/4/30 20:39:53 - --max-old-space-size=8192报错
vue项目运行时,如果经常运行慢,崩溃停止服务,报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中,通过JavaScript使用内存时只能使用部分内存(64位系统&…...
2024/5/1 4:45:02 - 基于深度学习的恶意软件检测
恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞,例如可以被劫持的合法软件(例如浏览器或 Web 应用程序插件)中的错误。 恶意软件渗透可能会造成灾难性的后果,包括数据被盗、勒索或网…...
2024/4/30 0:57:46 - JS原型对象prototype
让我简单的为大家介绍一下原型对象prototype吧! 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象…...
2024/4/29 3:42:58 - C++中只能有一个实例的单例类
C中只能有一个实例的单例类 前面讨论的 President 类很不错,但存在一个缺陷:无法禁止通过实例化多个对象来创建多名总统: President One, Two, Three; 由于复制构造函数是私有的,其中每个对象都是不可复制的,但您的目…...
2024/4/29 19:56:39 - python django 小程序图书借阅源码
开发工具: PyCharm,mysql5.7,微信开发者工具 技术说明: python django html 小程序 功能介绍: 用户端: 登录注册(含授权登录) 首页显示搜索图书,轮播图࿰…...
2024/5/1 5:23:20 - 电子学会C/C++编程等级考试2022年03月(一级)真题解析
C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...
2024/4/30 20:52:33 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57