Fragen bzgl. Voxel Engine

Einstiegsfragen, Mathematik, Physik, künstliche Intelligenz, Engine Design
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Mit dem Speicher wirst du sehr schnell am Ende sein. Wenn die 64³ Chunks je 16³ komplett ausgereizt werden, bekommst du pro Voxel-Byte ein Gigabyte RAM-Auslastung dazu.
Mein derzeitiger Ansatz ist es nur die Chunks zu laden die auch sichtbar sind und Chunks die nicht sichtbar sind wieder zu entladen, also den Speicher freigeben. Was momentan noch ein wenig die Framerate drückt, aber da kommen noch ein paar Optimierungen rein.

Momentan habe ich ein kleines Problem mit dem Rendering. Ich habe jetzt mehrere Methoden durchprobiert und werde die hier mal aufzählen und die Probleme die ich damit bekomme:

1 Methode: Für jeden Chunk einen eigene Vertex/Index Buffer und einen eigenen DrawPrimitive Aufruf
Problem - egal in welcher Reihenfolge (von hinten nach vorne) ich die Chunks rendere, sie werden "überzeichnet".
Meine Lösungsidee wäre alle Daten zu sammeln, in einen großen Vertex/Indexbuffer zu packen und mit einem einzigen Draw Aufruf alles zu zeichnen, wobei ich aber jedes mal einen Offset für meine Indices hinzuaddieren müsste was ich mir sehr ineffizient vorstelle (und natürlich der Speicherbedarf - Vertex/Index Daten in den Chunks und den Buffern).

2 Methode: Ich sammle alle Daten packe sie in mehrere große Vertex/Indexbuffer (ohne die Daten in den Chunks zu speichern) und rendere sie.
Problem - Meine Buffer werden, je mehr Chunks aktiviert werden, immer größer und die Framerate immer kleiner^^.
Eine Lösungsidee war es die Buffer ab einer bestimmten Größe zu leeren und neu zu füllen, was aber zu unschönen Effekten während des Leerens und Neu-Befüllens geführt hat.

Hat jemand gute Lösungsansätze wie man das ganze effektiv rendern kann, oder Links zu Seiten die sich mit dem Thema beschäftigen.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Schrompf »

Ich hätte ja zu Methode 1 geraten, weil die praktisch und schnell gemacht ist, wenn die Blöcke sich ändern sollen. Was meinst Du mit "überzeichnen"?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Ich hätte ja zu Methode 1 geraten, weil die praktisch und schnell gemacht ist, wenn die Blöcke sich ändern sollen. Was meinst Du mit "überzeichnen"?
Bevorzuge auch die 1 Methode weil das Culling so weniger Aufwand benötigt.
Mit "überzeichnen" meine ich das die hinteren Chunks über die vorderen Chunks gerendert werden, also so eine Art Z-Buffer Problem weil jeder Chunk einen eigenen Draw Aufruf hat. Hab schon versucht zu sortieren, aber das Problem besteht weiter. Liegt vermutlich an meiner Kamera Klasse.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Schrompf »

Wut? Genau dafür wurde der ZBuffer erfunden. Achte aber darauf, dass die Near Clipping Plane nicht zu nah ist und die Far Clipping Plane zu weit weg. Das Verhältnis zwischen den beiden Zahlen sollte kleiner als ~100.000 sein.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Ok, es lag an einer zu nahen NearPlane, daran hatte ich nicht gedacht... -.-
Danke Schrompf! War schon am verzweifeln und hab alles mögliche versucht um an dem Fehler vorbeizuarbeiten.
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Hier mal ein kleiner Screen des aktuellen Fortschrittes (ja, momentan ist noch Minecraft Style, aber da kommt noch mehr!)
Dateianhänge
Unbenannt3.png
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Schrompf »

Schönschön, es geht vorwärts!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Ich verwende jetzt zum Texturieren einen Texture Atlas und hab das "Texture Bleeding" Problem. Hab bereits gegoogelt, aber die Lösungsvorschläge die ich gefunden habe sind eher suboptimal, u.a. einen Rand für jede Textur der bei Anisotroper Filterung 8 Pixel breit wäre und für jede Filter Einstellung eine eigene Textur benötigen würde...
Das sollte ja eigentlich ein häufiges Problem sein, gibts dafür keine Standardmethode (z.b. RenderStates) das ganze zu lösen? Achja, ich verwende Momentan DX9 zum Rendern (ab DX10 gibts das "Bleeding" Problem ja scheinbar nicht mehr), werde aber später noch einen DX10 bzw. DX11 Renderer implementieren.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Schrompf »

