« AB是一家?VAO与VBOMD5模型的格式、导入与顶点蒙皮式骨骼动画I »

球体贴图小谈

球体贴图是老生常谈的东西了,很多时候都会遇到。选择什么方式去进行贴图,有时候也还是要考虑一番的。——ZwqXin.com

第一次接触球体贴图这玩意,是课程的第三次作业的时候做的Demo(LostHeaven)。那时候恰逢汶川的地震,自己就选择了那么个祈祷与人类破坏自然的主题,一开始的场景是一个下坠并“破碎”的地球。这个地球就是最初的我的球体贴图应用物了。怀念一下,贴图参考的是NEHE第二十多课那个,记不太清了,大致是直接用一张长方形纹理贴上去,然后设置一下纹理的生成方式(glTexGeni)之类的吧。其实哪怕是现在,这种贴图方式也是很平常的,就是Cylinder Map,把贴向一个柱体的纹理直接贴上球体上,让它包裹球体。确实简单,问题是球体的两极会因为过采样而出现褶皱。如果那两个点完全不暴露给观看者的话,那还好,不然就真的颇难看了。

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/opengl/sphere-mapping-cubemap-stuff.html

因为要考虑到贴到球体时的扭曲问题,赤道部分向两级的采样需求逐渐降低,所以那贴图一般都是中间“肥”上下两端“瘦”,呈现一定的扭曲,以尽量达到采样均匀,且贴到球体后看上去自然一点。对于两级的过采样问题,可以用一些方法降低采样率,具体不太懂所以就不多说了。针对CylinderMap的这些缺陷,部分人们开始选用CubeMap作为贴图方式。而本文也主要谈这种方式。

 关于CubeMapping:[Shader快速复习:Cube Mapping(立方环境贴图)]

说到星体渲染,可能有人会知道Celestia这个软件,使用它可以渲染出一个绚烂的太空场景。这类软件可谓与球体贴图最靠近乎的东西之一了,从它对球体贴图方式的采用选择上看起吧:

Creating Textures for Celestia

上面这篇文章提及了主要使用的是Cylinder Map(至少在1.4版),而Cube Map作为一个“将来也许会支持”的选择项而被介绍。可见,Celestia应该还是比较偏好于前者的,这里面有两个比较重要的原因。

1. 矩形的星体纹理,比起六张一体的立方纹理,较容易获得

如果你在网上搜索一些星体的纹理,譬如地球啊、月球啊、火星啊,你搜到的基本都是一般的长方形纹理吧,配以分辨率(譬如4k纹理通常指长边至少为4000像素的纹理图)。所以,一般是很少见到原生的cubemap(6张图或dds文件)的。在著名的NASA分网站(http://earthobservatory.nasa.gov/)上,你可以搜到一堆堆的星体纹理,非常丰富,但大多都是基于一般的单一矩形纹理的:

通过一些工具,我们可以将这样的图片转换成6张子图,也就是把cylinderMap转换成CubeMap。Sourceforge项目“cubemap”(当前版本1.03)就是这样的工具之一,我就是使用它把上面一张2D纹理转换成6张纹理组成cubemap的,还算是比较方便的,效果也不错:

http://www.zwqxin.com

所以说,虽然CubeMap的来源一般比较少,但动动手也是可以自己找素材做出来的。

2.cubemap贴图的时候6张纹理在球体表面贴合处会出现缝迹

如果说Cylinder贴图的弊端是两级位置的过采样造成的扭曲,那么Cube贴图的相应弊端就是接合处的欠采样造成的缝痕了。在这个论坛地址上可以看到一些截图。恰巧这个帖子也是针对这两种方法的讨论,建议看看。里面提及使用Cylinder贴图的同时使用VT来处理的方式,不过这对于我们来说实在也太specific了。

一般来说,相对于cylinder贴图造成的那种“几公里外”也能看到的两级扭曲痛苦状,cubemap这种缝痕基本是不把眼睛贴向表面上都不会察觉的程度。贴到表面——这本身就有纹理本身欠采样造成的巨大锯齿在那里了——任何纹理都会这样,所以说CubeMap的这种问题在很多时候都可以忽略的。但是确实也有采用超高分辨率贴图,同时也允许观看者近距离靠近球体的场合,这时候这道缝就很成问题了。

也是有对应的大致解决方案的,而且很简单。既然分别都是采样造成的问题,何不对应地在某些临界点改变一下采样率呢?对于Cylinder方式的贴图,在两级减少采样,这涉及采样规则方式的改变和效果的问题,临界点也很难界定,所以是很难做到的;而Cube方式的贴图,只要在边界处向相邻的纹理边界采样并混合(插值)一下,应该就能很好地拯救(模糊)那些缝痕。事实上,这甚至不用我们手动去搞,OpenGL3.2开始已经向我们提供了这么一个核心扩展了:seamless_cube_map

在以前的GPU上是无法把纹理的filtering应用在cubemap相邻的两张子纹理上的。但既然如今可以做到,那么这个扩展就很自然出现的,只要在两纹理边界处像素线性插值一下,缝痕就基本消失了。当然开启这个扩展是会有点点影响效率的(毕竟采样工作增加了嘛),所以如果你确实没有需要近处去观摩一个cubemap(不限于球体贴图)的边缘,那就不要启用这个扩展了。

事实上最好也要避免在运行渲染期间去切换这个OpenGL状态,很费效率。在初始化的时候设定,然后不要再去改变它——opengl的spec上如是说。设定很简单:

C++代码 初始化阶段
  1. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);  

以下是开启这个状态前后的程序截图,可见前者明显看到一条缝痕,后者基本看不到了:
http://www.zwqxin.com
http://www.zwqxin.com

如果真的需要一个总结的话,我会说:是时候使用CubeMap来做一般的球面贴图了。

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/opengl/sphere-mapping-cubemap-stuff.html

  • quote 1.daniel
  • 请教个问题,如果我用一系列控制点矩阵计算得到一个nurbs曲面,有办法对这个曲面贴图吗?
    zwqxin 于 2011-10-7 9:38:48 回复
    我的理解是跟球体贴图的原理差不多,就是把曲面分割成一些三角面,确定纹理坐标后进行贴图,曲面越复杂无规律这个过程越复杂。分割后计算法线并使用到cubemap也可但一般没必要。
  • 2011-10-7 2:48:27 回复该留言
  • quote 2.jimmy
  • 请问那个Cubemap的转换器怎么使用,已经精疲力尽了,请指教!
    zwqxin 于 2016-1-13 22:10:59 回复
    我记得就是改改原图片路径而已啊。当然你的图片尺寸规整一点像上面这张图长宽都是2的幂...
  • 2016-1-13 9:56:43 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

IE下本页面显示有问题?

→点击地址栏右侧【兼容视图】←

日历

Search

网站分类

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2024 ZwqXin. All Rights Reserved. Theme edited from ipati.