Jump to content

Increase / Eliminate the limit of how metin2 process the 3D models - Experimental


Recommended Posts

  • Active+ Member

TLDR about what these means: You can load medium to high poly models meaning that the models that are looking "awesome"and before were not able to be loaded to metin2, now these can be loaded!

I had some fun discussions with some people about the limit of how metin2 has about 3D models and I've scrapped out a bit the client source. Found some interesting things and I've managed to change them and increase that limit. If I understood correctly from the source, metin2 allows to be correctly rendered ~65k vertices (WORD) (maybe around 20k faces) at once for a mesh. I've Increased this limit to ~4.29 billion (I think) per mesh. 

These changes were made / tested on TMP4 + DX9 (based on what I saw, I think this will work for DX8 too)

 

This can be a nice addition if someone just make some checks to increase the limit, maybe around 100k vertiges or such? this little change can also make the work of the mappers a lot easier (to no longer split models)
I also know there are talented people that can develope this idea much further. 
There is someone that also managed to eliminate / increase this limit. He sustains that he is not encountering the below warnings that I'll share to you. He is also selling it but In my humble opinion, I think he has the same problems at me, based on what he shared some days ago.  

 

WARNING

  • Making these changes, you can experience a lot of lag / freezes or maybe crashes upon loading a model that is above the default (removed) metin2 limit. 
  • These changes are only experimental if you want to have fun. 
  • I'm not offering any kind of support. 
  • Using these changes to load map objects, are less laggy but still not good for gameplay. 
  • I'm not recommending using this. If you want to use this, use it for fun OR be sure that you are making a lot of optimisations since those are totally needed. If you someone have the time to make such optimisation for these little changes and wants to share with us, will be more than appreciated!

 

 

TESTS

  • I've uploaded and sucessfully loaded a model with ~154k vertices, 154k indices and around ~60k faces. 
  • Then I've loaded multiple entities (npcs) with this model. At the number 20, the game starts to lag, around 12-14 FPS. At 100 npcs loaded, the FPS are decreasing to 5-10. Also, the performance increase, somewhere around 1.4-1.8GB RAM used (instead of 400MB). 
  • I've used the same model to place map objects. The results are a bit better. at 100 objects, i had around 14-18 FPS still. 
  • Loading a single model up to 5 or 10, the performance changes are not quite visible. 

 



Download link for the test object!: 

This is the hidden content, please
 I tried metin2.download but is still in Pending Upload status 

Preview

 

Gyazio Map Objects: https://metin2.download/video/F4VFwWuNNV23M3P1fTKTfvnTJUcrscHO/.mp4  

https://metin2.download/video/F4VFwWuNNV23M3P1fTKTfvnTJUcrscHO/.mp4

Gyazio NPCs: 
https://metin2.download/picture/y6ust8DDOishXOU58Yh1y5tPgG7s4XrZ/.jpg 

https://metin2.download/video/3v3Iu78SBB119cZJtO3x2jiND4Bl91B3/.mp4

Before and After: 


https://metin2.download/picture/C368rtO43j7WsQ04E6uJn36Zo7o21b9r/.jpg 


https://metin2.download/picture/PTfoBGJCBNWkwm2RAPDJyT9t0X7yEi1f/.jpg 

TUTORIAL

   Early Note: was made for fun. it is not optimised. These changes were made by just having fun. I dont have the knowledge OR the time to optimise it. but its a start for everyone. 

This is the hidden content, please

Edited by KolenMG
Proper added download link for an test object.
  • Metin2 Dev 55
  • Good 7
  • muscle 1
  • Love 24
  • Active+ Member

Sure. Here we go a test object with 1.3 MILION faces (triangles) 

https://metin2.download/video/YU3dki4dTcNT19WUiZIeijlfaYUso2Mm/.mp4 

.png

 

.png

Download link: 

This is the hidden content, please
 

Edited by Metin2 Dev International
Core X - External 2 Internal
  • Metin2 Dev 6
  • Good 1
  • muscle 1
  • Love 3
18 minutes ago, KolenMG said:

Sure. Here we go a test object with 1.3 MILION faces (triangles) 

https://metin2.download/video/YU3dki4dTcNT19WUiZIeijlfaYUso2Mm/.mp4 

.png

 

.png

Download link: 

Hidden Content

  • Give reaction to this post to see the hidden content.

 

 

lol, one car is ate %70 of overclocked 5080

Edited by Metin2 Dev International
Core X - External 2 Internal
  • kekw 3
  • Active+ Member
25 minutes ago, Denizeri24 said:

lol, one car is ate %70 of overclocked 5080

well yea. :)) Ive took especially that car since is too "expensive". Due to how that car is made, it cannot be used in any of current games due to too many polys as overall. I took it from the internet and then just exported to metin2. I believe that car was made puerly for cinematics OR pure fun. 

