cp的小屋

not yet

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  27 随笔 :: 0 文章 :: 216 评论 :: 1 引用


有贴图拉伸问题的悬崖


解决了贴图拉伸问题的悬崖

  如果你玩过一些早期以室外地形为主的3D游戏,比如《起义》,就会发现遇到陡峭山崖的时候地面贴图会被严重拉伸。随着Shader的引入和显卡机能的提高,在近期发行的很多高品质3D游戏中悬崖贴图变得非常精细,不再有拉伸现象了。在FarCry中有一关好像桂林山水那样的风景,陡峭的山崖和深谷中的清澈的河水给人留下了深刻的印象。其实只要一个小小的技巧就可以解决贴图拉伸问题,并且不一定非要Shader支持,只不过没有Shader支持你通常需要3个顶点UV流才能实现这些效果,对于显卡的总线带宽和显存容量要求高了些。下面就结合插图来说说这个小技巧,为了方便我们还是采用2D图片说明问题,只需要稍稍费点脑力就可以想像在3D空间中的效果。


  
  想像图中AB、BC是一个悬崖的两个侧面,从图中可以看到,将AB向Y轴投影,BC向X轴投影可以获得较大的投影长度(相比将AB向X轴投影,BC向Y轴投影),如果有一张贴图分别沿X和Y轴平铺,则AB向Y轴投影、BC向X轴投影可以分别跨越较大范围的纹理尺度。根据悬崖的走向选择不同的投影坐标轴以获得最大的投影长度,将这个投影值作为悬崖贴图的UV坐标就可以避免采用固定UV带来的贴图拉伸问题。对于三维空间,假设XY平面是水平面,则XZ、YZ是两个垂直平面,根据悬崖的走向选择向XZ或YZ平面投影(原则是获得较大的投影跨度),在这两种情况下分别把投影得到的X、Z或者Y、Z值做为顶点的U、V坐标。通常UV坐标每跨越1.0纹理映射就会跨越整张贴图,所以把投影值直接作为UV坐标在多数情况下显得太大了,通常会再乘上一个比例因子。比如投影得到的跨度是100,在你的世界中代表10米,你希望这样的距离刚好跨过一张贴图,那就需要把投影得到的值乘以0.01。

  传统管道顶点UV可以通过预计算并保存在顶点Buffer中,如果使用可编程管道,则可以把UV计算放在VS中实现,不再需要通过顶点Buffer传入。不管用哪种方式,计算都是简单的点乘。假设沿三个坐标轴的单位向量分别是NX、NY、NZ,缩放因子是S,顶点坐标是P,下面就是悬崖UV的计算方式
  向XZ平面投影的时候:
    u = (P dot NX) * S
    v = (P dot NZ) * S
  向YZ平面投影的时候:
    u = (P dot NY) * S
    v = (P dot NZ) * S
实际计算的时候可以先把单位向量NX、NY、NZ乘以缩放因子S,再和顶点坐标做点乘,这样可以省去乘以缩放因子的开销

posted on 2006-08-07 16:36 cproom 阅读(692) 评论(10)  编辑 收藏

评论

看来大家最后用的手段都一样了
  回复  引用    

#2楼  2006-09-28 14:55 icecoffee      
固定管道坐标也可以通过纹理生成矩阵生成
  回复  引用  查看    

#3楼  2006-12-07 22:48 空明流转      
LZ的模型/材质资源都是哪里的出处。。。可以说一下么。。。
  回复  引用  查看    

#4楼 [楼主] 2006-12-08 10:50 cproom      
模型和贴图资源有些是美术同事提供的,大部分是其它游戏破解的资源,象魔兽世界网上已经有很多开原工具可以解读它的资源,另外向Doom3、Farcry的资源基本是官方公开的,只需改一下资源包文件扩展名就可以用WinZip打开。另外很多网游的资源包也很容易自己破解,如Rose、傲世Online。但是一般贴图资源比较容易使用,模型资源就需要进一步破解它的格式,比较麻烦。
  回复  引用  查看    

#5楼  2007-07-22 16:49 李锦俊 [未注册用户]
楼主,请问能否写个具体算法出来?
怎么我看你写的公式里好像不怎么对头啊,我用你的公式套进去之后结果还是拉伸,顶点 dot NX 不就是等于X的坐标值么?
  回复  引用    

#6楼  2007-07-23 16:27 cproom [未注册用户]
向XZ平面投影的时候:
    u = (P dot NX) * S
    v = (P dot NZ) * S
其实投影后的结果就是x、z坐标乘以一个比例因子S,这样的uv值正是我们需要的,有什么问题吗?
  回复  引用    

#7楼  2008-02-05 11:37 kamark [未注册用户]
AB和BC和公用顶点B的UV值怎么算?
  回复  引用    

#8楼  2008-02-05 11:49 kamark [未注册用户]
有个更简单的办法计算AB在Y轴的投影值:A.y-B.y
  回复  引用    

向XZ平面投影的时候:
    u = (P dot NX) * S
    v = (P dot NZ) * S
其实投影后的结果就是x、z坐标乘以一个比例因子S,这样的uv值正是我们需要的,有什么问题吗?

请问,为什么不用y的值进行计算呢?这个拉升效果,是因为y值拉的过高了啊。同事这个比例因子,是动态计算一个值的吗?
  回复  引用    

#10楼 [楼主] 2008-06-04 09:42 cproom      
@包子西施
向XZ平面投影的时候:
    u = (P dot NX) * S
    v = (P dot NZ) * S
这是拿向下投影的一般情况举例,悬崖当然要向XY或者ZY平面投影,这样时Y就参与运算了。

另外这个比例因子取值比较宽松,它决定了贴图的平铺重复频率,重复频率高贴图效果精细,但容易看出重复。你可以在编辑器里放个拉杆控件,让场景编辑人员自己去调整这个缩放因子到他们满意的值。
  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-08-18 20:06 编辑过


相关链接:
 


Locations of visitors to this page