带偏移限制的视差贴图

  • Post author:
  • Post category:其他


带偏移限制的视差贴图: 一种粗糙表面的逐像素近似法 by coollen

关注

ming1016@gmail.com


Parallax Mapping with Offset Limiting:



A Per-Pixel Approximation of Uneven Surfaces



带偏移限制的视差贴图:


一种粗糙表面的逐像素近似法

作者


Terry Welsh

翻译


Coollen.MMX



Abstract 概要

This paper describes parallax mapping and an enhancement that makes it more practical for general use. Parallax mapping is a method for approximating the correct appearance of uneven surfaces by modifying the texture coordinate for each pixel. Parallax is exhibited when areas of a surface appear to move relative to one another as the view position changes. This can be observed on any surface that is not flat. Parallax can be simulated well by constructing a complete geometric model of a surface, but it can be computationally expensive to draw all the necessary polygons. The method presented here requires no extra polygons and approximates surface parallax using surface height data.

这是一篇介绍视差贴图(parallax mapping)的文章,此外还会介绍一种让视差贴图变得更加真实的方法。视差贴图是一种通过修改每个像素的贴图坐标来模拟粗糙表面的近似算法。视差是指 当观察点变化时表面上的不同区域好像在做相对运动。就如同你在任何粗糙表面上看到的那样。视差可以通过构建一个复杂的几何模型来表现的非常好,但是这会消 耗大量计算成本来绘制全部必要的多边形。以下介绍的方法将不会需要额外的多边形,仅是使用表面的高度数据来近似地模拟视差。



1  Introduction 简介

The reader is assumed to have an understanding of computer graphics concepts and experience using a graphics language such as OpenGL.

这里假定读者都理解计算机图形概念并且有使用图形学语言(比如OpenGL)的经验。

Modern graphics hardware allows us to replace traditional vertex transformations and lighting equations with custom programs, known as “vertex programs” and “fragment programs.”  A vertex program acts upon vertex data, transforming vertices from Cartesian coordinates to screen coordinates.  Not only can vertex programs perform these necessary transformations, they can also modify and output vertex positions, colors, normals, texture coordinates, and other attributes.  These outputs are interpolated across the surface of a triangle defined by three such vertices to provide input for fragment programs.  A fragment program is executed once for every pixel that is drawn, receiving inputs in the form of interpolated vertex data, texture data, and possibly other values.  All this information is used to compute the final color of each pixel.

现代的图形硬件允许我我们用自定义的程序来替代传统的顶点转换和光照公式,叫做“顶点程序(vertex programs)”和“片元程序(fragment programs)”。(译:这是OpenGL的叫法,DirectX叫做Vertex Shader和Pixel Shader)顶点程序用来操作顶点数据,它能把顶点坐标从笛卡尔坐标转换成屏幕坐标。但它不仅仅能用来处理这些必要的坐标转换,还能修改和输出顶点位 置,颜色,法线,贴图坐标和其他属性。这些输出的数据经过由三个顶点组成的三角形表面的内插值计算后传递给片元程序。片元程序会接收插值过的顶点数据、贴 图数据和其他可能的数据,并对每个被绘制的像素执行一次计算。所有的这些信息都会用来计算每个像素的最终颜色。

Using vertex and fragment programs, it is possible to replace the traditional vertex projection and lighting equation used by real-time computer graphics hardware.  The method presented in this paper applies these capabilities to achieve an approximation of the parallax that can be observed on pitted or uneven surfaces.

使用顶点和片元程序能够取代计算机图形硬件上使用的传统的顶点投影和光照公式。这篇文章中的方法应用这些能力来达到近似模拟有凹痕的或者不平坦的表面的视差。

The following text presents pieces of vertex and fragment programs that use the syntax of OpenGL’s ARB_vertex_program version 1.0 and ARB_fragment_program version 1.0.

以下文本中的顶点和片元程序使用OpenGL的是ARB_vertex_program 1.0版本以及ARB_fragment_program 1.0版本的语法。



2  Related Work 相关工作


