2010年9月17日星期五

纹理过滤模式中的Bilinear、Trilinear以及Anistropic Filtering <转>

1、 为什么在纹理采样时需要texture filter(纹理过滤)。
我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixel不一定对应texture上的采样中心texel),大小也不一定一至。当纹理大于三维图形表面时,导至一个像素被映射到许多纹理像素上;当维理小于三维图形表面时,许多个象素都映射到同一纹理。
当这些情况发生时,贴图就会变得模糊或发生错位,马赛克。要解决此类问题,必须通过技术平滑texelpixel之间的对应。这种技术就是纹理滤波。
不同的过滤模式,计算复杂度不一样,会得到不同的效果。过滤模式由简单到复杂包括:Nearest Point Sampling(最近点采样),Bilinear(双线性过滤)、Trilinear(三线性过滤)、Anisotropic Filtering(各向异性过滤)。
在了解这些之前,有必要了解什么是MipMap和什么时各向同性,各向异性。

2、 什么是MipMap?
MipmapLance Williams 1983的一篇文章“Pyramidal parametrics”中提出。Wiki中有很详细的介绍( http://en.wikipedia.org/wiki/Mipmap ) . 比如一张256X256的图,在长和宽方向每次减少一倍,生成:128X128,64X64,32X32,16X16,8X8,4X4,2X2,1X1,八张图,组成MipMap,如下图示。
Mipmap早已被硬件支持,硬件会自动为创建的Texture生成mipmap的各级。在D3DAPICreateTexture中有一个参数levels,就是用于指定生成mipmap到哪个级别,当不指定时就一直生成到1X1

3、 什么是各向同性和各向异性?
当需要贴图的三维表面平行于屏幕(viewport),则是各向同性的。当要贴图的三维表面与屏幕有一定角度的倾斜,则是各向异性的。
也可以这样理解,当一个texture贴到三维表面上从Camera看来没有变形,投射到屏幕空间中后U方向和V方向比例仍然是一样的,便可以理解成各向同性。反之则认为是各向异性。

4、 Nearest Point Sampling(最近点采样)
这个最简单,每个像素的纹理坐标,并不是刚好对应Texture上的一个采样点texel,怎么办呢?最近点采样取最接近的texel进行采样。
当纹理的大小与贴图的三维图形的大小差不多时,这种方法非常有效和快捷。如果大小不同,纹理就需要进行放大或缩小,这样,结果就会变得矮胖、变形或模糊。

5、 Bilinear(双线性过滤)
双线性过滤以pixel对应的纹理坐标为中心,采该纹理坐标周围4texel的像素,再取平均,以平均值作为采样值。
双线性过滤像素之间的过渡更加平滑,但是它只作用于一个MipMap Level,它选取texelpixel之间大小最接近的那一层MipMap进行采样。当和pixel大小匹配的texel大小在两层Mipmap level之间时,双线性过滤在有些情况效果就不太好。于是就有了三线性过滤。

6、 Trilinear(三线性过滤)
三线性过滤以双线性过滤为基础。会对pixel大小与texel大小最接近的两层Mipmap level分别进行双线性过滤,然后再对两层得到的结果进生线性插值。
三线性过滤在一般情况下效果非常理想了。但是到目前为止,我们均是假设是texture投射到屏幕空间是各向同性的。但是当各向异性的情况时,效果仍然不理想,于是产生了Anisotropic Filtering(各向异性过滤)。

7、 Anisotropic Filtering(各向异性过滤)
先看效果,左边的图采用三线性过滤,右边的图采用各向异性过滤。

各向同性的过滤在采样的时候,是对正方形区域里行采样。各向异性过滤把纹理与屏幕空间的角度这个因素考虑时去。简单地说,它会考滤一个pixel(x:y=1:1)对应到纹理空间中在uv方向上uv的比例关系,当u:v不是1:1时,将会按比例在各方向上采样不同数量的点来计算最终的结果(这时采样就有可能是长方形区域)
我们一般指的Anisotropic Filtering(AF)均是基于三线过滤的Anisotropic Filtering,因此当u:v不为1:1时,则Anisotropic FilteringTrilinear需要采样更多的点,具体要采多少,取决于是多少XAF,现在的显卡最多技持到16X AF
当开启16X AF的时候,硬件并不是对所有的texture采样都用16X AF,而是需要先计算屏幕空间与纹理空间的夹角(量化后便是上面所说的u:v),只有当夹角大到需要16X时,才会真正使用16X.
如果想了解AF的实现原理,可以查阅此篇Paper: “Implementing an anisotropic texture filter”. 现在AF都是硬件实现,因此只有少数人才清楚AF就尽是怎样实现了(其实细节我也没搞清楚),其实完全可以由Pixel Shader来实现AF,当然性能和由硬件做是没得比的。

8、 各过滤模式性能比较。
 下表是各种过滤模式采一个pixel需要sample的次数:
Sample Number
Nearest Point Sampling 1
Bilinear 4
Trilinear 8
Anisotropic Filtering 4X 32
Anisotropic Filtering 16X 128
  
Anisotropic Filtering 16X效果最好,但是显卡Performance会下降很多,当然也是测试你手中显卡Texture Unit的好方法。如果你觉得你的显卡够牛,那么就把AAAF都打到最高再试试吧:)

