首页 > 其他分享 >HLSL基础语法

HLSL基础语法

时间:2023-01-29 22:56:27浏览次数:61  
标签:返回 HLSL 基础 c++ 语法 ._ float4 着色器 向量

HLSL着色器由变量和函数组成,函数又由语句组成,它的语法和c++十分相似

变量

​ HLSL变量类似于c++中的变量,具有命名限制、取决于声明它们的位置的范围属性、标准数据类型,不同的是,定义其他数据类型用以提高使用3d数据的性能

声明模板

[Storage_Class] [Type_Modifier] Type Name [Index] [: Semantic] [: Packoffset] [:Register]; 
  1. Storage_Class(存储类型)

    1. 用于为编译器提供关于变量范围和生存期的提示

    2. 可以按任意顺序指定修饰符

    3. value description
      extern 与c++一样,将全局变量标记为着色器的外部输入
      nointerpolation 将顶点着色器的输出传递给像素着色器之前,不要对它们进行插值
      shared 标记一个用于在效果之间共享的变量; 这是对编译器的提示
      groupshared 为计算着色器的线程组共享内存标记一个变量
      static 与c++一样,标记一个局部变量,使其初始化一次。若声明不对其进行显式初始化,将默认初始化为0
      volatile 与c++一样,标记经常更改的变量;仅适用于局部变量
      uniform 标记一个变量,该变量在整个着色器执行过程中是恒定的。此值可在c++应用层改变,但在着色器执行时,其值不变
      uniform变量在着色器程序外进行初始化
  2. Type_Modifier(类型修饰符)

    1. 若未指定类型修饰符,则编译器使用 column _ main 作为默认值
    value description
    const 与c++一样,标记一个不能被着色器更改的变量,必须在变量声明中初始化
    row_major 标记一个变量,该变量在一行中存储4个组件
    column_major 标记一个变量,该变量在一列中存储4个组件,以优化矩阵运算
  3. Type

    HLSL支持的内部数据类型

    1. 标量类型

      类型名 含义
      bool ture or false
      int 32位有符号整数
      uint 32位无符号整数
      dword 32位无符号整数
      half 半数据类型,16位浮点值。仅用于语言兼容性
      半数据类型不能用于统一的全局变量(若有需要,请使用/Gec 标志)
      float 32位浮点值
      double 64位浮点值。不能用于流的输入和输出,请使用一对uint数据类型,再使用 asuint 函数将每个 double 打包到这对 uint 中,并使用 asdouble()将这对 uint 解压至 double 中
      min16float 最小16位浮点值
      min10float 最小10位浮点值
      min16int 最小16位有符号整数
      min12int 最小12位有符号整数
      min16uint 最小16位无符号整数
      string ASCII 字符串。没有接受字符串的操作或状态,但是可以查询字符串参数和注释
    2. 向量类型

      1. 向量类型由两部分组成,一个向量的每个分量必须具有相同的类型

        1. 标量类型

        2. 分量的数量,在1-4间

        如:

        向量类型 含义
        float2 2d向量,每个分量都是float类型
        float3 3d向量
        float4 4d向量
      2. 初始化向量

        1. 以类似数组或构造函数的语法来初始化向量

          float3 v = {1.0f, 2.0f, 3.0f};
          float2 w = float(x,y);
          float4 u = float4(w, 3.0f, 4,0f)
          
      3. 访问分量

        1. 以数组下表语法来访问

          vec[i] = 1.0f;
          
        2. 以规定的分量名x、y、z、w、r、g、b、a像访问结构体成员一样来访问分量

          vec.x = vec.r = 1.0f;
          
      4. 重组(swizzleing)

        将向量u的分量复制到向量v的分量,可以乱序方式进行

        float4 u = {1.0f, 2.0f, 3.0f, 4.0f};
        float4 v = {0.0f, 0.0f, 5.0f, 6.0f};
        v = u.wyyx;	//v = {4.0f, 2.0f, 2.0f, 1.0f}
        
    3. 矩阵类型

      1. 包含1-16个分量,每个分量类型必须相同

        1. 矩阵类型由三部分组成

          1. 标量类型
          2. 行数,1-4的正整数
          3. 列数,1-4的正整数

          如:

          类型名称 含义
          float2x2 2x2矩阵,每个元素类型都为float
          float3x3 3x3矩阵
          float4x4 4x4矩阵
          float3x4 3x4矩阵
      2. 访问

        1. 以二维数组的双下标进行访问

          M[i][j] = value;
          
        2. 以访问结构体成员的方式进行访问

          //以1作为起始值的索引
          M._11 = M._12 = M._13 = M._14 = 0.0f;
          M._41 = M._42 = M._43 = M._44 = 0.0f;
          
          //以0作为基准值的索引
          M._m00 = M._m01 = M._m02 = M._m03 = 0.0f;
          M._m30 = M._m31 = M._m32 = M._m33 = 0.0f;
          
        3. 引用矩阵中特定的行向量。以数组的单下标实现

          float3 row = M[i];
          
    4. struct

      与c++的struct定义方式基本相同,区别在于HLSL的struct不含有成员函数

    5. typedef

      与c++的typedef功能完全相同

      typedef float3 point;
      
    6. array(数组)

      与c++相同

      half p[3];
      float M[4][4];
      
  4. Semantic(语义)

    1. 可选参数,语义是附加在着色器输入或输出上的字符串,它传递有关参数预期用途的信息

    2. 由编译器用于链接着色器输入和输出

    3. 在着色器阶段之间传递的所有变量都需要语义

    4. 一般来说,流水线阶段之间传递的数据是完全通用的,系统不进行唯一的解释

    5. System-Value Semantic(系统值语义)

      1. 所有系统值都以 SV _ 前缀开头,如SV _ POSITION

      2. 为什么需要系统值?

        因为系统值用于指出输入输出变量的意图

      3. 系统值在管道的其他部分也是有效的

    如:

    顶点着色器语义

    input description type
    COLOR[n] 镜面反射颜色 float4
    NORMAL[n] 法线向量 float4
    POSITION[n] 空间中的顶点位置 float4
    TEXCOORD[n] 纹理坐标 float4
    PSIZE[n] 点大小 float
    Output Description Type
    COLOR[n] 漫反射或镜面反射颜色 float4
    POSITION[n] 齐次空间中顶点的位置 float4
    PSIZE 点大小 float

    像素着色器语义

    Input Description Type
    COLOR[n] 漫反射或镜面反射颜色 float4
    TEXCOORD[n] 纹理坐标 float4
    VPOS 屏幕空间中的像素位置(x,y) float2
    Output Description Type
    COLOR[n] 输出颜色 float4
    DEPTH[n] 输出深度 float
  5. Packoffset

    可选参数,用于手动打包着色器常量

  6. Register

    可选参数,用于手动将着色器变量分配给特定寄存器

