当前位置: 首页 > news >正文

(自用)learnOpenGL学习总结-高级OpenGL-立方体贴图

ok终于来到了立方体贴图了,在这里面我们可以加入好看的天空包围盒,这样的画我们的背景就不再是黑色的了!

首先,立方体贴图和前面的sampler2D贴图一样,不过是6个2D组成的立方体而已。

那么为什么要把6个组合在一起呢?立方体贴图可以通过一个方向向量来进行索引(或者说采样)。什么意思?

我们类比一下,之前在一个2D面上我们通过uv纹理坐标来找到对应的纹理值对吧。这里也一样,不过是通过一个方向向量来获得。

 假设我们有一个立方体、然后又有一个立方体贴图,只要立方体中心在原点,我就可以通过立方体表面的位置来确定对应的方向向量从而确定对应的立方体纹理坐标。

创建立方体贴图

和前面创建贴图一样。

unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

不过因为有6个面,所以需要贴6次。

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);
}

这里我们有一个叫做textures_faces的vector,它包含了立方体贴图所需的所有纹理路径,并以表中的顺序排列。这将为当前绑定的立方体贴图中的每个面生成一个纹理。

然后还需要设置环绕和过滤方式

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_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);

可以看到这里出现了个R坐标,其实就是纹理的第三个维度,和位置的z一样。

最后在片段着色器中要使用一个samplerCube就行

天空盒

我们现在下载一个天空盒到我们的项目中。

 加载天空盒

和之前把图片加载到gpu一样,现在是加载一个cubemap。

unsigned int LoadCubeMapToGPU(std::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;};

然后需要存一个skybox的图片vector

float skyboxVertices[] = {// positions          -1.0f,  1.0f, -1.0f,-1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f,1.0f,  1.0f, -1.0f,-1.0f,  1.0f, -1.0f,-1.0f, -1.0f,  1.0f,-1.0f, -1.0f, -1.0f,-1.0f,  1.0f, -1.0f,-1.0f,  1.0f, -1.0f,-1.0f,  1.0f,  1.0f,-1.0f, -1.0f,  1.0f,1.0f, -1.0f, -1.0f,1.0f, -1.0f,  1.0f,1.0f,  1.0f,  1.0f,1.0f,  1.0f,  1.0f,1.0f,  1.0f, -1.0f,1.0f, -1.0f, -1.0f,-1.0f, -1.0f,  1.0f,-1.0f,  1.0f,  1.0f,1.0f,  1.0f,  1.0f,1.0f,  1.0f,  1.0f,1.0f, -1.0f,  1.0f,-1.0f, -1.0f,  1.0f,-1.0f,  1.0f, -1.0f,1.0f,  1.0f, -1.0f,1.0f,  1.0f,  1.0f,1.0f,  1.0f,  1.0f,-1.0f,  1.0f,  1.0f,-1.0f,  1.0f, -1.0f,-1.0f, -1.0f, -1.0f,-1.0f, -1.0f,  1.0f,1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f,-1.0f, -1.0f,  1.0f,1.0f, -1.0f,  1.0f
};std::vector<std::string> faces
{"right.jpg","left.jpg","top.jpg","bottom.jpg","front.jpg","back.jpg"
};

然后需要给这cube给一个VAO VBO

	unsigned int cubemapTexture = LoadCubeMapToGPU(faces);unsigned int skyboxVAO, skyboxVBO;glGenBuffers(1, &skyboxVBO);glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);glGenVertexArrays(1, &skyboxVAO);glBindVertexArray(skyboxVAO);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

最后写一个skybox的shader就好。

#version 330 corelayout(location = 0) in vec3 aPos;out vec3 TexCoords;uniform mat4 projMat;
uniform mat4 viewMat;void main(){gl_Position = projMat*viewMat*vec4(aPos,1.0f);TexCoords = aPos;
}#version 330 core
out vec4 FragColor;
in vec3 TexCoords;uniform samplerCube skybox;void main(){FragColor =	 texture(skybox,TexCoords);
}

可以看到在顶点着色器里面我们把坐标信息作为纹理信息传给了片段着色器,这是因为cubemap的纹理坐标就是一个向量,所以我们直接把原点在世界中心的立方体的各点坐标当作纹理向量给片段着色器就好。