But still, metin being able to load such files in such quality, its something. but again, not optimise.. 😕 

On 7/2/2025 at 6:36 PM, KolenMG said:

looking "awesome"and before were not able to be loaded to metin2, now these can be loaded!

Granny has no polygon/mesh limitations. You can load insane models with no problem (other than the time your computer can take to render it). Currently the largest model I've tried was a floating map with over 4.5k vertices.
The model in question used 4k textures + normal map, I had implemented it on the clean files I use (5.7 by Marty) and leaving aside those 3-4 extra seconds to load the first time entering the map, for the rest there were no problems.

In any case, out of curiosity, as soon as I have some free time from work, I will test this modification. 
Thanks for the release

-LN

  • Love 1
  • Active+ Member
17 hours ago, LoKnarash said:

Granny has no polygon/mesh limitations. You can load insane models with no problem (other than the time your computer can take to render it). Currently the largest model I've tried was a floating map with over 4.5k vertices.
The model in question used 4k textures + normal map, I had implemented it on the clean files I use (5.7 by Marty) and leaving aside those 3-4 extra seconds to load the first time entering the map, for the rest there were no problems.

In any case, out of curiosity, as soon as I have some free time from work, I will test this modification. 
Thanks for the release

-LN

Hmm. yeah. Granny itself yes. but strictely on client side, there are WORD limits for vertices / indexes (defined those as WORD = ~65k per mesh) . in regards of textures, I haven't had a chance to look on, but overall, as far as I've encountered before, I was able too to load insane textures resolutions too, on TMP4 clean. Of course, there is that known freeze / spike upon loading it. hmm, maybe there is a chance to change / get rid of this spike too. Good call out!

  • 2 weeks later...
  • Honorable Member
On 7/3/2025 at 6:47 PM, Denizeri24 said:

lol, one car is ate %70 of overclocked 5080

Really? For me one car doesn't reduce my FPS. It starts to drop to 50 at around 80 cars. (3070 Ti)

Edited by Distraught

992404397646696589.png
Former C++ Developer at Gameloft on DML
Join my Discord: Distraught Labs

6 hours ago, Distraught said:

Really? For me one car doesn't reduce my FPS. It starts to drop to 50 at around 80 cars. (3070 Ti)

idk, i get 240 fps when just one car also i using shader for rendering..

  • 8 months later...
  • Honorable Member
Posted (edited)

This is the change I made in the WEREMIX for supporting >65k vertices models.

  

From: martysama0134
Subject: EterGrnLib: support 32-bit index buffers for high-poly models

This patch adds automatic 32-bit index buffer support for models with
more than 65535 total vertices. Without it, index values are silently
truncated to 16 bits, causing mesh corruption on high-poly .gr2 models.

Changes:
- Model.h/cpp: Added m_idxFmt member (D3DFMT_INDEX16 or D3DFMT_INDEX32),
  determined at load time based on total vertex count. LoadIndices() now
  passes the index size to each mesh. New LoadSkinPNTVertices() method
  added for GPU skinning vertex extraction (optional, can be ignored if
  not using GPU skinning).
- Mesh.h/cpp: LoadIndices() now takes an idxSize parameter and uses
  byte-level pointer arithmetic instead of TIndex* to support both
  2-byte and 4-byte indices.
- GrpIndexBuffer.cpp: Fixed buffer size calculation - was hardcoded to
  sizeof(WORD)*idxCount even when D3DFMT_INDEX32 was requested, causing
  heap overflow crashes on high-poly models.

Applies to: any codebase using EterGrnLib with Granny2 SDK.
Tested on: WorldEditorRemix v56 (DX9Ex, Win32/x64, MfcDebug/MfcRelease)

diff --git a/Srcs/Client/EterGrnLib/Mesh.cpp b/Srcs/Client/EterGrnLib/Mesh.cpp
index a84eae1..5b75d5a 100644
--- a/Srcs/Client/EterGrnLib/Mesh.cpp
+++ b/Srcs/Client/EterGrnLib/Mesh.cpp
@@ -12,12 +12,12 @@ granny_data_type_definition GrannyPNT3322VertexType[5] =
 	{GrannyEndMember}
 };
 
-void CGrannyMesh::LoadIndices(void * dstBaseIndices)
+void CGrannyMesh::LoadIndices(void * dstBaseIndices, int idxSize)
 {
 	const granny_mesh * pgrnMesh = GetGrannyMeshPointer();
 
-	TIndex * dstIndices = ((TIndex *)dstBaseIndices) + m_idxBasePos;
-	GrannyCopyMeshIndices(pgrnMesh, sizeof(TIndex), dstIndices);
+	char * dstIndices = ((char *)dstBaseIndices) + m_idxBasePos * idxSize;
+	GrannyCopyMeshIndices(pgrnMesh, idxSize, dstIndices);
 }
 
 void CGrannyMesh::LoadPNTVertices(void * dstBaseVertices)
