高级着色语言(HLSL)

High-Level Shading Language,简称为HLSL,可以使用HLSL编写顶点着色器和像素着色器程序,简要地说,顶点着色器像素着色器就是我们自行编写的一些规模较小的定制程序,这些定制程序可取代固定功能流水线中某一功能模块,并可在图形卡的GPU(Graphics Processing Unit,.图形处理单元)中执行。通过这种功能替换,我们便在实现各种图形效果时获得了巨大的灵活性。也就是说,我们不再受制于那些预定义的“固定”运算。

还有一点要注意,如果您的图形卡不支持项点着色器和像素着色器,在运行着色器例程时,请务必切换至REF设备。使用REF设备也就意味着该着色器例程的运行速度将会很慢,但显示的结果一定是正确的,这样我们仍可验证代码的正确性。顶点着色器可用软件顶点运算方式来模拟,即在创建设备时,将设备行为标记设定为D3DCREATE_SOFTWARE_VERTEXPROCESSING

HLSL着色器程序的编制

HLSL着色器程序可以一个长字符串的形式出现在应用程序的源文件中。但更方便也更模块化的做法是将着色器代码与应用程序代码分离。基于上述考虑,我们可在记事本中编写着色器代码并将其保存为常规的ASCll文本文件。接下来就可以使用函数D3DXCompileShaderFromFile对着色器文件进行编译了。

下面向您介绍一个用HLSL编写的顶点着色器程序,该程序是在记事本中编辑的,并保存在文本文件“Transform.txt”中。该顶点着色器程序对顶点实施了取景变换(view transformation)和投影变换(projection transformation),并将顶点的漫反射颜色分量设为蓝色。

全局变量

matrix ViewProjMatrix;
vector Blue={0.0f,0.0f,1.0f,1.0f};

matrix是HLSL中内置类型,表示维数4x4的矩阵,该变量存储了取景变换矩阵和投影变换矩阵的乘积,这样它就同时描述了俩种变换,vector表示一个4D向量,我们只是将其视为RGBA颜色向量,并将其初始化为蓝色。

输入和输出结构

struct VS_INPUT
{
    vector position : POSITION;
};

struct VS_OUTPUT
{
    vector position : POSITION;
    vector diffuse : COLOR;
};

对于顶点着色器,输入和输出结构分别定义了该着色器的输入和输出的顶点数据,冒号语法用来指定变量的用途,:POSITION的意思指position用于描述输入顶点的位置信息,:COLOR意思是指diffuse用于描述输出顶点的颜色信息。

从底层观点看,语义语法建立了着色器中的变量与硬件寄存器之间的联系。即输入变量总是与输入寄存器相联系的,而输出变量总是与输出寄存器相联系的。例如,VS_INPUT结构的成员position将被连接到一个特定的项点输入位置寄存器。类似地,VS_OUTPUT结构中的diffuse成员将被连接到一个特定的顶点输出颜色寄存器。

入口函数

像C++程序一样,每个HLSL程序也应该有一个入口点。在上面的着色器例程中,入口函数为Main。但是,该名称并非强制性的。在遵循函数命名规则的前提下,着色器的入口函数的命名可自由选择。入口函数必须有一个可接收输入结构的参数,该参数将用于把输入顶点传给着色器,而且入口函数必须返回一个输出结构的实例,用来将经过处理的顶点自着色器输出。mul是HLSL的内置函数,它既可进行向量-矩阵乘法,也可以进行矩阵-矩阵乘法。

VS_OUTPUT Main(VS_INPUT input)
{
    //对该结构示例化,并将各成员设为0
    VS_OUTPUT output = (VS_OUTPUT)0;
    output.position = mul(input.position,ViewProjMatrix);
    output.diffuse = Blue;
    return output;
}

输入和输出结构的使用并非强制性,例如有时会遇到类似下面的用法,该用法在像素着色器程序中尤为常见,我们输入3个纹理坐标,着色器返回一个单个颜色作为输出,这是通过在函数签名后加上":COLOR":从语义层面表示的。