2.1  Parallax Mapping 视差贴图

This technique approximates the parallax that can be observed on uneven surfaces. Parallax mapping [3] alone will only approximate parallax and will not simulate occlusions, silhouettes, or self shadowing.  It is a 2D process, so no extra polygons are required.  It will be explained in detail in Section 4.1.

这项技术近似模拟了粗糙表面的视差。单独的视差贴图技术仅仅是近似模拟了视差,而不会模拟遮挡,轮廓,或者自投影。这是一种2D的处理,所以不会要求附加的三角形。在4.1中会有更详细的描述。



2.2  Displacement Mapping 置换贴图

The most straightforward way to achieve parallax effects when simulating a complex complex surface is to build a detailed model of the surface.  Displacement mapping [2] is a technique that subdivides a surface into a large number of small triangles.  The vertices of these triangles are then displaced perpendicularly to the surface normal according to some height function.  The vertices can also be assigned new normals to accurately simulate the surface lighting.

模拟非常复杂表面的视差效果的最直接方式是构建一个表面的精细模型。置换贴图(Displacement mapping)是一种把一个表面细分成大量小三角形的技术。这些三角形的顶点将会垂直于面法线并根据高度函数显示出来。这些顶点也会被分配新的法线来正 确的模拟表面光照。



2.3  Relief Texture Mapping 浮雕材质贴图

Relief texture mapping (RTM)  [4] is very similar to parallax mapping in that it attempts to simulate parallax with an image warping technique.  Relief textures are pre-warped through a software process before being sent to the graphics hardware.  Using many relief textures in a single application is likely to prevent the application from achieving real-time frame rates.  However, RTM gives high quality results.  It correctly handles self-occlusions and produces texel-accurate silhouettes.

浮雕材质贴图(Relief texture mapping)和视差贴图很像,它是用一种图像弯曲技术来模拟视差。在一个单独的程序中使用很多浮雕贴图很可以会使程度达不到实时的帧率。尽管如此,浮 雕材质贴图提供了高质量的效果。它正确的处理了自我遮挡(self-occlusions),并且产生了贴图像素级别精度的轮廓。



2.4  View-Dependent Displacement Mapping 基于视点的置换贴图

View-dependent displacement mapping (VDM) [5] is a per-pixel rendering technique capable of self-shadowing, occlusions, and silhouettes.  It stores a many-dimensional surface description in several texture maps, which are pre-computed from a height map. Although it requires a large amount of memory for textures, VDM produces convincing images at high frame rates.  A good parallax effect is achieved because VDM textures store the relation ship between texels along many viewing directions.

基于视点的置换贴图(View-dependent displacement mapping)是一种能够实现自我投影、遮挡和轮廓的逐像素光照技术。它把一个多维的表面定义存贮在多张贴图中,这些贴图都是通过高度图计算得到。尽管 它需要大量的内存来存放贴图,这项技术产生的图像和帧率都可以让人信服。因为基于视点的置换贴图技术的贴图存储了沿着观察方向上的贴图像素之间的关系,所 以达到了良好的视差效果。



3  Background 背景

The concept of tangent space is probably the most important piece of background information required to understand parallax mapping.  Tangent space is a coordinate system that is oriented relative to a given surface.  It is defined by three axes, the tangent, binormal, and normal.  The tangent and binormal lie in the plane of the surface, while the normal is perpendicular to the plane of the surface.  If a surface is curved, then tangent space rotates as you move along that surface.

理解视差贴图最重要的背景知识就是切线空间(tangent space)的概念。切线是一个和给定的表面相关的坐标系统。它由切线(tangent)、副法线(binormal)、法线(normal)来定义。当 法线正好垂直于给定的表面,切线和副法线在给点表面所在的平面上。如果给定表面被弯曲,那么切线空间将会跟着表面转动。

To apply bump mapping [1] with a normal map, it is necessary to compute the dot product of a vector pointing toward the light with a normal for each pixel.  Because the normal map is mapped to the surface, it already lies flat in tangent space. To compute the necessary dot products, the light vectors must lie in the same coordinate system, so they are transformed into tangent space as well.  Parallax mapping uses the concept of tangent space in the same manner.