最后是loop中,我们要记住,画天空盒,我们得先画,而且画的时候需要把深度测试关了,这样的画,之后的物体就是画在背景之前了。

loop中这么写。

//第一阶段
...
//clear screen
...
//skybox
glDepthMask(GL_FALSE);
skyboxShader->use();iewMat = camera.GetViewMatrix();
projMat = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(skyboxShader->ID, "viewMat"), 1, GL_FALSE, glm::value_ptr(viewMat));
glUniformMatrix4fv(glGetUniformLocation(skyboxShader->ID, "projMat"), 1, GL_FALSE, glm::value_ptr(projMat));glBindVertexArray(skyboxVAO);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDepthMask(GL_TRUE);
...
//木块 机器人 其他

不过结果不对,我们希望天空盒是以玩家为中心的,这样不论玩家移动了多远,天空盒都不会变近,让玩家产生周围环境非常大的印象。然而,当前的观察矩阵会旋转、缩放和位移来变换天空盒的所有位置,所以当玩家移动的时候,立方体贴图也会移动!我们希望移除观察矩阵中的位移部分,让移动不会影响天空盒的位置向量。

在基础光照小节中,我们通过取4x4矩阵左上角的3x3矩阵来移除变换矩阵的位移部分。我们可以将观察矩阵转换为3x3矩阵(移除位移),再将其转换回4x4矩阵,来达到类似的效果。

修改viewMat

glm::mat4 view = glm::mat4(glm::mat3(camera.GetViewMatrix()));

优化

 在刚刚的过程中,是先画天空盒,在这中间关闭了深度测试。是因为我们想让其他物体画在天空盒上。不过这样不过高效,是因为在画天空盒的时候会对每个像素都跑一次片段着色器。

所以我们要最后渲染天空盒。但是怎么做呢?提前深度测试可以做到,我们先渲染其他东西,然后再提前深度测试通过的地方渲染天空盒就行了。

不过要知道的我们的天空盒只有1x1x1,其他东西很容易就在天空盒上,所以我们需要欺骗深度缓冲,或者说让他认为天空盒的深度值有最大,要让天空盒最深。

在坐标系统小节中我们说过,透视除法是在顶点着色器运行之后执行的,将gl_Position的xyz坐标除以w分量。我们又从深度测试小节中知道,相除结果的z分量等于顶点的深度值。使用这些信息,我们可以将输出位置的z分量等于它的w分量,让z分量永远等于1.0,这样子的话,当透视除法执行之后,z分量会变为w / w = 1.0

修改顶点着色器

void main(){vec4 pos = projMat*viewMat*vec4(aPos,1.0);gl_Position = pos.xyww;TexCoords = aPos;
}

修改main中的顺序,把天空盒放在其他物体之后,但是是再透明物体之前。

我们还要改变一下深度函数,将它从默认的GL_LESS改为GL_LEQUAL。

深度缓冲将会填充上天空盒的1.0值,所以我们需要保证天空盒在值小于或等于深度缓冲而不是小于时通过深度测试。

结果和之前一样

环境映射

现在我们可以通过这个环境纹理来给物体一些反射折射的属性了

反射

 这里灰色向量是我们的观察方向向量、红色是法向方向,绿色是反射方向,可以通过reflect()来获得,之后把这个绿色的向量作为天空盒的纹理方向坐标就可以获得立方体贴图了。

所以重新写一个反射天空盒的箱子着色器。

#version 330 corelayout(location = 0) in vec3 aPos;
layout(location =1) in vec3 aNormal;out vec3 Position;
out vec3 Normal;uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;void main(){Normal = mat3(transpose(inverse(modelMat)))*aNormal;Position = vec3(modelMat* vec4(aPos,1.0f));gl_Position = projMat * viewMat * modelMat*vec4(aPos,1.0f);
}#version 330 corein vec3 Position;
in vec3 Normal;out vec4 FragColor;uniform vec3 cameraPos;
uniform samplerCube skybox;void main(){vec3 viewDir = normalize(Position-cameraPos);vec3 refDir = reflect(viewDir,normalize(Normal));FragColor = vec4(texture(skybox,refDir).rgb,1.0f);
}

