Освещение OpenGL работает сверху, снизу, спереди, сзади, но не по бокам модели.

У меня есть модель, состоящая из пяти кубов, вся модель текстурирована, я добавил освещение, и оно как бы работает для верха, низа, шрифта и задней части кубов, но не по бокам, также есть проблема с затенением, потому что есть свет там, где он должен быть затенен. Я использую для этого оболочку Matlab .NET opengl, основанную на платформе Tao, что, как я признаю, необычно.

Я могу предоставить весь код, если спросят, но пока вот мой код освещения

%% 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()

Наконец-то картинка моей модели и проблема в действии.


person Alla    schedule 21.06.2017    source источник


Ответы (1)


Я вижу две потенциальные проблемы:

  1. Если у вас возникли проблемы только с правой и левой гранями, возможно, вы просто случайно перевернули нормали их поверхностей. Я бы попробовал это:

    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, что означает, что задние грани не подсвечиваются. Я предполагаю, что именно поэтому вы не видите освещения по бокам.

  2. Я не знаю навскидку, имеет ли значение порядок ваших вершин, так что они всегда должны указываться либо по часовой стрелке, либо против часовой стрелки вокруг грани, если смотреть снаружи куба. Поскольку я не знаю, как выглядят ваши данные cornersx, cornersy или cornersz, я не могу сказать, определяете ли вы их как по часовой стрелке или против часовой стрелки. Однако я могу сказать вам, что одна из ваших граней определена с другим порядком по часовой стрелке, чем остальные: левая грань с вершинами, упорядоченными как 3 -> 1 -> 5 -> 7. Я недостаточно знаю о вашей структуре освещения, чтобы сказать, будет ли это проблемой, но для согласованности вы можете вместо этого определить вершины левой грани в порядке 1 -> 3 -> 7 -> 5.

person gnovice    schedule 21.06.2017
comment
Большое спасибо, gnovice, первое предложение помогло, это странно, потому что я использовал тот же код раньше, и он отлично работал со сплошными цветами, добавление текстур вызвало у меня всевозможные проблемы. Если я могу занять больше вашего времени и спросить вас о затенении, теперь, когда освещение работает, я все еще получаю освещение, например, на той стороне куба сзади, которая должна быть затенена. вот картинка: imgur.com/fNCQmRQ - person Alla; 21.06.2017
comment
@Alla: Ты путаешь затенение с тенями. Затенение, которое вы используете, например, когда вы вызываете Gl.glShadeModel(Gl.GL_SMOOTH);, управляет тем, как освещение применяется к поверхности, создавая эффекты затенения на основе освещения и свойств поверхности. отображение теней гораздо сложнее. - person gnovice; 21.06.2017
comment
Спасибо, grovince, я действительно перепутал их, похоже, отображение теней довольно сложно, поэтому мне потребуется некоторое время, чтобы его понять. Если вы не возражаете, что я выслушаю ваше мнение о чем-то другом, какую среду/настройку вы бы назвали наиболее оптимальной для того, кто работает над созданием модели, а затем имитирует выходной сигнал датчика LIDAR указанной модели, т. е. глубину по времени полета? - person Alla; 23.06.2017
comment
@Alla: Честно говоря, я не знаю лучшую среду или инструменты для обработки LiDAR. Я никогда этого не делал. Я полагаю, что Обмен файлами MathWorks может быть хорошее место для начала. - person gnovice; 23.06.2017
comment
@grovice: Спасибо за вашу ценную помощь. - person Alla; 26.06.2017