Doch, das gibt's auch unter DX10. Das ist ein ganz normales Phänomen, weil der Texturfilter ja nichts von Deinem Texturatlas weiß und demzufolge einfach von der Stelle samplet, die Du im sagst. Da eine Menge Bildqualität davon abhängt, betreibt die GPU einigen Aufwand beim Samplen und liest da gleich ein mehr oder weniger großes Gebiet rund um den Sample-Punkt. Damit bekommst Du zwangsweise Farben von benachbarten Atlas-Segmenten mit rein, wenn Du samplest. Das sind bis zu +-8 Texel bei Anisotropischem Filter, mal eine Zweierpotenz bei MipMapping. Das kann also beliebig heftig werden.

Einfache Lösung: schalte alle Texturfilter ab. Sieht aber scheiße aus.
Komplexere Lösung: ähnlich farbigen Platz rund um jedes Segment im Texturatlas lassen. Verschwendet Texturplatz.
Meine Lösung: im Vertex- oder Geometrie-Shader ausrechnen, welche MipMap-Stufe wahrscheinlich zum Einsatz kommt, und dann die Texturkoordinaten auf einen Bereich clampen, der um soviel Texel kleiner ist als das ursprüngliche Atlassegment.

Hab ich allerdings bisher nur bei 2D-Grafiken erprobt, aber da funktioniert es tadellos.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Slin
Beiträge: 44
Registriert: 15.05.2010, 01:21
Echter Name: Nils Daumann
Wohnort: Lübeck
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Slin »

Einen Texturatlas nutzt man ja normalerweise um den Overhead durch das ständige neu setzen von Texturen zu reduzieren. Die moderne Lösung für das Problem scheinen Array Texturen zu sein, die gibt es aber soweit ich weiß erst in DX10, oder sogar erst in 11...
Um an deinen Atlas angepasste Mipmaps führt nichts drumherum ansonsten ist dieses Paper eigentlich noch ganz interessant, da es Lösungen für die meisten Probleme vorstellt: ftp://download.nvidia.com/developer/NVT ... epaper.pdf
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Einfache Lösung: schalte alle Texturfilter ab. Sieht aber scheiße aus.
Komplexere Lösung: ähnlich farbigen Platz rund um jedes Segment im Texturatlas lassen. Verschwendet Texturplatz.
Meine Lösung: im Vertex- oder Geometrie-Shader ausrechnen, welche MipMap-Stufe wahrscheinlich zum Einsatz kommt, und dann die Texturkoordinaten auf einen Bereich clampen, der um soviel Texel kleiner ist als das ursprüngliche Atlassegment.
Ja, das sind so die Lösungen die ich beim Googlen herausgefunden habe. Werde vorerst mal nur lineares Filtering verwenden und das Texturproblem aufschieben^^
... Die moderne Lösung für das Problem scheinen Array Texturen zu sein, die gibt es aber soweit ich weiß erst in DX10, oder sogar erst in 11...
Bin auch auf das Thema Array Texturen gestoßen, aber dazu findet man fast nur Methoden für OpenGL.

Aber mal ein bisschen was anderes - Lässt sich Face-Merging mit Texturatlas Texturierung kombinieren? Wenn ich das ganze so durchdenke finde ich keine Möglichkeit.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Schrompf »

