Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL法线映射问题-法线可能朝向错误方向?_C++_Opengl_Glsl_Normals - Fatal编程技术网

C++ OpenGL法线映射问题-法线可能朝向错误方向?

C++ OpenGL法线映射问题-法线可能朝向错误方向?,c++,opengl,glsl,normals,C++,Opengl,Glsl,Normals,我目前正在开发我的第一个基于OpenGL的游戏引擎。我需要法线映射作为一个功能,但它不能正常工作 瑕疵受灯光和曲面上法线之间的角度影响。相机的移动不会以任何方式影响它。我还(至少现在)采用了效率较低的方法,从法线贴图中提取的法线将转换为视图空间,而不是将所有内容转换为切线空间 以下是我的相关代码: 生成切线和双切线 for(int k=0;k<(int)mb->getIndexCount();k+=3) { unsigned

我目前正在开发我的第一个基于OpenGL的游戏引擎。我需要法线映射作为一个功能,但它不能正常工作

瑕疵受灯光和曲面上法线之间的角度影响。相机的移动不会以任何方式影响它。我还(至少现在)采用了效率较低的方法,从法线贴图中提取的法线将转换为视图空间,而不是将所有内容转换为切线空间

以下是我的相关代码:

生成切线和双切线

        for(int k=0;k<(int)mb->getIndexCount();k+=3)
        {
            unsigned int i1 = mb->getIndex(k);
            unsigned int i2 = mb->getIndex(k+1);
            unsigned int i3 = mb->getIndex(k+2);

            JGE_v3f v0 = mb->getVertexPosition(i1);
            JGE_v3f v1 = mb->getVertexPosition(i2);
            JGE_v3f v2 = mb->getVertexPosition(i3);

            JGE_v2f uv0 = mb->getVertexUV(i1);
            JGE_v2f uv1 = mb->getVertexUV(i2);
            JGE_v2f uv2 = mb->getVertexUV(i3);

            JGE_v3f deltaPos1 = v1-v0;
            JGE_v3f deltaPos2 = v2-v0;
            JGE_v2f deltaUV1 = uv1-uv0;
            JGE_v2f deltaUV2 = uv2-uv0;

            float ur = deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x;

            if(ur != 0)
            {
                float r = 1.0 / ur;

                JGE_v3f tangent;
                JGE_v3f bitangent;

                tangent = ((deltaPos1 * deltaUV2.y) - (deltaPos2 * deltaUV1.y)) * r;
                tangent.normalize();

                bitangent = ((deltaPos1 * -deltaUV2.x) + (deltaPos2 * deltaUV1.x)) * r;
                bitangent.normalize();

                tans[i1] += tangent;
                tans[i2] += tangent;
                tans[i3] += tangent;
                btans[i1] += bitangent;
                btans[i2] += bitangent;
                btans[i3] += bitangent;
            }
        }
最后,在这里,我使用法线贴图中的采样法线,并尝试将其转换为片段着色器中的视图空间

fnormal = normalize(nmapcolor.xyz * 2.0 - 1.0);
fnormal = normalize(tmTBN * fnormal);
“nmapcolor”是法线贴图中的采样颜色。 “fnormal”然后在照明计算中像normal一样使用

我一直在试图解决这个问题这么长时间,但绝对不知道如何让这个工作。任何帮助都将不胜感激

编辑-我稍微修改了代码以在世界空间中工作并输出结果。大平台没有法线映射(并且工作正常),而小平台有法线映射。


我添加了法线所面对的方向。它们通常应该是相同的颜色,但它们明显不同。mTBN矩阵似乎没有正确地将切线空间法线转换为世界(和正常视图)空间。

嗯。。。我解决了这个问题。结果证明我的法线映射实现是完美的。问题其实出在我的纹理课上。当然,这是我第一次编写OpenGL渲染引擎,我没有意识到纹理类中的unlock()函数将我的所有纹理保存为GL_SRGB_ALPHA,包括法线贴图。只有漫反射贴图纹理应为GL_SRGB_ALPHA。临时强制所有纹理作为GL_RGBA加载修复了该问题。
真不敢相信我有这个问题已经11个月了,结果却发现它太小了。

这可能是个愚蠢的问题,但是你应该在顶点着色器中通过
mVW
转换
t正常的
吗?尝试这样做并不能解决问题。我认为
mNormal
会解决这个问题,因为它是mVW的逆转置。尝试反转
nmapcolor.y=1-nmapcolor.y
,也许你在某个地方混合了y轴向上与向下的约定。这最终会将法线更改为指向相反方向,但方向不正确/
fnormal = normalize(nmapcolor.xyz * 2.0 - 1.0);
fnormal = normalize(tmTBN * fnormal);