为了应用带法线的凹凸贴图技术[1],就必须逐像素计算法线和光源方向向量的点积。因为法线贴图会被映射到表面上,所以它已经是在切线空间中 了。(译:貌似没这个因果关系,^_^!!)为了计算点积,光源方向向量必须也在同一个坐标系中,所以他们都将被转换到切线空间。视差贴图同样使用了这样 的切线空间的概念。



4   Parallax Mapping 视差贴图


4.1  The basics 基础知识

When a texture map representing an uneven surface is applied to a flat polygon, the surface appears to get flattened. In Figure 1 you can see that when viewing the polygon along the texture map has been depicted eye vector, you will see point A of the surface.  However, if you were viewing the actual surface instead of a texture mapped polygon, you would see point B.  If the texture coordinate corresponding to point A could be corrected, then you could view point B instead.  By offsetting all the texture coordinates individually, high areas of the surface would shift away from the eye and low areas of the surface would shift toward the eye.  Thus parallax would be achieved for the simulated surface.  The process of parallax mapping requires that, for each pixel drawn, a texture coordinate, used to index one or more texture maps, be corrected by some displacement.  This technique approximates the parallax seen when moving the eye relative to an uneven surface.

当使用材质贴图在光滑的多边形上表现一个粗糙的表面时,那个表面看起来像是平坦的。在图一中你能看到,当你沿着图中画出的视线的方向看这个多边形的 时候,你看到的是表面上的点A。但是,当你看着一个实际表面而不是带材质贴图的多边形的时候,你将会看到的是点B。如果原本点A对应的贴图坐标能够被修正 的话,那么你将会看到B而非A。通过偏移所有这样的贴图坐标,表面上的较高的地方会相对眼睛被移远,而低的地方被移近。因此视差能在模拟的表面上表现出 来。视差贴图技术的过程有以下要求:对每个像素都做处理中,一个贴图坐标能被多张贴图使用,并且能做一些偏移。这项技术近似模拟了观察点相对于粗糙的表面 移动时的视差。

Three components are required to compute an offset texture coordinate for a pixel: a starting texture coordinate, a value of the surface height, and a tangent space vector pointing from the pixel to the eye point.  In Figure 2 you can see how it is possible to modulate the eye vector by the surface height to obtain a texture coordinate offset.

计算一个像素的贴图坐标需要3个数据:原始贴图坐标,表面的高度值,切线空间中的从像素到眼睛的向量(视向量)。在图2中你能看到视向量是如何通过表面高度数据计算得到贴图坐标的偏移。

A standard height map is used to represent the varying height of the surface.  The height map correlates to the surface’s regular texture map and stores one height value per texel.   These values are in the range {0.0, 1.0}.

一张标准的高度贴图被用来表现表面多变的高度。高度贴图和常规的材质贴图相关,并且存储了一个高度值在每个贴图像素中。这些高度值在{0.0, 1.0}的范围内。

Since any parallax effect depends on point of view, a vector from a point on the surface to the eye is required.  The original texture coordinate and height values are already represented in tangent space, so the eye vector must be as well.  The eye vector can be created in global coordinates by subtracting a surface position from the eye position and transforming the resulting vector into tangent space.  An application programmer must supply a tangent, binormal, and normal at each vertex.              These can be used to create a rotation matrix at every point on the surface which will transform vectors from the global coordinate system to tangent space.

因为任何视差效果都依赖于视点,所以就需要一个从表面到视点的向量。原始的材质贴图坐标和高度数据已经在切线空间中了,因此视向量最好也能如此。视 向量能够在全局坐标系中通过视点坐标减去表面坐标来创建,并且要把结果转换到切线空间中。程序员必须提供每个顶点的切线、副法线和法线。这些数据能会用来 为表面上每个顶点创建一个旋转矩阵,能够用来把向量从全局坐标系转换到切线空间。

