Opengl 光照适用于模型的顶部、底部、正面、背面,但不适用于模型的侧面
Opengl lighting works top,bottom,front, back but not on the sides of the model
我有一个由五个立方体组成的模型,整个模型都有纹理,我添加了灯光,它对立方体的顶部、底部、字体和背面都有效,但对侧面无效,还有一个阴影问题,因为在应该遮蔽的地方有光。
为此,我正在使用基于 Tao 框架的 Matlab .NET opengl 包装器,我承认这是不寻常的。
如果需要,我可以提供完整的代码,但现在,这是我的照明代码
%% Lighting
% Enable Light
Gl.glEnable(Gl.GL_LIGHTING);
% Vector for light position (directional light - try a positional one)
% Get Projection matrix in array of length 16
projmatrix = NET.createArray('System.Single', 16);
Gl.glGetFloatv(Gl.GL_PROJECTION_MATRIX,projmatrix);
% Reshape to 4x4 matrix
projmatrix=reshape(double(projmatrix),[4 4]);
% Use the inverse projection matrix to get the light fixed with the camera
LightPosCam=(projmatrix)\[0.3 0.5 -0.6 0]';
LightPos= NET.convertArray(LightPosCam, 'System.Single', 4);
Ambient = NET.convertArray([0.000001 0.000001 0.000001 .1],
'System.Single', 4);
Diffuse= NET.convertArray([0.7 0.7 0.7 1], 'System.Single', 4);
Specular= NET.convertArray([0.6 0.6 0.6 1], 'System.Single', 4);
% Turn on Lighting
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_POSITION,LightPos);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_AMBIENT,Ambient);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_DIFFUSE,Diffuse);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_SPECULAR,Specular);
% Constant attenuation (for distance, etc.)
% Only works for fixed light locations! Otherwise disabled
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_CONSTANT_ATTENUATION, 1.0);
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_LINEAR_ATTENUATION, 0.0);
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_QUADRATIC_ATTENUATION, 0.0);
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_LOCAL_VIEWER, Gl.GL_TRUE);
% Normalize vectors
Gl.glEnable(Gl.GL_NORMALIZE);
% Enable ColorMaterial
% Gl.glEnable (Gl.GL_COLOR_MATERIAL ) ;
% Set the Material Properties
floor_ambient = NET.convertArray([0, 0, 0, 0 ], 'System.Single', 4);
floor_diffuse = NET.convertArray([0.8, 0.8, 0.8, 1.0 ], 'System.Single', 4);
floor_specular= NET.convertArray([0.7,0.7,0.7, 1 ], 'System.Single', 4);
floor_emission= NET.convertArray([0.2,0.0,0.0, 1 ], 'System.Single', 4);
floor_shininess = 120;
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, floor_ambient);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, floor_diffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, floor_specular);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, floor_shininess);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, floor_emission);
% Gourang shanding
Gl.glShadeModel(Gl.GL_SMOOTH);
% Specular color enable
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_COLOR_CONTROL,
Gl.GL_SEPARATE_SPECULAR_COLOR);
% Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE,
Gl.GL_MODULATE);
% Gl.glEnable(Gl.GL_BLEND);
这里是我的代码,只有一个立方体
%% Draw Sats
% Select our texture
Gl.glEnable(Gl.GL_NORMALIZE)
% Bottom Face
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID8); %%Metalic Texture
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));
% Top Face
Gl.glEnd()
Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID3); %%Glyph1 Texture
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
Gl.glEnd()
% Front Face
Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));
% Back Face
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
% Right Face
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));
% Left Face
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
Gl.glEnd()
我发现有两个潜在问题:
如果您只是左右脸有问题,可能只是您不小心翻转了它们的表面法线。我会试试这个:
Gl.glNormal3f(1,0,0); % For all of the right face vertices
Gl.glNormal3f(-1,0,0); % For all of the left face vertices
当表面法线指向错误的方向时(即 进入 你的立方体),这意味着多边形的背面朝外。当您调用 Gl.glMaterialfv
时,您指定 Gl.GL_FRONT
而不是 Gl.GL_FRONT_AND_BACK
,这意味着背面没有被点亮。我猜这就是为什么您看不到侧面应用照明的原因。
我不知道你的顶点顺序是否重要,这样当从立方体的外面看时,它们应该始终以围绕面的顺时针或逆时针顺序指定.由于我不知道您的 cornersx
、cornersy
或 cornersz
数据是什么样的,因此我无法判断您将它们定义为顺时针还是逆时针。 但是,我可以告诉你,你的一张脸的顺时针顺序与其余的不同:左脸,顶点顺序为3 -> 1 -> 5 -> 7
。我对您的照明框架了解不多,无法说明这是否会成为问题,但为了保持一致性,您可能希望改为按 1 -> 3 -> 7 -> 5
的顺序定义左脸的顶点。
我有一个由五个立方体组成的模型,整个模型都有纹理,我添加了灯光,它对立方体的顶部、底部、字体和背面都有效,但对侧面无效,还有一个阴影问题,因为在应该遮蔽的地方有光。 为此,我正在使用基于 Tao 框架的 Matlab .NET opengl 包装器,我承认这是不寻常的。
如果需要,我可以提供完整的代码,但现在,这是我的照明代码
%% Lighting
% Enable Light
Gl.glEnable(Gl.GL_LIGHTING);
% Vector for light position (directional light - try a positional one)
% Get Projection matrix in array of length 16
projmatrix = NET.createArray('System.Single', 16);
Gl.glGetFloatv(Gl.GL_PROJECTION_MATRIX,projmatrix);
% Reshape to 4x4 matrix
projmatrix=reshape(double(projmatrix),[4 4]);
% Use the inverse projection matrix to get the light fixed with the camera
LightPosCam=(projmatrix)\[0.3 0.5 -0.6 0]';
LightPos= NET.convertArray(LightPosCam, 'System.Single', 4);
Ambient = NET.convertArray([0.000001 0.000001 0.000001 .1],
'System.Single', 4);
Diffuse= NET.convertArray([0.7 0.7 0.7 1], 'System.Single', 4);
Specular= NET.convertArray([0.6 0.6 0.6 1], 'System.Single', 4);
% Turn on Lighting
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_POSITION,LightPos);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_AMBIENT,Ambient);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_DIFFUSE,Diffuse);
Gl.glLightfv(Gl.GL_LIGHT0,Gl.GL_SPECULAR,Specular);
% Constant attenuation (for distance, etc.)
% Only works for fixed light locations! Otherwise disabled
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_CONSTANT_ATTENUATION, 1.0);
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_LINEAR_ATTENUATION, 0.0);
Gl.glLightf(Gl.GL_LIGHT0, Gl.GL_QUADRATIC_ATTENUATION, 0.0);
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_LOCAL_VIEWER, Gl.GL_TRUE);
% Normalize vectors
Gl.glEnable(Gl.GL_NORMALIZE);
% Enable ColorMaterial
% Gl.glEnable (Gl.GL_COLOR_MATERIAL ) ;
% Set the Material Properties
floor_ambient = NET.convertArray([0, 0, 0, 0 ], 'System.Single', 4);
floor_diffuse = NET.convertArray([0.8, 0.8, 0.8, 1.0 ], 'System.Single', 4);
floor_specular= NET.convertArray([0.7,0.7,0.7, 1 ], 'System.Single', 4);
floor_emission= NET.convertArray([0.2,0.0,0.0, 1 ], 'System.Single', 4);
floor_shininess = 120;
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, floor_ambient);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, floor_diffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, floor_specular);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, floor_shininess);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, floor_emission);
% Gourang shanding
Gl.glShadeModel(Gl.GL_SMOOTH);
% Specular color enable
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_COLOR_CONTROL,
Gl.GL_SEPARATE_SPECULAR_COLOR);
% Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE,
Gl.GL_MODULATE);
% Gl.glEnable(Gl.GL_BLEND);
这里是我的代码,只有一个立方体
%% Draw Sats
% Select our texture
Gl.glEnable(Gl.GL_NORMALIZE)
% Bottom Face
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID8); %%Metalic Texture
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));
Gl.glNormal3f(0,0,-1);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));
% Top Face
Gl.glEnd()
Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID3); %%Glyph1 Texture
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));
Gl.glNormal3f(0,0,1);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
Gl.glEnd()
% Front Face
Gl.glBindTexture(Gl.GL_TEXTURE_2D, data.TextureID);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));
Gl.glNormal3f(0,-1,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));
% Back Face
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));
Gl.glNormal3f(0,1,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
% Right Face
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(4), cornersy(4), cornersz(4));
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(2), cornersy(2), cornersz(2));
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(6), cornersy(6), cornersz(6));
Gl.glNormal3f(-1,0,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(8), cornersy(8), cornersz(8));
% Left Face
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(0,0);
Gl.glVertex3f(cornersx(3), cornersy(3), cornersz(3));
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(1,0);
Gl.glVertex3f(cornersx(1), cornersy(1), cornersz(1));
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(1,1);
Gl.glVertex3f(cornersx(5), cornersy(5), cornersz(5));
Gl.glNormal3f(1,0,0);
Gl.glTexCoord2f(0,1);
Gl.glVertex3f(cornersx(7), cornersy(7), cornersz(7));
Gl.glEnd()
我发现有两个潜在问题:
如果您只是左右脸有问题,可能只是您不小心翻转了它们的表面法线。我会试试这个:
Gl.glNormal3f(1,0,0); % For all of the right face vertices Gl.glNormal3f(-1,0,0); % For all of the left face vertices
当表面法线指向错误的方向时(即 进入 你的立方体),这意味着多边形的背面朝外。当您调用
Gl.glMaterialfv
时,您指定Gl.GL_FRONT
而不是Gl.GL_FRONT_AND_BACK
,这意味着背面没有被点亮。我猜这就是为什么您看不到侧面应用照明的原因。我不知道你的顶点顺序是否重要,这样当从立方体的外面看时,它们应该始终以围绕面的顺时针或逆时针顺序指定.由于我不知道您的
cornersx
、cornersy
或cornersz
数据是什么样的,因此我无法判断您将它们定义为顺时针还是逆时针。 但是,我可以告诉你,你的一张脸的顺时针顺序与其余的不同:左脸,顶点顺序为3 -> 1 -> 5 -> 7
。我对您的照明框架了解不多,无法说明这是否会成为问题,但为了保持一致性,您可能希望改为按1 -> 3 -> 7 -> 5
的顺序定义左脸的顶点。