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 Studio Chat / 3d plane mesh created from memblock is colored pink

Author
Message
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 15th Nov 2019 18:51
I created a plane mesh with the diamond-square algorithm. The mesh is created correctly but the light doesn't look right on it and also the color is all pink, even though I assigned colors to the vertices in the memblock based on the Y value of the vertex.

I didn't know how to setup nx, ny, nz (normals) on the memblock so I just set them all to (0, 1, 0) which allows me to see the mesh...

Do I need to get into Shaders or something to make my plane look like a low-poly mesh where the surface normals are pointing outward from the surface perpendicularly to give the plane mesh a low poly look.

Please help! Not sure how active these forms are.

Attachments

Login to view attachments
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 15th Nov 2019 20:30
Okay, figured out the coloring problem. I had 0x101010FF as the color (I saw the FF somewhere and thought it was needed) so I removed the FF at the end and now have valid colors.

My question now is, how do I make the mesh cast receive shadows or look like a low poly terrain. Below does not look like I want.

Attachments

Login to view attachments
Santman
8
Years of Service
User Offline
Joined: 15th Sep 2011
Location: Inverness
Posted: 15th Nov 2019 20:45
Normals are the issue. What you've done is essentially tell the shader the entire surface is dead flat. Changing mesh vertices heights wont set the normals correctly.

Someone shared an algorithm with me before to auto calculate normals, but not sure it will work on your mesh.
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 15th Nov 2019 20:55
Can you explain vertex normals? A vertex makes sense, a X, Y, Z position in space. The normal in the memblock also has an X, Y, Z... how does that work? It seems like you'd only have one "normal X,Y,Z position" for each triangle and it would be in the center of the triangle pushed forward outwards. Having x,y,z normals for every vertex is confusing me.
janbo
11
Years of Service
User Offline
Joined: 10th Nov 2008
Location: Germany
Posted: 15th Nov 2019 22:25 Edited at: 15th Nov 2019 22:37
How did you create your plane mesh ?
All by yourself or by using the CreateObjectFromHeightMap() command ?

To get hard edges(the low poly look) you need to create a mesh without indices/triangles which share vertices.
Each vertex needs to have their own normal data.
OR you use a shader I made some time ago: Flat shading

You can calculate the normal of Vertex A by calculating the cross product of the Vectors between the triangle edge B-A and C-A.
There are vector commands for that.

If you did it by yourself i.e creating a mesh with the right size, setting the vertex count, index count etc, adding vertex attributes and vertex and index data then...
did you add the vertex data manually or with for example SetMeshMemblockVertexColor() ?
Because the color attribute is a little bit different than the others(normalize flag and maybe its AGBR not sure)
To make some self advertising If you got my shader pack you also have the code to generate Softnormals and Hard edges as a byproduct
Bengismo
2
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 16th Nov 2019 00:11 Edited at: 16th Nov 2019 01:24
Santman and Janbo are completely correct and have given great answers above.

in order for it to look right you need correct normals. You are right that the normal is just a direction outwards from the face of every triangle. You will have to set them for the lighting to look correct.

Janbo is (of course) correct when he says you cannot share vertices with flat shading and the normal is then the same for all 3 vertices on the triangle

A couple of examples

Each triangle on the left has the same normal for each of its 3 vertices which is directly away from the triangles surface.
You cant share vertices between triangles using this method..(well unless two adjacent triangles just happen to have the same normals)


On the right is an alternative solution where you calculate the normal for a whole square of your terrain and set the normal across all of the 4 vertices which gives a nice retro look too and allows you to share 2 of the vertices.

No matter what you choose you will need to set the normals which means getting the cross product of any of the two sides of each triangle and ensuring that you have enough vertices in your memblock to store all the unique positions and normals.


You make the mesh cast and receive shadows with SetObjectCastShadow( objID, 1 ) and SetObjectReceiveShadow( objID, 1 )....also set your shadow mapping mode too.

EDITED: to correct image link
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 16th Nov 2019 00:25
I'm making the plane using the memblock to mesh function.

This is what I worked up:



From that I wrote:



Then with that array of Triangles3D, I do this:





Any help on how to get those nx,ny,nz values? Or am I doing this all wrong? I just started apk two days ago and haven't been through all the guides and docs.