float4 Main(in float2 base : TEXCOORD0, in float2 spot : TEXCOORD1, in float2 text : TEXCOORD2) : COLOR
{
}

上面定义等价于

struct INPUT
{
    float2 base : TEXCOORD0;
    float2 spot : TEXCOORD1;
    float2 text : TEXCOORD2;
};

sturct OUTPUT
{
    float4 c : COLOR;
};

OUTPUT Main(INPUT input)
{
    ...
}

常量表

每个着色器都用常量表来存储其变量。为了使应用程序能够访问着色器的常量表,D3DX库提供了接口ID3DXConstantTable。借助该接口,我们可在应用程序源代码中对着色器源代码中的变量进行设置

获取常量的句柄

为了从应用程序的源代码中对着色器程序中的某个变量进行设置,我们需要用某种方式来引用该变量。D3DXHANDLE类型的句柄恰合此意。当给定着色器中我们期望引用的那个变量的名称时,下面的函数将返回个引用了该变量的D3DXHANDLE类型的句柄(Handle)。

D3DXHANDLE ID3DXConstantTable::GetConstantByName(D3DXHANDLE hConstant,LPCSTR pName);

D3DXHANDLE h0;
h0 = ConstTable->GetConstantByName(0,"ViewProjMatrix");

hConstant:一个D3DXHANDLE类型的句柄,标识了那个包含了我们希望获取其句柄的变量的父结构。例如,如果我们希望得到某个特定结构实例的一个单个数据成员的句柄,可为该参数传入该结构实例的句柄。如果想要获取指向顶级变量的句柄,应将该参数指定为0
pName:我们希望获取其句柄的那个着色器源代码中的变量的名称。

常量的设置

一旦应用程序获取了着色器代码中希望被引用的那个变量的D3DXHANDLE类型的句柄,我们就可在应用程序中使用方法ID3DXConstantTable:SetXXX对该变量进行设置,其中XXX表示被设置变量的类型名称,实际调用时只要用类型名将其替换即可。例如,如果我们希望设置的变量为一个vector类型的数组,该方法将对应Set VectorArray。该方法的通用签名如下

HRESULT ID3DXConstantTable::SetXXX(
LPDIRECT3DDEVICE9 pDevice,
D3DXHANDLE hConstant, 
XXX value
);

pDevice:设备指针
hConstant:想要设置那个变量句柄
value:指定了我们引用的那个着色器中的变量应被赋为何值,XXX应替换为该额类型名,对于某些类型(bool,it,float),我们传入的是该值的一个副本,而对另外一些类型(向量、矩阵、结构体),我们传入的是指向该值(value)的指针。如果要对数组进行设置,SetXXX方法还应增加一个参数,以接收该数组的维数

HRESULT ID3DXConstantTable::SetVectorArray(
LPDIRECT3DDEVICE9 pDevice,
D3DXHANDLE hConstant, 
CONST D3DXVECTOR4* pVector,
UINT Count
);

SetBool 用于设置一个布尔值
bool b = true;
CostTable->SetBool(Device,handle,b);

SetBoolArray 用于设置布尔数组
bool b[3] = {true,false,true};
CostTable->SetBoolArray(Device,handle,b,3);

SetFloat 
float f = 3.14f;
CostTable->SetFloat(Device,handle,f);

SetFloatArray 
float f[2] = {1.0f,2.0f};
CostTable->SetFloatArray(Device,handle,f,2);

SetInt 
int x = 4;
CostTable->SetInt(Device,handle,x);

SetIntArray
int x[4] = {1,2,3,4};
CostTable->SetIntArray(Device,handle,x,4);

SetMatrix 用于设置一个4x4矩阵
D3DMATRIX M(...);
CostTable->SetMatrix(Device,handle,&M);

SetMatrixArray 用于设置一个4x4的矩阵数组
D3DMATRIX M[4];
//初始化矩阵...
CostTable->SetMatrixArray(Device,handle,M,4);