强制类型转换

HLSL中的强制类型转换与c相同

float f = 5.0f;
float4x4 m = (float4x4)f;	//将标量复制给m中每个元素

float3 n = float3(...);
float3 v = 2.0f * n - 1.0f;	//等同于 float3 v = 2.0f * n - float3(1.0f, 1.0f, 1.0f);

常用关键字

asm, bool, break, case, class, compile, const, continue, default, do, double, dword,
else, extern, false, true, float, for, half, if, in, inline, inout, int, matrix, namespace, NULL, out, pass, return, register, sampler, shared, static, string, struct, switch, typedef, uint, uniform, unsigned, vector, vertexshader, void, volatile, while,
texture, technique, pixelshader, discard

运算符

HLSL的运算符规则与c++基本相同,除了以下几种

  1. 取模运算符%可用于整数和浮点数,且操作数的正负号相同
  2. HLSL的部分运算以分量为基准
  3. 对于二元运算
    1. 若操作符左右操作数维度不同,维度较小的变量类型被转换为维度较大的变量类型
    2. 若操作符左右操作数类型不同,低精度变量被转换为高精度变量

如:

//乘法
float4x4 A;
float4x4 B;
A*B;	//分量式乘法
mul(A,B);	//矩阵乘法
    
//比较运算符
float4 u = {1.0f, 0.0f, -3.0f, 1.0f};
float4 v = {-4.0f, 0.0f, 1.0f, 1.0f};
float4 b = (u == v); // b = (false, true, false, true)

控制流

HLSL支持的控制流与c++相似.以下语句语法与c++完全相同

  1. return
  2. if & if...else
  3. while
  4. for
  5. do...while
  6. break
  7. continue
  8. switch