To compute a texture coordinate offset at a point P, the eye vector must first be normalized to produce a normalized eye vector V.  The height h at the original texture coordinate To is read from the height map.  The height is scaled by a scale factor s and biased by a bias b in order to map the height from the range {0.0, 1.0} to a range that better represents the physical properties of the surface being simulated.  For example, a brick wall texture might cover a 2×2 meter area.  Also imagine the surface of the bricks and the recessed grout give the surface a thickness of 0.02m.  The correct scale factor for this material would be 0.02 / 2 = 0.01.  Coupling this with a bias of 0.0 would then remap the height field to a range of {0.0, 0.01}.  Using a bias of -0.01 would remap the range to {-0.99, 0.0}.  The average of these two extremes is probably best for most textures.

为了计算P点的贴图坐标偏移,必须先规格化视向量,并记作V。原始贴图坐标To对应的高度h可以从高度图读取出来。高度能够被一个缩放因子s缩放, 并且被一个修正值b修正,这样可以把高度信息的范围从{0.0, 1.0}转到一个模拟效果更好的范围内。举例来说,一个砖墙的材质差不多是2×2米,想像一下那些砖块的表面,那些泥浆部分凹陷了0.02米。这个材质的 正确的缩放因子将会是0.02 / 2 = 0.01。结合上0.0的修正,高度值的范围变成了{0.0, 0.01}。如果使用-0.01的修正的话,高度值的范围就变成了{-0.99, 0.0}。这两个极值的平均值对大多数贴图来说都合适。

A bias that excludes 0.0 from the range would be impractical since that assumes that the surface being simulated does not intersect the polygon that represents it.  The new scaled and biased height hsb is given by :

把0.0排除在修正的范围之外是不切实际的,因为只有被模拟的表面和多边形没有交叉才会如此。新的被缩放和修正后的高度hsb如下:

An offset is then computed by tracing a vector parallel to the polygon from the point on the surface directly above P to the eye vector.(译:好强的句子,-_-!!)  This new vector is the offset and can be added to To to produce the new texture coordinate Tn.

偏移量是通过跟踪一个以P点垂直向上的真实表面上的点为起点,平行于多边形平面,指向视向量的向量来计算的。这个新的向量就是偏移量,把它加到原始贴图坐标To中就能得到新的贴图坐标Tn。


(本人插话:Voffset = Hsb * V{x,y} / V{z},推断:Voffset{x,y} / V{x,y} = Hsb / V{z}, 因为Hsb控制在[0,1]之内,因为加了限制(Hsb / V{z} < 1),所以V{z} = 1)?

The new texture coordinate is used to index a regular texture map and any other maps applied to the surface.

这个新的贴图坐标被用来索引一般的材质贴图和其他用在表面上的贴图。


4.2   Implementation 执行

Now to implement this on some fast graphics hardware.  Since vector data can be interpolated between connected vertices by graphics hardware, the simplest solution is to calculate a vector from each vertex to the eye point within a vertex program.  In the language of ARB_vertex_program, these vectors can be calculated with the following code.

现在,我们来试试在图形硬件上来执行它。因为顶点间的向量数据能够被硬件插值,所以计算每个点到视点的向量最简单的解决方案是在顶点程序中处理。在ARB_vertex_program的语言中,可以用下面的代码计算这些向量:

# input data


PARAM mvit[4] = {state.matrix.modelview.invtrans};


ATTRIB tangent = vertex.texcoord[1];


ATTRIB binormal = vertex.texcoord[2];


ATTRIB normal = vertex.normal;

# vector pointing to eye


SUB eyevec, mvit[3], vertex.position;

# transform eye vector into tangent space (DO NOT NORMALIZE)


DP3 result.texcoord[3].x, eyevec, tangent;


DP3 result.texcoord[3].y, eyevec, binormal;


DP3 result.texcoord[3].z, eyevec, normal;


MOV result.texcoord[3].w, 1.0;

The tangent, binormal, and normal attributes represent the coordinate axes of the tangent space surrounding each vertex.  The eye vector is stored in texcoord[3], which is a parameter that will be interpolated across the surface so that each pixel drawn will receive a unique eye vector.

