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

时间: 2024-08-25 03:55:53

NVIDIA CG语言 函数之所有数学类函数(Mathematical Functions)的相关文章

cg语言学习&amp;&amp;阳春白雪GPU编程入门学习

虽然所知甚少,但康大的<GPU编程与Cg编程之阳春白雪下里巴人>确实带我入了shader的门,在里面我第一次清晰地知道了"语义"的意思,非常感谢. 入门shader,我觉得可以先读3本书:<GPU编程与Cg编程之阳春白雪下里巴人>=><cg教程>=><Real-Time Rendering 3rd>(在读,最近忙,搁下了),打下理论基础. 下面是<cg教程>的读书笔记. 1.基本cg函数 1)数学函数:abs,ac

发挥GPU强大动力的CG语言

·CG推出的背景因素: 目前大部分的图形渲染系统的流水线由于各种原因,功能被限制为某些特殊效果,不具备扩充性,依据这些流水线编制的软件,只能实现特定的效果,这是一些游戏无法展现许多效果的罪魁.按道理,VertexShader和PixelShader的可编程性可以改变这一切,实际上问题远非如此简单,由于编程的困难,即使一些常用的API增添了很多专门为此编写的函数,为了实现理想的特殊效果,还是必须使用直接控制GPU的汇编语言,难度极大,效率又低,挫伤了开发人员的积极性,具有可编程性的VertexSh

05. Go 语言函数

Go 语言函数 函数是组织好的.可重复使用的.用来实现单一或相关联功能的代码段,其可以提高应用的模块性和代码的重复利用率. Go 语言支持普通函数.匿名函数和闭包,从设计上对函数进行了优化和改进,让函数使用起来更加方便. Go 语言的函数属于"一等公民"(first-class),也就是说: 函数本身可以作为值进行传递. 支持匿名函数和闭包(closure). 函数可以满足接口. Go语言函数声明(函数定义) 函数构成了代码执行的逻辑结构,在Go语言中,函数的基本组成为:关键字 fun

9.20 函数 时间、数学、递归、字符串

函数:     四要素:返回类型      函数名      参数      函数体 强类型语言函数写法访问修饰符 返回类型 函数名 (参数列表){            函数体                        } 弱类型语言函数写法function 1.无参数的函数2.有参数的函数3.有返回值的函数JS常用函数日期时间函数数学函数字符串函数 递归:   递归的本质:函数自己调自己(从别处看来的笑话:要想理解递归,首先要理解递归) 日期时间函数(需要用变量调用):var b = n

C语言函数手册学习

目录 1.字符测试函数 2.字符串操作函数 3.内存管理函数 4.日期与时间函数 5.数学函数 6.文件操作函数 7.进程管理函数 8.文件权限控制函数 9.信号处理函数 10.接口处理函数 11.环境变量函数 12.终端控制函数 总结:这次偶然间找到了C语言函数手册,看他分类分的很清楚,就花了几个小时学一下,具体的函数讲解可以点击链接查看,或者查找手册,常用的函数就是我知道已经碰到过的函数,或者是用过的函数. 1.字符测试函数 1.1 isxdigit() 1.2 isupper() 1.3i

C#委托与C语言函数指针及函数指针数组

C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用的时候通过指针访问这个函数. 在C语言中函数指针的申明如下: //可以理解为申明一个指着变量 Func ,它的类型是 返回Type(可以为 void )类型的参数,接收 (Type one,Type two,...)类型的//参数(可以不接受参数). Type *Func(Type one,Type

c 语言 函数的整理 百度脑图版本

下面整理一下C语言函数的知识点 :使用百度脑图进行整理,详情请看上传的图片: 版权声明:本文为博主原创文章,未经博主允许不得转载.

汇编1 ----C语言函数1

构造以下C程序并在合适位置插入breakpoints 在Visual Studio 2015 CTP6对其反汇编. 下面来分析 z = add(1, 2); 009C170E 6A 02 push 2 ????int z; ????z = add(1, 2); 009C1710 6A 01 push 1 009C1712 E8 8D FA FF FF call 009C11A4 009C1717 83 C4 08 add esp,8 009C171A 89 45 F8 mov dword ptr

(转)如何编写有多个返回值的C语言函数

1引言    笔者从事C语言教学多年,在教学中学生们常常会问到如何编写具有多个返回值的C语言函数.编写有多个返回值的函数是所有C语言教材里均没有提到的知识点,但在实际教学与应用的过程中我们都有可能会遇到这样的问题.有学生也尝试了不少方法:如把多个需要返回的值作相应的处理后变成一个可以用return语句返回的数据,再在主调函数中拆开返回的数据使之变成几个值:或者把需要返回多个值的一个函数分开几个函数去实现多个值的返回.这些方法虽然最终都能实现返回要求的多个值,但从程序算法的合理性与最优化方面去考虑