Lazarus

Programming => Graphics and Multimedia => OpenGL => Topic started by: ranny on June 27, 2019, 09:03:23 pm

Title: Lighting moving with model and want it fixed position
Post by: ranny on June 27, 2019, 09:03:23 pm
Hi,

I was posting elsewhere in this forum on a clipboard problem and it was turning into a OpenGL discussion so I am starting a new subject here.

I am really new to OpenGl and have had some excellent advice on this forum.  But I have a little problem...

I am drawing a function that is displayed with quads with a colour gradient.  All is well until I go to add lighting.  When I add the lighting direction and type etc., the faces of the quads are lit, maybe not quite as I expected, but also as I rotate the model the lit faces move with the model when I want the direction of lighting to be fixed.  On advice from others I tried to ensure that lighting is fixed before any other transformations and is called only once, but it doesn't seem to make any difference.

Any advice please?
Title: Re: Lighting moving with model and want it fixed position
Post by: SymbolicFrank on June 27, 2019, 10:20:07 pm
How does your shader(s) look like and how do you supply the inputs (calculated value, point, gradient, texture)?
Title: Re: Lighting moving with model and want it fixed position
Post by: ChrisR on June 27, 2019, 11:55:56 pm
Here are two Lazarus OpenGL mesh viewers that have the light position relative to the viewer:
 https://github.com/neurolabusc/plyview
 https://github.com/neurolabusc/Metal-Demos/tree/master/mesh
They are very similar, but the latter can also be compiled for Metal on MacOS (and therefore you will have to use the package inspector to remove the Metal package when you load the project with Windows or Linux).

The shader is here
  https://github.com/neurolabusc/Metal-Demos/blob/master/mesh/Resources/shader/Phong.glsl
 Lighting uses the viewing direction (vV) and the surface normal:
    vV = -vec3(ModelViewMatrix*vec4(Vert,1.0))
    vN = normalize((NormalMatrix * vec4(Norm,1.0)).xyz);
Title: Re: Lighting moving with model and want it fixed position
Post by: ranny on June 28, 2019, 08:19:15 am
Thanks, I cannot get github on my works laptop and I am far from home at the moment but will look at the weekend.

I did say I was new to this (!) so this is what I do...

Make polygons in clockwise order, establish normals using dot product/cross product and normalise, use one colour for all polygons, do all this in one begin/end quad block.

Lighting is set in an initialisation procedure called once.

Rotations and translations carried out in a OpenGL.paint event.

Am I creating the normals in the wrong place?

See attached plot, I am trying to get a better distribution of colour from light to dark that is from a fixed light source.

Thanks for any help.   
Title: Re: Lighting moving with model and want it fixed position
Post by: wp on June 28, 2019, 10:16:23 am
Looks correct. But the devil hides in the details. For giving better help I ask you to provide a simple compilable project which shows the issue (*.pas, *.lfm, *.lpr and *.lpi files in a shared zip which you upload in section "Attachment and other options" of this site. No exe, ppi or other compiler-generated files in the zip, please).

