stage3d编程-基础6 关于uv,采样算法

  1、纹理坐标

  之前谈到,顶点数据组成了三角形,很多个三角形组成了模型。但是这个也只是一个线框图。为了让它看起来跟真实的一样,我们需要一个纹理图,给他贴上去。将它包起来,那么它看起来就跟真实的一样了。但是一张2d的平面图,如何能够贴上去呢。那么这个时候,我们需要一个坐标来解决这个问题了。我们称纹理坐标为uv坐标。u是水平,v是垂直向下,坐标原点是纹理图的左上角(0,0)。但是大家想一下,纹理图可大可小,小到4,8,16,32.大到1024x1024,1024x2048。尺寸完全是乱的,不同的,所以这个时候,我们就不能通过纹理图的尺寸来设置坐标了。但是我们可以使用比率来做。一张图,最大为1,最小为0.中间为0.5。这个比率总不会变把!!!。因此呢,gpu就通过这种方式来根据uv值对纹理图进行采样。我们先来看最简单的,正方形。额外参考http://17de.com/library/d3d_6im/d3dim6_18.htm。

  

  大家看这个正方形。其实看了一眼就明了。原来是这样的。一共四个顶点。

  假设(右手坐标系):

      左上角:-1,1,0

      右上角: 1,1,0

      左下角:-1,-1,0

      右下角: 1,-1,0

  虽然顶点只有四个,但是我们可以通过索引来组合三角形。大家在看demo的时候,也就可以发现索引数据是0,1,2,0,2,3。

  如果我们把uv坐标也加上,那么就变成了:

      左上角:-1,1,0      0,0

      右上角: 1,1,0      1,0

      左下角:-1,-1,0       0,1

      右下角: 1,-1,0      1,1

  那么上面就有了四段数据,我们就可以通过创建vertexbuffer的时候,设置一段长度为5,总共4段数据来创建vertexbuffer了。然后

context3D.setVertexBufferAt(0, vertexBuffer, 0,Context3DVertexBufferFormat.FLOAT_3); 设置va0为顶点数据。
context3D.setVertexBufferAt(0, vertexBuffer, 1,Context3DVertexBufferFormat.FLOAT_2); 设置va1为uv数据。(我之前贴的那个demo我没有细看,它上传了三个进去,但是不影响,因为只会用到这个寄存器的前面两个值)
  然后我们就可以在agal里面写到. mov v0 va1。将uv存到v0中去,供片段程序使用。
  然后在片段程序里面: tex ft0, v0, fs0 <2d,repeat,miplinear>。即tex命令就会根据uv值从纹理图里面去采集颜色信息了,然后显示出来。大家可能会有疑问,明明左上角和右上角离了那么远,并且我也只指定两个uv值,中间并没有指定啊,为什么中间也显示出来了呢?这个过程其实是gpu帮我们完成的。(本来是以三角形为单位,但是这里为了更加通俗易懂,举了两个点的例子)。
 
  
  上面谈到了gpu里面帮我完成中间着色的事情。现在就来详细谈一下。完了呢,大家就对那么demo就了然了,然后看其他的呢,也就了然,原来如此啊。
  
  1、倍增算法:假设,相机离一面墙很近的时候,我们显示器的分辨率为1024x1024。但是墙的贴图为256x256。那么这个时候就会出现倍增的情况了。也就是说一个纹理图的像素要覆盖显示器的四个像素。所以呐gpu就提供了插值算法,线性插值算法:以1d空间的插值方法来说明:
  假设有一个纹理坐标u = 0.126484375。那么对应的纹理元素则为:0.12 * 256 = 32.38。这个值呢,其实是位于两个采样点之间。因此呢,我们就需要用插值来估算它。
  
  只是简单说明一下,大家明白是怎么一回事就行了,具体算法可以google。
  2、缩减:缩减与倍增刚好相反。所以大家在看demo的时候就会发现,用到了Mip。为什么呢,这个其实也就是提供了,当模型离得很远的时候,我们提供一个精度较小的纹理图来与之对应。
  
   
  现在再来解释一下:<2d,repeat,miplinear>这段代码的含义了。miplinear就是在说,启用mip映射,采用linear线性插值算法。还有其他算法,请看最后面。下面解释repeat的含义:。
  
  现在来解释一下repeat。
  这个涉及到了纹理的寻址模式。有几种方式repeat,wrap,clamp。当然stage3d只提供了这几种方式。repeat和wrap是重复模式(没什么特殊效果),clamp是截取。
  重复:通过在每个整点连接处重复图像来扩展纹理。
  
  我们之前谈到了uv值,之前说的uv值是0-1范围,但是如果uv值超过这个范围了呢?如果我们使用repeat模式,请看上图。如果uv为1.1,那么gpu就会将纹理图重复一倍拼接起来,然后去取1.1(注意不要理解为取0.1不一样)。其实我们在做墙砖等效果的,一堵很大的一面墙,我们总不能用一张很大的图来做吧?其实我们就是用一张很小的图,然后使用repeat模式,这样就可以做出墙的效果了。例如上面的箱子效果,纹理图其实就是第一张图。
  
  
  
   
  截取模式:
  
  
  
 
 
 
  这也就解释了<2d,repeat,miplinear>这段代码的详细意思了,至于前面的2d,大家看下面把,因为我没有用到其他的,所以不敢妄加推测。
    
  
  
  1. texture dimension: 2d, 3d, or cube. A 2D texture is the most commonly used format, a rectangular bitmap. A 3D texture has length, width, and depth, and takes up a lot of texture RAM but is great for 3D materials such as wood, grain, or marble. It is rarely used. A cube texture is a specially encoded group of six rectangular bitmaps and is usually used for reflections, as each of these six images maps to a particular direction like the sides on the inside of a box.

  2. mip mapping: nomip, mipnone, mipnearest, or miplinear. If your texture has mip maps (successively smaller versions of itself, generated to avoid jaggies during rendering), then you can instruct Stage3D to smoothly interpolate the texture using them. Mip mapped textures are very useful to increase render quality and avoid the "moiree effect" (flickering) when viewed from far away.

  3. texture filtering: nearest or linear. If you prefer a retro, then pixilated look you can use nearest here to tell Stage3D not to interpolate the values smoothly, resulting in blocky textures when viewed up close, for example. If you use linear, when zoomed into a texture it will be blurry and will have smoother edges.

  4. texture repeat: repeat, wrap, or clamp. If you want the texture tile properly, then you use repeat here. If you are not tiling the texture and run into problems with edge pixels being the color of the opposite edge (which often happens in transparent billboard particles and when rendering bitmap fonts in 3d), then specify clamp to force Stage3D not to blur adjacent edge pixels. 

  

  
  

posted on 2013-09-14 13:08  boblchen  阅读(1515)  评论(0)    收藏  举报