SetMatrixPointerArray用于设置一个4×4矩阵的指针数组
D3DXMATRIX*M(4];
//...Allocate and initialize matrix pointers
ConstTable->SetMatrixPointerArray(Device,handle,M,4);

SetMatrixTranspose 用于设置一个4×4的转置矩阵
D3DXMATRIX M(...)
D3DXMatrixTranspose (&M,&M);
ConstTable->SetMatrixTranspose(Device,handle,&M);

SetMatrixTransposeArray 用于设置一个4x4的转置矩阵数组
D3DXMATRIX M[4];
//..Initialize matrices and transpose them.
ConstTable->SetMatrixTransposeArray(Device,handle,M,4);

SetMatrixTransposePointerArray 用于设置4×4的转置矩阵的指针数组。调用实例:
D3DXMATRIX*M[4];
//...Allocate,initialize matrix pointers and transpose them.
ConstTable->SetMatrixTransposePointerArray(Device,handle,M,4)

SetVector 用于设置一个D3DXVECTOR4类型的变量
D3DXVECTOR4 v(1.0f,2.0f,3.0f,4.0f);
ConstTable->SetVector(Device,handle,&v);

SetVectorArray 用于设置向量数组类型的变量
D3DXVECTOR4 v[3];
//...Initialize vectors
ConstTable->SetVectorArray(Device,handle,v,3);

SetValue   用于设置大小任意的类型,例如结构体。在下面的调用实例中,我们用该函数对
一个D3DXMATRIX类型的变量进行了设置:
D3DXMATRIX M(...);
ConstTable->SetValue(Device,handle,(void*)&M,sizeof(M));

设置常量的默认值

下面的方法仪是将常量设为其默认值,即那些在变量声明时被赋予的初值。该方法在应用程序的设置过程中应调用一次。

HRESULT ID3DXConstantTable::SetDefaults(
LPDIRECT3DDEVICE9 pDevice
);

HLSL着色器程序的编译

HRESULT D3DXCompileShaderFromFile(
LPCSTR pSrcFile,
CONST D3DXMACRO* pDefines,
LPD3DXINCLUDE pInclude,
LPCSTR pFunctionName,
LPCSTR pTarget,
DWORD Flags,
LPD3DXBUFFER* ppShader,
LPD3DXBUFFER* ppErrorMsgs,
LPD3DXCONSTANTTABLE* ppConstantTable
);

pSrcFile:我们想要进行编译的、保存了着色器源代码的那个文本文件的名称。
pDefines:该参数可选,本书中我们将该参数设为NULL。
pInclude:指向ID3DXInterface接口的指针。应用程序应实现该接凵,以重载默认的include行为(include behavior)。通常,默认的include行为已足够满足要求,我们将该参数指定为NULL而将其忽略。
pFunctionName:一个指定了着色器入口函数名称的字符串。例如,如果着色器的入口函数为Main,该参数应赋为“Main”。
pTarget:指定了要将HLSL源代码编译成的着色器版本,该参数为一字符串。合法的顶点着色器版本有:vs1_1、vs2_0、vs_2_sw。合法的像素着色器版本有:ps_1_1、ps_1_2、ps_1_3、ps_1_4、ps_2_0、ps_2_sw。例如,如果我们想将顶点着色器编译为2.0版本,则需要将该参
数指定为vs_2_0。这种能够编译为不同着色器版本的能力是HLSL与汇编语言相比的一个主要优势。借助HLSL我们几乎可以即时地将一个着色器移植到不同版本中,而您所要做的仅仅是指定编译目标后重新执行编译。而如果编写着色器程序时使用了汇编语言,您只能手工进行移植。
Flags:可选的编译选项。若该参数设为0,表示不使用任何选项。合法的选项包括:

  • D3DXSHADER_DEBUG指示编译器写入调试信息
  • D3DXSHADER_SKIPVALIDATION指示编译器不要进行任何代码验证。仅当您正在使用一个已确定可用的着色器时,该参数才被使用。
  • D3DXSHADER_SKIPOPTIMIZATION指示编译器不要对代码做任何优化。实际上,仅在调试时该选项有用,因为调试时您不希望编译器对代码做任何改动。

