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

WebGL实现透明物体(α混合)

目录

α混合 

如何实现α混合

1. 开启混合功能:

2. 指定混合函数 

混合函数 

gl.blendFunc()函数规范

可以指定给src_factor和dst_factor的常量 

混合后颜色的计算公式 

加法混合 

半透明的三角形(LookAtBlendedTriangles.js)

示例效果

示例代码 

半透明的三维物体(BlendedCube.js)

示例效果 

示例代码

透明与不透明物体共存

同时实现隐藏面消除和α混合的5个步骤

1.开启隐藏面消除功能。

2.绘制所有不透明的物体(α为1.0)。 

3.锁定用于进行隐藏面消除的深度缓冲区的写入操作,使之只读。 

4.绘制所有半透明的物体(α小于1.0),注意它们应当按照深度排序,然后从后向前绘制。 

5.释放深度缓冲区,使之可读可写。 

gl.depthMask()函数规范


α混合 

颜色中的α分量(即RGBA中的A)控制着颜色的透明度。如果一个物体颜色的α分量值为0.5,该物体就是半透明的,透过它可以看到该物体背后的其他物体。如果一个物体颜色的α分量值为0,那么它就是完全透明的,我们将完全看不到它。在本文的示例程序中,随着α分量的降低,整个绘图区域会逐渐成为白色,因为在默认情况下,α混合不仅影响绘制的物体,也会影响背景色,最后你看到的白色实际上是<canvas>后空白的网页。

如何实现α混合

需要遵循以下两个步骤来开启α混合。

1. 开启混合功能:

gl.enable(gl.BLEND)

2. 指定混合函数 

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

混合函数 

下面来研究gl.blendFunc()函数的作用。在进行α混合时,实际上WebGL用到了两个颜色,即源颜色(source color)和目标颜色(destination color),前者是“待混合进去”的颜色,后者是“待被混合进去的颜色”。比如说,我们先绘制了一个三角形,然后在这个三角形之上又绘制了一个三角形,那么在绘制后一个三角形(中与前一个三角形重叠区域的像素)的时候,就涉及混合操作,需要把后者的颜色“混入”前者中,后者的颜色就是源颜色,而前者的颜色就是目标颜色。

gl.blendFunc()函数规范

可以指定给src_factor和dst_factor的常量 

WebGL移除了OpenGL中的gl.CONSTANT_COLOR、gl.ONE_MINUS_CONSTANT_COLOR、gl.CONSTANT_ALPHA、gl.ONE_MINUS_CONSTANT_ALPHA

上表中,(Rs,Gs,Bs,As)和(Rd,Gd,Bd,Ad)表示源颜色和目标颜色的各个分量。

本文的示例程序都将使用

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

混合后颜色的计算公式 

这样,如果源颜色是半透明的绿色(0.0,1.0,0.0,0.4),目标颜色是普通(完全不透明)的黄色(1.0,1.0,0.0,1.0),那么src_factor即源颜色的α分量为0.4,而dst_factor则是(1- 0.4)=0.6,计算出混合后的颜色就是(0.6,1.0,0.0),如下图。 

加法混合 

你可以试试将src_factor和dst_factor参数指定为其他常量,比如,有一种常用的混合模式——加法混合 (additive blending),如下所示。加法混合会使被混合的区域更加明亮,通常被用来实现爆炸的光照效果,或者游戏中需要引起玩家注意的任务物品等。

gl.BlendFunc(gl.SRC_ALHPA, gl.ONE) 