(Also that shader pack looks bad ass. I'm want to buy it. Does it work with AppGameKit Studio? I don't have "Classic" -- not sure what the difference is.

Attachments

Login to view attachments
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 16th Nov 2019 03:56
The image on the right is the one I am going for. Cool thanks.

I'm now making progress so that's good. Thanks!

One thing I didn't really understand is "shared vertices". You said no shared vertices but are they not shared where the triangles connect to each other?
janbo
11
Years of Service
User Offline
Joined: 10th Nov 2008
Location: Germany
Posted: 16th Nov 2019 11:17 Edited at: 16th Nov 2019 13:34
Quote: "Does it work with AppGameKit Studio?"

In the App Shader Kit thread there was someone who asked the same.
Do you mind if I just refer to my answer ?

For two days in AppGameKit you are picking it up pretty fast
In your code: // Refer to online docs (NOT SURE WHAT THIS DOES)

This tells the mesh abbout the names of each vertex attribute, it gets important when you need custom attributes for your shaders.
SetMemBlockInt(memblock,24,0x0C000300) is actually 4 bytes
The first byte tells you if the attributes components are floats or integers.
The second one is the number of components i.e vec3,vec4.
The third is the normalize flag (0-1 or 0-255 needed for the color attribute)
The last one is the following string length (it's a bit special)
I calculate it like this:

And the string is just the attribute name
Bengismo
2
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 17th Nov 2019 14:33 Edited at: 17th Nov 2019 14:57
To calculate the flat shaded normals I have a couple of functions which are shown below.

One sets flat shaded normal's on each triangle
The other sets flat shaded quads

They produce the results in the pic above.

You should just be able to set the vertex positions in the memblock then call either of these functions to set the normals for flat shading. Nice and simple. As already discussed you cant use indexed triangles with either of these functions but you aren't using them by the looks of it so far, so that's fine



For indexed meshes with shared vertices then smooth shading is the way to go and i have a few functions for those too if they are wanted.

PLEASE Note:
To get correctly flat shaded quads: the order of the vertices that you put into the memblock affects whether these functions will work or not. In my meshes V1,V2,V3 and V6 are the four corners of my quads. (V4=V2 and V5 = V3 - these are duplicated internal vertices). If this isnt the case for your meshes then you may need to change a few offsets used inside the quad function - (Looking at your code - you WILL have to change a few offsets when the vertex positions for the 4 corners are retrieved as the ordering is different to mine). I have also assumed you are using the same winding order as me but it might be that you aren't but i haven't checked if you are.

They should work fine if these are all set correctly or amended to match your vertex creation order.
Bengismo
2
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 17th Nov 2019 14:52
I almost forgot....

In your code you create a ludicrously large memblock....its like 100Mb (ish)??. i assume that you just wanted it "big enough not to worry about running out of room"
// Allocate space for data
memblock = CreateMemblock(100000000) <--- this is perhaps overkill

It would be a good idea to look at how to calculate the space you will need based on your vertex size and how may triangles you will make and the header info in the memblock. And also ensure you delete the memblock when you are done with it.
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 17th Nov 2019 16:45
So, I can't seem to get the quad flat shading to work although I thought I had everything right.

Here is how my triangles are put into an array:



Here is how I'm constructing the memblock and calculating normal (using the formulas above):



And here is the result:



Do I need to do anything with lighting? I'm just using the default lighting/shading.

Attachments

Login to view attachments
Bengismo
2
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 17th Nov 2019 17:25 Edited at: 17th Nov 2019 17:30
You dont need to do anything with the lighting,

Its quite likely that two of the vertices need swapping in the cross product - ive not looked through your code though so it could be something else. Chances are all those normals are pointing straight down right now rather than up.

Just guessing but trymultiplying by -n to rule that out first

// -- Normalize
n = pow(cx * cx + cy * cy + cz * cz, -0.5)
cx = cx * -n
cy = cy * -n
cz = cz * -n


Rather than trying to integrate the calculation into your code like you have done....you could have just used your old code without normals and just called one of the functions I listed right before creating the object from a memblock. That should work ok.
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 17th Nov 2019 18:20
Finally got it working. It was like you said. I had the points wrong on the corners.

Here is the fix.



Thanks everyone who helped! I'm glad you guys were here...this would have taken forever without your help!

Attachments

Login to view attachments
Bengismo
2
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 17th Nov 2019 19:02
Its good that it appears to be working, ...some great progress there

but.... There is quite a lot that seems "odd" in your code...lol im really not sure why its working

1) Your diagonal vectors for the quad dont seem to be calculated correctly. You should subtract one vertex position from another to get the vector between two vertices...you are adding for some reason?

2) You only calculate the normal for 1 of the 2 triangles in your quad (only using V1,V2 and V3 ...... V4 isnt used at all? - there was no point in putting it into a vector really) meaning that the normal for the whole quad wont be right. The normal for the quad should be the average of the two triangles making it up. Those two normals are not the same

2) You calculate a normal then you are multiplying by its length to normalise it - This is wrong...To normalize it you calculate its length then divide the normal by the length

I really dont mean to criticise at all, Its great progress and even seems to look right...but there does seem to be some "issues"
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 17th Nov 2019 19:44
I change the sign of v1.x, v1.y, and v1.z to negative so when I GetVertex3Add() it is actually a subtraction. I didn't see a way to GetVertex3Subtract()

I use two triangles for the vertices...

tri_1.a --------------------------- tri_2.b
| |
| |
| |
tri_1.b --------------------------- tri_1.c

My triangles are store in an order where the first triangle is the bottom left of above drawn and the next triangle is the top right of quad above.

And since the normal of that quad will be the normal of all the vertices I only add it once to the normal array and when getting normal I do this:



