Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Help calculating normlas on a mesh

Author
Message
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 25th Jun 2018 21:54
Ok, so I've come across an odd effect on the mesh normals on my landscape, where the lighting only works on one axis - so basically if you picture the light moving along the x axis hills far to either wide light correctly, but directly under neath do not light at all.

If you move it along the z axis, the lighting only works on one side of the light source, and stays dark on the other.

Has anyone got any idea how to calculate mesh normals? The following links seem to explain it, but not in AppGameKit terms - my best tranlsation doesn't work.

https://stackoverflow.com/questions/6656358/calculating-normals-in-a-triangle-mesh

https://stats.stackexchange.com/questions/70801/how-to-normalize-data-to-0-1-range
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 25th Jun 2018 22:22 Edited at: 25th Jun 2018 23:00
Sounds like your normals have an Z or X component only. How are they currently set? Either that or a shader being used isnt quite calculating the light result correctly??

On a terrain the normals should be fairly close to 0,1.0,0 (x,y,z) but obviously varying on the hills etc...

Ive a function for calculating the normals on an AppGameKit mesh in a memblock somewhere...i can dig it out if wanted.

Its basically a case of looping through your triangles...work out the normal for it (using cross product) and add that to each of the 3 vertices that make up the triangle . Then normalise the result in each vertex. Each triangle face then equally contributes to the vertex normal. It gives a result pretty identical to AGKs calculation of normals for terrain. Thats the correct way to do it for an arbitrary mesh.

Theres may be a quicker way as a terrain mesh always has 6 contributing triangles unless its right on the edge but unless your calculating normals every frame then it shouldn't be a problem to do set them once and just use them.
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 25th Jun 2018 23:14
Yeah, that's the exact principle that the website said, but it's not working no matter what I do. Wondering now if it's actually my shader......or some silly.little mistake. Could you dig it you?

It's not only the Y value you set, is it?
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 25th Jun 2018 23:22 Edited at: 27th Jun 2018 14:00
The normal has x,y and z components...on a flat section of terrain it will be 0,1.0,0 but it will vary depending on hills. i set all 3 components as they should be set.



Take a look at the GenerateHeightmapNormals() function, its somewhere in the code below. I can post a full example project showing how to use it if you wanted.

Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 25th Jun 2018 23:30
The is Benjisimo, that's awesome. Gonna take me a day or two to work it through, but I'll get there now I think.
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 25th Jun 2018 23:33
Actually I've literally just worked it out I think.....I assumed a flat terrain was 0,0,0..... not 0,1,0.....so for my Y height I need to add 1.0 in theory. That would potentily explain why it lights from only one side.....if I move the light source below the mesh it lights the other way.....my Y it at a 90 degree angle I think.
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 25th Jun 2018 23:33
Actually I've literally just worked it out I think.....I assumed a flat terrain was 0,0,0..... not 0,1,0.....so for my Y height I need to add 1.0 in theory. That would potentily explain why it lights from only one side.....if I move the light source below the mesh it lights the other way.....my Y it at a 90 degree angle I think.
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 25th Jun 2018 23:41
Cool....sounds like your position is being used for your normal?

