Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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++ 3D图形网格法向量旋转加倍_C++_Matrix_Graphics_3d_Rotation - Fatal编程技术网

C++ 3D图形网格法向量旋转加倍

C++ 3D图形网格法向量旋转加倍,c++,matrix,graphics,3d,rotation,C++,Matrix,Graphics,3d,Rotation,我目前正在实现一个软件渲染器,它模拟OpenGL,作为基于的学习体验。我的项目代码可以是 我在处理顶点法线时遇到了一些困难。我想用模型矩阵对它们进行变换,我知道当矩阵不是正交矩阵时,我应该使用模型矩阵的逆转置。应在世界空间中指定灯光方向,因此应变换法线,然后使用世界空间灯光方向的点积计算灯光强度 这就是问题所在。它在这里工作得很好,注意相机在上轴旋转45度观看模型 如果我将模型在任意轴上旋转90度,现在取向上轴,灯光方向将翻转到另一个方向。正如你在这里看到的,光是从后面来的 如果我旋转180

我目前正在实现一个软件渲染器,它模拟OpenGL,作为基于的学习体验。我的项目代码可以是

我在处理顶点法线时遇到了一些困难。我想用模型矩阵对它们进行变换,我知道当矩阵不是正交矩阵时,我应该使用模型矩阵的逆转置。应在世界空间中指定灯光方向,因此应变换法线,然后使用世界空间灯光方向的点积计算灯光强度

这就是问题所在。它在这里工作得很好,注意相机在上轴旋转45度观看模型

如果我将模型在任意轴上旋转90度,现在取向上轴,灯光方向将翻转到另一个方向。正如你在这里看到的,光是从后面来的

如果我旋转180度,又会好起来

如果我旋转到45度,灯光将指向90度,如图所示。注意这些尖峰以查看光线来自何处

这让我困惑了好几个小时。我想不出怎么了。这就好像旋转在灯光下加倍。但光线的矢量没有改变,请看这里:

vec4 SmoothShader::Vertex(int iFace, int nthVert)
{
    vec3 vposition = model->vert(iFace, nthVert);
    vec4 projectionSpace = MVP * embed<4>(vposition);

    vec3 light = vec3(0, 0, 1);

    mat4 normTrans = M.invert_transpose();
    vec4 normal =  normTrans * embed<4>(model->normal(iFace, nthVert), 0.f);
    vec3 norm = proj<3>(normal);
    intensity[nthVert] = std::max(0.0f, norm.normalise() * light.normalise());

    return projectionSpace;
}

bool SmoothShader::Fragment(vec3 barycentric, vec3 &Colour)
{
    float pixelIntensity = intensity * barycentric;
    Colour = vec3(255, 122, 122) * pixelIntensity;
    return true;
}

知道我做错了什么吗?

你应该使用模型矩阵变换法线,而不是它的逆矩阵。照明的行为与此相同,因为您正在向顶点位置的相反方向旋转顶点法线

vec4 normal =  M * embed<4>(model->normal(iFace, nthVert), 0.f);
如果您使用了此方案,那么很明显您使用了错误的转换

mat4 object_from_world = world_from_object.invert_transpose();
vec4 normal_world = object_from_world * normal_object; // wrong!
我个人使用以下术语来描述不同的空间:

  • 对象空间–模型的局部坐标系
  • 视图空间–相机的局部坐标系
  • 灯光空间–灯光的局部坐标系
  • 世界空间–场景的全局坐标系
  • 剪辑空间–标准化屏幕坐标

因此,我将
MVP
矩阵称为
clip\u from\u object
矩阵。

将模型矩阵传递给着色器,如下所示:

                o->shader->M = cameraRotate * cameraTranslate * Model;

因此,实际的M矩阵不是模型矩阵,而是模型视图矩阵,也就是说,现在在模型视图空间中相乘。我不确定,但这可能会导致不明确的结果。

恐怕这不起作用,没有变化。在这种情况下,模型矩阵是正交的,所以它的逆转置实际上是一样的。然而,许多在线消息来源说,当进行非均匀缩放(非正交)时,例如,变换法线时需要反向转置。@Constantine抱歉。我误以为你是在用倒数乘。逆转置是有意义的。我再看看。@Constantine我看不出还有其他问题。我认为您的问题可能存在于代码库的其他地方。是的,这是来自github repo的,不是吗,它有点过时了。以上图像是在通过模型矩阵时拍摄的。谢谢你。
mat4 object_from_world = world_from_object.invert_transpose();
vec4 normal_world = object_from_world * normal_object; // wrong!
                o->shader->M = cameraRotate * cameraTranslate * Model;