永远也不完美的程序

不断学习,不断实践,不断的重构……

常用链接

统计

积分与排名

好友链接

最新评论

The Complete Effect and HLSL Guide 函数

上一章里,我们学习了HLSL主要的语法元素。现在,唯一没有讲解的只剩下函数了,包括如何声明与定义函数,如何在shader中使用函数。函数是高级语言中的重要组成部分,它在shader中也同样扮演了重要角色。HLSL语法允许使用两种类型的函数。内置(或固有)函数为shader提供了一个预定义函数库,同时也为特定着色构架提供了某些特殊指令。

       当然,你可以创建自定义函数。自定义函数可以用来把shader组织为一个整体,也可以用来打包部分希望重用的功能。

       接下来的几节里,我将会讨论两种类型的函数,在最后还会讲解如何用函数定义shader。先来看看HLSL提供的丰富内置函数库吧。

 

内置函数

 

       HLSL着色语言包含了一系列广泛的,内置,或固有函数。这些函数在开发shader时相当有用。它们提供了从数学计算到纹理采样等广泛的功能。先依次浏览一下这些函数。

 

3-1 HLSL内置函数

函数名            用法

abs                         计算输入值的绝对值。

acos                        返回输入值反余弦值。

all                           测试非0值。

any                         测试输入值中的任何非零值。

asin                         返回输入值的反正弦值。

atan                        返回输入值的反正切值。

atan2                       返回y/x的反正切值。

ceil                         返回大于或等于输入值的最小整数。

clamp                      把输入值限制在[min, max]范围内。

clip                         如果输入向量中的任何元素小于0,则丢弃当前像素。

cos                         返回输入值的余弦。

cosh                       返回输入值的双曲余弦。

cross                      返回两个3D向量的叉积。

ddx                         返回关于屏幕坐标x轴的偏导数。

ddy                         返回关于屏幕坐标y轴的偏导数。

degrees                   弧度到角度的转换

determinant              返回输入矩阵的值。

distance                   返回两个输入点间的距离。

dot                          返回两个向量的点积。

exp                         返回以e为底数,输入值为指数的指数函数值。

exp2                       返回以2为底数,输入值为指数的指数函数值。

faceforward             检测多边形是否位于正面。

floor                       返回小于等于x的最大整数。

fmod                       返回a / b的浮点余数。

frac                        返回输入值的小数部分。

frexp                       返回输入值的尾数和指数

fwidth                     返回 abs ( ddx (x) + abs ( ddy(x))

isfinite                     如果输入值为有限值则返回true,否则返回false

isinf                        如何输入值为无限的则返回true

isnan                       如果输入值为NANQNAN则返回true

ldexp                       frexp的逆运算,返回 x * 2 ^ exp

len / lenth                返回输入向量的长度。

lerp                         对输入值进行插值计算。

lit                            返回光照向量(环境光,漫反射光,镜面高光,1)。

log                          返回以e为底的对数。

log10                      返回以10为底的对数。

log2                        返回以2为底的对数。

max                        返回两个输入值中较大的一个。

min                         返回两个输入值中较小的一个。

modf                       把输入值分解为整数和小数部分。

mul                         返回输入矩阵相乘的积。

normalize                 返回规范化的向量,定义为 x / length(x)

pow                        返回输入值的指定次幂。

radians                    角度到弧度的转换。

reflect                     返回入射光线i对表面法线n的反射光线。

refract                     返回在入射光线i,表面法线n,折射率为eta下的折射光线v

round                      返回最接近于输入值的整数。

rsqrt                       返回输入值平方根的倒数。

saturate                   把输入值限制到[0, 1]之间。

sign                        计算输入值的符号。

sin                          计算输入值的正弦值。

sincos                     返回输入值的正弦和余弦值。

sinh                        返回x的双曲正弦。

smoothstep              返回一个在输入值之间平稳变化的插值。

sqrt                         返回输入值的平方根。

step                        返回(x >= a? 1 : 0

tan                          返回输入值的正切值。

fanh                        返回输入值的双曲线切线。

transpose                 返回输入矩阵的转置。

tex1D*                    1D纹理查询。

tex2D*                    2D纹理查询。

tex3D*                    3D纹理查询。

texCUBE*                立方纹理查询。

 

       为了贴近实际,举个例子来展示如何使用这些函数吧。假设你需要把纹理映射到一个像素上,并且使用方向光来照亮这个像素。要完成这个任务,必须先计算光源对像素颜色的贡献,然后查找纹理颜色,最后把这两个颜色混合起来。首先,为了计算方向光的贡献,需要计算像素法线和光源方向的点积。使用dot函数可以很方便的完成这一步计算:

 

       LightIntensity = dot ( LightDirection , PixelNormal);

 

       这里可能会出现一点小小的问题,如果像素法线背对着光源方向,那么得到的亮度将为负值。必须保证亮度在01之间,以避免这种效果。怎么做呢?很幸运,saturate函数能完成这个任务,修改上面的代码:

 

       LightIntensity = saturate ( dot ( LightDirection , PixelNormal ) );

 

       在把灯光颜色添加到物体上之前,还需要从纹理中获得像素的颜色。假设像素已经包含了适当的纹理坐标并且有一张简单的2D纹理,那么纹理采样的代码如下:

 

       PixelColor = tex2D ( objectTexture , TextureCoord ) ;

 

       最后一步,就是对灯光和像素颜色进行混合。这里,我们需要灯光颜色,灯光亮度以及像素颜色作为参数。计算很简单,但你应该注意shader构架的矢量天性是如何对颜色中的所有分量同时起作用的。

 

       FinalColor = ( LightColor * LightIntensity) * PixelColor ;

 

       这个例子虽然简单,但是它展示了HLSL的强大威力,仅仅使用三行代码就能完成简单的光照。在进入下一个主题之前,需要指出根据完成功能的不同,内建函数可以接收不同的参数。另外,由于硬件性能的不同,部分内建函数并不是在所有顶点和像素着色器版本上都可用。

posted on 2008-08-08 15:29 狂烂球 阅读(1629) 评论(0)  编辑 收藏 引用 所属分类: 图形编程


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理