diff --git a/Srcs/Client/EterGrnLib/Mesh.h b/Srcs/Client/EterGrnLib/Mesh.h
index 323f361..2b97e52 100644
--- a/Srcs/Client/EterGrnLib/Mesh.h
+++ b/Srcs/Client/EterGrnLib/Mesh.h
@@ -37,7 +37,7 @@ class CGrannyMesh
 
 		bool					IsEmpty() const;
 		bool					CreateFromGrannyMeshPointer(granny_skeleton* pgrnSkeleton, granny_mesh* pgrnMesh, int vtxBasePos, int idxBasePos, CGrannyMaterialPalette& rkMtrlPal);
-		void					LoadIndices(void* dstBaseIndices);
+		void					LoadIndices(void* dstBaseIndices, int idxSize);
  		void					LoadPNTVertices(void* dstBaseVertices);
 		void					NEW_LoadVertices(void* dstBaseVertices);
 		void					Destroy();
diff --git a/Srcs/Client/EterGrnLib/Model.cpp b/Srcs/Client/EterGrnLib/Model.cpp
index 0ff7892..1808702 100644
--- a/Srcs/Client/EterGrnLib/Model.cpp
+++ b/Srcs/Client/EterGrnLib/Model.cpp
@@ -124,11 +124,10 @@ bool CGrannyModel::LoadPNTVertices()
 
 bool CGrannyModel::LoadIndices()
 {
-	//assert(m_idxCount > 0);
 	if (m_idxCount <= 0)
 		return true;
 
-	if (!m_idxBuf.Create(m_idxCount, D3DFMT_INDEX16))
+	if (!m_idxBuf.Create(m_idxCount, m_idxFmt))
 		return false;
 
 	void * indices;
@@ -136,10 +135,11 @@ bool CGrannyModel::LoadIndices()
 	if (!m_idxBuf.Lock((void**)&indices))
 		return false;
 
+	int idxSize = (m_idxFmt == D3DFMT_INDEX32) ? 4 : 2;
 	for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m)
 	{
 		CGrannyMesh& rMesh = m_meshs[m];
-		rMesh.LoadIndices(indices);
+		rMesh.LoadIndices(indices, idxSize);
 	}
 
 	m_idxBuf.Unlock();
@@ -254,6 +254,7 @@ bool CGrannyModel::LoadMeshs()
 
 	m_vtxCount = vtxPos;
 	m_idxCount = idxPos;
+	m_idxFmt = (m_vtxCount > 65535) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
 	return true;
 }
 
@@ -390,6 +391,7 @@ void CGrannyModel::Initialize()
 	m_deformVtxCount = 0;
 	m_vtxCount = 0;
 	m_idxCount = 0;
+	m_idxFmt = D3DFMT_INDEX16;
 
 	m_canDeformPNVertices = false;
 
diff --git a/Srcs/Client/EterGrnLib/Model.h b/Srcs/Client/EterGrnLib/Model.h
index 55e73a2..784081f 100644
--- a/Srcs/Client/EterGrnLib/Model.h
+++ b/Srcs/Client/EterGrnLib/Model.h
@@ -75,6 +75,7 @@ class CGrannyModel : public CReferenceObject
 		int						m_rigidVtxCount;
 		int						m_vtxCount;
 		int						m_idxCount;
+		D3DFORMAT				m_idxFmt;
 
 		int						m_meshNodeSize;
 
diff --git a/Srcs/Client/EterLib/GrpIndexBuffer.cpp b/Srcs/Client/EterLib/GrpIndexBuffer.cpp
index eb897a0..70074e7 100644
--- a/Srcs/Client/EterLib/GrpIndexBuffer.cpp
+++ b/Srcs/Client/EterLib/GrpIndexBuffer.cpp
@@ -113,7 +113,7 @@ bool CGraphicIndexBuffer::Create(int idxCount, D3DFORMAT d3dFmt)
 	Destroy();
 
 	m_iidxCount = idxCount;
-	m_dwBufferSize = sizeof(WORD) * idxCount;
+	m_dwBufferSize = ((d3dFmt == D3DFMT_INDEX32) ? sizeof(DWORD) : sizeof(WORD)) * idxCount;
 	m_d3dFmt = d3dFmt;
 
 	return CreateDeviceObjects();

@ Karbust Enable Diff SyntaxHighlighting 

Edited by martysama0134
  • Love 1
  • Love 4

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.