ppShader:返回一个指向接口ID3DXBuffer的指针,该接口包含了编译后的着色器代码。然后编译后的着色器代码就可作为另个函数的参数来创建实际的顶点着色器或像素着色器。
ppErrorMsgs:返回个指向接口ID3DXBuffer的指针,该接口包含了一个存储了错误代码和消息的字符串。
ppConstantTable:返回一个指向接口ID3DXConstantTable的指针,该接口包含了该着色器的常量表数据。

ID3DXConstantTable* TransformConstantTable = 0;
ID3DXBuffer* shader = 0:
ID3DXBuffer* errorBuffer = 0;
hr = D3DXCompileShaderFromFile(
"transform.txt",
0,
0,
"Main",
"vs_2_0",
D3DXSHADER DEBUG,
&shader,
&errorBuffer,
&TransformConstantTable);

if(errorBuffer)
{
    ::MessageBox(0,(char*)errorBuffer->GetBufferPointer(),0,0);
    d3d::Release<ID3DXBuffer*>(errorBuffer);
}

if (FAILED(hr))
{
    ::MessageBox(0,"D3DXCreateEffectFromFile()-FAILED",0,0);
    return false;
}

HLSL支持的变量类型

标量类型
  • bool  布尔值  注意,HLSL提供了关键词true和false。
  • int  32位的有符号整数。
  • half  16位的浮点数。
  • float  32位的浮点数。
  • double  64位的浮点数。

有些平台可能不支持int、half和double。如果遇到这种情况,这些类型将用float来模拟。

向量类型
  • vector  一个4D向量,其中每个元素的类型都是float。
  • vector<T,n>  一个n维向量,其中每个元素的类型均为标量类型T。维数n必须介于1~4之间。下面是一个二维double型向量的例子。

我们可通过数组下标语法来访问向量的每个元素。此外,借助一些已定义的分量名x,y,z,w,r,g,b,a,我们还可像访问结构体中成员那样访问向量vec中的分量。这些名称r、g、b、a与x、y、z、w一样,分别精确地指向了同一分量。当用向量表示颜色时,我们更倾向于使用RGBA表示法,因为这将有助于强调该向量代表了某种颜色的事实。我们还可使用其他预定义类型来分别表示2D向量、3D向量和4D向量。

vec[i] = 2.0f;

vec.x = vec.r = 1.0f;
vec.y = vec.g = 2.0f;
vec.z = vec.b = 3.0f;
vec.w = vec.a = 4.0f;

float2 vec2;
float3 vec3;
float4 vec4;

替换调配:给定向量u=(u_{x},u_{y},u_{z},u_{w}),假定我们要将向量u的各分量复制到向量v中,使得v=(u_{x},u_{y},u_{z},u_{w})。最直接的做法是将u的各元素逐个复制到v对应的元素中。但是,HLSL提供了一种特殊的语法一“替换调配(swizzles)”来专门用来完成这类不关心顺序的复制操作。对向量进行复制操作时,我们不一定非要对每个分量进行复制(可有选择地复制)。例如,我们可仅复制x和y分量。

vector u = {1.0f,2.0f,3.0f,4.0f};
vector v = {0.0f,0.0f,5.0f,6.0f}:
v = y.xyyw; //v={1.0f,2.0f,2.0f,4.0f}

vector u = {1.0f,2.0f,3.0f,4.0f};
vector v = {0.0f,0.0f,5.0f,6.0f};
v.xy=u;  //v=1.0f,2.0f,5.0f,6.0f}
矩阵类型
  • matrix表示一个4×4矩阵,该矩阵中每个元素的类型均为float。
  • matrix<T,m,n>表示一个m×n矩阵,其中的每个元素都为标量类型T。该矩阵的维数m和n必须介于1~4之间。例如,要表示一个2×2的整型矩阵,可写作:matrix<int,2,2> m2x2;
  • 我们还可用如下语法来定义一个m×n矩阵,其中m和n必须介于1~4之间。floatmxn matmxn

