• NVIDIA CG语言 函数之所有数学类函数(Mathematical Functions)


    数学类函数(Mathematical Functions)

    abs(x)

    返回标量和向量x的绝对值

    如果x是向量,则返回每一个成员的绝对值

    acos(x)

    返回标量和向量x的反余弦

    x的范围是[-1,1],返回值的范围是[0,π],

    如果x是向量,则返回每一个成员的反余弦

    all(x)

    如果一个布尔标量为真,或者布尔向量的所有成员为真,则返回真

    any(x)

    如果一个布尔标量为真,或者布尔向量成员存在真值,则返回真

    asin(x)

    返回标量和向量x的反正弦

    x的范围是[-1,1],返回值的范围是[-π/2,π/2],

    如果x是向量,则返回每一个成员的反正弦

    atan(x)

    返回标量和向量x的反正切

    x的范围不限,返回值的范围是[-π/2,π/2],

    如果x是向量,则返回每一个成员的反正切·

    atan2(y, x)

    返回标量和向量y/x的反正切

    返回值的范围是[-π,π],

    ceil(x)

    返回不小于x的下一个整数

    clamp(x, a, b)

    返回一个[a, b]范围内的数

    如果x<a则返回a

    如果x>b则返回b

    否则返回x

    cos(x)

    返回x的cos值

    cosh(x)

    返回一个x的双曲线cos值

    cross(a, b)

    返回a, b的叉积

    a, b一定含有3个成员

    degrees(x)

    弧度转化为角度

    determinant(M)

    返回的正方形矩阵m的行列式

    dot(a, b)

    返回a与b的点积

    exp(x)

    返回以e为底的x次幂

    exp2(x)

    返回以2为底的x次幂

    floor(x)

    返回不大于x的上一个整数

    fmod(x, y)

    返回一个x/y的余数,

    y如果为0,结果不可预料

    frac(x)

    返回x的小数部分

    frexp(x, out exp)

    将浮点数x分解为尾数(在[0.5, 1]范围内)和指数(输出为e)

    如果x为0,结果的所有部分都为0

    isfinite(x)

    如果x是有限的则返回true

    isinf(x)

    如果x是无限的则返回true

    isnan(x)

    NaN(not-a-number)

    如果x NaN(not-a-number)

    则返回true

    ldexp(x, n)

    x * 2的n次方

    lerp(a, b, w)

    w是比重

    当w= 0时返回a,当w= 1时返回b

    根据w返回一个[a, b]的值

    p.s. w可以为任意值,不用限制在[0, 1]之内

    w can be any value (so is not restricted to be between zero and one);

    lit(ndotl, ndoth, m)

    计算环境、漫反射、和高光的光照系数

    返回一个4维向量

    x,环境光系数,经常值为1.0

    y,漫反射系数 如果 dot(n, l) < 0返回0,否则返回dot(n, l)

    z,高光系数 如果 dot(n, l) < 0或dot(n, h) < 0返回0,否则返回dot(n, h)的m次方

    w 固定值为1.0

    log(x)

    ln(x)

    log2(x)

    以2为底x的对数

    log10(x)

    以10为底x的对数

    max(a, b)

    返回a,b中的最大值

    min(a, b)

    返回a,b中的最小值

    modf(x, out ip)

    把x分离成整数和小数部分,把x的整数值存在输出参数ip处,并返回x的小数部分

    mul(M, N)

    矩阵M和N的乘积

     

    如果M是一个AxB的矩阵,N是一个BxC的矩阵,就返回一个AxC的矩阵

    mul(M, v)

    矩阵M和列矢量v的乘积

     

    如果M是一个AxB的矩阵,v是一个Bx1的矢量,就返回一个Ax1的矢量

    mul(v, M)

    行矢量v和矩阵M的乘积

    如果v是一个1xA的矢量,M是一个AxB的矩阵,就返回一个1xB的矢量

    noise(x)

    任意一个1维2维或3维的噪波函数取决于x的类型。

    返回一个[0, 1]范围内的,总是和输入相同的值

    pow(x, y)

    返回x的y次方值

    radians(x)

    角度转化为弧度的值

    round(x)

    采用四舍五入法,返回把x化为整数值

    rsqrt(x)

    返回x的平方根的倒数

    x必须大于0

    saturate(x)

    返回一个[0, 1]范围内的数

    如果x<0则返回0

    如果x>1则返回1

    否则返回x

    sign(x)

    如果 x>0返回1

    如果 x<0返回-1

    否则返回0

    sin(x)

    返回x的sin值

    sincos(float x, out s, out c)

    输出参数s 为x的sin值,c为s的cos值

    这个函数比分别计算x的sin和cos有效率

    此函数无返回值

    sinh(x)

    返回一个x的双曲线sin值

    smoothstep(min, max, x)

    x是一个[min, max]范围内的数

    如果x=min返回0,如果x=max返回1

    否则返回如下公式的计算结果:

    step(a, x)

    如果 x<a返回0

    如果 x≥a返回1

    sqrt(x)

    返回x的平方根

    x必须大于0

    tan(x)

    返回x的tan值

    tanh(x)

    返回一个x的双曲线tan值

    transpose(M)

    返回M的转置矩阵

    cg函数的内部代码实施

    看了他们的函数内部实现代码,感觉他们写的都很巧妙,可以用“微量高效”来形容,值得我们学习

    abs(x)

    如果x是float值,则内部是这么实施的

    float abs(float a)
    {
      return max(-a, a);
    }

    操作消耗的非常小,等同于无

    acos(x)

    如果x是float值,则内部是这么实施的

    // Handbook of Mathematical Functions
    // M. Abramowitz and I.A. Stegun, Ed.
     
    // Absolute error <= 6.7e-5
    float acos(float x) {
      float negate = float(x < 0);
      x = abs(x);
      float ret = -0.0187293;
      ret = ret * x;
      ret = ret + 0.0742610;
      ret = ret * x;
      ret = ret - 0.2121144;
      ret = ret * x;
      ret = ret + 1.5707288;
      ret = ret * sqrt(1.0-x);
      ret = ret - 2 * negate * ret;
      return negate * 3.14159265358979 + ret;
    }



    all(x)

    如果x是float值,则内部是这么实施的

    bool all(bool4 a)
    {
      return a.x && a.y && a.z && a.w;
    }

    any(x)

    如果x是float值,则内部是这么实施的

    bool any(bool4 a)
    {
      return a.x || a.y || a.z || a.w;
    }

    asin(x)

    如果x是float值,则内部是这么实施的

    // Handbook of Mathematical Functions
    // M. Abramowitz and I.A. Stegun, Ed.
     
    float asin(float x) {
      float negate = float(x < 0);
      x = abs(x);
      float ret = -0.0187293;
      ret *= x;
      ret += 0.0742610;
      ret *= x;
      ret -= 0.2121144;
      ret *= x;
      ret += 1.5707288;
      ret = 3.14159265358979*0.5 - sqrt(1.0 - x)*ret;
      return ret - 2 * negate * ret;
    }

    atan(x)

    如果x是float值,则内部是这么实施的

    float atan(float x) {
        return atan2(x, float(1));
    }

    atan2(y, x)

    float2 atan2(float2 y, float2 x)
    {
      float2 t0, t1, t2, t3, t4;
     
      t3 = abs(x);
      t1 = abs(y);
      t0 = max(t3, t1);
      t1 = min(t3, t1);
      t3 = float(1) / t0;
      t3 = t1 * t3;
     
      t4 = t3 * t3;
      t0 =         - float(0.013480470);
      t0 = t0 * t4 + float(0.057477314);
      t0 = t0 * t4 - float(0.121239071);
      t0 = t0 * t4 + float(0.195635925);
      t0 = t0 * t4 - float(0.332994597);
      t0 = t0 * t4 + float(0.999995630);
      t3 = t0 * t3;
     
      t3 = (abs(y) > abs(x)) ? float(1.570796327) - t3 : t3;
      t3 = (x < 0) ?  float(3.141592654) - t3 : t3;
      t3 = (y < 0) ? -t3 : t3;
     
      return t3;
    }

    ceil(x)

    如果x是float值,则内部是这么实施的

    float ceil(float v)
    {
      return -floor(-v);
    }

    clamp(x)

    如果x是float值,则内部是这么实施的

    float clamp(float x, float a, float b)
    {
      return max(a, min(b, x));
    }

    cos(x)

    如果x是float值,则内部是这么实施的

    cos(float a)
    {
      /* C simulation gives a max absolute error of less than 1.8e-7 */
      const float4 c0 = float4( 0.0,            0.5,
                                1.0,            0.0            );
      const float4 c1 = float4( 0.25,          -9.0,
                                0.75,           0.159154943091 );
      const float4 c2 = float4( 24.9808039603, -24.9808039603,
                               -60.1458091736,  60.1458091736  );
      const float4 c3 = float4( 85.4537887573, -85.4537887573,
                               -64.9393539429,  64.9393539429  );
      const float4 c4 = float4( 19.7392082214, -19.7392082214,
                               -1.0,            1.0            );
     
      /* r0.x = cos(a) */
      float3 r0, r1, r2;
     
      r1.x  = c1.w * a;                       // normalize input
      r1.y  = frac( r1.x );                   // and extract fraction
      r2.x  = (float) ( r1.y < c1.x );        // range check: 0.0 to 0.25
      r2.yz = (float2) ( r1.yy >= c1.yz );    // range check: 0.75 to 1.0
      r2.y  = dot( r2, c4.zwz );              // range check: 0.25 to 0.75
      r0    = c0.xyz - r1.yyy;                // range centering
      r0    = r0 * r0;
      r1    = c2.xyx * r0 + c2.zwz;           // start power series
      r1    =     r1 * r0 + c3.xyx;
      r1    =     r1 * r0 + c3.zwz;
      r1    =     r1 * r0 + c4.xyx;
      r1    =     r1 * r0 + c4.zwz;
      r0.x  = dot( r1, -r2 );                 // range extract
     
      return r0.x;

    cosh(x)

    如果x是float值,则内部是这么实施的

    float cosh(float x)
    {
      return 0.5 * (exp(x)+exp(-x));
    }

    degrees(x)

    如果x是float值,则内部是这么实施的

    float degrees(float a)
    {
      return 57.29577951 * a;
    }

    determinant (x)

    float determinant(float1x1 A)
    {
      return A._m00;
    }
     
    float determinant(float2x2 A)
    {
      return A._m00*A._m11 - A._m01*A._m10;
    }
     
    float determinant(float3x3 A)
    {
      return dot(A._m00_m01_m02,
                 A._m11_m12_m10 * A._m22_m20_m21
               - A._m12_m10_m11 * A._m21_m22_m20);
    }
     
    float determinant(float4x4 A) {
      return dot(float4(1,-1,1,-1) * A._m00_m01_m02_m03,
                   A._m11_m12_m13_m10*(  A._m22_m23_m20_m21*A._m33_m30_m31_m32
                                       - A._m23_m20_m21_m22*A._m32_m33_m30_m31)
                 + A._m12_m13_m10_m11*(  A._m23_m20_m21_m22*A._m31_m32_m33_m30
                                       - A._m21_m22_m23_m20*A._m33_m30_m31_m32)
                 + A._m13_m10_m11_m12*(  A._m21_m22_m23_m20*A._m32_m33_m30_m31
                                       - A._m22_m23_m20_m21*A._m31_m32_m33_m30));
    }

    degrees(x)

    如果x是float4值,则内部是这么实施的

    float dot(float4 a, float4 b)
    {
      return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
    }

    exp(x)

    float3 exp(float3 a)
    {
      float3 rv;
      int i;
     
      for (i=0; i<3; i++) {
        rv[i] = exp(a[i]);  // this is the ANSI C standard library exp()
      }
      return rv;
    }

    exp2(x)

    float3 exp2(float3 a)
    {
      float3 rv;
      int i;
     
      for (i=0; i<3; i++) {
        rv[i] = exp2(a[i]);  // this is the ANSI C standard library exp2()
      }
      return rv;
    }
     
     

    floor(x)

    float3 floor(float3 v)
    {
      float3 rv;
      int i;
     
      for (i=0; i<3; i++) {
        rv[i] = v[i] - frac(v[i]);
      }
      return rv;
    }
     
     

    fmod(x)

     
    float2 fmod(float2 a, float2 b)
    {
      float2 c = frac(abs(a/b))*abs(b);
      return (a < 0) ? -c : c;   /* if ( a < 0 ) c = 0-c */
    }
     

    frac(x)

    float frac(float v)
    {
      return v - floor(v);
    }

    frexp(x)

    float3 frexp(float3 x, out float3 e)
    {
      float3 rv;
      int i;
     
      for (i=0; i<3; i++) {
        float eout;
     
        rv[i] = frexp(a[i], &eout);  // this is the ANSI C standard library frexp()
        e[i] = eout;
      }
      return rv;
    }

    isfinite(x)

    bool3 isfinite(float3 s)
    {
      // By IEEE 754 rule, 2*Inf equals Inf
      return (s == s) && ((s == 0) || (s != 2*s));
    }

    isinf(x)

    bool3 isinf(float3 s)
    {
      // By IEEE 754 rule, 2*Inf equals Inf
      return (2*s == s) && (s != 0);
    }

    isnan(x)

    bool3 isnan(float3 s)
    {
      // By IEEE 754 rule, NaN is not equal to NaN
      return s != s;
    }

    lerp(a, b, f)

    float3 lerp(float3 a, float3 b, float w)
    {
      return a + w*(b-a);
    }

    lit(ndotl, ndoth, m)

    float4 lit(float NdotL, float NdotH, float m)
    {
      float specular = (NdotL > 0) ? pow(max(0.0, NdotH), m);
      return float4(1.0, max(0.0, NdotL), specular, 1.0);
    }

    max(a, b)

    float3 max(float3 a, float3 b)
    {
      return float3(a.x > b.x ? a.x : b.x,
                    a.y > b.y ? a.y : b.y,
                    a.z > b.z ? a.z : b.z);
    }

    min(a, b)

    float3 min(float3 a, float3 b)
    {
      return float3(a.x < b.x ? a.x : b.x,
                    a.y < b.y ? a.y : b.y,
                    a.z < b.z ? a.z : b.z);
    }

    modf(x, out ip)

    float4 mul(float4x3 M, float3 v)
    {
      float4 r;
     
      r.x = dot( M._m00_m01_m02, v );
      r.y = dot( M._m10_m11_m12, v );
      r.z = dot( M._m20_m21_m22, v );
      r.w = dot( M._m30_m31_m32, v );
     
      return r;
    }

    pow(x, y)

    float3 pow(float3 x, float3 y)
    {
      float3 rv;
     
      for (int i=0; i<3; i++) {
        rv[i] = exp(x[i] * log(y[i]));
      }
      return rv;
    }

    round(x)

    // round-to-nearest even profiles
    float round(float a)
    {
      float x = a + 0.5;
      float f = floor(x);
      float r;
      if (x == f) {
        if (a > 0)
          r = f - fmod(f, 2);
        else
          r = f + fmod(f, 2);
      } else
        r = f;
      return r;
    }
     
    // round-to-nearest up profiles
    float round(float a)
    {
      return floor(x + 0.5);
    }
     

    rsqrt(x)

     
     
    float3 rsqrt(float3 a)
    {
      return pow(a, -0.5);
    }
     
     

    saturate(x)

     
     
    float saturate(float x)
    {
      return max(0, min(1, x));
    }
     

    sign(x)

    float3 sign(float x)
    {
      float3 val = a > 0;
      return val - (a < 0);
    }

    step(a, x)

    float3 step(float3 a, float3 x)
    {
      return x >= a;
    }

    sqrt(x)

    感觉这个有点麻烦了,直接pow就好了。

    float3 sqrt(float3 a)
    {
      return 1.0 / rsqrt(a);
    }
     

    transpose(M)

     
     
    float4x3 transpose(float3x4 A)
    {
      float4x3 C;
     
      C[0] = A._m00_m10_m20;
      C[1] = A._m01_m11_m21;
      C[2] = A._m02_m12_m22;
      C[3] = A._m03_m13_m23;
     
      return C;
    }
     

                                                                              ------------------------------------by wolf96  http://blog.csdn.net/wolf96

  • 相关阅读:
    Windows程序设计6(内存、线程、进程)
    Windows程序设计5(MDI、库程序、文件)
    Windows程序设计4(文字、对话框、各控件)
    大数据开发学习之构建Hadoop集群-(0)
    杂谈
    Windows程序设计2(消息机制、菜单)
    QT 学习笔记概述(一)
    Linux/Windows 实用工具简记
    读书笔记《深度探索c++对象模型》(0)
    读书笔记《深入理解计算机系统》(第三版) 概述
  • 原文地址:https://www.cnblogs.com/zhanlang96/p/4224986.html
Copyright © 2020-2023  润新知