游戏开发论坛

 找回密码
 立即注册
搜索
12
返回列表 发新帖
楼主: luckycrc

关于shader中像素的法向量的问题,求助

[复制链接]

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2008-4-22 00:48:00 | 显示全部楼层

Re:关于shader中像素的法向量的问题,求助

帮你在网上找了一个:
   
为任意网格的每个顶点计算切线空间的基向量


以下代码为一个任意网格计算每个顶点的切向量.要知道详细的数学推算,请跟贴。这段代码产生具有四个元素的切向量T(位于局部坐标系,w为第4元素,为标识使用左手还是右手坐标系),然后binormal 向量可以通过顶点法线N和T叉乘算出。
这段代码使用了Point2D, Vector3D, Point3D, Vector4D这几个类。

帮助理解:术语binormal(副法线)通常做为二次切线向量的替代名而被使用(此向量与面法线和切线为正交向量,可以共同组成一个切线坐标系,既切线空间)。这是一个不太适当的用词,副法线是二次切线向量而不是真的什么法线。术语binormal出现在曲线研究中。曲线只有一条切线,还有两条正交向量,就是normal和binormal。当讨论平面上一顶点的坐标系时,有一条法线,两条切线,这两条切线应叫主切线和二次切线。
就这样,有许多人错误的将bitangent叫成binormal,而且流行起来了。所以,一般在凹凸映射时为bitangent正名,使用它,而不是使用误叫的术语binormal.
代码如下:
#include "Vector4D.h"

//三角形结构,用于保存顶点索引。
struct Triangle
{
    unsigned short  index[3];
};

//计算切线。将其放入动态申请的内存中,注意有两条切线,一条为主切线,一条为二次切线。
//函数in值为顶点数vertexCount, 顶点信息数组vertex, 顶点法线数组,顶点纹理坐标数组,三角形数,
//三角形数组, 接收切线的数组指针。
void CalculateTangentArray(long vertexCount, const Point3D *vertex, const Vector3D *normal,
        const Point2D *texcoord, long triangleCount, const Triangle *triangle, Vector4D *tangent)
{

  //一个顶点对应两条切线,所以先在tan1中申请了2倍顶点数的3D向量空间。
//tan1为主切线存放地址起点
    Vector3D *tan1 = new Vector3D[vertexCount * 2];

  //tan2为二次切线存放地址起点
    Vector3D *tan2 = tan1 + vertexCount;

  //将两种切线存放空间清空先
    ClearMemory(tan1, vertexCount * sizeof(Vector3D) * 2);

    //对于每个三角形
    for (long a = 0; a < triangleCount; a++)
    {

      //获取第a个三角形的三个顶点索引 i1, i2, i3。
        long i1 = triangle->index[0];
        long i2 = triangle->index[1];
        long i3 = triangle->index[2];

        //通过顶点索引获取3个真实顶点的位置信息。
        const Point3D& v1 = vertex[i1];
        const Point3D& v2 = vertex[i2];
        const Point3D& v3 = vertex[i3];

        //获取顶点的纹理坐标信息。
    const Point2D& w1 = texcoord[i1];
        const Point2D& w2 = texcoord[i2];
        const Point2D& w3 = texcoord[i3];
        
        //然后根据算法得切线数据
    float x1 = v2.x - v1.x;
        float x2 = v3.x - v1.x;
        float y1 = v2.y - v1.y;
        float y2 = v3.y - v1.y;
        float z1 = v2.z - v1.z;
        float z2 = v3.z - v1.z;
        
        float s1 = w2.x - w1.x;
        float s2 = w3.x - w1.x;
        float t1 = w2.y - w1.y;
        float t2 = w3.y - w1.y;
        
        float r = 1.0F / (s1 * t2 - s2 * t1);

        Vector3D sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);

        Vector3D tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

        //将计算的第a个面的3个顶点的主切线保存
    tan1[i1] += sdir;
        tan1[i2] += sdir;
        tan1[i3] += sdir;
        
      //将计算的第a个面的3个顶点的二次切线保存
    tan2[i1] += tdir;
        tan2[i2] += tdir;
        tan2[i3] += tdir;
        
      //求下一个
        triangle++;
    }
   
    for (long a = 0; a < vertexCount; a++)
    {
        const Vector3D& n = normal[a];
        const Vector3D& t = tan1[a];
        
      
        // Gram-Schmidt orthogonalize
        tangent[a] = (t - n * Dot(n, t)).Normalize();
        
        // 计算使用左手系还是右手系,情况保存在w元素中。
    tangent[a].w = (Dot(Cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
    }
   
    delete[] tan1;
}
此信息来自〖软工吧论坛http://www.gcs8.cn〗
查看原网址:http://www.gcs8.cn/htm_data/42/0710/10374.html

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2008-4-22 00:49:00 | 显示全部楼层

Re:关于shader中像素的法向量的问题,求助

可能需要自己改一下,源代码中有些错误.

2

主题

15

帖子

15

积分

新手上路

Rank: 1

积分
15
 楼主| 发表于 2008-4-22 09:17:00 | 显示全部楼层

Re:关于shader中像素的法向量的问题,求助

感谢楼上的连续这么多天对我的帮助。

简单的设一个板子用手代了一下以上的公式,四个顶点两个面,顶点位置z值为0,x、y分别为(0,0)(1,0)(0,1)(1,1),纹理坐标同xy值,两个三角形的切线都是(1,0,0)。

其实上面的东西没有当作源代码来看,因为使用的类型不一样嘛,看懂算法自己写代码就OK了。

再次感谢一下楼上的
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-22 17:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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