矩阵类型可以不是float类型,我们也可使用其他类型

float2x2 mat2x2;
float3x3 mat3x3;
float4x4 mat4x4;
f1oat2x4 mat2×4;

int2x2 i2×2;

我们可用数组的双下标语法来访问矩阵的各项(enty,元素)。要对矩阵M中第i行、第j列的项进行设置,可以这样以下这样,此外,我们还可以像访问结构体中的成员那样访问矩阵M中的项。HLSL己定义了下列项名称。

M[i][j] = value;

//下标从1开始
M._11 = M._12 =M._13 = M._14 = 0.0f:
M._21 = M._22 =M._23 = M._24 = 0.0f:
M._31 = M._32 =M._33 = M._34 = 0.0f:
M._41 = M._42 =M._43 = M._44 = 0.0f:

//下标从0开始
M._m00 = M._m01 = M._m02 = M._m03 = 0.0f;
M._m10 = M._m11 = M._m12 = M._m13 = 0.0f;
M._m20 = M._m21 = M._m22 = M._m23 = 0.0f;
M._m30 = M._m31 = M._m32 = M._m33 = 0.0f;

有时,我们想要引用矩阵中某一特定行。我们可通过数组单下标语法来实现。例如,要想引用矩阵M的第i行,可以这样做:

vector ithRow = M[i];

初始化方式可以直接初始化也可以通过构造函数进行初始化

vector u={0.6f,0.3f,1.0f,1.0f};
vector v={1.0f,5.0f,0.2f,1.0f}:

vector u vector(0.6f,0.3f,1.0f,1.0f);
vector v vector(1.0f,5.0f,0.2f,1.0f);

float2x2 f2x2 = float2x2(1.0f,2.0f,3.0f,4.0f);
int2x2 m={1,2,3,4};
int n = int(5);
int a = {5};
float3 x = float3(0,0,0);
数组
f1oat M[4][4];
half p[4];
vector v[12];
结构体

HLSL中的结构体定义方法与C++完全相同。但是,HLSL中的结构体不允许有成员函数。下面是一个HLSL中结构体的例子。

struct MyStruct
{
    Matrix T;
    vector n;
    float f;
    int   x;
    bool  b;
};
MyStruct s;
s.f = 5.0f;

变量的前缀

static:如果全局变量在声明时使用了关键字static,就意味着这个变量在该着色器程序外不可见。这个全局变量是该着色器程序的局部变量。与C++中的局部变量具有完全相同的行为。即,包含该局部变量的函数在首次被调用时,该变量仅初始化一次,而且在该函数的所有调用过程中,该变量都对自身当前值进行维护(每次该函数调用结束时,该变量仍然保留了调用过程中的状态,直至主
程序的生命期结束)。如果在函数中没有对该变量进行初始化,该变量将自动初始化为0。

 uniform:如果变量声明时使用了关键字uniform,表明该变量将在该着色器之外进行初始化。例如,在C++应用程序中对该变量进行初始化,然后再作为输入传给该着色器。

extern:如果变量声明时使用了关键字extern,表明该变量可在该着色器程序之外进行访问,例如可由C++程序对其进行访问。只有全局变量可以使用关键字extern。非静态的全局变量在默认状态下都是extern类型的。

shared:如果变量声明时使用了关键字shared,则提示效果框架该变量可在多个效果之间共享。只有全局变量方可使用该关键字进行声明

volatile:如果变量声明时使用了关键字volatile,则提示效果框架该变量将经常被修改。只有全局变量方可使用该关键字进行声明。

const:HLSL中的const关键字与C++中的含义完全相同。

类型转换

HLSL支持一种灵活的类型转换机制。HLSL中的类型转换语法与C语言的完全相同。例如,如果要
将float类型转换为matrix类型,可以这样做