Nein, das wird knifflig. Zumindest die Eingaben für den PixelShader müssen an der Materialkante geändert werden. Das machst Du üblicherweise ja durch neue Vertices. Du könntest aber auch einen Texture Index auf eine Textur schreiben und jeder Würfelseitenfläche Texturkoordinaten mitgeben, dann kannst Du das live im PixelShader sampeln.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Dachte mir schon das falls es funktioniert das ganze nicht ganz einfach ist... Aber der Vertexcount ist momentan eh eine meiner kleineren Sorgen, im Gegensatz zum Laden und Erstellen der Chunks...
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Soo, hätte mal wieder eine Frage bzgl. eines Problems. :D
Und zwar geht es um das View Frustum Culling. Das ganze funktioniert nicht ganz wie es sollte, ich beschreibe mal wie das ganze funktioniert.
Ich verwende einen Octree für das Culling, erstelle mir die Planes und die Eckpunkte des Frustums und habe eine "BoxInFrustum" sowie eine "FrustumInBox" Methode um herauszufinden welche Chunks gerendert werden sollen. Das Problem ist, dass ich scheinbar False Negative Werte zurückbekomme (hatte zuerst nur BoxInFrustum Culling, nachdem ich FrustumInBox Culling hinzugefügt hatte wurde es besser aber es sind trotzdem noch Fehler), und zwar werden mir Chunks zu früh ausgeblendet.
Die Methoden sollten fehlerfrei sein, die Werte im Octree sollten auch stimmen, also vermute ich das ich irgendetwas übersehe.
Hoffe ich habe das Problem gut genug beschrieben, den Code hier zu posten wäre zu unübersichtlich.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Fragen bzgl. Voxel Engine

Beitrag von Schrompf »

Warum unübersichtlich? Ein Frustum besteht aus 5 Ebenen. Eine Box aus 8 Eckpunkten. Eine Box ist im einfachsten Fall nur dann nicht im Frustum, wenn alle 8 Ecken der Box jenseits der selben Ebene sind.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Warum unübersichtlich? ...
Weil ich dann die Kamera, Octree und Frustum Klasse posten müsste, und das wäre ne schlimme codewurst (ausserdem möchte ich den Code noch niemandem zumuten :mrgreen: )

Ja, mir ist schon klar wie das Culling funktioniert, und ich habs auch schon mehrfach überprüft, aber es scheint so als würde er das Frustum nicht korrekt erstellen, hier mal ein wenig Code wie das Frustum erstellt wird

Code: Alles auswählen

