游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1215|回复: 0

讨论贴:提出一种修正Compute Tangent错误的办法

[复制链接]

64

主题

855

帖子

856

积分

高级会员

Rank: 4

积分
856
QQ
发表于 2005-11-18 13:44:00 | 显示全部楼层 |阅读模式
前几天写了一片关于Compute Tangent算法缺陷的贴子,地址在:http://bbs.gameres.com/showthread.asp?threadid=41405,后来发现关于UV反向的问题可以解决,而三角形纹理坐标重合的问题却因为过于复杂而没有很好得到修正。

后来和朋友交流,有人提出可以用NVidia 的 MenshMender 类来修正这个问题,亲手试验了一下,发现这个办法不是很理想,有些面仍然有问题,而且NVidia为了解决问题,分裂出来了过多的顶点。

后来,我想到了一个修正办法,就是维持ComputeTangent的算法不变,而在Mesh的NormalMap层纹理坐标上进行修正,这个办法因为修改了NormalMap的贴图坐标,适用于关键要得到正确Per-Pixel光照而可以忽略NormalMap贴图方向的情况,比如NormalMap纹理表示的是一块平坦表面或者沙粒路面等没有大型可辨识凹凸图形的情况,比如通过NormalMap增加人脸肌肉凹凸细节的话就不能用此方法修正。

我们知道,Compute Tangent出错的原因之一,就是一个三角形所对应在UV空间中的图形是一条线或者是一个点,所以,我们修正的原理就是通过修改三角形3个顶点的UV值,使三角形在UV空间中能保证3个点不构成一条直线,或者3个点重合,仍然是一个三角形。所以,为了实现这个目标,我们可以通过一种Box的方式来进行纹理坐标映射,类似于CubeMap的纹理坐标映射。

具体算法如下:

首先要计算出整个Mesh的AABB包围盒,然后计算每一个三角形的面法线,假设一个坐标在原点的正方体(注意:不是AABB盒)包围了这个三角形,我们先求出面法线与正方体的哪个面相交,如果法线与正Y面相交(Positive Y),则我们可以通过该三角形的X、Z坐标进行纹理映射,X轴为+U坐标轴,-Z轴为+V坐标轴,同时通过AABB的X轴长度、Z轴长度及AABB的X最小值、Z最大值得到该三角形三个顶点的新UV坐标(NormalMap纹理的UV坐标),正方体另外5个面也依此原理计算。

注意:这个算法也需要分裂顶点,当计算出当前顶点的新UV的时候如果发线新UV已经计算过了,而且与这次算出来的新UV不一致,说明这个顶点被两个三角形共享,且纹理坐标不一致,需要分裂。

最后,用常规的ComputeTangent算法和修正过后的NormalMap纹理坐标即可得到正确的Tangent、Binormal。

这个修正当然还是有局限的,是对应于解决第三方模型的修正问题,如果要做到无错的模型,那么最好还是要用到专门制作NormalMap的工具、插件。大家有什么更好的解决方法不妨提出来一起交流吧。

附图如下:
sf_20051118134344.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 16:39

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表