OpenGL: 按列存储矩阵(column-major)。调用API形成的矩阵用来和一个列向量相乘,矩阵在左,列向量在右
GLSL: 存储方式和OpenGL相同(column-major)
DirectX: 按行存储矩阵(row-major)。调用API形成的矩阵用来和一个行向量相乘,矩阵在右,行向量在左
HLSL: 存储方式和DirectX相反(column-major)
因此,若HLSL的矩阵也是用来右乘行向量,则应将DX API构造的矩阵做Transpose,这样数学上HLSL会将Transpose后的矩阵视为 和DX API构造的矩阵是同一个矩阵,但是实际数值的存储顺序不同。若用来将矩阵左乘列向量,则可以不必做Transpose。
因此,一般的传入shader的操作是原封不动的将用来存储矩阵的array导入shader。但是如果是用的effect system里的setMatrix(), 则会先自动将矩阵由row-major改为colunn-major存储,再将其导入shader。这种情况下则无需在导入前手动Transpose 矩阵。
2010年10月30日星期六
2010年10月14日星期四
Bump Mapping [转]
Bump mapping is very much like Texture Mapping. However, where Texture Mapping added colour to a polygon, Bump Mapping adds, what appears to be surface roughness. This can have a dramatic effect on the look of a polygonal object. Bump Mapping can add minute detail to an object which would otherwise require a large number of polygons. Note that the polygon is still physically flat, but appears to a be bumpy.
The theory behind Bump Mapping
What is a Bump Map
So how's it done
x_gradient = pixel(x-1, y) - pixel(x+1, y) y_gradient = pixel(x, y-1) - pixel(x, y+1)
New_Normal = Normal + (U * x_gradient) + (V * y_gradient)
From: http://freespace.virgin.net/hugo.elias/graphics/x_polybm.htm
2010年10月10日星期日
Texture types in OpenGL
GL_TEXTURE_1D: Images in this texture all are 1-dimensional. They have width, but no height or depth.
GL_TEXTURE_2D: Images in this texture all are 2-dimensional. They have width and height, but no depth.
GL_TEXTURE_3D: Images in this texture all are 3-dimensional. They have width, height, and depth.
GL_TEXTURE_RECTANGLE: The image in this texture (only one image. No mipmapping) is 2-dimensional. Texture coordinates used for these textures are not normalized.
GL_TEXTURE_BUFFER: The image in this texture (only one image. No mipmapping) is 1-dimensional. The storage for this data comes from a Buffer Object.
GL_TEXTURE_CUBE_MAP: There are exactly 6 distinct sets of 2D images, all of the same size. They act as 6 faces of a cube.
GL_TEXTURE_1D_ARRAY: Images in this texture all are 1-dimensional. However, it contains multiple sets of 1-dimensional images, all within one texture. The array length is part of the texture's size.
GL_TEXTURE_2D_ARRAY Array: Images in this texture all are 2-dimensional. However, it contains multiple sets of 2-dimensional images, all within one texture. The array length is part of the texture's size.
GL_TEXTURE_2D_MULTISAMPLE: The image in this texture (only one image. No mipmapping) is 2-dimensional. Each pixel in these images contains multiple samples instead of just one value.
GL_TEXTURE_2D_MULTISAMPLE_ARRAY: Combines 2D array and 2D multisample types. No mipmapping.
From: http://www.opengl.org/wiki/Texture
2010年9月17日星期五
Texture Address Mode (Clamp, Wrap)
1. Clamp
这个寻址模式让所有的纹理坐标截取到[0,1]范围内,所有小于0的坐标截取到0,大于1的截取到1。
结果是,超出[0,1] 范围的纹理坐标的所有像素的颜色为纹理边缘的颜色。
2. Wrap
使用这个模式,显卡会从坐标加上或减去1直到坐标仍回到[0,1]范围。
这会导致原始纹理被复制。
这个寻址模式让所有的纹理坐标截取到[0,1]范围内,所有小于0的坐标截取到0,大于1的截取到1。
结果是,超出[0,1] 范围的纹理坐标的所有像素的颜色为纹理边缘的颜色。
2. Wrap
使用这个模式,显卡会从坐标加上或减去1直到坐标仍回到[0,1]范围。
这会导致原始纹理被复制。
下图是两种addressing mode的比较,左为Clamp, 右为Wrap。
纹理过滤模式中的Bilinear、Trilinear以及Anistropic Filtering <转>
1、 为什么在纹理采样时需要texture filter(纹理过滤)。