切线,副法线和法线代表了每个顶点的切线空间的三个轴。视向量存储在texcoord[3]中,它会根据表面被插值,所以在画每个像素的时候得到的是一个唯一的视向量。

The remainder of the computation is performed on a per-pixel basis in a fragment program.

剩下的计算是就是在片元程序中逐像素计算修正。

TEMP height, eyevects, newtexcoord, temp;

# normalize tangent space eye vector


DP3 temp, fragment.texcoord[3], fragment.texcoord[3];


RSQ temp, temp.x;


MUL eyevects, fragment.texcoord[3], temp;

# calculate offset and new texture coordinate


TEX height, fragment.texcoord[0], texture[2], 2D;


MAD height, height, 0.04, -0.02;  # scale and bias


RCP temp, eyevects.z;


MUL height, height, temp;


MAD newtexcoord, height, eyevects, fragment.texcoord[0];

The variable newtexcoord stores the shifted texture coordinate, which is used to index other texture maps.

newtexcoord变量存储的是计算之后的贴图坐标,它被用索引其他的贴图。


4.3   Offset Limiting 偏移限制

So far this paper has described a 2D approximation with a significant flaw. The computation presented in Section 4.1 assumes that the point at Tn has the same height as the point at To, which is rarely true.  Any surface that exhibits parallax will have varying heights.

到目前为之,这篇文章介绍了带有重大缺陷的二维近似算法。在4.1中描述的计算方法假定了Tn所在的点有着和To一样的高度,只有少数情况下是这样的。任何体现出视差的表面都会有各种不同的高度值。

At steep viewing angles, texture coordinate offsets tend to be small.  A small offset means that the height at To is likely to be very close to the height at Tn.  Consequently, the offset will be nearly correct.  As the viewing angle becomes more shallow, offset values approach infinity.  When offset values become significantly large, the odds of Tn indexing a similar height to that of To fade away to random chance.  This problem can reduce surfaces with complex height patterns to a shimmering mess of pixels that don’t look anything like the original texture map.

在一个接近垂直的观察角度,贴图坐标的偏移量往往非常小。一个非常小的偏移量则意味着To所在的高度和Tn所在的高度非常接近。因此偏移量非常接近 正确的值。当观察角度越来越平,偏移量接近无穷大。当偏移量变得非常大的时候, the odds of Tn indexing a similar height to that of To fade away to random chance。这个问题会把复杂的高度参数转换成一些有微弱混乱的像素,这会使它看起来和原始的贴图非常不像。




A simple solution to this offset problem is to limit the offsets so that they never eye vector grow longer than hsb.  Since parallax mapping is polygon an approximation, any limiting value could be chosen, but this one works well enough and it reduces the code in the fragment program by two instructions.  The new equation is

解决这个问题的简单解决办法是限制偏移,这样视向量就不会变得比hsb长。因为视差贴图技术是一种针对多边形的近似算法,所以你可以选择任意的限制值,不过这个限制值已经足够有效,并且可以让片元程序的代码少掉2个指令。下面这个就是新的公式:

Figure 3 shows that the texture coordinate offset will be no longer that the height at T o.

图3展示了贴图坐标偏移将不会比T o对应的高度更长。

And the simplified fragment code is

简化之后的代码如下:

TEMP height, eyevects, newtexcoord;

# normalize tangent space eye vector


DP3 temp, fragment.texcoord[3], fragment.texcoord[3];


RSQ temp, temp.x;


MUL eyevects, fragment.texcoord[3], temp;

# calculate offset and new texture coordinate


TEX height, fragment.texcoord[0], texture[2], 2D;


MAD height, height, 0.04, -0.02;  # scale and bias


MAD newtexcoord, height, eyevects, fragment.texcoord[0];

This simplification keeps textures looking good at shallow angles, but it also reduces the parallax effect, which isn’t as bad as it sounds.  Parallax effects are best viewed close up, but surfaces viewed at shallow angles tend to be relatively far away from the eye point.  As surfaces recede into the distance they become smaller, losing detail to minification and texture filtering.

