shader-函数

1、uint CreateShader(enum type) : 创建空的shader object;

   type: VERTEX_SHADER,

2、void ShaderSource(uint shader, sizeicount, const **string, const int *length):加载shader源码进shader object;可能多个字符串

3、void CompileShader(uint shader):编译shader object;

   shader object有状态 表示编译结果

4、void DeleteShader( uint shader ):删除 shader object;

5、void ShaderBinary( sizei count, const uint *shaders,
enum binaryformat, const void *binary, sizei length ): 加载预编译过的shader 二进制串;

6、uint CreateProgram( void ):创建空的program object, programe object组织多个shader object,成为executable;

7、void AttachShader( uint program, uint shader ):关联shader object和program object;

8、void DetachShader( uint program, uint shader ):解除关联;

9、void LinkProgram( uint program ):program object准备执行,其关联的shader object必须编译正确且符合限制条件;

10、void UseProgram( uint program ):执行program object;

11、void ProgramParameteri( uint program, enum pname,
int value ): 设置program object的参数;

12、void DeleteProgram( uint program ):删除program object;

13、shader 变量的qualifier:

    默认:无修饰符,普通变量读写, 与外界无连接;

    const:常量 const vec3 zAxis = vec3(0.0, 0.0, 1.0);

    attribute: 申明传给vertex shader的变量;只读;不能为array或struct;attribute vec4 position;

    uniform: 表明整个图元处理中值相同;只读; uniform vec4 lightPos;

    varying: 被差值;读写; varying vec3 normal;

    in, out, inout;

14、shader变量的精度:

    highp, mediump, lowp

15、shader内置变量:

    gl_Position: 用于vertex shader, 写顶点位置;被图元收集、裁剪等固定操作功能所使用;

                 其内部声明是:highp vec4 gl_Position;

    gl_PointSize: 用于vertex shader, 写光栅化后的点大小,像素个数;

                 其内部声明是:mediump float gl_Position;

    gl_FragColor: 用于Fragment shader,写fragment color;被后续的固定管线使用;

                  mediump vec4 gl_FragColor;

    gl_FragData: 用于Fragment shader,是个数组,写gl_FragData[n] 为data n;被后续的固定管线使用;

                  mediump vec4 gl_FragData[gl_MaxDrawBuffers];

    gl_FragColor和gl_FragData是互斥的,不会同时写入;

    gl_FragCoord: 用于Fragment shader,只读, Fragment相对于窗口的坐标位置 x,y,z,1/w; 这个是固定管线图元差值后产生的;z 是深度值; mediump vec4 gl_FragCoord;

    gl_FrontFacing: 用于判断 fragment是否属于 front-facing primitive;只读;

                    bool gl_FrontFacing;   

    gl_PointCoord: 仅用于 point primitive; mediump vec2 gl_PointCoord;

16、shader内置常量:

    const mediump int gl_MaxVertexAttribs = 8;

    const mediump int gl_MaxVertexUniformVectors = 128;

    const mediump int gl_MaxVaryingVectors = 8;

    const mediump int gl_MaxVertexTextureImageUnits = 0;

    const mediump int gl_MaxCombinedTextureImageUnits = 8;

    const mediump int gl_MaxTextureImageUnits = 8;

    const mediump int gl_MaxFragmentUnitformVectors = 16;

    const mediump int gl_MaxDrawBuffers = 1;

