Meshterrain und Nahtstellen
Übersicht

KrischanBetreff: Meshterrain und Nahtstellen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo,
ich beschäftige mich gerade mit Meshterrains und dabei bin ich auf ein Problem gestossen, bei dem ich gerade nicht durchblicke. Ich habe dazu mal eine Demo gebastelt. Screenshot: ![]() Da sieht man das Problem auch gleich gut. Wie schaffe ich es, die Nahtstellen an den vier Seiten des Meshterrains jeweils auf die gleiche Höhe zu bekommen, damit das Terrain nahtlos tiled? Ich habe mich mal daran versucht, die Seiten aneinander anzugleichen, bin aber kläglich gescheitert. Was auch ein bisschen blöd ist, dass die Heightmap 129x129 anstatt 128x128 gross sein muss, da die Übergänge sonst noch viel stärker zu Tage treten. Vielleicht habt Ihr eine Idee? Das Terrain und die texturen sind übrigens schnell mit dem "Large 3D Terrain Editor" SE generiert worden, cooles Programm. Code: [AUSKLAPPEN] Graphics3D 1024,768,32,1
; Pivot für Steuerung und globale Variablen Global cam, player Global cam_pitch#, cam_yaw# Global mvx#,mvy#,mvz#,targetpitch#,targetyaw# ; Kamerageschwindigkeit Global speed#=0.1 ; Playerpivot player=CreatePivot() PositionEntity player,64,10,40 ; Kamera an Pivot gehängt cam=CreateCamera(player) PositionEntity cam,0,0,0 CameraZoom cam,1 CameraRange cam,0.01,10000 AmbientLight 255,255,255 CameraFogMode cam,True CameraFogRange cam,0,256 CameraFogColor cam,96,64,32 CameraClsColor cam,96,64,32 ; Meshterrain mit Colormap und Lightmap generieren mesh1=LoadMeshTerrain("heightmap.bmp","colormap.jpg","lightmap.jpg") mesh2=CopyEntity(mesh1) mesh3=CopyEntity(mesh1) mesh4=CopyEntity(mesh1) ; das Mesh 4x im Quadrat setzen PositionEntity mesh1,0,0,0 PositionEntity mesh2,128,0,0 PositionEntity mesh3,128,0,128 PositionEntity mesh4,0,0,128 ; Mauszeiger in die Mitte MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 ; Hauptschleife While Not KeyHit(1) ; FPS counter FPS_C=FPS_C+1 If ms<MilliSecs() ms=MilliSecs()+1000 FPS=FPS_C FPS_C=0 EndIf ; Zusatztasten If KeyHit(57) Then wf=1-wf ; Space = Wireframe an/aus If KeyHit(2) Then m1=1-m1 ; 1 = Mesh 1 an/aus If KeyHit(3) Then m2=1-m2 ; 2 = Mesh 2 an/aus If KeyHit(4) Then m3=1-m3 ; 3 = Mesh 3 an/aus If KeyHit(5) Then m4=1-m4 ; 4 = Mesh 4 an/aus If m1 Then HideEntity mesh1 Else ShowEntity mesh1 If m2 Then HideEntity mesh2 Else ShowEntity mesh2 If m3 Then HideEntity mesh3 Else ShowEntity mesh3 If m4 Then HideEntity mesh4 Else ShowEntity mesh4 ; Maussteuerung PlayerControls() ; rendern WireFrame wf RenderWorld ; Infos ausgeben Text 0,0,"Tris: "+TrisRendered()+" FPS: "+FPS ; Bufferflip Flip 0 Wend End ; Spielersteuerung Function PlayerControls() mxspd# = MouseXSpeed()*0.25 myspd# = MouseYSpeed()*0.25 MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 targetpitch = targetpitch + myspd targetpitch = ClampValue(targetpitch, -85,85) targetyaw = targetyaw - mxspd cam_pitch = cam_pitch + (targetpitch - cam_pitch)/8.0 cam_yaw = cam_yaw + (targetyaw - cam_yaw)/8.0 RotateEntity player,0,cam_yaw,0 RotateEntity cam,cam_pitch,0,0 If KeyDown(200) Then mvz=mvz+speed# ; Pfeil rauf = vorwärts If KeyDown(208) Then mvz=mvz-speed# ; Pfeil runter = rückwärts If KeyDown(205) Then mvx=mvx+speed# ; Pfeil rechts = rechts If KeyDown(203) Then mvx=mvx-speed# ; Pfeil links = links If MouseDown(1) Then mvy=mvy+speed# ; LMB = nach oben If MouseDown(2) Then mvy=mvy-speed# ; RMB = nach unten If KeyDown(17) Then mvz=mvz+speed# ; W = vorwärts If KeyDown(31) Then mvz=mvz-speed# ; S = rückwärts If KeyDown(30) Then mvx=mvx-speed# ; A = links If KeyDown(32) Then mvx=mvx+speed# ; D = rechts If KeyDown(16) Then mvy=mvy+speed# ; Q = nach oben If KeyDown(18) Then mvy=mvy-speed# ; E = nach unten TranslateEntity player,0,mvy,0 MoveEntity player,mvx,0,mvz mvx=mvx/1.2 mvy=mvy/1.2 mvz=mvz/1.2 End Function ; Vertikale Begrenzung Function ClampValue(Original#, low#, high#) If Original<low Then Return low If Original>high Then Return high Return Original End Function ; Meshterrain aus Heightmap laden, evt. Colormap und Shadowmap blenden Function LoadMeshTerrain(hmap$,tmap$=0,lmap$=0) ; Heightmap laden temp = LoadImage(hmap$) If temp = 0 Then RuntimeError "Heightmap image "+hmap$+" does not exist." : Return 0 ; Grösse speichern x = ImageWidth(temp)-1 y = ImageHeight(temp)-1 ; Colormap und Shadowmap laden tmap = LoadTexture(tmap$) lmap = LoadTexture(lmap$) ; und auf meshgrösse skalieren If tmap ScaleTexture tmap,x,y If lmap ScaleTexture lmap,x,y ; Terrainmesh erstellen mesh = CreateMesh() surf = CreateSurface(mesh) ; Vertexe erstellen For ly = 0 To y For lx = 0 To x AddVertex surf,lx,0,ly,1.0/lx,1.0/ly Next Next RenderWorld ; Vertexe mit Faces verbinden For ly = 0 To y-1 For lx = 0 To x-1 AddTriangle surf,lx+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly) AddTriangle surf,(lx+1)+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly)+(x+1) Next Next ; Terrain nach 0,0,0 PositionMesh mesh,-x/2.0,0,-y/2.0 ; Vertexhöhe richtet sich nach dem Rotanteil der Heightmap SetBuffer ImageBuffer(temp) LockBuffer ImageBuffer(temp) For lx = 0 To x For ly = 0 To y ; Rotanteil des Pixel auslesen h=(ReadPixelFast(lx,y-ly) And $ff0000)/$10000 index = lx + ((x+1)*ly) VertexCoords surf,index,VertexX(surf,index),h/10.0,VertexZ(surf,index) ; Texturkoordinaten setzen VertexTexCoords surf,index,lx,-ly Next Next UnlockBuffer ImageBuffer(temp) SetBuffer BackBuffer() ; Normale updaten UpdateNormals mesh ; Colormap hinzufügen If tmap EntityTexture mesh,tmap,0,0 ; Shadowmap hinzufügen If lmap EntityTexture mesh,lmap,0,1 : TextureBlend lmap,2 ; Terrain übergeben Return Mesh End Function |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich vermute mal, dass du beim auslesen der Highmap folgendes machst:
Highmap mit einer Kantenlänge von 1024 Pixeln beim auslesen in 2 Teile X und 2 Teile Y. Auslesen der Highmap nun für X1 von 0 bis 511 und für X2 von 512 bis 1023 Hier wird zwar rein rechnerisch nichts überrprungen, aber es findet keine Interpolation zwischen Pixel 511 und 512 statt. Daher müsste man es wie folgt machen: Auslesen der Highmap nun für X1 von 0 bis 511 und für X2 von 511 bis ~1022 Hier würden dann die überlagerte Kanten die gleichen Maphöhe ergeben. Also die Vertices würden genau übereinander liegen. Leider konnte ich den Code so auf die Schnelle nicht explizit darauf untersuchen, da ich selber noch reinsteigern müsste. Aber versuche mal, ob es daran liegt. Ansonsten schöne Arbeit. Sieht sehr gut aus. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Den Hauptcode der Heightmap>Meshterrain-Umwandlung hab ich mir hier abgeschaut bzw. einfach kopiert - aber selbst visualisiert *hüstel*.
Interessant ist, dass das Rendern sauschnell ist, ich hab hier auf einem alten T30 mit Radeon 7500 (16MB) bei den max. 130.000 Tris noch 77FPS ![]() ![]() Was mich nur wundert sind diese minimalsten Höhenunterschiede bei den Nähten. Wenn ich eine rein schwarze Heightmap (also alles Level 0) verwende, gibt es diese gar nicht, seltsam (oder man sieht sie nur nicht). Vielleicht liegt es auch an der "Ungenauigkeit" von Blitz3D, was ja "nur" sechs(?) Stellen nach dem Komma berücksichtigt. |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ne, die stellen hinter dem Komma reichen schon. Wenn du genau hinsiehst, dann wirst du feststellen, dass immer genau 1 Highmap-Pixel fehlt. Du musst auf jeden fall, die Highmap-Pixelreihe die du bei dem einem Mesh am Ende ausgelesen hast, beim nächsten nochmal auslesen. Die Nahtstellen müssen also bei jedem benachbartem Mesh auch mit rein. Bei Schrägen kannst du das genau erkennen, dass immer genau eine Stufe fehlt. | ||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich weiss jetzt woran es liegt. Wenn man die Tileränder der Heightmap mal mit einer Farbpipette vergleicht, dann sieht man, dass es dort minimalste Unterschiede in der Helligkeit gibt. Das kommt davon, wenn man Heightmaps resized, trotz bilinearem Filter.
Die Lösung: Nach dem Resize einfach die gegenüberliegenden Kanten so überblenden, dass sich die Farben auf dem Pixelrand gleichen, der Code oben ist also völlig in Ordnung, klappt sogar mit "geraden" Heightmaps. Den Code hab irgendwo her, weiss aber nicht mehr genau wo der dabei war. Aufruf: MakeSeamless(image,1) ,1 = 1 Pixel am Rand überblenden Code: [AUSKLAPPEN] Function MakeSeamless(Image,Intensity#,Horizontal=True,Vertical=True,Method#=0.5,Variance#=0.0)
Local Width,Height Local Border ;Set up the image WriteBuff=ImageBuffer(Image) Width=ImageWidth(Image)-1 Height=ImageHeight(Image)-1 Border=((Width+Height)/2)*Intensity/2 Border2=((Width+Height)/2)*Method/2 ;Lock the buffer LockBuffer WriteBuff ;Make seamless If Horizontal Then For x=0 To Border x2=Width-x p#=Float(x)/Float(Border) p2#=Float(x)/Float(Border2) If p2>1 Then p2=1 For y=1 To Height clr1=ReadPixelFast(x2,y,WriteBuff) clr2=ReadPixelFast(x,y,WriteBuff) r1=clr1 Shr 16 And $FF:g1=clr1 Shr 8 And $FF:b1=clr1 And $FF r2=clr2 Shr 16 And $FF:g2=clr2 Shr 8 And $FF:b2=clr2 And $FF ;Color filter rc=(r1-r2)*(1-p) gc=(g1-g2)*(1-p) bc=(b1-b2)*(1-p) If y=0 Then frc#=rc:fgc#=gc:fbc#=bc frc#=frc#+Variance*(rc-frc) fgc#=fgc#+Variance*(gc-fgc) fbc#=fbc#+Variance*(bc-fbc) If r2+frc>255 Then frc=255-r2 If g2+fgc>255 Then fgc=255-g2 If b2+fbc>255 Then fbc=255-b2 If r2+frc<0 Then frc=0-r2 If g2+fgc<0 Then fgc=0-g2 If b2+fbc<0 Then fbc=0-b2 r2=r2+frc g2=g2+fgc b2=b2+fbc ;Clone filter r2=(1-p2)*r1+p2*r2 g2=(1-p2)*g1+p2*g2 b2=(1-p2)*b1+p2*b2 If r2<0 Then r2=0 If r2>255 Then r2=255 If g2<0 Then g2=0 If g2>255 Then g2=255 If b2<0 Then b2=0 If b2>255 Then b2=255 clr2=(r2 Shl 16)+(g2 Shl 8)+(b2) WritePixelFast(x,y,clr2,WriteBuff) Next Next End If If Vertical Then For y=0 To Border y2=Height-y p#=Float(y)/Float(Border) p2#=Float(y)/Float(Border2) If p2>1 Then p2=1 For x=0 To Width clr1=ReadPixelFast(x,y2,WriteBuff) clr2=ReadPixelFast(x,y,WriteBuff) r1=clr1 Shr 16 And $FF:g1=clr1 Shr 8 And $FF:b1=clr1 And $FF r2=clr2 Shr 16 And $FF:g2=clr2 Shr 8 And $FF:b2=clr2 And $FF ;Color filter rc=(r1-r2)*(1-p) gc=(g1-g2)*(1-p) bc=(b1-b2)*(1-p) If x=0 Then frc#=rc:fgc#=gc:fbc#=bc frc#=frc#+Variance*(rc-frc) fgc#=fgc#+Variance*(gc-fgc) fbc#=fbc#+Variance*(bc-fbc) If r2+frc>255 Then frc=255-r2 If g2+fgc>255 Then fgc=255-g2 If b2+fbc>255 Then fbc=255-b2 If r2+frc<0 Then frc=0-r2 If g2+fgc<0 Then fgc=0-g2 If b2+fbc<0 Then fbc=0-b2 r2=r2+frc g2=g2+fgc b2=b2+fbc ;Clone filter r2=(1-p2)*r1+p2*r2 g2=(1-p2)*g1+p2*g2 b2=(1-p2)*b1+p2*b2 clr2=(r2 Shl 16)+(g2 Shl 8)+(b2) WritePixelFast(x,y,clr2,WriteBuff) Next Next End If ;Unlock the buffer UnlockBuffer WriteBuff End Function Die Performance ist übrigens oberklasse, ich hab einfach mal dutzende Maps plaziert und das auf meinem Desktop (P4 3.2, Radeon 9800Pro) laufen lassen, bei 2.6 Millionen Tris waren es noch 20FPS ![]() ![]() |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das mit dem korrigieren der Highmap, hast du nichts anderes gemacht, als mein Vorschlag 'zu Fuss' zu erledigen. Bei jeder Highmap musst du nun eine manuelle Korrektur durchführen.
Die Performence ist gut, aber ich finde sie nicht so ganz oberklasse, da sie bei mir bis auf 90 FPS runter gegangen ist. Da sollte auf jeden Fall noch was gemacht werden, meiner Meinung nach. Sonst hat man kaum noch Raum für andere Sachen. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
So, ich habe das Ganze noch einmal weiterentwickelt, das Ergebnis habe ich mal "Monkey Island" genannt, weil es mich so an die Draufsicht im gleichnamigen Spiel erinnert.
Download mit Source Screenshot: ![]() Der jetzige Code kann aus einer 256x256 Pixel grossen Heightmap eigenständig ein Meshterrain erstellen, welches dann aus 32x32 = 1024 einzelnen Tiles besteht (ca. 131.000 Tris). Zudem erstellt es aus zwei separaten 2048x2048 Pixel grossen Grafiken (Colormap / Lightmap) je 1024 Texturen (à 64x64), die dann auf die entsprechenden Meshterrains geblendet werden. @hectic: Der Trick mit den Nahtstellen war übrigens hier, 9x9 anstatt 8x8 Pixel grosse Blöcke aus der Heightmap zu nehmen... Passt halt nur nicht ganz genau mit den UV-Koordinaten zusammen (sieht man aber nur, wenn man nah rangeht, ausserdem siehts durch die JPEG-Kompression der Colormap noch schlimmer aus). Steuerung:
Das Ding ist nicht perfekt und ich bin ehrlich gesagt überhaupt froh, dass es so einigermassen aussieht. Grosser Nachteil im Moment sind fehlendes Culling und ein merkwürdiger UV-Fehler an den Nahtstellen (da blendet die Textur nicht so 100% über, eher zu 99.9%). Durch das fehlende Culling und die vielen Texturen sind die FPS jetzt auch etwas in den Keller gegangen. Wie könnte man hier ein sinnvolles Culling realisieren oder das Ganze noch weiter optimieren? Ich erinnere mich da an meine Mapperzeit im Radiant, da gab es doch sowas wie VIS-Blöcke oder PVS? Ich hab keine Ahnung wie man das umsetzen könnte, evt. irgendwie vorberechnet vielleicht? Wie schnell läuft das bei Euch? Ich hab hier ca. 45FPS bei 128 Sichtweite und ca. 40.000 Tris im Schnitt. Code: [AUSKLAPPEN] ; Meshterrain Demo
; Version 1.0 ; ; 3D-Flug über eine virtuelle Insel (einfach mal Monkey Island genannt) ; by Krischan ; ; - erstellt ein 32x32=1024 Tiles grosses nahtloses Meshterrain aus einer 256x256 Heightmap ; - zerteilt je eine 2048x2048 Bild in 1024 Texturen und blendet die Color/Lightmap auf jedes Tile ; - Culling nicht implementiert ; - leichte UV-Fehler an den Nahtstellen ; ; Texturen und Heightmap generiert mit Large 3D Terrain SE 2.5 (http://www.bundysoft.com/L3DT) ; Grafikmodus Graphics3D 1024,768,32,1 SetBuffer FrontBuffer() ; Felder dimensionieren Dim hm(32,32),cm(32,32),lm(32,32),tile(32,32) ; Pivot für Steuerung und globale Variablen Global cam, player Global cam_pitch#, cam_yaw# Global mvx#,mvy#,mvz#,targetpitch#,targetyaw# ; Einstellungen Global speed#=0.00981 ; Laufgeschwindigkeit Global sw=256 ; Standardsichtweite (32-1024) Global sm=1 ; Karte anfangs anzeigen Global abstand#=1.00 ; 1.00 = nahtlos, z.B. 1.01 für Anzeige der Tiles ; Playerpivot player=CreatePivot() PositionEntity player,129,20,-223 EntityType player,1 EntityRadius player,1 ; Kamera an Pivot gehängt cam=CreateCamera(player) PositionEntity cam,0,0,0 CameraZoom cam,1 CameraRange cam,0.01,sw AmbientLight 255,255,255 ; Nebel CameraFogMode cam,True CameraFogRange cam,0,sw CameraFogColor cam,50,100,150 CameraClsColor cam,50,100,150 ; nur Pixelresize TFormFilter 0 ; Bilder einlesen Print "Lade Heightmap..." : hmap=LoadImage("heightmap.png") Print "Lade Colormap..." : cmap=LoadImage("colormap.jpg") Print "Lade Lightmap..." : lmap=LoadImage("lightmap.jpg") ; Leere Texturen erstellen Print "Erstelle Texturen..." For x=1 To 32 For y=1 To 32 cm(x,y)=CreateTexture(64,64,1+16+32) ; leuchtend, UV-Koordinaten fest lm(x,y)=CreateTexture(64,64,1+16+32) ; leuchtend, UV-Koordinaten fest hm(x,y)=CreateImage(9,9) ; Meshtile 9x9 Next Next ; Heightmap in 9x9 grosse Stücke zerteilen Print "Zerschneide Heightmap..." For y=8 To 256 Step 8 For x=8 To 256 Step 8 CopyRect(x-8,y-8,9,9,0,0,ImageBuffer(hmap),ImageBuffer(hm(x/8,y/8))) Next Next ; Colormap und Lightmap als Texturteil für jedes Meshtile aus den Bildern herauskopieren Print "Zerschneide Colourmap and Lightmap..." For y=64 To 2048 Step 64 For x=64 To 2048 Step 64 CopyRect(x-64,y-64,64,64,0,0,ImageBuffer(cmap),TextureBuffer(cm(x/64,y/64))) CopyRect(x-64,y-64,64,64,0,0,ImageBuffer(lmap),TextureBuffer(lm(x/64,y/64))) Next Next ; Colormap für spätere Ausgabe skalieren ResizeImage cmap,256,256 ; und nicht benötigte Grafiken löschen FreeImage(hmap) FreeImage(smap) ; Meshterrain erzeugen und positionieren For x=0 To 256-8 Step 8 For y=0 To -256+8 Step -8 tx=1+Abs(x)/8 : ty=1+Abs(y)/8 ; Hauptfunktion: aus dem 9x9 Heightmaptile ein 8x8 Meshtile erzeugen tile(tx,ty)=LoadMeshTerrain(hm(tx,ty),cm(tx,ty),lm(tx,ty)) PositionEntity tile(tx,ty),x*abstand#,0,y*abstand# EntityType tile(tx,ty),2 Next Next ; Mauszeiger in die Mitte MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 ; Hauptschleife While Not KeyHit(1) ; FPS counter FPS_C=FPS_C+1 If ms<MilliSecs() ms=MilliSecs()+1000 FPS=FPS_C FPS_C=0 EndIf ; Zusatztasten If KeyHit(59) Then wf=1-wf ; Space = Wireframe an/aus If KeyHit(28) Then sm=1-sm ; Return = Map an/aus If KeyHit(201) Then sw=sw+32 ; Bild rauf = Sichtweite höher If KeyHit(209) Then sw=sw-32 ; Bild rauf = Sichtweite höher ; Sichtweite begrenzen If sw<32 Then sw=32 If sw>1024 Then sw=1024 ; Maussteuerung PlayerControls() ; Position des Players berechnen plx#=EntityX(player) : ply#=EntityY(player) : plz#=EntityZ(player) ; Spielfeld begrenzen If plx#<5 Then plx#=5 If plx#>250 Then plx#=250 If plz#>5 Then plz#=5 If plz#<-250 Then plz#=-250 ; ein wenig Schwerkraft simulieren ply#=ply#-(speed#*10) ; Spieler neu positionieren PositionEntity player,plx#,ply#,plz# ; Sichtweite anpassen CameraRange cam,0.01,sw CameraFogRange cam,0,sw ; Kollisionen überprüfen Collisions 1,2,2,2 ; Rendern WireFrame wf UpdateWorld RenderWorld ; Infos ausgeben Color 255,255,255 Text 0,0,"Tris: "+TrisRendered()+" FPS: "+FPS+" Sichtweite: "+sw+" Wireframe: "+wf ; Karte zeigen und Player auf Map als roten Punkt einzeichnen If sm Then Color 0,0,0 Rect 0,15,256,256,1 DrawImage cmap,0,15 Color 255,255,255 Text 0,15,"X:"+Int(plx#)+" Y:"+Int(ply#)+" Z:"+Int(plz#) Color 255,0,0 Oval(plx#-1,15+Abs(plz#)-1,3,3,1) EndIf ; Bufferflip Flip Wend End ; Spielersteuerung Function PlayerControls() mxspd# = MouseXSpeed()*0.25 myspd# = MouseYSpeed()*0.25 MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 targetpitch = targetpitch + myspd targetpitch = ClampValue(targetpitch, -85,85) targetyaw = targetyaw - mxspd cam_pitch = cam_pitch + (targetpitch - cam_pitch)/16.0 cam_yaw = cam_yaw + (targetyaw - cam_yaw)/16.0 RotateEntity player,0,cam_yaw,0 RotateEntity cam,cam_pitch,0,0 If KeyDown(200) Then mvz=mvz+speed# ; Pfeil rauf = vorwärts If KeyDown(208) Then mvz=mvz-speed# ; Pfeil runter = rückwärts If KeyDown(205) Then mvx=mvx+speed# ; Pfeil rechts = rechts If KeyDown(203) Then mvx=mvx-speed# ; Pfeil links = links If MouseDown(1) Then mvy=mvy+speed# ; LMB = nach oben If MouseDown(2) Then mvy=mvy-speed# ; RMB = nach unten If KeyDown(17) Then mvz=mvz+speed# ; W = vorwärts If KeyDown(31) Then mvz=mvz-speed# ; S = rückwärts If KeyDown(30) Then mvx=mvx-speed# ; A = links If KeyDown(32) Then mvx=mvx+speed# ; D = rechts If KeyDown(16) Then mvy=mvy+speed# ; Q = nach oben If KeyDown(18) Then mvy=mvy-speed# ; E = nach unten TranslateEntity player,0,mvy,0 MoveEntity player,mvx,0,mvz mvx=mvx/1.05 mvy=mvy/1.05 mvz=mvz/1.05 End Function ; Vertikale Begrenzung Function ClampValue(Original#, low#, high#) If Original<low Then Return low If Original>high Then Return high Return Original End Function ; Meshterrain aus Heightmap laden, evt. Colormap und Shadowmap blenden Function LoadMeshTerrain(heightmap,colormap=False,lightmap=False) ; Grösse speichern x = ImageWidth(heightmap)-1 y = ImageHeight(heightmap)-1 ; Textur auf Meshgrösse skalieren If colormap ScaleTexture colormap,x,y If lightmap ScaleTexture lightmap,x,y ; Terrainmesh erstellen mesh = CreateMesh() surf = CreateSurface(mesh) ; Vertexe erstellen For ly = 0 To y For lx = 0 To x AddVertex surf,lx,0,ly,1.0/lx,1.0/ly Next Next ; Vertexe mit Faces verbinden For ly = 0 To y-1 For lx = 0 To x-1 AddTriangle surf,lx+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly) AddTriangle surf,(lx+1)+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly)+(x+1) Next Next ; Terrain nach 0,0,0 PositionMesh mesh,-x/2.0,0,-y/2.0 ; Vertexhöhe richtet sich nach dem Rotanteil der Heightmap SetBuffer ImageBuffer(heightmap) LockBuffer ImageBuffer(heightmap) For lx = 0 To x For ly = 0 To y ; Rotanteil des Pixel auslesen h=(ReadPixelFast(lx,y-ly) And $ff0000)/$10000 index = lx + ((x+1)*ly) VertexCoords surf,index,VertexX(surf,index),h/8.0,VertexZ(surf,index) ; Texturkoordinaten setzen VertexTexCoords surf,index,lx,y-ly Next Next UnlockBuffer ImageBuffer(heightmap) SetBuffer BackBuffer() ; Normale updaten UpdateNormals mesh ; Colormap hinzufügen If colormap EntityTexture mesh,colormap,0,0 ; Shadowmap hinzufügen If lightmap EntityTexture mesh,lightmap,0,1 : TextureBlend lightmap,2 ; Terrain übergeben Return Mesh End Function |
||
martin_moehler |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also bei den Standarteinstellung komm ich grad ma auf 25 FPS!
Auch wenn ich dazu sagen muss da meine Hardware schon leicht veraltet ist. aber 25 FPS... is nich viel!! ![]() Aber sieht echt geil aus!! |
||
Moses |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
finds ziehmlich gut bis jetzt, fps gehen bei nem 1,4 er k7 mit ner g4ti auf 18 runter ... bei 130000 tris (kartenecke)
mit den kanten die manchmal nicht sauber abschliessen, man könnte man doch die werte der von den vertexen von der kante des benachbarten tiles gleich fürs nächste verwenden, anstatt sie nochmal von der higmap zu lesen, oder du gehtst alle kanten nochmal durch und 'snappst' die vertexe aufeinander... mit den textur-nähten bin ich aber auch überfordert, so nach 100 einheiten fällt es ja weniger auf aber davor isses übel ![]() zur performanceoptimierung währe es wünschenswert tiles die von anderen komplett verdeckt werden auch gleich mal auszublenden ... dazu könnte man: - den winkel des vektors von der cam zum höchstem vertex des zu prüfenden tile (dafür ymax-koordinaten für jedes tile hinterlegen) ermitteln - mit den winkeln der vektoren von der cam zu den niedrigsten vertexes der tiles die davor liegen vergleichen (hierfür ymin-koordinaten für jedes tile hinterlegen) ... ![]() die grafik verdeutlicht das nochmal, und der enscheidungsfall wenn beide zuvergleichende koordinaten dieselben sind bzw, die winkel gleich ist auch einleuchtend, ob sich der rechenaufand lohnt kommt darauf an wie deatailiert die tiles sind und wie viele tiles du hast... aso landschaftreflektionen auf wasserflächen oder spiegelde objekte fällt damit natürlich flach... ... hoffe das war jetzt kein bockmist ^^ |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das wird wohl immer soweit runter gehen.
Die Menge an Surfaces und das fehlende Geomipmapping erzeugen hier einen gigantischen Overhead für die Grafikkarte. Da schon vor jahren mit P4 1.5 Ghz und GeForce 4MX 500'000 Polygon Terrains (also 500'000 sichtbar!) mit bedeutend grösseren Texturen und grösseren Heightmaps möglich waren, ohne das man Sichtbarkeitschecks eingebaut hat (bei 20FPS), denke ich, dass hier noch einiges optimiert werden kann. Der Haupttrick besteht da drin, dafür zu sorgen, dass die Anzahl Blöcke des Terrains und die Anzahl Polygone (Vertices pro Kantenrichtung) in ein gescheites Verhältnis kommen. Gut sind hier normalerweise Terrainblöcke mit einer 32x32 Unterteilung. Dadurch hat man normalerweise nicht zuviele Polygone, so das die Grafikkarte durch den Wechsel der Tiles beeinträchtigt wird, noch hat man zuviele Surfaces was bei 8 und 16 zu einem massiven Problem wird, denn mehr als 800-1200 Surfaces kann man nicht haben im ganzen, deswegen soll und darf man die unter keinen umständen mit dem Terrain auch nur im Ansatz erreichen. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
- Zuletzt bearbeitet von Dreamora am Do, Sep 27, 2007 19:08, insgesamt einmal bearbeitet
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kann Dreamora schonmal Recht geben. Habe vorgestern selbst mal ein Meshterrain erstellt, um zu testen wie ich es so hinbekomme. Bis jetzt läuft mein Meshterrain so etwa doppelt so schnell (etwa gleiche Anzahl Triangles, gleiche Quelldateien) auf meinem System. Ich habe Tileblöcke von 64x64 (65x65 Vertices, 64x64 Quads) erstellt. | ||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group