Interestingly I have the same issue in my own 3d-chart project (https://github.com/wp-xyz/OpenGLChart). Because every data point sphere, but not the calculated surfece, behaves correctly with respect to lighting I think that the issue is somewhere related to calculation of normals.

As for the contrast between dark and light: Did you change the position of the light? Did you play with the properties of the light source and, if you don't use COLOR_MATERIAL, of the surface (ambient, diffuse, specular)?
Title: Re: Lighting moving with model and want it fixed position
Post by: ranny on June 28, 2019, 10:56:37 am
Well here goes!

I apolgise in advance for the state of the coding, its got pieces from everywhere stitched in and it doesn't use the best of routines for anything, but it does work in principle.  I have included a sample text file with data to plot and hopefully it will work.

Comments welcome... 

Update:-

Yes, I did play with the light direction and COLOR_MATERIAL but didn't see significant changes towards what I was looking for.
Title: Re: Lighting moving with model and want it fixed position
Post by: wp on June 28, 2019, 12:21:18 pm
Nice.

I found these issues:
Code: Pascal  [Select]
  1. var
  2.     v1,v2,v3,vn:TVector3_single;
  3.     vs1, vs2, vs3: TVector3_single;
  4.     vline:array[1..2] of TVector3_single;
  5. begin
  6.     ...
  7.  
  8.               v1.data[0]:=xp[i];
  9.               v1.data[1]:=yp[i,j];
  10.               v1.data[2]:=zp[j];
  11.               v2.data[0]:=xp[i];
  12.               v2.data[1]:=yp[i,j+1];
  13.               v2.data[2]:=zp[j+1];
  14.               v3.data[0]:=xp[i+1];
  15.               v3.data[1]:=yp[i+1,j];
  16.               v3.data[2]:=zp[j];
  17.  
  18.               WorldToScreen(v1.data[0], v1.data[1], v1.data[2], vs1.data[0], vs1.data[1], vs1.data[2]);
  19.               WorldToScreen(v2.data[0], v2.data[1], v2.data[2], vs2.data[0], vs2.data[1], vs2.data[2]);
  20.               WorldToScreen(v3.data[0], v3.data[1], v3.data[2], vs3.data[0], vs3.data[1], vs3.data[2]);
  21.  
  22.               vline[1]:=Vector_sub(vs2,vs1);
  23.               vline[2]:=Vector_sub(vs3,vs1);
  24.  
  25.               vn:=vector_crossproduct(vline[1],vline[2]);
  26.               vn:=vector_normalise(vn);
  27.               glNormal3f(-vn.data[0],-vn.data[1],-vn.data[2]);
  28.   ...
  29.  

A suggestion finally: When you do a glRotatef(-90, 1, 0, 0 before the first intruction to create the model, i.e. before "DrawFunc", then the entire view is rotated by 90 degrees around the x axis, and you end up in a coordinate system in which z points upward (and y into the screen) - therefore it is no longer required to exchange y and z in the OpenGL calls.
Title: Re: Lighting moving with model and want it fixed position
Post by: ranny on June 28, 2019, 01:20:51 pm
Thanks for the valuable comments.

Normals - Yes, when to calculate them was a thought of mine.  I have done some other basic 3D work before and the normals were actually calculated after transforms.  But does this mean they are calculated in the OnPaint event since this is where the WorldtoScreen conversion is carried out?  Also how should this work with display lists where they list is supposed to be generated once for all transforms?  I can give it a go and see what happens.

Update:- Hmm..  I wasn't thinking about that properly.  Does the WorldtoScreen not just normalise all the data for the screen in terms of the values being from 0-1?  Would this make a fundamental difference?  I'm trying a few things to see what the difference is.

I thought my normals were "pointing out" based on my previous programs but I will take account of your suggestions and review the difference.  My other 3D work had Z in the opposite direction to OpenGL so I can imagine it is not right as is.

Good advice on use of Tform1. I tried to learn Delphi many years ago and didn't really do any proper studying on it.  I just followed some snippets of code and managed to make them work, eventually.  My biggest adventure was a complete 2D CAD package that works pretty well with lots of features but I am scared to look back on it now because it will be a real mess with such issues in its 50,000 lines of code!

Arrays - Good advice, again I just did what worked in the past but know dynamic arrays are better.  Something I can implement in all my programs going forward.

Normally I can handle the maths and fundamental scope of such programs, but I am never very elegant in my coding or in employing best practice so thanks for the tips, I will get working on it.

In my work we have to create lots of curves and so next up is trying to accommodate parametric splines and Akima fits, good for sharp turns and reversals,  although they don't generate simple formulas for spreadsheets.


Update:-  Lighting being called many times - that was me fiddling with trying to get it to work and was on the cards to tidy up once I got it to work reasonably well

Update:-  Pyramids - Since the pyramids represent the actual data point, they lie precisely on the curve and I guess it is which gets drawn first, pyramid or curve surface.  The centre of the pyramid is the point so if it were a flat surface you should see a little pyramid above the surface and a frustrum below.  Sometimes the pyramid is inside the cube which means the calculated and actual points are the same
Title: Re: Lighting moving with model and want it fixed position
Post by: ranny on June 28, 2019, 01:45:04 pm
Ah!  I have just had a major thought....

What I was hoping to achieve was when the image is rotated it will "light" the image based on the light direction being fixed.  Before I attempted OpenGL I did all my own rotations and transforms then calculated the normals.  I did not get the result I wanted because it was assuming the object drawn was solid so if you "looked underneath" it was dark, same is happening in the OpenGl version.

Previously I had the normal being considered against the light source and if the normal was pointing directly to it, it was bright, 90 deg to is was dark, more than 90 was dark (or actually removed from view thinking it was solid).  Seeing the issue I just changed the light intensity to be from 0 to 90 got darker, 90 to 180 got brighter and then you could see the underside being lit.  Have a look at the two images attached showing rotation where you can see the underside.  In the OpenGL version looking at the underside is always dark and it makes me think this is the same sort of issue..... 
Title: Re: Lighting moving with model and want it fixed position
Post by: ranny on July 19, 2019, 11:11:31 am
Just a quick update, was unable to try some of the links that were provided, I am using 1.6.4 and  I think the code in the links is for later versions?  I have not installed a later version on my PC because when I did it once before, one of my programs would not compile and I have not got around to sorting it yet.

Thanks for the support.