17、shader内置函数:

    一般默认都用弧度;

    radians(degree) : 角度变弧度;

    degrees(radian) : 弧度变角度;

    sin(angle), cos(angle), tan(angle)

    asin(x): arc sine, 返回弧度 [-PI/2, PI/2];

    acos(x): arc cosine,返回弧度 [0, PI];

    atan(y, x): arc tangent, 返回弧度 [-PI, PI];

    atan(y/x): arc tangent, 返回弧度 [-PI/2, PI/2];

   

    pow(x, y): x的y次方;

    exp(x): 指数, log(x):

    exp2(x): 2的x次方, log2(x):

    sqrt(x): x的根号; inversesqrt(x): x根号的倒数

   

    abs(x): 绝对值

    sign(x): 符号, 1, 0 或 -1

    floor(x): 底部取整

    ceil(x): 顶部取整

    fract(x): 取小数部分

    mod(x, y): 取模, x - y*floor(x/y)

    min(x, y): 取最小值

    max(x, y): 取最大值

    clamp(x, min, max):  min(max(x, min), max);

    mix(x, y, a): x, y的线性混叠, x(1-a) + y*a;

    step(edge, x): 如 x

    smoothstep(edge0, edge1, x): threshod  smooth transition时使用。 edge0<=edge0时为0.0, x>=edge1时为1.0

   

    length(x): 向量长度

    distance(p0, p1): 两点距离, length(p0-p1);

    dot(x, y): 点积,各分量分别相乘 后 相加

    cross(x, y): 差积,x[1]*y[2]-y[1]*x[2], x[2]*y[0] - y[2]*x[0], x[0]*y[1] - y[0]*x[1]

    normalize(x): 归一化, length(x)=1;

    faceforward(N, I, Nref): 如 dot(Nref, I)< 0则N, 否则 -N

    reflect(I, N): I的反射方向, I -2*dot(N, I)*N, N必须先归一化

    refract(I, N, eta): 折射,k=1.0-eta*eta*(1.0 - dot(N, I) * dot(N, I)); 如k<0.0 则0.0,否则 eta*I - (eta*dot(N, I)+sqrt(k))*N

   

    matrixCompMult(matX, matY): 矩阵相乘, 每个分量 自行相乘, 即 r[i][j] = x[i][j]*y[i][j];

                               矩阵线性相乘,直接用 *

    

    lessThan(vecX, vecY): 向量 每个分量比较 x < y

    lessThanEqual(vecX, vecY): 向量 每个分量比较 x<=y

    greaterThan(vecX, vecY): 向量 每个分量比较 x>y

    greaterThanEqual(vecX, vecY): 向量 每个分量比较 x>=y

    equal(vecX, vecY): 向量 每个分量比较 x==y

    notEqual(vecX, vexY): 向量 每个分量比较 x!=y

    any(bvecX): 只要有一个分量是true, 则true

    all(bvecX): 所有分量是true, 则true

    not(bvecX): 所有分量取反

   

    texture2D(sampler2D, coord): texture lookup

    texture2D(sampler2D, coord, bias): LOD bias, mip-mapped texture

    texture2DProj(sampler2D, coord):

    texture2DProj(sampler2D, coord, bias):

    texture2DLod(sampler2D, coord, lod):

    texture2DProjLod(sampler2D, coord, lod):

    textureCube(samplerCube, coord):

    textureCube(samplerCube, coord, bias):

    textureCubeLod(samplerCube, coord, lod):   

一、正弦余弦

正弦运动y = sin(x)

 

余弦运动y = cos(x)

 

动画演示:

 

通过给sin()cos()添加一些处理,可以制作出更多有趣的效果:

 

 

 

二、smoothstep

在两个值之间取埃尔米特插值(Hermite interpolation)link,它的值永远是 0~1。

 

描述:在edge0edge1之间取一个平缓的差值,在我们需要一个平滑的渐变的时候特别有用。当前值小于edge0,取值为0。当前值大于edge1,取值1。在这个区间内,取edge0edge1的差值。

适用场景1:由于它的值永远介于 0~1,edge0 和 edge1 的差值只会决定曲线的陡或平缓,所以我们可以控制他们的差值来做一些动画速度的变化。比如:

zoom(uv, smoothstep(0.0, nQuick, progress));
复制代码

上面通过控制 nQuick 的值来决定 zoom 缩放速度了。

适用场景2smoothstepedge0,edge10的时候,相当于step

smoothstep(0.0, 0.0, x);
复制代码

 

那我们怎么实现类似 step(edge, x) 的 edge 移动的效果呢,只需要这么做就一样了:

smoothstep(0.0, 0.0, x-edge);
复制代码

 

 

smoothstep() 的运算同样可以制作出一些不同的变体曲线:

y = smoothstep(0.0,1.0,x) - smoothstep(1.0,  2.0, x); 
复制代码

 

使用

float smoothstep(float edge0, float edge1, float x)  
vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x)  
vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x)  
vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x)

vec2 smoothstep(float edge0, float edge1, vec2 x)  
vec3 smoothstep(float edge0, float edge1, vec3 x)  
vec4 smoothstep(float edge0, float edge1, vec4 x)
复制代码

它等同于:

genType t;  /* Or genDType t; */
t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
复制代码

可视化呈现:y = smoothstep(0.0,1.0,x);

 

三、clamp

将值限制在两个其他值之间。link

说明clamp()返回minValmaxVal范围内的值。返回值计算:min(max(x, minVal), maxVal)。

使用

float clamp(float x, float minVal, float maxVal)  
vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal)  
vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal)  
vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal)

vec2 clamp(vec2 x, float minVal, float maxVal)  
vec3 clamp(vec3 x, float minVal, float maxVal)  
vec4 clamp(vec4 x, float minVal, float maxVal)
复制代码

可视化呈现:y = clamp(x,0.,1.);

 

四、step

通过比较两个值生成步进函数。link

说明step()通过将xedge进行比较来生成步进函数。对于返回值i,如果x[i] < edge[i]则返回0.0,否则返回1.0