float f 5.0f;
matrix m = (matrix)f;

运算符

运算符的行为与C++中的非常相似,但仍有一些差别。首先,取模运算符%适用于整型和浮点型数据。使用取模运算符时,左操作数和右操作数必须同号(即左右操作数必须同为正或同为负)。其次需要注意,许多HLSL运算都是在变量的分量级(component basis)上进行的。这是由于向量和矩阵都是HLSL的内置类型,而这些类型都由若干分量组成。由于有了能够在分量级上进行运算的运算符,如向量/知阵加法、向量/矩阵减法、向量/矩阵的相等测试等运算就可使用与标量类型相同的运算符来进行了。下面给出了几个例子。

vector u = {1.0f,0.0f,-3.0f,1.0f}:
vector v = {-4.0f,2.0f,1.0f,0.0f};
vector sum = u + v; //sum (-3.0f,2.0f,-2.0f,1.0f)

向量自增也就是每个分量进行自增:
sum++; //after increment:sum (-2.0f,3.0f,-1.0f,2.0f)

向量的逐分量(component-.wise)相乘:
vector u={1.0f,0.0f,-3.0f,1.0f}:
vector v={-4.0f,2.0f,1.0f,0.0f}:
vector sum =  u * v;  //product (-4.0f,0.0f,-3.0f,0.0f)

比较运算符也是在分量上操作的,并将返回一个bool型的向量或矩阵(其每个分量的类型均为bool
型)。返回的“bool”向量包含了两个分量的比较结果。例如:
vector u = {1.0f,0.0f,-3.0f,1.0f}
vector v = {-4.0f,0.0f,1.0f,1.0f};
vector b = (u==v);  //b = (false,true,false,true)

双目运算中的变量类型提升:

  • 对于双目运算,如果左操作数与右操作数的维数不同,则维数较小的操作数得到提升(类型转换)使得其维数与原先维数较大的操作数相同。例如,如果x的类型为float,y的类型为float3,则在表达式(x+y)中,x将被提升为float3类型,所以该表达式的值也是float3类型的。这种提升是按照已定义的类型转换规则进行的。在这个例子中,我们是将标量转换为向量:所以,x被提升为float3类型后,x=(x,x,x),标量到向量的转换就是这样定义。注意,如果某种类型转换没有定义,则相应的类型提升也就找不到依据而无法进行。例如,由于float2类型到float3类型的转换没有定义,所以我们无法将float2类型提升为float3类型。
  • 对于双目运算,如果左右操作数类型不同,则具有较低类型的操作数得到提升(类型转换),使得其类型精度与原先具有较高类型精度的操作数相同。例如,如果x是int类型变量,而y是half类型变量,则在表达式(x+y)中,变量x被提升为half类型,所以该表达式的结果也将是-个half类型的值。

用户自定义函数

HLSL中的函数具有以下性质

  • 函数使用与C++类似的语法
  • 参数总是按值传递的
  • 不支持递归
  • 函数总是内联的
关键字in、out、inout
bool foo(in const bool b,
         out int r1,
         inout float r2)
{
    if(b)
        r1=5;
    else
        r1=1;
    r2=r2*r2*r2;
    return true;
}

in:指定在该函数执行之前,必须对该形参传入实参的副本。函数声明中形参可以不显式指定in,因为默认状态下每个形参都是in类型的。

out:指定当函数返回时,形参的值将复制给实参。这样我们就可将形参作为返回值。关键字out是很必要的,因为HLSL不支持引用或指针。注意,如果一个形参是out类型的,则在函数开始执行时,实参值将不被复制到形参中。即out类型的参数仅用于输出数据,不可用作输入。

inout:表示一个参数同时兼有i和out类型参数的特点。即如果您希望一个参数即可作为输入又可作为输出,可指定该关键字。

俩者等价
float square(in float x)
{
    return x * x;
}

不显式指定in:
float square(float x)
{
    return x * x;
}

内置函数