函数

  • HLSL中函数的属性

    1. 函数采用类c++语法

    2. 参数只能按值传递

    3. 不支持递归

    4. 只有内联函数

    5. 与c++相较下,多了in、out、inout关键字

      1. in:目标函数执行前,此修饰符所指定的参数应从调用此函数的程序中复制有输入的数据.所有参数默认为in

      2. out:目标函数返回时,此修饰符所指定的参数应当已经复制该函数中的最后计算结果

        1. 因为HLSL没有引用和指针,需要用out返回数值

        2. 若一个参数被out修饰,此参数只能用于输出数据,不可用于输入数据,也就是说不能被复制

          void func(float x, out float y)
          {
              y = x * x;
          }
          
        3. inout:表示参数兼有in和out属性

  • 内置函数

    常用函数如下

    函数 描述
    abs(x) 返回|x|
    length(v) 返回向量v的长度
    cos(x) 返回x的余弦值,x单位为弧度
    clamp(x, a, b) 将x限制在[a,b]内,并返回结果
    saturate(x) 返回clamp(x, 0.0, 1.0)
    clip(x) 仅用于像素着色器。若x < 0,就将当前像素从后续流程中丢弃
    cross(u, v) 返回u和v的叉积
    dot(u, v) 返回u和v的点积
    ddx(p) 估算屏幕空间中的偏导数δp/δx
    确定屏幕空间x轴上,相邻像素间某属性值p的变化量
    ddy(p) 估算屏幕空间中的偏导数δp/δy
    确定屏幕空间y轴上,相邻像素间某属性值p的变化量
    determinant(m) 返回矩阵的行列式
    distance(u,v) 返回点u和点v间的距离
    floor(x) 返回≤x的最大整数
    ceil(x) 返回≥x的最小整数
    frac(x) 返回目标浮点数的小数部分
    lerp(u, v, t) 基于参数t∈[0, 1],在u、v间进行线性插值
    log(x) 返回ln(x)
    log10(x) 返回log10(x)
    log2(x) 返回log2(x)
    max(x, y) 返回x,y中的较大者
    min(x, y) 返回x,y中的较小者
    mul(m, n) 返回矩阵乘积mn
    normalize(v) 对v进行规范化处理
    pow(b, n) 返回b^n
    radians(x) 将x从角度转化为弧度
    degrees(x) 将x从弧度转化为角度
    sqrt(x) 返回根号x
    rsqrt(x) 返回1/根号x
    reflect(v, n) 根据表面法线n与入射向量v,计算反射向量
    refract(v, n, eta) 根据表面法线n与入射向量v,计算反射向量及两种材质的折射率之比eta来计算折射向量
    transpose(m) 返回矩阵m的转置矩阵
    Texture2D::Sample(X, texC) 根据SamplerState对象S与2D纹理坐标texC,返回2D纹理图中相应的颜色数据
    Texture2D::SampleLevel(S, texC, mipLevel) 根据SamplerState对象S、2D纹理坐标texC和mipmap层级mipLevel,从2D纹理图中返回相应的颜色数据
    TextureCube::Sample(S, V) 根据SamplerState对象S、3D查找向量v来返回立方体图中相应的颜色数据
    Texture2DArray::Sample(S, texC) 根据SamplerState对象S、3D纹理坐标texC,返回2D纹理数组中相应的颜色
  • 常量缓冲区的封装规则

    HLSL中,常量缓冲区会以padding(补齐填充)的方式,将其中的元素都包装在4D向量。但一个单独的元素不能被分开并横跨两个4D向量

    cbuffer cb : register(b0)
    {
        float3 Pos;
        float3 Dir;
    }
    //封装如下
    vector 1 : (Pos.x, Pos.y, Pos.z, empty)
    vector 2 : (Dir.x, Dir.y, Dir.z, empty)
    

reference

High-level shader language (HLSL) - Win32 apps | Microsoft Learn

Directx12 3D 游戏开发实战

标签:返回,HLSL,基础,c++,语法,._,float4,着色器,向量
From: https://www.cnblogs.com/chenglixue/p/17074041.html

相关文章

  • Redis缓存基础知识(一)
    一、基本概念1.Redis:属于开源的、键值对型的数据存储系统。支持网络、可基于内存、可持久化的日志型数据库。它可用作数据库、缓存、消息中间件。2.分析:正因为Redis是......
  • 日语语法l16
    2023/1/2921:061.して、「して」、します朝ジョギンゲをして、シャワーを浴びて、会社へいきます神戸へ行って、映画を見て、お茶を飲みました2.ちいさいーちい......
  • linux驱动移植-linux网卡驱动基础
    一、OSI七层模型1.1、概念OSI七层模式是一个标准,规定了各种计算机在世界范围内互联成网的标准框架,OSI模型是一个分层的模型,每一个部分称为一层,每一层扮演固定的角色,互不......
  • vue3语法糖+ts组件传值
    在开发中有些功能是通用的,而且逻辑大致相同,像这种东西可以封成一个组件,比较常用的就是函数封装,组件封装,组件封装是需要引入到页面使用的,所以通常它会有一些自己的方法,父子......
  • JS基础知识
    1.简单数据类型  1.1字符串型String   1.1.1字符串长度        1.1.2字符串拼接            1.1.3字符串拼接加强 ......
  • 【TS】基础类型
    在ts中定义基础类型,语法:let变量名:数据类型=值//布尔类型----booleanletflag:boolean=trueflag=false在赋值的时候,不能赋值定义外的数据......
  • 算法刷题 Day 24 | 回溯的理论基础 & 77. 组合
    今日内容:理论基础77.组合详细布置理论基础其实在讲解二叉树的时候,就给大家介绍过回溯,这次正式开启回溯算法,大家可以先看视频,对回溯算法有一个整体的了解......
  • 1.Java基础语法
    一、关键字和保留字1.关键字2.保留字二、......
  • Allen vue项目课day1_vue基础
    html讲义css讲义js讲义vue讲义去学。其他什么也不用管。就是脚踏实地,知识一个一个学。怎么挣到钱=怎么学会技术=怎么把成绩学好=怎么把一个又一个题目做出来。脚踏实......
  • monaco编辑器的基础api使用
    目录添加js/ts扩展库添加js扩展库添加ts扩展库添加js/ts扩展库添加js扩展库1.使用addExtraLibfilePath同名会覆盖monaco.languages.typescript.javascriptDefaults.ad......