半透明的三角形(LookAtBlendedTriangles.js

看一下示例程序LookAtBlendedTriangles,的运行效果如图中绘制了3个三角形并允许使用方向键来控制视点的位置。 本例将这3个三角形的α值从1.0改成0.4。下图显示了本例运行的效果。如你所见,三角形变成了半透明的,可以透过前面的三角形看到后面的三角形。使用方向键移动视点,可见半透明效果一直存在。、

示例效果

示例代码 

如下显示了LookAtBlendedTriangles.js的代码。我们开启了混合功能(第26行),指定了混合函数(第27行),并在initVertexBuffer()函数中修改三角形颜色的α分量值(第40~50行),gl.vertexAttribPointer()函数的size和stride参数也相应地作了修改。

var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec4 a_Color;\n' +'uniform mat4 u_ViewMatrix;\n' +'uniform mat4 u_ProjMatrix;\n' +'varying vec4 v_Color;\n' +'void main() {\n' +'  gl_Position = u_ProjMatrix * u_ViewMatrix * a_Position;\n' +'  v_Color = a_Color;\n' +'}\n';
var FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +'varying vec4 v_Color;\n' +'void main() {\n' +'  gl_FragColor = v_Color;\n' +'}\n';function main() {var canvas = document.getElementById('webgl');var gl = getWebGLContext(canvas);if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) returnvar n = initVertexBuffers(gl);gl.clearColor(0, 0, 0, 1);gl.enable (gl.BLEND); // 开启混合功能gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); // 指定混合函数var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');var viewMatrix = new Matrix4();window.onkeydown = function(ev){ keydown(ev, gl, n, u_ViewMatrix, viewMatrix); };var projMatrix = new Matrix4();projMatrix.setOrtho(-1, 1, -1, 1, 0, 2);gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);// Drawdraw(gl, n, u_ViewMatrix, viewMatrix);
}function initVertexBuffers(gl) {var verticesColors = new Float32Array([// 顶点坐标和颜色数据(颜色透明度是 0.4)0.0,  0.5,  -0.4,  0.4,  1.0,  0.4,  0.4, // The back green one-0.5, -0.5,  -0.4,  0.4,  1.0,  0.4,  0.4,0.5, -0.5,  -0.4,  1.0,  0.4,  0.4,  0.4, 0.5,  0.4,  -0.2,  1.0,  0.4,  0.4,  0.4, // The middle yerrow one-0.5,  0.4,  -0.2,  1.0,  1.0,  0.4,  0.4,0.0, -0.6,  -0.2,  1.0,  1.0,  0.4,  0.4, 0.0,  0.5,   0.0,  0.4,  0.4,  1.0,  0.4,  // The front blue one -0.5, -0.5,   0.0,  0.4,  0.4,  1.0,  0.4,0.5, -0.5,   0.0,  1.0,  0.4,  0.4,  0.4, ]);var n = 9;var vertexColorbuffer = gl.createBuffer();  gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);var FSIZE = verticesColors.BYTES_PER_ELEMENT;var a_Position = gl.getAttribLocation(gl.program, 'a_Position');gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 7, 0);gl.enableVertexAttribArray(a_Position);var a_Color = gl.getAttribLocation(gl.program, 'a_Color');gl.vertexAttribPointer(a_Color, 4, gl.FLOAT, false, FSIZE * 7, FSIZE * 3);gl.enableVertexAttribArray(a_Color);gl.bindBuffer(gl.ARRAY_BUFFER, null);return n;
}function keydown(ev, gl, n, u_ViewMatrix, viewMatrix) {if(ev.keyCode == 39) { // 按下了向右箭头键g_EyeX += 0.01;} else if (ev.keyCode == 37) { // 按下了向箭头键g_EyeX -= 0.01;} else return;draw(gl, n, u_ViewMatrix, viewMatrix);    
}// 眼位
var g_EyeX = 0.20, g_EyeY = 0.25, g_EyeZ = 0.25;
function draw(gl, n, u_ViewMatrix, viewMatrix) {viewMatrix.setLookAt(g_EyeX, g_EyeY, g_EyeZ, 0, 0, 0, 0, 1, 0);gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, n);
}

半透明的三维物体(BlendedCube.js)

此刻,我们将利用α混合功能,在一个典型的三维物体——立方体上实现半透明效果。示例程序BlendedCube在WebGL 从0到1绘制一个立方体_山楂树の的博客-CSDN博客中的ColoredCube的基础上,向代码中加入了使用α混合的两个步骤,如下图所示。 

示例效果 

 运行程序,你会发现并没出现下图(右)中预期的效果,实际的效果如下图(左)所示,和WebGL 从0到1绘制一个立方体_山楂树の的博客-CSDN博客的ColoredCube没有什么区别。

这是因为,程序开启了隐藏面消除功能(第27行)。我们知道,α混合发生在绘制片元的过程,而当隐藏面消除功能开启时,被隐藏的片元不会被绘制,所以也就不会发生混合过程,更不会有半透明的效果。实际上,只需要注释掉这一行开启隐藏面消除的代码即可。 

示例代码

var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec4 a_Color;\n' +'uniform mat4 u_MvpMatrix;\n' +'varying vec4 v_Color;\n' +'void main() {\n' +'  gl_Position = u_MvpMatrix * a_Position;\n' +'  v_Color = a_Color;\n' +'}\n';
var FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +'varying vec4 v_Color;\n' +'void main() {\n' +'  gl_FragColor = v_Color;\n' +'}\n';function main() {var canvas = document.getElementById('webgl');var gl = getWebGLContext(canvas);if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) returnvar n = initVertexBuffers(gl);// 设置清除背景色并开启深度测试gl.clearColor(0.0, 0.0, 0.0, 1.0);// gl.enable(gl.DEPTH_TEST);// 开启α混合gl.enable (gl.BLEND);// 设置混合函数gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');var mvpMatrix = new Matrix4();mvpMatrix.setPerspective(30, 1, 1, 100);mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0);gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
}function initVertexBuffers(gl) {//    v6----- v5//   /|      /|//  v1------v0|//  | |     | |//  | |v7---|-|v4//  |/      |///  v2------v3var vertices = new Float32Array([   // Vertex coordinates1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,    // v0-v1-v2-v3 front1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0,    // v0-v3-v4-v5 right1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0,    // v0-v5-v6-v1 up-1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,    // v1-v6-v7-v2 left-1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,    // v7-v4-v3-v2 down1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0     // v4-v7-v6-v5 back]);var colors = new Float32Array([     // Colors0.5, 0.5, 1.0, 0.4,  0.5, 0.5, 1.0, 0.4,  0.5, 0.5, 1.0, 0.4,  0.5, 0.5, 1.0, 0.4,  // v0-v1-v2-v3 front(blue)0.5, 1.0, 0.5, 0.4,  0.5, 1.0, 0.5, 0.4,  0.5, 1.0, 0.5, 0.4,  0.5, 1.0, 0.5, 0.4,  // v0-v3-v4-v5 right(green)1.0, 0.5, 0.5, 0.4,  1.0, 0.5, 0.5, 0.4,  1.0, 0.5, 0.5, 0.4,  1.0, 0.5, 0.5, 0.4,  // v0-v5-v6-v1 up(red)1.0, 1.0, 0.5, 0.4,  1.0, 1.0, 0.5, 0.4,  1.0, 1.0, 0.5, 0.4,  1.0, 1.0, 0.5, 0.4,  // v1-v6-v7-v2 left1.0, 1.0, 1.0, 0.4,  1.0, 1.0, 1.0, 0.4,  1.0, 1.0, 1.0, 0.4,  1.0, 1.0, 1.0, 0.4,  // v7-v4-v3-v2 down0.5, 1.0, 1.0, 0.4,  0.5, 1.0, 1.0, 0.4,  0.5, 1.0, 1.0, 0.4,  0.5, 1.0, 1.0, 0.4   // v4-v7-v6-v5 back]);var indices = new Uint8Array([       // Indices of the vertices0, 1, 2,   0, 2, 3,    // front4, 5, 6,   4, 6, 7,    // right8, 9,10,   8,10,11,    // up12,13,14,  12,14,15,    // left16,17,18,  16,18,19,    // down20,21,22,  20,22,23     // back]);var indexBuffer = gl.createBuffer();if (!initArrayBuffer(gl, vertices, 3, gl.FLOAT, 'a_Position')) return -1;if (!initArrayBuffer(gl, colors, 4, gl.FLOAT, 'a_Color')) return -1;gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);return indices.length;
}function initArrayBuffer(gl, data, num, type, attribute) {var buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);var a_attribute = gl.getAttribLocation(gl.program, attribute);gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);gl.enableVertexAttribArray(a_attribute);return true;
}