这里注意看下,因为片段着色器需要法向量信息,所以需要通过顶点着色器传个normal过去,但是这里是需要经过model变换的,也不能直接变换。所以需要通过

Normal = mat3(transpose(inverse(model))) * aNormal;

这样才能得到正确的法向量。

然后在main中 建立新的shader,绑定VAOVBO,之后再loop中画一个这样的cube,记得要把camera的position传进去。

//反射天空盒cubeskyboxReflectShader->use();modelMat = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 5.0f));viewMat = camera.GetViewMatrix();projMat = projMat = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);glUniformMatrix4fv(glGetUniformLocation(skyboxReflectShader->ID, "modelMat"), 1, GL_FALSE, glm::value_ptr(modelMat));glUniformMatrix4fv(glGetUniformLocation(skyboxReflectShader->ID, "viewMat"), 1, GL_FALSE, glm::value_ptr(viewMat));glUniformMatrix4fv(glGetUniformLocation(skyboxReflectShader->ID, "projMat"), 1, GL_FALSE, glm::value_ptr(projMat));glUniform3f(glGetUniformLocation(skyboxReflectShader->ID, "cameraPos"), camera.Position.x, camera.Position.y, camera.Position.z);glBindVertexArray(skyBoxReflectionVAO);glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);glDrawArrays(GL_TRIANGLES, 0, 36);

记得再画之前绑定一下天空盒的材质。

这是怎么少一个面呢,是因为面剔除的原因,这里的顶点坐标没有按照逆时针的顺序排列。

修改一下,在画的时候把面剔除关了。

 

OK了 。

如果直接另外画一个机器人模型,但是用这里的reflectShader的话

 这看起来非常棒,但在现实中大部分的模型都不具有完全反射性。我们可以引入反射贴图(Reflection Map),来给模型更多的细节。与漫反射和镜面光贴图一样,反射贴图也是可以采样的纹理图像,它决定这片段的反射性。通过使用反射贴图,我们可以知道模型的哪些部分该以什么强度显示反射。在本节的练习中,将由你来为我们之前创建的模型加载器中引入反射贴图,显著提升纳米装模型的细节。

折射

折射通过refract函数实现。需要一个法向量,一个观察方向,两个材质之间的折射率。

现在修改下片段着色器就好。

void main()
{             float ratio = 1.00 / 1.52;vec3 I = normalize(Position - cameraPos);vec3 R = refract(I, normalize(Normal), ratio);FragColor = vec4(texture(skybox, R).rgb, 1.0);
}

 它不太能显示折射的效果,现在看起来只是有点像一个放大镜。对纳米装使用相同的着色器却能够展现出了我们期待的效果:一个类玻璃的物体。

你可以想象出有了光照、反射、折射和顶点移动的正确组合,你可以创建出非常漂亮的水。注意,如果要想获得物理上精确的结果,我们还需要在光线离开物体的时候再次折射,现在我们使用的只是单面折射(Single-side Refraction),但它对大部分场合都是没问题的。

动态环境贴图

现在我们使用的都是静态图像的组合来作为天空盒,看起来很不错,但它没有在场景中包括可移动的物体。我们一直都没有注意到这一点,因为我们只使用了一个物体。如果我们有一个镜子一样的物体,周围还有多个物体,镜子中可见的只有天空盒,看起来就像它是场景中唯一一个物体一样。

通过使用帧缓冲,我们能够为物体的6个不同角度创建出场景的纹理,并在每个渲染迭代中将它们储存到一个立方体贴图中。之后我们就可以使用这个(动态生成的)立方体贴图来创建出更真实的,包含其它物体的,反射和折射表面了。这就叫做动态环境映射(Dynamic Environment Mapping),因为我们动态创建了物体周围的立方体贴图,并将其用作环境贴图。

虽然它看起来很棒,但它有一个很大的缺点:我们需要为使用环境贴图的物体渲染场景6次,这是对程序是非常大的性能开销。现代的程序通常会尽可能使用天空盒,并在可能的时候使用预编译的立方体贴图,只要它们能产生一点动态环境贴图的效果。虽然动态环境贴图是一个很棒的技术,但是要想在不降低性能的情况下让它工作还是需要非常多的技巧的。

