最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 着色器语言(下)

    正文概述 掘金(铧仔)   2021-08-06   451

    函数参数的限定符:

    函数的参数默认是以拷贝的形式传递的,也就是值传递,任何传递给函数参数的变量,其值都会被复制一份,然后再交给函数内部进行处理。所以,可以为参数添加限定符来达到传递引用的目的。

    限定符说明
    none:default默认使用in限定符in/centroid in复制到函数中在函数中可读可写。默认限定符,最终真正传入函数形参的其实是实参的一份拷贝,在函数中,修改in修饰的形参不会影响到实参变量本身。centroid in 变量于插值类型有关out/centroid out返回时从函数中复制出来。他的作用是想函数外部传递性质,out模式下传递进来的参数是write-only(可写不可读)的,在函数中,修改out修饰的形参回影响到实参本身。centroid out 变量于插值类型有关ninout复制到函数中斌返回时复制出来。可读可写,在函数中,修改inout修饰的形参会影响到实参本身

    GLSL的函数:

    glsl允许在程序的最外部声明函数。函数不能嵌套,不能递归调用,且必须声明返回值类型(无返回值时声明为void).

        vec4 getPosition(){
                vec4 v4=vec4(0.0,0.0,0.0,1.0);
                return v4;
        }
        void doubleSize(inout float size){
                size=size*2.0;
        }
        void main(){
            float psize= 10.0;
            doubleSize(psize);
            gl_Position = getPosition();
            gl_PointSize = psize;
        }
    

    构造函数:

    glsl中变量可以在声明的时候初始化,也可以先声明再在需要时赋值。而聚合类型对象,如(向量,举证,数组,结构),需要使用其构造函数来进行初始化。

        //一般类型
        float pSize=10.0;
        float pSize1;
        pSize1=10.0;
        //复合类型,如向量
        vec4 color=vec4(0.0,1.0,0.0,1.0);
        vec4 color1;
        color1=vec4(0.0,1.0,0.0,1.0);
        //结构
        struct light{
                float intensity;
                vec3 position;
        }
        light lightVar=light(3.0,vec3(1.0,2.0,3.0));
        //数组
        const float c[3]=float[3](5.0,7.2,1.1);
    

    精度限定:

    glsl在进行光栅化着色的时候,会产生大量的浮点数运算,这些运算可能会超出当前设备的承受能力,所以glsl提供了三种浮点数精度。在变量前面加上highp 、mediump 、lowp,即可对该变量的精度声明。

    • highp (-2的16次方, 2的16次方); 
    • mediump (-2的10次方, 2的10次方); 
    • lowp (-2的8次方, 2的8次方);
        lowp float color;
        varying mediump vec2 Coord;
        lowp ivec2 foo(lowp mat3);
        highp mat4 m
    

    确定精度:

    变量的精度首先都是由精度限定符确定的,如果没有精度限定符,则要寻找右侧表达式中已经确定精度的变量,一旦找到,那么整个表达式都将在该精度下运行。如果找到多个,则选择精度较高的,如果未找到,则会使用默认或者更大的精度类型。

        uniform highp float h1;
        highp float h2=2.3*4.7;//运算过程和结果都会使用高精度
        mediump float m;
        m=3.7*h1*h2;//运算过程是高精度
        h2=m*h1;//运算过程是高精度
        h2=m+m//运算过程和结果都是中精度
        //形参p是高精度,传入的3.3是高精度
        void f(highp float p);
        f(3.3);
    

    invariant

    关键: 由于shader在编译时会进行一些内部优化,可能会导致同样的运算在不同shader里结果不一定精确相等,这会引起一些问题,尤其是vertex shader向fragment shader传值的时候。所以需要使用invariant关键字来显示要求计算结果必须精确一直。当然也可以使用#pragma STDGL invariant(all)来命令所有输出变量必须精确一致,但这样会限制编译器优化程度,降低性能。

    #pragma STDGL invariant(all) //所有输出变量为 
    invariant invariant varying texCoord; //varying在传递数据的时候声明为invariant
    

    限定符的顺序:
    当需要用到多个限定符的是要遵循以下顺序:
    1.在一般变量中: invariant > storage > precision
    2.在参数中: storage > parameter > precision

    预编译指令

    以#开头的是预编译指令,常用的有: #define 、 #undef 、 #if 、 #ifdef 、#ifndef 、#else、#elif、 #endif 、#error 、#pragma 、#extension、#version 、#line 比如#version 100,表示规定当前shader使用GLSL ES 1.00标准进行编译,如果使用该指令,则必须出现在程序最开始的位置。

    内置的宏: LINE:当前源码中的行号。 VERSION:一个整数,指示当前的GLSL版本。 GL_ES:如果当前是在OpenGL ES环境中运行则GL_ES被设置成1,一般用来检查当前环境是不是OpenGL ES. GL_FRAGMENT_PRECISION_HIGH:如果当前系统glsl的片元着色器支持高浮点精度,则设置为1,一般用来检查着色器的精度。

    实例: 1.如何通过判断系统环境,来选择合适的精度:

        #ifdef GL_ES //
        #ifdef GL_FRAGMENT_PRECISION_HIGH
        precision highp float;
        #else
        precision mediump float;
        #endif
        #endif
    

    2.自定义宏:

        #define NUM 100 
        #if NUM==100 
        #endif
    

    内置的特殊变量

    GLSL程序使用一些特殊的内置变量与硬件进行沟通。大致分为两种,一种是input类型,负责向硬件(渲染管线)发送数据,另一种是output类型,负责向程序回传数据,以便编程需要。
    在vertex shader中:
    output类型的内置变量:

    变量说明单位
    highp vec4 gl_Positiongl_Position放置顶点坐标信息vec4mediump float gl_PointSizegl_PointSize需要绘制点的大小(只在gl.POINTS模式下有效)float

    在fragment shader中:
    input类型:

    变量说明单位
    mediump vec4 gl_FragCoord片元在framebuffer画面的相对位置vec4bool gl_FrontFaceing标志当前图元是不是正面图元的一部分boolmediump vec2 gl_PointCoord经过插值计算后的纹理坐标,点的范围是0.0~1.0vec2

    output类型:

    变量说明单位
    mediump vec4 gl_FragColor设置当前片点的颜色vec4 RGBA colormediump vec4 gl_FragData[n]设置当前片点的颜色,使用glDrawBuffers数据数组vec4 RGBA color

    起源地下载网 » 着色器语言(下)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元