透明与不透明物体共存

关闭隐藏面消除功能只是一个粗暴的解决方案,并不能满足实际的需求。在绘制三维场景时,场景中往往既有不透明的物体,也有半透明的物体。如果关闭隐藏面消除功能,那些不透明物体的前后关系就会乱套了。

同时实现隐藏面消除和α混合的5个步骤

实际上,通过某种机制,可以同时实现隐藏面消除和半透明效果,我们只需要:

1.开启隐藏面消除功能。

gl.enable(gl.DEPTH_TEST)

2.绘制所有不透明的物体(α为1.0)。 

3.锁定用于进行隐藏面消除的深度缓冲区的写入操作,使之只读。 

gl.depthMask(false)

4.绘制所有半透明的物体(α小于1.0),注意它们应当按照深度排序,然后从后向前绘制。 

5.释放深度缓冲区,使之可读可写。 

gl.depthMask(true) 

gl.depthMask()函数用来锁定和释放深度缓冲区,其规范如下所示: 

gl.depthMask()函数规范

我们知道,深度缓冲区存储了每个像素的z坐标值(归一化为0.0到1.0之间)。假设场景中有两个前后重叠的三角形A和B。首先,在绘制三角形A的时候,将它的每个片元的z值写入深度缓冲区,然后在绘制三角形B的时候,将B中与A重叠的片元和深度缓冲区中对应像素的z值作比较:如果深度缓冲区中的z值小,就说明三角形A在前面,那么B的这个片元就被舍弃了,不会写入颜色缓冲区;如果深度缓冲区中的z值大,就说明三角形B在前面,就把B的这个片元写入颜色缓冲区中,将之前A的颜色覆盖掉。这样,当绘制完成时,颜色缓冲区中的所有像素都是最前面的片元,而且每个像素的z值都存储在深度缓冲区中。这就是隐藏面消除的原理。注意,所有这些操作都是在片元层面上进行的,所以如果两个面相交,也可以正常显示。 