The x,y,z positions can be 0,0,0 but the normal should be approx 0,1,0 so yes...you need to set the normals to point upwards on a flat terrain or correctly calculate them using the technique described above...
Phaelax
DBPro Master
20
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 27th Jun 2018 13:02
With each poly [ABC] (points listed clockwise), make two vectors; AB and AC (doesn't really matter). Now take the cross product of those two vector and you'll have a normal (well, after you normalize the result).

That will give you the blocky result you see in Ben's image. You'll then have to smooth out the averages to get a nice effect. There's plenty of examples buried in DBP threads. If you can't find anything or haven't figured it out yet, I'll try to find my old matrix code tonight.
Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 27th Jun 2018 13:38 Edited at: 27th Jun 2018 15:17
Quote: "With each poly [ABC] (points listed clockwise), make two vectors; AB and AC (doesn't really matter). Now take the cross product of those two vector and you'll have a normal (well, after you normalize the result).

That will give you the blocky result you see in Ben's image. You'll then have to smooth out the averages to get a nice effect. There's plenty of examples buried in DBP threads. If you can't find anything or haven't figured it out yet, I'll try to find my old matrix code tonight."


Sorry but your getting confused...

The image above was just for illustration as it was the only one I could find with normals shown on a terrain! Its not my image and was posted by someone else. It just happened to have flat shading used on it and its not something rendered in AGK.

The result you get from the methods described by santman and myself above ARE smooth results.

The algorithm adds the normal generated for a number of triangles to each vertex - then normalises (averages) the result. Typically a vertex in the middle of the mesh will be used by 6 triangles and they each equally contribute to the final normal value at the vertex.

... an actual example is shown here. If you use the function I posted you get smoothed normals as it takes into account all the triangles which use the vertex. The only way you get flat triangles in AppGameKit is if you duplicate vertices or used non indexed triangles and set all the normals to be equal for just one triangle.

So you can use the method i described or even use my own function and it works fine and gives a smooth result...like this


And.... which two vectors you use to calculate the normal does matter! - as it will reverse the normal if you choose the wrong ones.
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 27th Jun 2018 13:56 Edited at: 27th Jun 2018 15:18
Quick example.....

If you create your own terrain using a function or some maths and you dont generate normals for a terrain then the lighting ends up being flat and rubbish

The normals on the terrain below are all set to 0,1,0...

Its suprising how much affect lighting has on the appearance of curvature.


If they are set correctly using the correct method above which calculates the correct smoothed normal


Same 3d heightmap model in both versions and no shadows involved....just correct normals

Thats the code i posted above.
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 27th Jun 2018 20:22
Ok so I just tried that last code sample.....something's not quite right! Lol.

Attachments

Login to view attachments
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 27th Jun 2018 20:45
You have used an AppGameKit heightmap object and attempted to generate heightmap normals for that by the looks of it.

The order of indices is different as its actually a triangle strip...not indexed triangles.

Hence I wrote in the code
// The mesh must be an indexed triangle mesh - see alternate function for non indexed

The alternate function alternates normal directions for every other vertex as strips are wound differently. (Clockwise...anticlockwise, clockwise, anticlockwise..etc....)
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 27th Jun 2018 20:59
Yup, that's exactly what it is....but I can;t make head nor tail of what the second function is meant to do - this just stores the index values in an array??
puzzler2018
User Banned
Posted: 27th Jun 2018 21:00 Edited at: 27th Jun 2018 21:02
You know so much so great Bengismo - joined 2017 but unsure how long you really been programming in agk - this maybe 10 years...I take my hat off to you

It would be nice to know for my own sanity how long you have been programming in AppGameKit to achieve all your knowledge
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 27th Jun 2018 21:19
So I think the easiest thing might be to just abandon the AppGameKit height map and create a blank, empty mesh to work from and try that......
puzzler2018
User Banned
Posted: 27th Jun 2018 21:22
We dont know how the Createoobjectfromheightmap is generally engineered by Paul

So starting from a blank canvas maybe a good thing - cause we can have total control on everything thats going on with it

Ooops sorry for jibba jabbing
puzzler2018
User Banned
Posted: 27th Jun 2018 21:24
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 27th Jun 2018 21:25 Edited at: 27th Jun 2018 21:47
No...no sorry.....it was my mistake....

I thought id posted both versions of the function above but i hadnt!! DOH!

I created
CreateHeightmapNormals() for meshes id made myself (As i use triangle lists)
CreateHeightmapNormalsAlt() for AGK's heightmaps (as they use Triangle Strips)

So...if you use AGK's created heightmap objects (created with CreateObjectFromHeightMap()) then it creates a triangle strip in the mesh.

The function for creating normals for that is very similar but subtley different


I have literally lost track of all the functions i made for this

Ive functions for creating a terrain as a trianglestrip from an image or for creating a trangle list from an image etc.... Way too many to keep track of as I havent touched them myself for months
Theres one for making a terrain from a 16bit greyscale png somewhere too if more Y resolution is wanted
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 27th Jun 2018 21:53
Puzler wrote: "It would be nice to know for my own sanity how long you have been programming in AppGameKit "


I've had AppGameKit since november last year... just do muck about with it for fun.
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 27th Jun 2018 22:03
Bengismo.....you're an absolute genuius, works like a charm. I have literally spent hours and hours trying to sort that!

Attachments

Login to view attachments
puzzler2018
User Banned
Posted: 27th Jun 2018 22:07
Exactly.... But Why is he a Genious though - are you a hard games programmer for a company or something

Tell us a bit about yourself -- Where did you come from to learn this so quickly Bengismo!!!!!???
Phaelax
DBPro Master
20
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 29th Jun 2018 07:55 Edited at: 29th Jun 2018 08:00
Quote: "And.... which two vectors you use to calculate the normal does matter! - as it will reverse the normal if you choose the wrong ones."


I thought the normal only reversed if you reversed the order of the vertices?

I just wrote up a quick example to test it myself. Though it still really depends on the direction you form your vectors, I see what you were saying. I think maybe it was myself this time that didn't explain very well what I meant. Generally, I've just always relied on using AB and AC as my two vectors. BC in place of one of those would still give the same result. As long as the vectors created follow a clockwise pattern it'll be the same. But reversing one of them, like B to A instead, then you start flipping the normal.




lol, sounds like Ben has some fans. He might be somewhat new to AppGameKit but I'm sure he's used other languages before that.
Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 29th Jun 2018 09:05 Edited at: 29th Jun 2018 09:15
Phaelax wrote: "I thought the normal only reversed if you reversed the order of the vertices?"


In a triangle strip every second triangle has its vertices reversed. (Clockwise,anticlockwise,clockwise)



If its a heightmap made by AGK's CreateMeshFromHeightmap function then its a triangle strip.



Your right for a triangle LIST that you can just take consistant vector so AB and AC would be fine but thats only if its a list of triangles or non indexed triangles.

If its a strip and you just use consistent vectors then you end up with the problem santman had above where every other normal is reversed and the render looks patchy and not correct. ^^ That above is a good example of how it goes wrong.



I'm not clever at all....I make more mistakes than most people and i only know some things because I already tried them and got them really wrong myself.

There's a lot to be learned about 3D and mesh memblocks by just reading the OpenGL tutorials online which explain all of these sorts of issues much better than I ever could. Most of the algorithms for creating meshes and normals were written by others way before I used them.
Phaelax
DBPro Master
20
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 2nd Jul 2018 20:01
Wasn't familiar with "strips" like that. I've kinda always worked with a polygon soup (a list). Is this a newer way of building meshes? Or am I just that out of the loop?
Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
Santman
12
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 4th Jul 2018 21:45
Bengisimo, can you explain this?

Create a blank 256*256 bitmap, then use AppGameKit to create a terrain from it. The create a memblock from that object, and then try to create another object from that memblock - you'll get an error saying the indices must be divisible by 3 (there should be 65,536 vertices, 131,068 indices - which is 43,689.33 recurring). HOWEVER....we can save that memblock, reload it, and set the object mesh based on the memblock contents.

So my thought is...the terrain system has a bug that calcs the vertice count wrong, but memblocks don;t use the vertex or indice count to set a mesh??
puzzler2018
User Banned
Posted: 4th Jul 2018 22:03
Possibly investigate after heightmap generation by getting its indices value print(GetMemblockInt(obj ,4)) and see what its returning after creating the heightmap to see if its a bug or not.. Maybe there is more to heightmap memblock generations then we think

But im sure you have done this already

Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 4th Jul 2018 22:16 Edited at: 4th Jul 2018 22:31
Firstly....AGK only allows you to create objects from scratch using triangle LISTS....it does allow you to manipulate and update Triangle strip based objects

The difference between triangle strips and triangle lists

TRIANGLE LIST: If your image is 256 x 256 you get....
65536 Vertices
130050 Triangles
390150 Indices (Divide by 3 and you get the number triangles above)

TRIANGLE STRIP: If your image is 256 x 256 you get....
65536 Vertices
131066 Triangles
131068 Indices (in a strip the number triangles is always 2 less then the number of indices)

These numbers are correct and make sense looking at the geometry numbers

If you attempt to create a new object from a memblock with a triangle strip in it ....it says NOOOOO!

Its easy enough to just copy a Triangle strip object and then set the new values in this mesh via a memblock....You just cant create one from scratch though and have to go via the CreateObjectfromHeightmap function or copyObject etc...

Its no bug really...we are just meant to create Triangle Lists for brand new objects - theres nothing in the docs about allowing us to create strip based objects even though the heightmaps use them. It would be nice to create strips too but you can work around it fairly easy.

It might be a feature request for paul I guess.... but it never bothered me too much to complain.

EDITED to correct spelling...

Login to post a reply

Server time is: 2024-03-28 22:06:08
Your offset time is: 2024-03-28 22:06:08