• normalMap的七七八八


    关于normalMap,主要是要谈谈tangent space,可以自行生成,或者从3dmax里取。

    我是这样想的,当检查到mesh的material使用了normalMap,那么mesh就会导出tangent和binormal。

    通过2天不停得试验和翻阅文档,有几点认知是需要明确指出:

    1.  tangent变换并不是正交变换,大部分情况下顶点normal和三角形表面是不垂直的,tangent和binormal也未互相必垂直。不考虑镜像映射的话还只是误差,镜像映射之后干脆连方向都反了。

    2.  如上述,一般的说法,在vertex buffer中只存tangent,而在vertex shader中使用cross(tangent, normal)计算出binormal是不正确的。

    3.  美术可能只画半张脸的normalMap,而另一半使用mirror出来。这种情况,使用cross出binormal的效果,就会原本凹的凸,凸的变凹。

     

    4.  还有一种说法,是重新计算比如tangent在平面上的投影,也就是Gram-Schmidt orthogonalize,但我的结论是在max中不需要这么做。

    5.  直接取max给的tangent和binormal是绝对不行的,那会变成这样,见下图: 

     

    左边是ogre自动生成的tangent,右边是直接取max的tangent不作处理,两者的binormal都是cross出来的,两者中间的镜像都是不正确的。

     

    结论是:

    1.  必须是源生tangent, binormal,指望只存1个,用cross出来另一个是想法是错误的。

    2.  要处理镜像,不单是tangent,连binormal都可能反向。

    关键代码如下:

    if (hasTangent)
    {
        int tangentIndex = mesh->GetFaceVertexTangentBinormal(face->meshFaceIndex, vertexIdx, tangentChannel);
        vertex.tangent 
    = mesh->GetTangent(tangentIndex, tangentChannel);
        vertex.binormal 
    = mesh->GetBinormal(tangentIndex, tangentChannel);

        if (vertex.binormal % CrossProd(vertex.normal, vertex.tangent) < 0)
            vertex.tangent 
    *= -1.0f;

        if (vertex.tangent % CrossProd(vertex.normal, vertex.binormal) < 0)
            vertex.binormal 
    *= -1.0f;


    这是处理后的NdotL图:

     

    注意这个地方:

     

    如果不处理则会凹凸相反。

    最终的渲染效果:

     

  • 相关阅读:
    <置顶>Eclipse和myeclipse常用快捷键-操作-设置
    Eclipse : Loading descriptor for ...错误解决
    ORA-00937: 不是单组分组函数
    An error has occurred,See error log for more details 错误解决办法
    [Error Code: 942, SQL State: 42000] ORA-00942: 表或视图不存在
    ORA-00001: 违反唯一约束条件
    eclipse 出现user operation is waiting
    [空格][空白][特殊]字符/文字
    powerdesigner16.5安装教程及破解步骤
    mybatis遇到日期类型数据时String到date的转化
  • 原文地址:https://www.cnblogs.com/oiramario/p/1985184.html
Copyright © 2020-2023  润新知