当我们按照上述步骤同时绘制透明和不透明物体时,在第1步和第2步结束后,所有不透明的物体都正确地绘制在了颜色缓冲区中,深度缓冲区记录了每个像素(最前面的片元)的深度。然后进行第3、4和5步,绘制所有半透明的物体。由于深度缓冲区的存在,不透明物体后面的物体,即使是半透明的也不会显示。这是因为深度缓冲区的写操作被锁定了,所以在绘制不透明物体前面的透明物体时,也不会更新深度缓冲区。

相关文章:

WebGL实现透明物体(α混合)

目录 α混合 如何实现α混合 1. 开启混合功能: 2. 指定混合函数 混合函数 gl.blendFunc()函数规范 可以指定给src_factor和dst_factor的常量 混合后颜色的计算公式 加法混合 半透明的三角形(LookAtBlendedTriangl…...

RecycleView刷新功能

RecycleView刷新某一个Item,或这某一个Item中某一个View。 这样的需求,在实际的开发中是很普遍的。 在数据变化后需要刷新列表。 刷新列表有三种方式: 前两种大家应该很熟,第三中会有点陌生。 那么这三种方式,有什…...

目标检测如何演变:从区域提议和 Haar 级联到零样本技术

目录 一、说明 二、目标检测路线图 2.1 路线图(一般) 2.2 路线图(更传统的方法) 2.3 路线图(深度学习方法) 2.4 对象检测指标的改进 三、传统检测方法 3.1 维奥拉-琼斯探测器 (2001) 3.2 HOG探测器…...

聊一聊国内大模型公司,大模型面试心得、经验、感受

有着过硬的技术却无处可用是不是很苦恼呢,大家在面试时是不是也积累了一些经验呢,本文详细总结了大佬在大模型面试时的一些经验及感悟,希望对大家面试找工作有所帮助。 2023年,大模型突然国内火了起来,笔者就面了一些…...

【分布式微服务】feign 异步调用获取不到ServletRequestAttributes

公司调用接口的时候使用feign,但是服务之间还是使用了鉴权,需要通过RequestInterceptor 去传递uuid 概念 OpenFeign是一个声明式的Web服务客户端,它使得编写HTTP客户端变得更简单。在使用OpenFeign进行异步调用时,你可以通过配置来实现。但是,如果你在配置或调用过程中遇…...

c#编程里面最复杂的技术问题有哪些

C#编程中最复杂的技术问题通常涉及高级主题和复杂的应用场景。以下是一些可能被认为是C#编程中最复杂的技术问题: 1. **多线程和并发编程:** 处理多线程和并发问题涉及到锁定、线程同步、死锁避免、线程安全性和性能优化等方面的知识。编写高效且线程安…...

github代码提交过程详细介绍

1、下载github上面的代码 (1)在github网站上,找到想要下载的代码仓库界面,点击Code选项就可以看到仓库的git下载地址; (2)使用命令下载:git clone 地址; 2、配置本地git…...

Linux -- 使用多张gpu卡进行深度学习任务(以tensorflow为例)

在linux系统上进行多gpu卡的深度学习任务 确保已安装最新的 TensorFlow GPU 版本。 import tensorflow as tf print("Num GPUs Available: ", len(tf.config.list_physical_devices(GPU)))1、确保你已经正确安装了tensorflow和相关的GPU驱动,这里可以通…...

Mendix中的依赖管理:npm和Maven的应用

序言 在传统java开发项目中,我们可以利用maven来管理jar包依赖,但在mendix项目开发Custom Java Action时,由于目录结构有一些差异,我们需要自行配置。同样的,在mendix项目开发Custom JavaScript Action时,…...

自定义hooks之useLastState、useSafeState

自定义hooks之useLastState、useSafeState useLastState 在某些情况下,可能需要知道状态的历史值,例如,希望在状态变化时执行某些操作,但又需要访问上一个状态的值,以便进行比较或其他操作。自定义 React Hook 可以帮…...

前端判断: []+[], []+{}, {}+[], {}+{}

本质: 二元操作符规则 一般判断规则: 如果操作数是对象,则对象会转换为原始值如果其中一个操作数是字符串的话,另一个操作数也会转换成字符串,进行字符串拼接否则,两个操作数都将转换成数字或NaN,进行加法操作 转为原始数据类型的值的方法: Symbol.ToPrimitiveObject.protot…...

el-input-number/el-input 实现实时输入数字转换千分位(失焦时展示千分位)

el-input-number/el-input 实现实时输入数字转换千分位(失焦时展示千分位) 我把封装指令的代码放在了main.js,代码如下 // 金额展示千分位 Vue.directive("thousands", {inserted: function(el, binding) {// debugger// 获取input节点if (el.tagName.toLocaleUppe…...

一篇博客学会系列(2)—— C语言中的自定义类型 :结构体、位段、枚举、联合体

目录 前言 1、结构体 1.1、结构体类型的声明 1.2、特殊的结构体类型声明 1.3、结构体的自引用 1.4、结构体的定义和初始化 1.5、结构体成员变量的调用 1.6、结构体内存对齐 1.6.1、offsetof 1.6.2、结构体大小的计算 1.6.3、为什么存在内存对齐? 1.7、…...

KongA 任意用户登录漏洞分析

KongA 简介 KongA 介绍 KongA 是 Kong 的一个 GUI 工具。GitHub 地址是 https://github.com/pantsel/konga 。 KongA 概述 KongA 带来的一个最大的便利就是可以很好地通过UI观察到现在 Kong 的所有的配置,并且可以对于管理 Kong 节点 漏洞成因 未设置TOKEN_SECRE…...

吉力宝:智能科技鞋品牌步力宝引领传统产业创新思维

在现代经济环境下,市场经济下产品的竞争非常的激烈,如果没有营销,产品很可能不被大众认可,酒香也怕巷子深,许多传统产业不得不面临前所未有的挑战。而为了冲出这个“巷子”,许多企业需要采用创新思维&#…...

【IPC 通信】信号处理接口 Signal API(1)

收发信号思想是 Linux 程序设计特性之一,一个信号可以认为是一种软中断,通过用来向进程通知异步事件。 本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解信号编程。 信号概述 遵循 POSIX.1,…...

使用GDIView排查GDI对象泄漏导致的程序UI界面绘制异常问题

目录 1、问题说明 2、初步分析 3、查看任务管理器,并使用GDIView工具分析 4、GDIView可能对Win10兼容性不好,显示的GDI对象个数不太准确 5、采用历史版本比对法,确定初次出现问题的时间点,并查看前一天的代码修改记录 6、将…...

蓝桥等考Python组别一级001

第一部分:选择题 1、Python L1 (15分) 下面哪个不是Python的编程环境?( ) Python在线编程IDLEPyCharmScratch正确答案:D 2、Python L1(15分) 世界上第一台通用电子计算机ENIAC是在( )诞生的。 美国英国日本德国正确答案:A 3、Python L1(20分) 关于P…...

Unity之Hololens2开发 如何接入的MRTK OpenXR Plugin

一.前言 什么是Hololens? Hololens是由微软开发的一款混合现实头戴式设备,它将虚拟内容与现实世界相结合,为用户提供了沉浸式的AR体验。Hololens通过内置的传感器和摄像头,能够感知用户的环境,并在用户的视野中显示虚拟对象。这使得用户可以与虚拟内容进行互动,将数字信…...

Ubuntu系统Linux内核安装和使用

安装: 检查树莓派Linux版本,我的是6.1 uname -r 内核下载链接: Raspberry Pi GitHub 找对应版本下载 导入之后,解压安装即可 unzip linux-rpi-6.1.y.zip 其他内容 treee 指令安装 sudo apt-get install tree 使用这…...

数学术语之源——群同态的“核(kernel)”

1. “kernel”这个术语在群论中的起源 Ivar Fredholm 在 1903 年的第27期Acta Math 数学学报发表的一篇关于“积分方程(INTEGRAL EQUATIONS)”的著名论文(“关于一类函数方程(Sur une classe des quations fonctionnelles)”)中使用了法语“noyau(核)”(365-390页)。 David …...

defcon-quals 2023 crackme.tscript.dso wp

将dso文件放到data/ExampleModule目录下,编辑ExampleModule.tscript文件 function ExampleModule::onCreate(%this) { trace(true); exec("./crackme"); __main("aaaaaaaa"); quit(); } 然后点击主目录下的Torque3D-debug.bat就可以在生成的c…...

前端开发 vs. 后端开发:编程之路的选择

文章目录 前端开发:用户界面的创造者1. HTML/CSS/JavaScript:2. 用户体验设计:3. 响应式设计:4. 前端框架: 后端开发:数据和逻辑的构建者1. 服务器端编程:2. 数据库:3. 安全性&#…...

算法练习4——删除有序数组中的重复项 II

LeetCode 80 删除有序数组中的重复项 II 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 …...

【C++进阶(六)】STL大法--栈和队列深度剖析优先级队列适配器原理

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C   🔝🔝 栈和队列 1. 前言2. 栈和队列的接口函数熟悉3. …...

linux opensuse使用mtk烧录工具flashtool

环境 linux发行版:opensuse leap 15.5 工具:SP_Flash_Tool_Selector_exe_Linux_v1.2316.00.100.rar 或其他版本 目标:mtk设备 下载链接 https://download.csdn.net/download/zmlovelx/88382784 或网络搜索。 使用 opensuse可直接解压后使…...

Visio如何对文本打下标、上标,以及插入公式编辑器等问题(已解决)

解决这个问题的本质问题,就是在Visio中插入公式编辑器(这不是visio的常用命令,需要添加)。 打开Visio--》文件--选项 点击选项,弹出对话框。在自定义功能区中,点击 常用命令,在下拉选项中&#…...

快速将iPhone大量照片快速传输到电脑的办法!

很多使用iPhone 的朋友要将照片传到电脑时,第一时间都只想到用iTunes 或iCloud,但这2个工具真的都非常难用,今天小编分享牛学长苹果数据管理工具的照片传输功能,他可以快速的将iPhone照片传输到电脑上,并且支持最新的i…...

TCP/IP协议簇包含的协议

应用层(Application Layer): HTTP(Hypertext Transfer Protocol):用于Web浏览器和Web服务器之间的通信。HTTPS(Hypertext Transfer Protocol Secure):安全的HTTP版本&…...

天地图绘制区域图层

背景&#xff1a; 业务方要求将 原效果图 参考效果图 最终实现效果 变更点&#xff1a; 1.将原有的高德地图改为天地图 2.呈现形式修改&#xff1a;加两层遮罩&#xff1a;半透明遮罩层mask区域覆盖物mask 实现过程&#xff1a; 1.更换地图引入源 <link rel"style…...

wordpress什么用/友情链接交换方式有哪些

| 极市线上分享 第71期 |一直以来&#xff0c;为让大家更好地了解学界业界优秀的论文和工作&#xff0c;极市已邀请了超过90位技术大咖嘉宾&#xff0c;并完成了70期极市线上直播分享。往期分享请前往bbs.cvmart.net/topics/149&#xff0c;也欢迎各位小伙伴自荐或推荐更多多优…...

微信咋做自己的网站/宣传软文模板

184行前添加&#xff1a; if (asm.GetType().FullName ! "System.Reflection.RuntimeAssembly") continue;忽略错误 缓存的Provider 不能执行 存储过程&#xff0c;报 NotSupportedException("Command tree type " commandTree.GetType() " is not …...

阿里百秀wordpress/港港网app下载最新版

转载于:https://www.cnblogs.com/supper-Ho/p/6264023.html...

网站建设包括什么/百度云网盘下载

大部分的数据分析师都或多或少掉入这样的陷阱&#xff1a;每天大部分的工作都花在查数上&#xff0c;干着干着变成了“查数菇”。看上去帮老板或其他同事查数据是数据分析师天经地义的任务&#xff0c;怎么会成为陷阱呢&#xff1f;我来给你分析分析&#xff1a;业务部门需求多…...

做设计的地图网站/网站怎样优化文章关键词

ZMQ (以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层&#xff0c;像框架一样的一个 socket library&#xff0c;他使得 Socket 编程更加简单、简洁和性能更高。是一个消息处理队列库&#xff0c;可在多个线程、内核和主机盒之间弹性伸缩。ZMQ 的明确目标是“成为标准网络协议栈的…...

轴承 网站建设 企炬/seo顾问张智伟

LDAP介绍LDAP概述LDAP是轻量目录访问协议&#xff0c;(LDAP, Lightweight Directory Access Protocol)LDAP是用于访问目录服务(特别是基于X.500的目录服务)&#xff0c;LDAP在TCP/IP或其他面向连接的传输服务上运行。LDAP是IETF标准的跟踪协议。  LDAP是目录非关系型的&#…...