我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixel不一定对应texture上的采样中心texel),大小也不一定一至。当纹理大于三维图形表面时,导至一个像素被映射到许多纹理像素上;当维理小于三维图形表面时,许多个象素都映射到同一纹理。
当这些情况发生时,贴图就会变得模糊或发生错位,马赛克。要解决此类问题,必须通过技术平滑texel和pixel之间的对应。这种技术就是纹理滤波。
不同的过滤模式,计算复杂度不一样,会得到不同的效果。过滤模式由简单到复杂包括:Nearest Point Sampling(最近点采样),Bilinear(双线性过滤)、Trilinear(三线性过滤)、Anisotropic Filtering(各向异性过滤)。
在了解这些之前,有必要了解什么是MipMap和什么时各向同性,各向异性。
2、 什么是MipMap?
Mipmap由Lance Williams 在1983的一篇文章“Pyramidal parametrics”中提出。Wiki中有很详细的介绍( http://en.wikipedia.org/wiki/Mipmap ) . 比如一张256X256的图,在长和宽方向每次减少一倍,生成:128X128,64X64,32X32,16X16,8X8,4X4,2X2,1X1,八张图,组成MipMap,如下图示。
Mipmap早已被硬件支持,硬件会自动为创建的Texture生成mipmap的各级。在D3D的API:CreateTexture中有一个参数levels,就是用于指定生成mipmap到哪个级别,当不指定时就一直生成到1X1。
3、 什么是各向同性和各向异性?
当需要贴图的三维表面平行于屏幕(viewport),则是各向同性的。当要贴图的三维表面与屏幕有一定角度的倾斜,则是各向异性的。也可以这样理解,当一个texture贴到三维表面上从Camera看来没有变形,投射到屏幕空间中后U方向和V方向比例仍然是一样的,便可以理解成各向同性。反之则认为是各向异性。
4、 Nearest Point Sampling(最近点采样)
这个最简单,每个像素的纹理坐标,并不是刚好对应Texture上的一个采样点texel,怎么办呢?最近点采样取最接近的texel进行采样。
当纹理的大小与贴图的三维图形的大小差不多时,这种方法非常有效和快捷。如果大小不同,纹理就需要进行放大或缩小,这样,结果就会变得矮胖、变形或模糊。
5、 Bilinear(双线性过滤)
双线性过滤以pixel对应的纹理坐标为中心,采该纹理坐标周围4个texel的像素,再取平均,以平均值作为采样值。
双线性过滤像素之间的过渡更加平滑,但是它只作用于一个MipMap Level,它选取texel和pixel之间大小最接近的那一层MipMap进行采样。当和pixel大小匹配的texel大小在两层Mipmap level之间时,双线性过滤在有些情况效果就不太好。于是就有了三线性过滤。
6、 Trilinear(三线性过滤)
三线性过滤以双线性过滤为基础。会对pixel大小与texel大小最接近的两层Mipmap level分别进行双线性过滤,然后再对两层得到的结果进生线性插值。
三线性过滤在一般情况下效果非常理想了。但是到目前为止,我们均是假设是texture投射到屏幕空间是各向同性的。但是当各向异性的情况时,效果仍然不理想,于是产生了Anisotropic Filtering(各向异性过滤)。
7、 Anisotropic Filtering(各向异性过滤)
先看效果,左边的图采用三线性过滤,右边的图采用各向异性过滤。
各向同性的过滤在采样的时候,是对正方形区域里行采样。各向异性过滤把纹理与屏幕空间的角度这个因素考虑时去。简单地说,它会考滤一个pixel(x:y=1:1)对应到纹理空间中在u和v方向上u和v的比例关系,当u:v不是1:1时,将会按比例在各方向上采样不同数量的点来计算最终的结果(这时采样就有可能是长方形区域)。
我们一般指的Anisotropic Filtering(AF)均是基于三线过滤的Anisotropic Filtering,因此当u:v不为1:1时,则Anisotropic Filtering比Trilinear需要采样更多的点,具体要采多少,取决于是多少X的AF,现在的显卡最多技持到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的好方法。如果你觉得你的显卡够牛,那么就把AA和AF都打到最高再试试吧:)
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,文本模式会认为这是文件结束符,也就是二进制模型不会对文件进行处理,而文本方式会按一定的方式对数据作相应的转换。
订阅:
博文 (Atom)