这样的简化可以让贴图在低视角的时候看起来比较好,但是这也会也减少视差效果,不过这并不像它听起来这么糟。当近看的时候视差效果非常好,但是低视角的时候会感觉表面会远离观察点。当表面后退时它会变小,并且压缩和材质过滤会使它丢失细节。



5  Applying Parallax Mapping 应用视差贴图

Parallax mapping is a computationally inexpensive, approximate 2D effect that.  All that it does is modify texture coordinates in order to warp a texture mapped image.  Because of its ease of implementation, it can be used in conjunction with other types of mapping.  The new texture coordinates can be used to index regular texture maps for coloring a surface, normal maps for bump mapping and computing reflection vectors, shininess maps for computing reflectivity, and probably any other standard type of texture data that your application may use.

视差贴图是一种计算开销不大的,近似2D效果。它所做的事情只是为了使贴图产生扭曲而修改贴图坐标。因为执行起来非常简单,所以它能和其他类型的贴 图一起使用。新的贴图坐标能够用来索引给表面着色的材质贴图,凹凸贴图技术中的法线图,以及用来计算反射向量,索引计算反射率的反光区图,或是任意其他你 会用到的标准的贴图数据。

The modified texture coordinates are not perfect, though, so care must be taken in producing height maps and specifying scale and bias values.  Because of the faulty assumption that height values are the same from one texture coordinate to the next, height maps with wildly varying heights tend to cause problems.  Parallax mapping is incapable of detecting areas of a surface that occlude other areas, which is common on a surface with steep angles.  This technique will produce the most attractive results when using height maps with gradual gradations and shallow angles.  The opposite extreme of height map can result in distracting artifacts when a surface is viewed at shallow angles.

修改贴图坐标的方法并非完美,因此,在生成高度图和设置缩放量、修正量的时候必须非常小心。因为我们错误的假定了从一个贴图坐标到下一个的高度值是 相等的(译:应该是指To和Tn的高度值),变化丰富的高度图往往会造成问题。视差贴图技术无法去检测表面上的一个区域是否被其他区域遮挡了,而这在高度 落差大的表面上是很普遍的。当使用逐步分级的并且角度平缓的高度图的时候,这项技术将会带来最吸引人的效果。



6  References 引用

1. James F. Blinn.  “Simulation of Wrinkled Surfaces,” Computer Graphics (SIGGRAPH ‘78 Proceedings), volume 12, pages 286-292, August 1978.

2. Robert Cook.  “Shade trees”, Computer Graphics (SIGGRAPH ‘84 Proceedings) 13(3), 223-231, 1984.

3. Tomomichi Kaneko, et al.  “Detailed Shape Representation with Parallax Mapping,”  ICAT, 2001.

4. Oliveira M., Bishop G., and McAllister D.  “Relief Texture Mapping,” Computer Graphics (SIGGRAPH ‘00Proceedings), 359-368, 2000.

5.  Lifeng Wang, et al.  “View-Dependent Displacement Mapping,” ACM Transactions on Graphics, Volume 22, Issue 3, July 2003.



7  Appendix 附录

A vertex program for computing bump mapping and parallax mapping:

计算凹凸贴图和视差贴图的一个顶点程序:

!!ARBvp1.0

PARAM mvi[4] = {state.matrix.modelview.inverse};


PARAM mvit[4] = {state.matrix.modelview.invtrans};


PARAM mvp[4] = {state.matrix.mvp};

ATTRIB tangent = vertex.texcoord[1];


ATTRIB binormal = vertex.texcoord[2];


ATTRIB normal = vertex.normal;

TEMP light0pos, light0vec;


TEMP light1pos, light1vec;


TEMP eyevec, eyevects;


TEMP temp;

# vector pointing to light0


DP4 light0pos.x, mvi[0], state.light[0].position;


DP4 light0pos.y, mvi[1], state.light[0].position;


DP4 light0pos.z, mvi[2], state.light[0].position;


