美文网首页
OpenGL glsl语法以及变量

OpenGL glsl语法以及变量

作者: 月影路西法 | 来源:发表于2020-01-31 10:08 被阅读0次

    概述

    GLSL 全称 OpenGL Shading Language,是用来在 OpenGL 中着色编程的语言,即开发人员写的自定义程序代码。是执行在 GPU上的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。
    GLSL 其使用 C 语言作为基础高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。
    GLSL 的变量命名方式与 C 语言类似,可使用字母,数字以及下划线,不能以数字开头。还需要注意的是,变量名不能以 gl_ 作为前缀,这个是 GLSL 保留的前缀,用于 GLSL 的内部变量。

    基本数据类型

    类型 描述
    void 表示空类型,作为函数的返回类型,便是这个函数不返回值
    bool 布尔类型
    int 有符号整形
    uint 无符号整形
    float 浮点型
    bool bDone = false;
    int iValue = 42;
    uint uiValue = 32u;
    float fValue = 3.14159f;
    
    向量/分量类型 描述
    vec2,vec3,vec4 2/3/4分量浮点向量
    ivec2,ivec3,ivec4 2/3/4分量整形向量
    uvec2,uvec3,uvec4 2/3/4无符号整型向量
    bvec2,bvec3,bvec4 2/3/4布尔型向量
    向量的使用
    //1.声明4分量的float向量
    vec4 v1;
    
    //2.声明4分量并构成它
    vec4 v2 = vec4(1,2,3,4); vec4 v3 = vec4(0,0,0,0);
    
    //3.向量运算
    //向量相加
    v1 = v2 + v3;
    vec4 v4 = v1;
    v1 += vec4(10,10,10,10);
    v1 *= 5;
    
    //获取向量的元素,可以通过x,y,z,w来获取向量中的元素;
    v1.x = 3.0f;
    v1.y = 4.0f;
    v1.z = 5.0f;
    v1.w = 1.0f;
    
    v1.xy = vec2(1,2);
    v1.xyz = vec3(1,2,3);
    //获取向量的元素,可以通过r,g,b,a 来获取向量中元素.
    v2.r = 1.0f;
    v2 = vec4(1.0f,1.0f,1.0f,1.0f);
    
    //获取向量元素,可以s,t,p,q 来获取纹理坐标控制 
    v1.st = vec2(1.0,2.0);
    v1.st = v2.st;
    //不可以如下:xt不允许混合
    v1.st = v2.xt;
    向量数据累形还可以swizzle(调换)操作
    //将颜色数据RGB顺序化BGR顺序
    v1.bgra = v2.rgba;
    //向量的一次性所有分量操作
    v1.x = v2.x + 5.0f;
    v1.xyz = v2.xyz + vec3(5.0f,4.0f,1.0f);
    
    

    变量存储限定符

    类型 描述
    <none> 只是普通的本地变量,外部不见,外部不可访问
    const ⼀个编译常量,或者说是一个对函数来说为只读的参数
    in/varying 从以前阶段传递过来的变量
    in/varying centroid ⼀个从以前的阶段传递过来的变量,使用质⼼插值
    out/attribute 传递到下一个处理阶段或者在一个函数中指定一个返回值
    out/attribute centroid 传递到下一个处理阶段,质⼼插值
    uniform ⼀个从客户端代码传递过来的变量,在顶点之间不做改变

    矩阵

    矩阵只支持float类型

    类型 描述
    mat2,mat2*2 两行两列
    mat3,mat3*3 三行三列
    mat4,mat4*4 四行四列
    matx*j j行x列
    mat4 m1;
    vec4 v2;
    vec4 vOutPos ;
    
    //矩阵可以与向量相乘,应用顶点模型/投影矩阵变化时
    m1 = mat4(
                1.0,1.0,1.0,1.0,
                1.0,1.0,1.0,1.0,
                1.0,1.0,1.0,1.0,
                1.0,1.0,1.0,1.0,
              )
    vOutPos = v2 * m1;
    m1 = mat4(1.0f);
    

    结构体

    结构体使用与C类似字段为struct

    struct forStruct{
     vec4 color;
     float start;
     float end;
    }fogVar;
    
    //初始化
    fogVar = fogStruct(vec4(1.0,0.0,0.0,1.0),0.5,2.0);
    //赋值给新的对象
    vec4 color = fogVar.color;
    float start = fogVar.start;
    

    数组

    //定义数组
    float floatArray[4];
    vec4 vecArray[2]; //定义了一个可以存储2个4分量数组。
    //注意
    //初始化
    float a[4] = float[](1.0,2.0,3.0,4.0);  //[]里面不填,就会算括号里面的元素个数。
    vec2 c[2] = vec2[2](vec2(1.0,2.0),vec2(3.0,4.0));
    

    函数

    函数定义了3个修饰符

    修饰符 描述
    in (没有指定时,默认限定修饰符),传递进入函数中,函数不能对其进行修改
    out 函数返回时,可以进行修改
    inout 传入相应的数值,并且在函数中可以进行修改
    vec4 myFunc(inout float myFloat, out vec4 m1, mat4 m2){
    //函数中计算
    }
    vec4 diffuse(vec3 normal ,vec3 light, vec4 baseColor) {
        return baseColor * dot(normal,light);
    }
    
    dot 是一个点乘。
    

    控制语句

    控制语句包括 if ,while,do while ,for

    GLSL预定义变量

    GLSL为不同的渲染阶段定义了一些特定的而变量。这些预定义的变量有特定的属性。所有的预定义变量都已gl_开头。用户定义的变量不能以此开头

    顶点变量

    顶点属性——指顶点的信息,OpenGL据此绘制各个图元,对于传统的顶点属性包括坐标、纹理坐标、颜色等GLSL都会设置一个内置变量与之对应,以便在需要时可以在顶点或片元着色器中直接引用,这也体现了GLSL与HLSL的一个最大的不同,HLSL里顶点的属性是通过语义来定义的,而GLSL充分考虑了OpenGL是个状态机这一事实,将顶点属性设为一个状态变量。GLSL中内置的顶点属性包括以下几个

    // 顶点属性
    
    attribute vec4 gl_Color;              // 顶点颜色
    
    attribute vec4 gl_SecondaryColor;     // 辅助顶点颜色
    
    attribute vec3 gl_Normal;             // 顶点法线
    
    attribute vec4 gl_Vertex;             // 顶点物体空间坐标(未变换)
    
    attribute vec4 gl_MultiTexCoord[0-N]; // 顶点纹理坐标(N = gl_MaxTextureCoords)
    
    attribute float gl_FogCoord;          // 顶点雾坐标
    

    一致变量

    就是常说的Uniform,这是用户向GLSL传递自己数据的最常用方法,比如光源位置等等。之所以称为一致变量,是为了与易变变量相区别。不同于顶点属性在每个顶点有其自己的值,也不同于易变变量由顶点程序向片元程序插值传递,一致变量在一个图元的绘制过程中是不会改变的,而且可以在顶点shader和片元shader间共享。这部分变量主要用来描述OpenGL的状态,可以看作OpenGL状态机的复制。GLSL内置的一致变量包括:

    // 矩阵状态
    
    uniform mat4 gl_ModelViewMatrix;                // 模型视图变换矩阵
    
    uniform mat4 gl_ProjectionMatrix;                  // 投影矩阵
    
    uniform mat4 gl_ModelViewProjectionMatrix;         // 模型视图投影变换矩阵(ftransform())
    
    uniform mat3 gl_NormalMatrix;                   // 法向量变换到视空间矩阵
    
    uniform mat4 gl_TextureMatrix[gl_MatTextureCoords];     // 各纹理变换矩阵
    
    // 普通缩放因子
    
    uniform float gl_NormalScale;
    
    // 窗口坐标深度范围
    
    struct gl_DepthRangeParameters
    
    {
    
        float near;
    
        float far;
    
        float diff; // far-near
    
    };
    
    uniform gl_DepthRangeParameters gl_DepthRange;
    
    // 裁剪平面
    
    uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];
    
    // 点属性
    
    struct gl_PointParameters
    
    {
    
        float size;
    
        float sizeMin;
    
        float sizeMax;
    
        float fadeThresholdSize;
    
        float distanceConstantAttenuation;
    
        float distanceLinearAttenuation;
    
        float distanceQuadraticAttenuation;
    
    };
    
    uniform gl_PointParameters gl_Point;
    
    // 材质
    
    struct gl_MaterialParameters
    
    {
    
        vec4 emission;       // 自身光照Ecm
    
        vec4 ambient;        // 环境光吸收系数Acm
    
        vec4 diffuse;        // 漫反射吸收系数Dcm
    
        vec4 specular;       // 镜面反射吸收系数Scm
    
        float shininess;     // Srm
    
    };
    
    uniform gl_MaterialParameters gl_FrontMaterial;       // 正面材质
    
    uniform gl_MaterialParameters gl_BackMaterial;        // 反面材质
    
    // 光源性质,参数性质就不解释了,和OpenGL的三种光源性质是一样的![image](https://img.haomeiwen.com/i16249515/d9c01827b81d1002.gif?imageMogr2/auto-orient/strip) 
    
    struct gl_LightSourceParameters
    
    {
    
        vec4 ambient;                // Acii
    
        vec4 diffuse;                // Dcii
    
        vec4 specular;               // Scii
    
        vec4 position;               // Ppii
    
        vec4 halfVector;             // Hi
    
        vec3 spotDirection;          // Sdli
    
        float spotExponent;          // Srli
    
        float spotCutoff;            // Crli
    
        float spotCosCutoff;         // cos(Crli)
    
        float constantAttenuation;   // K0
    
        float linearAttenuation;     // K1
    
        float quadraticAttenuation;  // K2
    
    };
    
    uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
    
    struct gl_LightModelParameters
    
    {
    
        vec4 ambient;    // Acs
    
    };
    
    uniform gl_LightModelParameters gl_LightModel;
    
    // 光照和材质的派生状态
    
    struct gl_LightModelProducts
    
    {
    
        vec4 sceneColor;       // Ecm+Acm*Acs
    
    };
    
    uniform gl_LightModelProducts gl_FrontLightModelProduct; 
    
    uniform gl_LightModelProducts gl_BackLightModelProduct;
    
    struct gl_LightProducts
    
    {
    
        vec4 ambient;      // Acm * Acli
    
        vec4 diffuse;      // Dcm * Dcli
    
        vec4 specular;     // Scm * Scli
    
    };
    
    uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
    
    uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];
    
    // 纹理环境和生成
    
    unifrom vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];
    
    unifrom vec4 gl_EyePlaneS[gl_MaxTextureCoords]; 
    
    unifrom vec4 gl_EyePlaneT[gl_MaxTextureCoords];
    
    unifrom vec4 gl_EyePlaneR[gl_MaxTextureCoords];
    
    unifrom vec4 gl_EyePlaneQ[gl_MaxTextureCoords];
    
    unifrom vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];
    
    unifrom vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];
    
    unifrom vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];
    
    unifrom vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];
    
    // 雾参数
    
    struct gl_FogParameters
    
    {
    
        vec4  color;
    
        float density;
    
        float start;
    
        float end;
    
        float scale;  // 1/(end-start)
    
    };
    
    uniform gl_FogParameters gl_Fog;
    
    

    易变变量

    易变变量只能在顶点shader和片元shader间传递,这期间实际上经过了一个光栅化的过程。内置的易变变量比较少,如下:

    varying vec4 gl_Color;
    
    varying vec4 gl_SecondaryColor;
    
    varying vec4 gl_TexCoord[gl_MaxTextureCoords];
    
    varying float gl_FogFragCoord;
    

    内置常量

    内置常量描述了显卡的渲染能力,依据各个显卡而定,这里就不一一列举了,如果想要查询的话可以用OpenGL的glGet函数获取MAX/MIN一族的常量值,这些值和内置变量的值是一致的。

    常量出处

    相关文章

      网友评论

          本文标题:OpenGL glsl语法以及变量

          本文链接:https://www.haomeiwen.com/subject/zztgthtx.html