OpenTK C# 透视光照看起来很麻烦
本文关键字:看起来 麻烦 透视 OpenTK | 更新日期: 2023-09-27 18:35:21
我的目标是使透视视图中的照明平滑。我对透视和正交使用相同的灯光设置。下图显示正交照明看起来很棒。透视照明看起来很毛刺,当我旋转它时会闪烁。我错过了什么才能使透视图照明看起来不错?
处理器: AMD FX 6100 6 核 3.31GHz
显卡: AMD Radeon HD 6800
注意:我引用了一个OpenGL示例。我正在尝试不同的灯光设置,以了解它们是如何工作的。我在这篇文章末尾粘贴的代码是创建图像的代码。
视角:https://i.stack.imgur.com/pSXul.png
正字法:https://i.stack.imgur.com/Q7Yr2.png
这是我的绘制方法中的相关代码。
private void glControl1_Paint(object sender, PaintEventArgs e)
{
if (!glLoaded)
return;
GL.Enable(EnableCap.DepthTest);
//GL.Enable(EnableCap.Blend);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
//SET PERSPECTIVE OR ORTHOGRAPHIC VIEW
if (chkPerspective.Checked)
{
double aspect = glControl1.Width / (double)glControl1.Height;
Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)aspect, 0.0001f, 5000.0f);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.LoadMatrix(ref perspective);
Matrix4 lookat = Matrix4.LookAt(eyeOffset.X, eyeOffset.Y, eyeOffset.Z, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);
//GL.Translate(-boxOffset);
}
else
{
setupViewPort(); //Orthographic settings
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
}
GL.Rotate(angleY, 1.0f, 0, 0);
GL.Rotate(angleX, 0, 1.0f, 0);
//LIGHTING
if (chkLighting.Checked)
{
float[] mat_specular = { 1.0f, 1.0f, 1.0f, 1.0f };
float[] mat_shininess = { 50.0f };
float[] light_position = { 1000.0f, 1000.0f, 1000.0f, 100.0f };
float[] light_ambient = { 0.5f, 0.5f, 0.5f, 1.0f };
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//GL.ShadeModel(ShadingModel.Smooth);
//GL.Material(MaterialFace.Front, MaterialParameter.Specular, mat_specular);
//GL.Material(MaterialFace.Front, MaterialParameter.Shininess, mat_shininess);
GL.Light(LightName.Light0, LightParameter.Position, light_position);
//GL.Light(LightName.Light0, LightParameter.Ambient, light_ambient);
//GL.Light(LightName.Light0, LightParameter.Diffuse, mat_specular);
GL.Enable(EnableCap.Lighting);
GL.Enable(EnableCap.Light0);
GL.Enable(EnableCap.ColorMaterial);
//GL.Enable(EnableCap.CullFace);
}
else
{
GL.Disable(EnableCap.Lighting);
GL.Disable(EnableCap.Light0);
}
foreach (Cube cube in cubes)
{
cube.drawCube(selectionCubeRadius);
}
glControl1.SwapBuffers();
}
这是我的正交视口代码,以防万一。
private void setupViewPort()
{
if (chkPerspective.Checked)
return;
int w = glControl1.Width;
int h = glControl1.Height;
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(-w, w, -h, h, -5000, 5000); // Bottom-left corner pixel has coordinate (0, 0)
GL.Viewport(0, 0, w, h); // Use all of the glControl paintingarea
}
仅根据图像,看起来深度测试被禁用或某些法线被翻转或非归一化。
drawCube到底是做什么的?
我找到了一个现在可以工作的解决方案。在透视视图中,我将立方体的大小从 200.0 减小到 5.0。然后我把相机移近,使它们看起来大小相同。有些人还说,当我创建透视视野时,我应该减小远 Z 平面。
减小模型的大小是有效的,但出于惯例目的,我也减少了远 z 平面的距离。我还可能会创建一个算法,根据我当前的模型大小和角度确定要使用的 z 平面距离。
用户"dflemstr"询问了我的GL。正常3f呼叫。答案是我没有。他们做什么,他们有必要吗?