DP4 light0pos.w, mvi[3], state.light[0].position;


SUB light0vec, light0pos, vertex.position;

# transform light0 vector into tangent space (DO NOT NORMALIZE)


DP3 result.texcoord[1].x, light0vec, tangent;


DP3 result.texcoord[1].y, light0vec, binormal;


DP3 result.texcoord[1].z, light0vec, normal;


MOV result.texcoord[1].w, 1.0;

# vector pointing to light1


DP4 light1pos.x, mvi[0], state.light[1].position;


DP4 light1pos.y, mvi[1], state.light[1].position;


DP4 light1pos.z, mvi[2], state.light[1].position;


DP4 light1pos.w, mvi[3], state.light[1].position;


SUB light1vec, light1pos, vertex.position;

# transform light1 vector into tangent space (DO NOT NORMALIZE)


DP3 result.texcoord[2].x, light1vec, tangent;


DP3 result.texcoord[2].y, light1vec, binormal;


DP3 result.texcoord[2].z, light1vec, normal;


MOV result.texcoord[2].w, 1.0;

# vector pointing to eye


SUB eyevec, mvit[3], vertex.position;

# transform eye vector into tangent space (DO NOT NORMALIZE)


DP3 result.texcoord[3].x, eyevec, tangent;


DP3 result.texcoord[3].y, eyevec, binormal;


DP3 result.texcoord[3].z, eyevec, normal;


MOV result.texcoord[3].w, 1.0;

# regular output


DP4 result.position.x, mvp[0], vertex.position;


DP4 result.position.y, mvp[1], vertex.position;


DP4 result.position.z, mvp[2], vertex.position;


DP4 result.position.w, mvp[3], vertex.position;


MOV result.color, vertex.color;


MOV result.texcoord[0], vertex.texcoord[0];

END

A fragment program for computing parallax mapping and bump mapping:

计算凹凸贴图和视差贴图的一个片元程序:

!!ARBfp1.0

PARAM light0color = state.light[0].diffuse;


PARAM light1color = state.light[1].diffuse;


PARAM ambient = state.lightmodel.ambient;

TEMP eyevects;


TEMP rgb, normal, height, temp, bump, total;


TEMP light0tsvec, light1tsvec;


TEMP newtexcoord;

# normalize tangent space eye vector


DP3 temp, fragment.texcoord[3], fragment.texcoord[3];


RSQ temp, temp.x;


MUL eyevects, fragment.texcoord[3], temp;

# calculate offset and new texture coordinate


TEX height, fragment.texcoord[0], texture[2], 2D;


MAD height, height, 0.04, -0.02;  # scale and bias


MAD newtexcoord, height, eyevects, fragment.texcoord[0];

# get texture data


TEX rgb, newtexcoord, texture[0], 2D;


TEX normal, newtexcoord, texture[1], 2D;

# remove scale and bias from the normal map


MAD normal, normal, 2.0, -1.0;

# normalize the normal map


DP3 temp, normal, normal;


RSQ temp, temp.r;


MUL normal, normal, temp;

# normalize the light0 vector


DP3 temp, fragment.texcoord[1], fragment.texcoord[1];


RSQ temp, temp.x;


MUL light0tsvec, fragment.texcoord[1], temp;

# normal dot lightdir


DP3 bump, normal, light0tsvec;

# add light0 color


MUL_SAT total, bump, light0color;

# normalize the light1 vector


DP3 temp, fragment.texcoord[2], fragment.texcoord[2];


RSQ temp, temp.x;


MUL light1tsvec, fragment.texcoord[2], temp;

# normal dot lightdir


DP3 bump, normal, light1tsvec;

# add light1 color


MUL_SAT bump, bump, light1color;


ADD_SAT total, total, bump;

# add ambient lighting


ADD_SAT total, total, ambient;

# multiply by regular texture map color


MUL_SAT result.color, rgb, total;

END

Flixel开发框架介绍 by coollen  (来自:

http://blog.coollen.com

)

文章地址:

http://coollen.com/blog/wordpress/?p=175