大多数函数都经过了重载,以适用于所有内置类型。例如,取绝对值对任意标量类型都是有意义的,所以函数abs就对各种内置标量类型做了重载。另外·一个例子是,叉积仅于3D向量有定义,所以cross函数仅对所有类型的3D向量(例如int类型的、float类型的、double类型的3D向量)做了重载。而线性插值对标量、2D向量、3D向量和4D向量均有意义,所以函数lerp对所有的内置类型都进行了重载。

如果您为一个“标量”函数(即一般只对标量进行运算的函数,如cos(x)传入一个非标量类
型的参数,该函数将针对该传入参数的每个分量进行计算。例如,如果有如下代码:

float3 v = float3(0.0f,0.0f,0.0f);
v cos(v);
则该函数将会分别对v的每个分量进行计算:v=(cos(x),cos(y),cos(z))

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

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

相关文章

Camtasia2024中文免费版电脑录屏软件

大家都知道在视频播放中&#xff0c;如果有一个令人印象深刻的精彩开头&#xff0c;整个视频的内容都能因此得到不少升华。所以有一个好的片头对于视频的制作来说十分重要。 要怎么做出效果不错的片头呢&#xff1f; 首先&#xff0c;我们要选择合适的素材来制作片头。这里直…

Qt 之自定义控件(开关按钮)

Qt 之自定义控件&#xff08;开关按钮&#xff09; 原理源码运行结果 接触过IOS系统的童鞋们应该对开关按钮很熟悉&#xff0c;在设置里面经常遇到&#xff0c;切换时候的滑动效果比较帅气。 通常说的开关按钮&#xff0c;有两个状态&#xff1a;on、off。 下面&#xff0c;我们…

【LSNET】用自己的数据复现LSNet变化检测代码

之前讲过LSNet网络的论文详解了,感兴趣的童鞋请移步【LSNET】变化检测。 本篇主要是讲解如何用自己的数据复现代码【python】。 🌺论文:paper 🌺代码: code 目录 🔔🔔1.环境安装

linux下安装向日葵

https://sunlogin.oray.com/download/linux?typepersonal下载 在文件所在位置的空白处右键&#xff08;在此处打开终端&#xff09; 输入命令&#xff1a; sudo dpkg -i 文件名.deb &#xff08;文件名为下载的deb文件名字&#xff09;/usr/local/sunlogin/bin/sunlogincl…

keepalived 的安装部署及使用详细完整版

架构 1.安装 yum install keepalived -ysystemctl enable keepalivedsystemctl restart keepalivedsystemctl status keepalived2.部署配置样例 vim /etc/keepalived/keepalived.conf global_defs {router_id PROXYSQL_HAscript_user rootenable_script_security } vrrp_scri…

掉瓶子小游戏

欢迎来到程序小院 掉瓶子 玩法&#xff1a;旋转的瓶子&#xff0c;根据瓶子方向&#xff0c;点击鼠标左键瓶子掉落&#xff0c;从桌面中间掉下即得1分&#xff0c;卡在桌边瓶子碎了游戏结束&#xff0c;快去掉瓶子吧^^。开始游戏https://www.ormcc.com/play/gameStart/203 htm…

TSINGSEE青犀视频平台EasyCVR自定义可视化页面一览

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支…

【科研新手指南2】「NLP+网安」相关顶级会议期刊 投稿注意事项+会议等级+DDL+提交格式

「NLP网安」相关顶级会议&期刊投稿注意事项 写在最前面一、会议ACL (The Annual Meeting of the Association for Computational Linguistics)IH&MMSec (The ACM Workshop on Information Hiding, Multimedia and Security)CCS (The ACM Conference on Computer and Co…

使用JDBC连接数据库出现The server time zone value ‘�й���׼ʱ��‘ is unrecognized 的解决方案

看到网上的大佬们说是引入的依赖版本太高所以导致了时区有问题 但是我把依赖的版本改低了还是报错 用另一种办法直接在配置文件中修改url然后成功解决 spring:datasource:url: jdbc:mysql://127.0.0.1:3306/datasource?useUnicodetrue&characterEncodingutf8&useSSL…

山西电力市场日前价格预测【2023-11-15】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-15&#xff09;山西电力市场全天平均日前电价为237.36元/MWh。其中&#xff0c;最高日前电价为360.45元/MWh&#xff0c;预计出现在00:15。最低日前电价为0.00元/MWh&#xff0c;预计出…

中国人民大学与加拿大女王大学金融硕士——热爱会穿越时间,埋在心底的读研梦也是

随着时光的流转&#xff0c;我们都在跌跌撞撞中成长&#xff0c;改变&#xff0c;但有一种东西是永恒的&#xff0c;那就是我们对梦想的渴望。那些被尘封的读研梦想&#xff0c;如同穿越漫长岁月&#xff0c;等待在未来的某一天重见天日。梦想&#xff0c;就如同热爱一样&#…

如何查找领取淘宝优惠券?

如何查找领取淘宝优惠券&#xff1f; 1、手机安装「草柴」领券应用后&#xff0c;打开手机淘宝&#xff0c;挑选要购买的商品&#xff0c;并点击分享复制链接&#xff1b; 2、复制淘宝商品链接后&#xff0c;打开「草柴」APP&#xff0c;将复制的链接粘贴并查询该商品优惠券及…

【机器学习】朴素贝叶斯算法:多项式、高斯、伯努利,实例应用(心脏病预测)

1. 朴素贝叶斯模型 对于不同的数据&#xff0c;我们有不同的朴素贝叶斯模型进行分类。 1.1 多项式模型 &#xff08;1&#xff09;如果特征是离散型数据&#xff0c;比如文本这些&#xff0c;推荐使用多项式模型来实现。该模型常用于文本分类&#xff0c;特别是单词&#xf…

竞赛选题 深度学习的智能中文对话问答机器人

文章目录 0 简介1 项目架构2 项目的主要过程2.1 数据清洗、预处理2.2 分桶2.3 训练 3 项目的整体结构4 重要的API4.1 LSTM cells部分&#xff1a;4.2 损失函数&#xff1a;4.3 搭建seq2seq框架&#xff1a;4.4 测试部分&#xff1a;4.5 评价NLP测试效果&#xff1a;4.6 梯度截断…

石原子科技亮相2023成都市信息领域新产品发布会

2023年11月13日至15日&#xff0c;由成都市互联网信息办公室、四川天府新区管委会、成都市经信局市新经济委、成都市农业农村局指导的以“信息创造价值 创新引领未来”为主题的成都市信息领域新产品发布会在科创生态岛1号馆举行。围绕人工智能、区块链、数字化绿色化、数字乡村…

keepalived+haproxy配置集群和负载均衡

1、简介 1.1. Keepalived Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障。一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟IP,主服务器会发送特定的消息给备…

Microsoft Forms

Microsoft Forms官网&#xff1a;Microsoft Forms - Free tool to create online surveys, forms, polls, and quizzes Microsoft Forms主要用来自定义一些表单和问卷调查 点击新建表单 填写完表单名称之后&#xff0c;下面就可以添加问题了&#xff0c;可以选择多种提问方式…

设计模式系列之最终篇:大盘点

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概4000多字&#xff0c;预计阅读时间长需要3分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&#x…

盘点72个Python网站项目Python爱好者不容错过

盘点72个Python网站项目Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/12twY8iZYhAG8BuyYXM7_bw?pwd8888 提取码&#xff1a;8888 项目名称 dailyfreshpython…

拼图游戏,开源代码

拼图游戏 最近玩了玩孩子的拼图游戏&#xff0c;感觉还挺好玩的&#xff0c;心血来潮要不动手做一个吧&#xff0c;偷懒摸鱼的时候可以来一把。 以下就是拼图游戏的界面截图。 体验地址 代码开源地址 心得体会 虽说是一个小游戏&#xff0c;但是需要注意的地方还是挺多的 方…
最新文章