I think it is working but it's hard to tell 100%. I have a bug in my diamond-square algorithm which is causing any terrain with 32 or more divisions to skip vertices... so I'm working on that again to try to get it working better. Once I get it correct, I'll come back to the normals and make sure they're working right. hard to test the normals on a completely screwed up terrain lol although everything looks okay with 2, 4, 8, and 16 divisions
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 17th Nov 2019 20:25
Yup. I think you are right. I think I have the algorithm fixed now. This doesn't seem right:



(hope it's okay to keep posting pictures...)

Attachments

Login to view attachments
Bengismo
2
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 17th Nov 2019 21:28 Edited at: 17th Nov 2019 21:46
Well, at least you have something thats looking sort of right

What you have already done is great and is a credit to you.

however...here's the "but"

Firstly (normalizing a vector):
Your code above uses this :
n = sqrt(cx * cx + cy * cy + cz * cz)
norm.x = cx * n
norm.y = cy * n
norm.z = cz * n

n is the the length of the normal. To normalize any vector, you have to divide by length. So...it should be

norm.x = cx / n
norm.y = cy / n
norm.z = cz / n

or use....
n = 1.0/sqrt(cx * cx + cy * cy + cz * cz) then multiply by n which is the INVERSE of the length...so multiplying by that value is the same as dividing by it

no matter how you do it....All normals should have a length of 1.0 -> Meaning sqrt(x*x +y*y +z*z) = 1.0


Secondly:
Your code to calculate the normal for a quad only uses 3 of the vertices. So...to put it simply: your code just cant be correct if it isnt using all 4 vertices

You use
// Calculate normals for four corners
cross = CreateVector3()
cross_u = v2
GetVector3Add(cross_u, v1)
cross_v = v3
GetVector3Add(cross_v, v1)
GetVector3Cross(cross, cross_u, cross_v)

You use V1,V2 and V3...but v4 is never referenced. V4 may not be coplanar with the other 3 so there is a correct way to get normals for quads

Id calculate the normal for a non coplanar, flat shaded quad by getting the cross product of the diagonal vectors

d1 = V3 - V1
d2 = V2 - V4

crossp = d1 x d2

This method gets a correct representation of the average across the quad face.

An alternate method is to calculate the normal of triangle 1 in the quad and the normal of triangle 2 and then average them (add them then normalize the result). This second method gives the exact same result as the cross product of the diagonals though so its why I use the first method.



Once the normal is truly calculated correctly - then you are right that you set that normal to all 6 vertices that make up the quad.
Technically , 2 vertices could be shared and you could index this quad and save some memory but that snot that important right now. First things first - get it working and ensure its absolutely correct.


Other than that....it looks like you have it sorted.

Sorry for being a stickler on the detail...i guess i have OCD or something...

Kudos to you and not many people get deep into 3d geometry when first starting in any game language!! So having working memblock code is greatly impressive.

Last thing I want to do is come across negative or critical. just trying to help is all.

Always really good to see people making the effort to learn how to do things in 3d awesome
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 18th Nov 2019 01:36
So...I decided to just use your code from above. I had to play with this:



And change some of the v+1, v+2 ...to be different indices before I could see the terrain and it wasn't all dark.

I fixed up my generation algorithm some, turns out random(-100, 100) seems to produce 0 - 100 instead of -100 - 100 so I made a little function for that which seems to work. I also got my colors working which helps the look of the mesh but I'm still a little unsure if the results are right. It looks okay, but I feel like it could be better...not sure if it's the normal or the generation (divisions and size stuff)


Attachments

Login to view attachments
blink0k
AGK Developer
6
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 18th Nov 2019 01:48
that looks awesome
fubarpk
Moderator
14
Years of Service
User Offline
Joined: 11th Jan 2005
Location: Adelaide
Posted: 18th Nov 2019 06:32
Looks great and shows the skills of many years of programming
fubarpk
fubarpk on Itch...………...https://fubarpk.itch.io/
fubarpk on googleplay..https://play.google.com/store/apps/developer?id=fubarpk
Xaby
FPSC Reloaded TGC Backer
12
Years of Service
User Offline
Joined: 17th Apr 2007
Location: Berlin
Posted: 19th Nov 2019 19:52
@blink0k,

It looks, like we have to drive with your kart on this mountain
blink0k
AGK Developer
6
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 19th Nov 2019 20:22
Quote: "It looks, like we have to drive with your kart on this mountain"

Hahahaha
tiresius
17
Years of Service
User Offline
Joined: 13th Nov 2002
Location: MA USA
Posted: 20th Nov 2019 21:26
How are you all doing the terrain generation itself (diamond square) ?
spenland
User Offline
Joined: 14th Nov 2019
Location:
Posted: 22nd Nov 2019 18:35
Yes, it's diamond-square.

I tweaked some things to get close to what I liked. I mainly just took a Unity diamond-square tutorial and ported it to agc.
tiresius
17
Years of Service
User Offline
Joined: 13th Nov 2002
Location: MA USA
Posted: 22nd Nov 2019 19:18
Ok cool, I spent a long time doing a diamond square algorithm using wikipedia and other web sources as well into agk and was worried there was some easy 3D function to do it and I wasted some time.

Login to post a reply

Server time is: 2019-12-12 05:32:26
Your offset time is: 2019-12-12 05:32:26