我目前正在实现一个基于these lessons的模拟OpenGL作为学习体验的软件渲染器。我的项目代码可以是found here.3D图形网格法向量旋转加倍
我在处理顶点法线方面遇到了一些困难。我想用模型矩阵对它们进行变换,我知道当矩阵不正交时应该使用模型矩阵的逆转置。光的方向应该在世界空间中指定,因此应该转换法线,然后用世界空间光方向的点积来计算光强。
虽然这是个问题。它在这里工作得很好,请注意相机在向上旋转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;
}
的MVP(模型,视图投影)和M(模式)矩阵计算如下:
// Model Matrix, converts to world space
mat4 scale = MakeScale(o->scale);
mat4 translate = MakeTranslate(o->position);
mat4 rotate = MakeRotate(o->rotation);
// Move objects backward from the camera's position
mat4 cameraTranslate = MakeTranslate(vec3(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z));
// Get the camera's rotated basis vectors to rotate everything to camera space.
vec3 Forward;
vec3 Right;
vec3 Up;
GetAxesFromRotation(cameraRotation, Forward, Right, Up);
mat4 cameraRotate = MakeLookAt(Forward, Up);
// Convert from camera space to perspective projection space
mat4 projection = MakePerspective(surf->w, surf->h, 1, 10, cameraFOV);
// Convert from projection space (-1, 1) to viewport space
mat4 viewport = MakeViewport(surf->w, surf->h);
mat4 M = translate * rotate * scale;
mat4 MVP = viewport * projection * cameraRotate * cameraTranslate * M;
任何想法我做错了?
恐怕这不起作用,没有任何改变。模型矩阵在这种情况下是正交的,所以它的逆转换实际上是同样的事情。尽管许多在线资源都表示,当进行非均匀缩放(非正交)时,例如在转换法线时需要逆转置。 – Constan7ine
@ Constan7ine对不起。我错误地认为你正在乘以逆。逆转置是有意义的。我会再看一次。 –
@ Constan7ine我看不到任何其他问题。我认为你的问题可能在于你的代码库中的其他地方。 –