Well, an easier solution would be to know what 3D Modelling Application you're using ... as it's likely in-experience in either how the Vertex Normals are set, or alternatively you're setting an option in the Exporter to Automatically set the Normal Angle to 90° and calculate on export.
Now... beyond this there are two optional routes to take here.
You can either:
1 • Use a Vertex / Pixel Shader that ignores the Object (Vertex) Normals and instead sets the Light Normalisation based upon a Normal and/or Tangent Map.
2 • Use Memblocks to Manually Recalculate the Vertex Normal Angles.
With Memblocks, it's actually quite a simple task to set the Vertex Normals to produce Facet (i.e. Uniform Lighting Per Triangle / Polygon) Shading... note that this is oft used interchangably with Flat Shading., but that's an incorrect as such is Uniform Lighting Per Object.
The mistake with this was made with 3D Studio Max terminology and just kind of got picked up by it's Clones.
If you do chose to get into Shaders, actually knowing the difference between these can be quite important.
Still, the basic premise of how to Calculate these is pretty simple.
Here's a Function for Calculating the Face Normal for a Triangle (AGK)
Function CalculateSurfaceNormal( Triangle As Float[3,3], Ref Normal As Float[3] )
Local Edge As Float[2,3] // 1 = X, 2 = Y, 3 = Z
// We get 2 Edge Vectors of the Triangle
For i = 1 To 3
Edge[1,i] = Triangle[2,i] - Triangle[1,i]
Edge[2,i] = Triangle[3,i] - Triangle[1,i]
Next
// Now we just Cross Product the 2 Edges for the Surface Normal
Normal[1] = (Edge[1,2] * Edge[2,3]) - (Edge[1,3] * Edge[2,2])
Normal[2] = (Edge[1,3] * Edge[2,1]) - (Edge[1,1] * Edge[2,3])
Normal[3] = (Edge[1,1] * Edge[2,2]) - (Edge[1,2] * Edge[2,1])
// As we've passed Normal in as a Reference, this means
// we don't need to return anything... whatever Array you passed
// in as Normal[] now contains the Normal Data
EndFunction
This can also be done with the Vector3 Commands., but the above approach means we don't have to think about cleaning up Vector3 Declarations afterwards.
It is however much easier.
Remember it's a simple case of
Edge 1 = VertexPos1 - VertexPos2
Edge 2 = VertexPos3 - VertexPos1
Normal = CrossProduct(Edge1, Edge2)
But seeing how this is actually calculates via Arrays is easier to understand what is actually going on.
Now bare in mind we're completely rewriting (or that's the intention) the existing Normal Data., so just Calculating the Normal for each Individual Triangle might not strictly be "Ideal"
We can of course take this further with Surface Normal Groups... which is a little more involved.
What we ideally want to do with this create a Custom Type and Array for Storage of the Data... as we want to Calculate the Face Normal, Edge Normal in order to ultimately figure out the Vertex Normal.
In the above example, we're basically limiting ourselves to a Face Normal; meaning the 3 Vertex are always going to Share this.
When we expand to have 2+ Triangles in a Group., then Shared Edge = Cross Product( Face 1 Normal , Face 2 Normal ) ... but when we have Shared Vertex (i.e. 3 Faces)., then we want to use the Shared Edge Normal then we're still performing a single Cross Product., but now: Shared Vertex = CrossProduct( Face 3 Normal, Shared Edge Normal ).
If we want to get "Super Fancy" about this., then we can set a 'Smooth Angle' (0 .. 90 Degrees); and in said case essentially as you're calculating said Angles you want to check if the Result is > Smooth Angle ... if so., you basically don't Store the Calculated Result. This is best done in the Shared Edge Calculations., thus we have Soft and Hard edges.
This isn't that difficult; it's just a case of SOHCAHTOA to find the Delta Angle between the two Normals.
Remember we're checking to ensure that the Delta Angle between the two Face Normals (not the Faces themselves) is < the Smoothing Angle; if it is... then Store Result, else ignore it and move on.
< • >
Now as for how we actually Store this Data... well that's fairly straight forward as well., as noted we'll be using Memblocks.
However keep in mind that if the Number of Indices is > 0 ... you WILL have to create a new MemblockMesh in order to switch it to a Non-Indexed Version that Declares all of the Vertex for each Face... it's not that difficult to then "Optimise" with Fewer Vertex via Generating an Index List., but to do this we MUST have a Raw (Unoptimised) Approach.
And remember it isn't just different Normals that require a dedicated Vertex but UV Texture Coordinate (for UV Shells) as well.
Still I'm sure with some tinkering you can figure out how Memblock Mesh work.
The Command Help is concise, but omits explaining a few elements and for some reason doesn't use Paragraphs or any other Formatting making it a LITERAL Wall-of-Text, which can be difficult to read.
By Default though you'll always have Position, Normal, Colour, UV ... as the set Attributes., and most programs won't export otherwise.
Still the lack of more in-depth explanation on how to manually set these up is certainly not ideal.
There should be a Guide and Example that can help though.