void Frustum::ConstructFrustum(float screenDepth, D3DXMATRIX matProj, D3DXMATRIX matView)
{
	float zMinimum;
	float r;
	D3DXMATRIX matrix;


	//D3DXVECTOR3 vDir = camera.vLookAt - camera.vPosition;
	D3DXMatrixLookAtLH( &matView, &camera.vPosition,&camera.vLookAt,&D3DXVECTOR3(0.0f,1.0f,0.0f));


	// Calculate the minimum Z distance in the frustrum
	zMinimum = -matProj._43 / matProj._33;
	r = screenDepth / (screenDepth - zMinimum);
	matProj._33 = r;
	matProj._43 = -r*zMinimum;


	// Create the frustrum matrix from the view matrix and update projection matrix
	D3DXMatrixMultiply(&matrix, &matView, &matProj);
//	D3DXMatrixInverse(&matrix,NULL,&matrix);

	// Calculate near plane of frustrum
	this->m_planes[0].a = matrix._14 + matrix._13;
	this->m_planes[0].b = matrix._24 + matrix._23;
	this->m_planes[0].c = matrix._34 + matrix._33;
	this->m_planes[0].d = matrix._44 + matrix._43;
	D3DXPlaneNormalize(&this->m_planes[0], &this->m_planes[0]);

	// Calculate far plane of frustrum
	this->m_planes[1].a = matrix._14 - matrix._13;
	this->m_planes[1].b = matrix._24 - matrix._23;
	this->m_planes[1].c = matrix._34 - matrix._33;
	this->m_planes[1].d = matrix._44 - matrix._43;
	D3DXPlaneNormalize(&this->m_planes[1], &this->m_planes[1]);

	// Calculate left plane of frustrum
	this->m_planes[2].a = matrix._14 + matrix._11;
	this->m_planes[2].b = matrix._24 + matrix._21;
	this->m_planes[2].c = matrix._34 + matrix._31;
	this->m_planes[2].d = matrix._44 + matrix._41;
	D3DXPlaneNormalize(&this->m_planes[2], &this->m_planes[2]);

	// Calculate right plane of frustrum
	this->m_planes[3].a = matrix._14 - matrix._11;
	this->m_planes[3].b = matrix._24 - matrix._21;
	this->m_planes[3].c = matrix._34 - matrix._31;
	this->m_planes[3].d = matrix._44 - matrix._41;
	D3DXPlaneNormalize(&this->m_planes[3], &this->m_planes[3]);

	// Calculate top plane of frustrum
	this->m_planes[4].a = matrix._14 - matrix._12;
	this->m_planes[4].b = matrix._24 - matrix._22;
	this->m_planes[4].c = matrix._34 - matrix._32;
	this->m_planes[4].d = matrix._44 - matrix._42;
	D3DXPlaneNormalize(&this->m_planes[4], &this->m_planes[4]);

	// Caclualte bottom plane of frustrum
	this->m_planes[5].a = matrix._14 + matrix._12;
	this->m_planes[5].b = matrix._24 + matrix._22;
	this->m_planes[5].c = matrix._34 + matrix._32;
	this->m_planes[5].d = matrix._44 + matrix._42;
	D3DXPlaneNormalize(&this->m_planes[5], &this->m_planes[5]);


	// Calculate Frustum Poins
	D3DXVECTOR3 dir,nc,fc,X,Y,Z;
	this->ratio = 1920.0f/1080.0f;
	this->angle = D3DX_PI/4;
	this->nearDistance = 0.5f;
	this->farDistance = 200.0f;

	// compute width and height of the near and far plane sections
	tang = (float)tan(ANG2RAD * angle * 0.5) ;
	nearHeight = nearDistance * tang;
	nearWidth = nearHeight * ratio;
	farHeight = farDistance  * tang;
	farWidth = farHeight * ratio;

	D3DXVECTOR3 vLookAt;
	D3DXVec3Normalize(&vLookAt, &camera.vLookAt);

	Z = camera.vPosition + vLookAt;
	D3DXVec3Normalize(&Z, &Z);

	D3DXVec3Cross(&X, &camera.vUp, &Z);
	D3DXVec3Normalize(&X, &X);
	D3DXVec3Cross(&Y, &Z, &X);

	// compute the centers of the near and far planes
	nc = camera.vPosition - Z * nearDistance;
	fc = camera.vPosition - Z * farDistance;

	// compute the 4 corners of the frustum on the near plane
	nearTopLeft = nc + Y * nearHeight - X * nearWidth;
	nearTopRight = nc + Y * nearHeight + X * nearWidth;
	nearBottomLeft = nc - Y * nearHeight - X * nearWidth;
	nearBottomRight = nc - Y * nearHeight + X * nearWidth;

	// compute the 4 corners of the frustum on the far plane
	farTopLeft = fc + Y * farHeight - X * farWidth;
	farTopRight = fc + Y * farHeight + X * farWidth;
	farBottomLeft = fc - Y * farHeight - X * farWidth;
	farBottomRight = fc - Y * farHeight + X * farWidth;


}
Und das Culling selbst überprüft einfach ob einer der Punkte im Frustum liegt bzw. bei größeren Objekten, das Frustum im Objekt.

Edit:
Und der Octree wird folgendermaßen geprüft:

Code: Alles auswählen

void ChunkOctree::getVisibleData(Chunk **ppData, DWORD &count)
{
	if(g_Frustum.CubeInFrustum(*m_MidPt,m_Radius) || g_Frustum.FrustumInCube(*m_MidPt,m_Radius))
	{
		for(int i=0;i<8;i++)
		{
			if(this->m_pChilds[i] != NULL)
				this->m_pChilds[i]->getVisibleData(ppData, count);
		}
		
		if(this->m_pChunkPtr != NULL)
		{
			ppData[count] = this->m_pChunkPtr;
			count++;
		}
	}
}
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: Fragen bzgl. Voxel Engine

Beitrag von exploid »

Hallo

Deine Fragen 1-3 werden ausführlich bei den folgenden links behandelt:

https://sites.google.com/site/letsmakeavoxelengine/home
https://www.sea-of-memes.com/LetsCode1/LetsCode1.html

In der Hoffnung etwas geholfen zu haben.

mfg
All your base are belong to us! Justice
Benutzeravatar
mike7774
Beiträge: 22
Registriert: 06.01.2014, 00:00

Re: Fragen bzgl. Voxel Engine

Beitrag von mike7774 »

Hallo

Deine Fragen 1-3 werden ausführlich bei den folgenden links behandelt:

https://sites.google.com/site/letsmakeavoxelengine/home
...
Hey, ja Let's make a Voxel Engine ist ne verdammt gute Seite, hat mir beim Start sehr geholfen.
Antworten