适用场景step()有着一个最大的特征,那就是非黑即白。edge 表示非黑即白的边界,小于edge就是黑(0),大于edge就是白(1)。当我们这么使用时,可以判断像素点是否存在归一化坐标系里:

step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0)
复制代码

当它为 0 时,表示像素点在水平或垂直方向超出了边界;当它为 1 时,表示在坐标系内。当我我们把它和mix(texture2D_1, texture2D_2, step())函数一起用时,就可以得到非黑即白的两张相连的纹理图(纹理图超过边界的部分会用纹理图2取代)。

使用

float step(float edge, float x)  
vec2 step(vec2 edge, vec2 x)  
vec3 step(vec3 edge, vec3 x)  
vec4 step(vec4 edge, vec4 x)

vec2 step(float edge, vec2 x)  
vec3 step(float edge, vec3 x)  
vec4 step(float edge, vec4 x)
复制代码

可视化呈现:y = step(0.5,x);

 

五、mod

以第二个模数计算第一个参数的值。

说明x指定要求模的值,y指定要获取模数的值。计算公式为:x - y * floor(x / y)

使用

float mod(float x, float y)  
vec2 mod(vec2 x, vec2 y)  
vec3 mod(vec3 x, vec3 y)  
vec4 mod(vec4 x, vec4 y)

vec2 mod(vec2 x, float y)  
vec3 mod(vec3 x, float y)  
vec4 mod(vec4 x, float y)
复制代码

可视化呈现:y = mod(x,1.)

 

六、fract

计算参数的小数部分。

说明fract()返回x的小数部分。计算公式为x - floor(x)

适用场景:假如我们在一个归一化的坐标系里,fract(uv) 能够让像素点永远都在坐标系里不会超出边界。以从上往下平移作为例子,fract()可以让从上往下的平移无限循环,且首尾相连。

使用

float fract(float x)  
vec2 fract(vec2 x)  
vec3 fract(vec3 x)  
vec4 fract(vec4 x)
复制代码

可视化呈现:y = fract(x)

 

七、floor

找到小于或等于参数的最接近的整数

说明floor()返回一个等于最小整数的值,该整数小于或等于x

使用

float floor(float x)  
vec2 floor(vec2 x)  
vec3 floor(vec3 x)  
vec4 floor(vec4 x)

复制代码

可视化呈现:y = floor(x)

 

八、ceil

找到大于或等于参数的最近整数

说明ceil()返回一个等于最接近的整数的值,该整数大于或等于x

使用

float ceil(float x)  
vec2 ceil(vec2 x)  
vec3 ceil(vec3 x)  
vec4 ceil(vec4 x)
复制代码

可视化呈现:y = ceil(x);

 

九、sign

提取参数的符号。

说明:如果x小于0.0,则sign()返回-1.0,如果x等于0.0,则返回0.0,如果x大于0.0,则返回+1.0

适用场景sign()用来判断运动方向非常高效,因为它的值只有 -1,0,1,所以我们可以通过

vec2 direction = vec2(0.0, 1.0);   // x, y 代表方向
sign(direction)
复制代码

来判断水平和垂直的方向,正数为正方向,负数为反方向,也不用担心用户传了超出长度为1的值。

使用

float sign(float x)  
vec2 sign(vec2 x)  
vec3 sign(vec3 x)  
vec4 sign(vec4 x)
复制代码

可视化呈现:y = sign(x);

 

十、mix

将值限制在两个其他值之间并做融合,常用于颜色混合:

 

说明mix()xy之间执行线性插值,使用它们之间的权重。返回值计算为x*(1-a)+y*a。可以这么理解,a决定了x,y所占的比重,比如a < 0.5,那么x的比重更大,a > 0.5y的比重更大。当 a = 0.5时,xy的比重各一半。

使用场景:我们经常会有一些动画,需要在单位时间内往返一次,比如先放大后缩小。通过以下公式可以轻松做到(scale 表示放大的倍数):

mix(scale, 1.0, 2.0 * abs(progress - 0.5))
复制代码

上面的公式即可做到先放大到scale(当进度为0.5时达到最大),然后再缩小到1

使用

float mix(float x, float y, float a)  
vec2 mix(vec2 x, vec2 y, vec2 a)  
vec3 mix(vec3 x, vec3 y, vec3 a)  
vec4 mix(vec4 x, vec4 y, vec4 a)

vec2 mix(vec2 x, vec2 y, float a)  
vec3 mix(vec3 x, vec3 y, float a)  
vec4 mix(vec4 x, vec4 y, float a)
复制代码

可视化呈现:y = mix(0.,1.,x);

发布了24 篇原创文章 · 获赞 1 · 访问量 1251

猜你喜欢

转载自blog.csdn.net/birdswillbecomdragon/article/details/104829256