相关文章:

(自用)learnOpenGL学习总结-高级OpenGL-立方体贴图

ok终于来到了立方体贴图了&#xff0c;在这里面我们可以加入好看的天空包围盒&#xff0c;这样的画我们的背景就不再是黑色的了&#xff01; 首先&#xff0c;立方体贴图和前面的sampler2D贴图一样&#xff0c;不过是6个2D组成的立方体而已。 那么为什么要把6个组合在一起呢&…...

【计算机网络】——TCP协议

&#x1f4d1;前言 本文主要是【计算机网络】——传输层TCP协议的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句…...

sql优化的方法

目录 一、准备数据 1.1、创建表结构 1.2、创建存储过程 二、索引介绍 2.1、类型介绍 2.2、建立索引 2.3、建立复合索引 2.4、查看所有建立的索引 2.5、删除索引 三、EXPLAIN分析参数说明 四、SQL优化案例 4.1、避免使用SELECT * 4.2、慎用UNION关键字 4.4、避免使…...

C++ Qt开发:运用QJSON模块解析数据

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍如何运用QJson组件的实现对JSON文本的灵活解析…...

MySQL数据库基础合集

MySQL数据库基础合集 目录 MySQL数据库基础合集SQL关键字DDL关键字DML关键字DQL关键字DCL关键字约束关键字 SQL基础数据类型整数类型字符类型浮点类型时间类型 数据定义语言DDL1.查看数据库2.创建库3.删除库4.切换库5.创建表6.删除表7.查看表8.查看表属性9.插入列10.修改列11.设…...

oracle19.22的patch已发布

2024年01月16日&#xff0c;oracle发布了19.22的patch 具体patch如下 Reserved for Database - Do not edit or delete (Doc ID 19202401.9) 文档ID规则如下 19&#xff08;版本&#xff09;年份&#xff08;202x&#xff09;(季度首月01,04,07,10).9 往期patch no信息和下…...

HTML+CSS:3D轮播卡片

效果演示 实现了一个3D翻转的卡片动画&#xff0c;其中每个卡片都有不同的图片和不同的旋转角度。整个动画循环播放&#xff0c;无限次。整个页面的背景是一个占据整个屏幕的背景图片&#xff0c;并且页面内容被隐藏在背景图片之下。 Code <div class"container"…...

ES 分词器

概述 分词器的主要作用将用户输入的一段文本&#xff0c;按照一定逻辑&#xff0c;分析成多个词语的一种工具 什么是分词器 顾名思义&#xff0c;文本分析就是把全文本转换成一系列单词&#xff08;term/token&#xff09;的过程&#xff0c;也叫分词。在 ES 中&#xff0c;Ana…...

从0开始搭建若依微服务项目 RuoYi-Cloud(保姆式教程完结)

文章接上一章&#xff1a; 从0开始搭建若依微服务项目 RuoYi-Cloud&#xff08;保姆式教程 一&#xff09;-CSDN博客 四. 项目配置与启动 当上面环境全部准备好之后&#xff0c;接下来就是项目配置。需要将项目相关配置修改成当前相关环境。 数据库配置 新建数据库&#xff…...

Linux true/false区分

bash的数值代表和其它代表相反&#xff1a;0表示true&#xff1b;非0代表false。 #!/bin/sh PIDFILE"pid"# truenginx进程运行 falsenginx进程未运行 checkRunning(){# -f true表示普通文件if [ -f "$PIDFILE" ]; then# -z 字符串长度为0trueif [ -z &qu…...

一些著名的软件都用什么语言编写?

1、操作系统 Microsoft Windows &#xff1a;汇编 -> C -> C 备注&#xff1a;曾经在智能手机的操作系统&#xff08;Windows Mobile&#xff09;考虑掺点C#写的程序&#xff0c;比如软键盘&#xff0c;结果因为写出来的程序太慢&#xff0c;实在无法和别的模块合并&…...

外卖跑腿系统开发:构建高效、安全的服务平台

在当今快节奏的生活中&#xff0c;外卖跑腿系统的开发已成为技术领域的一个重要课题。本文将介绍如何使用一些常见的编程语言和技术框架&#xff0c;构建一个高效、安全的外卖跑腿系统。 1. 技术选择 在开始开发之前&#xff0c;我们需要选择适合的技术栈。常用的技术包括&a…...