2010年8月30日星期一

<转>导数和微分的区别


1、一元函数,可导就是可微,没有本质区别,完全是一个意思的两种表述:
   可导强调的是曲线的斜率、变量的牵连变化率;
   可微强调的是可以分割性、连续性、光滑性。

   dx、dy: 可微性;  dy/dx: 可导性

   dy = (dy/dx)dx,  在工程应用中,变成: Δy = (dy/dx)Δx  

     这就是可导、可微之间的关系:
   可导 = 可微 = Differentiable。 
   导数 = 微分 = Differentiation,Derivative
     不可导 = 不可微 = Undifferentiable

  【说穿了,可以说是中文在玩游戏,也可以说中文概念更精确性】

   
2、二元和二元以上的多元函数有偏导(Partial Differentiation)的概念, 
   有全导数、全微分(Total Differentiatin)的概念。
  【说穿了,可以说也是中文在玩游戏,也可以说中文概念更有思辩性】
   多元函数有方向导数(Directional Differentiation/Derivative)的概念

   一元函数,无所谓偏导、全导,也没有全微分、偏微分、方向导数的概念。


3、对于多元函数,沿任何坐标轴方向的导数都是偏导数,
   a、沿任何特定方向的导数都是方向导数。
   b、方向导数取得最大值的方向导数就是梯度(Gradient)。
   c、英文中有全导数的概念(Total Differentian),只是我们的教学不太习惯
      这样称呼,我们习惯称为全微分,其实是完全等同的意思。

   一元函数没有这些概念。偏导就是全导,全导就是偏导。

4、dx、dy、du都是微分,只有在写成du=(∂f/∂x)dx + (∂f/∂y)dy时,
   du才是全微分,而dx、dy就是偏微分,只是我们不习惯这样讲罢了。 
   而∂f、∂x、∂y还是微分的概念,是df、dx、dy在多元函数中的变形。

x的单独变化会引起u的变化,du=(∂f/∂x)dx
y的单独变化会引起u的变化,du=(∂f/∂y)dy
其中的 ∂f/∂x、∂f/∂y 就是二元函数f分别对x,y的偏导数。
∂f/∂x 就是由于x的变化单独引起的f的变化率,部分原因引起,为“偏”;
∂f/∂y 就是由于y的变化单独引起的f的变化率,部分原因引起,为“偏”。

x、y同时变化,引起u的变化是:
du=(∂f/∂x)dx + (∂f/∂y)dy
这就是全微分,所有原因共同引起为“全”。
总而言之,言而总之:
对一元函数,可导与可微没有本质区别;
对多元函数,可微是指所有方向可以偏导,可微的要求更高。

2010年7月6日星期二

<转>文本文件和二进制文件的区别

从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种。

ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为:
ASC码:    00110101 00110110 00110111 00111000
                        ↓        ↓        ↓        ↓
十进制码:   5      6      7      8

共占用4个字节。ASCII码文件可在屏幕上按字符显示,例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。由于是按字符显示,因此能读懂文件内容。

二进制文件是按二进制的编码方式来存放文件的。例如,数5678的存储形式为:00010110 00101110只占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。 输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。因此也把这种文件称作“流式文件”。

一个文件可以以文本模式或二进制模式打开,这两种的区别是:在文本模式中回车被当成一个字符'\n',而二进制模式认为它是两个字符0x0D,0x0A;如果在文件中读到0x1B,文本模式会认为这是文件结束符,也就是二进制模型不会对文件进行处理,而文本方式会按一定的方式对数据作相应的转换。

2010年7月1日星期四

[转] Phong lighting model

From wikipedia:

Phong reflection is an empirical model of local illumination. It describes the way a surface reflects light as a combination of the diffuse reflection of rough surfaces with the specular reflection of shiny surfaces. It is based on Bui Tuong Phong's informal observation that shiny surfaces have small intense specular highlights, while dull surfaces have large highlights that fall off more gradually. The reflection model also includes an ambient term to account for the small amount of light that is scattered about the entire scene.

For each light source in the scene, we define the components is and id as the intensities (often as RGB values) of the specular and diffuse components of the light sources respectively. A single term ia controls the ambient lighting; it is sometimes computed as a sum of contributions from all light sources.

For each material in the scene, we define:

ks: specular reflection constant, the ratio of reflection of the specular term of incoming light
kd: diffuse reflection constant, the ratio of reflection of the diffuse term of incoming light (Lambertian reflectance)
ka: ambient reflection constant, the ratio of reflection of the ambient term present in all points in the scene rendered
α: is a shininess constant for this material, which is larger for surfaces that are smoother and more mirror-like. When this constant is large the specular highlight is small.

We further define lights as the set of all light sources, L as the direction vector from the point on the surface toward each light source, N as the normal at this point on the surface, R as the direction that a perfectly reflected ray of light would take from this point on the surface, and V as the direction pointing towards the viewer (such as a virtual camera).

Note L, N, R, V are all unit vecters.

Then the Phong reflection model provides an equation for computing the shading value of each surface point Ip:


The diffuse term is not affected by the viewer direction (V). The specular term is large only when the viewer direction (V) is aligned with the reflection direction R. Their alignment is measured by the α power of the cosine of the angle between them. The cosine of the angle between the normalized vectors R and V is equal to their dot product. When α is large, in the case of a nearly mirror-like reflection, the specular highlight will be small, because any viewpoint not aligned with the reflection will have a cosine less than one which rapidly approaches zero when raised to a high power.
When we have color representations as RGB values, this equation will typically be calculated separately for R, G and B intensities.

Although the above formulation is the common way of presenting the Phong model, a particular term in the sum should only be included if it is positive, i.e. the equation is formally incorrect.

Therefore, in the above fomulation, (Lm·N) should be exactly max(Lm·N, 0) and similarly (Rm·V) should be max(Rm·V, 0).

2010年6月25日星期五

Normal transformation matrix的推导

normal的transformation matrixh和vertex的transformation matrix并不相同。以下是推导:

vertex上的normal可以定义一个平面,  顶点在平面上,则有(nx, ny, nz, q)*(x0, yo, zo, w)' = 0。当顶点做完model-view transformation后,M为model-view transfornation matrix, 则有(nx, ny, nz, q)*inverse(M)*M*(x0, yo, zo, w)' = 0。变换后的(nx, ny, nz, q)为(nx', ny', nz', q') = (nx, ny, nz, q)*inverse(M), 由于我们并不需要q, 变换后的normal可以写成(nx', ny', nz')= (nx, ny, nz)*inverse(Mu),Mu为M的左上3×3submatrix。最后对(nx', ny', nz')做normalization使其变为unit vector完成变换。

由此得出若使用row vector表示normal则transformation matrix为inverse(Mu),使用column vector表示normal则transformation matrix为inverse(Mu)'

Projective Texture Mapping

Projective Texture Mapping是将texture用投影的方法投射到物体上的一种texture mapping方法。从顶点到texture坐标的变换如下图右所示:


在OpenGL里,实现projective mapping可以用两种texture生成方法, object linear和eye linear, 其变换矩阵分别如下图:

Object Linear Texgen

Eye Linear Texgen

Object Linear Texgen左乘的对象是顶点在object space的坐标,Eye Linear Texgen左乘的对象则是顶点在view space的坐标,一般使用Eye Linear Texgen来实现不同object coordinate system的物体的统一投影效果(如shadow mapping)。用OpenGL的实现Eye Linear Texgen,如果用R表示 [0,1] range transformation matrix,则需要将R*Pp*Vp的四个row vector分别设为s,t,r,q的eye plane。

最后发两张NV教学文档里的效果图:

 

2010年6月24日星期四

glTexGen中object linear和eye linear的区别

根据red book的解释,在eye linear模式下,t = p1' * Xe + p2' * Ye + p3' * Ze + p4' ,Xe,Ye,Ze是顶点在viewing space的坐标, 故有(Xe, Ye, Ze, We) = M * (x0, y0, z0, w0),x0 , y0 , z0 ,w0为顶点在object space的坐标。而( p1' , p2', p3', p4') = (p1, p2 , p3 ,p4)*inverse(M),这样看来 t =  (p1, p2, p3, p4) * (x0 , y0 , z0 ,w0), 生成的texture coordinates和在object linear模式下完全相同。怎么会这样呢?

实际上,在( p1' , p2', p3', p4') = (p1, p2 , p3 ,p4)*inverse(M)中,M为调用glTexGen时的Model-view矩阵,在生成坐标过程中不会再变化,而(Xe , Ye , Ze , We) = M * (x0 , y0 , z0 ,w0)中的M则是定义(x0 , y0 , z0 ,w0)时当前的Model-view矩阵,在定义不同顶点时Model-view矩阵可能会有所不同。只有在调用glTexGen后Model-view矩阵没有变化的情况下,在两种模式下生成的texture coordinates相同。简单的说,object linear模式中的纹理坐标跟据顶点的object coordinate(也就是glVertex定义的坐标)做一个固定的变换而生成,而eye linear模式则是把顶点变换到当先的viewing space,根据得到的viewing coordinate做一个固定的变换而生成。