【MQ02】基础简单消息队列应用

基础简单消息队列应用 在上一课中&#xff0c;我们已经学习到了什么是消息队列&#xff0c;有哪些消息队列&#xff0c;以及我们会用到哪个消息队列。今天&#xff0c;就直接进入主题&#xff0c;学习第一种&#xff0c;最简单&#xff0c;但也是最常用&#xff0c;最好用的消息…...

CTF CRYPTO 密码学-7

题目名称&#xff1a;敲击 题目描述&#xff1a; 让我们回到最开始的地方 0110011001101100011000010110011101111011011000110110010100110011011001010011010100110000001100100110001100101101001101000011100001100011001110010010110100110100011001000011010100110000…...

随机森林和决策树区别

随机森林&#xff08;Random Forest&#xff09;和决策树&#xff08;Decision Tree&#xff09;是两种不同的机器学习算法&#xff0c;其中随机森林是基于决策树构建的一种集成学习方法。以下是它们之间的主要区别&#xff1a; 决策树: 单一模型: 决策树是一种单一模型&#…...

新建VM虚拟机-安装centOS7-连接finalshell调试

原文 这里有问题 首先进入/etc/sysconfig/network-scripts/目录 cd /etc/sysconfig/network-scripts/ 然后编辑文件 ifcfg-ens33 vi ifcfg-ens33...

936. 戳印序列

Problem: 936. 戳印序列 文章目录 思路解题方法复杂度Code 思路 这道题目要求我们通过使用印章来印刷目标字符串&#xff0c;使得目标字符串最终变成全为’?‘的字符串。我们可以使用贪心的思想来解决这个问题。 首先&#xff0c;我们需要找到所有可以匹配印章的位置&#xff…...

20240129收获

今天终于发现《八部金刚功》第五部我一直做的是错的&#xff0c;嗨。这里这个写法非常聪明&#xff0c;创立的数组&#xff0c;以及用obj[key] item[key]这样的写法&#xff0c;这个写法充分展示了js常规写法中只有等号右边会去参与运算&#xff0c;等号左边就是普通的键的写法…...

【虚拟机数据恢复】异常断电导致虚拟机无法启动的数据恢复案例

虚拟机数据恢复环境&#xff1a; 某品牌R710服务器MD3200存储&#xff0c;上层是ESXI虚拟机和虚拟机文件&#xff0c;虚拟机中存放有SQL Server数据库。 虚拟机故障&#xff1a; 机房非正常断电导致虚拟机无法启动。服务器管理员检查后发现虚拟机配置文件丢失&#xff0c;所幸…...

vue3 + antd 封装动态表单组件(三)

传送带&#xff1a; vue3 antd 封装动态表单组件&#xff08;一&#xff09; vue3 antd 封装动态表单组件&#xff08;二&#xff09; 前置条件&#xff1a; vue版本 v3.3.11 ant-design-vue版本 v4.1.1 我们发现ant-design-vue Input组件和FormItem组件某些属性支持slot插…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构&#xff1a;由肠系膜上静脉和脾静脉汇合构成&#xff0c;是肝脏血液供应的主要来源。淤血后果&#xff1a;门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血&#xff0c;引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...

内窥镜检查中基于提示的息肉分割|文献速递-深度学习医疗AI最新文献

Title 题目 Prompt-based polyp segmentation during endoscopy 内窥镜检查中基于提示的息肉分割 01 文献速递介绍 以下是对这段英文内容的中文翻译&#xff1a; ### 胃肠道癌症的发病率呈上升趋势&#xff0c;且有年轻化倾向&#xff08;Bray等人&#xff0c;2018&#x…...

Android Framework预装traceroute执行文件到system/bin下

文章目录 Android SDK中寻找traceroute代码内置traceroute到SDK中traceroute参数说明-I 参数&#xff08;使用 ICMP Echo 请求&#xff09;-T 参数&#xff08;使用 TCP SYN 包&#xff09; 相关文章 Android SDK中寻找traceroute代码 设备使用的是Android 11&#xff0c;在/s…...